Экспорт данных в формат UmiDump2.0 при нехватке memory limit на хостинге
Материал из Umicms
Если вам необходимо сделать выгрузку большого объема данных в формат UmiDump, но это не позволяет сделать ограничение параметра memory_limit, т.е. выделенной памяти под php скрипты все равно не хватает, то можно воспользоваться скриптом, представленным ниже. Скрипт использует перезагрузку страницы и производит экспорт маленькими частями. После каждой итерации в итоговый файл umidump.xml добавляются новые данные. В методе umidumpnew() есть переменная $count, с помощью нее устанавливается количество элементов экспортируемых за одну итерацию. Три кастомных метода необходимо прописать в файле classes/modules/data/__custom.php:
public function umidumpnew() { $step = getRequest('file'); if(!$step){ $branches_ids = getRequest('branches'); $objects = umiObjectsCollection::getInstance(); $settings = $objects->getObject($branches_ids); $items = $settings->elements; $res = Array(); foreach($items as $item) { $select = new selector('pages'); $select->where('hierarchy')->page($item->id)->childs(15); $select->where('is_active')->isnull(false); $res = array_merge($res,$select->result()); } $result = array_unique(array_merge($items,$res)); $result_elements_id = array(); foreach($result as $item) { $result_elements_id []= $item->id; } file_put_contents("./sys-temp/export/elements", serialize($result_elements_id)); } else{ $elements_tmp = unserialize(file_get_contents("./sys-temp/export/elements")); $count = 50; $offset = ($step - 1)*$count; $elements = array_slice($elements_tmp,$offset,$count); $exporter = new xmlExporter("umiDump20"); $exporter->addElements($elements); $result = $exporter->execute(); if($step == 1){ $result->save('./sys-temp/export/umidump.xml'); }else{ $xpath_result = new DomXPath($result); $node = $xpath_result->query("/umidump/pages/page"); $doc = new DOMDocument; $doc->formatOutput = true; $doc->load("./sys-temp/export/umidump.xml"); $xpath_doc = new DomXPath($doc); foreach($node as $item){ $node = $doc->importNode($item, true); $xpath_doc->query("/umidump/pages")->item(0)->appendChild($node); } $nodlist_type = $xpath_doc->query("/umidump/types/type"); $arr_types = array(); foreach($nodlist_type as $item){ $arr_types []= $item->getAttribute('id'); } $nodlist_type = $xpath_result->query("/umidump/types/type"); $arr_types_result = array(); foreach($nodlist_type as $item){ $type_id = $item->getAttribute('id'); if(!in_array($type_id, $arr_types)){ $node_type = $doc->importNode($item, true); $xpath_doc->query("/umidump/types")->item(0)->appendChild($node_type); } } $doc->save('./sys-temp/export/umidump.xml'); } if(!count($elements)) { $url = getServer('HTTP_REFERER'); $offset = (int) strlen($step); $id_step = substr($url,-$offset); $link = substr($url, 0, -$offset)."999"; def_module::redirect($link); } } $url = getServer('HTTP_REFERER'); if (!strstr($url,"step")) { $link = $url."?step=1"; } else { $offset = (int) strlen($step); $id_step = substr($url,-$offset); $id_step++; $link = substr($url, 0, -$offset)."".$id_step; } def_module::redirect($link); } public function exportdump($branches){ if(array_key_exists('step',$_GET) && $_GET['step'] == 999){ return "<a href = \"/data/viewumidump/\">Ссылка на итоговый UmiDump файл</a>"; } if(array_key_exists('step',$_GET)){ $step = (int)$_GET['step']; $itog =<<<HTML <form id="steps" action="/data/umidumpnew/" method="post"> <input style="visibility:hidden" type="checkbox" checked="checked" name="file" value="{$step}" /> <input type="submit" value="Идет экспорт данных. Ждите..." /> </form> <script language="JavaScript">setTimeout('document.getElementById("steps").submit()', 500);</script> HTML; return $itog; }else{ $itog =<<<HTML <form action="/data/umidumpnew/" method="post"> <input style="visibility:hidden" type="checkbox" checked="checked" name="file" value="0" /> <input style="visibility:hidden" type="checkbox" checked="checked" name="branches" value="{$branches}" /> <input type="submit" value="Начать экспорт в UmiDump2.0" /> </form> HTML; return $itog; } } public function viewumidump(){ header("Content-type: text/xml; charset=utf-8"); echo file_get_contents("./sys-temp/export/umidump.xml"); exit(); }
Также в папке classes/modules/data/ необходимо создать файл permissions.custom.php с таким содержанием:
<?php
$permissions = Array('tree' => Array('umidumpnew', 'exportdump', 'viewumidump'));
?>
Принцип использования следующий. Вы в модуле "Обмен данными" создаете объект экспорта, указываете в нем какие разделы вы хотите экспортировать, выбираете формат экспорта umiDump2.0. Далее необходимо в структуре сайта создать страницу, допустим страницу контента, в поле "Контент" данной страницы прописать следующий макрос:
%data exportdump(23745)%
где 23745 – object_id вашего экспорта, созданного в модуле Обмен данными.
Переходим, в клиентской части сайта, на только что созданную страницу, нажимаем кнопку "Начать экспорт в UmiDump2.0" и ждем окончания процесса экспорта. По завершению экспорта отобразится ссылка на итоговый xml файл в формате UmiDump2.0. Физически, итоговый xml файл находится по пути /sys-temp/export/umidump.xml
