primo commit
This commit is contained in:
		
							
								
								
									
										84
									
								
								modules/mod_articles/src/Dispatcher/Dispatcher.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								modules/mod_articles/src/Dispatcher/Dispatcher.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,84 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Site | ||||
|  * @subpackage  mod_articles | ||||
|  * | ||||
|  * @copyright   (C) 2024 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Module\Articles\Site\Dispatcher; | ||||
|  | ||||
| use Joomla\CMS\Dispatcher\AbstractModuleDispatcher; | ||||
| use Joomla\CMS\Helper\HelperFactoryAwareInterface; | ||||
| use Joomla\CMS\Helper\HelperFactoryAwareTrait; | ||||
| use Joomla\CMS\Helper\ModuleHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Dispatcher class for mod_articles | ||||
|  * | ||||
|  * @since  5.2.0 | ||||
|  */ | ||||
| class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface | ||||
| { | ||||
|     use HelperFactoryAwareTrait; | ||||
|  | ||||
|     /** | ||||
|      * Returns the layout data. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   5.2.0 | ||||
|      */ | ||||
|     protected function getLayoutData(): array | ||||
|     { | ||||
|         $data   = parent::getLayoutData(); | ||||
|         $params = $data['params']; | ||||
|  | ||||
|         // Prep for Normal or Dynamic Modes | ||||
|         $mode   = $params->get('mode', 'normal'); | ||||
|         $idBase = null; | ||||
|  | ||||
|         switch ($mode) { | ||||
|             case 'dynamic': | ||||
|                 $option = $data['input']->get('option'); | ||||
|                 $view   = $data['input']->get('view'); | ||||
|  | ||||
|                 if ($option === 'com_content') { | ||||
|                     switch ($view) { | ||||
|                         case 'category': | ||||
|                         case 'categories': | ||||
|                             $idBase = $data['input']->getInt('id'); | ||||
|                             break; | ||||
|                         case 'article': | ||||
|                             if ($params->get('show_on_article_page', 1)) { | ||||
|                                 $idBase = $data['input']->getInt('catid'); | ||||
|                             } | ||||
|                             break; | ||||
|                     } | ||||
|                 } | ||||
|                 break; | ||||
|             default: | ||||
|                 $idBase = $params->get('catid'); | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         $cacheParams               = new \stdClass(); | ||||
|         $cacheParams->cachemode    = 'id'; | ||||
|         $cacheParams->class        = $this->getHelperFactory()->getHelper('ArticlesHelper'); | ||||
|         $cacheParams->method       = 'getArticles'; | ||||
|         $cacheParams->methodparams = [$params, $data['app']]; | ||||
|         $cacheParams->modeparams   = md5(serialize([$idBase, $this->module->module, $this->module->id])); | ||||
|  | ||||
|         $data['list'] = ModuleHelper::moduleCache($this->module, $params, $cacheParams); | ||||
|  | ||||
|         $data['grouped'] = $params->get('article_grouping', 'none') !== 'none'; | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										589
									
								
								modules/mod_articles/src/Helper/ArticlesHelper.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										589
									
								
								modules/mod_articles/src/Helper/ArticlesHelper.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,589 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Site | ||||
|  * @subpackage  mod_articles | ||||
|  * | ||||
|  * @copyright   (C) 2024 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Module\Articles\Site\Helper; | ||||
|  | ||||
| use Joomla\CMS\Access\Access; | ||||
| use Joomla\CMS\Application\SiteApplication; | ||||
| use Joomla\CMS\Component\ComponentHelper; | ||||
| use Joomla\CMS\Date\Date; | ||||
| use Joomla\CMS\Event\Content; | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\HTML\HTMLHelper; | ||||
| use Joomla\CMS\Plugin\PluginHelper; | ||||
| use Joomla\CMS\Router\Route; | ||||
| use Joomla\Component\Content\Administrator\Extension\ContentComponent; | ||||
| use Joomla\Component\Content\Site\Helper\RouteHelper; | ||||
| use Joomla\Database\DatabaseAwareInterface; | ||||
| use Joomla\Database\DatabaseAwareTrait; | ||||
| use Joomla\Registry\Registry; | ||||
| use Joomla\String\StringHelper; | ||||
| use Joomla\Utilities\ArrayHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Helper for mod_articles | ||||
|  * | ||||
|  * @since  5.2.0 | ||||
|  */ | ||||
| class ArticlesHelper implements DatabaseAwareInterface | ||||
| { | ||||
|     use DatabaseAwareTrait; | ||||
|  | ||||
|     /** | ||||
|      * Retrieve a list of articles | ||||
|      * | ||||
|      * @param   Registry         $params  The module parameters. | ||||
|      * @param   SiteApplication  $app     The current application. | ||||
|      * | ||||
|      * @return  object[] | ||||
|      * | ||||
|      * @since   5.2.0 | ||||
|      */ | ||||
|     public function getArticles(Registry $params, SiteApplication $app) | ||||
|     { | ||||
|         $factory = $app->bootComponent('com_content')->getMVCFactory(); | ||||
|  | ||||
|         // Get an instance of the generic articles model | ||||
|         $articles = $factory->createModel('Articles', 'Site', ['ignore_request' => true]); | ||||
|  | ||||
|         // Set application parameters in model | ||||
|         $input     = $app->getInput(); | ||||
|         $appParams = $app->getParams(); | ||||
|         $articles->setState('params', $appParams); | ||||
|  | ||||
|         $articles->setState('list.start', 0); | ||||
|         $articles->setState('filter.published', ContentComponent::CONDITION_PUBLISHED); | ||||
|  | ||||
|         // Set the filters based on the module params | ||||
|         $articles->setState('list.limit', (int) $params->get('count', 0)); | ||||
|         $articles->setState('load_tags', $params->get('show_tags', 0) || $params->get('article_grouping', 'none') === 'tags'); | ||||
|  | ||||
|         // Get the user object | ||||
|         $user = $app->getIdentity(); | ||||
|  | ||||
|         // Access filter | ||||
|         $access     = !ComponentHelper::getParams('com_content')->get('show_noauth'); | ||||
|         $authorised = Access::getAuthorisedViewLevels($user->id); | ||||
|         $articles->setState('filter.access', $access); | ||||
|  | ||||
|         // Prep for Normal or Dynamic Modes | ||||
|         $mode = $params->get('mode', 'normal'); | ||||
|  | ||||
|         switch ($mode) { | ||||
|             case 'dynamic': | ||||
|                 $option = $input->get('option'); | ||||
|                 $view   = $input->get('view'); | ||||
|  | ||||
|                 if ($option === 'com_content') { | ||||
|                     switch ($view) { | ||||
|                         case 'category': | ||||
|                         case 'categories': | ||||
|                             $catids = [$input->getInt('id')]; | ||||
|                             break; | ||||
|                         case 'article': | ||||
|                             if ($params->get('show_on_article_page', 1)) { | ||||
|                                 $article_id = $input->getInt('id'); | ||||
|                                 $catid      = $input->getInt('catid'); | ||||
|  | ||||
|                                 if (!$catid) { | ||||
|                                     // Get an instance of the generic article model | ||||
|                                     $article = $factory->createModel('Article', 'Site', ['ignore_request' => true]); | ||||
|  | ||||
|                                     $article->setState('params', $appParams); | ||||
|                                     $article->setState('filter.published', 1); | ||||
|                                     $article->setState('article.id', (int) $article_id); | ||||
|                                     $item   = $article->getItem(); | ||||
|                                     $catids = [$item->catid]; | ||||
|                                 } else { | ||||
|                                     $catids = [$catid]; | ||||
|                                 } | ||||
|                             } else { | ||||
|                                 // Return right away if show_on_article_page option is off | ||||
|                                 return; | ||||
|                             } | ||||
|                             break; | ||||
|  | ||||
|                         default: | ||||
|                             // Return right away if not on the category or article views | ||||
|                             return; | ||||
|                     } | ||||
|                 } else { | ||||
|                     // Return right away if not on a com_content page | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             default: | ||||
|                 $catids = $params->get('catid'); | ||||
|                 $articles->setState('filter.category_id.include', (bool) $params->get('category_filtering_type', 1)); | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         // Category filter | ||||
|         if ($catids) { | ||||
|             if ($params->get('show_child_category_articles', 0) && (int) $params->get('levels', 0) > 0) { | ||||
|                 // Get an instance of the generic categories model | ||||
|                 $categories = $factory->createModel('Categories', 'Site', ['ignore_request' => true]); | ||||
|                 $categories->setState('params', $appParams); | ||||
|                 $levels = $params->get('levels', 1) ?: 9999; | ||||
|                 $categories->setState('filter.get_children', $levels); | ||||
|                 $categories->setState('filter.published', 1); | ||||
|                 $categories->setState('filter.access', $access); | ||||
|                 $additional_catids = []; | ||||
|  | ||||
|                 foreach ($catids as $catid) { | ||||
|                     $categories->setState('filter.parentId', $catid); | ||||
|                     $recursive = true; | ||||
|                     $items     = $categories->getItems($recursive); | ||||
|  | ||||
|                     if ($items) { | ||||
|                         foreach ($items as $category) { | ||||
|                             $condition = (($category->level - $categories->getParent()->level) <= $levels); | ||||
|  | ||||
|                             if ($condition) { | ||||
|                                 $additional_catids[] = $category->id; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 $catids = array_unique(array_merge($catids, $additional_catids)); | ||||
|             } | ||||
|  | ||||
|             $articles->setState('filter.category_id', $catids); | ||||
|         } | ||||
|  | ||||
|         // Ordering | ||||
|         $ordering = $params->get('article_ordering', 'a.ordering'); | ||||
|  | ||||
|         switch ($ordering) { | ||||
|             case 'random': | ||||
|                 $articles->setState('list.ordering', $this->getDatabase()->getQuery(true)->rand()); | ||||
|                 break; | ||||
|  | ||||
|             case 'rating_count': | ||||
|             case 'rating': | ||||
|                 $articles->setState('list.ordering', $ordering); | ||||
|                 $articles->setState('list.direction', $params->get('article_ordering_direction', 'ASC')); | ||||
|  | ||||
|                 if (!PluginHelper::isEnabled('content', 'vote')) { | ||||
|                     $articles->setState('list.ordering', 'a.ordering'); | ||||
|                 } | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             default: | ||||
|                 $articles->setState('list.ordering', $ordering); | ||||
|                 $articles->setState('list.direction', $params->get('article_ordering_direction', 'ASC')); | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         // Filter by multiple tags | ||||
|         $articles->setState('filter.tag', $params->get('filter_tag', [])); | ||||
|  | ||||
|         // Filter by featured | ||||
|         $articles->setState('filter.featured', $params->get('show_featured', 'show')); | ||||
|  | ||||
|         // Filter by author | ||||
|         if ($params->get('author_filtering_type', 1) === 2) { | ||||
|             $articles->setState('filter.author_id', [$user->id]); | ||||
|         } else { | ||||
|             $articles->setState('filter.author_id', $params->get('created_by', [])); | ||||
|             $articles->setState('filter.author_id.include', $params->get('author_filtering_type', 1)); | ||||
|         } | ||||
|  | ||||
|         $articles->setState('filter.author_alias', $params->get('created_by_alias', [])); | ||||
|         $articles->setState('filter.author_alias.include', $params->get('author_alias_filtering_type', 1)); | ||||
|  | ||||
|         // Filter archived articles | ||||
|         if ($params->get('show_archived', 'hide') === 'show') { | ||||
|             $articles->setState('filter.published', ContentComponent::CONDITION_ARCHIVED); | ||||
|         } | ||||
|  | ||||
|         // Check if we include or exclude articles and process data | ||||
|         $ex_or_include_articles = $params->get('ex_or_include_articles', 0); | ||||
|         $filterInclude          = true; | ||||
|         $articlesList           = []; | ||||
|         $currentArticleId       = $input->get('id', 0, 'UINT'); | ||||
|  | ||||
|         $isArticleAndShouldExcluded = $params->get('exclude_current', 1) === 1 | ||||
|             && $input->get('option') === 'com_content' | ||||
|             && $input->get('view') === 'article'; | ||||
|  | ||||
|         $articlesListToProcess = $params->get('included_articles', ''); | ||||
|  | ||||
|         if ($ex_or_include_articles === 0) { | ||||
|             $filterInclude = false; | ||||
|  | ||||
|             if ($isArticleAndShouldExcluded) { | ||||
|                 $articlesList[] = $currentArticleId; | ||||
|             } | ||||
|  | ||||
|             $articlesListToProcess = $params->get('excluded_articles', ''); | ||||
|         } | ||||
|  | ||||
|         foreach (ArrayHelper::fromObject($articlesListToProcess) as $article) { | ||||
|             if ( | ||||
|                 $ex_or_include_articles === 1 | ||||
|                 && $isArticleAndShouldExcluded | ||||
|                 && (int) $article['id'] === $currentArticleId | ||||
|             ) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             $articlesList[] = (int) $article['id']; | ||||
|         } | ||||
|  | ||||
|         // Edge case when the user select include mode but didn't add an article, | ||||
|         // we might have to exclude the current article | ||||
|         if ( | ||||
|             $ex_or_include_articles === 1 | ||||
|             && $isArticleAndShouldExcluded | ||||
|             && empty($articlesList) | ||||
|         ) { | ||||
|             $filterInclude  = false; | ||||
|             $articlesList[] = $currentArticleId; | ||||
|         } | ||||
|  | ||||
|         if (!empty($articlesList)) { | ||||
|             $articles->setState('filter.article_id', $articlesList); | ||||
|             $articles->setState('filter.article_id.include', $filterInclude); | ||||
|         } | ||||
|  | ||||
|         $date_filtering = $params->get('date_filtering', 'off'); | ||||
|  | ||||
|         if ($date_filtering !== 'off') { | ||||
|             $articles->setState('filter.date_filtering', $date_filtering); | ||||
|             $articles->setState('filter.date_field', $params->get('date_field', 'a.created')); | ||||
|             $articles->setState('filter.start_date_range', $params->get('start_date_range', '1000-01-01 00:00:00')); | ||||
|             $articles->setState('filter.end_date_range', $params->get('end_date_range', '9999-12-31 23:59:59')); | ||||
|             $articles->setState('filter.relative_date', $params->get('relative_date', 30)); | ||||
|         } | ||||
|  | ||||
|         // Filter by language | ||||
|         $articles->setState('filter.language', $app->getLanguageFilter()); | ||||
|  | ||||
|         $items = $articles->getItems(); | ||||
|  | ||||
|         // Display options | ||||
|         $show_date          = $params->get('show_date', 0); | ||||
|         $show_date_field    = $params->get('show_date_field', 'created'); | ||||
|         $show_date_format   = $params->get('show_date_format', 'Y-m-d H:i:s'); | ||||
|         $show_category      = $params->get('show_category', 0); | ||||
|         $show_category_link = $params->get('show_category_link', 0); | ||||
|         $show_hits          = $params->get('show_hits', 0); | ||||
|         $show_author        = $params->get('show_author', 0); | ||||
|         $show_introtext     = $params->get('show_introtext', 0); | ||||
|         $introtext_limit    = $params->get('introtext_limit', 100); | ||||
|  | ||||
|         // Find current Article ID if on an article page | ||||
|         $option = $input->get('option'); | ||||
|         $view   = $input->get('view'); | ||||
|  | ||||
|         if ($option === 'com_content' && $view === 'article') { | ||||
|             $active_article_id = $input->getInt('id'); | ||||
|         } else { | ||||
|             $active_article_id = 0; | ||||
|         } | ||||
|  | ||||
|         // Prepare data for display using display options | ||||
|         foreach ($items as &$item) { | ||||
|             $item->slug = $item->id . ':' . $item->alias; | ||||
|  | ||||
|             $articleLink = Route::_(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language)); | ||||
|  | ||||
|             if ($access || \in_array($item->access, $authorised)) { | ||||
|                 // We know that user has the privilege to view the article | ||||
|                 $item->link = $articleLink; | ||||
|             } else { | ||||
|                 $menu      = $app->getMenu(); | ||||
|                 $menuitems = $menu->getItems('link', 'index.php?option=com_users&view=login'); | ||||
|  | ||||
|                 if (isset($menuitems[0])) { | ||||
|                     $Itemid = $menuitems[0]->id; | ||||
|                 } elseif ($input->getInt('Itemid') > 0) { | ||||
|                     // Use Itemid from requesting page only if there is no existing menu | ||||
|                     $Itemid = $input->getInt('Itemid'); | ||||
|                 } | ||||
|  | ||||
|                 $return = base64_encode($articleLink); | ||||
|  | ||||
|                 $item->link = Route::_('index.php?option=com_users&view=login&Itemid=' . $Itemid . '&return=' . $return); | ||||
|             } | ||||
|  | ||||
|             $item->event   = new \stdClass(); | ||||
|  | ||||
|             // Check if we should trigger additional plugin events | ||||
|             if ($params->get('trigger_events', 0)) { | ||||
|                 $dispatcher = Factory::getApplication()->getDispatcher(); | ||||
|  | ||||
|                 // Process the content plugins. | ||||
|                 PluginHelper::importPlugin('content', null, true, $dispatcher); | ||||
|  | ||||
|                 $contentEventArguments = [ | ||||
|                     'context' => 'com_content.article', | ||||
|                     'subject' => $item, | ||||
|                     'params'  => $item->params, | ||||
|                 ]; | ||||
|  | ||||
|                 // Extra content from events | ||||
|  | ||||
|                 $contentEvents = [ | ||||
|                     'afterDisplayTitle'    => new Content\AfterTitleEvent('onContentAfterTitle', $contentEventArguments), | ||||
|                     'beforeDisplayContent' => new Content\BeforeDisplayEvent('onContentBeforeDisplay', $contentEventArguments), | ||||
|                     'afterDisplayContent'  => new Content\AfterDisplayEvent('onContentAfterDisplay', $contentEventArguments), | ||||
|                 ]; | ||||
|  | ||||
|                 foreach ($contentEvents as $resultKey => $event) { | ||||
|                     $results = $dispatcher->dispatch($event->getName(), $event)->getArgument('result', []); | ||||
|  | ||||
|                     $item->event->{$resultKey} = $results ? trim(implode("\n", $results)) : ''; | ||||
|                 } | ||||
|             } else { | ||||
|                 $item->event->afterDisplayTitle    = ''; | ||||
|                 $item->event->beforeDisplayContent = ''; | ||||
|                 $item->event->afterDisplayContent  = ''; | ||||
|             } | ||||
|  | ||||
|             // Used for styling the active article | ||||
|             $item->active      = $item->id == $active_article_id ? 'active' : ''; | ||||
|  | ||||
|             if ($show_date) { | ||||
|                 $item->displayDate = HTMLHelper::_('date', $item->$show_date_field, $show_date_format); | ||||
|             } | ||||
|  | ||||
|             if ($show_category) { | ||||
|                 $item->displayCategoryTitle = $item->category_title; | ||||
|             } | ||||
|  | ||||
|             if ($show_category_link) { | ||||
|                 $item->displayCategoryLink = Route::_(RouteHelper::getCategoryRoute($item->catid, $item->category_language)); | ||||
|             } | ||||
|  | ||||
|             $item->displayAuthorName    = $show_author ? $item->author : ''; | ||||
|             $item->displayCategoryTitle = $show_category ? $item->category_title : ''; | ||||
|             $item->displayCategoryLink  = $show_category_link ? $item->displayCategoryLink : ''; | ||||
|             $item->displayDate          = $show_date ? $item->displayDate : ''; | ||||
|             $item->displayHits          = $show_hits ? $item->hits : ''; | ||||
|  | ||||
|             if ($show_introtext) { | ||||
|                 $item->displayIntrotext = HTMLHelper::_('content.prepare', $item->introtext, '', 'mod_articles.content'); | ||||
|  | ||||
|                 // Remove any images belongs to the text | ||||
|                 if (!$params->get('image')) { | ||||
|                     $item->displayIntrotext = preg_replace('/<img[^>]*>/', '', $item->displayIntrotext); | ||||
|                 } | ||||
|  | ||||
|                 if ($introtext_limit != 0) { | ||||
|                     $item->displayIntrotext = HTMLHelper::_('string.truncateComplex', $item->displayIntrotext, $introtext_limit); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Show the Intro/Full image field of the article | ||||
|             if ($params->get('img_intro_full') !== 'none') { | ||||
|                 $images             = (new Registry($item->images))->toObject(); | ||||
|                 $item->imageSrc     = ''; | ||||
|  | ||||
|                 if ($params->get('img_intro_full') === 'intro' && !empty($images->image_intro)) { | ||||
|                     $item->imageSrc      = htmlspecialchars($images->image_intro, ENT_COMPAT, 'UTF-8'); | ||||
|                     $images->float_intro = 'mod-articles-image'; | ||||
|                 } elseif ($params->get('img_intro_full') === 'full' && !empty($images->image_fulltext)) { | ||||
|                     $item->imageSrc         = htmlspecialchars($images->image_fulltext, ENT_COMPAT, 'UTF-8'); | ||||
|                     $images->float_fulltext = 'mod-articles-image'; | ||||
|                 } | ||||
|  | ||||
|                 $item->images = json_encode($images); | ||||
|             } | ||||
|  | ||||
|             $item->displayReadmore  = $item->alternative_readmore; | ||||
|         } | ||||
|  | ||||
|         // Check if items need be grouped | ||||
|         $article_grouping           = $params->get('article_grouping', 'none'); | ||||
|         $article_grouping_direction = $params->get('article_grouping_direction', 'ksort'); | ||||
|         $grouped                    = $article_grouping !== 'none'; | ||||
|  | ||||
|         if ($items && $grouped) { | ||||
|             switch ($article_grouping) { | ||||
|                 case 'year': | ||||
|                 case 'month_year': | ||||
|                     $items = ArticlesHelper::groupByDate( | ||||
|                         $items, | ||||
|                         $article_grouping_direction, | ||||
|                         $article_grouping, | ||||
|                         $params->get('month_year_format', 'F Y'), | ||||
|                         $params->get('date_grouping_field', 'created') | ||||
|                     ); | ||||
|                     break; | ||||
|                 case 'author': | ||||
|                 case 'category_title': | ||||
|                     $items = ArticlesHelper::groupBy($items, $article_grouping, $article_grouping_direction); | ||||
|                     break; | ||||
|                 case 'tags': | ||||
|                     $items = ArticlesHelper::groupByTags($items, $article_grouping_direction); | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $items; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Groups items by field | ||||
|      * | ||||
|      * @param   array   $list             list of items | ||||
|      * @param   string  $fieldName        name of field that is used for grouping | ||||
|      * @param   string  $direction        ordering direction | ||||
|      * @param   null    $fieldNameToKeep  field name to keep | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   5.2.0 | ||||
|      */ | ||||
|     public static function groupBy($list, $fieldName, $direction, $fieldNameToKeep = null) | ||||
|     { | ||||
|         $grouped = []; | ||||
|  | ||||
|         if (!\is_array($list)) { | ||||
|             if ($list === '') { | ||||
|                 return $grouped; | ||||
|             } | ||||
|  | ||||
|             $list = [$list]; | ||||
|         } | ||||
|  | ||||
|         foreach ($list as $key => $item) { | ||||
|             if (!isset($grouped[$item->$fieldName])) { | ||||
|                 $grouped[$item->$fieldName] = []; | ||||
|             } | ||||
|  | ||||
|             if ($fieldNameToKeep === null) { | ||||
|                 $grouped[$item->$fieldName][$key] = $item; | ||||
|             } else { | ||||
|                 $grouped[$item->$fieldName][$key] = $item->$fieldNameToKeep; | ||||
|             } | ||||
|  | ||||
|             unset($list[$key]); | ||||
|         } | ||||
|  | ||||
|         $direction($grouped); | ||||
|  | ||||
|         return $grouped; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Groups items by date | ||||
|      * | ||||
|      * @param   array   $list             list of items | ||||
|      * @param   string  $direction        ordering direction | ||||
|      * @param   string  $type             type of grouping | ||||
|      * @param   string  $monthYearFormat  date format to use | ||||
|      * @param   string  $field            date field to group by | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   5.2.0 | ||||
|      */ | ||||
|     public static function groupByDate($list, $direction = 'ksort', $type = 'year', $monthYearFormat = 'F Y', $field = 'created') | ||||
|     { | ||||
|         $grouped = []; | ||||
|  | ||||
|         if (!\is_array($list)) { | ||||
|             if ($list === '') { | ||||
|                 return $grouped; | ||||
|             } | ||||
|  | ||||
|             $list = [$list]; | ||||
|         } | ||||
|  | ||||
|         foreach ($list as $key => $item) { | ||||
|             switch ($type) { | ||||
|                 case 'month_year': | ||||
|                     $month_year = StringHelper::substr($item->$field, 0, 7); | ||||
|  | ||||
|                     if (!isset($grouped[$month_year])) { | ||||
|                         $grouped[$month_year] = []; | ||||
|                     } | ||||
|  | ||||
|                     $grouped[$month_year][$key] = $item; | ||||
|                     break; | ||||
|  | ||||
|                 default: | ||||
|                     $year = StringHelper::substr($item->$field, 0, 4); | ||||
|  | ||||
|                     if (!isset($grouped[$year])) { | ||||
|                         $grouped[$year] = []; | ||||
|                     } | ||||
|  | ||||
|                     $grouped[$year][$key] = $item; | ||||
|                     break; | ||||
|             } | ||||
|  | ||||
|             unset($list[$key]); | ||||
|         } | ||||
|  | ||||
|         $direction($grouped); | ||||
|  | ||||
|         if ($type === 'month_year') { | ||||
|             foreach ($grouped as $group => $items) { | ||||
|                 $date                      = new Date($group); | ||||
|                 $formatted_group           = $date->format($monthYearFormat); | ||||
|                 $grouped[$formatted_group] = $items; | ||||
|  | ||||
|                 unset($grouped[$group]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $grouped; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Groups items by tags | ||||
|      * | ||||
|      * @param   array   $list       list of items | ||||
|      * @param   string  $direction  ordering direction | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   5.2.0 | ||||
|      */ | ||||
|     public static function groupByTags($list, $direction = 'ksort') | ||||
|     { | ||||
|         $grouped  = []; | ||||
|         $untagged = []; | ||||
|  | ||||
|         if (!$list) { | ||||
|             return $grouped; | ||||
|         } | ||||
|  | ||||
|         foreach ($list as $item) { | ||||
|             if ($item->tags->itemTags) { | ||||
|                 foreach ($item->tags->itemTags as $tag) { | ||||
|                     $grouped[$tag->title][] = $item; | ||||
|                 } | ||||
|             } else { | ||||
|                 $untagged[] = $item; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $direction($grouped); | ||||
|  | ||||
|         if ($untagged) { | ||||
|             $grouped['MOD_ARTICLES_UNTAGGED'] = $untagged; | ||||
|         } | ||||
|  | ||||
|         return $grouped; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user