Убрал phptal и лишнее
This commit is contained in:
parent
651a841187
commit
96043d70e6
95 changed files with 4 additions and 10833 deletions
|
|
@ -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
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
function loadConfig($filename) {
|
||||
if (@include($filename)) {
|
||||
if (@include($filename)) {
|
||||
return $settings;
|
||||
}
|
||||
throw new Exception("config $filename not found");
|
||||
|
|
|
|||
|
|
@ -78,5 +78,3 @@ class FileRecord
|
|||
return isset($this->file['title']) ? $this->file['title'] : $this->getName();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
335
core/form.php
335
core/form.php
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -176,5 +176,3 @@ class TForm
|
|||
$this->field[$name]->setValue($value);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -83,4 +83,3 @@ class HFile {
|
|||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -10,4 +10,3 @@ class Point
|
|||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -49,5 +49,3 @@ class Rectangle
|
|||
return new Point((($base->left + $base->right) - ($this->left + $this->right)) / 2, $base->bottom - $this->height);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -26,5 +26,3 @@ class ModelFactory
|
|||
return $model;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -7,4 +7,3 @@ class Meta
|
|||
{
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -203,4 +203,3 @@ class Query
|
|||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -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')*
|
||||
;
|
||||
|
|
@ -12,4 +12,3 @@ class Table
|
|||
public $condition;
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
|
@ -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]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
||||
741
core/spyc.php
741
core/spyc.php
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
?>
|
||||
|
|
@ -120,4 +120,3 @@ class Drawing
|
|||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -435,4 +435,3 @@ class ExcelDocument {
|
|||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -30,4 +30,3 @@ function generatePassword($length = 9, $strength = 0) {
|
|||
return $password;
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -204,4 +204,3 @@ class TemplateImage
|
|||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
require_once 'core/widgets/widget.php';
|
||||
|
||||
/**
|
||||
* Отображение постраничности
|
||||
*/
|
||||
class Pages extends Widget // Selector
|
||||
{
|
||||
function setUp()
|
||||
{
|
||||
$this->template = "pages";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
|
||||
require_once 'core/widgets/widget.php';
|
||||
|
||||
/**
|
||||
* Компонент для генерации Дерева
|
||||
*/
|
||||
class Tree extends Widget
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
$this->template = "tree";
|
||||
}
|
||||
// Добавление ветки дерева
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
Loading…
Add table
Add a link
Reference in a new issue