Class luya\cms\admin\importers\CmslayoutImporter
| Inheritance | luya\cms\admin\importers\CmslayoutImporter » luya\console\Importer » yii\base\BaseObject | 
|---|---|
| Implements | yii\base\Configurable | 
| Available since version | 1.0.0 | 
| Source Code | https://github.com/luyadev/luya-module-cms/blob/master/src/admin/importers/CmslayoutImporter.php | 
CMS Layouts Importer.
Import cmslayout files from the folder and analyise placeholders.
Public Properties
| Property | Type | Description | Defined By | 
|---|---|---|---|
| $defaultPath | luya\cms\admin\importers\CmslayoutImporter | ||
| $ignorePrefix | array | A list of prefix keys which will be skipped. | luya\cms\admin\importers\CmslayoutImporter | 
| $importer | luya\console\interfaces\ImportControllerInterface | Importer object. | luya\console\Importer | 
| $module | luya\base\Module | The module context object. | luya\console\Importer | 
| $queueListPosition | integer | The priority between 0 and 100 where to Import command should be queued. | luya\console\Importer | 
Public Methods
| Method | Description | Defined By | 
|---|---|---|
| __call() | Calls the named method which is not a class method. | yii\base\BaseObject | 
| __construct() | Class constructor containing the importer object from where its called. | luya\console\Importer | 
| __get() | Returns the value of an object property. | yii\base\BaseObject | 
| __isset() | Checks if a property is set, i.e. defined and not null. | yii\base\BaseObject | 
| __set() | Sets value of an object property. | yii\base\BaseObject | 
| __unset() | Sets an object property to null. | yii\base\BaseObject | 
| addLog() | Add something to the output. Wrapper method from importer. | luya\console\Importer | 
| canGetProperty() | Returns a value indicating whether a property can be read. | yii\base\BaseObject | 
| canSetProperty() | Returns a value indicating whether a property can be set. | yii\base\BaseObject | 
| className() | Returns the fully qualified name of this class. | yii\base\BaseObject | 
| comparePlaceholders() | Compare two arrays with each in order to determined whether they have differences or not. | luya\cms\admin\importers\CmslayoutImporter | 
| getImporter() | Returns the import object to use the importers methods. | luya\console\Importer | 
| getModule() | Returns the module object where the command has been found. | luya\console\Importer | 
| hasMethod() | Returns a value indicating whether a method is defined. | yii\base\BaseObject | 
| hasProperty() | Returns a value indicating whether a property is defined. | yii\base\BaseObject | 
| init() | Initializes the object. | yii\base\BaseObject | 
| run() | Each Importer Class must contain a run method. | luya\cms\admin\importers\CmslayoutImporter | 
Protected Methods
| Method | Description | Defined By | 
|---|---|---|
| generateReadableName() | Generate readable name from name. | luya\cms\admin\importers\CmslayoutImporter | 
| getFilesFromFolder() | Get files from a given folder. | luya\cms\admin\importers\CmslayoutImporter | 
| handleLayoutFile() | Assigne saved files into the layoutFiles array defintion. | luya\cms\admin\importers\CmslayoutImporter | 
| importLayoutFile() | Importer the given layout file from a path. | luya\cms\admin\importers\CmslayoutImporter | 
| isValidPlaceholderName() | Verificy if a given string matches the variable rules. | luya\cms\admin\importers\CmslayoutImporter | 
Constants
| Constant | Value | Description | Defined By | 
|---|---|---|---|
| QUEUE_POSITION_FIRST | 0 | luya\console\Importer | |
| QUEUE_POSITION_LAST | 100 | luya\console\Importer | |
| QUEUE_POSITION_MIDDLE | 50 | luya\console\Importer | 
Property Details
A list of prefix keys which will be skipped.
Method Details
Defined in: yii\base\BaseObject::__call()
Calls the named method which is not a class method.
Do not call this method directly as it is a PHP magic method that will be implicitly called when an unknown method is being invoked.
| public mixed __call ( $name, $params ) | ||
| $name | string | 
                                The method name  | 
                        
| $params | array | 
                                Method parameters  | 
                        
| return | mixed | 
                                 The method return value  | 
                        
|---|---|---|
| throws | yii\base\UnknownMethodException | 
                                 when calling unknown method  | 
                        
                public function __call($name, $params)
{
    throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
}
            
        Defined in: luya\console\Importer::__construct()
Class constructor containing the importer object from where its called.
| public void __construct ( luya\console\interfaces\ImportControllerInterface $importer, luya\base\Module $module, $config = [] ) | ||
| $importer | luya\console\interfaces\ImportControllerInterface | 
                                Import Object   | 
                        
| $module | ||
| $config | ||
                public function __construct(ImportControllerInterface $importer, Module $module, $config = [])
{
    $this->_importer = $importer;
    $this->_module = $module;
    
    parent::__construct($config);
}
            
        Defined in: yii\base\BaseObject::__get()
Returns the value of an object property.
Do not call this method directly as it is a PHP magic method that
will be implicitly called when executing $value = $object->property;.
See also __set().
| public mixed __get ( $name ) | ||
| $name | string | 
                                The property name  | 
                        
| return | mixed | 
                                 The property value  | 
                        
|---|---|---|
| throws | yii\base\UnknownPropertyException | 
                                 if the property is not defined  | 
                        
| throws | yii\base\InvalidCallException | 
                                 if the property is write-only  | 
                        
                public function __get($name)
{
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {
        return $this->$getter();
    } elseif (method_exists($this, 'set' . $name)) {
        throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
    }
    throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
}
            
        Defined in: yii\base\BaseObject::__isset()
Checks if a property is set, i.e. defined and not null.
Do not call this method directly as it is a PHP magic method that
will be implicitly called when executing isset($object->property).
Note that if the property is not defined, false will be returned.
| public boolean __isset ( $name ) | ||
| $name | string | 
                                The property name or the event name  | 
                        
| return | boolean | 
                                 Whether the named property is set (not null).  | 
                        
|---|---|---|
                public function __isset($name)
{
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {
        return $this->$getter() !== null;
    }
    return false;
}
            
        Defined in: yii\base\BaseObject::__set()
Sets value of an object property.
Do not call this method directly as it is a PHP magic method that
will be implicitly called when executing $object->property = $value;.
See also __get().
| public void __set ( $name, $value ) | ||
| $name | string | 
                                The property name or the event name  | 
                        
| $value | mixed | 
                                The property value  | 
                        
| throws | yii\base\UnknownPropertyException | 
                                 if the property is not defined  | 
                        
|---|---|---|
| throws | yii\base\InvalidCallException | 
                                 if the property is read-only  | 
                        
                public function __set($name, $value)
{
    $setter = 'set' . $name;
    if (method_exists($this, $setter)) {
        $this->$setter($value);
    } elseif (method_exists($this, 'get' . $name)) {
        throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
    } else {
        throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
    }
}
            
        Defined in: yii\base\BaseObject::__unset()
Sets an object property to null.
Do not call this method directly as it is a PHP magic method that
will be implicitly called when executing unset($object->property).
Note that if the property is not defined, this method will do nothing. If the property is read-only, it will throw an exception.
| public void __unset ( $name ) | ||
| $name | string | 
                                The property name  | 
                        
| throws | yii\base\InvalidCallException | 
                                 if the property is read only.  | 
                        
|---|---|---|
                public function __unset($name)
{
    $setter = 'set' . $name;
    if (method_exists($this, $setter)) {
        $this->$setter(null);
    } elseif (method_exists($this, 'get' . $name)) {
        throw new InvalidCallException('Unsetting read-only property: ' . get_class($this) . '::' . $name);
    }
}
            
        Defined in: luya\console\Importer::addLog()
Add something to the output. Wrapper method from importer.
$this->addLog('new block <ID> have been found and added to database');
                            | public void addLog ( $value ) | ||
| $value | string | 
                                The value to be written for the log output.  | 
                        
                public function addLog($value)
{
    $this->getImporter()->addLog(get_called_class(), $value);
}
            
        Defined in: yii\base\BaseObject::canGetProperty()
Returns a value indicating whether a property can be read.
A property is readable if:
- the class has a getter method associated with the specified name (in this case, property name is case-insensitive);
 - the class has a member variable with the specified name (when 
$checkVarsis true); 
See also canSetProperty().
| public boolean canGetProperty ( $name, $checkVars = true ) | ||
| $name | string | 
                                The property name  | 
                        
| $checkVars | boolean | 
                                Whether to treat member variables as properties  | 
                        
| return | boolean | 
                                 Whether the property can be read  | 
                        
|---|---|---|
                public function canGetProperty($name, $checkVars = true)
{
    return method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name);
}
            
        Defined in: yii\base\BaseObject::canSetProperty()
Returns a value indicating whether a property can be set.
A property is writable if:
- the class has a setter method associated with the specified name (in this case, property name is case-insensitive);
 - the class has a member variable with the specified name (when 
$checkVarsis true); 
See also canGetProperty().
| public boolean canSetProperty ( $name, $checkVars = true ) | ||
| $name | string | 
                                The property name  | 
                        
| $checkVars | boolean | 
                                Whether to treat member variables as properties  | 
                        
| return | boolean | 
                                 Whether the property can be written  | 
                        
|---|---|---|
                public function canSetProperty($name, $checkVars = true)
{
    return method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name);
}
            
        ::class instead.                    
                Defined in: yii\base\BaseObject::className()
Returns the fully qualified name of this class.
| public static string className ( ) | ||
| return | string | 
                                 The fully qualified name of this class.  | 
                        
|---|---|---|
                public static function className()
{
    return get_called_class();
}
            
        Compare two arrays with each in order to determined whether they have differences or not.
An array must contain the keys placeholders otherwise false is returned too.
| public boolean comparePlaceholders ( $array1, $array2 ) | ||
| $array1 | array | |
| $array2 | array | |
| return | boolean | 
                                 True if the same, false if not the same  | 
                        
|---|---|---|
                public function comparePlaceholders($array1, $array2)
{
    if (!array_key_exists('placeholders', $array1) || !array_key_exists('placeholders', $array2)) {
        return false;
    }
    $a1 = $array1['placeholders'];
    $a2 = $array2['placeholders'];
    if ((is_countable($a1) ? count($a1) : 0) !== (is_countable($a2) ? count($a2) : 0)) {
        return false;
    }
    foreach ($a1 as $key => $holder) {
        if (!array_key_exists($key, $a2)) {
            return false;
        }
        foreach ($holder as $var => $value) {
            if ($var == "label") {
                continue;
            }
            if (!array_key_exists($var, $a2[$key])) {
                return false;
            }
            if ($value != $a2[$key][$var]) {
                return false;
            }
        }
    }
    return true;
}
            
        Generate readable name from name.
| protected string generateReadableName ( $name ) | ||
| $name | string | |
                protected function generateReadableName($name)
{
    return Inflector::humanize(Inflector::camel2words($name));
}
            
        Get files from a given folder.
| protected array getFilesFromFolder ( $folderPath ) | ||
| $folderPath | string | |
                protected function getFilesFromFolder($folderPath)
{
    return FileHelper::findFiles($folderPath, [
        'recursive' => false,
        'caseSensitive' => false,
        'only' => ['*.php'],
        'filter' => fn ($path) => in_array(substr(basename($path), 0, 1), $this->ignorePrefix) ? false : null]);
}
            
        Defined in: luya\console\Importer::getImporter()
Returns the import object to use the importers methods.
| public luya\console\interfaces\ImportControllerInterface getImporter ( ) | ||
| return | luya\console\interfaces\ImportControllerInterface | 
                                 The importer object.  | 
                        
|---|---|---|
                public function getImporter()
{
    return $this->_importer;
}
            
        Defined in: luya\console\Importer::getModule()
Returns the module object where the command has been found.
| public luya\base\Module getModule ( ) | 
                public function getModule()
{
    return $this->_module;
}
            
        Assigne saved files into the layoutFiles array defintion.
| protected void handleLayoutFile ( &$layoutFiles, $path, $themeName = null ) | ||
| $layoutFiles | array | |
| $path | string | |
| $themeName | string | |
                protected function handleLayoutFile(&$layoutFiles, $path, $themeName = null)
{
    $aliased = Yii::getAlias($path, false);
    $filePath = $aliased ?: $path;
    if (is_dir($filePath)) {
        foreach ($this->getFilesFromFolder($filePath) as $file) {
            $handler = $this->importLayoutFile($file, $path, $themeName);
            if ($handler) {
                $layoutFiles[] = $handler;
            }
        }
    } else {
        $handler = $this->importLayoutFile($filePath, $path, $themeName);
        if ($handler) {
            $layoutFiles[] = $handler;
        }
    }
}
            
        Defined in: yii\base\BaseObject::hasMethod()
Returns a value indicating whether a method is defined.
The default implementation is a call to php function method_exists().
You may override this method when you implemented the php magic method __call().
| public boolean hasMethod ( $name ) | ||
| $name | string | 
                                The method name  | 
                        
| return | boolean | 
                                 Whether the method is defined  | 
                        
|---|---|---|
                public function hasMethod($name)
{
    return method_exists($this, $name);
}
            
        Defined in: yii\base\BaseObject::hasProperty()
Returns a value indicating whether a property is defined.
A property is defined if:
- the class has a getter or setter method associated with the specified name (in this case, property name is case-insensitive);
 - the class has a member variable with the specified name (when 
$checkVarsis true); 
See also:
| public boolean hasProperty ( $name, $checkVars = true ) | ||
| $name | string | 
                                The property name  | 
                        
| $checkVars | boolean | 
                                Whether to treat member variables as properties  | 
                        
| return | boolean | 
                                 Whether the property is defined  | 
                        
|---|---|---|
                public function hasProperty($name, $checkVars = true)
{
    return $this->canGetProperty($name, $checkVars) || $this->canSetProperty($name, false);
}
            
        Importer the given layout file from a path.
| protected string importLayoutFile ( $file, $aliased, $themeName = null ) | ||
| $file | string | 
                                The path to the layout file.  | 
                        
| $aliased | ||
| $themeName | ||
| throws | luya\Exception | |
|---|---|---|
                protected function importLayoutFile($file, $aliased, $themeName = null)
{
    if (!file_exists($file)) {
        return false;
    }
    $fileinfo = FileHelper::getFileInfo($file);
    $baseName = $fileinfo->name . '.' . $fileinfo->extension;
    $fileBaseName = $aliased . DIRECTORY_SEPARATOR . $baseName;
    $json = false;
    if (file_exists($fileinfo->sourceFilename. '.json')) {
        $json = FileHelper::getFileContent($fileinfo->sourceFilename. '.json');
        try {
            if ($json) {
                $json = Json::decode($json);
                // the rows column defines the placeholders
                // if the rows column does not exists fail back to normal layout processing
                if (isset($json['rows'])) {
                    $json = $json['rows'];
                } else {
                    $json = false;
                }
            }
        } catch (\Exception $e) {
            $json = false;
        }
    }
    $readableFileName = $this->generateReadableName($fileinfo->name);
    if ($themeName) {
        $readableFileName = $this->generateReadableName($themeName) . ' - ' . $readableFileName;
    }
    $content = file_get_contents($file);
    preg_match_all("/placeholders\[[\'\"](.*?)[\'\"]\]/", $content, $results);
    if (!$json) {
        $placeholder = [];
        foreach (array_unique($results[1]) as $holderName) {
            if (!$this->isValidPlaceholderName($holderName)) {
                throw new Exception("Wrong variable name detected '".$holderName."'. Special chars are not allowed in placeholder variables, allowed chars are a-zA-Z0-9");
            }
            $placeholder[] = ['label' => $this->generateReadableName($holderName), 'var' => $holderName];
        }
        $_placeholders = ['placeholders' => [$placeholder]];
    } else {
        $_placeholders = ['placeholders' => $json];
    }
    $layoutItem = Layout::find()->where(['or', ['view_file' => $fileBaseName], ['view_file' => $baseName]])->one();
    if ($layoutItem) {
        $match = $this->comparePlaceholders($_placeholders, Json::decode($layoutItem->json_config, ));
        $matchRevert = $this->comparePlaceholders(Json::decode($layoutItem->json_config), $_placeholders);
        if ($match && $matchRevert) {
            $layoutItem->updateAttributes([
                'name' => $readableFileName,
                'view_file' => $fileBaseName,
            ]);
        } else {
            $layoutItem->updateAttributes([
                'name' => $readableFileName,
                'view_file' => $fileBaseName,
                'json_config' => Json::encode($_placeholders),
            ]);
            $this->addLog('Existing file '.$readableFileName.' updated.');
        }
        return $layoutItem->id;
    }
    // add item into the database table
    $data = new Layout();
    $data->scenario = 'restcreate';
    $data->setAttributes([
        'name' => $readableFileName,
        'view_file' => $fileBaseName,
        'json_config' => Json::encode($_placeholders),
    ]);
    if (!$data->save()) {
        $this->addLog('Error while adding layout file: ' . var_export($data->getErrors(), true));
        return;
    }
    $this->addLog('New file '.$readableFileName.' found and registered.');
    return $data->id;
}
            
        Defined in: yii\base\BaseObject::init()
Initializes the object.
This method is invoked at the end of the constructor after the object is initialized with the given configuration.
| public void init ( ) | 
                public function init()
{
}
            
        Verificy if a given string matches the variable rules.
| protected boolean isValidPlaceholderName ( $chars ) | ||
| $chars | string | |
                protected function isValidPlaceholderName($chars)
{
    if (preg_match('/[^a-zA-Z0-9]+/', $chars, $matches) == 1) {
        return false;
    }
    return true;
}
            
        Each Importer Class must contain a run method.
| public void run ( ) | 
                public function run()
{
    $layoutFiles = [];
    // get and import cmslayouts from @app/views/cmslayouts path
    $this->handleLayoutFile($layoutFiles, $this->defaultPath);
    // import files from the cmsadmin module $cmsLayouts property.
    foreach ((array) $this->module->cmsLayouts as $layoutDefintion) {
        $this->handleLayoutFile($layoutFiles, $layoutDefintion);
    }
    foreach (Yii::$app->themeManager->getThemes() as $themeConfig) {
        $this->handleLayoutFile($layoutFiles, $themeConfig->getViewPath() . DIRECTORY_SEPARATOR . 'cmslayouts', $themeConfig->name);
    }
    // remove all view files not found somewhere ...
    foreach (Layout::find()->where(['not in', 'id', $layoutFiles])->all() as $layoutItem) {
        $this->addLog('remove cms layout with id #' . $layoutItem->id);
        $layoutItem->delete();
    }
    return $this->addLog("cms layout importer finished with ".(is_countable($layoutFiles) ? count($layoutFiles) : 0) . " layout files.");
}