web/wp-content/plugins/ajax-calendar/plugin.php
changeset 136 bde1974c263b
equal deleted inserted replaced
135:53cff4b4a802 136:bde1974c263b
       
     1 <?php
       
     2 
       
     3 // ======================================================================================
       
     4 // This library is free software; you can redistribute it and/or
       
     5 // modify it under the terms of the GNU Lesser General Public
       
     6 // License as published by the Free Software Foundation; either
       
     7 // version 2.1 of the License, or (at your option) any later version.
       
     8 //
       
     9 // This library is distributed in the hope that it will be useful,
       
    10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    12 // Lesser General Public License for more details.
       
    13 // ======================================================================================
       
    14 // @author     John Godley (http://urbangiraffe.com)
       
    15 // @version    0.1.25
       
    16 // @copyright  Copyright &copy; 2007 John Godley, All Rights Reserved
       
    17 // ======================================================================================
       
    18 // 0.1.6  - Corrected WP locale functions
       
    19 // 0.1.7  - Add phpdoc comments
       
    20 // 0.1.8  - Support for Admin SSL
       
    21 // 0.1.9  - URL encoding, defer localization until init
       
    22 // 0.1.10 - Better URL encoding
       
    23 // 0.1.11 - Make work in WP 2.0, fix HTTPS issue on IIS
       
    24 // 0.1.12 - Activation/deactivation actions that take into account the directory
       
    25 // 0.1.13 - Add realpath function
       
    26 // 0.1.14 - Add select/checked functions, fix locale loader
       
    27 // 0.1.15 - Remove dependency on prototype
       
    28 // 0.1.16 - Add support for homedir in realpath
       
    29 // 0.1.17 - Added widget class
       
    30 // 0.1.18 - Expand checked function
       
    31 // 0.1.19 - Make url() cope with sites with no trailing slash
       
    32 // 0.1.20 - Change init function to prevent overloading
       
    33 // 0.1.21 - Make widget work for WP 2.1
       
    34 // 0.1.22 - Make select work with option groups, RSS compatability fix
       
    35 // 0.1.23 - Make widget count work better, fix widgets in K2
       
    36 // 0.1.24 - Make realpath better
       
    37 // 0.1.25 - Add description to widget class
       
    38 // ======================================================================================
       
    39 
       
    40 
       
    41 /**
       
    42  * Wraps up several useful functions for WordPress plugins and provides a method to separate
       
    43  * display HTML from PHP code.
       
    44  *
       
    45  * <h4>Display Rendering</h4>
       
    46  * The class uses a similar technique to Ruby On Rails views, whereby the display HTML is kept
       
    47  * in a separate directory and file from the main code.  A display is 'rendered' (sent to the browser)
       
    48  * or 'captured' (returned to the calling function).
       
    49  *
       
    50  * Template files are separated into two areas: admin and user.  Admin templates are only for display in
       
    51  * the WordPress admin interface, while user templates are typically for display on the site (although neither
       
    52  * of these are enforced).  All templates are PHP code, but are referred to without .php extension.
       
    53  *
       
    54  * The reason for this separation is that one golden rule of plugin creation is that someone will always want to change
       
    55  * the formatting and style of your output.  Rather than forcing them to modify the plugin (bad), or modify files within
       
    56  * the plugin (equally bad), the class allows user templates to be overridden with files contained within the theme.
       
    57  *
       
    58  * An additional benefit is that it leads to code re-use, especially with regards to Ajax (i.e. your display code can be called from
       
    59  * many locations)
       
    60  *
       
    61  * Template files are located within the 'view' subdirectory of the plugins base (specified when registering the plugin):
       
    62  *
       
    63  * <pre>myplugin/view/admin
       
    64  * myplugin/view/myplugin</pre>
       
    65  *
       
    66  * Admin templates are contained within 'admin', and user templates are contained within a directory of the same name as the plugin.
       
    67  *
       
    68  * User files can be overridden within the theme by creating a similar directory structure:
       
    69  *
       
    70  * <pre>/themes/mytheme/view/myplugin</pre>
       
    71  *
       
    72  * The class will first look in the theme and then defaults to the plugin.  A plugin should always provide default templates.
       
    73  *
       
    74  * <h4>Display Parameters</h4>
       
    75  * Also similar to Ruby On Rails, when you display a template you must supply the parameters that the template has access to.  This tries
       
    76  * to ensure a very clean separation between code and display.  Parameters are supplied as an associative array mapping variable name to variable value.
       
    77  *
       
    78  * For example,
       
    79  *
       
    80  * array ('message' => 'Your data was processed', 'items' => 103);
       
    81  *
       
    82  * <h4>How it works in practice</h4>
       
    83  * You create a template file to display how many items have been processed.  You store this in 'view/admin/processed.php':
       
    84  *
       
    85  * <pre>&lt;p&gt;You processed &lt;?php echo $items ?&gt; items&lt;/p&gt;</pre>
       
    86  *
       
    87  * When you want to display this in your plugin you use:
       
    88  *
       
    89  * <pre> $this->render_admin ('processed', array ('items' => 100));
       
    90  *
       
    91  * @package WordPress base library
       
    92  * @author John Godley
       
    93  * @copyright Copyright (C) John Godley
       
    94  **/
       
    95 
       
    96 class AJAX_Calendar_Plugin
       
    97 {
       
    98 	/**
       
    99 	 * Plugin name
       
   100 	 * @var string
       
   101 	 **/
       
   102 	var $plugin_name;
       
   103 
       
   104 	/**
       
   105 	 * Plugin 'view' directory
       
   106 	 * @var string Directory
       
   107 	 **/
       
   108 	var $plugin_base;
       
   109 
       
   110 
       
   111 	/**
       
   112 	 * Register your plugin with a name and base directory.  This <strong>must</strong> be called once.
       
   113 	 *
       
   114 	 * @param string $name Name of your plugin.  Is used to determine the plugin locale domain
       
   115 	 * @param string $base Directory containing the plugin's 'view' files.
       
   116 	 * @return void
       
   117 	 **/
       
   118 
       
   119 	function register_plugin ($name, $base)
       
   120 	{
       
   121 		$this->plugin_base = rtrim (dirname ($base), '/');
       
   122 		$this->plugin_name = $name;
       
   123 
       
   124 		$this->add_action ('init', 'load_locale');
       
   125 	}
       
   126 
       
   127 	function load_locale ()
       
   128 	{
       
   129 		// Here we manually fudge the plugin locale as WP doesnt allow many options
       
   130 		$locale = get_locale ();
       
   131 		if ( empty($locale) )
       
   132 			$locale = 'en_US';
       
   133 
       
   134 		$mofile = dirname (__FILE__)."/locale/$locale.mo";
       
   135 		load_textdomain ($this->plugin_name, $mofile);
       
   136 	}
       
   137 
       
   138 
       
   139 	/**
       
   140 	 * Register a WordPress action and map it back to the calling object
       
   141 	 *
       
   142 	 * @param string $action Name of the action
       
   143 	 * @param string $function Function name (optional)
       
   144 	 * @param int $priority WordPress priority (optional)
       
   145 	 * @param int $accepted_args Number of arguments the function accepts (optional)
       
   146 	 * @return void
       
   147 	 **/
       
   148 
       
   149 	function add_action ($action, $function = '', $priority = 10, $accepted_args = 1)
       
   150 	{
       
   151 		add_action ($action, array (&$this, $function == '' ? $action : $function), $priority, $accepted_args);
       
   152 	}
       
   153 
       
   154 
       
   155 	/**
       
   156 	 * Register a WordPress filter and map it back to the calling object
       
   157 	 *
       
   158 	 * @param string $action Name of the action
       
   159 	 * @param string $function Function name (optional)
       
   160 	 * @param int $priority WordPress priority (optional)
       
   161 	 * @param int $accepted_args Number of arguments the function accepts (optional)
       
   162 	 * @return void
       
   163 	 **/
       
   164 
       
   165 	function add_filter ($filter, $function = '', $priority = 10, $accepted_args = 1)
       
   166 	{
       
   167 		add_filter ($filter, array (&$this, $function == '' ? $filter : $function), $priority, $accepted_args);
       
   168 	}
       
   169 
       
   170 
       
   171 	/**
       
   172 	 * Special activation function that takes into account the plugin directory
       
   173 	 *
       
   174 	 * @param string $pluginfile The plugin file location (i.e. __FILE__)
       
   175 	 * @param string $function Optional function name, or default to 'activate'
       
   176 	 * @return void
       
   177 	 **/
       
   178 
       
   179 	function register_activation ($pluginfile, $function = '')
       
   180 	{
       
   181 		add_action ('activate_'.basename (dirname ($pluginfile)).'/'.basename ($pluginfile), array (&$this, $function == '' ? 'activate' : $function));
       
   182 	}
       
   183 
       
   184 
       
   185 	/**
       
   186 	 * Special deactivation function that takes into account the plugin directory
       
   187 	 *
       
   188 	 * @param string $pluginfile The plugin file location (i.e. __FILE__)
       
   189 	 * @param string $function Optional function name, or default to 'deactivate'
       
   190 	 * @return void
       
   191 	 **/
       
   192 
       
   193 	function register_deactivation ($pluginfile, $function = '')
       
   194 	{
       
   195 		add_action ('deactivate_'.basename (dirname ($pluginfile)).'/'.basename ($pluginfile), array (&$this, $function == '' ? 'deactivate' : $function));
       
   196 	}
       
   197 
       
   198 
       
   199 	/**
       
   200 	 * Renders an admin section of display code
       
   201 	 *
       
   202 	 * @param string $ug_name Name of the admin file (without extension)
       
   203 	 * @param string $array Array of variable name=>value that is available to the display code (optional)
       
   204 	 * @return void
       
   205 	 **/
       
   206 
       
   207 	function render_admin ($ug_name, $ug_vars = array ())
       
   208 	{
       
   209 		global $plugin_base;
       
   210 		foreach ($ug_vars AS $key => $val)
       
   211 			$$key = $val;
       
   212 
       
   213 		if (file_exists ("{$this->plugin_base}/view/admin/$ug_name.php"))
       
   214 			include ("{$this->plugin_base}/view/admin/$ug_name.php");
       
   215 		else
       
   216 			echo "<p>Rendering of admin template {$this->plugin_base}/view/admin/$ug_name.php failed</p>";
       
   217 	}
       
   218 
       
   219 
       
   220 	/**
       
   221 	 * Renders a section of user display code.  The code is first checked for in the current theme display directory
       
   222 	 * before defaulting to the plugin
       
   223 	 *
       
   224 	 * @param string $ug_name Name of the admin file (without extension)
       
   225 	 * @param string $array Array of variable name=>value that is available to the display code (optional)
       
   226 	 * @return void
       
   227 	 **/
       
   228 
       
   229 	function render ($ug_name, $ug_vars = array ())
       
   230 	{
       
   231 		foreach ($ug_vars AS $key => $val)
       
   232 			$$key = $val;
       
   233 
       
   234 		if (file_exists (TEMPLATEPATH."/view/{$this->plugin_name}/$ug_name.php"))
       
   235 			include (TEMPLATEPATH."/view/{$this->plugin_name}/$ug_name.php");
       
   236 		else if (file_exists ("{$this->plugin_base}/view/{$this->plugin_name}/$ug_name.php"))
       
   237 			include ("{$this->plugin_base}/view/{$this->plugin_name}/$ug_name.php");
       
   238 		else
       
   239 			echo "<p>Rendering of template $ug_name.php failed</p>";
       
   240 	}
       
   241 
       
   242 
       
   243 	/**
       
   244 	 * Renders a section of user display code.  The code is first checked for in the current theme display directory
       
   245 	 * before defaulting to the plugin
       
   246 	 *
       
   247 	 * @param string $ug_name Name of the admin file (without extension)
       
   248 	 * @param string $array Array of variable name=>value that is available to the display code (optional)
       
   249 	 * @return void
       
   250 	 **/
       
   251 
       
   252 	function capture ($ug_name, $ug_vars = array ())
       
   253 	{
       
   254 		ob_start ();
       
   255 		$this->render ($ug_name, $ug_vars);
       
   256 		$output = ob_get_contents ();
       
   257 		ob_end_clean ();
       
   258 		return $output;
       
   259 	}
       
   260 
       
   261 
       
   262 	/**
       
   263 	 * Captures an admin section of display code
       
   264 	 *
       
   265 	 * @param string $ug_name Name of the admin file (without extension)
       
   266 	 * @param string $array Array of variable name=>value that is available to the display code (optional)
       
   267 	 * @return string Captured code
       
   268 	 **/
       
   269 
       
   270 	function capture_admin ($ug_name, $ug_vars = array ())
       
   271 	{
       
   272 		ob_start ();
       
   273 		$this->render_admin ($ug_name, $ug_vars);
       
   274 		$output = ob_get_contents ();
       
   275 		ob_end_clean ();
       
   276 		return $output;
       
   277 	}
       
   278 
       
   279 
       
   280 	/**
       
   281 	 * Display a standard error message (using CSS ID 'message' and classes 'fade' and 'error)
       
   282 	 *
       
   283 	 * @param string $message Message to display
       
   284 	 * @return void
       
   285 	 **/
       
   286 
       
   287 	function render_error ($message)
       
   288 	{
       
   289 	?>
       
   290 <div class="fade error" id="message">
       
   291  <p><?php echo $message ?></p>
       
   292 </div>
       
   293 <?php
       
   294 	}
       
   295 
       
   296 
       
   297 	/**
       
   298 	 * Display a standard notice (using CSS ID 'message' and class 'updated').
       
   299 	 * Note that the notice can be made to automatically disappear, and can be removed
       
   300 	 * by clicking on it.
       
   301 	 *
       
   302 	 * @param string $message Message to display
       
   303 	 * @param int $timeout Number of seconds to automatically remove the message (optional)
       
   304 	 * @return void
       
   305 	 **/
       
   306 
       
   307 	function render_message ($message, $timeout = 0)
       
   308 	{
       
   309 		?>
       
   310 <div class="updated" id="message" onclick="this.parentNode.removeChild (this)">
       
   311  <p><?php echo $message ?></p>
       
   312 </div>
       
   313 	<?php
       
   314 	}
       
   315 
       
   316 
       
   317 	/**
       
   318 	 * Get the plugin's base directory
       
   319 	 *
       
   320 	 * @return string Base directory
       
   321 	 **/
       
   322 
       
   323 	function dir ()
       
   324 	{
       
   325 		return $this->plugin_base;
       
   326 	}
       
   327 
       
   328 
       
   329 	/**
       
   330 	 * Get a URL to the plugin.  Useful for specifying JS and CSS files
       
   331 	 *
       
   332 	 * For example, <img src="<?php echo $this->url () ?>/myimage.png"/>
       
   333 	 *
       
   334 	 * @return string URL
       
   335 	 **/
       
   336 
       
   337 	function url ($url = '')
       
   338 	{
       
   339 		if ($url)
       
   340 			return str_replace ('\\', urlencode ('\\'), str_replace ('&amp;amp', '&amp;', str_replace ('&', '&amp;', $url)));
       
   341 		else
       
   342 		{
       
   343 			$url = substr ($this->plugin_base, strlen ($this->realpath (ABSPATH)));
       
   344 			if (DIRECTORY_SEPARATOR != '/')
       
   345 				$url = str_replace (DIRECTORY_SEPARATOR, '/', $url);
       
   346 
       
   347 			$url = get_bloginfo ('wpurl').'/'.ltrim ($url, '/');
       
   348 
       
   349 			// Do an SSL check - only works on Apache
       
   350 			global $is_IIS;
       
   351 			if (isset ($_SERVER['HTTPS']) && !$is_IIS)
       
   352 				$url = str_replace ('http://', 'https://', $url);
       
   353 		}
       
   354 		return $url;
       
   355 	}
       
   356 
       
   357 
       
   358 
       
   359 	/**
       
   360 	 * Performs a version update check using an RSS feed.  The function ensures that the feed is only
       
   361 	 * hit once every given number of days, and the data is cached using the WordPress Magpie library
       
   362 	 *
       
   363 	 * @param string $url URL of the RSS feed
       
   364 	 * @param int $days Number of days before next check
       
   365 	 * @return string Text to display
       
   366 	 **/
       
   367 
       
   368 	function version_update ($url, $days = 7)
       
   369 	{
       
   370 		if (!function_exists ('fetch_rss'))
       
   371 		{
       
   372 			if (!file_exists (ABSPATH.'wp-includes/rss.php'))
       
   373 				return '';
       
   374 			include (ABSPATH.'wp-includes/rss.php');
       
   375 		}
       
   376 
       
   377 		$now = time ();
       
   378 
       
   379 		$checked = get_option ('plugin_urbangiraffe_rss');
       
   380 
       
   381 		// Use built-in Magpie caching
       
   382 		if (function_exists ('fetch_rss') && (!isset ($checked[$this->plugin_name]) || $now > $checked[$this->plugin_name] + ($days * 24 * 60 * 60)))
       
   383 		{
       
   384 			$rss = fetch_rss ($url);
       
   385 			if (count ($rss->items) > 0)
       
   386 			{
       
   387 				foreach ($rss->items AS $pos => $item)
       
   388 				{
       
   389 					if (isset ($checked[$this->plugin_name]) && strtotime ($item['pubdate']) < $checked[$this->plugin_name])
       
   390 						unset ($rss->items[$pos]);
       
   391 				}
       
   392 			}
       
   393 
       
   394 			$checked[$this->plugin_name] = $now;
       
   395 			update_option ('plugin_urbangiraffe_rss', $checked);
       
   396 			return $rss;
       
   397 		}
       
   398 	}
       
   399 
       
   400 
       
   401 	/**
       
   402 	 * Version of realpath that will work on systems without realpath
       
   403 	 *
       
   404 	 * @param string $path The path to canonicalize
       
   405 	 * @return string Canonicalized path
       
   406 	 **/
       
   407 
       
   408 	function realpath ($path)
       
   409 	{
       
   410 		if (function_exists ('realpath'))
       
   411 			return realpath ($path);
       
   412 		else if (DIRECTORY_SEPARATOR == '/')
       
   413 		{
       
   414 			$path = preg_replace ('/^~/', $_SERVER['DOCUMENT_ROOT'], $path);
       
   415 
       
   416 	    // canonicalize
       
   417 	    $path = explode (DIRECTORY_SEPARATOR, $path);
       
   418 	    $newpath = array ();
       
   419 	    for ($i = 0; $i < sizeof ($path); $i++)
       
   420 			{
       
   421 				if ($path[$i] === '' || $path[$i] === '.')
       
   422 					continue;
       
   423 
       
   424 				if ($path[$i] === '..')
       
   425 				{
       
   426 					array_pop ($newpath);
       
   427 					continue;
       
   428 				}
       
   429 
       
   430 				array_push ($newpath, $path[$i]);
       
   431 	    }
       
   432 
       
   433 	    $finalpath = DIRECTORY_SEPARATOR.implode (DIRECTORY_SEPARATOR, $newpath);
       
   434       return $finalpath;
       
   435 		}
       
   436 
       
   437 		return $path;
       
   438 	}
       
   439 
       
   440 
       
   441 	function checked ($item, $field = '')
       
   442 	{
       
   443 		if ($field && is_array ($item))
       
   444 		{
       
   445 			if (isset ($item[$field]) && $item[$field])
       
   446 				echo ' checked="checked"';
       
   447 		}
       
   448 		else if (!empty ($item))
       
   449 			echo ' checked="checked"';
       
   450 	}
       
   451 
       
   452 	function select ($items, $default = '')
       
   453 	{
       
   454 		if (count ($items) > 0)
       
   455 		{
       
   456 			foreach ($items AS $key => $value)
       
   457 			{
       
   458 				if (is_array ($value))
       
   459 				{
       
   460 					echo '<optgroup label="'.$key.'">';
       
   461 					foreach ($value AS $sub => $subvalue)
       
   462 						echo '<option value="'.$sub.'"'.($sub == $default ? ' selected="selected"' : '').'>'.$subvalue.'</option>';
       
   463 					echo '</optgroup>';
       
   464 				}
       
   465 				else
       
   466 					echo '<option value="'.$key.'"'.($key == $default ? ' selected="selected"' : '').'>'.$value.'</option>';
       
   467 			}
       
   468 		}
       
   469 	}
       
   470 }
       
   471 
       
   472 if (!class_exists ('Widget_AJAX_Calendar'))
       
   473 {
       
   474 	class Widget_AJAX_Calendar
       
   475 	{
       
   476 		function Widget_AJAX_Calendar ($name, $max = 1, $id = '', $args = '')
       
   477 		{
       
   478 			$this->name        = $name;
       
   479 			$this->id          = $id;
       
   480 			$this->widget_max  = $max;
       
   481 			$this->args        = $args;
       
   482 
       
   483 			if ($this->id == '')
       
   484 				$this->id = strtolower (preg_replace ('/[^A-Za-z]/', '-', $this->name));
       
   485 
       
   486 			$this->widget_available = 1;
       
   487 			if ($this->widget_max > 1)
       
   488 			{
       
   489 				$this->widget_available = get_option ('widget_available_'.$this->id ());
       
   490 				if ($this->widget_available === false)
       
   491 					$this->widget_available = 1;
       
   492 			}
       
   493 
       
   494 			add_action ('init', array (&$this, 'initialize'));
       
   495 		}
       
   496 
       
   497 		function initialize ()
       
   498 		{
       
   499 			// Compatability functions for WP 2.1
       
   500 			if (!function_exists ('wp_register_sidebar_widget'))
       
   501 			{
       
   502 				function wp_register_sidebar_widget ($id, $name, $output_callback, $classname = '')
       
   503 				{
       
   504 					register_sidebar_widget($name, $output_callback, $classname);
       
   505 				}
       
   506 			}
       
   507 
       
   508 			if (!function_exists ('wp_register_widget_control'))
       
   509 			{
       
   510 				function wp_register_widget_control($name, $control_callback, $width = 300, $height = 200)
       
   511 				{
       
   512 					register_widget_control($name, $control_callback, $width, $height);
       
   513 				}
       
   514 			}
       
   515 
       
   516 			if (function_exists ('wp_register_sidebar_widget'))
       
   517 			{
       
   518 				if ($this->widget_max > 1)
       
   519 				{
       
   520 					add_action ('sidebar_admin_setup', array (&$this, 'setup_save'));
       
   521 					add_action ('sidebar_admin_page', array (&$this, 'setup_display'));
       
   522 				}
       
   523 
       
   524 				$this->load_widgets ();
       
   525 			}
       
   526 		}
       
   527 
       
   528 		function load_widgets ()
       
   529 		{
       
   530 			for ($pos = 1; $pos <= $this->widget_max; $pos++)
       
   531 			{
       
   532 				wp_register_sidebar_widget ($this->id ($pos), $this->name ($pos), $pos <= $this->widget_available ? array (&$this, 'show_display') : '', $this->args (), $pos);
       
   533 
       
   534 				if ($this->has_config ())
       
   535 					wp_register_widget_control ($this->id ($pos), $this->name ($pos), $pos <= $this->widget_available ? array (&$this, 'show_config') : '', $this->args (), $pos);
       
   536 			}
       
   537 		}
       
   538 
       
   539 		function args ()
       
   540 		{
       
   541 			if ($this->args)
       
   542 				$args = $this->args;
       
   543 			else
       
   544 				$args = array ('classname' => '');
       
   545 
       
   546 			if ($this->description ())
       
   547 				$args['description'] = $this->description ();
       
   548 			return $args;
       
   549 		}
       
   550 
       
   551 		function description () { return ''; }
       
   552 
       
   553 		function name ($pos)
       
   554 		{
       
   555 			if ($this->widget_available > 1)
       
   556 				return $this->name.' ('.$pos.')';
       
   557 			return $this->name;
       
   558 		}
       
   559 
       
   560 		function id ($pos = 0)
       
   561 		{
       
   562 			if ($pos == 0)
       
   563 				return $this->id;
       
   564 			return $this->id.'-'.$pos;
       
   565 		}
       
   566 
       
   567 		function show_display ($args, $number = 1)
       
   568 		{
       
   569 			$config = get_option ('widget_config_'.$this->id ($number));
       
   570 			if ($config === false)
       
   571 				$config = array ();
       
   572 
       
   573 			$this->load ($config);
       
   574 			$this->display ($args);
       
   575 		}
       
   576 
       
   577 		function show_config ($position)
       
   578 		{
       
   579 			if (isset ($_POST['widget_config_save_'.$this->id ($position)]))
       
   580 			{
       
   581 				$data = $_POST[$this->id ()];
       
   582 				if (count ($data) > 0)
       
   583 				{
       
   584 					$newdata = array ();
       
   585 					foreach ($data AS $item => $values)
       
   586 						$newdata[$item] = $values[$position];
       
   587 					$data = $newdata;
       
   588 				}
       
   589 
       
   590 				update_option ('widget_config_'.$this->id ($position), $this->save ($data));
       
   591 			}
       
   592 
       
   593 			$options = get_option ('widget_config_'.$this->id ($position));
       
   594 			if ($options === false)
       
   595 				$options = array ();
       
   596 
       
   597 			$this->config ($options, $position);
       
   598 			echo '<input type="hidden" name="widget_config_save_'.$this->id ($position).'" value="1" />';
       
   599 		}
       
   600 
       
   601 		function has_config () { return false; }
       
   602 		function save ($data)
       
   603 		{
       
   604 			return array ();
       
   605 		}
       
   606 
       
   607 		function setup_save ()
       
   608 		{
       
   609 			if (isset ($_POST['widget_setup_save_'.$this->id ()]))
       
   610 			{
       
   611 				$this->widget_available = intval ($_POST['widget_setup_count_'.$this->id ()]);
       
   612 				if ($this->widget_available < 1)
       
   613 					$this->widget_available = 1;
       
   614 				else if ($this->widget_available > $this->widget_max)
       
   615 					$this->widget_available = $this->widget_max;
       
   616 
       
   617 				update_option ('widget_available_'.$this->id (), $this->widget_available);
       
   618 
       
   619 				$this->load_widgets ();
       
   620 			}
       
   621 		}
       
   622 
       
   623 		function config_name ($field, $pos)
       
   624 		{
       
   625 			return $this->id ().'['.$field.']['.$pos.']';
       
   626 		}
       
   627 
       
   628 		function setup_display ()
       
   629 		{
       
   630 			?>
       
   631 			<div class="wrap">
       
   632 				<form method="post">
       
   633 					<h2><?php echo $this->name ?></h2>
       
   634 					<p style="line-height: 30px;"><?php _e('How many widgets would you like?', $this->id); ?>
       
   635 						<select name="widget_setup_count_<?php echo $this->id () ?>" value="<?php echo $options; ?>">
       
   636 							<?php for ( $i = 1; $i <= $this->widget_max; ++$i ) : ?>
       
   637 							 <option value="<?php echo $i ?>"<?php if ($this->widget_available == $i) echo ' selected="selected"' ?>><?php echo $i ?></option>
       
   638 							<?php endfor; ?>
       
   639 						</select>
       
   640 						<span class="submit">
       
   641 							<input type="submit" name="widget_setup_save_<?php echo $this->id () ?>" value="<?php echo attribute_escape(__('Save', $this->id)); ?>" />
       
   642 						</span>
       
   643 					</p>
       
   644 				</form>
       
   645 			</div>
       
   646 			<?php
       
   647 		}
       
   648 	}
       
   649 }
       
   650 ?>