Total Complexity | 114 |
Total Lines | 654 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like ItemHandler often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ItemHandler, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
45 | class ItemHandler extends XoopsPersistableObjectHandler |
||
46 | { |
||
47 | /** |
||
48 | * @var Helper |
||
49 | * @access public |
||
50 | */ |
||
51 | public $helper = null; |
||
52 | |||
53 | public function __construct(Connection $db) |
||
54 | { |
||
55 | parent::__construct($db, 'publisher_items', Item::class, 'itemid', 'title'); |
||
56 | $this->helper = Helper::getInstance(); |
||
57 | } |
||
58 | |||
59 | /** |
||
60 | * insert a new item in the database |
||
61 | * |
||
62 | * @param XoopsObject $item reference to the {@link Publisher\Item} object |
||
63 | * @param bool $force |
||
64 | * |
||
65 | * @return bool FALSE if failed, TRUE if already present and unchanged or successful |
||
66 | */ |
||
67 | public function insert(XoopsObject $item, $force = true) |
||
68 | { |
||
69 | $xoops = Xoops::getInstance(); |
||
70 | if (!$item->getVar('meta_keywords') || !$item->getVar('meta_description') || !$item->getVar('short_url')) { |
||
71 | $publisher_metagen = new Publisher\Metagen($item->title(), $item->getVar('meta_keywords'), $item->getVar('summary')); |
||
72 | // Auto create meta tags if empty |
||
73 | if (!$item->getVar('meta_keywords')) { |
||
74 | $item->setVar('meta_keywords', $publisher_metagen->_keywords); |
||
75 | } |
||
76 | if (!$item->getVar('meta_description')) { |
||
77 | $item->setVar('meta_description', $publisher_metagen->_description); |
||
78 | } |
||
79 | // Auto create short_url if empty |
||
80 | if (!$item->getVar('short_url')) { |
||
81 | $item->setVar('short_url', $publisher_metagen::generateSeoTitle($item->getVar('title', 'n'), false)); |
||
82 | } |
||
83 | } |
||
84 | if (!parent::insert($item, $force)) { |
||
85 | return false; |
||
86 | } |
||
87 | if ($xoops->isActiveModule('tag')) { |
||
88 | // Storing tags information |
||
89 | $tagHandler = $xoops->getModuleHandler('tag', 'tag'); |
||
90 | $tagHandler->updateByItem($item->getVar('item_tag'), $item->getVar('itemid'), \PUBLISHER_DIRNAME, 0); |
||
91 | } |
||
92 | |||
93 | return true; |
||
94 | } |
||
95 | |||
96 | /** |
||
97 | * delete an item from the database |
||
98 | * |
||
99 | * @param XoopsObject $item reference to the ITEM to delete |
||
100 | * @param bool $force |
||
101 | * |
||
102 | * @return bool FALSE if failed. |
||
103 | */ |
||
104 | public function delete(XoopsObject $item, $force = false) |
||
105 | { |
||
106 | $xoops = Xoops::getInstance(); |
||
107 | // Deleting the files |
||
108 | if (!$this->helper->getFileHandler()->deleteItemFiles($item)) { |
||
109 | $item->setErrors('An error while deleting a file.'); |
||
110 | } |
||
111 | if (!parent::delete($item, $force)) { |
||
112 | $item->setErrors('An error while deleting.'); |
||
113 | |||
114 | return false; |
||
115 | } |
||
116 | // Removing tags information |
||
117 | if ($xoops->isActiveModule('tag')) { |
||
118 | $tagHandler = $xoops->getModuleHandler('tag', 'tag'); |
||
119 | $tagHandler->updateByItem('', $item->getVar('itemid'), \PUBLISHER_DIRNAME, 0); |
||
120 | } |
||
121 | |||
122 | return true; |
||
123 | } |
||
124 | |||
125 | /** |
||
126 | * retrieve items from the database |
||
127 | * |
||
128 | * @param object $criteria {@link CriteriaElement} conditions to be met |
||
129 | * @param string $id_key what shall we use as array key ? none, itemid, categoryid |
||
130 | * @param string $notNullFields fields that cannot be null or empty |
||
131 | * |
||
132 | * @return array array of {@link Publisher\Item} objects |
||
133 | */ |
||
134 | public function getItemObjects($criteria = null, $id_key = 'none', $notNullFields = ''): array |
||
135 | { |
||
136 | $ret = []; |
||
137 | $whereMode = ''; |
||
138 | |||
139 | $qb = $this->db2->createXoopsQueryBuilder(); |
||
140 | $qb->select('*')->fromPrefix('publisher_items', ''); |
||
141 | if (isset($criteria) && $criteria instanceof CriteriaElement) { |
||
142 | $criteria->renderQb($qb, ''); |
||
143 | $whereMode = 'AND'; |
||
144 | } |
||
145 | $this->addNotNullFieldClause($qb, $notNullFields, $whereMode); |
||
146 | $theObjects = []; |
||
147 | $result = $qb->execute(); |
||
148 | while (false !== ($myrow = $result->fetch(PDO::FETCH_ASSOC))) { |
||
149 | $item = new Publisher\Item(); |
||
150 | $item->assignVars($myrow); |
||
151 | $theObjects[$myrow['itemid']] = $item; |
||
152 | unset($item); |
||
153 | } |
||
154 | |||
155 | /* @var Publisher\Item $theObject */ |
||
156 | foreach ($theObjects as $theObject) { |
||
157 | if ('none' === $id_key) { |
||
158 | $ret[] = $theObject; |
||
159 | } elseif ('itemid' === $id_key) { |
||
160 | $ret[$theObject->getVar('itemid')] = $theObject; |
||
161 | } else { |
||
162 | $ret[$theObject->getVar($id_key)][$theObject->getVar('itemid')] = $theObject; |
||
163 | } |
||
164 | unset($theObject); |
||
165 | } |
||
166 | |||
167 | return $ret; |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * count items matching a condition |
||
172 | * |
||
173 | * @param object $criteria {@link CriteriaElement} to match |
||
174 | * @param string $notNullFields fields that cannot be null or empty |
||
175 | * |
||
176 | * @return int count of items |
||
177 | */ |
||
178 | public function getItemCount($criteria = null, $notNullFields = ''): int |
||
179 | { |
||
180 | $whereMode = ''; |
||
181 | |||
182 | $qb = $this->db2->createXoopsQueryBuilder(); |
||
183 | $qb->select('COUNT(*)')->fromPrefix('publisher_items', ''); |
||
184 | if (isset($criteria) && $criteria instanceof CriteriaElement) { |
||
185 | $whereClause = $criteria->renderQb($qb, ''); |
||
186 | $whereMode = 'AND'; |
||
187 | } |
||
188 | $this->addNotNullFieldClause($qb, $notNullFields, $whereMode); |
||
189 | $result = $qb->execute(); |
||
190 | |||
191 | if (!$result) { |
||
192 | return 0; |
||
193 | } |
||
194 | [$count] = $result->fetch(PDO::FETCH_NUM); |
||
195 | |||
196 | return $count; |
||
197 | } |
||
198 | |||
199 | /** |
||
200 | * @param $categoryid |
||
201 | * @param string|array $status |
||
202 | * @param string $notNullFields |
||
203 | */ |
||
204 | public function getItemsCount($categoryid = -1, $status = '', $notNullFields = ''): int |
||
205 | { |
||
206 | global $publisher_isAdmin; |
||
207 | $criteriaCategory = null; |
||
208 | if (!$publisher_isAdmin) { |
||
209 | $criteriaPermissions = new CriteriaCompo(); |
||
210 | // Categories for which user has access |
||
211 | $categoriesGranted = $this->helper->getPermissionHandler()->getGrantedItems('category_read'); |
||
212 | if (!empty($categoriesGranted)) { |
||
213 | $grantedCategories = new Criteria('categoryid', '(' . \implode(',', $categoriesGranted) . ')', 'IN'); |
||
214 | $criteriaPermissions->add($grantedCategories, 'AND'); |
||
215 | } else { |
||
216 | return 0; |
||
217 | } |
||
218 | } |
||
219 | if (isset($categoryid) && -1 != $categoryid) { |
||
220 | $criteriaCategory = new criteria('categoryid', $categoryid); |
||
221 | } |
||
222 | $criteriaStatus = new CriteriaCompo(); |
||
223 | if (!empty($status) && \is_array($status)) { |
||
224 | foreach ($status as $v) { |
||
225 | $criteriaStatus->add(new Criteria('status', $v), 'OR'); |
||
226 | } |
||
227 | } elseif (!empty($status) && -1 != $status) { |
||
228 | $criteriaStatus->add(new Criteria('status', $status), 'OR'); |
||
229 | } |
||
230 | $criteria = new CriteriaCompo(); |
||
231 | if (null !== $criteriaCategory) { |
||
232 | $criteria->add($criteriaCategory); |
||
233 | } |
||
234 | if (null !== $criteriaPermissions) { |
||
235 | $criteria->add($criteriaPermissions); |
||
236 | } |
||
237 | if (null !== $criteriaStatus) { |
||
238 | $criteria->add($criteriaStatus); |
||
239 | } |
||
240 | |||
241 | return $this->getItemCount($criteria, $notNullFields); |
||
242 | } |
||
243 | |||
244 | /** |
||
245 | * @param int $limit |
||
246 | * @param int $start |
||
247 | * @param int $categoryid |
||
248 | * @param string $sort |
||
249 | * @param string $order |
||
250 | * @param string $notNullFields |
||
251 | * @param bool $asobject |
||
252 | * @param string $id_key |
||
253 | */ |
||
254 | public function getAllPublished($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none'): array |
||
255 | { |
||
256 | $otherCriteria = new Criteria('datesub', \time(), '<='); |
||
257 | |||
258 | return $this->getItems($limit, $start, [\_PUBLISHER_STATUS_PUBLISHED], $categoryid, $sort, $order, $notNullFields, $asobject, $otherCriteria, $id_key); |
||
259 | } |
||
260 | |||
261 | /** |
||
262 | * @param Publisher\Item $obj |
||
263 | */ |
||
264 | public function getPreviousPublished($obj): bool |
||
265 | { |
||
266 | $ret = false; |
||
267 | $otherCriteria = new CriteriaCompo(); |
||
268 | $otherCriteria->add(new Criteria('datesub', $obj->getVar('datesub'), '<')); |
||
269 | $objs = $this->getItems(1, 0, [\_PUBLISHER_STATUS_PUBLISHED], $obj->getVar('categoryid'), 'datesub', 'DESC', '', true, $otherCriteria, 'none'); |
||
270 | if (\count($objs) > 0) { |
||
271 | $ret = $objs[0]; |
||
272 | } |
||
273 | |||
274 | return $ret; |
||
275 | } |
||
276 | |||
277 | /** |
||
278 | * @param Publisher\Item $obj |
||
279 | */ |
||
280 | public function getNextPublished($obj): bool |
||
281 | { |
||
282 | $ret = false; |
||
283 | $otherCriteria = new CriteriaCompo(); |
||
284 | $otherCriteria->add(new Criteria('datesub', $obj->getVar('datesub'), '>')); |
||
285 | $otherCriteria->add(new Criteria('datesub', \time(), '<=')); |
||
286 | $objs = $this->getItems(1, 0, [\_PUBLISHER_STATUS_PUBLISHED], $obj->getVar('categoryid'), 'datesub', 'ASC', '', true, $otherCriteria, 'none'); |
||
287 | if (\count($objs) > 0) { |
||
288 | $ret = $objs[0]; |
||
289 | } |
||
290 | |||
291 | return $ret; |
||
292 | } |
||
293 | |||
294 | /** |
||
295 | * @param int $limit |
||
296 | * @param int $start |
||
297 | * @param int $categoryid |
||
298 | * @param string $sort |
||
299 | * @param string $order |
||
300 | * @param string $notNullFields |
||
301 | * @param bool $asobject |
||
302 | * @param string $id_key |
||
303 | */ |
||
304 | public function getAllSubmitted($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none'): array |
||
305 | { |
||
306 | return $this->getItems($limit, $start, [\_PUBLISHER_STATUS_SUBMITTED], $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key); |
||
307 | } |
||
308 | |||
309 | /** |
||
310 | * @param int $limit |
||
311 | * @param int $start |
||
312 | * @param int $categoryid |
||
313 | * @param string $sort |
||
314 | * @param string $order |
||
315 | * @param string $notNullFields |
||
316 | * @param bool $asobject |
||
317 | * @param string $id_key |
||
318 | */ |
||
319 | public function getAllOffline($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none'): array |
||
320 | { |
||
321 | return $this->getItems($limit, $start, [\_PUBLISHER_STATUS_OFFLINE], $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key); |
||
322 | } |
||
323 | |||
324 | /** |
||
325 | * @param int $limit |
||
326 | * @param int $start |
||
327 | * @param int $categoryid |
||
328 | * @param string $sort |
||
329 | * @param string $order |
||
330 | * @param string $notNullFields |
||
331 | * @param bool $asobject |
||
332 | * @param string $id_key |
||
333 | */ |
||
334 | public function getAllRejected($limit = 0, $start = 0, $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $id_key = 'none'): array |
||
335 | { |
||
336 | return $this->getItems($limit, $start, [\_PUBLISHER_STATUS_REJECTED], $categoryid, $sort, $order, $notNullFields, $asobject, null, $id_key); |
||
337 | } |
||
338 | |||
339 | /** |
||
340 | * @param int $limit |
||
341 | * @param int $start |
||
342 | * @param string $status |
||
343 | * @param int $categoryid |
||
344 | * @param string $sort |
||
345 | * @param string $order |
||
346 | * @param string $notNullFields |
||
347 | * @param bool $asobject |
||
348 | * @param null $otherCriteria |
||
349 | * @param string $id_key |
||
350 | */ |
||
351 | public function getItems($limit = 0, $start = 0, $status = '', $categoryid = -1, $sort = 'datesub', $order = 'DESC', $notNullFields = '', $asobject = true, $otherCriteria = null, $id_key = 'none'): array |
||
398 | } |
||
399 | |||
400 | /** |
||
401 | * @param string $field |
||
402 | * @param string $status |
||
403 | * @param int $categoryId |
||
404 | */ |
||
405 | public function getRandomItem($field = '', $status = '', $categoryId = -1): bool |
||
406 | { |
||
407 | $ret = false; |
||
408 | $notNullFields = $field; |
||
409 | // Getting the number of published Items |
||
410 | $totalItems = $this->getItemsCount($categoryId, $status, $notNullFields); |
||
411 | if ($totalItems > 0) { |
||
412 | $totalItems = $totalItems - 1; |
||
413 | // mt_srand((float)\microtime() * 1000000); |
||
414 | $entrynumber = \random_int(0, $totalItems); |
||
415 | $item = $this->getItems(1, $entrynumber, $status, $categoryId, $sort = 'datesub', $order = 'DESC', $notNullFields); |
||
416 | if ($item) { |
||
417 | $ret = $item[0]; |
||
418 | } |
||
419 | } |
||
420 | |||
421 | return $ret; |
||
422 | } |
||
423 | |||
424 | /** |
||
425 | * @param $itemid |
||
426 | * |
||
427 | * @return bool |
||
428 | */ |
||
429 | public function updateCounter($itemid): ?bool |
||
430 | { |
||
431 | $qb = $this->db2->createXoopsQueryBuilder(); |
||
432 | $qb->updatePrefix('publisher_items', 'i')->set('i.counter', 'i.counter+1')->where('i.itemid = :itemid')->setParameter(':itemid', $itemid, PDO::PARAM_INT); |
||
433 | $result = $qb->execute(); |
||
434 | if ($result) { |
||
435 | return true; |
||
436 | } |
||
437 | |||
438 | return false; |
||
439 | } |
||
440 | |||
441 | /** |
||
442 | * addNotNullFieldClause exclude rows where specified columns are empty or null |
||
443 | * |
||
444 | * @param QueryBuilder $qb QueryBuilder instance |
||
445 | * @param string|array $notNullFields fields that should not be empty |
||
446 | * @param string $whereMode Initial where method, 'AND' andWhere(), otherwise where() |
||
447 | * |
||
448 | * @return QueryBuilder instance |
||
449 | */ |
||
450 | protected function addNotNullFieldClause(QueryBuilder $qb, $notNullFields = [], $whereMode = ''): QueryBuilder |
||
451 | { |
||
452 | $eb = $qb->expr(); |
||
453 | if (!empty($notNullFields)) { |
||
454 | if (!\is_array($notNullFields)) { |
||
455 | $notNullFields = (array)$notNullFields; |
||
456 | } |
||
457 | foreach ($notNullFields as $v) { |
||
458 | if ('AND' === $whereMode) { |
||
459 | $qb->andWhere($eb->isNotNull($v, ''))->andWhere($eb->neq($v, "''")); |
||
460 | } else { |
||
461 | $qb->where($eb->isNotNull($v, ''))->andWhere($eb->neq($v, "''")); |
||
462 | $whereMode = 'AND'; |
||
463 | } |
||
464 | } |
||
465 | } |
||
466 | |||
467 | return $qb; |
||
468 | } |
||
469 | |||
470 | /** |
||
471 | * @param array $queryarray |
||
472 | * @param string $andor |
||
473 | * @param int $limit |
||
474 | * @param int $offset |
||
475 | * @param int|array $userid |
||
476 | * @param array $categories |
||
477 | * @param int|string $sortby |
||
478 | * @param string|array $searchin |
||
479 | * @param string $extra |
||
480 | */ |
||
481 | public function getItemsFromSearch($queryarray = [], $andor = 'AND', $limit = 0, $offset = 0, $userid = 0, $categories = [], $sortby = 0, $searchin = '', $extra = ''): array |
||
573 | } |
||
574 | |||
575 | /** |
||
576 | * @param array $categoriesObj |
||
577 | * @param array $status |
||
578 | */ |
||
579 | public function getLastPublishedByCat($categoriesObj, $status = [\_PUBLISHER_STATUS_PUBLISHED]): array |
||
580 | { |
||
619 | } |
||
620 | |||
621 | /** |
||
622 | * @param int $parentid |
||
623 | * @param array $catsCount |
||
624 | * @param string $spaces |
||
625 | * @param array $resultCatCounts |
||
626 | */ |
||
627 | public function countArticlesByCat($parentid, &$catsCount, $spaces = '', $resultCatCounts = []): int |
||
628 | { |
||
629 | $newspaces = $spaces . '--'; |
||
630 | $thecount = 0; |
||
631 | foreach ($catsCount[$parentid] as $subCatId => $count) { |
||
632 | $thecount = $thecount + $count; |
||
633 | $resultCatCounts[$subCatId] = $count; |
||
634 | if (isset($catsCount[$subCatId])) { |
||
635 | $thecount = $thecount + $this->countArticlesByCat($subCatId, $catsCount, $newspaces, $resultCatCounts); |
||
636 | $resultCatCounts[$subCatId] = $thecount; |
||
637 | } |
||
638 | } |
||
639 | |||
640 | return $thecount; |
||
641 | } |
||
642 | |||
643 | /** |
||
644 | * @param int $cat_id |
||
645 | * @param array $status |
||
646 | * @param bool $inSubCat |
||
647 | */ |
||
648 | public function getCountsByCat($cat_id, $status, $inSubCat = false): array |
||
699 | } |
||
700 | } |
||
701 |