plugin_basename, array($this, 'install')); //Initilizes l10n domain $this->local(); } function admin_url() { return admin_url('options-general.php?page=' .$this->identifier); } function init() { //Admin Options update hook if(isset($_POST[$this->unique_prefix . '_admin_options'])) { //Temporarily add update function on init if form has been submitted $this->opts_update(); } //Admin Options reset hook if(isset($_POST[$this->unique_prefix . '_admin_reset'])) { //Run the reset function on init if reset form has been submitted $this->opts_reset(); } //Admin Options export hook else if(isset($_POST[$this->unique_prefix . '_admin_export'])) { //Run the export function on init if export form has been submitted $this->opts_export(); } //Admin Options import hook else if(isset($_FILES[$this->unique_prefix . '_admin_import_file']) && !empty($_FILES[$this->unique_prefix . '_admin_import_file']['name'])) { //Run the import function on init if import form has been submitted $this->opts_import(); } //Add in the nice "settings" link to the plugins page add_filter('plugin_action_links', array($this, 'filter_plugin_actions'), 10, 2); //Register options register_setting($this->unique_prefix . '_options', $this->unique_prefix . '_options', ''); } /** * add_page * * Adds the adminpage the menue and the nice little settings link * */ function add_page() { //Add the submenu page to "settings" menu $hookname = add_submenu_page('options-general.php', __($this->full_name, $this->identifier), $this->short_name, $this->access_level, $this->identifier, array($this, 'admin_page')); // check capability of user to manage options (access control) if(current_user_can($this->access_level)) { //Register admin_head-$hookname callback add_action('admin_head-' . $hookname, array($this, 'admin_head')); //Register Help Output add_action('contextual_help', array($this, 'contextual_help'), 10, 2); } } /** * local * * Initilizes localization textdomain for translations (if applicable) * * Will conditionally load the textdomain for translations. This is here for * plugins that span multiple files and have localization in more than one file * * @return void */ function local() { global $l10n; // the global and the check might become obsolete in // further wordpress versions // @see https://core.trac.wordpress.org/ticket/10527 if(!isset($l10n[$this->identifier])) { load_plugin_textdomain($this->identifier, false, $this->identifier . '/languages'); } } /** * filter_plugin_actions * * Places in a link to the settings page in the plugins listing entry * * @param array $links An array of links that are output in the listing * @param string $file The file that is currently in processing * @return array Array of links that are output in the listing. */ function filter_plugin_actions($links, $file) { //Make sure we are adding only for the current plugin if($file == $this->plugin_basename) { //Add our link to the end of the array to better integrate into the WP 2.8 plugins page $links[] = '' . __('Settings') . ''; } return $links; } /** * uninstall * * This removes database settings upon deletion of the plugin from WordPress */ function uninstall() { //Remove the option array setting $this->delete_option($this->unique_prefix . '_options'); //Remove the version setting $this->delete_option($this->unique_prefix . '_version'); } /** * opts_update * * Function prototype to prevent errors */ function opts_update() { } /** * opts_export * * Exports a XML options document */ function opts_export() { //Do a nonce check, prevent malicious link/form problems check_admin_referer($this->unique_prefix . '_admin_import_export'); //Update our internal settings $this->opt = get_option($this->unique_prefix . '_options'); //Create a DOM document $dom = new DOMDocument('1.0', 'UTF-8'); //Adds in newlines and tabs to the output $dom->formatOutput = true; //We're not using a DTD therefore we need to specify it as a standalone document $dom->xmlStandalone = true; //Add an element called options $node = $dom->createElement('options'); $parnode = $dom->appendChild($node); //Add a child element named plugin $node = $dom->createElement('plugin'); $plugnode = $parnode->appendChild($node); //Add some attributes that identify the plugin and version for the options export $plugnode->setAttribute('name', $this->short_name); $plugnode->setAttribute('version', $this->version); //Change our headder to text/xml for direct save header('Cache-Control: public'); //The next two will cause good browsers to download instead of displaying the file header('Content-Description: File Transfer'); header('Content-disposition: attachemnt; filename=' . $this->unique_prefix . '_settings.xml'); header('Content-Type: text/xml'); //Loop through the options array foreach($this->opt as $key=>$option) { //Add a option tag under the options tag, store the option value $node = $dom->createElement('option', htmlentities($option, ENT_COMPAT, 'UTF-8')); $newnode = $plugnode->appendChild($node); //Change the tag's name to that of the stored option $newnode->setAttribute('name', $key); } //Prepair the XML for output $output = $dom->saveXML(); //Let the browser know how long the file is header('Content-Length: ' . strlen($output)); // binary length //Output the file echo $output; //Prevent WordPress from continuing on die(); } /** * opts_import * * Imports a XML options document */ function opts_import() { //Our quick and dirty error supressor function error($errno, $errstr, $eerfile, $errline) { return true; } //Do a nonce check, prevent malicious link/form problems check_admin_referer($this->unique_prefix . '_admin_import_export'); //Create a DOM document $dom = new DOMDocument('1.0', 'UTF-8'); //We want to catch errors ourselves set_error_handler('error'); //Load the user uploaded file, handle failure gracefully if($dom->load($_FILES[$this->unique_prefix . 'admin_import_file']['tmp_name'])) { //Have to use an xpath query otherwise we run into problems $xpath = new DOMXPath($dom); $option_sets = $xpath->query('plugin'); //Loop through all of the xpath query results foreach($option_sets as $options) { //We only want to import options for only this plugin if($options->getAttribute('name') === $this->short_name) { //Do a quick version check list($plug_major, $plug_minor, $plug_release) = explode('.', $this->version); list($major, $minor, $release) = explode('.', $options->getAttribute('version')); //We don't support using newer versioned option files in older releases if($plug_major == $major && $plug_minor >= $minor) { //Loop around all of the options foreach($options->getelementsByTagName('option') as $child) { //Place the option into the option array, DOMDocument decodes html entities for us $this->opt[$child->getAttribute('name')] = $child->nodeValue; } } } } //Commit the loaded options to the database $this->update_option($this->unique_prefix . '_options', $this->opt); //Everything was successful, let the user know $this->message['updated fade'][] = __('Settings successfully imported from the uploaded file.', $this->identifier); } else { //Throw an error since we could not load the file for various reasons $this->message['error'][] = __('Importing settings from file failed.', $this->identifier); } //Reset to the default error handler after we're done restore_error_handler(); //Output any messages that there may be add_action('admin_notices', array($this, 'message')); } /** * opts_reset * * Resets the database settings array to the default set in opt */ function opts_reset() { //Do a nonce check, prevent malicious link/form problems check_admin_referer($this->unique_prefix . '_admin_import_export'); //Only needs this one line, will load in the hard coded default option values $this->update_option($this->unique_prefix . '_options', $this->opt); //Reset successful, let the user know $this->message['updated fade'][] = __('Settings successfully reset to the default values.', $this->identifier); add_action('admin_notices', array($this, 'message')); } /** * contextual_help action hook function * * @param string $contextual_help * @param string $screen * @return string */ function contextual_help($contextual_help, $screen) { //Add contextual help on current screen, keep compatibility with 2.8, 2.9 and 3.0 if($screen->base == 'settings_page_' . $this->identifier || $screen == 'settings_page_' . $this->identifier) { $contextual_help = $this->_get_contextual_help(); $this->_has_contextual_help = true; } return $contextual_help; } /** * get contextual help * * @return string */ protected function _get_contextual_help() { $t = $this->_get_help_text(); $t = sprintf('
', $t); $title = __($this->full_name, $this->identifier); $t = sprintf('%s