WPDK  1.5.0
WordPress Development Kit
 All Data Structures Files Functions Variables Pages
wpdk-menu.php
Go to the documentation of this file.
1 <?php
28 class WPDKMenu {
29 
35  const DEFAULT_CAPABILITY = 'read';
41  const GLOBAL_MENU = 'wpdk_menus';
49  public $capability;
57  public $hookName;
65  public $icon;
73  public $id;
81  public $menuTitle;
89  public $position;
97  public $subMenus;
98 
113  public function __construct( $id, $menu_title, $capability = self::DEFAULT_CAPABILITY, $icon = '', $position = null ) {
114  $this->id = sanitize_title( $id );
115  $this->menuTitle = $menu_title;
116  $this->pageTitle = $menu_title;
117  $this->capability = $capability;
118  $this->position = $position;
119  $this->icon = $icon;
120  $this->subMenus = array();
121  }
122 
132  public static function sanitizeViewController( $view_controller )
133  {
134  $result = '';
135 
136  if ( is_string( $view_controller ) ) {
137  $result = $view_controller;
138  }
139  elseif ( is_array( $view_controller ) ) {
140  $result = get_class( $view_controller[0] ) . '-' . $view_controller[1];
141  }
142  return $result;
143  }
144 
152  public static function menu( $view_controller )
153  {
154  $global_key = self::sanitizeViewController( $view_controller );
155 
156  if ( isset( $GLOBALS[self::GLOBAL_MENU] ) ) {
157  if ( !empty( $global_key ) && !empty( $GLOBALS[self::GLOBAL_MENU][$global_key] ) ) {
158  return $GLOBALS[self::GLOBAL_MENU][$global_key];
159  }
160  }
161  else {
162  $GLOBALS[self::GLOBAL_MENU] = array();
163  }
164  return null;
165  }
166 
174  public static function url( $view_controller )
175  {
176  $info = self::menu( $view_controller );
177 
178  $url = '';
179  if ( !empty( $info ) && isset( $info['parent'] ) ) {
180 
181  if ( false === strpos( $info['parent'], '.php' ) ) {
182  $url = add_query_arg( array( 'page' => $info['page'] ), admin_url( 'admin.php' ) );
183  }
184  else {
185  $url = add_query_arg( array( 'page' => $info['page'] ), admin_url( $info['parent'] ) );
186  }
187  }
188  return $url;
189  }
190 
201  public static function hook( $view_controller )
202  {
203  $info = self::menu( $view_controller );
204 
205  if ( !empty( $info ) ) {
206  return $info['hook'];
207  }
208  return false;
209  }
210 
221  public static function page( $view_controller )
222  {
223  $info = self::menu( $view_controller );
224 
225  if ( !empty( $info ) ) {
226  return $info['page'];
227  }
228  return false;
229  }
230 
268  public static function renderByArray( $menus ) {
269 
270  $result = array();
271 
272  foreach ( $menus as $key => $value ) {
273  if ( is_array( $value ) ) {
274 
275  $menu = new WPDKMenu( $key, $value['menuTitle'], $value['capability'], $value['icon'] );
276 
277  foreach ( $value['subMenus'] as $skey => $svalue ) {
278 
279  if ( is_string( $svalue ) && WPDKSubMenuDivider::DIVIDER === $svalue ) {
280  $menu->addDivider();
281  }
282  elseif ( is_array( $svalue ) ) {
283  if ( isset( $svalue[WPDKSubMenuDivider::DIVIDER] ) ) {
284  $menu->addDivider( $svalue[WPDKSubMenuDivider::DIVIDER] );
285  }
286  else {
287  $sub_menu = $menu->addSubMenu( $svalue['menuTitle'], $svalue['viewController'] );
288  /* Extra properties for sub menu */
289  foreach ( $svalue as $property => $pvalue ) {
290  $sub_menu->$property = $pvalue;
291  }
292  }
293  }
294  }
295 
296  /* Extra properties for menu */
297  foreach( $value as $property => $pvalue ) {
298  if ( !in_array( $property, array( 'subMenus' ) ) ) {
299  $menu->$property = $pvalue;
300  }
301  }
302 
303  /* Over */
304  $menu->render();
305  $result[$key] = $menu;
306  }
307  }
308  return $result;
309  }
310 
320  public function addDivider( $title = '' )
321  {
322  if ( count( $this->subMenus ) > 0 ) {
323  $divider = new WPDKSubMenuDivider( $this->id, $title );
324  $this->subMenus[$divider->id] = $divider;
325  return $divider;
326  }
327  return false;
328  }
329 
341  public function addSubMenu( $menu_title, $view_controller, $capability = WPDKMenu::DEFAULT_CAPABILITY ) {
342  if ( empty( $this->subMenus ) ) {
343  $id = $this->id;
344  }
345  else {
346  $id = sprintf( '%s-submenu-%s', $this->id, count( $this->subMenus ) );
347  }
348 
349  $sub_menu = new WPDKSubMenu( $this->id, $id, $menu_title, $view_controller, $capability );
350  $this->subMenus[$id] = $sub_menu;
351  return $sub_menu;
352  }
353 
359  public function render() {
360  $this->hookName = add_menu_page( $this->pageTitle, $this->menuTitle, $this->capability, $this->id, '', $this->icon, $this->position );
361 
362  while ( ( $sub_menu = current( $this->subMenus ) ) ) {
363  $next = next( $this->subMenus );
364  if ( is_a( $sub_menu, 'WPDKSubMenuDivider' ) ) {
365  if ( isset( $next ) && isset( $next->capability ) ) {
366  $sub_menu->capability = $next->capability;
367  }
368  }
369  $sub_menu->render();
370  }
371  }
372 
426  public static function addSubMenuAt( &$menus, $menu_item, $index )
427  {
428  $key = key( $menus );
429  if ( isset( $menus[$key]['subMenus'] ) ) {
430  $index = ( $index < 0 ) ? count( $menus[$key]['subMenus'] ) + 1 : $index;
431  $menus[$key]['subMenus'] = WPDKArray::insert( $menus[$key]['subMenus'], array( $menu_item ), $index );
432  }
433  else {
434  $menus[$key] = WPDKArray::insert( $menus[$key], array( $menu_item ), $index );
435  }
436  return $menus;
437  }
438 
467  public static function addSubMenusAt( &$menus, $submenus, $index )
468  {
469  $key = key( $menus );
470  if ( isset( $menus[$key]['subMenus'] ) ) {
471  $pos = ( $index < 0 ) ? count( $menus[$key]['subMenus'] ) + 1 : $index;
472  foreach ( $submenus as $menu ) {
473  $menus[$key]['subMenus'] = WPDKArray::insert( $menus[$key]['subMenus'], array( $menu ), $pos++ );
474  }
475  }
476  else {
477  $pos = ( $index < 0 ) ? count( $menus[$key] ) + 1 : $index;
478  foreach ( $submenus as $menu ) {
479  $menus[$key] = WPDKArray::insert( $menus[$key], array( $menu ), $pos++ );
480  }
481  }
482  return $menus;
483  }
484 
495  public static function isPageWithMenu( $id )
496  {
497  global $plugin_page;
498  if ( $id === $plugin_page ) {
499  return true;
500  }
501  return false;
502  }
503 
504 }
505 
521 class WPDKSubMenu {
522 
528  const DEFAULT_CAPABILITY = 'read';
529 
530  public $capability = self::DEFAULT_CAPABILITY;
531  public $hookName = '';
532  public $id = '';
533  public $menuTitle = '';
534  public $pageTitle = '';
535  public $parent = '';
536  public $viewController = '';
537 
546  public $query_args = array();
547 
562  public function __construct( $parent, $id, $menu_title, $view_controller = '', $capability = self::DEFAULT_CAPABILITY ) {
563  $this->parent = $parent;
564  if ( is_object( $parent ) && is_a( $parent, 'WPDKMenu' ) ) {
565  $this->parent = $parent->id;
566  }
567  $this->id = sanitize_title( $id );
568  $this->menuTitle = $menu_title;
569  $this->pageTitle = $menu_title;
570  $this->capability = $capability;
571  $this->viewController = $view_controller;
572  }
573 
611  public static function renderByArray( $sub_menus ) {
612  $result = array();
613  $index = 1;
614  foreach ( $sub_menus as $parent => $sub_menu ) {
615  foreach ( $sub_menu as $sub_item ) {
616  $item = false;
617  if ( is_string( $sub_item ) && WPDKSubMenuDivider::DIVIDER === $sub_item ) {
618  $item = new WPDKSubMenuDivider( $parent );
619  }
620  elseif ( is_array( $sub_item ) ) {
621  if ( isset( $sub_item[WPDKSubMenuDivider::DIVIDER] ) ) {
622  $item = new WPDKSubMenuDivider( $parent, $sub_item[WPDKSubMenuDivider::DIVIDER] );
623  }
624  else {
625  if( is_array( $sub_item['viewController'] ) ) {
626  $id = sprintf( '%s-submenu-%s', sanitize_title( $sub_item['viewController'][1] ), $index++ );
627  } else {
628  $id = sprintf( '%s-submenu-%s', sanitize_title( $sub_item['viewController'] ), $index++ );
629  }
630  $item = new WPDKSubMenu( $parent, $id, $sub_item['menuTitle'], $sub_item['viewController'] );
631  /* Extra properties */
632  foreach ( $sub_item as $property => $svalue ) {
633  $item->$property = $svalue;
634  }
635  }
636  }
637  if( !empty( $item ) ) {
638  $item->render();
639  }
640  }
641  if( !empty( $item ) ) {
642  $result[] = $item;
643  }
644  }
645  return $result;
646  }
647 
653  public function render()
654  {
655 
656  global $plugin_page;
657 
658  $hook = '';
659  $global_key = WPDKMenu::sanitizeViewController( $this->viewController );
660 
661  if ( !empty( $this->viewController ) && is_string( $this->viewController ) && !function_exists( $this->viewController ) && class_exists( $this->viewController ) ) {
662 
663  // Check for static ::init() method
664  if ( method_exists( $this->viewController, 'init' ) ) {
665  $hook = create_function( '', sprintf( '%s::init()->display();', $this->viewController ) );
666  }
667  else {
668  $hook = create_function( '', sprintf( '$view_controller = new %s; $view_controller->display();', $this->viewController ) );
669  }
670 
671  }
672  // If the callable is in the form array( obj, method ), I have to properly init $hook anyway
673  elseif ( is_callable( $this->viewController ) ) {
674  $hook = $this->viewController;
675  }
676 
677  if( !empty( $global_key ) ) {
678 
679  // Create a global list of my own menu.
680  $GLOBALS[WPDKMenu::GLOBAL_MENU][$global_key ] = array(
681  'parent' => $this->parent,
682  'page' => $this->id,
683  'hook' => '',
684  'menu_title' => ''
685  );
686  }
687 
688  /* Apply filter for change the title. */
689  $menu_title = apply_filters( 'wpdk_submenu_title', $this->menuTitle, $this->id, $this->parent );
690 
691  /* Create the menu item. */
692  $this->hookName = add_submenu_page( $this->parent, $this->pageTitle, $menu_title, $this->capability, $this->id, $hook );
693 
694  /* Check for query args. */
695  if ( isset( $this->query_args ) && !empty( $this->query_args ) ) {
696  $stack = array();
697  foreach ( $this->query_args as $var => $value ) {
698  $stack[] = sprintf( '$_GET["%s"] = $_REQUEST["%s"] = "%s";', $var, $var, $value );
699  }
700  $func = create_function( '', implode( '', $stack ) );
701  add_action( 'load-' . $this->hookName, $func );
702  }
703 
704  /* Execute this action when the page displayed ids for this submenu view. */
705  if( !empty( $plugin_page ) ) {
706  if( $this->id === $plugin_page ) {
707  do_action( 'wpdk_submenu_page', $this, $plugin_page );
708  }
709  }
710 
711  if ( !empty( $this->viewController ) && is_string( $this->viewController ) && !function_exists( $this->viewController && class_exists( $this->viewController ) ) ) {
712 
713  // Check for static ::init() method
714  if ( method_exists( $this->viewController, 'init' ) ) {
715  $load = create_function( '', sprintf( '%s::init()->load();', $this->viewController ) );
716  add_action( 'load-' . $this->hookName, $load );
717 
718  $admin_head = create_function( '', sprintf( '$v=%s::init();$v->admin_head();$v->_admin_head();', $this->viewController ) );
719  add_action( 'admin_head-' . $this->hookName, $admin_head );
720  }
721  //
722  elseif ( !is_callable( $this->viewController ) && class_exists( $this->viewController ) ) {
723  $load = create_function( '', sprintf( '%s::willLoad();', $this->viewController ) );
724  add_action( 'load-' . $this->hookName, $load );
725 
726  $admin_head = create_function( '', sprintf( '%s::didHeadLoad();', $this->viewController ) );
727  add_action( 'admin_head-' . $this->hookName, $admin_head );
728  }
729  }
730 
731  if ( !empty( $global_key ) ) {
732  $GLOBALS[WPDKMenu::GLOBAL_MENU][$global_key]['hook'] = $this->hookName;
733  $GLOBALS[WPDKMenu::GLOBAL_MENU][$global_key]['menu_title'] = $menu_title;
734  }
735  }
736 
737 }
738 
750 
756  const DEFAULT_CAPABILITY = 'manage_options';
762  const DIVIDER = 'wpdk_menu_divider';
763 
774  public function __construct( $parent, $title = '' ) {
775  static $index = 1;
776  $id = sprintf( '%s-%s', self::DIVIDER, $index++ );
777  parent::__construct( $parent, $id, $title );
778  $this->capability = self::DEFAULT_CAPABILITY;
779  }
780 
781 }