Rozbo /
puck
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | namespace puck; |
||
| 3 | |||
| 4 | use puck\tools\Str; |
||
| 5 | |||
| 6 | class Model { |
||
| 7 | /** |
||
| 8 | * Per page limit for pagination |
||
| 9 | * |
||
| 10 | * @var int |
||
| 11 | */ |
||
| 12 | public static $pageLimit = 20; |
||
| 13 | /** |
||
| 14 | * Variable that holds total pages count of last paginate() query |
||
| 15 | * |
||
| 16 | * @var int |
||
| 17 | */ |
||
| 18 | public static $totalPages = 0; |
||
| 19 | /** |
||
| 20 | * Models path |
||
| 21 | * |
||
| 22 | * @var modelPath |
||
| 23 | */ |
||
| 24 | protected static $modelPath; |
||
| 25 | /** |
||
| 26 | * An array that holds object data |
||
| 27 | * |
||
| 28 | * @var array |
||
| 29 | */ |
||
| 30 | public $data; |
||
| 31 | /** |
||
| 32 | * Flag to define is object is new or loaded from database |
||
| 33 | * |
||
| 34 | * @var boolean |
||
| 35 | */ |
||
| 36 | public $isNew = true; |
||
| 37 | /** |
||
| 38 | * Return type: 'Array' to return results as array, 'Object' as object |
||
| 39 | * 'Json' as json string |
||
| 40 | * |
||
| 41 | * @var string |
||
| 42 | */ |
||
| 43 | public $returnType = 'Object'; |
||
| 44 | /** |
||
| 45 | * An array that holds insert/update/select errors |
||
| 46 | * |
||
| 47 | * @var array |
||
| 48 | */ |
||
| 49 | public $errors = null; |
||
| 50 | /** |
||
| 51 | * Primary key for an object. 'id' is a default value. |
||
| 52 | * |
||
| 53 | * @var stating |
||
| 54 | */ |
||
| 55 | protected $primaryKey = 'id'; |
||
| 56 | /** |
||
| 57 | * Table name for an object. Class name will be used by default |
||
| 58 | * |
||
| 59 | * @var stating |
||
| 60 | */ |
||
| 61 | protected $dbTable; |
||
| 62 | protected $dbConn = null; |
||
| 63 | protected $prefix; |
||
| 64 | /** |
||
| 65 | * Working instance of MysqliDb created earlier |
||
| 66 | * |
||
| 67 | * @var Mysql |
||
| 68 | */ |
||
| 69 | private $db; |
||
| 70 | /** |
||
| 71 | * An array that holds has* objects which should be loaded togeather with main |
||
| 72 | * object togeather with main object |
||
| 73 | * |
||
| 74 | * @var string |
||
| 75 | */ |
||
| 76 | private $_with = Array(); |
||
| 77 | |||
| 78 | /** |
||
| 79 | * @param array $data Data to preload on object creation |
||
|
0 ignored issues
–
show
|
|||
| 80 | */ |
||
| 81 | public function __construct() { |
||
| 82 | $this->db = app('db')->connect($this->dbConn); |
||
| 83 | if ($this->prefix) { |
||
| 84 | $this->db = $this->db->setPrefix($this->prefix); |
||
| 85 | } |
||
| 86 | if (!$this->dbTable) { |
||
| 87 | $classFull = get_class($this); |
||
| 88 | $classArray = explode("\\", $classFull); |
||
| 89 | $classSelf = array_pop($classArray); |
||
| 90 | $classSelf = Str::snake($classSelf); |
||
| 91 | $this->dbTable = $classSelf; |
||
|
0 ignored issues
–
show
It seems like
$classSelf of type string is incompatible with the declared type object<puck\stating> of property $dbTable.
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. Loading history...
|
|||
| 92 | } |
||
| 93 | $this->db = $this->db->table($this->dbTable); |
||
| 94 | } |
||
| 95 | |||
| 96 | /** |
||
| 97 | * Helper function to create a virtual table class |
||
| 98 | * |
||
| 99 | * @param string tableName Table name |
||
| 100 | * @return dbObject |
||
| 101 | */ |
||
| 102 | public static function table($tableName) { |
||
| 103 | $tableName = preg_replace("/[^-a-z0-9_]+/i", '', $tableName); |
||
| 104 | if (!class_exists($tableName)) |
||
| 105 | eval ("class $tableName extends dbObject {}"); |
||
|
0 ignored issues
–
show
It is generally not recommended to use
eval unless absolutely required.
On one hand, Loading history...
|
|||
| 106 | return new $tableName (); |
||
| 107 | } |
||
| 108 | |||
| 109 | /** |
||
| 110 | * Catches calls to undefined static methods. |
||
| 111 | * |
||
| 112 | * Transparently creating dbObject class to provide smooth API like name::get() name::orderBy()->get() |
||
| 113 | * |
||
| 114 | * @param string $method |
||
| 115 | * @param mixed $arg |
||
| 116 | * |
||
| 117 | * @return mixed |
||
| 118 | */ |
||
| 119 | public static function __callStatic($method, $arg) { |
||
| 120 | $obj = new static; |
||
| 121 | $result = call_user_func_array(array($obj, $method), $arg); |
||
| 122 | if (method_exists($obj, $method)) |
||
| 123 | return $result; |
||
| 124 | return $obj; |
||
| 125 | } |
||
| 126 | |||
| 127 | public static function autoload($path = null) { |
||
| 128 | if ($path) |
||
| 129 | static::$modelPath = $path . "/"; |
||
|
0 ignored issues
–
show
It seems like
$path . '/' of type string is incompatible with the declared type object<puck\modelPath> of property $modelPath.
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. Loading history...
|
|||
| 130 | else |
||
| 131 | static::$modelPath = __DIR__ . "/models/"; |
||
|
0 ignored issues
–
show
It seems like
__DIR__ . '/models/' of type string is incompatible with the declared type object<puck\modelPath> of property $modelPath.
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. Loading history...
|
|||
| 132 | spl_autoload_register("dbObject::dbObjectAutoload"); |
||
| 133 | } |
||
| 134 | |||
| 135 | private static function dbObjectAutoload($classname) { |
||
|
0 ignored issues
–
show
|
|||
| 136 | $filename = static::$modelPath . $classname . ".php"; |
||
| 137 | if (file_exists($filename)) |
||
| 138 | include($filename); |
||
| 139 | } |
||
| 140 | |||
| 141 | /** |
||
| 142 | * Magic getter function |
||
| 143 | * |
||
| 144 | * @param $name Variable name |
||
| 145 | * |
||
| 146 | * @return mixed |
||
| 147 | */ |
||
| 148 | public function __get($name) { |
||
| 149 | if (property_exists($this, 'hidden') && array_search($name, $this->hidden) !== false) |
||
|
0 ignored issues
–
show
The property
hidden does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 150 | return null; |
||
| 151 | |||
| 152 | if (isset ($this->data[$name]) && $this->data[$name] instanceof dbObject) |
||
|
0 ignored issues
–
show
The class
puck\dbObject does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed. Loading history...
|
|||
| 153 | return $this->data[$name]; |
||
| 154 | |||
| 155 | if (property_exists($this, 'relations') && isset ($this->relations[$name])) { |
||
|
0 ignored issues
–
show
The property
relations does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 156 | $relationType = strtolower($this->relations[$name][0]); |
||
|
0 ignored issues
–
show
The property
relations does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 157 | $modelName = $this->relations[$name][1]; |
||
|
0 ignored issues
–
show
The property
relations does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 158 | switch ($relationType) { |
||
| 159 | case 'hasone': |
||
| 160 | $key = isset ($this->relations[$name][2]) ? $this->relations[$name][2] : $name; |
||
|
0 ignored issues
–
show
The property
relations does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 161 | $obj = new $modelName; |
||
| 162 | $obj->returnType = $this->returnType; |
||
| 163 | return $this->data[$name] = $obj->byId($this->data[$key]); |
||
| 164 | break; |
||
|
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. Loading history...
|
|||
| 165 | case 'hasmany': |
||
| 166 | $key = $this->relations[$name][2]; |
||
|
0 ignored issues
–
show
The property
relations does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 167 | $obj = new $modelName; |
||
| 168 | $obj->returnType = $this->returnType; |
||
| 169 | return $this->data[$name] = $obj->where($key, $this->data[$this->primaryKey])->get(); |
||
| 170 | break; |
||
|
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. Loading history...
|
|||
| 171 | default: |
||
| 172 | break; |
||
| 173 | } |
||
| 174 | } |
||
| 175 | |||
| 176 | if (isset ($this->data[$name])) |
||
| 177 | return $this->data[$name]; |
||
| 178 | |||
| 179 | if (property_exists($this->db, $name)) |
||
| 180 | return $this->db->$name; |
||
| 181 | } |
||
| 182 | |||
| 183 | /** |
||
| 184 | * Magic setter function |
||
| 185 | * |
||
| 186 | * @return mixed |
||
| 187 | */ |
||
| 188 | public function __set($name, $value) { |
||
| 189 | if (property_exists($this, 'hidden') && array_search($name, $this->hidden) !== false) |
||
|
0 ignored issues
–
show
The property
hidden does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 190 | return; |
||
| 191 | |||
| 192 | $this->data[$name] = $value; |
||
| 193 | } |
||
| 194 | |||
| 195 | public function __isset($name) { |
||
| 196 | if (isset ($this->data[$name])) |
||
| 197 | return isset ($this->data[$name]); |
||
| 198 | |||
| 199 | if (property_exists($this->db, $name)) |
||
| 200 | return isset ($this->db->$name); |
||
| 201 | } |
||
| 202 | |||
| 203 | public function __unset($name) { |
||
| 204 | unset ($this->data[$name]); |
||
| 205 | } |
||
| 206 | |||
| 207 | /** |
||
| 208 | * Save or Update object |
||
| 209 | * |
||
| 210 | * @return mixed insert id or false in case of failure |
||
| 211 | */ |
||
| 212 | public function save($data = null) { |
||
| 213 | if ($this->isNew) |
||
| 214 | return $this->insert(); |
||
| 215 | return $this->update($data); |
||
| 216 | } |
||
| 217 | |||
| 218 | /** |
||
| 219 | * @return mixed insert id or false in case of failure |
||
| 220 | */ |
||
| 221 | public function insert() { |
||
| 222 | if (!empty ($this->timestamps) && in_array("createdAt", $this->timestamps)) |
||
|
0 ignored issues
–
show
The property
timestamps does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 223 | $this->createdAt = date("Y-m-d H:i:s"); |
||
|
0 ignored issues
–
show
The property
createdAt does not exist on object<puck\Model>. Since you implemented __set, maybe consider adding a @property annotation.
Since your code implements the magic setter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
Since the property has write access only, you can use the @property-write annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 224 | $sqlData = $this->prepareData(); |
||
| 225 | if (!$this->validate($sqlData)) |
||
| 226 | return false; |
||
| 227 | |||
| 228 | $id = $this->db->insert($this->dbTable, $sqlData); |
||
| 229 | if (!empty ($this->primaryKey) && empty ($this->data[$this->primaryKey])) |
||
| 230 | $this->data[$this->primaryKey] = $id; |
||
| 231 | $this->isNew = false; |
||
| 232 | |||
| 233 | return $id; |
||
| 234 | } |
||
| 235 | |||
| 236 | private function prepareData() { |
||
| 237 | $this->errors = Array(); |
||
| 238 | $sqlData = Array(); |
||
| 239 | if (count($this->data) == 0) |
||
| 240 | return Array(); |
||
| 241 | |||
| 242 | if (method_exists($this, "preLoad")) |
||
| 243 | $this->preLoad($this->data); |
||
|
0 ignored issues
–
show
The method
preLoad does not exist on object<puck\Model>? Since you implemented __call, maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
Loading history...
|
|||
| 244 | |||
| 245 | if (!$this->dbFields) |
||
|
0 ignored issues
–
show
The property
dbFields does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 246 | return $this->data; |
||
| 247 | |||
| 248 | foreach ($this->data as $key => &$value) { |
||
| 249 | if ($value instanceof dbObject && $value->isNew == true) { |
||
|
0 ignored issues
–
show
The class
puck\dbObject does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed. Loading history...
|
|||
| 250 | $id = $value->save(); |
||
| 251 | if ($id) |
||
| 252 | $value = $id; |
||
| 253 | else |
||
| 254 | $this->errors = array_merge($this->errors, $value->errors); |
||
| 255 | } |
||
| 256 | |||
| 257 | if (!in_array($key, array_keys($this->dbFields))) |
||
|
0 ignored issues
–
show
The property
dbFields does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 258 | continue; |
||
| 259 | |||
| 260 | if (!is_array($value)) { |
||
| 261 | $sqlData[$key] = $value; |
||
| 262 | continue; |
||
| 263 | } |
||
| 264 | |||
| 265 | if (isset ($this->jsonFields) && in_array($key, $this->jsonFields)) |
||
|
0 ignored issues
–
show
The property
jsonFields does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 266 | $sqlData[$key] = json_encode($value); |
||
| 267 | else if (isset ($this->arrayFields) && in_array($key, $this->arrayFields)) |
||
|
0 ignored issues
–
show
The property
arrayFields does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 268 | $sqlData[$key] = implode("|", $value); |
||
| 269 | else |
||
| 270 | $sqlData[$key] = $value; |
||
| 271 | } |
||
| 272 | return $sqlData; |
||
| 273 | } |
||
| 274 | |||
| 275 | /** |
||
| 276 | * @param array $data |
||
| 277 | */ |
||
| 278 | private function validate($data) { |
||
| 279 | if (!$this->dbFields) |
||
|
0 ignored issues
–
show
The property
dbFields does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 280 | return true; |
||
| 281 | |||
| 282 | foreach ($this->dbFields as $key => $desc) { |
||
|
0 ignored issues
–
show
The property
dbFields does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 283 | $type = null; |
||
| 284 | $required = false; |
||
| 285 | if (isset ($data[$key])) |
||
| 286 | $value = $data[$key]; |
||
| 287 | else |
||
| 288 | $value = null; |
||
| 289 | |||
| 290 | if (is_array($value)) |
||
| 291 | continue; |
||
| 292 | |||
| 293 | if (isset ($desc[0])) |
||
| 294 | $type = $desc[0]; |
||
| 295 | if (isset ($desc[1]) && ($desc[1] == 'required')) |
||
| 296 | $required = true; |
||
| 297 | |||
| 298 | if ($required && strlen($value) == 0) { |
||
| 299 | $this->errors[] = Array($this->dbTable . "." . $key => "is required"); |
||
| 300 | continue; |
||
| 301 | } |
||
| 302 | if ($value == null) |
||
| 303 | continue; |
||
| 304 | |||
| 305 | switch ($type) { |
||
| 306 | case "text"; |
||
|
0 ignored issues
–
show
case statements should be defined using a colon.
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces.
There is no need for braces, since each case is terminated by the next There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages. switch ($expr) {
case "A": { //wrong
doSomething();
break;
}
case "B"; //wrong
doSomething();
break;
case "C": //right
doSomething();
break;
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. Loading history...
|
|||
| 307 | $regexp = null; |
||
| 308 | break; |
||
| 309 | case "int": |
||
| 310 | $regexp = "/^[0-9]*$/"; |
||
| 311 | break; |
||
| 312 | case "double": |
||
| 313 | $regexp = "/^[0-9\.]*$/"; |
||
| 314 | break; |
||
| 315 | case "bool": |
||
| 316 | $regexp = '/^[yes|no|0|1|true|false]$/i'; |
||
| 317 | break; |
||
| 318 | case "datetime": |
||
| 319 | $regexp = "/^[0-9a-zA-Z -:]*$/"; |
||
| 320 | break; |
||
| 321 | default: |
||
| 322 | $regexp = $type; |
||
| 323 | break; |
||
| 324 | } |
||
| 325 | if (!$regexp) |
||
| 326 | continue; |
||
| 327 | |||
| 328 | if (!preg_match($regexp, $value)) { |
||
| 329 | $this->errors[] = Array($this->dbTable . "." . $key => "$type validation failed"); |
||
| 330 | continue; |
||
| 331 | } |
||
| 332 | } |
||
| 333 | return !count($this->errors) > 0; |
||
| 334 | } |
||
| 335 | |||
| 336 | /** |
||
| 337 | * @param array $data Optional update data to apply to the object |
||
| 338 | */ |
||
| 339 | public function update($data = null) { |
||
| 340 | if (empty ($this->dbFields)) |
||
|
0 ignored issues
–
show
The property
dbFields does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 341 | return false; |
||
| 342 | |||
| 343 | if (empty ($this->data[$this->primaryKey])) |
||
| 344 | return false; |
||
| 345 | |||
| 346 | if ($data) { |
||
| 347 | foreach ($data as $k => $v) |
||
| 348 | $this->$k = $v; |
||
| 349 | } |
||
| 350 | |||
| 351 | if (!empty ($this->timestamps) && in_array("updatedAt", $this->timestamps)) |
||
|
0 ignored issues
–
show
The property
timestamps does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 352 | $this->updatedAt = date("Y-m-d H:i:s"); |
||
|
0 ignored issues
–
show
The property
updatedAt does not exist on object<puck\Model>. Since you implemented __set, maybe consider adding a @property annotation.
Since your code implements the magic setter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
Since the property has write access only, you can use the @property-write annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 353 | |||
| 354 | $sqlData = $this->prepareData(); |
||
| 355 | if (!$this->validate($sqlData)) |
||
| 356 | return false; |
||
| 357 | |||
| 358 | $this->db->where($this->primaryKey, $this->data[$this->primaryKey]); |
||
| 359 | return $this->db->update($this->dbTable, $sqlData); |
||
|
0 ignored issues
–
show
$sqlData is of type array, but the function expects a integer|null.
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
| 360 | } |
||
| 361 | |||
| 362 | /** |
||
| 363 | * Delete method. Works only if object primaryKey is defined |
||
| 364 | * |
||
| 365 | * @return boolean Indicates success. 0 or 1. |
||
| 366 | */ |
||
| 367 | public function delete() { |
||
| 368 | if (empty ($this->data[$this->primaryKey])) |
||
| 369 | return false; |
||
| 370 | |||
| 371 | $this->db->where($this->primaryKey, $this->data[$this->primaryKey]); |
||
| 372 | return $this->db->delete($this->dbTable); |
||
| 373 | } |
||
| 374 | |||
| 375 | /** |
||
| 376 | * 当执行一个自身不存在的方法时,重定向到mysql类中去 |
||
| 377 | * |
||
| 378 | * @param string $method |
||
| 379 | * @param mixed $arg |
||
| 380 | * |
||
| 381 | * @return mixed |
||
| 382 | */ |
||
| 383 | public function __call($method, $arg) { |
||
| 384 | if (method_exists($this, $method)) |
||
| 385 | return call_user_func_array(array($this, $method), $arg); |
||
| 386 | $this->db->table($this->dbTable); |
||
| 387 | return call_user_func_array(array($this->db, $method), $arg);; |
||
| 388 | } |
||
| 389 | |||
| 390 | /** |
||
| 391 | * Converts object data to a JSON string. |
||
| 392 | * |
||
| 393 | * @return string Converted data |
||
| 394 | */ |
||
| 395 | public function __toString() { |
||
| 396 | return $this->toJson(); |
||
| 397 | } |
||
| 398 | |||
| 399 | /** |
||
| 400 | * Converts object data to a JSON string. |
||
| 401 | * |
||
| 402 | * @return string Converted data |
||
| 403 | */ |
||
| 404 | public function toJson() { |
||
| 405 | return json_encode($this->toArray()); |
||
| 406 | } |
||
| 407 | |||
| 408 | /** |
||
| 409 | * Converts object data to an associative array. |
||
| 410 | * |
||
| 411 | * @return array Converted data |
||
| 412 | */ |
||
| 413 | public function toArray() { |
||
| 414 | $data = $this->data; |
||
| 415 | $this->processAllWith($data); |
||
| 416 | foreach ($data as &$d) { |
||
| 417 | if ($d instanceof dbObject) |
||
|
0 ignored issues
–
show
The class
puck\dbObject does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed. Loading history...
|
|||
| 418 | $d = $d->data; |
||
| 419 | } |
||
| 420 | return $data; |
||
| 421 | } |
||
| 422 | |||
| 423 | /** |
||
| 424 | * Function queries hasMany relations if needed and also converts hasOne object names |
||
| 425 | * |
||
| 426 | * @param array $data |
||
| 427 | */ |
||
| 428 | private function processAllWith(&$data, $shouldReset = true) { |
||
| 429 | if (count($this->_with) == 0) |
||
| 430 | return; |
||
| 431 | |||
| 432 | foreach ($this->_with as $name => $opts) { |
||
|
0 ignored issues
–
show
|
|||
| 433 | $relationType = strtolower($opts[0]); |
||
| 434 | $modelName = $opts[1]; |
||
| 435 | if ($relationType == 'hasone') { |
||
| 436 | $obj = new $modelName; |
||
| 437 | $table = $obj->dbTable; |
||
| 438 | $primaryKey = $obj->primaryKey; |
||
| 439 | |||
| 440 | if (!isset ($data[$table])) { |
||
| 441 | $data[$name] = $this->$name; |
||
| 442 | continue; |
||
| 443 | } |
||
| 444 | if ($data[$table][$primaryKey] === null) { |
||
| 445 | $data[$name] = null; |
||
| 446 | } else { |
||
| 447 | if ($this->returnType == 'Object') { |
||
| 448 | $item = new $modelName ($data[$table]); |
||
| 449 | $item->returnType = $this->returnType; |
||
| 450 | $item->isNew = false; |
||
| 451 | $data[$name] = $item; |
||
| 452 | } else { |
||
| 453 | $data[$name] = $data[$table]; |
||
| 454 | } |
||
| 455 | } |
||
| 456 | unset ($data[$table]); |
||
| 457 | } else |
||
| 458 | $data[$name] = $this->$name; |
||
| 459 | } |
||
| 460 | if ($shouldReset) |
||
| 461 | $this->_with = Array(); |
||
|
0 ignored issues
–
show
It seems like
array() of type array is incompatible with the declared type string of property $_with.
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. Loading history...
|
|||
| 462 | } |
||
| 463 | |||
| 464 | /** |
||
| 465 | * Fetch all objects |
||
| 466 | * |
||
| 467 | * @access public |
||
| 468 | * @param integer|array $limit Array to define SQL limit in format Array ($count, $offset) |
||
| 469 | * or only $count |
||
| 470 | * @param array|string $fields Array or coma separated list of fields to fetch |
||
| 471 | * |
||
| 472 | * @return array Array of dbObjects |
||
| 473 | */ |
||
| 474 | protected function get($limit = null, $fields = null) { |
||
| 475 | $objects = Array(); |
||
| 476 | $this->processHasOneWith(); |
||
| 477 | $results = $this->db->ArrayBuilder()->get($this->dbTable, $limit, $fields); |
||
|
0 ignored issues
–
show
It seems like
$fields defined by parameter $fields on line 474 can also be of type array or null; however, puck\Mysql::get() does only seem to accept 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...
|
|||
| 478 | if ($this->db->count == 0) |
||
| 479 | return null; |
||
| 480 | |||
| 481 | foreach ($results as &$r) { |
||
|
0 ignored issues
–
show
The expression
$results of type object<puck\Mysql>|array is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
Loading history...
|
|||
| 482 | $this->processArrays($r); |
||
| 483 | $this->data = $r; |
||
| 484 | $this->processAllWith($r, false); |
||
| 485 | if ($this->returnType == 'Object') { |
||
| 486 | $item = new static ($r); |
||
|
0 ignored issues
–
show
The call to
Model::__construct() has too many arguments starting with $r.
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the Loading history...
|
|||
| 487 | $item->isNew = false; |
||
| 488 | $objects[] = $item; |
||
| 489 | } |
||
| 490 | } |
||
| 491 | $this->_with = Array(); |
||
|
0 ignored issues
–
show
It seems like
array() of type array is incompatible with the declared type string of property $_with.
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. Loading history...
|
|||
| 492 | if ($this->returnType == 'Object') |
||
| 493 | return $objects; |
||
| 494 | |||
| 495 | if ($this->returnType == 'Json') |
||
| 496 | return json_encode($results); |
||
| 497 | |||
| 498 | return $results; |
||
| 499 | } |
||
| 500 | |||
| 501 | private function processHasOneWith() { |
||
| 502 | if (count($this->_with) == 0) |
||
| 503 | return; |
||
| 504 | foreach ($this->_with as $name => $opts) { |
||
|
0 ignored issues
–
show
|
|||
| 505 | $relationType = strtolower($opts[0]); |
||
| 506 | $modelName = $opts[1]; |
||
| 507 | $key = null; |
||
| 508 | if (isset ($opts[2])) |
||
| 509 | $key = $opts[2]; |
||
| 510 | if ($relationType == 'hasone') { |
||
| 511 | $this->db->setQueryOption("MYSQLI_NESTJOIN"); |
||
| 512 | $this->join($modelName, $key); |
||
| 513 | } |
||
| 514 | } |
||
| 515 | } |
||
| 516 | |||
| 517 | /** |
||
| 518 | * Function to join object with another object. |
||
| 519 | * |
||
| 520 | * @access public |
||
| 521 | * @param string $objectName Object Name |
||
| 522 | * @param string $key Key for a join from primary object |
||
| 523 | * @param string $joinType SQL join type: LEFT, RIGHT, INNER, OUTER |
||
| 524 | * @param string $primaryKey SQL join On Second primaryKey |
||
| 525 | * |
||
| 526 | * @return dbObject |
||
| 527 | */ |
||
| 528 | private function join($objectName, $key = null, $joinType = 'LEFT', $primaryKey = null) { |
||
| 529 | $joinObj = new $objectName; |
||
| 530 | if (!$key) |
||
|
0 ignored issues
–
show
The expression
$key of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
|
|||
| 531 | $key = $objectName . "id"; |
||
| 532 | |||
| 533 | if (!$primaryKey) |
||
|
0 ignored issues
–
show
The expression
$primaryKey of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
|
|||
| 534 | $primaryKey = $this->db->getPrefix() . $joinObj->dbTable . "." . $joinObj->primaryKey; |
||
| 535 | |||
| 536 | if (!strchr($key, '.')) |
||
| 537 | $joinStr = $this->db->getPrefix() . $this->dbTable . ".{$key} = " . $primaryKey; |
||
| 538 | else |
||
| 539 | $joinStr = $this->db->getPrefix() . "{$key} = " . $primaryKey; |
||
| 540 | |||
| 541 | $this->db->join($joinObj->dbTable, $joinStr, $joinType); |
||
| 542 | return $this; |
||
| 543 | } |
||
| 544 | |||
| 545 | /** |
||
| 546 | * @param array $data |
||
| 547 | */ |
||
| 548 | private function processArrays(&$data) { |
||
| 549 | if (isset ($this->jsonFields) && is_array($this->jsonFields)) { |
||
|
0 ignored issues
–
show
The property
jsonFields does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 550 | foreach ($this->jsonFields as $key) |
||
|
0 ignored issues
–
show
The property
jsonFields does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 551 | $data[$key] = json_decode($data[$key]); |
||
| 552 | } |
||
| 553 | |||
| 554 | if (isset ($this->arrayFields) && is_array($this->arrayFields)) { |
||
|
0 ignored issues
–
show
The property
arrayFields does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 555 | foreach ($this->arrayFields as $key) |
||
|
0 ignored issues
–
show
The property
arrayFields does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 556 | $data[$key] = explode("|", $data[$key]); |
||
| 557 | } |
||
| 558 | } |
||
| 559 | |||
| 560 | /** |
||
| 561 | * Function to get a total records count |
||
| 562 | * |
||
| 563 | * @return int |
||
| 564 | */ |
||
| 565 | protected function count() { |
||
| 566 | $res = $this->db->ArrayBuilder()->getValue($this->dbTable, "count(*)"); |
||
| 567 | if (!$res) |
||
| 568 | return 0; |
||
| 569 | return $res; |
||
| 570 | } |
||
| 571 | |||
| 572 | /** |
||
| 573 | * Helper function to create dbObject with Json return type |
||
| 574 | * |
||
| 575 | * @return dbObject |
||
| 576 | */ |
||
| 577 | private function JsonBuilder() { |
||
| 578 | $this->returnType = 'Json'; |
||
| 579 | return $this; |
||
| 580 | } |
||
| 581 | |||
| 582 | /* |
||
| 583 | * Function building hasOne joins for get/getOne method |
||
| 584 | */ |
||
| 585 | |||
| 586 | /** |
||
| 587 | * Helper function to create dbObject with Array return type |
||
| 588 | * |
||
| 589 | * @return dbObject |
||
| 590 | */ |
||
| 591 | private function ArrayBuilder() { |
||
| 592 | $this->returnType = 'Array'; |
||
| 593 | return $this; |
||
| 594 | } |
||
| 595 | |||
| 596 | /** |
||
| 597 | * Helper function to create dbObject with Object return type. |
||
| 598 | * Added for consistency. Works same way as new $objname () |
||
| 599 | * |
||
| 600 | * @return dbObject |
||
| 601 | */ |
||
| 602 | private function ObjectBuilder() { |
||
| 603 | $this->returnType = 'Object'; |
||
| 604 | return $this; |
||
| 605 | } |
||
| 606 | |||
| 607 | /** |
||
| 608 | * Get object by primary key. |
||
| 609 | * |
||
| 610 | * @access public |
||
| 611 | * @param $id Primary Key |
||
| 612 | * @param array|string $fields Array or coma separated list of fields to fetch |
||
| 613 | * |
||
| 614 | * @return dbObject|array |
||
| 615 | */ |
||
| 616 | private function byId($id, $fields = null) { |
||
| 617 | $this->db->where($this->db->getPrefix() . $this->dbTable . '.' . $this->primaryKey, $id); |
||
| 618 | return $this->getOne($fields); |
||
| 619 | } |
||
| 620 | |||
| 621 | /** |
||
| 622 | * Convinient function to fetch one object. Mostly will be togeather with where() |
||
| 623 | * |
||
| 624 | * @access public |
||
| 625 | * @param array|string $fields Array or coma separated list of fields to fetch |
||
| 626 | * |
||
| 627 | * @return dbObject |
||
| 628 | */ |
||
| 629 | protected function getOne($fields = null) { |
||
| 630 | $this->processHasOneWith(); |
||
| 631 | $results = $this->db->ArrayBuilder()->getOne($this->dbTable, $fields); |
||
|
0 ignored issues
–
show
It seems like
$fields defined by parameter $fields on line 629 can also be of type array or null; however, puck\Mysql::getOne() does only seem to accept 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...
|
|||
| 632 | if ($this->db->count == 0) |
||
| 633 | return null; |
||
| 634 | |||
| 635 | $this->processArrays($results); |
||
| 636 | $this->data = $results; |
||
| 637 | $this->processAllWith($results); |
||
| 638 | if ($this->returnType == 'Json') |
||
| 639 | return json_encode($results); |
||
| 640 | if ($this->returnType == 'Array') |
||
| 641 | return $results; |
||
|
0 ignored issues
–
show
The return type of
return $results; (array) is incompatible with the return type documented by puck\Model::getOne of type puck\dbObject.
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function Loading history...
|
|||
| 642 | |||
| 643 | $item = new static ($results); |
||
|
0 ignored issues
–
show
The call to
Model::__construct() has too many arguments starting with $results.
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the Loading history...
|
|||
| 644 | $item->isNew = false; |
||
| 645 | |||
| 646 | return $item; |
||
|
0 ignored issues
–
show
The return type of
return $item; (puck\Model) is incompatible with the return type documented by puck\Model::getOne of type puck\dbObject.
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function Loading history...
|
|||
| 647 | } |
||
| 648 | |||
| 649 | /** |
||
| 650 | * Function to set witch hasOne or hasMany objects should be loaded togeather with a main object |
||
| 651 | * |
||
| 652 | * @access public |
||
| 653 | * @param string $objectName Object Name |
||
| 654 | * |
||
| 655 | * @return dbObject |
||
| 656 | */ |
||
| 657 | private function with($objectName) { |
||
| 658 | if (!property_exists($this, 'relations') && !isset ($this->relations[$name])) |
||
|
0 ignored issues
–
show
The property
relations does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
The variable
$name seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?
This check looks for calls to This is most likely caused by the renaming of a variable or the removal of a function/method parameter. Loading history...
|
|||
| 659 | die ("No relation with name $objectName found"); |
||
|
0 ignored issues
–
show
The method
with() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an Loading history...
|
|||
| 660 | |||
| 661 | $this->_with[$objectName] = $this->relations[$objectName]; |
||
|
0 ignored issues
–
show
The property
relations does not exist on object<puck\Model>. Since you implemented __get, maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. Loading history...
|
|||
| 662 | |||
| 663 | return $this; |
||
| 664 | } |
||
| 665 | |||
| 666 | /* |
||
| 667 | * Enable models autoload from a specified path |
||
| 668 | * |
||
| 669 | * Calling autoload() without path will set path to dbObjectPath/models/ directory |
||
| 670 | * |
||
| 671 | * @param string $path |
||
| 672 | */ |
||
| 673 | |||
| 674 | /** |
||
| 675 | * Pagination wraper to get() |
||
| 676 | * |
||
| 677 | * @access public |
||
| 678 | * @param int $page Page number |
||
| 679 | * @param array|string $fields Array or coma separated list of fields to fetch |
||
| 680 | * @return array |
||
| 681 | */ |
||
| 682 | private function paginate($page, $fields = null) { |
||
| 683 | $this->db->pageLimit = self::$pageLimit; |
||
| 684 | $res = $this->db->paginate($this->dbTable, $page, $fields); |
||
|
0 ignored issues
–
show
|
|||
| 685 | self::$totalPages = $this->db->totalPages; |
||
| 686 | if ($this->db->count == 0) return null; |
||
| 687 | |||
| 688 | foreach ($res as &$r) { |
||
|
0 ignored issues
–
show
The expression
$res of type object<puck\Mysql>|array is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
Loading history...
|
|||
| 689 | $this->processArrays($r); |
||
| 690 | $this->data = $r; |
||
| 691 | $this->processAllWith($r, false); |
||
| 692 | if ($this->returnType == 'Object') { |
||
| 693 | $item = new static ($r); |
||
|
0 ignored issues
–
show
The call to
Model::__construct() has too many arguments starting with $r.
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the Loading history...
|
|||
| 694 | $item->isNew = false; |
||
| 695 | $objects[] = $item; |
||
|
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$objects was never initialized. Although not strictly required by PHP, it is generally a good practice to add $objects = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. Loading history...
|
|||
| 696 | } |
||
| 697 | } |
||
| 698 | $this->_with = Array(); |
||
|
0 ignored issues
–
show
It seems like
array() of type array is incompatible with the declared type string of property $_with.
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. Loading history...
|
|||
| 699 | if ($this->returnType == 'Object') |
||
| 700 | return $objects; |
||
|
0 ignored issues
–
show
The variable
$objects does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
Loading history...
|
|||
| 701 | |||
| 702 | if ($this->returnType == 'Json') |
||
| 703 | return json_encode($res); |
||
| 704 | |||
| 705 | return $res; |
||
| 706 | } |
||
| 707 | |||
| 708 | public function clear() { |
||
| 709 | $this->data=[]; |
||
| 710 | $this->isNew=true; |
||
| 711 | } |
||
| 712 | } |
||
| 713 |
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.
Consider the following example. The parameter
$italyis not defined by the methodfinale(...).The most likely cause is that the parameter was removed, but the annotation was not.