Completed
Branch CASC/store-to-db (67966b)
by
unknown
17:39 queued 08:43
created

ModelObjNodeTreeDTO   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 148
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 148
rs 10
c 0
b 0
f 0
wmc 12
lcom 1
cbo 1

6 Methods

Rating   Name   Duplication   Size   Complexity  
A initializeRootNodes() 0 18 4
A loadData() 0 4 1
A getData() 0 4 1
A addDiscoveredItem() 0 9 1
A getIndexPath() 0 4 1
A getCurrentItemList() 0 17 4
1
<?php
2
3
namespace EventEspresso\core\services\orm\tree_traversal;
4
5
use EE_Base_Class;
6
use Exception;
7
8
/**
9
 * Class ModelObjNodeTreeDTO
10
 *
11
 * Class for storing the discovered tree of model object dependencies. It is stored in a format that can be easily and
12
 * efficiently serialized for persistence, and unserialized with minimal memory usage, and so we can pickup where
13
 * we left off.
14
 * A tree of objects would be more convenient (my original implementation used that) but we'd need to either unserialize
15
 * to a PHP array and then ALSO build that data structure (which would be trouble when there could be thousands of
16
 * entries); or we'd need to write our own parser (which was fun excercise in school, but no thank you.)
17
 *
18
 * @package     Event Espresso
19
 * @author         Mike Nelson
20
 * @since         $VID:$
21
 *
22
 */
23
class ModelObjNodeTreeDTO
24
{
25
    const INDEX_PATH = 'ip';
26
    const ROOTS = 'rts';
27
    const MODEL = 'm';
28
    const ITEMS = 'i';
29
    const ID = 'id';
30
    const RELATIONSHIPS = 'r';
31
    const COUNT = 'c';
32
    /**
33
     * @var array with a special structure. Like the following:
34
     * {
35
     *  "index_path": [0,3,1,2],
36
     *  "roots": [
37
     *      {
38
     *          "model": "Event",
39
     *          "items": [
40
     *              {
41
     *                  "id": 123,
42
     *                  "rels": [
43
     *                      {
44
     *                          "model": "Datetime"
45
     *                          "count": 3
46
     *                          "items": [
47
     *                              {
48
     *                                  "id": 456,
49
     *                                  "rels": [
50
     *                                      {
51
     *                                          "model": "Datetime_Ticket",
52
     *                                          "count": 1,
53
     *                                          "items": [
54
     *                                              {
55
     *                                                  "id": 789,
56
     *                                                  "rels": [
57
     *                                                      {
58
     *                                                          "model": "Extra_Meta",
59
     *                                                          "count": 0,
60
     *                                                          "items":[],
61
     *                                                      }
62
     *                                                      // ... other models that have foreign keys to Datetime_Ticket
63
     *                                                  ]
64
     *                                              }.
65
     *                                          ]
66
     *                                      },
67
     *                                      // ... other models that have foreign keys to Datetime
68
     *                                  ]
69
     *                              },
70
     *                              // ... 2 more datetimes (unless we haven't fetched them from the DB yet. The count
71
     *                              // is useful here to know if we need to fetch more or not
72
     *                          ]
73
     *                      },
74
     *                      //  ...other models that have foreign keys to events, including implicit join models
75
     *                  ]
76
     *              },
77
     *              // ...other root events that we want to traverse
78
     *          ],
79
     *          /// ...other models with root nodes
80
     *      }
81
     */
82
    protected $data;
83
84
    /**
85
     * @since $VID:$
86
     * @param EE_Base_Class[] $model_objs
87
     */
88
    public function initializeRootNodes($model_objs){
89
        $this->data = [
90
            self::INDEX_PATH => [0,0],
91
            self::ROOTS => []
92
        ];
93
        foreach($model_objs as $model_obj) {
94
            if (!$model_obj instanceof EE_Base_Class) {
95
                throw new \InvalidArgumentException(esc_html__('You must initialize a ModelObjNodeTreeDTO with an array of EE_Base_Class.', 'event_espresso'));
96
            }
97
            if (!isset($this->data[ self::ROOTS ])){
98
                $this->data[ self::ROOTS ][ $model_obj->get_model()->get_this_model_name() ] = [];
99
            }
100
            $this->data[self::ROOTS][$model_obj->get_model()->get_this_model_name()][] = [
101
                self::ID => $model_obj->ID(),
102
                self::RELATIONSHIPS => []
103
            ];
104
        }
105
    }
106
107
    /**
108
     * @since $VID:$
109
     * @param array $data
110
     */
111
    public function loadData(&$data)
112
    {
113
        $this->data = $data;
114
    }
115
116
    /**
117
     * Returns a reference to the data (so it's not duplicated, because it could be really big).
118
     * @since $VID:$
119
     * @return array
120
     */
121
    public function &getData()
122
    {
123
        return $this->data;
124
    }
125
126
    /**
127
     * @since $VID:$
128
     * @param EE_Base_Class $model_obj
129
     */
130
    public function addDiscoveredItem($model_obj){
131
        // Figure out where our current spot in the tree.
132
        $current_items_list = $this->getCurrentItemList();
0 ignored issues
show
Unused Code introduced by
$current_items_list 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...
133
134
        // Ensure the data is of the correct type.
135
136
        // Add data that corresponds to it to that spot.
137
138
    }
139
140
    /**
141
     * Returns a list of indexes to follow.
142
     * @since $VID:$
143
     * @return array
144
     */
145
    protected function getIndexPath()
146
    {
147
        return $this->data[self::INDEX_PATH];
148
    }
149
150
    /**
151
     * @since $VID:$
152
     */
153
    public function getCurrentItemList()
154
    {
155
        $traverser = &$this->data[ self::ROOTS ];
156
        foreach ($this->getIndexPath() as $index) {
157
            if (isset($traverser[ $index ])) {
158
                if (isset($traverser[ $index ][ self::ID ])) {
159
                    $traverser = &$traverser[ $index ][ self::RELATIONSHIPS ];
160
                } else {
161
                    $traverser = &$traverser[ $index ][ self::ITEMS ];
162
                }
163
164
            } else {
165
                throw new Exception(esc_html__('Index out of sync', 'event_espresso'));
166
            }
167
        }
168
        return $traverser;
169
    }
170
}
171
// End of file ModelObjNodeTreeDTO.php
172
// Location: EventEspresso\core\services\orm\tree_traversal/ModelObjNodeTreeDTO.php
173