Class yii\sphinx\gii\model\Generator

Inheritanceyii\sphinx\gii\model\Generator » yii\gii\Generator
Available since extension's version2.0
Source Code https://github.com/yiisoft/yii2-sphinx/blob/master/src/gii/model/Generator.php

This generator will generate one or multiple ActiveRecord classes for the specified Sphinx index.

Protected Methods

Hide inherited methods

Method Description Defined By
generateClassName() Generates a class name from the specified table name. yii\sphinx\gii\model\Generator
getDbConnection() yii\sphinx\gii\model\Generator
getIndexNames() yii\sphinx\gii\model\Generator

Property Details

Hide inherited properties

$baseClass public property
public $baseClass 'yii\sphinx\ActiveRecord'
$db public property
public $db 'sphinx'
$indexName public property
public $indexName null
$modelClass public property
public $modelClass null
$ns public property
public $ns 'app\models'
$useIndexPrefix public property
public $useIndexPrefix false

Method Details

Hide inherited methods

attributeLabels() public method

public void attributeLabels ( )

                public function attributeLabels()
{
    return array_merge(parent::attributeLabels(), [
        'ns' => 'Namespace',
        'db' => 'Sphinx Connection ID',
        'indexName' => 'Index Name',
        'modelClass' => 'Model Class',
        'baseClass' => 'Base Class',
    ]);
}

            
autoCompleteData() public method

public void autoCompleteData ( )

                public function autoCompleteData()
{
    $db = $this->getDbConnection();
    if ($db !== null) {
        return [
            'indexName' => function () use ($db) {
                return $db->getSchema()->getIndexNames();
            },
        ];
    } else {
        return [];
    }
}

            
generate() public method

public void generate ( )

                public function generate()
{
    $files = [];
    $db = $this->getDbConnection();
    foreach ($this->getIndexNames() as $indexName) {
        $className = $this->generateClassName($indexName);
        $indexSchema = $db->getIndexSchema($indexName);
        $params = [
            'indexName' => $indexName,
            'className' => $className,
            'indexSchema' => $indexSchema,
            'labels' => $this->generateLabels($indexSchema),
            'rules' => $this->generateRules($indexSchema),
        ];
        $files[] = new CodeFile(
            Yii::getAlias('@' . str_replace('\\', '/', $this->ns)) . '/' . $className . '.php',
            $this->render('model.php', $params)
        );
    }
    return $files;
}

            
generateClassName() protected method

Generates a class name from the specified table name.

protected string generateClassName ( $indexName )
$indexName string

The table name (which may contain schema prefix)

return string

The generated class name

                protected function generateClassName($indexName)
{
    if (isset($this->_classNames[$indexName])) {
        return $this->_classNames[$indexName];
    }
    if (($pos = strrpos($indexName, '.')) !== false) {
        $indexName = substr($indexName, $pos + 1);
    }
    $db = $this->getDbConnection();
    $patterns = [];
    $patterns[] = "/^{$db->tablePrefix}(.*?)$/";
    $patterns[] = "/^(.*?){$db->tablePrefix}$/";
    if (strpos($this->indexName, '*') !== false) {
        $pattern = $this->indexName;
        if (($pos = strrpos($pattern, '.')) !== false) {
            $pattern = substr($pattern, $pos + 1);
        }
        $patterns[] = '/^' . str_replace('*', '(\w+)', $pattern) . '$/';
    }
    $className = $indexName;
    foreach ($patterns as $pattern) {
        if (preg_match($pattern, $indexName, $matches)) {
            $className = $matches[1];
            break;
        }
    }
    return $this->_classNames[$indexName] = Inflector::id2camel($className, '_');
}

            
generateIndexName() public method

Generates the table name by considering table prefix.

If $useIndexPrefix is false, the table name will be returned without change.

public string generateIndexName ( $indexName )
$indexName string

The table name (which may contain schema prefix)

return string

The generated table name

                public function generateIndexName($indexName)
{
    if (!$this->useIndexPrefix) {
        return $indexName;
    }
    $db = $this->getDbConnection();
    if (preg_match("/^{$db->tablePrefix}(.*?)$/", $indexName, $matches)) {
        $indexName = '{{%' . $matches[1] . '}}';
    } elseif (preg_match("/^(.*?){$db->tablePrefix}$/", $indexName, $matches)) {
        $indexName = '{{' . $matches[1] . '%}}';
    }
    return $indexName;
}

            
generateLabels() public method

Generates the attribute labels for the specified table.

public array generateLabels ( $table )
$table \yii\db\TableSchema

The table schema

return array

The generated attribute labels (name => label)

                public function generateLabels($table)
{
    $labels = [];
    foreach ($table->columns as $column) {
        if (!strcasecmp($column->name, 'id')) {
            $labels[$column->name] = 'ID';
        } else {
            $label = Inflector::camel2words($column->name);
            if (substr_compare($label, ' id', -3, 3, true) === 0) {
                $label = substr($label, 0, -3) . ' ID';
            }
            $labels[$column->name] = $label;
        }
    }
    return $labels;
}

            
generateRules() public method

Generates validation rules for the specified index.

public array generateRules ( $index )
$index yii\sphinx\IndexSchema

The index schema

return array

The generated validation rules

                public function generateRules($index)
{
    $types = [];
    foreach ($index->columns as $column) {
        if ($column->isMva) {
            $types['safe'][] = $column->name;
            continue;
        }
        if ($column->isPrimaryKey) {
            $types['required'][] = $column->name;
            $types['unique'][] = $column->name;
        }
        switch ($column->type) {
            case Schema::TYPE_PK:
            case Schema::TYPE_INTEGER:
            case Schema::TYPE_BIGINT:
                $types['integer'][] = $column->name;
                break;
            case Schema::TYPE_BOOLEAN:
                $types['boolean'][] = $column->name;
                break;
            case Schema::TYPE_FLOAT:
                $types['number'][] = $column->name;
                break;
            case Schema::TYPE_TIMESTAMP:
                $types['safe'][] = $column->name;
                break;
            default: // strings
                $types['string'][] = $column->name;
        }
    }
    $rules = [];
    foreach ($types as $type => $columns) {
        $rules[] = "[['" . implode("', '", $columns) . "'], '$type']";
    }
    return $rules;
}

            
getDbConnection() protected method

protected yii\sphinx\Connection getDbConnection ( )
return yii\sphinx\Connection

The Sphinx connection as specified by $db.

                protected function getDbConnection()
{
    return Yii::$app->get($this->db, false);
}

            
getDescription() public method

public void getDescription ( )

                public function getDescription()
{
    return 'This generator generates an ActiveRecord class for the specified Sphinx index.';
}

            
getIndexNames() protected method

protected array getIndexNames ( )
return array

The index names that match the pattern specified by $indexName.

                protected function getIndexNames()
{
    if ($this->_indexNames !== null) {
        return $this->_indexNames;
    }
    $db = $this->getDbConnection();
    if ($db === null) {
        return [];
    }
    $indexNames = [];
    if (strpos($this->indexName, '*') !== false) {
        $indexNames = $db->getSchema()->getIndexNames();
    } elseif (($index = $db->getIndexSchema($this->indexName, true)) !== null) {
        $indexNames[] = $this->indexName;
        $this->_classNames[$this->indexName] = $this->modelClass;
    }
    return $this->_indexNames = $indexNames;
}

            
getName() public method

public void getName ( )

                public function getName()
{
    return 'Sphinx Model Generator';
}

            
hints() public method

public void hints ( )

                public function hints()
{
    return array_merge(parent::hints(), [
        'ns' => 'This is the namespace of the ActiveRecord class to be generated, e.g., <code>app\models</code>',
        'db' => 'This is the ID of the Sphinx application component.',
        'indexName' => 'This is the name of the Sphinx index that the new ActiveRecord class is associated with, e.g. <code>post</code>.
            The index name may end with asterisk to match multiple table names, e.g. <code>idx_*</code>
            will match indexes, which name starts with <code>idx_</code>. In this case, multiple ActiveRecord classes
            will be generated, one for each matching index name; and the class names will be generated from
            the matching characters. For example, index <code>idx_post</code> will generate <code>Post</code>
            class.',
        'modelClass' => 'This is the name of the ActiveRecord class to be generated. The class name should not contain
            the namespace part as it is specified in "Namespace". You do not need to specify the class name
            if "Index Name" ends with asterisk, in which case multiple ActiveRecord classes will be generated.',
        'baseClass' => 'This is the base class of the new ActiveRecord class. It should be a fully qualified namespaced class name.',
        'useIndexPrefix' => 'This indicates whether the index name returned by the generated ActiveRecord class
            should consider the <code>tablePrefix</code> setting of the Sphinx connection. For example, if the
            index name is <code>idx_post</code> and <code>tablePrefix=idx_</code>, the ActiveRecord class
            will return the table name as <code>{{%post}}</code>.',
    ]);
}

            
requiredTemplates() public method

public void requiredTemplates ( )

                public function requiredTemplates()
{
    return ['model.php'];
}

            
rules() public method

public void rules ( )

                public function rules()
{
    return array_merge(parent::rules(), [
        [['db', 'ns', 'indexName', 'modelClass', 'baseClass'], 'filter', 'filter' => 'trim'],
        [['ns'], 'filter', 'filter' => function($value) { return trim($value, '\\'); }],
        [['db', 'ns', 'indexName', 'baseClass'], 'required'],
        [['db', 'modelClass'], 'match', 'pattern' => '/^\w+$/', 'message' => 'Only word characters are allowed.'],
        [['ns', 'baseClass'], 'match', 'pattern' => '/^[\w\\\\]+$/', 'message' => 'Only word characters and backslashes are allowed.'],
        [['indexName'], 'match', 'pattern' => '/^(\w+\.)?([\w\*]+)$/', 'message' => 'Only word characters, and optionally an asterisk and/or a dot are allowed.'],
        [['db'], 'validateDb'],
        [['ns'], 'validateNamespace'],
        [['indexName'], 'validateIndexName'],
        [['modelClass'], 'validateModelClass', 'skipOnEmpty' => false],
        [['baseClass'], 'validateClass', 'params' => ['extends' => ActiveRecord::className()]],
        [['enableI18N'], 'boolean'],
        [['useIndexPrefix'], 'boolean'],
        [['messageCategory'], 'validateMessageCategory', 'skipOnEmpty' => false],
    ]);
}

            
stickyAttributes() public method

public void stickyAttributes ( )

                public function stickyAttributes()
{
    return array_merge(parent::stickyAttributes(), ['ns', 'db', 'baseClass']);
}

            
validateDb() public method

Validates the $db attribute.

public void validateDb ( )

                public function validateDb()
{
    if (!Yii::$app->has($this->db)) {
        $this->addError('db', 'There is no application component named "' . $this->db . '".');
    } elseif (!Yii::$app->get($this->db) instanceof Connection) {
        $this->addError('db', 'The "' . $this->db . '" application component must be a Sphinx connection instance.');
    }
}

            
validateIndexName() public method

Validates the $indexName attribute.

public void validateIndexName ( )

                public function validateIndexName()
{
    if (strpos($this->indexName, '*') !== false && substr_compare($this->indexName, '*', -1, 1)) {
        $this->addError('indexName', 'Asterisk is only allowed as the last character.');
        return;
    }
    $tables = $this->getIndexNames();
    if (empty($tables)) {
        $this->addError('indexName', "Table '{$this->indexName}' does not exist.");
    } else {
        foreach ($tables as $table) {
            $class = $this->generateClassName($table);
            if ($this->isReservedKeyword($class)) {
                $this->addError('indexName', "Table '$table' will generate a class which is a reserved PHP keyword.");
                break;
            }
        }
    }
}

            
validateModelClass() public method

Validates the $modelClass attribute.

public void validateModelClass ( )

                public function validateModelClass()
{
    if ($this->isReservedKeyword($this->modelClass)) {
        $this->addError('modelClass', 'Class name cannot be a reserved PHP keyword.');
    }
    if ((empty($this->indexName) || substr_compare($this->indexName, '*', -1, 1)) && $this->modelClass == '') {
        $this->addError('modelClass', 'Model Class cannot be blank if table name does not end with asterisk.');
    }
}

            
validateNamespace() public method

Validates the $ns attribute.

public void validateNamespace ( )

                public function validateNamespace()
{
    $this->ns = ltrim($this->ns, '\\');
    $path = Yii::getAlias('@' . str_replace('\\', '/', $this->ns), false);
    if ($path === false) {
        $this->addError('ns', 'Namespace must be associated with an existing directory.');
    }
}