Синхронизировал частично с 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
|
<?php
|
||||||
/**
|
/**
|
||||||
* Коллекция
|
* Коллекция
|
||||||
*
|
*
|
||||||
* package core
|
|
||||||
*/
|
*/
|
||||||
class Collection implements ArrayAccess
|
class Collection implements ArrayAccess
|
||||||
{
|
{
|
||||||
|
|
@ -40,7 +39,7 @@ class Collection implements ArrayAccess
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function set($key, $value)
|
public function set(/*.string.*/$key, /*.any.*/$value)
|
||||||
{
|
{
|
||||||
$this->data[$key] = $value;
|
$this->data[$key] = $value;
|
||||||
}
|
}
|
||||||
|
|
@ -54,7 +53,7 @@ class Collection implements ArrayAccess
|
||||||
*/
|
*/
|
||||||
public function get($key, $default = null)
|
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)
|
public function getInt($key, $default = 0)
|
||||||
|
|
|
||||||
|
|
@ -1,423 +1,339 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
*
|
require_once __DIR__ . '/../functions.php';
|
||||||
* @package Core
|
|
||||||
*/
|
|
||||||
/**
|
function forceUrl($name)
|
||||||
* Переименовать контроллер !! (StubController, CrudController, PageController, BaseController) ModelController
|
|
||||||
* Возможно нужен еще класс с мета действиями как для actionIndex <= metaActionIndex либо с классам для этих действий
|
|
||||||
* Есть класс для управлениями действиями а есть сами действия в виде классов или функций !!
|
|
||||||
*/
|
|
||||||
class Controller_Model extends Controller_Action
|
|
||||||
{
|
{
|
||||||
public $schema = array();
|
if (is_callable($name)) {
|
||||||
public $schemaSearch = array();
|
return call_user_func($name);
|
||||||
|
}
|
||||||
|
return $name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIXME: Лучше $this->table->setHeader
|
* Контроллер страниц
|
||||||
*/
|
*/
|
||||||
public $tableSchema = null;
|
class Controller_Action
|
||||||
public $formSchema = array();
|
{
|
||||||
|
|
||||||
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 $path;
|
||||||
public $table;
|
|
||||||
|
|
||||||
public function __construct()
|
public function __construct ()
|
||||||
{
|
{
|
||||||
$this->path = new PathMenu();
|
//
|
||||||
$this->menu = new PageMenu();
|
|
||||||
$this->table = new ListTable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setUp ()
|
||||||
*/
|
|
||||||
function setUp()
|
|
||||||
{
|
{
|
||||||
$this->table->addMenuItem($this->aUrl('delete'), 'удалить', false, 'all', 'warning');
|
// override this
|
||||||
//$this->table->addMenuItem($this->nUrl('form'), 'редактировать', 'edit-24.png');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveParameters($args, $list)
|
public function loadConfig($name) {
|
||||||
{
|
$filename = Shortcut::getUrl('config', $name);
|
||||||
foreach ($list as $item) {
|
if (file_exists($filename)) {
|
||||||
$args->session()->set(array($this, $item), $args->get($item));
|
include($filename);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
} 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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function findIcon($icon, $size)
|
||||||
* Добавление пользователя
|
|
||||||
*/
|
|
||||||
public function actionAdd(HttpRequest $request)
|
|
||||||
{
|
{
|
||||||
require_once "core/validator/validator.php";
|
return Path::join($this->iconPath, $size . 'x' . $size, $icon . '.png');
|
||||||
// {{{ тоже может быть один 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Заголовок
|
* Создает представление
|
||||||
|
* @param string $file
|
||||||
|
* @return template
|
||||||
*/
|
*/
|
||||||
private function setTitlePath($ref)
|
public function getView($name)
|
||||||
{
|
{
|
||||||
if ($ref) {
|
$file = $name . self::TEMPLATE_EXTENSION;
|
||||||
$model = $this->getModel($this->useModel);
|
// Список возможных директорий для поиска файла шаблона
|
||||||
if (is_array($model->reference) && $model->reference[0]) {
|
$theme = $this->_registry->readKey(array('system', 'theme'));
|
||||||
$refmodel = $this->getModel($model->reference[0]);
|
$icon_theme = $this->_registry->readKey(array('system', 'icon_theme'));
|
||||||
try {
|
$list = array(
|
||||||
$parent = $refmodel->findById($ref);
|
Path::join($this->viewPath, TEMPLATES) => Path::join(WWW_PATH, "modules", $this->name, TEMPLATES),
|
||||||
$this->path->addTitle($parent->getTitle()); // Заголовок к подписям путей
|
PHPTAL_TEMPLATE_REPOSITORY => "");
|
||||||
} catch (Exception $e) {
|
|
||||||
// Не найден заголовок потому что неправильно определен родительский элемент
|
|
||||||
}
|
// Поиск файла для шаблона
|
||||||
}
|
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);
|
$tpl = new View_Composite($template);
|
||||||
$form = new TForm(); // Показываем форму
|
$tpl->icons = $this->iconPath; // Путь к файлам текущей темы
|
||||||
$form->header = 'Редактирование записи';
|
$tpl->media = $this->themePath; // Путь к файлам текущей темы
|
||||||
$this->formSetup($form, $request->get('id'), $request->get('ref')); // Инициализация формы
|
$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');
|
$tpl->loadImports(Path::skipExtension($template) . ".import");
|
||||||
$id = ($list[0]) ? $list[0] : $request->get('id');
|
|
||||||
|
|
||||||
$tpl = $this->formPage ($form, $request);
|
$this->addSuggest($tpl, $name);
|
||||||
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;
|
return $tpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getModel($name)
|
||||||
*/
|
|
||||||
function tableSetup($table, $id = null, $ref = null)
|
|
||||||
{
|
{
|
||||||
// FIXME: После замены везде $tableSchema -> table->setHeader удалить!
|
if (!$this->factory) {
|
||||||
if ($this->tableSchema) {
|
$this->factory = new ModelFactory($this->db, $this->_registry, $this->_shortcut);
|
||||||
$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);
|
|
||||||
}
|
}
|
||||||
|
return $this->factory->getModel($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Выбор действия
|
||||||
|
* Т.к действия являются методами класса то
|
||||||
|
* 1. Можно переопределить действия
|
||||||
|
* 2. Использовать наследование чтобы добавить к старому обработчику новое поведение
|
||||||
|
* @param $request Обьект запроса
|
||||||
*/
|
*/
|
||||||
public function actionIndex(HttpRequest $request)
|
public function execute1(HTTPRequest $request)
|
||||||
{
|
{
|
||||||
$this->getActionPath($request, 'index');
|
$action = self::ACTION_PREFIX . ucfirst($request->getAction());
|
||||||
// Такое мета действие наверное можно вынести в отдельный класс
|
if (method_exists($this, $action)) {
|
||||||
return $this->metaActionIndex($request, array($this, 'tableSetup'), $this->aUrl('list'));
|
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 или несколько
|
return "";
|
||||||
// {{{ история переходов
|
}
|
||||||
$ref = null;
|
|
||||||
if ($request->get('ref')) {
|
public function postUrl($name, $param)
|
||||||
$ref = $request->get('ref');
|
{
|
||||||
} else if ($request->session()->get('ref')) {
|
return "?" . http_build_query(
|
||||||
$ref = $request->session()->get('ref');
|
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);
|
public function fUrl($name, array $param = array())
|
||||||
$this->addParameter('ref', $ref);
|
{
|
||||||
// }}}
|
return forceUrl($this->nUrl($name, $param));
|
||||||
$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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Добавляет параметр для всех ссылок создаваемых функцией nUrl, aUrl
|
||||||
*/
|
*/
|
||||||
public function actionSetup($request)
|
public function addParameter($name, $value)
|
||||||
{
|
{
|
||||||
$left = explode(",", $request->get('left'));
|
if ($value) {
|
||||||
$right = explode(",", $request->get('right'));
|
$this->param [$name] = $value;
|
||||||
|
}
|
||||||
$$request->session()->set(strtolower(get_class($this)),
|
|
||||||
array('view' => array('left' => $left, 'right' => $right)));
|
|
||||||
|
|
||||||
return $this->forward('actionIndex', $request);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Генерация ссылки на действие контроллера
|
||||||
|
* Ajax определяется автоматически mode = ajax используется для смены layout
|
||||||
*/
|
*/
|
||||||
private function formPage($form, $request)
|
public function aUrl($name, array $param = array())
|
||||||
{
|
{
|
||||||
$view = $this->getView('form');
|
return $this->nUrl($name, array_merge(array('mode' => 'ajax'), $param)); // FIXME
|
||||||
$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*/)
|
* Добавление помошника контроллера
|
||||||
|
*/
|
||||||
|
public function addHelper($class)
|
||||||
{
|
{
|
||||||
require_once 'state.php';
|
$this->helpers [] = $class;
|
||||||
$this->_getActionPath()->getPath($this, ($action) ? $action : $request->getAction());
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Вызов помошников контроллера
|
||||||
|
*/
|
||||||
|
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
|
<?php
|
||||||
|
|
||||||
require_once 'core/controller/controller.php';
|
|
||||||
require_once 'core/controller/installer.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Первичный контроллер контроллер страниц
|
* Первичный контроллер контроллер страниц
|
||||||
* @package core
|
* @package core
|
||||||
*/
|
*/
|
||||||
class Controller_Front extends Controller
|
class Controller_Front extends Controller_Action
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $shortcut; // Ярлык к модулю
|
protected $shortcut; // Ярлык к модулю
|
||||||
protected $_param; // Параметр по которому выбирается модуль
|
protected $_param; // Параметр по которому выбирается модуль
|
||||||
protected $default; // Значение параметра по умолчанию
|
protected $default; // Значение параметра по умолчанию
|
||||||
protected $installer;
|
|
||||||
|
|
||||||
public function __construct(Settings $_registry, $_shortcut)
|
public function __construct(Settings $_registry, $_shortcut)
|
||||||
{
|
{
|
||||||
require_once 'core/database_pdo.php';
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$registry = $_registry;
|
$registry = $_registry;
|
||||||
$this->_registry = $_registry;
|
$this->_registry = $_registry;
|
||||||
$this->_shortcut = $_shortcut;
|
$this->_shortcut = $_shortcut;
|
||||||
|
|
||||||
$this->db = Database::getConnection($registry->readKey(array('system', 'dsn')));
|
$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)
|
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)
|
$moduleFile = Shortcut::getUrl($this->shortcut, $name); // ModuleLoader (2)
|
||||||
$module = $this->loadClass($moduleFile);
|
$module = $this->loadClass($moduleFile);
|
||||||
|
|
@ -59,10 +51,10 @@ class Controller_Front extends Controller
|
||||||
$module->db = $this->db;
|
$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));
|
$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->access->access = $this->loadSettings(Shortcut::getUrl('access', $name));
|
||||||
|
|
||||||
$module->setUp();
|
$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)
|
static function make($action)
|
||||||
{
|
{
|
||||||
return new State($action);
|
return new Controller_State($action);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addTitle($name, $url = array())
|
public function addTitle($name, $url = array())
|
||||||
|
|
@ -22,7 +22,7 @@ class Controller_State
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addState(State $state)
|
public function addState(Controller_State $state)
|
||||||
{
|
{
|
||||||
$this->states [$state->getAction()] = $state;
|
$this->states [$state->getAction()] = $state;
|
||||||
return $this;
|
return $this;
|
||||||
|
|
@ -49,7 +49,7 @@ class Controller_State
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeTitle($module)
|
function makeTitle(Controller_Action $module)
|
||||||
{
|
{
|
||||||
foreach ($this->titles as $item) {
|
foreach ($this->titles as $item) {
|
||||||
$module->path->addMenuItem($module->nUrl($this->action, $item[1]), $item[0]);
|
$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
|
<?php
|
||||||
|
|
||||||
require_once 'core/path.php';
|
|
||||||
|
|
||||||
class ActionLogger
|
class ActionLogger
|
||||||
{
|
{
|
||||||
public $before = array ();
|
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_SECRET = '@w3dsju45Msk#';
|
||||||
const SESSION_BROWSER_SIGN_KEYNAME = 'session.app.browser.sign';
|
const SESSION_BROWSER_SIGN_KEYNAME = 'session.app.browser.sign';
|
||||||
|
|
@ -20,16 +20,16 @@ class Filter_LoginFilter extends Filter_Filter
|
||||||
public function isLoggin(HttpRequest $request)
|
public function isLoggin(HttpRequest $request)
|
||||||
{
|
{
|
||||||
// Авторизация
|
// Авторизация
|
||||||
session_start();
|
// session_start();
|
||||||
$db = $this->getConnection();
|
$db = $this->getConnection();
|
||||||
UserAccess::setUp($db); // Соединение
|
Filter_UserAccess::setUp($db); // Соединение
|
||||||
switch ($request->getAction()) {
|
switch ($request->getAction()) {
|
||||||
// Авторизация по постоянному паролю
|
// Авторизация по постоянному паролю
|
||||||
case 'login':
|
case 'login':
|
||||||
$login = $request->get('login');
|
$login = $request->get('login');
|
||||||
$password = $request->get('password');
|
$password = $request->get('password');
|
||||||
|
|
||||||
$result = UserAccess::getUserByLogin($login); // Поиск по логину
|
$result = Filter_UserAccess::getUserByLogin($login); // Поиск по логину
|
||||||
if ($result) {
|
if ($result) {
|
||||||
if (md5($password) == $result->getString('password')) { // password
|
if (md5($password) == $result->getString('password')) { // password
|
||||||
$this->enter($db, $result);
|
$this->enter($db, $result);
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once 'filterbase.php';
|
|
||||||
require_once 'filterlogin.php';
|
|
||||||
|
|
||||||
// Класс должен быть в библиотеке приложения
|
// Класс должен быть в библиотеке приложения
|
||||||
class UserAccess
|
class Filter_UserAccess
|
||||||
{
|
{
|
||||||
const LIFE_TIME = 1800; // = 30min * 60sec;
|
const LIFE_TIME = 1800; // = 30min * 60sec;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,23 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Элемент формы
|
* Элемент формы
|
||||||
* @package core
|
|
||||||
*/
|
*/
|
||||||
class TField
|
class TField
|
||||||
{
|
{
|
||||||
|
public $hidden = false;
|
||||||
public $name;
|
public $name;
|
||||||
public $label; // Метка поля
|
public $label; // Метка поля
|
||||||
public $value; // Значение поля
|
public $value; // Значение поля
|
||||||
public $type; // Каждому типу элемента соответствует макрос TAL
|
public $type = ""; // Каждому типу элемента соответствует макрос TAL
|
||||||
public $error_msg = null;
|
public $error_msg = null;
|
||||||
|
public $default = null;
|
||||||
public $error = false;
|
public $error = false;
|
||||||
public $require = false;
|
public $require = false;
|
||||||
|
public $hint = null;
|
||||||
|
// Блоки (Убрать в отдельный класс!!!)
|
||||||
|
public $_title = array();
|
||||||
|
public $description = "";
|
||||||
|
public $alias = array();
|
||||||
|
|
||||||
public function __construct ($input)
|
public function __construct ($input)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ function compose() {
|
||||||
*
|
*
|
||||||
* @return array[int]mixed
|
* @return array[int]mixed
|
||||||
*/
|
*/
|
||||||
function rcurry() {
|
function rcurry($_rest) {
|
||||||
$closure = new __right(func_get_args ());
|
$closure = new __right(func_get_args ());
|
||||||
return array($closure, 'apply');
|
return array($closure, 'apply');
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +117,7 @@ function rcurry() {
|
||||||
*
|
*
|
||||||
* @return array[int]mixed
|
* @return array[int]mixed
|
||||||
*/
|
*/
|
||||||
function lcurry() {
|
function lcurry($_rest) {
|
||||||
$closure = new __left(func_get_args ());
|
$closure = new __left(func_get_args ());
|
||||||
return array($closure, 'apply');
|
return array($closure, 'apply');
|
||||||
}
|
}
|
||||||
|
|
@ -192,7 +192,7 @@ function __self($name, $o) {
|
||||||
|
|
||||||
function concat(/* $args ...*/) {
|
function concat(/* $args ...*/) {
|
||||||
$args = func_get_args();
|
$args = func_get_args();
|
||||||
return implode($args);
|
return implode("", $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
function __empty($x) {
|
function __empty($x) {
|
||||||
|
|
@ -229,6 +229,15 @@ function key_values($key, /*array|ArrayIterator*/ $array) {
|
||||||
return $result;
|
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) {
|
function assoc_key_values($key, $value, $array) {
|
||||||
$result = array();
|
$result = array();
|
||||||
foreach ($array as $item) {
|
foreach ($array as $item) {
|
||||||
|
|
@ -245,7 +254,7 @@ function assoc_key($key, $array) {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _get($key, $value, $array) {
|
function _get($key, /*.any.*/$value, /*.array.*/$array) {
|
||||||
foreach ($array as $item) {
|
foreach ($array as $item) {
|
||||||
if ($item[$key] == $value) return $item;
|
if ($item[$key] == $value) return $item;
|
||||||
}
|
}
|
||||||
|
|
@ -265,7 +274,7 @@ function _get_key($key, $value, $array) {
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function every(array $array, $callback) {
|
function every(array $array, $callback) {
|
||||||
foreach ($array as $key => $value) {
|
foreach ($array as $value) {
|
||||||
if (call_user_func($callback, $value) === false) {
|
if (call_user_func($callback, $value) === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -337,10 +346,33 @@ if (!function_exists('hash_key')) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function array_merge1($x, $y) {
|
/**
|
||||||
$result = $x;
|
* Выбирает все сроки из таблицы с уникальными значениями ключа
|
||||||
foreach ($y as $k => $v) {
|
* @param $name Имя ключа
|
||||||
$result [$k] = $v;
|
* @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
|
// HTTPRequest = ArrayAccess
|
||||||
class HttpRequest extends Collection implements ArrayAccess
|
class HttpRequest extends Collection implements ArrayAccess
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public $_session;
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* Stores "request data" in GPC order.
|
* Stores "request data" in GPC order.
|
||||||
|
|
@ -24,9 +26,8 @@ class HttpRequest extends Collection implements ArrayAccess
|
||||||
|
|
||||||
$ajax = $this->isAjax();
|
$ajax = $this->isAjax();
|
||||||
foreach ($list as $key => $value) {
|
foreach ($list as $key => $value) {
|
||||||
$data = new SafeCollection();
|
$data = new Collection();
|
||||||
$data->import($value);
|
$data->import($value);
|
||||||
|
|
||||||
parent::set($key, $data);
|
parent::set($key, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,50 +36,32 @@ class HttpRequest extends Collection implements ArrayAccess
|
||||||
parent::set('files', $data);
|
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)
|
function _get($key)
|
||||||
{
|
{
|
||||||
return parent::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 set($key, /*.any.*/$value)
|
||||||
function offsetExists($offset)
|
|
||||||
{
|
{
|
||||||
|
return parent::get('data')->set($key, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function offsetGet($offset)
|
function export($key = 'data')
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
function offsetSet($offset, $value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
function offsetUnset($offset)
|
|
||||||
{
|
{
|
||||||
|
return parent::get($key)->export();
|
||||||
}
|
}
|
||||||
|
|
||||||
function clear()
|
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');
|
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
|
<?php
|
||||||
|
|
||||||
require_once 'core/functions.php';
|
require_once __DIR__ . '/../functions.php';
|
||||||
// Переместить в фильтры!!
|
// Переместить в фильтры!!
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Выбор макета страницы.
|
* Выбор макета страницы.
|
||||||
* Выбор оформления страницы осуществляется если было совпадение с каким либо условием
|
* Выбор оформления страницы осуществляется если было совпадение с каким либо условием
|
||||||
*/
|
*/
|
||||||
class LayoutManager extends Filter
|
class Layout_Manager extends Filter_Filter
|
||||||
{
|
{
|
||||||
// Массив условий с их макетами
|
// Массив условий с их макетами
|
||||||
protected $condition = array();
|
protected $condition = array();
|
||||||
|
|
@ -20,7 +20,7 @@ class LayoutManager extends Filter
|
||||||
* addConditionGet(array('module' => 'personal'), 'personal')
|
* addConditionGet(array('module' => 'personal'), 'personal')
|
||||||
* addConditionGet(array('module' => 'login'), 'login')
|
* 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);
|
$this->addCondition(rcurry(array($this, 'checkGet'), $get), $layout);
|
||||||
}
|
}
|
||||||
|
|
@ -28,7 +28,7 @@ class LayoutManager extends Filter
|
||||||
/**
|
/**
|
||||||
* Условие для аякс запросов. Тоже самое что и addConditionGet но еще проверяется является ли запрос ajax
|
* Условие для аякс запросов. Тоже самое что и addConditionGet но еще проверяется является ли запрос ajax
|
||||||
*/
|
*/
|
||||||
public function addConditionXHR($get, Filter $layout)
|
public function addConditionXHR($get, Filter_Filter $layout)
|
||||||
{
|
{
|
||||||
$this->addCondition(rcurry(array($this, 'checkXHR'), $get), $layout);
|
$this->addCondition(rcurry(array($this, 'checkXHR'), $get), $layout);
|
||||||
}
|
}
|
||||||
|
|
@ -51,11 +51,11 @@ class LayoutManager extends Filter
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Добавляет есловие в общем виде
|
* Добавляет условие в общем виде
|
||||||
* @parma $get function(HttpRequest) Функция
|
* @parma $get function(HttpRequest) Функция
|
||||||
* @parma $layout Layout Макет
|
* @parma $layout Layout Макет
|
||||||
*/
|
*/
|
||||||
public function addCondition($get, Filter $layout)
|
public function addCondition($get, Filter_Filter $layout)
|
||||||
{
|
{
|
||||||
$this->condition [] = array($get, $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
|
class Mail
|
||||||
{
|
{
|
||||||
public $from;
|
public $_from;
|
||||||
public $to;
|
public $_to;
|
||||||
public $subject;
|
public $_subject;
|
||||||
public $content;
|
public $content;
|
||||||
public $copy;
|
public $copy;
|
||||||
|
|
||||||
private $encoding;
|
private $encoding;
|
||||||
private $notify= false;
|
private $_notify = null;
|
||||||
|
|
||||||
protected $attachment = array ();
|
protected $attachment = array ();
|
||||||
protected $uniqid;
|
protected $uniqid;
|
||||||
|
|
@ -22,8 +22,6 @@ class Mail
|
||||||
function __construct() {
|
function __construct() {
|
||||||
$this->setEncoding("UTF-8");
|
$this->setEncoding("UTF-8");
|
||||||
$this->uniqid = strtoupper(uniqid(time())); // Идентефикатор разделителя
|
$this->uniqid = strtoupper(uniqid(time())); // Идентефикатор разделителя
|
||||||
|
|
||||||
// $this->mime
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -31,7 +29,7 @@ class Mail
|
||||||
*/
|
*/
|
||||||
function from($name)
|
function from($name)
|
||||||
{
|
{
|
||||||
$this->from = $name;
|
$this->_from = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -39,7 +37,7 @@ class Mail
|
||||||
*/
|
*/
|
||||||
function to($name) // recipient
|
function to($name) // recipient
|
||||||
{
|
{
|
||||||
$this->to = $name;
|
$this->_to = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -52,7 +50,7 @@ class Mail
|
||||||
|
|
||||||
function notify($notify)
|
function notify($notify)
|
||||||
{
|
{
|
||||||
$this->notify = $notify;
|
$this->_notify = $notify;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -60,7 +58,7 @@ class Mail
|
||||||
*/
|
*/
|
||||||
function subject($subject)
|
function subject($subject)
|
||||||
{
|
{
|
||||||
$this->subject = $subject;
|
$this->_subject = $subject;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -70,12 +68,7 @@ class Mail
|
||||||
{
|
{
|
||||||
$this->content = $text;
|
$this->content = $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setType($type)
|
|
||||||
{
|
|
||||||
$this->type = $type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Кодировка текста в письме
|
* Кодировка текста в письме
|
||||||
*/
|
*/
|
||||||
|
|
@ -93,11 +86,18 @@ class Mail
|
||||||
|
|
||||||
if(file_exists($filename)) { // assert ??
|
if(file_exists($filename)) { // assert ??
|
||||||
$file = fopen($filename, "rb");
|
$file = fopen($filename, "rb");
|
||||||
$data = fread($file, filesize($filename));
|
if (is_resource($file)) {
|
||||||
$this->attachment [] = ($name) ? array($data, $name) : array($data, basename($filename));
|
$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
|
* Общий формат тегов MIME
|
||||||
* http://tools.ietf.org/html/rfc2045
|
* @see http://tools.ietf.org/html/rfc2045
|
||||||
*/
|
*/
|
||||||
function mimeTag($name, $value, array $args = array())
|
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')
|
function encodedWord($text, $encoding = 'B')
|
||||||
{
|
{
|
||||||
|
|
@ -144,16 +144,16 @@ class Mail
|
||||||
$message .= $this->mimeTag("Content-Transfer-Encoding", "8bit");
|
$message .= $this->mimeTag("Content-Transfer-Encoding", "8bit");
|
||||||
$message .= PHP_EOL . $this->content . PHP_EOL . PHP_EOL;
|
$message .= PHP_EOL . $this->content . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Вложения
|
* Вложения
|
||||||
* http://tools.ietf.org/html/rfc2046#section-5.1.3
|
* http://tools.ietf.org/html/rfc2046#section-5.1.3
|
||||||
*/
|
*/
|
||||||
foreach ($this->attachment as $value) {
|
foreach ($this->attachment as $value) {
|
||||||
list($data, $name) = $value;
|
list($data, $name) = $value;
|
||||||
$message .= "--" . $this->uniqid . PHP_EOL;
|
$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-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;
|
$message .= PHP_EOL . chunk_split(base64_encode($data)) . PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,11 +166,11 @@ class Mail
|
||||||
function getHeader()
|
function getHeader()
|
||||||
{
|
{
|
||||||
$head = $this->mimeTag("MIME-Version", "1.0");
|
$head = $this->mimeTag("MIME-Version", "1.0");
|
||||||
$head .= $this->mimeTag("From", $this->from);
|
$head .= $this->mimeTag("From", $this->_from);
|
||||||
$head .= $this->mimeTag("X-Mailer", "CIS Tool");
|
$head .= $this->mimeTag("X-Mailer", "CMS Tool");
|
||||||
$head .= $this->mimeTag("Reply-To", $this->from);
|
$head .= $this->mimeTag("Reply-To", $this->_from);
|
||||||
if ($this->notify) {
|
if (is_string($this->_notify)) {
|
||||||
$head .= $this->mimeTag("Disposition-Notification-To", "\"" . $this->notify . "\" <" . $this->from . ">");
|
$head .= $this->mimeTag("Disposition-Notification-To", "\"" . $this->_notify . "\" <" . $this->_from . ">");
|
||||||
}
|
}
|
||||||
$head .= $this->mimeTag("Content-Type", "multipart/mixed", array ("boundary" => $this->uniqid));
|
$head .= $this->mimeTag("Content-Type", "multipart/mixed", array ("boundary" => $this->uniqid));
|
||||||
if ($this->copy) {
|
if ($this->copy) {
|
||||||
|
|
@ -182,7 +182,7 @@ class Mail
|
||||||
|
|
||||||
function getSubject()
|
function getSubject()
|
||||||
{
|
{
|
||||||
return $this->encodedWord($this->subject);
|
return $this->encodedWord($this->_subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -190,7 +190,7 @@ class Mail
|
||||||
*/
|
*/
|
||||||
function eml()
|
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()
|
function send()
|
||||||
{
|
{
|
||||||
$result = mail($this->to, $this->getSubject(), $this->getMessage(), $this->getHeader());
|
$result = mail($this->_to, $this->getSubject(), $this->getMessage(), $this->getHeader());
|
||||||
if(! $result) {
|
if(! $result) {
|
||||||
throw new Exception('Невозможно отправить почту');
|
throw new Exception('Невозможно отправить почту');
|
||||||
// require_once "core/path.php";
|
// 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
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
**/
|
**/
|
||||||
class Simple_BB_Code{
|
class Markup_SimpleBBCode{
|
||||||
//General Tags
|
//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');
|
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
|
//Tags that must be mapped to diffierent parts
|
||||||
|
|
@ -38,7 +38,7 @@ class Simple_BB_Code{
|
||||||
var $auto_links = true;
|
var $auto_links = true;
|
||||||
//Internal Storage
|
//Internal Storage
|
||||||
var $_code = '';
|
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->convert_newlines = $new;
|
||||||
$this->parse_smilies = $parse;
|
$this->parse_smilies = $parse;
|
||||||
$this->auto_links = $links;
|
$this->auto_links = $links;
|
||||||
|
|
@ -12,7 +12,7 @@ class Numbers
|
||||||
return $i;
|
return $i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function prefix($prefix, array $array)
|
static function prefix($prefix, array $array, $key = false)
|
||||||
{
|
{
|
||||||
$result = array();
|
$result = array();
|
||||||
for ($i = 0; $i < count($array); $i++) {
|
for ($i = 0; $i < count($array); $i++) {
|
||||||
|
|
|
||||||
419
src/path.php
419
src/path.php
|
|
@ -1,33 +1,58 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*.
|
|
||||||
require_module 'standard';
|
|
||||||
.*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Класс для работы с папками и путями
|
* Класс для работы с папками и путями
|
||||||
* Для итерации над файлами возможно лучше использовать SPL
|
* Для итерации над файлами возможно лучше использовать SPL
|
||||||
*
|
*
|
||||||
* @package utils
|
|
||||||
*/
|
*/
|
||||||
class Path
|
|
||||||
|
class Path
|
||||||
{
|
{
|
||||||
const SEPARATOR = "/";
|
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->url = parse_url($path);
|
||||||
$this->optimize();
|
|
||||||
}
|
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) {
|
static function factory($path) {
|
||||||
return new Path($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
|
* @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);
|
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
|
* @return string
|
||||||
*/
|
*/
|
||||||
static function skipExtension ($fileName)
|
static function skipExtension($fileName)
|
||||||
{
|
{
|
||||||
assert(is_string($fileName));
|
assert(is_string($fileName));
|
||||||
|
|
||||||
|
|
@ -68,118 +102,13 @@ class Path
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
static function getFileName ($fileName)
|
static function getFileName($fileName)
|
||||||
{
|
{
|
||||||
assert(is_string($fileName));
|
assert(is_string($fileName));
|
||||||
|
|
||||||
return pathinfo($fileName, PATHINFO_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));
|
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;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Преобразует относительный путь в абсолютный
|
* Преобразует относительный путь в абсолютный
|
||||||
*/
|
*/
|
||||||
public function optimize ()
|
public static function optimize($path) //
|
||||||
{
|
{
|
||||||
$result = array(current($this->path));
|
$result = array();
|
||||||
while (next($this->path) !== false) {
|
foreach ($path as $n) {
|
||||||
$n = current ($this->path);
|
|
||||||
switch ($n) {
|
switch ($n) {
|
||||||
|
// Может быть относительным или абсолютным путем
|
||||||
case "": break;
|
case "": break;
|
||||||
case ".": break;
|
case ".": break;
|
||||||
case "..": if (count($result) > 0) array_pop($result); break;
|
case "..":
|
||||||
|
if (count($result) > 0) { array_pop($result); break; }
|
||||||
default:
|
default:
|
||||||
array_push($result, $n);
|
array_push($result, $n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reset($this->path);
|
return $result;
|
||||||
$this->path = $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
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function __toString ()
|
public function __toString()
|
||||||
{
|
{
|
||||||
$result = implode($this->path, self::SEPARATOR);
|
$result = (($this->absolute) ? '/' : '') . implode(self::SEPARATOR, $this->path);
|
||||||
return $result;
|
$this->url['path'] = $result;
|
||||||
|
return self::makeUrl($this->url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -234,8 +196,11 @@ class Path
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @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)) {
|
if (count($path->path) > count($this->path)) {
|
||||||
for ($i = 0; $i < count($this->path); $i++) {
|
for ($i = 0; $i < count($this->path); $i++) {
|
||||||
if ($path->path[$i] != $this->path[$i]) {
|
if ($path->path[$i] != $this->path[$i]) {
|
||||||
|
|
@ -246,6 +211,12 @@ class Path
|
||||||
}
|
}
|
||||||
return false;
|
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 Относительный путь к файлу
|
* @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) {
|
foreach ($this->path as $n) {
|
||||||
array_shift($path->path);
|
array_shift($path->path);
|
||||||
}
|
}
|
||||||
return $path->__toString();
|
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();
|
$base = $this->__toString();
|
||||||
return self::join($base, $path);
|
return self::join($base, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Создает недастающие папки для записи файла
|
* Обьединяет строки в путь соединяя необходимым разделителем
|
||||||
*
|
* fixme не обрабатывает параметры урла, решение Path::join(SITE_WWW_PATH) . '?param=pampam'
|
||||||
* @param string $dst Полное имя файла
|
* @return string
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
static function prepare ($dst)
|
static function join($_rest)
|
||||||
{
|
{
|
||||||
$path_dst = pathinfo($dst, PATHINFO_DIRNAME);
|
$args = func_get_args();
|
||||||
if (! file_exists($path_dst)) {
|
$result = array();
|
||||||
mkdir($path_dst, 0700, true);
|
$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 Новое имя файла
|
* @return string Новое имя файла
|
||||||
*/
|
*/
|
||||||
static function resolveFile ($dst)
|
static function resolveFile($dst)
|
||||||
{
|
{
|
||||||
$i = 0;
|
$i = 0;
|
||||||
$file = self::skipExtension($dst);
|
$file = self::skipExtension($dst);
|
||||||
|
|
@ -304,14 +338,93 @@ class Path
|
||||||
return $temp;
|
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
|
* @param array $allow массив расширений разрешеных для файлов
|
||||||
*/
|
* @param array $ignore массив имен пааок которые не нужно обрабатывать
|
||||||
static function join ()
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function getContentRec($allow = null, $ignore = array())
|
||||||
{
|
{
|
||||||
$args = func_get_args();
|
$result = array ();
|
||||||
return implode(self::SEPARATOR, $args);
|
$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
|
<?php
|
||||||
|
|
||||||
|
///<reference path="settings.php" />
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* http://www.patternsforphp.com/wiki/Registry
|
* http://www.patternsforphp.com/wiki/Registry
|
||||||
* http://www.patternsforphp.com/wiki/Singleton
|
* http://www.patternsforphp.com/wiki/Singleton
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ class Session
|
||||||
|
|
||||||
function start()
|
function start()
|
||||||
{
|
{
|
||||||
session_start();
|
@session_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
function stop()
|
function stop()
|
||||||
|
|
|
||||||
|
|
@ -12,23 +12,31 @@
|
||||||
class Settings extends Collection
|
class Settings extends Collection
|
||||||
{
|
{
|
||||||
protected $file;
|
protected $file;
|
||||||
|
protected $format = 'php';
|
||||||
|
|
||||||
public function __construct ($file = null)
|
public function __construct ($file = null)
|
||||||
{
|
{
|
||||||
|
$this->format = pathinfo($file, PATHINFO_EXTENSION);
|
||||||
$this->file = $file;
|
$this->file = $file;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Чтение настроек из файла
|
* Чтение настроек из файла
|
||||||
*
|
|
||||||
* @param File $file
|
|
||||||
*
|
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
*/
|
*/
|
||||||
public function read()
|
public function read()
|
||||||
{
|
{
|
||||||
if ( !file_exists ($this->file)) return false;
|
if (!file_exists ($this->file)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Не include_once т.к читать настройки можно несколько раз
|
// Не 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)) {
|
if (!is_array($settings)) {
|
||||||
throw new Exception($this->file);
|
throw new Exception($this->file);
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +59,9 @@ class Settings extends Collection
|
||||||
// assert(count($key) == 1);
|
// assert(count($key) == 1);
|
||||||
$name = array_shift($key);
|
$name = array_shift($key);
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
if (! isset($data[$name])) $data[$name] = array();
|
if (!isset($data[$name])) {
|
||||||
|
$data[$name] = array();
|
||||||
|
}
|
||||||
$this->merge($data[$name], $value);
|
$this->merge($data[$name], $value);
|
||||||
} else {
|
} else {
|
||||||
$data[$name] = $value;
|
$data[$name] = $value;
|
||||||
|
|
@ -107,7 +117,7 @@ class Settings extends Collection
|
||||||
* Чтение ключа из реестра (Собирает все ключи с определенным значением во всех модулях)
|
* Чтение ключа из реестра (Собирает все ключи с определенным значением во всех модулях)
|
||||||
* @param $key Путь к значению ключа внутри модуля
|
* @param $key Путь к значению ключа внутри модуля
|
||||||
*/
|
*/
|
||||||
public function readKeyList()
|
public function readKeyList($_rest)
|
||||||
{
|
{
|
||||||
$key = func_get_args();
|
$key = func_get_args();
|
||||||
$result = array();
|
$result = array();
|
||||||
|
|
@ -149,10 +159,15 @@ class Settings extends Collection
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function write($file = false)
|
public function write($file = null)
|
||||||
{
|
{
|
||||||
$result = var_export ($this->data, true);
|
if ($this->format == 'json') {
|
||||||
file_put_contents (($file) ? $file : $this->file, "<?php\n\$settings = ".$result.";\n?>");
|
$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
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Обработка файлов для установки
|
* <code>
|
||||||
*/
|
* $setup = new Setup('test.xml');
|
||||||
|
* $setup->set('target', 'dst');
|
||||||
|
* $setup->executeActions('install');
|
||||||
|
* </code>
|
||||||
|
*/
|
||||||
class Setup
|
class Setup
|
||||||
{
|
{
|
||||||
/**
|
protected $actions = array();
|
||||||
* Содержимое PHP файла
|
public $context = array();
|
||||||
*/
|
protected $file;
|
||||||
static function fileContent($file, array $tpl)
|
protected $action;
|
||||||
|
protected $node;
|
||||||
|
protected $stack = array();
|
||||||
|
|
||||||
|
public $zip;
|
||||||
|
public $target;
|
||||||
|
|
||||||
|
public function __construct($file)
|
||||||
{
|
{
|
||||||
ob_start();
|
$this->file = $file;
|
||||||
include $file;
|
$this->node = simplexml_load_file($file);
|
||||||
$result = ob_get_contents();
|
|
||||||
ob_clean();
|
$this->target = '';
|
||||||
return $result;
|
$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);
|
$this->actions[$name] = $action;
|
||||||
$path = new Path($dstPath);
|
}
|
||||||
$files = $path->getContentRec(null, array(".svn"));
|
|
||||||
|
|
||||||
foreach ($files as $file) {
|
/**
|
||||||
if (Path::getExtension($file) == $tplFile) {
|
* Установка переменных для шаблона
|
||||||
// Шаблон
|
*/
|
||||||
$dst = $out->append($path->relPath (Path::skipExtension($file)));
|
public function set($name, $value)
|
||||||
Path::prepare($dst);
|
{
|
||||||
file_put_contents($dst, self::fileContent($file, $tpl));
|
$this->context[$name] = $value;
|
||||||
} else {
|
}
|
||||||
// Обычный файл
|
|
||||||
$dst = $out->append($path->relPath ($file));
|
function replaceFn($matches) {
|
||||||
Path::prepare($dst);
|
if (isset($this->context[$matches[2]])) {
|
||||||
copy($file, $dst);
|
$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 команд
|
* Выполнение Списка 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) {
|
foreach ($stmtList as $stmt) {
|
||||||
$conn->executeQuery ($stmt);
|
$conn->executeQuery ($stmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ class Shortcut
|
||||||
public $list = array();
|
public $list = array();
|
||||||
|
|
||||||
// Singleton pattern
|
// Singleton pattern
|
||||||
static public function getInstance ()
|
static public function getInstance()
|
||||||
{
|
{
|
||||||
if (self::$instance == null) {
|
if (self::$instance == null) {
|
||||||
self::$instance = new Shortcut();
|
self::$instance = new Shortcut();
|
||||||
|
|
@ -24,7 +24,7 @@ class Shortcut
|
||||||
*/
|
*/
|
||||||
public function addUrl($prefix, $path)
|
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();
|
$shortcut = self::getInstance();
|
||||||
|
|
||||||
$names = $shortcut->variables;
|
$names = $shortcut->variables;
|
||||||
if ($name) {
|
if ($name) {
|
||||||
$names['$name'] = $name;
|
$names['$name'] = $name;
|
||||||
|
|
@ -48,10 +49,18 @@ class Shortcut
|
||||||
if ($name1) {
|
if ($name1) {
|
||||||
$names['$name1'] = $name1;
|
$names['$name1'] = $name1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($shortcut->list[$prefix])) {
|
if (isset($shortcut->list[$prefix])) {
|
||||||
return strtr($shortcut->list[$prefix], $names);
|
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 для отображения времени и даты
|
* Расширения для PHPTAL для отображения времени и даты
|
||||||
* package utils
|
|
||||||
*/
|
*/
|
||||||
class DateTime_Tales implements PHPTAL_Tales
|
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'));
|
* TALES для подключения компонентов
|
||||||
$registry->registerPrefix('time', array('DateTime_Tales', 'time'));
|
* 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)
|
function phptal_date ($e)
|
||||||
{
|
{
|
||||||
return date ("d.m.Y", $e);
|
return date("d.m.Y", $e);
|
||||||
}
|
}
|
||||||
|
|
||||||
function phptal_time ($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
|
class Drawing
|
||||||
{
|
{
|
||||||
|
|
||||||
const ALIGN_LEFT = "left";
|
const ALIGN_LEFT = "left";
|
||||||
const ALIGN_TOP = "top";
|
const ALIGN_TOP = "top";
|
||||||
const ALIGN_BOTTOM = "bottom";
|
const ALIGN_BOTTOM = "bottom";
|
||||||
|
|
@ -26,7 +25,6 @@ class Drawing
|
||||||
static function imagettftextbox(&$image, $size, $angle, $left, $top, $color, $font, $text,
|
static function imagettftextbox(&$image, $size, $angle, $left, $top, $color, $font, $text,
|
||||||
$max_width, $max_height, $align, $valign)
|
$max_width, $max_height, $align, $valign)
|
||||||
{
|
{
|
||||||
// echo var_dump($font);
|
|
||||||
// echo $left,"\n", $top, "\n";
|
// echo $left,"\n", $top, "\n";
|
||||||
// echo $max_width,"\n", $max_height, "\n";
|
// echo $max_width,"\n", $max_height, "\n";
|
||||||
// self::drawrectnagle($image, $left, $top, $max_width, $max_height, array(0xFF,0,0));
|
// self::drawrectnagle($image, $left, $top, $max_width, $max_height, array(0xFF,0,0));
|
||||||
|
|
@ -44,7 +42,6 @@ class Drawing
|
||||||
$last_width = 0;
|
$last_width = 0;
|
||||||
for ($i = 0; $i < count($words); $i++) {
|
for ($i = 0; $i < count($words); $i++) {
|
||||||
$item = $words[$i];
|
$item = $words[$i];
|
||||||
// echo "->", $font, "\n";
|
|
||||||
$dimensions = imagettfbbox($size, $angle, $font, $current_line . ($first_word ? '' : ' ') . $item);
|
$dimensions = imagettfbbox($size, $angle, $font, $current_line . ($first_word ? '' : ' ') . $item);
|
||||||
$line_width = $dimensions[2] - $dimensions[0];
|
$line_width = $dimensions[2] - $dimensions[0];
|
||||||
$line_height = $dimensions[1] - $dimensions[7];
|
$line_height = $dimensions[1] - $dimensions[7];
|
||||||
|
|
@ -75,6 +72,7 @@ class Drawing
|
||||||
}
|
}
|
||||||
|
|
||||||
// vertical align
|
// vertical align
|
||||||
|
$top_offset = 0;
|
||||||
if ($valign == self::ALIGN_CENTER) {
|
if ($valign == self::ALIGN_CENTER) {
|
||||||
$top_offset = ($max_height - $largest_line_height * count($lines)) / 2;
|
$top_offset = ($max_height - $largest_line_height * count($lines)) / 2;
|
||||||
} elseif ($valign == self::ALIGN_BOTTOM) {
|
} elseif ($valign == self::ALIGN_BOTTOM) {
|
||||||
|
|
@ -84,17 +82,15 @@ class Drawing
|
||||||
$top += $largest_line_height + $top_offset;
|
$top += $largest_line_height + $top_offset;
|
||||||
|
|
||||||
$i = 0;
|
$i = 0;
|
||||||
fb($lines);
|
|
||||||
fb($line_widths);
|
|
||||||
foreach ($lines as $line) {
|
foreach ($lines as $line) {
|
||||||
// horizontal align
|
// horizontal align
|
||||||
|
$left_offset = 0;
|
||||||
if ($align == self::ALIGN_CENTER) {
|
if ($align == self::ALIGN_CENTER) {
|
||||||
$left_offset = ($max_width - $line_widths[$i]) / 2;
|
$left_offset = ($max_width - $line_widths[$i]) / 2;
|
||||||
} elseif ($align == self::ALIGN_RIGHT) {
|
} elseif ($align == self::ALIGN_RIGHT) {
|
||||||
$left_offset = ($max_width - $line_widths[$i]);
|
$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);
|
imagettftext($image, $size, $angle, $left + $left_offset, $top + ($largest_line_height * $i), $color, $font, $line);
|
||||||
$i++;
|
$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
|
<?php
|
||||||
|
|
||||||
class _View_Composite // AbstractCompositeView
|
class View_Top // AbstractCompositeView
|
||||||
{
|
{
|
||||||
protected $_section = array(); // Вложенные шаблоны
|
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
|
class ZipFile extends ZipArchive
|
||||||
{
|
{
|
||||||
|
private $ignore = array('.', '..');
|
||||||
|
|
||||||
|
public function addIgnore($name)
|
||||||
|
{
|
||||||
|
$this->ignore [] = $name;
|
||||||
|
}
|
||||||
|
|
||||||
private function addDirDo($location, $name)
|
private function addDirDo($location, $name)
|
||||||
{
|
{
|
||||||
assert(is_string($location) && is_string($name));
|
assert(is_string($location) && is_string($name));
|
||||||
|
|
||||||
$name .= '/';
|
$name .= '/';
|
||||||
$location .= '/';
|
$location .= '/';
|
||||||
|
$file = null;
|
||||||
|
|
||||||
// Read all Files in Dir
|
// Read all Files in Dir
|
||||||
$dir = opendir($location);
|
$dir = opendir($location);
|
||||||
while (($file = readdir($dir)) !== false)
|
while (($file = readdir($dir)) !== false)
|
||||||
{
|
{
|
||||||
if ($file === '.' || $file === '..') continue;
|
if (in_array($file, $this->ignore)) continue;
|
||||||
|
|
||||||
// Rekursiv, If dir: FlxZipArchive::addDir(), else ::File();
|
// 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);
|
call_user_func(array($this, $call), $location . $file, $name . $file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue