PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / 3.3.4
Pods – Custom Content Types and Fields v3.3.4
trunk 1.14.8 2.7.31.3 2.8.23.3 2.9.19.3 3.0.10.3 3.1.4.1 3.2.0 3.2.1 3.2.1.1 3.2.2 3.2.4 3.2.5 3.2.6 3.2.7 3.2.7.1 3.2.8 3.2.8.1 3.2.8.2 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9
pods / classes / PodsComponents.php
pods / classes Last commit date
cli 3 years ago fields 9 months ago widgets 11 months ago Pods.php 9 months ago PodsAPI.php 11 months ago PodsAdmin.php 1 year ago PodsArray.php 2 years ago PodsComponent.php 8 years ago PodsComponents.php 1 year ago PodsData.php 1 year ago PodsField.php 1 year ago PodsForm.php 11 months ago PodsI18n.php 4 years ago PodsInit.php 9 months ago PodsMeta.php 9 months ago PodsMigrate.php 3 years ago PodsRESTFields.php 1 year ago PodsRESTHandlers.php 1 year ago PodsTermSplitting.php 3 years ago PodsUI.php 1 year ago PodsView.php 1 year ago
PodsComponents.php
871 lines
1 <?php
2
3 /**
4 * Component managing class
5 *
6 * @package Pods
7 */
8 class PodsComponents {
9
10 /**
11 * @var PodsComponents
12 */
13 public static $instance = null;
14
15 /**
16 * Root of Components directory
17 *
18 * @var string
19 *
20 * @private
21 * @since 2.0.0
22 */
23 private $components_dir = null;
24
25 /**
26 * Available components
27 *
28 * @var array
29 *
30 * @since 2.0.0
31 */
32 public $components = [];
33
34 /**
35 * Registered component menu items.
36 *
37 * @var array
38 *
39 * @since 2.9.8
40 */
41 public $components_menu_items = [];
42
43 /**
44 * Components settings
45 *
46 * @var array
47 *
48 * @since 2.0.0
49 */
50 public $settings = [];
51
52 /**
53 * Singleton handling for a basic pods_components() request
54 *
55 * @return \PodsComponents
56 *
57 * @since 2.3.5
58 */
59 public static function init() {
60
61 if ( ! is_object( self::$instance ) ) {
62 self::$instance = new self();
63 }
64
65 return self::$instance;
66 }
67
68 /**
69 * Setup actions and get options
70 *
71 * @since 2.0.0
72 */
73 public function __construct() {
74
75 $this->components_dir = realpath( apply_filters( 'pods_components_dir', PODS_DIR . 'components' ) ) . '/';
76
77 $settings = get_option( 'pods_component_settings', '' );
78
79 if ( ! empty( $settings ) ) {
80 $this->settings = (array) json_decode( $settings, true );
81 }
82
83 if ( ! isset( $this->settings['components'] ) ) {
84 $this->settings['components'] = array();
85 }
86
87 // Get components (give it access to theme)
88 add_action( 'setup_theme', array( $this, 'get_components' ), 11 );
89
90 // Load in components
91 add_action( 'setup_theme', array( $this, 'load' ), 12 );
92
93 // AJAX handling
94 if ( is_admin() ) {
95 add_action( 'wp_ajax_pods_admin_components', array( $this, 'admin_ajax' ) );
96 add_action( 'wp_ajax_nopriv_pods_admin_components', array( $this, 'admin_ajax' ) );
97
98 // Add the Pods Components capabilities
99 add_filter( 'members_get_capabilities', array( $this, 'admin_capabilities' ) );
100 }
101 }
102
103 /**
104 * Add menu item
105 *
106 * @param string $parent The parent slug.
107 *
108 * @since 2.0.0
109 *
110 * @uses add_submenu_page
111 */
112 public function menu( $parent ) {
113
114 global $submenu;
115
116 $custom_component_menus = array();
117
118 $pods_component_menu_items = array();
119
120 foreach ( $this->components as $component => $component_data ) {
121 $component_id = $component_data['ID'];
122
123 $component_data['MustUse'] = apply_filters( "pods_component_require_{$component_id}", $component_data['MustUse'], $component_data );
124
125 if ( empty( $component_data['MustUse'] ) && ( ! isset( $this->settings['components'][ $component ] ) || 0 === $this->settings['components'][ $component ] ) ) {
126 continue;
127 }
128
129 if ( ! empty( $component_data['Hide'] ) ) {
130 continue;
131 }
132
133 if ( ! empty( $component_data['DeveloperMode'] ) && ! pods_developer() ) {
134 continue;
135 }
136
137 if ( empty( $component_data['TablelessMode'] ) && pods_tableless() ) {
138 continue;
139 }
140
141 if ( empty( $component_data['MenuPage'] ) ) {
142 if ( ! isset( $component_data['object'] ) ) {
143 continue;
144 } elseif ( ! method_exists( $component_data['object'], 'admin' ) && ! method_exists( $component_data['object'], 'options' ) ) {
145 continue;
146 }
147 }
148
149 if ( false === $component_data['External'] ) {
150 $component_data['File'] = realpath( $this->components_dir . $component_data['File'] );
151 }
152
153 if ( ! file_exists( $component_data['File'] ) ) {
154 pods_message( 'Pods Component not found: ' . $component_data['File'] );
155
156 pods_transient_clear( 'pods_components' );
157
158 continue;
159 }
160
161 $capability = 'pods_component_' . str_replace( '-', '_', sanitize_title( $component ) );
162
163 if ( 0 < strlen( (string) $component_data['Capability'] ) ) {
164 $capability = $component_data['Capability'];
165 }
166
167 if ( ! pods_is_admin( array( 'pods', 'pods_components', $capability ) ) ) {
168 continue;
169 }
170
171 $menu_page = 'pods-component-' . $component;
172
173 if ( ! empty( $component_data['MenuPage'] ) ) {
174 $custom_component_menus[ $menu_page ] = $component_data;
175 }
176
177 $pods_component_menu_items[ $component_data['MenuName'] ] = array(
178 'menu_page' => $menu_page,
179 'page_title' => $component_data['Name'],
180 'capability' => 'read',
181 'callback' => array( $this, 'admin_handler' ),
182 );
183
184 if ( isset( $component_data['object'] ) && method_exists( $component_data['object'], 'admin_assets' ) ) {
185 $pods_component_menu_items[ $component_data['MenuName'] ]['assets'] = array(
186 $component_data['object'],
187 'admin_assets',
188 );
189 }
190 }//end foreach
191
192 /**
193 * Add or change the items in the Pods Components Submenu.
194 *
195 * Can also be used to change which menu components is a submenu of or change title of menu.
196 *
197 * @param array $pods_component_menu_items {
198 * An array of arguments for add_submenu_page
199 *
200 * @type string $parent_slug The slug name for the parent menu (or the file name of a standard WordPress admin page)
201 * @type string $page_title The text to be displayed in the title tags of the page when the menu is selected
202 * @type string $menu_title The text to be used for the menu
203 * @type string $capability The capability required for this menu to be displayed to the user.
204 * @type string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
205 * @type string $function The function to be called to output the content for this page.
206 * }
207 *
208 * @since 2.4.1
209 */
210 $pods_component_menu_items = apply_filters( 'pods_admin_components_menu', $pods_component_menu_items );
211
212 ksort( $pods_component_menu_items );
213
214 $this->components_menu_items = $pods_component_menu_items;
215
216 foreach ( $pods_component_menu_items as $menu_title => $menu_data ) {
217 if (
218 (
219 '' !== $menu_data['callback']
220 || false === strpos( $menu_data['menu_page'], '.php' )
221 )
222 && ! is_callable( $menu_data['callback'] )
223 ) {
224 continue;
225 }
226
227 $page = add_submenu_page( $parent, strip_tags( $menu_data['page_title'] ), '- ' . strip_tags( $menu_title ), pods_v( 'capability', $menu_data, 'read', true ), $menu_data['menu_page'], $menu_data['callback'] );
228
229 if ( isset( $menu_data['assets'] ) && is_callable( $menu_data['assets'] ) ) {
230 add_action( 'admin_print_styles-' . $page, $menu_data['assets'] );
231 }
232 }
233
234 if ( ! empty( $custom_component_menus ) ) {
235 foreach ( $custom_component_menus as $menu_page => $component_data ) {
236 if ( isset( $submenu[ $parent ] ) ) {
237 foreach ( $submenu[ $parent ] as $sub => &$menu ) {
238 if ( $menu[2] === $menu_page ) {
239 $menu_page = $component_data['MenuPage'];
240
241 $menu[2] = $menu_page;
242
243 $page = current( explode( '?', $menu[2] ) );
244
245 if ( isset( $component_data['object'] ) && method_exists( $component_data['object'], 'admin_assets' ) ) {
246 add_action(
247 'admin_print_styles-' . $page, array(
248 $component_data['object'],
249 'admin_assets',
250 )
251 );
252 }
253
254 break;
255 }//end if
256 }//end foreach
257 }//end if
258 }//end foreach
259 }//end if
260 }
261
262 /**
263 * Load activated components and init component
264 *
265 * @since 2.0.0
266 */
267 public function load() {
268
269 do_action( 'pods_components_load' );
270
271 foreach ( (array) $this->components as $component => $component_data ) {
272 $component_id = $component_data['ID'];
273
274 $component_data['MustUse'] = apply_filters( "pods_component_require_{$component_id}", $component_data['MustUse'], $component_data );
275
276 if ( false === $component_data['MustUse'] && ( ! isset( $this->settings['components'][ $component ] ) || 0 === $this->settings['components'][ $component ] ) ) {
277 continue;
278 }
279
280 if ( ! empty( $component_data['PluginDependency'] ) ) {
281 $dependency = explode( '|', $component_data['PluginDependency'] );
282
283 if ( ! pods_is_plugin_active( $dependency[1] ) ) {
284 continue;
285 }
286 }
287
288 if ( ! empty( $component_data['ThemeDependency'] ) ) {
289 $dependency = explode( '|', $component_data['ThemeDependency'] );
290
291 $check = strtolower( $dependency[1] );
292
293 if ( strtolower( get_template() ) !== $check && strtolower( get_stylesheet() ) !== $check ) {
294 continue;
295 }
296 }
297
298 if ( false === $component_data['External'] ) {
299 $component_data['File'] = realpath( $this->components_dir . $component_data['File'] );
300 }
301
302 if ( empty( $component_data['File'] ) ) {
303 pods_transient_clear( 'pods_components' );
304
305 continue;
306 }
307
308 if ( ! file_exists( $component_data['File'] ) ) {
309 pods_message( 'Pods Component not found: ' . $component_data['File'] );
310
311 pods_transient_clear( 'pods_components' );
312
313 continue;
314 }
315
316 include_once $component_data['File'];
317
318 if ( ( ! empty( $component_data['Class'] ) && class_exists( $component_data['Class'] ) ) || isset( $component_data['object'] ) ) {
319 if ( ! isset( $this->components[ $component ]['object'] ) ) {
320 $this->components[ $component ]['object'] = new $component_data['Class']();
321 }
322
323 if ( method_exists( $this->components[ $component ]['object'], 'options' ) ) {
324 if ( isset( $this->settings['components'][ $component ] ) ) {
325 $this->components[ $component ]['options'] = $this->components[ $component ]['object']->options( $this->settings['components'][ $component ] );
326 } else {
327 $this->components[ $component ]['options'] = $this->components[ $component ]['object']->options( array() );
328 }
329
330 $this->options( $component, $this->components[ $component ]['options'] );
331 } else {
332 $this->options( $component, array() );
333 }
334
335 if ( method_exists( $this->components[ $component ]['object'], 'handler' ) ) {
336 $this->components[ $component ]['object']->handler( $this->settings['components'][ $component ] );
337 }
338 }//end if
339 }//end foreach
340 }
341
342 /**
343 * Get list of components available
344 *
345 * @since 2.0.0
346 */
347 public function get_components() {
348
349 $components = pods_transient_get( 'pods_components' );
350
351 if ( 1 === (int) pods_v( 'pods_debug_components', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) ) {
352 $components = array();
353 }
354
355 if ( PODS_VERSION !== PodsInit::$version || ! is_array( $components ) || empty( $components ) || ( is_admin() && 'pods-components' === pods_v( 'page' ) && 1 !== (int) pods_transient_get( 'pods_components_refresh' ) ) ) {
356 do_action( 'pods_components_get' );
357
358 // @codingStandardsIgnoreLine
359 $component_dir = @opendir( untrailingslashit( $this->components_dir ) );
360 $component_files = array();
361
362 if ( false !== $component_dir ) {
363 $file = readdir( $component_dir );
364
365 while ( false !== $file ) {
366 if ( '.' === substr( $file, 0, 1 ) ) {
367 // Get next file
368 $file = readdir( $component_dir );
369
370 continue;
371 } elseif ( is_dir( $this->components_dir . $file ) ) {
372 // @codingStandardsIgnoreLine
373 $component_subdir = @opendir( $this->components_dir . $file );
374
375 if ( $component_subdir ) {
376 $subfile = readdir( $component_subdir );
377
378 while ( false !== $subfile ) {
379 if ( '.' === substr( $subfile, 0, 1 ) ) {
380 // Get next file
381 $subfile = readdir( $component_subdir );
382
383 continue;
384 } elseif ( '.php' === substr( $subfile, - 4 ) ) {
385 $component_files[] = str_replace( '\\', '/', $file . '/' . $subfile );
386 }
387
388 // Get next file
389 $subfile = readdir( $component_subdir );
390 }
391
392 closedir( $component_subdir );
393 }
394 } elseif ( '.php' === substr( $file, - 4 ) ) {
395 $component_files[] = $file;
396 }//end if
397
398 // Get next file
399 $file = readdir( $component_dir );
400 }//end while
401
402 closedir( $component_dir );
403 }//end if
404
405 $default_headers = [
406 'ID' => 'ID',
407 'Name' => 'Name',
408 'ShortName' => 'Short Name',
409 'PluginName' => 'Plugin Name',
410 'ComponentName' => 'Component Name',
411 'URI' => 'URI',
412 'MenuName' => 'Menu Name',
413 'MenuPage' => 'Menu Page',
414 'MenuAddPage' => 'Menu Add Page',
415 'MustUse' => 'Must Use',
416 'Description' => 'Description',
417 'Deprecated' => 'Deprecated',
418 'DeprecatedInVersion' => 'Deprecated In Version',
419 'DeprecatedRemovalVersion' => 'Deprecated Removal Version',
420 'Version' => 'Version',
421 'Category' => 'Category',
422 'Author' => 'Author',
423 'AuthorURI' => 'Author URI',
424 'Class' => 'Class',
425 'Hide' => 'Hide',
426 'PluginDependency' => 'Plugin Dependency',
427 'ThemeDependency' => 'Theme Dependency',
428 'DeveloperMode' => 'Developer Mode',
429 'TablelessMode' => 'Tableless Mode',
430 'Capability' => 'Capability',
431 'Plugin' => 'Plugin',
432 ];
433
434 $component_files = apply_filters( 'pods_components_register', $component_files );
435
436 $components = array();
437
438 foreach ( $component_files as $component_file ) {
439 $external = false;
440
441 if ( is_array( $component_file ) && isset( $component_file['File'] ) ) {
442 $component_file = $component_file['File'];
443 $component = $component_file;
444
445 $external = true;
446 } else {
447 $component = $this->components_dir . $component_file;
448 }
449
450 if ( ! is_readable( $component ) ) {
451 continue;
452 }
453
454 $component_data = get_file_data( $component, $default_headers, 'pods_component' );
455
456 if ( ( empty( $component_data['Name'] ) && empty( $component_data['ComponentName'] ) && empty( $component_data['PluginName'] ) ) || 'yes' === $component_data['Hide'] ) {
457 continue;
458 }
459
460 if ( isset( $component_data['Plugin'] ) && pods_is_plugin_active( $component_data['Plugin'] ) ) {
461 continue;
462 }
463
464 if ( empty( $component_data['Name'] ) ) {
465 if ( ! empty( $component_data['ComponentName'] ) ) {
466 $component_data['Name'] = $component_data['ComponentName'];
467 } elseif ( ! empty( $component_data['PluginName'] ) ) {
468 $component_data['Name'] = $component_data['PluginName'];
469 }
470 }
471
472 if ( empty( $component_data['ShortName'] ) ) {
473 $component_data['ShortName'] = $component_data['Name'];
474 }
475
476 if ( empty( $component_data['MenuName'] ) ) {
477 $component_data['MenuName'] = $component_data['Name'];
478 }
479
480 if ( empty( $component_data['Class'] ) ) {
481 $component_data['Class'] = 'Pods_' . pods_js_name( basename( $component, '.php' ), false );
482 }
483
484 if ( empty( $component_data['ID'] ) ) {
485 $component_data['ID'] = $component_data['Name'];
486 }
487
488 $component_data['ID'] = sanitize_title( $component_data['ID'] );
489
490 if ( 'on' === strtolower( $component_data['DeveloperMode'] ) && '1' === $component_data['DeveloperMode'] ) {
491 $component_data['DeveloperMode'] = true;
492 } else {
493 $component_data['DeveloperMode'] = false;
494 }
495
496 if ( 'on' === strtolower( $component_data['TablelessMode'] ) && '1' === $component_data['TablelessMode'] ) {
497 $component_data['TablelessMode'] = true;
498 } else {
499 $component_data['TablelessMode'] = false;
500 }
501
502 $component_data['External'] = $external;
503
504 if ( 'on' === strtolower( $component_data['MustUse'] ) || '1' === $component_data['MustUse'] ) {
505 $component_data['MustUse'] = true;
506 } elseif ( 'off' === strtolower( $component_data['MustUse'] ) || '0' === $component_data['MustUse'] ) {
507 $component_data['MustUse'] = false;
508 } else {
509 $component_data['MustUse'] = $component_data['External'];
510 }
511
512 $component_data['File'] = $component_file;
513
514 $components[ $component_data['ID'] ] = $component_data;
515 }//end foreach
516
517 ksort( $components );
518
519 pods_transient_set( 'pods_components_refresh', 1, HOUR_IN_SECONDS * 12 );
520
521 pods_transient_set( 'pods_components', $components, WEEK_IN_SECONDS );
522 }//end if
523
524 if ( is_admin() ) {
525 if ( 1 === (int) pods_v( 'pods_debug_components', 'get', 0 ) && pods_is_admin( [ 'pods' ] ) ) {
526 pods_debug( __METHOD__ . ':' . __LINE__ );
527 pods_debug( $components );
528 }
529
530 pods_debug_log_data( $components, 'components', __METHOD__, __LINE__ );
531 }
532
533 $this->components = $components;
534
535 return $this->components;
536 }
537
538 /**
539 * Set component options
540 *
541 * @param string $component Component name.
542 * @param array $options Component options.
543 *
544 * @since 2.0.0
545 */
546 public function options( $component, $options ) {
547
548 if ( ! isset( $this->settings['components'][ $component ] ) || ! is_array( $this->settings['components'][ $component ] ) ) {
549 $this->settings['components'][ $component ] = array();
550 }
551
552 foreach ( $options as $option => $data ) {
553 if ( ! isset( $this->settings['components'][ $component ][ $option ] ) && isset( $data['default'] ) ) {
554 $this->settings['components'][ $component ][ $option ] = $data['default'];
555 }
556 }
557 }
558
559 /**
560 * Call component specific admin functions
561 *
562 * @since 2.0.0
563 */
564 public function admin_handler() {
565 $component = str_replace( 'pods-component-', '', pods_v_sanitized( 'page' ) );
566
567 if ( isset( $this->components[ $component ] ) && isset( $this->components[ $component ]['object'] ) && is_object( $this->components[ $component ]['object'] ) ) {
568 // Component init
569 if ( method_exists( $this->components[ $component ]['object'], 'init' ) ) {
570 $this->components[ $component ]['object']->init( $this->settings['components'][ $component ], $component );
571 }
572
573 if ( method_exists( $this->components[ $component ]['object'], 'admin' ) ) {
574 // Component Admin handler
575 $this->components[ $component ]['object']->admin( $this->settings['components'][ $component ], $component );
576 } elseif ( method_exists( $this->components[ $component ]['object'], 'options' ) ) {
577 // Built-in Admin Handler
578 $this->admin( $this->components[ $component ]['object']->options( $this->settings['components'][ $component ] ), $this->settings['components'][ $component ], $component );
579 }
580 }
581 }
582
583 /**
584 * Render components admin.
585 *
586 * @param array $options Component options.
587 * @param array $settings Component setting values.
588 * @param string $component Component name.
589 */
590 public function admin( $options, $settings, $component ) {
591
592 if ( ! isset( $this->components[ $component ] ) ) {
593 wp_die( 'Invalid Component', '', array( 'back_link' => true ) );
594 }
595
596 $component_label = $this->components[ $component ]['Name'];
597
598 include PODS_DIR . 'ui/admin/components-admin.php';
599 }
600
601 /**
602 * Check if a component is active or not
603 *
604 * @param string $component The component name to check if active.
605 *
606 * @return bool
607 *
608 * @since 2.7.0
609 */
610 public function is_component_active( $component ) {
611
612 $active = false;
613
614 if ( isset( $this->components[ $component ] ) && isset( $this->settings['components'][ $component ] ) && 0 !== $this->settings['components'][ $component ] ) {
615 $active = true;
616 }
617
618 return $active;
619
620 }
621
622 /**
623 * Activate a component
624 *
625 * @param string $component The component name to activate.
626 *
627 * @return boolean Whether the component was activated.
628 *
629 * @since 2.7.0
630 */
631 public function activate_component( $component ) {
632
633 $activated = false;
634
635 if ( ! $this->is_component_active( $component ) ) {
636 if ( empty( $this->components ) ) {
637 // Setup components
638 PodsInit::$components->get_components();
639 }
640
641 if ( isset( $this->components[ $component ] ) ) {
642 $this->settings['components'][ $component ] = array();
643
644 $this->update_settings( $this->settings );
645
646 $activated = true;
647 }
648 } else {
649 $activated = true;
650 }//end if
651
652 return $activated;
653
654 }
655
656 /**
657 * Deactivate a component
658 *
659 * @param string $component The component name to deactivate.
660 *
661 * @since 2.7.0
662 */
663 public function deactivate_component( $component ) {
664
665 if ( $this->is_component_active( $component ) ) {
666 if ( isset( $this->components[ $component ] ) ) {
667 $this->settings['components'][ $component ] = 0;
668
669 $this->update_settings( $this->settings );
670 }
671 }
672
673 }
674
675 /**
676 * Toggle a component on or off
677 *
678 * @param string $component The component name to toggle.
679 * @param boolean $toggle_mode Force toggle on or off.
680 *
681 * @return bool
682 *
683 * @since 2.0.0
684 */
685 public function toggle( $component, $toggle_mode = false ) {
686
687 $toggled = null;
688
689 $toggle_mode = (boolean) pods_v( 'toggle', 'get', $toggle_mode );
690
691 if ( $toggle_mode ) {
692 $toggled = $this->activate_component( $component );
693 } else {
694 $this->deactivate_component( $component );
695
696 $toggled = false;
697 }
698
699 return $toggled;
700
701 }
702
703 /**
704 * Add pods specific capabilities.
705 *
706 * @param array $capabilities List of extra capabilities to add.
707 *
708 * @return array
709 */
710 public function admin_capabilities( $capabilities ) {
711
712 foreach ( $this->components as $component => $component_data ) {
713 if ( ! empty( $component_data['Hide'] ) ) {
714 continue;
715 }
716
717 if ( ! pods_developer() ) {
718 if ( true === (boolean) pods_v( 'DeveloperMode', $component_data, false ) ) {
719 continue;
720 }
721
722 if ( true === (boolean) pods_v( 'TablelessMode', $component_data, false ) ) {
723 continue;
724 }
725 }
726
727 if ( empty( $component_data['MenuPage'] ) && ( ! isset( $component_data['object'] ) || ! method_exists( $component_data['object'], 'admin' ) ) ) {
728 continue;
729 }
730
731 $capability = 'pods_component_' . str_replace( '-', '_', sanitize_title( str_replace( ' and ', ' ', strip_tags( $component_data['Name'] ) ) ) );
732
733 if ( 0 < strlen( (string) $component_data['Capability'] ) ) {
734 $capability = $component_data['Capability'];
735 }
736
737 if ( ! in_array( $capability, $capabilities, true ) ) {
738 $capabilities[] = $capability;
739 }
740 }//end foreach
741
742 return $capabilities;
743 }
744
745 /**
746 * Handle admin ajax
747 *
748 * @since 2.0.0
749 */
750 public function admin_ajax() {
751
752 if ( false === headers_sent() ) {
753 pods_session_start();
754
755 header( 'Content-Type: text/html; charset=' . get_bloginfo( 'charset' ) );
756 }
757
758 // Sanitize input @codingStandardsIgnoreLine
759 $params = pods_unslash( (array) $_POST );
760
761 foreach ( $params as $key => $value ) {
762 if ( 'action' === $key ) {
763 continue;
764 }
765
766 unset( $params[ $key ] );
767
768 $params[ str_replace( '_podsfix_', '', $key ) ] = $value;
769 }
770
771 $params = (object) $params;
772
773 $component = $params->component;
774 $method = $params->method;
775
776 if ( ! isset( $component ) || ! isset( $this->components[ $component ] ) || ! isset( $this->settings['components'][ $component ] ) ) {
777 pods_error( __( 'Invalid AJAX request', 'pods' ), $this );
778 }
779
780 if ( ! isset( $params->_wpnonce ) || false === wp_verify_nonce( $params->_wpnonce, 'pods-component-' . $component . '-' . $method ) ) {
781 pods_error( __( 'Unauthorized request', 'pods' ), $this );
782 }
783
784 // Cleaning up $params
785 unset( $params->action, $params->component, $params->method, $params->_wpnonce );
786
787 $params = (object) apply_filters( "pods_component_ajax_{$component}_{$method}", $params, $component, $method );
788
789 $output = false;
790
791 // Component init
792 if ( isset( $this->components[ $component ]['object'] ) && method_exists( $this->components[ $component ]['object'], 'init' ) ) {
793 $this->components[ $component ]['object']->init( $this->settings['components'][ $component ], $component );
794 }
795
796 if ( isset( $this->components[ $component ]['object'] ) && ! method_exists( $this->components[ $component ]['object'], 'ajax_' . $method ) && method_exists( $this, 'admin_ajax_' . $method ) ) {
797 // Handle internal methods
798 $output = call_user_func( array( $this, 'admin_ajax_' . $method ), $component, $params );
799 } elseif ( ! isset( $this->components[ $component ]['object'] ) || ! method_exists( $this->components[ $component ]['object'], 'ajax_' . $method ) ) {
800 // Make sure method exists
801 pods_error( __( 'API method does not exist', 'pods' ), $this );
802 } else {
803 // Dynamically call the component method
804 $output = call_user_func( array( $this->components[ $component ]['object'], 'ajax_' . $method ), $params );
805 }
806
807 if ( ! is_bool( $output ) ) {
808 // @codingStandardsIgnoreLine
809 echo $output;
810 }
811
812 die();
813 // KBAI!
814 }
815
816 /**
817 * Handle admin AJAX settings saving.
818 *
819 * @param string $component Component name.
820 * @param array $params AJAX parameters.
821 *
822 * @return string
823 */
824 public function admin_ajax_settings( $component, $params ) {
825
826 if ( ! isset( $this->components[ $component ] ) ) {
827 wp_die( 'Invalid Component', '', array( 'back_link' => true ) );
828 } elseif ( ! method_exists( $this->components[ $component ]['object'], 'options' ) ) {
829 pods_error( __( 'Component options method does not exist', 'pods' ), $this );
830 }
831
832 $options = $this->components[ $component ]['object']->options( $this->settings['components'][ $component ] );
833
834 if ( empty( $this->settings['components'][ $component ] ) ) {
835 $this->settings['components'][ $component ] = array();
836 }
837
838 foreach ( $options as $field_name => $field_option ) {
839 $field_option = PodsForm::field_setup( $field_option, null, $field_option['type'] );
840
841 if ( ! is_array( $field_option['group'] ) ) {
842 $field_value = pods_v( 'pods_setting_' . $field_name, $params );
843
844 $this->settings['components'][ $component ][ $field_name ] = $field_value;
845 } else {
846 foreach ( $field_option['group'] as $field_group_name => $field_group_option ) {
847 $field_value = pods_v( 'pods_setting_' . $field_group_name, $params );
848
849 $this->settings['components'][ $component ][ $field_group_name ] = $field_value;
850 }
851 }
852 }
853
854 $this->update_settings( $this->settings );
855
856 return '1';
857 }
858
859 /**
860 * Update settings.
861 *
862 * @param array $settings Component settings.
863 */
864 public function update_settings( $settings ) {
865 $settings = wp_json_encode( $settings, JSON_UNESCAPED_UNICODE );
866
867 update_option( 'pods_component_settings', $settings );
868
869 }
870 }
871