eZ Publish: еще одна реализация функции мультиаплоада файлов.

eZ Publish: еще одна реализация функции мультиаплоада файлов.

Структура нового расширения.

Давайте дадим простое имя нашей реализации – hr_pure_upload

1. В папке ezpublish-legacy/extension создадим папку hr_pure_upload

2. В ней минимально-необходимое количество папок:

design

modules/hr_pure_upload

settings

В папку settings минимально-необходимый набор файлов, сразу с содержанием

module.ini.append.php

<?php/* #?ini charset="utf-8"?

[ModuleSettings]
ExtensionRepositories[]=hr_pure_upload

ModuleList[]=hr_pure_upload

*/ ?>

site.ini.append.php

<?php
/* #?ini charset="utf-8"?
[TemplateSettings]
ExtensionAutoloadPath[]=hr_pure_upload

*/ ?>

design.ini.append.php

<?php /* #?ini charset="utf-8"?
# transmit to eZ, to search for designs in jacextension

[ExtensionSettings]
DesignExtensions[]=hr_pure_upload

*/ ?>

Здесь же, можно класть файл(ы) конфигурации, специфичные для данного расширения.

В папке modules/hr_pure_upload лежат собственно файлы кода расширения.

Именно так: в папке modules лежит папка имени расширения, в нашем случае hr_pure_upload, а все файлы реализации находятся внутри.

Минимально один файл — module.php.

Но ведь нам нужно сделать и саму реализацию, для этого создадим файл upload.php.

В папке design лежат шаблоны. Рассмотрим их отдельно. Похоже, что там всё очень запутанно.

3. Файл module.php по сути — конфигурационный

<?php
$Module = array( 'name' => 'Красивое имя нашего расширения', 'variable_params' => true );

$ViewList = array();
//в этом массиве описываем функции расширения
$ViewList['upload'] = array( 'script' => 'upload.php', //указываем имя файла, в котором,
//реализована функция
);

//на самом деле тут параметров может быть много, но я их не понимаю :(

?>

4. Файл upload.php — реализация функции загрузки

<?php
/**
Данный файл должен выполнять две задачи: создавать интерфейс мультизагрузчика, и обрабатывать данные присылаемые клиентом
*/

//так загружаем кастомныq файл конфигурации
$ini = eZINI::instance( 'hr_pure_upload.ini', '', null, false);

//простая проверка «что делать?» отдать интерфейс или обработать форму
if (условие «надо отдать форму») {
//подтягиваем системные сущности
$http = eZHTTPTool::instance();
$module = $Params['Module'];
$parentNodeID = $Params['ParentNodeID'];

//передаём данные в шаблон
$Result = array();
$tpl = eZTemplate::factory();
$tpl->setVariable('session_id', session_id());
$tpl->setVariable('session_name', session_name());
$tpl->setVariable('parent_node', $parentNode);
//указание на шаблон формы
$Result['content'] = $tpl->fetch('design:upload.tpl');
$Result['path'] = array(array('url' => false,
//не знаю смысла поля text, но в качестве «заклинания» всё прозрачно
//указываем путь к расширению и имя расширения
'text' => ezpI18n::tr('extension/hr_pure_upload', 'Красивое имя расширения')));
//что и как делать с шаблоном опишу отдельно
} else {
//подтягиваем системные сущности
$user = eZUser::fetchByName('admin');
$module = $Params['Module'];
$parentNodeID = $Params['ParentNodeID'];

//здесь будем создавать объект по загружаемым данным
$params = array();
$params['class_identifier'] = $_POST['classType']; //class name (found within setup=>classes in the admin if you need it
$params['creator_id'] = $user->attribute('contentobject_id'); //using the user created above
$params['parent_node_id'] = $parentNodeID; //pulling the node id out of the parent
$params['section_id'] = 1;

//подготавливаемся к загрузке текста в формате xml-блока
$attributesData = array();
$xmlDeclaration = '<?xml version="1.0" encoding="utf-8"?> <section xmlns:image="http://ez.no/namespaces/ezpublish3/image/" xmlns:xhtml="http://ez.no/namespaces/ezpublish3/xhtml/" xmlns:custom="http://ez.no/namespaces/ezpublish3/custom/">';
foreach($_POST as $key => $val){

//если тип блока text
//добавить в начале xml-декларацию
//и обернуть тегами. Иначе EZ вместо текста покажет нечто непредсказуемое
if(isset($ini->BlockValues[$classType][$key]) && $ini->BlockValues[$classType][$key]=='text'){
$attributesData[$key] = $xmlDeclaration.'<paragraph>'.$val.'</paragraph></section>';
}else{
$attributesData[$key] = $val;
}

//если тип поля $key == file
if(isset($ini->BlockValues[$classType][$key])) {
list($type, $default) = explode(';', $ini->BlockValues[$classType][$key]);
if($type=='file'){
$val = strtolower($val);
//надо осуществить проверку файлов на условие "это ссылка на интернет"
//проверим, вдруг, там начинается с http:// или https://
if(strpos($val, 'http://')!==false || strpos($val, 'https://')!==false){
//проверить расширение
$ext = pathinfo($val, PATHINFO_EXTENSION);
if(in_array($ext, array('jpg', 'png', 'gif'))) {
$tmp_name = '/tmp/hr' . md5($key).'.'.$ext;
//создаём локальный файл для передачи в EZ
file_put_contents($tmp_name, file_get_contents($val));
$attributesData[$key] = $tmp_name;
}
}
}
}
}

foreach($_FILES as $key => $val){
//$fp=fopen('/var/www/ezpublish-legacy/extension/hr_pure_upload/modules/hr_pure_upload/testU.txt', 'a');
$ext = pathinfo($_FILES[$key]['name'], PATHINFO_EXTENSION);
$tmp_name = '/tmp/'.$_FILES[$key]['name'];
copy($_FILES[$key]['tmp_name'], $tmp_name);
//если это файл, то нужно сохранить его во временной папке с настоящим именем,
//иначе EZ присвоит ему в качестве имени временную абракадабру
$attributesData[$key] = $tmp_name;
}
$params['attributes'] = $attributesData;

//создаём и публикуем объект
$contentObject = eZContentFunctions::createAndPublishObject($params);
//выводим какие-то данные для контроля
echo json_encode($params);

eZExecution::cleanExit();

//это «заклинание» позволяет отказаться от EZшного обрамления и вывести только то, что вводили echo'м в коде
//в данном случае это необходимо, т. к. форма возвращается как страница EZ, а результат аплодинга — как json код реакции
//это нужно чтобы нормально обрабатывать загрузку множества файлов через AJAX
eZExecution::cleanExit();
}
?>

Шаблоны в расширениях

В нашем случае, для $tpl→fetch('design:upload.tpl'); шаблон должен лежать в файле с полным путём:

extension/hr_pure_upload/design/standard/templates/upload.tpl

Это обычный шаблон. В нашем случае может выглядеть так:

<input type="file" id="images">
<input type="button" value="Отправить все файлы" onclick="sendAllFiles()">
{literal}
<script>
var currentFile = 0;
var files=null;
function next(){
if(currentFile < files.length){
//если текущий файл номер меньше всего, то отправляем следующий
$.ajax({
url: '',
dataType: 'text',
cache: false,
contentType: false,
processData: false,
data: files[currentFile],
type: 'post',
success: function (php_script_response) {
//если всё хорошо, то проверяем, остались ли ещё файлы
console.log('php_script_response', php_script_response);
currentFile++;
if(currentFile < files.length){
//и назначаем вызов для отправки следующего файла
setTimeout('next()', 100);
} else {
alert('Upload finished...');
}
},
error: function (error) {
console.log(error);
}
});

}
}
function sendAllFiles(){
//забрали файлы из поля
files = document.getElementById('images').files;
currentFile = 0;
next();
}
</script>
{literal}

Ряд шаблонов, которые нужны.

Так нужен шаблон для формы в админке. Размещается он в файле с полным путём

extension/hr_pure_upload/design/standard/override/templates/admin/node/view/full.tpl

Путь к этому файлу указывается в override.ini.append.php

В данном случае так:

<?php /* #?ini charset="utf-8"?

[admin_full]
Source=node/view/full.tpl
MatchFile=admin/node/view/full.tpl
Subdir=templates

*/ ?>

Примечание: копипаста - как, что и почему не знаю, только смутно догадываюсь

Шаблоны для пунктов контекстного меню в панели администратора.

В файле admininterface.ini.append.php указываем на шаблоны

<?php /*

[AdditionalMenuSettings]

ContextMenuTemplateArray[]=node/mucontextmenu.tpl
SubitemsContextMenuTemplateArray[]=node/musubitemscontextmenu.tpl
*/ ?>

Лежат эти файлы в папке extension/hr_pure_upload/design/standard/templates/node/

Шаблоны выглядят так:

mucontextmenu.tpl

<hr/>
<script type="text/javascript">
menuArray['ContextMenu']['elements']['menu-multiupload'] = new Array();
menuArray['ContextMenu']['elements']['menu-multiupload']['url'] = {"/hr_pure_upload/upload/%nodeID%"|ezurl};
</script>
<a id="menu-multiupload" href="#"
onmouseover="ezpopmenu_mouseOver( 'ContextMenu' )">{"Upload multiple files"|i18n("design/admin/popupmenu")}</a>

musubitemscontextmenu.tpl

<hr/>
<script type="text/javascript">
menuArray['SubitemsContextMenu']['elements']['child-menu-multiupload'] = new Array();
menuArray['SubitemsContextMenu']['elements']['child-menu-multiupload']['url'] = {"/hr_pure_upload/upload/%nodeID%"|ezurl};
</script>
<a id="child-menu-multiupload" href="#" onmouseover="ezpopmenu_mouseOver( 'ContextMenu' )" >{"Upload multiple files"|i18n("design/admin/popupmenu")}</a>

Примечание: копипаста - как, что и почему не знаю, только смутно догадываюсь

Файлы JavaScript.

Кладём их сюда extension/hr_pure_upload/design/standard/javascript/script.js

И обращаемся из шаблонов так:

<script src={"javascript/script.js"|ezdesign()}></script>

Файл websitetoolbar.ini.append.php содержит настройки

<?php /*

[CustomTemplateSettings]
CustomTemplateList[]=hr_pure_upload

IncludeInView[hr_pure_upload]=full

*/ ?>

Комментарии

Оставить комментарий

Теги:

В России:

Дорогой сердцу Hadrout (Гэдрут) в России. Проекты, клиенты, мысли и эмоции нашей команды.

В Америке:

Наш далекий и в тоже время очень близкий Hadrout в Америке. Те же клиенты и проекты, но уже немного другие мысли и совсем другой вид из окна.