202 lines
5.5 KiB
PHP
202 lines
5.5 KiB
PHP
|
<?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;
|
||
|
}
|
||
|
}
|