2014-05-14 23:24:20 +10:00
|
|
|
<?php namespace Cms\Classes;
|
|
|
|
|
|
|
|
use Str;
|
|
|
|
use Lang;
|
|
|
|
use Config;
|
|
|
|
use October\Rain\Extension\Extendable;
|
2016-02-13 15:23:53 +11:00
|
|
|
use BadMethodCallException;
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Component base class
|
|
|
|
*
|
|
|
|
* @package october\cms
|
|
|
|
* @author Alexey Bobkov, Samuel Georges
|
|
|
|
*/
|
|
|
|
abstract class ComponentBase extends Extendable
|
|
|
|
{
|
2014-05-22 20:27:44 +10:00
|
|
|
use \System\Traits\AssetMaker;
|
2016-12-10 09:02:06 +11:00
|
|
|
use \System\Traits\EventEmitter;
|
2014-05-22 20:27:44 +10:00
|
|
|
use \System\Traits\PropertyContainer;
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string A unique identifier for this component.
|
|
|
|
*/
|
|
|
|
public $id;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string Alias used for this component.
|
|
|
|
*/
|
|
|
|
public $alias;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string Component class name or class alias used in the component declaration in a template.
|
|
|
|
*/
|
|
|
|
public $name;
|
|
|
|
|
2014-08-06 22:42:09 +11:00
|
|
|
/**
|
2016-02-13 15:23:53 +11:00
|
|
|
* @var boolean Determines whether the component is hidden from the back-end UI.
|
2014-08-06 22:42:09 +11:00
|
|
|
*/
|
|
|
|
public $isHidden = false;
|
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
/**
|
2017-04-24 13:38:19 +02:00
|
|
|
* @var string Icon of the plugin that defines the component.
|
2014-05-14 23:24:20 +10:00
|
|
|
* This field is used by the CMS internally.
|
|
|
|
*/
|
|
|
|
public $pluginIcon;
|
|
|
|
|
2014-06-26 17:09:25 +11:00
|
|
|
/**
|
|
|
|
* @var string Component CSS class name for the back-end page/layout component list.
|
|
|
|
* This field is used by the CMS internally.
|
|
|
|
*/
|
|
|
|
public $componentCssClass;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var boolean Determines whether Inspector can be used with the component.
|
|
|
|
* This field is used by the CMS internally.
|
|
|
|
*/
|
|
|
|
public $inspectorEnabled = true;
|
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
/**
|
|
|
|
* @var string Specifies the component directory name.
|
|
|
|
*/
|
|
|
|
protected $dirName;
|
|
|
|
|
|
|
|
/**
|
2015-10-16 16:30:26 +02:00
|
|
|
* @var \Cms\Classes\Controller Controller object.
|
2014-05-14 23:24:20 +10:00
|
|
|
*/
|
|
|
|
protected $controller;
|
|
|
|
|
|
|
|
/**
|
2015-10-16 16:30:26 +02:00
|
|
|
* @var \Cms\Classes\PageCode Page object object.
|
2014-05-14 23:24:20 +10:00
|
|
|
*/
|
|
|
|
protected $page;
|
|
|
|
|
2014-05-25 00:57:10 +10:00
|
|
|
/**
|
2014-12-16 15:41:50 +11:00
|
|
|
* @var array A collection of external property names used by this component.
|
2014-05-25 00:57:10 +10:00
|
|
|
*/
|
2014-12-16 15:41:50 +11:00
|
|
|
protected $externalPropertyNames = [];
|
2014-05-25 00:57:10 +10:00
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
/**
|
|
|
|
* Component constructor. Takes in the page or layout code section object
|
|
|
|
* and properties set by the page or layout.
|
2015-10-16 16:30:26 +02:00
|
|
|
* @param null|CodeBase $cmsObject
|
|
|
|
* @param array $properties
|
2014-05-14 23:24:20 +10:00
|
|
|
*/
|
|
|
|
public function __construct(CodeBase $cmsObject = null, $properties = [])
|
|
|
|
{
|
|
|
|
if ($cmsObject !== null) {
|
2015-06-17 18:50:51 +10:00
|
|
|
$this->page = $cmsObject;
|
2014-05-14 23:24:20 +10:00
|
|
|
$this->controller = $cmsObject->controller;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->properties = $this->validateProperties($properties);
|
|
|
|
|
|
|
|
$className = Str::normalizeClassName(get_called_class());
|
|
|
|
$this->dirName = strtolower(str_replace('\\', '/', $className));
|
2015-02-17 20:58:38 +11:00
|
|
|
$this->assetPath = Config::get('cms.pluginsPath', '/plugins').dirname(dirname($this->dirName));
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
parent::__construct();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns information about this component, including name and description.
|
|
|
|
*/
|
|
|
|
abstract public function componentDetails();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the absolute component path.
|
|
|
|
*/
|
|
|
|
public function getPath()
|
|
|
|
{
|
2015-05-16 09:29:27 +10:00
|
|
|
return plugins_path() . $this->dirName;
|
|
|
|
}
|
|
|
|
|
2014-05-24 21:59:30 +10:00
|
|
|
/**
|
|
|
|
* Executed when this component is first initialized, before AJAX requests.
|
|
|
|
*/
|
2014-10-11 01:22:03 +02:00
|
|
|
public function init()
|
|
|
|
{
|
|
|
|
}
|
2014-05-24 21:59:30 +10:00
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
/**
|
2017-04-24 13:38:19 +02:00
|
|
|
* Executed when this component is bound to a page or layout, part of
|
2014-05-24 22:03:20 +10:00
|
|
|
* the page life cycle.
|
2014-05-14 23:24:20 +10:00
|
|
|
*/
|
2014-10-11 01:22:03 +02:00
|
|
|
public function onRun()
|
|
|
|
{
|
|
|
|
}
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2014-05-22 20:27:44 +10:00
|
|
|
/**
|
|
|
|
* Executed when this component is rendered on a page or layout.
|
|
|
|
*/
|
2014-10-11 01:22:03 +02:00
|
|
|
public function onRender()
|
|
|
|
{
|
|
|
|
}
|
2014-05-22 20:27:44 +10:00
|
|
|
|
2015-01-03 15:15:57 +11:00
|
|
|
/**
|
|
|
|
* Renders a requested partial in context of this component,
|
|
|
|
* see Cms\Classes\Controller@renderPartial for usage.
|
|
|
|
*/
|
|
|
|
public function renderPartial()
|
|
|
|
{
|
|
|
|
$this->controller->setComponentContext($this);
|
2015-08-30 11:56:44 +10:00
|
|
|
$result = call_user_func_array([$this->controller, 'renderPartial'], func_get_args());
|
|
|
|
$this->controller->setComponentContext(null);
|
|
|
|
return $result;
|
2015-01-03 15:15:57 +11:00
|
|
|
}
|
|
|
|
|
2015-01-03 12:51:09 +11:00
|
|
|
/**
|
|
|
|
* Executes the event cycle when running an AJAX handler.
|
|
|
|
* @return boolean Returns true if the handler was found. Returns false otherwise.
|
|
|
|
*/
|
|
|
|
public function runAjaxHandler($handler)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Extensibility
|
|
|
|
*/
|
2016-12-10 09:02:06 +11:00
|
|
|
if ($event = $this->fireSystemEvent('cms.component.beforeRunAjaxHandler', [$handler])) {
|
2015-01-03 12:51:09 +11:00
|
|
|
return $event;
|
|
|
|
}
|
|
|
|
|
|
|
|
$result = $this->$handler();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Extensibility
|
|
|
|
*/
|
2016-12-10 09:02:06 +11:00
|
|
|
if ($event = $this->fireSystemEvent('cms.component.runAjaxHandler', [$handler, $result])) {
|
2015-01-03 12:51:09 +11:00
|
|
|
return $event;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2014-12-16 15:41:50 +11:00
|
|
|
//
|
|
|
|
// External properties
|
|
|
|
//
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Description on how to access external property names.
|
|
|
|
*
|
|
|
|
* # When
|
|
|
|
* pageNumber = "7"
|
|
|
|
* $this->propertyName('pageNumber'); // Returns NULL
|
|
|
|
* $this->paramName('pageNumber'); // Returns NULL
|
|
|
|
*
|
|
|
|
* # When
|
|
|
|
* pageNumber = "{{ :page }}"
|
|
|
|
*
|
|
|
|
* $this->propertyName('pageNumber'); // Returns ":page"
|
|
|
|
* $this->paramName('pageNumber'); // Returns "page"
|
|
|
|
*
|
|
|
|
* # When
|
|
|
|
* pageNumber = "{{ page }}"
|
|
|
|
*
|
|
|
|
* $this->propertyName('pageNumber'); // Returns "page"
|
|
|
|
* $this->paramName('pageNumber'); // Returns NULL
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets names used by external properties.
|
|
|
|
* @param array $names The key should be the property name,
|
|
|
|
* the value should be the external property name.
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function setExternalPropertyNames(array $names)
|
|
|
|
{
|
|
|
|
$this->externalPropertyNames = $names;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets an external property name.
|
|
|
|
* @param string $name Property name
|
|
|
|
* @param string $extName External property name
|
2015-10-06 00:26:29 +02:00
|
|
|
* @return string
|
2014-12-16 15:41:50 +11:00
|
|
|
*/
|
|
|
|
public function setExternalPropertyName($name, $extName)
|
|
|
|
{
|
|
|
|
return $this->externalPropertyNames[$name] = $extName;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the external property name when the property value is an external property reference.
|
|
|
|
* Otherwise the default value specified is returned.
|
|
|
|
* @param string $name The property name
|
|
|
|
* @param mixed $default
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function propertyName($name, $default = null)
|
|
|
|
{
|
|
|
|
return array_get($this->externalPropertyNames, $name, $default);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the external property name when the property value is a routing parameter reference.
|
|
|
|
* Otherwise the default value specified is returned.
|
|
|
|
* @param string $name The property name
|
|
|
|
* @param mixed $default
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function paramName($name, $default = null)
|
|
|
|
{
|
|
|
|
if (($extName = $this->propertyName($name)) && substr($extName, 0, 1) == ':') {
|
|
|
|
return substr($extName, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $default;
|
|
|
|
}
|
2015-06-17 18:50:51 +10:00
|
|
|
|
|
|
|
//
|
|
|
|
// Magic methods
|
|
|
|
//
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dynamically handle calls into the controller instance.
|
|
|
|
* @param string $method
|
|
|
|
* @param array $parameters
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
public function __call($method, $parameters)
|
|
|
|
{
|
2016-02-13 15:23:53 +11:00
|
|
|
try {
|
2017-05-16 07:24:07 +10:00
|
|
|
return parent::__call($method, $parameters);
|
2015-06-17 18:50:51 +10:00
|
|
|
}
|
2016-02-13 15:23:53 +11:00
|
|
|
catch (BadMethodCallException $ex) {}
|
2015-06-17 18:50:51 +10:00
|
|
|
|
|
|
|
if (method_exists($this->controller, $method)) {
|
|
|
|
return call_user_func_array([$this->controller, $method], $parameters);
|
|
|
|
}
|
|
|
|
|
2016-02-13 15:23:53 +11:00
|
|
|
throw new BadMethodCallException(Lang::get('cms::lang.component.method_not_found', [
|
2015-06-17 18:50:51 +10:00
|
|
|
'name' => get_class($this),
|
|
|
|
'method' => $method
|
|
|
|
]));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the component's alias, used by __SELF__
|
|
|
|
*/
|
|
|
|
public function __toString()
|
|
|
|
{
|
|
|
|
return $this->alias;
|
|
|
|
}
|
2014-10-11 01:22:03 +02:00
|
|
|
}
|