WPCOM_JSON_API_Menus_Complexify

The Jetpack by WordPress.com WPCOM JSON API Menus Complexify class.

Defined (1)

The class is defined in the following location(s).

/json-endpoints/class.wpcom-json-api-menus-v1-1-endpoint.php  
  1. class WPCOM_JSON_API_Menus_Complexify extends WPCOM_JSON_API_Menus_Translator { 
  2. protected $filter = 'wpcom_menu_api_translator_complexify'; 
  3.  
  4. protected $filters = array( 
  5. 'untreeify',  
  6. 'set_locations',  
  7. 'whitelist_and_rename_keys',  
  8. ); 
  9.  
  10. protected $menu_whitelist = array( 
  11. 'id' => 'term_id',  
  12. 'name' => 'menu-name',  
  13. 'description' => 'description',  
  14. 'items' => 'items',  
  15. ); 
  16.  
  17. protected $menu_item_whitelist = array( 
  18. 'id' => 'menu-item-db-id',  
  19. 'content_id' => 'menu-item-object-id',  
  20. 'type' => 'menu-item-object',  
  21. 'type_family' => 'menu-item-type',  
  22. 'type_label' => 'menu-item-type-label',  
  23. 'name' => 'menu-item-title',  
  24. 'order' => 'menu-item-position',  
  25. 'parent' => 'menu-item-parent-id',  
  26. 'url' => 'menu-item-url',  
  27. 'link_target' => 'menu-item-target',  
  28. 'link_title' => 'menu-item-attr-title',  
  29. 'status' => 'menu-item-status',  
  30. 'tmp_id' => 'tmp_id',  
  31. 'tmp_parent' => 'tmp_parent',  
  32. 'description' => 'menu-item-description',  
  33. 'classes' => 'menu-item-classes',  
  34. 'xfn' => 'menu-item-xfn',  
  35. ); 
  36.  
  37. /************************** 
  38. * Filters methods 
  39. **************************/ 
  40.  
  41. public function untreeify( $menus ) { 
  42. return array_map( array( $this, 'untreeify_menu' ), $menus ); 
  43.  
  44. // convert the tree of menu items to a flat list suitable for 
  45. // the nav_menu APIs 
  46. protected function untreeify_menu( $menu ) { 
  47. if ( empty( $menu['items'] ) ) { 
  48. return $menu; 
  49.  
  50. $items_list = array(); 
  51. $counter = 1; 
  52. foreach ( $menu['items'] as &$item ) { 
  53. $item[ 'parent' ] = 0; 
  54. $this->untreeify_items( $menu['items'], $items_list, $counter ); 
  55. $menu['items'] = $items_list; 
  56.  
  57. return $menu; 
  58.  
  59. /** 
  60. * Recurse the items tree adding each item to a flat list and restoring 
  61. * `order` and `parent` fields. 
  62. * @param array $items item tree 
  63. * @param array &$items_list output flat list of items 
  64. * @param int &$counter for creating temporary IDs 
  65. */ 
  66. protected function untreeify_items( $items, &$items_list, &$counter ) { 
  67. foreach( $items as $index => $item ) { 
  68. $item['order'] = $index + 1; 
  69.  
  70. if( ! isset( $item['id'] ) ) { 
  71. $this->set_tmp_id( $item, $counter++ ); 
  72.  
  73. if ( isset( $item['items'] ) && is_array( $item['items'] ) ) { 
  74. foreach ( $item['items'] as &$i ) { 
  75. $i['parent'] = $item['id']; 
  76. $this->untreeify_items( $item[ 'items' ], $items_list, $counter ); 
  77. unset( $item['items'] ); 
  78.  
  79. $items_list[] = $item; 
  80.  
  81. /** 
  82. * Populate `tmp_id` field for a new item, and `tmp_parent` field 
  83. * for all its children, to maintain the hierarchy. 
  84. * These fields will be used when creating 
  85. * new items with wp_update_nav_menu_item(). 
  86. */ 
  87. private function set_tmp_id( &$item, $tmp_id ) { 
  88. $item['tmp_id'] = $tmp_id; 
  89. if ( ! isset( $item['items'] ) || ! is_array( $item['items'] ) ) { 
  90. return; 
  91. foreach ( $item['items'] as &$child ) { 
  92. $child['tmp_parent'] = $tmp_id; 
  93.  
  94. protected function whitelist_and_rename_keys( $menus ) { 
  95. $transformed_menus = array(); 
  96. foreach ( $menus as $menu ) { 
  97. $menu = $this->whitelist_and_rename_with( $menu, $this->menu_whitelist ); 
  98. if ( isset( $menu['items'] ) ) { 
  99. $menu['items'] = array_map( array( $this, 'whitelist_and_rename_item_keys' ), $menu['items'] ); 
  100. $transformed_menus[] = $menu; 
  101.  
  102. return $transformed_menus; 
  103.  
  104. protected function whitelist_and_rename_item_keys( $item ) { 
  105. $item = $this->implode_array_fields( $item ); 
  106. $item = $this->whitelist_and_rename_with( $item, $this->menu_item_whitelist ); 
  107. return $item; 
  108.  
  109. // all item fields are set as strings 
  110. protected function implode_array_fields( $menu_item ) { 
  111. return array_map( array( $this, 'implode_array_field' ), $menu_item ); 
  112.  
  113. protected function implode_array_field( $field ) { 
  114. if ( is_array( $field ) ) { 
  115. return implode( ' ', $field ); 
  116. return $field; 
  117.  
  118. protected function set_locations( $menus ) { 
  119. foreach ( $menus as $menu ) { 
  120. if ( isset( $menu['locations'] ) ) { 
  121. if ( true !== $this->locations_are_valid( $menu['locations'] ) ) { 
  122. return $this->locations_are_valid( $menu['locations'] ); 
  123.  
  124. return array_map( array( $this, 'set_location' ), $menus ); 
  125.  
  126. protected function set_location( $menu ) { 
  127. $this->set_menu_at_locations( $menu['locations'], $menu['id'] ); 
  128. return $menu; 
  129.  
  130. protected function set_menu_at_locations( $locations, $menu_id ) { 
  131. $location_map = get_nav_menu_locations(); 
  132. $this->remove_menu_from_all_locations( $menu_id, $location_map ); 
  133.  
  134. if ( is_array( $locations ) ) { 
  135. foreach ( $locations as $location ) { 
  136. $location_map[ $location ] = $menu_id; 
  137.  
  138. set_theme_mod( 'nav_menu_locations', $location_map ); 
  139.  
  140. $this->set_widget_menu_at_locations( $locations, $menu_id ); 
  141.  
  142. protected function remove_menu_from_all_locations( $menu_id, &$location_map ) { 
  143. foreach ( get_nav_menu_locations() as $existing_location => $existing_menu_id) { 
  144. if ( $existing_menu_id == $menu_id ) { 
  145. unset( $location_map[$existing_location] ); 
  146.  
  147. protected function set_widget_menu_at_locations( $locations, $menu_id ) { 
  148. $nav_menu_widgets = get_option( 'widget_nav_menu' ); 
  149.  
  150. if ( ! is_array( $nav_menu_widgets ) ) { 
  151. return; 
  152.  
  153. // Remove menus from all custom menu widget locations 
  154. foreach ( $nav_menu_widgets as &$widget ) { 
  155. if ( is_array( $widget ) && $widget['nav_menu'] == $menu_id ) { 
  156. $widget['nav_menu'] = 0; 
  157.  
  158. if ( is_array( $locations ) ) { 
  159. foreach ( $locations as $location ) { 
  160. if ( preg_match( '/^nav_menu_widget-(\d+)/', $location, $matches ) ) { 
  161. if ( isset( $matches[1] ) ) { 
  162. $nav_menu_widgets[$matches[1]]['nav_menu'] = $menu_id; 
  163.  
  164. update_option( 'widget_nav_menu', $nav_menu_widgets ); 
  165.  
  166. protected function locations_are_valid( $locations ) { 
  167. if ( is_int( $locations ) ) { 
  168. if ( $locations != 0) { 
  169. return new WP_Error( 'locations-int', 'Locations int must be 0.', 400 ); 
  170. } else { 
  171. return true; 
  172. } elseif ( is_array( $locations ) ) { 
  173. foreach ( $locations as $location_name ) { 
  174. if ( ! $this->location_name_exists( $location_name ) ) { 
  175. return new WP_Error( 'locations-array',  
  176. sprintf( "Location '%s' does not exist.", $location_name ), 404 ); 
  177. return true; 
  178. return new WP_Error( 'locations', 'Locations must be array or integer.', 400 ); 
  179.  
  180. protected function location_name_exists( $location_name ) { 
  181. $widget_location_names = wp_list_pluck( WPCOM_JSON_API_Menus_Widgets::get(), 'name' ); 
  182.  
  183. if ( ! is_array( get_registered_nav_menus() ) ) { 
  184. return false; 
  185.  
  186. return array_key_exists( $location_name, get_registered_nav_menus() ) || 
  187. in_array( $location_name, $widget_location_names ); 
  188.