PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/library/extensions/theme-options.php

https://github.com/middlesister/Thematic
PHP | 423 lines | 203 code | 81 blank | 139 comment | 37 complexity | aa7ab20e35001a543495887c54d574a3 MD5 | raw file
  1. <?php
  2. /**
  3. * Thematic Theme Options
  4. *
  5. * An improved theme options page using the WP Settings API
  6. * Child themes can use the WP settings api and the filters provided here to
  7. * customize their child theme's options and settings validation. <br>
  8. *
  9. * For Reference: {@link http://codex.wordpress.org/Creating_an_Archive_Index Codex-Creating an Archive Index}
  10. *
  11. * @package ThematicCoreLibrary
  12. * @subpackage ThemeOptions
  13. */
  14. /**
  15. * Sets default options in database if not pre-existent.
  16. * Registers with WP settings API, adds a main section with three settings fields.
  17. *
  18. * Override: childtheme_override_opt_init
  19. *
  20. * @since Thematic 1.0
  21. */
  22. if (function_exists('childtheme_override_opt_init')) {
  23. function thematic_opt_init() {
  24. childtheme_override_opt_init();
  25. }
  26. } else {
  27. function thematic_opt_init() {
  28. // Retrieve current options from database
  29. $current_options = thematic_get_wp_opt('thematic_theme_opt');
  30. $legacy_options = thematic_convert_legacy_opt();
  31. // Check for pre-1.0 options
  32. if ( false !== ( $legacy_options ) ) {
  33. // Theme upgrade: Convert legacy to current format and add to database
  34. add_option( 'thematic_theme_opt', $legacy_options );
  35. }
  36. // If we are missing a 2.0 option, this is an upgrade from previous version
  37. if ( !isset( $current_options['layout'] ) && isset( $current_options['footer_txt'] ) ) {
  38. $current_options = wp_parse_args( $current_options, thematic_default_opt() );
  39. // enable xhtml mode by default on theme upgrades
  40. $current_options['legacy_xhtml'] = 1;
  41. update_option( 'thematic_theme_opt', $current_options );
  42. }
  43. register_setting ('thematic_opt_group', 'thematic_theme_opt', 'thematic_validate_opt');
  44. add_settings_section ('thematic_opt_section_main', '', 'thematic_do_opt_section_main', 'thematic_theme_opt');
  45. add_settings_field ('thematic_insert_opt', __('Index Insert Position', 'thematic') , 'thematic_do_insert_opt' , 'thematic_theme_opt', 'thematic_opt_section_main');
  46. add_settings_field ('thematic_auth_opt', __('Info on Author Page' , 'thematic') , 'thematic_do_auth_opt' , 'thematic_theme_opt', 'thematic_opt_section_main');
  47. add_settings_field ('thematic_footer_opt', __('Text in Footer' , 'thematic') , 'thematic_do_footer_opt' , 'thematic_theme_opt', 'thematic_opt_section_main');
  48. /**
  49. * Filter to enable child themes to hide the legacy mode checkbox
  50. *
  51. * @param bool true
  52. */
  53. if( apply_filters( 'thematic_show_legacymode_checkbox', true ) ) {
  54. // show check box option for restoring legacy xtml1.0 doctype and compatible markup
  55. add_settings_field ('thematic_legacy_xhtml_opt', __('Restore Legacy XHTML1.0 Doctype' , 'thematic'), 'thematic_do_legacy_xhtml_opt' , 'thematic_theme_opt', 'thematic_opt_section_main');
  56. }
  57. // Show checkbox option for removing old options from database
  58. if ( isset( $legacy_options ) && false !== $legacy_options ) {
  59. add_settings_field ('thematic_legacy_opt', __('Remove Legacy Options' , 'thematic'), 'thematic_do_legacy_opt' , 'thematic_theme_opt', 'thematic_opt_section_main');
  60. }
  61. }
  62. }
  63. add_action ('admin_init', 'thematic_opt_init');
  64. /**
  65. * A wrapper for get_option that provides WP multi site compatibility.
  66. *
  67. * Returns an option's value from wp_otions table in database
  68. * or returns false if no value is found for that row
  69. *
  70. * @since Thematic 1.0
  71. */
  72. function thematic_get_wp_opt( $option_name, $default = false ) {
  73. global $blog_id;
  74. if (THEMATIC_MB) {
  75. $opt = get_blog_option( $blog_id, $option_name, $default );
  76. } else {
  77. $opt = get_option( $option_name, $default );
  78. }
  79. return $opt;
  80. }
  81. /**
  82. * Returns or echoes a theme option value by its key
  83. * or returns false if no value is found
  84. *
  85. * @uses thematic_get_wp_opt()
  86. * @since Thematic 1.0
  87. */
  88. function thematic_get_theme_opt( $opt_key, $echo = false ) {
  89. $theme_opt = wp_parse_args( thematic_get_wp_opt( 'thematic_theme_opt', array() ), thematic_default_opt() );
  90. if ( !isset( $theme_opt[$opt_key] ) ) {
  91. return false;
  92. }
  93. if ( false === $echo ) {
  94. return $theme_opt[$opt_key];
  95. } else {
  96. echo $theme_opt[$opt_key];
  97. }
  98. }
  99. /**
  100. * Retrieves legacy Thematic options from database
  101. * Returns theme as a sanitized array or false
  102. *
  103. * @uses thematic_theme_convert_legacy_opt
  104. *
  105. * @since Thematic 1.0
  106. */
  107. function thematic_convert_legacy_opt() {
  108. $thm_insert_position = thematic_get_wp_opt( 'thm_insert_position' );
  109. $thm_authorinfo = thematic_get_wp_opt( 'thm_authorinfo' );
  110. $thm_footertext = thematic_get_wp_opt( 'thm_footertext' );
  111. // Return false if no options found
  112. if ( false === $thm_insert_position && false === $thm_authorinfo && false === $thm_footertext ) {
  113. return false;
  114. }
  115. // Return a sanitized array from legacy options if found
  116. $legacy_sanitized_opt = array(
  117. 'index_insert' => intval( $thm_insert_position ),
  118. 'author_info' => ( $thm_authorinfo == "true" ) ? 1 : 0,
  119. 'footer_txt' => wp_kses_post( $thm_footertext ),
  120. 'del_legacy_opt'=> 0
  121. );
  122. return apply_filters( 'thematic_theme_convert_legacy_opt', $legacy_sanitized_opt );
  123. }
  124. /**
  125. * Returns default theme options.
  126. *
  127. * Filter: thematic_theme_default_opt
  128. *
  129. * @since Thematic 1.0
  130. *
  131. */
  132. function thematic_default_opt() {
  133. $thematic_default_opt = array(
  134. 'index_insert' => 2,
  135. 'author_info' => 0, // 0 = not checked 1 = checked
  136. 'footer_txt' => 'Powered by [wp-link]. Built on the [theme-link].',
  137. 'del_legacy_opt'=> 0, // 0 = not checked 1 = check
  138. 'legacy_xhtml' => 0, // 0 = not checked 1 = check
  139. 'layout' => thematic_default_theme_layout()
  140. );
  141. return apply_filters( 'thematic_theme_default_opt', $thematic_default_opt );
  142. }
  143. /**
  144. * Adds the theme option page as an admin menu item,
  145. * and queues the contextual help on theme options page load
  146. *
  147. * Filter: thematic_theme_add_opt_page
  148. * The filter provides the ability for child themes to customize or remove and add
  149. * their own options page and queue contextual help in one function
  150. *
  151. * @since Thematic 1.0
  152. */
  153. function thematic_opt_add_page() {
  154. $thematic_opt_page = add_theme_page ( __('Theme Options', 'thematic') , __('Theme Options', 'thematic'), 'edit_theme_options', 'thematic_opt', 'thematic_do_opt_page');
  155. $thematic_opt_page = apply_filters ('thematic_theme_add_opt_page', $thematic_opt_page );
  156. if ( ! $thematic_opt_page ) {
  157. return;
  158. }
  159. add_action( "load-$thematic_opt_page", 'thematic_opt_page_help' );
  160. }
  161. add_action( 'admin_menu', 'thematic_opt_add_page' );
  162. /**
  163. * Generates the help texts and help sidebar items for the options screen
  164. *
  165. * Filter: thematic_theme_opt_help_txt <br>
  166. * Filter: thematic_theme_opt_help_sidebar <br>
  167. * Override: childtheme_override_opt_page_help <br>
  168. *
  169. * @since Thematic 1.0
  170. */
  171. if (function_exists('childtheme_override_opt_page_help')) {
  172. function thematic_opt_page_help() {
  173. childtheme_override_opt_page_help();
  174. }
  175. } else {
  176. function thematic_opt_page_help() {
  177. $screen = get_current_screen();
  178. $sidebar = '<p><strong>' . __( 'For more information:', 'thematic') . '</strong></p>';
  179. $sidebar .= '<a href="http://thematictheme.com">ThematicTheme.com</a></p>';
  180. $sidebar .= '<p><strong>' . __('For support:', 'thematic') . '</strong></p>';
  181. $sidebar .= '<a href="http://thematictheme.com/forums/"> Thematic ';
  182. $sidebar .= __('forums', 'thematic' ) . '</a></p>';
  183. $sidebar = apply_filters ( 'thematic_theme_opt_help_sidebar', $sidebar );
  184. $help = '<p>' . __('The options below are enabled by the Thematic Theme and/or a child theme.', 'thematic') .' ';
  185. $help .= __('New options can be added and the default ones removed by creating a child theme. This contextual help can be customized in a child theme also.', 'thematic') . '</p>';
  186. $help = apply_filters ( 'thematic_theme_opt_help_txt', $help );
  187. $screen->add_help_tab( array( 'title' => __( 'Overview', 'thematic' ), 'id' => 'theme-opt-help', 'content' => $help, ) );
  188. $screen->set_help_sidebar( $sidebar );
  189. }
  190. }
  191. /**
  192. * Renders the theme options page
  193. *
  194. * @since Thematic 1.0
  195. */
  196. function thematic_do_opt_page() { ?>
  197. <div class="wrap">
  198. <?php screen_icon(); ?>
  199. <?php
  200. $frameworkData = wp_get_theme();
  201. $theme = $frameworkData->display( 'Name', false );
  202. ?>
  203. <h2><?php printf( _x( '%s Theme Options', '{$current theme} Theme Options', 'thematic' ), $theme ); ?></h2>
  204. <?php settings_errors(); ?>
  205. <form action="options.php" method="post" >
  206. <?php
  207. settings_fields( 'thematic_opt_group' );
  208. do_settings_sections( 'thematic_theme_opt' );
  209. submit_button();
  210. ?>
  211. </form>
  212. </div>
  213. <?php
  214. }
  215. /**
  216. * Renders the "Main" settings section. This is left blank in Thematic and outputs nothing
  217. *
  218. * Filter: thematic_theme_opt_section_main
  219. *
  220. * @since Thematic 1.0
  221. */
  222. function thematic_do_opt_section_main() {
  223. $thematic_opt_section_main = '';
  224. echo ( apply_filters( 'thematic_theme_opt_section_main' , $thematic_opt_section_main ) );
  225. }
  226. /**
  227. * Renders Index Insert elements
  228. *
  229. * @since Thematic 1.0
  230. */
  231. function thematic_do_insert_opt() {
  232. ?>
  233. <input type="text" maxlength="4" size="4" value="<?php esc_attr_e( (thematic_get_theme_opt('index_insert') ) ) ; ?>" id="thm_insert_position" name="thematic_theme_opt[index_insert]">
  234. <label for="thm_insert_position"><?php _e('The Index Insert widget area will appear after this post number. Entering nothing or 0 will disable this feature.','thematic'); ?></label>
  235. <?php
  236. }
  237. /**
  238. * Renders Author Info elements
  239. *
  240. * @since Thematic 1.0
  241. */
  242. function thematic_do_auth_opt() {
  243. ?>
  244. <input id="thm_authorinfo" type="checkbox" value="1" name="thematic_theme_opt[author_info]" <?php checked( thematic_get_theme_opt('author_info') , 1 ); ?> />
  245. <label for="thm_authorinfo"><?php printf( _x('Display a %1$smicroformatted vCard%2$s with the author\'s avatar, bio and email on the author page.', '%1$s and %2$s are <a> tags', 'thematic' ) , '<a target="_blank" href="http://microformats.org/wiki/hcard">', '</a>' ); ?></label>
  246. <?php
  247. }
  248. /**
  249. * Renders Footer Text elements
  250. *
  251. * @since Thematic 1.0
  252. */
  253. function thematic_do_footer_opt() {
  254. ?>
  255. <textarea rows="5" cols="94" id="thm_footertext" name="thematic_theme_opt[footer_txt]"><?php thematic_get_theme_opt('footer_txt', true ); ?></textarea>
  256. <br><?php printf( _x('You can use HTML and shortcodes in your footer text. Shortcode examples: %s', '%s are shortcode tags', 'thematic'), '[wp-link] [theme-link] [loginout-link] [blog-title] [blog-link] [the-year]' ); ?>
  257. <?php
  258. }
  259. /**
  260. * Renders Leagcy XTML1.0 mode checkbox
  261. *
  262. * @since Thematic 2.0
  263. */
  264. function thematic_do_legacy_xhtml_opt() {
  265. ?>
  266. <input id="thm_legacy_xhtml" type="checkbox" value="1" name="thematic_theme_opt[legacy_xhtml]" <?php checked( thematic_get_theme_opt('legacy_xhtml'), 1 ); ?> />
  267. <label for="thm_legacy_xhtml"><?php printf( __( 'Restore the legacy XHTML Doctype and xhtml compatible markup.', 'thematic' ) ) ?></label>
  268. <?php
  269. }
  270. /**
  271. * Renders Legacy Options elements
  272. *
  273. * @since Thematic 1.0
  274. */
  275. function thematic_do_legacy_opt() {
  276. ?>
  277. <input id="thm_legacy_opt" type="checkbox" value="1" name="thematic_theme_opt[del_legacy_opt]" <?php checked( thematic_get_theme_opt('del_legacy_opt'), 1 ); ?> />
  278. <?php
  279. $frameworkData = wp_get_theme();
  280. $theme = $frameworkData->display( 'Name', false );
  281. ?>
  282. <label for="thm_legacy_opt"><?php printf( __( '%s Theme Options have been upgraded to an improved format. Remove the legacy options from the database.', '{$current theme} Theme Options', 'thematic' ), $theme ); ?></label>
  283. <?php
  284. }
  285. /**
  286. * Validates theme options form post data.
  287. * Provides error reporting for invalid input.
  288. *
  289. * Override: childtheme_override_validate_opt <br>
  290. * Filter: thematic_theme_opt_validation
  291. *
  292. * @since Thematic 1.0
  293. */
  294. if (function_exists('childtheme_override_validate_opt')) {
  295. function thematic_validate_opt($input) {
  296. return childtheme_override_validate_opt($input);
  297. }
  298. } else {
  299. function thematic_validate_opt($input){
  300. $output = thematic_get_wp_opt( 'thematic_theme_opt', thematic_default_opt() );
  301. // Index Insert position must be a non-negative number
  302. if ( !is_numeric( $input['index_insert'] ) || $input['index_insert'] < 0 ) {
  303. add_settings_error(
  304. 'thematic_theme_opt',
  305. 'thematic_insert_opt',
  306. __('The index insert position value must be a number equal to or greater than zero. This setting has been reverted to the previous value.', 'thematic' ),
  307. 'error'
  308. );
  309. } else {
  310. // A sanitize numeric value to ensure a whole number
  311. $output['index_insert'] = intval( $input['index_insert'] );
  312. }
  313. // Author Info CheckBox value either 1(yes) or 0(no)
  314. $output['author_info'] = ( isset( $input['author_info'] ) && 1 == $input['author_info'] ? 1 : 0 );
  315. // Footer Text sanitized allowing HTML and WP shortcodes
  316. if ( isset( $input['footer_txt'] ) ) {
  317. $output['footer_txt'] = wp_kses_post( $input['footer_txt'] ) ;
  318. }
  319. // Remove Legacy XHTML CheckBox value either 1(yes) or 0(no)
  320. $output['legacy_xhtml'] = ( isset( $input['legacy_xhtml'] ) && 1 == $input['legacy_xhtml'] ? 1 : 0 );
  321. // Check and set layout
  322. if( isset( $input['layout'] ) ) {
  323. $available_layouts = thematic_available_layout_slugs();
  324. if( in_array( $input['layout'], $available_layouts ) ) {
  325. $output['layout'] = $input['layout'];
  326. } else {
  327. $output['layout'] = thematic_default_theme_layout();
  328. }
  329. }
  330. // Remove Legacy Options CheckBox value either 1(yes) or 0(no)
  331. $output['del_legacy_opt'] = ( isset( $input['del_legacy_opt'] ) && 1 == $input['del_legacy_opt'] ? 1 : 0 );
  332. if ( 1 == $output['del_legacy_opt'] ) {
  333. // Remove options if the choice is yes
  334. delete_option('thm_insert_position');
  335. delete_option('thm_authorinfo');
  336. delete_option('thm_footertext');
  337. // Reset checkbox value to unchecked in case a legacy set of options is ever saved to database again
  338. $output['del_legacy_opt'] = 0;
  339. }
  340. return apply_filters( 'thematic_theme_opt_validation', $output, $input );
  341. }
  342. }