Экспорт в YML при нехватке производительности сервера (umi 2.8.1)
Материал из Umicms
Будем использовать дополнительные кастомные методы, которые пропишем в файле classes/modules/data/__custom.php
public function ymlnew() { $ids = getRequest('ids'); $yml_file_temp = getRequest('file'); $cache_file_path = "./sys-temp/export/yml{$yml_file_temp}.xml"; $templxsl_temp = getRequest('templxsl'); $style_file = "./xsl/export/YML{$templxsl_temp}.xsl"; $objects = umiObjectsCollection::getInstance(); if (!is_dir("./sys-temp/export/")) mkdir("./sys-temp/export/", 0777, true); $exporter = new xmlExporter("YML"); $category_elements_arr[] = umiHierarchy::getInstance()->getElement($ids); $exporter->addBranches($category_elements_arr); $result = $exporter->execute(); $umiDump = $result->saveXML(); if (!is_file($style_file)) { throw new publicException("Can't load exporter {$style_file}"); } $doc = new DOMDocument("1.0", "utf-8"); $doc->formatOutput = XML_FORMAT_OUTPUT; $doc->loadXML($umiDump); $templater = xslTemplater::getInstance(); $templater->setIsInited(false); $templater->init($style_file); $templater->setXmlDocument($doc); $result = $templater->parseResult(); // convert to CP1251 $result = iconv("UTF-8", "CP1251", $result); $doc = new DOMDocument("1.0", "windows-1251"); $result = str_replace('<' . '?xml version="1.0" encoding="utf-8"?>', '<' . '?xml version="1.0" encoding="windows-1251"?>', $result); file_put_contents($cache_file_path, $result); $url = getServer('HTTP_REFERER'); if (!strstr($url,"step")) { $link = $url."?step=1"; } else { $id_step = substr($url,-1); $id_step++; $link = substr($url, 0, -1)."".$id_step; } def_module::redirect($link); } public function stepsform($parent_id){ $objects = umiObjectsCollection::getInstance(); $objectTypes = umiObjectTypesCollection::getInstance(); $id_category = Array(); if($category_obj = $objects->getObject($parent_id)){ if($category_obj->getTypeId() == $objectTypes->getBaseType("exchange", "export")){ $ids_category = $category_obj->getValue("elements"); foreach($ids_category as $element) { $id_category[] = $element->id; } } } else if($hierarchy = umiHierarchy::getInstance()->getChilds($parent_id,false,true,1,5)){ $id_category = array_keys($hierarchy); } else return ""; $size = sizeof($id_category); if(array_key_exists('step',$_GET) && $size >= $_GET['step']){ $step = (int)$_GET['step']; $index = $step - 1; $name = umiHierarchy::getInstance()->getElement($id_category[$index])->getName(); $itog =<<<HTML {$step}-й раздел из {$size}: <br /><br /> <form id="steps" action="/data/ymlnew/" method="post"> <input style="visibility:hidden" type="checkbox" checked="checked" name="ids" value="{$id_category[$index]}" /> <input style="visibility:hidden" type="checkbox" checked="checked" name="file" value="{$step}" /> <input style="visibility:hidden" type="checkbox" checked="checked" name="templxsl" value="3" /> <input type="submit" value="Экспорт раздела с id = {$id_category[$index]} ({$name})" /> </form> <script language="JavaScript">setTimeout('document.getElementById("steps").submit()', 10000);</script> HTML; return $itog; } if(!array_key_exists('step',$_GET)){ $itog =<<<HTML <form action="/data/ymlcategory/" method="post"> <input style="visibility:hidden" type="checkbox" checked="checked" name="ids" value="{$parent_id}" /> <input style="visibility:hidden" type="checkbox" checked="checked" name="file" value="0" /> <input type="submit" value="Начать экспорт в YML" /> </form> HTML; return $itog; } if(array_key_exists('step',$_GET) && sizeof($id_category) < $_GET['step']){ // Блок соединения всех xml файлов: yml0.xml, yml1.xml, ... в файл yml.xml $category = "./sys-temp/export/yml0.xml"; $handle_category = fopen($category, "r"); $size = filesize($category) - 21; $category_itog = fread($handle_category,$size); $handle = fopen("./yml.xml", "w+"); fwrite($handle, $category_itog); fclose($handle_category); fwrite($handle, "<offers>"); for($i = 1; $i <= sizeof($id_category); $i++){ $offers = "./sys-temp/export/yml{$i}.xml"; $handle_offers = fopen($offers, "r"); fread($handle_offers,54); $size_offers = filesize($offers) - 64; $offers_itog = fread($handle_offers,$size_offers); fwrite($handle, $offers_itog); fclose($handle_offers); } fwrite($handle, "</offers></shop></yml_catalog>"); fclose($handle); } return "<a href = \"/yml.xml\">Ссылка на итоговый YML файл</a>"; } public function ymlcategory(){ $parent_id = getRequest('ids'); $time = date("Y-m-d H:i"); $xml_date = "<yml_catalog date=\"".$time."\">"; $regedit = regedit::getInstance(); $site_name = $regedit->getVal("//settings/site_name"); $xml_name = "<name>{$site_name}</name>"; $xml_company = "<company>{$site_name}</company>"; $domain = domainsCollection::getInstance()->getDefaultDomain()->getHost(); $xml_url = "<url>http://{$domain}</url>"; $objectTypes = umiObjectTypesCollection::getInstance(); $objectTypeId = $objectTypes->getBaseType("emarket", "currency"); $sel = new umiSelection; $sel->addObjectType($objectTypeId); $result = umiSelectionsParser::runSelection($sel); $objects = umiObjectsCollection::getInstance(); $currency = ""; foreach($result as $objectId) { $object = $objects->getObject($objectId); $codename = $object->getValue("codename"); $rate = $object->getValue("rate"); $currency .= "<currency id=\"".$codename."\" rate=\"".$rate."\"/>"; } $category0 = Array(); if($category_obj = $objects->getObject($parent_id)){ if($category_obj->getTypeId() == $objectTypes->getBaseType("exchange", "export")){ $ids_category = $category_obj->getValue("elements"); $category = Array(); foreach($ids_category as $element) { $category0[] = $element->id; $category[] = "'{$element->id}'"; } $parent_id = implode(", ",$category); } }else{ $category0[] = $parent_id; $parent_id = "'{$parent_id}'"; } $sqls =<<<SQL SELECT h.id FROM cms3_hierarchy_relations hr, cms3_hierarchy h WHERE h.is_deleted = '0' AND (((hr.rel_id IN({$parent_id}) AND hr.level <= '11') AND hr.child_id = h.id)) AND h.type_id IN ('5') ORDER BY h.ord SQL; $result = l_mysql_query($sqls); $res = Array(); while ($row = mysql_fetch_row($result)) { list($element_id) = $row; $element_id = intval($element_id); if(in_array($element_id, $res) == false) { $res[] = $element_id; } } $all_category = array_merge($category0,$res); $category_str = ""; $h = umiHierarchy::getInstance(); foreach($all_category as $id) { $parent_str = ""; $name = $h->getElement($id)->getName(); if((array_search($id,$category0) === false) && $parent_category = $h->getParent($id)){ $parent_str = " parentId=\"".$parent_category."\""; } else{ $parent_str = ""; } $category_str .= "<category id=\"".$id."\"".$parent_str.">".$name."</category>"; } $xml_category = "<?xml version=\"1.0\" encoding=\"windows-1251\"?>\n{$xml_date}"; $xml_category .= "<shop>{$xml_name}{$xml_company}{$xml_url}"; $xml_category .= "<currencies>{$currency}</currencies>"; $xml_category .= "<categories>{$category_str}</categories></shop></yml_catalog>"; $cache_file_path = "./sys-temp/export/yml0.xml"; $result = iconv("UTF-8", "CP1251", $xml_category); file_put_contents($cache_file_path, $result); $url = getServer('HTTP_REFERER'); if (!strstr($url,"step")) { $link = $url."?step=1"; } else { $id_step = substr($url,-1); $id_step++; $link = substr($url, 0, -1)."".$id_step; } def_module::redirect($link); }
В той же папке необходимо создать файл permissions.custom.php с таким содержанием:
<?php
$permissions = Array('main' => Array('ymlnew','stepsform','ymlcategory'));
?>
В папке xsl/export/ необходимо создать YML3.xsl шаблон аналогичный YML.xsl, в котором шаблон <xsl:template match="umidump[@version='2.0']"> будет таким:
<xsl:template match="umidump[@version='2.0']"> <offers> <xsl:apply-templates select="pages/page[basetype/@method = 'object']" /> </offers> </xsl:template>
Создаем страницу контента в админке, в поле контент прописываем макрос %data stepsform(45)%, где 45 - id основного раздела каталога или oject_id шаблона экспорта в YML, в модуле "Обмен данными", вкладка Экспорт.
