Test Setup Failed
Push — master ( 3f28c5...3bfa70 )
by Gabriel
83:42
created

HasOneOrMany::initResults()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 0
cts 7
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
namespace Nip\Records\Relations;
4
5
use Nip\Database\Query\Select as Query;
6
use Nip\HelperBroker;
7
use Nip_Helper_Arrays as ArraysHelper;
8
use Nip\Records\AbstractModels\Record as Record;
9
use Nip\Records\Collections\Associated as AssociatedCollection;
10
use Nip\Records\Collections\Collection;
11
use Nip\Records\Collections\Collection as RecordCollection;
12
use Nip\Records\Relations\Traits\HasCollectionResults;
13
14
/**
15
 * Class HasOneOrMany
16
 * @package Nip\Records\Relations
17
 */
18
abstract class HasOneOrMany extends Relation
19
{
20
    use HasCollectionResults;
21
22
    /**
23
     * @var string
24
     */
25
    protected $type = 'hasMany';
26
27
    /**
28
     * @return bool
29
     */
30
    public function save()
31
    {
32
        if ($this->hasResults()) {
33
            $collection = $this->getResults();
34
            foreach ($collection as $item) {
0 ignored issues
show
Bug introduced by
The expression $collection of type object<Nip\Records\Colle...ect<Nip\Records\Record> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
35
                $this->saveResult($item);
36
            }
37
        }
38
        return true;
39
    }
40
41
    /**
42
     * @return bool
43
     */
44
    public function hasResults()
45
    {
46
        return $this->isPopulated() && count($this->getResults()) > 0;
47
    }
48
49
    /**
50
     * @param Record $item
51
     */
52 1
    public function saveResult(Record $item)
53
    {
54 1
        $primaryKey = $this->getManager()->getPrimaryKey();
55 1
        $foreignKey = $this->getFK();
56 1
        $item->{$foreignKey} = $this->getItem()->{$primaryKey};
57 1
        $item->saveRecord();
58 1
    }
59
60
    /**
61
     * @throws \Exception
62
     */
63
    public function initResults()
64
    {
65
        $query = $this->getQuery();
66
        $items = $this->getWith()->findByQuery($query);
67
        $collection = $this->newCollection();
68
        $this->populateCollection($collection, $items);
69
        $this->setResults($collection);
70
    }
71
72
    /**
73
     * @param RecordCollection $collection
74
     * @param Collection $items
75
     */
76
    public function populateCollection(RecordCollection $collection, $items)
77
    {
78
        foreach ($items as $item) {
79
            $collection->add($item);
80
        }
81
    }
82
83
    /** @noinspection PhpMissingParentCallCommonInspection
84
     * @inheritdoc
85
     */
86 1
    public function populateEagerQueryFromFkList($query, $fkList)
87
    {
88 1
        $query->where($this->getFK() . ' IN ?', $fkList);
89 1
        return $query;
90
    }
91
92
    /** @noinspection PhpMissingParentCallCommonInspection
93
     * @param RecordCollection $collection
94
     * @return array
95
     */
96 1
    public function getEagerFkList(RecordCollection $collection)
97
    {
98 1
        if ($collection->isEmpty()) {
99 1
            return [];
100
        }
101 1
        $key = $collection->getManager()->getPrimaryKey();
102
        /** @var ArraysHelper $arrayHelper */
103 1
        $arrayHelper = HelperBroker::get('Arrays');
104 1
        $return = $arrayHelper->pluck($collection, $key);
105
106 1
        return array_unique($return);
107
    }
108
109
    /**
110
     * @param array $dictionary
111
     * @param Collection $collection
112
     * @param Record $record
113
     * @return AssociatedCollection
114
     */
115
    public function getResultsFromCollectionDictionary($dictionary, $collection, $record)
116
    {
117
        $foreignKey = $record->getManager()->getPrimaryKey();
118
        $primaryKey = $record->{$foreignKey};
119
        $collection = $this->newCollection();
120
121
        if (isset($dictionary[$primaryKey])) {
122
            foreach ($dictionary[$primaryKey] as $record) {
123
                $collection->add($record);
124
            }
125
        }
126
        return $collection;
127
    }
128
129
    /**
130
     * Build model dictionary keyed by the relation's foreign key.
131
     *
132
     * @param RecordCollection $collection
133
     * @return array
134
     */
135 View Code Duplication
    protected function buildDictionary(RecordCollection $collection)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
136
    {
137
        $dictionary = [];
138
        $primaryKey = $this->getDictionaryKey();
139
        foreach ($collection as $record) {
140
            $dictionary[$record->{$primaryKey}][] = $record;
141
        }
142
        return $dictionary;
143
    }
144
145
    /**
146
     * @return string
147
     */
148
    protected function getDictionaryKey()
149
    {
150
        return $this->getFK();
151
    }
152
}
153