1: <?php
2:
3: 4: 5: 6:
7: final class Papi_Porter extends Papi_Container {
8:
9: 10: 11: 12: 13:
14: protected $driver;
15:
16: 17: 18:
19: public function __construct() {
20: $this->add_driver( new Papi_Porter_Driver_Core );
21: $this->use_driver( 'core' );
22: $this->driver->bootstrap();
23: }
24:
25: 26: 27: 28: 29: 30: 31:
32: public function add_driver( Papi_Porter_Driver $driver ) {
33: $driver->set_porter( $this );
34: return $this;
35: }
36:
37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
47: public function after( $filter, Closure $closure, $priority = 10, $accepted_args = 2 ) {
48: $filter = $this->driver->filter( 'after', $filter );
49: return add_filter( $filter, $closure, $priority, $accepted_args );
50: }
51:
52: 53: 54: 55: 56: 57: 58: 59: 60: 61:
62: public function before( $filter, Closure $closure, $priority = 10, $accepted_args = 2 ) {
63: $filter = $this->driver->filter( 'before', $filter );
64: return add_filter( $filter, $closure, $priority, $accepted_args );
65: }
66:
67: 68: 69: 70: 71: 72: 73:
74: public function driver( $driver ) {
75: return $driver instanceof Papi_Porter_Driver ?
76: $this->add_driver( $driver ) :
77: $this->use_driver( $driver );
78: }
79:
80: 81: 82: 83: 84: 85: 86:
87: public function driver_exists( $driver ) {
88: return is_string( $driver ) && $this->exists( 'driver.' . $driver );
89: }
90:
91: 92: 93: 94: 95: 96: 97: 98:
99: public function export( $post_id, $only_values = false ) {
100: $post_id = papi_get_post_id( $post_id );
101:
102: if ( empty( $post_id ) ) {
103: return [];
104: }
105:
106: $slugs = papi_get_slugs( $post_id );
107:
108: foreach ( $slugs as $key => $box ) {
109: foreach ( $box as $index => $slug ) {
110: unset( $slugs[$key][$index] );
111: $value = papi_get_field( $post_id, $slug, null );
112:
113: if ( $only_values === true ) {
114: $slugs[$key][$slug] = $value;
115: } else {
116: $page = papi_get_page( $post_id );
117:
118:
119: if ( is_null( $page ) ) {
120: continue;
121: }
122:
123:
124: $property = $page->get_property( $slug );
125:
126:
127: if ( ! papi_is_property( $property ) ) {
128: continue;
129: }
130:
131:
132: $options = clone $property->get_options();
133: $options->value = $value;
134: $slugs[$key][$slug] = $options;
135: }
136: }
137: }
138:
139: return $slugs;
140: }
141:
142: 143: 144: 145: 146: 147: 148: 149: 150: 151:
152: public function fire_filter( array $options ) {
153: if ( ! isset( $options['type'] ) ) {
154: $options['type'] = 'after';
155: }
156:
157: if ( ! isset( $options['filter'] ) ) {
158: throw new Exception( 'Missing `filter` in options array.' );
159: }
160:
161: if ( ! isset( $options['value'] ) ) {
162: throw new Exception( 'Missing `value` in options array.' );
163: }
164:
165: $arguments = [
166: $this->driver->filter( $options['type'], $options['filter'] ),
167: ];
168:
169: $value = $options['value'];
170:
171: foreach ( papi_to_array( $value ) as $val ) {
172: $arguments[] = $val;
173: }
174:
175: return call_user_func_array( 'apply_filters', $arguments );
176: }
177:
178: 179: 180: 181: 182: 183: 184:
185: protected function get_import_options( $options ) {
186: $default_options = [
187: 'post_id' => 0,
188: 'page_type' => '',
189: 'update_arrays' => false
190: ];
191:
192: if ( ! is_array( $options ) ) {
193: $options = array_merge( $default_options, [
194: 'post_id' => papi_get_post_id( $options )
195: ] );
196: }
197:
198: return $options;
199: }
200:
201: 202: 203: 204: 205: 206: 207:
208: protected function get_value( array $options ) {
209: return $this->driver->get_value( $options );
210: }
211:
212: 213: 214: 215: 216: 217: 218: 219:
220: public function import( $options, array $fields = [] ) {
221: $options = $this->get_import_options( $options );
222: $post_id = $options['post_id'];
223: $page_type = $options['page_type'];
224:
225: if ( isset( $options['update_arrays'] ) ) {
226: $this->driver->set_options( [
227: 'update_array' => $options['update_arrays']
228: ] );
229: }
230:
231: if ( empty( $post_id ) || empty( $fields ) ) {
232: return false;
233: }
234:
235: if ( empty( $page_type ) ) {
236: $page_type = papi_get_page_type_by_post_id( $options['post_id'] );
237: }
238:
239: if ( is_string( $page_type ) ) {
240: $page_type = papi_get_page_type_by_id( $page_type );
241: }
242:
243: if ( ! papi_is_page_type( $page_type ) ) {
244: return false;
245: }
246:
247: $result = true;
248:
249: foreach ( $fields as $slug => $value ) {
250: if ( ! is_string( $slug ) || papi_is_empty( $value ) ) {
251: continue;
252: }
253:
254: $property = $page_type->get_property( $slug );
255:
256: if ( ! papi_is_property( $property ) ) {
257: $result = false;
258: continue;
259: }
260:
261: $value = $this->fire_filter( [
262: 'filter' => 'driver:value',
263: 'type' => 'before',
264: 'value' => [
265: $value,
266: $slug
267: ]
268: ] );
269:
270: $value = $this->get_value( [
271: 'post_id' => $post_id,
272: 'property' => $property,
273: 'slug' => $slug,
274: 'value' => $value
275: ] );
276:
277: $value = $this->fire_filter( [
278: 'filter' => 'driver:value',
279: 'type' => 'after',
280: 'value' => [
281: $value,
282: $slug
283: ]
284: ] );
285:
286: $out = papi_update_property_meta_value( [
287: 'post_id' => $post_id,
288: 'slug' => $slug,
289: 'value' => $value
290: ] );
291:
292: $result = $out ? $result : $out;
293: }
294:
295: return $result;
296: }
297:
298: 299: 300: 301: 302: 303: 304:
305: public function options( array $options = [] ) {
306: $this->driver->set_options( [
307: 'custom' => $options
308: ] );
309: return $this;
310: }
311:
312: 313: 314: 315: 316: 317: 318: 319: 320: 321:
322: public function use_driver( $driver ) {
323: if ( ! is_string( $driver ) ) {
324: throw new InvalidArgumentException(
325: 'Invalid argument. Must be string.'
326: );
327: }
328:
329: $driver = strtolower( $driver );
330:
331: if ( ! $this->exists( 'driver.' . $driver ) ) {
332: throw new Exception( sprintf(
333: '`%s` driver does not exist.',
334: $driver
335: ) );
336: }
337:
338: $class = $this->make( 'driver.' . $driver );
339:
340: if ( class_exists( $class ) ) {
341: $this->driver = new $class( $this );
342: $this->driver->bootstrap();
343: }
344:
345: return $this;
346: }
347: }
348: