1. Уважаемые пользователи, прежде чем ответить в теме или создать новую,
    внимательно ознакомьтесь с правилами раздела

    Кому лень работать или руки не оттуда - пользуйтесь услугами специалистов
  2. Не задавайте глупых вопросов "Посоветуйте какой-нибудь компонент.."

    Есть JED!!! Ищите там!!!

offlajn virtuemart drop menu Облегчить запросы к бд

Тема в разделе "Virtuemart", создана пользователем silmarion, 27 май 2014.

Информация :
  • Уважаемые пользователи, прежде чем ответить в теме или создать новую, внимательно ознакомьтесь с правилами раздела
  • Не задавайте глупых вопросов "Посоветуйте какой-нибудь компонент.." Есть JED!!! Ищите там!!!
  • Аналоги ищите там же - на JED!!!
  • Новая версия? - У кого будет - тот выложит!
  1. silmarion

    silmarion

    Регистр.:
    21 июн 2012
    Сообщения:
    195
    Симпатии:
    19
    Доброго всем дня, прикупил давненько уже модуль этот

    , кому нужен то вот


    Работает отлично, но проблема в том, что если много категорий\подкатегорий то сайт конкретно виснет.

    Как можно облегчить запросы к бд чтобы меню грузилось быстро,
    или загнать уже найденные пункты меню в глубокий кэш
    либо ограничить уровень вложенности хотя бы до 3 уровня?

    Файл clean.php отвечает за вывод меню. Вроде как получалось обрезать вывод по уровню вложенности, но один фиг перед выводом он все равно большой запрос в бд отправляет.
    Код:
    <?php
    
    if($item->fib){
      $this->stack[] = $item->parent;
      $this->level = count($this->stack);
    }
    if($this->up){
      while($this->level > $item->level){
    ?>
    </dl></dd>
    <?php
      array_pop($this->stack);
      $this->level = count($this->stack);
      }
      $this->up = false;
    }
    
    $classes = array('level'.$this->level, 'off-nav-'.$item->id, ($item->p ? "parent" : "notparent"), ($item->opened ? "opened" : ""), ($item->active ? "active" : ""));
    if(isset($this->openedlevels[$this->level]) && $item->p){
      $classes[] = 'opened forceopened';
    }
    if($item->fib){
      $classes[] = 'first';
    }
    if($item->lib){
      $classes[] = 'last';
    }
    $classes = implode(' ', $classes);
    if($item->fib):
    ?>
    <dl <?php if($this->level == 1): ?>id="offlajn-dropmenu-<?php echo $this->_module->id ?>-<?php echo $this->level ?>"<?php endif; ?> class="level<?php echo $this->level ?>">
    <?php endif; ?>
      <dt class="<?php echo $classes ?>">
      <span class="outer">
      <span class="inner">
      <?php echo $item->nname; ?>
      </span>
      </span>
      </dt>
      <dd class="<?php echo $classes ?>">
      <?php if($item->p): $this->renderItem(); else: ?>
      </dd>
      <?php endif; ?>
    <?php
    if($item->lib):
      $this->up = true;
    ?>
    <?php if($item->level == 1): ?>
    </dl>
    <?php endif; ?>
    <?php endif;    ?>
    
    и файл menu.php тут вроде бы все запросы к бд
    Код:
    
    <?php
    // no direct access
    defined('_JEXEC') or die('Restricted access');
    
    global $mosConfig_absolute_path, $VM_LANG, $database;
    
    if(!defined('OfflajnVirtuemart2Menu')) {
      define("OfflajnVirtuemart2Menu", null);
    
      if (!class_exists( 'VmConfig' )) require(JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_virtuemart'.DS.'helpers'.DS.'config.php');
      $config= VmConfig::loadConfig();
      if(!class_exists('TableCategories')) require(JPATH_VM_ADMINISTRATOR.DS.'tables'.DS.'categories.php');
      if (!class_exists( 'VirtueMartModelCategory' )) require(JPATH_VM_ADMINISTRATOR.DS.'models'.DS.'category.php');
      if (!class_exists( 'VirtueMartModelProduct' )) require(JPATH_VM_ADMINISTRATOR.DS.'models'.DS.'product.php');
    
      require_once(dirname(__FILE__). DS .'..'. DS .'..'. DS .'core'. DS .'MenuBase.php');
    
      class OfflajnVirtuemart2Menu extends OfflajnMenuBase{
    
      function OfflajnVirtuemart2Menu($module, $params){
      parent::OfflajnMenuBase($module, $params);
      }
      
      function getAllItems(){
      $options = array();
      
      $db = & JFactory::getDBO();
      
      $categoryid = explode("|", $this->_params->get('vm2categoryid'));
      
      $query = "SELECT DISTINCT
      a.virtuemart_category_id AS id,
      a.category_description  AS description,
      a.category_name AS name, ";
      
      if(!is_array($categoryid) && $categoryid != 0){
      $query.="IF(f.category_parent_id = ".$categoryid.", 0 , IF(f.category_parent_id = 0, -1, f.category_parent_id)) AS parent, ";
      }elseif(count($categoryid) && is_array($categoryid) && !in_array('0', $categoryid)){
      $query.="IF(a.virtuemart_category_id in (".implode(',', $categoryid)."), 0 , IF(f.category_parent_id = 0, -1, f.category_parent_id)) AS parent, ";
      }else{
      $query.="f.category_parent_id AS parent, ";
      }
      
      $query.="'cat' AS typ, ";
      if($this->_params->get('displaynumprod', 0) != 0){
      $query.= "(SELECT COUNT(*) FROM #__virtuemart_product_categories AS ax LEFT JOIN #__virtuemart_products AS bp ON ax.virtuemart_product_id = bp.virtuemart_product_id WHERE ax.virtuemart_category_id = a.virtuemart_category_id";
      if( VmConfig::get('check_stock') && Vmconfig::get('show_out_of_stock_products') != '1') {
           $query.= " AND bp.product_in_stock > 0 ";
         }
      $query.= ") AS productnum";
      }else{
      $query.= "0 AS productnum";
      }
      $query.= " FROM #__virtuemart_categories_".VMLANG." AS a
      LEFT JOIN #__virtuemart_category_categories AS f ON a.virtuemart_category_id = f.category_child_id
      LEFT JOIN #__virtuemart_categories AS b ON a.virtuemart_category_id = b.virtuemart_category_id
      WHERE b.published='1' AND a.virtuemart_category_id = f.category_child_id ";
      if ($this->_params->get('elementorder', 0) == 0)
      $query.="ORDER BY b.ordering ASC";
      elseif ($this->_params->get('elementorder', 0)==1)
      $query.="ORDER BY a.category_name ASC";
      elseif ($this->_params->get('elementorder', 0)==2)
      $query.="ORDER BY a.category_name DESC";  
      $db->setQuery($query);
      $allItems = $db->loadObjectList('id');
      
      /*
      Get products for the categories
      */
      if($this->_params->get('showproducts', 0)){
      $query = "
      SELECT DISTINCT
      a.virtuemart_product_id,
      concat(a.virtuemart_category_id,'-',a.virtuemart_product_id) AS id,
      c.product_name AS name,
      a.virtuemart_category_id AS parent,
      'prod' AS typ,
      0 AS productnum
      FROM #__virtuemart_product_categories AS a
      LEFT JOIN #__virtuemart_products AS b ON a.virtuemart_product_id = b.virtuemart_product_id
      LEFT JOIN #__virtuemart_products_".VMLANG." AS c ON a.virtuemart_product_id = c.virtuemart_product_id
      
      WHERE b.product_parent_id = 0 AND b.published = '1'";
      if( VmConfig::get('check_stock') && Vmconfig::get('show_out_of_stock_products') != '1') {
           $query.= " AND b.product_in_stock > 0 ";
         }
      if ($this->_params->get('elementorder', 0) == 0)
      $query.=" ORDER BY a.ordering ASC";
      elseif ($this->_params->get('elementorder', 0) == 1)
      $query.=" ORDER BY name ASC";
      elseif ($this->_params->get('elementorder', 0) == 2)
      $query.=" ORDER BY name DESC";
      $db->setQuery($query);
      $allItems += $db->loadObjectList('id');
      }
      
      return $allItems;
      }
      
      function getActiveItem(){ 
      $active = null;
      if(JRequest::getVar('option') == 'com_virtuemart'){
      $product_id = JRequest::getInt('virtuemart_product_id');
      $category_id = JRequest::getInt('virtuemart_category_id');
      if($product_id > 0 && $this->_params->get('showproducts')){
      if($category_id > 0){
      $active = new stdClass();
      $active->id = $category_id.'-'.$product_id;
      }else{
      $active = new stdClass();
      $productModel = new VirtueMartModelProduct();
      $r = $productModel->getProductSingle($product_id)->categories;
      if(is_array($r)){
      $r = $r[0];
      }
      $active->id = $r.'-'.$product_id;
      }
      }else{
      if($category_id > 0){
      $active = new stdClass();
      $active->id = $category_id;
      }elseif($product_id > 0){
      $active = new stdClass();
      $productModel = new VirtueMartModelProduct();
      $r = $productModel->getProductSingle($product_id)->categories;
      if(is_array($r)){
      $r = $r[0];
      }
      $active->id = $r;
      }
      }
      }
      return $active;
      }
      
      function getItemsTree(){
      $items = $this->getItems();
      if($this->_params->get('displaynumprod', 0) == 2){
      for($i = count($items)-1; $i >= 0; $i--){
      $items[$i]->parent->productnum+= $items[$i]->productnum;
      }
      }
      return $items;
      }
      
      function filterItem(&$item){
         global $sess;
      $item->nname = stripslashes($item->name);
      $length = "";
      if (strlen($item->productnum) == 1 ) {
      $length = "one";
      } elseif(strlen($item->productnum) >= 2) {
      $length = "more";
      }
      if($this->_params->get('displaynumprod', 0) == 1 && $item->typ == 'cat' && $item->productnum > 0){
      $item->nname.= '<span class="productnum '.$length.'">'.$item->productnum.'</span>';
      }elseif($this->_params->get('displaynumprod', 0) == 2 && $item->typ == 'cat'){
      $item->nname.= '<span class="productnum '.$length.'">'.$item->productnum.'</span>';
      }
      
      $item->nname = '<span>'.$item->nname.'</span>';
      
      $image = '';
      if ($this->_params->get('menu_images') && @$item->description != '') {
      @preg_match('/<img.*?src=["\'](.*?((jpg)|(png)|(jpeg)))["\'].*?>/i',$item->description, $out);
      if($out[1]) $image = '<img src="'.JURI::base(true).$out[1].'" '.@$imgalign.' />';
             if($this->_params->get('menu_images_link')){
              //$item->nname = null;
      }
      
      switch ($this->_params->get('menu_images_align', 0)){
               case 0 :
               $item->nname = $image.$item->nname;
               break;
               case 1 :
               $item->nname = $item->nname.$image;
               break;
               default :
               $item->nname = $image.$item->nname;
               break;
             }
           }
      
      if($item->typ == 'cat'){
      if($this->_params->get('parentlink') == 0 && $item->p){
      $item->nname = '<a>'.$item->nname.'</a>';
      }else{
      $url = JRoute::_('index.php?option=com_virtuemart&view=category&virtuemart_category_id='.$item->id);
      if(defined('DEMO') && strstr($url, 'Itemid') === false ){
      $url.='&Itemid='.$_REQUEST['Itemid'];
      }
      $item->nname = '<a href="'.$url.'">'.$item->nname.'</a>';
      }
      }elseif($item->typ == 'prod'){
      $ids = explode('-', $item->id);
      $url = JRoute::_('index.php?option=com_virtuemart&view=productdetails&virtuemart_category_id='.$ids[0].'&virtuemart_product_id='.$ids[1]);
      if(defined('DEMO') && strstr($url, 'Itemid') === false ){
      $url.='&Itemid='.$_REQUEST['Itemid'];
      }
      $item->nname = '<a href="'.$url.'">'.$item->nname.'</a>';
      }
      }
      
      }
    }
    ?>
    
    Очень прошу помощи
     
  2. toma1971

    toma1971 Создатель

    Регистр.:
    29 май 2014
    Сообщения:
    21
    Симпатии:
    0
    Самое простое решение ограничить уровень вложенности, потом уже кэшировать.