wp/wp-admin/includes/plugin.php
changeset 5 5e2f62d02dcd
parent 0 d970ebf37754
child 7 cf61fcea0001
equal deleted inserted replaced
4:346c88efed21 5:5e2f62d02dcd
    12  * The metadata of the plugin's data searches for the following in the plugin's
    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
    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
    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.
    15  * and the same goes for the plugin data. The below is formatted for printing.
    16  *
    16  *
    17  * <code>
    17  *     /*
    18  * /*
    18  *     Plugin Name: Name of Plugin
    19  * Plugin Name: Name of Plugin
    19  *     Plugin URI: Link to plugin information
    20  * Plugin URI: Link to plugin information
    20  *     Description: Plugin Description
    21  * Description: Plugin Description
    21  *     Author: Plugin author's name
    22  * Author: Plugin author's name
    22  *     Author URI: Link to the author's web site
    23  * Author URI: Link to the author's web site
    23  *     Version: Must be set in the plugin for WordPress 2.3+
    24  * Version: Must be set in the plugin for WordPress 2.3+
    24  *     Text Domain: Optional. Unique identifier, should be same as the one used in
    25  * Text Domain: Optional. Unique identifier, should be same as the one used in
    25  *    		load_plugin_textdomain()
    26  *		plugin_text_domain()
    26  *     Domain Path: Optional. Only useful if the translations are located in a
    27  * Domain Path: Optional. Only useful if the translations are located in a
    27  *    		folder above the plugin's base path. For example, if .mo files are
    28  *		folder above the plugin's base path. For example, if .mo files are
    28  *    		located in the locale folder then Domain Path will be "/locale/" and
    29  *		located in the locale folder then Domain Path will be "/locale/" and
    29  *    		must have the first slash. Defaults to the base folder the plugin is
    30  *		must have the first slash. Defaults to the base folder the plugin is
    30  *    		located in.
    31  *		located in.
    31  *     Network: Optional. Specify "Network: true" to require that a plugin is activated
    32  * Network: Optional. Specify "Network: true" to require that a plugin is activated
    32  *    		across all sites in an installation. This will prevent a plugin from being
    33  *		across all sites in an installation. This will prevent a plugin from being
    33  *    		activated on a single site when Multisite is enabled.
    34  *		activated on a single site when Multisite is enabled.
    34  *      * / # Remove the space to close comment
    35  *  * / # Remove the space to close comment
       
    36  * </code>
       
    37  *
    35  *
    38  * Plugin data returned array contains the following:
    36  * Plugin data returned array contains the following:
    39  *		'Name' - Name of the plugin, must be unique.
    37  *
    40  *		'Title' - Title of the plugin and the link to the plugin's web site.
    38  * - 'Name' - Name of the plugin, must be unique.
    41  *		'Description' - Description of what the plugin does and/or notes
    39  * - 'Title' - Title of the plugin and the link to the plugin's web site.
    42  *		from the author.
    40  * - 'Description' - Description of what the plugin does and/or notes
    43  *		'Author' - The author's name
    41  * - from the author.
    44  *		'AuthorURI' - The authors web site address.
    42  * - 'Author' - The author's name
    45  *		'Version' - The plugin version number.
    43  * - 'AuthorURI' - The authors web site address.
    46  *		'PluginURI' - Plugin web site address.
    44  * - 'Version' - The plugin version number.
    47  *		'TextDomain' - Plugin's text domain for localization.
    45  * - 'PluginURI' - Plugin web site address.
    48  *		'DomainPath' - Plugin's relative directory path to .mo files.
    46  * - 'TextDomain' - Plugin's text domain for localization.
    49  *		'Network' - Boolean. Whether the plugin can only be activated network wide.
    47  * - 'DomainPath' - Plugin's relative directory path to .mo files.
       
    48  * - 'Network' - Boolean. Whether the plugin can only be activated network wide.
    50  *
    49  *
    51  * Some users have issues with opening large files and manipulating the contents
    50  * Some users have issues with opening large files and manipulating the contents
    52  * for want is usually the first 1kiB or 2kiB. This function stops pulling in
    51  * for want is usually the first 1kiB or 2kiB. This function stops pulling in
    53  * the plugin contents when it has all of the required plugin data.
    52  * the plugin contents when it has all of the required plugin data.
    54  *
    53  *
    58  *
    57  *
    59  * The plugin file is assumed to have permissions to allow for scripts to read
    58  * The plugin file is assumed to have permissions to allow for scripts to read
    60  * the file. This is not checked however and the file is only opened for
    59  * the file. This is not checked however and the file is only opened for
    61  * reading.
    60  * reading.
    62  *
    61  *
    63  * @link http://trac.wordpress.org/ticket/5651 Previous Optimizations.
    62  * @link https://core.trac.wordpress.org/ticket/5651 Previous Optimizations.
    64  * @link http://trac.wordpress.org/ticket/7372 Further and better Optimizations.
    63  * @link https://core.trac.wordpress.org/ticket/7372 Further and better Optimizations.
       
    64  *
    65  * @since 1.5.0
    65  * @since 1.5.0
    66  *
    66  *
    67  * @param string $plugin_file Path to the plugin file
    67  * @param string $plugin_file Path to the plugin file
    68  * @param bool $markup Optional. If the returned data should have HTML markup applied. Defaults to true.
    68  * @param bool $markup Optional. If the returned data should have HTML markup applied. Defaults to true.
    69  * @param bool $translate Optional. If the returned data should be translated. Defaults to true.
    69  * @param bool $translate Optional. If the returned data should be translated. Defaults to true.
   158 	$plugin_data['AuthorName'] = $plugin_data['Author'];
   158 	$plugin_data['AuthorName'] = $plugin_data['Author'];
   159 
   159 
   160 	// Apply markup
   160 	// Apply markup
   161 	if ( $markup ) {
   161 	if ( $markup ) {
   162 		if ( $plugin_data['PluginURI'] && $plugin_data['Name'] )
   162 		if ( $plugin_data['PluginURI'] && $plugin_data['Name'] )
   163 			$plugin_data['Title'] = '<a href="' . $plugin_data['PluginURI'] . '" title="' . esc_attr__( 'Visit plugin homepage' ) . '">' . $plugin_data['Name'] . '</a>';
   163 			$plugin_data['Title'] = '<a href="' . $plugin_data['PluginURI'] . '">' . $plugin_data['Name'] . '</a>';
   164 
   164 
   165 		if ( $plugin_data['AuthorURI'] && $plugin_data['Author'] )
   165 		if ( $plugin_data['AuthorURI'] && $plugin_data['Author'] )
   166 			$plugin_data['Author'] = '<a href="' . $plugin_data['AuthorURI'] . '" title="' . esc_attr__( 'Visit author homepage' ) . '">' . $plugin_data['Author'] . '</a>';
   166 			$plugin_data['Author'] = '<a href="' . $plugin_data['AuthorURI'] . '">' . $plugin_data['Author'] . '</a>';
   167 
   167 
   168 		$plugin_data['Description'] = wptexturize( $plugin_data['Description'] );
   168 		$plugin_data['Description'] = wptexturize( $plugin_data['Description'] );
   169 
   169 
   170 		if ( $plugin_data['Author'] )
   170 		if ( $plugin_data['Author'] )
   171 			$plugin_data['Description'] .= ' <cite>' . sprintf( __('By %s.'), $plugin_data['Author'] ) . '</cite>';
   171 			$plugin_data['Description'] .= ' <cite>' . sprintf( __('By %s.'), $plugin_data['Author'] ) . '</cite>';
   531 
   531 
   532 	$valid = validate_plugin($plugin);
   532 	$valid = validate_plugin($plugin);
   533 	if ( is_wp_error($valid) )
   533 	if ( is_wp_error($valid) )
   534 		return $valid;
   534 		return $valid;
   535 
   535 
   536 	if ( !in_array($plugin, $current) ) {
   536 	if ( ( $network_wide && ! isset( $current[ $plugin ] ) ) || ( ! $network_wide && ! in_array( $plugin, $current ) ) ) {
   537 		if ( !empty($redirect) )
   537 		if ( !empty($redirect) )
   538 			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
   538 			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
   539 		ob_start();
   539 		ob_start();
   540 		include_once(WP_PLUGIN_DIR . '/' . $plugin);
   540 		wp_register_plugin_realpath( WP_PLUGIN_DIR . '/' . $plugin );
       
   541 		$_wp_plugin_file = $plugin;
       
   542 		include_once( WP_PLUGIN_DIR . '/' . $plugin );
       
   543 		$plugin = $_wp_plugin_file; // Avoid stomping of the $plugin variable in a plugin.
   541 
   544 
   542 		if ( ! $silent ) {
   545 		if ( ! $silent ) {
   543 			/**
   546 			/**
   544 			 * Fires before a plugin is activated in activate_plugin() when the $silent parameter is false.
   547 			 * Fires before a plugin is activated.
       
   548 			 *
       
   549 			 * If a plugin is silently activated (such as during an update),
       
   550 			 * this hook does not fire.
   545 			 *
   551 			 *
   546 			 * @since 2.9.0
   552 			 * @since 2.9.0
   547 			 *
   553 			 *
   548 			 * @param string $plugin       Plugin path to main plugin file with plugin data.
   554 			 * @param string $plugin       Plugin path to main plugin file with plugin data.
   549 			 * @param bool   $network_wide Whether to enable the plugin for all sites in the network
   555 			 * @param bool   $network_wide Whether to enable the plugin for all sites in the network
   550 			 *                             or just the current site. Multisite only. Default is false.
   556 			 *                             or just the current site. Multisite only. Default is false.
   551 			 */
   557 			 */
   552 			do_action( 'activate_plugin', $plugin, $network_wide );
   558 			do_action( 'activate_plugin', $plugin, $network_wide );
   553 
   559 
   554 			/**
   560 			/**
   555 			 * Fires before a plugin is activated in activate_plugin() when the $silent parameter is false.
   561 			 * Fires as a specific plugin is being activated.
   556 			 *
   562 			 *
   557 			 * The action concatenates the 'activate_' prefix with the $plugin value passed to
   563 			 * This hook is the "activation" hook used internally by
   558 			 * activate_plugin() to create a dynamically-named action.
   564 			 * {@see register_activation_hook()}. The dynamic portion of the
       
   565 			 * hook name, `$plugin`, refers to the plugin basename.
       
   566 			 *
       
   567 			 * If a plugin is silently activated (such as during an update),
       
   568 			 * this hook does not fire.
   559 			 *
   569 			 *
   560 			 * @since 2.0.0
   570 			 * @since 2.0.0
   561 			 *
   571 			 *
   562 			 * @param bool $network_wide Whether to enable the plugin for all sites in the network
   572 			 * @param bool $network_wide Whether to enable the plugin for all sites in the network
   563 			 *                           or just the current site. Multisite only. Default is false.
   573 			 *                           or just the current site. Multisite only. Default is false.
   574 			update_option('active_plugins', $current);
   584 			update_option('active_plugins', $current);
   575 		}
   585 		}
   576 
   586 
   577 		if ( ! $silent ) {
   587 		if ( ! $silent ) {
   578 			/**
   588 			/**
   579 			 * Fires after a plugin has been activated in activate_plugin() when the $silent parameter is false.
   589 			 * Fires after a plugin has been activated.
       
   590 			 *
       
   591 			 * If a plugin is silently activated (such as during an update),
       
   592 			 * this hook does not fire.
   580 			 *
   593 			 *
   581 			 * @since 2.9.0
   594 			 * @since 2.9.0
   582 			 *
   595 			 *
   583 			 * @param string $plugin       Plugin path to main plugin file with plugin data.
   596 			 * @param string $plugin       Plugin path to main plugin file with plugin data.
   584 			 * @param bool   $network_wide Whether to enable the plugin for all sites in the network
   597 			 * @param bool   $network_wide Whether to enable the plugin for all sites in the network
   621 		if ( ! is_plugin_active($plugin) )
   634 		if ( ! is_plugin_active($plugin) )
   622 			continue;
   635 			continue;
   623 
   636 
   624 		$network_deactivating = false !== $network_wide && is_plugin_active_for_network( $plugin );
   637 		$network_deactivating = false !== $network_wide && is_plugin_active_for_network( $plugin );
   625 
   638 
   626 		if ( ! $silent )
   639 		if ( ! $silent ) {
   627 			/**
   640 			/**
   628 			 * Fires for each plugin being deactivated in deactivate_plugins(), before deactivation
   641 			 * Fires before a plugin is deactivated.
   629 			 * and when the $silent parameter is false.
   642 			 *
       
   643 			 * If a plugin is silently deactivated (such as during an update),
       
   644 			 * this hook does not fire.
   630 			 *
   645 			 *
   631 			 * @since 2.9.0
   646 			 * @since 2.9.0
   632 			 *
   647 			 *
   633 			 * @param string $plugin               Plugin path to main plugin file with plugin data.
   648 			 * @param string $plugin               Plugin path to main plugin file with plugin data.
   634 			 * @param bool   $network_deactivating Whether the plugin is deactivated for all sites in the network
   649 			 * @param bool   $network_deactivating Whether the plugin is deactivated for all sites in the network
   635 			 *                                     or just the current site. Multisite only. Default is false.
   650 			 *                                     or just the current site. Multisite only. Default is false.
   636 			 */
   651 			 */
   637 			do_action( 'deactivate_plugin', $plugin, $network_deactivating );
   652 			do_action( 'deactivate_plugin', $plugin, $network_deactivating );
       
   653 		}
   638 
   654 
   639 		if ( false !== $network_wide ) {
   655 		if ( false !== $network_wide ) {
   640 			if ( is_plugin_active_for_network( $plugin ) ) {
   656 			if ( is_plugin_active_for_network( $plugin ) ) {
   641 				$do_network = true;
   657 				$do_network = true;
   642 				unset( $network_current[ $plugin ] );
   658 				unset( $network_current[ $plugin ] );
   653 			}
   669 			}
   654 		}
   670 		}
   655 
   671 
   656 		if ( ! $silent ) {
   672 		if ( ! $silent ) {
   657 			/**
   673 			/**
   658 			 * Fires for each plugin being deactivated in deactivate_plugins(), after deactivation
   674 			 * Fires as a specific plugin is being deactivated.
   659 			 * and when the $silent parameter is false.
   675 			 *
   660 			 *
   676 			 * This hook is the "deactivation" hook used internally by
   661 			 * The action concatenates the 'deactivate_' prefix with the plugin's basename
   677 			 * {@see register_deactivation_hook()}. The dynamic portion of the
   662 			 * to create a dynamically-named action.
   678 			 * hook name, `$plugin`, refers to the plugin basename.
       
   679 			 *
       
   680 			 * If a plugin is silently deactivated (such as during an update),
       
   681 			 * this hook does not fire.
   663 			 *
   682 			 *
   664 			 * @since 2.0.0
   683 			 * @since 2.0.0
   665 			 *
   684 			 *
   666 			 * @param bool $network_deactivating Whether the plugin is deactivated for all sites in the network
   685 			 * @param bool $network_deactivating Whether the plugin is deactivated for all sites in the network
   667 			 *                                   or just the current site. Multisite only. Default is false.
   686 			 *                                   or just the current site. Multisite only. Default is false.
   668 			 */
   687 			 */
   669 			do_action( 'deactivate_' . $plugin, $network_deactivating );
   688 			do_action( 'deactivate_' . $plugin, $network_deactivating );
   670 
   689 
   671 			/**
   690 			/**
   672 			 * Fires for each plugin being deactivated in deactivate_plugins(), after deactivation
   691 			 * Fires after a plugin is deactivated.
   673 			 * and when the $silent parameter is false.
   692 			 *
       
   693 			 * If a plugin is silently deactivated (such as during an update),
       
   694 			 * this hook does not fire.
   674 			 *
   695 			 *
   675 			 * @since 2.9.0
   696 			 * @since 2.9.0
   676 			 *
   697 			 *
   677 			 * @param string $plugin               Plugin path to main plugin file with plugin data.
   698 			 * @param string $plugin               Plugin basename.
   678 			 * @param bool   $network_deactivating Whether the plugin is deactivated for all sites in the network
   699 			 * @param bool   $network_deactivating Whether the plugin is deactivated for all sites in the network
   679 			 *                                     or just the current site. Multisite only. Default is false.
   700 			 *                                     or just the current site. Multisite only. Default false.
   680 			 */
   701 			 */
   681 			do_action( 'deactivated_plugin', $plugin, $network_deactivating );
   702 			do_action( 'deactivated_plugin', $plugin, $network_deactivating );
   682 		}
   703 		}
   683 	}
   704 	}
   684 
   705 
   696  *
   717  *
   697  * The execution will be halted as soon as one of the plugins has an error.
   718  * The execution will be halted as soon as one of the plugins has an error.
   698  *
   719  *
   699  * @since 2.6.0
   720  * @since 2.6.0
   700  *
   721  *
   701  * @param string|array $plugins
   722  * @param string|array $plugins Single plugin or list of plugins to activate.
   702  * @param string $redirect Redirect to page after successful activation.
   723  * @param string $redirect Redirect to page after successful activation.
   703  * @param bool $network_wide Whether to enable the plugin for all sites in the network.
   724  * @param bool $network_wide Whether to enable the plugin for all sites in the network.
   704  * @param bool $silent Prevent calling activation hooks. Default is false.
   725  * @param bool $silent Prevent calling activation hooks. Default is false.
   705  * @return bool|WP_Error True when finished or WP_Error if there were errors during a plugin activation.
   726  * @return bool|WP_Error True when finished or WP_Error if there were errors during a plugin activation.
   706  */
   727  */
   722 
   743 
   723 	return true;
   744 	return true;
   724 }
   745 }
   725 
   746 
   726 /**
   747 /**
   727  * Remove directory and files of a plugin for a single or list of plugin(s).
   748  * Remove directory and files of a plugin for a list of plugins.
   728  *
       
   729  * If the plugins parameter list is empty, false will be returned. True when
       
   730  * completed.
       
   731  *
   749  *
   732  * @since 2.6.0
   750  * @since 2.6.0
   733  *
   751  *
   734  * @param array $plugins List of plugin
   752  * @param array  $plugins    List of plugins to delete.
   735  * @param string $redirect Redirect to page when complete.
   753  * @param string $deprecated Deprecated.
   736  * @return mixed
   754  * @return bool|null|WP_Error True on success, false is $plugins is empty, WP_Error on failure.
   737  */
   755  *                            Null if filesystem credentials are required to proceed.
   738 function delete_plugins($plugins, $redirect = '' ) {
   756  */
       
   757 function delete_plugins( $plugins, $deprecated = '' ) {
   739 	global $wp_filesystem;
   758 	global $wp_filesystem;
   740 
   759 
   741 	if ( empty($plugins) )
   760 	if ( empty($plugins) )
   742 		return false;
   761 		return false;
   743 
   762 
   776 		return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
   795 		return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
   777 
   796 
   778 	if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() )
   797 	if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() )
   779 		return new WP_Error('fs_error', __('Filesystem error.'), $wp_filesystem->errors);
   798 		return new WP_Error('fs_error', __('Filesystem error.'), $wp_filesystem->errors);
   780 
   799 
   781 	//Get the base plugin folder
   800 	// Get the base plugin folder.
   782 	$plugins_dir = $wp_filesystem->wp_plugins_dir();
   801 	$plugins_dir = $wp_filesystem->wp_plugins_dir();
   783 	if ( empty($plugins_dir) )
   802 	if ( empty( $plugins_dir ) ) {
   784 		return new WP_Error('fs_no_plugins_dir', __('Unable to locate WordPress Plugin directory.'));
   803 		return new WP_Error( 'fs_no_plugins_dir', __( 'Unable to locate WordPress Plugin directory.' ) );
       
   804 	}
   785 
   805 
   786 	$plugins_dir = trailingslashit( $plugins_dir );
   806 	$plugins_dir = trailingslashit( $plugins_dir );
   787 
   807 
       
   808 	$plugin_translations = wp_get_installed_translations( 'plugins' );
       
   809 
   788 	$errors = array();
   810 	$errors = array();
   789 
   811 
   790 	foreach( $plugins as $plugin_file ) {
   812 	foreach( $plugins as $plugin_file ) {
   791 		// Run Uninstall hook
   813 		// Run Uninstall hook.
   792 		if ( is_uninstallable_plugin( $plugin_file ) )
   814 		if ( is_uninstallable_plugin( $plugin_file ) ) {
   793 			uninstall_plugin($plugin_file);
   815 			uninstall_plugin($plugin_file);
   794 
   816 		}
   795 		$this_plugin_dir = trailingslashit( dirname($plugins_dir . $plugin_file) );
   817 
       
   818 		$this_plugin_dir = trailingslashit( dirname( $plugins_dir . $plugin_file ) );
   796 		// If plugin is in its own directory, recursively delete the directory.
   819 		// If plugin is in its own directory, recursively delete the directory.
   797 		if ( strpos($plugin_file, '/') && $this_plugin_dir != $plugins_dir ) //base check on if plugin includes directory separator AND that it's not the root plugin folder
   820 		if ( strpos( $plugin_file, '/' ) && $this_plugin_dir != $plugins_dir ) { //base check on if plugin includes directory separator AND that it's not the root plugin folder
   798 			$deleted = $wp_filesystem->delete($this_plugin_dir, true);
   821 			$deleted = $wp_filesystem->delete( $this_plugin_dir, true );
   799 		else
   822 		} else {
   800 			$deleted = $wp_filesystem->delete($plugins_dir . $plugin_file);
   823 			$deleted = $wp_filesystem->delete( $plugins_dir . $plugin_file );
   801 
   824 		}
   802 		if ( ! $deleted )
   825 
       
   826 		if ( ! $deleted ) {
   803 			$errors[] = $plugin_file;
   827 			$errors[] = $plugin_file;
       
   828 			continue;
       
   829 		}
       
   830 
       
   831 		// Remove language files, silently.
       
   832 		$plugin_slug = dirname( $plugin_file );
       
   833 		if ( '.' !== $plugin_slug && ! empty( $plugin_translations[ $plugin_slug ] ) ) {
       
   834 			$translations = $plugin_translations[ $plugin_slug ];
       
   835 
       
   836 			foreach ( $translations as $translation => $data ) {
       
   837 				$wp_filesystem->delete( WP_LANG_DIR . '/plugins/' . $plugin_slug . '-' . $translation . '.po' );
       
   838 				$wp_filesystem->delete( WP_LANG_DIR . '/plugins/' . $plugin_slug . '-' . $translation . '.mo' );
       
   839 			}
       
   840 		}
       
   841 	}
       
   842 
       
   843 	// Remove deleted plugins from the plugin updates list.
       
   844 	if ( $current = get_site_transient('update_plugins') ) {
       
   845 		// Don't remove the plugins that weren't deleted.
       
   846 		$deleted = array_diff( $plugins, $errors );
       
   847 
       
   848 		foreach ( $deleted as $plugin_file ) {
       
   849 			unset( $current->response[ $plugin_file ] );
       
   850 		}
       
   851 
       
   852 		set_site_transient( 'update_plugins', $current );
   804 	}
   853 	}
   805 
   854 
   806 	if ( ! empty($errors) )
   855 	if ( ! empty($errors) )
   807 		return new WP_Error('could_not_remove_plugin', sprintf(__('Could not fully remove the plugin(s) %s.'), implode(', ', $errors)) );
   856 		return new WP_Error('could_not_remove_plugin', sprintf(__('Could not fully remove the plugin(s) %s.'), implode(', ', $errors)) );
   808 
   857 
   809 	// Force refresh of plugin update information
       
   810 	if ( $current = get_site_transient('update_plugins') ) {
       
   811 		unset( $current->response[ $plugin_file ] );
       
   812 		set_site_transient('update_plugins', $current);
       
   813 	}
       
   814 
       
   815 	return true;
   858 	return true;
   816 }
   859 }
   817 
   860 
   818 /**
   861 /**
   819  * Validate active plugins
   862  * Validate active plugins
   824  * @since 2.5.0
   867  * @since 2.5.0
   825  * @return array invalid plugins, plugin as key, error as value
   868  * @return array invalid plugins, plugin as key, error as value
   826  */
   869  */
   827 function validate_active_plugins() {
   870 function validate_active_plugins() {
   828 	$plugins = get_option( 'active_plugins', array() );
   871 	$plugins = get_option( 'active_plugins', array() );
   829 	// validate vartype: array
   872 	// Validate vartype: array.
   830 	if ( ! is_array( $plugins ) ) {
   873 	if ( ! is_array( $plugins ) ) {
   831 		update_option( 'active_plugins', array() );
   874 		update_option( 'active_plugins', array() );
   832 		$plugins = array();
   875 		$plugins = array();
   833 	}
   876 	}
   834 
   877 
   835 	if ( is_multisite() && is_super_admin() ) {
   878 	if ( is_multisite() && current_user_can( 'manage_network_plugins' ) ) {
   836 		$network_plugins = (array) get_site_option( 'active_sitewide_plugins', array() );
   879 		$network_plugins = (array) get_site_option( 'active_sitewide_plugins', array() );
   837 		$plugins = array_merge( $plugins, array_keys( $network_plugins ) );
   880 		$plugins = array_merge( $plugins, array_keys( $network_plugins ) );
   838 	}
   881 	}
   839 
   882 
   840 	if ( empty( $plugins ) )
   883 	if ( empty( $plugins ) )
   841 		return;
   884 		return array();
   842 
   885 
   843 	$invalid = array();
   886 	$invalid = array();
   844 
   887 
   845 	// invalid plugins get deactivated
   888 	// Invalid plugins get deactivated.
   846 	foreach ( $plugins as $plugin ) {
   889 	foreach ( $plugins as $plugin ) {
   847 		$result = validate_plugin( $plugin );
   890 		$result = validate_plugin( $plugin );
   848 		if ( is_wp_error( $result ) ) {
   891 		if ( is_wp_error( $result ) ) {
   849 			$invalid[$plugin] = $result;
   892 			$invalid[$plugin] = $result;
   850 			deactivate_plugins( $plugin, true );
   893 			deactivate_plugins( $plugin, true );
   912 			update_option('uninstall_plugins', $uninstallable_plugins);
   955 			update_option('uninstall_plugins', $uninstallable_plugins);
   913 		}
   956 		}
   914 		unset($uninstallable_plugins);
   957 		unset($uninstallable_plugins);
   915 
   958 
   916 		define('WP_UNINSTALL_PLUGIN', $file);
   959 		define('WP_UNINSTALL_PLUGIN', $file);
   917 		include WP_PLUGIN_DIR . '/' . dirname($file) . '/uninstall.php';
   960 		wp_register_plugin_realpath( WP_PLUGIN_DIR . '/' . dirname( $file ) );
       
   961 		include( WP_PLUGIN_DIR . '/' . dirname($file) . '/uninstall.php' );
   918 
   962 
   919 		return true;
   963 		return true;
   920 	}
   964 	}
   921 
   965 
   922 	if ( isset( $uninstallable_plugins[$file] ) ) {
   966 	if ( isset( $uninstallable_plugins[$file] ) ) {
   923 		$callable = $uninstallable_plugins[$file];
   967 		$callable = $uninstallable_plugins[$file];
   924 		unset($uninstallable_plugins[$file]);
   968 		unset($uninstallable_plugins[$file]);
   925 		update_option('uninstall_plugins', $uninstallable_plugins);
   969 		update_option('uninstall_plugins', $uninstallable_plugins);
   926 		unset($uninstallable_plugins);
   970 		unset($uninstallable_plugins);
   927 
   971 
   928 		include WP_PLUGIN_DIR . '/' . $file;
   972 		wp_register_plugin_realpath( WP_PLUGIN_DIR . '/' . $file );
       
   973 		include( WP_PLUGIN_DIR . '/' . $file );
   929 
   974 
   930 		add_action( 'uninstall_' . $file, $callable );
   975 		add_action( 'uninstall_' . $file, $callable );
   931 
   976 
   932 		/**
   977 		/**
   933 		 * Fires in uninstall_plugin() once the plugin has been uninstalled.
   978 		 * Fires in uninstall_plugin() once the plugin has been uninstalled.
   957  * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
  1002  * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
   958  * @param string $menu_title The text to be used for the menu
  1003  * @param string $menu_title The text to be used for the menu
   959  * @param string $capability The capability required for this menu to be displayed to the user.
  1004  * @param string $capability The capability required for this menu to be displayed to the user.
   960  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1005  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
   961  * @param callback $function The function to be called to output the content for this page.
  1006  * @param callback $function The function to be called to output the content for this page.
   962  * @param string $icon_url The url to the icon to be used for this menu. Using 'none' would leave div.wp-menu-image empty
  1007  * @param string $icon_url The url to the icon to be used for this menu.
   963  *                         so an icon can be added as background with CSS.
  1008  *     * Pass a base64-encoded SVG using a data URI, which will be colored to match the color scheme.
       
  1009  *       This should begin with 'data:image/svg+xml;base64,'.
       
  1010  *     * Pass the name of a Dashicons helper class to use a font icon, e.g. 'dashicons-chart-pie'.
       
  1011  *     * Pass 'none' to leave div.wp-menu-image empty so an icon can be added via CSS.
   964  * @param int $position The position in the menu order this one should appear
  1012  * @param int $position The position in the menu order this one should appear
   965  *
  1013  *
   966  * @return string The resulting page's hook_suffix
  1014  * @return string The resulting page's hook_suffix
   967  */
  1015  */
   968 function add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $icon_url = '', $position = null ) {
  1016 function add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function = '', $icon_url = '', $position = null ) {
   976 
  1024 
   977 	if ( !empty( $function ) && !empty( $hookname ) && current_user_can( $capability ) )
  1025 	if ( !empty( $function ) && !empty( $hookname ) && current_user_can( $capability ) )
   978 		add_action( $hookname, $function );
  1026 		add_action( $hookname, $function );
   979 
  1027 
   980 	if ( empty($icon_url) ) {
  1028 	if ( empty($icon_url) ) {
   981 		$icon_url = 'none';
  1029 		$icon_url = 'dashicons-admin-generic';
   982 		$icon_class = 'menu-icon-generic ';
  1030 		$icon_class = 'menu-icon-generic ';
   983 	} else {
  1031 	} else {
   984 		$icon_url = set_url_scheme( $icon_url );
  1032 		$icon_url = set_url_scheme( $icon_url );
   985 		$icon_class = '';
  1033 		$icon_class = '';
   986 	}
  1034 	}
  1066  * @param string $menu_title The text to be used for the menu
  1114  * @param string $menu_title The text to be used for the menu
  1067  * @param string $capability The capability required for this menu to be displayed to the user.
  1115  * @param string $capability The capability required for this menu to be displayed to the user.
  1068  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1116  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1069  * @param callback $function The function to be called to output the content for this page.
  1117  * @param callback $function The function to be called to output the content for this page.
  1070  *
  1118  *
  1071  * @return string|bool The resulting page's hook_suffix, or false if the user does not have the capability required.
  1119  * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required.
  1072  */
  1120  */
  1073 function add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1121 function add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1074 	global $submenu;
  1122 	global $submenu;
  1075 	global $menu;
  1123 	global $menu;
  1076 	global $_wp_real_parent_file;
  1124 	global $_wp_real_parent_file;
  1087 	if ( !current_user_can( $capability ) ) {
  1135 	if ( !current_user_can( $capability ) ) {
  1088 		$_wp_submenu_nopriv[$parent_slug][$menu_slug] = true;
  1136 		$_wp_submenu_nopriv[$parent_slug][$menu_slug] = true;
  1089 		return false;
  1137 		return false;
  1090 	}
  1138 	}
  1091 
  1139 
  1092 	// If the parent doesn't already have a submenu, add a link to the parent
  1140 	/*
  1093 	// as the first item in the submenu. If the submenu file is the same as the
  1141 	 * If the parent doesn't already have a submenu, add a link to the parent
  1094 	// parent file someone is trying to link back to the parent manually. In
  1142 	 * as the first item in the submenu. If the submenu file is the same as the
  1095 	// this case, don't automatically add a link back to avoid duplication.
  1143 	 * parent file someone is trying to link back to the parent manually. In
       
  1144 	 * this case, don't automatically add a link back to avoid duplication.
       
  1145 	 */
  1096 	if (!isset( $submenu[$parent_slug] ) && $menu_slug != $parent_slug ) {
  1146 	if (!isset( $submenu[$parent_slug] ) && $menu_slug != $parent_slug ) {
  1097 		foreach ( (array)$menu as $parent_menu ) {
  1147 		foreach ( (array)$menu as $parent_menu ) {
  1098 			if ( $parent_menu[2] == $parent_slug && current_user_can( $parent_menu[1] ) )
  1148 			if ( $parent_menu[2] == $parent_slug && current_user_can( $parent_menu[1] ) )
  1099 				$submenu[$parent_slug][] = $parent_menu;
  1149 				$submenu[$parent_slug][] = array_slice( $parent_menu, 0, 4 );
  1100 		}
  1150 		}
  1101 	}
  1151 	}
  1102 
  1152 
  1103 	$submenu[$parent_slug][] = array ( $menu_title, $capability, $menu_slug, $page_title );
  1153 	$submenu[$parent_slug][] = array ( $menu_title, $capability, $menu_slug, $page_title );
  1104 
  1154 
  1105 	$hookname = get_plugin_page_hookname( $menu_slug, $parent_slug);
  1155 	$hookname = get_plugin_page_hookname( $menu_slug, $parent_slug);
  1106 	if (!empty ( $function ) && !empty ( $hookname ))
  1156 	if (!empty ( $function ) && !empty ( $hookname ))
  1107 		add_action( $hookname, $function );
  1157 		add_action( $hookname, $function );
  1108 
  1158 
  1109 	$_registered_pages[$hookname] = true;
  1159 	$_registered_pages[$hookname] = true;
  1110 	// backwards-compatibility for plugins using add_management page. See wp-admin/admin.php for redirect from edit.php to tools.php
  1160 
       
  1161 	/*
       
  1162 	 * Backward-compatibility for plugins using add_management page.
       
  1163 	 * See wp-admin/admin.php for redirect from edit.php to tools.php
       
  1164 	 */
  1111 	if ( 'tools.php' == $parent_slug )
  1165 	if ( 'tools.php' == $parent_slug )
  1112 		$_registered_pages[get_plugin_page_hookname( $menu_slug, 'edit.php')] = true;
  1166 		$_registered_pages[get_plugin_page_hookname( $menu_slug, 'edit.php')] = true;
  1113 
  1167 
  1114 	// No parent as top level
  1168 	// No parent as top level.
  1115 	$_parent_pages[$menu_slug] = $parent_slug;
  1169 	$_parent_pages[$menu_slug] = $parent_slug;
  1116 
  1170 
  1117 	return $hookname;
  1171 	return $hookname;
  1118 }
  1172 }
  1119 
  1173 
  1130  * @param string $menu_title The text to be used for the menu
  1184  * @param string $menu_title The text to be used for the menu
  1131  * @param string $capability The capability required for this menu to be displayed to the user.
  1185  * @param string $capability The capability required for this menu to be displayed to the user.
  1132  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1186  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1133  * @param callback $function The function to be called to output the content for this page.
  1187  * @param callback $function The function to be called to output the content for this page.
  1134  *
  1188  *
  1135  * @return string|bool The resulting page's hook_suffix, or false if the user does not have the capability required.
  1189  * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required.
  1136  */
  1190  */
  1137 function add_management_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1191 function add_management_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1138 	return add_submenu_page( 'tools.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1192 	return add_submenu_page( 'tools.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1139 }
  1193 }
  1140 
  1194 
  1151  * @param string $menu_title The text to be used for the menu
  1205  * @param string $menu_title The text to be used for the menu
  1152  * @param string $capability The capability required for this menu to be displayed to the user.
  1206  * @param string $capability The capability required for this menu to be displayed to the user.
  1153  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1207  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1154  * @param callback $function The function to be called to output the content for this page.
  1208  * @param callback $function The function to be called to output the content for this page.
  1155  *
  1209  *
  1156  * @return string|bool The resulting page's hook_suffix, or false if the user does not have the capability required.
  1210  * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required.
  1157  */
  1211  */
  1158 function add_options_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1212 function add_options_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1159 	return add_submenu_page( 'options-general.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1213 	return add_submenu_page( 'options-general.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1160 }
  1214 }
  1161 
  1215 
  1172  * @param string $menu_title The text to be used for the menu
  1226  * @param string $menu_title The text to be used for the menu
  1173  * @param string $capability The capability required for this menu to be displayed to the user.
  1227  * @param string $capability The capability required for this menu to be displayed to the user.
  1174  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1228  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1175  * @param callback $function The function to be called to output the content for this page.
  1229  * @param callback $function The function to be called to output the content for this page.
  1176  *
  1230  *
  1177  * @return string|bool The resulting page's hook_suffix, or false if the user does not have the capability required.
  1231  * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required.
  1178  */
  1232  */
  1179 function add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1233 function add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1180 	return add_submenu_page( 'themes.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1234 	return add_submenu_page( 'themes.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1181 }
  1235 }
  1182 
  1236 
  1193  * @param string $menu_title The text to be used for the menu
  1247  * @param string $menu_title The text to be used for the menu
  1194  * @param string $capability The capability required for this menu to be displayed to the user.
  1248  * @param string $capability The capability required for this menu to be displayed to the user.
  1195  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1249  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1196  * @param callback $function The function to be called to output the content for this page.
  1250  * @param callback $function The function to be called to output the content for this page.
  1197  *
  1251  *
  1198  * @return string|bool The resulting page's hook_suffix, or false if the user does not have the capability required.
  1252  * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required.
  1199  */
  1253  */
  1200 function add_plugins_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1254 function add_plugins_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1201 	return add_submenu_page( 'plugins.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1255 	return add_submenu_page( 'plugins.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1202 }
  1256 }
  1203 
  1257 
  1214  * @param string $menu_title The text to be used for the menu
  1268  * @param string $menu_title The text to be used for the menu
  1215  * @param string $capability The capability required for this menu to be displayed to the user.
  1269  * @param string $capability The capability required for this menu to be displayed to the user.
  1216  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1270  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1217  * @param callback $function The function to be called to output the content for this page.
  1271  * @param callback $function The function to be called to output the content for this page.
  1218  *
  1272  *
  1219  * @return string|bool The resulting page's hook_suffix, or false if the user does not have the capability required.
  1273  * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required.
  1220  */
  1274  */
  1221 function add_users_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1275 function add_users_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1222 	if ( current_user_can('edit_users') )
  1276 	if ( current_user_can('edit_users') )
  1223 		$parent = 'users.php';
  1277 		$parent = 'users.php';
  1224 	else
  1278 	else
  1238  * @param string $menu_title The text to be used for the menu
  1292  * @param string $menu_title The text to be used for the menu
  1239  * @param string $capability The capability required for this menu to be displayed to the user.
  1293  * @param string $capability The capability required for this menu to be displayed to the user.
  1240  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1294  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1241  * @param callback $function The function to be called to output the content for this page.
  1295  * @param callback $function The function to be called to output the content for this page.
  1242  *
  1296  *
  1243  * @return string|bool The resulting page's hook_suffix, or false if the user does not have the capability required.
  1297  * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required.
  1244  */
  1298  */
  1245 function add_dashboard_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1299 function add_dashboard_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1246 	return add_submenu_page( 'index.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1300 	return add_submenu_page( 'index.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1247 }
  1301 }
  1248 
  1302 
  1259  * @param string $menu_title The text to be used for the menu
  1313  * @param string $menu_title The text to be used for the menu
  1260  * @param string $capability The capability required for this menu to be displayed to the user.
  1314  * @param string $capability The capability required for this menu to be displayed to the user.
  1261  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1315  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1262  * @param callback $function The function to be called to output the content for this page.
  1316  * @param callback $function The function to be called to output the content for this page.
  1263  *
  1317  *
  1264  * @return string|bool The resulting page's hook_suffix, or false if the user does not have the capability required.
  1318  * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required.
  1265  */
  1319  */
  1266 function add_posts_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1320 function add_posts_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1267 	return add_submenu_page( 'edit.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1321 	return add_submenu_page( 'edit.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1268 }
  1322 }
  1269 
  1323 
  1280  * @param string $menu_title The text to be used for the menu
  1334  * @param string $menu_title The text to be used for the menu
  1281  * @param string $capability The capability required for this menu to be displayed to the user.
  1335  * @param string $capability The capability required for this menu to be displayed to the user.
  1282  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1336  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1283  * @param callback $function The function to be called to output the content for this page.
  1337  * @param callback $function The function to be called to output the content for this page.
  1284  *
  1338  *
  1285  * @return string|bool The resulting page's hook_suffix, or false if the user does not have the capability required.
  1339  * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required.
  1286  */
  1340  */
  1287 function add_media_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1341 function add_media_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1288 	return add_submenu_page( 'upload.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1342 	return add_submenu_page( 'upload.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1289 }
  1343 }
  1290 
  1344 
  1301  * @param string $menu_title The text to be used for the menu
  1355  * @param string $menu_title The text to be used for the menu
  1302  * @param string $capability The capability required for this menu to be displayed to the user.
  1356  * @param string $capability The capability required for this menu to be displayed to the user.
  1303  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1357  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1304  * @param callback $function The function to be called to output the content for this page.
  1358  * @param callback $function The function to be called to output the content for this page.
  1305  *
  1359  *
  1306  * @return string|bool The resulting page's hook_suffix, or false if the user does not have the capability required.
  1360  * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required.
  1307  */
  1361  */
  1308 function add_links_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1362 function add_links_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1309 	return add_submenu_page( 'link-manager.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1363 	return add_submenu_page( 'link-manager.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1310 }
  1364 }
  1311 
  1365 
  1322  * @param string $menu_title The text to be used for the menu
  1376  * @param string $menu_title The text to be used for the menu
  1323  * @param string $capability The capability required for this menu to be displayed to the user.
  1377  * @param string $capability The capability required for this menu to be displayed to the user.
  1324  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1378  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1325  * @param callback $function The function to be called to output the content for this page.
  1379  * @param callback $function The function to be called to output the content for this page.
  1326  *
  1380  *
  1327  * @return string|bool The resulting page's hook_suffix, or false if the user does not have the capability required.
  1381  * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required.
  1328 */
  1382 */
  1329 function add_pages_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1383 function add_pages_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1330 	return add_submenu_page( 'edit.php?post_type=page', $page_title, $menu_title, $capability, $menu_slug, $function );
  1384 	return add_submenu_page( 'edit.php?post_type=page', $page_title, $menu_title, $capability, $menu_slug, $function );
  1331 }
  1385 }
  1332 
  1386 
  1343  * @param string $menu_title The text to be used for the menu
  1397  * @param string $menu_title The text to be used for the menu
  1344  * @param string $capability The capability required for this menu to be displayed to the user.
  1398  * @param string $capability The capability required for this menu to be displayed to the user.
  1345  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1399  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1346  * @param callback $function The function to be called to output the content for this page.
  1400  * @param callback $function The function to be called to output the content for this page.
  1347  *
  1401  *
  1348  * @return string|bool The resulting page's hook_suffix, or false if the user does not have the capability required.
  1402  * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability required.
  1349 */
  1403 */
  1350 function add_comments_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1404 function add_comments_page( $page_title, $menu_title, $capability, $menu_slug, $function = '' ) {
  1351 	return add_submenu_page( 'edit-comments.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1405 	return add_submenu_page( 'edit-comments.php', $page_title, $menu_title, $capability, $menu_slug, $function );
  1352 }
  1406 }
  1353 
  1407 
  1400 /**
  1454 /**
  1401  * Get the url to access a particular menu page based on the slug it was registered with.
  1455  * Get the url to access a particular menu page based on the slug it was registered with.
  1402  *
  1456  *
  1403  * If the slug hasn't been registered properly no url will be returned
  1457  * If the slug hasn't been registered properly no url will be returned
  1404  *
  1458  *
  1405  * @since 3.0
  1459  * @since 3.0.0
  1406  *
  1460  *
  1407  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1461  * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu)
  1408  * @param bool $echo Whether or not to echo the url - default is true
  1462  * @param bool $echo Whether or not to echo the url - default is true
  1409  * @return string the url
  1463  * @return string the url
  1410  */
  1464  */
  1449 		if ( isset( $_wp_real_parent_file[$parent] ) )
  1503 		if ( isset( $_wp_real_parent_file[$parent] ) )
  1450 			$parent = $_wp_real_parent_file[$parent];
  1504 			$parent = $_wp_real_parent_file[$parent];
  1451 		return $parent;
  1505 		return $parent;
  1452 	}
  1506 	}
  1453 
  1507 
  1454 	/*
       
  1455 	if ( !empty ( $parent_file ) ) {
       
  1456 		if ( isset( $_wp_real_parent_file[$parent_file] ) )
       
  1457 			$parent_file = $_wp_real_parent_file[$parent_file];
       
  1458 
       
  1459 		return $parent_file;
       
  1460 	}
       
  1461 	*/
       
  1462 
       
  1463 	if ( $pagenow == 'admin.php' && isset( $plugin_page ) ) {
  1508 	if ( $pagenow == 'admin.php' && isset( $plugin_page ) ) {
  1464 		foreach ( (array)$menu as $parent_menu ) {
  1509 		foreach ( (array)$menu as $parent_menu ) {
  1465 			if ( $parent_menu[2] == $plugin_page ) {
  1510 			if ( $parent_menu[2] == $plugin_page ) {
  1466 				$parent_file = $plugin_page;
  1511 				$parent_file = $plugin_page;
  1467 				if ( isset( $_wp_real_parent_file[$parent_file] ) )
  1512 				if ( isset( $_wp_real_parent_file[$parent_file] ) )
  1492 				$parent_file = $parent;
  1537 				$parent_file = $parent;
  1493 				return $parent;
  1538 				return $parent;
  1494 			} elseif ( $submenu_array[2] == $pagenow && empty($typenow) && ( empty($parent_file) || false === strpos($parent_file, '?') ) ) {
  1539 			} elseif ( $submenu_array[2] == $pagenow && empty($typenow) && ( empty($parent_file) || false === strpos($parent_file, '?') ) ) {
  1495 				$parent_file = $parent;
  1540 				$parent_file = $parent;
  1496 				return $parent;
  1541 				return $parent;
  1497 			} else
  1542 			} elseif ( isset( $plugin_page ) && ($plugin_page == $submenu_array[2] ) ) {
  1498 				if ( isset( $plugin_page ) && ($plugin_page == $submenu_array[2] ) ) {
  1543 				$parent_file = $parent;
  1499 					$parent_file = $parent;
  1544 				return $parent;
  1500 					return $parent;
  1545 			}
  1501 				}
       
  1502 		}
  1546 		}
  1503 	}
  1547 	}
  1504 
  1548 
  1505 	if ( empty($parent_file) )
  1549 	if ( empty($parent_file) )
  1506 		$parent_file = '';
  1550 		$parent_file = '';
  1526 		foreach ( (array)$menu as $menu_array ) {
  1570 		foreach ( (array)$menu as $menu_array ) {
  1527 			if ( isset( $menu_array[3] ) ) {
  1571 			if ( isset( $menu_array[3] ) ) {
  1528 				if ( $menu_array[2] == $pagenow ) {
  1572 				if ( $menu_array[2] == $pagenow ) {
  1529 					$title = $menu_array[3];
  1573 					$title = $menu_array[3];
  1530 					return $menu_array[3];
  1574 					return $menu_array[3];
  1531 				} else
  1575 				} elseif ( isset( $plugin_page ) && ($plugin_page == $menu_array[2] ) && ($hook == $menu_array[3] ) ) {
  1532 					if ( isset( $plugin_page ) && ($plugin_page == $menu_array[2] ) && ($hook == $menu_array[3] ) ) {
  1576 					$title = $menu_array[3];
  1533 						$title = $menu_array[3];
  1577 					return $menu_array[3];
  1534 						return $menu_array[3];
  1578 				}
  1535 					}
       
  1536 			} else {
  1579 			} else {
  1537 				$title = $menu_array[0];
  1580 				$title = $menu_array[0];
  1538 				return $title;
  1581 				return $title;
  1539 			}
  1582 			}
  1540 		}
  1583 		}
  1597 
  1640 
  1598 	$parent = get_admin_page_parent( $parent_page );
  1641 	$parent = get_admin_page_parent( $parent_page );
  1599 
  1642 
  1600 	$page_type = 'admin';
  1643 	$page_type = 'admin';
  1601 	if ( empty ( $parent_page ) || 'admin.php' == $parent_page || isset( $admin_page_hooks[$plugin_page] ) ) {
  1644 	if ( empty ( $parent_page ) || 'admin.php' == $parent_page || isset( $admin_page_hooks[$plugin_page] ) ) {
  1602 		if ( isset( $admin_page_hooks[$plugin_page] ) )
  1645 		if ( isset( $admin_page_hooks[$plugin_page] ) ) {
  1603 			$page_type = 'toplevel';
  1646 			$page_type = 'toplevel';
  1604 		else
  1647 		} elseif ( isset( $admin_page_hooks[$parent] )) {
  1605 			if ( isset( $admin_page_hooks[$parent] ))
  1648 			$page_type = $admin_page_hooks[$parent];
  1606 				$page_type = $admin_page_hooks[$parent];
  1649 		}
  1607 	} else if ( isset( $admin_page_hooks[$parent] ) ) {
  1650 	} elseif ( isset( $admin_page_hooks[$parent] ) ) {
  1608 		$page_type = $admin_page_hooks[$parent];
  1651 		$page_type = $admin_page_hooks[$parent];
  1609 	}
  1652 	}
  1610 
  1653 
  1611 	$plugin_name = preg_replace( '!\.php!', '', $plugin_page );
  1654 	$plugin_name = preg_replace( '!\.php!', '', $plugin_page );
  1612 
  1655 
  1663 			if ( isset( $plugin_page ) && ( $submenu_array[2] == $plugin_page ) ) {
  1706 			if ( isset( $plugin_page ) && ( $submenu_array[2] == $plugin_page ) ) {
  1664 				if ( current_user_can( $submenu_array[1] ))
  1707 				if ( current_user_can( $submenu_array[1] ))
  1665 					return true;
  1708 					return true;
  1666 				else
  1709 				else
  1667 					return false;
  1710 					return false;
  1668 			} else if ( $submenu_array[2] == $pagenow ) {
  1711 			} elseif ( $submenu_array[2] == $pagenow ) {
  1669 				if ( current_user_can( $submenu_array[1] ))
  1712 				if ( current_user_can( $submenu_array[1] ))
  1670 					return true;
  1713 					return true;
  1671 				else
  1714 				else
  1672 					return false;
  1715 					return false;
  1673 			}
  1716 			}
  1694  * @since 2.7.0
  1737  * @since 2.7.0
  1695  *
  1738  *
  1696  * @param string $option_group A settings group name. Should correspond to a whitelisted option key name.
  1739  * @param string $option_group A settings group name. Should correspond to a whitelisted option key name.
  1697  * 	Default whitelisted option key names include "general," "discussion," and "reading," among others.
  1740  * 	Default whitelisted option key names include "general," "discussion," and "reading," among others.
  1698  * @param string $option_name The name of an option to sanitize and save.
  1741  * @param string $option_name The name of an option to sanitize and save.
  1699  * @param unknown_type $sanitize_callback A callback function that sanitizes the option's value.
  1742  * @param callable $sanitize_callback A callback function that sanitizes the option's value.
  1700  * @return unknown
       
  1701  */
  1743  */
  1702 function register_setting( $option_group, $option_name, $sanitize_callback = '' ) {
  1744 function register_setting( $option_group, $option_name, $sanitize_callback = '' ) {
  1703 	global $new_whitelist_options;
  1745 	global $new_whitelist_options;
  1704 
  1746 
  1705 	if ( 'misc' == $option_group ) {
  1747 	if ( 'misc' == $option_group ) {
  1720 /**
  1762 /**
  1721  * Unregister a setting
  1763  * Unregister a setting
  1722  *
  1764  *
  1723  * @since 2.7.0
  1765  * @since 2.7.0
  1724  *
  1766  *
  1725  * @param unknown_type $option_group
  1767  * @param string   $option_group
  1726  * @param unknown_type $option_name
  1768  * @param string   $option_name
  1727  * @param unknown_type $sanitize_callback
  1769  * @param callable $sanitize_callback
  1728  * @return unknown
       
  1729  */
  1770  */
  1730 function unregister_setting( $option_group, $option_name, $sanitize_callback = '' ) {
  1771 function unregister_setting( $option_group, $option_name, $sanitize_callback = '' ) {
  1731 	global $new_whitelist_options;
  1772 	global $new_whitelist_options;
  1732 
  1773 
  1733 	if ( 'misc' == $option_group ) {
  1774 	if ( 'misc' == $option_group ) {
  1750 /**
  1791 /**
  1751  * {@internal Missing Short Description}}
  1792  * {@internal Missing Short Description}}
  1752  *
  1793  *
  1753  * @since 2.7.0
  1794  * @since 2.7.0
  1754  *
  1795  *
  1755  * @param unknown_type $options
  1796  * @param array $options
  1756  * @return unknown
  1797  * @return array
  1757  */
  1798  */
  1758 function option_update_filter( $options ) {
  1799 function option_update_filter( $options ) {
  1759 	global $new_whitelist_options;
  1800 	global $new_whitelist_options;
  1760 
  1801 
  1761 	if ( is_array( $new_whitelist_options ) )
  1802 	if ( is_array( $new_whitelist_options ) )
  1768 /**
  1809 /**
  1769  * {@internal Missing Short Description}}
  1810  * {@internal Missing Short Description}}
  1770  *
  1811  *
  1771  * @since 2.7.0
  1812  * @since 2.7.0
  1772  *
  1813  *
  1773  * @param unknown_type $new_options
  1814  * @param array        $new_options
  1774  * @param unknown_type $options
  1815  * @param string|array $options
  1775  * @return unknown
  1816  * @return array
  1776  */
  1817  */
  1777 function add_option_whitelist( $new_options, $options = '' ) {
  1818 function add_option_whitelist( $new_options, $options = '' ) {
  1778 	if ( $options == '' )
  1819 	if ( $options == '' )
  1779 		global $whitelist_options;
  1820 		global $whitelist_options;
  1780 	else
  1821 	else
  1799 /**
  1840 /**
  1800  * {@internal Missing Short Description}}
  1841  * {@internal Missing Short Description}}
  1801  *
  1842  *
  1802  * @since 2.7.0
  1843  * @since 2.7.0
  1803  *
  1844  *
  1804  * @param unknown_type $del_options
  1845  * @param array        $del_options
  1805  * @param unknown_type $options
  1846  * @param string|array $options
  1806  * @return unknown
  1847  * @return array
  1807  */
  1848  */
  1808 function remove_option_whitelist( $del_options, $options = '' ) {
  1849 function remove_option_whitelist( $del_options, $options = '' ) {
  1809 	if ( $options == '' )
  1850 	if ( $options == '' )
  1810 		global $whitelist_options;
  1851 		global $whitelist_options;
  1811 	else
  1852 	else