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.
732 lines
18 KiB
732 lines
18 KiB
<? |
|
/** |
|
* Класс, включающий все свойства и методы для управления документами |
|
* |
|
* @package AVE.cms |
|
* @subpackage module_DocManager |
|
* @filesource |
|
*/ |
|
|
|
class ModuleImport |
|
{ |
|
|
|
/** |
|
* Свойства класса |
|
*/ |
|
|
|
/** |
|
* Путь к директории с шаблонами модуля |
|
*/ |
|
var $tpl_dir; |
|
|
|
/** |
|
* Основные поля документа, предлагаемые для импорта |
|
*/ |
|
var $fields_main = array( |
|
'Id', |
|
'document_title', |
|
'document_alias', |
|
'document_meta_keywords', |
|
'document_meta_description', |
|
'document_meta_robots', |
|
'document_published', |
|
'document_expire', |
|
'document_in_search', |
|
'document_status', |
|
'document_deleted', |
|
'document_linked_navi_id', |
|
'document_breadcrum_title', |
|
'document_parent', |
|
'document_count_view', |
|
'document_lang' |
|
); |
|
|
|
/** |
|
* Внутренние методы |
|
*/ |
|
|
|
/** |
|
* Метод получения импорта |
|
* $small - для сохранения памяти при импорте |
|
*/ |
|
function _import($import_id, $type='row', $small = false) |
|
{ |
|
global $AVE_DB; |
|
|
|
// забираем импорт |
|
$import = $AVE_DB->Query(" |
|
SELECT " . ($small |
|
? "i.rub_id,i.name,i.parser,i.docs_disable,i.docs_create,i.fields,i.file FROM " . PREFIX . "_module_import AS i" |
|
: "i.*, r.rubric_title AS rub_title |
|
FROM |
|
" . PREFIX . "_module_import AS i |
|
LEFT JOIN |
|
" . PREFIX . "_rubrics AS r ON r.Id = i.rub_id" |
|
) . " |
|
WHERE |
|
i.id=" . (int)$import_id |
|
)->FetchRow(); |
|
|
|
// поля |
|
$import->fields = $import->fields ? unserialize($import->fields) : array(); |
|
|
|
// теги |
|
if (isset($import->tags)) |
|
$import->tags = $import->tags |
|
? unserialize($import->tags) |
|
: array(); |
|
|
|
// возвращаем массив, если попросили |
|
if ($type != 'row' && $type != 'r') |
|
$import = (array)$import; |
|
|
|
return $import; |
|
} |
|
|
|
/** |
|
* Метод рекурсивно создаёт массив замен |
|
*/ |
|
function _replace($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($v, $res . ':' . $k, false); |
|
} |
|
|
|
return $arr; |
|
} |
|
|
|
/** |
|
* Метод рекурсивно создаёт массив замен |
|
*/ |
|
function _maketag($key) |
|
{ |
|
return '[row:' . $key . ']'; |
|
} |
|
|
|
/** |
|
* Метод заменяет в шаблонах полей теги и выполняет код php |
|
*/ |
|
function _parse_tpl(&$item, &$key, $replace) |
|
{ |
|
$code = stripslashes(strtr($item,$replace)); |
|
|
|
$item = trim(eval2var('?>' . $code . '<?')); |
|
|
|
if ($unser = unserialize($item)) |
|
$item = $unser; |
|
} |
|
|
|
/** |
|
* Проверка наличия документа по ключевым полям |
|
* |
|
* @param array $array - массив ID_поля_в_рубрике=>Ключевое_значение |
|
* @param int $rub - id рубрики |
|
* |
|
* @return int/false - возвращает Id документа или false |
|
*/ |
|
function _docs_find(&$fields_key, $fields_comp, $item_fields, $rub_id) |
|
{ |
|
global $AVE_DB; |
|
|
|
if (! $fields_key) |
|
return 0; |
|
|
|
foreach($fields_key['main'] as $field_id => &$val) |
|
{ |
|
$val = $item_fields['main'][$field_id]; |
|
|
|
if ($fields_comp['main'][$field_id] == 'LIKE') |
|
$main[] = 'a.' . $field_id . " LIKE '%" . (string)addslashes($item_fields['main'][$field_id]) . "%'"; |
|
else |
|
$main[] = 'a.' . $field_id . " = '" . (string)addslashes($item_fields['main'][$field_id]) . "'"; |
|
} |
|
|
|
if ($main) |
|
$main = ' AND ' . implode(' AND ', $main); |
|
|
|
$x = 0; |
|
|
|
foreach($fields_key['body'] as $field_id => &$val) |
|
{ |
|
$val = $item_fields['body'][$field_id]; |
|
|
|
$tables[] = PREFIX . "_document_fields AS t" . $x; |
|
|
|
if ($fields_comp['body'][$field_id] == 'LIKE') |
|
$body[] = "(a.Id=t" . $x . ".document_id AND (t" . $x . ".rubric_field_id = " . $field_id . " AND t" . $x . ".field_value LIKE '%" . (string)addslashes($item_fields['body'][$field_id]) . "%'))"; |
|
else |
|
$body[] = "(a.Id=t" . $x . ".document_id AND (t" . $x . ".rubric_field_id = " . $field_id . " AND t" . $x . ".field_value = '" . (string)addslashes($item_fields['body'][$field_id]) . "'))"; |
|
|
|
$x++; |
|
} |
|
|
|
if ($tables) |
|
$tables = ', ' . implode(', ', $tables); |
|
|
|
if ($body) |
|
$body = ' AND ' . implode(' AND ', $body); |
|
|
|
$docids = array(); |
|
|
|
$sql = $AVE_DB->Real_Query(" |
|
SELECT |
|
a.Id AS id |
|
FROM |
|
" . PREFIX . "_documents AS a " . $tables . " |
|
WHERE |
|
a.rubric_id = " . $rub_id . |
|
$main . |
|
$body |
|
); |
|
|
|
while ($docid = $sql->FetchRow()->id) |
|
$docids[] = $docid; |
|
|
|
return $docids; |
|
} |
|
|
|
/** |
|
* Внешние методы |
|
*/ |
|
|
|
/** |
|
* Метод вывода импортов |
|
*/ |
|
function importsList () |
|
{ |
|
global $AVE_DB, $AVE_Template; |
|
|
|
// Забираем все импорты |
|
$limit = 20; |
|
|
|
$start = get_current_page() * $limit - $limit; |
|
|
|
$sql = $AVE_DB->Query(" |
|
SELECT SQL_CALC_FOUND_ROWS |
|
* |
|
FROM |
|
" . PREFIX . "_module_import |
|
ORDER BY |
|
id ASC |
|
LIMIT |
|
" . $start . "," . $limit |
|
); |
|
|
|
while ($import = $sql->FetchAssocArray()) |
|
{ |
|
$import['rub_title'] = $AVE_DB->Query(" |
|
SELECT |
|
rubric_title |
|
FROM |
|
" . PREFIX . "_rubrics |
|
WHERE |
|
id=" . (int)$import['rub_id'] |
|
)->GetCell(); |
|
|
|
$imports[] = $import; |
|
} |
|
|
|
$num = $AVE_DB->NumAllRows; |
|
|
|
if ($num > $limit) |
|
{ |
|
$page_nav = '<a class="pnav" href="index.php?do=modules&action=modedit&mod=import&moduleaction=1&page={s}&cp=' . SESSION . '">{t}</a>'; |
|
$page_nav = get_pagination($pages, 'page', $page_nav); |
|
$AVE_Template->assign('page_nav', $page_nav); |
|
} |
|
|
|
$AVE_Template->assign('imports',$imports); |
|
$AVE_Template->assign('content', $AVE_Template->fetch($this->tpl_dir . 'admin_list.tpl')); |
|
} |
|
|
|
/** |
|
* Метод создания и редактирования импорта |
|
*/ |
|
function importEdit ($import_id=null) |
|
{ |
|
global $AVE_DB, $AVE_Template; |
|
|
|
if ($import_id) |
|
{ |
|
$import = $this->_import($import_id, 'array'); |
|
|
|
$import_fields = array(); |
|
|
|
// основные поля |
|
foreach ($this->fields_main as $field_id) |
|
{ |
|
$import_fields['main'][$field_id] = isset($import['fields']['main'][$field_id]) ? $import['fields']['main'][$field_id] : array(); |
|
$import_fields['main'][$field_id]['title'] = $AVE_Template->get_config_vars('field_' . $field_id); |
|
} |
|
|
|
// поля рубрики |
|
$sql = $AVE_DB->Query(" |
|
SELECT |
|
Id AS id, |
|
rubric_field_title AS title |
|
FROM |
|
" . PREFIX . "_rubric_fields |
|
WHERE |
|
rubric_id = '" . (int)$import['rub_id'] . "' |
|
ORDER BY |
|
rubric_field_position |
|
"); |
|
|
|
while ($field = $sql->FetchRow()) |
|
{ |
|
$field_id = $field->id; |
|
|
|
$import_fields['body'][$field_id] = isset($import['fields']['body'][$field_id]) |
|
? $import['fields']['body'][$field_id] |
|
: array(); |
|
|
|
$import_fields['body'][$field_id]['title'] = $field->title; |
|
} |
|
|
|
$import['fields'] = $import_fields; |
|
} |
|
else |
|
{ |
|
// рубрики |
|
$sql = $AVE_DB->Query(" |
|
SELECT |
|
Id AS id, |
|
rubric_title AS title |
|
FROM |
|
" . PREFIX . "_rubrics |
|
"); |
|
|
|
while ($row = $sql->FetchAssocArray()) |
|
{ |
|
$rubs[] = $row; |
|
} |
|
|
|
$AVE_Template->assign('rubs',$rubs); |
|
} |
|
|
|
// парсеры |
|
require_once (BASE_DIR . '/modules/import/class.import.parsers.php'); |
|
|
|
$parsers = get_class_methods('ModuleImportParsers'); |
|
|
|
$AVE_Template->assign('parsers',$parsers); |
|
$AVE_Template->assign('import_id',$import_id); |
|
$AVE_Template->assign('import',$import); |
|
$AVE_Template->assign('content', $AVE_Template->fetch($this->tpl_dir . 'admin_edit.tpl')); |
|
} |
|
|
|
/** |
|
* Метод сохранения профиля обмена |
|
*/ |
|
function importSave ($import_id=null) |
|
{ |
|
global $AVE_DB, $AVE_Template; |
|
|
|
// если новый |
|
if (! $import_id) |
|
{ |
|
$AVE_DB->Query(" |
|
INSERT INTO |
|
" . PREFIX . "_module_import |
|
SET |
|
name = '" . addslashes($_POST['name']) . "', |
|
rub_id = '" . (int)$_POST['rub_id'] . "', |
|
parser = '" . $_POST['parser'] . "', |
|
docs_disable = '" . (int)$_POST['docs_disable'] . "', |
|
docs_create = '" . (int)$_POST['docs_create'] . "', |
|
file = '" . trim(trim($_POST['file']),'/') . "', |
|
monitor = '" . (int)$_POST['monitor'] . "', |
|
time_edited = '" . time() . "' |
|
"); |
|
$import_id = $AVE_DB->InsertId(); |
|
} |
|
else // если редактирование |
|
{ |
|
$import_fields = array( |
|
'main' => array(), |
|
'body' => array() |
|
); |
|
|
|
// чистим массив от пустых шаблонов |
|
foreach ($_POST['fields']['main'] as $field_id => $field) |
|
{ |
|
$field['tpl'] = trim((string)$field['tpl']); |
|
|
|
if ($field['tpl'] === '') |
|
unset($field['tpl']); |
|
|
|
if (!$field['comp']) |
|
unset($field['comp']); |
|
elseif ($field['comp'] === 'LIKE' && isset($field['active'])) |
|
unset($field['active']); |
|
|
|
if (! empty($field)) |
|
$import_fields['main'][$field_id] = $field; |
|
} |
|
|
|
foreach ($_POST['fields']['body'] as $field_id => $field) |
|
{ |
|
$field['tpl'] = trim((string)$field['tpl']); |
|
|
|
if ($field['tpl'] === '') |
|
unset($field['tpl']); |
|
|
|
if (!$field['comp']) |
|
unset($field['comp']); |
|
elseif ($field['comp'] === 'LIKE' && isset($field['active'])) |
|
unset($field['active']); |
|
|
|
if (! empty($field)) $import_fields['body'][$field_id] = $field; |
|
} |
|
|
|
// записываем изменения в бд |
|
$AVE_DB->Query(" |
|
UPDATE |
|
" . PREFIX . "_module_import |
|
SET |
|
name = '" . addslashes($_POST['name']) . "', |
|
parser = '" . $_POST['parser'] . "', |
|
docs_disable = '" . (int)$_POST['docs_disable'] . "', |
|
docs_create = '" . (int)$_POST['docs_create'] . "', |
|
file = '" . trim(trim($_POST['file']),'/') . "', |
|
monitor = '" . (int)$_POST['monitor'] . "', |
|
fields = '" . addslashes(serialize($import_fields)) . "', |
|
time_edited = '" . time() . "' |
|
WHERE |
|
id = '" . $import_id . "' |
|
"); |
|
} |
|
if (isAjax()) |
|
{ |
|
$message = $AVE_Template->get_config_vars('saved'); |
|
$header = $AVE_Template->get_config_vars('success'); |
|
$theme = 'accept'; |
|
|
|
echo json_encode(array('message' => $message, 'header' => $header, 'theme' => $theme)); |
|
exit; |
|
} |
|
else |
|
{ |
|
return $import_id; |
|
} |
|
} |
|
|
|
/** |
|
* Метод удаления импорта |
|
*/ |
|
function importDelete ($import_id) |
|
{ |
|
global $AVE_DB; |
|
|
|
$AVE_DB->Query(" |
|
DELETE FROM |
|
" . PREFIX . "_module_import |
|
WHERE |
|
id = " . $import_id |
|
); |
|
} |
|
|
|
/** |
|
* Метод копирования импорта |
|
*/ |
|
function importCopy ($import_id) |
|
{ |
|
global $AVE_DB; |
|
|
|
$_POST = $this->_import($import_id,'array'); |
|
|
|
// сначала создаём и получаем id |
|
$import_id = $this->importSave(); |
|
|
|
// теперь сохраняем всё остальное |
|
return $this->importSave($import_id); |
|
} |
|
|
|
/** |
|
* Импорт |
|
*/ |
|
function importRun ($import_id, $tags_only = false, $file = null, $write_log = false) |
|
{ |
|
global $AVE_DB; |
|
|
|
require_once(BASE_DIR . '/class/class.docs.php'); |
|
$AVE_Document = new AVE_Document(); |
|
|
|
// задаём переменные |
|
$fields_active = array(); |
|
$fields_key = array(); |
|
$fields_oblig = array(); |
|
$fields_comp = array(); |
|
$fields = array(); |
|
|
|
// Получаем параметры импорта и создаём переменные с параметрами полей |
|
$import = $this->_import($import_id, 'row', true); |
|
|
|
foreach ($import->fields['main'] as $field_id => &$field) |
|
{ |
|
if (!isset($field['tpl'])) |
|
$field['tpl'] = ''; |
|
|
|
if ($field['active'] && $field['comp'] != 'LIKE') |
|
$fields_active['main'][$field_id] = true; |
|
|
|
if ($field['key']) |
|
{ |
|
$fields_key['main'][$field_id] = ''; |
|
$fields_comp['main'][$field_id] = (isset($field['comp']) && $field['comp'] == 'LIKE') ? 'LIKE' : ''; |
|
} |
|
|
|
if ($field['oblig']) |
|
$fields_oblig['main'][] = $field_id; |
|
|
|
if ($field['active'] || $field['tpl'] > '') |
|
$fields['main'][$field_id] = $field['tpl']; |
|
} |
|
|
|
foreach ($import->fields['body'] as $field_id => &$field) |
|
{ |
|
if (! isset($field['tpl'])) |
|
$field['tpl'] = ''; |
|
|
|
if ($field['active'] && $field['comp'] != 'LIKE') |
|
$fields_active['body'][$field_id] = true; |
|
|
|
if ($field['key']) |
|
{ |
|
$fields_key['body'][$field_id] = ''; |
|
$fields_comp['body'][$field_id] = (isset($field['comp']) && $field['comp'] == 'LIKE') ? 'LIKE' : ''; |
|
} |
|
|
|
if ($field['oblig']) |
|
$fields_oblig['body'][] = $field_id; |
|
|
|
if ($field['active'] || $field['tpl'] > '') |
|
$fields['body'][$field_id] = $field['tpl']; |
|
} |
|
|
|
// определяем файл |
|
// если файл не передан как аргумент функции, то берём из настроек |
|
if (! isset($file)) |
|
$file = BASE_DIR . '/' . $import->file; |
|
|
|
// если файл существует, парсим его |
|
if (file_exists($file) && is_file($file)) |
|
{ |
|
require_once (BASE_DIR . '/modules/import/class.import.parsers.php'); |
|
|
|
$ModuleImportParsers = new ModuleImportParsers; |
|
|
|
$parser = $import->parser; |
|
|
|
$import_data = $ModuleImportParsers->$parser($file); |
|
} |
|
|
|
// если в итоге (из файла или из кода) был |
|
// сформирован массив $import_data, то продолжаем |
|
// иначе, выходим |
|
if (! isset($import_data)) |
|
exit('Отсутствует файл! В ходе выполнения кода массив $import_data также не был передан!'); |
|
|
|
// Если просили узнать только теги, проходим весь массив $import_data и собираем теги |
|
/* !tags_only */ |
|
if ($tags_only) |
|
{ |
|
$tags = array(); |
|
|
|
foreach ($import_data['tags'] as $item) |
|
{ |
|
$tags[] = $this->_maketag($item); |
|
} |
|
|
|
$tags = array_unique($tags); |
|
|
|
$AVE_DB->Query(" |
|
UPDATE |
|
" . PREFIX . "_module_import |
|
SET |
|
tags = '" . serialize($tags) . "' |
|
WHERE |
|
id = " . $import_id |
|
); |
|
|
|
return $tags; |
|
} |
|
|
|
// Помечаем документы как неактивные в указанной рубрике, если нужно |
|
if($import->docs_disable && !$tags_only) |
|
{ |
|
$AVE_DB->Query(" |
|
UPDATE |
|
" . PREFIX . "_documents |
|
SET |
|
document_status = '0' |
|
WHERE |
|
rubric_id=" . $import->rub_id |
|
); |
|
} |
|
|
|
// чистим память |
|
unset ($import->fields, $import->code_start, $parser, $ModuleImportParsers, $file); |
|
|
|
$i = 0; |
|
|
|
$log = array( |
|
'updated' => array(), |
|
'created' => array(), |
|
'notfound' => array() |
|
); |
|
|
|
// Обрабатываем по очереди каждый объект |
|
foreach($import_data['rows'] as $item) |
|
{ |
|
// создаем массив замен |
|
$replace = array(); |
|
$replace = $this->_replace($item); |
|
$replace['[Y-m-d]'] = date('d.m.Y H:i'); |
|
|
|
// парсим шаблоны |
|
$item_fields = $fields; |
|
|
|
array_walk_recursive($item_fields, array($this, '_parse_tpl'), $replace); |
|
|
|
// чистим память |
|
unset ($replace,$item); |
|
|
|
$pass = true; |
|
|
|
// проверяем обязательные поля в параметрах документа |
|
foreach ($fields_oblig['main'] as $field_id) |
|
{ |
|
if (trim($item_fields['main'][$field_id]) === '') |
|
{ |
|
$pass = false; |
|
break; |
|
} |
|
} |
|
|
|
if (! $pass) |
|
continue; |
|
|
|
// проверяем обязательные поля в теле документа |
|
foreach ($fields_oblig['body'] as $field_id) |
|
{ |
|
if (trim($item_fields['body'][$field_id]) === '') |
|
{ |
|
$pass = false; |
|
break; |
|
} |
|
} |
|
|
|
if (! $pass) |
|
continue; |
|
|
|
// находим документ по ключевым полям |
|
$docids = $this->_docs_find($fields_key, $fields_comp, $item_fields, $import->rub_id); |
|
|
|
// если не совпал и не создаём новые |
|
if (! $docids && !$import->docs_create && $write_log) |
|
{ |
|
$log['notfound'][] = array('fields_key' => $fields_key, 'fields_values' => $item_fields); |
|
continue; |
|
} |
|
// если указано создавать документы при несовпадении, добавляем нулевой id |
|
elseif (! $docids && $import->docs_create) |
|
$docids[] = 0; |
|
|
|
// проходим каждый документ |
|
foreach ($docids as $doc_id) |
|
{ |
|
if ($doc_id) |
|
{ |
|
$doc = $AVE_DB->Real_Query(" |
|
SELECT |
|
* |
|
FROM |
|
" . PREFIX . "_documents |
|
WHERE |
|
Id = '" . $doc_id . "' |
|
")->FetchAssocArray(); |
|
|
|
// прописываем текущие значения в поля main, которые не надо импортировать |
|
foreach($this->fields_main as $field_id) |
|
{ |
|
if(! $fields_active['main'][$field_id]) |
|
{ |
|
$item_fields['main'][$field_id] = $doc[$field_id]; |
|
} |
|
} |
|
|
|
unset ($doc); |
|
} |
|
|
|
// меняем время, если в UNIX-е |
|
if (strlen((string)$item_fields['main']['document_published']) == 10) |
|
$item_fields['main']['document_published'] = date('d.m.Y H:i', $item_fields['main']['document_published']); |
|
|
|
if (strlen((string)$item_fields['main']['document_expire']) == 10) |
|
$item_fields['main']['document_expire'] = date('d.m.Y H:i', $item_fields['main']['document_expire']); |
|
|
|
// удаляем ненужные поля из полей рубрики |
|
foreach($item_fields['body'] as $field_id => $field) |
|
{ |
|
if (! $fields_active['body'][$field_id]) |
|
unset($item_fields['body'][$field_id]); |
|
else |
|
// если поле оказалось пустым, убираем значение из формы |
|
$item_fields['body'][$field_id] = preg_replace('/\[row:(.+?)\]/', '', $item_fields['body'][$field_id]); |
|
} |
|
|
|
// удаляем Id документа |
|
unset ($item_fields['main']['Id']); |
|
|
|
// сохраняем документ |
|
$data = array(); |
|
$data = $item_fields['main']; |
|
$data['doc_title'] = $data['document_title']; |
|
$data['document_expire'] = date("d.m.Y H:i", strtotime('+20 year')); |
|
$data['feld'] = $item_fields['body']; |
|
$data['import'] = 1; |
|
|
|
$response = $AVE_Document->documentSave($import->rub_id, $doc_id, $data); |
|
|
|
// записываем лог |
|
if ($write_log) |
|
{ |
|
// если совпал и обновлён |
|
if ($doc_id) |
|
$log['updated'][$doc_id] = array('fields_key' => $fields_key); |
|
|
|
// если не совпал и создан |
|
else |
|
$log['created'][$response] = array('fields_key' => $fields_key); |
|
} |
|
} |
|
} |
|
|
|
$AVE_DB->Query(" |
|
UPDATE |
|
" . PREFIX . "_module_import |
|
SET |
|
time_run = '" . time() . "' |
|
WHERE |
|
id = " . $import_id |
|
); |
|
|
|
return $log; |
|
} |
|
}
|
|
|