diff --git a/src/Controller/Action.php b/src/Controller/Action.php
index 6e51caa..4ddeb58 100644
--- a/src/Controller/Action.php
+++ b/src/Controller/Action.php
@@ -13,7 +13,7 @@ function forceUrl($name)
/**
* Контроллер страниц
- */
+ */
class Controller_Action
{
@@ -24,9 +24,16 @@ class Controller_Action
public $themePath; // Глобальный путь к текущей теме
// Параметры устанавливаются при создании контроллера
- public $name; // Имя модуля
- public $viewPath = null; // Путь к шаблонам контроллера
- public /*.Database.*/$db; // Соединение с базой данных
+ public $name = ''; // Имя модуля
+ public $viewPath = null; // Путь к шаблонам контроллера
+ public $viewPathPrefix = null; // Путь к шаблонам контроллера
+
+ public $moduleTitle = "";
+
+ /**
+ * Соединение с базой данных
+ */
+ public $db;
// Фильтры
public $access = null; // Обьект хранит параметры доступа
@@ -42,14 +49,11 @@ class Controller_Action
public $iconPath = '';
public $path;
- public function __construct ()
- {
- //
+ public function __construct () {
+ $this->path = new Widgets_PathMenu();
}
- public function setUp ()
- {
- // override this
+ public function setUp() {
}
public function loadConfig($name) {
@@ -69,15 +73,16 @@ class Controller_Action
public function installPath($name)
{
- return Path::join(CMS_PATH, "modules", $name, "install");
+ return Path::join(CMS_PATH, "modules", $name);
}
- public function addSuggest($view, $name)
+ public function addSuggest(View_View $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");
+ if (file_exists($file)) {
+ include($file);
+ $view->suggestions = $suggest;
}
}
@@ -85,39 +90,43 @@ class Controller_Action
{
return Path::join($this->iconPath, $size . 'x' . $size, $icon . '.png');
}
-
+
/**
* Создает представление
- * @param string $file
- * @return template
+ * @param $name String
+ * @param $viewClass String
+ * @return View_Composite
*/
- public function getView($name)
+ public function getView($name, $viewClass = 'View_Composite')
{
- $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 => "");
+ $file = $name . self::TEMPLATE_EXTENSION;
+ $list = array(
+ Path::join($this->viewPath, TEMPLATES, $this->viewPathPrefix) => Path::join(WWW_PATH, "modules", $this->name, TEMPLATES, $this->viewPathPrefix),
+ Path::join(CMS_PATH, "templates") => Path::join(WWW_PATH, "templates")
+ );
// Поиск файла для шаблона
foreach($list as $ospath => $path) {
- $template = Path::join($ospath, $file);
+ $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; // Путь к файлам текущего шаблона
+ /*.View_Composite.*/$tpl = new $viewClass($template);
+
+ $tpl->set('icons', $this->iconPath); // Путь к файлам текущей темы
+ $tpl->set('media', $this->themePath); // Путь к файлам текущей темы
+ $tpl->set('assets', Path::join(WWW_PATH, "assets", "css"));
+ $tpl->set('script', $this->jsPath); // Путь к файлам скриптов
+ $tpl->set('template', $path); // Путь к файлам текущего шаблона
+
$tpl->setAlias(array(
- '${icons}' => $this->iconPath,
- '${media}' => $this->themePath,
- '${script}' => $this->jsPath,
- '${template}' => $path));
+ 'icons' => $this->iconPath,
+ 'script' => $this->jsPath,
+ // Для media и template поиск происходит как для файлов шаблонов
+ 'media' => $list,
+ 'template' => $list
+ ));
$tpl->loadImports(Path::skipExtension($template) . ".import");
@@ -128,7 +137,7 @@ class Controller_Action
public function getModel($name)
{
if (!$this->factory) {
- $this->factory = new ModelFactory($this->db, $this->_registry, $this->_shortcut);
+ $this->factory = new Model_Factory($this->db, $this->_registry);
}
return $this->factory->getModel($name);
}
@@ -143,57 +152,59 @@ class Controller_Action
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);
+ if (!method_exists($this, $action)) {
+ $action = "actionIndex";
}
+ $view = $this->forward($action, $request);
+ if ($view instanceof View_View) {
+ $view->active_module = get_class($this);
+ $view->module_action = $action;
+ }
+ return $view;
}
public function execute(HttpRequest $request)
{
$result = $this->execute1($request);
- if ($result) {
+ if (!empty($result)) {
$this->view = $result;
}
- return $this->render();
+ $text = $this->render();
+ return $text;
}
- 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 forward($action, HttpRequest $args) {
+ $value = call_user_func(array($this, $action), $args);
+ return $value;
}
/**
* Страница по умолчанию
*/
- public function actionIndex(HttpRequest $request)
- {
+ 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));
+ $uri = array_merge(array('module' =>
+ strtr($this->modulePrefix . strtolower(get_class($this)), array('module_' => '')), "action" => $name),
+ $this->param, $param);
+
+ return "?" . http_build_query($uri);
}
/**
* Генерация ссылки c учетом прав пользователя на ссылки
- *
- * @parma string $name Действие
- * @parma string $param Дополнительные параметры
+ * @param string $name Действие
+ * @param array $param Дополнительные параметры
+ * 'mode' означает что элемент до отправки обрабатывается javascript
+ * @return array|null
*/
public function nUrl($name, array $param = array())
{
- if (!$this->access || $this->access->checkAction($name)) {
+ /*.Filter_ActionAccess.*/$access = $this->access;
+ if ($access != null || $access->checkAction($name)) {
return lcurry(array($this, 'postUrl'), $name, $param);
}
return null;
@@ -217,6 +228,12 @@ class Controller_Action
/**
* Генерация ссылки на действие контроллера
* Ajax определяется автоматически mode = ajax используется для смены layout
+ * @param $name
+ * @param array $param
+ * @return array|null
+ *
+ * @example ?action=$name&mode=ajax
+ * {$param[i].key = $param[i].value}
*/
public function aUrl($name, array $param = array())
{
@@ -249,14 +266,14 @@ class Controller_Action
/**
* Загрузка файла класса
*/
- public function loadClass($path, $setup = null)
+ public function loadClass($path, $setup = null, $prefix = '')
{
if (file_exists($path)) {
require_once ($path);
- $class = pathinfo($path, PATHINFO_FILENAME);
+ $class = $prefix . pathinfo($path, PATHINFO_FILENAME);
return new $class($setup);
}
- return null;
+ throw new Exception("NO CLASS $path");
}
public function loadSettings($path)
@@ -269,6 +286,7 @@ class Controller_Action
// Для Widgets
public $view = null;
public $childNodes = array();
+ public $ctrlValues = array();
public $childViews = array();
public function setView($name)
@@ -292,6 +310,11 @@ class Controller_Action
$this->childNodes[$section] = $node;
}
+ public function setValue(/*Widget*/ $name, $value)
+ {
+ $this->ctrlValues[$name] = $value;
+ }
+
/**
* Добавление дочернего отображения к текущему отображению
*/
@@ -306,34 +329,86 @@ class Controller_Action
*/
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);
- }
+ if ($this->view instanceof View_View) {
+ $this->view->assignValues($this->ctrlValues);
+
+ 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)
+ function getPageId(HttpRequest $request)
{
$pageId = time();
$request->session()->set('page', $pageId);
return $pageId;
}
- function checkPageId($request, $page)
+ function checkPageId(HttpRequest $request, $page)
{
+ if ($request->get('__forced__')) {
+ return true;
+ }
$_page = $request->session()->get('page');
$result = ($_page && $_page == $page);
$request->session()->clean('page');
return $result;
}
- function redirect($action) {
- header('location: ' . $this->fUrl($action));
- exit();
+ function _getActionPath()
+ {
+ return new Controller_State('index');
}
-}
+ // Тоже убрать в метод Controller_Model
+ function getActionPath(HttpRequest $request, $action = null)
+ {
+ $this->_getActionPath()->getPath($this, ($action) ? $action : $request->getAction());
+ }
+
+ function addFilePathToPath($filePath, $type)
+ {
+ $pathToItem = $this->directoryPath($filePath, $type, 'default');
+ $this->path->addMenuItems($pathToItem['path']);
+ }
+
+ function directoryPath($path, $type, $action)
+ {
+ $path = empty($path) ? '/' : $path;
+
+ $base = new Path($path);
+ $parts = $base->getParts();
+
+ $_path = '/' . implode('/', $parts);
+
+ $rs = new Model_Resources($this->db);
+ $section_path = $rs->getSectionByPath($_path, $type);
+
+ $pathMenu = new Widgets_PathMenu();
+ $pathMenu->addTitle('title');
+ $modules = ['image' => 'images','page' => 'pages','document' => 'documents','media' => 'videos'];
+
+ while ($section_path->id_parent) {
+ $_path = '/' . implode('/', $parts);
+ $pathMenu->addMenuItem(
+ forceUrl($this->nUrl('', array('module'=>$modules[$type],'action' => $action, 'mode' => 'ajax', 'path' => $_path))),
+ $section_path->title
+ );
+ $section_path = $rs->getSectionById($section_path->id_parent);
+ array_pop($parts);
+ }
+
+ $pathMenu->addMenuItem(
+ forceUrl($this->nUrl('', array('module'=>$modules[$type],'action' => $action, 'mode' => 'ajax', 'path' => '/'))),
+ $this->moduleTitle
+ );
+ return $pathMenu->getItemsReverse();
+ }
+
+}
diff --git a/src/Controller/Component.php b/src/Controller/Component.php
index ae4c131..0a8220c 100644
--- a/src/Controller/Component.php
+++ b/src/Controller/Component.php
@@ -1,7 +1,40 @@
]*>/u', 'replaceContent', $text);
+}
+
+class ComponentRequest {
+ public $component_id;
+ public $r;
+
+ function __construct($c, HttpRequest $r) {
+ $this->component_id = $c;
+ $this->r = $r;
+ }
+
+ function get($key, $default = null) {
+ if ($key == 'active_page') {
+ return $this->r->get($key);
+ }
+ if ($arr = $this->r->get($key)) {
+ if (is_array($arr)) {
+ return Arr::get($arr, $this->component_id, $default);
+ } else {
+ return $arr;
+ }
+ }
+ return $default;
+ }
+
+ function getAction() {
+ return $this->r->getAction();
+ }
}
/**
@@ -9,51 +42,87 @@ class FileNotFountException extends Exception
*/
class Controller_Component
{
- static $_uid = 1;
- public $uid; // UID компонента создается при создании страницы, вставки компонента, или это статическое свойство
- public $viewPath;
- public $registry; // Registry->getInstance
- public $template;
+ public $viewPath = array();
+ public $webPath = array();
- function __construct()
- {
- self::$_uid ++;
- $this->uid = self::$_uid;
+ public $template = null;
+ public $templatePath;
+
+ public $component_id;
+ public $COMPONENTS_WEB;
+
+ public /*.Settings.*/$registry;
+ public /*.Database.*/$db;
+ public /*.Collection.*/$parameter;
+
+ public $module;
+ public $item_module;
+
+ function before() {
}
- function getUID()
- {
- return 'component:'. $this->uid;
+ function get($request, $key, $default) {
+ }
+
+ function execute(HttpRequest $request, $has_id = true) {
+ $crequest = new ComponentRequest($this->component_id, $request);
+ $action = 'action' . ucfirst($request->get('action', 'index'));
+
+ $this->before();
+ if (method_exists($this, $action)) {
+ return call_user_func(array($this, $action), $crequest);
+ } else {
+ return $this->actionIndex($crequest);
+ }
}
public function getView($name)
{
- require_once "core/view/compositeview.php";
//
- $template = ($this->template) ? $this->template : $this->_registry->readKey(array('system', 'template'));
- // Загружать шаблон по умолчанию если не найден текущий
- if (is_dir(Path::join($this->viewPath, 'templates', $template))) {
- $template_file = Path::join($this->viewPath, 'templates', $template, $name);
- } else {
- $template_file = Path::join($this->viewPath, 'templates', 'modern', $name);
+ /*.Settings.*/$registry = $this->registry;
+ $template = ($this->template) ? $this->template : $registry->readKey(array('system', 'template'));
+
+ $selected = null;
+ foreach ($this->viewPath as $index => $viewPath) {
+ // Загружать шаблон по умолчанию если не найден текущий
+ if(is_dir(Path::join($this->viewPath[$index], 'templates', $template))) {
+ $tpl = new PHPTAL(Path::join($this->viewPath[$index], 'templates', $template, $name));
+ $tpl->setPhpCodeDestination(PHPTAL_PHP_CODE_DESTINATION);
+ $selected = $index;
+ break;
+ }
}
- $tpl = new View_Composite($template_file);
- $tpl->script = $_script = Path::join(WWW_PATH, 'js');
- $tpl->media = $_media = Path::join(TEMPLATE_WEB, $template);
- $tpl->component = $_template = Path::join(COMPONENTS_WEB, strtolower(get_class($this)), 'templates', 'modern');
- $tpl->setAlias(array(
- '${media}' => $_media,
- '${script}' => $_script,
- '${template}' => $_template));
+ if ($selected === null) {
+ $tpl = new PHPTAL(Path::join($this->viewPath[0], 'templates', 'modern', $name));
+ $tpl->setPhpCodeDestination(PHPTAL_PHP_CODE_DESTINATION);
+ $template = 'modern';
+ $selected = 0;
+ }
- $tpl->loadImports(Path::skipExtension($template_file) . ".import");
+ $tpl->stripComments(true);
+ $tpl->addPreFilter(new PHPTAL_PreFilter_Normalize());
+
+ $tpl->set('common', Path::join(WWW_PATH, '../', 'common'));
+ $tpl->set('script', Path::join(WWW_PATH, 'js'));
+ $tpl->set('media', Path::join(TEMPLATE_WEB, $template));
+ $tpl->set('site_template', SITE_WWW_PATH . '/templates' . $registry->readKey(array('system', 'template')));
+ $tpl->set('base', SITE_WWW_PATH);
+
+ $tpl->set('component_base', $this->webPath[$selected]);
+ $tpl->set('component', Path::join($this->webPath[$selected], 'templates', $template));
+ $tpl->set('component_id', $this->component_id);
return $tpl;
}
- public function setParameters($view)
+ public function getTemplatePath($name) {
+ return Path::join($this->viewPath[0], 'templates', 'modern', $name);
+ }
+
+ public function getTemplateWebPath()
{
+ return Path::join($this->webPath[0], 'templates', 'modern');
}
/**
@@ -71,8 +140,6 @@ class Controller_Component
*/
public function getModel($name)
{
- require_once 'core/mapper/mapper.php';
-
require_once ($this->getModelPath ($name));
$modelName = $name . "Mapper";
$model = new $modelName ();
@@ -80,104 +147,179 @@ class Controller_Component
return $model;
}
- public function options($key, $val, $res) {
+ public function options($key, $val, /*.Database_PDOStatement.*/$res) {
$result = array();
while($res->next()) {
- $result[] = array('value' => $res->getInt($key), 'name' => $res->getString($val));
+ $result[] = array('value' => $res->getString($key), 'name' => $res->getString($val));
}
return $result;
}
- public function optionsPair($list) {
+ public function optionsPair($list, $selected = false) {
$result = array();
foreach ($list as $key => $value) {
- $result [] = array('value' => $key, 'name' => $value);
+ $result [] = array('value' => $key, 'name' => $value, 'selected' => $key == $selected);
}
return $result;
}
- /* В дальнейшем нужно зменить на методы
- + Методы могут быть и javascript
- */
- protected $editUrl;
-
- function setEditUrl($url)
- {
- $this->editUrl = $url;
+ function getInfo() {
+ $filename = Path::join($this->viewPath[0], 'install.json');
+ if (file_exists($filename)) {
+ $settings = json_decode(file_get_contents($filename), true);
+ return $settings;
+ }
+ return array();
}
- function getEditUrl()
+ /**
+ * Генерация интерфейса для выбора галлереи фотографии
+ */
+ public function setParameters(/*.View_Composite.*/$view)
{
- return $this->editUrl;
- }
-}
+ $form = new Form_Form();
+ $options = new OptionFactory($this->db);
-/**
- * TALES для подключения компонентов
- * component:name?param1=value1¶m2=value2
- */
-class Component_Tales implements PHPTAL_Tales
-{
- static public function component($expression, $nothrow = false)
+ $settings = $this->getInfo();
+ $form->addFieldList($settings['parameter'], $options);
+
+ $view->form = $form;
+ $view->component = $settings['component'];
+ $view->component_title = $settings['title'];
+ }
+
+ static function loadComponent($expression, Database $db, Settings $registry)
{
- return "phptal_component('" . $expression . "')";
- }
-}
+
+ $expression = htmlspecialchars_decode($expression);
+ $offset = strpos($expression, '?');
+ $url = parse_url($expression);
+
+ $arguments = array();
+ if ($offset === false) {
+ $path = $expression;
+ } else if (is_int($offset)) {
+ $path = substr($expression, 0, $offset);
+ $query = substr($expression, $offset + 1);
+ parse_str($query, $arguments);
+ }
+ $name = $path;
+
+ $path = Path::join (BASE_PATH, 'components', $name, $name . '.php');
+ $className = 'Component_' . $name;
+
+ if (file_exists($path)) {
+ require_once ($path);
+
+ $component = new $className();
+ $component->db = $db;
+ $component->registry = $registry;
+
+ $component->viewPath = array(BASE_PATH . '/components/' . $name . '/');
+ $component->webPath = array(SITE_WWW_PATH . '/components/' . $name);
+
+ $component->COMPONENTS_WEB = SITE_WWW_PATH . '/components/';
+
+ } else {
+ $path = Path::join (COMPONENTS, $name, $name . '.php');
+ require_once ($path);
+ $component = new $className();
+ $component->db = $db;
+ $component->registry = $registry;
+
+ $component->viewPath = array(COMPONENTS . '/' . $name . '/', BASE_PATH . '/components/' . $name . '/');
+ if (defined('COMPONENTS_WEB')) {
+ $component->webPath = array(COMPONENTS_WEB . '/' . $name, SITE_WWW_PATH . '/components/' . $name);
+ $component->COMPONENTS_WEB = COMPONENTS_WEB;
+ }
+ }
+
+ $stmt = $db->prepareStatement("SELECT * FROM component WHERE code = ?");
+ $stmt->setString(1, $expression);
+ $cid = $stmt->executeQuery();
+ if ($cid->next()) {
+ $component->component_id = $cid->getInt('id_component');
+ } else {
+ $last = $db->getIdGenerator();
+ if ($last->isBeforeInsert()) {
+ $result = $last->getId('component_id_component_seq');
+
+ $stmt = $db->prepareStatement("INSERT INTO component (id_component, code) VALUES ($result, ?)");
+ $stmt->setString(1, $expression);
+ $stmt->executeQuery();
+ }
+ if ($last->isAfterInsert()) {
+ $stmt = $db->prepareStatement("INSERT INTO component (code) VALUES (?)");
+ $stmt->setString(1, $expression);
+ $stmt->executeQuery();
+
+ $result = $last->getId('component_id_component_seq');
+ }
+ $component->component_id = $result;
+ }
+
+ $params = new Collection();
+ $params->import(array_merge($_GET, $arguments));
+ $component->parameter = $params;
+ $component->template = $params->get('template', false);
+
+ global $componentsConfig;
+ $editor = $component->getEditUrl();
+ if ($editor) {
+ $componentsConfig[] = $editor;
+ }
-function loadComponent($name, $db, $registry)
-{
- $path = Path::join(COMPONENTS, $name, $name . ".php");
-// echo COMPONENTS, '
';
-// echo $path;
- if (file_exists($path)) {
- require_once ($path);
- $component = new $name();
- $component->db = $db;
- $component->_registry = $registry;
- $component->viewPath = COMPONENTS."/".$name."/";
return $component;
}
- throw new FileNotFountException();
+
+ function getEditUrl() {
+ return null;
+ }
+
+ function raw_query(/*.ComponentRequest.*/ $request)
+ {
+ $arr = $request->r->export('get');
+
+ $param = array();
+ /*.Collection.*/$parameter = $this->parameter;
+ foreach($parameter->export() as $key => $value) {
+ $param[$key] = $value;
+ }
+
+ $data = array();
+ foreach($arr as $key => $value) {
+ if (is_array($value)) {
+ $data[$key] = Arr::get($value, $this->component_id);
+ } else {
+ $data[$key] = $value;
+ }
+ }
+ $data['param'] = $param;
+ return $data;
+ }
+
+
+ function query(/*.ComponentRequest.*/ $request, $list)
+ {
+ $arr = $request->r->export('get');
+
+ foreach($list as $key => $val) {
+ $arr[$key] [$this->component_id] = $val;
+ }
+
+ unset($arr['active_page']);
+ return '?' . http_build_query($arr);
+ }
+
+ function addRequireJsPath($name, $path, $shim = null) {
+ global $requireJsConfig;
+ $requireJsConfig['paths'][$name] = $path;
+ if ($shim) {
+ $requireJsConfig['shim'][$name] = $shim;
+ }
+ }
+
+ function actionIndex(/*.ComponentRequest.*/ $request) {
+ }
}
-/**
- * Функция подключения компонента
- */
-global $componentList;
-$componentList = array();
-
-function phptal_component ($real_expression, $offset = 0) {
- global $db, $registry, $componentList; // Нужно както передавать параметры
-
- $expression = htmlspecialchars_decode($real_expression);
- $url = parse_url($expression);
- parse_str($url['query'], $arguments);
- $name = $url['path'];
-
- $component = loadComponent($name, $db, $registry);
- $req = new HttpRequest();
- $params = new Collection();
- $params->import(array_merge($_GET, $arguments));
- $component->params = $params;
-
- $componentList [] = array(
- 'uid' => $component->getUID(), 'params' => $expression, 'name' => $name, 'offset' => $offset,
- 'size' => strlen($real_expression),
- /* Вместо ссылки на редактирование нужно передавать список методов для работы с компонентом
- edit (редактирование содержание), new (новое содержание), шаблон коменнента ... вместе с иконками этих методов
- ! Компоненты могут содержать другие компоненты
- */
- 'editurl' => $component->getEditUrl(),
- 'newurl' => ''
- );
-
- unset($req['active_page']);
- $component->template = $params->get('template', false);
-
- return $component->execute($params, $req);
-}
-
-/* Регистрация нового префикса для подключения компонента */
-$registry = PHPTAL_TalesRegistry::getInstance();
-$registry->registerPrefix('component', array('Component_Tales', 'component'));
-
diff --git a/src/Controller/Front.php b/src/Controller/Front.php
index badcf43..38b1a40 100644
--- a/src/Controller/Front.php
+++ b/src/Controller/Front.php
@@ -2,25 +2,37 @@
/**
* Первичный контроллер контроллер страниц
- * @package core
+ * @package system.controller
*/
class Controller_Front extends Controller_Action
{
-
+
+ /** @var Shortcut */
protected $shortcut; // Ярлык к модулю
protected $_param; // Параметр по которому выбирается модуль
protected $default; // Значение параметра по умолчанию
- public function __construct(Settings $_registry, $_shortcut)
+ protected $modules = array();
+
+ /**
+ * @param Settings $_registry
+ * @param Shortcut $_shortcut
+ */
+ public function __construct(Settings $_registry, $_shortcut) // $db, $installer, $shortcut
{
parent::__construct();
$registry = $_registry;
$this->_registry = $_registry;
- $this->_shortcut = $_shortcut;
+ $this->_shortcut = $_shortcut; // $cc->newShortcut();
- $this->db = Database::getConnection($registry->readKey(array('system', 'dsn')));
+ $dsn = $registry->readKey(array('system', 'dsn'));
+ $this->db = Database::getConnection($dsn); // $cc->newConnection();
}
+ public function isLoaded($name)
+ {
+ return isset($this->modules[$name]);
+ }
/**
* Создает экземпляр модуля и выполняет действия для него
@@ -28,15 +40,22 @@ class Controller_Front extends Controller_Action
* @param request $request Имя модуля
* @return string
*/
- public function loadModule($name, Collection $request)
+ public function loadModule($name, Collection $request, $controller = false)
{
+ if ($this->isLoaded($name)) {
+ $module = $this->modules[$name];
+ return $module->access->execute($request);
+ }
- $moduleFile = Shortcut::getUrl($this->shortcut, $name); // ModuleLoader (2)
- $module = $this->loadClass($moduleFile);
+ if ($controller) {
+ $moduleFile = Shortcut::getUrl($this->shortcut, $name, $controller); // ModuleLoader (2)
+ } else {
+ $moduleFile = Shortcut::getUrl($this->shortcut, $name, $name); // ModuleLoader (2)
+ }
+ $module = $this->loadClass($moduleFile, null, 'Module_');
if ($module) {
// Инициализация модуля
-// $module->viewPath = dirname($moduleFile);
$module->viewPath = Shortcut::getUrl('modulepath', $name);
$module->name = $name;
@@ -51,15 +70,17 @@ class Controller_Front extends Controller_Action
$module->db = $this->db;
// Не для всех приложений нужно вести лог действий
// Ведение лога
- $logger = $this->loadClass(FRAMEWORK_PATH . '/src/filter/actionlogger.php', $module);
+ $logger = $this->loadClass(FRAMEWORK_PATH . '/filter/actionlogger.php', $module, 'Filter_');
$logger->before = $this->loadSettings(Shortcut::getUrl('logger', $name));
// Управление доступом
- $module->access = $this->loadClass(FRAMEWORK_PATH . '/src/filter/actionaccess.php', $logger);
+ $module->access = $this->loadClass(FRAMEWORK_PATH . '/filter/actionaccess.php', $logger, 'Filter_');
$module->access->access = $this->loadSettings(Shortcut::getUrl('access', $name));
$module->setUp();
- return $module->access->execute($request);
+ $this->modules[$name] = $module;
+ $result = $module->access->execute($request);
+ return $result;
}
return null; // throw new FileNotFoundException();
}
@@ -72,13 +93,14 @@ class Controller_Front extends Controller_Action
$this->default = $name;
}
- private function getParameter(Collection $list)
- {
- return ($list->get($this->_param)) ? $list->get($this->_param): $this->default;
- }
-
public function execute(HTTPRequest $request)
{
- return $this->loadModule($this->getParameter($request), $request);
+ $name = explode("_", $request->get($this->_param, $this->default));
+ if (count($name) >= 2) {
+ $controller = $name[1];
+ } else {
+ $controller = false;
+ }
+ return $this->loadModule($name[0], $request, $controller);
}
}
diff --git a/src/Controller/Installer.php b/src/Controller/Installer.php
index 1bbbe3a..dcc4562 100644
--- a/src/Controller/Installer.php
+++ b/src/Controller/Installer.php
@@ -2,7 +2,7 @@
class Controller_Installer
{
- protected $db;
+ protected $db_manager;
protected $installPath;
public $_registry;
@@ -11,15 +11,20 @@ class Controller_Installer
$this->_registry = $_registry;
}
- public function setUp($db, $installPath)
+ public function setUp($db_manager, $installPath)
{
- $this->db = $db;
+ $this->db_manager = $db_manager;
$this->installPath = $installPath;
}
function getSetupFile($name)
{
- return Path::join(call_user_func($this->installPath, $name), "setup.php");
+ $setup = Path::join(call_user_func($this->installPath, $name), "install.json");
+ return $setup;
+ }
+
+ function getUninstallFile($name){
+ return Path::join(call_user_func($this->installPath, $name), "sql", "uninstall.json");
}
// Проверка версии обновления
@@ -38,22 +43,33 @@ class Controller_Installer
function installSQL(array $sql, $version_new, $version_old, $name)
{
- require_once "core/setup.php";
+ $result = [];
+ $json_installer = new Database_JsonInstall($this->db_manager);
foreach ($sql as $version => $install) {
if (version_compare($version, $version_new, "<=") && version_compare($version, $version_old, ">")) {
- // this->installPath this->db
$file = Path::join(call_user_func($this->installPath, $name), "sql", $install);
- Setup::batchSQL($this->db, $file);
+ $json_installer->install($file,null);
+ $result[] = $version;
}
}
+ return $result;
}
+ function uninstall($name){
+ $uninstall = $this->getUninstallFile($name);
+ if (file_exists($uninstall)) {
+ $json_installer = new Database_JsonInstall($this->db_manager);
+ $json_installer->install($uninstall,null);
+ }
+ $this->_registry->removeKey($name);
+ $this->_registry->write();
+ }
// Устанавливает обновления если есть
function doUpdates($name, $force = false) // Установка модуля
{
+ $result = array();
$setup = $this->getSetupFile($name);
if (file_exists($setup) && ($this->isChanged($name) || $force)) {
-
$registry = $this->_registry;
$settings = new Settings($setup);
$settings->read();
@@ -67,21 +83,29 @@ class Controller_Installer
$version_old = "0.0";
$registry->writeKey(array($name), array());
}
-
if (version_compare($version_old, $settings->get('version'), "!=")) {
$sql = $settings->get('sql');
if (is_array($sql)) {
- $this->installSQL($sql, $version_new, $version_old, $name);
+ $res = $this->installSQL($sql, $version_new, $version_old, $name);
+ if($res){
+ $result[]=$res;
+ }
}
}
// Обновление версии меню
+ $registry->removeKey($name);
$registry->writeKey(array($name), $settings->get('settings'));
$registry->writeKey(array($name),
array('version' => $version_new,
'time' => filemtime($setup)));
$registry->write();
}
+ return $result;
+ }
+
+ function install($dbinit_path,$dbfill_path=null){
+ $json_installer = new Database_JsonInstall($this->db_manager);
+ $json_installer->install($dbinit_path,$dbfill_path);
}
}
-
diff --git a/src/Controller/Model.php b/src/Controller/Model.php
index 9c4dab7..4c1cbf9 100644
--- a/src/Controller/Model.php
+++ b/src/Controller/Model.php
@@ -28,38 +28,53 @@ class Controller_Model extends Controller_Action
public function __construct()
{
- $this->path = new PathMenu();
- $this->menu = new PageMenu();
- $this->table = new ListTable();
+ parent::__construct();
+ $this->menu = new Widgets_PageMenu();
+ $this->table = new Widgets_ReactListTable();
}
/**
*/
- function setUp()
- {
- $this->table->addMenuItem($this->aUrl('delete'), 'удалить', false, 'all', 'warning');
- //$this->table->addMenuItem($this->nUrl('form'), 'редактировать', 'edit-24.png');
+ function setUp() {
+ parent::setUp();
+ $this->table->addMenuItem($this->aUrl('delete'), 'удалить', false, 'all', 'btn-danger', 'remove');
}
- function saveParameters($args, $list)
- {
+ function saveParameters(HttpRequest $args, $list) {
foreach ($list as $item) {
$args->session()->set(array($this, $item), $args->get($item));
}
}
- protected function getJSONList(/*Mapper*/ $model, Collection $request)
- {
+ protected function getJSONList(/*.Model_Mapper.*/ $model, HttpRequest $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);
+ return json_encode($result);
}
+ protected function getCSV(Model_Mapper $model, HttpRequest $request, $title) {
+ $ref = $request->get('ref');
+
+ $list = $model->findAll($request, $request->get('ref'));
+
+ header('Content-Type: text/csv; charset=utf-8');
+ header('Content-Disposition: attachment; filename='.$title.'.csv');
+
+ echo "\xEF\xBB\xBF"; //UTF-8 BOM.
+
+ $output = fopen('php://output', 'w');
+ if (is_resource($output)) {
+ foreach ($list as $row) {
+ fputcsv($output, (array)$row,';');
+ }
+ }
+ }
+
/**
- * Удаление сторк из таблицы
+ * Удаление строк из таблицы
*/
public function actionDelete(HttpRequest $request)
{
@@ -68,7 +83,8 @@ class Controller_Model extends Controller_Action
$list = ($request->get('table_item')) ? $request->get('table_item'): $request->get('id');
$model->deleteList($list);
- return $this->getJSONList($model, $request);
+// return $this->getJSONList($model, $request);
+ return json_encode(array('result' => 'ok'));
}
/**
@@ -88,16 +104,29 @@ class Controller_Model extends Controller_Action
public function actionList(HttpRequest $request)
{
$model = $this->getModel($this->useModel);
+
+ if ($request->get('filter')) {
+ $data = new Collection();
+ $data->import($request->get('filter'));
+ $model->addFilter($model->requestToSQL($data, $this->formSchema));
+ }
return $this->getJSONList($model, $request);
}
+ public function actionCSV(HttpRequest $request)
+ {
+ $model = $this->getModel($this->useModel);
+ $title = $request->get("title");
+ if(!$title){
+ $title = "noname";
+ }
+ return $this->getCSV($model, $request, $title);
+ }
private function setFormSchema()
{
- require_once 'core/mapper/uimapper.php';
-
$model = $this->getModel($this->useModel);
- $ui = new UIMapper($model);
+ $ui = new Model_UIMapper($model);
$this->formSchema = $ui->getFormSchema();
}
@@ -105,29 +134,29 @@ class Controller_Model extends Controller_Action
/**
* Сохранение формы
*/
- function beforeSave(/*Model*/ $item, Collection $request)
+ function beforeSave(/*Model*/ $item, HttpRequest $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)); // Здесть нужно преобразовывать тип значения
+ $item->$value = call_user_func(array('Primitive', 'to_' . $type), $request->get($key)); // Здесь нужно преобразовывать тип значения
}
}
/**
* Обновление формы
*/
- function formUpdate(TForm $form, Collection $request)
- {
+ function formUpdate(Form_Form $form, HttpRequest $request) {
+ $form->setValues($request);
}
/**
* Загрузка формы
*/
- function beforeLoad(/*Model*/ $item, TForm $form)
+ function beforeLoad(/*.Model_Model.*/$item, Form_Form $form)
{
if (empty($this->formSchema)) {
$this->setFormSchema();
@@ -137,8 +166,13 @@ class Controller_Model extends Controller_Action
$form->fill($item, $this->formSchema);
}
+ function beforeFirstLoad(Form_Form $form)
+ {
+
+ }
+
// Проверка ввода
- protected function validate($validator, $request)
+ protected function validate(Validator_Validator $validator, Collection $request)
{
}
@@ -147,8 +181,7 @@ class Controller_Model extends Controller_Action
*/
public function actionValidate($request)
{
- require_once "core/validator/validator.php";
- $validator = new Validator();
+ $validator = new Validator_Validator();
$validator->addRuleList($this->schema);
// Действия до проверки формы
@@ -156,19 +189,19 @@ class Controller_Model extends Controller_Action
$validator->validate($request); // --|
// Проверка формы
if (!$validator->isValid()) {
- return json::encode($validator->getErrorMsg());
+ return json_encode($validator->getErrorMsg());
}
- return json::encode(true);
+ return json_encode(true);
}
/**
* Инициализация формы
*/
- protected function formSetup($form, $id = null, $ref = null)
+ protected function formSetup(Form_Form $form, $id = null, $ref = null)
{
if (empty($this->schema)) {
$model = $this->getModel($this->useModel);
- $ui = new UIMapper($model);
+ $ui = new Model_UIMapper($model);
$schema = $ui->getEditSchema();
$form->addFieldList($schema);
@@ -178,71 +211,57 @@ class Controller_Model extends Controller_Action
}
/**
- * Добавление пользователя
+ * Добавление
*/
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);
+ // Проверка
+ $validator = new Validator_Validator();
+ $validator->addRuleList($this->schema);
- $form = new TForm();
- $this->formSetup($form, $request->get('id'), $request->get('ref')); // Инициализация формы
+ // Действия до проверки формы
+ $this->validate($validator, $request); // <--|
+ $validator->validate($request); // --|
+ // Проверка формы
+ if (!$validator->isValid()) {
+ return json_encode(array('result'=>'fail','errors'=>$validator->getErrorMsg()));
+ }
+ // Нужен тест для формы
+ $model = $this->getModel($this->useModel);
+ $className = $model->className;
+ $item = new $className();
- $form->setValues($request); // <-- Убрать в formUpdate
- $this->formUpdate($form, $request);
+ // Сохраняем значение в базе данных
+ $item->id = $request->get('id');
+ // Если таблица связана с другой таблицей
+ if ($request->get('ref') && $model->reference[1]) {
+ $ref_id = $model->reference[1];
+ $item->$ref_id = $request->get('ref');
+ }
- $form->setError($validator); // Установка ошибок для формы
+ // Подготовка к сохранению
+ $this->beforeSave($item, $request); // Сюдаже и истрия переходов
+ // nextId ??? или выход или новая форма для создания новости
+
+ $id = $model->saveDB($item, $request);
- $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 -> идентефикатор родительской таблицы !!??
+ // Для страницы со списком id -> идентификатор родительской таблицы !!??
// $request->set('id', $request->get('ref'));
if ($request->get('apply')) {
$request->setAction('form');
- return $this->forward('actionForm', $request);
+ return (string) $this->forward('actionForm', $request);
}
- return $this->forward('actionIndex', $request);
+ //$request->setAction('index');
+ $result = array('result'=>'ok');
+ if($id){
+ $result['action'] = forceUrl($this->nUrl('add', array('id' => $id, 'ref' => $request->get('ref'))));
+ }
+ return json_encode($result);
}
/**
@@ -275,38 +294,40 @@ class Controller_Model extends Controller_Action
$this->setTitlePath($ref);
$model = $this->getModel($this->useModel);
- $form = new TForm(); // Показываем форму
+ $form = new Form_Form(); // Показываем форму
$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);
+ //
+ $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);
- ///
+ }else{//Создание нового элемента
+ $this->beforeFirstLoad($form);
}
- return $tpl;
+ return json_encode($tpl);
}
/**
*/
- function tableSetup($table, $id = null, $ref = null)
+ function tableSetup(Widgets_ListTable $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();
+ $ui = new Model_UIMapper($model);
+ $ui->hidden = $table->hidden;
+
+ $schema = $ui->getTableSchema();
+ $schema[0]['action'] = forceUrl($table->getFirstItem());
$table->setHeader($schema);
}
@@ -314,7 +335,7 @@ class Controller_Model extends Controller_Action
/**
*/
- public function actionIndex(HttpRequest $request)
+ public function actionDefault(HttpRequest $request)
{
$this->getActionPath($request, 'index');
// Такое мета действие наверное можно вынести в отдельный класс
@@ -335,14 +356,14 @@ class Controller_Model extends Controller_Action
$ref = $request->session()->get('ref');
}
- $request->session->set('ref', $ref);
+ $request->session()->set('ref', $ref);
$this->addParameter('ref', $ref);
// }}}
$this->setTitlePath($ref);
- $tpl = $this->getView('list');
+ $tpl = new stdClass();
- // Помошники действий
+ // Помощники действий
$this->callHelpers($request);
// Таблица
if ($request->session()->get(strtolower(get_class($this)))) {
@@ -355,7 +376,7 @@ class Controller_Model extends Controller_Action
'size' => $session['size'],
'desc' => $session['desc']));
- $this->table->setData('sorter', $session['key']);
+ //$this->table->setData('sorter', $session['key']);
if (isset($session['desc'])) {
$this->table->setData('desc', $session['desc']);
}
@@ -363,64 +384,137 @@ class Controller_Model extends Controller_Action
call_user_func($setup, $this->table, $request->get('id'), $ref);// --> Эквивалент formSetup
$this->table->setAction($list);
- //
+ if (!$this->table->getData('module')) {
+ $this->table->setData('module', strtolower($this->useModel));
+ }
$tpl->menu_path = $this->path->getItems();
- // Поиск
- $search = new SearchDialog();
- $search->setTitle('Поиск');
- $search->setAction($this->aUrl('search'));
- $search->setFriend($this->table);
- $search->addFields($this->schemaSearch);
+ $this->table->makeData();
+ $tpl->table = array('data' => $this->table->data);
+ $tpl->menu = $this->menu->menu->getItems();
+ $tpl->path = $this->path->getItems();
- // Настройки
- $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;
+ return json_encode($tpl);
}
/**
*/
- public function actionSetup($request)
- {
+ public function actionSetup(HttpRequest $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)));
+ $request->session()->set(strtolower(get_class($this)),
+ array('view' => array('left' => $left, 'right' => $right), 'page' => 1, 'size' => 0, 'desc' => 'asc', 'key' => false));
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)))); // Действие для формы
+ protected function formPage($form, $request, $template = 'form') {
+ $view = new stdClass();//$this->getView($template);
+ $view->form = $form;
+ $form->action = forceUrl($this->nUrl('add', array('page' => $this->getPageId($request)))); // Действие для формы
- $view->menu_path = $this->path->getItems();
+ $view->path = $this->path->getItems();
$view->back = $this->path->getPrev();
return $view;
}
+ function _getActionPath() {
+ return new Controller_State('index');
+ }
+
// Тоже убрать в метод Controller_Model
- function getActionPath(HttpRequest $request/*, $action = false*/)
- {
- require_once 'state.php';
+ function getActionPath(HttpRequest $request, $action = null) {
$this->_getActionPath()->getPath($this, ($action) ? $action : $request->getAction());
}
+
+
+ function parse_params($expression) {
+ $expression = htmlspecialchars_decode($expression);
+ $offset = strpos($expression, '?');
+ $url = parse_url($expression);
+
+ $arguments = array();
+ if ($offset === false) {
+ $path = $expression;
+ } else if (is_int($offset)) {
+ $path = substr($expression, 0, $offset);
+ $query = substr($expression, $offset+1);
+ parse_str($query, $arguments);
+ }
+ return $arguments;
+ }
+
+ public function actionFormPage(HttpRequest $request) {
+ //$tpl = $this->getView('formpage', 'View_Top');
+
+ $view = $this->getView('formpage', 'View_Top');
+
+ $params = $this->parse_params($request->get('params'));
+
+
+// $model = $this->getModel($this->useModel);
+ $form = new Form_Form(); // Показываем форму
+ $form->header = 'Редактирование записи';
+ $this->formSetup($form, $request->get('id'), $request->get('ref')); // Инициализация формы
+ /*
+ $ui = new Model_UIMapper($model);
+ $schema = $ui->getEditSchema();
+ $form->addFieldList($schema);
+ */
+
+ $list = $request->get('table_item');
+ $id = ($list[0]) ? $list[0] : $request->get('id');
+
+// $tpl = $this->formPage($form, $request);
+
+ $view->setView('form', $form);
+ $view->action = forceUrl($this->nUrl('addpage', array('ref' => $params['id']))); // Действие для формы
+
+// $view->menu_path = $this->path->getItems();
+ $view->back = '';
+ return $view;
+
+// return $tpl;
+ }
+
+ /* Для поддержки редактрования на сайте */
+ public function actionAddPage(HttpRequest $request)
+ {
+ // {{{ тоже может быть один ref или несколько
+ $ref = $request->get('ref');
+ $this->addParameter('ref', $ref); // Добавляет параметр в url
+ /// }}}
+ $validator = new Validator_Validator();
+ $validator->addRuleList($this->schema);
+
+ // Действия до проверки формы
+ $this->validate($validator, $request); // <--|
+ $validator->validate($request); // --|
+ // Проверка формы
+ if (!$validator->isValid()) {
+ return $validator;
+ }
+
+ // Нужен тест для формы
+ $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); // Сюдаже и истрия переходов
+ $model->saveDB($item, $request);
+
+ return null;
+ }
}
diff --git a/src/Database/PDOStatement.php b/src/Database/PDOStatement.php
index 4561611..4df5db7 100644
--- a/src/Database/PDOStatement.php
+++ b/src/Database/PDOStatement.php
@@ -1,5 +1,7 @@
fields[$name]);
+ return strToArray($this->fields[$name]);
}
function getRecordCount() {
diff --git a/src/Filter/Login.php b/src/Filter/Login.php
index 7b0c8ea..4ce7302 100644
--- a/src/Filter/Login.php
+++ b/src/Filter/Login.php
@@ -13,6 +13,9 @@ class Filter_Login extends Filter_Filter
const SESSION_BROWSER_SIGN_SECRET = '@w3dsju45Msk#';
const SESSION_BROWSER_SIGN_KEYNAME = 'session.app.browser.sign';
public $mode = 'ajax';
+
+ //AJAX-Реквесты для которых не требуется авторизация, потребовалось для сбора статистики
+ public $whiteRequestList = array(array('module' => "requiredcontent", "action" => "getcount"));
/**
* Проверка авторизации
* @return Boolean Авторизовани пользователь или нет
@@ -20,7 +23,7 @@ class Filter_Login extends Filter_Filter
public function isLoggin(HttpRequest $request)
{
// Авторизация
- // session_start();
+ session_start();
$db = $this->getConnection();
Filter_UserAccess::setUp($db); // Соединение
switch ($request->getAction()) {
@@ -31,7 +34,18 @@ class Filter_Login extends Filter_Filter
$result = Filter_UserAccess::getUserByLogin($login); // Поиск по логину
if ($result) {
- if (md5($password) == $result->getString('password')) { // password
+ $userPassword = $result->getString('password');
+ if (Filter_UserAccess::$access == 'site_root' && defined('PARENT_PATH')) {
+ $s = new Settings(PARENT_PATH . '/settings.json');
+ $s->read();
+ $dsn = $s->readKey(array('system', 'dsn'));
+
+ $db = Database::getConnection($dsn);
+ $user = $db->fetchOneArray("SELECT * FROM users WHERE login = :login", ['login' => $login]);
+ $userPassword = $user['password'];
+ }
+ // Извлечнеие пользователя из родительской CMS, для проверки пароля
+ if (md5($password) == $userPassword) { // password
$this->enter($db, $result);
return true;
}
@@ -45,7 +59,7 @@ class Filter_Login extends Filter_Filter
case 'enter':
$login = $request->get('login');
$password = $request->get('sid');
- $result = UserAccess::getUserByLogin($login); // Поиск по логину
+ $result = Filter_UserAccess::getUserByLogin($login); // Поиск по логину
if ($result) {
$temp = md5($result->getString('password') . $result->getString('login') . $result->getString('sid'));
if ($password == $temp) {
@@ -57,12 +71,15 @@ class Filter_Login extends Filter_Filter
default:
$hash = $this->getBrowserSign();
// Если $hash не совпадает $_SESSION['hash'] то удаляем сессию
- if (isset($_SESSION ['access']) && isset($_SESSION[self::SESSION_BROWSER_SIGN_SECRET])) {
- if ($hash == $_SESSION[self::SESSION_BROWSER_SIGN_SECRET]) {
- UserAccess::getUserById($_SESSION ['access']); // Поиск по идентификатору
+ if (isset($_SESSION ['access']) && isset($_SESSION[self::SESSION_BROWSER_SIGN_KEYNAME])) {
+ if ($hash == $_SESSION[self::SESSION_BROWSER_SIGN_KEYNAME]) {
+ $this->user = $user = Filter_UserAccess::getUserById($_SESSION['access']); // Поиск по идентификатору
+ if ($user && isset($_SESSION['random']) && ($user->get('sid') == $_SESSION['random'])) {
+ return true;
+ }
return true;
} else {
- session_destroy();
+ session_destroy();
}
}
}
@@ -72,9 +89,9 @@ class Filter_Login extends Filter_Filter
private function getBrowserSign()
{
$rawSign = self::SESSION_BROWSER_SIGN_SECRET;
- $signParts = array('HTTP_USER_AGENT', 'HTTP_ACCEPT_ENCODING');
+ //$signParts = array('HTTP_USER_AGENT', 'HTTP_ACCEPT_ENCODING');
+ $signParts = array();
- $rawSign = '';
foreach ($signParts as $signPart) {
$rawSign .= '::' . (isset($_SERVER[$signPart]) ? $_SERVER[$signPart] : 'none');
}
@@ -83,23 +100,78 @@ class Filter_Login extends Filter_Filter
private function enter($db, $result)
{
- $db->executeQuery("UPDATE users SET sid = '' WHERE id_user = " . $result->getInt('id_user'));
+ $this->user = $result;
+ $random = rand(0, 1024 * 1024);
+ $db->executeQuery("UPDATE users SET sid = '$random' WHERE id_user = " . $result->getInt('id_user'));
- $_SESSION ["group"] = $result->getInt('access');
- $_SESSION ["access"] = $result->getInt('id_user'); // id_user
- $_SESSION [self::SESSION_BROWSER_SIGN_SECRET] = $this->getBrowserSign();
- $_SESSION ["time"] = time();
+ $_SESSION["group"] = $result->getInt('access');
+ $_SESSION["access"] = $result->getInt('id_user'); // id_user
+ $_SESSION["random"] = $random; // id_user
+ $_SESSION[self::SESSION_BROWSER_SIGN_KEYNAME] = $this->getBrowserSign();
+ $_SESSION["time"] = time();
}
public function execute(HttpRequest $request)
{
- if (!$this->isLoggin($request)) {
- // Параметры при неправильной авторизации
- // Действия по умолчанию !! Возможно переход на форму регистрации
- $request->set('module', 'login');
- $request->set('mode', $this->mode);
+ $logged = $this->isLoggin($request);
+ if ($request->get('action') == 'user_access') {
+ if ($logged) {
+ $result = array();
+ $result['fullname'] = $this->user->getString('patronymic') . " " . $this->user->getString('firstname');
+ $result['email'] = $this->user->getString('email');
+ $result['site'] = 187;
+ $result['hash'] = sha1(self::SESSION_BROWSER_SIGN_SECRET . $this->user->getString('email'));
+ return json_encode($result);
+ } else {
+ return json_encode("NOT AUTHORIZED");
+ }
}
- return $this->processor->execute($request);
+
+ if ($request->get('action') == 'relogin') {
+ if ($logged) {
+ return json_encode(array('result' => 'ok', 'message' => "Авторизация успешна"));
+ } else {
+ return json_encode(array('result' => 'fail', 'message' => "Неправильное имя пользователя или пароль"));
+ }
+ }
+
+ if (!$logged) {
+ // Параметры при неправильной авторизации
+ // Действия по умолчанию !! Возможно переход на форму регистрации
+ if ($request->get('mode') == 'ajax') {
+ if (!$this->requestIsWhite($request, $this->whiteRequestList)) {
+ return json_encode(array('result' => 'fail', 'message' =>"NOT_AUTHORIZED"));
+ }
+ } else {
+ $request->set('module', 'login');
+ $request->set('mode', $this->mode);
+ }
+ } else if (isset($_SERVER['HTTP_REFERER'])) {
+ $arr = array();
+ parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $arr);
+ if (isset($arr['back_page']) && $request->get('mode') != 'ajax') {
+ $request->redirect($arr['back_page']);
+ }
+ }
+
+ $text = $this->processor->execute($request);
+ return $text;
+ }
+
+ /* ---------------------
+ * Проверка на попадание реквеста в белый список
+ */
+
+ public function requestIsWhite(Collection $request, $whiteRequestList){
+ $module = $request->get('module');
+ $action = $request->get('action');
+ foreach ($whiteRequestList as $whiteRequest) {
+ if ($module == $whiteRequest['module'] && $action == $whiteRequest['action']) {
+ return true;
+ }
+ }
+
+ return false;
}
}
diff --git a/src/Form/Form.php b/src/Form/Form.php
index 7d38691..aa68acc 100644
--- a/src/Form/Form.php
+++ b/src/Form/Form.php
@@ -20,68 +20,147 @@ class TField
public $description = "";
public $alias = array();
- public function __construct ($input)
+ public function __construct ($input = array(), $factory = null)
{
- $this->deafult = null;
+
+ $this->default = null;
if (isset($input['validate'])) {
- $this->require = strpos($input['validate'], 'require') !== false;
+ $this->require = strpos($input['validate'], 'require') !== false;
}
// Инициализация свойст обьетка
- foreach (array('label', 'name', 'type') as $name) {
- $this->$name = $input[$name];
+ foreach (array('label', 'name', 'type', 'description') as $name) {
+ if (isset($input[$name])) {
+ $this->$name = $input[$name];
+ }
}
}
- function setValue($value)
+ function setValue(/*.any.*/$value)
{
$this->value = $value;
}
+
+ function getId()
+ {
+ return $this->name . '_label';
+ }
}
/**
* Поле ввода Input
- * @package core
*/
class TInput extends TField {
}
+class TCheckbox extends TField
+{
+ public $checked = false;
+ function setValue($value)
+ {
+ $this->value = $value;
+ $this->checked = $value;
+ }
+}
+
+
+class TSelect extends TField
+{
+ public $options = array();
+
+ public function __construct ($input, $factory) {
+ parent::__construct($input, $factory);
+
+ if ($factory != null) {
+ $factory->create($this, $input);
+ } else if (isset($input['options.pair'])) {
+ $this->options = $this->optionsPair($input['options.pair']);
+ } else if (isset($input['options'])) {
+ $this->options = $input['options'];
+ }
+
+ foreach ($this->options as &$option) {
+ $option['selected'] = false;
+ $option['class'] = (isset($option['class'])) ? $option['class'] : false;
+ }
+ }
+
+ public function optionsPair($list, $selected = false) {
+ $result = array();
+ foreach ($list as $key => $value) {
+ $result [] = array('value' => $key, 'name' => $value, 'selected' => $key == $selected);
+ }
+ return $result;
+ }
+}
+
/**
* Выбор из одного элемента
*/
-class TSelect1 extends TField
+class TSelectOne extends TSelect
{
- public $options = array ();
- public function __construct ($input) {
- parent::__construct($input);
- $this->options = $input['options'];
- }
-
function setValue($value)
{
// Установить selected у options
$this->value = $value;
+ foreach ($this->options as &$option) {
+ $option['selected'] = ($option['value'] == $value);
+ }
+ }
+}
+
+class TSelectMany extends TSelect
+{
+ function setValue($value)
+ {
+ // Установить selected у options
+ if (!is_array($value)) { $value = array($value); }
+ $this->value = $value;
+ foreach ($this->options as &$option) {
+ $option['selected'] = (in_array($option['value'], $value));
+ }
+ }
+}
+
+class TQuestionType extends TSelect
+{
+ function setValue($value)
+ {
+ // Установить selected у options
+ $this->value = $value;
+ foreach ($this->options as &$option) {
+ $option['selected'] = ($option['value'] == $value);
+ }
}
}
/**
* Поле с датой
- * @package core
*/
class TDate extends TField
{
}
-/* *
+/**
+ * Поле с цветом
+ */
+class TColor extends TField
+{
+}
+
+
+/**
* Текстовое поле
- * @package core
*/
class TTextArea extends TField
{
+ function setValue($value)
+ {
+ $this->value = $value;
+ }
}
/**
* Поле для ввода пароля
- * @package core
*/
class TSecret extends TField
{
@@ -91,62 +170,181 @@ class TUpload extends TField
{
}
+class THidden extends TInput {
+ public $hidden = true;
+}
+
+class TComponentBrowserInput extends TInput
+{
+}
+
+/**
+ * При рендеринге каждому классу соответствует шаблон (см. themes/maxim/templates/macros.html)
+ */
+class TDateTime extends TInput {
+}
+
+class OptionFactory {
+ public $db;
+
+ function __construct($db) {
+ $this->db = $db;
+ }
+
+ function create(TSelect $field, $input) {
+ if (isset($input['options.resid'])) {
+ $type = $input['options.resid'];
+
+ $res = new Model_Resources($this->db);
+ $field->options = $this->optionsArray('id_section', 'title', $res->getSubsections('', $type));
+
+ } else if (isset($input['options.res'])) {
+ $type = $input['options.res'];
+
+ $res = new Model_Resources($this->db);
+ $field->options = $this->optionsArray('path', 'title', $res->getSubsections('', $type));
+
+ } else if (isset($input['options.all_res'])) {
+ $type = $input['options.all_res'];
+
+ $res = new Model_Resources($this->db);
+ $field->options = $this->optionsArray('id_resource', 'subtitle', $res->getAllResource($type));
+
+ } else if (isset($input['options.db'])) {
+ list($table, $keyvalue) = explode(":", $input['options.db']);
+ list($key, $value) = explode(",", $keyvalue);
+
+ $field->options = $this->optionsDB($key, $value, $this->db->executeQuery("SELECT * FROM $table"));
+ } elseif (isset($input['options.pair'])) {
+ $field->options = $this->optionsPair($input['options.pair']);
+ } else {
+ $field->options = $input['options'];
+ }
+ }
+
+ public function optionsDB($key, $val, $res) {
+ $result = array();
+ while($res->next()) {
+ $result[] = array('value' => $res->getInt($key), 'name' => $res->getString($val));
+ }
+ return $result;
+ }
+
+ public function optionsArray($key, $val, $res) {
+ $result = array();
+ foreach($res as $item) {
+ $result[] = array('value' => $item->{$key}, 'name' => $item->{$val});
+ }
+ return $result;
+ }
+
+ public function optionsPair($list, $selected = false) {
+ $result = array();
+ foreach ($list as $key => $value) {
+ $result [] = array('value' => $key, 'name' => $value, 'selected' => $key == $selected);
+ }
+ return $result;
+ }
+}
+
/**
* Форма для ввода
- * @package core
*/
-class Form_Form
-{
- public $field = array ();
+class Form_Form extends View_View {
+ public $field = array();
public $action = "";
public $method = 'post';
+ public $header;
+
protected $replace;
protected $before;
+
+ public $_title = array();
+ public $alias = array();
+ public $constructor = array();
- public function __construct ()
+ /**
+ * Строим форму по ее структуре. Каждому типу соответствует определенный класс.
+ */
+ public function __construct()
{
- $this->constructor = array (
- 'input' => 'TInput',
- 'date' => 'TDate',
- 'textarea' => 'TTextArea',
- 'select' => 'TSelect',
- 'select1' => 'TSelect1',
- 'secret' => 'TSecret',
- 'upload' => 'TUpload'
+ $this->constructor = array(
+ 'input' => 'TInput',
+ 'inputreq' => 'TInput', // input с проверкой на заполненность
+
+ 'date' => 'TDate',
+ 'datereq' => 'TDate',
+ 'datetime' => 'TDateTime',
+
+ 'color' => 'TColor',
+ 'textarea' => 'TTextArea',
+ 'text' => 'TTextArea',
+ 'multiselect' => 'TSelectMany',
+// 'selectmany' => 'TSelectMany',
+ 'select1' => 'TSelectOne',
+ 'select' => 'TSelectOne',
+ 'questiontype'=> 'TQuestionType',
+ 'secret' => 'TSecret',
+ 'upload' => 'TUpload',
+ 'image' => 'TUpload',
+ 'checkbox' => 'TCheckbox',
+ 'checkmany' => 'TSelectMany',
+ 'hidden' => 'THidden',
+ 'radio' => 'TSelectOne',
+ 'filebrowser' => 'TComponentBrowserInput',
);
+
}
+
+ function getId()
+ {
+ return '_form_edit';
+ }
+
+ public function addFieldClass($name, $class)
+ {
+ $this->constructor [$name] = $class;
+ }
/**
* Добавляет одно поле ввода на форму
*/
- public function addField (array $init)
+ public function addField(array $init, $factory = null)
{
- assert (isset($init['type']));
- assert (isset($init['name']));
+ assert(isset($init['type']));
+ assert(isset($init['name']));
+
+// print_r($init);
$constructor = $this->constructor[$init['type']];
- $el = new $constructor ($init);
- $el->type = $init['type'];
+ $el = new $constructor($init, $factory);
+ if (!$el->type) {
+ $el->type = $init['type'];
+ }
+ if(isset($init['hint'])) {
+ $el->hint = $init['hint'];
+ }
+
$this->field [$init['name']] = $el;
return $el;
}
/**
- * Добавляет спсок полей для формы
+ * Добавляет список полей для формы
* @param array $list
*/
- public function addFieldList (array $list)
+ public function addFieldList(array $list, $factory = null)
{
foreach ($list as $init) {
- $this->addField ($init);
+ $this->addField($init, $factory);
}
}
/**
* Устанавливает ошибки после проверки
*/
- function setError (Validator $validator)
+ function setError(Validator_Validator $validator)
{
foreach ($validator->getErrorMsg() as $name => $error)
{
@@ -155,12 +353,18 @@ class Form_Form
}
}
+ function setFieldError($name, $message)
+ {
+ $this->field[$name]->error = true;
+ $this->field[$name]->error_msg = $message;
+ }
+
/**
* Устанавливает значения из масива
*/
- function setValues (Collection $request) {
+ function setValues(HttpRequest $request) {
foreach ($this->field as $key => $el) {
- $value = $request->getRawData ($this->method, $key);
+ $value = $request->getRawData($this->method, $key);
$this->field[$key]->setValue($value);
}
}
@@ -170,10 +374,11 @@ class Form_Form
* @param object $data
* @param array $schema Связь между элементами формы и свойствами обьекта
*/
- public function fill ($data, array $schema)
+ public function fill($data, array $schema)
{
- foreach ($schema as $key => $value) {
- $this->field [$value]->setValue($data->$value->getString ());
+ foreach ($schema as $key => $conv) {
+ list($value, $type) = $conv;
+ $this->field [$key]->setValue(call_user_func(array('Primitive', 'from_' . $type), $data->$value));
}
}
@@ -181,4 +386,9 @@ class Form_Form
{
$this->field[$name]->setValue($value);
}
+
+ function execute()
+ {
+ return $this;
+ }
}
diff --git a/src/Primitive.php b/src/Primitive.php
index e9dab1a..aec45fd 100644
--- a/src/Primitive.php
+++ b/src/Primitive.php
@@ -1,103 +1,119 @@
name = $name;
+ return ((string) $value);
}
- // Преобразование из внешнего вормата
- public function setString ($value)
+ public static function from_varchar($value)
{
- $this->value = $value;
+ return $value;
}
- // Преобразование из формата базы данных
- public function setRes ($res, $key)
+ // int
+ public static function to_bool($value)
{
- $this->value = $res->getString ($key);
+ return filter_var($value, FILTER_VALIDATE_BOOLEAN);//(int)((bool) $value);
}
- public function __toString ()
+ public static function from_bool($value)
{
- return ((string) $this->value);
+ return ((bool) $value);
}
- // Преобразование во внешний формат
- public function getString ()
+ // int
+ public static function to_int($value)
{
- return $this->__toString ();
- }
-}
-
-/**
- * Отображение поля таблицы в целое число
- * @package core
- */
-class Int4 extends Primitive {
- public function setRes ($res, $key) {
- $this->value = $res->getInt ($key);
+ return ((int) $value);
}
- public function setString ($value) {
- $this->value = ((int) $value);
- }
-}
-
-/* Foreign key */
-class FKey extends Int4 {}
-
-/**
- * Отображение поля таблицы в дату - время
- */
-class Date extends Primitive
-{
- public function setRes ($res, $key)
+ public static function from_int($value)
{
- $this->value = $res->getInt ($key);
+ return ((string) $value);
}
-
- public function setString ($value)
+
+ // date
+ public static function to_date($value)
{
- $this->value = 0;
- if ($tmp = explode("/",$value,3)) {
- if ($tmp[1] && $tmp[0] && $tmp[2]) {
- if (checkdate($tmp[1], $tmp[0], $tmp[2])) {
- $this->value = mktime(0, 0, 0, $tmp[1], $tmp[0], $tmp[2]);
+ $result = 0;
+ $tmp = explode("/", $value, 3);
+ if (!empty($tmp)) {
+ if (count($tmp) != 3) return $result;
+
+ $year = intval($tmp[2]);
+ $month = intval($tmp[1]);
+ $day = intval($tmp[0]);
+
+ if ($month != 0 && $day != 0 && $year != 0) {
+ if (checkdate($month, $day, $year)) {
+ return mktime(0, 0, 0, $month, $day, $year);
+ } else {
+ return 0;
}
}
}
+ return $result;
}
- public function getString ()
+ public static function to_datetime($value)
{
- return date ("d/m/Y", $this->value);
+ $result = 0;
+
+ $tmp = array();
+ if (preg_match('/(\d+)-(\d+)-(\d+)T(\d+):(\d+)Z/', $value, $tmp)) {
+ if (checkdate($tmp[2], $tmp[3], $tmp[1])) {
+ $result = mktime($tmp[4], $tmp[5], 0, $tmp[2], $tmp[3], $tmp[1]);
+ }
+ }
+ return $result;
+ }
+
+ public static function from_date($value)
+ {
+ if ($value > 0) {
+ return date("d/m/Y", $value);
+ }
+ return '';
+ }
+
+ public static function from_datetime($value)
+ {
+ if ($value > 0) {
+ return date("Y-m-d\TH:i\Z", $value);
+ }
+ return '';
+ }
+
+
+ // secure
+ public static function to_secure($value)
+ {
+ // Значение приабразуется во время сохранения в базе данных
+ return $value;
+ }
+
+ public static function from_secure($value)
+ {
+ return $value;
+ }
+
+ // array
+ public static function to_array($value)
+ {
+ return (is_array($value)) ? $value : array();
+ }
+
+ public static function from_array($value)
+ {
+ return $value;
}
}
-/**
- *
- */
-class Password extends Primitive
-{
- public function setRes ($res, $key)
- {
- $this->value = $res->getString($key);
- }
-
- public function setString ($value)
- {
- $this->value = md5($value);
- }
-
- public function getString ()
- {
- return $this->value;
- }
-}
diff --git a/src/Tools/String.php b/src/Tools/String.php
index 1745b25..32aeb3b 100644
--- a/src/Tools/String.php
+++ b/src/Tools/String.php
@@ -1,53 +1,107 @@
0) { // already in sub-array?
- $subarr[$in_subarr][] = $tok;
- if ('}' === substr($tok, -1, 1)) { // check to see if we just added last component
- $res[] = $this->strToArray(implode(',', $subarr[$in_subarr]));
- $in_subarr--;
- }
- } elseif ($tok{0} === '{') { // we're inside a new sub-array
- if ('}' !== substr($tok, -1, 1)) {
- $in_subarr++;
- // if sub-array has more than one element
- $subarr[$in_subarr] = array();
- $subarr[$in_subarr][] = $tok;
- } else {
- $res[] = $this->strToArray($tok);
- }
- } else { // not sub-array
- $val = trim($tok, '"'); // remove " (surrounding strings)
- // perform type castng here?
- $res[] = $val;
- }
- }
-
- return $res;
- }
-
-
- static function translit($st) {
- $st = strtr($st,"абвгдеёзийклмнопрстуфхъыэ !№", "abvgdeeziyklmnoprstufh_ie__#");
- $st = strtr($st,"АБВГДЕЁЗИЙКЛМНОПРСТУФХЪЫЭ", "ABVGDEEZIYKLMNOPRSTUFH_IE");
- $st = strtr($st, array(
- "ж"=>"zh", "ц"=>"ts", "ч"=>"ch", "ш"=>"sh",
- "щ"=>"shch","ь"=>"", "ю"=>"yu", "я"=>"ya",
- "Ж"=>"ZH", "Ц"=>"TS", "Ч"=>"CH", "Ш"=>"SH",
- "Щ"=>"SHCH","Ь"=>"", "Ю"=>"YU", "Я"=>"YA",
- "ї"=>"i", "Ї"=>"Yi", "є"=>"ie", "Є"=>"Ye"
- ));
- return $st;
- }
+// from creole
+function strToArray($str) {
+ $str = substr($str, 1, -1); // remove { }
+ $res = array();
+
+ $subarr = array();
+ $in_subarr = 0;
+
+ $toks = explode(',', $str);
+ foreach($toks as $tok) {
+ if ($in_subarr > 0) { // already in sub-array?
+ $subarr[$in_subarr][] = $tok;
+ if ('}' === substr($tok, -1, 1)) { // check to see if we just added last component
+ $res[] = strToArray(implode(',', $subarr[$in_subarr]));
+ $in_subarr--;
+ }
+ } elseif ($tok{0} === '{') { // we're inside a new sub-array
+ if ('}' !== substr($tok, -1, 1)) {
+ $in_subarr++;
+ // if sub-array has more than one element
+ $subarr[$in_subarr] = array();
+ $subarr[$in_subarr][] = $tok;
+ } else {
+ $res[] = strToArray($tok);
+ }
+ } else { // not sub-array
+ $val = trim($tok, '"'); // remove " (surrounding strings)
+ // perform type castng here?
+ $res[] = $val;
+ }
+ }
+
+ return $res;
+}
+
+//Нормализация строк на русском
+function normalizeRussian($str) {
+ $result = preg_replace('/\s+/',' ', $str);
+ if (is_string($result)) {
+ $result = trim($result); //Замена длинных пробелов на одинарные, пробелы по краям
+ $result = mb_strtolower($result);
+ $result = preg_replace('/ё/','е', $str); //е на ё
+ }
+ return $result;
+}
+
+//Проверка равенства двух строк на русском языке.
+function equalRussianCheck($str1,$str2) {
+ return normalizeRussian($str1) == normalizeRussian($str2);
+}
+
+
+/**
+ * Попадает ли строка в список вариантов
+ * input: $str="foo1" $variants="foo1|foo2|foo3"
+ * output: true
+ * input: $str="foo" $variants="foo1|foo2|foo3"
+ * output: false
+*/
+function compare_string_to_variants($str, $variants){
+ $variants_array = explode('|', $variants);
+ $founded = false;
+ foreach ($variants_array as $variant) {
+ $founded = $founded || equalRussianCheck($variant, $str);
+ }
+ return $founded;
+}
+
+function mb_str_split($str) {
+ return preg_split('~~u', $str, null, PREG_SPLIT_NO_EMPTY);
+}
+
+function mb_strtr($str, $from, $to) {
+ return str_replace(mb_str_split($from), mb_str_split($to), $str);
+}
+
+function encodestring($st) {
+ $st = mb_strtr($st,"абвгдеёзийклмнопрстуфхъыэ !+-()", "abvgdeeziyklmnoprstufh_ie______");
+ $st = mb_strtr($st,"АБВГДЕЁЗИЙКЛМНОПРСТУФХЪЫЭ", "ABVGDEEZIYKLMNOPRSTUFH_IE");
+ $st = strtr($st, array(
+ " " => '_',
+ "." => '_',
+ "," => '_',
+ "?" => '_',
+ "\"" => '_',
+ "'" => '_',
+ "/" => '_',
+ "\\" => '_',
+ "%" => '_',
+ "#" => '_',
+ "*" => '_',
+ "ж"=>"zh", "ц"=>"ts", "ч"=>"ch", "ш"=>"sh",
+ "щ"=>"shch","ь"=>"", "ю"=>"yu", "я"=>"ya",
+ "Ж"=>"ZH", "Ц"=>"TS", "Ч"=>"CH", "Ш"=>"SH",
+ "Щ"=>"SHCH","Ь"=>"", "Ю"=>"YU", "Я"=>"YA",
+ "Й"=>"i", "й"=>"ie", "ё"=>"Ye",
+ "№"=>"N"
+ ));
+ return strtolower($st);
+}
+
+function validate_encoded_string($st) {
+ $enc_st = encodestring($st);
+ return preg_match('/^[\w_-]+(\.[\w_-]+)?$/', $enc_st);
}
diff --git a/src/Validator/Rule/Alpha.php b/src/Validator/Rule/Alpha.php
index 02b422e..2443da1 100644
--- a/src/Validator/Rule/Alpha.php
+++ b/src/Validator/Rule/Alpha.php
@@ -3,7 +3,7 @@
/**
* Проверка на число
*/
-class Validator_Rule_Alpha extends Rule_Abstract
+class Validator_Rule_Alpha extends Validator_Rule_Abstract
{
public function getErrorMsg()
{
diff --git a/src/Validator/Rule/Date.php b/src/Validator/Rule/Date.php
index 8b40b4d..be8e17e 100644
--- a/src/Validator/Rule/Date.php
+++ b/src/Validator/Rule/Date.php
@@ -3,7 +3,7 @@
/**
* Проверка формата даты
*/
-class Validator_Rule_Date extends Rule_Abstract
+class Validator_Rule_Date extends Validator_Rule_Abstract
{
private $split = "\\/";
diff --git a/src/Validator/Rule/Email.php b/src/Validator/Rule/Email.php
index e40486a..dd2b0e0 100644
--- a/src/Validator/Rule/Email.php
+++ b/src/Validator/Rule/Email.php
@@ -3,7 +3,7 @@
/**
* Проверка формата электронной почты
*/
-class Validator_Rule_Email extends Rule_Abstract
+class Validator_Rule_Email extends Validator_Rule_Abstract
{
public function getErrorMsg()
{
diff --git a/src/Validator/Rule/EmailList.php b/src/Validator/Rule/EmailList.php
index 16bdd50..98ac122 100644
--- a/src/Validator/Rule/EmailList.php
+++ b/src/Validator/Rule/EmailList.php
@@ -3,7 +3,7 @@
/**
* Проверка формата электронной почты
*/
-class Validator_Rule_EmailList extends Rule_Abstract
+class Validator_Rule_EmailList extends Validator_Rule_Abstract
{
public function getErrorMsg()
{
diff --git a/src/Validator/Rule/Match.php b/src/Validator/Rule/Match.php
index c3fdcdf..eb37a82 100644
--- a/src/Validator/Rule/Match.php
+++ b/src/Validator/Rule/Match.php
@@ -3,7 +3,7 @@
/**
* Проверка на равентство двух полей
*/
-class Validator_Rule_Match extends Rule_Abstract
+class Validator_Rule_Match extends Validator_Rule_Abstract
{
public $same;
@@ -12,14 +12,6 @@ class Validator_Rule_Match extends Rule_Abstract
return "Поля не совпадают";
}
-/* public function __construct($field, $refField, $errorMsg)
- {
- $this->field = $field;
- $this->refField = $refField;
- $this->errorMsg = $errorMsg;
- }
-*/
-
public function isValid(Collection $container, $status = null) {
return (strcmp($container->get($this->field), $container->get($this->same)) == 0);
}
diff --git a/src/Validator/Rule/Numeric.php b/src/Validator/Rule/Numeric.php
index 86b2bc2..2d080e7 100644
--- a/src/Validator/Rule/Numeric.php
+++ b/src/Validator/Rule/Numeric.php
@@ -3,7 +3,7 @@
/**
* Проверка на число
*/
-class Validator_Rule_Numeric extends Rule_Abstract
+class Validator_Rule_Numeric extends Validator_Rule_Abstract
{
public function getErrorMsg()
{
diff --git a/src/Validator/Rule/Time.php b/src/Validator/Rule/Time.php
index b343a84..05a7a46 100644
--- a/src/Validator/Rule/Time.php
+++ b/src/Validator/Rule/Time.php
@@ -3,7 +3,7 @@
/**
* Проверка формата времени
*/
-class Validator_Rule_Time extends Rule_Abstract
+class Validator_Rule_Time extends Validator_Rule_Abstract
{
private $split = ":";
diff --git a/src/Validator/Rule/Unique.php b/src/Validator/Rule/Unique.php
index fe97a07..e458b8d 100644
--- a/src/Validator/Rule/Unique.php
+++ b/src/Validator/Rule/Unique.php
@@ -1,9 +1,8 @@
ctx->isUnique($container->get($this->field), $status);
+ return $this->ctx->isUnique($container->get($this->field), $status, $container);
}
}
diff --git a/src/Validator/Validator.php b/src/Validator/Validator.php
index 4f053a4..fe3ea2e 100644
--- a/src/Validator/Validator.php
+++ b/src/Validator/Validator.php
@@ -32,7 +32,8 @@ class Validator_Validator
'require' => 'Validator_Rule_Notnull',
'numeric' => 'Validator_Rule_Numeric',
'unique' => 'Validator_Rule_Unique',
- 'count' => 'Validator_Rule_Count',
+ 'filename' => 'Validator_Rule_FileName',
+ 'count' => 'Validator_Rule_Count',
'isfile' => 'Validator_Rule_IsFile',
'code' => 'Validator_Rule_Code'
);
@@ -41,8 +42,7 @@ class Validator_Validator
// Формат правила 'rule1|rule2,param1=value1|rule3,param1=value1,param2=value2'
foreach ($input as $value) {
// Список правил
- if (!isset($value['validate']) || $value['validate'] == '') continue;
-
+ if (! isset($value['validate'])) continue;
$rules = explode("|", $value['validate']);
foreach ($rules as $rule) {
// Список параметров правила
@@ -50,17 +50,17 @@ class Validator_Validator
$name = array_shift($rule_param);
if (isset($type[$name])) {
- $constructor = $type[$name]; // "Rule_" . ucfirst($name)
- $rule = new $constructor($value['name'], false); // Нужны шаблонные сообщения для правил
+ $constructor = $type[$name];
+ $ruleObj = new $constructor($value['name'], false); // Нужны шаблонные сообщения для правил
if (isset($value['context'])) {
- $rule->setContext($value['context']);
+ $ruleObj->setContext($value['context']);
}
foreach ($rule_param as $param) {
// Имя и значение параметра
- list($name, $value) = explode("=", $param);
- $rule->$name = $value;
+ list($p_name, $p_value) = explode("=", $param);
+ $ruleObj->$p_name = $p_value;
}
- $this->addRule($rule);
+ $this->addRule($ruleObj);
} else {
throw new Exception('Unknown validation rule "' . $rule . "'");
}
@@ -90,14 +90,17 @@ class Validator_Validator
public function validate(Collection $container, $rule = null, $status = null)
{
+ $fields = array();
if ($rule) {
$this->chain = $rule;
}
$this->errorMsg = array();
- foreach ($this->chain as $key => $rule) {
- if (!$this->skip($rule, $container) && !$rule->isValid($container, $status)) {
+ foreach ($this->chain as $rule) {
+ //echo $key;
+ if (!in_array($rule->field, $fields) && !$this->skip($rule, $container) && !$rule->isValid($container, $status)) {
$name = $rule->field;
$this->errorMsg[$name] = $rule->getErrorMsg();
+ $fields [] = $name;
}
}
return $this->isValid();
diff --git a/src/View/Composite.php b/src/View/Composite.php
index e9427a6..0a21508 100644
--- a/src/View/Composite.php
+++ b/src/View/Composite.php
@@ -1,36 +1,37 @@
tal = new PHPTAL($file);
+ $this->tal->setPhpCodeDestination(PHPTAL_PHP_CODE_DESTINATION);
+ $this->tal->setEncoding(PHPTAL_DEFAULT_ENCODING); // PHPTAL_DEFAULT_ENCODING !!
+ $this->tal->setTemplateRepository(PHPTAL_TEMPLATE_REPOSITORY);
+ $this->tal->setOutputMode(PHPTAL::HTML5);
$this->tal->stripComments(true);
+// $this->tal->addPreFilter(new PHPTAL_PreFilter_Normalize());
}
- function set($key, $val)
- {
+ function set($key, $val) {
if ($key == 'title') {
$this->setTitle($val);
}
$this->tal->set($key, $val);
}
- function __set($key, $val)
- {
+ function __set($key, $val) {
$this->tal->set($key, $val);
}
- function setTranslator($tr)
- {
- $this->tal->setTranslator($tr);
- }
-
function execute()
{
parent::execute();
diff --git a/src/View/Top.php b/src/View/Top.php
index 776d6d4..95bbff5 100644
--- a/src/View/Top.php
+++ b/src/View/Top.php
@@ -1,88 +1,139 @@
_section [$section] = $view;
+ return implode(" - ", array_filter($this->doTree('_title', false), array($this, 'isNotNull')));
}
- public function jGrowl($message, $args)
+ private function findGroup($groups, $file)
{
- $this->addScriptRaw('$.jGrowl("' . $message . '", ' . json_encode($args) . ");\n", true);
- }
-
- public function setGlobal($name, $args)
- {
- $this->addScriptRaw("var " . $name . " = " . json_encode($args) . ";\n", false);
- }
-
- /**
- * Добавляет скипт к текущему шаблону
- *
- * @param string $name путь к скрипту
- */
- public function addScript($name)
- {
- $this->_script [] = $name;
- }
-
- /**
- * Добавляет код скипта к текущему шаблону
- *
- * @param string $name строка javascript кода
- */
- public function addScriptRaw($name, $startup = false)
- {
- if ($startup) {
- $this->_startup [] = $name;
- } else {
- $this->_scriptstring [] = $name;
+ foreach($groups as $key => $group) {
+ if(in_array($file, $group)) {
+ return $key;
+ }
}
+ return false;
}
+ private function groupFiles(array $list, $debug = true)
+ {
+ $debug = ($debug) ? 'debug=1' : '';
+ $path = parse_url(WWW_PATH, PHP_URL_PATH);
+ // Группы определять в import через ,
+ $groups = array( );
+ $use = array();
+
+ $result = array();
+ foreach ($list as $file) {
+ $name = $this->findGroup($groups, $file);
+ if($name) {
+ $use [$name] = 1;
+ } else {
+ if (strpos($file, 'ckeditor')) {
+ $result [] = $file;
+ } else {
+// $result [] = WWW_PATH . "/min/?$debug&f=" . parse_url($file, PHP_URL_PATH);
+ $result [] = $file;
+ }
+ }
+ }
+ $list = array();
+ foreach ($use as $name => $value) {
+// $list [] = WWW_PATH . "/min/?$debug&f=" . implode(",", $groups[$name]);
+ $list [] = $groups[$name];
+ }
+
+ return array_merge($list, $result);
+ }
+
+
+ function getId($pref) {
+ $this->mid++;
+ return $pref.$this->mid;
+ }
+
/**
- * Добавляет стили к текущему шаблону
- *
- * @param string $name путь к стилю
- */
- public function addStyleSheet($name)
- {
- $this->_stylesheet [] = $name;
- }
-
- /**
- * Рекурсивно извлекает из значение свойства обьекта
+ * Обработка шаблона
*
- * @param string $list Имя свойства
- * @param boolean $flatten
+ * @return string
*/
- private function doTree($list, $flatten = true) {
- $result = ($flatten == true) ? $this->$list : array($this->$list);
- foreach ($this->_section as $key => $value) {
- if (is_object($value)) $result = array_merge($value->doTree($list, $flatten), $result);
- }
- return $result;
+ public function render()
+ {
+
+ $alias = $this->doTree('alias');
+
+// require_once 'minify.php';
+ // Скрипты и стили
+ $this->set('scriptstring', $this->getScriptRaw());
+ $this->set('scripts', array_unique($this->groupFiles($this->getScripts(), false)));
+ $this->set('stylesheet', array_unique($this->groupFiles($this->getStyleSheet(), false)));
+
+ $this->require = array('admin' => 'ma');
+ $this->deps = array();
+
+ $startup = array();
+ foreach($this->_section as $s) {
+ $module = explode('_', $s->active_module, 2);
+ if (count($module) < 2) {
+ continue;
+ }
+
+ $module = $module[1];
+
+ $name = mb_strtolower($module);
+ $fname = $name . '/' . $name;
+
+ $current = $this->getId('m');
+ $this->require[$fname] = $current;
+
+ $value = $this->getId('v');
+
+ $script = "var " . $value . " = new " . $current . '.' . $module . "();\n";
+ foreach($s->_values as $key => $v) {
+ $script .= $value . "." . $key . " = " . json_encode($v/*, JSON_PRETTY_PRINT*/) . ";\n";
+ }
+
+ $init = array();
+ foreach($s->_section as $key => $item) {
+ /*.View_View.*/$ss = $item;
+ if ($ss->codeGenerator !== null) {
+ // функцию которая вычисляет а не результат
+ $part = call_user_func($ss->codeGenerator, $this, $key, $value);
+ $init [] = $part;
+ }
+ }
+
+ $script .= $value . ".execute('" . $s->module_action . "', " . json_encode($init) .");\n";
+ $startup[] = $script;
+
+ }
+
+
+/* echo "
";
+ print_r($this->require);
+ print_r(implode("", $startup));
+ echo "";*/
+
+ //$this->set('scriptstring', '');
+ $this->set('startup', implode("", $startup) . $this->getScriptStartup());
+
+
+ $this->set('require', implode(",", array_map(function ($x) { return "'$x'";}, array_keys($this->require))));
+ $this->set('deps', implode(",", array_values($this->require)));
+
+
+ $this->set('title', $this->getTitle());
+ $this->set('jspath', WWW_PATH);
+ //
+ return $this->execute(); // execute+phptal ??
}
/**
@@ -95,15 +146,6 @@ class View_Top // AbstractCompositeView
return $this->doTree('_script');
}
- function resolveAlias($alias, $list)
- {
- $result = array();
- foreach($list as $item) {
- $result [] = strtr($item, $alias);
- }
- return $result;
- }
-
/**
* Строка со скриптом
*
@@ -119,10 +161,6 @@ class View_Top // AbstractCompositeView
return implode("\n", $this->doTree('_startup'));
}
- /*abstract*/ public function set($key, $value)
- {
- }
-
/**
* Массив имен файлов стилей
*
@@ -132,128 +170,5 @@ class View_Top // AbstractCompositeView
{
return $this->doTree('_stylesheet');
}
-
- /**
- * Обработка всех вложенных шаблонов
- *
- * @return string
- */
- public function execute()
- {
- foreach ($this->_section as $key => $value) {
- $this->set($key, (is_object($value)) ? $value->execute() : $value); // ?
- }
- }
- /**
- * Установка заголовка шаблона
- *
- * @param string $title
- */
- public function setTitle($title)
- {
- $this->_title = $title;
- }
-
- private function isNotNull($title)
- {
- return $title !== null;
- }
-
- /**
- * Общая строка заголовка
- */
- public function getTitle()
- {
- return implode(" - ", array_filter($this->doTree('_title', false), array($this, 'isNotNull')));
- }
-
- private function findGroup($groups, $file)
- {
- foreach($groups as $key => $group) {
- if(in_array($file, $group)) {
- return $key;
- }
- }
- return false;
- }
-
- private function groupFiles(array $list, $debug)
- {
- $debug = ($debug) ? 'debug=1' : '';
- $path = parse_url(WWW_PATH, PHP_URL_PATH);
- $list = array_reverse($list);
- // Группы нужно передвавать как параметр !!!
- $groups = array(
- 'table' => array($path . '/js/table.js', $path . '/js/listtable.js',
- $path . '/js/page.js', $path . '/js/pagemenu.js'),
- 'base' => array($path . '/js/admin.js', $path . '/js/cookie.js'),
- );
- $use = array();
-
- $result = array();
- foreach ($list as $file) {
- $name = $this->findGroup($groups, $file);
- if($name) {
- $use [$name] = 1;
- } else {
- $result [] = $file;
- }
- }
- $list = array();
- foreach ($use as $name => $value) {
- $list [] = WWW_PATH . "/min/?$debug&f=" . implode(",", $groups[$name]);
- }
- return array_merge($list, $result);
- }
-
- /**
- * Обработка шаблона
- *
- * @return string
- */
- public function render()
- {
-
- $alias = $this->doTree('alias');
-
-// require_once 'minify.php';
- // Скрипты и стили
- $this->set('scripts', array_unique($this->groupFiles($this->resolveAlias($alias, $this->getScripts()), false)));
- $this->set('stylesheet', array_unique($this->groupFiles($this->resolveAlias($alias, $this->getStyleSheet()), false)));
-
- $this->set('scriptstring', $this->getScriptRaw());
- $this->set('startup', $this->getScriptStartup());
- $this->set('title', $this->getTitle());
- //
- return $this->execute(); // execute+phptal ??
- }
-
- function setAlias($alias)
- {
- $this->alias = $alias;
- }
-
- function addAlias($name, $path)
- {
- $this->alias['${' . $name . '}'] = $path;
- $this->set($name, $path);
- }
-
- function loadImports($importFile)
- {
- // Подключение стилей и скриптов
- if (file_exists($importFile)) {
- $import = file_get_contents($importFile);
- $files = explode("\n", $import);
- foreach ($files as $file) {
- if (strpos($file, ".js") !== false) {
- $this->addScript(strtr(trim($file), $this->alias));
- } else if(strpos($file, ".css") !== false) {
- $this->addStyleSheet(strtr(trim($file), $this->alias));
- }
- }
- }
- }
}
-