1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Model for store and access SEO data for ActiveRecord in Yii2 framework |
4
|
|
|
* |
5
|
|
|
* @link https://github.com/inblank/yii2-seobility |
6
|
|
|
* @copyright Copyright (c) 2016 Pavel Aleksandrov <[email protected]> |
7
|
|
|
* @license http://opensource.org/licenses/MIT |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
namespace inblank\seobility\models; |
11
|
|
|
|
12
|
|
|
use yii\base\Model; |
13
|
|
|
use yii\db\ActiveRecord; |
14
|
|
|
use yii\db\Query; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Model for store and access SEO data for ActiveRecord in Yii2 framework |
18
|
|
|
* |
19
|
|
|
* @package inblank\seobility |
20
|
|
|
*/ |
21
|
|
|
class Seo extends Model |
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* @var string suffix for build table name for the tables stored SEO data for ActiveRecord |
25
|
|
|
*/ |
26
|
|
|
static public $tableSuffix = 'seo'; |
27
|
|
|
/** |
28
|
|
|
* @var int SEO data owner model id |
29
|
|
|
*/ |
30
|
|
|
public $model_id; |
31
|
|
|
/** |
32
|
|
|
* @var int SEO data condition |
33
|
|
|
*/ |
34
|
|
|
public $condition = 0; |
35
|
|
|
/** |
36
|
|
|
* @var string SEO title |
37
|
|
|
*/ |
38
|
|
|
public $title = ''; |
39
|
|
|
/** |
40
|
|
|
* @var string SEO keywords |
41
|
|
|
*/ |
42
|
|
|
public $keywords = ''; |
43
|
|
|
/** |
44
|
|
|
* @var string SEO description |
45
|
|
|
*/ |
46
|
|
|
public $description = ''; |
47
|
|
|
/** |
48
|
|
|
* @var bool new record flag |
49
|
|
|
*/ |
50
|
|
|
protected $_isNewRecord; |
51
|
|
|
/** |
52
|
|
|
* @var ActiveRecord SEO data owner |
53
|
|
|
*/ |
54
|
|
|
protected $_owner; |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* Search SEO data. If not found, will be returned new SEO model with empty data |
58
|
|
|
* @param ActiveRecord $owner the ActiveRecord model for which to find data |
59
|
|
|
* @param int $condition optional condition for searched SEO data |
60
|
|
|
* @return self |
61
|
|
|
*/ |
62
|
1 |
|
public static function find(ActiveRecord $owner, $condition = 0) |
63
|
|
|
{ |
64
|
1 |
|
$seo = new self(); |
65
|
1 |
|
$seo->_owner = $owner; |
66
|
1 |
|
$condition = (int)$condition; |
67
|
1 |
|
$data = $owner->getIsNewRecord() ? false : (new Query()) |
68
|
1 |
|
->from(Seo::tableName($owner)) |
69
|
1 |
|
->limit(1) |
70
|
1 |
|
->andWhere([ |
71
|
1 |
|
'condition' => $condition, |
72
|
1 |
|
'model_id' => $owner->getPrimaryKey(), |
73
|
1 |
|
])->one($owner->getDb()); |
74
|
1 |
|
$seo->_isNewRecord = empty($data); |
75
|
1 |
|
$seo->setAttributes($data); |
|
|
|
|
76
|
1 |
|
$seo->condition = $condition; |
77
|
1 |
|
return $seo; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Get table name of SEO data table for ActiveRecord |
82
|
|
|
* @param ActiveRecord $activeRecord |
83
|
|
|
* @return string |
84
|
|
|
*/ |
85
|
1 |
|
static public function tableName(ActiveRecord $activeRecord) |
|
|
|
|
86
|
|
|
{ |
87
|
1 |
|
$tableName = $activeRecord->tableName(); |
88
|
1 |
|
if (substr($tableName, -2) == '}}') { |
89
|
1 |
|
return preg_replace('/{{(.+)}}/', '{{$1_' . self::$tableSuffix . '}}', $tableName); |
90
|
|
|
} else { |
91
|
1 |
|
return $tableName . '_' . self::$tableSuffix; |
92
|
|
|
} |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* Find all SEO data. |
97
|
|
|
* Result will be in format ['condition1'=>Seo(), 'condition2'=>Seo(), ...] |
98
|
|
|
* @param ActiveRecord $owner the model for which to find data |
99
|
|
|
* @return self[] |
100
|
|
|
*/ |
101
|
1 |
|
public static function findAll(ActiveRecord $owner) |
102
|
|
|
{ |
103
|
|
|
/** @var self[] $seoList */ |
104
|
1 |
|
$seoList = []; |
105
|
1 |
|
if ($owner->getIsNewRecord()) { |
106
|
1 |
|
return $seoList; |
107
|
|
|
} |
108
|
1 |
|
$query = (new Query())->from(Seo::tableName($owner))->andWhere(['model_id' => $owner->getPrimaryKey()]); |
109
|
1 |
|
foreach ($query->all($owner->getDb()) as $seo) { |
110
|
1 |
|
$seo = new Seo($seo); |
111
|
1 |
|
$seo->_isNewRecord = false; |
112
|
1 |
|
$seo->_owner = $owner; |
113
|
1 |
|
$seoList[$seo['condition']] = $seo; |
114
|
|
|
} |
115
|
1 |
|
return $seoList; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* Delete all SEO data for ActiveRecord |
120
|
|
|
* @param ActiveRecord $owner |
121
|
|
|
*/ |
122
|
1 |
|
static public function deleteAll(ActiveRecord $owner) |
|
|
|
|
123
|
|
|
{ |
124
|
1 |
|
$owner->getDb()->createCommand()->delete(self::tableName($owner), ['model_id' => $owner->getPrimaryKey()])->execute(); |
125
|
1 |
|
} |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* @return array |
129
|
|
|
*/ |
130
|
1 |
|
public function rules() |
131
|
|
|
{ |
132
|
|
|
return [ |
133
|
1 |
|
[['title', 'keywords', 'description'], 'safe'], |
134
|
|
|
]; |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* Save SEO data |
139
|
|
|
*/ |
140
|
1 |
|
public function save() |
141
|
|
|
{ |
142
|
1 |
|
if (empty($this->_owner)) { |
143
|
1 |
|
$this->addError('owner', "You can't use Seo model without owner"); |
144
|
1 |
|
return false; |
145
|
|
|
} |
146
|
1 |
|
$this->model_id = $this->_owner->getPrimaryKey(); |
147
|
1 |
|
$command = $this->_owner->getDb()->createCommand(); |
148
|
1 |
|
$attributes = ['title', 'keywords', 'description']; |
149
|
1 |
|
$tableName = self::tableName($this->_owner); |
150
|
1 |
|
if ($this->_isNewRecord) { |
151
|
1 |
|
if (empty(array_filter($this->getAttributes($attributes)))) { |
152
|
|
|
// don't save new SEO data with empty values |
153
|
1 |
|
return true; |
154
|
|
|
} |
155
|
1 |
|
$command->insert($tableName, $this->toArray()); |
156
|
|
|
} else { |
157
|
1 |
|
$command->update( |
158
|
1 |
|
$tableName, $this->toArray($attributes), |
159
|
1 |
|
['model_id' => $this->model_id, 'condition' => $this->condition] |
160
|
|
|
); |
161
|
|
|
} |
162
|
1 |
|
$command->execute(); |
163
|
1 |
|
$this->_isNewRecord = false; |
164
|
1 |
|
return true; |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* Delete SEO data |
169
|
|
|
* @return $this|bool |
170
|
|
|
*/ |
171
|
1 |
|
public function delete() |
172
|
|
|
{ |
173
|
1 |
|
if (!$this->_isNewRecord) { |
174
|
1 |
|
$this->_owner->getDb() |
175
|
1 |
|
->createCommand() |
176
|
1 |
|
->delete( |
177
|
1 |
|
self::tableName($this->_owner), |
178
|
1 |
|
['model_id' => $this->_owner->getPrimaryKey(), 'condition' => $this->condition] |
179
|
1 |
|
)->execute(); |
180
|
|
|
} |
181
|
1 |
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* Get isNewRecord flag |
185
|
|
|
* @return bool |
186
|
|
|
*/ |
187
|
1 |
|
public function getIsNewRecord() |
188
|
|
|
{ |
189
|
1 |
|
return $this->_isNewRecord; |
190
|
|
|
} |
191
|
|
|
} |
192
|
|
|
|
This check looks for type mismatches where the missing type is
false
. This is usually indicative of an error condtion.Consider the follow example
This function either returns a new
DateTime
object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returnedfalse
before passing on the value to another function or method that may not be able to handle afalse
.