Прайслист — различия между версиями

Материал из Umicms
Перейти к:навигация, поиск
 
(не показано 25 промежуточных версий этого же участника)
Строка 1: Строка 1:
[[category:Написание кастомных макросов]]
+
[[category:Написание кастомных макросов]][[Категория: Верстка в XSLT]][[Категория:Верстка в TPL]][[Категория:API]][[Категория:Модуль_Интернет_магазин]][[Категория:Модуль_Каталог]]
 
'''Актуально для версии 2.9.1'''
 
'''Актуально для версии 2.9.1'''
 
== Общее описание ==
 
== Общее описание ==
Строка 24: Строка 24:
 
== Листинг макроса и служебных методов==
 
== Листинг макроса и служебных методов==
 
<source lang="php">
 
<source lang="php">
//возвращаем прайслист
+
//возвращаем прайслист
public function getPriceList($asFile = '', $parent = '', $childs = 10, $expire = 0, $fileName = '', $template = 'default'){
+
public function getPriceList($asFile = '', $parent = '', $childs = 10, $expire = 0, $fileName = '', $template = 'default'){
                //если первый параметр не задан, то он будет равен 'yes'
+
//если первый параметр не задан, то он будет равен 'yes'
if(!$asFile) $asFile = 'yes';
+
if(!$asFile) $asFile = 'yes';
                        //если второй параметр не задан, то берем id текущей страницы
+
//если второй параметр не задан, то берем id текущей страницы
if(!$parent){
+
if(!$parent){
$parentId = cmsController::getInstance()->getCurrentElementId();  
+
$parentId = cmsController::getInstance()->getCurrentElementId();  
 +
}else{
 +
//если задан, то анализируем путь до файла
 +
$parentId = def_module::analyzeRequiredPath($parent);
 +
//если parentId не получен, то кидаем исключение
 +
if($parentId === false && $parent != KEYWORD_GRAB_ALL) {
 +
throw new publicException('<b>В макросе emarket getPriceList() необходимо указать корректное значение второго параметра $parent<b/>');
 +
}
 +
}
 +
//если третий параметр не задан, то он будет равен десяти
 +
if(!$childs) $childs = 10;
 +
//если третий параметр не число, то кидаем исключение
 +
if(!is_numeric($childs)){
 +
throw new publicException('<b>В макросе emarket getPriceList() необходимо указать корректное значение третьего параметра $childs<b/>');
 +
}
 +
//если четвертый параметр не задан, то он будет равен нулю
 +
if(!$expire) $expire = 0;
 +
//если значение четвертого параметра не число, кидаем исключене
 +
if(!is_numeric($expire)){
 +
throw new publicException('<b>В макросе emarket getPriceList() необходимо указать корректное значение четвертого параметра $expire<b/>');
 +
}
 +
//получаем altname страницы, указанной во втором параметре
 +
$hierarchy = umiHierarchy::getInstance();
 +
$page = $hierarchy->getElement($parentId);
 +
$altName = $page->getAltName();
 +
//ветвление относительно первого параметра
 +
switch ($asFile) {
 +
//если $asFile = 'no 'возвращаем результат макроса в виде итемов с информацией о товарах
 +
case 'no':
 +
//если xslt - кешируем результат парсинга
 +
$isXslt = def_module::isXSLTResultMode();
 +
if ($isXslt){
 +
$path = self::getPath('/sys-temp/price_as_page/', $altName .'-cashed-as-array.txt');
 +
if(is_file($path)) $mtime = filemtime($path);
 +
//получаем и возвращаем результат, сохраняем в кеш результат
 +
if(!is_file($path) || time() > ($mtime + $expire)){
 +
$pages = self::getQuery($parentId, $childs);
 +
$result = self::getResult($pages, $template);
 +
file_put_contents($path, serialize($result));
 +
unset($path, $mtime, $pages);
 +
return $result;
 +
}else{
 +
//возвращаем результат из кеша
 +
return unserialize(file_get_contents($path));
 +
}
 
}else{
 
}else{
                                //если задан, то анализируем путь до файла
+
//если tpl - кешируем результат выборки
$parentId = def_module::analyzeRequiredPath($parent);
+
$path = self::getPath('/sys-temp/price_as_page/', $altName .'-cashed-as-query.txt');
                                //если parentId не получен, то кидаем исключение
+
if(is_file($path)) $mtime = filemtime($path);
if($parentId === false && $parent != KEYWORD_GRAB_ALL) {
+
//получаем и возвращаем результат, сохраняем в кеш выборку
throw new publicException('<b>В макросе emarket getPriceList() необходимо указать корректное значение второго параметра $parent<b/>');
+
if(!is_file($path) || time() > ($mtime + $expire)){
 +
$pages = self::getQuery($parentId, $childs);
 +
file_put_contents($path, serialize($pages));
 +
$result = self::getResult($pages, $template);
 +
unset($path, $mtime, $pages);
 +
return $result;
 +
}else{
 +
//берем выборку из кеша, получаем и возвращаем результат
 +
return self::getResult(unserialize(file_get_contents($path)), $template);
 
}
 
}
 
}
 
}
                        //если третий параметр не задан, то он будет равен десяти
+
break;
if(!$childs) $childs = 10;
+
//если $asFile = 'yes' возвращаем результат макроса в виде ссылки на файл с прайслистом
                        //если третий параметр не число, то кидаем исключение
+
case 'yes':
if(!is_numeric($childs)){
+
//если имя файла не задано, оно будет равно altName страницы-родителя
throw new publicException('<b>В макросе emarket getPriceList() необходимо указать корректное значение третьего параметра $childs<b/>');
+
if(!$fileName){
 +
$correctFileName = $altName;  
 +
//если имя файла есть, то прогоняем через транлит, на случай ввода русского названия файла
 +
}else{
 +
$correctFileName = translit::convert($fileName);
 
}
 
}
                        //если четвертый параметр не задан, то он будет равен нулю
+
$path = self::getPath('/files/price_as_file/', $correctFileName . '.csv');
if(!$expire) $expire = 0;
+
if(is_file($path)) $mtime = filemtime($path);
                        //если значение четвертого параметра не число, кидаем исключене
+
//получаем результат, сохраняем его в csv файл и возвращаем ссылку
if(!is_numeric($expire)){
+
if(!is_file($path) || time() > ($mtime + $expire)){
throw new publicException('<b>В макросе emarket getPriceList() необходимо указать корректное значение четвертого параметра $expire<b/>');
+
$open = fopen($path, 'w+');
}
+
//задаем 'шапку' csv файла
                        //получаем altname страницы, указанной во втором параметре
+
$hat = array(
$hierarchy = umiHierarchy::getInstance();
+
'artikul' => 'Артикул',
$page = $hierarchy->getElement($parentId);
+
'name' => 'Наименование',
$altName = $page->getAltName();
+
'price' => 'Цена'
                        //ветвление относительно первого параметра
+
);
switch ($asFile) {
+
fputcsv($open, $hat, ';');
                                //если $asFile = 'no 'возвращаем результат макроса в виде итемов с информацией о товарах
+
$pages = self::getQuery($parentId, $childs);
case 'no':
+
//наполняем файл данными, если вовремя наполнения будет ошибка, то на сайте появится информация о ней
                                        //если xslt - кешируем результат парсинга
+
try {
$isXslt = def_module::isXSLTResultMode();
+
foreach($pages as $page){
if ($isXslt){
+
$lines = array();
$path = self::getPath('/sys-temp/price_as_page/', $altName .'-cashed-as-array.txt');
+
$lines['artikul'] = $page->getValue('artikul');
if(is_file($path)) $mtime = filemtime($path);
+
$lines['name'] = $page->getName();
                                                //получаем и возвращаем результат, сохраняем в кеш результат
+
$lines['price'] = $page->getValue('price');
if(!is_file($path) || time() > ($mtime + $expire)){
+
fputcsv($open, $lines, ';');
$pages = self::getQuery($parentId, $childs);
 
$result = self::getResult($pages, $template);
 
file_put_contents($path, serialize($result));
 
unset($path, $mtime, $pages);
 
return $result;
 
}else{
 
                                                //возвращаем результат из кеша
 
return unserialize(file_get_contents($path));
 
}
 
}else{
 
                                //если tpl - кешируем результат выборки
 
$path = self::getPath('/sys-temp/price_as_page/', $altName .'-cashed-as-query.txt');
 
if(is_file($path)) $mtime = filemtime($path);
 
                                                //получаем и возвращаем результат, сохраняем в кеш выборку
 
if(!is_file($path) || time() > ($mtime + $expire)){
 
$pages = self::getQuery($parentId, $childs);
 
file_put_contents($path, serialize($pages));
 
$result = self::getResult($pages, $template);
 
unset($path, $mtime, $pages);
 
return $result;
 
}else{
 
                                                //берем выборку из кеша, получаем и возвращаем результат
 
return self::getResult(unserialize(file_get_contents($path)), $template);
 
}
 
 
}
 
}
break;
+
}catch (Exception $e) {
                                //если $asFile = 'yes' возвращаем результат макроса в виде ссылки на файл с прайслистом
+
return '<b>Файл с прайсом не смог сгенерироваться из-за ошибки:</b>'.$e->getMessage();
case 'yes':
+
}
                                        //если имя файла не задано, оно будет равно altName страницы-родителя
+
unset($pages, $page, $lines, $price, $name);
if(!$fileName){
+
fclose($open);
$correctFileName = $altName;
+
return '/files/price_as_file/'.$correctFileName.'.csv';
                                        //если имя файла есть, то прогоняем через транлит, на случай ввода русского названия файла
+
}else{
}else{
+
//возвращаем ссылку
$correctFileName = translit::convert($fileName);
+
return '/files/price_as_file/'.$correctFileName.'.csv';
}
 
$path = self::getPath('/files/price_as_file/', $correctFileName . '.csv');
 
if(is_file($path)) $mtime = filemtime($path);
 
                                        //получаем результат, сохраняем его в csv файл и возвращаем ссылку
 
if(!is_file($path) || time() > ($mtime + $expire)){
 
$open = fopen($path, 'w+');
 
                                                //задаем 'шапку' csv файла
 
$hat = array(
 
'artikul' => 'Артикул',
 
'name' => 'Наименование',
 
'price' => 'Цена'
 
);
 
fputcsv($open, $hat, ';');
 
$pages = self::getQuery($parentId, $childs);
 
                                                //наполняем файл данными, если вовремя наполнения будет ошибка, то на сайте появится информация о ней
 
try {
 
foreach($pages as $page){
 
$lines = array();
 
$lines['artikul'] = $page->getValue('artikul');
 
$lines['name'] = $page->getName();
 
$lines['price'] = $page->getValue('price');
 
fputcsv($open, $lines, ';');
 
}
 
}catch (Exception $e) {
 
return '<b>Файл с прайсом не смог сгенерироваться из-за ошибки:</b>'.$e->getMessage();
 
}
 
unset($pages, $page, $lines, $price, $name);
 
fclose($open);
 
return '/files/price_as_file/'.$correctFileName.'.csv';
 
}else{
 
                                        //возвращаем ссылку
 
return '/files/price_as_file/'.$correctFileName.'.csv';
 
}
 
break;
 
                                //если $asFile != 'yes' и != 'no' кидаем исключение
 
default:
 
throw new publicException('<b>В макросе emarket getPriceList() необходимо указать корректное значение первого параметра $asFile</b>');
 
 
}
 
}
}
+
break;
//возвращаем путь до файла
+
//если $asFile != 'yes' и != 'no' кидаем исключение
private function getPath($dirName, $file){
+
default:
$folder = CURRENT_WORKING_DIR . $dirName;   
+
throw new publicException('<b>В макросе emarket getPriceList() необходимо указать корректное значение первого параметра $asFile</b>');
$path = $folder . $file;
+
}
if(!is_dir($folder)) mkdir($folder, 0777, true);
+
}
return $path;
+
//возвращаем путь до файла
}
+
private function getPath($dirName, $file){
//возвращаем результат выборки
+
$folder = CURRENT_WORKING_DIR . $dirName;   
private function getQuery($parentId, $childs){
+
$path = $folder . $file;
$pages = new selector('pages');
+
if(!is_dir($folder)) mkdir($folder, 0777, true);
$pages->types('object-type')->name('catalog', 'object');
+
return $path;
$pages->where('hierarchy')->page($parentId)->childs($childs);
+
}
$pages->limit(0,2000);
+
//возвращаем результат выборки
return $pages;
+
private function getQuery($parentId, $childs){
}
+
$pages = new selector('pages');
//возвращаем результат парсинга шаблонов
+
$pages->types('object-type')->name('catalog', 'object');
private function getResult($pages, $template){
+
$pages->where('hierarchy')->page($parentId)->childs($childs);
if(!@$template) $template = 'default';
+
$pages->limit(0,2000);
list($itemsTemplate, $itemTemplate) = def_module::loadTemplates("emarket/{$template}", "items", "item");
+
return $pages;
$item = array();
+
}
$items = array();
+
//возвращаем результат парсинга шаблонов
foreach($pages as $page){
+
private function getResult($pages, $template){
$item['attribute:id'] = $page->id;
+
if(!@$template) $template = 'default';
$item['attribute:link'] = $page->link;
+
list($itemsTemplate, $itemTemplate) = def_module::loadTemplates("emarket/{$template}", "items", "item");
$item['attribute:price'] = $page->getValue('price');
+
$item = array();
$item['attribute:artikul'] = $page->getValue('artikul');
+
$items = array();
$item['attribute:name'] =  $page->getName();
+
foreach($pages as $page){
$items[] = def_module::parseTemplate($itemTemplate, $item);
+
$item['attribute:id'] = $page->id;
}
+
$item['attribute:link'] = $page->link;
$items = array('subnodes:items' => $items);
+
$item['attribute:price'] = $page->getValue('price');
$result = def_module::parseTemplate($itemsTemplate, $items);
+
$item['attribute:artikul'] = $page->getValue('artikul');
return $result;
+
$item['attribute:name'] =  $page->getName();
}
+
$items[] = def_module::parseTemplate($itemTemplate, $item);
 +
}
 +
$items = array('subnodes:items' => $items);
 +
$result = def_module::parseTemplate($itemsTemplate, $items);
 +
return $result;
 +
}
 
</source>
 
</source>
 
== Применение в xslt ==
 
== Применение в xslt ==
=== вызов содержимого прайслиста на страницу ===
+
=== Вызов содержимого прайслиста на страницу ===
 
'''Пример вызова'''
 
'''Пример вызова'''
 
+
<source lang="xml">
udata/emarket/getPriceList/no/(/about/)/10/0/
+
udata://emarket/getPriceList/no/(/about/)/10/3600/
 
+
</source>
 
'''XML-ответ UData'''
 
'''XML-ответ UData'''
 
<source lang="xml">
 
<source lang="xml">
Строка 187: Строка 187:
 
</udata>
 
</udata>
 
</source>
 
</source>
=== вызов файла для скачивания прайслиста на страницу ===
+
'''Элементы и атрибуты'''
 +
 
 +
'''<items>'''
 +
 
 +
    Ветвь, содержащая элементы item — страницы, удовлетворяющие параметрам выборки.
 +
'''<item>'''
 +
 
 +
    Элемент, описывающий отдельную страницу.
 +
'''@id'''
 +
 
 +
    Идентификатор страницы товара.
 +
'''@link'''
 +
 
 +
    Путь до страницы товара.
 +
'''@price'''
 +
   
 +
    Значение поля 'price'.
 +
'''@name'''
 +
 
 +
    Название товара.
 +
'''@artikul'''
 +
 
 +
    Значение поля 'artikul'.
 +
'''Примеры использования'''
 +
 
 +
Для того, чтобы вставить результат работы макроса в определенное место на странице, необходимо вызвать макрос по протоколу UData. Укажем в шаблоне дизайна место вывода при помощи инструкции apply-templates:
 +
<source lang="xml">
 +
  <xsl:apply-templates select="document('udata://emarket/getPriceList/no/(/shop/)/10/0/')/udata" mode="no"/>
 +
</source>
 +
Теперь необходимо описать шаблон, обрабатывающий результаты макроса и выводящий весь перечень элементов:
 +
<source lang="xml">
 +
<xsl:template match="udata[@module = 'emarket'][@method = 'getPriceList']" mode="no">
 +
  <table style="border:1">
 +
      <xsl:apply-templates select="items/item" mode="no"/>
 +
  </table>
 +
</xsl:template>
 +
</source>
 +
Теперь опишем шаблон для для отдельного элемента:
 +
<source lang="xml">
 +
  <xsl:template match="item" mode="getPriceList" mode="no">
 +
      <tr>
 +
        <td>
 +
    <xsl:value-of select="@price" />
 +
</td>
 +
<td>
 +
    <a href="{@link}">
 +
      <xsl:value-of select="@name" />
 +
    </a>
 +
</td>
 +
      </tr>
 +
  </xsl:template>
 +
</source>
 +
На странице выведется таблица с прайслистом выбранного раздела.
 +
=== Вызов файла для скачивания прайслиста на страницу ===
 +
'''Пример вызова'''
 +
 
 +
<source lang="xml">
 +
udata://emarket/getPriceList/yes/(/shop/)/0/3600/price
 +
</source>
 +
'''XML-ответ UData'''
 +
 
 +
<source lang="xml">
 +
<udata xmlns:xlink="http://www.w3.org/TR/xlink" module="emarket" method="getPriceList" generation-time="0.143948">/files/price_as_file/price.csv</udata>
 +
</source>
 +
'''Элементы и атрибуты'''
 +
 
 +
    макрос возвращает только value у <udata>
 +
'''Возвращаемый файл'''
 +
 
 +
Файл получается в csv формате и может свободно открывать MS Office, пример содержимого файла(если его открыть в текстовом редакторе):
 +
<source lang="text">
 +
Артикул;Наименование;Цена
 +
3453453;FY-8850;0
 +
4234234;"Телевизор «Horizont»";0
 +
6547547;"Player A4";0
 +
</source>
 +
'''Примеры использования'''
 +
 
 +
Для того, чтобы вставить результат работы макроса в определенное место на странице, необходимо вызвать макрос по протоколу UData. Укажем в шаблоне дизайна место вывода при помощи инструкции apply-templates:
 +
<source lang="xml">
 +
  <xsl:apply-templates select="document('udata://emarket/getPriceList/yes/(/shop/)/0/3600/price')/udata" mode="yes"/>
 +
</source>
 +
Теперь необходимо описать шаблон, обрабатывающий результаты макроса и выводящий ссылку на скачивание:
 +
<source lang="xml">
 +
  <xsl:template match="udata[@module = 'emarket'][@method = 'getPriceList']" mode="yes">
 +
      <xsl:variable name="path" select="." />
 +
      <a href="{$path}">прайс-лист</a>
 +
  </xsl:template>
 +
</source>
 +
На странице выведется ссылка на скачивание прайслиста.
 
== Применение в tpl ==
 
== Применение в tpl ==
== Полезные ссылки ==
+
Вывод макроса осуществляется по шаблону, указанному в параметре template. Вы можете не указывать этот параметр, тогда для вывода будет использован шаблон по умолчанию — default.tpl.
 +
=== Вызов содержимого прайслиста на страницу ===
 +
'''Используемые шаблоны'''
 +
 
 +
Макрос оперирует шаблонами, находящимися в каталоге /tpls/emarket/.
 +
'''Используемые блоки шаблона'''
 +
 
 +
'''items'''
 +
 
 +
Выводит обрамляющий блок для вывода результатов работы макроса, куда будут подставляться результирующие элементы. Отдельных страницы будут отрисованы по блоку item.
 +
 
 +
%items%
 +
 
 +
    Выводит список страниц, отрисованных с помощью блока item.
 +
 
 +
'''item'''
 +
 
 +
Отвечает за вывод отдельной страницы, полученной в результате работы макроса.
 +
 
 +
%id%
 +
 
 +
    Выводит id полученной страницы товара.
 +
%link%
 +
 
 +
    Выводит uri полученной страницы товара.
 +
%name%
 +
 
 +
    Выводит имя полученного товара.
 +
%price%
 +
 
 +
    Выводит цену полученного товара.
 +
%artikul%
 +
 
 +
    Выводит имя полученной страницы.
 +
 
 +
В шаблоне дизайна поставьте макрос %emarket getPriceList('no','36','10','0','','priceaspage')%
 +
 
 +
Создайте файл priceaspage.tpl в папке /tpls/emarket/ следующего содержания:
 +
 
 +
<source lang="php">
 +
<?php
 +
$FORMS = Array();
 +
 +
$FORMS['items'] = <<<END
 +
<table>
 +
%items%
 +
</table>
 +
END;
 +
 +
$FORMS['item'] = <<<END
 +
<tr>
 +
<td>
 +
%artikul%
 +
</td>
 +
<td>
 +
<a href="%link%">%name%</a>
 +
</td>
 +
<td>
 +
%price% рублей
 +
</td>
 +
</tr>
 +
END;
 +
?>
 +
</source>
 +
На странице выведется таблица с прайслистом выбранного раздела.
 +
=== Вызов файла для скачивания прайслиста на страницу ===
 +
 
 +
Для вывода ссылки на файл нет необходимости отрисовывать шаблон, вы можете вызвать макрос следующим образом:
 +
<source lang="html4strict">
 +
<a href="http://%domain%%emarket getPriceList('yes','36','10','3600')%">Прайс-лист</a>
 +
</source>
 +
И выведется ссылка на скачивание прайслиста.

Текущая версия на 13:01, 17 октября 2013

Актуально для версии 2.9.1

Общее описание

%emarket getPriceList()% — выводит прайслист товаров из указанного раздела

Параметры: getPriceList([$asFile = 'yes', $parent= , $childs = 10, $expire = 0, $fileName = , $template = 'default'])

$asFile

  Определяем режим работы макроса, если указано 'yes', то выводит прайслист на страниц, если 'no', то создаем csv с прайслистом и выводит путь до него на страницу,
  значение по-умолчанию - 'yes'. Сsv файл расположен по пути /files/price_as_file/, имя определяется параметром $fileName.

$parent

  id или путь до раздела, в котором будут искаться товары, если не указан, то макрос возьмет id страницы, на которой вызван.

$childs

  Глубина поиска объектов списка (во вложенных подразделах). По умолчанию в десятки уровнях вложенности.

$expire

  Время хранения кеша в секундах, если не указан, то равен нулю. Кеш храниться в директории /sys-temp/price_as_page/.

$fileName

  Используется только при значении первого параметра $asFile = 'yes', определяет имя csv файла, если ввести русские символы, то они транслитирируются, если
  параметр не указан, то берется AltName страницы, на которой он вызван.

$template

  Шаблон, по которому выводится результат макроса, используется только при значении первого параметра $asFile = 'no'. В XSLT-шаблонизаторе игнорируется.

Для применения этого макроса скопируйте содержимое листинга макроса и служебных методов в файл /classes/modules/custom.php или в __custom.php какого-либо модуля, если воспользуетесь вторым вариантом, то не забудьте указать имя метода в permissions.custom.php.

Листинг макроса и служебных методов

//возвращаем прайслист
public function getPriceList($asFile = '', $parent = '', $childs = 10, $expire = 0, $fileName = '', $template = 'default'){
	//если первый параметр не задан, то он будет равен 'yes'
	if(!$asFile) $asFile = 'yes';
	//если второй параметр не задан, то берем id текущей страницы
	if(!$parent){
	$parentId = cmsController::getInstance()->getCurrentElementId(); 
	}else{
		//если задан, то анализируем путь до файла
		$parentId = def_module::analyzeRequiredPath($parent);
		//если parentId не получен, то кидаем исключение
		if($parentId === false && $parent != KEYWORD_GRAB_ALL) {
			throw new publicException('<b>В макросе emarket getPriceList() необходимо указать корректное значение второго параметра $parent<b/>');
		}
	}
	//если третий параметр не задан, то он будет равен десяти
	if(!$childs) $childs = 10;
	//если третий параметр не число, то кидаем исключение
	if(!is_numeric($childs)){
		throw new publicException('<b>В макросе emarket getPriceList() необходимо указать корректное значение третьего параметра $childs<b/>');
	}
	//если четвертый параметр не задан, то он будет равен нулю
	if(!$expire) $expire = 0;
	//если значение четвертого параметра не число, кидаем исключене
	if(!is_numeric($expire)){
		throw new publicException('<b>В макросе emarket getPriceList() необходимо указать корректное значение четвертого параметра $expire<b/>');
	}
	//получаем altname страницы, указанной во втором параметре
	$hierarchy = umiHierarchy::getInstance();
	$page = $hierarchy->getElement($parentId); 
	$altName = $page->getAltName();
	//ветвление относительно первого параметра
	switch ($asFile) {
		//если $asFile = 'no 'возвращаем результат макроса в виде итемов с информацией о товарах
		case 'no':
			//если xslt - кешируем результат парсинга
			$isXslt = def_module::isXSLTResultMode();
			if ($isXslt){
				$path = self::getPath('/sys-temp/price_as_page/', $altName .'-cashed-as-array.txt');
				if(is_file($path)) $mtime = filemtime($path);
				//получаем и возвращаем результат, сохраняем в кеш результат
				if(!is_file($path) || time() > ($mtime + $expire)){
					$pages = self::getQuery($parentId, $childs);
					$result = self::getResult($pages, $template);
					file_put_contents($path, serialize($result));
					unset($path, $mtime, $pages);
					return $result;
				}else{
					//возвращаем результат из кеша
					return unserialize(file_get_contents($path));
				}
			}else{
				//если tpl - кешируем результат выборки
				$path = self::getPath('/sys-temp/price_as_page/', $altName .'-cashed-as-query.txt');
				if(is_file($path)) $mtime = filemtime($path);
				//получаем и возвращаем результат, сохраняем в кеш выборку
				if(!is_file($path) || time() > ($mtime + $expire)){
					$pages = self::getQuery($parentId, $childs);
					file_put_contents($path, serialize($pages));
					$result = self::getResult($pages, $template);
					unset($path, $mtime, $pages);
					return $result;
				}else{
					//берем выборку из кеша, получаем и возвращаем результат
					return self::getResult(unserialize(file_get_contents($path)), $template);
				}
			}
			break;
		//если $asFile = 'yes' возвращаем результат макроса в виде ссылки на файл с прайслистом
		case 'yes':
			//если имя файла не задано, оно будет равно altName страницы-родителя
			if(!$fileName){
				$correctFileName = $altName; 
			//если имя файла есть, то прогоняем через транлит, на случай ввода русского названия файла
			}else{
				$correctFileName = translit::convert($fileName);
			}
			$path = self::getPath('/files/price_as_file/', $correctFileName . '.csv');
			if(is_file($path)) $mtime = filemtime($path);
			//получаем результат, сохраняем его в csv файл и возвращаем ссылку	
			if(!is_file($path) || time() > ($mtime + $expire)){
				$open = fopen($path, 'w+');
				//задаем 'шапку' csv файла
				$hat = array(
					'artikul' => 'Артикул',
					'name' => 'Наименование',
					'price' => 'Цена'
				);
				fputcsv($open, $hat, ';');
				$pages = self::getQuery($parentId, $childs);
				//наполняем файл данными, если вовремя наполнения будет ошибка, то на сайте появится информация о ней
				try {
					foreach($pages as $page){
						$lines = array();
						$lines['artikul'] = $page->getValue('artikul');
						$lines['name'] = $page->getName();
						$lines['price'] = $page->getValue('price');
						fputcsv($open, $lines, ';');
					}
				}catch (Exception $e) {
					return '<b>Файл с прайсом не смог сгенерироваться из-за ошибки:</b>'.$e->getMessage();
				}
				unset($pages, $page, $lines, $price, $name);
				fclose($open);
				return '/files/price_as_file/'.$correctFileName.'.csv';
			}else{
				//возвращаем ссылку
				return '/files/price_as_file/'.$correctFileName.'.csv';
			}
			break;
		//если $asFile != 'yes' и != 'no' кидаем исключение
		default:
			throw new publicException('<b>В макросе emarket getPriceList() необходимо указать корректное значение первого параметра $asFile</b>');
	}
}
//возвращаем путь до файла
private function getPath($dirName, $file){
	$folder = CURRENT_WORKING_DIR . $dirName;  
	$path = $folder . $file;
	if(!is_dir($folder)) mkdir($folder, 0777, true);	
	return $path;
}
//возвращаем результат выборки
private function getQuery($parentId, $childs){
	$pages = new selector('pages');
	$pages->types('object-type')->name('catalog', 'object');
	$pages->where('hierarchy')->page($parentId)->childs($childs);
	$pages->limit(0,2000);
	return $pages;
}
//возвращаем результат парсинга шаблонов
private function getResult($pages, $template){
	if(!@$template) $template = 'default';
	list($itemsTemplate, $itemTemplate) = def_module::loadTemplates("emarket/{$template}", "items", "item");	
	$item = array();
	$items = array();
	foreach($pages as $page){
		$item['attribute:id'] = $page->id;
		$item['attribute:link'] = $page->link;
		$item['attribute:price'] = $page->getValue('price');
		$item['attribute:artikul'] = $page->getValue('artikul');
		$item['attribute:name'] =  $page->getName();
		$items[] = def_module::parseTemplate($itemTemplate, $item);
	}
	$items = array('subnodes:items' => $items);
	$result = def_module::parseTemplate($itemsTemplate, $items);
	return $result;
}

Применение в xslt

Вызов содержимого прайслиста на страницу

Пример вызова

udata://emarket/getPriceList/no/(/about/)/10/3600/

XML-ответ UData

<udata xmlns:xlink="http://www.w3.org/TR/xlink" module="emarket" method="getPriceList" generation-time="0.068570">
   <items>
      <item id="59" link="/about/toshiba_pcx6ad/" price="0" name="Toshiba PC-X6AD" artikul="A324234234"/>
   </items>
</udata>

Элементы и атрибуты

<items>

   Ветвь, содержащая элементы item — страницы, удовлетворяющие параметрам выборки.

<item>

   Элемент, описывающий отдельную страницу.

@id

   Идентификатор страницы товара.

@link

   Путь до страницы товара.

@price

   Значение поля 'price'.

@name

   Название товара.

@artikul

   Значение поля 'artikul'.

Примеры использования

Для того, чтобы вставить результат работы макроса в определенное место на странице, необходимо вызвать макрос по протоколу UData. Укажем в шаблоне дизайна место вывода при помощи инструкции apply-templates:

   <xsl:apply-templates select="document('udata://emarket/getPriceList/no/(/shop/)/10/0/')/udata" mode="no"/>

Теперь необходимо описать шаблон, обрабатывающий результаты макроса и выводящий весь перечень элементов:

<xsl:template match="udata[@module = 'emarket'][@method = 'getPriceList']" mode="no">
   <table style="border:1">	
      <xsl:apply-templates select="items/item" mode="no"/>
   </table>
</xsl:template>

Теперь опишем шаблон для для отдельного элемента:

   <xsl:template match="item" mode="getPriceList" mode="no">
      <tr>
         <td>
	    <xsl:value-of select="@price" />
	 </td>
	 <td>
	    <a href="{@link}">
	       <xsl:value-of select="@name" />
	    </a>
	 </td>
      </tr>
   </xsl:template>

На странице выведется таблица с прайслистом выбранного раздела.

Вызов файла для скачивания прайслиста на страницу

Пример вызова

udata://emarket/getPriceList/yes/(/shop/)/0/3600/price

XML-ответ UData

<udata xmlns:xlink="http://www.w3.org/TR/xlink" module="emarket" method="getPriceList" generation-time="0.143948">/files/price_as_file/price.csv</udata>

Элементы и атрибуты

   макрос возвращает только value у <udata>

Возвращаемый файл

Файл получается в csv формате и может свободно открывать MS Office, пример содержимого файла(если его открыть в текстовом редакторе):

Артикул;Наименование;Цена
3453453;FY-8850;0
4234234;"Телевизор «Horizont»";0
6547547;"Player A4";0

Примеры использования

Для того, чтобы вставить результат работы макроса в определенное место на странице, необходимо вызвать макрос по протоколу UData. Укажем в шаблоне дизайна место вывода при помощи инструкции apply-templates:

   <xsl:apply-templates select="document('udata://emarket/getPriceList/yes/(/shop/)/0/3600/price')/udata" mode="yes"/>

Теперь необходимо описать шаблон, обрабатывающий результаты макроса и выводящий ссылку на скачивание:

   <xsl:template match="udata[@module = 'emarket'][@method = 'getPriceList']" mode="yes">		
      <xsl:variable name="path" select="." />
      <a href="{$path}">прайс-лист</a>
   </xsl:template>

На странице выведется ссылка на скачивание прайслиста.

Применение в tpl

Вывод макроса осуществляется по шаблону, указанному в параметре template. Вы можете не указывать этот параметр, тогда для вывода будет использован шаблон по умолчанию — default.tpl.

Вызов содержимого прайслиста на страницу

Используемые шаблоны

Макрос оперирует шаблонами, находящимися в каталоге /tpls/emarket/. Используемые блоки шаблона

items

Выводит обрамляющий блок для вывода результатов работы макроса, куда будут подставляться результирующие элементы. Отдельных страницы будут отрисованы по блоку item.

%items%

   Выводит список страниц, отрисованных с помощью блока item.

item

Отвечает за вывод отдельной страницы, полученной в результате работы макроса.

%id%

   Выводит id полученной страницы товара.

%link%

   Выводит uri полученной страницы товара.

%name%

   Выводит имя полученного товара.

%price%

   Выводит цену полученного товара.

%artikul%

   Выводит имя полученной страницы.

В шаблоне дизайна поставьте макрос %emarket getPriceList('no','36','10','0',,'priceaspage')%

Создайте файл priceaspage.tpl в папке /tpls/emarket/ следующего содержания:

<?php
$FORMS = Array();
 
$FORMS['items'] = <<<END
<table>
	%items%
</table>
END;
 
$FORMS['item'] = <<<END
<tr>
	<td>
		%artikul%
	</td>
	<td>
		<a href="%link%">%name%</a>
	</td>
	<td>
		%price% рублей
	</td>
</tr>
END;
?>

На странице выведется таблица с прайслистом выбранного раздела.

Вызов файла для скачивания прайслиста на страницу

Для вывода ссылки на файл нет необходимости отрисовывать шаблон, вы можете вызвать макрос следующим образом:

<a href="http://%domain%%emarket getPriceList('yes','36','10','3600')%">Прайс-лист</a>

И выведется ссылка на скачивание прайслиста.