| [ PHPXref.com ] | [ Generated: Sun Sep 13 08:17:58 2009 ] | [ WordPress 2.8.4 ] |
| [ Index ] [ Variables ] [ Functions ] [ Classes ] [ Constants ] [ Statistics ] | ||
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * WordPress Plugin Administration API 4 * 5 * @package WordPress 6 * @subpackage Administration 7 */ 8 9 /** 10 * Parse the plugin contents to retrieve plugin's metadata. 11 * 12 * The metadata of the plugin's data searches for the following in the plugin's 13 * header. All plugin data must be on its own line. For plugin description, it 14 * must not have any newlines or only parts of the description will be displayed 15 * and the same goes for the plugin data. The below is formatted for printing. 16 * 17 * <code> 18 * /* 19 * Plugin Name: Name of Plugin 20 * Plugin URI: Link to plugin information 21 * Description: Plugin Description 22 * Author: Plugin author's name 23 * Author URI: Link to the author's web site 24 * Version: Must be set in the plugin for WordPress 2.3+ 25 * Text Domain: Optional. Unique identifier, should be same as the one used in 26 * plugin_text_domain() 27 * Domain Path: Optional. Only useful if the translations are located in a 28 * folder above the plugin's base path. For example, if .mo files are 29 * located in the locale folder then Domain Path will be "/locale/" and 30 * must have the first slash. Defaults to the base folder the plugin is 31 * located in. 32 * * / # Remove the space to close comment 33 * </code> 34 * 35 * Plugin data returned array contains the following: 36 * 'Name' - Name of the plugin, must be unique. 37 * 'Title' - Title of the plugin and the link to the plugin's web site. 38 * 'Description' - Description of what the plugin does and/or notes 39 * from the author. 40 * 'Author' - The author's name 41 * 'AuthorURI' - The authors web site address. 42 * 'Version' - The plugin version number. 43 * 'PluginURI' - Plugin web site address. 44 * 'TextDomain' - Plugin's text domain for localization. 45 * 'DomainPath' - Plugin's relative directory path to .mo files. 46 * 47 * Some users have issues with opening large files and manipulating the contents 48 * for want is usually the first 1kiB or 2kiB. This function stops pulling in 49 * the plugin contents when it has all of the required plugin data. 50 * 51 * The first 8kiB of the file will be pulled in and if the plugin data is not 52 * within that first 8kiB, then the plugin author should correct their plugin 53 * and move the plugin data headers to the top. 54 * 55 * The plugin file is assumed to have permissions to allow for scripts to read 56 * the file. This is not checked however and the file is only opened for 57 * reading. 58 * 59 * @link http://trac.wordpress.org/ticket/5651 Previous Optimizations. 60 * @link http://trac.wordpress.org/ticket/7372 Further and better Optimizations. 61 * @since 1.5.0 62 * 63 * @param string $plugin_file Path to the plugin file 64 * @param bool $markup If the returned data should have HTML markup applied 65 * @param bool $translate If the returned data should be translated 66 * @return array See above for description. 67 */ 68 function get_plugin_data( $plugin_file, $markup = true, $translate = true ) { 69 // We don't need to write to the file, so just open for reading. 70 $fp = fopen($plugin_file, 'r'); 71 72 // Pull only the first 8kiB of the file in. 73 $plugin_data = fread( $fp, 8192 ); 74 75 // PHP will close file handle, but we are good citizens. 76 fclose($fp); 77 78 preg_match( '|Plugin Name:(.*)$|mi', $plugin_data, $name ); 79 preg_match( '|Plugin URI:(.*)$|mi', $plugin_data, $uri ); 80 preg_match( '|Version:(.*)|i', $plugin_data, $version ); 81 preg_match( '|Description:(.*)$|mi', $plugin_data, $description ); 82 preg_match( '|Author:(.*)$|mi', $plugin_data, $author_name ); 83 preg_match( '|Author URI:(.*)$|mi', $plugin_data, $author_uri ); 84 preg_match( '|Text Domain:(.*)$|mi', $plugin_data, $text_domain ); 85 preg_match( '|Domain Path:(.*)$|mi', $plugin_data, $domain_path ); 86 87 foreach ( array( 'name', 'uri', 'version', 'description', 'author_name', 'author_uri', 'text_domain', 'domain_path' ) as $field ) { 88 if ( !empty( ${$field} ) ) 89 ${$field} = _cleanup_header_comment(${$field}[1]); 90 else 91 ${$field} = ''; 92 } 93 94 $plugin_data = array( 95 'Name' => $name, 'Title' => $name, 'PluginURI' => $uri, 'Description' => $description, 96 'Author' => $author_name, 'AuthorURI' => $author_uri, 'Version' => $version, 97 'TextDomain' => $text_domain, 'DomainPath' => $domain_path 98 ); 99 if ( $markup || $translate ) 100 $plugin_data = _get_plugin_data_markup_translate($plugin_file, $plugin_data, $markup, $translate); 101 102 return $plugin_data; 103 } 104 105 function _get_plugin_data_markup_translate($plugin_file, $plugin_data, $markup = true, $translate = true) { 106 107 //Translate fields 108 if( $translate && ! empty($plugin_data['TextDomain']) ) { 109 if( ! empty( $plugin_data['DomainPath'] ) ) 110 load_plugin_textdomain($plugin_data['TextDomain'], dirname($plugin_file). $plugin_data['DomainPath']); 111 else 112 load_plugin_textdomain($plugin_data['TextDomain'], dirname($plugin_file)); 113 114 foreach ( array('Name', 'PluginURI', 'Description', 'Author', 'AuthorURI', 'Version') as $field ) 115 $plugin_data[ $field ] = translate($plugin_data[ $field ], $plugin_data['TextDomain']); 116 } 117 118 //Apply Markup 119 if ( $markup ) { 120 if ( ! empty($plugin_data['PluginURI']) && ! empty($plugin_data['Name']) ) 121 $plugin_data['Title'] = '<a href="' . $plugin_data['PluginURI'] . '" title="' . __( 'Visit plugin homepage' ) . '">' . $plugin_data['Name'] . '</a>'; 122 else 123 $plugin_data['Title'] = $plugin_data['Name']; 124 125 if ( ! empty($plugin_data['AuthorURI']) && ! empty($plugin_data['Author']) ) 126 $plugin_data['Author'] = '<a href="' . $plugin_data['AuthorURI'] . '" title="' . __( 'Visit author homepage' ) . '">' . $plugin_data['Author'] . '</a>'; 127 128 $plugin_data['Description'] = wptexturize( $plugin_data['Description'] ); 129 if( ! empty($plugin_data['Author']) ) 130 $plugin_data['Description'] .= ' <cite>' . sprintf( __('By %s'), $plugin_data['Author'] ) . '.</cite>'; 131 } 132 133 $plugins_allowedtags = array('a' => array('href' => array(),'title' => array()),'abbr' => array('title' => array()),'acronym' => array('title' => array()),'code' => array(),'em' => array(),'strong' => array()); 134 135 // Sanitize all displayed data 136 $plugin_data['Title'] = wp_kses($plugin_data['Title'], $plugins_allowedtags); 137 $plugin_data['Version'] = wp_kses($plugin_data['Version'], $plugins_allowedtags); 138 $plugin_data['Description'] = wp_kses($plugin_data['Description'], $plugins_allowedtags); 139 $plugin_data['Author'] = wp_kses($plugin_data['Author'], $plugins_allowedtags); 140 141 return $plugin_data; 142 } 143 144 /** 145 * Get a list of a plugin's files. 146 * 147 * @since 2.8.0 148 * 149 * @param string $plugin Plugin ID 150 * @return array List of files relative to the plugin root. 151 */ 152 function get_plugin_files($plugin) { 153 $plugin_file = WP_PLUGIN_DIR . '/' . $plugin; 154 $dir = dirname($plugin_file); 155 $plugin_files = array($plugin); 156 if ( is_dir($dir) && $dir != WP_PLUGIN_DIR ) { 157 $plugins_dir = @ opendir( $dir ); 158 if ( $plugins_dir ) { 159 while (($file = readdir( $plugins_dir ) ) !== false ) { 160 if ( substr($file, 0, 1) == '.' ) 161 continue; 162 if ( is_dir( $dir . '/' . $file ) ) { 163 $plugins_subdir = @ opendir( $dir . '/' . $file ); 164 if ( $plugins_subdir ) { 165 while (($subfile = readdir( $plugins_subdir ) ) !== false ) { 166 if ( substr($subfile, 0, 1) == '.' ) 167 continue; 168 $plugin_files[] = plugin_basename("$dir/$file/$subfile"); 169 } 170 @closedir( $plugins_subdir ); 171 } 172 } else { 173 if ( plugin_basename("$dir/$file") != $plugin ) 174 $plugin_files[] = plugin_basename("$dir/$file"); 175 } 176 } 177 @closedir( $plugins_dir ); 178 } 179 } 180 181 return $plugin_files; 182 } 183 184 /** 185 * Check the plugins directory and retrieve all plugin files with plugin data. 186 * 187 * WordPress only supports plugin files in the base plugins directory 188 * (wp-content/plugins) and in one directory above the plugins directory 189 * (wp-content/plugins/my-plugin). The file it looks for has the plugin data and 190 * must be found in those two locations. It is recommended that do keep your 191 * plugin files in directories. 192 * 193 * The file with the plugin data is the file that will be included and therefore 194 * needs to have the main execution for the plugin. This does not mean 195 * everything must be contained in the file and it is recommended that the file 196 * be split for maintainability. Keep everything in one file for extreme 197 * optimization purposes. 198 * 199 * @since unknown 200 * 201 * @param string $plugin_folder Optional. Relative path to single plugin folder. 202 * @return array Key is the plugin file path and the value is an array of the plugin data. 203 */ 204 function get_plugins($plugin_folder = '') { 205 206 if ( ! $cache_plugins = wp_cache_get('plugins', 'plugins') ) 207 $cache_plugins = array(); 208 209 if ( isset($cache_plugins[ $plugin_folder ]) ) 210 return $cache_plugins[ $plugin_folder ]; 211 212 $wp_plugins = array (); 213 $plugin_root = WP_PLUGIN_DIR; 214 if( !empty($plugin_folder) ) 215 $plugin_root .= $plugin_folder; 216 217 // Files in wp-content/plugins directory 218 $plugins_dir = @ opendir( $plugin_root); 219 $plugin_files = array(); 220 if ( $plugins_dir ) { 221 while (($file = readdir( $plugins_dir ) ) !== false ) { 222 if ( substr($file, 0, 1) == '.' ) 223 continue; 224 if ( is_dir( $plugin_root.'/'.$file ) ) { 225 $plugins_subdir = @ opendir( $plugin_root.'/'.$file ); 226 if ( $plugins_subdir ) { 227 while (($subfile = readdir( $plugins_subdir ) ) !== false ) { 228 if ( substr($subfile, 0, 1) == '.' ) 229 continue; 230 if ( substr($subfile, -4) == '.php' ) 231 $plugin_files[] = "$file/$subfile"; 232 } 233 } 234 } else { 235 if ( substr($file, -4) == '.php' ) 236 $plugin_files[] = $file; 237 } 238 } 239 } 240 @closedir( $plugins_dir ); 241 @closedir( $plugins_subdir ); 242 243 if ( !$plugins_dir || empty($plugin_files) ) 244 return $wp_plugins; 245 246 foreach ( $plugin_files as $plugin_file ) { 247 if ( !is_readable( "$plugin_root/$plugin_file" ) ) 248 continue; 249 250 $plugin_data = get_plugin_data( "$plugin_root/$plugin_file", false, false ); //Do not apply markup/translate as it'll be cached. 251 252 if ( empty ( $plugin_data['Name'] ) ) 253 continue; 254 255 $wp_plugins[plugin_basename( $plugin_file )] = $plugin_data; 256 } 257 258 uasort( $wp_plugins, create_function( '$a, $b', 'return strnatcasecmp( $a["Name"], $b["Name"] );' )); 259 260 $cache_plugins[ $plugin_folder ] = $wp_plugins; 261 wp_cache_set('plugins', $cache_plugins, 'plugins'); 262 263 return $wp_plugins; 264 } 265 266 /** 267 * Check whether the plugin is active by checking the active_plugins list. 268 * 269 * @since 2.5.0 270 * 271 * @param string $plugin Base plugin path from plugins directory. 272 * @return bool True, if in the active plugins list. False, not in the list. 273 */ 274 function is_plugin_active($plugin) { 275 return in_array($plugin, get_option('active_plugins')); 276 } 277 278 /** 279 * Attempts activation of plugin in a "sandbox" and redirects on success. 280 * 281 * A plugin that is already activated will not attempt to be activated again. 282 * 283 * The way it works is by setting the redirection to the error before trying to 284 * include the plugin file. If the plugin fails, then the redirection will not 285 * be overwritten with the success message. Also, the options will not be 286 * updated and the activation hook will not be called on plugin error. 287 * 288 * It should be noted that in no way the below code will actually prevent errors 289 * within the file. The code should not be used elsewhere to replicate the 290 * "sandbox", which uses redirection to work. 291 * {@source 13 1} 292 * 293 * If any errors are found or text is outputted, then it will be captured to 294 * ensure that the success redirection will update the error redirection. 295 * 296 * @since unknown 297 * 298 * @param string $plugin Plugin path to main plugin file with plugin data. 299 * @param string $redirect Optional. URL to redirect to. 300 * @return WP_Error|null WP_Error on invalid file or null on success. 301 */ 302 function activate_plugin($plugin, $redirect = '') { 303 $current = get_option('active_plugins'); 304 $plugin = plugin_basename(trim($plugin)); 305 306 $valid = validate_plugin($plugin); 307 if ( is_wp_error($valid) ) 308 return $valid; 309 310 if ( !in_array($plugin, $current) ) { 311 if ( !empty($redirect) ) 312 wp_redirect(add_query_arg('_error_nonce', wp_create_nonce('plugin-activation-error_' . $plugin), $redirect)); // we'll override this later if the plugin can be included without fatal error 313 ob_start(); 314 @include(WP_PLUGIN_DIR . '/' . $plugin); 315 $current[] = $plugin; 316 sort($current); 317 update_option('active_plugins', $current); 318 do_action('activate_' . $plugin); 319 ob_end_clean(); 320 } 321 322 return null; 323 } 324 325 /** 326 * Deactivate a single plugin or multiple plugins. 327 * 328 * The deactivation hook is disabled by the plugin upgrader by using the $silent 329 * parameter. 330 * 331 * @since unknown 332 * 333 * @param string|array $plugins Single plugin or list of plugins to deactivate. 334 * @param bool $silent Optional, default is false. Prevent calling deactivate hook. 335 */ 336 function deactivate_plugins($plugins, $silent= false) { 337 $current = get_option('active_plugins'); 338 339 if ( !is_array($plugins) ) 340 $plugins = array($plugins); 341 342 foreach ( $plugins as $plugin ) { 343 $plugin = plugin_basename($plugin); 344 if( ! is_plugin_active($plugin) ) 345 continue; 346 array_splice($current, array_search( $plugin, $current), 1 ); // Fixed Array-fu! 347 if ( ! $silent ) //Used by Plugin updater to internally deactivate plugin, however, not to notify plugins of the fact to prevent plugin output. 348 do_action('deactivate_' . trim( $plugin )); 349 } 350 351 update_option('active_plugins', $current); 352 } 353 354 /** 355 * Activate multiple plugins. 356 * 357 * When WP_Error is returned, it does not mean that one of the plugins had 358 * errors. It means that one or more of the plugins file path was invalid. 359 * 360 * The execution will be halted as soon as one of the plugins has an error. 361 * 362 * @since unknown 363 * 364 * @param string|array $plugins 365 * @param string $redirect Redirect to page after successful activation. 366 * @return bool|WP_Error True when finished or WP_Error if there were errors during a plugin activation. 367 */ 368 function activate_plugins($plugins, $redirect = '') { 369 if ( !is_array($plugins) ) 370 $plugins = array($plugins); 371 372 $errors = array(); 373 foreach ( (array) $plugins as $plugin ) { 374 if ( !empty($redirect) ) 375 $redirect = add_query_arg('plugin', $plugin, $redirect); 376 $result = activate_plugin($plugin, $redirect); 377 if ( is_wp_error($result) ) 378 $errors[$plugin] = $result; 379 } 380 381 if ( !empty($errors) ) 382 return new WP_Error('plugins_invalid', __('One of the plugins is invalid.'), $errors); 383 384 return true; 385 } 386 387 /** 388 * Remove directory and files of a plugin for a single or list of plugin(s). 389 * 390 * If the plugins parameter list is empty, false will be returned. True when 391 * completed. 392 * 393 * @since unknown 394 * 395 * @param array $plugins List of plugin 396 * @param string $redirect Redirect to page when complete. 397 * @return mixed 398 */ 399 function delete_plugins($plugins, $redirect = '' ) { 400 global $wp_filesystem; 401 402 if( empty($plugins) ) 403 return false; 404 405 $checked = array(); 406 foreach( $plugins as $plugin ) 407 $checked[] = 'checked[]=' . $plugin; 408 409 ob_start(); 410 $url = wp_nonce_url('plugins.php?action=delete-selected&verify-delete=1&' . implode('&', $checked), 'bulk-manage-plugins'); 411 if ( false === ($credentials = request_filesystem_credentials($url)) ) { 412 $data = ob_get_contents(); 413 ob_end_clean(); 414 if( ! empty($data) ){ 415 include_once ( ABSPATH . 'wp-admin/admin-header.php'); 416 echo $data; 417 include ( ABSPATH . 'wp-admin/admin-footer.php'); 418 exit; 419 } 420 return; 421 } 422 423 if ( ! WP_Filesystem($credentials) ) { 424 request_filesystem_credentials($url, '', true); //Failed to connect, Error and request again 425 $data = ob_get_contents(); 426 ob_end_clean(); 427 if( ! empty($data) ){ 428 include_once ( ABSPATH . 'wp-admin/admin-header.php'); 429 echo $data; 430 include ( ABSPATH . 'wp-admin/admin-footer.php'); 431 exit; 432 } 433 return; 434 } 435 436 if ( ! is_object($wp_filesystem) ) 437 return new WP_Error('fs_unavailable', __('Could not access filesystem.')); 438 439 if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() ) 440 return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors); 441 442 //Get the base plugin folder 443 $plugins_dir = $wp_filesystem->wp_plugins_dir(); 444 if ( empty($plugins_dir) ) 445 return new WP_Error('fs_no_plugins_dir', __('Unable to locate WordPress Plugin directory.')); 446 447 $plugins_dir = trailingslashit( $plugins_dir ); 448 449 $errors = array(); 450 451 foreach( $plugins as $plugin_file ) { 452 // Run Uninstall hook 453 if ( is_uninstallable_plugin( $plugin_file ) ) 454 uninstall_plugin($plugin_file); 455 456 $this_plugin_dir = trailingslashit( dirname($plugins_dir . $plugin_file) ); 457 // If plugin is in its own directory, recursively delete the directory. 458 if ( strpos($plugin_file, '/') && $this_plugin_dir != $plugins_dir ) //base check on if plugin includes directory seperator AND that its not the root plugin folder 459 $deleted = $wp_filesystem->delete($this_plugin_dir, true); 460 else 461 $deleted = $wp_filesystem->delete($plugins_dir . $plugin_file); 462 463 if ( ! $deleted ) 464 $errors[] = $plugin_file; 465 } 466 467 if ( ! empty($errors) ) 468 return new WP_Error('could_not_remove_plugin', sprintf(__('Could not fully remove the plugin(s) %s'), implode(', ', $errors)) ); 469 470 // Force refresh of plugin update information 471 if ( $current = get_transient('update_plugins') ) { 472 unset( $current->response[ $plugin_file ] ); 473 set_transient('update_plugins', $current); 474 } 475 476 return true; 477 } 478 479 function validate_active_plugins() { 480 $check_plugins = get_option('active_plugins'); 481 482 // Sanity check. If the active plugin list is not an array, make it an 483 // empty array. 484 if ( !is_array($check_plugins) ) { 485 update_option('active_plugins', array()); 486 return; 487 } 488 489 //Invalid is any plugin that is deactivated due to error. 490 $invalid = array(); 491 492 // If a plugin file does not exist, remove it from the list of active 493 // plugins. 494 foreach ( $check_plugins as $check_plugin ) { 495 $result = validate_plugin($check_plugin); 496 if ( is_wp_error( $result ) ) { 497 $invalid[$check_plugin] = $result; 498 deactivate_plugins( $check_plugin, true); 499 } 500 } 501 return $invalid; 502 } 503 504 /** 505 * Validate the plugin path. 506 * 507 * Checks that the file exists and {@link validate_file() is valid file}. 508 * 509 * @since unknown 510 * 511 * @param string $plugin Plugin Path 512 * @return WP_Error|int 0 on success, WP_Error on failure. 513 */ 514 function validate_plugin($plugin) { 515 if ( validate_file($plugin) ) 516 return new WP_Error('plugin_invalid', __('Invalid plugin path.')); 517 if ( ! file_exists(WP_PLUGIN_DIR . '/' . $plugin) ) 518 return new WP_Error('plugin_not_found', __('Plugin file does not exist.')); 519 520 $installed_plugins = get_plugins(); 521 if ( ! isset($installed_plugins[$plugin]) ) 522 return new WP_Error('no_plugin_header', __('The plugin does not have a valid header.')); 523 return 0; 524 } 525 526 /** 527 * Whether the plugin can be uninstalled. 528 * 529 * @since 2.7.0 530 * 531 * @param string $plugin Plugin path to check. 532 * @return bool Whether plugin can be uninstalled. 533 */ 534 function is_uninstallable_plugin($plugin) { 535 $file = plugin_basename($plugin); 536 537 $uninstallable_plugins = (array) get_option('uninstall_plugins'); 538 if ( isset( $uninstallable_plugins[$file] ) || file_exists( WP_PLUGIN_DIR . '/' . dirname($file) . '/uninstall.php' ) ) 539 return true; 540 541 return false; 542 } 543 544 /** 545 * Uninstall a single plugin. 546 * 547 * Calls the uninstall hook, if it is available. 548 * 549 * @since 2.7.0 550 * 551 * @param string $plugin Relative plugin path from Plugin Directory. 552 */ 553 function uninstall_plugin($plugin) { 554 $file = plugin_basename($plugin); 555 556 $uninstallable_plugins = (array) get_option('uninstall_plugins'); 557 if ( file_exists( WP_PLUGIN_DIR . '/' . dirname($file) . '/uninstall.php' ) ) { 558 if ( isset( $uninstallable_plugins[$file] ) ) { 559 unset($uninstallable_plugins[$file]); 560 update_option('uninstall_plugins', $uninstallable_plugins); 561 } 562 unset($uninstallable_plugins); 563 564 define('WP_UNINSTALL_PLUGIN', $file); 565 include WP_PLUGIN_DIR . '/' . dirname($file) . '/uninstall.php'; 566 567 return true; 568 } 569 570 if ( isset( $uninstallable_plugins[$file] ) ) { 571 $callable = $uninstallable_plugins[$file]; 572 unset($uninstallable_plugins[$file]); 573 update_option('uninstall_plugins', $uninstallable_plugins); 574 unset($uninstallable_plugins); 575 576 include WP_PLUGIN_DIR . '/' . $file; 577 578 add_action( 'uninstall_' . $file, $callable ); 579 do_action( 'uninstall_' . $file ); 580 } 581 } 582 583 // 584 // Menu 585 // 586 587 function add_menu_page( $page_title, $menu_title, $access_level, $file, $function = '', $icon_url = '' ) { 588 global $menu, $admin_page_hooks, $_registered_pages; 589 590 $file = plugin_basename( $file ); 591 592 $admin_page_hooks[$file] = sanitize_title( $menu_title ); 593 594 $hookname = get_plugin_page_hookname( $file, '' ); 595 if (!empty ( $function ) && !empty ( $hookname )) 596 add_action( $hookname, $function ); 597 598 if ( empty($icon_url) ) 599 $icon_url = 'images/generic.png'; 600 elseif ( is_ssl() && 0 === strpos($icon_url, 'http://') ) 601 $icon_url = 'https://' . substr($icon_url, 7); 602 603 $menu[] = array ( $menu_title, $access_level, $file, $page_title, 'menu-top ' . $hookname, $hookname, $icon_url ); 604 605 $_registered_pages[$hookname] = true; 606 607 return $hookname; 608 } 609 610 function add_object_page( $page_title, $menu_title, $access_level, $file, $function = '', $icon_url = '') { 611 global $menu, $admin_page_hooks, $_wp_last_object_menu, $_registered_pages; 612 613 $file = plugin_basename( $file ); 614 615 $admin_page_hooks[$file] = sanitize_title( $menu_title ); 616 617 $hookname = get_plugin_page_hookname( $file, '' ); 618 if (!empty ( $function ) && !empty ( $hookname )) 619 add_action( $hookname, $function ); 620 621 if ( empty($icon_url) ) 622 $icon_url = 'images/generic.png'; 623 624 $_wp_last_object_menu++; 625 626 $menu[$_wp_last_object_menu] = array ( $menu_title, $access_level, $file, $page_title, 'menu-top ' . $hookname, $hookname, $icon_url ); 627 628 $_registered_pages[$hookname] = true; 629 630 return $hookname; 631 } 632 633 function add_utility_page( $page_title, $menu_title, $access_level, $file, $function = '', $icon_url = '') { 634 global $menu, $admin_page_hooks, $_wp_last_utility_menu, $_registered_pages; 635 636 $file = plugin_basename( $file ); 637 638 $admin_page_hooks[$file] = sanitize_title( $menu_title ); 639 640 $hookname = get_plugin_page_hookname( $file, '' ); 641 if (!empty ( $function ) && !empty ( $hookname )) 642 add_action( $hookname, $function ); 643 644 if ( empty($icon_url) ) 645 $icon_url = 'images/generic.png'; 646 elseif ( is_ssl() && 0 === strpos($icon_url, 'http://') ) 647 $icon_url = 'https://' . substr($icon_url, 7); 648 649 $_wp_last_utility_menu++; 650 651 $menu[$_wp_last_utility_menu] = array ( $menu_title, $access_level, $file, $page_title, 'menu-top ' . $hookname, $hookname, $icon_url ); 652 653 $_registered_pages[$hookname] = true; 654 655 return $hookname; 656 } 657 658 function add_submenu_page( $parent, $page_title, $menu_title, $access_level, $file, $function = '' ) { 659 global $submenu; 660 global $menu; 661 global $_wp_real_parent_file; 662 global $_wp_submenu_nopriv; 663 global $_registered_pages; 664 665 $file = plugin_basename( $file ); 666 667 $parent = plugin_basename( $parent); 668 if ( isset( $_wp_real_parent_file[$parent] ) ) 669 $parent = $_wp_real_parent_file[$parent]; 670 671 if ( !current_user_can( $access_level ) ) { 672 $_wp_submenu_nopriv[$parent][$file] = true; 673 return false; 674 } 675 676 // If the parent doesn't already have a submenu, add a link to the parent 677 // as the first item in the submenu. If the submenu file is the same as the 678 // parent file someone is trying to link back to the parent manually. In 679 // this case, don't automatically add a link back to avoid duplication. 680 if (!isset( $submenu[$parent] ) && $file != $parent ) { 681 foreach ( (array)$menu as $parent_menu ) { 682 if ( $parent_menu[2] == $parent && current_user_can( $parent_menu[1] ) ) 683 $submenu[$parent][] = $parent_menu; 684 } 685 } 686 687 $submenu[$parent][] = array ( $menu_title, $access_level, $file, $page_title ); 688 689 $hookname = get_plugin_page_hookname( $file, $parent); 690 if (!empty ( $function ) && !empty ( $hookname )) 691 add_action( $hookname, $function ); 692 693 $_registered_pages[$hookname] = true; 694 // backwards-compatibility for plugins using add_management page. See wp-admin/admin.php for redirect from edit.php to tools.php 695 if ( 'tools.php' == $parent ) 696 $_registered_pages[get_plugin_page_hookname( $file, 'edit.php')] = true; 697 698 return $hookname; 699 } 700 701 /** 702 * Add sub menu page to the tools main menu. 703 * 704 * @param string $page_title 705 * @param unknown_type $menu_title 706 * @param unknown_type $access_level 707 * @param unknown_type $file 708 * @param unknown_type $function 709 * @return unknown 710 */ 711 function add_management_page( $page_title, $menu_title, $access_level, $file, $function = '' ) { 712 return add_submenu_page( 'tools.php', $page_title, $menu_title, $access_level, $file, $function ); 713 } 714 715 function add_options_page( $page_title, $menu_title, $access_level, $file, $function = '' ) { 716 return add_submenu_page( 'options-general.php', $page_title, $menu_title, $access_level, $file, $function ); 717 } 718 719 function add_theme_page( $page_title, $menu_title, $access_level, $file, $function = '' ) { 720 return add_submenu_page( 'themes.php', $page_title, $menu_title, $access_level, $file, $function ); 721 } 722 723 function add_users_page( $page_title, $menu_title, $access_level, $file, $function = '' ) { 724 if ( current_user_can('edit_users') ) 725 $parent = 'users.php'; 726 else 727 $parent = 'profile.php'; 728 return add_submenu_page( $parent, $page_title, $menu_title, $access_level, $file, $function ); 729 } 730 731 function add_dashboard_page( $page_title, $menu_title, $access_level, $file, $function = '' ) { 732 return add_submenu_page( 'index.php', $page_title, $menu_title, $access_level, $file, $function ); 733 } 734 735 function add_posts_page( $page_title, $menu_title, $access_level, $file, $function = '' ) { 736 return add_submenu_page( 'edit.php', $page_title, $menu_title, $access_level, $file, $function ); 737 } 738 739 function add_media_page( $page_title, $menu_title, $access_level, $file, $function = '' ) { 740 return add_submenu_page( 'upload.php', $page_title, $menu_title, $access_level, $file, $function ); 741 } 742 743 function add_links_page( $page_title, $menu_title, $access_level, $file, $function = '' ) { 744 return add_submenu_page( 'link-manager.php', $page_title, $menu_title, $access_level, $file, $function ); 745 } 746 747 function add_pages_page( $page_title, $menu_title, $access_level, $file, $function = '' ) { 748 return add_submenu_page( 'edit-pages.php', $page_title, $menu_title, $access_level, $file, $function ); 749 } 750 751 function add_comments_page( $page_title, $menu_title, $access_level, $file, $function = '' ) { 752 return add_submenu_page( 'edit-comments.php', $page_title, $menu_title, $access_level, $file, $function ); 753 } 754 755 // 756 // Pluggable Menu Support -- Private 757 // 758 759 function get_admin_page_parent( $parent = '' ) { 760 global $parent_file; 761 global $menu; 762 global $submenu; 763 global $pagenow; 764 global $plugin_page; 765 global $_wp_real_parent_file; 766 global $_wp_menu_nopriv; 767 global $_wp_submenu_nopriv; 768 769 if ( !empty ( $parent ) && 'admin.php' != $parent ) { 770 if ( isset( $_wp_real_parent_file[$parent] ) ) 771 $parent = $_wp_real_parent_file[$parent]; 772 return $parent; 773 } 774 /* 775 if ( !empty ( $parent_file ) ) { 776 if ( isset( $_wp_real_parent_file[$parent_file] ) ) 777 $parent_file = $_wp_real_parent_file[$parent_file]; 778 779 return $parent_file; 780 } 781 */ 782 783 if ( $pagenow == 'admin.php' && isset( $plugin_page ) ) { 784 foreach ( (array)$menu as $parent_menu ) { 785 if ( $parent_menu[2] == $plugin_page ) { 786 $parent_file = $plugin_page; 787 if ( isset( $_wp_real_parent_file[$parent_file] ) ) 788 $parent_file = $_wp_real_parent_file[$parent_file]; 789 return $parent_file; 790 } 791 } 792 if ( isset( $_wp_menu_nopriv[$plugin_page] ) ) { 793 $parent_file = $plugin_page; 794 if ( isset( $_wp_real_parent_file[$parent_file] ) ) 795 $parent_file = $_wp_real_parent_file[$parent_file]; 796 return $parent_file; 797 } 798 } 799 800 if ( isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$pagenow][$plugin_page] ) ) { 801 $parent_file = $pagenow; 802 if ( isset( $_wp_real_parent_file[$parent_file] ) ) 803 $parent_file = $_wp_real_parent_file[$parent_file]; 804 return $parent_file; 805 } 806 807 foreach (array_keys( (array)$submenu ) as $parent) { 808 foreach ( $submenu[$parent] as $submenu_array ) { 809 if ( isset( $_wp_real_parent_file[$parent] ) ) 810 $parent = $_wp_real_parent_file[$parent]; 811 if ( $submenu_array[2] == $pagenow ) { 812 $parent_file = $parent; 813 return $parent; 814 } else 815 if ( isset( $plugin_page ) && ($plugin_page == $submenu_array[2] ) ) { 816 $parent_file = $parent; 817 return $parent; 818 } 819 } 820 } 821 822 if ( empty($parent_file) ) 823 $parent_file = ''; 824 return ''; 825 } 826 827 function get_admin_page_title() { 828 global $title; 829 global $menu; 830 global $submenu; 831 global $pagenow; 832 global $plugin_page; 833 834 if ( isset( $title ) && !empty ( $title ) ) { 835 return $title; 836 } 837 838 $hook = get_plugin_page_hook( $plugin_page, $pagenow ); 839 840 $parent = $parent1 = get_admin_page_parent(); 841 842 if ( empty ( $parent) ) { 843 foreach ( (array)$menu as $menu_array ) { 844 if ( isset( $menu_array[3] ) ) { 845 if ( $menu_array[2] == $pagenow ) { 846 $title = $menu_array[3]; 847 return $menu_array[3]; 848 } else 849 if ( isset( $plugin_page ) && ($plugin_page == $menu_array[2] ) && ($hook == $menu_array[3] ) ) { 850 $title = $menu_array[3]; 851 return $menu_array[3]; 852 } 853 } else { 854 $title = $menu_array[0]; 855 return $title; 856 } 857 } 858 } else { 859 foreach (array_keys( $submenu ) as $parent) { 860 foreach ( $submenu[$parent] as $submenu_array ) { 861 if ( isset( $plugin_page ) && 862 ($plugin_page == $submenu_array[2] ) && 863 (($parent == $pagenow ) || ($parent == $plugin_page ) || ($plugin_page == $hook ) || (($pagenow == 'admin.php' ) && ($parent1 != $submenu_array[2] ) ) ) 864 ) { 865 $title = $submenu_array[3]; 866 return $submenu_array[3]; 867 } 868 869 if ( $submenu_array[2] != $pagenow || isset( $_GET['page'] ) ) // not the current page 870 continue; 871 872 if ( isset( $submenu_array[3] ) ) { 873 $title = $submenu_array[3]; 874 return $submenu_array[3]; 875 } else { 876 $title = $submenu_array[0]; 877 return $title; 878 } 879 } 880 } 881 if ( !isset($title) || empty ( $title ) ) { 882 foreach ( $menu as $menu_array ) { 883 if ( isset( $plugin_page ) && 884 ($plugin_page == $menu_array[2] ) && 885 ($pagenow == 'admin.php' ) && 886 ($parent1 == $menu_array[2] ) ) 887 { 888 $title = $menu_array[3]; 889 return $menu_array[3]; 890 } 891 } 892 } 893 } 894 895 return $title; 896 } 897 898 function get_plugin_page_hook( $plugin_page, $parent_page ) { 899 $hook = get_plugin_page_hookname( $plugin_page, $parent_page ); 900 if ( has_action($hook) ) 901 return $hook; 902 else 903 return null; 904 } 905 906 function get_plugin_page_hookname( $plugin_page, $parent_page ) { 907 global $admin_page_hooks; 908 909 $parent = get_admin_page_parent( $parent_page ); 910 911 $page_type = 'admin'; 912 if ( empty ( $parent_page ) || 'admin.php' == $parent_page || isset( $admin_page_hooks[$plugin_page] ) ) { 913 if ( isset( $admin_page_hooks[$plugin_page] ) ) 914 $page_type = 'toplevel'; 915 else 916 if ( isset( $admin_page_hooks[$parent] )) 917 $page_type = $admin_page_hooks[$parent]; 918 } else if ( isset( $admin_page_hooks[$parent] ) ) { 919 $page_type = $admin_page_hooks[$parent]; 920 } 921 922 $plugin_name = preg_replace( '!\.php!', '', $plugin_page ); 923 924 return $page_type.'_page_'.$plugin_name; 925 } 926 927 function user_can_access_admin_page() { 928 global $pagenow; 929 global $menu; 930 global $submenu; 931 global $_wp_menu_nopriv; 932 global $_wp_submenu_nopriv; 933 global $plugin_page; 934 global $_registered_pages; 935 936 $parent = get_admin_page_parent(); 937 938 if ( !isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$parent][$pagenow] ) ) 939 return false; 940 941 if ( isset( $plugin_page ) ) { 942 if ( isset( $_wp_submenu_nopriv[$parent][$plugin_page] ) ) 943 return false; 944 945 $hookname = get_plugin_page_hookname($plugin_page, $parent); 946 if ( !isset($_registered_pages[$hookname]) ) 947 return false; 948 } 949 950 if ( empty( $parent) ) { 951 if ( isset( $_wp_menu_nopriv[$pagenow] ) ) 952 return false; 953 if ( isset( $_wp_submenu_nopriv[$pagenow][$pagenow] ) ) 954 return false; 955 if ( isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$pagenow][$plugin_page] ) ) 956 return false; 957 if ( isset( $plugin_page ) && isset( $_wp_menu_nopriv[$plugin_page] ) ) 958 return false; 959 foreach (array_keys( $_wp_submenu_nopriv ) as $key ) { 960 if ( isset( $_wp_submenu_nopriv[$key][$pagenow] ) ) 961 return false; 962 if ( isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$key][$plugin_page] ) ) 963 return false; 964 } 965 return true; 966 } 967 968 if ( isset( $plugin_page ) && ( $plugin_page == $parent ) && isset( $_wp_menu_nopriv[$plugin_page] ) ) 969 return false; 970 971 if ( isset( $submenu[$parent] ) ) { 972 foreach ( $submenu[$parent] as $submenu_array ) { 973 if ( isset( $plugin_page ) && ( $submenu_array[2] == $plugin_page ) ) { 974 if ( current_user_can( $submenu_array[1] )) 975 return true; 976 else 977 return false; 978 } else if ( $submenu_array[2] == $pagenow ) { 979 if ( current_user_can( $submenu_array[1] )) 980 return true; 981 else 982 return false; 983 } 984 } 985 } 986 987 foreach ( $menu as $menu_array ) { 988 if ( $menu_array[2] == $parent) { 989 if ( current_user_can( $menu_array[1] )) 990 return true; 991 else 992 return false; 993 } 994 } 995 996 return true; 997 } 998 999 /* Whitelist functions */ 1000 1001 /** 1002 * Register a setting and its sanitization callback 1003 * 1004 * @since 2.7.0 1005 * 1006 * @param string $option_group A settings group name. Can be anything. 1007 * @param string $option_name The name of an option to sanitize and save. 1008 * @param unknown_type $sanitize_callback A callback function that sanitizes the option's value. 1009 * @return unknown 1010 */ 1011 function register_setting($option_group, $option_name, $sanitize_callback = '') { 1012 return add_option_update_handler($option_group, $option_name, $sanitize_callback); 1013 } 1014 1015 /** 1016 * Unregister a setting 1017 * 1018 * @since 2.7.0 1019 * 1020 * @param unknown_type $option_group 1021 * @param unknown_type $option_name 1022 * @param unknown_type $sanitize_callback 1023 * @return unknown 1024 */ 1025 function unregister_setting($option_group, $option_name, $sanitize_callback = '') { 1026 return remove_option_update_handler($option_group, $option_name, $sanitize_callback); 1027 } 1028 1029 /** 1030 * {@internal Missing Short Description}} 1031 * 1032 * @since unknown 1033 * 1034 * @param unknown_type $option_group 1035 * @param unknown_type $option_name 1036 * @param unknown_type $sanitize_callback 1037 */ 1038 function add_option_update_handler($option_group, $option_name, $sanitize_callback = '') { 1039 global $new_whitelist_options; 1040 $new_whitelist_options[ $option_group ][] = $option_name; 1041 if ( $sanitize_callback != '' ) 1042 add_filter( "sanitize_option_{$option_name}", $sanitize_callback ); 1043 } 1044 1045 /** 1046 * {@internal Missing Short Description}} 1047 * 1048 * @since unknown 1049 * 1050 * @param unknown_type $option_group 1051 * @param unknown_type $option_name 1052 * @param unknown_type $sanitize_callback 1053 */ 1054 function remove_option_update_handler($option_group, $option_name, $sanitize_callback = '') { 1055 global $new_whitelist_options; 1056 $pos = array_search( $option_name, (array) $new_whitelist_options ); 1057 if ( $pos !== false ) 1058 unset( $new_whitelist_options[ $option_group ][ $pos ] ); 1059 if ( $sanitize_callback != '' ) 1060 remove_filter( "sanitize_option_{$option_name}", $sanitize_callback ); 1061 } 1062 1063 /** 1064 * {@internal Missing Short Description}} 1065 * 1066 * @since unknown 1067 * 1068 * @param unknown_type $options 1069 * @return unknown 1070 */ 1071 function option_update_filter( $options ) { 1072 global $new_whitelist_options; 1073 1074 if ( is_array( $new_whitelist_options ) ) 1075 $options = add_option_whitelist( $new_whitelist_options, $options ); 1076 1077 return $options; 1078 } 1079 add_filter( 'whitelist_options', 'option_update_filter' ); 1080 1081 /** 1082 * {@internal Missing Short Description}} 1083 * 1084 * @since unknown 1085 * 1086 * @param unknown_type $new_options 1087 * @param unknown_type $options 1088 * @return unknown 1089 */ 1090 function add_option_whitelist( $new_options, $options = '' ) { 1091 if( $options == '' ) { 1092 global $whitelist_options; 1093 } else { 1094 $whitelist_options = $options; 1095 } 1096 foreach( $new_options as $page => $keys ) { 1097 foreach( $keys as $key ) { 1098 if ( !isset($whitelist_options[ $page ]) || !is_array($whitelist_options[ $page ]) ) { 1099 $whitelist_options[ $page ] = array(); 1100 $whitelist_options[ $page ][] = $key; 1101 } else { 1102 $pos = array_search( $key, $whitelist_options[ $page ] ); 1103 if ( $pos === false ) 1104 $whitelist_options[ $page ][] = $key; 1105 } 1106 } 1107 } 1108 return $whitelist_options; 1109 } 1110 1111 /** 1112 * {@internal Missing Short Description}} 1113 * 1114 * @since unknown 1115 * 1116 * @param unknown_type $del_options 1117 * @param unknown_type $options 1118 * @return unknown 1119 */ 1120 function remove_option_whitelist( $del_options, $options = '' ) { 1121 if( $options == '' ) { 1122 global $whitelist_options; 1123 } else { 1124 $whitelist_options = $options; 1125 } 1126 foreach( $del_options as $page => $keys ) { 1127 foreach( $keys as $key ) { 1128 if ( isset($whitelist_options[ $page ]) && is_array($whitelist_options[ $page ]) ) { 1129 $pos = array_search( $key, $whitelist_options[ $page ] ); 1130 if( $pos !== false ) 1131 unset( $whitelist_options[ $page ][ $pos ] ); 1132 } 1133 } 1134 } 1135 return $whitelist_options; 1136 } 1137 1138 /** 1139 * Output nonce, action, and option_page fields for a settings page. 1140 * 1141 * @since 2.7.0 1142 * 1143 * @param string $option_group A settings group name. This should match the group name used in register_setting(). 1144 */ 1145 function settings_fields($option_group) { 1146 echo "<input type='hidden' name='option_page' value='" . esc_attr($option_group) . "' />"; 1147 echo '<input type="hidden" name="action" value="update" />'; 1148 wp_nonce_field("$option_group-options"); 1149 } 1150 1151 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| [ Powered by PHPXref - Served by Debian GNU/Linux ] |