fpietka /
Zend-Nested-Set
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 | /** |
||
| 3 | * This object is a pattern to store hieriarchical data into a SQL database. |
||
| 4 | * |
||
| 5 | * The objective is to make it easier to get a full or partial tree from the database |
||
| 6 | * with a single request. In addition, it adds multiple methods in order to |
||
| 7 | * manipulate the nested tree: |
||
| 8 | * - add() |
||
| 9 | * - delete() |
||
| 10 | * - move() |
||
| 11 | * |
||
| 12 | * methods to get results: |
||
| 13 | * - getAll() |
||
| 14 | * - getLeafs() |
||
| 15 | * - getChildren() |
||
| 16 | * |
||
| 17 | * methods to get state of elements: |
||
| 18 | * - hasChildren() |
||
| 19 | * - isRoot() |
||
| 20 | * - getLevel() |
||
| 21 | * - numberOfDescendant() |
||
| 22 | * |
||
| 23 | * methods to get those result to a specific output: |
||
| 24 | * - toArray() |
||
| 25 | * - toXml() |
||
| 26 | * - toJson() |
||
| 27 | * - toCsv() |
||
| 28 | * |
||
| 29 | * Hierarchical data are handled as an array with depth information, but is |
||
| 30 | * never outputed that way. |
||
| 31 | * |
||
| 32 | * @version 0.5 |
||
| 33 | * @author François Pietka (fpietka) |
||
| 34 | * |
||
| 35 | * Powered by Nextcode, 2009 |
||
| 36 | */ |
||
| 37 | |||
| 38 | class Nestedset_Model |
||
| 39 | { |
||
| 40 | /** |
||
| 41 | * In MySQL and PostgreSQL, 'left' and 'right' are reserved words |
||
| 42 | * |
||
| 43 | * This represent the default table structure |
||
| 44 | */ |
||
| 45 | protected $_structure = array( |
||
| 46 | 'id' => 'id', |
||
| 47 | 'name' => 'name', |
||
| 48 | 'left' => 'lft', |
||
| 49 | 'right' => 'rgt', |
||
| 50 | ); |
||
| 51 | |||
| 52 | /** |
||
| 53 | * Database informations required to locate/save the set |
||
| 54 | */ |
||
| 55 | protected $_db; |
||
| 56 | protected $_tableName; |
||
| 57 | |||
| 58 | /** |
||
| 59 | * @param $tableName|string |
||
| 60 | * |
||
| 61 | * @return $this |
||
| 62 | */ |
||
| 63 | public function setTableName($tableName) |
||
| 64 | { |
||
| 65 | if (!is_null($tableName)) { |
||
| 66 | $this->_tableName = $tableName; |
||
| 67 | } |
||
| 68 | |||
| 69 | return $this; |
||
| 70 | } |
||
| 71 | |||
| 72 | public function getTableName() |
||
| 73 | { |
||
| 74 | return $this->_tableName; |
||
| 75 | } |
||
| 76 | |||
| 77 | /** |
||
| 78 | * @param $db|Zend_Db_Adapter |
||
| 79 | * |
||
| 80 | * @return $this |
||
| 81 | */ |
||
| 82 | public function setDb(Zend_Db_Adapter_Abstract $db) |
||
| 83 | { |
||
| 84 | $this->_db = $db; |
||
| 85 | |||
| 86 | return $this; |
||
| 87 | } |
||
| 88 | |||
| 89 | public function getDb() |
||
| 90 | { |
||
| 91 | return $this->_db; |
||
| 92 | } |
||
| 93 | |||
| 94 | /** |
||
| 95 | * @param $fieldName |
||
| 96 | * |
||
| 97 | * @return $this |
||
| 98 | */ |
||
| 99 | public function setStructureId($fieldName) |
||
| 100 | { |
||
| 101 | $this->_structure['id'] = $fieldName; |
||
| 102 | return $this; |
||
| 103 | } |
||
| 104 | |||
| 105 | public function getStructureId() |
||
| 106 | { |
||
| 107 | return $this->_structure['id']; |
||
| 108 | } |
||
| 109 | |||
| 110 | /** |
||
| 111 | * @param $fieldName |
||
| 112 | * |
||
| 113 | * @return $this |
||
| 114 | */ |
||
| 115 | public function setStructureName($fieldName) |
||
| 116 | { |
||
| 117 | $this->_structure['name'] = $fieldName; |
||
| 118 | return $this; |
||
| 119 | } |
||
| 120 | |||
| 121 | public function getStructureName() |
||
| 122 | { |
||
| 123 | return $this->_structure['name']; |
||
| 124 | } |
||
| 125 | |||
| 126 | /** |
||
| 127 | * @param $fieldName |
||
| 128 | * |
||
| 129 | * @return $this |
||
| 130 | */ |
||
| 131 | public function setStructureLeft($fieldName) |
||
| 132 | { |
||
| 133 | $this->_structure['left'] = $fieldName; |
||
| 134 | return $this; |
||
| 135 | } |
||
| 136 | |||
| 137 | public function getStructureLeft() |
||
| 138 | { |
||
| 139 | return $this->_structure['left']; |
||
| 140 | } |
||
| 141 | |||
| 142 | /** |
||
| 143 | * @param $fieldName |
||
| 144 | * |
||
| 145 | * @return $this |
||
| 146 | */ |
||
| 147 | public function setStructureRight($fieldName) |
||
| 148 | { |
||
| 149 | $this->_structure['right'] = $fieldName; |
||
| 150 | return $this; |
||
| 151 | } |
||
| 152 | |||
| 153 | public function getStructureRight() |
||
| 154 | { |
||
| 155 | return $this->_structure['right']; |
||
| 156 | } |
||
| 157 | |||
| 158 | /** |
||
| 159 | * @param $name|string Name of the element |
||
| 160 | * @param $reference|int Id of the reference element |
||
| 161 | * @param $position|string Position from the reference element. Values are |
||
| 162 | * 'into', 'before', 'after'. |
||
| 163 | * |
||
| 164 | * @return $this |
||
| 165 | */ |
||
| 166 | public function add($name, $reference = null, $position = 'into') |
||
|
0 ignored issues
–
show
|
|||
| 167 | { |
||
| 168 | if (is_null($reference)) { |
||
| 169 | (new NestedSet_Model_Builder)->append($this, $name); |
||
| 170 | } else { |
||
| 171 | $reference = (int) $reference; |
||
| 172 | |||
| 173 | (new NestedSet_Model_Builder)->addInto($this, $name, $reference); |
||
| 174 | } |
||
| 175 | |||
| 176 | return $this; |
||
| 177 | } |
||
| 178 | |||
| 179 | /** |
||
| 180 | * If recursive, delete children, else children move up in the tree |
||
| 181 | * |
||
| 182 | * @param $id|int Id of the element to delete |
||
| 183 | * @param $recursive|boolean Delete element's childrens, default is true |
||
| 184 | * |
||
| 185 | * @return $this |
||
| 186 | */ |
||
| 187 | public function delete($id, $recursive = true) |
||
| 188 | { |
||
| 189 | $db = $this->getDb(); |
||
| 190 | |||
| 191 | $select = $db |
||
| 192 | ->select() |
||
| 193 | ->from($this->_tableName, array($this->_structure['id'], $this->_structure['left'], $this->_structure['right'])) |
||
| 194 | ->where($this->_structure['id'] . ' = ?', $id); |
||
| 195 | |||
| 196 | $stmt = $db->query($select); |
||
| 197 | $result = $stmt->fetch(); |
||
| 198 | |||
| 199 | if (!$result) { |
||
| 200 | return false; |
||
| 201 | } |
||
| 202 | |||
| 203 | if ($recursive) { |
||
| 204 | (new NestedSet_Model_Builder)->deleteRecursive($this, $result); |
||
| 205 | } else { |
||
| 206 | (new NestedSet_Model_Builder)->deleteNonRecursive($this, $result); |
||
| 207 | } |
||
| 208 | |||
| 209 | return $this; |
||
| 210 | } |
||
| 211 | |||
| 212 | /** |
||
| 213 | * @param $elementId|int Id of the element to move |
||
| 214 | * @param $referenceId|int Id of the reference element |
||
| 215 | * @param $position|string Position from the reference element. Values are |
||
| 216 | * 'into', 'before', 'after'. |
||
| 217 | * |
||
| 218 | * @return $this |
||
| 219 | */ |
||
| 220 | public function move($elementId, $referenceId, $position = 'into') |
||
| 221 | { |
||
| 222 | $db = $this->getDb(); |
||
|
0 ignored issues
–
show
$db is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the Loading history...
|
|||
| 223 | |||
| 224 | $reference = $this->getElement($referenceId); |
||
| 225 | $element = $this->getElement($elementId); // @TODO get one level, we don't need all this tree |
||
| 226 | |||
| 227 | // error handling |
||
| 228 | if (empty($element) || empty($reference)) { |
||
| 229 | return false; |
||
| 230 | } |
||
| 231 | |||
| 232 | switch ($position) { |
||
| 233 | case 'into': |
||
| 234 | default: |
||
| 235 | (new NestedSet_Model_Builder)->moveInto($this, $element, $reference); |
||
| 236 | } |
||
| 237 | |||
| 238 | return true; |
||
| 239 | } |
||
| 240 | |||
| 241 | /** |
||
| 242 | * Get width of a node |
||
| 243 | */ |
||
| 244 | public function getNodeWidth($elementId) |
||
| 245 | { |
||
| 246 | return (new NestedSet_Model_Reader)->getNodeWidth($this, $elementId); |
||
| 247 | } |
||
| 248 | |||
| 249 | /** |
||
| 250 | * Get all nodes without children |
||
| 251 | * |
||
| 252 | * @return array |
||
| 253 | */ |
||
| 254 | public function getLeafs() |
||
| 255 | { |
||
| 256 | return (new NestedSet_Model_Reader)->getLeafs($this); |
||
| 257 | } |
||
| 258 | |||
| 259 | /** |
||
| 260 | * Get all elements from nested set |
||
| 261 | * |
||
| 262 | * @param $depth|array Array of depth wanted. Default is all |
||
| 263 | * @param $mode|string Mode of depth selection: include/exclude |
||
| 264 | * @param $order|string Mode of sort |
||
| 265 | * |
||
| 266 | * @return array |
||
| 267 | */ |
||
| 268 | public function getAll($depth = null, $mode = 'include', $order = 'ASC') |
||
| 269 | { |
||
| 270 | return (new NestedSet_Model_Reader)->getAll($this, $depth, $mode, $order); |
||
| 271 | } |
||
| 272 | |||
| 273 | /** |
||
| 274 | * Convert a tree array (with depth) into a hierarchical array. |
||
| 275 | * |
||
| 276 | * @param $nodes|array Array with depth value. |
||
| 277 | * |
||
| 278 | * @return array |
||
| 279 | */ |
||
| 280 | public function toArray(array $nodes = array()) |
||
| 281 | { |
||
| 282 | if (empty($nodes)) { |
||
| 283 | $nodes = $this->getAll(); |
||
| 284 | } |
||
| 285 | |||
| 286 | return (new NestedSet_Model_Output)->toArray($nodes); |
||
| 287 | } |
||
| 288 | |||
| 289 | /** |
||
| 290 | * Convert a tree array (with depth) into a hierarchical XML string. |
||
| 291 | * |
||
| 292 | * @param $nodes|array Array with depth value. |
||
| 293 | * |
||
| 294 | * @return string |
||
| 295 | */ |
||
| 296 | public function toXml(array $nodes = array()) |
||
| 297 | { |
||
| 298 | if (empty($nodes)) { |
||
| 299 | $nodes = $this->getAll(); |
||
| 300 | } |
||
| 301 | |||
| 302 | return (new NestedSet_Model_Output)->toXml($nodes); |
||
| 303 | } |
||
| 304 | |||
| 305 | /** |
||
| 306 | * Return nested set as JSON |
||
| 307 | * |
||
| 308 | * @params $nodes|array Original 'flat' nested tree |
||
| 309 | * |
||
| 310 | * @return string |
||
| 311 | */ |
||
| 312 | public function toJson(array $nodes = array()) |
||
| 313 | { |
||
| 314 | if (empty($nodes)) { |
||
| 315 | $nodes = $this->getAll(); |
||
| 316 | } |
||
| 317 | |||
| 318 | return (new NestedSet_Model_Output)->toJson($nodes); |
||
| 319 | } |
||
| 320 | |||
| 321 | /** |
||
| 322 | * Returns all elements as <ul>/<li> structure |
||
| 323 | * |
||
| 324 | * Possible options: |
||
| 325 | * - list (simple <ul><li>) |
||
| 326 | * |
||
| 327 | * @return string |
||
| 328 | */ |
||
| 329 | public function toHtml(array $nodes = array(), $method = 'list') |
||
| 330 | { |
||
| 331 | if (empty($nodes)) { |
||
| 332 | $nodes = $this->getAll(); |
||
| 333 | } |
||
| 334 | |||
| 335 | return (new NestedSet_Model_Output)->toHtml($nodes, $method); |
||
| 336 | } |
||
| 337 | |||
| 338 | /** |
||
| 339 | * Public method to get an element |
||
| 340 | * |
||
| 341 | */ |
||
| 342 | public function getElement($elementId, $depth = null) |
||
| 343 | { |
||
| 344 | return (new NestedSet_Model_Reader)->getElement($this, $elementId, $depth); |
||
| 345 | } |
||
| 346 | |||
| 347 | /** |
||
| 348 | * Get path of an element |
||
| 349 | * |
||
| 350 | * @param $elementId|int Id of the element we want the path of |
||
| 351 | * |
||
| 352 | * @return array |
||
| 353 | */ |
||
| 354 | public function getPath($elementId, $order = 'ASC') |
||
| 355 | { |
||
| 356 | return (new NestedSet_Model_Reader)->getPath($this, $elementId, $order); |
||
| 357 | } |
||
| 358 | |||
| 359 | /** |
||
| 360 | * Get the parent of an element. |
||
| 361 | * |
||
| 362 | * @param $elementId|int Element ID |
||
| 363 | * @param $depth|int Depth of the parent, compared to the child. |
||
| 364 | * Default is 1 (as immediate) |
||
| 365 | * |
||
| 366 | * @return array|false |
||
| 367 | */ |
||
| 368 | public function getParent($elementId, $depth = 1) |
||
| 369 | { |
||
| 370 | return (new NestedSet_Model_Reader)->getParent($this, $elementId, $depth); |
||
| 371 | } |
||
| 372 | |||
| 373 | /** |
||
| 374 | * Returns the number of descendant of an element. |
||
| 375 | * |
||
| 376 | * @params $elementId|int ID of the element |
||
| 377 | * |
||
| 378 | * @return int |
||
| 379 | */ |
||
| 380 | public function numberOfDescendant($elementId) |
||
| 381 | { |
||
| 382 | $width = (new NestedSet_Model_Reader)->getNodeWidth($this, $elementId); |
||
| 383 | $result = ($width - 2) / 2; |
||
| 384 | |||
| 385 | return $result; |
||
| 386 | } |
||
| 387 | |||
| 388 | /** |
||
| 389 | * Returns if the element is root. |
||
| 390 | * |
||
| 391 | * @param $elementId|int Element ID |
||
| 392 | * |
||
| 393 | * @return boolean |
||
| 394 | */ |
||
| 395 | public function isRoot($elementId) |
||
| 396 | { |
||
| 397 | return (new NestedSet_Model_Reader)->isRoot($this, $elementId); |
||
| 398 | } |
||
| 399 | } |
||
| 400 |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.