Прайслист — различия между версиями
Mad grant (обсуждение | вклад) |
Mad grant (обсуждение | вклад) |
||
(не показаны 33 промежуточные версии этого же участника) | |||
Строка 1: | Строка 1: | ||
− | [[category:Написание кастомных макросов]] | + | [[category:Написание кастомных макросов]][[Категория: Верстка в XSLT]][[Категория:Верстка в TPL]][[Категория:API]][[Категория:Модуль_Интернет_магазин]][[Категория:Модуль_Каталог]] |
'''Актуально для версии 2.9.1''' | '''Актуально для версии 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. | ||
== Листинг макроса и служебных методов== | == Листинг макроса и служебных методов== | ||
<source lang="php"> | <source lang="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{ | }else{ | ||
− | + | //если tpl - кешируем результат выборки | |
− | $ | + | $path = self::getPath('/sys-temp/price_as_page/', $altName .'-cashed-as-query.txt'); |
− | + | if(is_file($path)) $mtime = filemtime($path); | |
− | if($parentId = | + | //получаем и возвращаем результат, сохраняем в кеш выборку |
− | + | 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(!$ | + | //если $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; | ||
+ | } | ||
+ | </source> | ||
+ | == Применение в xslt == | ||
+ | === Вызов содержимого прайслиста на страницу === | ||
+ | '''Пример вызова''' | ||
+ | <source lang="xml"> | ||
+ | udata://emarket/getPriceList/no/(/about/)/10/3600/ | ||
+ | </source> | ||
+ | '''XML-ответ UData''' | ||
+ | <source lang="xml"> | ||
+ | <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> | ||
+ | </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> | </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>
И выведется ссылка на скачивание прайслиста.