Убрал phptal и лишнее

This commit is contained in:
Фёдор Подлеснов 2016-07-21 14:49:21 +03:00
parent 651a841187
commit 96043d70e6
95 changed files with 4 additions and 10833 deletions

View file

@ -11,7 +11,7 @@ class Adapter
$this->adaptee = $adaptee;
}
public function get ($name)
public function get($name)
{
if (is_array ($this->adaptee)) {
return $this->adaptee [$name];
@ -20,5 +20,3 @@ class Adapter
}
}
}
?>

View file

@ -1,7 +1,7 @@
<?php
function loadConfig($filename) {
if (@include($filename)) {
if (@include($filename)) {
return $settings;
}
throw new Exception("config $filename not found");

View file

@ -78,5 +78,3 @@ class FileRecord
return isset($this->file['title']) ? $this->file['title'] : $this->getName();
}
}
?>

View file

@ -1,583 +0,0 @@
<?php
require_once 'core/path.php';
require_once 'core/file.php';
interface IFileSystem
{
// Операции над файлами
public function makeDirectory($name);
public function deleteDirectory($name);
public function deleteFile($name);
public function renameFile($source, $destination);
public function copyFile($source, $destination);
public function moveUploadedFile($source, $destination);
// deleteDirectoryRecursive
public function isDir($name);
public function readFile($source);
public function writeFile($source, $content);
// Содержание директории
public function directoryFiles($name);
public function directoryFilesRecursive($name);
}
interface IFileControl
{
public function commitFile($name, $who, $message);
public function readFileVersion($name, $version = false);
// Информация о файле
public function getFileLog($name);
public function getFileInfo($name);
}
// Реальная файловая система
class FileSystem implements IFileSystem
{
protected $hidden = array('.', '..');
protected $visible = null;
public function __construct()
{
}
public function setVisibleFiles(array $visible)
{
$this->visible = $visible;
}
public function setHiddenFiles(array $hidden)
{
$this->hidden = array_merge($this->hidden, $hidden);
}
/**
*
*/
public function makeDirectory($name)
{
if (file_exists($name) === false) {
mkdir($name);
}
}
/**
*
*/
public function makeFile($name)
{
if (file_exists($name) === false) {
file_put_contents($name, '');
}
}
/**
*
*/
public function deleteDirectory($name)
{
rmdir($name);
}
/**
*
*/
public function deleteDirectoryRecursive($name)
{
if ($handle = opendir($name)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
$sf = $name . DIRECTORY_SEPARATOR . $file;
if (is_dir($sf) && !is_link($sf)) {
self::deleteDirectoryRecursive($sf);
} else {
unlink($sf);
}
}
}
closedir($handle);
@rmdir($name);
}
}
/**
*
*/
public function deleteFile($name)
{
if (file_exists($name)) {
unlink($name);
}
}
// При перемещении или все файлы если есть совпадения переписываются
/**
*
*/
public function renameFile($source, $destination)
{
rename($source, $destination);
}
/**
*
*/
public function copyFile($source, $destination)
{
copy($source, $destination);
}
/**
*
*/
public function copyDirectory($source, $destination)
{
if (is_dir($source)) {
if (! file_exists($destination)) mkdir($destination);
$handle = opendir($source);
while (false !== ($file = readdir($handle))) {
$entry = $source . DIRECTORY_SEPARATOR . $file;
if (is_dir($entry)) {
self::copyDirectory($entry, $destination . DIRECTORY_SEPARATOR . $file);
} else {
copy($entry, $destination . DIRECTORY_SEPARATOR . $file);
}
}
}
}
/**
*
*/
public function moveUploadedFile($source, $destination)
{
move_uploaded_file($source, $destination);
}
/**
*
*/
public function isVisible($file)
{
if (in_array(basename($file), $this->hidden) === true) {
return false;
}
return ($this->isDir($file) || $this->visible == null) || in_array(pathinfo($file, PATHINFO_EXTENSION), $this->visible);
}
/**
*
*/
public function directoryFiles($name)
{
$result = array();
$files = scandir($name);
foreach ($files as $file) {
$fullname = $name . DIRECTORY_SEPARATOR . $file;
if ($this->isVisible($fullname)) {
$result [$file] = new FileRecord(array(), $fullname);
}
}
return $result;
}
/**
*
*/
public function readFile($name)
{
return file_get_contents($name);
}
/**
*
*/
public function writeFile($name, $content)
{
file_put_contents($name, $content);
}
/**
*
*/
public function directoryFilesRecursive($name)
{
}
function isDir($name)
{
return is_dir($name);
}
}
// То что хранится в базе данных
class EFileSystem implements IFileSystem, IFileControl
{
protected $basepath;
protected $db;
public function __construct($basepath, $db, $fs)
{
$this->basepath = $basepath;
$this->db = $db;
$this->fs = $fs;
}
/*function createExtendRecord($index)
{
static $fileSQL = "INSERT INTO file (id_record) VALUES (?)";
$query = $this->db->prepareStatement($fileSQL);
$query->setString(1, $index);
$query->executeQuery();
}*/
private function createRecord($name, $type, $path)
{
static $recordSQL = "INSERT INTO files (filename, idfile, lastrevdate, filepath, filetype) VALUES (?, ?, ?, ?, ?)";
$last = $this->db->getIdGenerator();
$index = $last->getId('files_idfile_seq');
$query = $this->db->prepareStatement($recordSQL);
$query->setString(1, $name);
$query->setInt(2, $index);
$query->setInt(3, 0);
$query->setString(4, $path);
$query->setString(5, $type);
$query->executeQuery();
/*if ($type == 0) {
$this->createExtendRecord($index);
}*/
return $index;
}
function setVisibleFiles(array $visible)
{
$this->fs->setVisibleFiles($visible);
}
function setHiddenFiles(array $hidden)
{
$this->fs->setHiddenFiles($hidden);
}
public function getFullPath($name)
{
return Path::join($this->basepath, $name);
}
private function getRecordId($name, $path)
{
static $recordSQL = "SELECT idfile FROM files WHERE filename = ? AND filepath = ?";
$query = $this->db->prepareStatement($recordSQL);
$query->setString(1, $name);
$query->setString(2, $path);
$result = $query->executeQuery();
if ($result->next()) {
$index = $result->getInt('idfile');
return $index;
}
return false; // Может лучше кидать исключение ??
}
function getIdFromPath($name)
{
return $this->getRecordId(basename($name), self::getPathName($name));
}
// Создание новой директории
public function makeDirectory($name)
{
$path = new Path($name);
$fullpath = $this->basepath;
$temp_path = '';
foreach ($path->getParts() as $subpath)
{
$index = $this->getRecordId($subpath, $temp_path);
if ($index === false) {
$index = $this->createRecord($subpath, 1, $temp_path);
}
$temp_path = Path::join($temp_path, $subpath);
}
$this->fs->makeDirectory($this->getFullPath($name));
}
public function isDir($name)
{
return $this->fs->isDir($this->getFullPath($name));
}
// Переименование файла или директории все изменения должны записываться в базу чтобы можно было сделать отмену !!!
public function renameFile($source, $destination)
{
// При перемещении файлы могут совпадать
$stmt = $this->db->prepareStatement('UPDATE files SET filepath = ?, filename = ? WHERE filepath = ? AND filename = ?');
$stmt->setString(1, self::getPathName($destination));
$stmt->setString(2, basename($destination));
$stmt->setString(3, self::getPathName($source));
$stmt->setString(4, basename($source));
$stmt->executeQuery();
if ($this->isDir($source)) {
$length = strlen($from) + 1;
$stmt = $this->db->prepareStatement("UPDATE file
SET filepath = '?' || substr(filepath, ?) WHERE filepath LIKE (?) OR filepath LIKE (? || '/%')");
$stmt->setString(1, $destination);
$stmt->setInt(2, $length);
$stmt->setString(3, $source);
$stmt->setString(4, $source);
}
$this->fs->renameFile($this->getFullPath($source), $this->getFullPath($destination));
}
// Копирование файла или директории
public function copyFile($source, $destination)
{
// При копировании файлы могут совпадать
$stmt = $this->db->prepareStatement('INSERT INTO files (filepath, filename, lastrevdate) VALUES (?, ?, ?)');
$stmt->setString(1, self::getPathName($destination));
$stmt->setString(2, basename($destination));
$stmt->setString(3, time());
$stmt->executeQuery();
if ($this->isDir($source)) {
$stmt = $this->db->prepareStatement("INSERT INTO files (filepath, filename, lastrevdate)
SELECT '?' || substr(filepath, ?) AS filepath, filename, lastrevdate WHERE WHERE filepath LIKE (?) OR filepath LIKE (? || '/%')");
$stmt->setString(1, $destination);
$stmt->setInt(2, $length);
$stmt->setString(3, $source);
$stmt->setString(4, $source);
}
$this->fs->copyFile($this->getFullPath($source), $this->getFullPath($destination));
}
private function getPathName($name)
{
$path = dirname($name);
return ($path == '.') ? '' : $path;
}
public function makeFile($name)
{
$base = self::getPathName($name);
$this->makeDirectory($base);
$filename = basename($name);
$index = $this->getRecordId($filename, $base);
if ($index === false) {
$index = $this->createRecord($filename, 0, $base);
}
$this->fs->makeFile($this->getFullPath($name));
}
public function readFile($name)
{
return $this->fs->readFile($this->getFullPath($name));
}
public function readFileVersion($name, $revision = false)
{
if ($revision === false) {
return $this->readFile($name);
} else {
$id_file = $this->getIdFromPath($name);
$query = $this->db->prepareStatement("SELECT * FROM history WHERE revision = ? AND idfile = ?");
$query->setInt(1, $revision);
$query->setInt(2, $id_file);
$file = $query->executeQuery();
if ($file->next()) {
return gzuncompress($file->getBlob('content'));
}
}
return null;
}
public function writeFile($name, $content)
{
$this->makeFile($name);
$this->fs->writeFile($this->getFullPath($name), $content);
}
public function getLastRevision($name)
{
$id_file = $this->getIdFromPath($name);
$stmt = $this->db->prepareStatement("SELECT * FROM history WHERE revision IN (SELECT MAX(revision) AS lastrev FROM history WHERE idfile = ?)");
$stmt->setInt(1, $id_file);
$rev = $stmt->executeQuery();
if ($rev->next()) {
return $rev;
}
return false;
}
/**
*
*/
public function commitFile($name, $owner, $message)
{
$id_file = $this->getIdFromPath($name);
$content = $this->readFile($name);
$stmt = $this->db->prepareStatement("SELECT MAX(revision) AS lastrev FROM history WHERE idfile = ?");
$stmt->setInt(1, $id_file);
$rev = $stmt->executeQuery();
$revision = ($rev->next()) ? $rev->getInt('lastrev') + 1 : 1;
$query = $this->db->prepareStatement("INSERT INTO history (content, owner, revsummary, revdate, revision, idfile) VALUES (?, ?, ?, ?, ?, ?)");
$query->setBlob(1, gzcompress($content));
$query->setString(2, $owner);
$query->setString(3, $message);
$query->setInt(4, time());
$query->setInt(5, $revision);
$query->setInt(6, $id_file);
$query->executeQuery();
}
/**
*
*/
public function getFileDifference($name, $revision1, $revision2 = false)
{
$first = $this->readFileVersion($name, $revision1);
$second = $this->readFileVersion($name, $revision2);
}
/**
*
*/
public function getFileLog($name)
{
$id_file = $this->getIdFromPath($name);
$query = $this->db->prepareStatement("SELECT revision,revsummary,owner,revdate FROM history WHERE idfile = ? ORDER BY revision");
$query->setInt(1, $id_file);
$list = $query->executeQuery();
return iterator_to_array($list->getIterator());
}
public function directoryFiles($name)
{
$result = $this->fs->directoryFiles($this->getFullPath($name));
/* Список файлов из базы данных */
$query = $this->db->prepareStatement("SELECT * FROM files WHERE filepath = ?");
$query->setString(1, $name);
$list = $query->executeQuery();
foreach ($list as $file) {
$fullpath = $this->getFullPath($name . DIRECTORY_SEPARATOR . $file['filename']);
if ($this->fs->isVisible($fullpath)) {
$file['state'] =
((isset($result[$file['filename']])) ?
(($file['lastrevdate'] > $file['change']) ? 'exclamation' : 'unchanged')
: 'expected');
$record = new FileRecord($file, $fullpath);
$result [$file['filename']] = $record;
}
}
return $result;
}
public function getFileInfo($name)
{
$index = $this->getIdFromPath($name);
$fullpath = $this->basepath . DIRECTORY_SEPARATOR . $name;
if ($index !== false) {
$query = $this->db->prepareStatement("SELECT * FROM files AS r LEFT JOIN filemeta AS f ON r.idfile = f.id_record WHERE r.idfile = ?");
$query->setInt(1, $index);
$list = $query->executeQuery();
$list->next();
$file = $list->getRow();
$file['state'] = (file_exists($fullpath) ? 'unchanged' : 'expected');
$result = new FileRecord($file, $fullpath);
} else {
$result = new FileRecord(array(), $fullpath);
}
return $result;
}
public function setFileInfo($name, Collection $list)
{
$index = $this->getIdFromPath($name);
if ($index !== false) {
$stmt = $this->db->prepareStatement("UPDATE files SET title = ? WHERE idfile = ?");
$stmt->setString(1, $list->get('title'));
$stmt->setInt(2, $index);
$stmt->executeQuery();
/*if (some($list, array('keywords', 'author', 'description'))) {
$hasfile = $this->db->executeQuery("SELECT * FROM file WHERE id_record = $index");
if(!$hasfile->next()) {
static $fileSQL = "INSERT INTO file (id_record) VALUES (?)";
$query = $this->db->prepareStatement($fileSQL);
$query->setString(1, $index);
$query->executeQuery();
}
$query = $this->db->prepareStatement("UPDATE file SET keywords = ?, author = ?, description = ? WHERE id_record = ?");
$query->setString(1, $list->get('keywords'));
$query->setString(2, $list->get('author'));
$query->setString(3, $list->get('description'));
$query->setInt(4, $index);
$query->executeQuery();
}*/
}
}
/**
* Удаляем директорию если она не пустая
*/
function deleteDirectory($name)
{
$index = $this->getIdFromPath($name);
$query = $this->db->prepareStatement("SELECT COUNT(*) AS col FROM files WHERE filepath = (?) OR filepath LIKE(? || '/%')");
$query->setString(1, $name);
$query->setString(2, $name);
$result = $query->executeQuery();
$result->next();
if ($index && $result->getInt('col') == 0) {
$query = $this->db->prepareStatement("DELETE FROM files WHERE idfile = ?");
$query->setInt(1, $index);
$query->executeQuery();
}
$this->fs->deleteDirectory($this->getFullPath($name));
}
function deleteFile($name)
{
$index = $this->getIdFromPath($name);
if ($index) {
$query = $this->db->prepareStatement("DELETE FROM history WHERE idfile = ?;
DELETE FROM filemeta WHERE id_record = ?;DELETE FROM files WHERE idfile = ?");
$query->setInt(1, $index);
$query->setInt(2, $index);
$query->setInt(3, $index);
$query->executeQuery();
}
$this->fs->deleteFile($this->getFullPath($name));
}
function moveUploadedFile($source, $destination)
{
$this->fs->moveUploadedFile($source, $this->getFullPath($destination));
$this->makeFile($destination);
}
function directoryFilesRecursive($name)
{
$files = $this->fs->directoryFilesRecursive($this->getFullPath($name));
$query = $this->db->prepareStatement("DELETE FROM files WHERE filepath = (?) OR filepath LIKE (? || '/%')");
$query->setString(1, $name);
$query->setString(2, $name);
$query->executeQuery();
}
}

View file

@ -1,335 +0,0 @@
<?php
/**
* Deprecated !!!!
*/
require_once 'core/adapter.php';
/**
* Новое API для Форм
* $form = new Form ();
* $form->render () -> html,
* $form->adjust ($scheme);
* $form->input ($name, $type, $label, );
* $form->set($name, $value);
* $form->get($name); -> value
* $form->parse ($request),
* $form->validate () -> boolean,
* $form->values () -> pair[key] = value
*/
/**
* Элемент формы
* @package core
*/
class TField {
protected $_value; // Форматированное значение поля
var $label; // Метка поля
var $rule = array ();// Правила для проверки поля
var $value; // Форматированное Значение поля
// var $default; // Значение по умолчанию
var $error = false; // в XRule Правила для проверки значений
var $error_msg = "Поле не может быть пустым";
var $type; // Каждому типу элемента соответствует макрос TAL
public function __construct ($input) {
// $this->deafult = null;
$this->require = false;
// Инициализация свойст обьетка
foreach ($input as $key => $value) {
$this->$key = $value;
}
}
public function __toString () {
return $this->value;
}
public function isValid ($name) {
if ($this->require == true && empty($this->value)) {
$this->error = true;
return false;
}
$this->setValue ($this->value);
return true;
}
// Добавить методы getString, setString ??
function setValue ($value) {
$this->_value = $value;
$this->value = $value;
}
function getValue () {
return $this->_value;
}
}
/**
* Поле ввода Input
* @package core
*/
class TInput extends TField {
public function __construct ($input) {
parent::__construct ($input);
$this->setValue ("");
}
}
// checkbox
class TCheckbox extends TField {
public $checked = false;
public function __construct ($input) {
parent::__construct ($input);
$this->setValue (1);
}
function setValue ($value) {
$this->_value = intval ($value);
$this->value = 1;
if ($this->_value == 1) $this->checked = true; else $this->checked = false;
}
}
/**
* Выбор из одного элемента
*/
class TSelect1 extends TField {
var $options = array ();
public function __construct ($input) {
parent::__construct ($input);
$this->setValue (0);
}
function setValue ($value) {
$this->_value = $value;
$this->value = $value;
foreach ($this->options as $key => $o) {
$this->options[$key]['selected'] = ($this->options[$key]['value'] == $this->_value);
}
}
}
class TSelectGroup extends TField {
var $groups = array ();
public function __construct ($input) {
parent::__construct ($input);
$this->setValue (0);
}
function setValue ($value) {
$this->_value = $value;
$this->value = $value;
foreach ($this->groups as $gkey => $o) {
foreach ($this->groups[$gkey]['options'] as $key => $v) {
$this->groups[$gkey]['options'][$key]['selected'] = ($this->groups[$gkey]['options'][$key]['value'] == $this->_value);
}
}
}
}
/**
* Поле с датой
* @package core
*/
class TDate extends TField {
var $error_msg = "Неверный формат даты";
var $separator = ".";
public function __construct ($input) {
parent::__construct ($input);
$this->setValue (time ());
}
function isValid ($name) {
$value = $this->value;
if ($tmp = explode(".", $value, 3)) {
if ($tmp[1] && $tmp[0] && $tmp[2]) {
if (checkdate ($tmp[1], $tmp[0], $tmp[2])) {
$this->setValue (mktime (0, 0, 0, $tmp[1], $tmp[0], $tmp[2]));
return true;
}
}
}
$this->error = true;
return false;
}
function setValue ($value) {
$this->_value = $value;
$this->value = date ("d.m.Y", $value);
}
}
class TTime extends TField {
var $error_msg = "Неверный формат времени";
public function __construct ($input) {
parent::__construct ($input);
$this->setValue (mktime(0, 0, 0, 11, 30, 1999));
}
function isValid ($name) {
$value = $this->value;
if ($tmp = explode(":", $value, 2)) {
if ($this->checktime ($tmp[0], $tmp[1])) {
$this->setValue (mktime ($tmp[0], $tmp[1], 0, 0, 0, 0));
return true;
}
}
$this->error = true;
return false;
}
function checktime($hour, $minute) {
if ($hour > -1 && $hour < 24 && $minute > -1 && $minute < 60) {
return true;
}
}
function setValue ($value) {
$this->_value = $value;
$this->value = date ("H:i", $value);
}
}
/* *
* Текстовое поле
* @package core
*/
class TTextArea extends TField {
public function __construct ($input) {
parent::__construct ($input);
$this->setValue ("");
}
}
/**
* Поле для ввода пароля
* @package core
*/
class TSecret extends TField {
public function __construct ($input) {
parent::__construct ($input);
$this->setValue ("");
}
}
class TUpload extends TField {
public $types = array ();
public function __construct ($input) {
parent::__construct ($input);
$this->setValue ("");
}
public function setValue ($value) {
$this->_value = basename ($value);
$this->value = $value;
}
}
/**
* Форма для ввода
* @package core
*/
class TForm {
var $field = array ();
var $action = "";
var $method = 'post';
var $request;
var $replace;
public function __construct ($request) {
$this->uid = get_form_uid ();
$this->constructor = array (
'input' => 'TInput',
'checkbox' => 'TCheckbox',
'date' => 'TDate',
'time' => 'TTime',
'textarea' => 'TTextArea',
'select' => 'TSelect',
'select1' => 'TSelect1',
'selgroup' => 'TSelectGroup',
'secret' => 'TSecret',
'upload' => 'TUpload'
);
$this->request = $request;
}
function get ($name) {
return $this->field [$name]->getValue ();
}
function addFieldObject ($name, $el) {
$this->field [$name] = $el;
}
/**
* Метод должен проверять значения полей формы полсле заполнения
* Проверка правильности заполнения формы и установка значений
*/
function isValid () {
$haveErrors = false;
foreach ($this->field as $name => $el) { // ссылка
if ($this->field [$name] instanceof TUpload) {
// print_r ($_POST);
$filename = $this->request->getRawData ('files', $name);
if ((bool) $filename['name']) {
$this->field [$name]->value = $filename['name'];
} else {
$this->field [$name]->value = $this->request->getRawData ($this->method, $name."_file");
}
} else {
$this->field [$name]->value = $this->request->getRawData ($this->method, $name);
}
if (!$this->field [$name]->isValid($name)) {
$haveErrors = true;
}
}
return !$haveErrors;
}
/**
* Добавляет одно поле ввода на форму
*/
public function addField ($init) {
assert ($init['type']);
assert ($init['name']);
$constructor = $this->constructor[$init['type']];
$el = new $constructor ($init);
$el->type = $init['type'];
$this->addFieldObject ($init['name'], $el);
return $el;
}
/**
* Добавляет спсок полей для формы
* @param array $list
*/
public function addFieldList ($list) {
foreach ($list as $init) {
$this->addField ($init);
}
}
/**
* Заполняет форму данными из коллекции
* Для обьектов и массивов можно использовать Adapter pattern
* @param object $data
* @param array $schema Связь между элементами формы и свойствами обьекта
*/
public function fill ($data) {
foreach ($this->field as $name => $el) {
$this->field [$name]->setValue ($data->get ($name));
}
}
}
?>

View file

@ -176,5 +176,3 @@ class TForm
$this->field[$name]->setValue($value);
}
}
?>

View file

@ -83,4 +83,3 @@ class HFile {
}
}
?>

View file

@ -10,4 +10,3 @@ class Point
}
}
?>

View file

@ -49,5 +49,3 @@ class Rectangle
return new Point((($base->left + $base->right) - ($this->left + $this->right)) / 2, $base->bottom - $this->height);
}
}
?>

View file

@ -26,5 +26,3 @@ class ModelFactory
return $model;
}
}
?>

View file

@ -7,4 +7,3 @@ class Meta
{
}
?>

View file

@ -203,4 +203,3 @@ class Query
}
}
?>

View file

@ -1,865 +0,0 @@
// Version: 0.8
// ANTLR Version: 2.7.2
// Date: 2003.08.25
//
// Description: This is a MS SQL Server 2000 SELECT statement grammar.
//
// =======================================================================================
// Author: Tomasz Jastrzebski
// Contact: tdjastrzebski@yahoo.com
// Working parser/lexer generated based on this grammar will available for some time at:
// http://jastrzebski.europe.webmatrixhosting.net/mssqlparser.aspx
options {
language = "CSharp";
}
// PARSER ********************************************************************************
class SqlParser extends Parser;
options {
k = 2;
}
// starting rule
statement
: selectStatement (SEMICOLON)? EOF
;
selectStatement
:
queryExpression
(computeClause)?
(forClause)?
(optionClause)?
;
queryExpression
: subQueryExpression (unionOperator subQueryExpression)* (orderByClause)?
;
subQueryExpression
:
querySpecification
| LPAREN queryExpression RPAREN
;
querySpecification
:
selectClause
(fromClause)?
(whereClause)?
(groupByClause (havingClause)? )?
;
selectClause
: SELECT (ALL | DISTINCT)? (TOP Integer (PERCENT)? (WITH TIES)? )? selectList
;
whereClause
: WHERE searchCondition
;
orderByClause
: ORDER BY expression (ASC | DESC)? (COMMA expression (ASC | DESC)? )*
;
groupByClause
: GROUP BY (ALL)? expression (COMMA expression)* (WITH (CUBE | ROLLUP) )?
;
havingClause
: HAVING searchCondition
;
optionClause
: OPTION LPAREN queryHint (COMMA queryHint)* RPAREN
;
queryHint
:
(HASH | ORDER) GROUP
| (CONCAT | HASH | MERGE) UNION
| (LOOP | MERGE | HASH) JOIN
| FAST Integer
| FORCE ORDER
| MAXDOP Integer
| ROBUST PLAN
| KEEP PLAN
| KEEPFIXED PLAN
| EXPAND VIEWS
;
forClause
:
FOR (
BROWSE
| XML (RAW | AUTO | EXPLICIT) (COMMA XMLDATA)? (COMMA ELEMENTS)? (COMMA BINARY BASE64)
)
;
computeClause
:
COMPUTE
// only allowed functions are: AVG, COUNT, MAX, MIN, STDEV, STDEVP, VAR, VARP, SUM
identifier LPAREN expression RPAREN
(COMMA identifier LPAREN expression RPAREN)*
(BY expression (COMMA expression)* )?
;
searchCondition
: subSearchCondition ( (AND | OR) subSearchCondition )*
;
subSearchCondition
:
(NOT)? (
(LPAREN searchCondition RPAREN) => LPAREN searchCondition RPAREN
| predicate
)
;
predicate
:
(
expression (
// expression comparisonOperator expression
comparisonOperator (
expression
| (ALL | SOME | ANY) LPAREN selectStatement RPAREN
)
| IS (NOT)? NULL
| (NOT)? (
LIKE expression (ESCAPE expression)? // only single char
| BETWEEN expression AND expression
| IN LPAREN (
(selectStatement) => selectStatement
| expression (COMMA expression)*
) RPAREN
)
| CONTAINS LPAREN (dbObject | STAR) COMMA (stringLiteral | Variable) RPAREN
| FREETEXT LPAREN (dbObject | STAR) COMMA (stringLiteral | Variable) RPAREN
)
| EXISTS LPAREN selectStatement RPAREN
)
;
selectList
: selectItem ( COMMA selectItem )*
;
selectItem
:
STAR // "*, *" is a valid select list
| (
// starts with: "alias = column_name"
(alias2) => (
(alias2 dbObject COMMA) => alias2 column
| (alias2 dbObject (binaryOperator | LPAREN)) => alias2 expression
| (alias2 column) => alias2 column
| (alias2 expression) => alias2 expression
)
// all table columns: "table.*"
| (tableColumns) => tableColumns
// some shortcuts:
| (dbObject (alias1)? COMMA) => column (alias1)?
| (dbObject (binaryOperator | LPAREN) ) => expression (alias1)?
// less obvious cases:
| (column) => column (alias1)?
| (expression) => expression (alias1)?
)
;
fromClause
: FROM tableSource (COMMA tableSource)*
;
tableSource
: subTableSource (joinedTable)*
;
subTableSource
:
(
LPAREN (
(joinedTables) => joinedTables RPAREN
| (queryExpression) => queryExpression RPAREN alias1 // "derived table", mandatory alias
)
| (function) => function (alias1)?
| dbObject (alias1)? ( (WITH)? LPAREN tableHint (COMMA tableHint)* RPAREN )?
| Variable (alias1)?
| (CONTAINSTABLE | FREETEXTTABLE) LPAREN
dbObject COMMA (dbObject | STAR) COMMA (stringLiteral | Variable) (COMMA Integer)?
RPAREN (alias1)?
| COLON COLON function (alias1)? // built-in function
)
;
joinedTable
:
CROSS JOIN subTableSource
// "joinHint JOIN" is invalid join expression
| ( (INNER | (LEFT | RIGHT | FULL) (OUTER)? ) (joinHint)? )? JOIN tableSource ON searchCondition
;
joinedTables
: subTableSource (joinedTable)+
;
joinHint
:
LOOP
| HASH
| MERGE
| REMOTE
;
tableHint
:
INDEX (
LPAREN (identifier | Integer) ( COMMA (identifier | Integer) )* RPAREN
| ASSIGNEQUAL identifier // old index hint syntax
)
| FASTFIRSTROW
| HOLDLOCK
| NOLOCK
| PAGLOCK
| READCOMMITED
| READPAST
| READUNCOMMITED
| REPEATABLEREAD
| ROWLOCK
| SERIALIZABLE
| TABLOCK
| TABLOCKX
| UPDLOCK
| XLOCK
;
collate
: COLLATE identifier
;
alias1
: // alias name can also be single-quoted literal (but not for table names)
(AS)? (
identifier
| stringLiteral
| keywordAsIdentifier
)
;
alias2
:
(
identifier
| stringLiteral
| keywordAsIdentifier
)
ASSIGNEQUAL
;
tableColumns
:
o:dbObject DOT_STAR
;
column
:
(PLUS)* // "++column_name" is valid and updatable column name
(
dbObject
// for expression like "(column)" SQL Server returns updatable column
| LPAREN column RPAREN
)
(collate)? // it is not well documented but COLLATE can be used almost anywhere ...
;
expression
: // current definition ignores operator precedence
subExpression (binaryOperator subExpression)*
;
subExpression
:
(unaryOperator)?
(
constant
| Variable
| (function) => function
| LPAREN (
(selectStatement) => selectStatement // select statement returning a single value
| expression
) RPAREN
| dbObject // column
| parameterlessFunction
| caseFunction
| castFunction
)
(collate)? // it is not well documented but COLLATE can be used almost everywhere ...
;
// todo: create a separate rule for aggregate functions
function
: // LEFT and RIGHT keywords are also function names
(dbObject | LEFT | RIGHT) LPAREN (
expression (COMMA expression)*
| STAR // aggregate functions like Count(), Checksum() accept "*" as a parameter
| (ALL | DISTINCT) (STAR | expression) // aggregate function
| Variable ASSIGNEQUAL expression (COMMA Variable ASSIGNEQUAL expression)*
)?
RPAREN
;
caseFunction
: CASE (
expression (WHEN expression THEN expression)+
| (WHEN searchCondition THEN expression)+ // boolean expression
)
(ELSE expression)? END
;
castFunction
: CAST LPAREN expression AS identifier (LPAREN Integer (COMMA Integer)? RPAREN)? RPAREN
;
dbObject
// server.catalog.schema.object
// server.catalog..object
:
(identifier | IDENTITYCOL | ROWGUIDCOL | keywordAsIdentifier) (
DOT (identifier | IDENTITYCOL | ROWGUIDCOL | keywordAsIdentifier)
| (DOT DOT) => DOT DOT (identifier | IDENTITYCOL | ROWGUIDCOL | keywordAsIdentifier)
)*
;
parameterlessFunction
: // any others ?
CURRENT_TIMESTAMP
| CURRENT_USER
| SESSION_USER
| SYSTEM_USER
;
systemVariable
:
F_CONNECTIONS
| F_CPU_BUSY
| F_CURSOR_ROWS
| F_DATEFIRST
| F_DBTS
| F_ERROR
| F_FETCH_STATUS
| F_IDENTITY
| F_IDLE
| F_IO_BUSY
| F_LANGID
| F_LANGUAGE
| F_LOCK_TIMEOUT
| F_MAX_CONNECTIONS
| F_MAX_PRECISION
| F_NESTLEVEL
| F_OPTIONS
| F_PACK_RECEIVED
| F_PACK_SENT
| F_PACKET_ERRORS
| F_PROCID
| F_REMSERVER
| F_ROWCOUNT
| F_SERVERNAME
| F_SERVICENAME
| F_SPID
| F_TEXTSIZE
| F_TIMETICKS
| F_TOTAL_ERRORS
| F_TOTAL_READ
| F_TOTAL_WRITE
| F_TRANCOUNT
| F_VERSION
;
keywordAsIdentifier
:
(
AUTO
| BASE64
| BINARY
| CAST
| CONCAT
| CUBE
| ELEMENTS
| EXPAND
| EXPLICIT
| FAST
| FASTFIRSTROW
| FORCE
| HASH
| KEEP
| KEEPFIXED
| LOOP
| MAXDOP
| MERGE
| NOLOCK
| PAGLOCK
| RAW
| READCOMMITED
| READPAST
| READUNCOMMITED
| REMOTE
| REPEATABLEREAD
| ROBUST
| ROLLUP
| ROWLOCK
| SERIALIZABLE
| TABLOCK
| TABLOCKX
| TIES
| UPDLOCK
| VIEWS
| XLOCK
| XML
| XMLDATA
)
;
stringLiteral
:
UnicodeStringLiteral
| ASCIIStringLiteral
;
identifier
:
NonQuotedIdentifier
| QuotedIdentifier
;
constant
: Integer | Real | NULL | stringLiteral | HexLiteral | Currency | ODBCDateTime | systemVariable
;
unaryOperator
: PLUS | MINUS | TILDE
;
binaryOperator
: arithmeticOperator | bitwiseOperator
;
arithmeticOperator
: PLUS | MINUS | STAR | DIVIDE | MOD
;
bitwiseOperator
: AMPERSAND | TILDE | BITWISEOR | BITWISEXOR
;
comparisonOperator
:
ASSIGNEQUAL | NOTEQUAL1 | NOTEQUAL2 | LESSTHANOREQUALTO1 | LESSTHANOREQUALTO2
| LESSTHAN | GREATERTHANOREQUALTO1 | GREATERTHANOREQUALTO2 | GREATERTHAN
;
logicalOperator
: ALL | AND | ANY | BETWEEN | EXISTS | IN | LIKE | NOT | OR | SOME
;
unionOperator
: UNION (ALL)?
;
// LEXER *********************************************************************************
class SqlLexer extends Lexer;
options {
testLiterals = false;
k = 2;
caseSensitive = false;
caseSensitiveLiterals = false;
charVocabulary='\u0000'..'\uFFFE';
}
tokens {
ADD = "add" ;
ALL = "all" ;
ALTER = "alter" ;
AND = "and" ;
ANY = "any" ;
AS = "as" ;
ASC = "asc" ;
AUTHORIZATION = "authorization" ;
AUTO = "auto" ;
BACKUP = "backup" ;
BASE64 = "base64" ;
BEGIN = "begin" ;
BETWEEN = "between" ;
BINARY = "binary" ;
BREAK = "break" ;
BROWSE = "browse" ;
BULK = "bulk" ;
BY = "by" ;
CASCADE = "cascade" ;
CASE = "case" ;
CAST = "cast" ;
CHECK = "check" ;
CHECKPOINT = "checkpoint" ;
CLOSE = "close" ;
CLUSTERED = "clustered" ;
// COALESCE = "coalesce" ;
COLLATE = "collate" ;
COLUMN = "column" ;
COMMIT = "commit" ;
COMPUTE = "compute" ;
CONCAT = "concat" ;
CONSTRAINT = "constraint" ;
CONTAINS = "contains" ;
CONTAINSTABLE = "containstable" ;
CONTINUE = "continue" ;
// CONVERT = "convert" ;
CREATE = "create" ;
CROSS = "cross" ;
CUBE = "cube" ;
CURRENT = "current" ;
CURRENT_DATE = "current_date" ;
CURRENT_TIME = "current_time" ;
CURRENT_TIMESTAMP = "current_timestamp" ;
CURRENT_USER = "current_user" ;
CURSOR = "cursor" ;
DATABASE = "database" ;
DBCC = "dbcc" ;
DEALLOCATE = "deallocate" ;
DECLARE = "declare" ;
DEFAULT = "default" ;
DELETE = "delete" ;
DENY = "deny" ;
DESC = "desc" ;
DISK = "disk" ;
DISTINCT = "distinct" ;
DISTRIBUTED = "distributed" ;
DOUBLE = "double" ;
DROP = "drop" ;
// DUMMY = "dummy" ;
DUMP = "dump" ;
ELEMENTS = "elements" ;
ELSE = "else" ;
END = "end" ;
ERRLVL = "errlvl" ;
ESCAPE = "escape" ;
EXCEPT = "except" ;
EXEC = "exec" ;
EXECUTE = "execute" ;
EXISTS = "exists" ;
EXIT = "exit" ;
EXPAND = "expand" ;
EXPLICIT = "explicit" ;
FAST = "fast" ;
FASTFIRSTROW = "fastfirstrow" ;
FETCH = "fetch" ;
FILE = "file" ;
FILLFACTOR = "fillfactor" ;
FOR = "for" ;
FORCE = "force" ;
FOREIGN = "foreign" ;
FREETEXT = "freetext" ;
FREETEXTTABLE = "freetexttable" ;
FROM = "from" ;
FULL = "full" ;
FUNCTION = "function" ;
GOTO = "goto" ;
GRANT = "grant" ;
GROUP = "group" ;
HASH = "hash" ;
HAVING = "having" ;
HOLDLOCK = "holdlock" ;
IDENTITY = "identity" ;
IDENTITY_INSERT = "identity_insert" ;
IDENTITYCOL = "identitycol" ;
IF = "if" ;
IN = "in" ;
INDEX = "index" ;
INNER = "inner" ;
INSERT = "insert" ;
INTERSECT = "intersect" ;
INTO = "into" ;
IS = "is" ;
JOIN = "join" ;
KEEP = "keep" ;
KEEPFIXED = "keepfixed" ;
KEY = "key" ;
KILL = "kill" ;
LEFT = "left" ;
LIKE = "like" ;
LINENO = "lineno" ;
LOAD = "load" ;
LOOP = "loop" ;
MAXDOP = "maxdop" ;
MERGE = "merge" ;
NATIONAL = "national" ;
NOCHECK = "nocheck" ;
NOLOCK = "nolock" ;
NONCLUSTERED = "nonclustered" ;
NOT = "not" ;
NULL = "null" ;
// NULLIF = "nullif" ;
OF = "of" ;
OFF = "off" ;
OFFSETS = "offsets" ;
ON = "on" ;
OPEN = "open" ;
OPENDATASOURCE = "opendatasource" ;
OPENQUERY = "openquery" ;
OPENROWSET = "openrowset" ;
OPENXML = "openxml" ;
OPTION = "option" ;
OR = "or" ;
ORDER = "order" ;
OUTER = "outer" ;
OVER = "over" ;
PAGLOCK = "paglock" ;
PERCENT = "percent" ;
PLAN = "plan" ;
PRECISION = "precision" ;
PRIMARY = "primary" ;
PRINT = "print" ;
PROC = "proc" ;
PROCEDURE = "procedure" ;
PUBLIC = "public" ;
RAISERROR = "raiserror" ;
RAW = "raw" ;
READ = "read" ;
READCOMMITED = "readcommited" ;
READPAST = "readpast" ;
READTEXT = "readtext" ;
READUNCOMMITED = "readuncommited" ;
RECONFIGURE = "reconfigure" ;
REFERENCES = "references" ;
REMOTE = "remote" ;
REPEATABLEREAD = "repeatableread" ;
REPLICATION = "replication" ;
RESTORE = "restore" ;
RESTRICT = "restrict" ;
RETURN = "return" ;
REVOKE = "revoke" ;
RIGHT = "right" ;
ROBUST = "robust" ;
ROLLBACK = "rollback" ;
ROLLUP = "rollup" ;
ROWCOUNT = "rowcount" ;
ROWGUIDCOL = "rowguidcol" ;
ROWLOCK = "rowlock" ;
RULE = "rule" ;
SAVE = "save" ;
SCHEMA = "schema" ;
SELECT = "select" ;
SERIALIZABLE = "serializable" ;
SESSION_USER = "session_user" ;
SET = "set" ;
SETUSER = "setuser" ;
SHUTDOWN = "shutdown" ;
SOME = "some" ;
STATISTICS = "statistics" ;
SYSTEM_USER = "system_user" ;
TABLE = "table" ;
TABLOCK = "tablock" ;
TABLOCKX = "tablockx" ;
TEXTSIZE = "textsize" ;
THEN = "then" ;
TIES = "ties" ;
TO = "to" ;
TOP = "top" ;
TRAN = "tran" ;
TRANSACTION = "transaction" ;
TRIGGER = "trigger" ;
TRUNCATE = "truncate" ;
TSEQUAL = "tsequal" ;
UNION = "union" ;
UNIQUE = "unique" ;
UPDATE = "update" ;
UPDATETEXT = "updatetext" ;
UPDLOCK = "updlock" ;
USE = "use" ;
USER = "user" ;
VALUES = "values" ;
VARYING = "varying" ;
VIEW = "view" ;
VIEWS = "views" ;
WAITFOR = "waitfor" ;
WHEN = "when" ;
WHERE = "where" ;
WHILE = "while" ;
WITH = "with" ;
WRITETEXT = "writetext" ;
XLOCK = "xlock" ;
XML = "xml" ;
XMLDATA = "xmldata" ;
// system variables
F_CONNECTIONS = "@@connections" ;
F_CPU_BUSY = "@@cpu_busy" ;
F_CURSOR_ROWS = "@@cursor_rows" ;
F_DATEFIRST = "@@datefirst" ;
F_DBTS = "@@dbts" ;
F_ERROR = "@@error" ;
F_FETCH_STATUS = "@@fetch_status" ;
F_IDENTITY = "@@identity" ;
F_IDLE = "@@idle" ;
F_IO_BUSY = "@@io_busy" ;
F_LANGID = "@@langid" ;
F_LANGUAGE = "@@language" ;
F_LOCK_TIMEOUT = "@@lock_timeout" ;
F_MAX_CONNECTIONS = "@@max_connections" ;
F_MAX_PRECISION = "@@max_precision" ;
F_NESTLEVEL = "@@nestlevel" ;
F_OPTIONS = "@@options" ;
F_PACK_RECEIVED = "@@pack_received" ;
F_PACK_SENT = "@@pack_sent" ;
F_PACKET_ERRORS = "@@packet_errors" ;
F_PROCID = "@@procid" ;
F_REMSERVER = "@@remserver" ;
F_ROWCOUNT = "@@rowcount" ;
F_SERVERNAME = "@@servername" ;
F_SERVICENAME = "@@servicename" ;
F_SPID = "@@spid" ;
F_TEXTSIZE = "@@textsize" ;
F_TIMETICKS = "@@timeticks" ;
F_TOTAL_ERRORS = "@@total_errors" ;
F_TOTAL_READ = "@@total_read" ;
F_TOTAL_WRITE = "@@total_write" ;
F_TRANCOUNT = "@@trancount" ;
F_VERSION = "@@version" ;
}
// Operators
protected DOT:; // generated as a part of Number rule
COLON : ':' ;
COMMA : ',' ;
SEMICOLON : ';' ;
LPAREN : '(' ;
RPAREN : ')' ;
//LSQUARE : '[' ;
//RSQUARE : ']' ;
ASSIGNEQUAL : '=' ;
NOTEQUAL1 : "<>" ;
NOTEQUAL2 : "!=" ;
LESSTHANOREQUALTO1 : "<=" ;
LESSTHANOREQUALTO2 : "!>" ;
LESSTHAN : "<" ;
GREATERTHANOREQUALTO1 : ">=" ;
GREATERTHANOREQUALTO2 : "!<" ;
GREATERTHAN : ">" ;
DIVIDE : '/' ;
PLUS : '+' ;
MINUS : '-' ;
STAR : '*' ;
MOD : '%' ;
AMPERSAND : '&' ;
TILDE : '~' ;
BITWISEOR : '|' ;
BITWISEXOR : '^' ;
DOT_STAR : ".*" ;
Whitespace
: (' ' | '\t' | '\n' | '\r')
{ _ttype = Token.SKIP; }
;
// COMMENTS
SingleLineComment
: "--"( ~('\r' | '\n') )*
{ _ttype = Token.SKIP; }
;
MultiLineComment
: "/*" (~'*')* '*' ('*' | ( ~('*' | '/') (~'*')* '*') )* '/'
{ _ttype = Token.SKIP; }
;
// LITERALS
protected
Letter
: 'a'..'z' | '_' | '#' | '@' | '\u0080'..'\ufffe'
;
protected
Digit
: '0'..'9'
;
protected
Integer :;
protected
Real :;
protected
Exponent
: 'e' ( '+' | '-' )? (Digit)+
;
Number
:
( (Digit)+ ('.' | 'e') ) => (Digit)+ ( '.' (Digit)* (Exponent)? | Exponent) { _ttype = Real; }
| '.' { _ttype = DOT; } ( (Digit)+ (Exponent)? { _ttype = Real; } )?
| (Digit)+ { _ttype = Integer; }
| "0x" ('a'..'f' | Digit)* { _ttype = HexLiteral; } // "0x" is valid hex literal
;
protected
Currency
: // generated as a part of NonQuotedIdentifier rule
('$' | '\u00a3'..'\u00a5' | '\u09f2'..'\u09f3' | '\u0e3f' | '\u20a0'..'\u20a4' | '\u20a6'..'\u20ab')
((Digit)+ ('.' (Digit)* )? | '.' (Digit)+)
;
ODBCDateTime
: '{' (Whitespace)? ("ts" | 't' | 'd') (Whitespace)?
('n')? '\'' (~'\'')* '\'' ( '\'' (~'\'')* '\'' )* (Whitespace)? '}'
;
NonQuotedIdentifier
options { testLiterals = true; }
:
(Currency) => Currency { _ttype = Currency; }
| ('a'..'z' | '_' | '#' | '\u0080'..'\ufffe') (Letter | Digit)* // first char other than '@'
;
QuotedIdentifier
:
(
'[' (~']')* ']' (']' (~']')* ']')*
| '"' (~'"')* '"' ('"' (~'"')* '"')*
)
;
Variable
// test for literals in case of a function begining with '@' (eg. "@@ERROR")
options { testLiterals = true; }
: '@' (Letter | Digit)+
;
ASCIIStringLiteral
:
'\'' (~'\'')* '\'' ( '\'' (~'\'')* '\'' )*
;
UnicodeStringLiteral
:
'n' '\'' (~'\'')* '\'' ( '\'' (~'\'')* '\'' )*
;
// Numeric Constants
protected
HexLiteral // generated as a part of Number rule
: // "0x" ('0'..'9' | 'a'..'f')*
;

View file

@ -12,4 +12,3 @@ class Table
public $condition;
}
?>

View file

@ -1,85 +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,86 +0,0 @@
<?php
require_once 'core/search/htmlhelper.php';
require_once 'core/search/stemmer.php';
require_once 'core/path.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,93 +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,98 +0,0 @@
<?php
require_once 'core/search/lexer.php';
require_once 'core/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,102 +0,0 @@
<?php
require_once 'core/search/search.php';
require_once 'core/search/htmlhelper.php';
require_once 'core/search/stemmer.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,181 +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

@ -1,741 +0,0 @@
<?php
/**
* Spyc -- A Simple PHP YAML Class
* @version 0.3
* @author Chris Wanstrath <chris@ozmm.org>
* @author Vlad Andersen <vlad@oneiros.ru>
* @link http://spyc.sourceforge.net/
* @copyright Copyright 2005-2006 Chris Wanstrath
* @license http://www.opensource.org/licenses/mit-license.php MIT License
* @package Spyc
*/
/**
* The Simple PHP YAML Class.
*
* This class can be used to read a YAML file and convert its contents
* into a PHP array. It currently supports a very limited subsection of
* the YAML spec.
*
* Usage:
* <code>
* $parser = new Spyc;
* $array = $parser->load($file);
* </code>
* @package Spyc
*/
class Spyc {
/**#@+
* @access private
* @var mixed
*/
private $_haveRefs;
private $_allNodes;
private $_allParent;
private $_lastIndent;
private $_lastNode;
private $_inBlock;
private $_isInline;
private $_dumpIndent;
private $_dumpWordWrap;
private $_containsGroupAnchor = false;
private $_containsGroupAlias = false;
private $path;
private $result;
private $LiteralBlockMarkers = array ('>', '|');
private $LiteralPlaceHolder = '___YAML_Literal_Block___';
private $SavedGroups = array();
/**#@+
* @access public
* @var mixed
*/
public $_nodeId;
/**
* Load YAML into a PHP array statically
*
* The load method, when supplied with a YAML stream (string or file),
* will do its best to convert YAML in a file into a PHP array. Pretty
* simple.
* Usage:
* <code>
* $array = Spyc::YAMLLoad('lucky.yaml');
* print_r($array);
* </code>
* @access public
* @return array
* @param string $input Path of YAML file or string containing YAML
*/
public static function YAMLLoad($input) {
$Spyc = new Spyc;
return $Spyc->load($input);
}
/**
* Dump YAML from PHP array statically
*
* The dump method, when supplied with an array, will do its best
* to convert the array into friendly YAML. Pretty simple. Feel free to
* save the returned string as nothing.yaml and pass it around.
*
* Oh, and you can decide how big the indent is and what the wordwrap
* for folding is. Pretty cool -- just pass in 'false' for either if
* you want to use the default.
*
* Indent's default is 2 spaces, wordwrap's default is 40 characters. And
* you can turn off wordwrap by passing in 0.
*
* @access public
* @return string
* @param array $array PHP array
* @param int $indent Pass in false to use the default, which is 2
* @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
*/
public static function YAMLDump($array,$indent = false,$wordwrap = false) {
$spyc = new Spyc;
return $spyc->dump($array,$indent,$wordwrap);
}
/**
* Dump PHP array to YAML
*
* The dump method, when supplied with an array, will do its best
* to convert the array into friendly YAML. Pretty simple. Feel free to
* save the returned string as tasteful.yaml and pass it around.
*
* Oh, and you can decide how big the indent is and what the wordwrap
* for folding is. Pretty cool -- just pass in 'false' for either if
* you want to use the default.
*
* Indent's default is 2 spaces, wordwrap's default is 40 characters. And
* you can turn off wordwrap by passing in 0.
*
* @access public
* @return string
* @param array $array PHP array
* @param int $indent Pass in false to use the default, which is 2
* @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
*/
public function dump($array,$indent = false,$wordwrap = false) {
// Dumps to some very clean YAML. We'll have to add some more features
// and options soon. And better support for folding.
// New features and options.
if ($indent === false or !is_numeric($indent)) {
$this->_dumpIndent = 2;
} else {
$this->_dumpIndent = $indent;
}
if ($wordwrap === false or !is_numeric($wordwrap)) {
$this->_dumpWordWrap = 40;
} else {
$this->_dumpWordWrap = $wordwrap;
}
// New YAML document
$string = "---\n";
// Start at the base of the array and move through it.
foreach ($array as $key => $value) {
$string .= $this->_yamlize($key,$value,0);
}
return $string;
}
/**
* Attempts to convert a key / value array item to YAML
* @access private
* @return string
* @param $key The name of the key
* @param $value The value of the item
* @param $indent The indent of the current node
*/
private function _yamlize($key,$value,$indent) {
if (is_array($value)) {
// It has children. What to do?
// Make it the right kind of item
$string = $this->_dumpNode($key,NULL,$indent);
// Add the indent
$indent += $this->_dumpIndent;
// Yamlize the array
$string .= $this->_yamlizeArray($value,$indent);
} elseif (!is_array($value)) {
// It doesn't have children. Yip.
$string = $this->_dumpNode($key,$value,$indent);
}
return $string;
}
/**
* Attempts to convert an array to YAML
* @access private
* @return string
* @param $array The array you want to convert
* @param $indent The indent of the current level
*/
private function _yamlizeArray($array,$indent) {
if (is_array($array)) {
$string = '';
foreach ($array as $key => $value) {
$string .= $this->_yamlize($key,$value,$indent);
}
return $string;
} else {
return false;
}
}
/**
* Returns YAML from a key and a value
* @access private
* @return string
* @param $key The name of the key
* @param $value The value of the item
* @param $indent The indent of the current node
*/
private function _dumpNode($key,$value,$indent) {
// do some folding here, for blocks
if (strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false) {
$value = $this->_doLiteralBlock($value,$indent);
} else {
$value = $this->_doFolding($value,$indent);
}
if (is_bool($value)) {
$value = ($value) ? "true" : "false";
}
$spaces = str_repeat(' ',$indent);
if (is_int($key)) {
// It's a sequence
$string = $spaces.'- '.$value."\n";
} else {
// It's mapped
$string = $spaces.$key.': '.$value."\n";
}
return $string;
}
/**
* Creates a literal block for dumping
* @access private
* @return string
* @param $value
* @param $indent int The value of the indent
*/
private function _doLiteralBlock($value,$indent) {
$exploded = explode("\n",$value);
$newValue = '|';
$indent += $this->_dumpIndent;
$spaces = str_repeat(' ',$indent);
foreach ($exploded as $line) {
$newValue .= "\n" . $spaces . trim($line);
}
return $newValue;
}
/**
* Folds a string of text, if necessary
* @access private
* @return string
* @param $value The string you wish to fold
*/
private function _doFolding($value,$indent) {
// Don't do anything if wordwrap is set to 0
if ($this->_dumpWordWrap === 0) {
return $value;
}
if (strlen($value) > $this->_dumpWordWrap) {
$indent += $this->_dumpIndent;
$indent = str_repeat(' ',$indent);
$wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent");
$value = ">\n".$indent.$wrapped;
}
return $value;
}
/* LOADING FUNCTIONS */
private function load($input) {
$Source = $this->loadFromSource($input);
if (empty ($Source)) return array();
$this->path = array();
$this->result = array();
for ($i = 0; $i < count($Source); $i++) {
$line = $Source[$i];
$lineIndent = $this->_getIndent($line);
$this->path = $this->getParentPathByIndent($lineIndent);
$line = $this->stripIndent($line, $lineIndent);
if ($this->isComment($line)) continue;
if ($literalBlockStyle = $this->startsLiteralBlock($line)) {
$line = rtrim ($line, $literalBlockStyle . "\n");
$literalBlock = '';
$line .= $this->LiteralPlaceHolder;
while ($this->literalBlockContinues($Source[++$i], $lineIndent)) {
$literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle);
}
$i--;
}
$lineArray = $this->_parseLine($line);
if ($literalBlockStyle)
$lineArray = $this->revertLiteralPlaceHolder ($lineArray, $literalBlock);
$this->addArray($lineArray, $lineIndent);
}
return $this->result;
}
private function loadFromSource ($input) {
if (!empty($input) && strpos($input, "\n") === false && file_exists($input))
return file($input);
$foo = explode("\n",$input);
foreach ($foo as $k => $_) {
$foo[$k] = trim ($_, "\r");
}
return $foo;
}
/**
* Finds and returns the indentation of a YAML line
* @access private
* @return int
* @param string $line A line from the YAML file
*/
private function _getIndent($line) {
if (!preg_match('/^ +/',$line,$match)) return 0;
if (!empty($match[0])) return strlen ($match[0]);
return 0;
}
/**
* Parses YAML code and returns an array for a node
* @access private
* @return array
* @param string $line A line from the YAML file
*/
private function _parseLine($line) {
if (!$line) return array();
$line = trim($line);
if (!$line) return array();
$array = array();
if ($group = $this->nodeContainsGroup($line)) {
$this->addGroup($line, $group);
$line = $this->stripGroup ($line, $group);
}
if ($this->startsMappedSequence($line))
return $this->returnMappedSequence($line);
if ($this->startsMappedValue($line))
return $this->returnMappedValue($line);
if ($this->isArrayElement($line))
return $this->returnArrayElement($line);
return $this->returnKeyValuePair($line);
}
/**
* Finds the type of the passed value, returns the value as the new type.
* @access private
* @param string $value
* @return mixed
*/
private function _toType($value) {
if (strpos($value, '#') !== false)
$value = trim(preg_replace('/#(.+)$/','',$value));
if (preg_match('/^("(.*)"|\'(.*)\')/',$value,$matches)) {
$value = (string)preg_replace('/(\'\'|\\\\\')/',"'",end($matches));
$value = preg_replace('/\\\\"/','"',$value);
} elseif (preg_match('/^\\[(.+)\\]$/',$value,$matches)) {
// Inline Sequence
// Take out strings sequences and mappings
$explode = $this->_inlineEscape($matches[1]);
// Propogate value array
$value = array();
foreach ($explode as $v) {
$value[] = $this->_toType($v);
}
} elseif (strpos($value,': ')!==false && !preg_match('/^{(.+)/',$value)) {
// It's a map
$array = explode(': ',$value);
$key = trim($array[0]);
array_shift($array);
$value = trim(implode(': ',$array));
$value = $this->_toType($value);
$value = array($key => $value);
} elseif (preg_match("/{(.+)}$/",$value,$matches)) {
// Inline Mapping
// Take out strings sequences and mappings
$explode = $this->_inlineEscape($matches[1]);
// Propogate value array
$array = array();
foreach ($explode as $v) {
$array = $array + $this->_toType($v);
}
$value = $array;
} elseif (strtolower($value) == 'null' or $value == '' or $value == '~') {
$value = null;
} elseif (preg_match ('/^[0-9]+$/', $value)) {
$value = (int)$value;
} elseif (in_array(strtolower($value),
array('true', 'on', '+', 'yes', 'y'))) {
$value = true;
} elseif (in_array(strtolower($value),
array('false', 'off', '-', 'no', 'n'))) {
$value = false;
} elseif (is_numeric($value)) {
$value = (float)$value;
} else {
// Just a normal string, right?
// $value = trim(preg_replace('/#(.+)$/','',$value));
}
// print_r ($value);
return $value;
}
/**
* Used in inlines to check for more inlines or quoted strings
* @access private
* @return array
*/
private function _inlineEscape($inline) {
// There's gotta be a cleaner way to do this...
// While pure sequences seem to be nesting just fine,
// pure mappings and mappings with sequences inside can't go very
// deep. This needs to be fixed.
$saved_strings = array();
// Check for strings
$regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/';
if (preg_match_all($regex,$inline,$strings)) {
$saved_strings = $strings[0];
$inline = preg_replace($regex,'YAMLString',$inline);
}
unset($regex);
// Check for sequences
if (preg_match_all('/\[(.+)\]/U',$inline,$seqs)) {
$inline = preg_replace('/\[(.+)\]/U','YAMLSeq',$inline);
$seqs = $seqs[0];
}
// Check for mappings
if (preg_match_all('/{(.+)}/U',$inline,$maps)) {
$inline = preg_replace('/{(.+)}/U','YAMLMap',$inline);
$maps = $maps[0];
}
$explode = explode(', ',$inline);
// Re-add the sequences
if (!empty($seqs)) {
$i = 0;
foreach ($explode as $key => $value) {
if (strpos($value,'YAMLSeq') !== false) {
$explode[$key] = str_replace('YAMLSeq',$seqs[$i],$value);
++$i;
}
}
}
// Re-add the mappings
if (!empty($maps)) {
$i = 0;
foreach ($explode as $key => $value) {
if (strpos($value,'YAMLMap') !== false) {
$explode[$key] = str_replace('YAMLMap',$maps[$i],$value);
++$i;
}
}
}
// Re-add the strings
if (!empty($saved_strings)) {
$i = 0;
foreach ($explode as $key => $value) {
while (strpos($value,'YAMLString') !== false) {
$explode[$key] = preg_replace('/YAMLString/',$saved_strings[$i],$value, 1);
++$i;
$value = $explode[$key];
}
}
}
return $explode;
}
private function literalBlockContinues ($line, $lineIndent) {
if (!trim($line)) return true;
if ($this->_getIndent($line) > $lineIndent) return true;
return false;
}
private function addArray ($array, $indent) {
$key = key ($array);
if (!isset ($array[$key])) return false;
if ($array[$key] === array()) { $array[$key] = ''; };
$value = $array[$key];
// Unfolding inner array tree as defined in $this->_arrpath.
//$_arr = $this->result; $_tree[0] = $_arr; $i = 1;
$tempPath = Spyc::flatten ($this->path);
eval ('$_arr = $this->result' . $tempPath . ';');
if ($this->_containsGroupAlias) {
do {
if (!isset($this->SavedGroups[$this->_containsGroupAlias])) { echo "Bad group name: $this->_containsGroupAlias."; break; }
$groupPath = $this->SavedGroups[$this->_containsGroupAlias];
eval ('$value = $this->result' . Spyc::flatten ($groupPath) . ';');
} while (false);
$this->_containsGroupAlias = false;
}
// Adding string or numeric key to the innermost level or $this->arr.
if ($key)
$_arr[$key] = $value;
else {
if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; }
else { $_arr[] = $value; end ($_arr); $key = key ($_arr); }
}
$this->path[$indent] = $key;
eval ('$this->result' . $tempPath . ' = $_arr;');
if ($this->_containsGroupAnchor) {
$this->SavedGroups[$this->_containsGroupAnchor] = $this->path;
$this->_containsGroupAnchor = false;
}
}
private function flatten ($array) {
$tempPath = array();
if (!empty ($array)) {
foreach ($array as $_) {
if (!is_int($_)) $_ = "'$_'";
$tempPath[] = "[$_]";
}
}
//end ($tempPath); $latestKey = key($tempPath);
$tempPath = implode ('', $tempPath);
return $tempPath;
}
private function startsLiteralBlock ($line) {
$lastChar = substr (trim($line), -1);
if (in_array ($lastChar, $this->LiteralBlockMarkers))
return $lastChar;
return false;
}
private function addLiteralLine ($literalBlock, $line, $literalBlockStyle) {
$line = $this->stripIndent($line);
$line = str_replace ("\r\n", "\n", $line);
if ($literalBlockStyle == '|') {
return $literalBlock . $line;
}
if (strlen($line) == 0) return $literalBlock . "\n";
// echo "|$line|";
if ($line != "\n")
$line = trim ($line, "\r\n ") . " ";
return $literalBlock . $line;
}
private function revertLiteralPlaceHolder ($lineArray, $literalBlock) {
foreach ($lineArray as $k => $_) {
if (substr($_, -1 * strlen ($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder)
$lineArray[$k] = rtrim ($literalBlock, " \r\n");
}
return $lineArray;
}
private function stripIndent ($line, $indent = -1) {
if ($indent == -1) $indent = $this->_getIndent($line);
return substr ($line, $indent);
}
private function getParentPathByIndent ($indent) {
if ($indent == 0) return array();
$linePath = $this->path;
do {
end($linePath); $lastIndentInParentPath = key($linePath);
if ($indent <= $lastIndentInParentPath) array_pop ($linePath);
} while ($indent <= $lastIndentInParentPath);
return $linePath;
}
private function clearBiggerPathValues ($indent) {
if ($indent == 0) $this->path = array();
if (empty ($this->path)) return true;
foreach ($this->path as $k => $_) {
if ($k > $indent) unset ($this->path[$k]);
}
return true;
}
private function isComment ($line) {
if (preg_match('/^#/', $line)) return true;
return false;
}
private function isArrayElement ($line) {
if (!$line) return false;
if ($line[0] != '-') return false;
if (strlen ($line) > 3)
if (substr($line,0,3) == '---') return false;
return true;
}
private function isHashElement ($line) {
if (!preg_match('/^(.+?):/', $line, $matches)) return false;
$allegedKey = $matches[1];
if ($allegedKey) return true;
//if (substr_count($allegedKey, )
return false;
}
private function isLiteral ($line) {
if ($this->isArrayElement($line)) return false;
if ($this->isHashElement($line)) return false;
return true;
}
private function startsMappedSequence ($line) {
if (preg_match('/^-(.*):$/',$line)) return true;
}
private function returnMappedSequence ($line) {
$array = array();
$key = trim(substr(substr($line,1),0,-1));
$array[$key] = '';
return $array;
}
private function returnMappedValue ($line) {
$array = array();
$key = trim(substr($line,0,-1));
$array[$key] = '';
return $array;
}
private function startsMappedValue ($line) {
if (preg_match('/^(.*):$/',$line)) return true;
}
private function returnKeyValuePair ($line) {
$array = array();
if (preg_match('/^(.+):/',$line,$key)) {
// It's a key/value pair most likely
// If the key is in double quotes pull it out
if (preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) {
$value = trim(str_replace($matches[1],'',$line));
$key = $matches[2];
} else {
// Do some guesswork as to the key and the value
$explode = explode(':',$line);
$key = trim($explode[0]);
array_shift($explode);
$value = trim(implode(':',$explode));
}
// Set the type of the value. Int, string, etc
$value = $this->_toType($value);
if (empty($key)) {
$array[] = $value;
} else {
$array[$key] = $value;
}
}
return $array;
}
private function returnArrayElement ($line) {
if (strlen($line) <= 1) return array(array()); // Weird %)
$array = array();
$value = trim(substr($line,1));
$value = $this->_toType($value);
$array[] = $value;
return $array;
}
private function nodeContainsGroup ($line) {
if (strpos($line, '&') === false && strpos($line, '*') === false) return false; // Please die fast ;-)
if (preg_match('/^(&[^ ]+)/', $line, $matches)) return $matches[1];
if (preg_match('/^(\*[^ ]+)/', $line, $matches)) return $matches[1];
if (preg_match('/(&[^" ]+$)/', $line, $matches)) return $matches[1];
if (preg_match('/(\*[^" ]+$)/', $line, $matches)) return $matches[1];
return false;
}
private function addGroup ($line, $group) {
if (substr ($group, 0, 1) == '&') $this->_containsGroupAnchor = substr ($group, 1);
if (substr ($group, 0, 1) == '*') $this->_containsGroupAlias = substr ($group, 1);
//print_r ($this->path);
}
private function stripGroup ($line, $group) {
$line = trim(str_replace($group, '', $line));
return $line;
}
}
?>

View file

@ -120,4 +120,3 @@ class Drawing
}
}
}
?>

View file

@ -435,4 +435,3 @@ class ExcelDocument {
}
}
?>

View file

@ -30,4 +30,3 @@ function generatePassword($length = 9, $strength = 0) {
return $password;
}
?>

View file

@ -204,4 +204,3 @@ class TemplateImage
}
}
?>

View file

@ -1,36 +0,0 @@
<?php
require_once 'core/widgets/widget.php';
/**
* Класс для создания диалоговых окон, типа поиска и настройки таблицы
*/
class Dialog extends Widget
{
protected $title;
protected $action;
private $friend;
function setFriend(Widget $friend)
{
$this->friend = $friend->getName();
}
function getPostCode()
{
return $this->getName() . ".setFriend(" . $this->friend . ");";
}
function setTitle($title)
{
$this->title = $title;
}
function setAction($action)
{
$this->action = forceUrl($action);
}
}
?>

View file

@ -1,39 +0,0 @@
<?php
require_once 'core/widgets/listtable.php';
/**
* Класс для генерации таблицы
*/
class FileBrowser extends ListTable
{
private $friend;
public function setType($type)
{
$this->setData('type', $type);
}
function setHeader($header)
{
$this->setData('table', $header);
}
function setFriend(Widget $friend)
{
$this->friend = $friend->getName();
}
function getPostCode()
{
if ($this->friend) {
return $this->getName() . ".setFriend(" . $this->friend . ");";
}
return "";
}
function postMake() {
$this->view->addScriptRaw($this->getPostCode(), true); // CompositeView
}
}
?>

View file

@ -1,71 +0,0 @@
<?php
require_once 'core/widgets/widget.php';
require_once 'core/functions.php';
/**
* Класс для генерации таблицы
*/
class ListTable extends Widget // MenuTable
{
private $visible = null;
private $menu;
function setUp()
{
$this->menu = array();
$this->template = "table";
}
/**
* Устанавливает формат таблицы, структуру $header см. table.js
*/
function setHeader($header)
{
$this->setData('table', $header);
}
function setView($visible)
{
$this->visible = $visible;
}
function setAction($action)
{
$this->setData('list', forceUrl($action));
}
function addMenuItem($href, $name, $to = 'item')
{
if ($href) {
if ($to === true) $to = 'all';
if (! isset($this->menu[$to])) {
$this->menu[$to] = array('group' => $to, 'all' => ($to == 'all'), 'items' => array());
}
$this->menu[$to]['items'][] = array('href' => $href, 'name' => $name);
}
}
function make(Controller $parent)
{
$view = $this->visible;
if (is_null($view)) {
$view = array('left' => key_values('key', $this->data['table']), 'right' => array());
}
$this->setData('setup', $view);
foreach ($this->menu as &$menu) {
foreach ($menu['items'] as &$item) {
$item['href'] = forceUrl($item['href']);
}
}
$this->setData('menu', array_keys($this->menu));
parent::make($parent);
$this->view->menus = $this->menu;
}
}
?>

View file

@ -1,38 +0,0 @@
<?php
/**
* Список ссылок
*/
class SimpleMenu
{
private $items = array();
/**
* Добавление элемента меню
* @param $href Обьект ссылки или строка, ссылка должна быть сгенерирована при генерации страницы, т.к может зависеть от параметров
* которые могут измениться при создании страницы, поэтому передается ссылка на функцию (отложенная/ленивая ссылка)
* @param $name Подпись к ссылке
*/
function addMenuItem(/*. url .*/ $href,/*. string .*/ $name)
{
if($href) { // если ссылка пустая то элемент не добовляется
$this->items[] = array('href' => $href, 'name' => ucfirst($name)); // menu_item
}
}
/**
* Массив ссылок
* @return Массив
*/
function getItems()
{
foreach ($this->items as &$item) {
if (is_callable($item['href'])) {
$item['href'] = call_user_func($item['href']);
}
}
return $this->items;
}
}
?>

View file

@ -1,30 +0,0 @@
<?php
require_once 'core/widgets/widget.php';
require_once 'core/widgets/menu.php';
/**
* Компонент для генерации меню
*/
class PageMenu extends Widget
{
private $menu;
function setUp()
{
$this->menu = new SimpleMenu();
$this->template = "menu";
}
function addMenuItem($name, $value)
{
$this->menu->addMenuItem($name, $value);
}
function postMake()
{
$this->view->items = $this->menu->getItems();
}
}
?>

View file

@ -1,16 +0,0 @@
<?php
require_once 'core/widgets/widget.php';
/**
* Отображение постраничности
*/
class Pages extends Widget // Selector
{
function setUp()
{
$this->template = "pages";
}
}
?>

View file

@ -1,32 +0,0 @@
<?php
require_once 'core/widgets/dialog.php';
class SearchDialog extends Dialog
{
private $fields;
function setUp()
{
$this->template = "search";
}
function addFields($fields)
{
$this->fields = $fields;
}
function postMake()
{
$form = new TForm (); // Показывем форму
$form->addFieldList ($this->fields); // Разделить форму поиска и редактирования
$this->view->form = $form;
$this->view->action = $this->action;
$this->view->title = $this->title;
$this->view->addScriptRaw($this->getPostCode(), true); // CompositeView
}
}
?>

View file

@ -1,20 +0,0 @@
<?php
require_once 'core/widgets/dialog.php';
class SetupDialog extends Dialog
{
function setUp()
{
$this->template = "setup";
}
function postMake()
{
$this->view->action = $this->action;
$this->view->title = $this->title;
$this->view->addScriptRaw($this->getPostCode(), true); // CompositeView
}
}
?>

View file

@ -1,17 +0,0 @@
<?php
require_once 'core/widgets/widget.php';
/**
* Компонент для генерации Дерева
*/
class Tree extends Widget
{
public function setUp()
{
$this->template = "tree";
}
// Добавление ветки дерева
}
?>

View file

@ -1,87 +0,0 @@
<?php
require_once 'core/json.php';
function forceUrl($name)
{
if(is_callable($name)) {
return call_user_func($name);
}
return $name;
}
/**
* Класс для генерации и управления активными компонентами страницы
* Компонент состоит из следующих частей
* PHP - Управление компонентом (Генерация, Инициализация, Обработка событий)
* HTML - Необходимые шаблоны
* CSS - Стили
* Javascript - Клиентская часть управления компонентом
*/
class Widget
{
private static $prefix = "_g";
private static $idx = 0;
private $id;
public $data = array();
public $view;
protected $template;
public function __construct()
{
$this->id = self::$idx ++;
$this->setUp();
}
function setUp()
{
}
public function getName()
{
return self::$prefix . intval($this->id);
}
/**
* Генерация кода инициализации компонента на стороне клиента
*/
public function getCodeBefore()
{
$result =
// "alert('".$this->getName()."');" .
"var " . $this->getName() . " = new " . get_class($this) . "("
. json::encode($this->data) . ");";
return $result;
}
public function setData($name, $value)
{
$this->data[$name] = $value;
}
public function getCodeAfter()
{
return $this->getName() . ".appendTo(document.getElementById('" . $this->getName() . "'));\n";
}
public function postMake()
{
}
/**
* Генерация компонента
*/
function make(Controller $parent)
{
$this->view = $parent->getView($this->template); // Controller
$this->view->index = $this->getName();
foreach ($this->data as $name => $value) {
$this->view->set($name, $value);
}
$this->view->addScriptRaw($this->getCodeBefore(), true);
$this->postMake();
$this->view->addScriptRaw($this->getCodeAfter(), true);
}
}
?>

View file

@ -1,16 +1,11 @@
<?php
/*.
require_module 'standard';
require_module 'zip';
.*/
/**
* Расширение класса ZipArchive с возможность архивирования директории
*/
class ZipFile extends ZipArchive
{
private function addDirDo(/*. string.*/ $location, /*. string .*/ $name)
private function addDirDo($location, $name)
{
assert(is_string($location) && is_string($name));
@ -29,7 +24,7 @@ class ZipFile extends ZipArchive
}
}
public function addDir(/*. string.*/ $location, /*. string .*/ $name)
public function addDir($location, $name)
{
assert(is_string($location) && is_string($name));
@ -37,5 +32,3 @@ class ZipFile extends ZipArchive
$this->addDirDo($location, $name);
}
}
?>