Модуль импорта v2.26.0 (Light версия)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

641 lines
18 KiB

<?php
/**
* Класс модуля импорта
*
* @package AVE.cms
* @subpackage module_import
* @author Realter
* @since 3.00
* @filesource
*/
class import
{
/**
* Свойства класса
*/
/**
* Парсеры
*/
var $parsers = array('CSV2Array','XML2Array','Excel2Array');
/**
* Основные поля документа, предлагаемые для импорта
*/
var $header_fields = array(
'Id',
'document_title',
'document_alias',
'document_meta_keywords',
'document_meta_description',
'document_meta_robots',
'document_published',
'document_in_search',
'document_status',
'document_linked_navi_id',
'document_breadcrum_title',
'document_parent',
'document_count_view',
);
/**
* Внутренние методы класса
*/
/**
* Удаление документа
*
* @param int $id идентификатор документа
*/
function GetDoc($id)
{
global $AVE_DB;
$AVE_DB->Query("
UPDATE " . PREFIX . "_documents
SET
document_status = '0',
document_deleted = '1'
WHERE Id = " . $id
);
}
/**
* Удаление документа
*
* @param int $id идентификатор документа
*/
function DeleteDoc($id)
{
global $AVE_DB;
$AVE_DB->Query("
UPDATE " . PREFIX . "_documents
SET
document_status = '0',
document_deleted = '1'
WHERE Id=". $id
);
}
/**
* Изменение документа
* @param int $id идентификатор документа
* @param array $array набор данных документа
*/
function UpdateDoc($rub, $id, $array)
{
require_once(BASE_DIR . '/class/class.docs.php');
$AVE_Document = new AVE_Document();
$d = $array['header'];
$d['doc_title'] = $d['document_title'];
$d['document_expire'] = date("d.m.Y H:i",strtotime('+20 year'));
$d['document_status'] = 1;
$d['feld'] = $array['body'];
return $AVE_Document->documentSave($rub,$id,$d);
}
/**
* Добавление документа
*
* @param int $rub идентификатор рубрики
* @param array $array набор данных документа
*/
function InsertDoc($rub, $array)
{
require_once(BASE_DIR.'/class/class.docs.php');
$AVE_Document=new AVE_Document();
$d = $array['header'];
$d['document_expire'] = date("d.m.Y H:i",strtotime('+20 year'));
$d['document_status'] = 1;
$d['doc_title'] = $d['document_title'];
$d['feld'] = $array['body'];
return $AVE_Document->documentSave((int)$rub, null, $d);
}
/**
* Проверка наличия документа по ключевым полям
*
* @param array $array - массив ID_поля_в_рублике=>Ключевое_значение
* @param int $rub - id рубрики
*
* @return int/false - возвращает Id документа или false
*/
function Doc_Exists($key_fields,$rub)
{
global $AVE_DB;
$sql_tables='';
$sql_header='';
$sql_body='';
$header = array();
foreach($key_fields['header'] as $k => $v)
{
$header[] = 'a.' . $k . " = '" . $v . "'";
}
if ($header) $sql_header = ' AND ' . implode(' AND ', $header);
$tables = array();
$body = array();
$x = 0;
foreach($key_fields['body'] as $k => $v)
{
$tables[] = PREFIX . "_document_fields AS t" . $x;
$body[] = "(a.Id=t" . $x . ".document_id AND(t" . $x . ".rubric_field_id=" . $k . " AND t" . $x . ".field_value='" . addslashes($v) . "'))";
$x++;
}
if ($tables) $sql_tables = ', ' . implode(', ', $tables);
if ($body) $sql_body = ' AND ' . implode(' AND ', $body);
$sql = "
SELECT a.Id FROM " . PREFIX . "_documents
AS a " . $sql_tables . "
WHERE
a.rubric_id=" . $rub . $sql_header . $sql_body;
$doc_id = $AVE_DB->Query($sql)->GetCell();
return $doc_id;
}
static function object_to_array($Class)
{
# Typecast to (array) automatically converts stdClass -> array.
$Class = (array)$Class;
$emptyarr=array();
if($emptyarr===$Class) return '';
# Iterate through the former properties looking for any stdClass properties.
# Recursively apply (array).
foreach($Class as $key => &$value)
{
if((is_object($value)||is_array($value)))
{
$Class[$key] = import::object_to_array($value);
}
//$value=addslashes($value);
}
return $Class;
}
/**
* read a csv file and return an indexed array.
* @param string $cvsfile path to csv file
* @param array $fldnames array of fields names. Leave this to null to use the first row values as fields names.
* @param string $sep string used as a field separator (default ';')
* @param string $protect char used to protect field (generally single or double quote)
* @param array $filters array of regular expression that row must match to be in the returned result.
* ie: array('fldname'=>'/pcre_regexp/')
* @return array
*/
function CSV2Array($csvfile,$fldnames=null,$sep=',',$protect='"',$filters=null)
{
if(! $csv = file($csvfile) )
return FALSE;
# use the first line as fields names
if( is_null($fldnames) ){
$fldnames = array_shift($csv);
$fldnames = explode($sep,$fldnames);
$fldnames = array_map('trim',$fldnames);
if($protect){
foreach($fldnames as $k=>$v)
$fldnames[$k] = preg_replace(array("/(?<!\\\\)$protect/","!\\\\($protect)!"),'\\1',$v);
}
}elseif( is_string($fldnames) ){
$fldnames = explode($sep,$fldnames);
$fldnames = array_map('trim',$fldnames);
}
$i=0;
foreach($csv as $row){
if($protect){
$row = preg_replace(array("/(?<!\\\\)$protect/","!\\\\($protect)!"),'\\1',$row);
}
$row = explode($sep,trim($row));
foreach($row as $fldnb=>$fldval)
$res[$i][(isset($fldnames[$fldnb])?$fldnames[$fldnb]:$fldnb)] = $fldval;
if( is_array($filters) ){
foreach($filters as $k=>$exp){
if(! preg_match($exp,$res[$i][$k]) )
unset($res[$i]);
}
}
$i++;
}
unset($csv);
return $res;
}
function Excel2Array($fname)
{
require_once(dirname(__FILE__).'/excel_reader.php');
$Excel = new Spreadsheet_Excel_Reader(); // создаем объект
$Excel->setOutputEncoding('UTF-8'); // устанавливаем кодировку
$Excel->read($fname); // открываем файл
$rowscount = $Excel->sheets[0]['numRows']; // узнаем количество строк в 1 листе $xml = import::object_to_array($xml);
$res = array();
for($rowNum=2;$rowNum<=$rowscount;$rowNum++)
{
$collscount=count($Excel->sheets[0]['cells'][$rowNum]);
for($cell=1;$cell<($collscount+1);$cell++)
{
//Чойто с екселя приходит 160 символ если пусто в ячейке
$val=(trim($Excel->val($rowNum,$cell)));
$res[$rowNum][$Excel->sheets[0]['cells'][1][$cell]]=($val===chr(160) ? '' : $val);
}
}
return $res;
}
function XML2Array($fname)
{
$xml = (simplexml_load_file($fname));
$xml = import::object_to_array($xml);
// Убираем роот элемент из Массива чтобы добраться до самих записей - может есть варианты полегче...
$a = array_values($xml);
unset($xml);
return ($a[0]);
}
// рекурсивно создаёт массив с заменами
function _replace_array($mixed,$key='',$new=true)
{
static $arr = array();
if($new) $arr = array();
if (!is_array($mixed)) return $arr['[row'.$key.']'] = $mixed;
$res = $key;
foreach ($mixed as $k=>$v)
{
if(is_array($v))
{
$arr['[row:'.$k.']'] = serialize($v);
}
$this->_replace_array($v,$res.':'.$k,false);
}
return $arr;
}
// Заменяет в массиве доков, используя массив замен, выполняя код php
function _replace(&$item, &$key, $repl_array)
{
$code = stripslashes(strtr($item,$repl_array));
$item = eval2var('?>' . $code . '<?');
}
/**
* Внешние методы класса
*/
/**
* Вывод списка импортов
*
* @param string $tpl_dir - путь к папке с шаблонами модуля
*/
function importList($tpl_dir)
{
global $AVE_DB, $AVE_Template;
$imports = array();
$sql = $AVE_DB->Query("SELECT * FROM " . PREFIX . "_module_import");
while ($result = $sql->FetchRow())
{
array_push($imports, $result);
}
$rubs = array();
$sql = $AVE_DB->Query("SELECT * FROM " . PREFIX . "_rubrics");
while ($result = $sql->FetchRow())
{
array_push($rubs, $result);
}
$AVE_Template->assign('imports', $imports);
$AVE_Template->assign('rubs', $rubs);
$AVE_Template->assign('content', $AVE_Template->fetch($tpl_dir . 'admin_list.tpl'));
}
/**
* Редактирование импорта
*
* @param int $import_id идентификатор системного блока
* @param string $tpl_dir - путь к папке с шаблонами модуля
*
* @todo сделать отдельно методы добавления и редактирования
*/
function importEdit($import_id, $tpl_dir)
{
global $AVE_DB, $AVE_Template;
if (is_numeric($import_id))
{
$row = $AVE_DB->Query("
SELECT *
FROM " . PREFIX . "_module_import
WHERE id = '" . $import_id . "'
")->FetchAssocArray();
$row['import_text'] = unserialize($row['import_text']);
}
else
{
$row['import_name'] = '';
$row['import_text'] = array();
$row['import_delete_docs'] = 0;
$row['import_docs_create'] = 0;
}
// рубрики
$sql = $AVE_DB->Query("SELECT * FROM " . PREFIX . "_rubrics");
while ($result = $sql->FetchRow())
{
$rubs[] = $result;
}
// основные поля
$fields = array();
foreach ($this->header_fields as $field)
{
$val = @$row['import_text']['fields']['header'][$field];
$fields['header'][$field] = array(0 => $val, 1 => $AVE_Template->get_config_vars('IMPORT_' . $field));
}
// поля
$s = $AVE_DB->Query("
SELECT * FROM " . PREFIX . "_rubric_fields
WHERE rubric_id = " . intval(@$row['import_rub'])
);
while ($r = $s->FetchAssocArray())
{
$val = $row['import_text']['fields']['body'][$r['Id']];
$fields['body'][$r['Id']] = array(0 => $val, 1 => $r['rubric_field_title']);
}
$row['import_text']['fields'] = $fields;
// передаём данные в смарти
$AVE_Template->assign('rubs',$rubs);
$AVE_Template->assign('parses', $this->parsers);
$AVE_Template->assign('data', $row['import_text']);
unset($row['import_text']);
$AVE_Template->assign($row);
$AVE_Template->assign('content', $AVE_Template->fetch($tpl_dir . 'admin_edit.tpl'));
}
/**
* Сохранение импорта
*
* @param int $import_id идентификатор импорта
*/
function importSave($import_id = null)
{
global $AVE_DB;
if (is_numeric($import_id))
{
$AVE_DB->Query("
UPDATE " . PREFIX . "_module_import
SET
`import_name` = '" . addslashes($_POST['import_name']) . "',
".($_POST['import_rub']> '' ? "`import_rub` = '" . addslashes($_POST['import_rub']) . "'," : "" )."
`import_parser` = '" . addslashes($_POST['import_parser']) . "',
`import_delete_docs` = '" . ($_POST['import_delete_docs'] ? 1 : 0) . "',
`import_docs_create` = '" . ($_POST['import_docs_create'] ? 1 : 0) . "',
`import_default_file` = '" . addslashes($_POST['import_default_file']) . "',
`import_monitor_file` = '" . addslashes($_POST['import_monitor_file'] ? '1' : '0') . "',
`import_last_update` = '" . addslashes($_POST['import_last_update']) . "',
`import_text` = '" . addslashes(serialize($_POST['document'])) . "'
WHERE
id = '" . $import_id . "'
");
header('Location:index.php?do=modules&action=modedit&mod=import&moduleaction=1&cp=' . SESSION);
exit();
}
else
{
$AVE_DB->Query("
INSERT
INTO " . PREFIX . "_module_import
SET
`import_name` = '" . addslashes($_POST['import_name']) . "',
`import_rub` = '" . addslashes($_POST['import_rub']) . "',
`import_parser` = '" . addslashes($_POST['import_parser']) . "',
`import_delete_docs` = '" . ($_POST['import_delete_docs'] ? 1 : 0) . "',
`import_docs_create` = '" . ($_POST['import_docs_create'] ? 1 : 0) . "',
`import_default_file` = '" . addslashes($_POST['import_default_file']) . "',
`import_monitor_file` = '" . addslashes($_POST['import_monitor_file'] ? '1' : '0') . "',
`import_last_update` = '" . addslashes($_POST['import_last_update']) . "',
`import_text` = '" . addslashes(serialize($_POST['document'])) . "'
");
$import_id = $AVE_DB->Query("SELECT LAST_INSERT_ID(id) FROM " . PREFIX . "_module_import ORDER BY id DESC LIMIT 1")->GetCell();
header('Location:index.php?do=modules&action=modedit&mod=import&moduleaction=edit&id=' . $import_id . '&cp=' . SESSION);
exit();
}
}
/**
* Удаление импорта
*
* @param int $import_id идентификатор системного блока
*/
function importDelete($import_id)
{
global $AVE_DB;
if (is_numeric($import_id))
{
$AVE_DB->Query("
DELETE
FROM " . PREFIX . "_module_import
WHERE id = '" . $import_id . "'
");
}
header('Location:index.php?do=modules&action=modedit&mod=import&moduleaction=1&cp=' . SESSION);
}
/**
* Импорт
*
* @param int $import_id идентификатор системного блока
*/
function DoImport($import_id, $tags_only = false, $location = true)
{
global $AVE_DB;
$_REQUEST['import'] = 'import';
$import = $AVE_DB->Query("
SELECT *
FROM " . PREFIX . "_module_import
WHERE id = '" . $import_id . "'
")->FetchAssocArray();
$import['import_text'] = @unserialize($import['import_text']);
if($tags_only) $import['import_text']['tags'] = array();
//Создаем массив ключевых полей
if(is_array(@$import['import_text']['key']['header'])){
foreach($import['import_text']['key']['header'] as $k=>$v)
{
$import_key_fields['header'][$k] = $import['import_text']['fields']['header'][$k];
}
}
if(is_array(@$import['import_text']['key']['body'])){
foreach($import['import_text']['key']['body'] as $k=>$v)
{
$import_key_fields['body'][$k] = $import['import_text']['fields']['body'][$k];
}
}
// Получаем массив из файла импорта
$func = $import['import_parser'];
$rows = $this->$func(BASE_DIR . $import['import_default_file']);
// Помечаем документы как удалённые, если нужно
if($import['import_delete_docs'] && !$tags_only)
{
$AVE_DB->Query("
UPDATE " . PREFIX . "_documents
SET
document_status = '0'
WHERE rubric_id=" . $import['import_rub']
);
}
// Обрабатываем по очереди каждый объект
foreach($rows as $row)
{
// создаем массив замен
$replace_array = array();
$replace_array = $this->_replace_array($row);
$replace_array['[Y-m-d]'] = date('d.m.Y H:i');
// если нужно только обновить теги
if($tags_only)
{
$import['import_text']['tags'] = array_unique(array_merge($import['import_text']['tags'],array_keys($replace_array)));
}
else
{
// дополняем массив замен отсутствующими тегами
foreach($import['import_text']['tags'] as $v)
{
if(! $replace_array[$v]) $replace_array[$v] = '';
}
$key_fields = $import_key_fields;
$doc_fields = array();
$doc_fields['header'] = $import['import_text']['fields']['header'];
$doc_fields['body'] = $import['import_text']['fields']['body'];
// гуляем по шаблонам - заменяем теги на значения
array_walk_recursive($key_fields, array($this, '_replace'), $replace_array);
array_walk_recursive($doc_fields, array($this, '_replace'), $replace_array);
//проверяем значения по критическим полям
$critical = false;
if(isset($import['import_text']['critical']['header'])&&is_array($import['import_text']['critical']['header']))
foreach(@$import['import_text']['critical']['header'] as $k => $v)
if(trim($doc_fields['header'][$k])=='') $critical=true;
if(isset($import['import_text']['critical']['body'])&&is_array($import['import_text']['critical']['body']))
foreach(@$import['import_text']['critical']['body'] as $k => $v)
if(trim($doc_fields['body'][$k])=='') $critical=true;
if(! $critical)
{
//Если прошли проверку импортируем
// проверяем наличие документа по ключевому полю
$id = $this->Doc_Exists($key_fields, $import['import_rub']);
if ($id)
{
// удаляем из массива поля, которые не надо импортировать
foreach($import['import_text']['active']['header'] as $k => $v)
{
if(! $v)
{
$doc_fields['header'][$k] = $AVE_DB->Query("
SELECT " . $k . " FROM " . PREFIX . "_documents
WHERE Id = " . $id
)->GetCell();
}
}
foreach($import['import_text']['active']['body'] as $k => $v)
{
if(! $v)
unset($doc_fields['body'][$k]);
}
unset($doc_fields['header']['Id']);
$this->UpdateDoc($import['import_rub'], $id, $doc_fields);
}
else
{
if ($import['import_docs_create'])
$this->InsertDoc($import['import_rub'], $doc_fields);
}
}
}
}
if (! $tags_only)
{
$AVE_DB->Query("
UPDATE " . PREFIX . "_module_import
SET
import_last_update = '" . time() . "',
import_text = '" . addslashes(serialize($import['import_text'])) . "'
WHERE id = " . $import_id
);
header('Location:index.php?do=modules&action=modedit&mod=import&moduleaction=1&cp=' . SESSION);
}
else
{
$AVE_DB->Query("
UPDATE " . PREFIX . "_module_import
SET
import_text = '" . addslashes(serialize($import['import_text'])) . "'
WHERE id = " . $import_id
);
if ($location)
{
header('Location:index.php?do=modules&action=modedit&mod=import&moduleaction=edit&id=' . $import_id . '&cp=' . SESSION);
}
}
}
}
?>