diff --git a/README.txt b/README.txt
index 8b7c6f8..a827ddd 100644
--- a/README.txt
+++ b/README.txt
@@ -19,9 +19,9 @@
3. Edit cheezcap/config.php
4. Sprinkle theme options around your code, like this:
- if ($cap->my_boolean_option) {
- // do stuff
- }
+ if ($cap->my_boolean_option) {
+ // do stuff
+ }
5. Enjoy!
@@ -77,6 +77,7 @@ are three types of Options available to create:
1. Boolean Option
2. Text Option
3. Dropdown Option
+ 4. MediaOption
## 1. Boolean Option
The simplest form of option...creates a true or false dropdown that can be used to turn features on or off.
@@ -112,6 +113,16 @@ Allows you to create a dropdown with custom values by passing the constructor an
DefaultIndex = an integer identifying the item in the array that is the default value; if not specified,
the default is 0.
+## 4. Media Option
+Allows you to open a media library modal and get the URL for an item. If it's an image, a preview will display
+
+ new MediaOption(Name, Description, OptionID, Default )
+
+ Name = a human readable name for the option.
+ Description = a human readable description for the option.
+ OptionID = a machine readable option identifier, cannot have spaces and must be unique
+ Default = a string as the default value for the option; if not specified, the default is ""
+
##
## Usage
##
diff --git a/cheezcap.php b/cheezcap.php
index 6db840e..ff4bc40 100644
--- a/cheezcap.php
+++ b/cheezcap.php
@@ -1,66 +1,317 @@
post_ratings is the same as get_bool_option("cap_post_ratings", false)
+ */
+class CheezCap {
+ private $data = false;
+ private $cache = array();
+ private $settings = array();
+ private $options = array();
+
+ private $messages = array();
+
+ function __construct( $options, $settings = array() ) {
+ $settings = wp_parse_args( $settings, array(
+ 'themename' => 'CheezCap',
+ 'req_cap_to_edit' => 'manage_options',
+ 'cap_menu_position' => 99,
+ 'cap_icon_url' => '',
+ ) );
+
+ $settings['themeslug'] = sanitize_key( $settings['themename'] );
+
+ // Let's prevent accidentally allowing low-level users access to cap
+ if( ! in_array( $settings['req_cap_to_edit'], apply_filters( 'cheezcap_req_cap_to_edit_whitelist', array( 'manage_network', 'manage_options', 'edit_others_posts', 'publish_posts' ) ) ) )
+ $settings['req_cap_to_edit'] = 'manage_options';
+
+ $this->settings = $settings;
+ $this->options = $options;
+ $this->messages = $this->get_default_messages();
+
+ add_action( 'admin_menu', array( $this, 'add_admin_page' ) );
+ add_action( 'admin_init', array( $this, 'handle_admin_actions' ) );
+ }
-function cap_add_admin() {
- global $themename, $req_cap_to_edit, $cap_menu_position, $cap_icon_url;
+ function init() {
+ if ( $this->data )
+ return;
- if ( ! current_user_can ( $req_cap_to_edit ) )
- return;
+ $this->data = array();
+ $options = $this->get_options();
- if ( isset( $_GET['page'] ) && $_GET['page'] == basename( __FILE__ ) ) {
- $options = cap_get_options();
- $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';
- $method = false;
- $done = false;
- $data = new ImportData();
- switch ( $action ) {
- case 'save':
- $method = 'Update';
- break;
- case 'Reset':
- $method = 'Reset';
- break;
- case 'Export':
- $method = 'Export';
- $done = 'cap_serialize_export';
- break;
- case 'Import':
- $method = 'Import';
- $data = unserialize( file_get_contents( $_FILES['file']['tmp_name'] ) );
- break;
+ foreach ( $options as $group ) {
+ foreach( $group->options as $option ) {
+ $this->data[$option->_key] = $option;
+ }
}
+ }
+
+ public function __get( $name ) {
+ $this->init();
+
+ if ( array_key_exists( $name, $this->cache ) )
+ return $this->cache[$name];
- if ( $method ) {
- foreach ( $options as $group ) {
- foreach ( $group->options as $option ) {
- call_user_func( array( $option, $method ), $data );
- }
- }
- if ( $done )
- call_user_func( $done, $data );
+ $option = $this->data[$name];
+ if ( empty( $option ) && defined( 'WP_DEBUG' ) && WP_DEBUG )
+ throw new Exception( "Unknown key: $name" );
+ elseif( empty( $option ) )
+ $value = '';
+ else
+ $value = $this->cache[$name] = $option->get();
+
+ return $value;
+ }
+
+ public function get_options() {
+ return $this->options;
+ }
+
+ public function get_settings() {
+ return $this->settings;
+ }
+
+ public function get_setting( $setting, $default = '' ) {
+ if( isset( $this->settings[$setting] ) )
+ return $this->settings[$setting];
+ return $default;
+ }
+
+ // UI-related functions
+ function add_admin_page() {
+ $page_name = sprintf( __( '%s Settings', 'cheezcap' ), esc_html( $this->get_setting( 'themename' ) ) );
+ $page_hook = add_menu_page( $page_name, $page_name, $this->get_setting( 'req_cap_to_edit' ), $this->get_setting( 'themeslug' ), array( $this, 'display_admin_page' ), $this->get_setting( 'cap_icon_url' ), $this->get_setting( 'cap_menu_position' ) );
+
+ add_action( "admin_print_scripts-$page_hook", array( $this, 'admin_js_libs' ) );
+ add_action( "admin_footer-$page_hook", array( $this, 'admin_js_footer' ) );
+ add_action( "admin_print_styles-$page_hook", array( $this, 'admin_css' ) );
+ }
+
+ function handle_admin_actions() {
+ global $plugin_page;
+
+ $themeslug = $this->get_setting( 'themeslug' );
+
+ if ( $plugin_page == $themeslug ) {
+
+ $action = isset( $_POST['action'] ) ? strtolower( $_POST['action'] ) : '';
+
+ if( ! $action )
+ return;
+
+ check_admin_referer( $themeslug . '-action', $themeslug . '-nonce' );
+
+ if ( ! current_user_can ( $this->get_setting( 'req_cap_to_edit' ) ) )
+ return;
+
+ $options = $this->get_options();
+ $method = false;
+ $done = false;
+ $redirect = false;
+ $data = new CheezCapImportData();
+
+ switch ( $action ) {
+ case 'save':
+ $method = 'update';
+ $redirect = array( 'success' => $method );
+ break;
+
+ case 'reset':
+ $method = 'reset';
+ $redirect = array( 'success' => $method );
+ break;
+
+ case 'export':
+ $method = 'export';
+ $done = array( $this, 'serialize_export' );
+ break;
+
+ case 'import':
+
+ $data = @ unserialize( file_get_contents( $_FILES['file']['tmp_name'] ) ); // We're using @ to suppress the E_NOTICE
+
+ if( $data && is_a( $data, 'CheezCapImportData' ) ) {
+ $method = 'import';
+ $redirect = array( 'success' => $method );
+ } else {
+ $redirect = array( 'error' => 'import' );
+ }
+
+ break;
+ }
+
+ if ( $method ) {
+ foreach ( $options as $group ) {
+ foreach ( $group->options as $option ) {
+ call_user_func( array( $option, $method ), $data );
+ }
+ }
+
+ if ( $done )
+ call_user_func( $done, $data );
+ }
+
+ if( ! empty( $redirect ) )
+ wp_redirect( add_query_arg( $redirect, menu_page_url( $plugin_page, false ) ) );
+
}
}
+
+ function display_message( $type ) {
+ $theme_name = $this->get_setting( 'themename' );
+ $message_key = sanitize_key( $_GET[ $type ] );
+ $message = isset( $this->messages[$type][$message_key] ) ? $this->messages[$type][$message_key] : '';
+
+ $message_class = ( $type != 'error' ) ? 'updated' : $type;
+
+ if( $message )
+ echo sprintf( '
+
+
+
+
+
+
+
+
+ array(
+ 'update' => __( 'Sweet! The settings for %s were saved!', 'cheezcap' ),
+ 'reset' => __( 'Yay! The settings for %s were reset!', 'cheezcap' ),
+ 'import' => __( 'Woo! The settings for %s were imported!', 'cheezcap' )
+ ),
+ 'error' => array(
+ 'import' => __( 'That doesn\'t look like a CheezCap Export file. Homie don\'t play that!', 'cheezcap' ),
+ )
+ );
+ }
+
+ function serialize_export( $data ) {
+ $filename = sprintf( '%s-%s-theme-export.txt', date( 'Y.m.d' ), sanitize_key( get_bloginfo( 'name' ) ) );
+ header( 'Content-disposition: attachment; filename=' . $filename );
+ echo serialize( $data );
+ exit();
+ }
+}
+
+/**
+ * Access $cap option using the CheezCap option name
+ *
+ * @param mixed $option Option name
+ * @param bool $echo Should the value be echoed?
+ * @param string $sanitize_callback Callback function used to sanitize the returned value
+ */
+function cheezcap_get_option( $option, $echo = false, $sanitize_callback = '' ) {
+ global $cap;
+
+ $value = $cap->$option;
+
+ if( $sanitize_callback && is_callable( $sanitize_callback ) )
+ $value = call_user_func( $sanitize_callback, $value );
- $pgName = "$themename Settings";
- $hook = add_menu_page( $pgName, $pgName, isset( $req_cap_to_edit ) ? $req_cap_to_edit : 'manage_options', basename( __FILE__ ), 'top_level_settings', isset( $cap_icon_url ) ? $cap_icon_url : $default, isset( $cap_menu_position ) ? $cap_menu_position : $default );
- add_action( "admin_print_scripts-$hook", 'cap_admin_js_libs' );
- add_action( "admin_footer-$hook", 'cap_admin_js_footer' );
- add_action( "admin_print_styles-$hook", 'cap_admin_css' );
+ if( $echo )
+ echo $value;
+ else
+ return $value;
}
diff --git a/config.php b/config.php
index e8a1e3f..11060f0 100644
--- a/config.php
+++ b/config.php
@@ -1,132 +1,168 @@
'CheezCap', // used on the title of the custom admin page
+ 'req_cap_to_edit' => 'manage_options', // the user capability that is required to access the CheezCap settings page
+ 'cap_menu_position' => 99, // OPTIONAL: This value represents the order in the dashboard menu that the CheezCap menu will display in. Larger numbers push it further down.
+ 'cap_icon_url' => '', // OPTIONAL: Path to a custom icon for the CheezCap menu item. ex. $cap_icon_url = WP_CONTENT_URL . '/your-theme-name/images/awesomeicon.png'; Image size should be around 20px x 20px.
+ )
+);
+
+
+/**
+ * Custom validation callback
+ *
+ * @param $key cheezcap option key
+ * @param mixed $value value of option
+ *
+ */
+function my_validation_cb( $key, $value ) {
+ switch ( $key ) {
+ case 'my-date':
+ // Perform date specific validation
+ break;
+ default:
+ // Treat everything else as string
+ $value = filter_var( $value, FILTER_SANITIZE_STRING );
+ }
+ return $value;
}
diff --git a/library.php b/library.php
index 6891a6c..2b2f49a 100644
--- a/library.php
+++ b/library.php
@@ -1,174 +1,433 @@
name = $_name;
$this->id = "cap_$_id";
$this->options = $_options;
}
- function WriteHtml() {
+ function write_html() {
?>
name = $_name;
$this->desc = $_desc;
$this->id = "cap_$_id";
$this->_key = $_id;
$this->std = $_std;
+ if ( $_validation_cb && is_callable( $_validation_cb ) ) {
+ $this->validation_cb = $_validation_cb;
+ }
}
- function WriteHtml() {
- echo '';
+ function write_html() {
}
- function Update( $ignored ) {
- $value = stripslashes_deep( $_POST[$this->id] );
- update_option( $this->id, $value );
+ function update( $ignored = '' ) {
+ $value = isset( $_POST[$this->id] ) ? $_POST[$this->id] : '';
+ $this->save( $value );
}
- function Reset( $ignored ) {
- update_option( $this->id, $this->std );
+ function reset( $ignored = '' ) {
+ $this->save( $this->std );
}
- function Import( $data ) {
+ function import( $data ) {
if ( array_key_exists( $this->id, $data->dict ) )
- update_option( $this->id, $data->dict[$this->id] );
+ $this->save( $data->dict[$this->id] );
}
- function Export( $data ) {
+ function export( $data ) {
$data->dict[$this->id] = get_option( $this->id );
}
+ function save( $value ) {
+ if ( $this->validation_cb )
+ $value = call_user_func($this->validation_cb, $this->id, $value);
+ else
+ $value = stripslashes_deep( $value );
+ update_option( $this->id, $value );
+ }
+
function get() {
return get_option( $this->id );
}
}
-class TextOption extends Option {
+/**
+ * Adds support for selecting any media libarary
+ * content. If image, the URL will be saved, otherwise
+ * the attachment Id will be saved in wp_options
+ *
+ */
+class CheezCapMediaOption extends CheezCapOption {
+ var $options;
+
+ function __construct( $_name, $_desc, $_id, $_std = '' ) {
+ parent::__construct( $_name, $_desc, $_id, $_std );
+ }
+
+ function write_html() {
+
+ // Pre-reqs for loading the WP media-upload modal
+ wp_enqueue_script( 'jquery' );
+ wp_enqueue_script( 'media-upload' );
+ wp_enqueue_script( 'thickbox' );
+ wp_enqueue_style( 'thickbox' );
+ wp_enqueue_media();
+
+ $is_img = false;
+
+ // Populate the default option or the saved one
+ $stdText = $this->std;
+ $stdTextOption = get_option( $this->id );
+
+ $val = (int) $stdTextOption;
+
+ // User chose an image
+ if ( $val == 0 ) {
+ $stdText = $stdTextOption;
+ $is_img = true;
+ }
+
+ // User chose a non-image file
+ else {
+
+ $stdText = $val;
+
+ // Get the attachment object
+ $attach = get_post( $val );
+
+ // Extract filename
+ if ( isset( $attach->guid ) ) {
+ $guid = $attach->guid;
+ $arr = explode( '/', $guid );
+ $filename = $arr[ count( $arr ) - 1 ];
+ }
+ }
+
+ ?>
+
+
+
+
+ name ); ?> |
+
+
+ |
+
+
+
+
+ desc ); ?>
+ |
+
+
+
+ id, $this->std );
+ if ( strtolower( $value ) == 'disabled' )
+ return false;
+ return $value;
+ }
+}
+
+class CheezCapTextOption extends CheezCapOption {
var $useTextArea;
- function TextOption( $_name, $_desc, $_id, $_std = '', $_useTextArea = false ) {
- $this->Option( $_name, $_desc, $_id, $_std );
+ function __construct( $_name, $_desc, $_id, $_std = '', $_useTextArea = false, $_validation_cb = false ) {
+ parent::__construct( $_name, $_desc, $_id, $_std, $_validation_cb );
$this->useTextArea = $_useTextArea;
}
- function WriteHtml() {
+ function save( $value ) {
+ parent::save( $this->sanitize( $value ) );
+ }
+
+ function write_html() {
$stdText = $this->std;
$stdTextOption = get_option( $this->id );
- if ( ! empty( $stdTextOption ) )
+ if ( ! empty( $stdTextOption ) )
$stdText = $stdTextOption;
?>
- name . ':' ); ?> |
- useTextArea ) :
- $commentWidth = 1;
- ?>
-
-
- |
-
+ | |
+ useTextArea ) :
+ $commentWidth = 1; ?>
+
+
+
+ |
+
+
|
-
desc ); ?> |
|
+
+
+
+ |
+
+
+
|
+
useTextArea )
+ return wp_filter_post_kses( $value );
+ else
+ return strip_tags( $value );
+ }
+
function get() {
$value = get_option( $this->id );
if ( empty( $value ) )
return $this->std;
- return $value;
+ return $this->sanitize( $value );
}
}
-class DropdownOption extends Option {
+class CheezCapDropdownOption extends CheezCapOption {
var $options;
- function DropdownOption( $_name, $_desc, $_id, $_options, $_stdIndex = 0 ) {
- $this->Option( $_name, $_desc, $_id, $_stdIndex );
+ function __construct( $_name, $_desc, $_id, $_options, $_stdIndex = 0, $_options_labels = array(), $_validation_cb = false ) {
+ $_std = ! isset( $_options[$_stdIndex] ) ? $_options[0] : $_options[$_stdIndex];
+ parent::__construct( $_name, $_desc, $_id, $_std, $_validation_cb );
$this->options = $_options;
+ $this->options_labels = $_options_labels;
}
- function WriteHtml() {
+ function save( $value ) {
+ if( ! in_array( $value, $this->options ) )
+ $this->reset();
+ parent::save( $value );
+ }
+
+ function write_html() {
?>
- name ); ?> |
+ |
|
- desc ); ?>
+
|
id, $this->std );
- if ( strtolower( $value ) == 'disabled' )
+ if ( strtolower( $value ) == 'disabled' )
return false;
- return $value;
+ return $this->sanitize( $value );
}
}
-class BooleanOption extends DropdownOption {
+class CheezCapBooleanOption extends CheezCapDropdownOption {
var $default;
- function BooleanOption( $_name, $_desc, $_id, $_default = false ) {
+ function __construct( $_name, $_desc, $_id, $_default = false ) {
$this->default = $_default;
- $this->DropdownOption( $_name, $_desc, $_id, array( 'Disabled', 'Enabled' ), $_default ? 1 : 0 );
+ parent::__construct( $_name, $_desc, $_id, array( 0, 1 ), $_default ? 0 : 1, array( 'Disabled', 'Enabled' ) );
}
function get() {
@@ -179,6 +438,8 @@ function get() {
case 'true':
case 'enable':
case 'enabled':
+ case '1':
+ case 1:
return true;
default:
return false;
@@ -186,130 +447,45 @@ function get() {
}
}
-// This class is the handy short cut for accessing config options
-//
-// $cap->post_ratings is the same as get_bool_option("cap_post_ratings", false)
-//
-class autoconfig {
- private $data = false;
- private $cache = array();
-
- function init() {
- if ( $this->data )
- return;
-
- $this->data = array();
- $options = cap_get_options();
+class CheezCapMultipleCheckboxesOption extends CheezCapOption {
+ var $options_checked;
+ var $options;
+ var $options_labels;
- foreach ( $options as $group ) {
- foreach( $group->options as $option ) {
- $this->data[$option->_key] = $option;
- }
- }
+ function __construct( $_name, $_desc, $_id, $_options, $_options_labels = array(), $_options_checked, $_validation_cb = false ) {
+ $this->options = $_options;
+ $this->options_labels = $_options_labels;
+ parent::__construct( $_name, $_desc, $_id, '', $_validation_cb );
+ $this->options_checked = is_array( $_options_checked ) ? $_options_checked : $this->get();
}
- public function __get( $name ) {
- $this->init();
-
- if ( array_key_exists( $name, $this->cache ) )
- return $this->cache[$name];
-
- $option = $this->data[$name];
- if ( empty( $option ) )
- throw new Exception( "Unknown key: $name" );
+ function write_html() {
+ ?>
+
+ |
+
+
+
+ options as $option ) : ?>
+ options_checked ) ? ' checked="checked" ' : ''; ?>
+ options_labels[$count] ) ? $this->options_labels[$count] : $option; ?>
+ />
+
+
+
+
- $value = $this->cache[$name] = $option->get();
- return $value;
+ |
+
+
+
+
+ |
+
+
-
-
' . esc_html( $themename . ' settings saved.' ) . '
';
- if ( isset( $_REQUEST['reset'] ) )
- echo '