PageRenderTime 42ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/wp-pagenavi/scb/AdminPage.php

https://github.com/EthanBlast/Glam-Star-Life
PHP | 463 lines | 284 code | 115 blank | 64 comment | 38 complexity | aa830c0935c95cfc166e755293ccf472 MD5 | raw file
  1. <?php
  2. /*
  3. Creates an admin page
  4. You must set $this->args and define the page_content() method
  5. */
  6. abstract class scbAdminPage {
  7. /** Page args
  8. * $toplevel string If not empty, will create a new top level menu
  9. * $icon string Path to an icon for the top level menu
  10. * $parent string ( default: options-general.php )
  11. * $capability string ( default: 'manage_options' )
  12. * $page_title string ( mandatory )
  13. * $menu_title string ( default: $page_title )
  14. * $page_slug string ( default: sanitized $page_title )
  15. * $nonce string ( default: $page_slug )
  16. * $action_link string|bool Text of the action link on the Plugins page ( default: 'Settings' )
  17. */
  18. protected $args;
  19. // URL to the current plugin directory.
  20. // Useful for adding css and js files
  21. protected $plugin_url;
  22. // Created at page init
  23. protected $pagehook;
  24. // scbOptions object holder
  25. // Normally, it's used for storing formdata
  26. protected $options;
  27. protected $option_name;
  28. // l10n
  29. protected $textdomain;
  30. // Formdata used for filling the form elements
  31. protected $formdata = array();
  32. // ____________REGISTRATION COMPONENT____________
  33. private static $registered = array();
  34. static function register( $class, $file, $options = null ) {
  35. if ( isset( self::$registered[$class] ) )
  36. return false;
  37. self::$registered[$class] = array( $file, $options );
  38. add_action( '_admin_menu', array( __CLASS__, '_pages_init' ) );
  39. return true;
  40. }
  41. static function replace( $old_class, $new_class ) {
  42. if ( ! isset( self::$registered[$old_class] ) )
  43. return false;
  44. self::$registered[$new_class] = self::$registered[$old_class];
  45. unset( self::$registered[$old_class] );
  46. return true;
  47. }
  48. static function remove( $class ) {
  49. if ( ! isset( self::$registered[$class] ) )
  50. return false;
  51. unset( self::$registered[$class] );
  52. return true;
  53. }
  54. static function _pages_init() {
  55. foreach ( self::$registered as $class => $args )
  56. new $class( $args[0], $args[1] );
  57. }
  58. // ____________MAIN METHODS____________
  59. // Constructor
  60. function __construct( $file, $options = NULL ) {
  61. if ( NULL !== $options ) {
  62. $this->options = $options;
  63. $this->formdata = $this->options->get();
  64. }
  65. $this->file = $file;
  66. $this->plugin_url = plugin_dir_url( $file );
  67. $this->setup();
  68. $this->check_args();
  69. if ( isset( $this->option_name ) ) {
  70. add_action( 'admin_init', array( $this, 'option_init' ) );
  71. if ( function_exists( 'settings_errors' ) )
  72. add_action( 'admin_notices', 'settings_errors' );
  73. }
  74. add_action( 'admin_menu', array( $this, 'page_init' ) );
  75. add_filter( 'contextual_help', array( $this, '_contextual_help' ), 10, 2 );
  76. if ( $this->args['action_link'] )
  77. add_filter( 'plugin_action_links_' . plugin_basename( $file ), array( $this, '_action_link' ) );
  78. }
  79. // This is where all the page args can be set
  80. function setup(){}
  81. // This is where the css and js go
  82. // Both wp_enqueue_*() and inline code can be added
  83. function page_head(){}
  84. // This is where the contextual help goes
  85. // @return string
  86. function page_help(){}
  87. // A generic page header
  88. function page_header() {
  89. echo "<div class='wrap'>\n";
  90. screen_icon();
  91. echo "<h2>" . $this->args['page_title'] . "</h2>\n";
  92. }
  93. // This is where the page content goes
  94. abstract function page_content();
  95. // A generic page footer
  96. function page_footer() {
  97. echo "</div>\n";
  98. }
  99. // This is where the form data should be validated
  100. function validate( $new_data, $old_data ) {
  101. return $new_data;
  102. }
  103. // Manually handle option saving ( use Settings API instead )
  104. function form_handler() {
  105. if ( empty( $_POST['action'] ) )
  106. return false;
  107. check_admin_referer( $this->nonce );
  108. $new_data = array();
  109. foreach ( array_keys( $this->formdata ) as $key )
  110. $new_data[$key] = @$_POST[$key];
  111. $new_data = stripslashes_deep( $new_data );
  112. $this->formdata = $this->validate( $new_data, $this->formdata );
  113. if ( isset( $this->options ) )
  114. $this->options->set( $this->formdata );
  115. $this->admin_msg();
  116. }
  117. // Manually generate a standard admin notice ( use Settings API instead )
  118. function admin_msg( $msg = '', $class = "updated" ) {
  119. if ( empty( $msg ) )
  120. $msg = __( 'Settings <strong>saved</strong>.', $this->textdomain );
  121. echo "<div class='$class fade'><p>$msg</p></div>\n";
  122. }
  123. // ____________UTILITIES____________
  124. // Generates a form submit button
  125. function submit_button( $value = '', $action = 'action', $class = "button" ) {
  126. if ( is_array( $value ) ) {
  127. extract( wp_parse_args( $value, array( 'value' => __( 'Save Changes', $this->textdomain ),
  128. 'action' => 'action',
  129. 'class' => 'button',
  130. 'ajax' => true ) ) );
  131. if ( ! $ajax )
  132. $class .= ' no-ajax';
  133. }
  134. else {
  135. if ( empty( $value ) )
  136. $value = __( 'Save Changes', $this->textdomain );
  137. }
  138. $input_args = array( 'type' => 'submit',
  139. 'names' => $action,
  140. 'values' => $value,
  141. 'extra' => '',
  142. 'desc' => false );
  143. if ( ! empty( $class ) )
  144. $input_args['extra'] = "class='{$class}'";
  145. $output = "<p class='submit'>\n" . scbForms::input( $input_args ) . "</p>\n";
  146. return $output;
  147. }
  148. /*
  149. Mimics scbForms::form_wrap()
  150. $this->form_wrap( $content ); // generates a form with a default submit button
  151. $this->form_wrap( $content, false ); // generates a form with no submit button
  152. // the second argument is sent to submit_button()
  153. $this->form_wrap( $content, array( 'text' => 'Save changes',
  154. 'name' => 'action',
  155. 'ajax' => true,
  156. ) );
  157. */
  158. function form_wrap( $content, $submit_button = true ) {
  159. if ( is_array( $submit_button ) ) {
  160. $content .= call_user_func( array( $this, 'submit_button' ), $submit_button );
  161. } elseif ( true === $submit_button ) {
  162. $content .= $this->submit_button();
  163. } elseif ( false !== strpos( $submit_button, '<input' ) ) {
  164. $content .= $submit_button;
  165. } elseif ( false !== $submit_button ) {
  166. $button_args = array_slice( func_get_args(), 1 );
  167. $content .= call_user_func_array( array( $this, 'submit_button' ), $button_args );
  168. }
  169. return scbForms::form_wrap( $content, $this->nonce );
  170. }
  171. // See scbForms::form()
  172. function form( $rows, $formdata = array() ) {
  173. return scbForms::form( $rows, $formdata, $this->nonce );
  174. }
  175. // Generates a table wrapped in a form
  176. function form_table( $rows, $formdata = array() ) {
  177. $output = '';
  178. foreach ( $rows as $row )
  179. $output .= $this->table_row( $row, $formdata );
  180. $output = $this->form_table_wrap( $output );
  181. return $output;
  182. }
  183. // Wraps the given content in a <form><table>
  184. function form_table_wrap( $content ) {
  185. $output = $this->table_wrap( $content );
  186. $output = $this->form_wrap( $output, $this->nonce );
  187. return $output;
  188. }
  189. // Generates a form table
  190. function table( $rows, $formdata = array() ) {
  191. $output = '';
  192. foreach ( $rows as $row )
  193. $output .= $this->table_row( $row, $formdata );
  194. $output = $this->table_wrap( $output );
  195. return $output;
  196. }
  197. // Generates a table row
  198. function table_row( $args, $formdata = array() ) {
  199. return $this->row_wrap( $args['title'], $this->input( $args, $formdata ) );
  200. }
  201. // Wraps the given content in a <table>
  202. function table_wrap( $content ) {
  203. return
  204. html( 'table class="form-table"', $content );
  205. }
  206. // Wraps the given content in a <tr><td>
  207. function row_wrap( $title, $content ) {
  208. return
  209. html( 'tr',
  210. html( 'th scope="row"', $title )
  211. .html( 'td', $content ) );
  212. }
  213. function input( $args, $formdata = array() ) {
  214. if ( empty( $formdata ) )
  215. $formdata = $this->formdata;
  216. if ( isset( $args['name_tree'] ) ) {
  217. $tree = ( array ) $args['name_tree'];
  218. unset( $args['name_tree'] );
  219. $value = $formdata;
  220. $name = $this->option_name;
  221. foreach ( $tree as $key ) {
  222. $value = $value[$key];
  223. $name .= '[' . $key . ']';
  224. }
  225. $args['name'] = $name;
  226. unset( $args['names'] );
  227. unset( $args['values'] );
  228. $formdata = array( $name => $value );
  229. }
  230. return scbForms::input( $args, $formdata );
  231. }
  232. // Mimic scbForms inheritance
  233. function __call( $method, $args ) {
  234. return call_user_func_array( array( 'scbForms', $method ), $args );
  235. }
  236. // Wraps a string in a <script> tag
  237. function js_wrap( $string ) {
  238. return "\n<script type='text/javascript'>\n" . $string . "\n</script>\n";
  239. }
  240. // Wraps a string in a <style> tag
  241. function css_wrap( $string ) {
  242. return "\n<style type='text/css'>\n" . $string . "\n</style>\n";
  243. }
  244. // ____________INTERNAL METHODS____________
  245. // Registers a page
  246. function page_init() {
  247. extract( $this->args );
  248. if ( ! $toplevel ) {
  249. $this->pagehook = add_submenu_page( $parent, $page_title, $menu_title, $capability, $page_slug, array( $this, '_page_content_hook' ) );
  250. } else {
  251. $func = 'add_' . $toplevel . '_page';
  252. $this->pagehook = $func( $page_title, $menu_title, $capability, $page_slug, array( $this, '_page_content_hook' ), $icon_url );
  253. }
  254. if ( ! $this->pagehook )
  255. return;
  256. if ( $ajax_submit ) {
  257. $this->ajax_response();
  258. add_action( 'admin_footer', array( $this, 'ajax_submit' ), 20 );
  259. }
  260. add_action( 'admin_print_styles-' . $this->pagehook, array( $this, 'page_head' ) );
  261. }
  262. function option_init() {
  263. register_setting( $this->option_name, $this->option_name, array( $this, 'validate' ) );
  264. }
  265. private function check_args() {
  266. if ( empty( $this->args['page_title'] ) )
  267. trigger_error( 'Page title cannot be empty', E_USER_WARNING );
  268. $this->args = wp_parse_args( $this->args, array(
  269. 'toplevel' => '',
  270. 'icon' => '',
  271. 'parent' => 'options-general.php',
  272. 'capability' => 'manage_options',
  273. 'menu_title' => $this->args['page_title'],
  274. 'page_slug' => '',
  275. 'nonce' => '',
  276. 'action_link' => __( 'Settings', $this->textdomain ),
  277. 'ajax_submit' => false,
  278. ) );
  279. if ( empty( $this->args['page_slug'] ) )
  280. $this->args['page_slug'] = sanitize_title_with_dashes( $this->args['menu_title'] );
  281. if ( empty( $this->args['nonce'] ) )
  282. $this->nonce = $this->args['page_slug'];
  283. }
  284. function _contextual_help( $help, $screen ) {
  285. if ( is_object( $screen ) )
  286. $screen = $screen->id;
  287. $actual_help = $this->page_help();
  288. if ( $screen == $this->pagehook && $actual_help )
  289. return $actual_help;
  290. return $help;
  291. }
  292. function ajax_response() {
  293. if ( ! isset( $_POST['_ajax_submit'] ) || $_POST['_ajax_submit'] != $this->pagehook )
  294. return;
  295. $this->form_handler();
  296. die;
  297. }
  298. function ajax_submit() {
  299. global $page_hook;
  300. if ( $page_hook != $this->pagehook )
  301. return;
  302. ?>
  303. <script type="text/javascript">
  304. jQuery( document ).ready( function( $ ){
  305. var $spinner = $( new Image() ).attr( 'src', '<?php echo admin_url( "images/wpspin_light.gif" ); ?>' );
  306. $( ':submit' ).click( function( ev ){
  307. var $submit = $( this );
  308. var $form = $submit.parents( 'form' );
  309. if ( $submit.hasClass( 'no-ajax' ) || $form.attr( 'method' ).toLowerCase() != 'post' )
  310. return true;
  311. var $this_spinner = $spinner.clone();
  312. $submit.before( $this_spinner ).hide();
  313. var data = $form.serializeArray();
  314. data.push( {name: $submit.attr( 'name' ), value: $submit.val()} );
  315. data.push( {name: '_ajax_submit', value: '<?php echo $this->pagehook; ?>'} );
  316. $.post( location.href, data, function( response ){
  317. var $prev = $( '.wrap > .updated, .wrap > .error' );
  318. var $msg = $( response ).hide().insertAfter( $( '.wrap h2' ) );
  319. if ( $prev.length > 0 )
  320. $prev.fadeOut( 'slow', function(){ $msg.fadeIn( 'slow' ); } );
  321. else
  322. $msg.fadeIn( 'slow' );
  323. $this_spinner.hide();
  324. $submit.show();
  325. } );
  326. ev.stopPropagation();
  327. ev.preventDefault();
  328. } );
  329. } );
  330. </script>
  331. <?php
  332. }
  333. function _page_content_hook() {
  334. $this->form_handler();
  335. $this->page_header();
  336. $this->page_content();
  337. $this->page_footer();
  338. }
  339. function _action_link( $links ) {
  340. $url = add_query_arg( 'page', $this->args['page_slug'], admin_url( $this->args['parent'] ) );
  341. $links[] = html_link( $url, $this->args['action_link'] );
  342. return $links;
  343. }
  344. }