Интеграция навигационного меню WordPress в OpenCart.

Собственно сама задача: имеется связка WordPress и OpenCart, необходимо навигацонное меню из WordPress подключить к OpenCart. В принципе задача не такая уж и сложная, если разобраться в структуре хранения данных в WordPress.
Итак, базовые данные о меню (уникальный идентификатор, имя, имя пригодное для использования в URL), как и для любого терма, хранятся в таблице – wp_terms.

Далее мы подходим к понятию таксономии, которое появилось в WordPress 2.4., с математической точки зрения таксономией называется древообразная структура классификаций определенного объекта. В базе таксономии термов хранятся в таблице wp_term_taxonomy, рассмотрим подробнее ее структуру нужные нам поля: term_taxonomy_id и term_id, идентификатор таксономии терма и идентификатор терма соответственно. Для полноты теоретических сведений упомяну остальные поля taxonomy – собственно таксономия (например, рубрики записей — category, метки записей – post_tag и т.д.), parent – родительский терм и count – количество объектов, связанных с данной таксономией.
Ну и пришло время рассмотреть последнюю таблицу, в которой хранятся отношения термов, объектов и таксономий – wp_term_relationships. Поля таблицы wp_ term_relationships:
object_id – идентификатор объекта, относящегося к данной таксономии,
term_taxonomy_id – идентификатор таксономии термв, относящегося к данному объекту и term_order –поле для сортировки.

Теперь задача получения данных о меню и его элементу становится совсем тривиальной. Выбираем из таблицы термов (wp_term) по названию нашего меню идентификатор нужного нам терма, далее выбираем из таблицы таксономий (wp_term_taxonomy) идентификатор таксономии терма ну и выбираем из таблицы отношения термов и объектов идентификаторы объектов относящихся к нашему меню. Но, как всегда есть одно но. Объекты, которые мы получили – это не совсем те данные, которые нам необходимы. Для получения подробной информации обратимся к таблице wp_postmeta и выберем из нее записи с полученными нами идентификаторами и meta ключом — _menu_item_object, таким образом, мы узнаем, что представляет, из себя наш пункт меню страница (page), рубрика (category) или произвольная ссылка(custom). Эти данные на понадобятся для получения подробной информации о пункте меню.
Итак, запрос:
SELECT
              wp_postmeta.*,
              wp_posts.menu_order
            FROM wp_term_taxonomy
              INNER JOIN wp_term_relationships
                ON wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id
              INNER JOIN wp_terms
                ON wp_term_taxonomy.term_id = wp_terms.term_id
              INNER JOIN wp_postmeta
                ON wp_term_relationships.object_id = wp_postmeta.post_id
              INNER JOIN wp_posts
                ON wp_term_relationships.object_id = wp_posts.ID
            WHERE wp_terms.name = 'MainMenu' AND wp_postmeta.meta_key = '_menu_item_object'
            ORDER BY wp_posts.menu_order

Ура!!! Данные получены, теперь осталось по ним пройтись, и если наш пункт меню является страницей или произвольной ссылкой, мы собираем информацию о пункте меню из таблицы wp_posts, ну а если рубрикой из таблицы wp_terms.
Теперь собственно сам класс с функцией, я его размести на сервере по пути models/tool/wpdata.php
<?php
class ModelToolWpdata extends Model {
    public function GetNavMenu(){
        $query = $this->db->query("
            SELECT
              wp_postmeta.*,
              wp_posts.menu_order
            FROM wp_term_taxonomy
              INNER JOIN wp_term_relationships
                ON wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id
              INNER JOIN wp_terms
                ON wp_term_taxonomy.term_id = wp_terms.term_id
              INNER JOIN wp_postmeta
                ON wp_term_relationships.object_id = wp_postmeta.post_id
              INNER JOIN wp_posts
                ON wp_term_relationships.object_id = wp_posts.ID
            WHERE wp_terms.name = 'MainMenu' AND wp_postmeta.meta_key = '_menu_item_object'
            ORDER BY wp_posts.menu_order");
            
        $wp_menu_items = $query->rows;
        $menu_item_index = 0;
        if(!empty($wp_menu_items)){
            foreach($wp_menu_items as $wp_menu_item){
                if($wp_menu_item['meta_value'] == 'page' || $wp_menu_item['meta_value'] == 'custom'){
                    if($wp_menu_item['meta_value'] == 'page'){
                        $check = 'wp_post';
                    }else{
                        $check = 'wp_custom';
                    }
                    
                    $post_query = $this->db->query("
                    SELECT
                      wp_posts.ID,
                      wp_posts.*
                    FROM wp_postmeta
                      INNER JOIN wp_posts
                        ON wp_postmeta.meta_value = wp_posts.ID
                    WHERE wp_postmeta.post_id = ".$wp_menu_item['post_id']." AND wp_postmeta.meta_key = '_menu_item_object_id'");
                    $post = $post_query->rows;
                    //print_r($post);
                } elseif($wp_menu_item['meta_value'] == 'category') {
                    $check = 'wp_terms';
                    $post_query = $this->db->query("
                    SELECT
                      wp_terms.*
                    FROM wp_postmeta
                      INNER JOIN wp_terms
                        ON wp_postmeta.meta_value = wp_terms.term_id
                    WHERE wp_postmeta.post_id = ".$wp_menu_item['post_id']." AND wp_postmeta.meta_key = '_menu_item_object_id'");
                    $post = $post_query->rows;
                }
                
                
                if($check == 'wp_post'){
                    $menu_item[++$menu_item_index]['name'] = $post[0]['post_title'];
                    $menu_item[$menu_item_index]['url'] = 'http://' . $_SERVER['SERVER_NAME'] . '/' . $post[0]['post_name'];
                }elseif($check == 'wp_custom'){
                    $menu_item[++$menu_item_index]['name'] = $post[0]['post_title'];
                    $url_query = $this->db->query("SELECT * FROM wp_postmeta WHERE meta_key='_menu_item_url' AND post_id='".$wp_menu_item['post_id']."'");
                    $menu_item_url = $url_query->rows;
                    $menu_item[$menu_item_index]['url'] = $menu_item_url[0]['meta_value'];
                }else{
                    $menu_item[++$menu_item_index]['name'] = $post[0]['name'];
                    $menu_item[$menu_item_index]['url'] = 'http://' . $_SERVER['SERVER_NAME'] . '/' . $post[0]['slug'];
                }
            }
        }
        if(!empty($menu_item)){
            return $menu_item;
        }else{
            return false;
        }
    }
}
?>

Подключение и получение данных для шаблона размещаем в нужном нам контроллере. Исходный код приведен ниже:
$this->load->model('tool/wpdata');        
        $wp_menu = $this->model_tool_wpdata->GetNavMenu();
        foreach($wp_menu as $menu_item){
            $this->data['menu_items'][] = $menu_item;
        }

Ну и сам вывод в шаблоне:
<div id="top-menu">
<?php 
    if(!empty($menu_items)){ ?>
    <ul>
        <?php foreach($menu_items as $menu_item){ ?>
            <li><a href="<?php echo $menu_item['url']; ?>"><?php echo $menu_item['name']; ?></a></li>
        <?php } ?>      
    </ul>
<?php } ?>
</div>

Всем спасибо за внимание, в будущем думаю, класс будет потихоньку расти, о чем мы будем незамедлительно сообщать. Ну и как всегда критика и предложения по оптимизации приветствуются.
  • +1
  • 18 августа 2013, 14:27
  • Maugli

Комментарии (0)

RSS свернуть / развернуть
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.
comments powered by Disqus