set('THIS', $current); $Pagination->set('LAST', $last); $Pagination->set('HREF', "{$location}?site=%d"); return $Pagination; } #=============================================================================== # Helper function to reduce duplicate code #=============================================================================== function generateCategoryItemTemplate(Category $Category, bool $is_root = FALSE): Template { $CategoryRepository = Application::getRepository('Category'); foreach($CategoryRepository->findWithParents($Category->getID()) as $Category) { $category_data = generateItemTemplateData($Category); $category_list[] = $category_data; } $Template = TemplateFactory::build('category/item'); $Template->set('IS_ROOT', $is_root); $Template->set('CATEGORY', $category_data ?? []); $Template->set('CATEGORIES', $category_list ?? []); $Template->set('COUNT', [ 'POST' => $CategoryRepository->getNumberOfPosts($Category), 'CHILDREN' => $CategoryRepository->getNumberOfChildren($Category) ]); return $Template; } #=============================================================================== # Helper function to reduce duplicate code #=============================================================================== function generatePageItemTemplate(Page $Page, User $User): Template { $Template = TemplateFactory::build('page/item'); $Template->set('PAGE', generateItemTemplateData($Page)); $Template->set('USER', generateItemTemplateData($User)); return $Template; } #=============================================================================== # Helper function to reduce duplicate code #=============================================================================== function generatePostItemTemplate(Post $Post, User $User): Template { $CategoryRepository = Application::getRepository('Category'); foreach($CategoryRepository->findWithParents($Post->get('category')) as $Category) { $category_data = generateItemTemplateData($Category); $categories[] = $category_data; } $Template = TemplateFactory::build('post/item'); $Template->set('POST', generateItemTemplateData($Post)); $Template->set('USER', generateItemTemplateData($User)); $Template->set('CATEGORY', $category_data ?? []); $Template->set('CATEGORIES', $categories ?? []); return $Template; } #=============================================================================== # Helper function to reduce duplicate code #=============================================================================== function generateUserItemTemplate(User $User): Template { $Template = TemplateFactory::build('user/item'); $Template->set('USER', generateItemTemplateData($User)); return $Template; } #=============================================================================== # Helper function to reduce duplicate code #=============================================================================== function generateItemTemplateData(EntityInterface $Entity): array { $ArgumentParser = new ArgumentParser; $MarkdownParser = new MarkdownParser; $attribute = $Entity->getAll(['password']); $attribute = array_change_key_case($attribute, CASE_UPPER); $text = parseContentTags($Entity->get('body')); $arguments = $ArgumentParser->parse($Entity->get('argv') ?? ''); $images = $MarkdownParser->parse($text)['img']['src'] ?? []; $images = array_map('htmlentities', $images); return [ 'URL' => Application::getEntityURL($Entity), 'GUID' => generatePseudoGUID($Entity), 'ARGV' => $arguments, 'ATTR' => $attribute, 'PREV' => FALSE, 'NEXT' => FALSE, 'FILE' => [ 'LIST' => $images, ], 'BODY' => [ 'TEXT' => function() use($text) { return $text; }, 'HTML' => function() use($Entity) { return parseEntityContent($Entity); } ] ]; } #=============================================================================== # Generate a nested tree from a category data array #=============================================================================== function generateCategoryDataTree(array $category_data, $root = 0): array { foreach($category_data as &$category){ $tree[intval($category['PARENT'])][] = &$category; unset($category['PARENT']); } foreach($category_data as &$category){ if (isset($tree[$category['ID']])){ $category['CHILDS'] = $tree[$category['ID']]; } } return $tree[$root] ?? []; } #=============================================================================== # Generate pseudo GUID for entity #=============================================================================== function generatePseudoGUID(EntityInterface $Entity) { switch(get_class($Entity)) { case "ORM\Entities\Post": $attr = Application::get('POST.FEED_GUID'); break; default: $attr = ['id', 'time_insert']; } foreach($attr as $attribute) { $attributes[] = $Entity->get($attribute); } return sha1(implode('', $attributes)); } #=============================================================================== # Parse content tags #=============================================================================== function parseContentTags(string $text): string { $entity_tags = '#\{(POST|PAGE|USER)\[([0-9]+)\]\}#'; $text = preg_replace_callback($entity_tags, function($matches) { $namespace = ucfirst(strtolower($matches[1])); $Repository = Application::getRepository($namespace); if($Entity = $Repository->find($matches[2])) { return Application::getEntityURL($Entity); } else { return '{undefined}'; } }, $text); $base_tag = '#\{BASE\[\"([^"]+)\"\]\}#'; $file_tag = '#\{FILE\[\"([^"]+)\"\]\}#'; $text = preg_replace($base_tag, \Application::getURL('$1'), $text); $text = preg_replace($file_tag, \Application::getFileURL('$1'), $text); return $text; } #=============================================================================== # Parse entity content #=============================================================================== function parseEntityContent(EntityInterface $Entity): string { $text = parseContentTags($Entity->get('body')); if(Application::get('WRAP_EMOTICONS')) { $EmoticonParser = new EmoticonParser; $text = $EmoticonParser->transform($text); } $MarkdownParser = new MarkdownParser; return $MarkdownParser->transform($text); } #=============================================================================== # Parser for datetime formatted strings [YYYY-MM-DD HH:II:SS] #=============================================================================== function parseDatetime($datetime, $format): string { list($date, $time) = explode(' ', $datetime); list($DATE['Y'], $DATE['M'], $DATE['D']) = explode('-', $date); list($TIME['H'], $TIME['M'], $TIME['S']) = explode(':', $time); $unixtime = strtotime($datetime); return strtr($format, [ '[Y]' => $DATE['Y'], '[M]' => $DATE['M'], '[D]' => $DATE['D'], '[H]' => $TIME['H'], '[I]' => $TIME['M'], '[S]' => $TIME['S'], '[W]' => strftime('%A', $unixtime), '[F]' => strftime('%B', $unixtime), '[DATE]' => $date, '[TIME]' => $time, '[RFC2822]' => date('r', $unixtime) ]); } #=============================================================================== # Get emoticons with their explanations #=============================================================================== function getUnicodeEmoticons(): array { return (new EmoticonParser)->getEmoticons(); } #=============================================================================== # Wrapper function for htmlspecialchars() #=============================================================================== function escapeHTML($string): string { return htmlspecialchars($string); } #=============================================================================== # Remove all double line breaks from string #=============================================================================== function removeDoubleLineBreaks($string): string { return preg_replace('#(\r?\n){2,}#', "\n\n", $string); } #=============================================================================== # Remove all multiple whitespace characters #=============================================================================== function removeWhitespace($string): string { return preg_replace('/\s+/S', ' ', trim($string)); } #=============================================================================== # Return truncated string #=============================================================================== function truncate($string, $length, $replace = '') { if(mb_strlen($string) > $length) { $truncated = preg_replace("/^(.{0,{$length}}\\b).*/su", '$1', $string); $truncated = trim($truncated); # The additional trim call is useful, because if $truncated is empty, # then there will be an unnecessary space between those two variables # if $replace is preceded by a space (for example: " […]"). return trim("{$truncated}{$replace}"); } return $string; } #=============================================================================== # Return excerpt content #=============================================================================== function excerpt($string, $length = 500, $replace = ' […]') { $string = strip_tags($string); $string = removeDoubleLineBreaks($string); $string = truncate($string, $length, $replace); $string = nl2br($string); return $string; } #=============================================================================== # Return content for meta description #=============================================================================== function description($string, $length = 200, $replace = ' […]') { $string = strip_tags($string); $string = removeWhitespace($string); $string = truncate($string, $length, $replace); return $string; } #=============================================================================== # Generate a valid slug URL part from a string #=============================================================================== function generateSlug($string, $separator = '-') { $string = strtr(mb_strtolower($string), [ 'ä' => 'ae', 'ö' => 'oe', 'ü' => 'ue', 'ß' => 'ss' ]); $string = preg_replace('#[^[:lower:][:digit:]]+#', $separator, $string); return trim($string, $separator); } #=============================================================================== # Function for use in templates to get data of a category #=============================================================================== function CATEGORY(int $id): array { $Repository = Application::getRepository('Category'); if($Category = $Repository->find($id)) { return generateItemTemplateData($Category); } return []; } #=============================================================================== # Function for use in templates to get data of a page #=============================================================================== function PAGE(int $id): array { $Repository = Application::getRepository('Page'); if($Page = $Repository->find($id)) { return generateItemTemplateData($Page); } return []; } #=============================================================================== # Function for use in templates to get data of a post #=============================================================================== function POST(int $id): array { $Repository = Application::getRepository('Post'); if($Post = $Repository->find($id)) { return generateItemTemplateData($Post); } return []; } #=============================================================================== # Function for use in templates to get data of a user #=============================================================================== function USER(int $id): array { $Repository = Application::getRepository('User'); if($User = $Repository->find($id)) { return generateItemTemplateData($User); } return []; }