/** * Returns the categories * * @param FTL_Binding * @param array/null * * @return array * */ public static function get_categories(FTL_Binding $tag) { // Categories model self::$ci->load->model('category_model'); // Current page $page = $tag->get('page'); // Local storage key $lsk = '__all__'; // Get the local cache data $element_name = $tag->getParentName(); $element = $tag->get($element_name); if (!is_null($element)) { $lsk = '__' . $element_name . '__' . $element['name']; } // Set the local cache data if (!isset(self::$categories[$lsk])) { // CSS class to use for the current category $active_class = $tag->getAttribute('active_class', 'active'); // Asked category $asked_category_name = self::get_asked_category_uri(); // Check if the element has one category array (eg. for Articles) if (isset($element['categories'])) { $categories = $element['categories']; // Fix the 'nb' key (nb_articles using this category) foreach ($categories as $key => $category) { $categories[$key]['nb'] = '1'; } } else { if ($element_name == 'page') { $id_page = !is_null($page) ? $page['id_page'] : NULL; } else { $id_page = NULL; } $categories = self::$ci->category_model->get_categories_list($id_page, Settings::get_lang()); } $page_url = !is_null($page) ? trim($page['absolute_url'], '/') . '/' : Pages::get_home_page_url(); $category_uri_segment = self::get_config_special_uri_segment('category'); // Add the URL to the category to each category row // Also add the active class foreach ($categories as $key => $category) { $categories[$key]['url'] = $page_url . $category_uri_segment . '/' . $category['name']; $categories[$key]['lang_url'] = $page_url . $category_uri_segment . '/' . $category['name']; // Active category ? $categories[$key]['active_class'] = $category['name'] == $asked_category_name ? $active_class : ''; $categories[$key]['is_active'] = !empty($categories[$key]['active_class']) ? TRUE : FALSE; } self::$categories[$lsk] = array_values($categories); } return self::$categories[$lsk]; }
/** * Returns one article's author * * @param FTL_Binding * * @return string * * @usage <ion:article:user [who='updater']> * <ion:name /> * <ion:email /> * <ion:join_date /> * ... * </ion:article:user> * */ public static function tag_writer(FTL_Binding $tag) { self::load_model('user_model'); $parent_tag_name = $tag->getParentName(); $element = $tag->get($parent_tag_name); $user_key = $tag->getAttribute('who', 'author'); if (!is_null($element) && isset($element[$user_key])) { $user = self::$ci->user_model->get(array('username' => $element[$user_key])); $tag->set('writer', $user); } return self::wrap($tag, $tag->expand()); }
/** * Returns the pagination base URL * Adds all special URI element to the URL they're found * * @param FTL_Binding * @return string * */ public static function get_pagination_base_url(FTL_Binding $tag) { $pagination_base_uri = ''; $page = $tag->get('page'); if (is_null($page)) { $page = self::registry('page'); } $special_uri_array = self::get_special_uri_array(); if (!is_null($special_uri_array)) { foreach ($special_uri_array as $code => $args) { if ($code != 'pagination') { $pagination_base_uri .= '/' . self::get_config_special_uri_segment($code); $pagination_base_uri .= '/' . implode('/', $args); } } } $pagination_base_uri = $page['absolute_url'] . $pagination_base_uri . '/'; $pagination_base_uri .= self::get_config_special_uri_segment('pagination'); return $pagination_base_uri; }
/** * Return an adjacent page * Internal use * * @param FTL_Binding object * @param String Mode. 'prev' or 'next' * * @return Mixed Page array or FALSE if no page was found. * */ private static function get_adjacent_page(FTL_Binding $tag, $mode = 'prev') { $mode = $mode == 'prev' ? -1 : 1; $menu_name = $tag->getAttribute('menu'); $menu_name = is_null($menu_name) ? 'main' : $menu_name; $id_menu = 1; // $current_page = self::$context->registry('page'); // Get the current page: Fall down to registry if no one found in tag $current_page = $tag->get('page'); foreach (self::registry('menus') as $menu) { if ($menu_name == $menu['name']) { $id_menu = $menu['id_menu']; } } $level = is_null($tag->getAttribute('level')) ? 0 : $tag->getAttribute('level'); // Order the pages, because the are not. if (is_null(self::$ordered_pages)) { self::$ordered_pages = array(); self::order_pages(self::registry('pages'), self::$ordered_pages); } // Filter by menu and asked level : We only need the asked level pages ! $pages = array(); foreach (self::$ordered_pages as $p) { if ($p['level'] == $level && $p['id_menu'] == $id_menu) { $pages[] = $p; } } // Filter on 'appears'=>'1' $pages = array_values(array_filter($pages, array(__CLASS__, '_filter_appearing_pages'))); foreach ($pages as $idx => $page) { if ($page['id_page'] == $current_page['id_page']) { if (!empty($pages[$idx + $mode])) { return $pages[$idx + $mode]; } } } return FALSE; }
/** * Returns the media complete src URL * * @usage : <ion:src [size="200" square="<true|false>" unsharp="true|false"] /> * For pictures, if size is set, returns the path to one thumb with this size * */ public static function tag_media_src(FTL_Binding $tag) { $media = $tag->get('media'); if (!empty($media)) { if ($media['type'] === 'picture') { $settings = self::get_src_settings($tag); if (empty($settings['size'])) { return base_url() . $media['path']; } self::$ci->load->library('medias'); return self::$ci->medias->get_src($media, $settings, Settings::get('no_source_picture')); } if ($media['provider'] != '') { return $media['path']; } return base_url() . $media['path']; } return ''; }
public static function create_sub_tags(FTL_Binding $tag, $key = NULL, $prefix = NULL) { $key = !is_null($key) ? $key : $tag->getName(); $data = !is_null($tag->get($key)) ? $tag->get($key) : NULL; $prefix = !is_null($prefix) ? $prefix . ':' : ''; if (!empty($data)) { $names = array_keys($data); foreach ($names as $name) { if (!is_array($data[$name]) && !isset(self::$tags[$name]) && !isset(self::$tags[$key . ':' . $name])) { self::$context->define_tag($prefix . $key . ':' . $name, array(__CLASS__, 'tag_simple_value')); } } } }
/** * Return a tree navigation based on the given helper. * One helper is needed to use this tag. * The default helper is /application/helpers/navigation_helper->get_tree_navigation() * If you wish to change the * * @param FTL_Binding object * * @return string * * @usage <ion:tree_navigation [helper="navigation::your_helper_method"] /> * */ public static function tag_tree_navigation(FTL_Binding $tag) { // Page : Asked one through the page tag $page = $tag->get('page'); // Current page if (is_null($page)) { $page = self::registry('page'); } // If 404 : Put empty vars, so the menu will prints out without errors /* if ( !isset($page['id_page'])) { $page = array( 'id_page' => '', 'id_parent' => '' ); } */ // Menu : Main menu by default $menu_name = $tag->getAttribute('menu', 'main'); $id_menu = 1; foreach (self::registry('menus') as $menu) { if ($menu_name == $menu['name']) { $id_menu = $menu['id_menu']; break; } } // Attribute level, else parent page level + 1 $from_level = $tag->getAttribute('level', 0); // Depth $depth = $tag->getAttribute('depth', -1); // Attribute : active class, first_class, last_class $active_class = $tag->getAttribute('active_class', 'active'); $first_class = $tag->getAttribute('first_class', ''); $last_class = $tag->getAttribute('last_class', ''); // Display hidden navigation elements ? $display_hidden = $tag->getAttribute('display_hidden', FALSE); // Includes articles as menu elements $with_articles = $tag->getAttribute('articles', FALSE); // Attribute : HTML Tree container ID & class attribute $id = $tag->getAttribute('id'); if (strpos($id, 'id') !== FALSE) { $id = str_replace('\'', '"', $id); } $class = $tag->getAttribute('class'); if (strpos($active_class, 'class') !== FALSE) { $active_class = str_replace('\'', '"', $active_class); } // Attribute : Helper to use to print out the tree navigation $helper = $tag->getAttribute('helper', 'navigation'); // Get helper method $helper_function = substr(strrchr($helper, ':'), 1) ? substr(strrchr($helper, ':'), 1) : 'get_tree_navigation'; $helper = strpos($helper, ':') !== FALSE ? substr($helper, 0, strpos($helper, ':')) : $helper; // load the helper self::$ci->load->helper($helper); // Page from locals : By ref because of active_class definition // $pages = $tag->locals->_pages; $pages = self::registry('pages'); /* Get the reference parent page ID * Note : this is depending on the whished level. * If the curent page level > asked level, we need to find recursively the parent page which has the good level. * This is done to avoid tree cut when navigation to a child page * * e.g : * * On the "services" page and each subpage, we want the tree navigation composed by the sub-pages of "services" * We are in the page "offer" * We have to find out that the level 1 parent is "services" * * Page structure Level * * home 0 * |_ about 1 * |_ services 1 <- We want all the nested nav starting at level 1 from this parent page * |_ development 2 * |_ design 2 * |_ offer 3 <- We are here. * |_ portfolio 3 */ $page_level = isset($page['level']) ? $page['level'] : 0; // Asked Level exists $parent_page = array('id_page' => $from_level > 0 ? $page['id_page'] : 0, 'id_parent' => isset($page['id_parent']) ? $page['id_parent'] : 0); if ($from_level !== FALSE) { $parent_page = array('id_page' => $from_level > 0 ? $page['id_page'] : 0, 'id_parent' => isset($page['id_parent']) ? $page['id_parent'] : 0); } else { foreach ($pages as $p) { // Parent page is the id_subnav page if ($p['id_page'] == $page['id_subnav']) { $parent_page = $p; } } } // Find out the wished parent page while ($page_level >= $from_level && $from_level > 0) { $potential_parent_page = array(); foreach ($pages as $p) { if ($p['id_page'] == $parent_page['id_parent']) { $potential_parent_page = $p; break; } } if (!empty($potential_parent_page)) { $parent_page = $potential_parent_page; $page_level = $parent_page['level']; } else { $page_level--; } } // Active pages array. Array of ID $active_pages = Structure::get_active_pages($pages, $page['id_page']); foreach ($pages as $key => $p) { $pages[$key]['active_class'] = in_array($p['id_page'], $active_pages) ? $active_class : ''; } // Filter on 'appears'=>'1' $nav_pages = $pages; if ($display_hidden === FALSE) { $nav_pages = array_values(array_filter($pages, array('TagManager_Page', '_filter_appearing_pages'))); } $final_nav_pages = $nav_pages_list = array(); foreach ($nav_pages as $k => $np) { if ($np['id_menu'] == $id_menu) { $final_nav_pages[] = $np; $nav_pages_list[] = $np['id_page']; } } // Should we include articles ? $articles = FALSE; if ($with_articles == TRUE) { $entity = self::get_entity(); $id_active_article = $entity['type'] == 'article' ? $entity['id_entity'] : NULL; foreach ($final_nav_pages as $key => $p) { // TODO : Change for future "Articles" lib call $tag->set('page', $p); $articles = TagManager_Article::get_articles($tag); // Set active article if (!is_null($id_active_article)) { foreach ($articles as $akey => $a) { if ($a['id_article'] == $id_active_article) { $articles[$akey]['active_class'] = $active_class; $articles[$akey]['is_active'] = TRUE; } } } $final_nav_pages[$key]['articles'] = $articles; } } // Get the tree navigation array $tree = Structure::get_tree_navigation($final_nav_pages, $parent_page['id_page'], $from_level, $depth, $articles); // Return the helper function if (function_exists($helper_function)) { return call_user_func($helper_function, $tree, $id, $class, $first_class, $last_class); } }
/** * Search results tag * Parent tag for results * * @param FTL_Binding * @return string * @usage <ion:search:results> * */ public static function tag_search_results(FTL_Binding $tag) { $str = ''; // POST realm $realm = $tag->get('realm'); $tag->set('count', 0); if ($realm !== FALSE && $realm != '') { // Get the results if (is_null(self::$_articles)) { // Loads the serach module model self::$ci->load->model('search_model', '', TRUE); $articles = self::$ci->search_model->get_articles($realm); if (!empty($articles)) { // arrays of keys, for multisorting $knum = $kdate = array(); $unique = array(); foreach ($articles as $key => &$article) { // remove duplicates if (!in_array($article['id_article'], $unique)) { $unique[] = $article['id_article']; // set number of found words preg_match_all('#' . $realm . '#i', $article['title'] . ' ' . $article['content'], $match); $num = count($match[0]); $article['nb_words'] = $knum[$key] = $num; $kdate[$key] = strtotime($article['date']); } else { unset($articles[$key]); } } // Sort the results by realm occurences DESC first, by date DESC second. array_multisort($knum, SORT_DESC, SORT_NUMERIC, $kdate, SORT_DESC, SORT_NUMERIC, $articles); } // Init the articles URLs TagManager_Article::init_articles_urls($articles); // Adds the page URL to each article self::init_pages_urls($articles); self::$_articles = $articles; } // Add the number of result to the tag data $count = count(self::$_articles); $tag->set('count', $count); $tag->set('results', self::$_articles); foreach (self::$_articles as $key => $_article) { // The tag should at least do 1 expand to get the child "loop" attribute if ($tag->getAttribute('loop') === FALSE) { return $tag->expand(); } else { $tag->set('result', $_article); $tag->set('count', $count); $tag->set('index', $key); $str .= $tag->expand(); } } } // Expand the tag if no articles : Allows the children tags to be processed even not results were found // Must not be done if articles or this add one unwanted expand. if (empty(self::$_articles)) { $str .= $tag->expand(); } return $str; }
/** * @param FTL_Binding $tag * * @return string * */ public static function tag_static_item_field_options(FTL_Binding $tag) { $str = ''; $item = $tag->get('item'); $field_name = $tag->getParentName(); if (isset($item['fields'][$field_name])) { $field = $item['fields'][$field_name]; // All available values for this multi-value field $all_values = explode("\n", $field['value']); foreach ($all_values as $value) { $val_label = explode(':', $value); $tag->set('value', $val_label[0]); $tag->set('label', $val_label[1]); $str .= self::wrap($tag, $tag->expand()); } } return $str; }
public static function get_archives(FTL_Binding $tag) { // Categories model self::$ci->load->model('article_model'); // Page $page = $tag->get('page'); if (is_null($page)) { $page = self::registry('page'); } // Period format. see : http://php.net/manual/fr/function.date.php $format = $tag->getAttribute('format', 'F'); // Attribute : active class $active_class = $tag->getAttribute('active_class', 'active'); // filter $filter = $tag->getAttribute('filter', FALSE); if ($filter != FALSE) { $filter = self::process_filter($filter); } // month $with_month = $tag->getAttribute('month'); // order $order = $tag->getAttribute('order'); $order = $order == 'ASC' ? 'period ASC' : 'period DESC'; // Archive string : 'yyyy' or 'yyyy.mm'. Used for CSS active class $_archive_string = ''; // Archive URI args $args = self::get_special_uri_array('archives'); if (!empty($args)) { $_archive_string = isset($args[0]) ? $args[0] : ''; $_archive_string .= isset($args[1]) ? '.' . $args[1] : ''; } // Archives URI segment, as set in the config file $archives_uri_segment = self::get_config_special_uri_segment('archives'); // Get the archives $archives = self::$ci->article_model->get_archives_list(array('id_page' => $page['id_page']), Settings::get_lang(), $filter, $with_month, $order); // Translated period array $month_formats = array('D', 'l', 'F', 'M'); $page_url = !is_null($page) ? $page['absolute_url'] . '/' : Pages::get_home_page_url(); foreach ($archives as &$row) { $year = substr($row['period'], 0, 4); $month = substr($row['period'], 4); if ($month != '') { $month = strlen($month) == 1 ? '0' . $month : $month; $timestamp = mktime(0, 0, 0, $month, 1, $year); // Get date in the wished format $period = (string) date($format, $timestamp); // Translate the period month if (in_array($format, $month_formats)) { $period = lang(strtolower($period)); } $row['period'] = $period . ' ' . $year; $row['url'] = $page_url . $archives_uri_segment . '/' . $year . '/' . $month; $row['active_class'] = $year . '.' . $month == $_archive_string ? $active_class : ''; } else { $row['period'] = $year; $row['url'] = $page_url . $archives_uri_segment . '/' . $year; $row['active_class'] = $year == $_archive_string ? $active_class : ''; } $row['is_active'] = !empty($row['active_class']) ? TRUE : FALSE; } return $archives; }
/** * Find and parses the article view * * @param FTL_Binding * @param array * * @return string * */ private static function find_and_parse_article_view(FTL_Binding $tag, $article) { // Registered page $page = self::registry('page'); // Local articles $articles = $tag->get('articles'); // Try to get the view defined for article $tag_view = $tag->getAttribute('view'); $article_view = !is_null($tag_view) ? $tag_view : (!empty($article['view']) ? $article['view'] : NULL); if (!is_null($article_view)) { // Force first the view defined by the tag if (!is_null($tag_view)) { $article['view'] = $tag_view; } else { if (count($articles) == 1) { $article['view'] = $page['article_view']; } else { $article['view'] = $page['article_list_view']; } } } // Default article view if (empty($article['view'])) { $article['view'] = Theme::get_default_view('article'); } // View path $view_path = Theme::get_theme_path() . 'views/' . $article['view'] . EXT; // Return the Ionize default's theme view if (!file_exists($view_path)) { $view_path = Theme::get_theme_path() . 'views/' . Theme::get_default_view('article') . EXT; if (!file_exists($view_path)) { $view_path = APPPATH . 'views/' . Theme::get_default_view('article') . EXT; } } return $tag->parse_as_nested(file_get_contents($view_path)); }
/** * Article Core Tag Extend : Authors List tag * * @param FTL_Binding Tag object * @return String List of Authors * * @usage <ion:articles> * <ion:authors> * ... * </ion:authors> * <ion:articles> * */ public static function core_article_authors(FTL_Binding $tag) { $str = ''; // Model load self::load_model('demo_author_model', 'author_model'); // Get the article from local tag var : // The 'article' tag is a parent of this tag and has the 'article' data array set. $article = $tag->get('article'); $authors = self::$ci->author_model->get_linked_author('article', $article['id_article']); foreach ($authors as $author) { // Set the local tag var "author" $tag->set('author', $author); // Tag expand : Process of the children tags $str .= $tag->expand(); } return $str; }
/** * Element field generic tag * * @param FTL_Binding $tag * * @return string */ public static function tag_element_item_field(FTL_Binding $tag) { $item = $tag->get('item'); $field_key = $tag->getName(); if (isset($item['fields'][$field_key])) { $tag->set($field_key, $item['fields'][$field_key]); // Availability of field for TagManager->tag_extend_field_medias() $tag->set('extend', $item['fields'][$field_key]); } return self::wrap($tag, $tag->expand()); }