marc-leopold/cms/plugins/rainlab/builder/classes/ModelYamlModel.php

202 lines
5.5 KiB
PHP
Raw Permalink Normal View History

2019-02-25 14:56:59 +00:00
<?php namespace RainLab\Builder\Classes;
use DirectoryIterator;
use SystemException;
use Exception;
use Lang;
use File;
use Yaml;
/**
* A base class for models belonging to databse models (forms, lists, etc.).
*
* @package rainlab\builder
* @author Alexey Bobkov, Samuel Georges
*/
abstract class ModelYamlModel extends YamlModel
{
public $fileName;
protected $modelClassName;
public function fill(array $attributes)
{
parent::fill($attributes);
if (strlen($this->fileName)) {
$this->fileName = $this->addExtension($this->fileName);
}
}
public function setModelClassName($className)
{
if (!preg_match('/^[a-zA-Z]+[0-9a-z\_]*$/', $className)) {
throw new SystemException('Invalid class name: '.$className);
}
$this->modelClassName = $className;
}
public function validate()
{
$this->validationMessages = [
'fileName.required' => Lang::get('rainlab.builder::lang.form.error_file_name_required'),
'fileName.regex' => Lang::get('rainlab.builder::lang.form.error_file_name_invalid')
];
return parent::validate();
}
/**
* Returns a string suitable for displaying in the Builder UI tabs.
*/
public function getDisplayName($nameFallback)
{
$fileName = $this->fileName;
if (substr($fileName, -5) == '.yaml') {
$fileName = substr($fileName, 0, -5);
}
if (!strlen($fileName)) {
$fileName = $nameFallback;
}
return $this->getModelClassName().'/'.$fileName;
}
public static function listModelFiles($pluginCodeObj, $modelClassName)
{
if (!self::validateModelClassName($modelClassName)) {
throw new SystemException('Invalid model class name: '.$modelClassName);
}
$modelDirectoryPath = $pluginCodeObj->toPluginDirectoryPath().'/models/'.strtolower($modelClassName);
$modelDirectoryPath = File::symbolizePath($modelDirectoryPath);
if (!File::isDirectory($modelDirectoryPath)) {
return [];
}
$result = [];
foreach (new DirectoryIterator($modelDirectoryPath) as $fileInfo) {
if (!$fileInfo->isFile() || $fileInfo->getExtension() != 'yaml') {
continue;
}
try {
$fileContents = Yaml::parseFile($fileInfo->getPathname());
}
catch (Exception $ex) {
continue;
}
if (!is_array($fileContents)) {
$fileContents = [];
}
if (!static::validateFileIsModelType($fileContents)) {
continue;
}
$result[] = $fileInfo->getBasename();
}
return $result;
}
public static function getPluginRegistryData($pluginCode, $modelClassName)
{
$pluginCodeObj = new PluginCode($pluginCode);
$classParts = explode('\\', $modelClassName);
if (!$classParts) {
return [];
}
$modelClassName = array_pop($classParts);
if (!self::validateModelClassName($modelClassName)) {
return [];
}
$models = self::listModelFiles($pluginCodeObj, $modelClassName);
$modelDirectoryPath = $pluginCodeObj->toPluginDirectoryPath().'/models/'.strtolower($modelClassName).'/';
$result = [];
foreach ($models as $fileName) {
$fullFilePath = $modelDirectoryPath.$fileName;
$result[$fullFilePath] = $fileName;
}
return $result;
}
public static function getPluginRegistryDataAllRecords($pluginCode)
{
$pluginCodeObj = new PluginCode($pluginCode);
$pluginDirectoryPath = $pluginCodeObj->toPluginDirectoryPath();
$models = ModelModel::listPluginModels($pluginCodeObj);
$result = [];
foreach ($models as $model) {
$modelRecords = self::listModelFiles($pluginCodeObj, $model->className);
$modelDirectoryPath = $pluginDirectoryPath.'/models/'.strtolower($model->className).'/';
foreach ($modelRecords as $fileName) {
$label = $model->className.'/'.$fileName;
$key = $modelDirectoryPath.$fileName;
$result[$key] = $label;
}
}
return $result;
}
public static function validateFileIsModelType($fileContentsArray)
{
return false;
}
protected static function validateModelClassName($modelClassName)
{
return preg_match('/^[A-Z]+[a-zA-Z0-9_]+$/i', $modelClassName);
}
protected function getModelClassName()
{
if ($this->modelClassName === null) {
throw new SystemException('The model class name is not set.');
}
return $this->modelClassName;
}
/**
* Returns a file path to save the model to.
* @return string Returns a path.
*/
protected function getFilePath()
{
$fileName = trim($this->fileName);
if (!strlen($fileName)) {
throw new SystemException('The form model file name is not set.');
}
$fileName = $this->addExtension($fileName);
return $this->getPluginCodeObj()->toPluginDirectoryPath().'/models/'.strtolower($this->getModelClassName()).'/'.$fileName;
}
protected function addExtension($fileName) {
if (substr($fileName, -5) !== '.yaml') {
$fileName .= '.yaml';
}
return $fileName;
}
}