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
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); |
|
} |
|
} |
|
|
|
} |
|
} |
|
?>
|