Completed
Push — master ( e58eb5...5b23f9 )
by James Ekow Abaka
02:57
created

ManyHaveManyRelationship   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 98
Duplicated Lines 10.2 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 58.62%

Importance

Changes 7
Bugs 0 Features 0
Metric Value
wmc 18
c 7
b 0
f 0
lcom 1
cbo 6
dl 10
loc 98
ccs 34
cts 58
cp 0.5862
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B prepareQuery() 0 26 4
B runSetup() 10 26 6
A preSave() 0 9 1
B postSave() 0 19 6

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
/*
4
 * The MIT License
5
 *
6
 * Copyright 2015 ekow.
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated documentation files (the "Software"), to deal
10
 * in the Software without restriction, including without limitation the rights
11
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
 * copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
 * THE SOFTWARE.
25
 */
26
27
namespace ntentan\nibii\relationships;
28
29
use ntentan\utils\Text;
30
use ntentan\nibii\ORMContext;
31
use ntentan\nibii\NibiiException;
32
33
class ManyHaveManyRelationship extends \ntentan\nibii\Relationship
34
{
35
36
    protected $type = self::MANY_HAVE_MANY;
37
    private $tempdata;
38
    private $junctionModelInstance;
39
40 4
    public function __construct(ORMContext $context)
41
    {
42 4
        $this->container = $context->getContainer();
43 4
        $this->context = $context;
44 4
    }
45
46 4
    public function prepareQuery($data)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
47
    {
48 4
        $junctionModel = $this->container->resolve($this->options['junction_model']);
49 4
        $filter = $junctionModel->fields($this->options['junction_foreign_key'])
50 4
                ->filterBy($this->options['junction_local_key'], $data[$this->options['local_key']])
51 4
                ->fetch();
52 4
        if ($filter->count() == 0) {
53
            return null;
54
        }
55 4
        $foreignKeys = [];
56 4
        foreach ($filter->toArray() as $foreignItem) {
57 4
            $foreignKeys[] = $foreignItem[$this->options['junction_foreign_key']];
58
        }
59
60
        // @todo throw an exception when the data doesn't have the local key
61 4
        $query = $this->getQuery();
62 4
        if ($this->queryPrepared) {
63
            $query->setBoundData($this->options['foreign_key'], $foreignKeys);
64
        } else {
65 4
            $query = $this->getQuery()
66 4
                    ->setTable($this->getModelInstance()->getDBStoreInformation()['quoted_table'])
67 4
                    ->addFilter($this->options['foreign_key'], $foreignKeys);
68 4
            $this->queryPrepared = true;
69
        }
70 4
        return $query;
71
    }
72
73 4
    public function runSetup()
74
    {
75 4
        if (isset($this->options['through'])) {
76
            $junctionModelName = $this->context->getClassName($this->options['through']);
77
        } else {
78 4
            $junctionModelName = $this->context->joinModels($this->setupName, $this->options['model']);
79
        }
80 4
        $this->options['junction_model'] = $junctionModelName;
81
82 4
        $foreignModel = $this->context->load($this->options['model']);
83 4
        if ($this->options['foreign_key'] == null) {
84 4
            $this->options['foreign_key'] = $foreignModel->getDescription()->getPrimaryKey()[0];
85
        }
86
87 4 View Code Duplication
        if ($this->options['local_key'] == null) {
88 4
            $this->options['local_key'] = $this->setupPrimaryKey[0];
89
        }
90
91 4 View Code Duplication
        if (!isset($this->options['junction_local_key'])) {
92 4
            $this->options['junction_local_key'] = Text::singularize($this->setupTable) . '_id';
93
        }
94
95 4 View Code Duplication
        if (!isset($this->options['junction_foreign_key'])) {
96 4
            $this->options['junction_foreign_key'] = Text::singularize($foreignModel->getDBStoreInformation()['table']) . '_id';
97
        }
98 4
    }
99
100
    public function preSave(&$wrapper, $value)
101
    {
102
        $this->tempdata = $wrapper[$this->options['model']];
103
        $this->junctionModelInstance = $this->container->resolve($this->options['junction_model']);
104
        $this->junctionModelInstance->delete([
105
            $this->options['junction_local_key'] => $wrapper[$this->options['local_key']]
106
        ]);
107
        unset($wrapper[$this->options['model']]);
108
    }
109
110
    public function postSave(&$wrapper)
111
    {
112
        $jointModelRecords = [];
113
        foreach ($this->tempdata as $relatedRecord) {
114
            var_dump($relatedRecord);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($relatedRecord); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
115
            $data = $relatedRecord->toArray();
116
            if (!isset($data[$this->options['foreign_key']]) || (isset($data[$this->options['foreign_key']]) && count($data) > 1)) {
117
                if (!$relatedRecord->save()) {
118
                    throw new NibiiException("Failed to save related model {$this->options['model']}");
119
                }
120
            }
121
            $jointModelRecords[] = [
122
                $this->options['junction_local_key'] => $wrapper[$this->options['local_key']],
123
                $this->options['junction_foreign_key'] => $relatedRecord[$this->options['foreign_key']]
124
            ];
125
        }
126
        $this->junctionModelInstance->setData($jointModelRecords);
127
        $this->junctionModelInstance->save();
128
    }
129
130
}
131