1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Created by PhpStorm. |
4
|
|
|
* User: Nikola nb |
5
|
|
|
* Date: 19.10.2014 |
6
|
|
|
* Time: 11:35 ч. |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
namespace nkostadinov\taxonomy\components\terms; |
10
|
|
|
|
11
|
|
|
use nkostadinov\taxonomy\components\interfaces\ITaxonomyTermInterface; |
12
|
|
|
use nkostadinov\taxonomy\models\TaxonomyDef; |
13
|
|
|
use nkostadinov\taxonomy\models\TaxonomyTerms; |
14
|
|
|
use Yii; |
15
|
|
|
use yii\base\Exception; |
16
|
|
|
use yii\base\BaseObject; |
17
|
|
|
use yii\db\Connection; |
18
|
|
|
use yii\db\Query; |
19
|
|
|
use yii\helpers\ArrayHelper; |
20
|
|
|
|
21
|
|
|
abstract class BaseTerm extends BaseObject implements ITaxonomyTermInterface |
22
|
|
|
{ |
23
|
|
|
public $migrationPath = '@app/migrations'; |
24
|
|
|
|
25
|
|
|
public $id; |
26
|
|
|
public $name; //the name of the term |
27
|
|
|
public $data_table; |
28
|
|
|
public $ref_table; |
29
|
|
|
public $is_multi = false; |
30
|
|
|
public $created_at; |
31
|
|
|
public $total_count; |
32
|
|
|
public $migration; |
33
|
|
|
|
34
|
|
|
public abstract function addTerm($object_id, $params); |
35
|
|
|
|
36
|
|
|
public function removeTerm($object_id, $params = []) |
37
|
|
|
{ |
38
|
|
|
if(empty($params)) { |
39
|
|
|
$params = $this->getTerms($object_id); |
40
|
|
|
} |
41
|
|
|
|
42
|
|
View Code Duplication |
foreach($params as $item) { |
|
|
|
|
43
|
|
|
$term = $this->getTaxonomyTerm($item); |
44
|
|
|
$data['term_id'] = $term->id; |
|
|
|
|
45
|
|
|
$data['object_id'] = $object_id; |
|
|
|
|
46
|
|
|
|
47
|
|
|
$query = new Query(); |
48
|
|
|
if ($query->from($this->table)->where($data)->exists($this->getDb())) { |
|
|
|
|
49
|
|
|
$this->getDb()->createCommand()->delete($this->table, $data)->execute(); |
|
|
|
|
50
|
|
|
|
51
|
|
|
$term->updateCounters(['total_count' => -1]); |
|
|
|
|
52
|
|
|
Taxonomydef::updateAllCounters(['total_count' => -1], [ 'id' => $this->id ]); |
53
|
|
|
} |
54
|
|
|
} |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
public function getTerms($object_id = null, $name = []) |
58
|
|
|
{ |
59
|
|
|
$query = TaxonomyTerms::find() |
60
|
|
|
->select('term') |
61
|
|
|
->where(['taxonomy_id' => $this->id]) |
62
|
|
|
->andFilterWhere(['taxonomy_terms.term' => $name]); |
63
|
|
|
|
64
|
|
|
if ($object_id) { |
65
|
|
|
$query->innerJoin($this->table, $this->table . '.term_id = taxonomy_terms.id') |
|
|
|
|
66
|
|
|
->onCondition("$this->table.object_id = $object_id"); |
|
|
|
|
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
return ArrayHelper::getColumn($query->all(), 'term'); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
public function setTerms($object_id, $params = []) |
73
|
|
|
{ |
74
|
|
|
Yii::$app->db->transaction(function() use ($object_id, $params) { |
75
|
|
|
$this->removeTerm($object_id); |
76
|
|
|
$this->addTerm($object_id, $params); |
77
|
|
|
}); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
public function isInstalled() |
81
|
|
|
{ |
82
|
|
|
return Yii::$app->db->getTableSchema($this->getTable(), true) !== null; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
public function install() |
86
|
|
|
{ |
87
|
|
|
return $this->createMigration(); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
public function uninstall() |
91
|
|
|
{ |
92
|
|
|
//drop the data table |
93
|
|
|
//$this->getDb()->createCommand()->dropTable($this->getTable())->execute(); |
94
|
|
|
//delete the term itself |
95
|
|
|
$model = TaxonomyDef::findOne($this->id); |
96
|
|
|
$model->delete(); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Return the db connection component. |
101
|
|
|
* |
102
|
|
|
* @return Connection |
103
|
|
|
*/ |
104
|
|
|
public static function getDb() |
105
|
|
|
{ |
106
|
|
|
return Yii::$app->db; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
public function canInstall() { |
110
|
|
|
if(!$this->getTable()) |
111
|
|
|
return 'Missing "table" property'; |
112
|
|
|
return true; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
public function getTaxonomyTerm($name, $create = true) |
116
|
|
|
{ |
117
|
|
|
$term = TaxonomyTerms::findOne(['term'=>$name, 'taxonomy_id' => $this->id]); |
118
|
|
View Code Duplication |
if($create and !isset($term)) { |
|
|
|
|
119
|
|
|
$term = new TaxonomyTerms(); |
120
|
|
|
$term->taxonomy_id = $this->id; |
121
|
|
|
$term->term = $name; |
122
|
|
|
$term->total_count = 0; |
123
|
|
|
$term->save(); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
return $term; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
public function getRefTableName() |
130
|
|
|
{ |
131
|
|
|
if(strpos($this->refTable, '\\') === FALSE) //not an AR class but a table name |
|
|
|
|
132
|
|
|
return $this->refTable; |
|
|
|
|
133
|
|
|
else |
134
|
|
|
return call_user_func([$this->refTable, 'tableName']); |
|
|
|
|
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
public function getTable() |
138
|
|
|
{ |
139
|
|
|
return $this->data_table; |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
public function getRefTable() |
143
|
|
|
{ |
144
|
|
|
return $this->ref_table; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
public function getMigrationFile() |
148
|
|
|
{ |
149
|
|
|
if (!preg_match('/^\w+$/', $this->name)) { |
150
|
|
|
throw new Exception('The migration name should contain letters, digits and/or underscore characters only.'); |
151
|
|
|
} |
152
|
|
|
$name = 'm' . gmdate('ymd_His') . '_' . $this->name; |
153
|
|
|
return $name; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
public function createMigration() |
157
|
|
|
{ |
158
|
|
|
|
159
|
|
|
$name = $this->getMigrationFile(); |
160
|
|
|
$file = Yii::getAlias($this->migrationPath . DIRECTORY_SEPARATOR . $name . '.php'); |
161
|
|
|
|
162
|
|
|
//$data = get_object_vars($this); |
163
|
|
|
$data = []; |
164
|
|
|
$data['name'] = $this->name; |
165
|
|
|
$data['class'] = get_class($this); |
166
|
|
|
$data['data_table'] = $this->data_table; |
167
|
|
|
$data['ref_table'] = $this->getRefTableName(); |
168
|
|
|
$data['migration'] = $name; |
169
|
|
|
|
170
|
|
|
$this->migration = $name; |
171
|
|
|
$content = Yii::$app->getView()->renderFile(Yii::getAlias($this->templateFile), [ 'data' => $data ]); |
|
|
|
|
172
|
|
|
file_put_contents($file, $content); |
173
|
|
|
return $name; |
174
|
|
|
} |
175
|
|
|
} |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.