cli
16 hours ago
fields
16 hours ago
widgets
16 hours ago
Pods.php
16 hours ago
PodsAPI.php
16 hours ago
PodsAdmin.php
16 hours ago
PodsArray.php
16 hours ago
PodsComponent.php
16 hours ago
PodsComponents.php
16 hours ago
PodsData.php
16 hours ago
PodsField.php
16 hours ago
PodsForm.php
16 hours ago
PodsI18n.php
16 hours ago
PodsInit.php
16 hours ago
PodsMeta.php
16 hours ago
PodsMigrate.php
16 hours ago
PodsRESTFields.php
16 hours ago
PodsRESTHandlers.php
16 hours ago
PodsTermSplitting.php
16 hours ago
PodsUI.php
16 hours ago
PodsView.php
16 hours ago
PodsComponents.php
869 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 ( 1 === (int) pods_v( 'pods_debug_components', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) ) { |
| 524 | pods_debug( $components ); |
| 525 | } |
| 526 | |
| 527 | $this->components = $components; |
| 528 | |
| 529 | return $this->components; |
| 530 | } |
| 531 | |
| 532 | /** |
| 533 | * Set component options |
| 534 | * |
| 535 | * @param string $component Component name. |
| 536 | * @param array $options Component options. |
| 537 | * |
| 538 | * @since 2.0.0 |
| 539 | */ |
| 540 | public function options( $component, $options ) { |
| 541 | |
| 542 | if ( ! isset( $this->settings['components'][ $component ] ) || ! is_array( $this->settings['components'][ $component ] ) ) { |
| 543 | $this->settings['components'][ $component ] = array(); |
| 544 | } |
| 545 | |
| 546 | foreach ( $options as $option => $data ) { |
| 547 | if ( ! isset( $this->settings['components'][ $component ][ $option ] ) && isset( $data['default'] ) ) { |
| 548 | $this->settings['components'][ $component ][ $option ] = $data['default']; |
| 549 | } |
| 550 | } |
| 551 | } |
| 552 | |
| 553 | /** |
| 554 | * Call component specific admin functions |
| 555 | * |
| 556 | * @since 2.0.0 |
| 557 | */ |
| 558 | public function admin_handler() { |
| 559 | $component = str_replace( 'pods-component-', '', pods_v_sanitized( 'page' ) ); |
| 560 | |
| 561 | if ( isset( $this->components[ $component ] ) && isset( $this->components[ $component ]['object'] ) && is_object( $this->components[ $component ]['object'] ) ) { |
| 562 | // Component init |
| 563 | if ( method_exists( $this->components[ $component ]['object'], 'init' ) ) { |
| 564 | $this->components[ $component ]['object']->init( $this->settings['components'][ $component ], $component ); |
| 565 | } |
| 566 | |
| 567 | if ( method_exists( $this->components[ $component ]['object'], 'admin' ) ) { |
| 568 | // Component Admin handler |
| 569 | $this->components[ $component ]['object']->admin( $this->settings['components'][ $component ], $component ); |
| 570 | } elseif ( method_exists( $this->components[ $component ]['object'], 'options' ) ) { |
| 571 | // Built-in Admin Handler |
| 572 | $this->admin( $this->components[ $component ]['object']->options( $this->settings['components'][ $component ] ), $this->settings['components'][ $component ], $component ); |
| 573 | } |
| 574 | } |
| 575 | } |
| 576 | |
| 577 | /** |
| 578 | * Render components admin. |
| 579 | * |
| 580 | * @param array $options Component options. |
| 581 | * @param array $settings Component setting values. |
| 582 | * @param string $component Component name. |
| 583 | */ |
| 584 | public function admin( $options, $settings, $component ) { |
| 585 | |
| 586 | if ( ! isset( $this->components[ $component ] ) ) { |
| 587 | wp_die( 'Invalid Component', '', array( 'back_link' => true ) ); |
| 588 | } |
| 589 | |
| 590 | $component_label = $this->components[ $component ]['Name']; |
| 591 | |
| 592 | include PODS_DIR . 'ui/admin/components-admin.php'; |
| 593 | } |
| 594 | |
| 595 | /** |
| 596 | * Check if a component is active or not |
| 597 | * |
| 598 | * @param string $component The component name to check if active. |
| 599 | * |
| 600 | * @return bool |
| 601 | * |
| 602 | * @since 2.7.0 |
| 603 | */ |
| 604 | public function is_component_active( $component ) { |
| 605 | |
| 606 | $active = false; |
| 607 | |
| 608 | if ( isset( $this->components[ $component ] ) && isset( $this->settings['components'][ $component ] ) && 0 !== $this->settings['components'][ $component ] ) { |
| 609 | $active = true; |
| 610 | } |
| 611 | |
| 612 | return $active; |
| 613 | |
| 614 | } |
| 615 | |
| 616 | /** |
| 617 | * Activate a component |
| 618 | * |
| 619 | * @param string $component The component name to activate. |
| 620 | * |
| 621 | * @return boolean Whether the component was activated. |
| 622 | * |
| 623 | * @since 2.7.0 |
| 624 | */ |
| 625 | public function activate_component( $component ) { |
| 626 | |
| 627 | $activated = false; |
| 628 | |
| 629 | if ( ! $this->is_component_active( $component ) ) { |
| 630 | if ( empty( $this->components ) ) { |
| 631 | // Setup components |
| 632 | PodsInit::$components->get_components(); |
| 633 | } |
| 634 | |
| 635 | if ( isset( $this->components[ $component ] ) ) { |
| 636 | $this->settings['components'][ $component ] = array(); |
| 637 | |
| 638 | $this->update_settings( $this->settings ); |
| 639 | |
| 640 | $activated = true; |
| 641 | } |
| 642 | } else { |
| 643 | $activated = true; |
| 644 | }//end if |
| 645 | |
| 646 | return $activated; |
| 647 | |
| 648 | } |
| 649 | |
| 650 | /** |
| 651 | * Deactivate a component |
| 652 | * |
| 653 | * @param string $component The component name to deactivate. |
| 654 | * |
| 655 | * @since 2.7.0 |
| 656 | */ |
| 657 | public function deactivate_component( $component ) { |
| 658 | |
| 659 | if ( $this->is_component_active( $component ) ) { |
| 660 | if ( isset( $this->components[ $component ] ) ) { |
| 661 | $this->settings['components'][ $component ] = 0; |
| 662 | |
| 663 | $this->update_settings( $this->settings ); |
| 664 | } |
| 665 | } |
| 666 | |
| 667 | } |
| 668 | |
| 669 | /** |
| 670 | * Toggle a component on or off |
| 671 | * |
| 672 | * @param string $component The component name to toggle. |
| 673 | * @param boolean $toggle_mode Force toggle on or off. |
| 674 | * |
| 675 | * @return bool |
| 676 | * |
| 677 | * @since 2.0.0 |
| 678 | */ |
| 679 | public function toggle( $component, $toggle_mode = false ) { |
| 680 | |
| 681 | $toggled = null; |
| 682 | |
| 683 | $toggle_mode = (boolean) pods_v( 'toggle', 'get', $toggle_mode ); |
| 684 | |
| 685 | if ( $toggle_mode ) { |
| 686 | $toggled = $this->activate_component( $component ); |
| 687 | } else { |
| 688 | $this->deactivate_component( $component ); |
| 689 | |
| 690 | $toggled = false; |
| 691 | } |
| 692 | |
| 693 | return $toggled; |
| 694 | |
| 695 | } |
| 696 | |
| 697 | /** |
| 698 | * Add pods specific capabilities. |
| 699 | * |
| 700 | * @param array $capabilities List of extra capabilities to add. |
| 701 | * |
| 702 | * @return array |
| 703 | */ |
| 704 | public function admin_capabilities( $capabilities ) { |
| 705 | |
| 706 | foreach ( $this->components as $component => $component_data ) { |
| 707 | if ( ! empty( $component_data['Hide'] ) ) { |
| 708 | continue; |
| 709 | } |
| 710 | |
| 711 | if ( ! pods_developer() ) { |
| 712 | if ( true === (boolean) pods_v( 'DeveloperMode', $component_data, false ) ) { |
| 713 | continue; |
| 714 | } |
| 715 | |
| 716 | if ( true === (boolean) pods_v( 'TablelessMode', $component_data, false ) ) { |
| 717 | continue; |
| 718 | } |
| 719 | } |
| 720 | |
| 721 | if ( empty( $component_data['MenuPage'] ) && ( ! isset( $component_data['object'] ) || ! method_exists( $component_data['object'], 'admin' ) ) ) { |
| 722 | continue; |
| 723 | } |
| 724 | |
| 725 | $capability = 'pods_component_' . str_replace( '-', '_', sanitize_title( str_replace( ' and ', ' ', strip_tags( $component_data['Name'] ) ) ) ); |
| 726 | |
| 727 | if ( 0 < strlen( (string) $component_data['Capability'] ) ) { |
| 728 | $capability = $component_data['Capability']; |
| 729 | } |
| 730 | |
| 731 | if ( ! in_array( $capability, $capabilities, true ) ) { |
| 732 | $capabilities[] = $capability; |
| 733 | } |
| 734 | }//end foreach |
| 735 | |
| 736 | return $capabilities; |
| 737 | } |
| 738 | |
| 739 | /** |
| 740 | * Handle admin ajax |
| 741 | * |
| 742 | * @since 2.0.0 |
| 743 | */ |
| 744 | public function admin_ajax() { |
| 745 | |
| 746 | if ( false === headers_sent() ) { |
| 747 | pods_session_start(); |
| 748 | |
| 749 | header( 'Content-Type: text/html; charset=' . get_bloginfo( 'charset' ) ); |
| 750 | } |
| 751 | |
| 752 | // Sanitize input @codingStandardsIgnoreLine |
| 753 | $params = pods_unslash( (array) $_POST ); |
| 754 | |
| 755 | foreach ( $params as $key => $value ) { |
| 756 | if ( 'action' === $key ) { |
| 757 | continue; |
| 758 | } |
| 759 | |
| 760 | unset( $params[ $key ] ); |
| 761 | |
| 762 | $params[ str_replace( '_podsfix_', '', $key ) ] = $value; |
| 763 | } |
| 764 | |
| 765 | $params = (object) $params; |
| 766 | |
| 767 | $component = $params->component; |
| 768 | $method = $params->method; |
| 769 | |
| 770 | if ( ! isset( $component ) || ! isset( $this->components[ $component ] ) || ! isset( $this->settings['components'][ $component ] ) ) { |
| 771 | return pods_error( __( 'Invalid AJAX request', 'pods' ), $this ); |
| 772 | } |
| 773 | |
| 774 | if ( ! is_user_logged_in() || ! pods_is_admin( 'pods_components' ) ) { |
| 775 | return pods_error( __( 'Unauthorized request', 'pods' ), $this ); |
| 776 | } |
| 777 | |
| 778 | if ( ! isset( $params->_wpnonce ) || false === wp_verify_nonce( $params->_wpnonce, 'pods-component-' . $component . '-' . $method ) ) { |
| 779 | return pods_error( __( 'Unauthorized request', 'pods' ), $this ); |
| 780 | } |
| 781 | |
| 782 | // Cleaning up $params |
| 783 | unset( $params->action, $params->component, $params->method, $params->_wpnonce ); |
| 784 | |
| 785 | $params = (object) apply_filters( "pods_component_ajax_{$component}_{$method}", $params, $component, $method ); |
| 786 | |
| 787 | $output = false; |
| 788 | |
| 789 | // Component init |
| 790 | if ( isset( $this->components[ $component ]['object'] ) && method_exists( $this->components[ $component ]['object'], 'init' ) ) { |
| 791 | $this->components[ $component ]['object']->init( $this->settings['components'][ $component ], $component ); |
| 792 | } |
| 793 | |
| 794 | if ( isset( $this->components[ $component ]['object'] ) && ! method_exists( $this->components[ $component ]['object'], 'ajax_' . $method ) && method_exists( $this, 'admin_ajax_' . $method ) ) { |
| 795 | // Handle internal methods |
| 796 | $output = call_user_func( array( $this, 'admin_ajax_' . $method ), $component, $params ); |
| 797 | } elseif ( ! isset( $this->components[ $component ]['object'] ) || ! method_exists( $this->components[ $component ]['object'], 'ajax_' . $method ) ) { |
| 798 | // Make sure method exists |
| 799 | return pods_error( __( 'API method does not exist', 'pods' ), $this ); |
| 800 | } else { |
| 801 | // Dynamically call the component method |
| 802 | $output = call_user_func( array( $this->components[ $component ]['object'], 'ajax_' . $method ), $params ); |
| 803 | } |
| 804 | |
| 805 | if ( ! is_bool( $output ) ) { |
| 806 | // @codingStandardsIgnoreLine |
| 807 | echo $output; |
| 808 | } |
| 809 | |
| 810 | die(); |
| 811 | // KBAI! |
| 812 | } |
| 813 | |
| 814 | /** |
| 815 | * Handle admin AJAX settings saving. |
| 816 | * |
| 817 | * @param string $component Component name. |
| 818 | * @param array $params AJAX parameters. |
| 819 | * |
| 820 | * @return string |
| 821 | */ |
| 822 | public function admin_ajax_settings( $component, $params ) { |
| 823 | |
| 824 | if ( ! isset( $this->components[ $component ] ) ) { |
| 825 | wp_die( 'Invalid Component', '', array( 'back_link' => true ) ); |
| 826 | } elseif ( ! method_exists( $this->components[ $component ]['object'], 'options' ) ) { |
| 827 | return pods_error( __( 'Component options method does not exist', 'pods' ), $this ); |
| 828 | } |
| 829 | |
| 830 | $options = $this->components[ $component ]['object']->options( $this->settings['components'][ $component ] ); |
| 831 | |
| 832 | if ( empty( $this->settings['components'][ $component ] ) ) { |
| 833 | $this->settings['components'][ $component ] = array(); |
| 834 | } |
| 835 | |
| 836 | foreach ( $options as $field_name => $field_option ) { |
| 837 | $field_option = PodsForm::field_setup( $field_option, null, $field_option['type'] ); |
| 838 | |
| 839 | if ( ! is_array( $field_option['group'] ) ) { |
| 840 | $field_value = pods_v( 'pods_setting_' . $field_name, $params ); |
| 841 | |
| 842 | $this->settings['components'][ $component ][ $field_name ] = $field_value; |
| 843 | } else { |
| 844 | foreach ( $field_option['group'] as $field_group_name => $field_group_option ) { |
| 845 | $field_value = pods_v( 'pods_setting_' . $field_group_name, $params ); |
| 846 | |
| 847 | $this->settings['components'][ $component ][ $field_group_name ] = $field_value; |
| 848 | } |
| 849 | } |
| 850 | } |
| 851 | |
| 852 | $this->update_settings( $this->settings ); |
| 853 | |
| 854 | return '1'; |
| 855 | } |
| 856 | |
| 857 | /** |
| 858 | * Update settings. |
| 859 | * |
| 860 | * @param array $settings Component settings. |
| 861 | */ |
| 862 | public function update_settings( $settings ) { |
| 863 | $settings = wp_json_encode( $settings, JSON_UNESCAPED_UNICODE ); |
| 864 | |
| 865 | update_option( 'pods_component_settings', $settings ); |
| 866 | |
| 867 | } |
| 868 | } |
| 869 |