Экспорт данных в формат 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

Личные инструменты