|
13 | 13 | use yii\base\InvalidConfigException;
|
14 | 14 | use yii\base\InvalidParamException;
|
15 | 15 | use yii\base\NotSupportedException;
|
| 16 | +use yii\db\ActiveQueryInterface; |
| 17 | +use yii\db\ActiveRecordInterface; |
16 | 18 | use yii\db\BaseActiveRecord;
|
17 | 19 | use yii\db\StaleObjectException;
|
18 | 20 | use yii\helpers\ArrayHelper;
|
19 | 21 | use yii\helpers\Inflector;
|
20 |
| -use yii\helpers\Json; |
21 | 22 | use yii\helpers\StringHelper;
|
22 | 23 |
|
23 | 24 | /**
|
@@ -118,10 +119,10 @@ public static function findAll($condition)
|
118 | 119 | */
|
119 | 120 | private static function filterCondition($condition)
|
120 | 121 | {
|
121 |
| - foreach($condition as $k => $v) { |
| 122 | + foreach ($condition as $k => $v) { |
122 | 123 | if (is_array($v)) {
|
123 | 124 | $condition[$k] = array_values($v);
|
124 |
| - foreach($v as $vv) { |
| 125 | + foreach ($v as $vv) { |
125 | 126 | if (is_array($vv)) {
|
126 | 127 | throw new InvalidArgumentException('Nested arrays are not allowed in condition for findAll() and findOne().');
|
127 | 128 | }
|
@@ -358,7 +359,7 @@ public static function populateRecord($record, $row)
|
358 | 359 | if (isset($row['fields'])) {
|
359 | 360 | // reset fields in case it is scalar value
|
360 | 361 | $arrayAttributes = $record->arrayAttributes();
|
361 |
| - foreach($row['fields'] as $key => $value) { |
| 362 | + foreach ($row['fields'] as $key => $value) { |
362 | 363 | if (!isset($arrayAttributes[$key]) && count($value) === 1) {
|
363 | 364 | $row['fields'][$key] = reset($value);
|
364 | 365 | }
|
@@ -528,14 +529,14 @@ public function update($runValidation = true, $attributeNames = null, $options =
|
528 | 529 | }
|
529 | 530 |
|
530 | 531 | /**
|
531 |
| - * @see update() |
532 | 532 | * @param array $attributes attributes to update
|
533 | 533 | * @param array $options options given in this parameter are passed to elasticsearch
|
534 | 534 | * as request URI parameters. See [[update()]] for details.
|
535 | 535 | * @return int|false the number of rows affected, or false if [[beforeSave()]] stops the updating process.
|
536 | 536 | * @throws StaleObjectException if optimistic locking is enabled and the data being updated is outdated.
|
537 | 537 | * @throws InvalidParamException if no [[version]] is available and optimistic locking is enabled.
|
538 | 538 | * @throws Exception in case update failed.
|
| 539 | + * @see update() |
539 | 540 | */
|
540 | 541 | protected function updateInternal($attributes = null, $options = [])
|
541 | 542 | {
|
@@ -564,7 +565,7 @@ protected function updateInternal($attributes = null, $options = [])
|
564 | 565 | $values,
|
565 | 566 | $options
|
566 | 567 | );
|
567 |
| - } catch(Exception $e) { |
| 568 | + } catch (Exception $e) { |
568 | 569 | // HTTP 409 is the response in case of failed optimistic locking
|
569 | 570 | // http://www.elastic.co/guide/en/elasticsearch/guide/current/optimistic-concurrency-control.html
|
570 | 571 | if (isset($e->errorInfo['responseCode']) && $e->errorInfo['responseCode'] == 409) {
|
@@ -629,9 +630,9 @@ protected static function primaryKeysByCondition($condition)
|
629 | 630 | * @param array $attributes attribute values (name-value pairs) to be saved into the table
|
630 | 631 | * @param array $condition the conditions that will be passed to the `where()` method when building the query.
|
631 | 632 | * Please refer to [[ActiveQuery::where()]] on how to specify this parameter.
|
632 |
| - * @see [[ActiveRecord::primaryKeysByCondition()]] |
633 | 633 | * @return int the number of rows updated
|
634 | 634 | * @throws Exception on error.
|
| 635 | + * @see [[ActiveRecord::primaryKeysByCondition()]] |
635 | 636 | */
|
636 | 637 | public static function updateAll($attributes, $condition = [])
|
637 | 638 | {
|
@@ -677,9 +678,9 @@ public static function updateAll($attributes, $condition = [])
|
677 | 678 | * Use negative values if you want to decrement the counters.
|
678 | 679 | * @param array $condition the conditions that will be passed to the `where()` method when building the query.
|
679 | 680 | * Please refer to [[ActiveQuery::where()]] on how to specify this parameter.
|
680 |
| - * @see [[ActiveRecord::primaryKeysByCondition()]] |
681 | 681 | * @return int the number of rows updated
|
682 | 682 | * @throws Exception on error.
|
| 683 | + * @see [[ActiveRecord::primaryKeysByCondition()]] |
683 | 684 | */
|
684 | 685 | public static function updateAllCounters($counters, $condition = [])
|
685 | 686 | {
|
@@ -767,7 +768,7 @@ public function delete($options = [])
|
767 | 768 | $this->getOldPrimaryKey(false),
|
768 | 769 | $options
|
769 | 770 | );
|
770 |
| - } catch(Exception $e) { |
| 771 | + } catch (Exception $e) { |
771 | 772 | // HTTP 409 is the response in case of failed optimistic locking
|
772 | 773 | // http://www.elastic.co/guide/en/elasticsearch/guide/current/optimistic-concurrency-control.html
|
773 | 774 | if (isset($e->errorInfo['responseCode']) && $e->errorInfo['responseCode'] == 409) {
|
@@ -799,9 +800,9 @@ public function delete($options = [])
|
799 | 800 | *
|
800 | 801 | * @param array $condition the conditions that will be passed to the `where()` method when building the query.
|
801 | 802 | * Please refer to [[ActiveQuery::where()]] on how to specify this parameter.
|
802 |
| - * @see [[ActiveRecord::primaryKeysByCondition()]] |
803 | 803 | * @return int the number of rows deleted
|
804 | 804 | * @throws Exception on error.
|
| 805 | + * @see [[ActiveRecord::primaryKeysByCondition()]] |
805 | 806 | */
|
806 | 807 | public static function deleteAll($condition = [])
|
807 | 808 | {
|
@@ -857,4 +858,57 @@ public function unlinkAll($name, $delete = false)
|
857 | 858 | {
|
858 | 859 | throw new NotSupportedException('unlinkAll() is not supported by elasticsearch, use unlink() instead.');
|
859 | 860 | }
|
| 861 | + |
| 862 | + public function link($name, $model, $extraColumns = []) |
| 863 | + { |
| 864 | + $relation = $this->getRelation($name); |
| 865 | + |
| 866 | + if ($relation->via === null) { |
| 867 | + $this->validateViaRelationLink($model, $relation); |
| 868 | + } |
| 869 | + |
| 870 | + parent::link($name, $model, $extraColumns); |
| 871 | + } |
| 872 | + |
| 873 | + /** |
| 874 | + * Validates model so that it does not contain array as it's keys while linking. |
| 875 | + * |
| 876 | + * @param ActiveRecordInterface $model the model to be linked with the current one. |
| 877 | + * @param ActiveQueryInterface|ActiveQuery the relational query object. |
| 878 | + */ |
| 879 | + protected function validateViaRelationLink($model, $relation) |
| 880 | + { |
| 881 | + $p1 = $model->isPrimaryKey(array_keys($relation->link)); |
| 882 | + $p2 = static::isPrimaryKey(array_values($relation->link)); |
| 883 | + |
| 884 | + $atLeastOneExists = !$this->getIsNewRecord() || !$model->getIsNewRecord(); |
| 885 | + |
| 886 | + $foreign = null; |
| 887 | + $link = null; |
| 888 | + |
| 889 | + if ($p1 && $p2 && $atLeastOneExists) { |
| 890 | + |
| 891 | + if ($this->getIsNewRecord()) { |
| 892 | + $foreign = $this; |
| 893 | + $link = array_flip($relation->link); |
| 894 | + } else { |
| 895 | + $foreign = $model; |
| 896 | + $link = $relation->link; |
| 897 | + } |
| 898 | + } elseif ($p1) { |
| 899 | + $foreign = $this; |
| 900 | + $link = array_flip($relation->link); |
| 901 | + } elseif ($p2) { |
| 902 | + $foreign = $model; |
| 903 | + $link = $relation->link; |
| 904 | + } |
| 905 | + |
| 906 | + if ($foreign && $link) { |
| 907 | + foreach ($link as $fk => $pk) { |
| 908 | + if (is_array($foreign->{$fk})) { |
| 909 | + throw new InvalidCallException('Unable to link models: foreign model cannot be linked if it\'s property is an array.'); |
| 910 | + } |
| 911 | + } |
| 912 | + } |
| 913 | + } |
860 | 914 | }
|
0 commit comments