1 | <?php |
||
23 | class Sections { |
||
24 | use |
||
25 | CRUD, |
||
26 | Singleton; |
||
27 | |||
28 | protected $data_model = [ |
||
29 | 'id' => 'int:0', |
||
30 | 'parent' => 'int:0', |
||
31 | 'title' => 'ml:text', |
||
32 | 'path' => 'ml:text' |
||
33 | ]; |
||
34 | protected $table = '[prefix]blogs_sections'; |
||
35 | protected $data_model_ml_group = 'Blogs/sections'; |
||
36 | /** |
||
37 | * @var Cache_prefix |
||
38 | */ |
||
39 | protected $cache; |
||
40 | |||
41 | protected function construct () { |
||
42 | $this->cache = new Cache_prefix('Blogs'); |
||
43 | } |
||
44 | /** |
||
45 | * Returns database index |
||
46 | * |
||
47 | * @return int |
||
48 | */ |
||
49 | protected function cdb () { |
||
50 | return Config::instance()->module('Blogs')->db('posts'); |
||
51 | } |
||
52 | /** |
||
53 | * Get array of sections in form [<i>id</i> => <i>title</i>] |
||
54 | * |
||
55 | * @return array|false |
||
56 | */ |
||
57 | function get_list () { |
||
58 | $L = Language::instance(); |
||
59 | return $this->cache->get( |
||
60 | "sections/list/$L->clang", |
||
61 | function () { |
||
62 | return $this->get_list_internal( |
||
63 | $this->get_structure() |
||
64 | ); |
||
65 | } |
||
66 | ); |
||
67 | } |
||
68 | private function get_list_internal ($structure) { |
||
69 | if (!empty($structure['sections'])) { |
||
70 | $list = []; |
||
71 | foreach ($structure['sections'] as $section) { |
||
72 | $list += $this->get_list_internal($section); |
||
73 | } |
||
74 | return $list; |
||
75 | } else { |
||
76 | return [$structure['id'] => $structure['title']]; |
||
77 | } |
||
78 | } |
||
79 | /** |
||
80 | * Get array of sections structure |
||
81 | * |
||
82 | * @return array|false |
||
83 | */ |
||
84 | function get_structure () { |
||
85 | $L = Language::instance(); |
||
86 | return $this->cache->get( |
||
87 | "sections/structure/$L->clang", |
||
88 | function () { |
||
89 | return $this->get_structure_internal(); |
||
90 | } |
||
91 | ); |
||
92 | } |
||
93 | private function get_structure_internal ($parent = 0) { |
||
94 | $structure = [ |
||
95 | 'id' => $parent, |
||
96 | 'posts' => 0 |
||
97 | ]; |
||
98 | if ($parent != 0) { |
||
99 | $structure = array_merge( |
||
100 | $structure, |
||
101 | $this->get($parent) |
||
102 | ); |
||
103 | } else { |
||
104 | $L = new Language_prefix('blogs_'); |
||
105 | $structure['title'] = $L->root_section; |
||
106 | $structure['posts'] = Posts::instance()->get_for_section_count($structure['id']); |
||
107 | } |
||
108 | $sections = $this->db()->qfa( |
||
109 | [ |
||
110 | "SELECT |
||
111 | `id`, |
||
112 | `path` |
||
113 | FROM `[prefix]blogs_sections` |
||
114 | WHERE `parent` = '%s'", |
||
115 | $parent |
||
116 | ] |
||
117 | ) ?: []; |
||
118 | $structure['sections'] = []; |
||
119 | foreach ($sections as $section) { |
||
120 | $structure['sections'][$this->ml_process($section['path'])] = $this->get_structure_internal($section['id']); |
||
121 | } |
||
122 | return $structure; |
||
123 | } |
||
124 | /** |
||
125 | * Get data of specified section |
||
126 | * |
||
127 | * @param int|int[] $id |
||
128 | * |
||
129 | * @return array|false |
||
130 | */ |
||
131 | function get ($id) { |
||
132 | if (is_array($id)) { |
||
133 | foreach ($id as &$i) { |
||
134 | $i = $this->get($i); |
||
135 | } |
||
136 | return $id; |
||
137 | } |
||
138 | $L = Language::instance(); |
||
139 | $id = (int)$id; |
||
140 | return $this->cache->get( |
||
141 | "sections/$id/$L->clang", |
||
142 | function () use ($id) { |
||
143 | $data = $this->read($id); |
||
144 | if ($data) { |
||
145 | $data['posts'] = Posts::instance()->get_for_section_count($id); |
||
146 | $data['full_path'] = [$data['path']]; |
||
147 | $parent = $data['parent']; |
||
148 | while ($parent != 0) { |
||
149 | $section = $this->get($parent); |
||
150 | $data['full_path'][] = $section['path']; |
||
151 | $parent = $section['parent']; |
||
152 | } |
||
153 | $data['full_path'] = implode('/', array_reverse($data['full_path'])); |
||
154 | } |
||
155 | return $data; |
||
156 | } |
||
157 | ); |
||
158 | } |
||
159 | /** |
||
160 | * @return array[]|false |
||
161 | */ |
||
162 | function get_all () { |
||
163 | $L = Language::instance(); |
||
164 | return $this->cache->get( |
||
165 | "sections/all/$L->clang", |
||
166 | function () { |
||
167 | $sections = $this->db()->qfa( |
||
168 | "SELECT * |
||
169 | FROM `[prefix]blogs_sections`" |
||
170 | ) ?: []; |
||
171 | foreach ($sections as &$section) { |
||
|
|||
172 | $section['id'] = (int)$section['id']; |
||
173 | $section['parent'] = (int)$section['parent']; |
||
174 | $section['title'] = $this->ml_process($section['title']); |
||
175 | $section['path'] = $this->ml_process($section['path']); |
||
176 | } |
||
177 | return $sections; |
||
178 | } |
||
179 | ); |
||
180 | } |
||
181 | /** |
||
182 | * Get sections ids for each section in full path |
||
183 | * |
||
184 | * @param string|string[] $path |
||
185 | * |
||
186 | * @return false|int[] |
||
187 | */ |
||
188 | function get_by_path ($path) { |
||
204 | /** |
||
205 | * Add new section |
||
206 | * |
||
207 | * @param int $parent |
||
208 | * @param string $title |
||
209 | * @param string $path |
||
210 | * |
||
211 | * @return false|int Id of created section on success of <b>false</> on failure |
||
1 ignored issue
–
show
|
|||
212 | */ |
||
213 | function add ($parent, $title, $path) { |
||
229 | /** |
||
230 | * Set data of specified section |
||
231 | * |
||
232 | * @param int $id |
||
233 | * @param int $parent |
||
234 | * @param string $title |
||
235 | * @param string $path |
||
236 | * |
||
237 | * @return bool |
||
238 | */ |
||
239 | function set ($id, $parent, $title, $path) { |
||
246 | /** |
||
247 | * Delete specified section |
||
248 | * |
||
249 | * @param int $id |
||
250 | * |
||
251 | * @return bool |
||
1 ignored issue
–
show
|
|||
252 | */ |
||
253 | function del ($id) { |
||
289 | } |
||
290 |
There are different options of fixing this problem.
If you want to be on the safe side, you can add an additional type-check:
If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:
Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.