Class yii\sphinx\gii\model\Generator
Inheritance | yii\sphinx\gii\model\Generator » yii\gii\Generator |
---|---|
Available since extension's version | 2.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.
Public Properties
Public Methods
Protected 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
Method Details
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',
]);
}
public void autoCompleteData ( ) |
public function autoCompleteData()
{
$db = $this->getDbConnection();
if ($db !== null) {
return [
'indexName' => function () use ($db) {
return $db->getSchema()->getIndexNames();
},
];
} else {
return [];
}
}
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;
}
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, '_');
}
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;
}
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;
}
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;
}
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);
}
public void getDescription ( ) |
public function getDescription()
{
return 'This generator generates an ActiveRecord class for the specified Sphinx index.';
}
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;
}
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>.',
]);
}
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],
]);
}
public void stickyAttributes ( ) |
public function stickyAttributes()
{
return array_merge(parent::stickyAttributes(), ['ns', 'db', 'baseClass']);
}
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.');
}
}
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;
}
}
}
}
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.');
}
}
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.');
}
}