Guest User

Untitled

a guest
Feb 17th, 2019
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.53 KB | None | 0 0
  1. <?php
  2.  
  3. class custom_menu_items {
  4. // only register with wp hooks once
  5. protected $has_registered = false;
  6.  
  7. // internal list of menus affected
  8. public $menus = array();
  9.  
  10. // internal list of new menu items
  11. public $menu_items = array();
  12.  
  13. private function __construct(){}
  14. private function __wakeup() {}
  15. private function __clone() {}
  16.  
  17. /**
  18. * Singleton
  19. *
  20. * @return custom_menu_items
  21. */
  22. static public function get_instance(){
  23. static $instance = null;
  24.  
  25. if ( is_null( $instance ) ){
  26. $instance = new self;
  27. }
  28.  
  29. $instance->register();
  30. return $instance;
  31. }
  32.  
  33. /**
  34. * Hook up plugin with WP
  35. */
  36. private function register(){
  37. if ( ! is_admin() && ! $this->has_registered ){
  38. $this->has_registered = true;
  39.  
  40. add_filter( 'wp_get_nav_menu_items', array( $this, 'wp_get_nav_menu_items' ), 20, 2 );
  41. add_filter( 'wp_get_nav_menu_object', array( $this, 'wp_get_nav_menu_object' ), 20, 2 );
  42. }
  43. }
  44.  
  45. /**
  46. * Update the menu items count when building the menu
  47. *
  48. * @param $menu_obj
  49. * @param $menu
  50. *
  51. * @return mixed
  52. */
  53. function wp_get_nav_menu_object( $menu_obj, $menu ){
  54. if ( is_a( $menu_obj, 'WP_Term' ) && isset( $this->menus[ $menu_obj->slug ] ) ){
  55. $menu_obj->count += $this->count_menu_items( $menu_obj->slug );
  56. }
  57. return $menu_obj;
  58. }
  59.  
  60. /**
  61. * Get the menu items from WP and add our new ones
  62. *
  63. * @param $items
  64. * @param $menu
  65. *
  66. * @return mixed
  67. */
  68. function wp_get_nav_menu_items( $items, $menu ){
  69. if ( isset( $this->menus[ $menu->slug ] ) ) {
  70. $new_items = $this->get_menu_items( $menu->slug );
  71.  
  72. if ( ! empty( $new_items ) ) {
  73. foreach ( $new_items as $new_item ) {
  74. $items[] = $this->make_item_obj( $new_item );
  75. }
  76. }
  77.  
  78. $items = $this->fix_menu_orders( $items );
  79. }
  80.  
  81. return $items;
  82. }
  83.  
  84. /**
  85. * Entry point.
  86. * Add a new menu item to the list of custom menu items
  87. *
  88. * @param $menu_slug
  89. * @param $title
  90. * @param $url
  91. * @param $order
  92. * @param $parent
  93. * @param null $ID
  94. */
  95. static public function add_item( $menu_slug, $title, $url, $order = 0, $parent = 0, $ID = null, $classes = array() ){
  96. $instance = custom_menu_items::get_instance();
  97. $instance->menus[ $menu_slug ] = $menu_slug;
  98. $instance->menu_items[] = array(
  99. 'menu' => $menu_slug,
  100. 'title' => $title,
  101. 'url' => $url,
  102. 'order' => $order,
  103. 'parent' => $parent,
  104. 'ID' => $ID,
  105. 'classes' => $classes,
  106. );
  107. }
  108.  
  109. /**
  110. * Add a WP_Post or WP_Term to the menu using the object ID.
  111. *
  112. * @param $menu_slug
  113. * @param $object_ID
  114. * @param string $object_type
  115. * @param $order
  116. * @param $parent
  117. * @param null $ID
  118. */
  119. static public function add_object( $menu_slug, $object_ID, $object_type = 'post', $order = 0, $parent = 0, $ID = NULL, $classes = array() ) {
  120. $instance = custom_menu_items::get_instance();
  121. $instance->menus[ $menu_slug ] = $menu_slug;
  122.  
  123. if ($object_type == 'post' && $object = get_post( $object_ID ) ) {
  124. $instance->menu_items[] = array(
  125. 'menu' => $menu_slug,
  126. 'order' => $order,
  127. 'parent' => $parent,
  128. 'post_parent' => $object->post_parent,
  129. 'title' => get_the_title($object),
  130. 'url' => get_permalink($object),
  131. 'ID' => $ID,
  132. 'type' => 'post_type',
  133. 'object' => get_post_type($object),
  134. 'object_id' => $object_ID,
  135. 'classes' => $classes,
  136. );
  137. }
  138. else if ($object_type == 'term') {
  139. global $wpdb;
  140. $sql = "SELECT t.*, tt.taxonomy, tt.parent FROM {$wpdb->terms} as t LEFT JOIN {$wpdb->term_taxonomy} as tt on tt.term_id = t.term_id WHERE t.term_id = %d";
  141. $object = $wpdb->get_row($wpdb->prepare($sql, $object_ID));
  142.  
  143. if ( $object ) {
  144. $instance->menu_items[] = $tmp = array(
  145. 'menu' => $menu_slug,
  146. 'order' => $order,
  147. 'parent' => $parent,
  148. 'post_parent' => $object->parent,
  149. 'title' => $object->name,
  150. 'url' => get_term_link((int)$object->term_id, $object->taxonomy),
  151. 'ID' => $ID,
  152. 'type' => 'taxonomy',
  153. 'object' => $object->taxonomy,
  154. 'object_id' => $object_ID,
  155. 'classes' => $classes,
  156. );
  157. }
  158. }
  159. }
  160.  
  161. /**
  162. * Get an array of new menu items for a specific menu slug
  163. *
  164. * @param $menu_slug
  165. *
  166. * @return array
  167. */
  168. private function get_menu_items( $menu_slug ){
  169. $items = array();
  170.  
  171. if ( isset( $this->menus[ $menu_slug ] ) ) {
  172. $items = array_filter( $this->menu_items, function ( $item ) use ( $menu_slug ) {
  173. return $item['menu'] == $menu_slug;
  174. } );
  175. }
  176. return $items;
  177. }
  178.  
  179. /**
  180. * Count the number of new menu items we are adding to an individual menu
  181. *
  182. * @param $menu_slug
  183. *
  184. * @return int
  185. */
  186. private function count_menu_items( $menu_slug ){
  187. if ( ! isset( $this->menus[ $menu_slug ] ) ) {
  188. return 0;
  189. }
  190.  
  191. $items = $this->get_menu_items( $menu_slug );
  192.  
  193. return count( $items );
  194. }
  195.  
  196. /**
  197. * Helper to create item IDs
  198. *
  199. * @param $item
  200. *
  201. * @return int
  202. */
  203. private function make_item_ID( $item ){
  204. return 1000000 + $item['order'] + $item['parent'];
  205. }
  206.  
  207. /**
  208. * Make a stored item array into a menu item object
  209. *
  210. * @param array $item
  211. *
  212. * @return mixed
  213. */
  214. private function make_item_obj( $item ) {
  215. // generic object made to look like a post object
  216. $item_obj = new stdClass();
  217. $item_obj->ID = ( $item['ID'] ) ? $item['ID'] : $this->make_item_ID( $item );
  218. $item_obj->title = $item['title'];
  219. $item_obj->url = $item['url'];
  220. $item_obj->menu_order = $item['order'];
  221. $item_obj->menu_item_parent = $item['parent'];
  222. $item_obj->post_parent = !empty( $item['post_parent'] ) ? $item['post_parent'] : '';
  223.  
  224. // menu specific properties
  225. $item_obj->db_id = $item_obj->ID;
  226. $item_obj->type = !empty( $item['type'] ) ? $item['type'] : '';
  227. $item_obj->object = !empty( $item['object'] ) ? $item['object'] : '';
  228. $item_obj->object_id = !empty( $item['object_id'] ) ? $item['object_id'] : '';
  229.  
  230. // output attributes
  231. $item_obj->classes = $item['classes'];
  232. $item_obj->target = '';
  233. $item_obj->attr_title = '';
  234. $item_obj->description = '';
  235. $item_obj->xfn = '';
  236. $item_obj->status = '';
  237.  
  238. return $item_obj;
  239. }
  240.  
  241. /**
  242. * Menu items with the same menu_order property cause a conflict. This
  243. * method attempts to provide each menu item with its own unique order value.
  244. * Thanks @codepuncher
  245. *
  246. * @param $items
  247. *
  248. * @return mixed
  249. */
  250. private function fix_menu_orders( $items ){
  251. $items = wp_list_sort( $items, 'menu_order' );
  252.  
  253. for( $i = 0; $i < count( $items ); $i++ ){
  254. $items[ $i ]->menu_order = $i;
  255. }
  256.  
  257. return $items;
  258. }
  259. }
Add Comment
Please, Sign In to add comment