<?php
/**
* ÐлаÑÑ Component.
*
* @package energine
* @subpackage core
* @author 1m.dm
* @copyright ColoCall 2006
* @version $Id: Component.class.php,v 1.17 2007/12/17 14:16:03 pavka Exp $
*/
//require_once('core/framework/ComponentConfig.class.php');
//require_once('core/framework/DBWorker.class.php');
//require_once('core/framework/Request.class.php');
//require_once('core/framework/Builder.class.php');
/**
* ÐÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ ÑÑÑаниÑÑ.
*
* @package energine
* @subpackage core
*/
class Component extends DBWorker {
/**
* ÐÐ¼Ñ Ð´ÐµÐ¹ÑÑÐ²Ð¸Ñ Ð¿Ð¾-ÑмолÑаниÑ.
*/
const DEFAULT_ACTION_NAME = 'main';
/**
* @access protected
* @var DOMDocument DOM-докÑÐ¼ÐµÐ½Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа
*/
protected $doc;
/**
* @access protected
* @var Request ÑкземплÑÑ Ð¾Ð±ÑекÑа Request
*/
protected $request;
/**
* @access protected
* @var array паÑамеÑÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа
*/
protected $params;
/**
* @access protected
* @var Document докÑÐ¼ÐµÐ½Ñ ÑÑÑаниÑÑ
*/
protected $document;
/**
* @access protected
* @var string Ð¸Ð¼Ñ Ð¼Ð¾Ð´ÑлÑ, коÑоÑÐ¾Ð¼Ñ Ð¿ÑÐ¸Ð½Ð°Ð´Ð»ÐµÐ¶Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ
*/
protected $module;
/**
* @access protected
* @var Response ÑкземплÑÑ Ð¾Ð±ÑекÑа Response
*/
protected $response;
/**
* @access private
* @var int ÑÑÐ¾Ð²ÐµÐ½Ñ Ð¿Ñав, необÑ
одимÑй Ð´Ð»Ñ Ð·Ð°Ð¿ÑÑка меÑода компоненÑа
*/
private $rights;
/**
* @access private
* @var string Ð¸Ð¼Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа
*/
private $name;
/**
* @var boolean Флаг, ÑказÑваÑÑий на Ñо, ÑвлÑеÑÑÑ Ð»Ð¸ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ Ð°ÐºÑивнÑм
* @access private
*/
private $enabled = true;
/**
* @access private
* @var array паÑамеÑÑÑ Ð´ÐµÐ¹ÑÑвиÑ
*/
private $actionParams = false;
/**
* @access private
* @var array ÑвойÑÑва компоненÑа
*/
private $properties = array();
/**
* @access private
* @var array ÑпиÑок оÑибок, пÑоизоÑедÑиÑ
во вÑÐµÐ¼Ñ ÑабоÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа
*/
private $errors = array();
/**
* РезÑлÑÑÐ°Ñ ÑвлÑеÑÑÑ Ð¾Ð±ÑекÑом клаÑÑа DOMNode или boolean:
* true - ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ Ð¾ÑÑабоÑал ÑÑпеÑно, но ниÑего не вÑвел;
* false - пÑоизоÑла оÑибка пÑи ÑабоÑе компоненÑа.
*
* @access private
* @var mixed ÑезÑлÑÑÐ°Ñ ÑабоÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа
*/
private $result;
/**
* @access private
* @var string Ð¸Ð¼Ñ ÑекÑÑего дейÑÑÐ²Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа
*/
private $action = self::DEFAULT_ACTION_NAME;
/**
* @access private
* @var Builder поÑÑÑоиÑÐµÐ»Ñ ÑезÑлÑÑаÑа ÑабоÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа
*/
private $builder = false;
/**
* @access protected
* @var ComponentConfig конÑигÑÑаÑÐ¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа
*/
protected $config;
/**
* ÐонÑÑÑÑкÑÐ¾Ñ ÐºÐ»Ð°ÑÑа.
*
* @access public
* @param string $name
* @param string $module
* @param Document $document
* @param array $params
* @return void
*/
public function __construct($name, $module, Document $document, array $params = null) {
parent::__construct();
$this->name = $name;
$this->module = $module;
$this->document = $document;
$this->params = $this->defineParams();
if (is_array($params)) {
foreach ($params as $name => $value) {
$this->setParam($name, $value);
//$this->params[$name] = $value;
}
}
$this->rights = $this->getParam('rights');
$this->response = Response::getInstance();
$this->request = Request::getInstance();
/**
* @todo ÐÑовеÑиÑÑ, можно ли пеÑенеÑÑи в build
*/
$this->doc = new DOMDocument('1.0', 'UTF-8');
$this->setProperty('template', $template = $this->request->getPath(Request::PATH_TEMPLATE, true));
$this->setProperty(
'single_template',
($this->document->getProperty('single') ? $template : $template.'single/'.$this->getName().'/')
);
$this->config = new ComponentConfig($this->getParam('configFilename'), get_class($this), $this->module);
$this->determineAction();
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ñлаг акÑивноÑÑи компоненÑа
*
* @return bool
* @access protected
* @final
*/
final protected function isActive() {
return $this->params['active'];
}
/**
* УÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð¿Ð¾ÑÑÑоиÑÐµÐ»Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа.
*
* @access protected
* @final
* @param Builder $builder
* @return void
*/
final protected function setBuilder(Builder $builder) {
$this->builder = $builder;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¿Ð¾ÑÑÑоиÑÐµÐ»Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа.
*
* @access protected
* @final
* @return Builder
*/
final protected function getBuilder() {
return $this->builder;
}
/**
* ÐпÑеделÑÐµÑ Ð´Ð¾Ð¿ÑÑÑимÑе паÑамеÑÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа и иÑ
знаÑÐµÐ½Ð¸Ñ Ð¿Ð¾-ÑмолÑаниÑ
* в виде маÑÑива array(paramName => defaultValue).
*
* @access protected
* @return array
*/
protected function defineParams() {
return array(
'action' => $this->action,
'rights' => $this->document->getRights(),
'configFilename' => false,
'active' => false,
);
}
/**
* УÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð·Ð½Ð°Ñение паÑамеÑÑа компоненÑа, еÑли Ñакой ÑÑÑеÑÑвÑеÑ.
* РпÑоÑивном ÑлÑÑае возбÑждаеÑÑÑ Ð¸ÑклÑÑение.
*
* @access protected
* @param string $name
* @param mixed $value
* @return void
*/
protected function setParam($name, $value) {
if (!isset($this->params[$name])) {
throw new SystemException('ERR_DEV_NO_PARAM', SystemException::ERR_DEVELOPER, $name);
}
/*if (in_array($name, array('action','configFilename', 'active'))) {
throw new SystemException('ERR_DEV_INVARIANT_PARAM', SystemException::ERR_DEVELOPER, $name);
}*/
// еÑли новое знаÑение пÑÑÑое - оÑÑавлÑем знаÑение по-ÑмолÑаниÑ
if (!empty($value) || $value === false) {
$this->params[$name] = $value;
}
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð·Ð½Ð°Ñение паÑамеÑÑа компоненÑа, или null, еÑли Ñакого
* паÑамеÑÑа не ÑÑÑеÑÑвÑеÑ.
*
* @access protected
* @final
* @param string $name
* @return mixed
*/
final protected function getParam($name) {
return (isset($this->params[$name]) ? $this->params[$name] : null);
}
/**
* ÐпÑеделÑÐµÑ ÑекÑÑее дейÑÑвие
*
* @return void
* @access private
*/
protected function determineAction() {
//ТекÑÑее дейÑÑвие беÑем из паÑамеÑÑов
//Ðо ÑмолÑÐ°Ð½Ð¸Ñ Ð¾Ð½Ð¾ Ñавно self::DEFAULT_ACTION_NAME
$this->action = $this->getParam('action');
// еÑли ÑÑо оÑновной ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ ÑÑÑаниÑÑ, должен бÑÑÑ ÐºÐ¾Ð½ÑигÑÑаÑионнÑй Ñайл
if ($this->isActive()) {
if ($this->config->isEmpty()) {
throw new SystemException('ERR_DEV_NO_COMPONENT_CONFIG', SystemException::ERR_DEVELOPER, $this->getName());
}
// опÑеделÑем дейÑÑвие по запÑоÑÐµÐ½Ð½Ð¾Ð¼Ñ URI
$action = $this->config->getActionByURI($this->request->getPath(Request::PATH_ACTION, true));
if ($action !== false) {
$this->action = $action['name'];
$this->actionParams = $action['params'];
}
}
// еÑли Ð¸Ð¼Ñ Ð´ÐµÐ¹ÑÑÐ²Ð¸Ñ Ñказано в POST-запÑоÑе - иÑполÑзÑем его
elseif (isset($_POST[$this->getName()]['action'])) {
$this->action = $_POST[$this->getName()]['action'];
}
// ÑÑÑанавливаем пÑава на дейÑÑвие из конÑигÑÑаÑии, еÑли опÑеделенÑ
if (!$this->config->isEmpty()) {
$this->config->setCurrentMethod($this->getAction());
if (!is_null($rights = $this->config->getCurrentMethodConfig()->getAttribute('rights'))) {
$this->rights = (int)$rights;
}
}
}
/**
* ÐпÑеделÑÐµÑ Ð¸Ð¼Ñ ÑекÑÑего дейÑÑÐ²Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа.
*
* @access public
* @return string
* @final
*/
final public function getAction() {
return $this->action;
}
/**
* ÐозвÑаÑÐ°ÐµÑ ÑÑÐ¾Ð²ÐµÐ½Ñ Ð¿Ñав полÑзоваÑелÑ, необÑ
одимÑÑ
Ð´Ð»Ñ Ð·Ð°Ð¿ÑÑка
* ÑекÑÑего дейÑÑÐ²Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа.
*
* @access public
* @final
* @return int
*/
final public function getMethodRights() {
return (int)$this->rights;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¸Ð¼Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа.
*
* @access public
* @final
* @return string
*/
final public function getName() {
return $this->name;
}
/**
* ÐапÑÑÐºÐ°ÐµÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ Ð½Ð° иÑполнение.
*
* @access public
* @final
* @return void
*/
final public function run() {
if (!method_exists($this, $this->getAction())) {
throw new SystemException(
'ERR_DEV_NO_ACTION',
SystemException::ERR_DEVELOPER,
array($this->getAction(), $this->getName())
);
}
$this->{$this->getAction()}();
}
/**
* ÐейÑÑвие по-ÑмолÑаниÑ.
*
* @access protected
* @return boolean
*/
protected function main() {
$this->prepare(); // вÑзÑваем меÑод подгоÑовки даннÑÑ
return true;
}
/**
* ÐеÑод подгоÑовки даннÑÑ
.
* ÐÑзÑваеÑÑÑ Ð²Ð½Ð°Ñале ÑабоÑÑ Ð¼ÐµÑода, ÑеализÑÑÑего оÑновное дейÑÑвие.
*
* @access protected
* @return void
*/
protected function prepare() {
}
/**
* ÐÑклÑÑÐ°ÐµÑ Ð¾ÑобÑажение компоненÑа
*
* @return void
* @access public
* @final
*/
final public function disable() {
$this->enabled = false;
}
/**
* ÐклÑÑÐ°ÐµÑ Ð¾ÑобÑажение компоненÑа
*
* @return void
* @access public
* @final
*/
final public function enable() {
$this->enabled = true;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð°ÐºÑивноÑÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа
*
* @return boolean
* @access public
* @final
*/
final public function enabled() {
return $this->enabled;
}
/**
* УÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð·Ð½Ð°Ñение ÑвойÑÑва компоненÑа.
*
* @access protected
* @final
* @param string $propName
* @param mixed $propValue
* @return void
*/
final protected function setProperty($propName, $propValue) {
$this->properties[$propName] = $propValue;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð·Ð½Ð°Ñение ÑвойÑÑва компоненÑа.
*
* @access protected
* @final
* @param string $propName
* @return mixed
*/
final protected function getProperty($propName) {
$result = false;
if (isset($this->properties[$propName])) {
$result = $this->properties[$propName];
}
return $result;
}
/**
* УдалÑÐµÑ ÑвойÑÑво компоненÑа.
*
* @access protected
* @final
* @param string
* @return void
*/
final protected function removeProperty($propName) {
unset($this->properties[$propName]);
}
/**
* СÑÑÐ¾Ð¸Ñ ÑезÑлÑÑÐ°Ñ ÑабоÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа иÑполÑзÑÑ Ð¾Ð¿ÑеделÑннÑй поÑÑÑоиÑелÑ.
*
* @access public
* @return DOMDocument
*/
public function build() {
$result = $this->doc->createElement('component');
$result->setAttribute('name', $this->getName());
$result->setAttribute('module', $this->module);
$result->setAttribute('componentAction', $this->getAction());
$result->setAttribute('class', get_class($this));
foreach ($this->properties as $propName => $propValue) {
$result->setAttribute($propName, $propValue);
}
/*
* СÑÑеÑÑвÑÐµÑ Ð»Ð¸ поÑÑÑоиÑÐµÐ»Ñ Ð¸ пÑавилÑно ли он оÑÑабоÑал?
* ÐоÑÑÑоиÑÐµÐ»Ñ Ð¼Ð¾Ð¶ÐµÑ Ð½Ðµ ÑÑÑеÑÑвоваÑÑ, еÑли Ð¼Ñ Ñоздаем ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ Ð² коÑоÑом Ð½ÐµÑ Ð´Ð°Ð½Ð½ÑÑ
.
*/
if ($this->getBuilder() && $this->getBuilder()->build()) {
$result->appendChild(
$this->doc->importNode(
$this->getBuilder()->getResult(),
true
)
);
}
$this->doc->appendChild($result);
$result = $this->doc;
return $result;
}
/**
* ÐенеÑиÑÑÐµÑ Ð¾ÑÐ¸Ð±ÐºÑ Ð¸ добавлÑÐµÑ ÐµÑ Ð² ÑпиÑок оÑибок компоненÑа.
*
* @access protected
* @param int $errorType Ñип оÑибки
* @param string $errorMessage ÑообÑение об оÑибке
* @param mixed $errorCustomInfo дополниÑелÑÐ½Ð°Ñ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾Ð± оÑибке
* @return void
*/
protected function generateError($errorType, $errorMessage, $errorCustomInfo = false) {
$errorInfo = array(
'type' => $errorType,
'message' => $errorMessage,
'custom' => $errorCustomInfo
);
array_push($this->errors, $errorInfo);
// еÑли оÑибка не позволÑÐµÑ Ð¿ÑодолжиÑÑ ÑабоÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа, возбÑждаем ÑикÑивное иÑклÑÑение
if ($errorType == SystemException::ERR_WARNING) {
throw new DummyException;
}
}
/**
* ÐбÑабаÑÑÐ²Ð°ÐµÑ Ð¾Ñибки, пÑоизоÑедÑие во вÑÐµÐ¼Ñ ÑабоÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа.
* ÐозвÑаÑÐ°ÐµÑ DOMDocument, пÑедÑÑавлÑÑÑий оÑибки компоненÑа, или
* false, еÑли никакиÑ
оÑибок не пÑоизоÑло.
*
* @access public
* @final
* @return mixed
*/
final public function handleErrors() {
$result = false;
if (sizeof($this->errors) > 0) {
$dom_errorDoc = new DOMDocument('1.0', 'UTF-8');
$dom_errors = $dom_errorDoc->createElement('errors');
$dom_errors->setAttribute('title', $this->translate('TXT_ERRORS'));
foreach ($this->errors as $errorInfo) {
$dom_error = $dom_errorDoc->createElement('error', $errorInfo['message']);
$dom_error->setAttribute('type', $errorInfo['type']);
/**
* @todo вÑводиÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ ÑолÑко в debug-Ñежиме.
*/
if (isset($errorInfo['custom'])) {
if (is_array($errorInfo['custom'])) {
$customMessage = implode('. ', $errorInfo['custom']);
}
else {
$customMessage = $errorInfo['custom'];
}
if (!empty($customMessage)) {
$dom_error->nodeValue = "{$errorInfo['message']} [ $customMessage ]";
}
else {
$dom_error->nodeValue = $errorInfo['message'];
}
}
$dom_errors->appendChild($dom_error);
}
$dom_errorDoc->appendChild($dom_errors);
$result = $dom_errorDoc;
}
return $result;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¿Ð°ÑамеÑÑÑ Ð´ÐµÐ¹ÑÑвиÑ.
*
* @access protected
* @return array
*/
protected function getActionParams() {
return $this->actionParams;
}
}