Commit d73d995b authored by John Fox Woland's avatar John Fox Woland
Browse files

* site/handler/*.php -> site/tpl/pioneer.page-*.tpl

- site/handler/stub.php - за ненадобностью
- site/handler - устарело
- mod_handler::mk_handler_path
- mod_handler::render
* Новая структура БД: mod_handler, mod_tpl, - mod_dbpage
* mod_tpl: изменилось назначение. Теперь его задача вытаскивать и отдавать содержимое шаблона из бд или файла в соответствии с путём
+ Класс для работы с постгрес-специфичными фичами
+ mod_ilj::render
* mod_ilj::parse стала приватной. Весь парсинг должен делаться через render
+ mod_ilj::state - массив параметров: вложенность, путь вложения
+ mod_ilj: перед обработкой тэга в массив параметров добавляется "parser-state" - массив внутренних переменных экземпляра парсера
- mod_ilj::tag_func - ибо нехуй
* Жаваскрипт вынесен из шаблона pioneer в отдельный файл
parent ae813e31
......@@ -5,11 +5,11 @@
// REQS: global:error, module:sql, module:lang ; REG: true ; USES: _SERVER["SCRIPT_NAME"]
class Handler extends Module
{
public $handler_id = null;
public $handler_path = array();
public $handler_parents = null;
public $handler = null;
public $defchild = false;
public $url = null;
public $url = array();
public $urltail = null;
private $error, $mod_sql, $mod_lang, $requested;
......@@ -38,123 +38,41 @@
return true;
}
public function render ($params)
{
return file_get_contents($this->mk_handler_path());
}
private function mk_handler_path ()
{
return "site/handler/{$this->handler}.php";
}
private function set_error ($error)
private function set_error ($error, $cicle = false)
{
/* TODO: + lang + переменная "ошибка" */
$this->requested = "/ошибка/$error/";
$this->error = $error;
$this->handler = "error";
$this->handler_init(true);
}
private function handler_init ()
private function handler_init ($error = false)
{
$this->urltail = split("/", $this->requested);
array_shift($this->urltail);
$current = array_shift($this->urltail);
if (strcmp($current, $this->mod_lang->lang) == 0)
$current = array_shift($this->urltail);
if (!isset($current))
{
$this->set_error(500);
return -1;
}
if (strcmp($this->urltail[0], $this->mod_lang->lang) == 0)
array_shift($this->urltail);
$query = <<<SQL
select handler_id, handler_script
from www.tbl_handler
where parent is NULL
and active = true
and request = :request
SQL;
$this->mod_sql->query($query, array($current));
if ($row = $this->mod_sql->res[0])
{
$this->handler_id = $row['handler_id'];
$this->handler = $row['handler_script'];
$this->url = array($current);
$query = <<<SQL
select handler_id, handler_script
from www.tbl_handler
where parent = :parent
and active = true
and request = :request
SQL;
$this->mod_sql->prepare($query);
/* Найти запрошенный УРЛ */
for ($current = array_shift($this->urltail);
count($this->urltail) && $current;
$current = array_shift($this->urltail)
)
{
$this->mod_sql->execute(array("parent" => $this->handler_id, "request" => $current));
if ($row = $this->mod_sql->res[0])
{
array_push($this->url, $current);
$this->handler_id = $row['handler_id'];
$this->handler = $row['handler_script'];
}
else
break;
}
}
else
if (!count($this->urltail))
array_push($this->urltail, "");
$query = "select * from www.func_get_handler(" . PgSQL::mk_array($this->urltail) . ") as handler_id";
$this->mod_sql->query($query);
foreach ($this->mod_sql->res as $row)
{
$this->set_error(404);
return -1;
array_push($this->url, array_shift($this->urltail));
array_push($this->handler_path, $row["handler_id"]);
}
/* Если у УРЛа есть обработчик, загрузить его */
if ($this->handler)
if (count($this->url))
{
if ($current)
array_unshift($this->urltail, $current);
if (!file_exists($this->mk_handler_path()))
$this->set_error(404);
$this->handler_parents = $this->handler_path;
array_pop($this->handler_parents);
$this->handler =& $this->handler_path[count($this->handler_path) - 1];
}
/* Если обработчика нет, найти под-УРЛ по умолчанию */
else
{
$this->urltail = null;
$query = <<<SQL
select handler_id, handler_script
from www.tbl_handler
where parent = :parent
and active = true
and priority is not NULL
order by priority asc
limit 1
SQL;
$this->mod_sql->query($query, array("parent" => $this->handler_id));
if ($row = $this->mod_sql->res[0])
{
$this->handler_id = $row["handler_id"];
$this->handler = $row["handler_script"];
$this->defchild = true;
if ($this->handler)
{
/* TODO: Предусмотреть два варианта:
1. Прямая подгрузка суб-обработчика по умолчанию
2. Перенаправление клиента на правильный УРЛ
*/
if (!file_exists($this->mk_handler_path()))
$this->set_error(404);
}
}
else
$this->set_error(404);
}
set_error(404, $error);
}
}
?>
\ No newline at end of file
......@@ -4,7 +4,23 @@
{
public $res, $tpl, $tags;
private $footnotes = array();
/* Содержание переменной state - массив со следующими значениями:
- nesting = уровень вложенности парсера
- path = путь вложенности. Содержит все тэги, результат обработки которых парсится, в порядке вложения */
private $footnotes = array(), $state;
public function __construct ($state = null)
{
if ($state)
$this->state = $state;
else
$this->state = array("nesting" => 0, "path" => array());
}
public function render ($params)
{
return $this->parse($params["tpl"]);
}
/* Ссылка на внутренний ресурс*/
private function tag_ilink ($tag)
......@@ -51,18 +67,7 @@
return $GLOBALS[$tag["var"]];
}
/* Выполнить указанную функцию */
private function tag_func ($tag)
{
$func = $tag["func"];
if (function_exists($func))
return $func($tag["params"]);
else
/* TODO: Заменить на универсальное сообщение об ошибке */
return "<i>PARSER WARNING: function <b>$func</b> does not exists</i>";
}
/* Вызвать метод render у модуля
/* Вызвать метод render у модуля
Должен существовать объект класса с указанным именем */
private function tag_module ($tag)
{
......@@ -70,6 +75,7 @@
if ($module)
return $module->render($tag["params"]);
else
/* TODO: Унифицировать сообщения об ошибках, языконезависимость */
return "<i>СООБЩЕНИЕ ПАРСЕРА: не найден модуль '<b>{$tag["module"]}</b>'</i>";
}
......@@ -92,13 +98,23 @@
$keys = array_keys($json);
$func = "tag_{$keys[0]}";
/* FIX: Несколько извращённый способ передачи модулю состояния парсера и ид тэга */
$state = $this->state;
++$state["nesting"];
array_push($state["path"], $json);
if (!$json["params"])
$json["params"] = array();
$json["params"]["parser-state"] = $state;
if (method_exists($this, $func))
{
$res = $this->$func($json);
if ($json["parse"])
{
$ilj = new Ilj();
$res = $ilj->parse($res);
$ilj = new Ilj($state);
$res = $ilj->render(array("tpl" => $res));
$ilj = null;
}
return $res;
......@@ -107,7 +123,7 @@
return $tag;
}
public function parse ($tpl)
private function parse ($tpl)
{
$this->tags = false;
$this->tpl = $tpl;
......
......@@ -58,12 +58,8 @@
private function lang_init ($default)
{
$query = <<<SQL
select lang_id, lang
from www.tbl_lang
where lang = :lang
and visible = true
SQL;
$query = "select lang_id, lang from www.tbl_lang where lang = :lang and visible = true";
$this->mod_sql->prepare($query);
/* Проверяем первый элемент адреса на наличие языка */
......
......@@ -3,8 +3,10 @@
Структура меню:
(
{
request = ссылка элемента
link = ссылка элемента
title = название элемента
handler = ид хандлера
current = относится ли к выбранной ветке
sub = (
{
...
......@@ -66,7 +68,7 @@
if ($elem["id"] == $this->current["id"])
$res .= "<span class='menucurrent'>{$elem["title"]}</a>";
else
$res .= "<a href='{$elem["request"]}'>{$elem["title"]}</a>";
$res .= "<a href='{$elem["link"]}'>{$elem["title"]}</a>";
if (count($elem["sub"]) && ($showsubmenu || $elem["current"]))
$res .= $this->show_menu($elem["sub"], $showsubmenu, $level + 1);
$res .= "</li>";
......@@ -96,21 +98,16 @@
return "$res</div>";
}
private function fill_menu (&$elem, $handled)
private function fill_menu (&$elem)
{
if (count($handled))
$req = array_shift($handled);
else
$req = null;
$this->mod_sql->execute(array("parent" => $elem["id"], "langid" => $this->mod_lang->langid));
foreach ($this->mod_sql->res as $row)
{
$current = false;
if ($elem["current"] && (strcmp($row["request"], $req) == 0))
if (!(array_search($row["handler_id"], $this->mod_handler->handler_path) === false))
$current = true;
array_push($elem["sub"], array("id" => $row["menu_id"], "request" => $elem["request"] . $row["request"] . "/",
array_push($elem["sub"], array("id" => $row["menu_id"], "link" => $elem["link"] . $row["urlpart"] . "/",
"title" => $row["title"], "current" => $current, "sub" => array()));
if ($current)
......@@ -118,21 +115,16 @@
}
foreach ($elem["sub"] as $subelem)
$this->fill_menu($subelem, $handled);
$this->fill_menu($subelem);
}
private function menu_init ()
{
$handled = $this->mod_handler->url;
if (count($handled))
$req = array_shift($handled);
else
$req = "";
$query = <<<SQL
select m.menu_id, m.request, t.title
select m.menu_id, m.handler_id, t.title, h.urlpart
from www.tbl_menu m
join www.tbl_menutitle t using (menu_id)
join www.tbl_handler h using (handler_id)
where m.visible = true
and m.parent is NULL
and t.lang_id = :langid
......@@ -143,11 +135,11 @@ SQL;
foreach ($this->mod_sql->res as $row)
{
$current = false;
if (strcmp($row["request"], $req) == 0)
if (!(array_search($row["handler_id"], $this->mod_handler->handler_path) === false))
$current = true;
array_push($this->menu, array("id" => $row["menu_id"],
"request" => "/{$row["request"]}" . ($row["request"] ? "/" : ""),
"link" => "/{$row["urlpart"]}" . ($row["urlpart"] ? "/" : ""),
"title" => $row["title"], "current" => $current, "sub" => array()));
if ($current)
......@@ -155,9 +147,10 @@ SQL;
}
$query = <<<SQL
select m.menu_id, m.request, t.title
select m.menu_id, m.handler_id, h.urlpart, t.title
from www.tbl_menu m
join www.tbl_menutitle t using (menu_id)
join www.tbl_handler h using (handler_id)
where m.visible = true
and m.parent = :parent
and t.lang_id = :langid
......@@ -166,7 +159,7 @@ SQL;
$this->mod_sql->prepare($query);
for ($i = 0; $i < count($this->menu); $i++)
$this->fill_menu($this->menu[$i], $handled);
$this->fill_menu($this->menu[$i]);
}
}
?>
\ No newline at end of file
<?php
require_once("sql.php");
require_once("pgsql.php");
?>
\ No newline at end of file
<?
// Статический класс для работы с PgSQL
class PgSQL
{
const ARRAY_STR = 1;
const ARRAY_INT = 2;
static function mk_array ($array, $type = self::ARRAY_STR)
{
$res = "";
$delim = "";
foreach ($array as $elem)
{
if ($res)
$delim = ", ";
switch ($type)
{
case self::ARRAY_INT:
if (is_numeric($elem))
$res .= "$delim$elem";
break;
case self::ARRAY_STR:
$res .= "$delim'" . pg_escape_string($elem) . "'";
break;
}
}
if (!$res)
return "null";
$res = "ARRAY[$res]";
return $res;
}
};
?>
\ No newline at end of file
<?php
// REQS: setting:template, global:head, mod:ilj ; REG: true
// REQS: mod:sql, mod:handler ; REG: true
class Tpl extends Module
{
public $head = "";
public $html = "";
private $template, $syshead, $mod_ilj;
private $mod_sql, $mod_handler;
public function reg ()
{
......@@ -14,25 +11,53 @@
public function reqs ()
{
return array (array("type" => "setting", "value" => "template"),
array("type" => "global", "value" => "head"),
array("type" => "module", "value" => "ilj")
return array(array("type" => "module", "value" => "sql"),
array("type" => "module", "value" => "handler")
);
}
public function render ($params)
{
$this->syshead .= $this->head;
/* Ищем путь текущего шаблона по вложенности тэгов */
$path = array();
foreach ($params["parser-state"]["path"] as $container)
{
/* TODO: Возможно, проверять только наличие name */
$keys = array_keys($container);
if ((strcmp($keys[0], "module") == 0) &&
(strcmp($container["module"], "tpl") == 0))
array_push($path, $container["id"]);
else
$path = array();
}
if (!count($path))
return "";
$path = implode(".", $path);
$query = "select content, bodyfile from www.func_get_tpl(:path, :handler, " .
PgSQL::mk_array($this->mod_handler->handler_parents, PgSQL::ARRAY_INT) . ")";
$this->mod_sql->query($query, array("path" => $path, "handler" => $this->mod_handler->handler));
if ($row = $this->mod_sql->res[0])
{
if ($row["content"])
$content = $row["content"];
else if ($row["bodyfile"])
$content = @file_get_contents($row["bodyfile"]);
}
return $this->mod_ilj->parse($this->html);
if ($content)
return $content;
/* TODO: унифицировать сообщения об ошибках, языконезависимость */
return "Не найдено содержимое для шаблона '$path'";
}
public function init ($initvals)
{
$this->template =& $initvals["S_template"];
$this->mod_ilj =& $initvals["mod_ilj"];
$this->syshead =& $initvals["G_head"];
$this->mod_sql =& $initvals["mod_sql"];
$this->mod_handler =& $initvals["mod_handler"];
/*
TODO: Всякая фигня с цссами и проч, которую тоже надо бы подгрузить куда-то
$tpl = "site/tpl/{$this->template}.tpl";
$css = "site/css/{$this->template}.css";
$js = "site/js/{$this->template}.js";
......@@ -51,7 +76,7 @@
if (file_exists($icon))
$this->head .= "<link rel='shortcut icon' href='/$icon' />";
*/
return true;
}
};
......
......@@ -20,9 +20,11 @@
$S_modules_forbid = array();
$S_template = "pioneer";
$S_init_module = "tpl";
/* На самом деле нам надо, чтобы всё начиналось модулем tpl с шаблоном по умолчанию pioneer.
Но шаблон ещё надо распарсить. Поэтому мы передаём контент, вызывающий нужный модуль в ilj. */
$S_init_module = "ilj";
$S_init_params = array("tpl" => '{"module":"tpl","id":"pioneer","parse":true}');
/* Инкладим файл с настоящим паролем. Это чтобы в сабвершене не светить. */
require ("sql_passwd.php");
?>
\ No newline at end of file
<?php
// define ("DEBUG", 1);
define ("DEBUG", 1);
if (defined("DEBUG") && DEBUG)
......
<div id="title">http://fox.perm.ru</div>
<div id="background">Скоро открытие</div>
<table id="contacts">
<tr>
<td align="left">E-mail</td>
<td align="center">JabberId</td>
<td align="right">SIP-Id</td>
</tr>
<tr id="address">
<td colspan="3">fox@fox.perm.ru</td>
</tr>
</table>
\ No newline at end of file
function show_ie_notice ()
{
if (navigator.userAgent.indexOf("MSIE") != -1)
{
var msie = document.getElementById("msie");
if (msie)
msie.style.display = 'inline';
}
}
\ No newline at end of file
......@@ -2,6 +2,8 @@
<html>
<head>
{"var":"G_head","parse":true}
<link rel="stylesheet" type="text/css" href="/site/css/pioneer.css" />
<script language="javascript" type="text/javascript" src="/site/js/pioneer.js"></script>
</head>
<body>
<div id="root">
......@@ -9,7 +11,7 @@
<div id="msie">
<!-- {* TODO: языконезависимость } -->
({"elink":"http://www.opera.com/browser/download/","title":"Скачать Opera"})
R u usin MS IE? Don't do this! // Вы используете MS IE? Перестаньте немедленно!
Вы используете MS Internet Explorer? Перестаньте немедленно!
({"elink":"http://www.mozilla-europe.org/ru/firefox/","title":"Скачать Firefox"})
</div>
<span>&gt; Http://Fox.perm.ru _</span>
......@@ -22,7 +24,7 @@
</div>
<div id="rightcolumn">
<div id="page">
{"module":"handler","parse":true}
{"module":"tpl","id":"page","parse":true}
</div>
</div>
</div>
......@@ -32,12 +34,7 @@
</div>
</div>
<script language="javascript">
if (navigator.userAgent.indexOf("MSIE") != -1)
{
var msie = document.getElementById("msie");
if (msie)
msie.style.display = 'inline';
}
show_ie_notice();
</script>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment