BaseRepository::_getPrimaryKeyColumnName()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace BWC\Share\Data;
4
5
use BWC\Share\Object\ObjectHelper;
6
use Doctrine\DBAL\Connection;
7
8
9
abstract class BaseRepository
10
{
11
    /** @var \Doctrine\DBAL\Connection */
12
    protected $_con;
13
14
    /** @var int */
15
    public $totalRows = 0;
16
17
18
    /** @var array */
19
    private $_classFields = null;
20
21
22
23
    function __construct(Connection $connection) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
24
        $this->_con = $connection;
25
    }
26
27
28
    protected function _getPrimaryKeyColumnName() {
29
        return 'id';
30
    }
31
32
    protected function _isAutoincrement() {
33
        return true;
34
    }
35
36
    abstract function _getTableName();
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
37
38
39
    abstract function _getClassName();
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
40
41
42
43
    /**
44
     * @param object|array|null $row
45
     * @param string $prefix
46
     * @return object|null
47
     */
48
    function hydrateObject($row, $prefix = '') {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
49
        $result = null;
50
        if ($row) {
51
            $class = $this->_getClassName();
52
            $result = new $class();
53
            ObjectHelper::copyExistingProperties($row, $result, $prefix);
54
        }
55
        return $result;
56
    }
57
58
59
    protected function _getNonDbFields() {
60
        return array();
61
    }
62
63
64
    /**
65
     * @return array   field=>defaultValue
66
     */
67
    protected function getClassFields() {
68
        if ($this->_classFields === null) {
69
            $this->_classFields = get_class_vars($this->_getClassName());
70
            $nonDbFields = $this->_getNonDbFields();
71
            foreach ($nonDbFields as $f) {
72
                unset($this->_classFields[$f]);
73
            }
74
        }
75
76
        return $this->_classFields;
77
    }
78
79
80
    /**
81
     * @return string[]
82
     */
83
    function getFields() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
84
        $result = array();
85
        $arr = $this->getClassFields();
86
        $arr = array_keys($arr);
87
        foreach ($arr as $field) {
88
            $result[] = $field;
89
        }
90
        return $result;
91
    }
92
93
94
    /**
95
     * @param string $fieldName
96
     * @return bool
97
     */
98
    protected function hasClassField($fieldName) {
99
        $result = array_key_exists((string)$fieldName, $this->getClassFields());
100
        return $result;
101
    }
102
103
    /**
104
     * @param array $array
105
     * @param string $prefix
106
     * @return object[]
107
     */
108
    function hydrateArray(array $array, $prefix = '') {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
109
        $result = array();
110
        foreach ($array as $row) {
111
            $result[] = $this->hydrateObject($row, $prefix);
112
        }
113
        return $result;
114
    }
115
116
117
118
    /**
119
     * @return \BWC\Share\Data\Select
120
     */
121
    protected function getCommonSelect() {
122
        return $this->select();
123
    }
124
125
126
    /**
127
     * @param int $id
128
     * @return object|null
129
     */
130
    protected function _getByID($id) {
131
        $select = $this->getCommonSelect();
132
        $alias = $select->getAlias();
133
        $name = $alias ? $alias.'.id' : 'id';
134
        $row = $this->getCommonSelect()->where($name, $id)->getRow();
135
        return $this->hydrateObject($row, '');
136
    }
137
138
139
    /**
140
     * @param array $filter   column=>value
141
     * @param int $pageNum
142
     * @param int $pageSize
143
     * @param array|string|null $orderBy
144
     * @throws \InvalidArgumentException
145
     * @return object[]
146
     */
147
    protected function _getAllBy(array $filter = null, $pageNum = 0, $pageSize = 0, $orderBy = null) {
148
        $arrWhere = array();
149
        $arrKeys = array();
150
        if ($filter) {
151
            foreach ($filter as $key=>$value) {
152
                if (!$this->hasClassField($key)) {
153
                    throw new \InvalidArgumentException($key);
154
                }
155
                $arrWhere[] = "`{$key}`=:{$key}";
156
                $arrKeys[":{$key}"] = $value;
157
            }
158
        }
159
        $pageSize = intval($pageSize);
160
        $select = $this->getCommonSelect();
161
        if ($arrWhere) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $arrWhere of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
162
            $select->where($filter);
0 ignored issues
show
Bug introduced by
It seems like $filter defined by parameter $filter on line 147 can also be of type null; however, BWC\Share\Data\Select::where() does only seem to accept array|string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
163
        }
164
        if ($orderBy) {
165
            $select->sort($orderBy);
166
        }
167
        if ($pageSize) {
168
            $select->paging($pageNum, $pageSize);
169
        }
170
        $pr = $select->pagedResult();
171
        $this->totalRows = $pr->totalRows;
172
        $result = $this->hydrateArray($pr->data);
173
        return $result;
174
    }
175
176
177
178
    /**
179
     * @param object $object Entity to save
180
     * @param array|null $unsetColumns
181
     * @return int Affected rows
182
     */
183
    protected function _save($object, array $unsetColumns = null) {
184
        $data = $this->_getObjectData($object);
185
        if ($unsetColumns) {
186
            foreach ($unsetColumns as $col) {
187
                unset($data[$col]);
188
            }
189
        }
190
        foreach ($this->_getNonDbFields() as $col) {
191
            unset($data[$col]);
192
        }
193
        $pk = $this->_getPrimaryKeyColumnName();
194
        if (isset($object->$pk) && $object->$pk) {
195
            $arrID = array($pk=>$object->$pk);
196
            unset($data[$pk]);
197
            $affectedRows = $this->_con->update($this->_getTableName(), $data, $arrID);
198
        } else {
199
            $affectedRows = $this->_con->insert($this->_getTableName(), $data);
200
            if ($this->_isAutoincrement()) {
201
                $object->$pk = $this->_con->lastInsertId();
202
            }
203
        }
204
        return $affectedRows;
205
    }
206
207
    protected function _getObjectData($object)
208
    {
209
        return get_object_vars($object);
210
    }
211
212
    /**
213
     * @param null|array|string $columns
214
     * @param null|string $alias
215
     * @return Select
216
     */
217
    function select($columns = null, $alias = null) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
218
        return new Select($this->_getTableName(), $this->_con, $columns, $alias);
219
    }
220
221
222
    /**
223
     * @param $id
224
     * @return int  affected rows
225
     */
226
    function deleteByID($id) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
227
        return $this->_con->delete($this->_getTableName(), array($this->_getPrimaryKeyColumnName() => $id));
228
    }
229
230
231
    function transactional(\Closure $func) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
232
        $this->_con->transactional($func);
233
    }
234
}