From e6cef37e0c782fe770db20888d99c17d10e2c479 Mon Sep 17 00:00:00 2001 From: Thomas Lange Date: Thu, 1 Jul 2021 20:11:34 +0200 Subject: Add category system to categorize posts (readme) This commit implements a new category system to categorize posts. Each category can have an unlimited number of nested children categories. A single post don't necessarily need to be in a category, but it can. Each category can have a full content body like posts or pages, so you have enough space to describe the content of your categories. Please note that you need to have at least the following MySQL/MariaDB versions to use the category system, because it uses "WITH RECURSIVE" database queries, the so-called "Common-Table-Expressions (CTE)". MariaDB: 10.2.2 MySQL: 8.0 See: https://mariadb.com/kb/en/with/ See: https://dev.mysql.com/doc/refman/8.0/en/with.html --- core/include/category/list.php | 69 +++++++++++++++++++++ core/include/category/main.php | 134 +++++++++++++++++++++++++++++++++++++++++ core/include/post/main.php | 17 ++++++ 3 files changed, 220 insertions(+) create mode 100644 core/include/category/list.php create mode 100644 core/include/category/main.php (limited to 'core/include') diff --git a/core/include/category/list.php b/core/include/category/list.php new file mode 100644 index 0000000..9bd2a68 --- /dev/null +++ b/core/include/category/list.php @@ -0,0 +1,69 @@ +getCount(['parent' => NULL]); +$count = $CategoryRepository->getCount(); +$lastSite = ceil($count / $site_size); + +$currentSite = HTTP::GET('site') ?? 1; +$currentSite = intval($currentSite); + +if($currentSite < 1 OR ($currentSite > $lastSite AND $lastSite > 0)) { + Application::error404(); +} + +#=============================================================================== +# Single redirect +#=============================================================================== +if(Application::get('CATEGORY.SINGLE_REDIRECT') === TRUE AND $count === 1) { + $Category = $CategoryRepository->getLast(); + HTTP::redirect(Application::getEntityURL($Category)); +} + +#=============================================================================== +# Get paginated category list +#=============================================================================== +$categories = $CategoryRepository->getPaginatedTree( + $site_size, + ($currentSite-1) * $site_size +); + +foreach($categories as $Category) { + $templates[] = generateCategoryItemTemplate($Category, TRUE); +} + +#=============================================================================== +# Build document +#=============================================================================== +$ListTemplate = Template\Factory::build('category/list'); +$ListTemplate->set('PAGINATION', [ + 'THIS' => $currentSite, + 'LAST' => $lastSite, + 'HTML' => generateCategoryNaviTemplate($currentSite) +]); +$ListTemplate->set('LIST', [ + 'CATEGORIES' => $templates ?? [] +]); + +$MainTemplate = Template\Factory::build('main'); +$MainTemplate->set('HTML', $ListTemplate); +$MainTemplate->set('HEAD', [ + 'NAME' => $Language->text('title_category_overview', $currentSite) +]); + +echo $MainTemplate; diff --git a/core/include/category/main.php b/core/include/category/main.php new file mode 100644 index 0000000..57f8625 --- /dev/null +++ b/core/include/category/main.php @@ -0,0 +1,134 @@ +findWithParentsBy('slug', $param)) { + if($categories = $CategoryRepository->findWithParents($param)) { + $redirect_scheduled = TRUE; + } + } +} + +else { + if(!$categories = $CategoryRepository->findWithParents($param)) { + if($categories = $CategoryRepository->findWithParentsBy('slug', $param)) { + $redirect_scheduled = TRUE; + } + } +} + +#=============================================================================== +# Throw 404 error if category (with parents) could not be found +#=============================================================================== +if(!isset($categories)) { + Application::error404(); +} + +#=============================================================================== +# The last element represents the current category +#=============================================================================== +$Category = $categories[array_key_last($categories)]; + +#=============================================================================== +# If category with parents was found by alternative, redirect to correct URL +#=============================================================================== +if(isset($redirect_scheduled)) { + HTTP::redirect(Application::getEntityURL($Category)); +} + +#=============================================================================== +# Generate category template data (including parents) +#=============================================================================== +foreach($categories as $_Category) { + $category_list[] = generateItemTemplateData($_Category); +} + +#=============================================================================== +# Define data variable for current category +#=============================================================================== +$category_data = $category_list[array_key_last($category_list)]; + +#=============================================================================== +# Generate category children list +#=============================================================================== +$child_categories = $CategoryRepository->getAll( + ['parent' => $Category->getID()], + Application::get('CATEGORY.LIST_SORT') +); + +foreach($child_categories as $ChildCategory) { + $child_templates[] = generateCategoryItemTemplate($ChildCategory); +} + +#=============================================================================== +# Pagination (for posts in this category) +#=============================================================================== +$site_size = Application::get('POST.LIST_SIZE'); +$site_sort = Application::get('POST.LIST_SORT'); + +$count = $PostRepository->getCountByCategory($Category); +$lastSite = ceil($count / $site_size); + +$currentSite = HTTP::GET('site') ?? 1; +$currentSite = intval($currentSite); + +if($currentSite < 1 OR ($currentSite > $lastSite AND $lastSite > 0)) { + Application::error404(); +} + +#=============================================================================== +# Get paginated post list for this category +#=============================================================================== +$posts = $PostRepository->getAll( + ['category' => $Category->getID()], + $site_sort, + ($currentSite-1) * $site_size.','.$site_size +); + +foreach($posts as $Post) { + $User = $UserRepository->find($Post->get('user')); + $post_templates[] = generatePostItemTemplate($Post, $User); +} + +#=============================================================================== +# Build document +#=============================================================================== +$CategoryTemplate = Template\Factory::build('category/main'); +$CategoryTemplate->set('CATEGORY', $category_data); +$CategoryTemplate->set('CATEGORIES', $category_list ?? []); +$CategoryTemplate->set('COUNT', [ + 'POST' => $PostRepository->getCountByCategory($Category), + 'CHILDREN' => $CategoryRepository->getChildrenCount($Category) +]); +$CategoryTemplate->set('PAGINATION', [ + 'THIS' => $currentSite, + 'LAST' => $lastSite, + 'HTML' => generatePostNaviTemplate($currentSite) +]); +$CategoryTemplate->set('LIST', [ + 'POSTS' => $post_templates ?? [], + 'CATEGORIES' => $child_templates ?? [] +]); + +$MainTemplate = Template\Factory::build('main'); +$MainTemplate->set('TYPE', 'CATEGORY'); +$MainTemplate->set('CATEGORY', $category_data); +$MainTemplate->set('CATEGORIES', $category_list ?? []); +$MainTemplate->set('HTML', $CategoryTemplate); +$MainTemplate->set('HEAD', [ + 'NAME' => $category_data['ATTR']['NAME'], + 'DESC' => description($category_data['BODY']['HTML'](), + Application::get('CATEGORY.DESCRIPTION_SIZE')), + 'PERM' => $category_data['URL'], + 'OG_IMAGES' => $category_data['FILE']['LIST'] +]); + +echo $MainTemplate; diff --git a/core/include/post/main.php b/core/include/post/main.php index 86008f6..bfccc7b 100644 --- a/core/include/post/main.php +++ b/core/include/post/main.php @@ -2,6 +2,7 @@ #=============================================================================== # Get repositories #=============================================================================== +$CategoryRepository = Application::getRepository('Category'); $PostRepository = Application::getRepository('Post'); $UserRepository = Application::getRepository('User'); @@ -49,12 +50,28 @@ if($NextPost = $PostRepository->findNext($Post)) { $post_data['NEXT'] = generateItemTemplateData($NextPost); } +#=============================================================================== +# Generate category template data (including parents) +#=============================================================================== +foreach($CategoryRepository->findWithParents($Post->get('category')) as $Category) { + $category_list[] = generateItemTemplateData($Category); +} + +#=============================================================================== +# Define data variable for current category +#=============================================================================== +if(isset($category_list)) { + $category_data = $category_list[array_key_last($category_list)]; +} + #=============================================================================== # Build document #=============================================================================== $PostTemplate = Template\Factory::build('post/main'); $PostTemplate->set('POST', $post_data); $PostTemplate->set('USER', $user_data); +$PostTemplate->set('CATEGORY', $category_data ?? []); +$PostTemplate->set('CATEGORIES', $category_list ?? []); $MainTemplate = Template\Factory::build('main'); $MainTemplate->set('TYPE', 'POST'); -- cgit v1.2.3