Nestedset_Model::getStructureLeft()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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
Unused Code introduced by
The parameter $position is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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
Unused Code introduced by
$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 $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

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