Content of themetoolkit.php from minimalissimplistic.zip

without / with line numbers
  1. <?php
    
  2. /*
    
  3. Hack Name: WordPress Theme Toolkit
    
  4. Hack URI: http://planetozh.com/blog/my-projects/wordpress-theme-toolkit-admin-menu/
    
  5. What is does: Helps theme authors set up an admin menu. Helps theme users customise the theme.
    
  6. Version: 1.2
    
  7. Author: Ozh
    
  8. Author URI: http://planetOzh.com/
    
  9. */
    
  10. 
    
  11. /************************************************************************************
    
  12. *                             DO NOT MODIFY THIS FILE !
    
  13. ************************************************************************************/
    
  14. 
    
  15. /* RELEASE HISTORY :
    
  16. * 1.0 : initial release
    
  17. * 1.1 : update for WordPress 2.0 compatibility
    
  18. * 1.11 : added {separator} template
    
  19. * 1.12 : more or less minor bug fixing (one when no plugin activated, other with rare mod_security issue) and better compliancy with WP 2.0 roles
    
  20. * 1.2 : check for WordPress 2.3, a few improvements & typos, better error handling, improved security, added 'select', added localization
    
  21. */
    
  22. 
    
  23. if (!function_exists('themetoolkit')) {
    
  24.     function themetoolkit($theme='',$array='',$file='') {
    
  25.         global ${$theme};
    
  26.         if ($theme == '' or $array == '' or $file == '') {
    
  27.             die ($this->__('No theme name, theme option, or parent defined in Theme Toolkit'));
    
  28.         }
    
  29.         ${$theme} = new ThemeToolkit($theme,$array,$file);
    
  30.     }
    
  31. }
    
  32. 
    
  33. if (!class_exists('ThemeToolkit')) {
    
  34.     class ThemeToolkit{
    
  35. 
    
  36.         var $option, $infos;
    
  37. 
    
  38.         function ThemeToolkit($theme,$array,$file){
    
  39.             
    
  40.             global $wp_version;
    
  41.             // is it WP 2.0+ and do we have plugins like "../themes/foo/functions.php" running ?
    
  42.             if ( $wp_version >= 2 and count(@preg_grep('#^\.\./themes/[^/]+/functions.php$#', get_settings('active_plugins'))) > 0 ) {
    
  43.                 wp_cache_flush();
    
  44.                 $this->upgrade_toolkit();
    
  45.             }
    
  46.             
    
  47.             $this->infos['path'] = '../themes/' . basename(dirname($file));
    
  48.             load_plugin_textdomain('themetoolkit', 'wp-content/themes/'.basename(dirname($file)));
    
  49.             // I use load_plugin_textdomain() and not load_theme_domain() to be able to specify a filename, ie themetoolkit-{locale}.mo
    
  50. 
    
  51.             /* Create some vars needed if an admin menu is to be printed */
    
  52.             if ($array['debug']) {
    
  53.                 if ((basename($file)) == $_GET['page']) $this->infos['debug'] = 1;
    
  54.                 unset($array['debug']);
    
  55.             }
    
  56.             if ((basename($file)) == $_GET['page']){
    
  57.                 $this->infos['menu_options'] = $array;
    
  58.                 $this->infos['classname'] = $theme;
    
  59.             }
    
  60.             $this->option=array();
    
  61. 
    
  62.             /* Check this file is registered as a plugin, do it if needed */
    
  63.             $this->pluginification();
    
  64. 
    
  65.             /* Get infos about the theme and particularly its 'shortname'
    
  66.              * which is used to name the entry in wp_options where data are stored */
    
  67.             $this->do_init();
    
  68. 
    
  69.             /* Read data from options table */
    
  70.             $this->read_options();
    
  71. 
    
  72.             /* Nonce wrapper for old WP versions */
    
  73.             if ( !function_exists('wp_nonce_field') ) {
    
  74.                 $this->nonce = -1;
    
  75.             } else {
    
  76.                 $this->nonce = 'theme-toolkit';
    
  77.             }
    
  78.             add_action('explain_nonce_theme-toolkit', array(&$this,'nonce_explain'));
    
  79. 
    
  80.             /* Are we in the admin area ? Add a menu then ! */
    
  81.             $this->file = $file;
    
  82.             add_action('admin_menu', array(&$this, 'add_menu'));
    
  83.             
    
  84. 
    
  85.         }
    
  86. 
    
  87.         /* Nonce confirmation */
    
  88.         function nonce_explain() {
    
  89.             return( sprintf($this->__('You are about to modify your preferences or settings for your theme "%s". Are you sure you want to do this ?'), $this->infos['theme_name']) );
    
  90.         }
    
  91. 
    
  92.         /* Nonce wrapper function, for older WP compatibility */
    
  93.         function nonce_field($action = -1) {
    
  94.             if ( !function_exists('wp_nonce_field') ) {
    
  95.                 return;
    
  96.             } else {
    
  97.                 return wp_nonce_field($action);
    
  98.             }
    
  99.         }
    
  100.         
    
  101.         /* Wrappers for translating functions */
    
  102.         function __($string) {
    
  103.             return __($string, 'themetoolkit');
    
  104.         }
    
  105. 
    
  106.         /* Add an entry to the admin menu area */
    
  107.         function add_menu() {
    
  108.             global $wp_version;
    
  109.             if ( $wp_version >= 2 ) {
    
  110.                 $level = 'edit_themes';
    
  111.             } else {
    
  112.                 $level = 9;
    
  113.             }
    
  114.             add_theme_page(sprintf($this->__('Configure %s') , $this->infos['theme_name']), $this->__($this->infos['theme_name']), 'edit_themes', basename($this->file), array(&$this,'admin_menu'));
    
  115.             /* Thank you MCincubus for the array($this,'admin_menu') bit */
    
  116.         }
    
  117. 
    
  118.         /* Get infos about this theme */
    
  119.         function do_init() {
    
  120.             $themes = get_themes();
    
  121.             $shouldbe= basename($this->infos['path']);
    
  122.             foreach ($themes as $theme) {
    
  123.                 $current= basename($theme['Template Dir']);
    
  124.                 if ($current == $shouldbe) {
    
  125.                     if (get_settings('template') == $current) {
    
  126.                         $this->infos['active'] = TRUE;
    
  127.                     } else {
    
  128.                         $this->infos['active'] = FALSE;
    
  129.                     }
    
  130.                 $this->infos['theme_name'] = $theme['Name'];
    
  131.                 $this->infos['theme_shortname'] = $current;
    
  132.                 $this->infos['theme_site'] = $theme['Title'];
    
  133.                 $this->infos['theme_version'] = $theme['Version'];
    
  134.                 $this->infos['theme_author'] = preg_replace("#>\s*([^<]*)</a>#", ">\\1</a>", $theme['Author']);
    
  135.                 }
    
  136.             }
    
  137.         }
    
  138. 
    
  139.         /* Read theme options as defined by user and populate the array $this->option */
    
  140.         function read_options() {
    
  141.             $options = get_option('theme-'.$this->infos['theme_shortname'].'-options');
    
  142.             $options['_________junk-entry________'] = 'ozh is my god';
    
  143.             foreach ($options as $key=>$val) {
    
  144.                 $this->option["$key"] = stripslashes($val);
    
  145.             }
    
  146.             array_pop($this->option);
    
  147.             return $this->option;
    
  148.             /* Curious about this "junk-entry" ? :) A few explanations then.
    
  149.              * The problem is that get_option always return an array, even if
    
  150.              * no settings has been previously saved in table wp_options. This
    
  151.              * junk entry is here to populate the array with at least one value,
    
  152.              * removed afterwards, so that the foreach loop doesn't go moo. */
    
  153.         }
    
  154.         
    
  155.         /* Prepare options for display */
    
  156.         function sanitize_options() {
    
  157.             foreach($this->option as $key=>$val) {
    
  158.                 $this->option["$key"] = $this->sanitize($val);
    
  159.             }
    
  160.         }
    
  161. 
    
  162.         /* Write theme options as defined by user in database */
    
  163.         function store_options($array) {
    
  164.             // Remove nonce informations before storing
    
  165.             if (isset($array['_wpnonce'])) unset($array['_wpnonce']);
    
  166.             if (isset($array['_wp_http_referer'])) unset($array['_wp_http_referer']);
    
  167.             
    
  168.             update_option('theme-'.$this->infos['theme_shortname'].'-options','');
    
  169.             if (update_option('theme-'.$this->infos['theme_shortname'].'-options',$array)) {
    
  170.                 return $this->__('Options successfully stored');
    
  171.             } else {
    
  172.                 return $this->__('Could not save options !');
    
  173.             }
    
  174.         }
    
  175. 
    
  176.         /* Delete options from database */
    
  177.         function delete_options() {
    
  178.             /* Remove entry from database */
    
  179.             delete_option('theme-'.$this->infos['theme_shortname'].'-options');
    
  180.             /* Unregister this file as a plugin (therefore remove the admin menu) */
    
  181.             $this->depluginification();
    
  182.             /* Revert theme back to default theme if this theme was activated */
    
  183.             if ($this->infos['active']) {
    
  184.                 update_option('template', 'default');
    
  185.                 update_option('stylesheet', 'default');
    
  186.                 do_action('switch_theme', 'Default');
    
  187.             }
    
  188.             /* Go back to Theme admin */
    
  189.             print '<meta http-equiv="refresh" content="0;URL=themes.php?activated=true">';
    
  190.             echo "<script> self.location(\"themes.php?activated=true\");</script>";
    
  191.             exit;
    
  192.         }
    
  193. 
    
  194.         /* Check if the theme has been loaded at least once (so that this file has been registered as a plugin) */
    
  195.         function is_installed() {
    
  196.             global $wpdb;
    
  197.             $where = 'theme-'.$this->infos['theme_shortname'].'-options';
    
  198.             $check = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->options WHERE option_name = '$where'");
    
  199.             if ($check == 0) {
    
  200.                 return FALSE;
    
  201.             } else {
    
  202.                 return TRUE;
    
  203.             }
    
  204.         }
    
  205. 
    
  206.         /* Theme used for the first time (create blank entry in database) */
    
  207.         function do_firstinit() {
    
  208.             global $wpdb;
    
  209.             $options = array();
    
  210.             foreach(array_keys($this->option) as $key) {
    
  211.                 $options["$key"]='';
    
  212.             }
    
  213.             add_option('theme-'.$this->infos['theme_shortname'].'-options',$options, 'Options for theme '.$this->infos['theme_name']);
    
  214.             $this->firstinit = true;
    
  215.             return sprintf($this->__('Theme options added in database (1 entry in table "%s"'), $wpdb->options);
    
  216.         }
    
  217. 
    
  218.         /* The mother of them all : the Admin Menu printing func */
    
  219.         function admin_menu () {
    
  220.             global $cache_settings, $wpdb;
    
  221.             
    
  222.             /* Process things when things are to be processed */
    
  223.             if (@$_POST['action']) {
    
  224.                 check_admin_referer($this->nonce);
    
  225.                 if (@$_POST['action'] == 'store_option') {
    
  226.                     unset($_POST['action']);
    
  227.                     $msg = $this->store_options($_POST);
    
  228.                 } elseif (@$_POST['action'] == 'delete_options') {
    
  229.                     $this->delete_options();
    
  230.                 }
    
  231.             } elseif (!$this->is_installed()) {
    
  232.                 $msg = $this->do_firstinit();
    
  233.             }
    
  234.             
    
  235.             // ze debug print_r
    
  236.             // echo "<pre>";print_r($this);echo "</pre>";
    
  237. 
    
  238.             if (@$msg) print "<div class='updated'><p><b>" . $msg . "</b></p></div>\n";
    
  239. 
    
  240.             echo '<div class="wrap">';
    
  241.             if ($this->firstinit) {
    
  242.                 echo '<h2>'.$this->__('Thank you !').'</h2>';
    
  243.                 echo '<p>';
    
  244.                 printf($this->__('Thank you for installing "%s", a theme for WordPress.'),  $this->infos['theme_site'] ); 
    
  245.                 printf($this->__('This theme was made by %s'), $this->infos['theme_author']);
    
  246.                 echo "</p>\n";
    
  247. 
    
  248.                 if (!$this->infos['active']) { /* theme is not active */
    
  249.                     echo '<p>('.$this->__('Please note that this theme is currently <strong>not activated</strong> on your site as the default theme.').'</p>';
    
  250.                 }
    
  251.             }
    
  252. 
    
  253.             $cache_settings = '';
    
  254.             $check = $this->read_options();
    
  255.             $this->sanitize_options();
    
  256.             
    
  257.             echo '<h2>'.$this->__('Configure').' <em>'.$this->__($this->infos['theme_name']).'</em> </h2>';
    
  258.             echo '<p>'.$this->__('This theme allows you to configure some variables to suit your blog, which are :').'</p>
    
  259.             <form action="" name="ttkform" id="ttkform" method="post">';
    
  260.             echo '
    
  261.             <table cellspacing="2" cellpadding="5" border="0" width=100% class="editform">';
    
  262. 
    
  263.             /* Print form, here comes the fun part :) */
    
  264.             
    
  265.             $firstelement = '';        
    
  266.             foreach ($this->infos['menu_options'] as $key=>$val) {
    
  267.                 if (!$firstelement) $firstelement = $key;
    
  268.                 $items='';
    
  269.                 preg_match('/\s*([^{#]*)\s*({([^}]*)})*\s*([#]*\s*(.*))/', $val, $matches);
    
  270.                 if ($matches[3]) {
    
  271.                     $items = split("\|", $matches[3]);
    
  272.                 }
    
  273. 
    
  274.             echo "<tr valign='top'><th scope='row' width='33%'>\n";
    
  275.                 if (@$items) {
    
  276.                     $type = array_shift($items);
    
  277.                     switch ($type) {
    
  278.                     
    
  279.                     case 'text':
    
  280.                         $s = array_shift($items);
    
  281.                         $m = array_shift($items);
    
  282.                         echo "<label for='$key'>".$this->__($matches[1])."</label></th>\n<td>";
    
  283.                         echo "<input type='text' name='$key' id='$key' size='$s' maxlength='$m' value='" . $this->option[$key] . "' />";
    
  284.                         break;
    
  285.                     
    
  286.                     case 'separator':
    
  287.                         echo '<h3>'.$this->__($matches[1])."</h3></th>\n<td>&nbsp;</td>";
    
  288.                         break;
    
  289. 
    
  290.                     case 'select':
    
  291.                     case 'dropdown':
    
  292.                         echo $this->__($matches[1])."</th>\n<td>";
    
  293.                         echo "<select id='${key}' name='${key}'>";
    
  294.                         while ($items) {
    
  295.                             $v=array_shift($items);
    
  296.                             $t=array_shift($items);
    
  297.                             $selected='';
    
  298.                             if ($v == $this->option[$key]) $selected=' selected';
    
  299.                             echo "<option value='$v' $selected>".$this->__($t)."</option>\n";
    
  300.                         }
    
  301.                         echo "</select>\n";
    
  302.                         break;
    
  303. 
    
  304.                     case 'radio':
    
  305.                         echo $this->__($matches[1])."</th>\n<td>";
    
  306.                         while ($items) {
    
  307.                             $v=array_shift($items);
    
  308.                             $t=array_shift($items);
    
  309.                             $checked='';
    
  310.                             if ($v == $this->option[$key]) $checked='checked';
    
  311.                             echo "<label for='${key}${v}'><input type='radio' id='${key}${v}' name='$key' value='$v' $checked />".$this->__($t).'</label>';
    
  312.                             if (@$items) echo "<br />\n";
    
  313.                         }
    
  314.                         break;
    
  315. 
    
  316.                     case 'textarea':
    
  317.                         $rows=array_shift($items);
    
  318.                         $cols=array_shift($items);
    
  319.                         echo "<label for='$key'>".$this->__($matches[1])."</label></th>\n<td>";
    
  320.                         echo "<textarea name='$key' id='$key' rows='$rows' cols='$cols'>" . $this->option[$key] . "</textarea>";
    
  321.                         break;
    
  322. 
    
  323.                     case 'checkbox':
    
  324.                         echo $this->__($matches[1])."</th>\n<td>";
    
  325.                         while ($items) {
    
  326.                             $k=array_shift($items);
    
  327.                             $v=array_shift($items);
    
  328.                             $t=array_shift($items);
    
  329.                             $checked='';
    
  330.                             if ($v == $this->option[$k]) $checked='checked';
    
  331.                             echo "<label for='${k}${v}'><input type='checkbox' id='${k}${v}' name='$k' value='$v' $checked />".$this->__( $t).'</label>';
    
  332.                             if (@$items) echo "<br />\n";
    
  333.                         }
    
  334.                         break;
    
  335.                     
    
  336.                     default:
    
  337.                         echo '<span style="color:red">'.$this->__('Unrecognized token').'</span></th><td class="updated"> '.$matches[2];
    
  338.                         break;
    
  339.                     }
    
  340.                 } else {
    
  341.                     // default to plain input text field
    
  342.                     echo "<label for='$key'>".$this->__($matches[1])."</label></th>\n<td>";
    
  343.                     echo "<input type='text' name='$key' id='$key' value='" . $this->option[$key] . "' />";
    
  344.                 }
    
  345. 
    
  346.                 if ($matches[5]) echo '<br/>'. $this->__($matches[5]);
    
  347.                 echo "</td></tr>\n";
    
  348.             }
    
  349.             echo '</table>
    
  350.             <p class="submit"><input type="submit" value="'.$this->__('Store Options').' &raquo;" /></p>';
    
  351.             $this->nonce_field($this->nonce);
    
  352.             echo '
    
  353.             <input type="hidden" name="action" value="store_option">
    
  354.             </form>';
    
  355. 
    
  356.             if ($this->infos['debug'] and $this->option) {
    
  357.                 $g = '<span style="color:#006600">';
    
  358.                 $b = '<span style="color:#0000CC">';
    
  359.                 $o = '<span style="color:#FF9900">';
    
  360.                 $r = '<span style="color:#CC0000">';
    
  361.                 echo '<h2>'.$this->__("Programmer's corner").'</h2>';
    
  362.                 echo '<p>'.sprintf($this->__('The array <em>$%s->option</em> is actually populated with the following keys and values'),$this->infos['classname']).' :</p>
    
  363.                 <p><pre class="updated">';
    
  364.                 $count = 0;
    
  365.                 foreach ($this->option as $key=>$val) {
    
  366.                     $val=str_replace('<','&lt;',$val);
    
  367.                     if ($val) {
    
  368.                         print '<span class="ttkline">'.$g.'$'.$this->infos['classname'].'</span>'.$b.'-></span>'.$g.'option</span>'.$b.'[</span>'.$g.'\'</span>'.$r.$key.'</span>'.$g.'\'</span>'.$b.']</span>'.$g.' = "</span>'. $o.$val.'</span>'.$g."\"</span></span>\n";
    
  369.                         $count++;
    
  370.                     }
    
  371.                 }
    
  372.                 if (!$count) print "\n\n";
    
  373.                 echo '</pre><p>'.$this->__('To disable this report (for example before packaging your theme and making it available for download), remove the line "&nbsp;<em>\'debug\' => \'debug\'</em>&nbsp;" in the array you edited at the beginning of this file.').'</p>';
    
  374.             }
    
  375. 
    
  376.             echo '<h2>'.$this->__('Delete Theme options').'</h2>
    
  377.             <p>'.sprintf($this->__('To completely remove these theme options from your database (reminder: they are all stored in a single entry, in WordPress options table <em>%s</em>), click on the following button. You will be then redirected to the <a href="themes.php">Themes admin interface</a>'), $wpdb->options);
    
  378.             if ($this->infos['active']) {
    
  379.                 echo ' '.$this->__('and the Default theme will have been activated');
    
  380.             }
    
  381.             echo '.</p>';
    
  382.             echo '<p>'.$this->__('<strong>Special notice for people allowing their readers to change theme</strong> (i.e. using a Theme Switcher on their blog)');
    
  383.             echo '<br/>';
    
  384.             echo $this->__('Unless you really remove the theme files from your server, this theme will still be available to users, and therefore will self-install again as soon as someone selects it.').' ';
    
  385.             echo $this->__('Also, all custom variables as defined in the above menu will be blank, this could lead to unexpected behaviour.').' ';
    
  386.             echo $this->__('Press "Delete" only if you intend to remove the theme files right after this.').'</p>
    
  387.             <form action="" method="post">';
    
  388.             $this->nonce_field($this->nonce);
    
  389.             echo '
    
  390.             <input type="hidden" name="action" value="delete_options">
    
  391.             <p class="submit"><input type="submit" value="'.$this->__('Delete Options').' &raquo;" onclick="return confirm(\''.$this->__('Are you really sure you want to delete ?').'\');"/></p>
    
  392.             </form>';
    
  393.             
    
  394.             // Little javascript bit to set focus on first element, if applicable
    
  395.             echo "
    
  396.             <script type='text/javascript'>
    
  397.             if (document.getElementById('$firstelement')) {
    
  398.                 document.getElementById('$firstelement').focus();
    
  399.             }
    
  400.             </script>";
    
  401.             
    
  402.             echo '<h2>'.$this->__('Credits').'</h2>';
    
  403.             echo '<p>'.sprintf($this->__('%s has been created by %s'),$this->infos['theme_site'],$this->infos['theme_author']).'. ';
    
  404.             printf($this->__('This administration menu uses <a href="%s">WordPress Theme Toolkit</a> by %s.'),'http://planetozh.com/blog/my-projects/wordpress-theme-toolkit-admin-menu/','<a href="http://planetozh.com/" title="planetOzh">Ozh</a>');
    
  405.             echo '</p>
    
  406.             </div>';
    
  407.         }
    
  408. 
    
  409.         /***************************************
    
  410.          * Self-Pluginification
    
  411.          *
    
  412.          * Prior to WP 2.0 this files registers
    
  413.          * itself as a plugin. Ow, that's smart.
    
  414.          **************************************/
    
  415.         function pluginification () {
    
  416.             global $wp_version;
    
  417.             if ($wp_version<2) {        
    
  418.                 $us = $this->infos['path'].'/functions.php';
    
  419.                 $them = get_settings('active_plugins');
    
  420.                 /* Now, are we members of the PPC (Plugins Private Club) yet ? */
    
  421.                 if (!in_array($us,$them)) {
    
  422.                     /* No ? Jeez, claim member card ! */
    
  423.                     $them[]=$us;
    
  424.                     update_option('active_plugins',$them); 
    
  425.                     /* Wow. We're l33t now. */ 
    
  426.                     return TRUE; 
    
  427.                 } else { 
    
  428.                     return FALSE; 
    
  429.                 } 
    
  430.             }
    
  431.         } 
    
  432.          
    
  433.         /*************************************** 
    
  434.          * De-Pluginification
    
  435.          **************************************/ 
    
  436.         function depluginification () {
    
  437.             global $wp_version;
    
  438.             if ($wp_version<2) {
    
  439.                 $us = $this->infos['path'].'/functions.php';
    
  440.                 $them = get_settings('active_plugins');
    
  441.                 if (in_array($us,$them)) {
    
  442.                     $here = array_search($us,$them);
    
  443.                     unset($them[$here]);
    
  444.                     update_option('active_plugins',$them);
    
  445.                     return TRUE;
    
  446.                 } else {
    
  447.                     return FALSE;
    
  448.                 }
    
  449.             }
    
  450.         }
    
  451.         
    
  452.         /* attribute_escape() compatibility for older installs */
    
  453.         function sanitize($text) {
    
  454.             if (function_exists('attribute_escape')) {
    
  455.                 return attribute_escape($text);
    
  456.             } else {
    
  457.                 // All this taken from wp_specialchars()
    
  458.                 $text = str_replace('&&', '&#038;&', $text);
    
  459.                 $text = str_replace('&&', '&#038;&', $text);
    
  460.                 $text = preg_replace('/&(?:$|([^#])(?![a-z1-4]{1,8};))/', '&#038;$1', $text);
    
  461.                 $text = str_replace('<', '&lt;', $text);
    
  462.                 $text = str_replace('>', '&gt;', $text);
    
  463.                 $text = str_replace('"', '&quot;', $text);
    
  464.                 $text = str_replace("'", '&#039;', $text);
    
  465.                 return $text;
    
  466.             }            
    
  467.         }
    
  468. 
    
  469.         /* Clean plugins lists in order to work with WordPress 2.0 */
    
  470.         function upgrade_toolkit () {
    
  471.             $plugins=get_settings('active_plugins');
    
  472.             $delete=@preg_grep('#^\.\./themes/[^/]+/functions.php$#', $plugins);
    
  473.             $result=array_diff($plugins,$delete);
    
  474.             $temp = array();
    
  475.             foreach($result as $item) $temp[]=$item;
    
  476.             $result = $temp;
    
  477.             update_option('active_plugins',$result);
    
  478.             wp_cache_flush;
    
  479.         }
    
  480.     }
    
  481. }
    
  482. 
    
  483. /***** Pretend we're a plugin to abuse WordPress updater *****/
    
  484. 
    
  485. /*
    
  486. Plugin Name: WordPress Theme Toolkit
    
  487. Plugin URI: http://planetozh.com/blog/my-projects/wordpress-theme-toolkit-admin-menu/
    
  488. Description: <strong>This is not a plugin</strong>, do not put in <code>/wp-content/plugins/</code>, do not activate!</span>
    
  489. */
    
  490. 
    
  491. 
    
  492. 
    
  493. ?>
  494.  

Return to listing of minimalissimplistic.zip