Частичная синхронизация с CMS

This commit is contained in:
origami11 2017-02-17 16:22:44 +03:00
parent 312f18a20a
commit b26e521657
62 changed files with 827 additions and 5992 deletions

View file

@ -8,18 +8,23 @@ class Connection_HttpRequest
private $param = array(); // Параметры запроса
public $data = null; // Содержание
public $url; // Адресс
public $method = self::GET; // Метод
public $method; // Метод
public $port = 80;
public $host = "";
public $proxy_host = false;
public $proxy_port = false;
public $proxy_host = null;
public $proxy_port = null;
public $http_version = 'HTTP/1.1';
function __construct() {
$this->method = self::GET;
}
/**
* Возвращает заголовок соединения
*/
public function getHeader()
{
$result = $this->method . " " . $this->url . " HTTP/1.1\r\n";
$result = $this->method . " " . $this->url . " " . $this->http_version . "\r\n";
$result .= "Host: ". $this->host ."\r\n";
foreach ($this->param as $key => $value) {
$result .= $key . ": " . $value . "\r\n";
@ -74,10 +79,10 @@ class Connection_HttpRequest
{
$host = ($this->proxy_host) ? $this->proxy_host : $this->host;
$port = ($this->proxy_port) ? $this->proxy_port : $this->port;
$errno = 0;
$errstr = '';
$socket = fsockopen($host, $port, $errno, $errstr, 30);
if (! $socket) {
return null; // Exception
} else {
if (is_resource($socket)) {
$header = $this->getHeader();
fwrite($socket, $header);
@ -90,5 +95,17 @@ class Connection_HttpRequest
}
return null;
}
static function getJSON($url, $data) {
$c = new Connection_HttpRequest();
$c->http_version = "HTTP/1.0";
$query = http_build_query($data);
$c->setUrl($q = $url . '?' . $query);
$page = $c->getPage();
$response = new Connection_HttpResponse($page);
return json_decode((string) preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/', '', $response->getData()), true);
}
}

View file

@ -9,8 +9,8 @@ class Connection_HttpResponse
private $param = array ();
private $code;
public $response;
public $data;
public $version;
public $data;
public function __construct($response)
{

View file

@ -0,0 +1,16 @@
<?php
class Controller_Request {
function __construct($request, $id) {
$this->r = $request;
$this->id = $id;
}
function get($name) {
$v = $this->r->get($name);
if ($id && is_array($v)) {
return isset($v[$id]) ? $v[$id] : $def;
}
return $v;
}
}

View file

@ -0,0 +1,64 @@
<?php
/**
* Класс сервиса = Упрощенный компонент
*/
class Controller_Service
{
public $viewPath = array();
public $registry; // Registry->getInstance
public $template;
public $templatePath;
public $COMPONENTS_WEB;
public function getTemplatePath($name)
{
return Path::join($this->viewPath[0], 'templates', 'modern', $name);
}
public function getTemplateWebPath()
{
return Path::join($this->webPath[0], strtolower(get_class($this)), 'templates', 'modern');
}
/**
* @param $name Имя модели
*/
private function getModelPath($name)
{
return Path::join (CMS_PATH, "model", $name . ".php");
}
/**
* Создает модель
* @param string $name
* @return model
*/
public function getModel($name)
{
require_once 'mapper/mapper.php';
require_once ($this->getModelPath ($name));
$modelName = $name . "Mapper";
$model = new $modelName ();
$model->db = $this->db;
return $model;
}
public function options($key, $val, $res) {
$result = array();
while($res->next()) {
$result[] = array('value' => $res->getInt($key), 'name' => $res->getString($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;
}
}

View file

@ -8,11 +8,11 @@ class Database_IdGenerator {
}
function isBeforeInsert() {
return $this->db->isPostgres();
return false;
}
function isAfterInsert() {
return !$this->db->isPostgres();
return true;
}
function getId($seq) {

View file

@ -1,86 +0,0 @@
<?php
// Report simple running errors
define('ERROR_FILE', 'phedor@edu.yar.ru');
define('ERROR_TYPE', 1);
ini_set('error_reporting', 0);
ini_set('display_errors', 0);
error_reporting(0);
function get_error_name($id) {
$names = array(1 => 'E_ERROR',
2 => 'E_WARNING',
4 => 'E_PARSE',
8 => 'E_NOTICE',
16 => 'E_CORE_ERROR',
32 => 'E_CORE_WARNING',
64 => 'E_COMPILE_ERROR',
128 => 'E_COMPILE_WARNING',
256 => 'E_USER_ERROR',
512 => 'E_USER_WARNING',
1024 => 'E_USER_NOTICE',
2048 => 'E_STRICT',
4096 => 'E_RECOVERABLE_ERROR',
8192 => 'E_DEPRECATED',
16384 => 'E_USER_DEPRECATED',
30719 => 'E_ALL');
return $names[$id];
}
function send_error($description) {
$message = "request: " . "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] . "\n";
$message .= "from: " . $_SERVER['REMOTE_ADDR'] . "\n";
if(isset($_SERVER['HTTP_REFERER'])) $message .= "referer: " . $_SERVER['HTTP_REFERER'] . "\n";
$message .= "post:" . var_export($_POST, true) . "\n";
$message .= "description: " . $description;
// error_log($message, ERROR_TYPE, ERROR_FILE);
return false;
}
function error_handler($errno, $errstr, $errfile, $errline) {
$message = "request: " . "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] . "\n";
$message .= "from: " . $_SERVER['REMOTE_ADDR'] . "\n";
if(isset($_SERVER['HTTP_REFERER'])) $message .= "referer: " . $_SERVER['HTTP_REFERER'] . "\n";
$message .= "post:" . var_export($_POST, true) . "\n";
$message .= "type: " . get_error_name($errno) . "\n"
. "error: " . $errstr . "\n"
. "line: " . $errline . "\n"
. "file: " . $errfile;
// error_log($message, ERROR_TYPE, ERROR_FILE);
return false;
}
function shutdown() {
$error = error_get_last();
$message = "request: " . "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] . "\n";
$message .= "from: " . $_SERVER['REMOTE_ADDR'] . "\n";
if(isset($_SERVER['HTTP_REFERER'])) $message .= "referer: " . $_SERVER['HTTP_REFERER'] . "\n";
if (is_array($error)) {
foreach ($error as $info => $string) {
$message .= "{$info}: {$string}\n";
}
}
error_log($message, ERROR_TYPE, ERROR_FILE);
}
function exception_handler($exception) {
$message = "request: " . "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] . "\n";
$message .= "from: " . $_SERVER['REMOTE_ADDR'] . "\n";
if(isset($_SERVER['HTTP_REFERER'])) $message .= "referer: " . $_SERVER['HTTP_REFERER'] . "\n";
$message .=
"file: " . $exception->getFile() . "\n"
. "line: " . $exception->getLine() . "\n"
. "message: " . $exception->getMessage() . "\n"
. "trace: " . $exception->getTraceAsString();
error_log($message, ERROR_TYPE, ERROR_FILE);
return true;
}
set_exception_handler('exception_handler');
set_error_handler("error_handler");
//register_shutdown_function('shutdown');

View file

@ -1,80 +0,0 @@
<?php
require_once 'core/sort.php';
//Становиться похоже на работу файлов через SPL возможно стоит реализовать на базе его
class FileRecord
{
public $file;
protected $src;
protected $parent;
function __construct(array $file, $src, $parent = false)
{
$this->file = $file;
$this->filename = $src;
$this->parent = $parent;
}
function get($name) {
return isset($this->file[$name]) ? $this->file[$name] : null;
}
function fileStat()
{
$type = is_dir($this->filename);
return array(
'name' => ($this->parent) ? ".." : $this->getName(),
'type' => $type,
'extension' => ($type) ? 'folder' : pathinfo($this->filename, PATHINFO_EXTENSION),
'date' => date("d.m.Y H:i", $this->getTime()),
'access' => 0,
'size' => ($type) ? "" : $this->getSizeString(),
'state' => isset($this->file['state']) ? $this->file['state'] : 'unknown',
'title' => $this->getTitle(),
/*'author' => $this->file['author'],
'description' => $this->file['description'],
'keywords' => $this->file['keywords'],*/
);
}
function isExpected()
{
if (isset($this->file['state'])) {
return ($this->file['state'] == 'expected');
}
return false;
}
function getSizeString()
{
$size = $this->getSize();
foreach (array('б ', 'Kб', 'Mб') as $suffix) {
if (($size / 1024) <= 1) {
return round($size, 0) . ' ' . $suffix;
}
$size /= 1024;
}
return round($size, 0) . ' GB';
}
function getSize()
{
return ($this->isExpected()) ? 0 : filesize($this->filename);
}
function getTime()
{
return ($this->isExpected()) ? 0 : filemtime($this->filename);
}
function getName()
{
return pathinfo($this->filename, PATHINFO_BASENAME);
}
function getTitle()
{
return isset($this->file['title']) ? $this->file['title'] : $this->getName();
}
}

View file

@ -6,9 +6,9 @@
class Filter_ActionAccess
{
public $access = array();
public $processor;
function __construct($processor)
{
function __construct(/*.Filter_Filter.*/$processor) {
$this->processor = $processor;
}
@ -17,14 +17,12 @@ class Filter_ActionAccess
* !! Реализация класса проверки действий не должна быть внутри Контроллера!!!
* Информация о доступе может быть в файле, базе данных и т.д.
*/
function checkAction($action)
{
function checkAction($action) {
// Импликация !! http://ru.wikipedia.org/wiki/Импликация
return (!isset($this->access[$action]) || in_array(UserAccess::$access, $this->access[$action]));
return (!isset($this->access[$action]) || in_array(Filter_UserAccess::$access, $this->access[$action]));
}
function execute(HTTPRequest $request)
{
function execute(HttpRequest $request) {
$action = $request->getAction();
if(! $this->checkAction($action)) {
$request->set('action', 'index');

View file

@ -7,17 +7,15 @@ class Filter_ActionLogger
public $action;
public $processor;
function __construct($processor)
{
function __construct(/*.Filter_Filter.*/$processor) {
$this->processor = $processor;
$this->file = fopen(Shortcut::getUrl('access.log'), "a");
}
function execute(HTTPRequest $request)
{
function execute(HttpRequest $request) {
$action = $request->getAction();
if(in_array($action, $this->before)) {
fwrite($this->file, "time: " . date("r", time()) . " query: ". json::encode(array_merge($_POST, $_GET)) . " by: " . UserAccess::$name . "\n");
fwrite($this->file, "time: " . date("r", time()) . " query: ". json_encode(array_merge($_POST, $_GET)) . " by: " . Filter_UserAccess::$name . "\n");
}
return $this->processor->execute($request);
}

View file

@ -0,0 +1,52 @@
<?php
class Filter_Authorization {
const SESSION_BROWSER_SIGN_SECRET = '@w3dsju45Msk#';
const SESSION_BROWSER_SIGN_KEYNAME = 'session.app.browser.sign';
static function isLogged() {
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
$hash = self::getBrowserSign();
// Если $hash не совпадает $_SESSION['hash'] то удаляем сессию
if (isset($_SESSION ['access']) && isset($_SESSION[self::SESSION_BROWSER_SIGN_KEYNAME])) {
if ($hash == $_SESSION[self::SESSION_BROWSER_SIGN_KEYNAME]) {
// UserAccess::getUserById($_SESSION ['access']); // Поиск по идентификатору
return true;
} else {
return false;
}
}
return false;
}
static function enter($id)
{
// $db->executeQuery("UPDATE visitor SET sid = '' WHERE id_visitor = " . $result->getInt('id_user'));
session_register("access");
session_register("time");
// $_SESSION ["group"] = $result->getInt('access');
$_SESSION ["access"] = $id; // id_user
$_SESSION [self::SESSION_BROWSER_SIGN_KEYNAME] = self::getBrowserSign();
$_SESSION ["time"] = time();
}
private static function getBrowserSign()
{
$rawSign = self::SESSION_BROWSER_SIGN_SECRET;
// $signParts = array('HTTP_USER_AGENT', 'HTTP_ACCEPT_ENCODING');
$signParts = array();
foreach ($signParts as $signPart) {
$rawSign .= '::' . (isset($_SERVER[$signPart]) ? $_SERVER[$signPart] : 'none');
}
return md5($rawSign);
}
static function logout() {
session_destroy();
}
}

View file

@ -6,7 +6,7 @@
class Filter_Filter
{
public $processor;
public function __construct($processor)
public function __construct(/*.Filter_Filter.*/$processor)
{
$this->processor = $processor;
}
@ -16,9 +16,9 @@ class Filter_Filter
return $this->processor->execute($request);
}
public function getView($name)
public function getView($name, $class = 'View_Top')
{
return $this->processor->getView($name);
return $this->processor->getView($name, $class);
}
public function getConnection()

View file

@ -16,12 +16,12 @@ class Filter_UserAccess
{
}
public static function setUp($db)
public static function setUp(Database $db)
{
self::$db = $db;
}
public static function getUserByQuery($stmt)
public static function getUserByQuery(Database_Statement $stmt)
{
global $GROUPS;
$result = $stmt->executeQuery();
@ -62,7 +62,7 @@ class Filter_UserAccess
$time = time();
if ($time - $lasttime > self::LIFE_TIME) return null; // Вышло время сессии
$id = self::$id;
$stmt = self::$db->executeQuery("UPDATE users SET lasttime = $time WHERE id_user = $id"); // Время последнего обращения входа
self::$db->executeQuery("UPDATE users SET lasttime = $time WHERE id_user = $id"); // Время последнего обращения входа
}
return $result;
}

View file

@ -1,50 +0,0 @@
<?php
/**
* Генерация файлов Grpahviz dot
*/
class Formats_Dot
{
static function getHeader ()
{
$header =
"digraph G {\n"
. "\toverlap=false; splines=true;\n"
. "\tfontname = \"Verdana\"\n"
. "\tfontsize = 8\n"
. "\tnode [\n"
. "\t\tfontname = \"Verdana\"\n"
. "\t\tfontsize = 8\n"
. "\t\tshape = \"record\"\n"
. "\t]\n"
. "\tedge [\n"
. "\t\tfontname = \"Verdana\"\n"
. "\t\tfontsize = 8\n"
. "\t]\n";
return $header;
}
static function getFooter ()
{
$footer = "}\n";
return $footer;
}
function assocToDot (array $array, array $label)
{
$result = array (self::getHeader());
// Метки
foreach ($label as $value) {
$result [] = "\t\"{$value[0]}\" [ label = \"{$value[1]}\" ] \n";
}
// Ассоциации
foreach ($array as $key => $value) {
foreach ($value as $n) {
$result [] = "\t\"$key\" -> \"$n\"\n";
}
}
$result [] = self::getFooter();
return implode("", $result);
}
}

View file

@ -1,85 +0,0 @@
<?php
define ('URL_CLIP', 0);
define ('URL_DIRECTORY', 1);
class HAuthorize {
public $password;
public $uuid;
public $uuid_writeable;
public function __construct () {
$this->uuid = "*";
$this->uuid_writeable = 1;
}
public function getString () {
return "{$this->password};{$this->uuid};{$this->uuid_writeable}";
}
public function setPassword ($username, $realm, $password) {
$this->password = md5 ("$username:$realm:$password");
}
}
class HPermission {
public $url;
public $url_type;
public $permission_type;
public $expires;
public $debitted_time;
public function __construct ($url, $url_type) {
$this->url = $url;
$this->url_type = $url_type;
$this->expires = "*"; // MM/DD/YYYY:HH:MM:SS
$this->permission_type = 0;
$this->debitted_time = 0;
}
public function getString () {
return "{$this->url};{$this->url_type};{$this->permission_type};{$this->expires};{$this->debitted_time}";
}
}
class HFile {
public $authorize;
public $permission = array ();
public function addAuthorize ($name, $realm, $password) {
$this->authorize = new HAuthorize ();
$this->authorize->setPassword ($name, $realm, $password);
}
public function addPermission ($url, $url_type) {
$this->permission[] = new HPermission ($url, $url_type);
}
public function write ($name) {
$file = fopen ($name, 'w');
fwrite ($file, $this->getString ());
fclose ($file);
}
public function writeFTP ($ftp, $path) {
$file = tmpfile ();
fwrite ($file, $this->getString ());
fseek ($file, 0);
ftp_fput ($ftp, $path, $file, FTP_BINARY);
fclose ($file);
}
public function getString () {
$result = array ();
$result[] = $this->authorize->getString ();
$result[] = "\n";
foreach ($this->permission as $p) {
$result[] = $p->getString ();
$result[] = "\n";
}
return implode ("", $result);
}
}

View file

@ -1,12 +0,0 @@
<?php
class Geometry_Point
{
public $left, $top;
function __construct ($left = 0, $top = 0)
{
$this->left = $left;
$this->top = $top;
}
}

View file

@ -1,49 +0,0 @@
<?php
class Geometry_Rectangle
{
public $left, $top, $width, $height;
function __construct($left = 0, $top = 0, $width = 0, $height = 0)
{
$this->left = $left;
$this->top = $top;
$this->width = $width;
$this->height = $height;
}
function __get($name)
{
switch ($name) {
case 'right': return $this->left + $this->width;
case 'bottom': return $this->top + $this->height;
}
}
function __set($name, $value)
{
switch ($name) {
case 'right': $this->width = $value - $this->left;
case 'bottom': $this->height = $value - $this->top;
}
}
/**
* Смещает прямоугольник на заданное положение
*/
function addPoint(Point $point)
{
$result = clone $this;
$result->left += $point->left;
$result->top += $point->top;
return $result;
}
/**
* Координаты точки при выравнивании прямоугольника относительно текущего
*/
function alignment(Rectangle $base)
{
return new Point((($base->left + $base->right) - ($this->left + $this->right)) / 2, $base->bottom - $this->height);
}
}

File diff suppressed because it is too large Load diff

13
src/Layout/Empty.php Normal file
View file

@ -0,0 +1,13 @@
<?php
/**
* Самый простой макет
*/
class Layout_Empty extends Filter_Filter
{
function execute(HttpRequest $request)
{
$text = $this->processor->execute($request);
return $text;
}
}

View file

@ -69,8 +69,7 @@ class Layout_Manager extends Filter_Filter
if (call_user_func($condition[0], $request)) {
$layout = $condition[1];
$view = $layout->execute($request);
if ($view instanceof View_Composite) {
if (is_object($view)) {
echo $view->render();
} else {
echo $view;

View file

@ -1,11 +0,0 @@
<?php
/**
* Самый простой макет
*/
class Layout_None extends Filter_Filter
{
function execute(HttpRequest $request)
{
return $this->processor->execute($request);
}
}

View file

@ -200,9 +200,8 @@ class Mail
{
$result = mail($this->_to, $this->getSubject(), $this->getMessage(), $this->getHeader());
if(! $result) {
file_put_contents(Path::resolveFile("send.eml"), $this->eml());
throw new Exception('Невозможно отправить почту');
// require_once "core/path.php";
// file_put_contents(Path::resolveFile("data/email/send.eml"), $this->eml());
}
return $result;
}

View file

@ -1,28 +0,0 @@
<?php
class ModelFactory
{
static $shortcut = "model";
public function __construct (Connection $db)
{
$this->db = $db;
}
/**
* Создает модель
* @param string $name
* @return model
*/
public function getModel ($name)
{
require_once 'core/mapper/mapper.php'; // ????
require_once (Shortcut::getUrl(self::$shortcut, $name));
$modelName = $name . "Mapper";
$model = new $modelName();
$model->db = $this->db;
$model->factory = $this;
return $model;
}
}

View file

@ -1,265 +0,0 @@
<?php
/**
* Использовать интерфейсы чтобы определить какие действия можно совершать с обьектом и таким образом
* Строить набор действий Action и отображений View для обьекта
* Т.к отображение данных может быть не только на таблицу баз данных
* И возможно реализованны все интерфейсы
*/
interface IDataList
{
function findAll (Collection $request, $id = null);
function findById ($id);
function getCount (Collection $request, $id);
}
interface IDataSave
{
function saveTo ($o);
function updateTo ($o);
}
/**
* Отображение таблицы базы данных в обьекты
* Mapper -> DataMapper implements IDataList, IDataSave, IDataSort, IDataDelete ...
*
* @package core
*/
class DataMapper implements IDataList
{
/* Хранить метаданные в статическом свойстве класса для ототбражения ?!, + Скрипт для генерации метаданных!!
*/
public $factory;
public $className; /* Класс на который будет отображаться строчка таблицы */
public $filter = ""; /* */
public $schema = array (); /* Соответствие между свойством обьекта и столбцом, добавить тип для записей !! */
public $database; /* Таблица */
public $index; /* Индексный столбец */
public $db; /* Соединение с базой данных */
public $reference = array (null, null);
public function __construct ()
{
}
public function setRange ($stmt, $page, $size)
{
$stmt->setLimit ($size);
$stmt->setOffset (($page-1) * $size);
}
public function listSQL (array $list)
{
return implode ($list, ",");
}
/**
* Поиск строки в таблице по идентификатору
* @param $id Значение идентификатора
* @return Обьект класса $className
*/
public function findById ($id)
{
// Строки запроса преобразовать в методы (getSQLSelect ...)
// Query::from($this->database)->where ($this->index, "=", $id)->select();
$stmt = $this->db->prepareStatement ("SELECT * FROM ".$this->database." WHERE ".$this->index." = ?");
$stmt->setInt (1, $id);
$rs = $stmt->executeQuery ();
$rs->next ();
return $this->mapOne ($rs);
}
/**
* Преобразует parseResult в обьект
*/
public /* private */ function mapOne ($rs)
{
$result = new $this->className ();
foreach ($this->schema as $key => $value) {
list($value) = $value;
$result->$value->setRes($rs, $key);
}
return $result;
}
public /* private */ function mapAll ($rs)
{
$result = array ();
// Преобразование SQL в обьект
while ($rs->next ()) {
$result[] = $this->mapOne ($rs);
}
return $result;
}
private function clean ($value) {
return strtolower(trim(iconv('utf-8', 'cp1251', $value)));
}
/**
* Преобразует параметры формы в SQL запрос WHERE
* @param array $params
* @param array $schema
* @return string
*/
public function requestToSQL (Collection $request, array $schema)
{
$result = array ();
foreach ($schema as $key => $value) {
$param = $request->get ($key);
if ($param) {
array_push ($result, "lower (".$value.") LIKE '".$this->clean ($param)."%'");
}
}
if (empty ($result)) return null;
return implode ($result, " AND ");
}
/**
* Удаление строк из таблицы с заданными индексами
* @param $list array Массив идентефикаторов
*/
public function deleteList (array $list)
{
// Query::from($this->database)->where($this->index, "in", $list)->delete();
$sql = "DELETE FROM " . $this->database . " WHERE " . $this->index . " IN (" . $this->listSQL ($list) . ")";
return $this->db->executeQuery ($sql);
}
public static function findKey (array $schema, $sort)
{
foreach ($schema as $key => $item) {
list($item) = $item;
if ($item == $sort) {
return $key;
}
}
return $sort;
}
public function getOrder (Collection $request)
{
$order = "";
$sort = $request->get('key');
$desc = ($request->get('desc') == 0)? 'DESC' : 'ASC';
if ($sort) {
$sort = self::findKey ($this->schema, $sort);
$order = " ORDER BY $sort $desc";
}
return $order;
}
/**
* Извлекает список записей из базы данных
*/
public function findAll (Collection $request, $id = null)
{
$name0 = $this->database;
$foreign = $this->reference[1];
// Переписать используя Query !!!
if ($foreign && $id) {
$filter = ($this->filter)?$filter = " AND ".$this->filter: "";
$sql = "SELECT t1.* FROM $name0 as t1 WHERE t1.$foreign = $id " . $filter.self::getOrder($request);
} else {
$filter = ($this->filter)?$filter = " WHERE " . $this->filter: "";
$sql = "SELECT * FROM $name0 " . $filter . self::getOrder($request);
}
$stmt = $this->db->prepareStatement ($sql);
$page = $request->get('page');
$limit = $request->get('size');
if ($page && $limit) {
$this->setRange($stmt, $page, $limit);
}
return $this->mapAll($stmt->executeQuery());
}
public function getCount (Collection $request, $id)
{
$name0 = $this->database;
$foreign = $this->reference[1];
// Переписать используя Query !!!
if ($foreign && $id) {
$filter = ($this->filter)?$filter = " AND " . $this->filter: "";
$sql = "SELECT count(t1.*) as length FROM $name0 as t1 WHERE t1.$foreign = $id " . $filter;
} else {
$filter = ($this->filter)?$filter = " WHERE " . $this->filter: "";
$sql = "SELECT count(*) as length FROM $name0 " . $filter;
}
$rs = $this->db->executeQuery($sql);
$rs->next();
return $rs->getInt('length');
}
/**
* Добавление записи в базу данных
* @param $o Обьект для записи в базу данных
*/
public function saveTo (Model $o)
{
$keys = array ();
$values = array ();
foreach ($this->schema as $key => $value) {
list($value) = $value;
if ($key != $this->index) {
$keys[] = $key;
$values[] = "'".$o->$value."'";
}
}
$stmt = $this->db->prepareStatement ("INSERT INTO ".$this->database." (".implode ($keys, ",").") VALUES (".implode ($values, ",").")");
$stmt->executeQuery ();
}
/**
* Обновляет запись в базе данных
* @param $o Обьект для обновления
*/
public function updateTo (Model $o)
{
$keys_values = array ();
foreach ($this->schema as $key => $value) {
list($value) = $value;
if ($key != $this->index && !($o->$value instanceof FKey)) {
$keys_values[] = $key." = '".$o->$value."'";
}
}
// Для всех должен быть идентефикатор id
$stmt = $this->db->prepareStatement ("UPDATE ".$this->database." SET ".implode($keys_values, ",")." WHERE ".$this->index." = ".$o->id);
$stmt->executeQuery ();
}
function saveDB (Model $o)
{
if ($o->id) {
$this->updateTo($o);
} else {
$this->saveTo($o);
}
}
function getModel($name)
{
require_once 'core/Mapper/Factory.php';
if (!$this->factory) {
$this->factory = new ModelFactory($this->db);
}
return $this->factory->getModel($name);
}
}
/**
*
*/
class Model
{
public function __construct ()
{
foreach (get_class_vars (get_class ($this)) as $key => $value) {
$this->$key = new Primitive ();
}
}
// __get, __set методы. В метаданных хранится тип свойств, проверять при присваивании!!
}
?>

View file

@ -1,74 +0,0 @@
<?php
/**
* Отображение списка папок с настройками на обьект
*/
class PathMapper
{
private $count;
private $base = null;
public $reference = null;
function plane (&$target, Collection $array)
{
$vars = get_class_vars(get_class($target));
foreach ($vars as $name => $value) {
$target->$name = $array->get($name);
}
}
function basePath ()
{
if ( ! $this->base) $this->base = $this->getBasePath();
return $this->base;
}
function findAll (Collection $request, $id = null)
{
$this->reference = $id;
$base = $this->basePath ();
$path = new Path($base);
$list = $path->getContent();
$result = array ();
$this->count = 0;
foreach ($list as $name) {
if (is_dir (Path::join($this->basePath (), $name))
&& $module = $this->findById ($name)) {
$this->count++;
$result [] = $module;
}
}
return $result;
}
function findById ($name)
{
$file = Path::join($this->basePath(), $this->getSettingsFile ($name));
if (file_exists($file)) {
$settings = new Settings($file);
$settings->read();
return $this->settingsMap($name, $settings);
}
return null;
}
/**
* Число папок
*/
function getCount ()
{
return $this->count;
}
/**
* Удаление списка папок
*/
function deleteList(array $list)
{
foreach ($list as $name)
Path::delete(Path::join($this->getBasePath(), $name));
}
}

View file

@ -1,113 +0,0 @@
<?php
/**
Copyright (c) 2007 Brady Mulhollem
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**/
class Markup_SimpleBBCode{
//General Tags
var $tags = array('b' => 'strong','i' => 'em','u' => 'span style="text-decoration:underline"','quote' => 'blockquote','s' => 'span style="text-decoration: line-through"', 'list' => 'ul','\*' => 'li');
//Tags that must be mapped to diffierent parts
var $mapped = array('url' => array('a','href',true),'img' => array('img','src',false));
//Tags with atributes
var $tags_with_att = array('color' => array('font','color'),'size' => array('font','size'),'url' => array('a','href'));
//Gotta have smilies
var $smilies = array(':)' => 'smile.gif',':(' => 'frown.gif');
//Config Variables
//Convert new line charactes to linebreaks?
var $convert_newlines = true;
//Parse For smilies?
var $parse_smilies = true;
//auto link urls(http and ftp), and email addresses?
var $auto_links = true;
//Internal Storage
var $_code = '';
function __construct($new=true,$parse=true,$links=true){
$this->convert_newlines = $new;
$this->parse_smilies = $parse;
$this->auto_links = $links;
}
function parse($code){
$this->_code = $code;
$this->_strip_html();
$this->_parse_tags();
$this->_parse_mapped();
$this->_parse_tags_with_att();
$this->_parse_smilies();
$this->_parse_links();
$this->_convert_nl();
return $this->_code;
}
function _strip_html(){
$this->_code = strip_tags($this->_code);
}
function _convert_nl(){
if($this->convert_newlines){
$this->_code = nl2br($this->_code);
}
}
function _parse_tags(){
foreach($this->tags as $old=>$new){
$ex = explode(' ',$new);
$this->_code = preg_replace('/\['.$old.'\](.+?)\[\/'.$old.'\]/is','<'.$new.'>$1</'.$ex[0].'>',$this->_code);
}
}
function _parse_mapped(){
foreach($this->mapped as $tag=>$data){
$reg = '/\['.$tag.'\](.+?)\[\/'.$tag.'\]/is';
if($data[2]){
$this->_code = preg_replace($reg,'<'.$data[0].' '.$data[1].'="$1">$1</'.$data[0].'>',$this->_code);
}
else{
$this->_code = preg_replace($reg,'<'.$data[0].' '.$data[1].'="$1">',$this->_code);
}
}
}
function _parse_tags_with_att(){
foreach($this->tags_with_att as $tag=>$data){
$this->_code = preg_replace('/\['.$tag.'=(.+?)\](.+?)\[\/'.$tag.'\]/is','<'.$data[0].' '.$data[1].'="$1">$2</'.$data[0].'>',$this->_code);
}
}
function _parse_smilies(){
if($this->parse_smilies){
foreach($this->smilies as $s=>$im){
$this->_code = str_replace($s,'<img src="'.$im.'">',$this->_code);
}
}
}
function _parse_links(){
if($this->auto_links){
$this->_code = preg_replace('/([^"])(http:\/\/|ftp:\/\/)([^\s,]*)/i','$1<a href="$2$3">$2$3</a>',$this->_code);
$this->_code = preg_replace('/([^"])([A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4})/i','$1<a href="mailto:$2">$2</a>',$this->_code);
}
}
function addTag($old,$new){
$this->tags[$old] = $new;
}
function addMapped($bb,$html,$att,$end=true){
$this->mapped[$bb] = array($html,$att,$end);
}
function addTagWithAttribute($bb,$html,$att){
$this->tags_with_att[$bb] = array($html,$att);
}
function addSmiley($code,$src){
$this->smilies[$code] = $src;
}
}
?>

View file

@ -1,9 +0,0 @@
<?php
/**
* Класс метаданных таблицы
*/
class Meta
{
}

View file

@ -1,202 +0,0 @@
<?php
/**
* Класс для составления запроса
*/
class Query
{
static $alias = 0;
public $table;
public $filter = array ();
public $calc = array ();
public $order = array ();
/**
* Создает пустой зарос
*/
static function create()
{
return new Query();
}
/**
* Метаданные таблицы
* @param string $name Имя таблицы
*/
function getTableMeta($name)
{
}
/**
* Создает новый запрос
* @param string $name Имя таблицы
*
* @return Query
*/
public function from($name)
{
$result = clone $this;
$table = new Table();
$table->type = 'simple';
$table->name = $name;
$table->alias = "t" . self::$alias++;
$result->table = $table;
return $result;
}
/**
* Добавляет к запросу условие
* @param string $field Имя поля таблицы
* @param string $op Имя оператора
* @param $value Значение поля
*
* @return Query
*/
public function filter($field, $op, $value)
{
$result = clone $this;
$result->filter [] = $result->table->alias ."." . $field . $op . "'" . $value . "'";
return $result;
}
/**
* @param string $e Выражение
*/
public function calc($e)
{
$result = clone $this;
$result->calc [] = $e;
return $result;
}
public function joinOn($first, $e)
{
$result = $this->compose($first, array ('filter', 'calc', 'order'));
$e = strtr($e, array ("a." => $this->table->alias . ".",
"b." => $first->table->alias . "."));
$table = new Table ();
$table->type = 'join';
$table->name = $this->table->name;
$table->alias = $this->table->alias;
$table->join = $first->table;
$table->condition = $e;
$result->table = $table;
return $result;
}
/**
* Обьединяет параметры двух заросов
* @param Query $first
* @pram array $list Список параметров
*
* @return Query
*/
private function compose(Query $first, array $list)
{
$result = new Query();
foreach ($list as $name) {
$result->$name = array_merge($this->$name, $first->$name);
}
return $result;
}
/**
* Заковычивает значение
*/
public function quote ($value)
{
return "'" . $value . "'";
}
/**
* Компиляция таблицы
* @param Table $table
*
* @return string Часть строки SQL
*/
private function table(Table $table)
{
if ($table->type == 'simple') {
return $table->name ." AS ".$table->alias;
}
if ($table->type == 'join') {
return $table->name ." AS ".$table->alias. " JOIN " . $this->table ($table->join) . " ON " . $table->condition;
}
return "";
}
/**
* Компиляция WHERE
*
* @return string Часть строки SQL
*/
private function where ()
{
return implode(" AND ", $this->filter);
}
/**
* Компиляция запроса в SELECT SQL
*
* @return string SQL выражение
*/
public function select()
{
return "SELECT "
. ((!empty($this->calc))? implode (",", $this->calc): "*")
. " FROM " . $this->table($this->table)
. ((!empty ($this->filter))? " WHERE " . $this->where() : "");
}
/**
* Компиляция в DELETE
*/
public function delete()
{
return "DELETE FROM " . $this->table->name
. ((!empty ($this->filter))? " WHERE " . $this->where() : "");
}
private function add_prefix($prefix, $array) {
$result = array();
foreach ($array as $value) {
$result [] = $prefix . $value;
}
return $result;
}
/**
* Компиляция в UPDATE
* TODO: Разные типы запросов Query->update(); Query->select(), Query->insert();!!
* Возвраащают statement
*/
public function update($values)
{
$pairs = array ();
foreach ($values as $key => $value) { //
$pairs [] = $key . "=" . $this->quote ($value);
}
return "UPDATE " . $this->table->name . " SET "
. implode(",", $pairs)
. ((!empty($this->filter))? " WHERE " . $this->where() : "");
}
/**
* Компиляция в INSERT
*/
public function insert($values)
{
return "INSERT INTO ". $this->table->name . "("
. implode(",", array_keys($values))
. ") VALUES (" . implode(",", array_map(array($this, 'quote'), array_values($values))) . ")";
}
}

View file

@ -1,14 +0,0 @@
<?php
/**
* Класс таблицы
*/
class Table
{
public $type = 'simple';
public $name;
public $alias;
public $join;
public $condition;
}

View file

@ -1,82 +0,0 @@
<?php
/**
* Извлекает текст из HTML документа
*/
function stripText($document)
{
$search = array("'<script[^>]*?>.*?</script>'si" => "", // strip out javascript
"'<[\/\!]*?[^<>]*?>'si" => "", // strip out html tags
"'([\r\n])[\s]+'" => "\\1", // strip out white space
"'&(quot|#34|#034|#x22);'i" => "\"", // replace html entities
"'&(amp|#38|#038|#x26);'i" => "&", // added hexadecimal values
"'&(lt|#60|#060|#x3c);'i" => ">",
"'&(gt|#62|#062|#x3e);'i" => "<",
"'&(nbsp|#160|#xa0);'i" => " ",
"'&(iexcl|#161);'i" => chr(161),
"'&(cent|#162);'i" => chr(162),
"'&(pound|#163);'i" => chr(163),
"'&(copy|#169);'i" => chr(169),
"'&(reg|#174);'i" => chr(174),
"'&(deg|#176);'i" => chr(176));
$text = preg_replace(array_keys($search), array_values($search), $document);
return $text;
}
/**
* Разделение текста на массив слов
*/
function tokenize ($document)
{
$array = preg_split("/[\W]+/", $document);
return $array;
}
/**
* Ищет один из символов с конца строки
*
* @param string $haystack
* @param array $needle Массив символов для поиска
* @param int $offset Смещение от начала строки
*
* @return int Позицию первого совпадения
*/
function indexRight ($haystack, $needle, $offset = 0)
{
if ((bool)$offset === false) $offset = 0;
while ($offset >= 0) {
if (in_array ($haystack[$offset], $needle)) {
return $offset;
}
$offset --;
}
return false;
}
/**
* Ищет один из символов с начала строки
*
* @param string $haystack
* @param array $needle Массив символов для поиска
* @param int $offset Смещение от начала строки
*
* @return int Позицию первого совпадения
*/
function indexLeft ($haystack, $needle, $offset = 0)
{
if ($offset < 0) return false;
while ($offset < strlen($haystack)) {
if ((is_callable($needle) && call_user_func ($needle, $haystack[$offset]))
|| (is_array ($needle) && in_array ($haystack[$offset], $needle))) {
return $offset;
}
$offset ++;
}
return false;
}
function not_ctype_alpha ($ch)
{
return !ctype_alpha($ch);
}

View file

@ -1,80 +0,0 @@
<?php
/**
* Индексирование файлов
*/
class Index
{
const ARRAY_FILE = 0;
const ARRAY_TEXT = 1;
public $index = array ();
public $text = array ();
protected $count = 0;
function getTitle ($content) {
$title = "'<title[^>]*?>(.*?)</title>'si";
preg_match($title, $content, $matches);
if(isset($matches[1])) {
return $matches[1];
}
return "";
}
// Выбираем основу слова
function clean ($word)
{
return Stemmer::russian(strtolower($word));
}
function process ($base, $files)
{
$path = new Path($base);
// Список документов
foreach ($path->getContentRec($files) as $file) {
$content = file_get_contents ($file);
$text = stripText($content);
// $title = self::getTitle ($content);
$title = pathinfo($file, PATHINFO_BASENAME);
// echo $file, "\n";
// Список слов в документе
$list = tokenize($text);
foreach ($list as $word) {
$preword = self::clean($word);
if (isset($this->index[$preword])) {
$index = $this->index[$preword];
if ( ! in_array ($this->count, $index)) $this->index[$preword] [] = $this->count;
} else {
// Не записываем слова длинна которых меньше 2
if (strlen($preword) > 1) {
$this->index[$preword] = array ($this->count);
}
}
}
$this->text [] = array ($title, $path->relPath ($file), $text);
$this->count ++;
}
ksort($this->index);
}
/**
* Сохранение результата поиска
*/
function saveData ($file)
{
$file = fopen($file, "w");
// Количество слов и текстов
fwrite ($file, pack("SS", count($this->index), count($this->text)));
foreach ($this->index as $word => $value) {
$length = strlen($word);
array_unshift ($value, "SSa*S*", $length, count($value), $word);
fwrite($file, call_user_func_array ('pack', $value));
}
foreach ($this->text as $text) {
fwrite($file, pack("SSSa*a*a*",
strlen($text[0]), strlen($text[1]), strlen($text[2])
, $text[0], $text[1], $text[2]));
}
}
}

View file

@ -1,91 +0,0 @@
<?php
/**
* Разбирвет строку запроса на токены
*/
class Lexer
{
const TOKEN_NOT = 1;
const TOKEN_OR = 2;
const TOKEN_LPAREN = 3;
const TOKEN_RPAREN = 4;
const TOKEN_AND = 5;
const TOKEN_WORD = 6;
const TOKEN_EOL = 7;
protected $src;
private $offset = 0;
public $token;
public function __construct ()
{
}
function setSource ($src)
{
$this->src = $src;
$this->offset;
}
private function skipSpace ()
{
while (!$this->isEOL() && $this->getChar() == " ") {
$this->offset++;
}
}
private function getChar ()
{
return $this->src [$this->offset];
}
/**
* Проверяет на конец строки
*/
private function isEOL () {
return $this->offset >= strlen($this->src);
}
/**
* Односимвольный токен
*/
private function easyToken () {
$ch = $this->getChar ();
switch ($ch) {
case '~': $token = array(self::TOKEN_NOT, $ch); break;
case '|': $token = array(self::TOKEN_OR, $ch); break;
case '(': $token = array(self::TOKEN_LPAREN, $ch); break;
case ')': $token = array(self::TOKEN_RPAREN, $ch); break;
case '&': $token = array(self::TOKEN_AND, $ch); break;
default:
$this->offset++;
$token = $this->getToken();
}
$this->offset++;
return $token;
}
/**
* Возвращает следующий токен
*/
public function getToken ()
{
$this->skipSpace ();
if ($this->isEOL()) {
return array(self::TOKEN_EOL, "");
}
if (ctype_alpha($this->getChar())) {
$start = $this->offset;
while (!$this->isEOL() && ctype_alpha($this->getChar())) {
$this->offset ++;
}
return array(self::TOKEN_WORD, substr ($this->src, $start, $this->offset-$start));
}
return $this->easyToken();
}
public function nextToken ()
{
$this->token = $this->getToken();
}
}

View file

@ -1,96 +0,0 @@
<?php
require_once __DIR__ '/../functions.php';
/**
* Поиск в индексе
*/
class Search
{
private $lexer;
private $index;
function __construct ($index)
{
$this->lexer = new Lexer();
$this->index = $index;
$this->op = array ($this, 'Op');
$this->binary = array ($this, 'binaryOp');
$this->union = array ($this, 'union');
$this->intersection = lcurry($this->op, 'array_uintersect', $this->union);
$this->notQuery = lcurry ($this->binary, Lexer::TOKEN_NOT,
lcurry($this->op, 'array_udiff', 'array_udiff'), array ($this, 'easyQuery'));
$this->orQuery = lcurry ($this->binary, Lexer::TOKEN_OR,
lcurry($this->op, $this->union, $this->union), $this->notQuery);
$this->andQuery = lcurry ($this->binary, Lexer::TOKEN_AND, $this->intersection, $this->orQuery);
}
function union ($a, $b, $callback)
{
return array_merge($a, $b);
}
function Eq ($a, $b)
{
return $a == $b;
}
function Op ($files, $words, $a, $b) {
return array (
'words' => call_user_func ($words, $a['words'], $b['words'], array ($this, 'eq')),
'files' => call_user_func ($files, $a['files'], $b['files'], array ($this, 'eq'))
);
}
public function getQuery ($source)
{
$this->lexer->setSource ($source);
$this->lexer->nextToken();
return $this->topQuery();
}
function topQuery ()
{
$result = call_user_func ($this->andQuery);
while ($this->lexer->token[0] == Lexer::TOKEN_LPAREN) {
$result = call_user_func ($this->intersection, $result, call_user_func ($this->andQuery));
}
return $result;
}
function easyQuery ()
{
$result = null;
if ($this->lexer->token[0] == Lexer::TOKEN_LPAREN) {
$this->lexer->nextToken ();
$result = $this->topQuery ();
if ($this->lexer->token[0] == Lexer::TOKEN_RPAREN) {
$this->lexer->nextToken ();
}
return $result;
} else {
$result = call_user_func ($this->index, $this->lexer->token[1]);
$this->lexer->nextToken ();
return $result;
}
}
/**
* @param int $type Тип лексемы
* @param function $op Функция при совпадении типа лексемы при запросе
* @param function $next Следующий обработчик запроса
*/
function binaryOp ($type, $op, $next)
{
$result = call_user_func($next);
while ($this->lexer->token[0] == $type) {
$this->lexer->nextToken();
$result = call_user_func($op, $result, call_user_func ($next));
}
return $result;
}
}

View file

@ -1,97 +0,0 @@
<?php
class Searcher {
/* protected */ public $index;
protected $text;
protected $search;
public function __construct ()
{
// Может передавать обьект метод по умлочанию getWordStat??
$this->search = new Search (array ($this, 'getWord'));
}
/**
* Читает содержимое индексного файла
*
* @param string $file Имя файла
*/
function setSource ($fileName)
{
$file = fopen($fileName, "r");
$words = fread($file, 4);
$all = unpack("Swords/Stexts", $words);
for ($i = 0; $i < $all['words']; $i++) {
$pos = fread($file, 4);
$size = unpack("Sword/Sindex", $pos);
$word = fread($file, $size['word']);
$index = unpack("S*", fread($file, $size['index']*2));
$this->index[$word] = $index;
}
for ($i = 0; $i < $all['texts']; $i++) {
$pos = fread($file, 6);
$size = unpack("Stitle/Surl/Stext", $pos);
//
$title = fread($file, $size['title']);
$url = fread($file, $size['url']);
$text = fread($file, $size['text']);
$this->text [] = array ($title, $url, $text);
}
}
// По слову возвращаем список файлов и слово
public function getWord ($word)
{
$preword = Stemmer::russian($word); // Index?? -> clean
if (isset($this->index[$preword])) { // Search??
return array ('files' => $this->index[$preword], 'words' => array ($preword));
}
return array ('files' => array (), 'words' => array ());
}
/**
* Список документов в которых встечается слово
*
*/
function getResult (&$query)
{
$result = array ();
$word = $query['words'];
$list = $query['files'];
//
foreach ($list as $n) {
$result [] = array (
'title' => $this->text[$n][0],
'file' => $this->text[$n][1],
'text' => self::getSlice ($word[0], $this->text[$n][2]));
}
return $result;
}
/**
* Часть документа в котором встречается слово
*
* @param $word Слово
* @param $text Текст содержащий слово
*/
function getSlice ($word, $text)
{
$pos = stripos($text, $word);
$offset = max(max ($pos-100, indexRight($text, array ("."), $pos) + 1), 0);
$real = substr($text, $pos, strlen($word)) ;
return substr($text, $offset, $pos - $offset)
. "<span style='color: red'>" . $real . "</span>" . substr ($text, $pos + strlen($word), 100);
}
/**
* Поиск по запросу
*
*/
function search ($query)
{
$result = $this->search->getQuery($query);
return $this->getResult($result);
}
}

View file

@ -1,180 +0,0 @@
<?php
/*
* PHP5 implementation of Martin Porter's stemming algorithm for Russian language.
* Written on a cold winter evening close to the end of 2005 by Dennis Kreminsky (etranger at etranger dot ru)
* Use the code freely, but don't hold me responsible if it breaks whatever it might break.
*
*/
define ('CHAR_LENGTH', '1'); // all Russian characters take 2 bytes in UTF-8, so instead of using (not supported by default) mb_*
// string functions, we use the standard ones with a dirty char-length trick.
// Should you want to use WIN-1251 (or any other charset), convert this source file to that encoding
// and then change CHAR_LENGTH to the proper value, which is likely to be '1' then.
//
class Stemmer {
static public function russian($word)
{
$a = self::rv($word);
$start = $a[0];
$rv = $a[1];
$rv = self::step1($rv);
$rv = self::step2($rv);
$rv = self::step3($rv);
$rv = self::step4($rv);
return $start.$rv;
}
static private function rv($word)
{
$vowels = array('а','е','и','о','у','ы','э','ю','я');
$flag = 0;
$rv = '';
$start = '';
for ($i=0; $i<strlen($word); $i+=CHAR_LENGTH) {
if ($flag==1)
$rv .= substr($word, $i, CHAR_LENGTH);
else
$start .= substr($word, $i, CHAR_LENGTH);
if (array_search(substr($word,$i,CHAR_LENGTH), $vowels) !== false)
$flag=1;
}
return array($start,$rv);
}
static function substitute ($word, &$suffix_list)
{
foreach ($suffix_list as $suffix) {
if (self::has_suffix($word, $suffix)) {
$word = self::cut_suffix($word, $suffix);
}
}
return $word;
}
static function has_suffix ($word, $suffix)
{
return substr($word, -(strlen($suffix))) == $suffix;
}
static function has_aya ($word, $suffix)
{
return (substr($word,-strlen($suffix)-CHAR_LENGTH,CHAR_LENGTH)=='а' || substr($word,-strlen($suffix)-CHAR_LENGTH,CHAR_LENGTH)=='я');
}
static function cut_suffix ($word, $suffix)
{
return substr($word, 0, strlen($word) - strlen($suffix));
}
static private function step1($word)
{
$perfective1 = array('в', 'вши', 'вшись');
foreach ($perfective1 as $suffix) {
if (self::has_suffix($word, $suffix) && self::has_aya ($word, $suffix)) {
return self::cut_suffix($word, $suffix);
}
}
$perfective2 = array('ив','ивши','ившись','ывши','ывшись');
foreach ($perfective2 as $suffix) {
if (self::has_suffix($word, $suffix)) {
return self::cut_suffix($word, $suffix);
}
}
$reflexive = array('ся', 'сь');
$word = self::substitute($word, $reflexive);
$adjective = array('ее','ие','ые','ое','ими','ыми','ей','ий','ый','ой','ем','им','ым','ом','его','ого','ему','ому','их','ых','ую','юю','ая','яя','ою','ею');
$participle2 = array('ем','нн','вш','ющ','щ');
$participle1 = array('ивш','ывш','ующ');
foreach ($adjective as $suffix) {
if (self::has_suffix($word, $suffix)) {
$word = self::cut_suffix($word, $suffix);
foreach ($participle1 as $suffix)
if (self::has_suffix($word, $suffix) && self::has_aya ($word, $suffix))
$word = self::cut_suffix($word, $suffix);
return self::substitute($word, $participle2);
}
}
$verb1 = array('ла','на','ете','йте','ли','й','л','ем','н','ло','но','ет','ют','ны','ть','ешь','нно');
foreach ($verb1 as $suffix)
if (self::has_suffix($word, $suffix) && self::has_aya ($word, $suffix))
return self::cut_suffix($word, $suffix);
$verb2 = array('ила','ыла','ена','ейте','уйте','ите','или','ыли','ей','уй','ил','ыл','им','ым','ен','ило','ыло','ено','ят','ует','уют','ит','ыт','ены','ить','ыть','ишь','ую','ю');
foreach ($verb2 as $suffix)
if (self::has_suffix($word, $suffix))
return self::cut_suffix($word, $suffix);
$noun = array('а','ев','ов','ие','ье','е','иями','ями','ами','еи','ии','и','ией','ей','ой','ий','й','иям','ям','ием','ем','ам','ом','о','у','ах','иях','ях','ы','ь','ию','ью','ю','ия','ья','я');
foreach ($noun as $suffix) {
if (self::has_suffix($word, $suffix))
return self::cut_suffix($word, $suffix);
}
return $word;
}
static private function step2($word)
{
if (substr($word,-CHAR_LENGTH,CHAR_LENGTH) == 'и')
$word = substr($word, 0, strlen($word)-CHAR_LENGTH);
return $word;
}
static private function step3($word)
{
$vowels = array('а','е','и','о','у','ы','э','ю','я');
$flag = 0;
$r1 = '';
$r2 = '';
for ($i=0; $i<strlen($word); $i+=CHAR_LENGTH)
{
if ($flag==2)
$r1.=substr($word, $i, CHAR_LENGTH);
if (array_search(substr($word,$i,CHAR_LENGTH), $vowels) !== false)
$flag=1;
if ($flag=1 && array_search(substr($word,$i,CHAR_LENGTH), $vowels) === false)
$flag=2;
}
$flag=0;
for ($i=0; $i<strlen($r1); $i+=CHAR_LENGTH)
{
if ($flag==2)
$r2.=substr($r1, $i, CHAR_LENGTH);
if (array_search(substr($r1,$i,CHAR_LENGTH), $vowels) !== false)
$flag=1;
if ($flag=1 && array_search(substr($r1,$i,CHAR_LENGTH), $vowels) === false)
$flag=2;
}
$derivational=array('ост', 'ость');
foreach ($derivational as $suffix)
if (substr($r2,-(strlen($suffix))) == $suffix)
$word=substr($word, 0, strlen($r2)-strlen($suffix));
return $word;
}
static private function step4($word)
{
if (substr($word,-CHAR_LENGTH*2)=='нн')
$word=substr($word, 0, strlen($word)-CHAR_LENGTH);
else
{
$superlative=array('ейш', 'ейше');
foreach ($superlative as $suffix)
if (substr($word,-(strlen($suffix))) == $suffix)
$word = substr($word, 0, strlen($word) - strlen($suffix));
if (substr($word,-CHAR_LENGTH*2) == 'нн')
$word = substr($word, 0, strlen($word) - CHAR_LENGTH);
}
// should there be a guard flag? can't think of a russian word that ends with ейшь or ннь anyways, though the algorithm states this is an "otherwise" case
if (substr($word,-CHAR_LENGTH,CHAR_LENGTH) == 'ь')
$word=substr($word, 0, strlen($word)-CHAR_LENGTH);
return $word;
}
}

View file

@ -2,6 +2,10 @@
class SortRecord
{
public $key;
public $mode;
public $order;
function __construct($key, $mode, $order)
{
$this->key = $key;

View file

@ -1,98 +0,0 @@
<?php
require_once 'core/search/htmlhelper.php';
/**
* Функции для проверки орфографии
* rename Spell -> SpellHelper ??
*/
class Spell
{
private $pspell;
public $autocorrect = false;
public function __construct ($language, $encoding)
{
$this->pspell = pspell_new($language, '', '', $encoding, PSPELL_NORMAL);
}
function spellCheckWord ($word)
{
$word = $word[0];
// Ignore ALL CAPS
if (preg_match('/^[A-Z0-9]*$/', $word)) return $word;
// Return dictionary words
if (pspell_check($this->pspell, $word))
return $word;
// Auto-correct with the first suggestion, color green
if ($this->autocorrect && $suggestions = pspell_suggest($this->pspell, $word))
return '<span class="spell-suggest">' . current($suggestions) . '</span>';
// No suggestions, color red
return '<span class="spell-nosuggest">' . $word . '</span>';
}
function isGoodWord ($word)
{
// Ignore ALL CAPS
if (preg_match('/^[A-Z]*$/', $word)) return true;
if (preg_match('/^[0-9]*$/', $word)) return true;
// Return dictionary words
if (pspell_check($this->pspell, $word))
return true;
return false;
}
function suggest ($string)
{
return preg_replace_callback('/\b\w+\b/', array($this, 'spellCheckWord'), $string);
}
/**
* Вызывает функцию для каждого найденного слова
*/
function eachWord ($call, $string)
{
$begin = indexLeft ($string, 'ctype_alpha', 0);
while ($begin !== false) {
$end = indexLeft ($string, 'not_ctype_alpha', $begin);
call_user_func ($call, $string, $begin, $end);
$begin = indexLeft ($string, 'ctype_alpha', $end);
}
return false;
}
/**
* Проверяет слово на соответствие со словарем
*
*/
function doWord (&$string, $begin, $end)
{
$word = substr($string, $begin, $end - $begin);
if (! $this->isGoodWord ($word)) {
$start = max(indexLeft ($string, 'not_ctype_alpha', $begin - 100), 0);
$offset = indexLeft ($string, 'not_ctype_alpha', $end + 100);
if (! $offset) {
$offset = strlen($string);
}
$length = $offset - $start;
throw new Exception ($this->suggest(substr($string, $start, $length)));
}
}
/**
* Часть текста содержащий неправильное слово
*/
function getError ($string)
{
try {
self::eachWord (array ($this, 'doWord'), $string);
} catch (Exception $e) {
return $e->getMessage();
}
return false;
}
}

View file

@ -6,7 +6,7 @@ class Excel_Number
function __construct($value)
{
$this->value = $value;
$this->value = intval($value);
}
function getString()
@ -75,8 +75,8 @@ class ExcelTable
private $style;
protected $rows = array();
protected $splitVertical = false;
protected $splitHorizontal = false;
protected $_splitVertical = false;
protected $_splitHorizontal = false;
function __construct()
{
@ -94,7 +94,8 @@ class ExcelTable
if(! isset($this->rows[$x])) {
$this->rows[$x] = new TableRow();
}
$this->rows[$x]->setCell($y, $value);
/*.TableRow.*/$row = $this->rows[$x];
$row->setCell($y, $value);
}
/**
@ -142,12 +143,13 @@ class ExcelTable
* @param $cell Номер столбца
* @param $merge Количество клеток для обьединения
*/
function setCellMerge ($row, $cell, $merge)
function setCellMerge($x, $cell, $merge)
{
assert(is_numeric($row) && $row > 0);
assert(is_numeric($x) && $x > 0);
assert(is_numeric($cell) && $cell > 0);
$this->rows[$row]->cells[$cell]->merge = $merge;
/*.TableRow.*/$row = $this->rows[$x];
$row->cells[$cell]->merge = $merge;
}
/**
@ -181,7 +183,8 @@ class ExcelTable
*/
function getRows()
{
return max(array_keys($this->rows));
/*.array.*/$keys = array_keys($this->rows);
return max($keys);
}
/**
@ -189,27 +192,26 @@ class ExcelTable
*
* @return int
*/
function getRowCells($row)
function getRowCells(TableRow $row)
{
return max(array_keys($row->cells));
/*.array.*/$keys = array_keys($row->cells);
return max($keys);
}
/**
* Разделяет таблицу на две части по вертикали
* @param $n integer Количество столбцов слева
*/
function splitVertical($n)
{
$this->splitVertical = $n;
function splitVertical($n) {
$this->_splitVertical = $n;
}
/**
* Разделяет таблицу на две части по горизонтали
* @param $n integer Количество столбцов сверху
*/
function splitHorizontal($n)
{
$this->splitHorizontal = $n;
function splitHorizontal($n) {
$this->_splitHorizontal = $n;
}
@ -218,8 +220,7 @@ class ExcelTable
*
* @return int
*/
function getColumns()
{
function getColumns() {
return max(array_map(array($this, 'getRowCells'), $this->rows));
}
@ -231,7 +232,7 @@ class ExcelTable
/**
* Генерация клетки таблицы (Переработать)
*/
function createCell ($ncell, XMLWriter $doc, $j, $value, $setIndex) {
function createCell (TableCell $ncell, XMLWriter $doc, $j, /*.any.*/$value, $setIndex) {
$doc->startElement("Cell");
if ($ncell->style) {
@ -291,7 +292,7 @@ class ExcelTable
$doc->writeAttribute('ss:Height', $this->rows[$i]->height);
}
$nrow = $this->rows[$i];
/*.TableRow.*/$nrow = $this->rows[$i];
// Флаг индикатор подстановки номера столбца
$setIndex = false;
for ($j = 1; $j <= $columns; $j++) {
@ -321,17 +322,17 @@ class ExcelTable
$doc->writeAttribute('xmlns', 'urn:schemas-microsoft-com:office:excel');
$doc->writeElement('FrozenNoSplit');
if ($this->splitVertical) {
$doc->writeElement('SplitVertical', $this->splitVertical);
$doc->writeElement('LeftColumnRightPane', $this->splitVertical);
if ($this->_splitVertical) {
$doc->writeElement('SplitVertical', $this->_splitVertical);
$doc->writeElement('LeftColumnRightPane', $this->_splitVertical);
}
if ($this->splitHorizontal) {
$doc->writeElement('SplitHorizontal', $this->splitHorizontal);
$doc->writeElement('TopRowBottomPane', $this->splitHorizontal);
if ($this->_splitHorizontal) {
$doc->writeElement('SplitHorizontal', $this->_splitHorizontal);
$doc->writeElement('TopRowBottomPane', $this->_splitHorizontal);
}
if ($this->splitHorizontal && $this->splitVertical) {
if ($this->_splitHorizontal && $this->_splitVertical) {
$doc->writeElement('ActivePane', 0);
} else if($this->splitHorizontal) {
} else if($this->_splitHorizontal) {
$doc->writeElement('ActivePane', 2);
}
$doc->endElement();
@ -377,6 +378,7 @@ class ExcelDocument {
if ($type == 'Borders') {
$doc->startElement('Borders');
foreach ($s as $border) {
/*.array.*/$border = $border;
$doc->startElement('Border');
foreach ($border as $key => $value) {
$doc->writeAttribute('ss:' . $key, $value);
@ -403,7 +405,7 @@ class ExcelDocument {
function clean ($s) {
assert(is_string($s));
return strtr($s, array ("\n" => '&#10;'));
return strtr($s, array ("\n" => "&#10;"));
}
/**
@ -412,7 +414,7 @@ class ExcelDocument {
*/
function save($filename)
{
$doc = new xmlWriter();
$doc = new XMLWriter();
$doc->openURI($filename);
$doc->setIndent(false);
$doc->startDocument('1.0','utf-8');

View file

@ -16,7 +16,6 @@ class Tools_Image
{
$width = imagesx($image);
$height = imagesy($image);
$percent = min($prewidth / $width, $preheight / $height);
if ($percent > 1 && !$force) $percent = 1;
$new_width = $width * $percent;

View file

@ -1,32 +0,0 @@
<?php
function generatePassword($length = 9, $strength = 0) {
$vowels = 'aeuy';
$consonants = 'bdghjmnpqrstvz';
if ($strength & 1) {
$consonants .= 'BDGHJLMNPQRSTVWXZ';
}
if ($strength & 2) {
$vowels .= "AEUY";
}
if ($strength & 4) {
$consonants .= '23456789';
}
if ($strength & 8) {
$consonants .= '@#$%';
}
$password = '';
$alt = time() % 2;
for ($i = 0; $i < $length; $i++) {
if ($alt == 1) {
$password .= $consonants[(rand() % strlen($consonants))];
$alt = 0;
} else {
$password .= $vowels[(rand() % strlen($vowels))];
$alt = 1;
}
}
return $password;
}

View file

@ -0,0 +1,164 @@
<?php
/*
* $Id: SQLStatementExtractor.php,v 1.5 2004/07/27 23:13:46 hlellelid Exp $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://creole.phpdb.org>.
*/
/**
* Static class for extracting SQL statements from a string or file.
*
* @author Hans Lellelid <hans@xmpl.org>
* @version $Revision: 1.5 $
* @package creole.util.sql
*/
class Tools_SQLStatementExtractor {
protected static $delimiter = ';';
/**
* Get SQL statements from file.
*
* @param string $filename Path to file to read.
* @return array SQL statements
*/
public static function extractFile($filename) {
$buffer = file_get_contents($filename);
if ($buffer === false) {
throw new Exception("Unable to read file: " . $filename);
}
return self::extractStatements(self::getLines($buffer));
}
/**
* Extract statements from string.
*
* @param string $txt
* @return array
*/
public static function extract($buffer) {
return self::extractStatements(self::getLines($buffer));
}
/**
* Extract SQL statements from array of lines.
*
* @param array $lines Lines of the read-in file.
* @return string
*/
protected static function extractStatements($lines) {
$statements = array();
$sql = "";
foreach($lines as $line) {
$line = trim($line);
if (self::startsWith("//", $line) ||
self::startsWith("--", $line) ||
self::startsWith("#", $line)) {
continue;
}
if (strlen($line) > 4 && strtoupper(substr($line,0, 4)) == "REM ") {
continue;
}
$sql .= " " . $line;
$sql = trim($sql);
// SQL defines "--" as a comment to EOL
// and in Oracle it may contain a hint
// so we cannot just remove it, instead we must end it
if (strpos($line, "--") !== false) {
$sql .= "\n";
}
if (self::endsWith(self::$delimiter, $sql)) {
$statements[] = self::substring($sql, 0, strlen($sql)-1 - strlen(self::$delimiter));
$sql = "";
}
}
return $statements;
}
//
// Some string helper methods
//
/**
* Tests if a string starts with a given string.
* @param string $check The substring to check.
* @param string $string The string to check in (haystack).
* @return boolean True if $string starts with $check, or they are equal, or $check is empty.
*/
protected static function startsWith($check, $string) {
if ($check === "" || $check === $string) {
return true;
} else {
return (strpos($string, $check) === 0) ? true : false;
}
}
/**
* Tests if a string ends with a given string.
* @param string $check The substring to check.
* @param string $string The string to check in (haystack).
* @return boolean True if $string ends with $check, or they are equal, or $check is empty.
*/
protected static function endsWith($check, $string) {
if ($check === "" || $check === $string) {
return true;
} else {
return (strpos(strrev($string), strrev($check)) === 0) ? true : false;
}
}
/**
* a natural way of getting a subtring, php's circular string buffer and strange
* return values suck if you want to program strict as of C or friends
*/
protected static function substring($string, $startpos, $endpos = -1) {
$len = strlen($string);
$endpos = (int) (($endpos === -1) ? $len-1 : $endpos);
if ($startpos > $len-1 || $startpos < 0) {
trigger_error("substring(), Startindex out of bounds must be 0<n<$len", E_USER_ERROR);
}
if ($endpos > $len-1 || $endpos < $startpos) {
trigger_error("substring(), Endindex out of bounds must be $startpos<n<".($len-1), E_USER_ERROR);
}
if ($startpos === $endpos) {
return (string) $string{$startpos};
} else {
$len = $endpos-$startpos;
}
return substr($string, $startpos, $len+1);
}
/**
* Convert string buffer into array of lines.
*
* @param string $filename
* @return array string[] lines of file.
*/
protected static function getLines($buffer) {
$lines = preg_split("/\r?\n|\r/", $buffer);
return $lines;
}
}

View file

@ -1,94 +0,0 @@
<?php
class TableExcelView {
private $list = array();
private $data = array();
function setColumns(array $list) {
$this->list = $list;
}
function makeTable() {
$xls = new ExcelTable();
$xls->setRow(1, 1, array_keys($this->list));
foreach($this->data as $n => $item) {
$result = array();
foreach($this->list as $key => $c) {
if (is_callable($c)) {
$result [] = call_user_func($c, $item, $n);
} else {
if (is_numeric($item[$c])) {
$result [] = new Excel_Number($item[$c]);
} else {
$result [] = $item[$c];
}
}
}
$xls->addRow(1, $result);
}
return $xls;
}
function writeTable($data, $file) {
$this->data = $data;
$xls = new ExcelDocument();
$xls->addTable(array($this, 'makeTable'));
$xls->save($file);
}
}
class TableHTMLView {
private $list = array();
private $stack = array();
private $result = array();
function writeElement($name, $content) {
echo "<".$name.">";
echo $content;
echo "</".$name.">";
}
function startElement($name) {
array_push($this->stack, $name);
echo "<".$name.">";
}
function endElement() {
$name = array_pop($this->stack);
echo "</".$name.">";
}
function setColumns(array $list) {
$this->list = $list;
}
function writeTable($data) {
$this->startElement('table');
$this->startElement('thead');
$this->startElement('tr');
foreach($this->list as $key => $c) {
$this->writeElement('th', $key);
}
$this->endElement();
$this->endElement();
$this->startElement('tbody');
foreach($data as $n => $item) {
$this->startElement('tr');
foreach($this->list as $key => $c) {
if (is_callable($c)) {
$this->writeElement('td', call_user_func($c, $item, $n));
} else {
$this->writeElement('td', $item[$c]);
}
}
$this->endElement();
}
$this->endElement();
$this->endElement();
}
}

View file

@ -1,636 +0,0 @@
<?php
//****************************************************************************
// phpDBTree 1.4
//****************************************************************************
// Author: Maxim Poltarak <maxx at e dash taller dot net>
// WWW: http://dev.e-taller.net/dbtree/
// Category: Databases
// Description: PHP class implementing a Nested Sets approach to storing
// tree-like structures in database tables. This technique was
// introduced by Joe Celko <http://www.celko.com/> and has some
// advantages over a widely used method called Adjacency Matrix.
//****************************************************************************
// The lib is FREEWARE. That means you may use it anywhere you want, you may
// do anything with it. The Author mentioned above is NOT responsible for any
// consequences of using this library.
// If you don't agree with this, you are NOT ALLOWED to use the lib!
//****************************************************************************
// You're welcome to send me all improvings, feature requests, bug reports...
//****************************************************************************
// SAMPLE DB TABLE STRUCTURE:
//
// CREATE TABLE categories (
// cat_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
// cat_left INT UNSIGNED NOT NULL,
// cat_right INT UNSIGNED NOT NULL,
// cat_level INT UNSIGNED NOT NULL,
// PRIMARY KEY(cat_id),
// KEY(cat_left, cat_right, cat_level)
// );
//
// This is believed to be the optimal Nested Sets use case. Use `one-to-one`
// relations on `cat_id` field between this `structure` table and
// another `data` table in your database.
//
// Don't forget to make a single call to clear()
// to set up the Root node in an empty table.
//
//****************************************************************************
// NOTE: Although you may use this library to retrieve data from the table,
// it is recommended to write your own queries for doing that.
// The main purpose of the library is to provide a simpler way to
// create, update and delete records. Not to SELECT them.
//****************************************************************************
//
// IMPORTANT! DO NOT create either UNIQUE or PRIMARY keys on the set of
// fields (`cat_left`, `cat_right` and `cat_level`)!
// Unique keys will destroy the Nested Sets structure!
//
//****************************************************************************
// CHANGELOG:
// 16-Apr-2003 -=- 1.1
// - Added moveAll() method
// - Added fourth parameter to the constructor
// - Renamed getElementInfo() to getNodeInfo() /keeping BC/
// - Added "Sample Table Structure" comment
// - Now it trigger_error()'s in case of any serious error, because if not you
// will lose the Nested Sets structure in your table
// 19-Feb-2004 -=- 1.2
// - Fixed a bug in moveAll() method?
// Thanks to Maxim Matyukhin for the patch.
// 13-Jul-2004 -=- 1.3
// - Changed all die()'s for a more standard trigger_error()
// Thanks to Dmitry Romakhin for pointing out an issue with
// incorrect error message call.
// 09-Nov-2004 -=- 1.4
// - Added insertNear() method.
// Thanks to Michael Krenz who sent its implementation.
// - Removed IGNORE keyword from UPDATE clauses in insert() methods.
// It was dumb to have it there all the time. Sorry. Anyway, you had
// to follow the important note mencioned above. If you hadn't, you're
// in problem.
//
//****************************************************************************
// Note: For best viewing of the code Tab size 4 is recommended
//****************************************************************************
function _case($c, $then, $else) {
return " (CASE WHEN $c THEN $then ELSE $else END) ";
}
function _between($a, $x, $y) {
return " " . $a . " BETWEEN " . $x . " AND " . $y;
}
function _inside($a, $x, $y) {
return " " . $a . " > " . $x . " AND " . $a . " < " . $y;
}
class Tree_DBTree
{
var $db; // CDatabase class to plug to
var $table; // Table with Nested Sets implemented
var $id; // Name of the ID-auto_increment-field in the table.
// These 3 variables are names of fields which are needed to implement
// Nested Sets. All 3 fields should exist in your table!
// However, you may want to change their names here to avoid name collisions.
var $left = 'cat_left';
var $right = 'cat_right';
var $level = 'cat_level';
var $qryParams = '';
var $qryFields = '';
var $qryTables = '';
var $qryWhere = '';
var $qryGroupBy = '';
var $qryHaving = '';
var $qryOrderBy = '';
var $qryLimit = '';
var $sqlNeedReset = true;
var $sql; // Last SQL query
//************************************************************************
// Constructor
// $DB : CDatabase class instance to link to
// $tableName : table in database where to implement nested sets
// $itemId : name of the field which will uniquely identify every record
// $fieldNames : optional configuration array to set field names. Example:
// array(
// 'left' => 'cat_left',
// 'right' => 'cat_right',
// 'level' => 'cat_level'
// )
function CDBTree(&$DB, $tableName, $itemId, $seq, $fieldNames = array())
{
if (empty($tableName)) trigger_error("phpDbTree: Unknown table", E_USER_ERROR);
if (empty($itemId)) trigger_error("phpDbTree: Unknown ID column", E_USER_ERROR);
$this->seq = $seq;
$this->db = $DB;
$this->table = $tableName;
$this->id = $itemId;
if (is_array($fieldNames) && sizeof($fieldNames))
foreach($fieldNames as $k => $v) $this->$k = $v;
}
//************************************************************************
// Returns a Left and Right IDs and Level of an element or false on error
// $ID : an ID of the element
function getElementInfo($ID)
{
return $this->getNodeInfo($ID);
}
function getNodeInfo($ID)
{
$this->sql = 'SELECT ' . $this->left . ',' . $this->right . ',' . $this->level . ' FROM ' . $this->table . ' WHERE ' . $this->id . '=\'' . $ID . '\'';
// print_r($this->sql);
if (($query = $this->db->query($this->sql)) && ($this->db->num_rows($query) == 1) && ($Data = $this->db->fetch_array($query))) return array(
(int)$Data[$this->left],
(int)$Data[$this->right],
(int)$Data[$this->level]
);
else trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR); // throw new Exception();
}
//************************************************************************
// Clears table and creates 'root' node
// $data : optional argument with data for the root node
function clear($data = array())
{
// clearing table
if ((!$this->db->query('TRUNCATE ' . $this->table)) && (!$this->db->query('DELETE FROM ' . $this->table))) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
// preparing data to be inserted
if (sizeof($data)) {
$fld_names = implode(',', array_keys($data)) . ',';
if (sizeof($data)) $fld_values = '\'' . implode('\',\'', array_values($data)) . '\',';
}
$fld_names.= $this->left . ',' . $this->right . ',' . $this->level;
$fld_values.= '1,2,0';
// inserting new record
$this->sql = 'INSERT INTO ' . $this->table . '(' . $fld_names . ') VALUES(' . $fld_values . ')';
if (!($this->db->query($this->sql))) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
return $this->db->insert_id($this->seq);
}
//************************************************************************
// Updates a record
// $ID : element ID
// $data : array with data to update: array(<field_name> => <fields_value>)
function update($ID, $data)
{
$sql_set = '';
foreach($data as $k => $v) $sql_set.= ',' . $k . '=\'' . addslashes($v) . '\'';
return $this->db->query('UPDATE ' . $this->table . ' SET ' . substr($sql_set, 1) . ' WHERE ' . $this->id . '=\'' . $ID . '\'');
}
//************************************************************************
// Inserts a record into the table with nested sets
// $ID : an ID of the parent element
// $data : array with data to be inserted: array(<field_name> => <field_value>)
// Returns : true on success, or false on error
function insert($ID, $data)
{
if (!(list($leftId, $rightId, $level) = $this->getNodeInfo($ID))) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
// preparing data to be inserted
if (sizeof($data)) {
$fld_names = implode(',', array_keys($data)) . ',';
$fld_values = '\'' . implode('\',\'', array_values($data)) . '\',';
}
$fld_names.= $this->left . ',' . $this->right . ',' . $this->level;
$fld_values.= ($rightId) . ',' . ($rightId+1) . ',' . ($level+1);
// creating a place for the record being inserted
if ($ID) {
$this->sql = 'UPDATE ' . $this->table . ' SET ' . $this->left . '=' . _case($this->left . '>' . $rightId, $this->left . '+2', $this->left) . ',' . $this->right . '=' . _case($this->right . '>=' . $rightId, $this->right . '+2', $this->right) . 'WHERE ' . $this->right . '>=' . $rightId;
if (!($this->db->query($this->sql))) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
}
// inserting new record
$this->sql = 'INSERT INTO ' . $this->table . '(' . $fld_names . ') VALUES(' . $fld_values . ')';
if (!($this->db->query($this->sql))) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
return $this->db->insert_id($this->seq);
}
//************************************************************************
// Inserts a record into the table with nested sets
// $ID : ID of the element after which (i.e. at the same level) the new element
// is to be inserted
// $data : array with data to be inserted: array(<field_name> => <field_value>)
// Returns : true on success, or false on error
function insertNear($ID, $data)
{
if (!(list($leftId, $rightId, $level) = $this->getNodeInfo($ID))) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
// preparing data to be inserted
if (sizeof($data)) {
$fld_names = implode(',', array_keys($data)) . ',';
$fld_values = '\'' . implode('\',\'', array_values($data)) . '\',';
}
$fld_names.= $this->left . ',' . $this->right . ',' . $this->level;
$fld_values.= ($rightId+1) . ',' . ($rightId+2) . ',' . ($level);
// creating a place for the record being inserted
if ($ID) {
$this->sql = 'UPDATE ' . $this->table . ' SET ' . $this->left . '=' . _case($this->left . '>' . $rightId, $this->left . '+2', $this->left) . $this->right . '=' . _case($this->right . '>' . $rightId, $this->right . '+2', $this->right) . 'WHERE ' . $this->right . '>' . $rightId;
if (!($this->db->query($this->sql))) trigger_error("phpDbTree error:" . $this->db->error() , E_USER_ERROR);
}
// inserting new record
$this->sql = 'INSERT INTO ' . $this->table . '(' . $fld_names . ') VALUES(' . $fld_values . ')';
if (!($this->db->query($this->sql))) trigger_error("phpDbTree error:" . $this->db->error() , E_USER_ERROR);
return $this->db->insert_id($this->seq);
}
//************************************************************************
// Assigns a node with all its children to another parent
// $ID : node ID
// $newParentID : ID of new parent node
// Returns : false on error
function moveAll($ID, $newParentId)
{
if (!(list($leftId, $rightId, $level) = $this->getNodeInfo($ID))) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
if (!(list($leftIdP, $rightIdP, $levelP) = $this->getNodeInfo($newParentId))) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
if ($ID == $newParentId || $leftId == $leftIdP || ($leftIdP >= $leftId && $leftIdP <= $rightId)) return false;
// whether it is being moved upwards along the path
if ($leftIdP < $leftId && $rightIdP > $rightId && $levelP < $level-1) {
$this->sql = 'UPDATE ' . $this->table . ' SET '
. $this->level . '=' . _case($this->left . ' BETWEEN ' . $leftId . ' AND ' . $rightId, $this->level . sprintf('%+d', -($level-1) +$levelP) , $this->level) . ","
. $this->right . '=' . _case($this->right . ' BETWEEN ' . ($rightId+1) . ' AND ' . ($rightIdP-1) , $this->right . '-' . ($rightId-$leftId+1)
, _case($this->left . ' BETWEEN ' . ($leftId) . ' AND ' . ($rightId) , $this->right . '+' . ((($rightIdP-$rightId-$level+$levelP) /2) *2+$level-$levelP-1) , $this->right)) . ","
. $this->left . '=' . _case($this->left . ' BETWEEN ' . ($rightId+1) . ' AND ' . ($rightIdP-1) , $this->left . '-' . ($rightId-$leftId+1) , _case($this->left . ' BETWEEN ' . $leftId . ' AND ' . ($rightId) , $this->left . '+' . ((($rightIdP-$rightId-$level+$levelP) /2) *2+$level-$levelP-1) , $this->left)) . 'WHERE ' . $this->left . ' BETWEEN ' . ($leftIdP+1) . ' AND ' . ($rightIdP-1);
} elseif ($leftIdP < $leftId) {
$this->sql = 'UPDATE ' . $this->table . ' SET '
. $this->level . '=' . _case($this->left . ' BETWEEN ' . $leftId . ' AND ' . $rightId, $this->level . sprintf('%+d', -($level-1) +$levelP) , $this->level) . ","
. $this->left . '=' . _case($this->left . ' BETWEEN ' . $rightIdP . ' AND ' . ($leftId-1) , $this->left . '+' . ($rightId-$leftId+1)
, _case($this->left . ' BETWEEN ' . $leftId . ' AND ' . $rightId, $this->left . '-' . ($leftId-$rightIdP) , $this->left)) . ","
. $this->right . '=' . _case($this->right . ' BETWEEN ' . $rightIdP . ' AND ' . $leftId, $this->right . '+' . ($rightId-$leftId+1) , _case($this->right . ' BETWEEN ' . $leftId . ' AND ' . $rightId, $this->right . '-' . ($leftId-$rightIdP) , $this->right)) . 'WHERE ' . $this->left . ' BETWEEN ' . $leftIdP . ' AND ' . $rightId
// !!! added this line (Maxim Matyukhin)
. ' OR ' . $this->right . ' BETWEEN ' . $leftIdP . ' AND ' . $rightId;
} else {
$this->sql = 'UPDATE ' . $this->table . ' SET '
. $this->level . '=' . _case($this->left . ' BETWEEN ' . $leftId . ' AND ' . $rightId, $this->level . sprintf('%+d', -($level-1) +$levelP) , $this->level) . ","
. $this->left . '=' . _case($this->left . ' BETWEEN ' . $rightId . ' AND ' . $rightIdP, $this->left . '-' . ($rightId-$leftId+1)
, _case($this->left . ' BETWEEN ' . $leftId . ' AND ' . $rightId, $this->left . '+' . ($rightIdP-1-$rightId), $this->left)) . ", "
. $this->right . '=' . _case($this->right . ' BETWEEN ' . ($rightId+1) . ' AND ' . ($rightIdP-1) , $this->right . '-' . ($rightId-$leftId+1) , _case($this->right . ' BETWEEN ' . $leftId . ' AND ' . $rightId, $this->right . '+' . ($rightIdP-1-$rightId) , $this->right)) . 'WHERE ' . $this->left . ' BETWEEN ' . $leftId . ' AND ' . $rightIdP
// !!! added this line (Maxim Matyukhin)
. ' OR ' . $this->right . ' BETWEEN ' . $leftId . ' AND ' . $rightIdP;
}
return $this->db->query($this->sql) or trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
}
// Перемещение всех детей ветки в другую ветку
function moveChildren($ID, $newParentId)
{
if (!(list($leftId, $rightId, $level) = $this->getNodeInfo($ID))) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
if (!(list($leftIdP, $rightIdP, $levelP) = $this->getNodeInfo($newParentId))) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
if ($ID == $newParentId || $leftId == $leftIdP || ($leftIdP >= $leftId && $leftIdP <= $rightId)) return false;
// whether it is being moved upwards along the path
if ($leftIdP < $leftId && $rightIdP > $rightId && $levelP < $level-1) {
// _update($this->table, array(), )
$this->sql = 'UPDATE ' . $this->table . ' SET '
// Меняем уровень
. $this->level . '=' .
_case(_between($this->left, $leftId, $rightId),
$this->level . sprintf('%+d', -($level-1) +$levelP) , $this->level)
// Меняем границы
. $this->left . '=' .
_case(_beetween($this->left, $rightId+1, $rightIdP-1), $this->left . '-' . $rightId-$leftId+1 ,
_case(_between($this->left, $leftId, $rightId), $this->left . '+' . ((($rightIdP-$rightId-$level+$levelP) /2) *2+$level-$levelP-1) , $this->left))
. $this->right . '=' .
_case(_between($this->right, $rightId+1, $rightIdP-1), $this->right . '-' . ($rightId-$leftId+1) ,
_case(_between($this->left, $leftId, $rightId), $this->right . '+' . ((($rightIdP-$rightId-$level+$levelP) /2) *2+$level-$levelP-1) , $this->right))
. 'WHERE ' . _between($this->left, ($leftIdP+1), ($rightIdP-1));
} elseif ($leftIdP < $leftId) {
$this->sql = 'UPDATE ' . $this->table . ' SET '
. $this->level . '=' .
_case(_between($this->left, $leftId, $rightId),
$this->level . sprintf('%+d', -($level-1) +$levelP) , $this->level)
. $this->left . '=' .
_case(_between($this->left, $rightIdP, $leftId-1), $this->left . '+' . ($rightId-$leftId+1),
_case(_between($this->left, $leftId, $rightId), $this->left . '-' . ($leftId-$rightIdP) , $this->left))
. $this->right . '=' .
_case(_between($this->right, $rightIdP, $leftId), $this->right . '+' . ($rightId-$leftId+1),
_case(_between($this->right, $leftId, $rightId), $this->right . '-' . ($leftId-$rightIdP) , $this->right))
. 'WHERE ' . _between($this->left, $leftIdP, $rightId)
// !!! added this line (Maxim Matyukhin)
. ' OR ' . _between($this->right, $leftIdP, $rightId);
} else {
$this->sql = 'UPDATE ' . $this->table . ' SET '
. $this->level . '='
. _case(_between($this->left, $leftId, $rightId),
$this->level . sprintf('%+d', -($level-1) +$levelP) , $this->level)
. $this->left . '=' .
_case(_between($this->left, $rightId, $rightIdP), $this->left . '-' . ($rightId-$leftId+1),
_case(_between($this->left, $leftId, $rightId), $this->left . '+' . ($rightIdP-1-$rightId), $this->left))
. $this->right . '=' .
_case(_between($this->right, $rightId+1, $rightIdP-1), $this->right . '-' . ($rightId-$leftId+1),
_case(_between($this->right, $leftId, $rightId), $this->right . '+' . ($rightIdP-1-$rightId) , $this->right))
. 'WHERE ' . _between($this->left, $leftId, $rightIdP)
// !!! added this line (Maxim Matyukhin)
. ' OR ' . _between($this->right, $leftId, $rightIdP);
}
return $this->db->query($this->sql) or trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
}
//************************************************************************
// Deletes a record wihtout deleting its children
// $ID : an ID of the element to be deleted
// Returns : true on success, or false on error
function delete($ID)
{
if (!(list($leftId, $rightId, $level) = $this->getNodeInfo($ID))) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
// Deleting record
$this->sql = 'DELETE FROM ' . $this->table . ' WHERE ' . $this->id . '=\'' . $ID . '\'';
if (!$this->db->query($this->sql)) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
// Clearing blank spaces in a tree
$this->sql = 'UPDATE ' . $this->table . ' SET '
. $this->left . '=' . _case($this->left . ' BETWEEN ' . $leftId . ' AND ' . $rightId, $this->left . '-1', $this->left) . ", "
. $this->right . '=' . _case($this->right . ' BETWEEN ' . $leftId . ' AND ' . $rightId, $this->right . '-1', $this->right) . ", "
. $this->level . '=' . _case($this->left . ' BETWEEN ' . $leftId . ' AND ' . $rightId, $this->level . '-1', $this->level) . ", "
. $this->left . '=' . _case($this->left . '>' . $rightId, $this->left . '-2', $this->left) . ", "
. $this->right . '=' . _case($this->right . '>' . $rightId, $this->right . '-2', $this->right)
. ' WHERE ' . $this->right . '>' . $leftId;
if (!$this->db->query($this->sql)) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
return true;
}
//************************************************************************
// Deletes a record with all its children
// $ID : an ID of the element to be deleted
// Returns : true on success, or false on error
function deleteAll($ID)
{
if (!(list($leftId, $rightId, $level) = $this->getNodeInfo($ID))) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
// Deleteing record(s)
$this->sql = 'DELETE FROM ' . $this->table . ' WHERE ' . $this->left . ' BETWEEN ' . $leftId . ' AND ' . $rightId;
if (!$this->db->query($this->sql)) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
// Clearing blank spaces in a tree
$deltaId = ($rightId-$leftId) +1;
$this->sql = 'UPDATE ' . $this->table . ' SET '
. $this->left . '=' . _case($this->left . '>' . $leftId, $this->left . '-' . $deltaId, $this->left) . ", "
. $this->right . '=' . _case($this->right . '>' . $leftId, $this->right . '-' . $deltaId, $this->right)
. ' WHERE ' . $this->right . '>' . $rightId;
if (!$this->db->query($this->sql)) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
return true;
}
//************************************************************************
// Enumerates children of an element
// $ID : an ID of an element which children to be enumerated
// $start_level : relative level from which start to enumerate children
// $end_level : the last relative level at which enumerate children
// 1. If $end_level isn't given, only children of
// $start_level levels are enumerated
// 2. Level values should always be greater than zero.
// Level 1 means direct children of the element
// Returns : a result id for using with other DB functions
function enumChildrenAll($ID)
{
return $this->enumChildren($ID, 1, 0);
}
function enumChildren($ID, $start_level = 1, $end_level = 1)
{
if ($start_level < 0) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
// We could use sprintf() here, but it'd be too slow
$whereSql1 = ' AND ' . $this->table . '.' . $this->level;
$whereSql2 = '_' . $this->table . '.' . $this->level . '+';
if (!$end_level) $whereSql = $whereSql1 . '>=' . $whereSql2 . (int)$start_level;
else {
$whereSql = ($end_level <= $start_level) ? $whereSql1 . '=' . $whereSql2 . (int)$start_level : ' AND ' . $this->table . '.' . $this->level . ' BETWEEN _' . $this->table . '.' . $this->level . '+' . (int)$start_level . ' AND _' . $this->table . '.' . $this->level . '+' . (int)$end_level;
}
$this->sql = $this->sqlComposeSelect(array(
'', // Params
'', // Fields
$this->table . ' _' . $this->table . ', ' . $this->table, // Tables
'_' . $this->table . '.' . $this->id . '=\'' . $ID . '\'' . ' AND ' . $this->table . '.' . $this->left . ' BETWEEN _' . $this->table . '.' . $this->left . ' AND _' . $this->table . '.' . $this->right . $whereSql
));
return $this->db->query($this->sql);
}
function enumChildrenArray($ID, $start_level = 1, $end_level = 1)
{
return $this->db->result2array($this->enumChildren($ID, $start_level, $end_level));
}
//************************************************************************
// Enumerates the PATH from an element to its top level parent
// $ID : an ID of an element
// $showRoot : whether to show root node in a path
// Returns : a result id for using with other DB functions
function enumPath($ID, $showRoot = false)
{
$this->sql = $this->sqlComposeSelect(array(
'', // Params
'', // Fields
$this->table . ' _' . $this->table . ', ' . $this->table, // Tables
'_' . $this->table . '.' . $this->id . '=\'' . $ID . '\'' . ' AND _' . $this->table . '.' . $this->left . ' BETWEEN ' . $this->table . '.' . $this->left . ' AND ' . $this->table . '.' . $this->right . (($showRoot) ? '' : ' AND ' . $this->table . '.' . $this->level . '>0') , // Where
'', // GroupBy
'', // Having
$this->table . '.' . $this->left // OrderBy
));
return $this->db->query($this->sql);
}
function enumPathArray($ID, $showRoot = false)
{
return $this->db->result2array($this->enumPath($ID, $showRoot));
}
//************************************************************************
// Returns query result to fetch data of the element's parent
// $ID : an ID of an element which parent to be retrieved
// $level : Relative level of parent
// Returns : a result id for using with other DB functions
function getParent($ID, $level = 1)
{
if ($level < 1) trigger_error("phpDbTree error: " . $this->db->error() , E_USER_ERROR);
$this->sql = $this->sqlComposeSelect(array(
'', // Params
'', // Fields
$this->table . ' _' . $this->table . ', ' . $this->table, // Tables
'_' . $this->table . '.' . $this->id . '=\'' . $ID . '\'' . ' AND _' . $this->table . '.' . $this->left . ' BETWEEN ' . $this->table . '.' . $this->left . ' AND ' . $this->table . '.' . $this->right . ' AND ' . $this->table . '.' . $this->level . '=_' . $this->table . '.' . $this->level . '-' . (int)$level // Where
));
$result = $this->db->result2array($this->db->query($this->sql));
return (int)$result[0][$this->id];
}
//************************************************************************
function sqlReset()
{
$this->qryParams = '';
$this->qryFields = '';
$this->qryTables = '';
$this->qryWhere = '';
$this->qryGroupBy = '';
$this->qryHaving = '';
$this->qryOrderBy = '';
$this->qryLimit = '';
return true;
}
//************************************************************************
function sqlSetReset($resetMode)
{
$this->sqlNeedReset = ($resetMode) ? true : false;
}
//************************************************************************
function sqlParams($param = '')
{
return (empty($param)) ? $this->qryParams : $this->qryParams = $param;
}
function sqlFields($param = '')
{
return (empty($param)) ? $this->qryFields : $this->qryFields = $param;
}
function sqlSelect($param = '')
{
return $this->sqlFields($param);
}
function sqlTables($param = '')
{
return (empty($param)) ? $this->qryTables : $this->qryTables = $param;
}
function sqlFrom($param = '')
{
return $this->sqlTables($param);
}
function sqlWhere($param = '')
{
return (empty($param)) ? $this->qryWhere : $this->qryWhere = $param;
}
function sqlGroupBy($param = '')
{
return (empty($param)) ? $this->qryGroupBy : $this->qryGroupBy = $param;
}
function sqlHaving($param = '')
{
return (empty($param)) ? $this->qryHaving : $this->qryHaving = $param;
}
function sqlOrderBy($param = '')
{
return (empty($param)) ? $this->qryOrderBy : $this->qryOrderBy = $param;
}
function sqlLimit($param = '')
{
return (empty($param)) ? $this->qryLimit : $this->qryLimit = $param;
}
//************************************************************************
function sqlComposeSelect($arSql)
{
$joinTypes = array(
'join' => 1,
'cross' => 1,
'inner' => 1,
'straight' => 1,
'left' => 1,
'natural' => 1,
'right' => 1
);
$this->sql = 'SELECT ' . $arSql[0] . ' ';
if (!empty($this->qryParams)) $this->sql.= $this->sqlParams . ' ';
if (empty($arSql[1]) && empty($this->qryFields)) $this->sql.= $this->table . '.' . $this->id;
else {
if (!empty($arSql[1])) $this->sql.= $arSql[1];
if (!empty($this->qryFields)) $this->sql.= ((empty($arSql[1])) ? '' : ',') . $this->qryFields;
}
$this->sql.= ' FROM ';
// $tblAr = array(0 => 'join');
$isJoin = ($tblAr = explode(' ', trim($this->qryTables)))
&& /*($joinTypes[strtolower($tblAr[0]) ])*/ 1;
if (empty($arSql[2]) && empty($this->qryTables)) $this->sql.= $this->table;
else {
if (!empty($arSql[2])) $this->sql.= $arSql[2];
if (!empty($this->qryTables)) {
if (!empty($arSql[2])) $this->sql.= (($isJoin) ? ' ' : ',');
elseif ($isJoin) $this->sql.= $this->table . ' ';
$this->sql.= $this->qryTables;
}
}
if ((!empty($arSql[3])) || (!empty($this->qryWhere))) {
$this->sql.= ' WHERE ' . $arSql[3] . ' ';
if (!empty($this->qryWhere)) $this->sql.= (empty($arSql[3])) ? $this->qryWhere : 'AND(' . $this->qryWhere . ')';
}
if ((!empty($arSql[4])) || (!empty($this->qryGroupBy))) {
$this->sql.= ' GROUP BY ' . $arSql[4] . ' ';
if (!empty($this->qryGroupBy)) $this->sql.= (empty($arSql[4])) ? $this->qryGroupBy : ',' . $this->qryGroupBy;
}
if ((!empty($arSql[5])) || (!empty($this->qryHaving))) {
$this->sql.= ' HAVING ' . $arSql[5] . ' ';
if (!empty($this->qryHaving)) $this->sql.= (empty($arSql[5])) ? $this->qryHaving : 'AND(' . $this->qryHaving . ')';
}
if ((!empty($arSql[6])) || (!empty($this->qryOrderBy))) {
$this->sql.= ' ORDER BY ' . (isset($arSql[6]) ? $arSql[6] : '') . ' ';
if (!empty($this->qryOrderBy)) $this->sql.= (empty($arSql[6])) ? $this->qryOrderBy : ',' . $this->qryOrderBy;
}
if (!empty($arSql[7])) $this->sql.= ' LIMIT ' . $arSql[7];
elseif (!empty($this->qryLimit)) $this->sql.= ' LIMIT ' . $this->qryLimit;
if ($this->sqlNeedReset) $this->sqlReset();
return $this->sql;
}
//************************************************************************
}

View file

@ -1,135 +0,0 @@
<?php
//****************************************************************************
// phpDatabase 2.1
//****************************************************************************
// Author: Maxim Poltarak <maxx at e dash taller dot net>
// Category: Databases
//****************************************************************************
// The lib is FREEWARE. This means you may use it anywhere you want, you may
// do anything with it. The Author mentioned above is NOT responsible for any
// consequences of using this library.
// If you don't agree with this, you MAY NOT use the lib!
//****************************************************************************
// All improvings, feature requests, bug reports, etc. are gladly accepted.
//****************************************************************************
// Note: For best viewing of the code Tab size 4 is recommended
//****************************************************************************
class Tree_Database
{
var $link;
var $db;
var $host, $user, $pass;
function CDatabase($db, $host = "localhost", $user = "", $pass = "")
{
$this->db = $db;
$this->host = $host;
$this->user = $user;
$this->pass = $pass;
$str = "host={$host} port=5432 dbname={$db} user={$user} password={$pass}";
$this->link = pg_connect($str);
}
function query($sql)
{
if (!$this->link) return 0;
return pg_query($this->link, $sql);
}
function affected_rows()
{
return pg_affected_rows($this->link);
}
function num_rows($q)
{
return pg_num_rows($q);
}
function fetch_array($q) // fetchAll
{
return pg_fetch_array($q, NULL);
}
function fetch_object($q) // fetchObject
{
return pg_fetch_object($q);
}
/* function data_seek($q, $n) {
return pg_data_seek($q, $n);
}
*/
function free_result($q)
{
return pg_free_result($q);
}
function insert_id($seq)
{
$query = "SELECT currval('$seq')";
$res = $this->query($query);
$row = pg_fetch_array($res, NULL, PGSQL_ASSOC);
pg_free_result($res);
return ($row) ? $row['currval'] : 0;
}
function error()
{
return pg_last_error($this->link);
}
function error_die($msg = '')
{
die(((empty($msg)) ? '' : $msg . ': ') . $this->error());
}
function sql2var($sql)
{
if ((empty($sql)) || (!($query = $this->query($sql)))) return false;
if ($this->num_rows($query) < 1) return false;
return $this->result2var($query);
}
function result2var($q)
{
if (!($Data = $this->fetch_array($q))) return false;
$this->free_result($q);
foreach($Data as $k => $v) $GLOBALS[$k] = $v;
return true;
}
/*function sql2array($sql, $keyField = '')
{
if ((empty($sql)) || (!($query = $this->query($sql)))) return false;
if ($this->num_rows($query) < 1) return false;
return $this->result2array($query, $keyField);
}*/
function result2array($q, $keyField = '')
{
$Result = array();
while ($Data = $this->fetch_array($q))
if (empty($keyField)) $Result[] = $Data;
else $Result[$Data[$keyField]] = $Data;
$this->free_result($q);
return $Result;
}
/*function list_tables()
{
return mysql_list_tables($this->db, $this->link);
}
function list_fields($table_name)
{
return mysql_list_fields($this->db, $table_name, $this->link);
}*/
};

View file

@ -1,79 +0,0 @@
<?php
/**
* Сортировка дерева в представлении Nested Set
* Для дерева которое хранится в базе данных используя представление Nested Set нет возможности отсортировать элементы дерева по
* произвольному полю. Поэтому после извлечения дерева из базы данных оно преобразуется в обычное представление сортируется и обратно
*
* Пример:
* $sort = new NestedSetSort();
* $data = $sort->sortBy($data, 'name');
*/
class Tree_Sort {
private $data = array();
private $result = array();
private $sortBy = '';
public function __construct() {
}
// Преобразуем Nested Set в дерево и сортируем
private function listTree(array $tree, $offset, $level) {
$result = array();
for ($i = $offset; $i < sizeof($tree); $i++) {
$leaf = $tree[$i];
$clevel = $leaf['cat_level'];
if ($clevel == $level) {
$result [] = array($i);
} else if ($clevel > $level) {
list($subtree, $i) = $this->listTree($tree, $i, $clevel);
$i--;
$result[sizeof($result) - 1][1] = $subtree;
} else {
$this->sortList($result, $tree);
return array($result, $i);
}
}
$this->sortList($result, $tree);
return array($result, $i);
}
// Сравнение двух элементов
private function compare($a, $b) {
$a1 = $this->data[$a[0]][$this->sortBy];
$b1 = $this->data[$b[0]][$this->sortBy];
return strcmp($a1, $b1);
}
// Сортировка списка
private function sortList(array &$list, $data) {
usort($list, array($this, 'compare'));
}
// Создает дерево в виде списка
private function reorder(array $tree) {
foreach($tree as $node) {
$this->result[] = $this->data[$node[0]];
if (isset($node[1])) {
$this->reorder($node[1]);
}
}
}
public function sortBy0(array $data, $sortBy)
{
$this->data = $data;
$this->sortBy = $sortBy;
$order = $this->listTree($data, 0, 0);
return $order[0];
}
// Сортировка по заданному полю
public function sortBy(array $data, $sortBy) {
$this->data = $data;
$this->sortBy = $sortBy;
$order = $this->listTree($data, 0, 0);
$this->reorder($order[0]);
return $this->result;
}
}

12
src/UTF8.php Normal file
View file

@ -0,0 +1,12 @@
<?php
class UTF8 {
static function str_split($str, $split_length = 1) {
$split_length = (int) $split_length;
$matches = array();
preg_match_all('/.{'.$split_length.'}|[^\x00]{1,'.$split_length.'}$/us', $str, $matches);
return $matches[0];
}
}

View file

@ -0,0 +1,14 @@
<?php
class Validator_Rule_FileName extends Validator_Rule_Abstract {
public function getErrorMsg()
{
return 'Название файла может содержать только символы латиницы в нижнем регистре и цифры';
}
public function isValid(Collection $container, $status = null)
{
return Path::isName($container->get($this->field));
}
}

View file

@ -1,5 +1,7 @@
<?php
///<reference path="rule/notnull.php"/>
/**
* Проверка коллекции
*/
@ -66,8 +68,7 @@ class Validator_Validator
}
}
public function addRule(&$rule)
{
public function addRule(/*.any.*/&$rule) {
if (is_array($rule)) {
$this->chain = array_merge($this->chain, $rule);
} else {

73
src/View/Page.php Normal file
View file

@ -0,0 +1,73 @@
<?php
class View_Page extends View_View
{
private $counter;
public $text;
function __construct($data)
{
// Вставка компонентов на странице
$pattern = '/<(\w+)(\s+[a-zA-Z\-]+=\"[^\"]*\")*\s+tal:replace="structure\s+component:([^\"]*)"[^>]*>/u';
$matches = array();
preg_match_all($pattern, $data, $matches, PREG_OFFSET_CAPTURE, 0);
$split = array();
$offset = 0;
foreach ($matches[0] as $key => $match) {
$text = $this->fixHTML(substr($data, $offset, $match[1] - $offset));
if (trim($text)) {
$split[] = array('type' => 'page-text', 'content' => $text, 'component' => '', 'module' => '');
}
$offset = $match[1] + strlen($match[0]);
$split[] = $this->replaceContent($matches[3][$key][0], $matches[3][$key][1]);
}
$text = $this->fixHTML(substr($data, $offset));
if (trim($text)) {
$split[] = array('type' => 'page-text', 'content' => $text, 'component' => '', 'module' => '');
}
$this->text = $this->merge($split);
}
function fixHTML($fragment) {
return $fragment;
}
function merge($data) {
if (count($data) == 0) {
$data[] = array('type' => 'page-text', 'content' =>"<p>Добавьте текст<p>", 'component' => '', 'module' => '');
}
$result = array();
foreach($data as $key => $part) {
$result[] = $part['content'];
}
return implode("", $result);
}
function replaceContent($match, $offset)
{
//$result = phptal_component($match, $offset);
//*
global $db, $registry; // Нужно как-то передавать параметры
$component = Controller_Component::loadComponent($match, $db, $registry);
$req = new HttpRequest();
unset($req['active_page']);
$info = $component->getInfo();
$result = $component->execute($req);
if (is_string($result)) {
return array('type' => 'page-component', 'content' => $result, 'component' => $match);
} else {
$this->setView('view' . $this->counter++, $result);
return array('type' => 'page-component', 'content' => $result->execute(), 'component' => $match);
}
}
function execute() {
return $this->text;
}
}

48
src/View/Plain.php Normal file
View file

@ -0,0 +1,48 @@
<?php
// Класс отображения
// CompositeView !! Composite pattern
/**
* @package system.view
*/
class View_Plain
{
protected $document;
protected $values = array();
public function __construct ($document)
{
$this->document = $document;
}
public function set($key, $value)
{
$this->values[$key] = $value;
}
public function import($list)
{
$this->values = array_merge($this->values, $list);
}
public function __set($key, $value)
{
$this->set($key, $value);
}
public function execute()
{
$result = $this->values;
return self::getTemplateContent ($this->document, $result);
}
static function getTemplateContent($document, $result)
{
ob_start ();
include ($document);
$content = ob_get_contents ();
ob_clean ();
return $content;
}
}

View file

@ -1,40 +1,203 @@
<?php
// Класс отображения
// CompositeView !! Composite pattern
// View_Top => View_Base + View_List + View_Template
class View_View
{
protected $document;
protected $values;
protected $_section = array(); // Вложенные шаблоны
// Блоки
protected $_stylesheet = array(); // Массив стилей текущего шаблона
protected $_script = array(); // Массив скриптов текущего шаблона
protected $_scriptstring = array();
protected $_startup = array();
protected $_values = array();
public function __construct ($document)
{
$this->document = $document;
protected $_title = null; // Заголовок текущего шаблона
public $active_module;
public $module_action;
public $suggestions; //подсказки
public $alias = array();
public $codeGenerator = null;
public $parent_view = null;
function __construct() {
}
public function set($key, $value)
/**
* Связывет переменную с вложенным шаблоном
*
* @param string $section переменная шаблона
* @param CompositeView $view вложенный шаблон
*/
public function setView($section, View_View $view)
{
$this->values[$key] = $value;
$this->_section [$section] = $view;
$view->parent_view = $this;
}
public function __set($key, $value)
public function assignValues($values)
{
$this->set($key, $value);
$this->_values = $values;
$this->_values["suggestions"] = $this->suggestions;
}
public function jGrowl($message, $args)
{
$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)
{
$output = $this->resolveName($this->alias, $name);
$this->_script [] = $output;
}
/**
* Добавляет код скипта к текущему шаблону
*
* @param string $name строка javascript кода
*/
public function addScriptRaw($name, $startup = false)
{
if ($startup) {
$this->_startup [] = $name;
} else {
$this->_scriptstring [] = $name;
}
}
/**
* Добавляет стили к текущему шаблону
*
* @param string $name путь к стилю
*/
public function addStyleSheet($name)
{
$output = $this->resolveName($this->alias, $name);
$this->_stylesheet [] = $output;
}
/**
* Рекурсивно извлекает из значение свойства обьекта
*
* @param string $list Имя свойства
* @param boolean $flatten
*/
protected function doTree($list, $flatten = true)
{
$result = ($flatten == true) ? $this->$list : array($this->$list);
foreach ($this->_section as $value) {
if (is_object($value)) {
if ($list == '_script' || $list == '_stylesheet') {
$result = array_merge($result, $value->doTree($list, $flatten));
} else {
$result = array_merge($value->doTree($list, $flatten), $result);
}
}
}
return $result;
}
/*abstract*/ public function set($key, $value)
{
}
/**
* Обработка всех вложенных шаблонов
*
* @return string
*/
public function execute()
{
$result = $this->values;
return self::getTemplateContent ($this->document, $result);
foreach ($this->_section as $key => $value) {
$this->set($key, (is_object($value)) ? $value->execute() : $value); // ?
}
}
static function getTemplateContent($document, $result)
/**
* Установка заголовка шаблона
*
* @param string $title
*/
public function setTitle($title)
{
ob_start ();
include ($document);
$result = ob_get_contents ();
ob_clean ();
$this->_title = $title;
}
protected function isNotNull($title)
{
return $title !== null;
}
function setAlias($alias)
{
$this->alias = $alias;
}
function addAlias($name, $path)
{
$this->alias[$name] = $path;
$this->set($name, $path);
}
function find_file($pathlist, $file) {
foreach($pathlist as $key => $www) {
if (file_exists($key . '/' . $file)) {
return $www . '/' . $file;
}
}
throw new Exception("file not found: $file");
}
function resolveName($alias, $file) {
list($type, $filename) = explode(":", $file, 2);
// Сделать поиск а не просто замену папки при совпадении имени
if (is_array($alias[$type])) {
$output = $this->find_file($alias[$type], $filename);
} else {
$output = $alias[$type] . '/' . $filename;
}
return $output;
}
function loadImports($importFile)
{
$types = array(
'js' => array($this, 'addScript'),
'css' => array($this, 'addStyleSheet')
);
// Подключение стилей и скриптов
if (file_exists($importFile)) {
$files = file($importFile);
foreach ($files as $file) {
// Получить расширение вместо strpos
$file = trim($file);
if (!empty($file)) {
$ext = pathinfo($file, PATHINFO_EXTENSION);
call_user_func($types[$ext], $file);
}
}
}
}
public function resolveAllNames($alias, $list) {
$result = array();
foreach($list as $item) {
$result [] = $this->resolveName($alias, $item);
}
return $result;
}
}

13
src/View/list.php Normal file
View file

@ -0,0 +1,13 @@
<?php
class View_List extends View_View
{
function execute()
{
$result = array();
foreach ($this->_section as $key => $value) {
$result [] = $value->execute();
}
return $result;
}
}

View file

@ -1,26 +0,0 @@
<?php
$settings = array
(
0 => '',
1 => 'Город Ярославль',
2 => 'Большесельский район',
3 => 'Борисоглебский район',
4 => 'Брейтовский район',
5 => 'Гаврилов-Ямский район',
6 => 'Даниловский район',
7 => 'Любимский район',
8 => 'Мышкинский район',
9 => 'Некоузский район',
10 => 'Некрасовский район',
11 => 'Переславский район',
12 => 'Первомайский район',
13 => 'Пошехонский район',
14 => 'Ростовский район',
15 => 'Рыбинский район',
16 => 'Тутаевский район',
17 => 'Угличский район',
18 => 'Ярославский район',
19 => 'Город Переславль',
20 => 'Город Рыбинск'
);

View file

@ -1,14 +0,0 @@
<?php
$settings = array(
0 => '',
1 => 'г.',
2 => 'с.',
3 => 'п.',
4 => 'д.',
5 => 'пгт.',
6 => 'р.п.',
7 => 'ст.',
8 => 'а.'
);

View file

@ -1,14 +0,0 @@
<?php
// Массив типов поселений
$settings = array(
// 0 => '',
1 => 'город',
2 => 'село',
3 => 'поселок',
4 => 'деревня',
5 => 'поселок городского типа',
6 => 'рабочий поселок',
7 => 'станица',
8 => 'аул'
);

View file

@ -1,196 +0,0 @@
<?php
/**
* http://www.w3schools.com/media/media_mimeref.asp
*/
$settings = array (
"" => "application/octet-stream",
"323" => "text/h323",
"acx" => "application/internet-property-stream",
"ai" => "application/postscript",
"aif" => "audio/x-aiff",
"aifc" => "audio/x-aiff",
"aiff" => "audio/x-aiff",
"asf" => "video/x-ms-asf",
"asr" => "video/x-ms-asf",
"asx" => "video/x-ms-asf",
"au" => "audio/basic",
"avi" => "video/x-msvideo",
"axs" => "application/olescript",
"bas" => "text/plain",
"bcpio" => "application/x-bcpio",
"bin" => "application/octet-stream",
"bmp" => "image/bmp",
"c" => "text/plain",
"cat" => "application/vnd.ms-pkiseccat",
"cdf" => "application/x-cdf",
"cer" => "application/x-x509-ca-cert",
"class" => "application/octet-stream",
"clp" => "application/x-msclip",
"cmx" => "image/x-cmx",
"cod" => "image/cis-cod",
"cpio" => "application/x-cpio",
"crd" => "application/x-mscardfile",
"crl" => "application/pkix-crl",
"crt" => "application/x-x509-ca-cert",
"csh" => "application/x-csh",
"css" => "text/css",
"dcr" => "application/x-director",
"der" => "application/x-x509-ca-cert",
"dir" => "application/x-director",
"dll" => "application/x-msdownload",
"dms" => "application/octet-stream",
"doc" => "application/msword",
"dot" => "application/msword",
"dvi" => "application/x-dvi",
"dxr" => "application/x-director",
"eps" => "application/postscript",
"etx" => "text/x-setext",
"evy" => "application/envoy",
"exe" => "application/octet-stream",
"fif" => "application/fractals",
"flr" => "x-world/x-vrml",
"gif" => "image/gif",
"gtar" => "application/x-gtar",
"gz" => "application/x-gzip",
"h" => "text/plain",
"hdf" => "application/x-hdf",
"hlp" => "application/winhlp",
"hqx" => "application/mac-binhex40",
"hta" => "application/hta",
"htc" => "text/x-component",
"htm" => "text/html",
"html" => "text/html",
"htt" => "text/webviewhtml",
"ico" => "image/x-icon",
"ief" => "image/ief",
"iii" => "application/x-iphone",
"ins" => "application/x-internet-signup",
"isp" => "application/x-internet-signup",
"jfif" => "image/pipeg",
"jpe" => "image/jpeg",
"jpeg" => "image/jpeg",
"jpg" => "image/jpeg",
"js" => "application/x-javascript",
"latex" => "application/x-latex",
"lha" => "application/octet-stream",
"lsf" => "video/x-la-asf",
"lsx" => "video/x-la-asf",
"lzh" => "application/octet-stream",
"m13" => "application/x-msmediaview",
"m14" => "application/x-msmediaview",
"m3u" => "audio/x-mpegurl",
"man" => "application/x-troff-man",
"mdb" => "application/x-msaccess",
"me" => "application/x-troff-me",
"mht" => "message/rfc822",
"mhtml" => "message/rfc822",
"mid" => "audio/mid",
"mny" => "application/x-msmoney",
"mov" => "video/quicktime",
"movie" => "video/x-sgi-movie",
"mp2" => "video/mpeg",
"mp3" => "audio/mpeg",
"mpa" => "video/mpeg",
"mpe" => "video/mpeg",
"mpeg" => "video/mpeg",
"mpg" => "video/mpeg",
"mpp" => "application/vnd.ms-project",
"mpv2" => "video/mpeg",
"ms" => "application/x-troff-ms",
"mvb" => "application/x-msmediaview",
"nws" => "message/rfc822",
"oda" => "application/oda",
"p10" => "application/pkcs10",
"p12" => "application/x-pkcs12",
"p7b" => "application/x-pkcs7-certificates",
"p7c" => "application/x-pkcs7-mime",
"p7m" => "application/x-pkcs7-mime",
"p7r" => "application/x-pkcs7-certreqresp",
"p7s" => "application/x-pkcs7-signature",
"pbm" => "image/x-portable-bitmap",
"pdf" => "application/pdf",
"pfx" => "application/x-pkcs12",
"pgm" => "image/x-portable-graymap",
"pko" => "application/ynd.ms-pkipko",
"pma" => "application/x-perfmon",
"pmc" => "application/x-perfmon",
"pml" => "application/x-perfmon",
"pmr" => "application/x-perfmon",
"pmw" => "application/x-perfmon",
"pnm" => "image/x-portable-anymap",
"pot," => "application/vnd.ms-powerpoint",
"ppm" => "image/x-portable-pixmap",
"pps" => "application/vnd.ms-powerpoint",
"ppt" => "application/vnd.ms-powerpoint",
"prf" => "application/pics-rules",
"ps" => "application/postscript",
"pub" => "application/x-mspublisher",
"qt" => "video/quicktime",
"ra" => "audio/x-pn-realaudio",
"ram" => "audio/x-pn-realaudio",
"ras" => "image/x-cmu-raster",
"rgb" => "image/x-rgb",
"rmi" => "audio/mid",
"roff" => "application/x-troff",
"rtf" => "application/rtf",
"rtx" => "text/richtext",
"scd" => "application/x-msschedule",
"sct" => "text/scriptlet",
"setpay" => "application/set-payment-initiation",
"setreg" => "application/set-registration-initiation",
"sh" => "application/x-sh",
"shar" => "application/x-shar",
"sit" => "application/x-stuffit",
"snd" => "audio/basic",
"spc" => "application/x-pkcs7-certificates",
"spl" => "application/futuresplash",
"src" => "application/x-wais-source",
"sst" => "application/vnd.ms-pkicertstore",
"stl" => "application/vnd.ms-pkistl",
"stm" => "text/html",
"svg" => "image/svg+xml",
"sv4cpio" => "application/x-sv4cpio",
"sv4crc" => "application/x-sv4crc",
"swf" => "application/x-shockwave-flash",
"t" => "application/x-troff",
"tar" => "application/x-tar",
"tcl" => "application/x-tcl",
"tex" => "application/x-tex",
"texi" => "application/x-texinfo",
"texinfo" => "application/x-texinfo",
"tgz" => "application/x-compressed",
"tif" => "image/tiff",
"tiff" => "image/tiff",
"tr" => "application/x-troff",
"trm" => "application/x-msterminal",
"tsv" => "text/tab-separated-values",
"txt" => "text/plain",
"uls" => "text/iuls",
"ustar" => "application/x-ustar",
"vcf" => "text/x-vcard",
"vrml" => "x-world/x-vrml",
"wav" => "audio/x-wav",
"wcm" => "application/vnd.ms-works",
"wdb" => "application/vnd.ms-works",
"wks" => "application/vnd.ms-works",
"wmf" => "application/x-msmetafile",
"wps" => "application/vnd.ms-works",
"wri" => "application/x-mswrite",
"wrl" => "x-world/x-vrml",
"wrz" => "x-world/x-vrml",
"xaf" => "x-world/x-vrml",
"xbm" => "image/x-xbitmap",
"xla" => "application/vnd.ms-excel",
"xlc" => "application/vnd.ms-excel",
"xlm" => "application/vnd.ms-excel",
"xls" => "application/vnd.ms-excel",
"xlt" => "application/vnd.ms-excel",
"xlw" => "application/vnd.ms-excel",
"xof" => "x-world/x-vrml",
"xpm" => "image/x-xpixmap",
"xwd" => "image/x-xwindowdump",
"z" => "application/x-compress",
"zip" => "application/zip",
);

View file

@ -1,35 +0,0 @@
<?php
// В ОКАТО приняты следующие сокращения:
// http://www.consultant.ru/online/base/?req=doc;base=LAW;n=62484
$settings = array (
"р" => "район",
"г" => "город",
"пгт" => "поселок городского типа",
"рп" => "рабочий поселок",
"кп" => "курортный поселок",
"к" => "кишлак",
"пс" => "поселковый совет",
"сс" => "сельсовет",
"смн" => "сомон",
"вл" => "волость",
"дп" => "дачный поселковый совет",
"п" => "поселок сельского типа",
"нп" => "населенный пункт",
"п. ст" => "поселок при станции",
"ж/д ст" => "железнодорожная станция",
"с" => "село",
"м" => "местечко",
"д" => "деревня",
"сл" => "слобода",
"ст" => "станция",
"ст-ца" => "станица",
"х" => "хутор",
"у" => "улус",
"рзд" => "разъезд",
"клх" => "колхоз",
"им" => "имени",
"свх" => "совхоз",
"зим" => "зимовье",
);

View file

@ -1,91 +0,0 @@
<?php
$settings = array (
0 => '',
2 => 'Алтайский край',
3 => 'Амурская область',
4 => 'Архангельская область',
5 => 'Астраханская область',
6 => 'Белгородская область',
7 => 'Брянская область',
8 => 'Владимирская область',
9 => 'Волгоградская область',
10 => 'Вологодская область',
11 => 'Воронежская область',
12 => 'г. Москва',
13 => 'г. Санкт-Петербург',
14 => 'Еврейская автономная область',
84 => 'Забайкальский край',
15 => 'Ивановская область',
16 => 'Иркутская область',
17 => 'Кабардино-Балкарская Республика',
18 => 'Калининградская область',
19 => 'Калужская область',
20 => 'Камчатский край',
21 => 'Карачаево-Черкесская Республика',
22 => 'Кемеровская область',
23 => 'Кировская область',
28 => 'Костромская область',
29 => 'Краснодарский край',
30 => 'Красноярский край',
31 => 'Курганская область',
32 => 'Курская область',
33 => 'Ленинградская область',
34 => 'Липецкая область',
35 => 'Магаданская область',
36 => 'Московская область',
37 => 'Мурманская область',
38 => 'Ненецкий автономный округ',
39 => 'Нижегородская область',
40 => 'Новгородская область',
41 => 'Новосибирская область',
42 => 'Омская область',
43 => 'Оренбургская область',
44 => 'Орловская область',
45 => 'Пензенская область',
46 => 'Пермский край',
47 => 'Приморский край',
48 => 'Псковская область',
49 => 'Республика Адыгея',
50 => 'Республика Алтай',
51 => 'Республика Башкортостан',
52 => 'Республика Бурятия',
25 => 'Республика Дагестан',
26 => 'Республика Ингушетия',
53 => 'Республика Калмыкия',
54 => 'Республика Карелия',
55 => 'Республика Коми',
56 => 'Республика Марий Эл',
57 => 'Республика Мордовия',
58 => 'Республика Саха(Якутия)',
59 => 'Республика Северная Осетия-Алания',
60 => 'Республика Татарстан',
61 => 'Республика Тыва',
62 => 'Республика Хакасия',
63 => 'Ростовская область',
64 => 'Рязанская область',
65 => 'Самарская область',
66 => 'Саратовская область',
67 => 'Сахалинская область',
68 => 'Свердловская область',
69 => 'Смоленская область',
70 => 'Ставропольский край',
71 => 'Таймырский (Долгано-Ненецкий) автономный округ',
72 => 'Тамбовская область',
73 => 'Тверская область',
74 => 'Томская область',
75 => 'Тульская область',
76 => 'Тюменская область',
77 => 'Удмуртская Республика',
78 => 'Ульяновская область',
80 => 'Хабаровский край',
81 => 'Ханты-Мансийский автономный округ',
82 => 'Челябинская область',
83 => 'Чеченская Республика',
85 => 'Чувашская Республика',
86 => 'Чукотский автономный округ',
87 => 'Эвенкийский автономный округ',
88 => 'Ямало-Ненецкий автономный округ',
89 => 'Ярославская область'
);

View file

@ -1,32 +0,0 @@
<?php
$settings = array (
0 => array('title' => ''),
1 => array(
'title' => 'Центральный федеральный округ',
'short' => 'ЦФО',
'regions' => array(6, 7, 8, 11, 12, 15, 19, 28, 32, 34, 36, 44, 64, 69, 72, 73, 75, 89)),
2 => array(
'title' => 'Южный федеральный округ',
'short' => 'ЮФО',
'regions' => array(5, 9, 17, 21, 29, 49, 25, 26, 53, 59, 63, 70, 83)),
3 => array(
'title' => 'Северо-западный федеральный округ',
'short' => 'СЗФО',
'regions' => array(4, 10, 13, 18, 33, 37, 38, 40, 48, 54, 55)),
4 => array(
'title' => 'Дальневосточный федеральный округ',
'short' => 'ДФО',
'regions' => array(3, 14, 20, 35, 47, 58, 67, 80, 86)),
5 => array(
'title' => 'Сибирский федеральный округ',
'short' => 'СФО',
'regions' => array(2, 16, 22, 30, 41, 42, 50, 52, 61, 62, 71, 74, 84, 86, 87)),
6 => array(
'title' => 'Уральский федеральный округ',
'short' => 'УФО',
'regions' => array(31, 68, 76, 81, 82, 88)),
7 => array(
'title' => 'Приволжский федеральный округ',
'short' => 'ПФО',
'regions' => array(23, 39, 43, 45, 46, 51, 56, 57, 60, 65, 66, 77, 78, 85)));

41
src/process.php Normal file
View file

@ -0,0 +1,41 @@
<?php
if (!function_exists('str_getcsv')) {
function str_getcsv($input, $delimiter = ",", $enclosure = '"', $escape = "\\") {
$fiveMBs = 1024;
$fp = fopen("php://temp/maxmemory:$fiveMBs", 'r+');
if (is_resource($fp)) {
fputs($fp, $input);
rewind($fp);
$data = fgetcsv($fp, 1000, $delimiter, $enclosure);
fclose($fp);
}
return $data;
}
}
function process_exists($pid) {
if (PHP_OS == 'WINNT') {
$processes = explode("\n", shell_exec("tasklist.exe /NH /FO CSV"));
foreach($processes as $process) {
if ($process != "") {
$csv = str_getcsv($process);
if ($pid == $csv[1]) return true;
}
}
return false;
} else {
return file_exists("/proc/$pid");
}
}
function create_single_proces($fpid, $fn) {
if (file_exists($fpid)) {
print_r(realpath($fpid));
if (process_exists(file_get_contents($fpid))) {
return 1;
}
}
call_user_func($fn);
return 0;
}

33
src/security.php Normal file
View file

@ -0,0 +1,33 @@
<?php
class Security {
static function generatePassword($length = 9, $strength = 0) {
$vowels = 'aeuy';
$consonants = 'bdghjmnpqrstvz';
if ($strength & 1) {
$consonants .= 'BDGHJLMNPQRSTVWXZ';
}
if ($strength & 2) {
$vowels .= "AEUY";
}
if ($strength & 4) {
$consonants .= '23456789';
}
if ($strength & 8) {
$consonants .= '@#$%';
}
$password = '';
$alt = time() % 2;
for ($i = 0; $i < $length; $i++) {
if ($alt == 1) {
$password .= $consonants[(rand() % strlen($consonants))];
$alt = 0;
} else {
$password .= $vowels[(rand() % strlen($vowels))];
$alt = 1;
}
}
return $password;
}
}

View file

@ -4,19 +4,20 @@
* Преобразование дерева из модели Plain в массив массивов (Adjacency List)
*/
require_once 'src/functions.php';
require_once 'functions.php';
/**
* Обходит таблицу как дерево
* @param $level Array Уровни вложенности
* @param $table Таблица
* @param $fn Функция которая применяется к каждой ветке дерева
* $fn ($name, $index, $rows, $cc)
* @param $name Ключ уровня
* @param $index Значение ключа уровня
* @param $rows Все столбцы текущго уровня
* @parma $cc Столбцы более низкого уровня
* $name Ключ уровня
* $index Значение ключа уровня
* $rows Все столбцы текущго уровня
* $cc Столбцы более низкого уровня
*
* @param Array $level Уровни вложенности
* @param array $table Таблица
* @param Function $fn Функция которая применяется к каждой ветке дерева
*/
function tableTreeWalk($level, $table, $fn) {
if (empty ($level)) return $table;

View file

@ -47,10 +47,14 @@ function phptal_time ($e)
function phptal_component ($expression) {
global $db, $registry; // Нужно как-то передавать параметры
$begin = microtime(true);
$component = Controller_Component::loadComponent($expression, $db, $registry);
$req = new HttpRequest();
return $component->execute($req);
$result = $component->execute($req);
echo "<!-- ", $expression, ", ", round(microtime(true) - $begin, 4), "sec -->";
return $result;
}