module-import/import/class.import.php

641 lines
18 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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