Синхронизировал частично с CMS2
This commit is contained in:
parent
6b412f5d6f
commit
f2938b1353
30 changed files with 1447 additions and 1099 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
*.bak
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
<?php
|
||||
/**
|
||||
* Коллекция
|
||||
*
|
||||
* package core
|
||||
*
|
||||
*/
|
||||
class Collection implements ArrayAccess
|
||||
{
|
||||
|
|
@ -40,7 +39,7 @@ class Collection implements ArrayAccess
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($key, $value)
|
||||
public function set(/*.string.*/$key, /*.any.*/$value)
|
||||
{
|
||||
$this->data[$key] = $value;
|
||||
}
|
||||
|
|
@ -54,7 +53,7 @@ class Collection implements ArrayAccess
|
|||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
return isset($this->data[$key]) ? $this->data[$key] : $default;
|
||||
return isset($this->data[$key]) && $this->data[$key] != '' ? $this->data[$key] : $default;
|
||||
}
|
||||
|
||||
public function getInt($key, $default = 0)
|
||||
|
|
|
|||
|
|
@ -1,423 +1,339 @@
|
|||
<?php
|
||||
/**
|
||||
*
|
||||
* @package Core
|
||||
*/
|
||||
/**
|
||||
* Переименовать контроллер !! (StubController, CrudController, PageController, BaseController) ModelController
|
||||
* Возможно нужен еще класс с мета действиями как для actionIndex <= metaActionIndex либо с классам для этих действий
|
||||
* Есть класс для управлениями действиями а есть сами действия в виде классов или функций !!
|
||||
*/
|
||||
class Controller_Model extends Controller_Action
|
||||
|
||||
require_once __DIR__ . '/../functions.php';
|
||||
|
||||
|
||||
function forceUrl($name)
|
||||
{
|
||||
public $schema = array();
|
||||
public $schemaSearch = array();
|
||||
if (is_callable($name)) {
|
||||
return call_user_func($name);
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME: Лучше $this->table->setHeader
|
||||
*/
|
||||
public $tableSchema = null;
|
||||
public $formSchema = array();
|
||||
/**
|
||||
* Контроллер страниц
|
||||
*/
|
||||
class Controller_Action
|
||||
{
|
||||
|
||||
public $menu;
|
||||
const TEMPLATE_EXTENSION = ".html"; // Расширение для шаблонов
|
||||
const ACTION_PREFIX = "action"; // Префикс для функций действий
|
||||
|
||||
public $jsPath; // Глобальный путь к скриптам
|
||||
public $themePath; // Глобальный путь к текущей теме
|
||||
|
||||
// Параметры устанавливаются при создании контроллера
|
||||
public $name; // Имя модуля
|
||||
public $viewPath = null; // Путь к шаблонам контроллера
|
||||
public $db; // Соединение с базой данных
|
||||
|
||||
// Фильтры
|
||||
public $access = null; // Обьект хранит параметры доступа
|
||||
public $logger = null; // Обьект для ведения лога
|
||||
|
||||
private $factory = null; // Ссылка на обьект создания модели
|
||||
private $helpers = array(); // Помошники для действий
|
||||
public $param = array(); // Параметры для ссылки
|
||||
|
||||
public /*.Registry.*/$_registry; // Ссылка на реестр
|
||||
public $_shortcut;
|
||||
public $modulePrefix = '';
|
||||
public $iconPath = '';
|
||||
public $path;
|
||||
public $table;
|
||||
|
||||
public function __construct()
|
||||
public function __construct ()
|
||||
{
|
||||
$this->path = new PathMenu();
|
||||
$this->menu = new PageMenu();
|
||||
$this->table = new ListTable();
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function setUp()
|
||||
public function setUp ()
|
||||
{
|
||||
$this->table->addMenuItem($this->aUrl('delete'), 'удалить', false, 'all', 'warning');
|
||||
//$this->table->addMenuItem($this->nUrl('form'), 'редактировать', 'edit-24.png');
|
||||
// override this
|
||||
}
|
||||
|
||||
function saveParameters($args, $list)
|
||||
{
|
||||
foreach ($list as $item) {
|
||||
$args->session()->set(array($this, $item), $args->get($item));
|
||||
}
|
||||
}
|
||||
|
||||
protected function getJSONList(/*Mapper*/ $model, Collection $request)
|
||||
{
|
||||
$result = array();
|
||||
$this->saveParameters($request, array('size','page','desc', 'key'));
|
||||
|
||||
$result['list'] = $model->findAll($request, $request->get('ref'));
|
||||
$result['size'] = $model->getCount($request, $request->get('ref'));
|
||||
return json::encode($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаление сторк из таблицы
|
||||
*/
|
||||
public function actionDelete(HttpRequest $request)
|
||||
{
|
||||
$model = $this->getModel($this->useModel);
|
||||
// Почему table_item ???
|
||||
$list = ($request->get('table_item')) ? $request->get('table_item'): $request->get('id');
|
||||
$model->deleteList($list);
|
||||
|
||||
return $this->getJSONList($model, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ответ на запрос по поиску
|
||||
*/
|
||||
public function actionSearch(HttpRequest $request)
|
||||
{
|
||||
$model = $this->getModel($this->useModel);
|
||||
$model->addFilter($model->requestToSQL($request, $this->formSchema));
|
||||
|
||||
return $this->getJSONList($model, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Список элементов
|
||||
*/
|
||||
public function actionList(HttpRequest $request)
|
||||
{
|
||||
$model = $this->getModel($this->useModel);
|
||||
return $this->getJSONList($model, $request);
|
||||
}
|
||||
|
||||
|
||||
private function setFormSchema()
|
||||
{
|
||||
require_once 'core/mapper/uimapper.php';
|
||||
|
||||
$model = $this->getModel($this->useModel);
|
||||
$ui = new UIMapper($model);
|
||||
|
||||
$this->formSchema = $ui->getFormSchema();
|
||||
}
|
||||
|
||||
/**
|
||||
* Сохранение формы
|
||||
*/
|
||||
function beforeSave(/*Model*/ $item, Collection $request)
|
||||
{
|
||||
if (empty($this->formSchema)) {
|
||||
$this->setFormSchema();
|
||||
}
|
||||
// Сделать отображение Формы в обьект и обратно <-- Убрать в beforeSave
|
||||
foreach ($this->formSchema as $key => $conv) {
|
||||
list($value, $type) = $conv;
|
||||
$item->$value = call_user_func(array('Cast', 'to_' . $type), $request->get($key)); // Здесть нужно преобразовывать тип значения
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновление формы
|
||||
*/
|
||||
function formUpdate(TForm $form, Collection $request)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Загрузка формы
|
||||
*/
|
||||
function beforeLoad(/*Model*/ $item, TForm $form)
|
||||
{
|
||||
if (empty($this->formSchema)) {
|
||||
$this->setFormSchema();
|
||||
}
|
||||
// Вставка значений из данных в форму
|
||||
// Отображение обьекта в поля формы
|
||||
$form->fill($item, $this->formSchema);
|
||||
}
|
||||
|
||||
// Проверка ввода
|
||||
protected function validate($validator, $request)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Действие для проверки формы
|
||||
*/
|
||||
public function actionValidate($request)
|
||||
{
|
||||
require_once "core/validator/validator.php";
|
||||
$validator = new Validator();
|
||||
$validator->addRuleList($this->schema);
|
||||
|
||||
// Действия до проверки формы
|
||||
$this->validate($validator, $request); // <--|
|
||||
$validator->validate($request); // --|
|
||||
// Проверка формы
|
||||
if (!$validator->isValid()) {
|
||||
return json::encode($validator->getErrorMsg());
|
||||
}
|
||||
return json::encode(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Инициализация формы
|
||||
*/
|
||||
protected function formSetup($form, $id = null, $ref = null)
|
||||
{
|
||||
if (empty($this->schema)) {
|
||||
$model = $this->getModel($this->useModel);
|
||||
$ui = new UIMapper($model);
|
||||
$schema = $ui->getEditSchema();
|
||||
|
||||
$form->addFieldList($schema);
|
||||
public function loadConfig($name) {
|
||||
$filename = Shortcut::getUrl('config', $name);
|
||||
if (file_exists($filename)) {
|
||||
include($filename);
|
||||
} else {
|
||||
$form->addFieldList($this->schema);
|
||||
throw new Exception('Невозможно загрузить файл настроек ' . $name);
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->db;
|
||||
}
|
||||
|
||||
public function installPath($name)
|
||||
{
|
||||
return Path::join(CMS_PATH, "modules", $name, "install");
|
||||
}
|
||||
|
||||
public function addSuggest($view, $name)
|
||||
{
|
||||
$suggest = array();
|
||||
$file = Path::join($this->viewPath, 'help', $name . '.suggest');
|
||||
if (file_exists($file) && include($file)) {
|
||||
$view->addScriptRaw("add_suggest(".json::encode($suggest).");\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавление пользователя
|
||||
*/
|
||||
public function actionAdd(HttpRequest $request)
|
||||
function findIcon($icon, $size)
|
||||
{
|
||||
require_once "core/validator/validator.php";
|
||||
// {{{ тоже может быть один ref или несколько
|
||||
$ref = $request->get('ref');
|
||||
$this->addParameter('ref', $ref); // Добавляет параметр в url
|
||||
/// }}}
|
||||
|
||||
if ($this->checkPageId($request, $request->get('page'))) {
|
||||
// Проверка
|
||||
$validator = new Validator();
|
||||
$validator->addRuleList($this->schema);
|
||||
return Path::join($this->iconPath, $size . 'x' . $size, $icon . '.png');
|
||||
}
|
||||
|
||||
// Действия до проверки формы
|
||||
$this->validate($validator, $request); // <--|
|
||||
$validator->validate($request); // --|
|
||||
// Проверка формы
|
||||
if (!$validator->isValid()) {
|
||||
$request->setAction('form');
|
||||
$this->getActionPath($request);
|
||||
|
||||
$form = new TForm();
|
||||
$this->formSetup($form, $request->get('id'), $request->get('ref')); // Инициализация формы
|
||||
|
||||
$form->setValues($request); // <-- Убрать в formUpdate
|
||||
$this->formUpdate($form, $request);
|
||||
|
||||
$form->setError($validator); // Установка ошибок для формы
|
||||
|
||||
$tpl = $this->formPage($form, $request);
|
||||
$id = $request->get('id');
|
||||
if ($id) { // Редактирование
|
||||
$tpl->action = forceUrl($this->nUrl('add', array('id' => $id, 'page' => $this->getPageId($request)))); // action Совйство формы
|
||||
}
|
||||
return $tpl /*->execute()*/;
|
||||
}
|
||||
|
||||
// Нужен тест для формы
|
||||
$model = $this->getModel($this->useModel);
|
||||
$className = $model->className;
|
||||
$item = new $className();
|
||||
|
||||
// Сохраняем значение в базе данных
|
||||
$item->id = $request->get('id');
|
||||
// Если таблица связана с другой таблицей
|
||||
if ($request->get('ref') && $model->reference[1]) {
|
||||
$ref_id = $model->reference[1];
|
||||
$item->$ref_id = $request->get('ref');
|
||||
}
|
||||
|
||||
// Подготовка к сохранению
|
||||
$this->beforeSave($item, $request); // Сюдаже и истрия переходов
|
||||
// nextId ??? или выход или новая форма для создания новости
|
||||
$model->saveDB($item, $request);
|
||||
}
|
||||
|
||||
// Для страницы со списком id -> идентефикатор родительской таблицы !!??
|
||||
// $request->set('id', $request->get('ref'));
|
||||
if ($request->get('apply')) {
|
||||
$request->setAction('form');
|
||||
return $this->forward('actionForm', $request);
|
||||
}
|
||||
return $this->forward('actionIndex', $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Заголовок
|
||||
* Создает представление
|
||||
* @param string $file
|
||||
* @return template
|
||||
*/
|
||||
private function setTitlePath($ref)
|
||||
public function getView($name)
|
||||
{
|
||||
if ($ref) {
|
||||
$model = $this->getModel($this->useModel);
|
||||
if (is_array($model->reference) && $model->reference[0]) {
|
||||
$refmodel = $this->getModel($model->reference[0]);
|
||||
try {
|
||||
$parent = $refmodel->findById($ref);
|
||||
$this->path->addTitle($parent->getTitle()); // Заголовок к подписям путей
|
||||
} catch (Exception $e) {
|
||||
// Не найден заголовок потому что неправильно определен родительский элемент
|
||||
}
|
||||
}
|
||||
$file = $name . self::TEMPLATE_EXTENSION;
|
||||
// Список возможных директорий для поиска файла шаблона
|
||||
$theme = $this->_registry->readKey(array('system', 'theme'));
|
||||
$icon_theme = $this->_registry->readKey(array('system', 'icon_theme'));
|
||||
$list = array(
|
||||
Path::join($this->viewPath, TEMPLATES) => Path::join(WWW_PATH, "modules", $this->name, TEMPLATES),
|
||||
PHPTAL_TEMPLATE_REPOSITORY => "");
|
||||
|
||||
|
||||
// Поиск файла для шаблона
|
||||
foreach($list as $ospath => $path) {
|
||||
$template = Path::join($ospath, $file);
|
||||
if(file_exists($template)) { break; }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Форма для редактирования
|
||||
*/
|
||||
public function actionForm(HttpRequest $request)
|
||||
{
|
||||
$this->getActionPath($request);
|
||||
$ref = $request->get('ref');
|
||||
$this->addParameter('ref', $ref); // Добавляет параметр в url
|
||||
$this->setTitlePath($ref);
|
||||
|
||||
$model = $this->getModel($this->useModel);
|
||||
$form = new TForm(); // Показываем форму
|
||||
$form->header = 'Редактирование записи';
|
||||
$this->formSetup($form, $request->get('id'), $request->get('ref')); // Инициализация формы
|
||||
$tpl = new View_Composite($template);
|
||||
$tpl->icons = $this->iconPath; // Путь к файлам текущей темы
|
||||
$tpl->media = $this->themePath; // Путь к файлам текущей темы
|
||||
$tpl->script = $this->jsPath; // Путь к файлам скриптов
|
||||
$tpl->template = $path; // Путь к файлам текущего шаблона
|
||||
$tpl->setAlias(array(
|
||||
'${icons}' => $this->iconPath,
|
||||
'${media}' => $this->themePath,
|
||||
'${script}' => $this->jsPath,
|
||||
'${template}' => $path));
|
||||
|
||||
$list = $request->get('table_item');
|
||||
$id = ($list[0]) ? $list[0] : $request->get('id');
|
||||
$tpl->loadImports(Path::skipExtension($template) . ".import");
|
||||
|
||||
$tpl = $this->formPage ($form, $request);
|
||||
if ($id) { // Редактирование
|
||||
$form->action = forceUrl($this->nUrl('add', array('id' => $id, 'page' => $this->getPageId($request)))); // action Свойство формы
|
||||
$item = $model->findById($id);
|
||||
// Загрузка формы
|
||||
$this->beforeLoad($item, $form);
|
||||
///
|
||||
}
|
||||
$this->addSuggest($tpl, $name);
|
||||
return $tpl;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function tableSetup($table, $id = null, $ref = null)
|
||||
public function getModel($name)
|
||||
{
|
||||
// FIXME: После замены везде $tableSchema -> table->setHeader удалить!
|
||||
if ($this->tableSchema) {
|
||||
$table->setHeader($this->tableSchema);
|
||||
} else {
|
||||
// Настройка таблицы отображения по схеме данных
|
||||
require_once 'core/mapper/uimapper.php';
|
||||
$model = $this->getModel($this->useModel);
|
||||
$ui = new UIMapper($model);
|
||||
$schema = $ui->getTableSchema();
|
||||
$schema[0]['action'] = $table->getFirstItem();
|
||||
|
||||
$table->setHeader($schema);
|
||||
if (!$this->factory) {
|
||||
$this->factory = new ModelFactory($this->db, $this->_registry, $this->_shortcut);
|
||||
}
|
||||
return $this->factory->getModel($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Выбор действия
|
||||
* Т.к действия являются методами класса то
|
||||
* 1. Можно переопределить действия
|
||||
* 2. Использовать наследование чтобы добавить к старому обработчику новое поведение
|
||||
* @param $request Обьект запроса
|
||||
*/
|
||||
public function actionIndex(HttpRequest $request)
|
||||
public function execute1(HTTPRequest $request)
|
||||
{
|
||||
$this->getActionPath($request, 'index');
|
||||
// Такое мета действие наверное можно вынести в отдельный класс
|
||||
return $this->metaActionIndex($request, array($this, 'tableSetup'), $this->aUrl('list'));
|
||||
$action = self::ACTION_PREFIX . ucfirst($request->getAction());
|
||||
if (method_exists($this, $action)) {
|
||||
return $this->forward($action, $request);
|
||||
} else {
|
||||
return $this->forward("actionIndex", $request);
|
||||
}
|
||||
}
|
||||
|
||||
public function execute(HTTPRequest $request)
|
||||
{
|
||||
$result = $this->execute1($request);
|
||||
if ($result) {
|
||||
$this->view = $result;
|
||||
}
|
||||
return $this->render();
|
||||
}
|
||||
|
||||
public function forward($action, HTTPRequest $args)
|
||||
{
|
||||
// Действия до вызова основного обработчика
|
||||
/*foreach($this->_aspect as $aspect) {
|
||||
if (isset($aspect->before[$action])) {
|
||||
call_user_func ($aspect->before[$action], $action, $args);
|
||||
}
|
||||
}*/
|
||||
return call_user_func(array($this, $action), $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Страница по умолчанию
|
||||
*/
|
||||
public function metaActionIndex(HttpRequest $request, $setup, $list)
|
||||
public function actionIndex(HttpRequest $request)
|
||||
{
|
||||
// может быть одно ref или несколько
|
||||
// {{{ история переходов
|
||||
$ref = null;
|
||||
if ($request->get('ref')) {
|
||||
$ref = $request->get('ref');
|
||||
} else if ($request->session()->get('ref')) {
|
||||
$ref = $request->session()->get('ref');
|
||||
return "";
|
||||
}
|
||||
|
||||
public function postUrl($name, $param)
|
||||
{
|
||||
return "?" . http_build_query(
|
||||
array_merge(array('module' => strtolower(get_class($this)), "action" => $name),
|
||||
$this->param, $param));
|
||||
}
|
||||
|
||||
/**
|
||||
* Генерация ссылки c учетом прав пользователя на ссылки
|
||||
*
|
||||
* @parma string $name Действие
|
||||
* @parma string $param Дополнительные параметры
|
||||
*/
|
||||
public function nUrl($name, array $param = array())
|
||||
{
|
||||
if (!$this->access || $this->access->checkAction($name)) {
|
||||
return lcurry(array($this, 'postUrl'), $name, $param);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
$request->session->set('ref', $ref);
|
||||
$this->addParameter('ref', $ref);
|
||||
// }}}
|
||||
$this->setTitlePath($ref);
|
||||
|
||||
$tpl = $this->getView('list');
|
||||
|
||||
// Помошники действий
|
||||
$this->callHelpers($request);
|
||||
// Таблица
|
||||
if ($request->session()->get(strtolower(get_class($this)))) {
|
||||
$session = $request->session()->get(strtolower(get_class($this)));
|
||||
if (isset($session['view'])) {
|
||||
$this->table->setView($session['view']);
|
||||
}
|
||||
$this->table->setData('state', array(
|
||||
'page' => $session['page'],
|
||||
'size' => $session['size'],
|
||||
'desc' => $session['desc']));
|
||||
|
||||
$this->table->setData('sorter', $session['key']);
|
||||
if (isset($session['desc'])) {
|
||||
$this->table->setData('desc', $session['desc']);
|
||||
}
|
||||
}
|
||||
|
||||
call_user_func($setup, $this->table, $request->get('id'), $ref);// --> Эквивалент formSetup
|
||||
$this->table->setAction($list);
|
||||
//
|
||||
$tpl->menu_path = $this->path->getItems();
|
||||
|
||||
// Поиск
|
||||
$search = new SearchDialog();
|
||||
$search->setTitle('Поиск');
|
||||
$search->setAction($this->aUrl('search'));
|
||||
$search->setFriend($this->table);
|
||||
$search->addFields($this->schemaSearch);
|
||||
|
||||
// Настройки
|
||||
$setup = new SetupDialog();
|
||||
$setup->setTitle('Настройки');
|
||||
$setup->setAction($this->nUrl('setup'));
|
||||
$setup->setFriend($this->table);
|
||||
|
||||
// Меню
|
||||
$this->menu->addMenuItem('?menu=toggle&id=' . $search->getName(), 'поиск', 'actions/system-search'); // Стандартный размер для иконок 22-24px
|
||||
$this->menu->addMenuItem('?menu=toggle&id=' . $setup->getName(), 'настройки', 'categories/applications-system');
|
||||
// Добавление компонентов
|
||||
$this->addChild('menu', $this->menu);
|
||||
$this->addChild('search', $search);
|
||||
$this->addChild('setup', $setup);
|
||||
$this->addChild('table', $this->table);
|
||||
//
|
||||
return $tpl;
|
||||
public function fUrl($name, array $param = array())
|
||||
{
|
||||
return forceUrl($this->nUrl($name, $param));
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавляет параметр для всех ссылок создаваемых функцией nUrl, aUrl
|
||||
*/
|
||||
public function actionSetup($request)
|
||||
public function addParameter($name, $value)
|
||||
{
|
||||
$left = explode(",", $request->get('left'));
|
||||
$right = explode(",", $request->get('right'));
|
||||
|
||||
$$request->session()->set(strtolower(get_class($this)),
|
||||
array('view' => array('left' => $left, 'right' => $right)));
|
||||
|
||||
return $this->forward('actionIndex', $request);
|
||||
if ($value) {
|
||||
$this->param [$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Генерация ссылки на действие контроллера
|
||||
* Ajax определяется автоматически mode = ajax используется для смены layout
|
||||
*/
|
||||
private function formPage($form, $request)
|
||||
public function aUrl($name, array $param = array())
|
||||
{
|
||||
$view = $this->getView('form');
|
||||
$view->setView('form', $form);
|
||||
$view->action = forceUrl($this->nUrl('add', array('page' => $this->getPageId($request)))); // Действие для формы
|
||||
|
||||
$view->menu_path = $this->path->getItems();
|
||||
$view->back = $this->path->getPrev();
|
||||
return $view;
|
||||
return $this->nUrl($name, array_merge(array('mode' => 'ajax'), $param)); // FIXME
|
||||
}
|
||||
|
||||
// Тоже убрать в метод Controller_Model
|
||||
function getActionPath(HttpRequest $request/*, $action = false*/)
|
||||
/**
|
||||
* Добавление помошника контроллера
|
||||
*/
|
||||
public function addHelper($class)
|
||||
{
|
||||
require_once 'state.php';
|
||||
$this->_getActionPath()->getPath($this, ($action) ? $action : $request->getAction());
|
||||
}
|
||||
$this->helpers [] = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Вызов помошников контроллера
|
||||
*/
|
||||
public function callHelpers(HttpRequest $request)
|
||||
{
|
||||
$action = self::ACTION_PREFIX . $request->getAction();
|
||||
foreach ($this->helpers as $helper) {
|
||||
if (method_exists($helper, $action)) {
|
||||
return call_user_func(array($helper, $action), $request, $this);
|
||||
} else {
|
||||
return $helper->actionIndex($request, $this); // Вместо return response ???
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Загрузка файла класса
|
||||
*/
|
||||
public function loadClass($path, $setup = null)
|
||||
{
|
||||
if (file_exists($path)) {
|
||||
require_once ($path);
|
||||
$class = pathinfo($path, PATHINFO_FILENAME);
|
||||
return new $class($setup);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function loadSettings($path)
|
||||
{
|
||||
$result = new Settings($path);
|
||||
$result->read();
|
||||
return $result->export();
|
||||
}
|
||||
|
||||
// Для Widgets
|
||||
public $view = null;
|
||||
public $childNodes = array();
|
||||
public $childViews = array();
|
||||
|
||||
public function setView($name)
|
||||
{
|
||||
$this->view = $this->getView($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Установка заголовка для отображения
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->view->setTitle($title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавление widget к отображению
|
||||
*/
|
||||
public function addChild(/*Widget*/ $section, $node)
|
||||
{
|
||||
$this->childNodes[$section] = $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавление дочернего отображения к текущему отображению
|
||||
*/
|
||||
public function addView(/*CompositeView*/ $section, $node)
|
||||
{
|
||||
$this->childViews[$section] = $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Генерация содержания
|
||||
* Путаница c execute и render
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
foreach ($this->childNodes as $name => $node) {
|
||||
$node->make($this);
|
||||
$this->view->setView($name, $node->view);
|
||||
}
|
||||
foreach ($this->childViews as $name => $node) {
|
||||
$this->view->setView($name, $node);
|
||||
}
|
||||
return $this->view;
|
||||
}
|
||||
|
||||
function getPageId($request)
|
||||
{
|
||||
$pageId = time();
|
||||
$request->session()->set('page', $pageId);
|
||||
return $pageId;
|
||||
}
|
||||
|
||||
function checkPageId($request, $page)
|
||||
{
|
||||
$_page = $request->session()->get('page');
|
||||
$result = ($_page && $_page == $page);
|
||||
$request->session()->clean('page');
|
||||
return $result;
|
||||
}
|
||||
|
||||
function redirect($action) {
|
||||
header('location: ' . $this->fUrl($action));
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,341 +0,0 @@
|
|||
<?php
|
||||
|
||||
require_once 'core/functions.php';
|
||||
|
||||
|
||||
function forceUrl($name)
|
||||
{
|
||||
if (is_callable($name)) {
|
||||
return call_user_func($name);
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Контроллер страниц
|
||||
* @package core
|
||||
*/
|
||||
class Controller_Controller
|
||||
{
|
||||
|
||||
const TEMPLATE_EXTENSION = ".html"; // Расширение для шаблонов
|
||||
const ACTION_PREFIX = "action"; // Префикс для функций действий
|
||||
|
||||
public $jsPath; // Глобальный путь к скриптам
|
||||
public $themePath; // Глобальный путь к текущей теме
|
||||
|
||||
// Параметры устанавливаются при создании контроллера
|
||||
public $name; // Имя модуля
|
||||
public $viewPath = null; // Путь к шаблонам контроллера
|
||||
public $db; // Соединение с базой данных
|
||||
|
||||
// Фильтры
|
||||
public $access; // Обьект хранит параметры доступа
|
||||
public $logger; // Обьект для ведения лога
|
||||
|
||||
private $factory; // Ссылка на обьект создания модели
|
||||
private $helpers = array(); // Помошники для действий
|
||||
public $param = array(); // Параметры для ссылки
|
||||
|
||||
public $_registry; // Ссылка на реестр
|
||||
public $_shortcut;
|
||||
|
||||
public function __construct ()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function setUp ()
|
||||
{
|
||||
// override this
|
||||
}
|
||||
|
||||
public function loadConfig($name) {
|
||||
$filename = Shortcut::getUrl('config', $name);
|
||||
if (file_exists($filename)) {
|
||||
include($filename);
|
||||
} else {
|
||||
throw new Exception('Невозможно загрузить файл настроек ' . $name);
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->db;
|
||||
}
|
||||
|
||||
public function installPath($name)
|
||||
{
|
||||
return Path::join(CMS_PATH, "modules", $name, "install");
|
||||
}
|
||||
|
||||
public function addSuggest($view, $name)
|
||||
{
|
||||
$suggest = array();
|
||||
$file = Path::join($this->viewPath, 'help', $name . '.suggest');
|
||||
if (file_exists($file) && include($file)) {
|
||||
$view->addScriptRaw("add_suggest(".json::encode($suggest).");\n");
|
||||
}
|
||||
}
|
||||
|
||||
function findIcon($icon, $size)
|
||||
{
|
||||
return Path::join($this->iconPath, $size . 'x' . $size, $icon . '.png');
|
||||
}
|
||||
|
||||
/**
|
||||
* Создает представление
|
||||
* @param string $file
|
||||
* @return template
|
||||
*/
|
||||
public function getView($name)
|
||||
{
|
||||
require_once "core/view/compositeview.php";
|
||||
|
||||
$file = $name . self::TEMPLATE_EXTENSION;
|
||||
// Список возможных директорий для поиска файла шаблона
|
||||
$theme = $this->_registry->readKey(array('system', 'theme'));
|
||||
$icon_theme = $this->_registry->readKey(array('system', 'icon_theme'));
|
||||
$list = array(
|
||||
Path::join($this->viewPath, TEMPLATES) => Path::join(WWW_PATH, "modules", $this->name, TEMPLATES),
|
||||
PHPTAL_TEMPLATE_REPOSITORY => "");
|
||||
|
||||
|
||||
// Поиск файла для шаблона
|
||||
foreach($list as $ospath => $path) {
|
||||
$template = Path::join($ospath, $file);
|
||||
if(file_exists($template)) { break; }
|
||||
}
|
||||
|
||||
$tpl = new View_Composite($template);
|
||||
$tpl->icons = $this->iconPath; // Путь к файлам текущей темы
|
||||
$tpl->media = $this->themePath; // Путь к файлам текущей темы
|
||||
$tpl->script = $this->jsPath; // Путь к файлам скриптов
|
||||
$tpl->template = $path; // Путь к файлам текущего шаблона
|
||||
$tpl->setAlias(array(
|
||||
'${icons}' => $this->iconPath,
|
||||
'${media}' => $this->themePath,
|
||||
'${script}' => $this->jsPath,
|
||||
'${template}' => $path));
|
||||
|
||||
$tpl->loadImports(Path::skipExtension($template) . ".import");
|
||||
|
||||
$this->addSuggest($tpl, $name);
|
||||
return $tpl;
|
||||
}
|
||||
|
||||
public function getModel($name)
|
||||
{
|
||||
if (!$this->factory) {
|
||||
$this->factory = new ModelFactory($this->db, $this->_registry, $this->_shortcut);
|
||||
}
|
||||
return $this->factory->getModel($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Выбор действия
|
||||
* Т.к действия являются методами класса то
|
||||
* 1. Можно переопределить действия
|
||||
* 2. Использовать наследование чтобы добавить к старому обработчику новое поведение
|
||||
* @param $request Обьект запроса
|
||||
*/
|
||||
public function execute1(HTTPRequest $request)
|
||||
{
|
||||
$action = self::ACTION_PREFIX . ucfirst($request->getAction());
|
||||
if (method_exists($this, $action)) {
|
||||
return $this->forward($action, $request);
|
||||
} else {
|
||||
return $this->forward("actionIndex", $request);
|
||||
}
|
||||
}
|
||||
|
||||
public function execute(HTTPRequest $request)
|
||||
{
|
||||
$result = $this->execute1($request);
|
||||
if ($result) {
|
||||
$this->view = $result;
|
||||
}
|
||||
return $this->render();
|
||||
}
|
||||
|
||||
public function forward($action, HTTPRequest $args)
|
||||
{
|
||||
// Действия до вызова основного обработчика
|
||||
/*foreach($this->_aspect as $aspect) {
|
||||
if (isset($aspect->before[$action])) {
|
||||
call_user_func ($aspect->before[$action], $action, $args);
|
||||
}
|
||||
}*/
|
||||
return call_user_func(array($this, $action), $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Страница по умолчанию
|
||||
*/
|
||||
public function actionIndex(HttpRequest $request)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public function postUrl($name, $param)
|
||||
{
|
||||
return "?" . http_build_query(
|
||||
array_merge(array('module' => strtolower(get_class($this)), "action" => $name),
|
||||
$this->param, $param));
|
||||
}
|
||||
|
||||
/**
|
||||
* Генерация ссылки c учетом прав пользователя на ссылки
|
||||
*
|
||||
* @parma string $name Действие
|
||||
* @parma string $param Дополнительные параметры
|
||||
*/
|
||||
public function nUrl($name, array $param = array())
|
||||
{
|
||||
if (!$this->access || $this->access->checkAction($name)) {
|
||||
return lcurry(array($this, 'postUrl'), $name, $param);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function fUrl($name, array $param = array())
|
||||
{
|
||||
return forceUrl($this->nUrl($name, $param));
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавляет параметр для всех ссылок создаваемых функцией nUrl, aUrl
|
||||
*/
|
||||
public function addParameter($name, $value)
|
||||
{
|
||||
if ($value) {
|
||||
$this->param [$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Генерация ссылки на действие контроллера
|
||||
* Ajax определяется автоматически mode = ajax используется для смены layout
|
||||
*/
|
||||
public function aUrl($name, array $param = array())
|
||||
{
|
||||
return $this->nUrl($name, array_merge(array('mode' => 'ajax'), $param)); // FIXME
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавление помошника контроллера
|
||||
*/
|
||||
public function addHelper($class)
|
||||
{
|
||||
$this->helpers [] = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Вызов помошников контроллера
|
||||
*/
|
||||
public function callHelpers(HttpRequest $request)
|
||||
{
|
||||
$action = self::ACTION_PREFIX . $request->getAction();
|
||||
foreach ($this->helpers as $helper) {
|
||||
if (method_exists($helper, $action)) {
|
||||
return call_user_func(array($helper, $action), $request, $this);
|
||||
} else {
|
||||
return $helper->actionIndex($request, $this); // Вместо return response ???
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Загрузка файла класса
|
||||
*/
|
||||
public function loadClass($path, $setup = null)
|
||||
{
|
||||
if (file_exists($path)) {
|
||||
require_once ($path);
|
||||
$class = pathinfo($path, PATHINFO_FILENAME);
|
||||
return new $class($setup);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function loadSettings($path)
|
||||
{
|
||||
$result = new Settings($path);
|
||||
$result->read();
|
||||
return $result->export();
|
||||
}
|
||||
|
||||
// Для Widgets
|
||||
public $view = null;
|
||||
public $childNodes = array();
|
||||
public $childViews = array();
|
||||
|
||||
public function setView($name)
|
||||
{
|
||||
$this->view = $this->getView($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Установка заголовка для отображения
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->view->setTitle($title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавление widget к отображению
|
||||
*/
|
||||
public function addChild(/*Widget*/ $section, $node)
|
||||
{
|
||||
$this->childNodes[$section] = $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавление дочернего отображения к текущему отображению
|
||||
*/
|
||||
public function addView(/*CompositeView*/ $section, $node)
|
||||
{
|
||||
$this->childViews[$section] = $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Генерация содержания
|
||||
* Путаница c execute и render
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
foreach ($this->childNodes as $name => $node) {
|
||||
$node->make($this);
|
||||
$this->view->setView($name, $node->view);
|
||||
}
|
||||
foreach ($this->childViews as $name => $node) {
|
||||
$this->view->setView($name, $node);
|
||||
}
|
||||
return $this->view;
|
||||
}
|
||||
|
||||
function getPageId($request)
|
||||
{
|
||||
$pageId = time();
|
||||
$request->session()->set('page', $pageId);
|
||||
return $pageId;
|
||||
}
|
||||
|
||||
function checkPageId($request, $page)
|
||||
{
|
||||
$_page = $request->session()->get('page');
|
||||
$result = ($_page && $_page == $page);
|
||||
$request->session()->clean('page');
|
||||
return $result;
|
||||
}
|
||||
|
||||
function redirect($action) {
|
||||
header('location: ' . $this->fUrl($action));
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
class Controller_Action extends Controller {}
|
||||
|
||||
|
|
@ -1,30 +1,24 @@
|
|||
<?php
|
||||
|
||||
require_once 'core/controller/controller.php';
|
||||
require_once 'core/controller/installer.php';
|
||||
|
||||
/**
|
||||
* Первичный контроллер контроллер страниц
|
||||
* @package core
|
||||
*/
|
||||
class Controller_Front extends Controller
|
||||
class Controller_Front extends Controller_Action
|
||||
{
|
||||
|
||||
protected $shortcut; // Ярлык к модулю
|
||||
protected $_param; // Параметр по которому выбирается модуль
|
||||
protected $default; // Значение параметра по умолчанию
|
||||
protected $installer;
|
||||
|
||||
public function __construct(Settings $_registry, $_shortcut)
|
||||
{
|
||||
require_once 'core/database_pdo.php';
|
||||
parent::__construct();
|
||||
$registry = $_registry;
|
||||
$this->_registry = $_registry;
|
||||
$this->_shortcut = $_shortcut;
|
||||
|
||||
$this->db = Database::getConnection($registry->readKey(array('system', 'dsn')));
|
||||
$this->installer = new Installer($_registry);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -36,8 +30,6 @@ class Controller_Front extends Controller
|
|||
*/
|
||||
public function loadModule($name, Collection $request)
|
||||
{
|
||||
$this->installer->setUp($this->db, array($this, 'installPath'));
|
||||
$this->installer->doUpdates($name); // ModuleLoader (1)
|
||||
|
||||
$moduleFile = Shortcut::getUrl($this->shortcut, $name); // ModuleLoader (2)
|
||||
$module = $this->loadClass($moduleFile);
|
||||
|
|
@ -59,10 +51,10 @@ class Controller_Front extends Controller
|
|||
$module->db = $this->db;
|
||||
// Не для всех приложений нужно вести лог действий
|
||||
// Ведение лога
|
||||
$logger = $this->loadClass(FRAMEWORK_PATH . '/core/filter/actionlogger.php', $module);
|
||||
$logger = $this->loadClass(FRAMEWORK_PATH . '/src/filter/actionlogger.php', $module);
|
||||
$logger->before = $this->loadSettings(Shortcut::getUrl('logger', $name));
|
||||
// Управление доступом
|
||||
$module->access = $this->loadClass(FRAMEWORK_PATH . '/core/filter/actionaccess.php', $logger);
|
||||
$module->access = $this->loadClass(FRAMEWORK_PATH . '/src/filter/actionaccess.php', $logger);
|
||||
$module->access->access = $this->loadSettings(Shortcut::getUrl('access', $name));
|
||||
|
||||
$module->setUp();
|
||||
|
|
|
|||
426
src/controller/model.php
Normal file
426
src/controller/model.php
Normal file
|
|
@ -0,0 +1,426 @@
|
|||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* Переименовать контроллер !! (StubController, CrudController, PageController, BaseController) ModelController
|
||||
* Возможно нужен еще класс с мета действиями как для actionIndex <= metaActionIndex либо с классам для этих действий
|
||||
* Есть класс для управлениями действиями а есть сами действия в виде классов или функций !!
|
||||
*
|
||||
* @class Controller_Model в котором определены основные действия для редактирования, вывода списка, сохранения, поиска и т.д
|
||||
* В модуле определяется только способ отображения этих данных
|
||||
*/
|
||||
class Controller_Model extends Controller_Action
|
||||
{
|
||||
public /*.array.*/$schema = array();
|
||||
public /*.array.*/$schemaSearch = array();
|
||||
|
||||
/**
|
||||
* FIXME: Лучше $this->table->setHeader
|
||||
*/
|
||||
public $tableSchema = null;
|
||||
public /*.array.*/$formSchema = array();
|
||||
|
||||
public $menu;
|
||||
public $table;
|
||||
|
||||
protected /*.string.*/$useModel;
|
||||
protected /*.string.*/$itemModel;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->path = new PathMenu();
|
||||
$this->menu = new PageMenu();
|
||||
$this->table = new ListTable();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function setUp()
|
||||
{
|
||||
$this->table->addMenuItem($this->aUrl('delete'), 'удалить', false, 'all', 'warning');
|
||||
//$this->table->addMenuItem($this->nUrl('form'), 'редактировать', 'edit-24.png');
|
||||
}
|
||||
|
||||
function saveParameters($args, $list)
|
||||
{
|
||||
foreach ($list as $item) {
|
||||
$args->session()->set(array($this, $item), $args->get($item));
|
||||
}
|
||||
}
|
||||
|
||||
protected function getJSONList(/*Mapper*/ $model, Collection $request)
|
||||
{
|
||||
$result = array();
|
||||
$this->saveParameters($request, array('size','page','desc', 'key'));
|
||||
|
||||
$result['list'] = $model->findAll($request, $request->get('ref'));
|
||||
$result['size'] = $model->getCount($request, $request->get('ref'));
|
||||
return json::encode($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаление сторк из таблицы
|
||||
*/
|
||||
public function actionDelete(HttpRequest $request)
|
||||
{
|
||||
$model = $this->getModel($this->useModel);
|
||||
// Почему table_item ???
|
||||
$list = ($request->get('table_item')) ? $request->get('table_item'): $request->get('id');
|
||||
$model->deleteList($list);
|
||||
|
||||
return $this->getJSONList($model, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ответ на запрос по поиску
|
||||
*/
|
||||
public function actionSearch(HttpRequest $request)
|
||||
{
|
||||
$model = $this->getModel($this->useModel);
|
||||
$model->addFilter($model->requestToSQL($request, $this->formSchema));
|
||||
|
||||
return $this->getJSONList($model, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Список элементов
|
||||
*/
|
||||
public function actionList(HttpRequest $request)
|
||||
{
|
||||
$model = $this->getModel($this->useModel);
|
||||
return $this->getJSONList($model, $request);
|
||||
}
|
||||
|
||||
|
||||
private function setFormSchema()
|
||||
{
|
||||
require_once 'core/mapper/uimapper.php';
|
||||
|
||||
$model = $this->getModel($this->useModel);
|
||||
$ui = new UIMapper($model);
|
||||
|
||||
$this->formSchema = $ui->getFormSchema();
|
||||
}
|
||||
|
||||
/**
|
||||
* Сохранение формы
|
||||
*/
|
||||
function beforeSave(/*Model*/ $item, Collection $request)
|
||||
{
|
||||
if (empty($this->formSchema)) {
|
||||
$this->setFormSchema();
|
||||
}
|
||||
// Сделать отображение Формы в обьект и обратно <-- Убрать в beforeSave
|
||||
foreach ($this->formSchema as $key => $conv) {
|
||||
list($value, $type) = $conv;
|
||||
$item->$value = call_user_func(array('Cast', 'to_' . $type), $request->get($key)); // Здесть нужно преобразовывать тип значения
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновление формы
|
||||
*/
|
||||
function formUpdate(TForm $form, Collection $request)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Загрузка формы
|
||||
*/
|
||||
function beforeLoad(/*Model*/ $item, TForm $form)
|
||||
{
|
||||
if (empty($this->formSchema)) {
|
||||
$this->setFormSchema();
|
||||
}
|
||||
// Вставка значений из данных в форму
|
||||
// Отображение обьекта в поля формы
|
||||
$form->fill($item, $this->formSchema);
|
||||
}
|
||||
|
||||
// Проверка ввода
|
||||
protected function validate($validator, $request)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Действие для проверки формы
|
||||
*/
|
||||
public function actionValidate($request)
|
||||
{
|
||||
require_once "core/validator/validator.php";
|
||||
$validator = new Validator();
|
||||
$validator->addRuleList($this->schema);
|
||||
|
||||
// Действия до проверки формы
|
||||
$this->validate($validator, $request); // <--|
|
||||
$validator->validate($request); // --|
|
||||
// Проверка формы
|
||||
if (!$validator->isValid()) {
|
||||
return json::encode($validator->getErrorMsg());
|
||||
}
|
||||
return json::encode(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Инициализация формы
|
||||
*/
|
||||
protected function formSetup($form, $id = null, $ref = null)
|
||||
{
|
||||
if (empty($this->schema)) {
|
||||
$model = $this->getModel($this->useModel);
|
||||
$ui = new UIMapper($model);
|
||||
$schema = $ui->getEditSchema();
|
||||
|
||||
$form->addFieldList($schema);
|
||||
} else {
|
||||
$form->addFieldList($this->schema);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавление пользователя
|
||||
*/
|
||||
public function actionAdd(HttpRequest $request)
|
||||
{
|
||||
require_once "core/validator/validator.php";
|
||||
// {{{ тоже может быть один ref или несколько
|
||||
$ref = $request->get('ref');
|
||||
$this->addParameter('ref', $ref); // Добавляет параметр в url
|
||||
/// }}}
|
||||
|
||||
if ($this->checkPageId($request, $request->get('page'))) {
|
||||
// Проверка
|
||||
$validator = new Validator();
|
||||
$validator->addRuleList($this->schema);
|
||||
|
||||
// Действия до проверки формы
|
||||
$this->validate($validator, $request); // <--|
|
||||
$validator->validate($request); // --|
|
||||
// Проверка формы
|
||||
if (!$validator->isValid()) {
|
||||
$request->setAction('form');
|
||||
$this->getActionPath($request);
|
||||
|
||||
$form = new TForm();
|
||||
$this->formSetup($form, $request->get('id'), $request->get('ref')); // Инициализация формы
|
||||
|
||||
$form->setValues($request); // <-- Убрать в formUpdate
|
||||
$this->formUpdate($form, $request);
|
||||
|
||||
$form->setError($validator); // Установка ошибок для формы
|
||||
|
||||
$tpl = $this->formPage($form, $request);
|
||||
$id = $request->get('id');
|
||||
if ($id) { // Редактирование
|
||||
$tpl->action = forceUrl($this->nUrl('add', array('id' => $id, 'page' => $this->getPageId($request)))); // action Совйство формы
|
||||
}
|
||||
return $tpl /*->execute()*/;
|
||||
}
|
||||
|
||||
// Нужен тест для формы
|
||||
$model = $this->getModel($this->useModel);
|
||||
$className = $model->className;
|
||||
$item = new $className();
|
||||
|
||||
// Сохраняем значение в базе данных
|
||||
$item->id = $request->get('id');
|
||||
// Если таблица связана с другой таблицей
|
||||
if ($request->get('ref') && $model->reference[1]) {
|
||||
$ref_id = $model->reference[1];
|
||||
$item->$ref_id = $request->get('ref');
|
||||
}
|
||||
|
||||
// Подготовка к сохранению
|
||||
$this->beforeSave($item, $request); // Сюдаже и истрия переходов
|
||||
// nextId ??? или выход или новая форма для создания новости
|
||||
$model->saveDB($item, $request);
|
||||
}
|
||||
|
||||
// Для страницы со списком id -> идентефикатор родительской таблицы !!??
|
||||
// $request->set('id', $request->get('ref'));
|
||||
if ($request->get('apply')) {
|
||||
$request->setAction('form');
|
||||
return $this->forward('actionForm', $request);
|
||||
}
|
||||
return $this->forward('actionIndex', $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Заголовок
|
||||
*/
|
||||
private function setTitlePath($ref)
|
||||
{
|
||||
if ($ref) {
|
||||
$model = $this->getModel($this->useModel);
|
||||
if (is_array($model->reference) && $model->reference[0]) {
|
||||
$refmodel = $this->getModel($model->reference[0]);
|
||||
try {
|
||||
$parent = $refmodel->findById($ref);
|
||||
$this->path->addTitle($parent->getTitle()); // Заголовок к подписям путей
|
||||
} catch (Exception $e) {
|
||||
// Не найден заголовок потому что неправильно определен родительский элемент
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Форма для редактирования
|
||||
*/
|
||||
public function actionForm(HttpRequest $request)
|
||||
{
|
||||
$this->getActionPath($request);
|
||||
$ref = $request->get('ref');
|
||||
$this->addParameter('ref', $ref); // Добавляет параметр в url
|
||||
$this->setTitlePath($ref);
|
||||
|
||||
$model = $this->getModel($this->useModel);
|
||||
$form = new TForm(); // Показываем форму
|
||||
$form->header = 'Редактирование записи';
|
||||
$this->formSetup($form, $request->get('id'), $request->get('ref')); // Инициализация формы
|
||||
|
||||
$list = $request->get('table_item');
|
||||
$id = ($list[0]) ? $list[0] : $request->get('id');
|
||||
|
||||
$tpl = $this->formPage ($form, $request);
|
||||
if ($id) { // Редактирование
|
||||
$form->action = forceUrl($this->nUrl('add', array('id' => $id, 'page' => $this->getPageId($request)))); // action Свойство формы
|
||||
$item = $model->findById($id);
|
||||
// Загрузка формы
|
||||
$this->beforeLoad($item, $form);
|
||||
///
|
||||
}
|
||||
return $tpl;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function tableSetup($table, $id = null, $ref = null)
|
||||
{
|
||||
// FIXME: После замены везде $tableSchema -> table->setHeader удалить!
|
||||
if ($this->tableSchema) {
|
||||
$table->setHeader($this->tableSchema);
|
||||
} else {
|
||||
// Настройка таблицы отображения по схеме данных
|
||||
require_once 'core/mapper/uimapper.php';
|
||||
$model = $this->getModel($this->useModel);
|
||||
$ui = new UIMapper($model);
|
||||
$schema = $ui->getTableSchema();
|
||||
$schema[0]['action'] = $table->getFirstItem();
|
||||
|
||||
$table->setHeader($schema);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function actionIndex(HttpRequest $request)
|
||||
{
|
||||
$this->getActionPath($request, 'index');
|
||||
// Такое мета действие наверное можно вынести в отдельный класс
|
||||
return $this->metaActionIndex($request, array($this, 'tableSetup'), $this->aUrl('list'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Страница по умолчанию
|
||||
*/
|
||||
public function metaActionIndex(HttpRequest $request, $setup, $list)
|
||||
{
|
||||
// может быть одно ref или несколько
|
||||
// {{{ история переходов
|
||||
$ref = null;
|
||||
if ($request->get('ref')) {
|
||||
$ref = $request->get('ref');
|
||||
} else if ($request->session()->get('ref')) {
|
||||
$ref = $request->session()->get('ref');
|
||||
}
|
||||
|
||||
$request->session->set('ref', $ref);
|
||||
$this->addParameter('ref', $ref);
|
||||
// }}}
|
||||
$this->setTitlePath($ref);
|
||||
|
||||
$tpl = $this->getView('list');
|
||||
|
||||
// Помошники действий
|
||||
$this->callHelpers($request);
|
||||
// Таблица
|
||||
if ($request->session()->get(strtolower(get_class($this)))) {
|
||||
$session = $request->session()->get(strtolower(get_class($this)));
|
||||
if (isset($session['view'])) {
|
||||
$this->table->setView($session['view']);
|
||||
}
|
||||
$this->table->setData('state', array(
|
||||
'page' => $session['page'],
|
||||
'size' => $session['size'],
|
||||
'desc' => $session['desc']));
|
||||
|
||||
$this->table->setData('sorter', $session['key']);
|
||||
if (isset($session['desc'])) {
|
||||
$this->table->setData('desc', $session['desc']);
|
||||
}
|
||||
}
|
||||
|
||||
call_user_func($setup, $this->table, $request->get('id'), $ref);// --> Эквивалент formSetup
|
||||
$this->table->setAction($list);
|
||||
//
|
||||
$tpl->menu_path = $this->path->getItems();
|
||||
|
||||
// Поиск
|
||||
$search = new SearchDialog();
|
||||
$search->setTitle('Поиск');
|
||||
$search->setAction($this->aUrl('search'));
|
||||
$search->setFriend($this->table);
|
||||
$search->addFields($this->schemaSearch);
|
||||
|
||||
// Настройки
|
||||
$setup = new SetupDialog();
|
||||
$setup->setTitle('Настройки');
|
||||
$setup->setAction($this->nUrl('setup'));
|
||||
$setup->setFriend($this->table);
|
||||
|
||||
// Меню
|
||||
$this->menu->addMenuItem('?menu=toggle&id=' . $search->getName(), 'поиск', 'actions/system-search'); // Стандартный размер для иконок 22-24px
|
||||
$this->menu->addMenuItem('?menu=toggle&id=' . $setup->getName(), 'настройки', 'categories/applications-system');
|
||||
// Добавление компонентов
|
||||
$this->addChild('menu', $this->menu);
|
||||
$this->addChild('search', $search);
|
||||
$this->addChild('setup', $setup);
|
||||
$this->addChild('table', $this->table);
|
||||
//
|
||||
return $tpl;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function actionSetup($request)
|
||||
{
|
||||
$left = explode(",", $request->get('left'));
|
||||
$right = explode(",", $request->get('right'));
|
||||
|
||||
$$request->session()->set(strtolower(get_class($this)),
|
||||
array('view' => array('left' => $left, 'right' => $right)));
|
||||
|
||||
return $this->forward('actionIndex', $request);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
private function formPage($form, $request)
|
||||
{
|
||||
$view = $this->getView('form');
|
||||
$view->setView('form', $form);
|
||||
$view->action = forceUrl($this->nUrl('add', array('page' => $this->getPageId($request)))); // Действие для формы
|
||||
|
||||
$view->menu_path = $this->path->getItems();
|
||||
$view->back = $this->path->getPrev();
|
||||
return $view;
|
||||
}
|
||||
|
||||
// Тоже убрать в метод Controller_Model
|
||||
function getActionPath(HttpRequest $request/*, $action = false*/)
|
||||
{
|
||||
require_once 'state.php';
|
||||
$this->_getActionPath()->getPath($this, ($action) ? $action : $request->getAction());
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@ class Controller_State
|
|||
|
||||
static function make($action)
|
||||
{
|
||||
return new State($action);
|
||||
return new Controller_State($action);
|
||||
}
|
||||
|
||||
public function addTitle($name, $url = array())
|
||||
|
|
@ -22,7 +22,7 @@ class Controller_State
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function addState(State $state)
|
||||
public function addState(Controller_State $state)
|
||||
{
|
||||
$this->states [$state->getAction()] = $state;
|
||||
return $this;
|
||||
|
|
@ -49,7 +49,7 @@ class Controller_State
|
|||
return false;
|
||||
}
|
||||
|
||||
function makeTitle($module)
|
||||
function makeTitle(Controller_Action $module)
|
||||
{
|
||||
foreach ($this->titles as $item) {
|
||||
$module->path->addMenuItem($module->nUrl($this->action, $item[1]), $item[0]);
|
||||
|
|
@ -68,12 +68,3 @@ class Controller_State
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
$path = State::make('index')
|
||||
->addState(State::make('form'))
|
||||
->addState(State::make('view'));
|
||||
|
||||
$path->getPath(0, 'form');
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
require_once 'core/path.php';
|
||||
|
||||
class ActionLogger
|
||||
{
|
||||
public $before = array ();
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
// В класс авторизации передавать обьект для управления пользователем
|
||||
// Вынести в отдельный файл
|
||||
class Filter_LoginFilter extends Filter_Filter
|
||||
class Filter_Login extends Filter_Filter
|
||||
{
|
||||
const SESSION_BROWSER_SIGN_SECRET = '@w3dsju45Msk#';
|
||||
const SESSION_BROWSER_SIGN_KEYNAME = 'session.app.browser.sign';
|
||||
|
|
@ -20,16 +20,16 @@ class Filter_LoginFilter extends Filter_Filter
|
|||
public function isLoggin(HttpRequest $request)
|
||||
{
|
||||
// Авторизация
|
||||
session_start();
|
||||
// session_start();
|
||||
$db = $this->getConnection();
|
||||
UserAccess::setUp($db); // Соединение
|
||||
Filter_UserAccess::setUp($db); // Соединение
|
||||
switch ($request->getAction()) {
|
||||
// Авторизация по постоянному паролю
|
||||
case 'login':
|
||||
$login = $request->get('login');
|
||||
$password = $request->get('password');
|
||||
|
||||
$result = UserAccess::getUserByLogin($login); // Поиск по логину
|
||||
$result = Filter_UserAccess::getUserByLogin($login); // Поиск по логину
|
||||
if ($result) {
|
||||
if (md5($password) == $result->getString('password')) { // password
|
||||
$this->enter($db, $result);
|
||||
|
|
@ -1,10 +1,7 @@
|
|||
<?php
|
||||
|
||||
require_once 'filterbase.php';
|
||||
require_once 'filterlogin.php';
|
||||
|
||||
// Класс должен быть в библиотеке приложения
|
||||
class UserAccess
|
||||
class Filter_UserAccess
|
||||
{
|
||||
const LIFE_TIME = 1800; // = 30min * 60sec;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,17 +2,23 @@
|
|||
|
||||
/**
|
||||
* Элемент формы
|
||||
* @package core
|
||||
*/
|
||||
class TField
|
||||
{
|
||||
public $hidden = false;
|
||||
public $name;
|
||||
public $label; // Метка поля
|
||||
public $value; // Значение поля
|
||||
public $type; // Каждому типу элемента соответствует макрос TAL
|
||||
public $type = ""; // Каждому типу элемента соответствует макрос TAL
|
||||
public $error_msg = null;
|
||||
public $default = null;
|
||||
public $error = false;
|
||||
public $require = false;
|
||||
public $hint = null;
|
||||
// Блоки (Убрать в отдельный класс!!!)
|
||||
public $_title = array();
|
||||
public $description = "";
|
||||
public $alias = array();
|
||||
|
||||
public function __construct ($input)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ function compose() {
|
|||
*
|
||||
* @return array[int]mixed
|
||||
*/
|
||||
function rcurry() {
|
||||
function rcurry($_rest) {
|
||||
$closure = new __right(func_get_args ());
|
||||
return array($closure, 'apply');
|
||||
}
|
||||
|
|
@ -117,7 +117,7 @@ function rcurry() {
|
|||
*
|
||||
* @return array[int]mixed
|
||||
*/
|
||||
function lcurry() {
|
||||
function lcurry($_rest) {
|
||||
$closure = new __left(func_get_args ());
|
||||
return array($closure, 'apply');
|
||||
}
|
||||
|
|
@ -192,7 +192,7 @@ function __self($name, $o) {
|
|||
|
||||
function concat(/* $args ...*/) {
|
||||
$args = func_get_args();
|
||||
return implode($args);
|
||||
return implode("", $args);
|
||||
}
|
||||
|
||||
function __empty($x) {
|
||||
|
|
@ -229,6 +229,15 @@ function key_values($key, /*array|ArrayIterator*/ $array) {
|
|||
return $result;
|
||||
}
|
||||
|
||||
function key_values_object($key, /*array|ArrayIterator*/ $array) {
|
||||
$result = array();
|
||||
|
||||
foreach($array as $item) {
|
||||
$result[] = $item->{$key};
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function assoc_key_values($key, $value, $array) {
|
||||
$result = array();
|
||||
foreach ($array as $item) {
|
||||
|
|
@ -245,7 +254,7 @@ function assoc_key($key, $array) {
|
|||
return $result;
|
||||
}
|
||||
|
||||
function _get($key, $value, $array) {
|
||||
function _get($key, /*.any.*/$value, /*.array.*/$array) {
|
||||
foreach ($array as $item) {
|
||||
if ($item[$key] == $value) return $item;
|
||||
}
|
||||
|
|
@ -265,7 +274,7 @@ function _get_key($key, $value, $array) {
|
|||
* @return bool
|
||||
*/
|
||||
function every(array $array, $callback) {
|
||||
foreach ($array as $key => $value) {
|
||||
foreach ($array as $value) {
|
||||
if (call_user_func($callback, $value) === false) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -337,10 +346,33 @@ if (!function_exists('hash_key')) {
|
|||
};
|
||||
}
|
||||
|
||||
function array_merge1($x, $y) {
|
||||
$result = $x;
|
||||
foreach ($y as $k => $v) {
|
||||
$result [$k] = $v;
|
||||
/**
|
||||
* Выбирает все сроки из таблицы с уникальными значениями ключа
|
||||
* @param $name Имя ключа
|
||||
* @param $table Двухмерный массив
|
||||
* @example
|
||||
* key_unique_values ('name', array (array ('name' => 1), array ('name' => 2), array ('name' => 1)))
|
||||
=> array (1, 2)
|
||||
* @end example
|
||||
*/
|
||||
function key_unique_values ($name, $table) {
|
||||
// Ищем уникальные значения для заданного ключа
|
||||
$keys = array ();
|
||||
foreach ($table as $row) {
|
||||
if (!in_array ($row[$name], $keys))
|
||||
$keys[] = $row[$name];
|
||||
}
|
||||
return $result;
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Сортировка двумерного массива по заданному ключу
|
||||
* @param $array Массив
|
||||
* @param $key Имя ключа по значению которого будет идти сравнение
|
||||
* @return Отсортированный массив
|
||||
*/
|
||||
function sortOn($array, $key, $fn = '__cmp') {
|
||||
usort ($array, rcurry($fn, $key));
|
||||
//usort ($array, create_function ('$x,$y', 'return __cmp ($x, $y, "'.$key.'");'));
|
||||
return $array;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ class WrongRequestException extends Exception
|
|||
// HTTPRequest = ArrayAccess
|
||||
class HttpRequest extends Collection implements ArrayAccess
|
||||
{
|
||||
|
||||
public $_session;
|
||||
/**
|
||||
* Constructor
|
||||
* Stores "request data" in GPC order.
|
||||
|
|
@ -24,9 +26,8 @@ class HttpRequest extends Collection implements ArrayAccess
|
|||
|
||||
$ajax = $this->isAjax();
|
||||
foreach ($list as $key => $value) {
|
||||
$data = new SafeCollection();
|
||||
$data = new Collection();
|
||||
$data->import($value);
|
||||
|
||||
parent::set($key, $data);
|
||||
}
|
||||
|
||||
|
|
@ -35,50 +36,32 @@ class HttpRequest extends Collection implements ArrayAccess
|
|||
parent::set('files', $data);
|
||||
}
|
||||
|
||||
function get($key, $default = null)
|
||||
{
|
||||
return parent::get('data')->get($key, $default);
|
||||
}
|
||||
|
||||
function session($value = false)
|
||||
{
|
||||
if ($value) {
|
||||
$this->session = $value;
|
||||
}
|
||||
return $this->session;
|
||||
}
|
||||
|
||||
function set($key, $value)
|
||||
{
|
||||
return parent::get('data')->set($key, $value);
|
||||
}
|
||||
|
||||
|
||||
function _get($key)
|
||||
{
|
||||
return parent::get($key);
|
||||
}
|
||||
|
||||
function export()
|
||||
function get($key, $default = null)
|
||||
{
|
||||
return parent::get('data')->export();
|
||||
return parent::get('data')->get($key, $default);
|
||||
}
|
||||
|
||||
function session(Session $value = null)
|
||||
{
|
||||
if ($value) {
|
||||
$this->_session = $value;
|
||||
}
|
||||
return $this->_session;
|
||||
}
|
||||
|
||||
/* Array Acces Interface */
|
||||
function offsetExists($offset)
|
||||
function set($key, /*.any.*/$value)
|
||||
{
|
||||
return parent::get('data')->set($key, $value);
|
||||
}
|
||||
|
||||
function offsetGet($offset)
|
||||
{
|
||||
}
|
||||
|
||||
function offsetSet($offset, $value)
|
||||
{
|
||||
}
|
||||
|
||||
function offsetUnset($offset)
|
||||
function export($key = 'data')
|
||||
{
|
||||
return parent::get($key)->export();
|
||||
}
|
||||
|
||||
function clear()
|
||||
|
|
@ -125,4 +108,22 @@ class HttpRequest extends Collection implements ArrayAccess
|
|||
{
|
||||
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest');
|
||||
}
|
||||
|
||||
public function redirect($url) {
|
||||
header('location: ' . $url);
|
||||
exit();
|
||||
}
|
||||
|
||||
|
||||
public function offsetSet($key, $value) {
|
||||
}
|
||||
|
||||
public function offsetExists($key) {
|
||||
}
|
||||
|
||||
public function offsetUnset($key) {
|
||||
}
|
||||
|
||||
public function offsetGet($key) {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
<?php
|
||||
|
||||
require_once 'core/functions.php';
|
||||
require_once __DIR__ . '/../functions.php';
|
||||
// Переместить в фильтры!!
|
||||
|
||||
/**
|
||||
* Выбор макета страницы.
|
||||
* Выбор оформления страницы осуществляется если было совпадение с каким либо условием
|
||||
*/
|
||||
class LayoutManager extends Filter
|
||||
class Layout_Manager extends Filter_Filter
|
||||
{
|
||||
// Массив условий с их макетами
|
||||
protected $condition = array();
|
||||
|
|
@ -20,7 +20,7 @@ class LayoutManager extends Filter
|
|||
* addConditionGet(array('module' => 'personal'), 'personal')
|
||||
* addConditionGet(array('module' => 'login'), 'login')
|
||||
*/
|
||||
public function addConditionGet($get, Filter $layout)
|
||||
public function addConditionGet($get, Filter_Filter $layout)
|
||||
{
|
||||
$this->addCondition(rcurry(array($this, 'checkGet'), $get), $layout);
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ class LayoutManager extends Filter
|
|||
/**
|
||||
* Условие для аякс запросов. Тоже самое что и addConditionGet но еще проверяется является ли запрос ajax
|
||||
*/
|
||||
public function addConditionXHR($get, Filter $layout)
|
||||
public function addConditionXHR($get, Filter_Filter $layout)
|
||||
{
|
||||
$this->addCondition(rcurry(array($this, 'checkXHR'), $get), $layout);
|
||||
}
|
||||
|
|
@ -51,11 +51,11 @@ class LayoutManager extends Filter
|
|||
}
|
||||
|
||||
/**
|
||||
* Добавляет есловие в общем виде
|
||||
* Добавляет условие в общем виде
|
||||
* @parma $get function(HttpRequest) Функция
|
||||
* @parma $layout Layout Макет
|
||||
*/
|
||||
public function addCondition($get, Filter $layout)
|
||||
public function addCondition($get, Filter_Filter $layout)
|
||||
{
|
||||
$this->condition [] = array($get, $layout);
|
||||
}
|
||||
|
|
@ -81,13 +81,3 @@ class LayoutManager extends Filter
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Самый простой макет
|
||||
*/
|
||||
class LayoutNone extends Filter
|
||||
{
|
||||
function execute(HttpRequest $request)
|
||||
{
|
||||
return $this->processor->execute($request);
|
||||
}
|
||||
}
|
||||
11
src/layout/none.php
Normal file
11
src/layout/none.php
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
/**
|
||||
* Самый простой макет
|
||||
*/
|
||||
class Layout_None extends Filter_Filter
|
||||
{
|
||||
function execute(HttpRequest $request)
|
||||
{
|
||||
return $this->processor->execute($request);
|
||||
}
|
||||
}
|
||||
62
src/mail.php
62
src/mail.php
|
|
@ -6,14 +6,14 @@
|
|||
*/
|
||||
class Mail
|
||||
{
|
||||
public $from;
|
||||
public $to;
|
||||
public $subject;
|
||||
public $_from;
|
||||
public $_to;
|
||||
public $_subject;
|
||||
public $content;
|
||||
public $copy;
|
||||
|
||||
private $encoding;
|
||||
private $notify= false;
|
||||
private $_notify = null;
|
||||
|
||||
protected $attachment = array ();
|
||||
protected $uniqid;
|
||||
|
|
@ -22,8 +22,6 @@ class Mail
|
|||
function __construct() {
|
||||
$this->setEncoding("UTF-8");
|
||||
$this->uniqid = strtoupper(uniqid(time())); // Идентефикатор разделителя
|
||||
|
||||
// $this->mime
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -31,7 +29,7 @@ class Mail
|
|||
*/
|
||||
function from($name)
|
||||
{
|
||||
$this->from = $name;
|
||||
$this->_from = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -39,7 +37,7 @@ class Mail
|
|||
*/
|
||||
function to($name) // recipient
|
||||
{
|
||||
$this->to = $name;
|
||||
$this->_to = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -52,7 +50,7 @@ class Mail
|
|||
|
||||
function notify($notify)
|
||||
{
|
||||
$this->notify = $notify;
|
||||
$this->_notify = $notify;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -60,7 +58,7 @@ class Mail
|
|||
*/
|
||||
function subject($subject)
|
||||
{
|
||||
$this->subject = $subject;
|
||||
$this->_subject = $subject;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -70,12 +68,7 @@ class Mail
|
|||
{
|
||||
$this->content = $text;
|
||||
}
|
||||
|
||||
function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Кодировка текста в письме
|
||||
*/
|
||||
|
|
@ -93,11 +86,18 @@ class Mail
|
|||
|
||||
if(file_exists($filename)) { // assert ??
|
||||
$file = fopen($filename, "rb");
|
||||
$data = fread($file, filesize($filename));
|
||||
$this->attachment [] = ($name) ? array($data, $name) : array($data, basename($filename));
|
||||
if (is_resource($file)) {
|
||||
$data = fread($file, filesize($filename));
|
||||
$this->attachment [] = ($name) ? array($data, $name) : array($data, basename($filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавление вложения из строки с указанием имени файла
|
||||
*/
|
||||
|
|
@ -115,7 +115,7 @@ class Mail
|
|||
|
||||
/**
|
||||
* Общий формат тегов MIME
|
||||
* http://tools.ietf.org/html/rfc2045
|
||||
* @see http://tools.ietf.org/html/rfc2045
|
||||
*/
|
||||
function mimeTag($name, $value, array $args = array())
|
||||
{
|
||||
|
|
@ -127,7 +127,7 @@ class Mail
|
|||
|
||||
/**
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc2047
|
||||
* @see http://tools.ietf.org/html/rfc2047
|
||||
*/
|
||||
function encodedWord($text, $encoding = 'B')
|
||||
{
|
||||
|
|
@ -144,16 +144,16 @@ class Mail
|
|||
$message .= $this->mimeTag("Content-Transfer-Encoding", "8bit");
|
||||
$message .= PHP_EOL . $this->content . PHP_EOL . PHP_EOL;
|
||||
|
||||
/**
|
||||
/*
|
||||
* Вложения
|
||||
* http://tools.ietf.org/html/rfc2046#section-5.1.3
|
||||
*/
|
||||
foreach ($this->attachment as $value) {
|
||||
list($data, $name) = $value;
|
||||
$message .= "--" . $this->uniqid . PHP_EOL;
|
||||
$message .= $this->mimeTag("Content-Type", "application/octet-stream", array ('name' => $name));
|
||||
$message .= $this->mimeTag("Content-Type", "application/octet-stream", array ('name' => basename($name)));
|
||||
$message .= $this->mimeTag("Content-Transfer-Encoding", "base64");
|
||||
$message .= $this->mimeTag("Content-Disposition", "attachment", array ('filename' => $name));
|
||||
$message .= $this->mimeTag("Content-Disposition", "attachment", array ('filename' => basename($name)));
|
||||
$message .= PHP_EOL . chunk_split(base64_encode($data)) . PHP_EOL;
|
||||
}
|
||||
|
||||
|
|
@ -166,11 +166,11 @@ class Mail
|
|||
function getHeader()
|
||||
{
|
||||
$head = $this->mimeTag("MIME-Version", "1.0");
|
||||
$head .= $this->mimeTag("From", $this->from);
|
||||
$head .= $this->mimeTag("X-Mailer", "CIS Tool");
|
||||
$head .= $this->mimeTag("Reply-To", $this->from);
|
||||
if ($this->notify) {
|
||||
$head .= $this->mimeTag("Disposition-Notification-To", "\"" . $this->notify . "\" <" . $this->from . ">");
|
||||
$head .= $this->mimeTag("From", $this->_from);
|
||||
$head .= $this->mimeTag("X-Mailer", "CMS Tool");
|
||||
$head .= $this->mimeTag("Reply-To", $this->_from);
|
||||
if (is_string($this->_notify)) {
|
||||
$head .= $this->mimeTag("Disposition-Notification-To", "\"" . $this->_notify . "\" <" . $this->_from . ">");
|
||||
}
|
||||
$head .= $this->mimeTag("Content-Type", "multipart/mixed", array ("boundary" => $this->uniqid));
|
||||
if ($this->copy) {
|
||||
|
|
@ -182,7 +182,7 @@ class Mail
|
|||
|
||||
function getSubject()
|
||||
{
|
||||
return $this->encodedWord($this->subject);
|
||||
return $this->encodedWord($this->_subject);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -190,7 +190,7 @@ class Mail
|
|||
*/
|
||||
function eml()
|
||||
{
|
||||
return "To: " . $this->to . PHP_EOL . "Subject: {$this->getSubject()}" . PHP_EOL . $this->getHeader() . $this->getMessage();
|
||||
return "To: " . $this->_to . PHP_EOL . "Subject: {$this->getSubject()}" . PHP_EOL . $this->getHeader() . $this->getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -198,7 +198,7 @@ class Mail
|
|||
*/
|
||||
function send()
|
||||
{
|
||||
$result = mail($this->to, $this->getSubject(), $this->getMessage(), $this->getHeader());
|
||||
$result = mail($this->_to, $this->getSubject(), $this->getMessage(), $this->getHeader());
|
||||
if(! $result) {
|
||||
throw new Exception('Невозможно отправить почту');
|
||||
// require_once "core/path.php";
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**/
|
||||
class Simple_BB_Code{
|
||||
class Markup_SimpleBBCode{
|
||||
//General Tags
|
||||
var $tags = array('b' => 'strong','i' => 'em','u' => 'span style="text-decoration:underline"','quote' => 'blockquote','s' => 'span style="text-decoration: line-through"', 'list' => 'ul','\*' => 'li');
|
||||
//Tags that must be mapped to diffierent parts
|
||||
|
|
@ -38,7 +38,7 @@ class Simple_BB_Code{
|
|||
var $auto_links = true;
|
||||
//Internal Storage
|
||||
var $_code = '';
|
||||
function Simple_BB_Code($new=true,$parse=true,$links=true){
|
||||
function __construct($new=true,$parse=true,$links=true){
|
||||
$this->convert_newlines = $new;
|
||||
$this->parse_smilies = $parse;
|
||||
$this->auto_links = $links;
|
||||
|
|
@ -12,7 +12,7 @@ class Numbers
|
|||
return $i;
|
||||
}
|
||||
|
||||
static function prefix($prefix, array $array)
|
||||
static function prefix($prefix, array $array, $key = false)
|
||||
{
|
||||
$result = array();
|
||||
for ($i = 0; $i < count($array); $i++) {
|
||||
|
|
|
|||
419
src/path.php
419
src/path.php
|
|
@ -1,33 +1,58 @@
|
|||
<?php
|
||||
|
||||
/*.
|
||||
require_module 'standard';
|
||||
.*/
|
||||
|
||||
/**
|
||||
* Класс для работы с папками и путями
|
||||
* Для итерации над файлами возможно лучше использовать SPL
|
||||
*
|
||||
* @package utils
|
||||
*/
|
||||
class Path
|
||||
|
||||
class Path
|
||||
{
|
||||
const SEPARATOR = "/";
|
||||
|
||||
protected $path;
|
||||
protected $path = array();
|
||||
protected $url = array();
|
||||
protected $absolute = false;
|
||||
|
||||
public function __construct ($path)
|
||||
public function __construct($path)
|
||||
{
|
||||
assert(is_string($path));
|
||||
// assert(is_string($path));
|
||||
|
||||
$this->path = $this->fromString($path);
|
||||
$this->optimize();
|
||||
}
|
||||
$this->url = parse_url($path);
|
||||
|
||||
if (isset($this->url['path'])) {
|
||||
$path = $this->url['path'];
|
||||
// $path = preg_replace('/\/{2,}/', '/', $path);
|
||||
$this->path = self::optimize($this->fromString($path));
|
||||
}
|
||||
}
|
||||
|
||||
static function factory($path) {
|
||||
return new Path($path);
|
||||
}
|
||||
|
||||
public function getParts()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public static function normalize($pathName)
|
||||
{
|
||||
$path = new Path($pathName);
|
||||
return $path->__toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Базовое имя
|
||||
* @param $path
|
||||
* @return mixed
|
||||
*/
|
||||
public static function basename($path)
|
||||
{
|
||||
$list = preg_split('#\\\\|/#s', $path);
|
||||
return end($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает расширение файла
|
||||
*
|
||||
|
|
@ -35,13 +60,22 @@ class Path
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
static function getExtension ($fileName)
|
||||
static function getExtension($fileName)
|
||||
{
|
||||
assert(is_string($fileName));
|
||||
assert(is_string($fileName) || is_null($fileName));
|
||||
|
||||
return pathinfo($fileName, PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
static function isType($fileName, $extension)
|
||||
{
|
||||
if (is_array($extension)) {
|
||||
return in_array(pathinfo($fileName, PATHINFO_EXTENSION), $extension);
|
||||
} else {
|
||||
return (pathinfo($fileName, PATHINFO_EXTENSION) == $extension);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Полное имя файла без расширения
|
||||
*
|
||||
|
|
@ -49,7 +83,7 @@ class Path
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
static function skipExtension ($fileName)
|
||||
static function skipExtension($fileName)
|
||||
{
|
||||
assert(is_string($fileName));
|
||||
|
||||
|
|
@ -68,118 +102,13 @@ class Path
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
static function getFileName ($fileName)
|
||||
static function getFileName($fileName)
|
||||
{
|
||||
assert(is_string($fileName));
|
||||
|
||||
return pathinfo($fileName, PATHINFO_FILENAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Список файлов в директории
|
||||
*
|
||||
* @param array $allow массив расширений для файлов
|
||||
* @param array $ignore массив имен пааок которые не нужно обрабатывать
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getContent ($allow = null, $ignore = array())
|
||||
{
|
||||
$ignore = array_merge(array (".", "..", $ignore));
|
||||
return self::fileList($this->__toString(), $allow, $ignore);
|
||||
}
|
||||
|
||||
// Использовать SPL ???
|
||||
protected function fileList ($base, &$allow, &$ignore)
|
||||
{
|
||||
$result = array ();
|
||||
if ($handle = opendir($base)) {
|
||||
while (false !== ($file = readdir($handle))) {
|
||||
if (! in_array ($file, $ignore)) {
|
||||
$isDir = is_dir (Path::join ($base, $file));
|
||||
if ($isDir || ($allow == null) || in_array (self::getExtension($file), $allow)) {
|
||||
$result[] = $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function fileListAll (&$result, $base, &$allow, &$ignore)
|
||||
{
|
||||
$files = self::fileList($base, $allow, $ignore);
|
||||
foreach ($files as $name) {
|
||||
$fullname = self::join($base, $name);
|
||||
if (is_dir($fullname)) {
|
||||
self::fileListAll($result, $fullname, $allow, $ignore);
|
||||
} else {
|
||||
array_push ($result, $fullname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Список файлов в директориии и ее поддиректорий
|
||||
*
|
||||
* @param array $allow массив расширений разрешеных для файлов
|
||||
* @param array $ignore массив имен пааок которые не нужно обрабатывать
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getContentRec ($allow = null, $ignore = array())
|
||||
{
|
||||
$result = array ();
|
||||
$ignore = array_merge(array (".", ".."), $ignore);
|
||||
self::fileListAll($result, $this->__toString(), $allow, $ignore);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Рекурсивно копирует директорию
|
||||
*
|
||||
* @param string $source Папка из которой копируется
|
||||
* @param string $target Папка в которую копируется
|
||||
*/
|
||||
public static function copy ($source, $target)
|
||||
{
|
||||
if (is_dir($source)) {
|
||||
if (! file_exists($target)) mkdir ($target);
|
||||
$path = new Path($source);
|
||||
$files = $path->getContent();
|
||||
foreach ($files as $file) {
|
||||
$entry = self::join($source, $file);
|
||||
if (is_dir($entry)) {
|
||||
self::copy($entry, Path::join($target, $file));
|
||||
} else {
|
||||
copy($entry, Path::join($target, $file));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Рекурсивно удаляет директорию
|
||||
*
|
||||
* @param string $path Папка
|
||||
*/
|
||||
public static function delete ($path)
|
||||
{
|
||||
assert(is_string($path));
|
||||
|
||||
if (is_dir($path)) {
|
||||
foreach(glob($path . '/*') as $sf) {
|
||||
if (is_dir($sf) && !is_link($sf)) {
|
||||
self::delete($sf);
|
||||
} else {
|
||||
unlink($sf);
|
||||
}
|
||||
}
|
||||
rmdir($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Преобразует строку путя в массив
|
||||
|
|
@ -192,28 +121,60 @@ class Path
|
|||
{
|
||||
assert(is_string($path));
|
||||
|
||||
$list = preg_split("/[\/\\\\]/", $path);
|
||||
$list = preg_split('#\\\\|/#s', $path);
|
||||
if (isset($this->url['scheme']) && !isset($this->url['host'])) {
|
||||
$this->absolute = false;
|
||||
} else if ($list[0] == '' && count($list) > 1) {
|
||||
$this->absolute = true;
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Преобразует относительный путь в абсолютный
|
||||
*/
|
||||
public function optimize ()
|
||||
public static function optimize($path) //
|
||||
{
|
||||
$result = array(current($this->path));
|
||||
while (next($this->path) !== false) {
|
||||
$n = current ($this->path);
|
||||
$result = array();
|
||||
foreach ($path as $n) {
|
||||
switch ($n) {
|
||||
// Может быть относительным или абсолютным путем
|
||||
case "": break;
|
||||
case ".": break;
|
||||
case "..": if (count($result) > 0) array_pop($result); break;
|
||||
case "..":
|
||||
if (count($result) > 0) { array_pop($result); break; }
|
||||
default:
|
||||
array_push($result, $n);
|
||||
}
|
||||
}
|
||||
reset($this->path);
|
||||
$this->path = $result;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Сравнение двух путей на равентство
|
||||
public function equal(/*.Path.*/ $path)
|
||||
{
|
||||
if (count($this->path) == count($path->path)) {
|
||||
for ($i = 0; $i < count($this->path); $i++) {
|
||||
if ($this->path[$i] != $path->path[$i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function makeUrl($path)
|
||||
{
|
||||
return (isset($path['scheme']) ? $path['scheme'] . ':/' : '')
|
||||
. (isset($path['host']) ? ('/'
|
||||
. (isset($path['user']) ? $path['user'] . (isset($path['pass']) ? ':' . $path['pass'] : '') . '@' : '')
|
||||
. $path['host']
|
||||
. (isset($path['port']) ? ':' . $path['port'] : '')) : '')
|
||||
. $path['path']
|
||||
. (isset($path['query']) ? '?' . $path['query'] : '')
|
||||
. (isset($path['fragment']) ? '#' . $path['fragment'] : '');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -221,10 +182,11 @@ class Path
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString ()
|
||||
public function __toString()
|
||||
{
|
||||
$result = implode($this->path, self::SEPARATOR);
|
||||
return $result;
|
||||
$result = (($this->absolute) ? '/' : '') . implode(self::SEPARATOR, $this->path);
|
||||
$this->url['path'] = $result;
|
||||
return self::makeUrl($this->url);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -234,8 +196,11 @@ class Path
|
|||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isParent ($path)
|
||||
public function isParent(/*.Path.*/ $path)
|
||||
{
|
||||
if (isset($this->url['host']) && isset($path->url['host'])
|
||||
&& ($this->url['host'] != $path->url['host'])) return false;
|
||||
|
||||
if (count($path->path) > count($this->path)) {
|
||||
for ($i = 0; $i < count($this->path); $i++) {
|
||||
if ($path->path[$i] != $this->path[$i]) {
|
||||
|
|
@ -246,6 +211,12 @@ class Path
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function _isParent($path1, $path2)
|
||||
{
|
||||
$path = new Path($path1);
|
||||
return $path->isParent(new Path($path2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Находит путь относительно текущего путя
|
||||
|
|
@ -254,34 +225,97 @@ class Path
|
|||
*
|
||||
* @return string Относительный путь к файлу
|
||||
*/
|
||||
public function relPath ($name)
|
||||
public function relPath($name)
|
||||
{
|
||||
$path = new Path ($name);
|
||||
$path = new Path($name);
|
||||
unset($path->url['scheme']);
|
||||
// $this->absolute = false;
|
||||
$path->absolute = false;
|
||||
foreach ($this->path as $n) {
|
||||
array_shift($path->path);
|
||||
}
|
||||
return $path->__toString();
|
||||
}
|
||||
|
||||
public function append ($path)
|
||||
// Вычисляет относительный путь в виде строки
|
||||
static function relative($rpath, $lpath) {
|
||||
// Нужно проверять диск!!
|
||||
$self = new Path($rpath);
|
||||
$list = new Path($lpath);
|
||||
$self_path = $self->getParts();
|
||||
$list_path = $list->getParts();
|
||||
|
||||
$result = array();
|
||||
for ($i = 0; $i < count($list_path); $i++) {
|
||||
if (($i >= count($self_path)) || $list_path[$i] != $self_path[$i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for($j = $i; $j < count($list_path); $j++) {
|
||||
array_push($result, '..');
|
||||
}
|
||||
for($j = $i; $j < count($self_path); $j++) {
|
||||
array_push($result, $self_path[$j]);
|
||||
}
|
||||
return implode("/", $result);
|
||||
}
|
||||
|
||||
public function append($path)
|
||||
{
|
||||
$base = $this->__toString();
|
||||
return self::join($base, $path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Создает недастающие папки для записи файла
|
||||
*
|
||||
* @param string $dst Полное имя файла
|
||||
*
|
||||
* @return void
|
||||
* Обьединяет строки в путь соединяя необходимым разделителем
|
||||
* fixme не обрабатывает параметры урла, решение Path::join(SITE_WWW_PATH) . '?param=pampam'
|
||||
* @return string
|
||||
*/
|
||||
static function prepare ($dst)
|
||||
static function join($_rest)
|
||||
{
|
||||
$path_dst = pathinfo($dst, PATHINFO_DIRNAME);
|
||||
if (! file_exists($path_dst)) {
|
||||
mkdir($path_dst, 0700, true);
|
||||
$args = func_get_args();
|
||||
$result = array();
|
||||
$parts0 = new Path(array_shift($args));
|
||||
$result [] = $parts0->getParts();
|
||||
foreach ($args as $file) {
|
||||
$parts = new Path($file);
|
||||
$result [] = $parts->getParts();
|
||||
}
|
||||
// При обьединении ссылок можно обьеденить path, query, fragment
|
||||
$path = implode(self::SEPARATOR, call_user_func_array('array_merge', $result));
|
||||
$parts0->url['path'] = ($parts0->isAbsolute()) ? '/' . $path : $path;
|
||||
return self::makeUrl($parts0->url);
|
||||
}
|
||||
|
||||
// Проверка структуры имени файла
|
||||
static function checkName($name, $extension)
|
||||
{
|
||||
return (strlen(pathinfo($name, PATHINFO_FILENAME)) > 0) && (pathinfo($name, PATHINFO_EXTENSION) == $extension);
|
||||
}
|
||||
|
||||
static function isCharName($char)
|
||||
{
|
||||
$ch = ord($char);
|
||||
return ((($ch >= ord('a')) && ($ch <= ord('z'))) || (strpos('-._', $char) !== false) || (($ch >= ord('0')) && ($ch <= ord('9'))));
|
||||
}
|
||||
|
||||
// Проверка имени файла
|
||||
static function isName($name) {
|
||||
if (strlen(trim($name)) == 0) {
|
||||
return false;
|
||||
}
|
||||
for ($i = 0; $i < strlen($name); $i++) {
|
||||
if (!self::isCharName($name[$i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isAbsolute()
|
||||
{
|
||||
return $this->absolute;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -291,7 +325,7 @@ class Path
|
|||
*
|
||||
* @return string Новое имя файла
|
||||
*/
|
||||
static function resolveFile ($dst)
|
||||
static function resolveFile($dst)
|
||||
{
|
||||
$i = 0;
|
||||
$file = self::skipExtension($dst);
|
||||
|
|
@ -304,14 +338,93 @@ class Path
|
|||
return $temp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Список файлов в директории
|
||||
*
|
||||
* @param array $allow массив расширений для файлов
|
||||
* @param array $ignore массив имен пааок которые не нужно обрабатывать
|
||||
*
|
||||
* @returnarray
|
||||
*/
|
||||
public function getContent($allow = null, $ignore = array())
|
||||
{
|
||||
$ignore = array_merge(array(".", ".."), $ignore);
|
||||
return self::fileList($this->__toString(), $allow, $ignore);
|
||||
}
|
||||
|
||||
/**
|
||||
* Обьединяет строки в путь соединяя необходимым разделителем
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static function join ()
|
||||
* @param array $allow массив расширений разрешеных для файлов
|
||||
* @param array $ignore массив имен пааок которые не нужно обрабатывать
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getContentRec($allow = null, $ignore = array())
|
||||
{
|
||||
$args = func_get_args();
|
||||
return implode(self::SEPARATOR, $args);
|
||||
$result = array ();
|
||||
$ignore = array_merge(array (".", ".."), $ignore);
|
||||
self::fileListAll($result, $this->__toString(), $allow, $ignore);
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Использовать SPL ???
|
||||
protected static function fileList($base, &$allow, &$ignore)
|
||||
{
|
||||
if ($base == '') $base = '.';
|
||||
$result = array ();
|
||||
$handle = opendir($base);
|
||||
if (is_resource($handle)) {
|
||||
while (true) {
|
||||
$file = readdir($handle);
|
||||
if (is_string($file)) {
|
||||
if (! in_array($file, $ignore)) {
|
||||
$isDir = is_dir(Path::join($base, $file));
|
||||
if ($isDir || ($allow == null) || in_array(self::getExtension($file), $allow)) {
|
||||
$result[] = $file;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
// При обьединении ссылок можно обьеденить path, query, fragment
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected static function fileListAll(&$result, $base, &$allow, &$ignore)
|
||||
{
|
||||
$files = self::fileList($base, $allow, $ignore);
|
||||
foreach ($files as $name) {
|
||||
$fullname = self::join($base, $name);
|
||||
if (is_dir($fullname)) {
|
||||
self::fileListAll($result, $fullname, $allow, $ignore);
|
||||
} else {
|
||||
array_push($result, $fullname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Создает недастающие папки для записи файла
|
||||
*
|
||||
* @param string $dst Полное имя файла
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static function prepare($dst, $filename = true)
|
||||
{
|
||||
if ($filename) {
|
||||
$path_dst = pathinfo($dst, PATHINFO_DIRNAME);
|
||||
} else {
|
||||
$path_dst = $dst;
|
||||
}
|
||||
if (! file_exists($path_dst)) {
|
||||
mkdir($path_dst, 0777, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
///<reference path="settings.php" />
|
||||
|
||||
/**
|
||||
* http://www.patternsforphp.com/wiki/Registry
|
||||
* http://www.patternsforphp.com/wiki/Singleton
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class Session
|
|||
|
||||
function start()
|
||||
{
|
||||
session_start();
|
||||
@session_start();
|
||||
}
|
||||
|
||||
function stop()
|
||||
|
|
|
|||
|
|
@ -12,23 +12,31 @@
|
|||
class Settings extends Collection
|
||||
{
|
||||
protected $file;
|
||||
protected $format = 'php';
|
||||
|
||||
public function __construct ($file = null)
|
||||
{
|
||||
$this->format = pathinfo($file, PATHINFO_EXTENSION);
|
||||
$this->file = $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Чтение настроек из файла
|
||||
*
|
||||
* @param File $file
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function read()
|
||||
{
|
||||
if ( !file_exists ($this->file)) return false;
|
||||
if (!file_exists ($this->file)) {
|
||||
return false;
|
||||
}
|
||||
// Не include_once т.к читать настройки можно несколько раз
|
||||
include($this->file);
|
||||
$settings = array();
|
||||
if ($this->format == 'json') {
|
||||
$settings = json_decode(file_get_contents($this->file), true);
|
||||
} else {
|
||||
include ($this->file);
|
||||
}
|
||||
|
||||
if (!is_array($settings)) {
|
||||
throw new Exception($this->file);
|
||||
}
|
||||
|
|
@ -51,7 +59,9 @@ class Settings extends Collection
|
|||
// assert(count($key) == 1);
|
||||
$name = array_shift($key);
|
||||
if (is_array($value)) {
|
||||
if (! isset($data[$name])) $data[$name] = array();
|
||||
if (!isset($data[$name])) {
|
||||
$data[$name] = array();
|
||||
}
|
||||
$this->merge($data[$name], $value);
|
||||
} else {
|
||||
$data[$name] = $value;
|
||||
|
|
@ -107,7 +117,7 @@ class Settings extends Collection
|
|||
* Чтение ключа из реестра (Собирает все ключи с определенным значением во всех модулях)
|
||||
* @param $key Путь к значению ключа внутри модуля
|
||||
*/
|
||||
public function readKeyList()
|
||||
public function readKeyList($_rest)
|
||||
{
|
||||
$key = func_get_args();
|
||||
$result = array();
|
||||
|
|
@ -149,10 +159,15 @@ class Settings extends Collection
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
public function write($file = false)
|
||||
public function write($file = null)
|
||||
{
|
||||
$result = var_export ($this->data, true);
|
||||
file_put_contents (($file) ? $file : $this->file, "<?php\n\$settings = ".$result.";\n?>");
|
||||
if ($this->format == 'json') {
|
||||
$result = json_encode($this->data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||
} else {
|
||||
$result = var_export($this->data, true);
|
||||
$result = "<?php\n\$settings = ".$result.";\n?>";
|
||||
}
|
||||
file_put_contents (($file) ? $file : $this->file, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
218
src/setup.php
218
src/setup.php
|
|
@ -1,54 +1,212 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Обработка файлов для установки
|
||||
*/
|
||||
* <code>
|
||||
* $setup = new Setup('test.xml');
|
||||
* $setup->set('target', 'dst');
|
||||
* $setup->executeActions('install');
|
||||
* </code>
|
||||
*/
|
||||
class Setup
|
||||
{
|
||||
/**
|
||||
* Содержимое PHP файла
|
||||
*/
|
||||
static function fileContent($file, array $tpl)
|
||||
protected $actions = array();
|
||||
public $context = array();
|
||||
protected $file;
|
||||
protected $action;
|
||||
protected $node;
|
||||
protected $stack = array();
|
||||
|
||||
public $zip;
|
||||
public $target;
|
||||
|
||||
public function __construct($file)
|
||||
{
|
||||
ob_start();
|
||||
include $file;
|
||||
$result = ob_get_contents();
|
||||
ob_clean();
|
||||
return $result;
|
||||
$this->file = $file;
|
||||
$this->node = simplexml_load_file($file);
|
||||
|
||||
$this->target = '';
|
||||
$this->zip = new ZipArchive();
|
||||
$this->zip->open(strtr($file, array('.xml' => '.zip')));
|
||||
|
||||
|
||||
array_push($this->stack, $this->node);
|
||||
|
||||
$this->registerAction('copy', array($this, 'copyFile'));
|
||||
$this->registerAction('make-directory', array($this, 'makeDirectory'));
|
||||
$this->registerAction('make-link', array($this, 'makeLink'));
|
||||
$this->registerAction('include', array($this, 'includeFile'));
|
||||
$this->registerAction('when', array($this, 'testWhen'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Копирует файлы шаблонной директории
|
||||
* Регистрация новых действия для установки
|
||||
*/
|
||||
static function copyTemplatePath($srcPath, $dstPath, array $tpl, $tplFile = 'tpl')
|
||||
public function registerAction($name, $action)
|
||||
{
|
||||
$out = new Path($srcPath);
|
||||
$path = new Path($dstPath);
|
||||
$files = $path->getContentRec(null, array(".svn"));
|
||||
$this->actions[$name] = $action;
|
||||
}
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (Path::getExtension($file) == $tplFile) {
|
||||
// Шаблон
|
||||
$dst = $out->append($path->relPath (Path::skipExtension($file)));
|
||||
Path::prepare($dst);
|
||||
file_put_contents($dst, self::fileContent($file, $tpl));
|
||||
} else {
|
||||
// Обычный файл
|
||||
$dst = $out->append($path->relPath ($file));
|
||||
Path::prepare($dst);
|
||||
copy($file, $dst);
|
||||
}
|
||||
/**
|
||||
* Установка переменных для шаблона
|
||||
*/
|
||||
public function set($name, $value)
|
||||
{
|
||||
$this->context[$name] = $value;
|
||||
}
|
||||
|
||||
function replaceFn($matches) {
|
||||
if (isset($this->context[$matches[2]])) {
|
||||
$v = $this->context[$matches[2]];
|
||||
} else {
|
||||
$v = $matches[2];
|
||||
}
|
||||
|
||||
if ($matches[1] == '*') {
|
||||
return addslashes($v);
|
||||
}
|
||||
return $v;
|
||||
}
|
||||
|
||||
public function fileContent($file, array $tpl)
|
||||
{
|
||||
$result = $this->zip->getFromName($file);
|
||||
$result = preg_replace_callback('/\{\{\s*(\*?)(\w+)\s*\}\}/', array($this, 'replaceFn'), $result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
function callAction($name, array $attributes)
|
||||
{
|
||||
if(isset($this->actions[$name])) {
|
||||
call_user_func_array($this->actions[$name], $attributes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Заменяет переменные на их значения в строке
|
||||
*/
|
||||
function replaceVariable(array $match)
|
||||
{
|
||||
if (isset($this->context[$match[1]])) {
|
||||
return $this->context[$match[1]];
|
||||
}
|
||||
return $match[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Для всех аттрибутов заменяет переменные на их значения
|
||||
*/
|
||||
function resolve($attributes)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($attributes as $key => $value) {
|
||||
$result [$key] = preg_replace_callback("/\\\${(\w+)}/", array($this, 'replaceVariable'), $value);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Выполняет список действий если для действия не указан аттрибут when то оно выполняется всегда
|
||||
*
|
||||
* @param $action специальное действие
|
||||
*/
|
||||
function executeActions($action = "install")
|
||||
{
|
||||
$this->action = $action;
|
||||
if ($this->stack[count($this->stack) - 1] === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*.SimpleXMLElement.*/$item = $this->stack[count($this->stack) - 1];
|
||||
$root = $item->children();
|
||||
foreach ($root as $node)
|
||||
{
|
||||
$attributes = $node->attributes();
|
||||
array_push($this->stack, $node);
|
||||
$this->callAction($node->getName(), array($this->resolve($attributes)));
|
||||
array_pop($this->stack);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Копирования файла
|
||||
* @param preserve Не переписывать файл если он существует
|
||||
* @param template Файл является шаблоном подставить параметры до копирования
|
||||
* @param src Исходный файл
|
||||
* @param dst Новый файл
|
||||
*/
|
||||
public function copyFile(array $attributes)
|
||||
{
|
||||
$path = $this->targetPath($attributes['dst']);
|
||||
|
||||
if (!(file_exists($path) && isset($attributes['preserve']))) {
|
||||
file_put_contents($path, $this->fileContent($attributes['src'], $this->context));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Создает символическую ссылку на папку/файл
|
||||
* @param dst Имя папки
|
||||
*/
|
||||
public function makeLink(array $attributes)
|
||||
{
|
||||
if (function_exists('symlink')) {
|
||||
symlink($attributes['target'], $attributes['link']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Подключение файла установки
|
||||
* @param file Имя подключаемого файла
|
||||
*/
|
||||
public function includeFile(array $attributes)
|
||||
{
|
||||
$file = basename($this->file) . "/" . $attributes['file'];
|
||||
|
||||
$setup = new Setup($file);
|
||||
$setup->context = $this->context;
|
||||
$setup->executeActions();
|
||||
}
|
||||
|
||||
function targetPath($s) {
|
||||
return $this->target . '/' . $s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Создает новую папку
|
||||
* @param dst Имя папки
|
||||
*/
|
||||
public function makeDirectory(array $attributes)
|
||||
{
|
||||
$path = $this->targetPath($attributes['dst']);
|
||||
if (!file_exists($path)) {
|
||||
mkdir($path);
|
||||
}
|
||||
}
|
||||
|
||||
function testWhen(array $attributes)
|
||||
{
|
||||
if (!isset($attributes['test']) || $attributes['test'] == $this->action) {
|
||||
$this->executeActions($this->action);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Выполнение Списка SQL команд
|
||||
*/
|
||||
static function batchSQL(Connection $conn, $file)
|
||||
function batchSQLZip(/*.Database.*/ $conn, $file)
|
||||
{
|
||||
$stmtList = SQLStatementExtractor::extractFile ($file);
|
||||
$stmtList = Tools_SQLStatementExtractor::extract($this->zip->getFromName($file));
|
||||
foreach ($stmtList as $stmt) {
|
||||
$conn->executeQuery ($stmt);
|
||||
}
|
||||
}
|
||||
|
||||
static function batchSQL(/*.Database.*/ $conn, $file)
|
||||
{
|
||||
$stmtList = Utils_SQLStatementExtractor::extractFile($file);
|
||||
foreach ($stmtList as $stmt) {
|
||||
$conn->executeQuery ($stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class Shortcut
|
|||
public $list = array();
|
||||
|
||||
// Singleton pattern
|
||||
static public function getInstance ()
|
||||
static public function getInstance()
|
||||
{
|
||||
if (self::$instance == null) {
|
||||
self::$instance = new Shortcut();
|
||||
|
|
@ -24,7 +24,7 @@ class Shortcut
|
|||
*/
|
||||
public function addUrl($prefix, $path)
|
||||
{
|
||||
$this->list [$prefix] = $path;
|
||||
$this->list[$prefix] = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -38,9 +38,10 @@ class Shortcut
|
|||
/**
|
||||
* Возвращает путь по имени ярлыка
|
||||
*/
|
||||
static function getUrl ($prefix, $name = null, $name1 = false)
|
||||
static function getUrl($prefix, $name = null, $name1 = null)
|
||||
{
|
||||
$shortcut = self::getInstance();
|
||||
|
||||
$names = $shortcut->variables;
|
||||
if ($name) {
|
||||
$names['$name'] = $name;
|
||||
|
|
@ -48,10 +49,18 @@ class Shortcut
|
|||
if ($name1) {
|
||||
$names['$name1'] = $name1;
|
||||
}
|
||||
|
||||
if (isset($shortcut->list[$prefix])) {
|
||||
return strtr($shortcut->list[$prefix], $names);
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static function expand($path)
|
||||
{
|
||||
$shortcut = self::getInstance();
|
||||
$names = $shortcut->variables;
|
||||
return strtr($path, $names);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,33 +2,61 @@
|
|||
|
||||
/**
|
||||
* Расширения для PHPTAL для отображения времени и даты
|
||||
* package utils
|
||||
*/
|
||||
class DateTime_Tales implements PHPTAL_Tales
|
||||
{
|
||||
static public function date ($expression, $nothrow = false)
|
||||
static public function date($expression, $nothrow = false)
|
||||
{
|
||||
return "phptal_date(".PHPTAL_TalesInternal::path ($expression).")";
|
||||
return "phptal_date(".PHPTAL_Php_TalesInternal::path ($expression).")";
|
||||
}
|
||||
|
||||
static public function time ($expression, $nothrow = false)
|
||||
static public function time($expression, $nothrow = false)
|
||||
{
|
||||
return "phptal_time(".PHPTAL_TalesInternal::path ($expression).")";
|
||||
return "phptal_time(".PHPTAL_Php_TalesInternal::path ($expression).")";
|
||||
}
|
||||
}
|
||||
|
||||
/* Регистрация нового префикса для подключения компонента */
|
||||
$registry = PHPTAL_TalesRegistry::getInstance();
|
||||
$registry->registerPrefix('date', array('DateTime_Tales', 'date'));
|
||||
$registry->registerPrefix('time', array('DateTime_Tales', 'time'));
|
||||
|
||||
/**
|
||||
* TALES для подключения компонентов
|
||||
* component:name?param1=value1¶m2=value2
|
||||
*/
|
||||
class Component_Tales implements PHPTAL_Tales
|
||||
{
|
||||
static public function component($expression, $nothrow = false)
|
||||
{
|
||||
$s = PHPTAL_Php_TalesInternal::string($expression);
|
||||
return "phptal_component(" . $s . ")";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function phptal_date ($e)
|
||||
{
|
||||
return date ("d.m.Y", $e);
|
||||
return date("d.m.Y", $e);
|
||||
}
|
||||
|
||||
function phptal_time ($e)
|
||||
{
|
||||
return date ("H:i", $e);
|
||||
return date("H:i", $e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Функция подключения компонента
|
||||
*/
|
||||
function phptal_component ($expression) {
|
||||
global $db, $registry; // Нужно как-то передавать параметры
|
||||
|
||||
$component = Controller_Component::loadComponent($expression, $db, $registry);
|
||||
$req = new HttpRequest();
|
||||
|
||||
return $component->execute($req);
|
||||
}
|
||||
|
||||
|
||||
/* Регистрация нового префикса для подключения компонента */
|
||||
$tales = PHPTAL_TalesRegistry::getInstance();
|
||||
$tales->registerPrefix('component', array('Component_Tales', 'component'));
|
||||
$tales->registerPrefix('date', array('DateTime_Tales', 'date'));
|
||||
$tales->registerPrefix('time', array('DateTime_Tales', 'time'));
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
class Drawing
|
||||
{
|
||||
|
||||
const ALIGN_LEFT = "left";
|
||||
const ALIGN_TOP = "top";
|
||||
const ALIGN_BOTTOM = "bottom";
|
||||
|
|
@ -26,7 +25,6 @@ class Drawing
|
|||
static function imagettftextbox(&$image, $size, $angle, $left, $top, $color, $font, $text,
|
||||
$max_width, $max_height, $align, $valign)
|
||||
{
|
||||
// echo var_dump($font);
|
||||
// echo $left,"\n", $top, "\n";
|
||||
// echo $max_width,"\n", $max_height, "\n";
|
||||
// self::drawrectnagle($image, $left, $top, $max_width, $max_height, array(0xFF,0,0));
|
||||
|
|
@ -44,7 +42,6 @@ class Drawing
|
|||
$last_width = 0;
|
||||
for ($i = 0; $i < count($words); $i++) {
|
||||
$item = $words[$i];
|
||||
// echo "->", $font, "\n";
|
||||
$dimensions = imagettfbbox($size, $angle, $font, $current_line . ($first_word ? '' : ' ') . $item);
|
||||
$line_width = $dimensions[2] - $dimensions[0];
|
||||
$line_height = $dimensions[1] - $dimensions[7];
|
||||
|
|
@ -75,6 +72,7 @@ class Drawing
|
|||
}
|
||||
|
||||
// vertical align
|
||||
$top_offset = 0;
|
||||
if ($valign == self::ALIGN_CENTER) {
|
||||
$top_offset = ($max_height - $largest_line_height * count($lines)) / 2;
|
||||
} elseif ($valign == self::ALIGN_BOTTOM) {
|
||||
|
|
@ -84,17 +82,15 @@ class Drawing
|
|||
$top += $largest_line_height + $top_offset;
|
||||
|
||||
$i = 0;
|
||||
fb($lines);
|
||||
fb($line_widths);
|
||||
foreach ($lines as $line) {
|
||||
// horizontal align
|
||||
$left_offset = 0;
|
||||
if ($align == self::ALIGN_CENTER) {
|
||||
$left_offset = ($max_width - $line_widths[$i]) / 2;
|
||||
} elseif ($align == self::ALIGN_RIGHT) {
|
||||
$left_offset = ($max_width - $line_widths[$i]);
|
||||
}
|
||||
|
||||
// echo $font, "\n";
|
||||
imagettftext($image, $size, $angle, $left + $left_offset, $top + ($largest_line_height * $i), $color, $font, $line);
|
||||
$i++;
|
||||
}
|
||||
|
|
|
|||
40
src/view/composite.php
Normal file
40
src/view/composite.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
// CompositeView+PHPTAL
|
||||
class View_Composite extends View_Top
|
||||
{
|
||||
private $tal;
|
||||
|
||||
function __construct($file)
|
||||
{
|
||||
parent::__construct($file);
|
||||
|
||||
$this->tal = new PHPTAL($file);
|
||||
$this->tal->stripComments(true);
|
||||
}
|
||||
|
||||
function set($key, $val)
|
||||
{
|
||||
if ($key == 'title') {
|
||||
$this->setTitle($val);
|
||||
}
|
||||
$this->tal->set($key, $val);
|
||||
}
|
||||
|
||||
function __set($key, $val)
|
||||
{
|
||||
$this->tal->set($key, $val);
|
||||
}
|
||||
|
||||
function setTranslator($tr)
|
||||
{
|
||||
$this->tal->setTranslator($tr);
|
||||
}
|
||||
|
||||
function execute()
|
||||
{
|
||||
parent::execute();
|
||||
// postProcess
|
||||
return $this->tal->execute();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
class _View_Composite // AbstractCompositeView
|
||||
class View_Top // AbstractCompositeView
|
||||
{
|
||||
protected $_section = array(); // Вложенные шаблоны
|
||||
// Блоки
|
||||
|
|
@ -257,42 +257,3 @@ class _View_Composite // AbstractCompositeView
|
|||
}
|
||||
}
|
||||
|
||||
// CompositeView+PHPTAL
|
||||
class View_Composite extends _View_Composite
|
||||
{
|
||||
private $tal;
|
||||
|
||||
function __construct($file)
|
||||
{
|
||||
parent::__construct($file);
|
||||
|
||||
$this->tal = new PHPTAL($file);
|
||||
$this->tal->setEncoding('WINDOWS-1251'); // PHP_TAL_DEFAULT_ENCODING !!
|
||||
$this->tal->stripComments(true);
|
||||
}
|
||||
|
||||
function set($key, $val)
|
||||
{
|
||||
if ($key == 'title') {
|
||||
$this->setTitle($val);
|
||||
}
|
||||
$this->tal->set($key, $val);
|
||||
}
|
||||
|
||||
function __set($key, $val)
|
||||
{
|
||||
$this->tal->set($key, $val);
|
||||
}
|
||||
|
||||
function setTranslator($tr)
|
||||
{
|
||||
$this->tal->setTranslator($tr);
|
||||
}
|
||||
|
||||
function execute()
|
||||
{
|
||||
parent::execute();
|
||||
// postProcess
|
||||
return $this->tal->execute();
|
||||
}
|
||||
}
|
||||
|
|
@ -5,21 +5,28 @@
|
|||
*/
|
||||
class ZipFile extends ZipArchive
|
||||
{
|
||||
private $ignore = array('.', '..');
|
||||
|
||||
public function addIgnore($name)
|
||||
{
|
||||
$this->ignore [] = $name;
|
||||
}
|
||||
|
||||
private function addDirDo($location, $name)
|
||||
{
|
||||
assert(is_string($location) && is_string($name));
|
||||
|
||||
$name .= '/';
|
||||
$location .= '/';
|
||||
$file = null;
|
||||
|
||||
// Read all Files in Dir
|
||||
$dir = opendir($location);
|
||||
while (($file = readdir($dir)) !== false)
|
||||
{
|
||||
if ($file === '.' || $file === '..') continue;
|
||||
|
||||
if (in_array($file, $this->ignore)) continue;
|
||||
// Rekursiv, If dir: FlxZipArchive::addDir(), else ::File();
|
||||
$call = (is_dir($file)) ? 'addDir' : 'addFile';
|
||||
$call = (is_dir($location . $file)) ? 'addDir' : 'addFile';
|
||||
call_user_func(array($this, $call), $location . $file, $name . $file);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue