Test Setup Failed
Push — master ( 3bfa70...333906 )
by Gabriel
13:19
created

HasOneOrMany   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 137
Duplicated Lines 6.57 %

Coupling/Cohesion

Components 2
Dependencies 9

Test Coverage

Coverage 40.38%

Importance

Changes 0
Metric Value
wmc 19
lcom 2
cbo 9
dl 9
loc 137
ccs 21
cts 52
cp 0.4038
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A save() 0 10 3
A hasResults() 0 4 2
A saveResult() 0 7 1
A initResults() 0 10 2
A populateCollection() 0 6 2
A populateEagerQueryFromFkList() 0 5 1
A getEagerFkList() 0 12 2
A getResultsFromCollectionDictionary() 0 13 3
A buildDictionary() 9 9 2
A getDictionaryKey() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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 1
    public function initResults()
64
    {
65 1
        $collection = $this->newCollection();
66 1
        if ($this->isPopulatable()) {
67
            $query = $this->getQuery();
68
            $items = $this->getWith()->findByQuery($query);
69
            $this->populateCollection($collection, $items);
70
        }
71 1
        $this->setResults($collection);
72 1
    }
73
74
    /**
75
     * @param RecordCollection $collection
76
     * @param Collection $items
77
     */
78
    public function populateCollection(RecordCollection $collection, $items)
79
    {
80
        foreach ($items as $item) {
81
            $collection->add($item);
82
        }
83
    }
84
85
    /** @noinspection PhpMissingParentCallCommonInspection
86
     * @inheritdoc
87
     */
88 1
    public function populateEagerQueryFromFkList($query, $fkList)
89
    {
90 1
        $query->where($this->getFK() . ' IN ?', $fkList);
91 1
        return $query;
92
    }
93
94
    /** @noinspection PhpMissingParentCallCommonInspection
95
     * @param RecordCollection $collection
96
     * @return array
97
     */
98 1
    public function getEagerFkList(RecordCollection $collection)
99
    {
100 1
        if ($collection->isEmpty()) {
101 1
            return [];
102
        }
103 1
        $key = $collection->getManager()->getPrimaryKey();
104
        /** @var ArraysHelper $arrayHelper */
105 1
        $arrayHelper = HelperBroker::get('Arrays');
106 1
        $return = $arrayHelper->pluck($collection, $key);
107
108 1
        return array_unique($return);
109
    }
110
111
    /**
112
     * @param array $dictionary
113
     * @param Collection $collection
114
     * @param Record $record
115
     * @return AssociatedCollection
116
     */
117
    public function getResultsFromCollectionDictionary($dictionary, $collection, $record)
118
    {
119
        $foreignKey = $record->getManager()->getPrimaryKey();
120
        $primaryKey = $record->{$foreignKey};
121
        $collection = $this->newCollection();
122
123
        if (isset($dictionary[$primaryKey])) {
124
            foreach ($dictionary[$primaryKey] as $record) {
125
                $collection->add($record);
126
            }
127
        }
128
        return $collection;
129
    }
130
131
    /**
132
     * Build model dictionary keyed by the relation's foreign key.
133
     *
134
     * @param RecordCollection $collection
135
     * @return array
136
     */
137 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...
138
    {
139
        $dictionary = [];
140
        $primaryKey = $this->getDictionaryKey();
141
        foreach ($collection as $record) {
142
            $dictionary[$record->{$primaryKey}][] = $record;
143
        }
144
        return $dictionary;
145
    }
146
147
    /**
148
     * @return string
149
     */
150
    protected function getDictionaryKey()
151
    {
152
        return $this->getFK();
153
    }
154
}
155