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