Complex classes like ActiveRecord often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ActiveRecord, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
22 | class ActiveRecord extends BaseActiveRecord |
||
23 | { |
||
24 | /** |
||
25 | * Returns the database connection used by this AR class. |
||
26 | * By default, the "hiart" application component is used as the database connection. |
||
27 | * You may override this method if you want to use a different database connection. |
||
28 | * |
||
29 | * @return Connection the database connection used by this AR class. |
||
30 | */ |
||
31 | public static function getDb() |
||
35 | |||
36 | /** |
||
37 | * {@inheritdoc} |
||
38 | * |
||
39 | * @return ActiveQuery the newly created [[ActiveQuery]] instance. |
||
40 | */ |
||
41 | public static function find($options = []) |
||
42 | { |
||
43 | $config = [ |
||
44 | 'class' => ActiveQuery::className(), |
||
45 | 'options' => $options, |
||
46 | ]; |
||
47 | return \Yii::createObject($config, [get_called_class()]); |
||
48 | } |
||
49 | |||
50 | /** |
||
51 | * {@inheritdoc} |
||
52 | */ |
||
53 | public static function findOne($condition, $options = []) |
||
54 | { |
||
55 | $query = static::find($options); |
||
56 | if (is_array($condition)) { |
||
57 | return $query->andWhere($condition)->one(); |
||
|
|||
58 | } else { |
||
59 | return static::get($condition); |
||
60 | } |
||
61 | } |
||
62 | |||
63 | /** |
||
64 | * {@inheritdoc} |
||
65 | */ |
||
66 | public static function findAll($condition, $options = []) |
||
70 | |||
71 | public function isScenarioDefault() |
||
75 | |||
76 | /** |
||
77 | * Gets a record by its primary key. |
||
78 | * |
||
79 | * @param mixed $primaryKey the primaryKey value |
||
80 | * @param array $options options given in this parameter are passed to API. |
||
81 | * |
||
82 | * @return null|static The record instance or null if it was not found. |
||
83 | */ |
||
84 | public static function get($primaryKey = null, $options = []) |
||
85 | { |
||
86 | if ($primaryKey === null) { |
||
87 | return null; |
||
88 | } |
||
89 | $command = static::getDb()->createCommand(); |
||
90 | $result = $command->get(static::type(), $primaryKey, $options); |
||
91 | |||
92 | if ($result) { |
||
93 | $model = static::instantiate($result); |
||
94 | static::populateRecord($model, $result); |
||
95 | $model->afterFind(); |
||
96 | |||
97 | return $model; |
||
98 | } |
||
99 | |||
100 | return null; |
||
101 | } |
||
102 | |||
103 | /** |
||
104 | * This method defines the attribute that uniquely identifies a record. |
||
105 | * |
||
106 | * The primaryKey for HiArt objects is the `id` field by default. This field is not part of the |
||
107 | * ActiveRecord attributes so you should never add `_id` to the list of [[attributes()|attributes]]. |
||
108 | * |
||
109 | * You may override this method to define the primary key name. |
||
110 | * |
||
111 | * Note that HiArt only supports _one_ attribute to be the primary key. However to match the signature |
||
112 | * of the [[\yii\db\ActiveRecordInterface|ActiveRecordInterface]] this methods returns an array instead of a |
||
113 | * single string. |
||
114 | * |
||
115 | * @return string[] array of primary key attributes. Only the first element of the array will be used. |
||
116 | */ |
||
117 | public static function primaryKey() |
||
121 | |||
122 | /** |
||
123 | * + * The name of the main attribute |
||
124 | * + * |
||
125 | * Examples:. |
||
126 | * |
||
127 | * This will directly reference to the attribute 'name' |
||
128 | * ``` |
||
129 | * return 'name'; |
||
130 | * ``` |
||
131 | * |
||
132 | * This will concatenate listed attributes, separated with `delimiter` value. |
||
133 | * If delimiter is not set, space is used by default. |
||
134 | * ``` |
||
135 | * return ['seller', 'client', 'delimiter' => '/']; |
||
136 | * ``` |
||
137 | * |
||
138 | * The callable method, that will get [[$model]] and should return value of name attribute |
||
139 | * ``` |
||
140 | * return function ($model) { |
||
141 | * return $model->someField ? $model->name : $model->otherName; |
||
142 | * }; |
||
143 | * ``` |
||
144 | * |
||
145 | * @throws InvalidConfigException |
||
146 | * |
||
147 | * @return string|callable|array |
||
148 | * |
||
149 | * @author SilverFire |
||
150 | */ |
||
151 | public function primaryValue() |
||
155 | |||
156 | /** |
||
157 | * Returns the value of the primary attribute. |
||
158 | * |
||
159 | * @throws InvalidConfigException |
||
160 | * |
||
161 | * @return mixed|null |
||
162 | * |
||
163 | * @see primaryValue() |
||
164 | */ |
||
165 | public function getPrimaryValue() |
||
179 | |||
180 | /** |
||
181 | * Returns the list of all attribute names of the model. |
||
182 | * |
||
183 | * This method must be overridden by child classes to define available attributes. |
||
184 | * |
||
185 | * Attributes are names of fields of the corresponding API object. |
||
186 | * The primaryKey for HiArt documents is the `id` field by default which is not part of the attributes. |
||
187 | * |
||
188 | * @throws \yii\base\InvalidConfigException if not overridden in a child class. |
||
189 | * |
||
190 | * @return string[] list of attribute names. |
||
191 | */ |
||
192 | public function attributes() |
||
196 | |||
197 | /** |
||
198 | * @return string the name of the index this record is stored in. |
||
199 | */ |
||
200 | public static function index() |
||
205 | |||
206 | public static function joinIndex() |
||
210 | |||
211 | /** |
||
212 | * Creates an active record instance. |
||
213 | * |
||
214 | * This method is called together with [[populateRecord()]] by [[ActiveQuery]]. |
||
215 | * It is not meant to be used for creating new records directly. |
||
216 | * |
||
217 | * You may override this method if the instance being created |
||
218 | * depends on the row data to be populated into the record. |
||
219 | * For example, by creating a record based on the value of a column, |
||
220 | * you may implement the so-called single-table inheritance mapping. |
||
221 | * |
||
222 | * @param array $row row data to be populated into the record. |
||
223 | * This array consists of the following keys: |
||
224 | * - `_source`: refers to the attributes of the record. |
||
225 | * - `_type`: the type this record is stored in. |
||
226 | * - `_index`: the index this record is stored in. |
||
227 | * |
||
228 | * @return static the newly created active record |
||
229 | */ |
||
230 | public static function instantiate($row) |
||
234 | |||
235 | /** |
||
236 | * @return string the name of the type of this record. |
||
237 | */ |
||
238 | public static function type() |
||
242 | |||
243 | /** |
||
244 | * Declares the name of the model associated with this class. |
||
245 | * By default this method returns the class name by calling [[Inflector::camel2id()]]. |
||
246 | * |
||
247 | * @return string the module name |
||
248 | */ |
||
249 | public static function modelName() |
||
253 | |||
254 | public function insert($runValidation = true, $attributes = null, $options = []) |
||
282 | |||
283 | /** |
||
284 | * {@inheritdoc} |
||
285 | */ |
||
286 | public function delete($options = []) |
||
302 | |||
303 | public function update($runValidation = true, $attributeNames = null, $options = []) |
||
311 | |||
312 | protected function updateInternal($attributes = null, $options = []) |
||
341 | |||
342 | /** |
||
343 | * Custom method for HiArt. |
||
344 | * |
||
345 | * @param $action |
||
346 | * @param array $options |
||
347 | * @param bool $bulk |
||
348 | * |
||
349 | * @return array |
||
350 | */ |
||
351 | public static function perform($action, $options = [], $bulk = false) |
||
358 | |||
359 | /** |
||
360 | * Creates the command name for the specified scenario name. |
||
361 | * |
||
362 | * @param string $default |
||
363 | * @param bool $bulk |
||
364 | * |
||
365 | * @throws InvalidConfigException |
||
366 | * @throws NotSupportedException |
||
367 | * |
||
368 | * @return string |
||
369 | */ |
||
370 | public function getScenarioCommand($default = '', $bulk = false) |
||
403 | |||
404 | /** |
||
405 | * Define an array of relations between scenario and API call action. |
||
406 | * |
||
407 | * Example: |
||
408 | * |
||
409 | * ``` |
||
410 | * [ |
||
411 | * 'update-name' => 'set-name', /// ModuleSetName |
||
412 | * 'update-related-name' => [Action::formName(), 'SetName'], /// ActionSetName |
||
413 | * 'update-self-case-sensetive' => [null, 'SomeSENSETIVE'] /// ModuleSomeSENSETIVE |
||
414 | * ] |
||
415 | * ~~ |
||
416 | * |
||
417 | * key string name of scenario |
||
418 | * value string|array |
||
419 | * string will be passed to [[Inflector::id2camel|id2camel]] inflator |
||
420 | * array - first attribute a module name, second - value |
||
421 | * |
||
422 | * Tricks: pass null as first argument of array to leave command's case unchanged (no inflator calling) |
||
423 | * |
||
424 | * @return array |
||
425 | */ |
||
426 | public function scenarioCommands() |
||
430 | |||
431 | /** |
||
432 | * @return bool |
||
433 | */ |
||
434 | public function getIsNewRecord() |
||
438 | |||
439 | /** |
||
440 | * This method has no effect in HiArt ActiveRecord. |
||
441 | */ |
||
442 | public function optimisticLock() |
||
446 | |||
447 | /** |
||
448 | * Destroys the relationship in current model. |
||
449 | * |
||
450 | * This method is not supported by HiArt. |
||
451 | */ |
||
452 | public function unlinkAll($name, $delete = false) |
||
456 | |||
457 | /** |
||
458 | * {@inheritdoc} |
||
459 | * |
||
460 | * @return ActiveQueryInterface|ActiveQuery the relational query object. If the relation does not exist |
||
461 | * and `$throwException` is false, null will be returned. |
||
462 | */ |
||
463 | public function getRelation($name, $throwException = true) |
||
467 | |||
468 | /** |
||
469 | * {@inheritdoc} |
||
470 | * @return ActiveQuery the relational query object. |
||
471 | */ |
||
472 | public function hasOne($class, $link) |
||
476 | |||
477 | /** |
||
478 | * {@inheritdoc} |
||
479 | * @return ActiveQuery the relational query object. |
||
480 | */ |
||
481 | public function hasMany($class, $link) |
||
485 | } |
||
486 |