PageRenderTime 24ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/_/inc/options-framework.php

https://bitbucket.org/eduplessis/html5-reset-wordpress-theme
PHP | 470 lines | 221 code | 78 blank | 171 comment | 41 complexity | d4a56020378e5cc4cdacf78bb7ac4b10 MD5 | raw file
  1. <?php
  2. /*
  3. Description: A framework for building theme options.
  4. Author: Devin Price
  5. Author URI: http://www.wptheming.com
  6. License: GPLv2
  7. Version: 1.5.2
  8. */
  9. /*
  10. This program is free software; you can redistribute it and/or
  11. modify it under the terms of the GNU General Public License
  12. as published by the Free Software Foundation; either version 2
  13. of the License, or (at your option) any later version.
  14. This program is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. GNU General Public License for more details.
  18. You should have received a copy of the GNU General Public License
  19. along with this program; if not, write to the Free Software
  20. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  21. */
  22. /* If the user can't edit theme options, no use running this plugin */
  23. add_action( 'init', 'optionsframework_rolescheck' );
  24. function optionsframework_rolescheck () {
  25. if ( current_user_can( 'edit_theme_options' ) ) {
  26. // If the user can edit theme options, let the fun begin!
  27. add_action( 'admin_menu', 'optionsframework_add_page');
  28. add_action( 'admin_init', 'optionsframework_init' );
  29. add_action( 'wp_before_admin_bar_render', 'optionsframework_adminbar' );
  30. }
  31. }
  32. /* Loads the file for option sanitization */
  33. add_action( 'init', 'optionsframework_load_sanitization' );
  34. function optionsframework_load_sanitization() {
  35. require_once dirname( __FILE__ ) . '/options-sanitize.php';
  36. }
  37. /*
  38. * Creates the settings in the database by looping through the array
  39. * we supplied in options.php. This is a neat way to do it since
  40. * we won't have to save settings for headers, descriptions, or arguments.
  41. *
  42. * Read more about the Settings API in the WordPress codex:
  43. * http://codex.wordpress.org/Settings_API
  44. *
  45. */
  46. function optionsframework_init() {
  47. // Include the required files
  48. require_once dirname( __FILE__ ) . '/options-interface.php';
  49. require_once dirname( __FILE__ ) . '/options-media-uploader.php';
  50. // Optionally Loads the options file from the theme
  51. $location = apply_filters( 'options_framework_location', array( 'options.php' ) );
  52. $optionsfile = locate_template( $location );
  53. // Load settings
  54. $optionsframework_settings = get_option('optionsframework' );
  55. // Updates the unique option id in the database if it has changed
  56. if ( function_exists( 'optionsframework_option_name' ) ) {
  57. optionsframework_option_name();
  58. }
  59. elseif ( has_action( 'optionsframework_option_name' ) ) {
  60. do_action( 'optionsframework_option_name' );
  61. }
  62. // If the developer hasn't explicitly set an option id, we'll use a default
  63. else {
  64. $default_themename = get_option( 'stylesheet' );
  65. $default_themename = preg_replace("/\W/", "_", strtolower($default_themename) );
  66. $default_themename = 'optionsframework_' . $default_themename;
  67. if ( isset( $optionsframework_settings['id'] ) ) {
  68. if ( $optionsframework_settings['id'] == $default_themename ) {
  69. // All good, using default theme id
  70. } else {
  71. $optionsframework_settings['id'] = $default_themename;
  72. update_option( 'optionsframework', $optionsframework_settings );
  73. }
  74. }
  75. else {
  76. $optionsframework_settings['id'] = $default_themename;
  77. update_option( 'optionsframework', $optionsframework_settings );
  78. }
  79. }
  80. // If the option has no saved data, load the defaults
  81. if ( ! get_option( $optionsframework_settings['id'] ) ) {
  82. optionsframework_setdefaults();
  83. }
  84. // Registers the settings fields and callback
  85. register_setting( 'optionsframework', $optionsframework_settings['id'], 'optionsframework_validate' );
  86. // Change the capability required to save the 'optionsframework' options group.
  87. add_filter( 'option_page_capability_optionsframework', 'optionsframework_page_capability' );
  88. }
  89. /**
  90. * Ensures that a user with the 'edit_theme_options' capability can actually set the options
  91. * See: http://core.trac.wordpress.org/ticket/14365
  92. *
  93. * @param string $capability The capability used for the page, which is manage_options by default.
  94. * @return string The capability to actually use.
  95. */
  96. function optionsframework_page_capability( $capability ) {
  97. return 'edit_theme_options';
  98. }
  99. /*
  100. * Adds default options to the database if they aren't already present.
  101. * May update this later to load only on plugin activation, or theme
  102. * activation since most people won't be editing the options.php
  103. * on a regular basis.
  104. *
  105. * http://codex.wordpress.org/Function_Reference/add_option
  106. *
  107. */
  108. function optionsframework_setdefaults() {
  109. $optionsframework_settings = get_option( 'optionsframework' );
  110. // Gets the unique option id
  111. $option_name = $optionsframework_settings['id'];
  112. /*
  113. * Each theme will hopefully have a unique id, and all of its options saved
  114. * as a separate option set. We need to track all of these option sets so
  115. * it can be easily deleted if someone wishes to remove the plugin and
  116. * its associated data. No need to clutter the database.
  117. *
  118. */
  119. if ( isset( $optionsframework_settings['knownoptions'] ) ) {
  120. $knownoptions = $optionsframework_settings['knownoptions'];
  121. if ( !in_array( $option_name, $knownoptions ) ) {
  122. array_push( $knownoptions, $option_name );
  123. $optionsframework_settings['knownoptions'] = $knownoptions;
  124. update_option( 'optionsframework', $optionsframework_settings );
  125. }
  126. } else {
  127. $newoptionname = array( $option_name );
  128. $optionsframework_settings['knownoptions'] = $newoptionname;
  129. update_option( 'optionsframework', $optionsframework_settings );
  130. }
  131. // Gets the default options data from the array in options.php
  132. $options =& _optionsframework_options();
  133. // If the options haven't been added to the database yet, they are added now
  134. $values = of_get_default_values();
  135. if ( isset( $values ) ) {
  136. add_option( $option_name, $values ); // Add option with default settings
  137. }
  138. }
  139. /* Add a subpage called "Theme Options" to the appearance menu. */
  140. if ( !function_exists( 'optionsframework_add_page' ) ) {
  141. function optionsframework_add_page() {
  142. $of_page = add_theme_page( __('Theme Options', 'options_framework_theme'), __('Theme Options', 'options_framework_theme'), 'edit_theme_options', 'options-framework','optionsframework_page' );
  143. // Load the required CSS and javscript
  144. add_action( 'admin_enqueue_scripts', 'optionsframework_load_scripts' );
  145. add_action( 'admin_print_styles-' . $of_page, 'optionsframework_load_styles' );
  146. }
  147. }
  148. /* Loads the CSS */
  149. function optionsframework_load_styles() {
  150. wp_enqueue_style( 'optionsframework', OPTIONS_FRAMEWORK_DIRECTORY.'css/optionsframework.css' );
  151. if ( !wp_style_is( 'wp-color-picker','registered' ) ) {
  152. wp_register_style( 'wp-color-picker', OPTIONS_FRAMEWORK_DIRECTORY.'css/color-picker.min.css' );
  153. }
  154. wp_enqueue_style( 'wp-color-picker' );
  155. }
  156. /* Loads the javascript */
  157. function optionsframework_load_scripts( $hook ) {
  158. if ( 'appearance_page_options-framework' != $hook )
  159. return;
  160. // Enqueue colorpicker scripts for versions below 3.5 for compatibility
  161. if ( !wp_script_is( 'wp-color-picker', 'registered' ) ) {
  162. wp_register_script( 'iris', OPTIONS_FRAMEWORK_DIRECTORY . 'js/iris.min.js', array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), false, 1 );
  163. wp_register_script( 'wp-color-picker', OPTIONS_FRAMEWORK_DIRECTORY . 'js/color-picker.min.js', array( 'jquery', 'iris' ) );
  164. $colorpicker_l10n = array(
  165. 'clear' => __( 'Clear','options_framework_theme' ),
  166. 'defaultString' => __( 'Default', 'options_framework_theme' ),
  167. 'pick' => __( 'Select Color', 'options_framework_theme' )
  168. );
  169. wp_localize_script( 'wp-color-picker', 'wpColorPickerL10n', $colorpicker_l10n );
  170. }
  171. // Enqueue custom option panel JS
  172. wp_enqueue_script( 'options-custom', OPTIONS_FRAMEWORK_DIRECTORY . 'js/options-custom.js', array( 'jquery','wp-color-picker' ) );
  173. // Inline scripts from options-interface.php
  174. add_action( 'admin_head', 'of_admin_head' );
  175. }
  176. function of_admin_head() {
  177. // Hook to add custom scripts
  178. do_action( 'optionsframework_custom_scripts' );
  179. }
  180. /*
  181. * Builds out the options panel.
  182. *
  183. * If we were using the Settings API as it was likely intended we would use
  184. * do_settings_sections here. But as we don't want the settings wrapped in a table,
  185. * we'll call our own custom optionsframework_fields. See options-interface.php
  186. * for specifics on how each individual field is generated.
  187. *
  188. * Nonces are provided using the settings_fields()
  189. *
  190. */
  191. if ( !function_exists( 'optionsframework_page' ) ) :
  192. function optionsframework_page() {
  193. settings_errors(); ?>
  194. <div id="optionsframework-wrap" class="wrap">
  195. <?php screen_icon( 'themes' ); ?>
  196. <h2 class="nav-tab-wrapper">
  197. <?php echo optionsframework_tabs(); ?>
  198. </h2>
  199. <div id="optionsframework-metabox" class="metabox-holder">
  200. <div id="optionsframework" class="postbox">
  201. <form action="options.php" method="post">
  202. <?php settings_fields( 'optionsframework' ); ?>
  203. <?php optionsframework_fields(); /* Settings */ ?>
  204. <div id="optionsframework-submit">
  205. <input type="submit" class="button-primary" name="update" value="<?php esc_attr_e( 'Save Options', 'options_framework_theme' ); ?>" />
  206. <input type="submit" class="reset-button button-secondary" name="reset" value="<?php esc_attr_e( 'Restore Defaults', 'options_framework_theme' ); ?>" onclick="return confirm( '<?php print esc_js( __( 'Click OK to reset. Any theme settings will be lost!', 'options_framework_theme' ) ); ?>' );" />
  207. <div class="clear"></div>
  208. </div>
  209. </form>
  210. </div> <!-- / #container -->
  211. </div>
  212. <?php do_action( 'optionsframework_after' ); ?>
  213. </div> <!-- / .wrap -->
  214. <?php
  215. }
  216. endif;
  217. /**
  218. * Validate Options.
  219. *
  220. * This runs after the submit/reset button has been clicked and
  221. * validates the inputs.
  222. *
  223. * @uses $_POST['reset'] to restore default options
  224. */
  225. function optionsframework_validate( $input ) {
  226. /*
  227. * Restore Defaults.
  228. *
  229. * In the event that the user clicked the "Restore Defaults"
  230. * button, the options defined in the theme's options.php
  231. * file will be added to the option for the active theme.
  232. */
  233. if ( isset( $_POST['reset'] ) ) {
  234. add_settings_error( 'options-framework', 'restore_defaults', __( 'Default options restored.', 'options_framework_theme' ), 'updated fade' );
  235. return of_get_default_values();
  236. }
  237. /*
  238. * Update Settings
  239. *
  240. * This used to check for $_POST['update'], but has been updated
  241. * to be compatible with the theme customizer introduced in WordPress 3.4
  242. */
  243. $clean = array();
  244. $options =& _optionsframework_options();
  245. foreach ( $options as $option ) {
  246. if ( ! isset( $option['id'] ) ) {
  247. continue;
  248. }
  249. if ( ! isset( $option['type'] ) ) {
  250. continue;
  251. }
  252. $id = preg_replace( '/[^a-zA-Z0-9._\-]/', '', strtolower( $option['id'] ) );
  253. // Set checkbox to false if it wasn't sent in the $_POST
  254. if ( 'checkbox' == $option['type'] && ! isset( $input[$id] ) ) {
  255. $input[$id] = false;
  256. }
  257. // Set each item in the multicheck to false if it wasn't sent in the $_POST
  258. if ( 'multicheck' == $option['type'] && ! isset( $input[$id] ) ) {
  259. foreach ( $option['options'] as $key => $value ) {
  260. $input[$id][$key] = false;
  261. }
  262. }
  263. // For a value to be submitted to database it must pass through a sanitization filter
  264. if ( has_filter( 'of_sanitize_' . $option['type'] ) ) {
  265. $clean[$id] = apply_filters( 'of_sanitize_' . $option['type'], $input[$id], $option );
  266. }
  267. }
  268. // Hook to run after validation
  269. do_action( 'optionsframework_after_validate', $clean );
  270. return $clean;
  271. }
  272. /**
  273. * Display message when options have been saved
  274. */
  275. function optionsframework_save_options_notice() {
  276. add_settings_error( 'options-framework', 'save_options', __( 'Options saved.', 'options_framework_theme' ), 'updated fade' );
  277. }
  278. add_action( 'optionsframework_after_validate', 'optionsframework_save_options_notice' );
  279. /**
  280. * Format Configuration Array.
  281. *
  282. * Get an array of all default values as set in
  283. * options.php. The 'id','std' and 'type' keys need
  284. * to be defined in the configuration array. In the
  285. * event that these keys are not present the option
  286. * will not be included in this function's output.
  287. *
  288. * @return array Rey-keyed options configuration array.
  289. *
  290. * @access private
  291. */
  292. function of_get_default_values() {
  293. $output = array();
  294. $config =& _optionsframework_options();
  295. foreach ( (array) $config as $option ) {
  296. if ( ! isset( $option['id'] ) ) {
  297. continue;
  298. }
  299. if ( ! isset( $option['std'] ) ) {
  300. continue;
  301. }
  302. if ( ! isset( $option['type'] ) ) {
  303. continue;
  304. }
  305. if ( has_filter( 'of_sanitize_' . $option['type'] ) ) {
  306. $output[$option['id']] = apply_filters( 'of_sanitize_' . $option['type'], $option['std'], $option );
  307. }
  308. }
  309. return $output;
  310. }
  311. /**
  312. * Add Theme Options menu item to Admin Bar.
  313. */
  314. function optionsframework_adminbar() {
  315. global $wp_admin_bar;
  316. $wp_admin_bar->add_menu( array(
  317. 'parent' => 'appearance',
  318. 'id' => 'of_theme_options',
  319. 'title' => __( 'Theme Options', 'options_framework_theme' ),
  320. 'href' => admin_url( 'themes.php?page=options-framework' )
  321. ));
  322. }
  323. /**
  324. * Wrapper for optionsframework_options()
  325. *
  326. * Allows for manipulating or setting options via 'of_options' filter
  327. * For example:
  328. *
  329. * <code>
  330. * add_filter('of_options', function($options) {
  331. * $options[] = array(
  332. * 'name' => 'Input Text Mini',
  333. * 'desc' => 'A mini text input field.',
  334. * 'id' => 'example_text_mini',
  335. * 'std' => 'Default',
  336. * 'class' => 'mini',
  337. * 'type' => 'text'
  338. * );
  339. *
  340. * return $options;
  341. * });
  342. * </code>
  343. *
  344. * Also allows for setting options via a return statement in the
  345. * options.php file. For example (in options.php):
  346. *
  347. * <code>
  348. * return array(...);
  349. * </code>
  350. *
  351. * @return array (by reference)
  352. */
  353. function &_optionsframework_options() {
  354. static $options = null;
  355. if ( !$options ) {
  356. // Load options from options.php file (if it exists)
  357. $location = apply_filters( 'options_framework_location', array('options.php') );
  358. if ( $optionsfile = locate_template( $location ) ) {
  359. $maybe_options = require_once $optionsfile;
  360. if ( is_array($maybe_options) ) {
  361. $options = $maybe_options;
  362. } else if ( function_exists( 'optionsframework_options' ) ) {
  363. $options = optionsframework_options();
  364. }
  365. }
  366. // Allow setting/manipulating options via filters
  367. $options = apply_filters('of_options', $options);
  368. }
  369. return $options;
  370. }
  371. /**
  372. * Get Option.
  373. *
  374. * Helper function to return the theme option value.
  375. * If no value has been saved, it returns $default.
  376. * Needed because options are saved as serialized strings.
  377. */
  378. if ( ! function_exists( 'of_get_option' ) ) {
  379. function of_get_option( $name, $default = false ) {
  380. $config = get_option( 'optionsframework' );
  381. if ( ! isset( $config['id'] ) ) {
  382. return $default;
  383. }
  384. $options = get_option( $config['id'] );
  385. if ( isset( $options[$name] ) ) {
  386. return $options[$name];
  387. }
  388. return $default;
  389. }
  390. }