1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-07-03 06:55:03 +03:00

Документация классов

This commit is contained in:
Mzhelskiy Maxim 2012-04-17 21:58:32 +04:00
parent 573cfbf42b
commit 3982af66eb
11 changed files with 545 additions and 393 deletions

View file

@ -17,42 +17,33 @@
require_once('Action.class.php');
/**
* Абстрактный класс экшена
* Абстрактный класс экшена плагина.
* От этого класса необходимо наследовать экшены плагина, эот позволит корректно определять текущий шаблон плагина для рендеринга экшена
*
* @package engine
* @since 1.0
*/
abstract class ActionPlugin extends Action {
/**
* Путь к шаблонам с учетом наличия соответствующего skin`a
* Полный серверный путь до текущего шаблона плагина
*
* @var string
* @var string|null
*/
protected $sTemplatePathPlugin=null;
/**
* Конструктор
*
* @param Engine $oEngine
* @param string $sAction
*/
public function __construct(Engine $oEngine, $sAction) {
parent::__construct($oEngine, $sAction);
$this->Viewer_Assign('sTemplatePathPlugin',rtrim($this->getTemplatePathPlugin(),'/'));
$this->Viewer_Assign('sTemplateWebPathPlugin',Plugin::GetTemplateWebPath(get_class($this)));
}
/**
* Возвращает путь к шаблонам плагина
* Возвращает путь к текущему шаблону плагина
*
* @return string
*/
public function getTemplatePathPlugin() {
public function getTemplatePathPlugin() {
if(is_null($this->sTemplatePathPlugin)) {
preg_match('/^Plugin([\w]+)_Action([\w]+)$/i',$this->GetActionClass(),$aMatches);
/**
* Проверяем в списке шаблонов
*/
$aMatches[1]=strtolower($aMatches[1]);
$aPaths=glob(Config::Get('path.root.server').'/plugins/'.$aMatches[1].'/templates/skin/*/actions/Action'.ucfirst($aMatches[2]),GLOB_ONLYDIR);
$aPaths=glob(Config::Get('path.root.server').'/plugins/'.$aMatches[1].'/templates/skin/*/actions/Action'.ucfirst($aMatches[2]),GLOB_ONLYDIR);
$sTemplateName=($aPaths and in_array(
Config::Get('view.skin'),
array_map(
@ -65,24 +56,24 @@ abstract class ActionPlugin extends Action {
))
? Config::Get('view.skin')
: 'default';
$sDir=Config::Get('path.root.server')."/plugins/{$aMatches[1]}/templates/skin/{$sTemplateName}/";
$this->sTemplatePathPlugin = is_dir($sDir) ? $sDir : null;
}
return $this->sTemplatePathPlugin;
}
/**
* Установить значение пути к директории шаблонов плагина
* Установить значение пути к директории шаблона плагина
*
* @param string $sTemplatePath
* @param string $sTemplatePath Полный серверный путь до каталога с шаблоном
* @return bool
*/
public function setTemplatePathPlugin($sTemplatePath) {
if(!is_dir($sTemplatePath)) return false;
$this->sTemplatePathPlugin = $sTemplatePath;
}
}
?>

View file

@ -19,16 +19,39 @@
* Абстрактный класс блока
* Это те блоки которые обрабатывают шаблоны Smarty перед выводом(например блок "Облако тегов")
*
* @package engine
* @since 1.0
*/
abstract class Block extends LsObject {
protected $oEngine=null;
/**
* Ядро движка
*
* @var Engine|null
*/
protected $oEngine=null;
/**
* Список параметров блока
*
* @var array
*/
protected $aParams=array();
public function __construct($aParams) {
$this->aParams=$aParams;
$this->oEngine=Engine::getInstance();
/**
* При создании блока передаем в него параметры
*
* @param array $aParams Список параметров блока
*/
public function __construct($aParams) {
$this->aParams=$aParams;
$this->oEngine=Engine::getInstance();
}
/**
* Возвращает параметр по имени
*
* @param string $sName Имя параметра
* @param null|mixed $def Дефолтное значение параметра, возвращается если такого параметра нет
* @return mixed
*/
protected function GetParam($sName,$def=null) {
if (isset($this->aParams[$sName])) {
return $this->aParams[$sName];
@ -36,11 +59,23 @@ abstract class Block extends LsObject {
return $def;
}
}
/**
* Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля
* @see Engine::_CallModule
*
* @param string $sName Имя метода
* @param array $aArgs Аргументы
* @return mixed
*/
public function __call($sName,$aArgs) {
return $this->oEngine->_CallModule($sName,$aArgs);
}
}
/**
* Метод запуска обработки блока.
* Его необходимо определять в конкретном блоге.
*
* @abstract
*/
abstract public function Exec();
}
?>

View file

@ -18,15 +18,23 @@
require_once("Engine.class.php");
/**
* Абстрактный слой работы с крон-процессами
* Абстрактный класс для работы с крон-процессами.
* Например, его использует отложенная рассылка почтовых уведомлений для пользователей.
* Обработчик крона не запускается автоматически(!!), его необходимо добавлять в системный крон (nix*: crontab -e)
*
* @package engine
* @since 1.0
*/
class Cron extends LsObject {
/**
* Объект ядра
*
* @var Engine
*/
protected $oEngine=null;
/**
* Дескриптор блокирующего файла
* Если этот файл существует, то крон не запустится повторно.
*
* @var string
*/
@ -37,7 +45,10 @@ class Cron extends LsObject {
* @var string
*/
protected $sProcessName;
/**
* @param string|null $sLockFile Полный путь до лок файла, например <pre>Config::Get('sys.cache.dir').'notify.lock'</pre>
*/
public function __construct($sLockFile=null) {
$this->sProcessName=get_class($this);
$this->oEngine=Engine::getInstance();
@ -49,19 +60,16 @@ class Cron extends LsObject {
if(!empty($sLockFile)) {
$this->oLockFile=fopen($sLockFile,'a');
}
/**
* Инициализируем лог и делает пометку о старте процесса
*/
$this->oEngine->Logger_SetFileName(Config::Get('sys.logs.cron_file'));
$this->Log('Cron process started');
}
/**
* Делает запись в лог
*
* @param string $sMsg
* @return
* @param string $sMsg Сообщение для записи в лог
*/
public function Log($sMsg) {
if (Config::Get('sys.logs.cron')) {
@ -69,27 +77,27 @@ class Cron extends LsObject {
$this->oEngine->Logger_Notice($sMsg);
}
}
/**
* Проверяет уникальность создаваемого процесса
*
* @return bool
*/
public function isLock() {
return ($this->oLockFile && !flock($this->oLockFile, LOCK_EX|LOCK_NB));
}
/**
* Снимает блокировку на повторный процесс
*
* @return bool
*/
public function unsetLock() {
return ($this->oLockFile && @flock($this->oLockFile, LOCK_UN));
}
/**
* Основная функция слоя. Реализует логику работы
* крон процесса с последующей передачей управления
* на пользовательскую функцию
* Основной метод крон-процесса.
* Реализует логику работы крон процесса с последующей передачей управления на пользовательскую функцию
*
* @param ( string|array ) $sFunction
* @param array $aArgs
* @return string
*/
public function Exec() {
/**
@ -113,15 +121,16 @@ class Cron extends LsObject {
return $sContent;
}
/**
* Здесь будет реализована логика завершения работы cron-процесса
* Завершение крон-процесса
*/
public function Shutdown() {
$this->unsetLock();
$this->Log('Cron process ended');
}
/**
* Вызывается при уничтожении объекта
*/
public function __destruct() {
$this->Shutdown();
}
@ -132,7 +141,14 @@ class Cron extends LsObject {
public function Client(){
throw new Exception('Call undefined client function');
}
/**
* Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля
* @see Engine::_CallModule
*
* @param string $sName Имя метода
* @param array $aArgs Аргументы
* @return mixed
*/
public function __call($sName,$aArgs) {
return $this->oEngine->_CallModule($sName,$aArgs);
}

View file

@ -16,34 +16,79 @@
*/
/**
* Абстрактный класс сущности
* Абстрактный класс сущности.
* При запросе к базе данных удобно возвращать не просто массив данных, а данные в виде специального объекта - Entity.
* Основные методы такого объекта делятся на два вида: get-методы и set-методы.
* Первые получают свойство объекта по его имени, а вторые устанавливают.
* Сущности поддерживает "магические" методы set* и get* , например
* <pre>
* $oEntity->getMyProperty()
* </pre> вернет данные по ключу/полю my_property
*
* @package engine
* @since 1.0
*/
abstract class Entity extends LsObject {
/**
* Данные сущности, на этот массив мапятся методы set* и get*
*
* @var array
*/
protected $_aData=array();
/**
* Имя поля с первичным ключом в БД
*
* @var null|string
*/
protected $sPrimaryKey = null;
/**
* Список правил валидации полей
* @see ModuleValidate
*
* @var array
*/
protected $aValidateRules=array();
/**
* Список ошибок валидации в разрезе полей, например
* <pre>
* array(
* 'title' => array('error one','error two'),
* 'name' => array('error one','error two'),
* )
* </pre>
*
* @var array
*/
protected $aValidateErrors=array();
/**
* Сценарий валиадции полей
* @see _setValidateScenario
*
* @var string
*/
protected $sValidateScenario='';
/**
* Если передать в конструктор ассоциативный массив свойств и их значений, то они автоматом загрузятся в сущность
*
* @param array|null $aParam
* @param array|false $aParam Ассоциативный массив данных сущности
*/
public function __construct($aParam = false) {
$this->_setData($aParam);
$this->Init();
}
/**
* Метод инициализации сущности, вызывается при её создании
*/
public function Init() {
}
/**
* Устанавливает данные сущности
*
* @param array $aData Ассоциативный массив данных сущности
*/
public function _setData($aData) {
if(is_array($aData)) {
foreach ($aData as $sKey => $val) {
@ -51,7 +96,12 @@ abstract class Entity extends LsObject {
}
}
}
/**
* Получает массив данных сущности
*
* @param array|null $aKeys Список полей, данные по которым необходимо вернуть, если не передан, то возвращаются все данные
* @return array
*/
public function _getData($aKeys=array()) {
if(!is_array($aKeys) or !count($aKeys)) return $this->_aData;
@ -63,19 +113,24 @@ abstract class Entity extends LsObject {
}
return $aReturn;
}
/**
* Возвращает данные по конкретному полю
*
* @param string $sKey Название поля, например <pre>'my_property'</pre>
* @return null|mixed
*/
public function _getDataOne($sKey) {
if(array_key_exists($sKey,$this->_aData)) {
return $this->_aData[$sKey];
}
return null;
}
/**
* Рекурсивное преобразование объекта и вложенных объектов в массив
*
* @return array
*/
public function _getDataArray()
{
public function _getDataArray() {
$aResult = array();
foreach ($this->_aData as $sKey => $sValue) {
if (is_object($sValue) && $sValue instanceOf Entity) {
@ -86,13 +141,14 @@ abstract class Entity extends LsObject {
}
return $aResult;
}
/**
* Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля
* Также производит обработку методов set* и get*
* @see Engine::_CallModule
*
* @param string $sName
* @param array $aArgs
* @return unknown
* @param string $sName Имя метода
* @param array $aArgs Аргументы
* @return mixed
*/
public function __call($sName,$aArgs) {
$sType=strtolower(substr($sName,0,3));
@ -117,12 +173,13 @@ abstract class Entity extends LsObject {
return Engine::getInstance()->_CallModule($sName,$aArgs);
}
}
/**
* Получение первичного ключа сущности (ключ, а не значение!)
* @see _getPrimaryKeyValue
*
* @return null|string
*/
public function _getPrimaryKey()
{
public function _getPrimaryKey() {
if (!$this->sPrimaryKey) {
if (isset($this->_aData['id'])) {
$this->sPrimaryKey = 'id';
@ -134,32 +191,32 @@ abstract class Entity extends LsObject {
return $this->sPrimaryKey;
}
/**
* Возвращает значение первичного ключа/поля
*
* @return mixed|null
*/
public function _getPrimaryKeyValue() {
return $this->_getDataOne($this->_getPrimaryKey());
}
/**
* Выполняет валидацию данных сущности
* Если $aFields=null, то выполняется валидация по всем полям из $this->aValidateRules, иначе по пересечению
*
* @param null $attributes
* @param bool $clearErrors
* @param null|array $aFields Список полей для валидации, если null то по всем полям
* @param bool $bClearErrors Очищать или нет стек ошибок перед валидацией
*
* @return bool
*/
public function _Validate($aFields=null, $clearErrors=true) {
if($clearErrors) {
public function _Validate($aFields=null, $bClearErrors=true) {
if($bClearErrors) {
$this->_clearValidateErrors();
}
foreach($this->_getValidators() as $validator) {
$validator->validateEntity($this,$aFields);
}
return !$this->_hasValidateErrors();
}
/**
* Возвращает список валидаторов с учетом текущего сценария
*
@ -184,9 +241,9 @@ abstract class Entity extends LsObject {
}
return $aValidatorsReturn;
}
/**
* Создает и возвращает список валидаторов для сущности
* @see ModuleValidate::CreateValidator
*
* @return array
* @throws Exception
@ -202,7 +259,6 @@ abstract class Entity extends LsObject {
}
return $aValidators;
}
/**
* Проверяет есть ли ошибки валидации
*
@ -217,7 +273,6 @@ abstract class Entity extends LsObject {
return isset($this->aValidateErrors[$sField]);
}
}
/**
* Возвращает список ошибок для всех полей или одного поля
*
@ -232,7 +287,6 @@ abstract class Entity extends LsObject {
return isset($this->aValidateErrors[$sField]) ? $this->aValidateErrors[$sField] : array();
}
}
/**
* Возвращает первую ошибку для поля или среди всех полей
*
@ -249,17 +303,15 @@ abstract class Entity extends LsObject {
return isset($this->aValidateErrors[$sField]) ? reset($this->aValidateErrors[$sField]) : null;
}
}
/**
* Добавляет для поля ошибку в список ошибок
*
* @param string $sField Поле сущности
* @param string $error Сообщение об ошибке
* @param string $sError Сообщение об ошибке
*/
public function _addValidateError($sField,$error) {
$this->aValidateErrors[$sField][]=$error;
public function _addValidateError($sField,$sError) {
$this->aValidateErrors[$sField][]=$sError;
}
/**
* Очищает список всех ошибок или для конкретного поля
*
@ -272,7 +324,6 @@ abstract class Entity extends LsObject {
unset($this->aValidateErrors[$sField]);
}
}
/**
* Возвращает текущий сценарий валидации
*
@ -281,9 +332,10 @@ abstract class Entity extends LsObject {
public function _getValidateScenario() {
return $this->sValidateScenario;
}
/**
* Устанавливает сценарий валидации
* Если использовать валидацию без сценария, то будут использоваться только те правила, где нет никаких сценариев, либо указан пустой сценарий ''
* Если указать сценарий, то проверка будет только по правилом, где в списке сценарией есть указанный
*
* @param string $sValue
*/

View file

@ -17,10 +17,25 @@
/**
* Абстрактный класс сущности ORM - аналог active record
* Позволяет без написания SQL запросов работать с базой данных.
* <pre>
* $oUser=$this->User_GetUserById(1);
* $oUser->setName('Claus');
* $oUser->Update();
* </pre>
* Возможно получать списки объектов по фильтру:
* <pre>
* $aUsers=$this->User_GetUserItemsByAgeAndSex(18,'male');
* // эквивалентно
* $aUsers=$this->User_GetUserItemsByFilter(array('age'=>18,'sex'=>'male'));
* // эквивалентно
* $aUsers=$this->User_GetUserItemsByFilter(array('#where'=>array('age = ?d and sex = ?' => array(18,'male'))));
* </pre>
*
* @package engine
* @since 1.0
*/
abstract class EntityORM extends Entity {
/**
* Типы связей сущностей
*
@ -31,53 +46,57 @@ abstract class EntityORM extends Entity {
const RELATION_TYPE_MANY_TO_MANY='many_to_many';
const RELATION_TYPE_TREE='tree';
/**
* Массив исходных данных сущности
*
* @var array
*/
protected $_aOriginalData=array();
/**
* Список полей таблицы сущности
*
* @var unknown_type
* @var array
*/
protected $aFields=array();
/**
* Список связей
*
* @var unknown_type
* @var array
*/
protected $aRelations=array();
/**
* Список данных связей
*
* @var unknown_type
* @var array
*/
protected $aRelationsData=array();
// Объекты связей many_to_many
protected $_aManyToManyRelations = array();
/**
* Primary key таблицы сущности
* Объекты связей many_to_many
*
* @var unknown_type
* @var array
*/
protected $sPrimaryKey=null;
protected $_aManyToManyRelations = array();
/**
* Флаг новая или нет сущность
*
* @var unknown_type
* @var bool
*/
protected $bIsNew=true;
/**
* Установка связей
* @see Entity::__construct
*
* @param bool $aParam Ассоциативный массив данных сущности
*/
public function __construct($aParam=false) {
parent::__construct($aParam);
$this->aRelations=$this->_getRelations();
}
/**
* Получение primary key из схемы таблицы
*
* @return string | array
* @return string|array Если индекс составной, то возвращает массив полей
*/
public function _getPrimaryKey() {
if(!$this->sPrimaryKey) {
@ -92,38 +111,35 @@ abstract class EntityORM extends Entity {
}
return $this->sPrimaryKey;
}
/**
* Получение значения primary key
*
* @return unknown
* @return string
*/
public function _getPrimaryKeyValue() {
return $this->_getDataOne($this->_getPrimaryKey());
}
/**
* Новая или нет сущность
* Новая - еще не сохранялась в БД
*
* @return bool
*/
public function _getPrimaryKeyValue() {
return $this->_getDataOne($this->_getPrimaryKey());
}
/**
* Новая или нет сущность
*
* @return unknown
*/
public function _isNew() {
return $this->bIsNew;
}
/**
* Установка флага "новая"
*
* @param unknown_type $bIsNew
* @param bool $bIsNew Флаг - новая сущность или нет
*/
public function _SetIsNew($bIsNew) {
$this->bIsNew=$bIsNew;
}
/**
* Добавление сущности в БД
*
* @return unknown
* @return Entity|false
*/
public function Add() {
if ($this->beforeSave())
@ -133,11 +149,10 @@ abstract class EntityORM extends Entity {
}
return false;
}
/**
* Обновление сущности в БД
*
* @return unknown
* @return Entity|false
*/
public function Update() {
if ($this->beforeSave())
@ -147,11 +162,10 @@ abstract class EntityORM extends Entity {
}
return false;
}
/**
* Сохранение сощности в БД (если новая то создается)
* Сохранение сущности в БД (если новая то создается)
*
* @return unknown
* @return Entity|false
*/
public function Save() {
if ($this->beforeSave())
@ -161,11 +175,10 @@ abstract class EntityORM extends Entity {
}
return false;
}
/**
* Удаление сущности из БД
*
* @return unknown
* @return Entity|false
*/
public function Delete() {
if ($this->beforeDelete())
@ -175,43 +188,38 @@ abstract class EntityORM extends Entity {
}
return false;
}
/**
* Обновляет данные сущности из БД
*
* @return unknown
* @return Entity|false
*/
public function Reload() {
return $this->_Method(__FUNCTION__);
}
/**
* Список полей сущности
* Возвращает список полей сущности
*
* @return unknown
* @return array
*/
public function ShowColumns() {
return $this->_Method(__FUNCTION__ .'From');
}
/**
* Primary индекс сущности
* Возвращает primary индекс сущности
*
* @return unknown
* @return array
*/
public function ShowPrimaryIndex() {
return $this->_Method(__FUNCTION__ .'From');
}
/**
* Хук, срабатывает перед сохранением сущности
*
* @return unknown
* @return bool
*/
protected function beforeSave() {
return true;
}
/**
* Хук, срабатывает после сохранением сущности
*
@ -219,16 +227,14 @@ abstract class EntityORM extends Entity {
protected function afterSave() {
}
/**
* Хук, срабатывает перед удалением сущности
*
* @return unknown
* @return bool
*/
protected function beforeDelete() {
return true;
}
/**
* Хук, срабатывает после удаления сущности
*
@ -236,60 +242,54 @@ abstract class EntityORM extends Entity {
protected function afterDelete() {
}
/**
* Для сущности со связью RELATION_TYPE_TREE возвращает список прямых потомков
*
* @return unknown
* @return array
*/
public function getChildren() {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
return $this->_Method(__FUNCTION__ .'Of');
}
return $this->__call(__FUNCTION__);
return $this->__call(__FUNCTION__,array());
}
/**
* Для сущности со связью RELATION_TYPE_TREE возвращает список всех потомков
*
* @return unknown
* @return array
*/
public function getDescendants() {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
return $this->_Method(__FUNCTION__ .'Of');
}
return $this->__call(__FUNCTION__);
return $this->__call(__FUNCTION__,array());
}
/**
* Для сущности со связью RELATION_TYPE_TREE возвращает предка
*
* @return unknown
* @return Entity
*/
public function getParent() {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
return $this->_Method(__FUNCTION__ .'Of');
}
return $this->__call(__FUNCTION__);
return $this->__call(__FUNCTION__,array());
}
/**
* Для сущности со связью RELATION_TYPE_TREE возвращает список всех предков
*
* @return unknown
* @return array
*/
public function getAncestors() {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
return $this->_Method(__FUNCTION__ .'Of');
}
return $this->__call(__FUNCTION__);
return $this->__call(__FUNCTION__,array());
}
/**
* Для сущности со связью RELATION_TYPE_TREE устанавливает потомков
*
* @param unknown_type $aChildren
* @return unknown
* @param array $aChildren Список потомков
*/
public function setChildren($aChildren=array()) {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
@ -299,12 +299,10 @@ abstract class EntityORM extends Entity {
return $this->__call(__FUNCTION__,$aArgs);
}
}
/**
* Для сущности со связью RELATION_TYPE_TREE устанавливает потомков
*
* @param unknown_type $aDescendants
* @return unknown
* @param array $aDescendants Список потомков
*/
public function setDescendants($aDescendants=array()) {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
@ -314,12 +312,10 @@ abstract class EntityORM extends Entity {
return $this->__call(__FUNCTION__,$aArgs);
}
}
/**
* Для сущности со связью RELATION_TYPE_TREE устанавливает предка
*
* @param unknown_type $oParent
* @return unknown
* @param Entity $oParent Родитель
*/
public function setParent($oParent=null) {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
@ -329,12 +325,10 @@ abstract class EntityORM extends Entity {
return $this->__call(__FUNCTION__,$aArgs);
}
}
/**
* Для сущности со связью RELATION_TYPE_TREE устанавливает предков
*
* @param unknown_type $oParent
* @return unknown
* @param array $oParent Родитель
*/
public function setAncestors($oParent=null) {
if(in_array(self::RELATION_TYPE_TREE,$this->aRelations)) {
@ -344,12 +338,11 @@ abstract class EntityORM extends Entity {
return $this->__call(__FUNCTION__,$aArgs);
}
}
/**
* Проксирует вызов методов в модуль сущности
*
* @param unknown_type $sName
* @return unknown
* @param string $sName Название метода
* @return mixed
*/
protected function _Method($sName) {
$sModuleName=Engine::GetModuleName($this);
@ -365,11 +358,10 @@ abstract class EntityORM extends Entity {
}
return Engine::GetInstance()->_CallModule("{$sPluginPrefix}{$sModuleName}_{$sName}{$sEntityName}",array($this));
}
/**
* Устанавливает данные сущности
*
* @param unknown_type $aData
* @param array $aData Ассоциативный массив данных сущности
*/
public function _setData($aData) {
if(is_array($aData)) {
@ -383,20 +375,18 @@ abstract class EntityORM extends Entity {
$this->_aOriginalData = $this->_aData;
}
}
/**
* Возвращает все данные сущности
*
* @return unknown
* @return array
*/
public function _getOriginalData() {
return $this->_aOriginalData;
}
/**
* Возвращает список полей сущности
*
* @return unknown
* @return array
*/
public function _getFields() {
if(empty($this->aFields)) {
@ -404,13 +394,12 @@ abstract class EntityORM extends Entity {
}
return $this->aFields;
}
/**
* Возвращает поле в нужном формате
*
* @param unknown_type $sField
* @param unknown_type $iPersistence
* @return unknown
* @param string $sField Название поля
* @param int $iPersistence Тип "глубины" определения поля
* @return null|string
*/
public function _getField($sField,$iPersistence=3) {
if($aFields=$this->_getFields()) {
@ -442,11 +431,10 @@ abstract class EntityORM extends Entity {
}
return $sField;
}
/**
* Возвращает список связей
*
* @return unknown
* @return array
*/
public function _getRelations() {
$sParent=get_parent_class($this);
@ -460,34 +448,34 @@ abstract class EntityORM extends Entity {
}
return array_merge($aParentRelations,$this->aRelations);
}
/**
* Возвращает список данный связей
*
* @return unknown
* @return array
*/
public function _getRelationsData() {
return $this->aRelationsData;
}
/**
* Устанавливает данные связей
*
* @param unknown_type $aData
* @param array $aData Список связанных данных
*/
public function _setRelationsData($aData) {
$this->aRelationsData=$aData;
}
/**
* Вызов методов сущности
* Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля
* Также производит обработку методов set* и get*
* Учитывает связи и может возвращать связанные данные
* @see Engine::_CallModule
*
* @param unknown_type $sName
* @param unknown_type $aArgs
* @return unknown
* @param string $sName Имя метода
* @param array $aArgs Аргументы
* @return mixed
*/
public function __call($sName,$aArgs) {
$sType=substr($sName,0,strpos(func_underscore($sName),'_'));
$sType=substr($sName,0,strpos(func_underscore($sName),'_'));
if (!strpos($sName,'_') and in_array($sType,array('get','set','reload'))) {
$sKey=func_underscore(preg_replace('/'.$sType.'/','',$sName, 1));
if ($sType=='get') {
@ -546,13 +534,13 @@ abstract class EntityORM extends Entity {
$mCmdArgs=array($sRelationKey => $iPrimaryKeyValue);
break;
case self::RELATION_TYPE_MANY_TO_MANY :
$sCmd="{$sRelPluginPrefix}Module{$sRelModuleName}_get{$sRelEntityName}ItemsByJoinTable";
$sCmd="{$sRelPluginPrefix}Module{$sRelModuleName}_get{$sRelEntityName}ItemsByJoinTable";
$mCmdArgs=array(
'#join_table' => Config::Get($sRelationJoinTable),
'#relation_key' => $sRelationKey,
'#by_key' => $sRelationJoinTableKey,
'#by_value' => $iPrimaryKeyValue,
'#index-from-primary' => true // Для MANY_TO_MANY необходимо индексами в $aRelationsData иметь первичные ключи сущностей
'#index-from-primary' => true // Для MANY_TO_MANY необходимо индексами в $aRelationsData иметь первичные ключи сущностей
);
break;
default:
@ -593,33 +581,37 @@ abstract class EntityORM extends Entity {
return Engine::getInstance()->_CallModule($sName,$aArgs);
}
}
public function __get($sName) {
// Обработка обращений к обёрткам связей MANY_TO_MANY
// Если связь загружена, возвращаем объект связи
if (isset($this->_aManyToManyRelations[func_underscore($sName)])) {
return $this->_aManyToManyRelations[func_underscore($sName)];
// Есл не загружена, но связь с таким именем существет, пробуем загрузить и вернуть объект связи
} elseif (isset($this->aRelations[func_underscore($sName)]) && $this->aRelations[func_underscore($sName)][0] == self::RELATION_TYPE_MANY_TO_MANY) {
$sMethod = 'get' . func_camelize($sName);
$this->__call($sMethod, array());
if (isset($this->_aManyToManyRelations[func_underscore($sName)])) {
return $this->_aManyToManyRelations[func_underscore($sName)];
}
// В противном случае возвращаем то, что просили у объекта
} else {
return $this->$sName;
}
}
/**
* Сбрасывает данные необходимой связи
*
* @param unknown_type $sKey
*/
public function resetRelationsData($sKey) {
if (isset($this->aRelationsData[$sKey])) {
unset($this->aRelationsData[$sKey]);
}
}
/**
* Используется для доступа к связанным данным типа MANY_TO_MANY
*
* @param string $sName Название свойства к которому обращаемсяя
* @return mixed
*/
public function __get($sName) {
// Обработка обращений к обёрткам связей MANY_TO_MANY
// Если связь загружена, возвращаем объект связи
if (isset($this->_aManyToManyRelations[func_underscore($sName)])) {
return $this->_aManyToManyRelations[func_underscore($sName)];
// Есл не загружена, но связь с таким именем существет, пробуем загрузить и вернуть объект связи
} elseif (isset($this->aRelations[func_underscore($sName)]) && $this->aRelations[func_underscore($sName)][0] == self::RELATION_TYPE_MANY_TO_MANY) {
$sMethod = 'get' . func_camelize($sName);
$this->__call($sMethod, array());
if (isset($this->_aManyToManyRelations[func_underscore($sName)])) {
return $this->_aManyToManyRelations[func_underscore($sName)];
}
// В противном случае возвращаем то, что просили у объекта
} else {
return $this->$sName;
}
}
/**
* Сбрасывает данные необходимой связи
*
* @param string $sKey Ключ(поле) связи
*/
public function resetRelationsData($sKey) {
if (isset($this->aRelationsData[$sKey])) {
unset($this->aRelationsData[$sKey]);
}
}
}

View file

@ -17,30 +17,56 @@
/**
* Абстракция хука, от которой наследуются все хуки
* Дает возможность создавать обработчики хуков в каталоге /hooks/
*
* @package engine
* @since 1.0
*/
abstract class Hook extends LsObject {
public function __construct() {
}
/**
* Добавляет обработчик на хук
* @see ModuleHook::AddExecHook
*
* @param string $sName Название хука на который вешается обработчик
* @param string $sCallBack Название метода обработчика
* @param null|string $sClassNameHook Название класса обработчика, по умолчанию это текущий класс хука
* @param int $iPriority Приоритет обработчика хука, чем выше число, тем больше приоритет - хук обработчик выполнится раньше остальных
*/
protected function AddHook($sName,$sCallBack,$sClassNameHook=null,$iPriority=1) {
if (is_null($sClassNameHook)) {
$sClassNameHook=get_class($this);
}
$this->Hook_AddExecHook($sName,$sCallBack,$iPriority,array('sClassName'=>$sClassNameHook));
}
/**
* Добавляет делегирующий обработчик на хук. Актуален для хуков на выполнение методов модулей.
* После него другие обработчики не выполняются, а результат метода моуля заменяется на рузультат обработчика.
*
* @param $sName Название хука на который вешается обработчик
* @param $sCallBack Название метода обработчика
* @param null $sClassNameHook Название класса обработчика, по умолчанию это текущий класс хука
* @param int $iPriority Приоритет обработчика хука
*/
protected function AddDelegateHook($sName,$sCallBack,$sClassNameHook=null,$iPriority=1) {
if (is_null($sClassNameHook)) {
$sClassNameHook=get_class($this);
}
$this->Hook_AddDelegateHook($sName,$sCallBack,$iPriority,array('sClassName'=>$sClassNameHook));
}
/**
* Обязательный метод в хуке - в нем происходит регистрация обработчиков хуков
*
* @abstract
*/
abstract public function RegisterHook();
/**
* Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля
* @see Engine::_CallModule
*
* @param string $sName Имя метода
* @param array $aArgs Аргументы
* @return mixed
*/
public function __call($sName,$aArgs) {
return Engine::getInstance()->_CallModule($sName,$aArgs);
}

View file

@ -16,57 +16,76 @@
*/
/**
* Класс. представляющий собой обёертку для связей MANY_TO_MANY.
* Позволяет оперровать коллекцией загруженных по связи эдементов через имя связи
* Класс представляющий собой обёертку для связей MANY_TO_MANY.
* Позволяет оперировать коллекцией загруженных по связи элементов через имя связи
* Например, $oTopic->Tags->add($oTag) или $oTopic->Tags->delete($oTag->getId()) при
* наличии настроенной MANY_TO_MANY связи 'tags'
*
* @package engine
* @since 1.0
*/
class LS_ManyToManyRelation extends LsObject {
// Ссылка на $oEntityORM->aRelationsData[<relation_name>],
// где relation_name - имя сязи, которую представляет объект
protected $_aCollection = array();
protected $bUpdated = false;
/**
* Список объектов связи
*
* @var array
*/
protected $_aCollection = array();
/**
* Флаг обновления списка объектов связи
*
* @var bool
*/
protected $bUpdated = false;
public function __construct($aCollection)
{
$this->_aCollection = $aCollection;
}
/**
* Добавление объекта в коллекцию
* @param <type> $oEntity
*/
public function add($oEntity)
{
$this->bUpdated = true;
$this->_aCollection[$oEntity->_getPrimaryKeyValue()] = $oEntity;
}
/**
* Удаление объекта из коллекции по его id или массиву id
* @param <type> $iId
*/
public function delete($iId)
{
$this->bUpdated = true;
if (is_array($iId)) {
foreach ($iId as $id) {
if (isset($this->_aCollection[$id])) {
unset($this->_aCollection[$id]);
}
}
} elseif (isset($this->_aCollection[$iId])) {
unset($this->_aCollection[$iId]);
}
}
public function getCollection()
{
return $this->_aCollection;
}
public function isUpdated()
{
return $this->bUpdated;
}
/**
* Устанавливает список объектов
*
* @param $aCollection Список объектов связи
*/
public function __construct($aCollection) {
$this->_aCollection = $aCollection;
}
/**
* Добавление объекта в список
*
* @param Entity $oEntity
*/
public function add($oEntity) {
$this->bUpdated = true;
$this->_aCollection[$oEntity->_getPrimaryKeyValue()] = $oEntity;
}
/**
* Удаление объекта из списка по его id или массиву id
*
* @param int|array $iId
*/
public function delete($iId) {
$this->bUpdated = true;
if (is_array($iId)) {
foreach ($iId as $id) {
if (isset($this->_aCollection[$id])) {
unset($this->_aCollection[$id]);
}
}
} elseif (isset($this->_aCollection[$iId])) {
unset($this->_aCollection[$iId]);
}
}
/**
* Возвращает список объектов связи
*
* @return array
*/
public function getCollection() {
return $this->_aCollection;
}
/**
* Проверка списка на обновление
*
* @return bool
*/
public function isUpdated() {
return $this->bUpdated;
}
}

View file

@ -17,13 +17,21 @@
/**
* Абстрактный класс мапера
* Вся задача маппера сводится в выполнению запроса к базе данных (или либому другому источнику данных) и возвращения результата в модуль.
*
* @package engine
* @since 1.0
*/
abstract class Mapper extends LsObject {
protected $oDb;
/**
* Сохраняем коннект к БД
* Объект подключения к базе данных
*
* @var DbSimple_Generic_Database
*/
protected $oDb;
/**
* Передаем коннект к БД
*
* @param DbSimple_Generic_Database $oDb
*/

View file

@ -17,69 +17,71 @@
/**
* Абстракция модуля, от которой наследуются все модули
* Модули предназначены для объединения часто используемого функционала, т.е. некие аналоги внутренних библиотек.
*
* @package engine
* @since 1.0
*/
abstract class Module extends LsObject {
/**
* Engine object
* Объект ядра
*
* @var Engine
*/
protected $oEngine=null;
/**
* Указывает на то, была ли проведенна инициализация модуля
*
* @var bool
*/
protected $bIsInit=false;
final public function __construct(Engine $oEngine) {
$this->oEngine=$oEngine;
/**
* При создании модуля передаем объект ядра
*
* @param Engine $oEngine
*/
final public function __construct(Engine $oEngine) {
$this->oEngine=$oEngine;
}
/**
* Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля
* @see Engine::_CallModule
*
* @param string $sName
* @param array $aArgs
* @return unknown
* @param string $sName Имя метода
* @param array $aArgs Аргументы
* @return mixed
*/
public function __call($sName,$aArgs) {
return $this->oEngine->_CallModule($sName,$aArgs);
}
/**
* Блокируем копирование/клонирование объекта роутинга
* Блокируем копирование/клонирование объекта
*
*/
protected function __clone() {
}
/**
* Абстрактный метод инициализации модуля, должен быть переопределен в модуле
*
*/
abstract public function Init();
/**
* Метод срабатывает после отработки цепочки экшенов(action)
* Метод срабатывает при завершении работы ядра
*
*/
public function Shutdown() {
}
/**
* Возвращает значение флага инициализации
* Возвращает значение флага инициализации модуля
*
* @return bool
*/
public function isInit() {
return $this->bIsInit;
}
/**
* Помечает модуль как инициализированный
*

View file

@ -18,6 +18,8 @@
/**
* От этого класса наследуются все остальные
*
* @package engine
* @since 1.0
*/
abstract class LsObject {

View file

@ -17,7 +17,10 @@
/**
* Абстракция плагина, от которой наследуются все плагины
* Файл плагина должен находиться в каталоге /plugins/plgname/ и иметь название PluginPlgname.class.php
*
* @package engine
* @since 1.0
*/
abstract class Plugin extends LsObject {
/**
@ -31,7 +34,7 @@ abstract class Plugin extends LsObject {
*
* @var array
*/
static protected $aTemplateWebPath=array();
static protected $aTemplateWebPath=array();
/**
* Массив делегатов плагина
*
@ -44,83 +47,49 @@ abstract class Plugin extends LsObject {
* @var array
*/
protected $aInherits=array();
public function __construct() {
}
/**
* Функция инициализации плагина
* Метод инициализации плагина
*
*/
public function Init() {
}
/**
* Передает информацию о делегатах на Plugin-модуль
* Передает информацию о делегатах в модуль ModulePlugin
* Вызывается Engine перед инициализацией плагина
* @see Engine::LoadPlugins
*/
final function Delegate() {
/**
* Получаем название плагина
*/
preg_match('/^Plugin([\w]+)$/i',get_class($this),$aMatches);
$sPluginName=strtolower($aMatches[1]);
$aDelegates=$this->GetDelegates();
foreach ($aDelegates as $sObjectName=>$aParams) {
foreach ($aParams as $sFrom=>$sTo) {
$this->Plugin_Delegate($sObjectName,$sFrom,$sTo,get_class($this));
}
}
$aInherits=$this->GetInherits();
foreach ($aInherits as $sObjectName=>$aParams) {
foreach ($aParams as $sFrom=>$sTo) {
foreach ($aParams as $sFrom=>$sTo) {
$this->Plugin_Inherit($sFrom,$sTo,get_class($this));
}
}
}
/**
* Возвращает массив делегатов
*
* @return array
*/
final function GetInherits() {
$aReturn=array();
if(is_array($this->aInherits) and count($this->aInherits)) {
foreach ($this->aInherits as $sObjectName=>$aParams) {
if(is_array($aParams) and count($aParams)) {
foreach ($aParams as $sFrom=>$sTo) {
if (is_int($sFrom)) {
$sFrom=$sTo;
$sTo=null;
}
list($sFrom,$sTo)=$this->MakeDelegateParams($sObjectName,$sFrom,$sTo);
$aReturn[$sObjectName][$sFrom]=$sTo;
}
}
}
}
return $aReturn;
}
/**
* Возвращает массив наследников
*
* @return array
*/
final function GetDelegates() {
final function GetInherits() {
$aReturn=array();
if(is_array($this->aDelegates) and count($this->aDelegates)) {
foreach ($this->aDelegates as $sObjectName=>$aParams) {
if(is_array($this->aInherits) and count($this->aInherits)) {
foreach ($this->aInherits as $sObjectName=>$aParams) {
if(is_array($aParams) and count($aParams)) {
foreach ($aParams as $sFrom=>$sTo) {
if (is_int($sFrom)) {
$sFrom=$sTo;
$sTo=null;
}
list($sFrom,$sTo)=$this->MakeDelegateParams($sObjectName,$sFrom,$sTo);
list($sFrom,$sTo)=$this->MakeDelegateParams($sObjectName,$sFrom,$sTo);
$aReturn[$sObjectName][$sFrom]=$sTo;
}
}
@ -128,10 +97,41 @@ abstract class Plugin extends LsObject {
}
return $aReturn;
}
/**
* Возвращает массив делегатов
*
* @return array
*/
final function GetDelegates() {
$aReturn=array();
if(is_array($this->aDelegates) and count($this->aDelegates)) {
foreach ($this->aDelegates as $sObjectName=>$aParams) {
if(is_array($aParams) and count($aParams)) {
foreach ($aParams as $sFrom=>$sTo) {
if (is_int($sFrom)) {
$sFrom=$sTo;
$sTo=null;
}
list($sFrom,$sTo)=$this->MakeDelegateParams($sObjectName,$sFrom,$sTo);
$aReturn[$sObjectName][$sFrom]=$sTo;
}
}
}
}
return $aReturn;
}
/**
* Преобразовывает краткую форму имен делегатов в полную
*
* @param $sObjectName Название типа объекта делегата
* @see ModulePlugin::aDelegates
* @param $sFrom Что делегируем
* @param $sTo Что делегирует
* @return array
*/
public function MakeDelegateParams($sObjectName,$sFrom,$sTo) {
/**
* Если не указан делегат TO, считаем, что делегатом является
* Если не указан делегат TO, считаем, что делегатом является
* одноименный объект текущего плагина
*/
if ($sObjectName=='template') {
@ -149,169 +149,178 @@ abstract class Plugin extends LsObject {
}
return array($sFrom,$sTo);
}
/**
* Функция активации плагина
* Метод активации плагина
*
* @return bool
*/
public function Activate() {
return true;
}
/**
* Функция деактивации плагина
* Метод деактивации плагина
*
* @return bool
*/
public function Deactivate() {
return true;
}
/**
* Транслирует на базу данных запросы из указанного файла
*
* @param string $sFilePath
* @see ModuleDatabase::ExportSQL
*
* @param string $sFilePath Полный путь до файла с SQL
* @return array
*/
protected function ExportSQL($sFilePath) {
return $this->Database_ExportSQL($sFilePath);
return $this->Database_ExportSQL($sFilePath);
}
/**
* Выполняет SQL
* @see ModuleDatabase::ExportSQLQuery
*
* @param string $sSql
* @param string $sSql Строка SQL запроса
* @return array
*/
protected function ExportSQLQuery($sSql) {
return $this->Database_ExportSQLQuery($sSql);
}
/**
* Проверяет наличие таблицы в БД
* @see ModuleDatabase::isTableExists
*
* @param unknown_type $sTableName
* @param string $sTableName Название таблицы, необходимо перед именем таблицы добавлять "prefix_", это позволит учитывать произвольный префикс таблиц у пользователя
* <pre>
* prefix_topic
* </pre>
* @return bool
*/
protected function isTableExists($sTableName) {
return $this->Database_isTableExists($sTableName);
}
/**
* Проверяет наличие поля в таблице
* @see ModuleDatabase::isFieldExists
*
* @param string $sTableName
* @param string $sFieldName
* @param string $sTableName Название таблицы, необходимо перед именем таблицы добавлять "prefix_", это позволит учитывать произвольный префикс таблиц у пользователя
* @param string $sFieldName Название поля в таблице
* @return bool
*/
protected function isFieldExists($sTableName,$sFieldName) {
return $this->Database_isFieldExists($sTableName,$sFieldName);
}
/**
* Добавляет тип в поле enum
* Добавляет новый тип в поле enum(перечисление)
* @see ModuleDatabase::addEnumType
*
* @param string $sTableName
* @param string $sFieldName
* @param string $sType
* @param string $sTableName Название таблицы, необходимо перед именем таблицы добавлять "prefix_", это позволит учитывать произвольный префикс таблиц у пользователя
* @param string $sFieldName Название поля в таблице
* @param string $sType Название типа
*/
protected function addEnumType($sTableName,$sFieldName,$sType) {
$this->Database_addEnumType($sTableName,$sFieldName,$sType);
}
/**
* Получает версию плагина
* Возвращает версию плагина
*
* @return unknown
* @return string|null
*/
public function GetVersion() {
preg_match('/^Plugin([\w]+)$/i',get_class($this),$aMatches);
preg_match('/^Plugin([\w]+)$/i',get_class($this),$aMatches);
$sPluginXML = Config::Get('path.root.server').'/plugins/'.strtolower($aMatches[1]).'/'.ModulePlugin::PLUGIN_XML_FILE;
if($oXml = @simplexml_load_file($sPluginXML)) {
return (string)$oXml->version;
}
return null;
}
/**
* Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля
* @see Engine::_CallModule
*
* @param string $sName Имя метода
* @param array $aArgs Аргументы
* @return mixed
*/
public function __call($sName,$aArgs) {
return Engine::getInstance()->_CallModule($sName,$aArgs);
}
/**
* Возвращает полный путь до плагина
* Возвращает полный серверный путь до плагина
*
* @param unknown_type $sName
* @return unknown
* @param string $sName
* @return string
*/
static public function GetPath($sName) {
$sName = preg_match('/^Plugin([\w]+)(_[\w]+)?$/Ui',$sName,$aMatches)
? strtolower($aMatches[1])
: strtolower($sName);
return Config::Get('path.root.server').'/plugins/'.$sName.'/';
}
/**
* Возвращает правильный путь к директории шаблонов
* Возвращает правильный серверный путь к директории шаблонов с учетом текущего шаблона
* Если пользователь использует шаблон которого нет в плагине, то возвращает путь до шабона плагина 'default'
*
* @return string
* @param string $sName Название плагина или его класс
* @return string|null
*/
static public function GetTemplatePath($sName) {
static public function GetTemplatePath($sName) {
$sName = preg_match('/^Plugin([\w]+)(_[\w]+)?$/Ui',$sName,$aMatches)
? strtolower($aMatches[1])
: strtolower($sName);
if(!isset(self::$aTemplatePath[$sName])) {
$aPaths=glob(Config::Get('path.root.server').'/plugins/'.$sName.'/templates/skin/*',GLOB_ONLYDIR);
if(!isset(self::$aTemplatePath[$sName])) {
$aPaths=glob(Config::Get('path.root.server').'/plugins/'.$sName.'/templates/skin/*',GLOB_ONLYDIR);
$sTemplateName=($aPaths and in_array(Config::Get('view.skin'),array_map('basename',$aPaths)))
? Config::Get('view.skin')
: 'default';
$sDir=Config::Get('path.root.server')."/plugins/{$sName}/templates/skin/{$sTemplateName}/";
self::$aTemplatePath[$sName] = is_dir($sDir) ? $sDir : null;
}
return self::$aTemplatePath[$sName];
}
}
/**
* Возвращает правильный web-адрес директории шаблонов
* Если пользователь использует шаблон которого нет в плагине, то возвращает путь до шабона плагина 'default'
*
* @param string $sName Название плагина или его класс
* @return string
*/
static public function GetTemplateWebPath($sName) {
$sName = preg_match('/^Plugin([\w]+)(_[\w]+)?$/Ui',$sName,$aMatches)
? strtolower($aMatches[1])
: strtolower($sName);
if(!isset(self::$aTemplateWebPath[$sName])) {
if(!isset(self::$aTemplateWebPath[$sName])) {
$aPaths=glob(Config::Get('path.root.server').'/plugins/'.$sName.'/templates/skin/*',GLOB_ONLYDIR);
$sTemplateName=($aPaths and in_array(Config::Get('view.skin'),array_map('basename',$aPaths)))
? Config::Get('view.skin')
: 'default';
self::$aTemplateWebPath[$sName]=Config::Get('path.root.web')."/plugins/{$sName}/templates/skin/{$sTemplateName}/";
}
return self::$aTemplateWebPath[$sName];
}
/**
* Устанавливает значение пути до шаблонов плагина
* Устанавливает значение серверного пути до шаблонов плагина
*
* @param string $sName
* @param string $sTemplatePath
* @param string $sName Имя плагина
* @param string $sTemplatePath Серверный путь до шаблона
* @return bool
*/
static public function SetTemplatePath($sName,$sTemplatePath) {
if(!is_dir($sTemplatePath)) return false;
self::$aTemplatePath[$sName]=$sTemplatePath;
return true;
}
/**
* Устанавливает значение web-пути до шаблонов плагина
*
* @param string $sName
* @param string $sTemplatePath
* @return bool
* @param string $sName Имя плагина
* @param string $sTemplatePath Серверный путь до шаблона
*/
static public function SetTemplateWebPath($sName,$sTemplatePath) {
self::$aTemplateWebPath[$sName]=$sTemplatePath;
}
}
}
?>