Completed
Pull Request — 2.x (#4180)
by Scott Kingsley
04:37
created

PodsComponents::toggle()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 10
nc 2
nop 1
dl 0
loc 17
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Component managing class
4
 *
5
 * @package Pods
6
 */
7
class PodsComponents {
8
9
    /**
10
     * @var PodsComponents
11
     */
12
    static $instance = null;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $instance.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
13
14
    /**
15
     * Root of Components directory
16
     *
17
     * @var string
18
     *
19
     * @private
20
     * @since 2.0
21
     */
22
    private $components_dir = null;
23
24
    /**
25
     * Available components
26
     *
27
     * @var array
28
     *
29
     * @since 2.0
30
     */
31
    public $components = array();
32
33
    /**
34
     * Components settings
35
     *
36
     * @var array
37
     *
38
     * @since 2.0
39
     */
40
    public $settings = array();
41
42
    /**
43
     * Singleton handling for a basic pods_components() request
44
     *
45
     * @return \PodsComponents
46
     *
47
     * @since 2.3.5
48
     */
49
    public static function init () {
50
        if ( !is_object( self::$instance ) )
51
            self::$instance = new PodsComponents();
52
53
        return self::$instance;
54
    }
55
56
    /**
57
     * Setup actions and get options
58
     *
59
     * @return \PodsComponents
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
60
     *
61
     * @since 2.0
62
     */
63
    public function __construct () {
64
        $this->components_dir = realpath( apply_filters( 'pods_components_dir', PODS_DIR . 'components' ) ) . '/';
65
66
        $settings = get_option( 'pods_component_settings', '' );
67
68
        if ( !empty( $settings ) )
69
            $this->settings = (array) json_decode( $settings, true );
70
71
        if ( !isset( $this->settings[ 'components' ] ) )
72
            $this->settings[ 'components' ] = array();
73
74
        // Get components (give it access to theme)
75
        add_action( 'setup_theme', array( $this, 'get_components' ), 11 );
76
77
        // Load in components
78
        add_action( 'setup_theme', array( $this, 'load' ), 12 );
79
80
        // AJAX handling
81
        if ( is_admin() ) {
82
            add_action( 'wp_ajax_pods_admin_components', array( $this, 'admin_ajax' ) );
83
            add_action( 'wp_ajax_nopriv_pods_admin_components', array( $this, 'admin_ajax' ) );
84
85
            // Add the Pods Components capabilities
86
            add_filter( 'members_get_capabilities', array( $this, 'admin_capabilities' ) );
87
        }
88
    }
89
90
    /**
91
     * Add menu item
92
     *
93
     * @param string $parent The parent slug.
94
     *
95
     * @since 2.0
96
     *
97
     * @uses add_submenu_page
98
     */
99
    public function menu ( $parent ) {
100
        global $submenu;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
101
102
        $custom_component_menus = array();
103
104
		$pods_component_menu_items = array();
105
106
        foreach ( $this->components as $component => $component_data ) {
107
            $component_data[ 'MustUse' ] = apply_filters( 'pods_component_require_' . $component_data[ 'ID' ], $component_data[ 'MustUse' ], $component_data );
108
109 View Code Duplication
            if ( empty( $component_data[ 'MustUse' ] ) && ( !isset( $this->settings[ 'components' ][ $component ] ) || 0 == $this->settings[ 'components' ][ $component ] ) )
110
                continue;
111
112
            if ( !empty( $component_data[ 'Hide' ] ) )
113
                continue;
114
115
            if ( !empty( $component_data[ 'DeveloperMode' ] ) && !pods_developer() )
116
                continue;
117
118
            if ( empty( $component_data[ 'TablelessMode' ] ) && pods_tableless() )
119
                continue;
120
121
            if ( empty( $component_data[ 'MenuPage' ] ) ) {
122
                if ( !isset( $component_data[ 'object' ] ) )
123
                    continue;
124
                elseif ( !method_exists( $component_data[ 'object' ], 'admin' ) && !method_exists( $component_data[ 'object' ], 'options' ) )
125
                    continue;
126
            }
127
128 View Code Duplication
            if ( false === $component_data[ 'External' ] )
129
                $component_data[ 'File' ] = realpath( $this->components_dir . $component_data[ 'File' ] );
130
131 View Code Duplication
            if ( !file_exists( $component_data[ 'File' ] ) ) {
132
                pods_message( 'Pods Component not found: ' . $component_data[ 'File' ] );
133
134
                pods_transient_clear( 'pods_components' );
135
136
                continue;
137
            }
138
139
            $capability = 'pods_component_' . str_replace( '-', '_', sanitize_title( $component ) );
140
141
            if ( 0 < strlen( $component_data[ 'Capability' ] ) )
142
                $capability = $component_data[ 'Capability' ];
143
144
            if ( !pods_is_admin( array( 'pods', 'pods_components', $capability ) ) )
145
                continue;
146
147
            $menu_page = 'pods-component-' . $component;
148
149
            if ( !empty( $component_data[ 'MenuPage' ] ) )
150
                $custom_component_menus[ $menu_page ] = $component_data;
151
152
			$pods_component_menu_items[ $component_data[ 'MenuName' ] ] = array(
153
				'menu_page' => $menu_page,
154
				'page_title' => $component_data[ 'Name' ],
155
				'capability' => 'read',
156
				'callback' => array( $this, 'admin_handler' )
157
			);
158
159
            if ( isset( $component_data[ 'object' ] ) && method_exists( $component_data[ 'object' ], 'admin_assets' ) ) {
160
				$pods_component_menu_items[ $component_data[ 'MenuName' ] ][ 'assets' ] = array( $component_data[ 'object' ], 'admin_assets' );
161
			}
162
        }
163
164
		/**
165
		 * Add or change the items in the Pods Components Submenu.
166
		 *
167
		 * Can also be used to change which menu components is a submenu of or change title of menu.
168
		 *
169
		 * @params array $pods_component_menu_items {
170
		 *          An array of arguments for add_submenu_page
171
		 *
172
		 *		  	@param string $parent_slug The slug name for the parent menu (or the file name of a standard WordPress admin page)
173
		 *		  	@param string $page_title The text to be displayed in the title tags of the page when the menu is selected
174
		 *		  	@param $menu_title The text to be used for the menu
175
		 *		  	@param $capability The capability required for this menu to be displayed to the user.
176
		 *		  	@param $menu_slug The slug name to refer to this menu by (should be unique for this menu)
177
		 *		  	@param $function The function to be called to output the content for this page.
178
		 * }
179
		 *
180
		 * @returns array Array of submenu pages to be passed to add_submenu_page()
181
		 *
182
		 * @since 2.4.1
183
		 */
184
		$pods_component_menu_items = apply_filters( 'pods_admin_components_menu', $pods_component_menu_items );
185
186
		ksort( $pods_component_menu_items );
187
188
		foreach ( $pods_component_menu_items as $menu_title => $menu_data ) {
189
			if ( !is_callable( $menu_data[ 'callback' ] ) ) {
190
				continue;
191
			}
192
193
            $page = add_submenu_page(
194
                $parent,
195
                strip_tags( $menu_data[ 'page_title' ] ),
196
                '- ' . strip_tags( $menu_title ),
197
				pods_v( 'capability', $menu_data, 'read', true ),
198
                $menu_data[ 'menu_page' ],
199
                $menu_data[ 'callback' ]
200
            );
201
202
			if ( isset( $menu_data[ 'assets' ] ) && is_callable( $menu_data[ 'assets' ] ) ) {
203
                add_action( 'admin_print_styles-' . $page, $menu_data[ 'assets' ] );
204
			}
205
		}
206
207
        if ( !empty( $custom_component_menus ) ) {
208
            foreach ( $custom_component_menus as $menu_page => $component_data ) {
209
                if ( isset( $submenu[ $parent ] ) ) {
210
                    foreach ( $submenu[ $parent ] as $sub => &$menu ) {
211
                        if ( $menu[ 2 ] == $menu_page ) {
212
                            $menu_page = $component_data[ 'MenuPage' ];
213
214
                            /*if ( !empty( $component_data[ 'MenuAddPage' ] ) ) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
215
                                if ( false !== strpos( $_SERVER[ 'REQUEST_URI' ], $component_data[ 'MenuAddPage' ] ) )
216
                                    $menu_page = $component_data[ 'MenuAddPage' ];
217
                            }*/
218
219
                            $menu[ 2 ] = $menu_page;
220
221
                            $page = current( explode( '?', $menu[ 2 ] ) );
222
223
                            if ( isset( $component_data[ 'object' ] ) && method_exists( $component_data[ 'object' ], 'admin_assets' ) )
224
                                add_action( 'admin_print_styles-' . $page, array( $component_data[ 'object' ], 'admin_assets' ) );
225
226
                            break;
227
                        }
228
                    }
229
                }
230
            }
231
        }
232
    }
233
234
    /**
235
     * Load activated components and init component
236
     *
237
     * @since 2.0
238
     */
239
    public function load () {
240
        do_action( 'pods_components_load' );
241
242
        foreach ( (array) $this->components as $component => $component_data ) {
243
            $component_data[ 'MustUse' ] = apply_filters( 'pods_component_require_' . $component_data[ 'ID' ], $component_data[ 'MustUse' ], $component_data );
244
245 View Code Duplication
            if ( false === $component_data[ 'MustUse' ] && ( !isset( $this->settings[ 'components' ][ $component ] ) || 0 == $this->settings[ 'components' ][ $component ] ) )
246
                continue;
247
248
            if ( !empty( $component_data[ 'PluginDependency' ] ) ) {
249
                $dependency = explode( '|', $component_data[ 'PluginDependency' ] );
250
251
                if ( !pods_is_plugin_active( $dependency[ 1 ] ) )
252
                    continue;
253
            }
254
255
            if ( !empty( $component_data[ 'ThemeDependency' ] ) ) {
256
                $dependency = explode( '|', $component_data[ 'ThemeDependency' ] );
257
258
                if ( strtolower( $dependency[ 1 ] ) != strtolower( get_template() ) && strtolower( $dependency[ 1 ] ) != strtolower( get_stylesheet() ) )
259
                    continue;
260
            }
261
262 View Code Duplication
            if ( false === $component_data[ 'External' ] )
263
                $component_data[ 'File' ] = realpath( $this->components_dir . $component_data[ 'File' ] );
264
265
            if ( empty( $component_data[ 'File' ] ) ) {
266
                pods_transient_clear( 'pods_components' );
267
268
                continue;
269
            }
270
271 View Code Duplication
            if ( !file_exists( $component_data[ 'File' ] ) ) {
272
                pods_message( 'Pods Component not found: ' . $component_data[ 'File' ] );
273
274
                pods_transient_clear( 'pods_components' );
275
276
                continue;
277
            }
278
279
            include_once $component_data[ 'File' ];
280
281
            if ( ( !empty( $component_data[ 'Class' ] ) && class_exists( $component_data[ 'Class' ] ) ) || isset( $component_data[ 'object' ] ) ) {
282
                if ( !isset( $this->components[ $component ][ 'object' ] ) )
283
                    $this->components[ $component ][ 'object' ] = new $component_data[ 'Class' ];
284
285
                if ( method_exists( $this->components[ $component ][ 'object' ], 'options' ) ) {
286
                    if ( isset( $this->settings[ 'components' ][ $component ] ) )
287
                        $this->components[ $component ][ 'options' ] = $this->components[ $component ][ 'object' ]->options( $this->settings[ 'components' ][ $component ] );
288
                    else
289
                        $this->components[ $component ][ 'options' ] = $this->components[ $component ][ 'object' ]->options( array() );
290
291
                    $this->options( $component, $this->components[ $component ][ 'options' ] );
292
                }
293
                else
294
                    $this->options( $component, array() );
295
296 View Code Duplication
                if ( method_exists( $this->components[ $component ][ 'object' ], 'handler' ) )
297
                    $this->components[ $component ][ 'object' ]->handler( $this->settings[ 'components' ][ $component ] );
298
            }
299
        }
300
    }
301
302
    /**
303
     * Get list of components available
304
     *
305
     * @since 2.0
306
     */
307
    public function get_components () {
308
        $components = pods_transient_get( 'pods_components' );
309
310 View Code Duplication
        if ( 1 == pods_var( 'pods_debug_components', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) )
311
            $components = array();
312
313
        if ( PodsInit::$version != PODS_VERSION || !is_array( $components ) || empty( $components ) || ( is_admin() && isset( $_GET[ 'page' ] ) && 'pods-components' == $_GET[ 'page' ] && 1 !== pods_transient_get( 'pods_components_refresh' ) ) ) {
0 ignored issues
show
Bug introduced by
The property version cannot be accessed from this context as it is declared private in class PodsInit.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
314
            do_action( 'pods_components_get' );
315
316
            $component_dir = @opendir( untrailingslashit( $this->components_dir ) );
317
            $component_files = array();
318
319
            if ( false !== $component_dir ) {
320
                while ( false !== ( $file = readdir( $component_dir ) ) ) {
321
                    if ( '.' == substr( $file, 0, 1 ) )
322
                        continue;
323
                    elseif ( is_dir( $this->components_dir . $file ) ) {
324
                        $component_subdir = @opendir( $this->components_dir . $file );
325
326
                        if ( $component_subdir ) {
327
                            while ( false !== ( $subfile = readdir( $component_subdir ) ) ) {
328
                                if ( '.' == substr( $subfile, 0, 1 ) )
329
                                    continue;
330
                                elseif ( '.php' == substr( $subfile, -4 ) )
331
                                    $component_files[] = str_replace( '\\', '/', $file . '/' . $subfile );
332
                            }
333
334
                            closedir( $component_subdir );
335
                        }
336
                    }
337
                    elseif ( '.php' == substr( $file, -4 ) )
338
                        $component_files[] = $file;
339
                }
340
341
                closedir( $component_dir );
342
            }
343
344
            $default_headers = array(
345
                'ID' => 'ID',
346
                'Name' => 'Name',
347
                'ShortName' => 'Short Name',
348
                'PluginName' => 'Plugin Name',
349
                'ComponentName' => 'Component Name',
350
                'URI' => 'URI',
351
                'MenuName' => 'Menu Name',
352
                'MenuPage' => 'Menu Page',
353
                'MenuAddPage' => 'Menu Add Page',
354
                'MustUse' => 'Must Use',
355
                'Description' => 'Description',
356
                'Version' => 'Version',
357
                'Category' => 'Category',
358
                'Author' => 'Author',
359
                'AuthorURI' => 'Author URI',
360
                'Class' => 'Class',
361
                'Hide' => 'Hide',
362
                'PluginDependency' => 'Plugin Dependency',
363
                'ThemeDependency' => 'Theme Dependency',
364
                'DeveloperMode' => 'Developer Mode',
365
                'TablelessMode' => 'Tableless Mode',
366
                'Capability' => 'Capability',
367
                'Plugin' => 'Plugin'
368
            );
369
370
            $component_files = apply_filters( 'pods_components_register', $component_files );
371
372
            $components = array();
373
374
            foreach ( $component_files as $component_file ) {
375
                $external = false;
376
377
                if ( is_array( $component_file ) && isset( $component_file[ 'File' ] ) ) {
378
                    $component = $component_file = $component_file[ 'File' ];
379
380
                    $external = true;
381
                }
382
                else
383
                    $component = $this->components_dir . $component_file;
384
385
                if ( !is_readable( $component ) )
386
                    continue;
387
388
                $component_data = get_file_data( $component, $default_headers, 'pods_component' );
389
390
                if ( ( empty( $component_data[ 'Name' ] ) && empty( $component_data[ 'ComponentName' ] ) && empty( $component_data[ 'PluginName' ] ) ) || 'yes' == $component_data[ 'Hide' ] )
391
                    continue;
392
393
                if ( isset( $component_data[ 'Plugin' ] ) && pods_is_plugin_active( $component_data[ 'Plugin' ] ) )
394
                    continue;
395
396
                if ( empty( $component_data[ 'Name' ] ) ) {
397
                    if ( !empty( $component_data[ 'ComponentName' ] ) )
398
                        $component_data[ 'Name' ] = $component_data[ 'ComponentName' ];
399
                    elseif ( !empty( $component_data[ 'PluginName' ] ) )
400
                        $component_data[ 'Name' ] = $component_data[ 'PluginName' ];
401
                }
402
403
                if ( empty( $component_data[ 'ShortName' ] ) )
404
                    $component_data[ 'ShortName' ] = $component_data[ 'Name' ];
405
406
                if ( empty( $component_data[ 'MenuName' ] ) )
407
                    $component_data[ 'MenuName' ] = $component_data[ 'Name' ];
408
409
                if ( empty( $component_data[ 'Class' ] ) )
410
                    $component_data[ 'Class' ] = 'Pods_' . pods_js_name( basename( $component, '.php' ), false );
411
412
                if ( empty( $component_data[ 'ID' ] ) )
413
                    $component_data[ 'ID' ] = $component_data[ 'Name' ];
414
415
                $component_data[ 'ID' ] = sanitize_title( $component_data[ 'ID' ] );
416
417 View Code Duplication
                if ( 'on' == strtolower( $component_data[ 'DeveloperMode' ] ) || 1 == $component_data[ 'DeveloperMode' ] )
418
                    $component_data[ 'DeveloperMode' ] = true;
419
                else
420
                    $component_data[ 'DeveloperMode' ] = false;
421
422 View Code Duplication
                if ( 'on' == strtolower( $component_data[ 'TablelessMode' ] ) || 1 == $component_data[ 'TablelessMode' ] )
423
                    $component_data[ 'TablelessMode' ] = true;
424
                else
425
                    $component_data[ 'TablelessMode' ] = false;
426
427
                $component_data[ 'External' ] = (boolean) $external;
428
429
                if ( 'on' == strtolower($component_data[ 'MustUse' ] ) || '1' == $component_data[ 'MustUse' ] )
430
                    $component_data[ 'MustUse' ] = true;
431
                elseif ( 'off' == strtolower($component_data[ 'MustUse' ] ) || '0' == $component_data[ 'MustUse' ] )
432
                    $component_data[ 'MustUse' ] = false;
433
                else
434
                    $component_data[ 'MustUse' ] = $component_data[ 'External' ];
435
436
                $component_data[ 'File' ] = $component_file;
437
438
                $components[ $component_data[ 'ID' ] ] = $component_data;
439
            }
440
441
            ksort( $components );
442
443
            pods_transient_set( 'pods_components_refresh', 1, ( 60 * 60 * 12 ) );
444
445
            pods_transient_set( 'pods_components', $components );
446
        }
447
448 View Code Duplication
        if ( 1 == pods_var( 'pods_debug_components', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) )
449
            pods_debug( $components );
450
451
        $this->components = $components;
452
453
        return $this->components;
454
    }
455
456
    /**
457
     * Set component options
458
     *
459
     * @param $component
460
     * @param $options
461
     *
462
     * @since 2.0
463
     */
464
    public function options ( $component, $options ) {
465
        if ( !isset( $this->settings[ 'components' ][ $component ] ) || !is_array( $this->settings[ 'components' ][ $component ] ) )
466
            $this->settings[ 'components' ][ $component ] = array();
467
468
        foreach ( $options as $option => $data ) {
469
            if ( !isset( $this->settings[ 'components' ][ $component ][ $option ] ) && isset( $data[ 'default' ] ) )
470
                $this->settings[ 'components' ][ $component ][ $option ] = $data[ 'default' ];
471
        }
472
    }
473
474
    /**
475
     * Call component specific admin functions
476
     *
477
     * @since 2.0
478
     */
479
    public function admin_handler () {
480
        $component = str_replace( 'pods-component-', '', $_GET[ 'page' ] );
481
482
        if ( isset( $this->components[ $component ] ) && isset( $this->components[ $component ][ 'object' ] ) && is_object( $this->components[ $component ][ 'object' ] ) ) {
483
            // Component init
484 View Code Duplication
            if ( method_exists( $this->components[ $component ][ 'object' ], 'init' ) )
485
                $this->components[ $component ][ 'object' ]->init( $this->settings[ 'components' ][ $component ], $component );
486
487
            // Component Admin handler
488
            if ( method_exists( $this->components[ $component ][ 'object' ], 'admin' ) )
489
                $this->components[ $component ][ 'object' ]->admin( $this->settings[ 'components' ][ $component ], $component );
490
            // Built-in Admin Handler
491 View Code Duplication
            elseif ( method_exists( $this->components[ $component ][ 'object' ], 'options' ) )
492
                $this->admin( $this->components[ $component ][ 'object' ]->options( $this->settings[ 'components' ][ $component ] ), $this->settings[ 'components' ][ $component ], $component );
493
        }
494
    }
495
496
    public function admin ( $options, $settings, $component ) {
497
        if ( !isset( $this->components[ $component ] ) )
498
            wp_die( 'Invalid Component', '', array( 'back_link' => true ) );
499
500
        $component_label = $this->components[ $component ][ 'Name' ];
501
502
        include PODS_DIR . 'ui/admin/components-admin.php';
503
    }
504
505
    /**
506
     * Check if a component is active or not
507
     *
508
     * @param string $component The component name to check if active
509
     *
510
     * @return bool
511
     *
512
     * @since 2.7
513
     */
514
    public function is_component_active( $component ) {
515
516
        $active = false;
517
518
        if ( isset( $this->components[ $component ] ) && isset( $this->settings[ 'components' ][ $component ] ) && 0 !== $this->settings[ 'components' ][ $component ] ) {
519
            $active = true;
520
        }
521
522
        return $active;
523
524
    }
525
526
	/**
527
	 * Activate a component
528
	 *
529
	 * @param string $component The component name to activate
530
	 *
531
	 * @return boolean Whether the component was activated.
532
	 *
533
	 * @since 2.7
534
	 */
535
	public function activate_component( $component ) {
536
537
		$activated = false;
538
539
		if ( ! $this->is_component_active( $component ) ) {
540
			if ( empty( $this->components ) ) {
541
				// Setup components
542
				PodsInit::$components->get_components();
0 ignored issues
show
Bug introduced by
The property components cannot be accessed from this context as it is declared private in class PodsInit.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
543
			}
544
545 View Code Duplication
			if ( isset( $this->components[ $component ] ) ) {
546
				$this->settings['components'][ $component ] = array();
547
548
				$settings = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $this->settings, JSON_UNESCAPED_UNICODE ) : json_encode( $this->settings );
0 ignored issues
show
Unused Code introduced by
The call to json_encode() has too many arguments starting with JSON_UNESCAPED_UNICODE.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
549
550
				update_option( 'pods_component_settings', $settings );
551
552
				$activated = true;
553
			}
554
		} else {
555
			$activated = true;
556
		}
557
558
		return $activated;
559
560
	}
561
562
    /**
563
     * Deactivate a component
564
     *
565
     * @param string $component The component name to deactivate
566
     *
567
     * @since 2.7
568
     */
569
    public function deactivate_component( $component ) {
570
571 View Code Duplication
        if ( $this->is_component_active( $component ) ) {
572
            if ( isset( $this->components[ $component ] ) ) {
573
                $this->settings[ 'components' ][ $component ] = 0;
574
575
                $settings = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $this->settings, JSON_UNESCAPED_UNICODE ) : json_encode( $this->settings );
0 ignored issues
show
Unused Code introduced by
The call to json_encode() has too many arguments starting with JSON_UNESCAPED_UNICODE.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
576
577
                update_option( 'pods_component_settings', $settings );
578
            }
579
        }
580
581
    }
582
583
    /**
584
     * Toggle a component on or off
585
     *
586
     * @param string $component The component name to toggle
587
     *
588
     * @return bool
589
     *
590
     * @since 2.0
591
     */
592
    public function toggle ( $component ) {
593
594
	    $toggle = null;
595
596
	    $toggle_mode = (int) pods_v( 'toggle', 'get' );
597
598
	    if ( 1 == $toggle_mode ) {
599
		    $this->activate_component( $component );
600
		    $toggle = true;
601
	    } else {
602
		    $this->deactivate_component( $component );
603
		    $toggle = false;
604
	    }
605
606
	    return $toggle;
607
608
    }
609
610
    /**
611
     * Add pods specific capabilities.
612
     *
613
     * @param $capabilities List of extra capabilities to add
614
     *
615
     * @return array
616
     */
617
    public function admin_capabilities ( $capabilities ) {
618
        foreach ( $this->components as $component => $component_data ) {
619
            if ( !empty( $component_data[ 'Hide' ] ) )
620
                continue;
621
622
            if ( true === (boolean) pods_var( 'DeveloperMode', $component_data, false ) && !pods_developer() )
623
                continue;
624
625
            if ( true === (boolean) pods_var( 'TablelessMode', $component_data, false ) && !pods_developer() )
626
                continue;
627
628
            if ( empty( $component_data[ 'MenuPage' ] ) && ( !isset( $component_data[ 'object' ] ) || !method_exists( $component_data[ 'object' ], 'admin' ) ) )
629
                continue;
630
631
            $capability = 'pods_component_' . str_replace( '-', '_', sanitize_title( str_replace( ' and ', ' ', strip_tags( $component_data[ 'Name' ] ) ) ) );
632
633
            if ( 0 < strlen ( $component_data[ 'Capability' ] ) )
634
                $capability = $component_data[ 'Capability' ];
635
636
            if ( !in_array( $capability, $capabilities ) )
637
                $capabilities[] = $capability;
638
        }
639
640
        return $capabilities;
641
    }
642
643
    /**
644
     * Handle admin ajax
645
     *
646
     * @since 2.0
647
     */
648
    public function admin_ajax () {
649
        if ( false === headers_sent() ) {
650
			pods_session_start();
651
652
            header( 'Content-Type: text/html; charset=' . get_bloginfo( 'charset' ) );
653
        }
654
655
        // Sanitize input
656
        $params = pods_unslash( (array) $_POST );
657
658 View Code Duplication
        foreach ( $params as $key => $value ) {
659
            if ( 'action' == $key )
660
                continue;
661
662
            unset( $params[ $key ] );
663
664
            $params[ str_replace( '_podsfix_', '', $key ) ] = $value;
665
        }
666
667
        $params = (object) $params;
668
669
        $component = $params->component;
670
        $method = $params->method;
671
672
        if ( !isset( $component ) || !isset( $this->components[ $component ] ) || !isset( $this->settings[ 'components' ][ $component ] ) )
673
            pods_error( 'Invalid AJAX request', $this );
674
675
        if ( !isset( $params->_wpnonce ) || false === wp_verify_nonce( $params->_wpnonce, 'pods-component-' . $component . '-' . $method ) )
676
            pods_error( 'Unauthorized request', $this );
677
678
        // Cleaning up $params
679
        unset( $params->action );
680
        unset( $params->component );
681
        unset( $params->method );
682
        unset( $params->_wpnonce );
683
684
        $params = (object) apply_filters( 'pods_component_ajax_' . $component . '_' . $method, $params, $component, $method );
685
686
        $output = false;
687
688
        // Component init
689 View Code Duplication
        if ( isset( $this->components[ $component ][ 'object' ] ) && method_exists( $this->components[ $component ][ 'object' ], 'init' ) )
690
            $this->components[ $component ][ 'object' ]->init( $this->settings[ 'components' ][ $component ], $component );
691
692
        // Handle internal methods
693
        if ( isset( $this->components[ $component ][ 'object' ] ) && !method_exists( $this->components[ $component ][ 'object' ], 'ajax_' . $method ) && method_exists( $this, 'admin_ajax_' . $method ) )
694
            $output = call_user_func( array( $this, 'admin_ajax_' . $method ), $component, $params );
695
        // Make sure method exists
696
        elseif ( !isset( $this->components[ $component ][ 'object' ] ) || !method_exists( $this->components[ $component ][ 'object' ], 'ajax_' . $method ) )
697
            pods_error( 'API method does not exist', $this );
698
        // Dynamically call the component method
699
        else
700
            $output = call_user_func( array( $this->components[ $component ][ 'object' ], 'ajax_' . $method ), $params );
701
702
        if ( !is_bool( $output ) )
703
            echo $output;
704
705
        die(); // KBAI!
706
    }
707
708
    public function admin_ajax_settings ( $component, $params ) {
709
        if ( !isset( $this->components[ $component ] ) )
710
            wp_die( 'Invalid Component', '', array( 'back_link' => true ) );
711
        elseif ( !method_exists( $this->components[ $component ][ 'object' ], 'options' ) )
712
            pods_error( 'Component options method does not exist', $this );
713
714
        $options = $this->components[ $component ][ 'object' ]->options( $this->settings[ 'components' ][ $component ] );
715
716
        if ( empty( $this->settings[ 'components' ][ $component ] ) )
717
            $this->settings[ 'components' ][ $component ] = array();
718
719
        foreach ( $options as $field_name => $field_option ) {
720
            $field_option = PodsForm::field_setup( $field_option, null, $field_option[ 'type' ] );
721
722
            if ( !is_array( $field_option[ 'group' ] ) ) {
723
                $field_value = pods_var_raw( 'pods_setting_' . $field_name, $params );
724
725
                $this->settings[ 'components' ][ $component ][ $field_name ] = $field_value;
726
            }
727
            else {
728
                foreach ( $field_option[ 'group' ] as $field_group_name => $field_group_option ) {
729
                    $field_value = pods_var_raw( 'pods_setting_' . $field_group_name, $params );
730
731
                    $this->settings[ 'components' ][ $component ][ $field_group_name ] = $field_value;
732
                }
733
            }
734
        }
735
736
        $settings = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $this->settings, JSON_UNESCAPED_UNICODE ) : json_encode( $this->settings );
0 ignored issues
show
Unused Code introduced by
The call to json_encode() has too many arguments starting with JSON_UNESCAPED_UNICODE.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
737
738
        update_option( 'pods_component_settings', $settings );
739
740
        return '1';
741
    }
742
}
743