Decouple ComponentPartial from CmsObject

This commit is contained in:
Samuel Georges 2016-03-09 21:01:57 +11:00
parent d65bc5c2ad
commit c34f72b821
3 changed files with 181 additions and 26 deletions

View File

@ -13,6 +13,7 @@ use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use ArrayAccess;
use Exception;
use Cms\Contracts\CmsObject as CmsObjectContract;
/**
* This is a base class for all CMS objects - content files, pages, partials and layouts.
@ -21,7 +22,7 @@ use Exception;
* @package october\cms
* @author Alexey Bobkov, Samuel Georges
*/
class CmsObject extends Extendable implements ArrayAccess
class CmsObject extends Extendable implements ArrayAccess, CmsObjectContract
{
/**
* @var string Specifies the file name corresponding the CMS object.

View File

@ -1,20 +1,55 @@
<?php namespace Cms\Classes;
use File;
use Lang;
use Cms\Contracts\CmsObject as CmsObjectContract;
use Cms\Helpers\File as FileHelper;
/**
* The CMS component partial class.
* The CMS component partial class. These objects are read-only.
*
* @package october\cms
* @author Alexey Bobkov, Samuel Georges
*/
class ComponentPartial extends CmsObject
class ComponentPartial implements CmsObjectContract
{
/**
* @var \Cms\Classes\ComponentBase A reference to the CMS component containing the object.
*/
protected $component;
/**
* @var string The component partial file name.
*/
protected $fileName;
/**
* @var string Last modified time.
*/
protected $mtime;
/**
* @var string Partial content.
*/
protected $content;
/**
* @var int The maximum allowed path nesting level. The default value is 2,
* meaning that files can only exist in the root directory, or in a
* subdirectory. Set to null if any level is allowed.
*/
protected $maxNesting = 2;
/**
* @var array Allowable file extensions.
*/
protected $allowedExtensions = ['htm'];
/**
* @var string Default file extension.
*/
protected $defaultExtension = 'htm';
/**
* Creates an instance of the object and associates it with a CMS component.
* @param \Cms\Classes\ComponentBase $component Specifies the component the object belongs to.
@ -25,32 +60,153 @@ class ComponentPartial extends CmsObject
}
/**
* Returns the directory name corresponding to the object type.
* For pages the directory name is "pages", for layouts - "layouts", etc.
* @return string
* Loads the object from a file.
* This method is used in the CMS back-end. It doesn't use any caching.
* @param Cms\Classes\ComponentBase $component Specifies the component the object belongs to.
* @param string $fileName Specifies the file name, with the extension.
* The file name can contain only alphanumeric symbols, dashes and dots.
* @return mixed Returns a CMS object instance or null if the object wasn't found.
*/
public static function getObjectTypeDirName()
public static function load($component, $fileName)
{
return 'partials';
return (new static($component))->find($fileName);
}
/**
* Returns the full path to the template file corresponding to this object.
* There is not much point caching a component partial, so this behavior
* reverts to a regular load call.
* @param Cms\Classes\ComponentBase $component
* @param string $fileName
* @return mixed
*/
public static function loadCached($component, $fileName)
{
return static::load($component, $fileName);
}
/**
* Find a single template by its file name.
*
* @param string $fileName
* @return mixed|static
*/
public function find($fileName)
{
$fileName = $this->validateFileName($fileName);
$filePath = $this->getFilePath($fileName);
if (!File::isFile($filePath)) {
return null;
}
if (($content = @File::get($filePath)) === false) {
return null;
}
$this->fileName = $fileName;
$this->mtime = File::lastModified($filePath);
$this->content = $content;
return $this;
}
/**
* Returns true if the specific component contains a matching partial.
* @param \Cms\Classes\ComponentBase $component Specifies a component the file belongs to.
* @param string $fileName Specifies the file name to check.
* @return bool
*/
public static function check(ComponentBase $component, $fileName)
{
$partial = new static($component);
$filePath = $partial->getFilePath($fileName);
if (!strlen(File::extension($filePath))) {
$filePath .= '.'.$partial->getDefaultExtension();
}
return File::isFile($filePath);
}
/**
* Checks the supplied file name for validity.
* @param string $fileName
* @return string
*/
public function getFullPath()
protected function validateFileName($fileName)
{
return static::getFilePath($this->component, $this->fileName);
if (!FileHelper::validatePath($fileName, $this->maxNesting)) {
throw new ApplicationException(Lang::get('cms::lang.cms_object.invalid_file', ['name'=>$fileName]));
}
if (!strlen(File::extension($fileName))) {
$fileName .= '.'.$this->defaultExtension;
}
return $fileName;
}
/**
* Returns the file content.
* @return string
*/
public function getContent()
{
return $this->content;
}
/**
* Returns the Twig content string.
* @return string
*/
public function getTwigContent()
{
return $this->content;
}
/**
* Returns the file name.
* @return string
*/
public function getFileName()
{
return $this->fileName;
}
/**
* Returns the default extension used by this template.
* @return string
*/
public function getDefaultExtension()
{
return $this->defaultExtension;
}
/**
* Returns the file name without the extension.
* @return string
*/
public function getBaseFileName()
{
$pos = strrpos($this->fileName, '.');
if ($pos === false) {
return $this->fileName;
}
return substr($this->fileName, 0, $pos);
}
/**
* Returns the absolute file path.
* @param \Cms\Classes\ComponentBase $component Specifies a component the file belongs to.
* @param string$fileName Specifies the file name to return the path to.
* @param string $fileName Specifies the file name to return the path to.
* @return string
*/
public static function getFilePath($component, $fileName)
public function getFilePath($fileName = null)
{
if ($fileName === null) {
$fileName = $this->fileName;
}
$component = $this->component;
$path = $component->getPath().'/'.$fileName;
/*
@ -66,4 +222,12 @@ class ComponentPartial extends CmsObject
return $path;
}
// @deprecated This method should be removed globally
// remove if year >= 2016
public function getFullPath()
{
return $this->getFilePath();
}
}

View File

@ -1276,23 +1276,13 @@ class Controller
public function findComponentByPartial($partial)
{
foreach ($this->page->components as $component) {
$fileName = ComponentPartial::getFilePath($component, $partial);
if (!strlen(File::extension($fileName))) {
$fileName .= '.htm';
}
if (File::isFile($fileName)) {
if (ComponentPartial::check($component, $partial)) {
return $component;
}
}
foreach ($this->layout->components as $component) {
$fileName = ComponentPartial::getFilePath($component, $partial);
if (!strlen(File::extension($fileName))) {
$fileName .= '.htm';
}
if (File::isFile($fileName)) {
if (ComponentPartial::check($component, $partial)) {
return $component;
}
}