Универсальный метод для кэширования html-данных в XSLT

Материал из Umicms
Перейти к:навигация, поиск

В одной из статей уже был рассмотрен способ кеширования html-кода в XSLT, это была статья Блочное кеширование html-кода в XSLT

В данной статьей будет показан пример универсального кастомного метода, в который можно передавать основной вызов: модуль, метод, параметры и также путь к шаблону для трансформации xml данных. Кастомный метод необходимо добавить в файл classes/modules/custom.php:

  public function xsltHtmlCache($expire = 3600, $module, $method){
      $xslFilePath = getRequest('xsl');
        // $filePath - путь к xsl-шаблону трансформации.
      $filePath = CURRENT_WORKING_DIR . '/xsltTpls/' . $xslFilePath;
      if(!is_file($filePath)) return;
      
      $args = func_get_args();
      $params = array_slice($args, 3);
      $params_str = implode('/', $params);
      $url = "udata://" . $module . '/' . $method . '/' . $params_str;

      $folder = CURRENT_WORKING_DIR . '/sys-temp/udatacache/';  
      $path = $folder . md5($url . $filePath) . '.xml';
      if(!is_dir($folder)) mkdir($folder, 0777, true);
      if(is_file($path)) $mtime = filemtime($path);
   
      if(!is_file($path) || time() > ($mtime + $expire)) {    
      	
        $xsltDom = new DomDocument;
        $xsltDom->resolveExternals = true;
        $xsltDom->substituteEntities = true;
      
        $xsltDom->load($filePath, DOM_LOAD_OPTIONS);
 
        $xslt = new xsltProcessor;
        $xslt->registerPHPFunctions();
        $xslt->importStyleSheet($xsltDom);
        $page_id = cmsController::getInstance()->getCurrentElementId();
        $parent_id = "";
        $active    = "";
        
        if($page_id){
           $page = umiHierarchy::getInstance()->getElement($page_id);
           $parent_id = $page->getParentId();
           $active    = (int) $page->getIsDefault();
        }
        
        // Добавляем необходимые глобальные переменные, которые можно будет использовать в xsl-шаблоне 
        $xslt->setParameter("", 'parent-id', $parent_id);
        $xslt->setParameter("", 'document-page-id', $page_id);
        $xslt->setParameter("", 'active', $active);
        
        $dom_new = new DOMDocument("1.0", "utf-8");
        // $xml - xml-данные для трансформации.
        $xml = file_get_contents($url);
        $dom_new->loadXML($xml);
 
        //производим трансформацию
        $result = $xslt->transformToXML($dom_new);
        //html-данные необходимо включить в CDATA и в какой либо корневой узел.
        $result = "<udata mode=\"cache\"><![CDATA[" . $result . "]]></udata>";
        // данный принцип возвращения данных отключает xslt-трансформацию системой UMI.CMS
        return array('plain:result' => $result);
         
      }else{
        $result = file_get_contents($path);
        return array('plain:result' => $result);
      }	
  }


Вызов может быть следующим:

<xsl:value-of select="document('udata://custom/xsltHtmlCache/3600/catalog/getCategoryList//8//1?xsl=modules/catalog/category-cache.xsl')/udata" 
disable-output-escaping="yes" />

Обратите внимание в кастомном методе на блок:

        // page_id текущей страницы сайта
        $page_id = cmsController::getInstance()->getCurrentElementId();
        $parent_id = "";
        $active    = "";
        
        if($page_id){
           $page = umiHierarchy::getInstance()->getElement($page_id);
           $parent_id = $page->getParentId();
           $active    = (int) $page->getIsDefault();
        }
        
        // Добавляем необходимые глобальные переменные, которые можно будет использовать в xsl-шаблоне 
        $xslt->setParameter("", 'parent-id', $parent_id);
        $xslt->setParameter("", 'document-page-id', $page_id);
        $xslt->setParameter("", 'active', $active);