简体   繁体   中英

Opencart 1.5.5.1 header menu linking directly to first subcategory

I'm currently looking for help with linking the main category links in the header menu directly to their first subcategory.

In other words:

when clicking on the category link I would like to add the ID of the first subcategory at the end, ie

route=product/category&path=18_59 

instead of

route=product/category&path=18

Does anyone has a suggestion how to do that?

<div id="menu">
  <ul>
    <?php foreach ($categories as $category) { ?>
    <li><a href="<?php echo $category['href']; ?>"><?php echo $category['name']; ?></a>
      <?php if ($category['children']) { ?>
      <div>
        <?php for ($i = 0; $i < count($category['children']);) { ?>
        <ul>
          <?php $j = $i + ceil(count($category['children']) / $category['column']); ?>
          <?php for (; $i < $j; $i++) { ?>
          <?php if (isset($category['children'][$i])) { ?>
          <li><a href="<?php echo $category['children'][$i]['href']; ?>"><?php echo $category['children'][$i]['name']; ?></a></li>
          <?php } ?>
          <?php } ?>
        </ul>
        <?php } ?>
      </div>
      <?php } ?>
    </li>
    <?php } ?>
  </ul>
</div>

Welcome to StackOverflow !

This could be achieved by getting the first child of the main category and we have two options, one cleaner and one easier.

The cleaner one . This would require the changes in the catalog/controller/common/header.php and model catalog/model/catalog/category.php , let's go on step by step. First, add the new necessary function into the category model:

public function getCategoryFirstChildId($category_id) {
    $query = $this->db->query('SELECT category_id FROM '. DB_PREFIX .'category WHERE parent_id = '. (int)$category_id .' ORDER BY category_id ASC LIMIT 1');

    return $query->row['category_id'];
}

This function will get all the categories where parent_id is the $category_id given as a parameter, sort them ascending by category_id (You can change that to whatever sorting You want) and return only the first one.

Now let's go to the controller - we will edit the part where categories are loaded:

    foreach ($categories as $category) {
        if ($category['top']) {
            // Level 2
            $children_data = array();

            $children = $this->model_catalog_category->getCategories($category['category_id']);

            foreach ($children as $child) {
                $data = array(
                    'filter_category_id'  => $child['category_id'],
                    'filter_sub_category' => true
                );

                $product_total = $this->model_catalog_product->getTotalProducts($data);

                $children_data[] = array(
                    'name'  => $child['name'] . ($this->config->get('config_product_count') ? ' (' . $product_total . ')' : ''),
                    'href'  => $this->url->link('product/category', 'path=' . $category['category_id'] . '_' . $child['category_id'])
                );                      
            }

/*NEW =>*/  $first_child_id = $this->model_catalog_category->getCategoryFirstChildId($category['category_id']);

            // Level 1
            $this->data['categories'][] = array(
                'name'     => $category['name'],
                'children' => $children_data,
                'column'   => $category['column'] ? $category['column'] : 1,
                'href'     => $this->url->link('product/category', 'path=' . $category['category_id'] . '_' . $first_child_id)
//     >>>          >>>          >>>           >>>          >>>           >>>          >>>           ^^^^^^^^^^^^^^^^^^^^^^^^
            );
        }
    }

This should be it. Be wise that this though cleaner way requires one more DB query per category thus may slow down (though a tiny bit) the site when large number of categories is being processed.

The easier way - need changes to be done only within header controller (no new function is added to the model):

    foreach ($categories as $category) {
        if ($category['top']) {
            // Level 2
            $children_data = array();
/*NEW =>*/  $first_child_id = 0;
/*NEW =>*/  $first_child = true;

            $children = $this->model_catalog_category->getCategories($category['category_id']);

            foreach ($children as $child) {
/*NEW =>*/      if($first_child) {
/*NEW =>*/          $first_child = false;
/*NEW =>*/          $first_child_id = $child['category_id'];
/*NEW =>*/      }

                $data = array(
                    'filter_category_id'  => $child['category_id'],
                    'filter_sub_category' => true
                );

                $product_total = $this->model_catalog_product->getTotalProducts($data);

                $children_data[] = array(
                    'name'  => $child['name'] . ($this->config->get('config_product_count') ? ' (' . $product_total . ')' : ''),
                    'href'  => $this->url->link('product/category', 'path=' . $category['category_id'] . '_' . $child['category_id'])
                );                      
            }

            // Level 1
            $this->data['categories'][] = array(
                'name'     => $category['name'],
                'children' => $children_data,
                'column'   => $category['column'] ? $category['column'] : 1,
                'href'     => $this->url->link('product/category', 'path=' . $category['category_id'] . '_' . $first_child_id)
//     >>>          >>>          >>>           >>>          >>>           >>>          >>>           ^^^^^^^^^^^^^^^^^^^^^^^^
            );
        }
    }

The easier way will also work very well and would be a little quicker but the first category it will point to will always be the one that comes as first when sorting ascending by sort_order - whenever it may change, the main category will point to a different child category...

I didn't test neither of the ways but I believe they will work on 100%.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM