Decouple Asset object

Add extensible to ComponentPartial
This commit is contained in:
Samuel Georges 2016-03-12 10:17:07 +11:00
parent c34f72b821
commit 1bc647f978
3 changed files with 232 additions and 26 deletions

View File

@ -1,7 +1,13 @@
<?php namespace Cms\Classes;
use File;
use Lang;
use Config;
use Cms\Classes\Theme;
use Cms\Helpers\File as FileHelper;
use October\Rain\Extension\Extendable;
use ApplicationException;
use ValidationException;
/**
* The CMS theme asset file class.
@ -9,26 +15,239 @@ use Cms\Classes\Theme;
* @package october\cms
* @author Alexey Bobkov, Samuel Georges
*/
class Asset extends CmsObject
class Asset extends Extendable
{
/**
* @var \Cms\Classes\Theme A reference to the CMS theme containing the object.
*/
protected $theme;
/**
* @var string The container name inside the theme.
*/
protected $dirName = 'assets';
/**
* @var string Specifies the file name corresponding the CMS object.
*/
public $fileName;
/**
* @var string Specifies the file name, the CMS object was loaded from.
*/
protected $originalFileName = null;
/**
* @var string Last modified time.
*/
public $mtime;
/**
* @var string The entire file content.
*/
public $content;
/**
* @var array The attributes that are mass assignable.
*/
protected $fillable = [
'fileName',
'content'
];
/**
* @var array Allowable file extensions.
*/
protected $allowedExtensions = [];
/**
* @var bool Indicates if the model exists.
*/
public $exists = false;
/**
* Creates an instance of the object and associates it with a CMS theme.
* @param \Cms\Classes\Theme $theme Specifies the theme the object belongs to.
*/
public function __construct(Theme $theme)
{
parent::__construct($theme);
$this->theme = $theme;
self::$allowedExtensions = self::getEditableExtensions();
$this->allowedExtensions = self::getEditableExtensions();
parent::__construct();
}
/**
* Sets path for new asset files created from the back-end.
* @param string $path Specifies the path.
* Loads the object from a file.
* This method is used in the CMS back-end. It doesn't use any caching.
* @param \Cms\Classes\Theme $theme Specifies the theme 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 function setInitialPath($path)
public static function load($theme, $fileName)
{
$this->fileName = $path;
return (new static($theme))->find($fileName);
}
/**
* Find a single template by its file name.
*
* @param string $fileName
* @return mixed|static
*/
public function find($fileName)
{
$filePath = $this->getFilePath($fileName);
if (!File::isFile($filePath)) {
return null;
}
if (($content = @File::get($filePath)) === false) {
return null;
}
$this->fileName = $fileName;
$this->originalFileName = $fileName;
$this->mtime = File::lastModified($filePath);
$this->content = $content;
$this->exists = true;
return $this;
}
/**
* Sets the object attributes.
* @param array $attributes A list of attributes to set.
*/
public function fill(array $attributes)
{
foreach ($attributes as $key => $value) {
if (!in_array($key, $this->fillable)) {
throw new ApplicationException(Lang::get(
'cms::lang.cms_object.invalid_property',
['name' => $key]
));
}
$this->$key = $value;
}
}
/**
* Saves the object to the disk.
*/
public function save()
{
$this->validateFileName();
$fullPath = $this->getFilePath();
if (File::isFile($fullPath) && $this->originalFileName !== $this->fileName) {
throw new ApplicationException(Lang::get(
'cms::lang.cms_object.file_already_exists',
['name'=>$this->fileName]
));
}
$dirPath = $this->theme->getPath().'/'.$this->dirName;
if (!file_exists($dirPath) || !is_dir($dirPath)) {
if (!File::makeDirectory($dirPath, 0777, true, true)) {
throw new ApplicationException(Lang::get(
'cms::lang.cms_object.error_creating_directory',
['name'=>$dirPath]
));
}
}
if (($pos = strpos($this->fileName, '/')) !== false) {
$dirPath = dirname($fullPath);
if (!is_dir($dirPath) && !File::makeDirectory($dirPath, 0777, true, true)) {
throw new ApplicationException(Lang::get(
'cms::lang.cms_object.error_creating_directory',
['name'=>$dirPath]
));
}
}
$newFullPath = $fullPath;
if (@File::put($fullPath, $this->content) === false) {
throw new ApplicationException(Lang::get(
'cms::lang.cms_object.error_saving',
['name'=>$this->fileName]
));
}
if (strlen($this->originalFileName) && $this->originalFileName !== $this->fileName) {
$fullPath = $this->getFilePath($this->originalFileName);
if (File::isFile($fullPath)) {
@unlink($fullPath);
}
}
clearstatcache();
$this->mtime = @File::lastModified($newFullPath);
$this->originalFileName = $this->fileName;
$this->exists = true;
}
/**
* Validate the supplied filename, extension and path.
* @param string $fileName
*/
protected function validateFileName($fileName = null)
{
if ($fileName === null) {
$fileName = $this->fileName;
}
$fileName = trim($fileName);
if (!strlen($fileName)) {
throw new ValidationException(['fileName' =>
Lang::get('cms::lang.cms_object.file_name_required', [
'allowed' => implode(', ', $this->allowedExtensions),
'invalid' => pathinfo($fileName, PATHINFO_EXTENSION)
])
]);
}
if (!FileHelper::validateExtension($fileName, $this->allowedExtensions, false)) {
throw new ValidationException(['fileName' =>
Lang::get('cms::lang.cms_object.invalid_file_extension', [
'allowed' => implode(', ', $this->allowedExtensions),
'invalid' => pathinfo($fileName, PATHINFO_EXTENSION)
])
]);
}
}
/**
* Returns the file name.
* @return string
*/
public function getFileName()
{
return $this->fileName;
}
/**
* Returns the absolute file path.
* @param string $fileName Specifies the file name to return the path to.
* @return string
*/
public function getFilePath($fileName = null)
{
if ($fileName === null) {
$fileName = $this->fileName;
}
return $this->theme->getPath().'/'.$this->dirName.'/'.$fileName;
}
/**
@ -48,21 +267,4 @@ class Asset extends CmsObject
return $configTypes;
}
/**
* Returns the directory name corresponding to the object type.
* For pages the directory name is "pages", for layouts - "layouts", etc.
* @return string
*/
public static function getObjectTypeDirName()
{
return 'assets';
}
/**
* {@inheritDoc}
*/
protected static function getMaxAllowedPathNesting()
{
return null;
}
}

View File

@ -4,6 +4,8 @@ use File;
use Lang;
use Cms\Contracts\CmsObject as CmsObjectContract;
use Cms\Helpers\File as FileHelper;
use October\Rain\Extension\Extendable;
use ApplicationException;
/**
* The CMS component partial class. These objects are read-only.
@ -11,7 +13,7 @@ use Cms\Helpers\File as FileHelper;
* @package october\cms
* @author Alexey Bobkov, Samuel Georges
*/
class ComponentPartial implements CmsObjectContract
class ComponentPartial extends Extendable implements CmsObjectContract
{
/**
* @var \Cms\Classes\ComponentBase A reference to the CMS component containing the object.
@ -57,6 +59,8 @@ class ComponentPartial implements CmsObjectContract
public function __construct(ComponentBase $component)
{
$this->component = $component;
parent::__construct();
}
/**

View File

@ -202,7 +202,7 @@ class Index extends Controller
$template = $this->createTemplate($type);
if ($type == 'asset') {
$template->setInitialPath($this->widget->assetList->getCurrentRelativePath());
$template->fileName = $this->widget->assetList->getCurrentRelativePath();
}
$widget = $this->makeTemplateFormWidget($type, $template);