/** * Normally to be called after 'updatePagesBasedOnHierarchy', basically updates the ParentID/Sort of pages * based on how they're structured for the given menu. * * (Silverstripe doesn't seperate its menu and page-structure like Wordpress) */ public function updatePagesBasedOnNavMenu($menu_slug = '') { if (!$menu_slug) { // If first parameter left blank, throw exception showing the developer what menu slugs they can provide. $menuItems = ''; foreach ($this->_db->getNavMenuTypes() as $navMenuType) { $menuItems .= $navMenuType['name'] . ' (slug: ' . $navMenuType['slug'] . ')' . ", \n"; } throw new WordpressImportException("Must provide menu slug for " . __FUNCTION__ . "({$menu_slug}).\nAvailable menus:\n" . $menuItems); } $this->logFunctionStart(__FUNCTION__); $wpNavMenuItems = $this->_db->getNavMenuItems($menu_slug); if (!$wpNavMenuItems) { throw new WordpressImportException("Bad menu slug. Either invalid or does not contain any menu items."); } // Make all non-Wordpress pages no longer show in menu. $list = SiteTree::get()->filter(array('WordpressID' => 0, 'ShowInMenus' => 1)); foreach ($list as $record) { $record->ShowInMenus = 0; $record->WordpressData = true; try { $this->writeAndPublishRecord($record); } catch (Exception $e) { $this->log($record, 'error', $e); } } // Make SiteTree items match the nav_menu_item post_type's structure and sort order. $wordpressIDsToSilverstripeIDs = singleton('SiteTree')->WordpressIDToSilverstripeIDMap(); $trackRecordsChangedByIDs = array(); $list = $this->applyWordpressFilter(SiteTree::get()); foreach ($wpNavMenuItems as $wpData) { $wpMeta = $this->_db->attachAndGetPostMeta($wpData); if (!isset($wpMeta['_menu_item_type'])) { throw new Exception('Menu item is missing _menu_item_type postmeta. Your Wordpress database might be too old. Update it if possible.'); } $record = null; if (isset($wpMeta['_menu_item_object_id']) && $wpMeta['_menu_item_object_id'] > 0) { // Detect if menu has an associated page ID, if so, and if that page has been imported, use it. $record = $list->find('WordpressID', $wpMeta['_menu_item_object_id']); } $type = $wpMeta['_menu_item_type']; if ($type === 'post_type' || $type === 'custom') { if (!$record) { // If direct link to external URL or home. if (isset($wpMeta['_menu_item_url']) && $wpMeta['_menu_item_url']) { // A direct URL link // Eg: "http://www.mylivesite.com.au/newsletters/" $url = $wpMeta['_menu_item_url']; if ($url === '/') { // Detect "home" page // - _menu_item_object_id references itself in this case, so we // can't use it to detect the record. $record = $list->filter(array('URLSegment' => 'home'))->first(); } else { $record = RedirectorPage::get()->filter(array('RedirectionType' => 'External', 'ExternalURL' => $url))->first(); if (!$record) { $record = RedirectorPage::create(); $record->RedirectionType = 'External'; $record->ExternalURL = $url; } $record->WordpressData = $wpData; } } else { $this->log('Found "custom" menu item type (Post ID #' . $wpData['ID'] . ') with Sort "' . $sort . '". Unable to handle. Skipping.', 'notice'); continue; } } } else { throw new Exception('Unable to handle menu type "' . $type . '"'); } if (!$record) { DB::alteration_message('Unable to find menu items post record.', 'error'); continue; } if (isset($trackRecordsChangedByIDs[$record->ID])) { DB::alteration_message('Already used "' . $record->Title . '" #' . $record->ID . ' in this menu.', 'error'); continue; } // Determine where to place Page in SS based on Wordpress IDs $wordpressParentID = 0; $wpParentNavItem = null; if (isset($wpMeta['_menu_item_menu_item_parent']) && $wpMeta['_menu_item_menu_item_parent'] > 0) { $wpParentNavID = $wpMeta['_menu_item_menu_item_parent']; if ($wpParentNavID > 0 && isset($wpNavMenuItems[$wpParentNavID])) { $wpParentNavItem = $wpNavMenuItems[$wpParentNavID]; $wpParentMeta = $this->_db->attachAndGetPostMeta($wpParentNavItem); if (!$wpParentMeta) { throw new Exception('Missing meta on parent nav_menu_item #' . $wpParentNavID); } $wordpressParentID = $wpParentMeta['_menu_item_object_id']; } else { throw new Exception('Unable to find parent nav_menu_item #' . $wpParentNavID); } } if ($wordpressParentID > 0) { $silverstripeParentID = $wordpressIDsToSilverstripeIDs[$wordpressParentID]; $record->ParentID = $silverstripeParentID; } else { if ($wordpressParentID == 0) { $record->ParentID = $this->root_parent_id; } } // Update with menu data $record->MenuTitle = $wpData['post_title']; if ($record instanceof RedirectorPage && $record->Title == '') { $record->Title = $record->MenuTitle; } $record->ShowInMenus = 1; // NOTE(Jake): Wordpress keeps its menu_order value going even under parents, like so: // - Menu Item 1 (menu_order = 1) // - Menu Sub Item 1 (menu_order = 2) // - Menu Item 2 (menu_order = 3) // - Menu Sub Item 1 (menu_order = 4) // - Menu Sub Item 2 (menu_order = 5) $record->Sort = $wpData['menu_order']; if ($changedFields = $record->getChangedFields(true, DataObject::CHANGE_VALUE)) { try { $this->writeAndPublishRecord($record); $trackRecordsChangedByIDs[$record->ID] = $record->ID; } catch (Exception $e) { $this->log($record, 'error', $e); } } else { $this->log($record, 'nochange'); } } $this->logFunctionEnd(__FUNCTION__); }