Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- /*
- Settings Helper for WordPress
- Copyright (C) 2011 William Barnes
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
- /** WP Settings Form Helper
- *
- * Helper class for creating settings forms.
- */
- if (!class_exists('WP_Settings_Form')):
- class WP_Settings_Form
- {
- /**
- * Configuration
- *
- * Public so that you can make adjustments.
- */
- public $config = array();
- protected $_errors = array();
- // CONFIG
- public function __construct($config)
- {
- $this->config = $config;
- }
- /**
- * Gets the option
- *
- * In simple mode: returns the row from wp_options that corresponds to the
- * option_name for the form.
- *
- * In multi mode: returns either the row from options array or if no key
- * then the defaults.
- *
- * The force argument causes it to return the entire array when in multi
- * mode.
- */
- public function get_option($force=false)
- {
- $config = $this->config;
- $option = get_option($config['option_name']);
- if (!is_array($option)):
- $option = array();
- endif;
- if ($force || !$this->is_multi()):
- return $option;
- // MULTI: Insert
- elseif ($this->get_request_type() == 'insert'):
- return isset($config['defaults']) ? $config['defaults'] : array();
- // MULTI: Edit
- else:
- return $option[$_REQUEST['_wpform_key']];
- endif;
- }
- // QUERY
- // Many of these are called only once, but this makes it easier to read the
- // code later.
- public function is_multi()
- {
- return isset($this->config['multi']);
- }
- public function is_form_submission()
- {
- return (isset($_POST['_wpform_option']) && ($_POST['_wpform_option'] == $this->config['option_name']));
- }
- public function get_request_type()
- {
- if (!$this->is_multi()):
- return 'edit'; // Always edit
- elseif (!isset($_REQUEST['_wpform_key']) || empty($_REQUEST['_wpform_key'])):
- return 'insert';
- elseif (is_numeric($_GET['_wpform_key'])):
- return 'edit';
- elseif (is_array($_POST['_wpform_key']) && isset($_REQUEST['_wpform_action']) && ($_POST['_wpform_action'] == 'delete')):
- return 'delete';
- elseif (is_array($_POST['_wpform_key']) && isset($_REQUEST['_wpform_action'])):
- // Custom action
- return $_REQUEST['_wpform_action'];
- else:
- return null;
- endif;
- }
- public function is_single_form()
- {
- // Simple mode always shows the form.
- // Multi mode only shows it if we're editing or inserting a new item.
- // In multi, make sure that it's *this* form.
- return (
- ( !$this->is_multi() ) ||
- ( isset($_GET['_wpform_option']) && ($_GET['_wpform_option'] == $this->config['option_name']) )
- );
- }
- /**
- * Validate
- *
- * Provide it with a new option. It checks for variables based on the form
- * definition, validates them, and returns the validated option.
- *
- */
- public function validate($new_option_group)
- {
- $config = $this->config;
- $option = $this->get_option();
- // Loop through the form definition and process only defined variables
- $sections = $config['sections'];
- foreach ($sections as $section):
- $fields = $section['fields'];
- foreach ($fields as $field):
- // Check for field in submission
- if (array_key_exists($field['name'],$new_option_group)):
- $name = $field['name'];
- $old_value = isset($option[$name]) ? $option[$name] : null;
- $test_value = $new_option_group[$name];
- // User provided default validation
- if (!isset($field['validator'])):
- $option[$name] = call_user_func($config['validator'],$test_value,$old_value,$field);
- // Use local validation
- elseif (is_array($field['validator']) && array_key_exists('type',$field['validator'])):
- $option[$name] = $this->validate_local($field['validator'],$test_value,$old_value,$field);
- // No validation
- elseif ($field['validator'] === false):
- $option[$name] = $test_value;
- // User provided field-specific validation
- else:
- $option[$name] = call_user_func($field['validator'],$test_value,$old_value,$field);
- endif;
- endif;
- endforeach; // Fields
- endforeach; // Sections
- return $option;
- }
- /**
- * Validation shortcuts
- *
- * So users don't have to write their own.
- */
- public function validate_local($validator,$test_value,$old_value,$field)
- {
- if ((!isset($field['required']) || $field['required'] == false) && $test_value == ''): // Allow empty values
- return '';
- endif;
- switch($validator['type']):
- case "preg_replace":
- return preg_replace($validator['pattern'],$validator['replacement'],$test_value);
- case "preg_match":
- if (preg_match($validator['pattern'],$test_value)):
- return $test_value;
- else:
- $this->error($$field['label'] . ': incorrect format');
- return $old_value;
- endif;
- case "url": // http://daringfireball.net/2010/07/improved_regex_for_matching_urls
- $re = "%^(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))$%";
- if (preg_match($re,$test_value)):
- return $test_value;
- else:
- $this->error($field['label'] . ': not a valid url');
- return $old_value;
- endif;
- case "email": // http://www.regular-expressions.info/email.html
- $re = "/^(?i)[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/";
- if (preg_match($re,$test_value)):
- return $test_value;
- else:
- $this->error($field['label'] . ': not a valid email');
- return $old_value;
- endif;
- case "numeric":
- if (is_numeric($test_value)):
- return $test_value;
- else:
- $this->error($field['label'] . ': must be a number');
- return $old_value;
- endif;
- default:
- // If you get this error, there's something wrong with your $config
- $this->error($field['label'] . ': validation type does not exist.');
- return $old_value;
- endswitch;
- }
- /**
- * Register the form
- */
- public function register()
- {
- $config = $this->config;
- $option_name = $config['option_name'];
- // Is this a form submission?
- if ($this->is_form_submission()):
- $option = $this->get_option(true);
- // Adding or editing
- if ($this->is_single_form() && check_admin_referer('_wpform_single','_wpform_nonce')):
- $key = isset($_POST['_wpform_key']) ? $_POST['_wpform_key'] : '';
- $new_option = $this->validate( $_POST[$option_name] );
- // Do nothing if there were validation errors
- if (empty($this->_errors)):
- // MULTI MODE: Adding
- if ($this->get_request_type() == 'insert'):
- // Defaults
- if (array_key_exists('defaults',$config)):
- $new_option += $config['defaults'];
- endif;
- // Add new item to end of array
- $key = time(); // Use a timestamp so keys are always unique
- $option[$key] = $new_option;
- // Forward to the edit page for the item just added
- $redirect = add_query_arg(array(
- '_wpform_key'=>$key,
- '_wpform_success' => $config['option_name'],
- '_wpform_error'=>false
- ));
- // MULTI MODE: Editing
- elseif ($this->is_multi() && ($this->get_request_type() == 'edit')):
- if (array_key_exists($key,$option)):
- $option[$key] = $new_option;
- // Return to the edit page
- $redirect = add_query_arg(array(
- '_wpform_success' => $config['option_name'],
- '_wpform_error'=>false
- ));
- // Somebody requested a key that doesn't exist, do nothing
- else:
- $this->error('Key does not exist');
- endif;
- // SIMPLE MODE: Editing
- else:
- $option = $new_option;
- // Back to edit page (index)
- $redirect = add_query_arg(array(
- '_wpform_success' => $config['option_name'],
- '_wpform_error'=>false
- ));
- endif;
- endif;
- // MULTI MODE ONLY: Deleting or other
- elseif ($this->get_request_type() && check_admin_referer('_wpform_multi','_wpform_nonce')):
- $keys = $_POST['_wpform_key'];
- $action = $this->get_request_type();
- // Delete
- if ($action == 'delete'):
- foreach($keys as $key):
- if (array_key_exists($key,$option)) unset($option[$key]);
- endforeach;
- // Back to index
- $redirect = add_query_arg(array(
- '_wpform_success' => $config['option_name'],
- '_wpform_error'=>false
- ));
- // Custom action
- // Loop through the provided keys and call the user-provided function on each row
- else:
- $buttons = isset($config['multi']['table_buttons']) ? $config['multi']['table_buttons'] : array();
- if (array_key_exists($action, $buttons)):
- foreach($keys as $key):
- if (array_key_exists($key, $option) && isset($buttons[$action]['callback'])):
- $option[$key] = call_user_func($buttons[$action]['callback'], $option[$key], &$this);
- endif;
- endforeach;
- // Back to index
- $redirect = add_query_arg(array(
- '_wpform_success' => $config['option_name'],
- '_wpform_error' => false
- ));
- else:
- $this->error('Action does not exist');
- endif;
- endif;
- // Something weird happened
- else:
- $this->error('Malformed request');
- endif;
- // Save changes to database
- if (empty($this->_errors)):
- update_option($config['option_name'],$option);
- // Print errors
- else:
- $message = '';
- foreach($this->_errors as $error):
- $message .= '<li>' . $error . '</li>';
- endforeach;
- $redirect = add_query_arg(array(
- '_wpform_error'=>urlencode($message),
- '_wpform_success'=>false,
- ));
- endif;
- wp_redirect($redirect);
- exit;
- endif;
- }
- public function error($message)
- {
- $this->_errors[] = $message;
- }
- /**
- * Echos a form field
- *
- * TODO: Define more field types
- * You can add field types yourself, it's not too hard
- */
- public function echo_field($field)
- {
- $config = $this->config;
- $option = $this->get_option();
- // Attribute values
- $option_name = $config['option_name'];
- $field_name = $field['name'];
- $field_id = $config['option_name'].'_'.$field['name'];
- $field_value = isset($option[$field['name']]) ? $option[$field['name']] : '';
- $field_size = isset($field['size']) ? $field['size'] : '40';
- switch ($field['type']):
- // Category Dropdown
- case "authors":
- wp_dropdown_users("id={$field_id}&name={$option_name}[{$field_name}]&selected={$field_value}");
- break;
- // Boolean (checkbox, value=1)
- case "boolean":
- echo "<input id='{$field_id}' name='{$option_name}[{$field_name}]' size='{$field_size}' type='checkbox' value='1'". (($field_value == 1) ? " checked='yes'" : '') ."' />";
- break;
- // Category Dropdown
- case "categories":
- wp_dropdown_categories("id={$field_id}&name={$option_name}[{$field_name}]&selected={$field_value}");
- break;
- // Dropdown
- case "dropdown":
- echo "<select id='{$field_id}' name='{$option_name}[{$field_name}]' />";
- foreach ($field['options'] as $key=>$value):
- echo "<option value='{$key}'".($value == $field_value ? "selected='selected'" : "").">{$value}</option>";
- endforeach;
- echo "</select>";
- break;
- // Password
- case "password":
- echo "<input id='{$field_id}' name='{$option_name}[{$field_name}]' size='{$field_size}' type='password' value='{$field_value}' />";
- break;
- // Text field
- case "text":
- default:
- echo "<input id='{$field_id}' name='{$option_name}[{$field_name}]' size='{$field_size}' type='text' value='{$field_value}' />";
- break;
- endswitch;
- // Description (if present)
- if (isset($field['description'])) echo '<br />'.$field['description'];
- }
- public function echo_settings_page()
- {
- $config = $this->config;
- if ($this->is_single_form()):
- $this->echo_single_form();
- else:
- $this->echo_multi_index();
- endif;
- }
- /**
- * Echo form
- *
- * Call this within the HTML of your settings page function.
- */
- public function echo_single_form()
- {
- $config = $this->config;
- ?>
- <form action="<?php echo add_query_arg(array('_wpform_success'=>false,'_wpform_error'=>false)); ?>" method="post">
- <div class="inner">
- <?php if (isset($_REQUEST['_wpform_error'])): ?>
- <div class="error">
- <ul>
- <?php echo $_REQUEST['_wpform_error']; ?>
- </ul>
- </div>
- <?php elseif (isset($_REQUEST['_wpform_success']) && ($_REQUEST['_wpform_success'] == $config['option_name'])): ?>
- <div class="updated">
- <p>Update successful.</p>
- </div>
- <?php
- endif;
- $sections = $config['sections'];
- foreach ($sections as $section):
- ?>
- <h3><?php echo $section['title']; ?></h3>
- <table class="form-table">
- <tbody>
- <?php
- $fields = $section['fields'];
- foreach ($fields as $field):
- $field_id = $config['option_name'].'_'.$field['name'];
- ?>
- <tr valign="top">
- <th scope="row"><label for="<?php echo $field_id; ?>"><?php echo $field['label']; ?></label></th>
- <td>
- <?php $this->echo_field($field); ?>
- </td>
- </tr>
- <?php endforeach; ?>
- </tbody>
- </table>
- <?php endforeach; ?>
- <?php
- if (array_key_exists('hidden',$config)):
- foreach ($config['hidden'] as $input):
- echo "<input type='hidden' name='{$input['name']}' value='{$input['value']}' />";
- endforeach;
- endif;
- if (isset($config['multi'])):
- ?>
- <input type="hidden" name="_wpform_key" value="<?php echo isset($_REQUEST['_wpform_key']) ? $_REQUEST['_wpform_key'] : ''; ?>" />
- <?php
- endif;
- ?>
- <input type="hidden" name="_wpform_option" value="<?php echo $config['option_name']; ?>" />
- <?php wp_nonce_field( '_wpform_single', '_wpform_nonce', true); ?>
- <p class="submit">
- <input name="Submit" class="button-primary" type="submit" value="Save Changes" />
- </p>
- </div>
- </form>
- <?php
- }
- /**
- * Echo table
- *
- * Prints a table of the items in a multi-dimensional option.
- */
- public function echo_multi_index()
- {
- $config = $this->config;
- $fields = $config['multi']['table_fields'];
- ?>
- <form action="<?php echo add_query_arg(array('_wpform_success'=>false,'_wpform_error'=>false)); ?>" method="post">
- <?php if (isset($_REQUEST['_wpform_error'])): ?>
- <div class="error">
- <ul>
- <?php echo $_REQUEST['_wpform_error']; ?>
- </ul>
- </div>
- <?php elseif (isset($_REQUEST['_wpform_success']) && ($_REQUEST['_wpform_success'] == $config['option_name'])): ?>
- <div class="update">
- <p>Update successful.</p>
- </div>
- <?php endif; ?>
- <?php if (isset($config['multi']['list_title'])): ?>
- <h3><?php echo $config['multi']['list_title']; ?></h3>
- <?php endif; ?>
- <table class="widefat">
- <colgroup>
- <col style="width:20px;"/>
- <col style="width:40px;"/>
- <?php
- foreach($fields as $field):
- echo '<col' . (isset($field['width']) ? ' style="width:' . $field['width'] . '"' : '') . " />";
- endforeach;
- ?>
- </colgroup>
- <thead><tr>
- <th scope="col" class="check-column"><input type="checkbox" /></th>
- <th scope="col">ID</th>
- <?php
- foreach($fields as $field):
- echo '<th scope="col">' . $field['label'] . '</th>';
- endforeach;
- ?>
- </tr></thead>
- <tbody>
- <?php
- $rows = $this->get_option(true);
- foreach ($rows as $id=>$row):
- ?>
- <tr>
- <th class="check-column" scope="row"><input type="checkbox" value="<?php echo $id; ?>" name="_wpform_key[]" /></th>
- <td><?php echo $id; ?></td>
- <?php
- foreach($fields as $field):
- $type = isset($field['type']) ? $field['type'] : 'text';
- $content = isset($row[$field['name']]) ? $row[$field['name']] : null;
- switch ($type):
- case "date":
- $content = date('D, M j, Y',strtotime($content));
- break;
- case "datetime":
- $content = date('D, M j, Y H:i:s e',strtotime($content));
- break;
- case "timestamp":
- $content = date('D, M j, Y H:i:s e',$content);
- break;
- default:
- $content = (!empty($content) || ($content === 0) ? $content : ' ');
- break;
- endswitch;
- if (array_key_exists('link',$field) && $field['link']):
- echo '<td><a href="'.add_query_arg(array('_wpform_option'=>$config['option_name'],'_wpform_key'=>$id,'_wpform_success'=>false,'_wpform_error'=>false)).'">'.$content.'</a></td>';
- else:
- echo "<td>$content</td>";
- endif;
- endforeach;
- ?>
- </tr>
- <?php endforeach; ?>
- </tbody>
- </table>
- <input type="hidden" name="_wpform_option" value="<?php echo $config['option_name']; ?>" />
- <?php wp_nonce_field( '_wpform_multi', '_wpform_nonce', true); ?>
- <div class="tablenav">
- <div class="alignleft">
- <?php
- $buttons = isset($config['multi']['table_buttons']) ? $config['multi']['table_buttons'] : array();
- foreach ($buttons as $id=>$button):
- echo '<button type="submit" name="'. (isset($button['name']) ? $button['name'] : '_wpform_action') .'" value="'. (isset($button['value']) ? $button['value'] : $id) .'" class="button-'. (isset($button['priority']) ? $button['priority'] : 'secondary') .'">'. $button['label'] .'</button> ';
- endforeach;
- ?>
- <button type="submit" name="_wpform_action" value="delete" class="button-secondary delete"><?php _e('Delete'); ?></button>
- </div>
- <br class="clear" />
- </div>
- </form>
- <form action="<?php echo add_query_arg(array('_wpform_success'=>false,'_wpform_error'=>false)); ?>" method="GET">
- <div class="inner">
- <?php
- if (isset($config['multi']['new_fields'])):
- ?>
- <h3><?php echo $config['multi']['new_title'] ?></h3>
- <table class="form-table">
- <tbody>
- <?php
- $fields = $config['multi']['new_fields'];
- foreach ($fields as $field):
- $field_id = $config['option_name'].'_'.$field['name'];
- ?>
- <tr valign="top">
- <th scope="row"><label for="<?php echo $field_id; ?>"><?php echo $field['label']; ?></label></th>
- <td><?php $this->echo_field($field); ?></td>
- </tr>
- <?php endforeach; ?>
- </tbody>
- </table>
- <?php
- endif;
- ?>
- <input type="hidden" name="_wpform_option" value="<?php echo $config['option_name']; ?>" />
- <input type="hidden" name="page" value="<?php echo $_GET['page']; ?>" />
- <p class="submit"><input class="button-primary" type="submit" value="<?php echo $config['multi']['new_title'] ?>" /></p>
- </div>
- </form>
- <?php
- }
- }
- endif; // class_exists
- ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement