Completed
Push — work-fleets ( 5c3a01...351cf4 )
by SuperNova.WS
06:40
created

EntityModel::assignAccessor()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 11
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
nc 3
nop 3
dl 11
loc 11
rs 9.4285
c 1
b 0
f 0
ccs 0
cts 10
cp 0
crap 12
1
<?php
2
3
/**
4
 * Class EntityModel
5
 *
6
 * Describes persistent entity - which can be loaded from/stored to storage
7
 *
8
 * @property int|float|string $dbId EntityModel unique ID for entire entities' set
9
 */
10
class EntityModel  {
11
  /**
12
   * Link to DB which used by this EntityModel
13
   *
14
   * @var \db_mysql $dbStatic
15
   * deprecated - replace with container ID like 'db' or 'dbAuth'
16
   */
17
  protected $dbStatic;
18
  /**
19
   * Service to work with rows
20
   *
21
   * @var \DbRowDirectOperator $rowOperator
22
   */
23
  protected $rowOperator;
24
  /**
25
   * Name of table for this entity
26
   *
27
   * @var string $tableName
28
   */
29
  protected $tableName = '_table';
30
  /**
31
   * Name of key field field in this table
32
   *
33
   * @var string $idField
34
   */
35
  protected $idField = 'id';
36
37
  /**
38
   * Name of exception class that would be thrown
39
   *
40
   * Uses for calling when you don't know which exact exception should be called
41
   * On EntityModel's children should be used exception class name
42
   *
43
   * @var string $exceptionClass
44
   */
45
  protected $exceptionClass = 'EntityException';
46
  protected $entityContainerClass = '\EntityContainer';
47
48
  /**
49
   * Property list and description
50
   *
51
   * propertyName => array(
52
   *    P_DB_FIELD => 'dbFieldName', - directly converts property to field and vice versa
53
   * )
54
   *
55
   * @var array[] $properties
56
   */
57
  protected $properties = array();
58
59
  /**
60
   * Array of accessors - getters/setters/etc
61
   *
62
   * @var callable[][]
63
   */
64
  protected $accessors = array();
65
66 View Code Duplication
  protected function assignAccessor($varName, $type, $callable) {
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...
67
    if (empty($callable)) {
68
      return;
69
    }
70
71
    if (is_callable($callable)) {
72
      $this->accessors[$varName][$type] = $callable;
73
    } else {
74
      throw new \Exception('Error assigning callable in ' . get_called_class() . '! Callable typed [' . $type . '] is not a callable or not accessible in the scope');
75
    }
76
  }
77
78
79
  /**
80
   * EntityModel constructor.
81
   *
82
   * @param \Common\GlobalContainer $gc
83
   */
84
  public function __construct($gc) {
85
    $this->dbStatic = $gc->db;
0 ignored issues
show
Documentation Bug introduced by
It seems like $gc->db can also be of type object<Closure>. However, the property $dbStatic is declared as type object<db_mysql>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
86
    $this->rowOperator = $gc->dbRowOperator;
0 ignored issues
show
Documentation Bug introduced by
It seems like $gc->dbRowOperator can also be of type object<Closure>. However, the property $rowOperator is declared as type object<DbRowDirectOperator>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
87
  }
88
89
  /**
90
   * Returns link to DB used by entity
91
   *
92
   * DB can be differ for different entity. For ex. - UNIT EntityModel will use standard DB while AUTH entity would prefer dbAuth
93
   *
94
   * @return db_mysql
95
   */
96
  public function getDbStatic() {
97
    return $this->dbStatic;
98
  }
99
100
  /**
101
   * @return \DbRowDirectOperator
102
   */
103
  public function getRowOperator() {
104
    return $this->rowOperator;
105
  }
106
107
  /**
108
   * @param string $value
109
   */
110
  public function setTableName($value) {
111
    $this->tableName = $value;
112
  }
113
114
  /**
115
   * Gets entity's table name
116
   *
117
   * @return string
118
   */
119
  public function getTableName() {
120
    return $this->tableName;
121
  }
122
123
  /**
124
   * @param string $value
125
   */
126
  public function setIdFieldName($value) {
127
    $this->idField = $value;
128
  }
129
130
  /**
131
   * Gets entity's DB ID field name (which is unique within entity set)
132
   *
133
   * @return string
134
   */
135
  public function getIdFieldName() {
136
    return $this->idField;
137
  }
138
139
140
141
142
143
  /**
144
   * @param array $array
145
   *
146
   * @return \EntityContainer
147
   */
148
  public function fromArray($array) {
149
    /**
150
     * @var EntityContainer $cEntity
151
     */
152
    $cEntity = $this->getContainer();
153
    $cEntity->importRow($array);
154
155
    return $cEntity;
156
  }
157
158
159
  /**
160
   * Exports object properties to DB row state WITHOUT ID
161
   *
162
   * Useful for INSERT operations
163
   *
164
   * @param \EntityContainer $cEntity
165
   * @return array
166
   */
167
  public function exportRow($cEntity) {
168
    return $cEntity->exportRow();
169
  }
170
171
  /**
172
   * Exports object properties to DB row state with ID
173
   *
174
   * @param \EntityContainer $cEntity
175
   * @return array
176
   */
177
  public function exportRowNoId($cEntity) {
178
    $row = $this->exportRow($cEntity);
179
180
    unset($row[$this->getIdFieldName()]);
181
182
    return $row;
183
  }
184
185
186
  /**
187
   * @return \EntityContainer
188
   */
189
  public function getContainer() {
190
    /**
191
     * @var \EntityContainer $container
192
     */
193
    $container = new $this->entityContainerClass();
194
    $container->setProperties($this->properties);
195
    $container->setAccessors($this->accessors);
196
    return $container;
197
  }
198
199
200
  /**
201
   * @param mixed $dbId
202
   *
203
   * @return \EntityContainer|false
204
   */
205
  public function loadById($dbId) {
206
    $row = $this->rowOperator->getById($this, $dbId);
207
    if (empty($row)) {
208
      return false;
209
    } else {
210
      $cEntity = $this->fromArray($row);
211
    }
212
213
    return $cEntity;
214
  }
215
216
}
217