function nvweb_search($vars = array()) { global $website; global $webuser; global $DB; global $current; global $cache; global $structure; global $theme; $out = array(); $search_what = $_REQUEST[$vars['request']]; $search_archive = array(); if (!empty($_REQUEST['archive'])) { $search_archive = explode("-", $_REQUEST['archive']); } // YEAR, MONTH, CATEGORIES (separated by commas) if (isset($_REQUEST[$vars['request']]) || !empty($search_archive[0]) && !empty($search_archive[1])) { // LOG search request $wu_id = 0; if (!empty($webuser->id)) { $wu_id = $webuser->id; } $DB->execute(' INSERT INTO nv_search_log (id, website, date, webuser, origin, text) VALUES (0, :website, :date, :webuser, :origin, :text) ', array('website' => $website->id, 'date' => time(), 'webuser' => $wu_id, 'origin' => empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER'], 'text' => $search_what)); // prepare and execute the search $search_what = explode(' ', $search_what); $search_what = array_filter($search_what); if (empty($search_what)) { $search_what = array(); } $likes = array(); $likes[] = ' 1=1 '; foreach ($search_what as $what) { if (substr($what, 0, 1) == '-') { $likes[] = 'd.text NOT LIKE ' . protect('%' . substr($what, 1) . '%') . ' AND i.id IN( SELECT p.node_id FROM nv_properties_items p WHERE p.element = "item" AND p.website = ' . protect($website->id) . ' AND p.value NOT LIKE ' . protect('%' . substr($what, 1) . '%') . ' )'; } else { $likes[] = 'd.text LIKE ' . protect('%' . $what . '%') . ' OR i.id IN( SELECT p.node_id FROM nv_properties_items p WHERE p.element = "item" AND p.website = ' . protect($website->id) . ' AND p.value LIKE ' . protect('%' . $what . '%') . ' )'; } } if (!empty($search_archive)) { $start_date = gmmktime(0, 0, 0, $search_archive[1], 1, $search_archive[0]); $end_date = gmmktime(0, 0, 0, $search_archive[1] + 1, 1, $search_archive[0]); $likes[] = ' (i.date_to_display >= ' . $start_date . ')'; $likes[] = ' (i.date_to_display <= ' . $end_date . ')'; } if (!empty($search_archive[2])) { $vars['categories'] = $search_archive[2]; } $categories = NULL; if (isset($vars['categories'])) { if ($vars['categories'] == 'all') { $categories = array(0); $vars['children'] = 'true'; } else { if ($vars['categories'] == 'parent') { $categories = array($current['object']->id); $parent = $DB->query_single('parent', 'nv_structure', 'id = ' . intval($categories[0])); $categories = array($parent); } else { if ($vars['categories'] == 'nvlist_parent') { if ($vars['nvlist_parent_type'] === 'structure') { $categories = array($vars['nvlist_parent_item']->id); } } else { if (!is_numeric($vars['categories'])) { // if "categories" attribute has a comma, then we suppose it is a list of comma separated values // if not, then maybe we want to get the categories from a specific property of the current page if (strpos($vars['categories'], ',') === false) { $categories = nvweb_properties(array('property' => $vars['categories'])); } if (empty($categories) && @$vars['nvlist_parent_vars']['source'] == 'block_group') { $categories = nvweb_properties(array('mode' => 'block_group_block', 'property' => $vars['categories'])); } if (empty($categories)) { $categories = $vars['categories']; } if (!is_array($categories)) { $categories = explode(',', $categories); $categories = array_filter($categories); // remove empty elements } } else { $categories = explode(',', $vars['categories']); $categories = array_filter($categories); // remove empty elements } } } } } if ($vars['children'] == 'true') { $categories = nvweb_menu_get_children($categories); } // if we have categories="x" children="true" [to get the children of a category, but not itself] if ($vars['children'] == 'only') { $children = nvweb_menu_get_children($categories); for ($c = 0; $c < count($categories); $c++) { array_shift($children); } $categories = $children; } if (!empty($vars['children']) && intval($vars['children']) > 0) { $children = nvweb_menu_get_children($categories, intval($vars['children'])); for ($c = 0; $c < count($categories); $c++) { array_shift($children); } $categories = $children; } // apply a filter on categories, if given // example: request_categories="c" ... in the url &q=text&c=23,35 if (!empty($vars['request_categories'])) { $categories_filter = explode(",", $_REQUEST[$vars['request_categories']]); if (empty($categories)) { // note: categories may be empty by the rules applies on categories + children; // in this case we give preference to the request_categories filter $categories = array_values($categories_filter); } else { for ($cf = 0; $cf < count($categories_filter); $cf++) { if (!in_array($categories_filter[$cf], $categories)) { unset($categories_filter[$cf]); } $categories_filter = array_filter($categories_filter); } $categories = $categories_filter; } } // retrieve entries $permission = !empty($_SESSION['APP_USER#' . APP_UNIQUE]) ? 1 : 0; $access = !empty($current['webuser']) ? 1 : 2; if (empty($_GET['page'])) { $_GET['page'] = 1; } $offset = intval($_GET['page'] - 1) * $vars['items']; // get order type: PARAMETER > NV TAG PROPERTY > DEFAULT (priority given in CMS) $order = @$_REQUEST['order']; if (empty($order)) { $order = @$vars['order']; } if (empty($order)) { // default order: latest $order = 'latest'; } $orderby = nvweb_list_get_orderby($order); if (empty($vars['items']) || $vars['items'] == '0') { $vars['items'] = 500; //2147483647; // maximum integer // NOTE: having >500 items on a page without a paginator is probably a bad idea... disagree? Contact Navigate CMS team! } else { if (!is_numeric($vars['items'])) { $max_items = ""; // the number of items is defined by a property $max_items = nvweb_properties(array('property' => $vars['items'])); if (empty($max_items) && @$vars['nvlist_parent_vars']['source'] == 'block_group') { $max_items = nvweb_properties(array('mode' => 'block_group_block', 'property' => $vars['items'], 'id' => $vars['nvlist_parent_item']->id, 'uid' => $vars['nvlist_parent_item']->uid)); } if (!empty($max_items)) { $vars['items'] = $max_items; } else { $vars['items'] = 500; } // default maximum } } // TODO: try to optimize search to use less memory and increase the maximum number of items $DB->query(' SELECT SQL_CALC_FOUND_ROWS rs.id FROM ( SELECT i.id as id, i.permission, i.date_published, i.date_unpublish, i.date_to_display, COALESCE(NULLIF(i.date_to_display, 0), i.date_created) as pdate, i.position as position, wd.text as title FROM nv_items i, nv_webdictionary d LEFT JOIN nv_webdictionary wd ON wd.node_id = d.node_id AND wd.lang = ' . protect($current['lang']) . ' AND wd.node_type = "item" AND wd.website = ' . protect($website->id) . ' WHERE i.website = ' . $website->id . ' AND i.permission <= ' . $permission . ' AND (i.date_published = 0 OR i.date_published < ' . core_time() . ') AND (i.date_unpublish = 0 OR i.date_unpublish > ' . core_time() . ') AND (i.access = 0 OR i.access = ' . $access . ') AND d.website = ' . protect($website->id) . ' AND d.node_id = i.id AND d.lang = ' . protect($current['lang']) . ' AND (d.node_type = "item" OR d.node_type = "tags") AND ( ' . implode(' AND ', $likes) . ' ) ' . (empty($categories) ? '' : 'AND category IN(' . implode(",", $categories) . ')') . ' ' . $orderby . ' ) rs GROUP BY rs.id LIMIT ' . $vars['items'] . ' OFFSET ' . $offset); $rs = $DB->result(); $total = $DB->foundRows(); for ($i = 0; $i < count($rs); $i++) { if (empty($rs[$i]->id)) { break; } $item = new item(); $item->load($rs[$i]->id); // get the nv list template $item_html = $vars['template']; // now, parse the nvlist_conditional tags (with html source code inside (and other nvlist tags)) unset($nested_condition_fragments); list($item_html, $nested_conditional_fragments) = nvweb_list_isolate_conditionals($item_html); $conditional_placeholder_tags = nvweb_tags_extract($item_html, 'nvlist_conditional_placeholder', true, true, 'UTF-8'); // selfclosing = true while (!empty($conditional_placeholder_tags)) { $tag = $conditional_placeholder_tags[0]; $conditional = $nested_conditional_fragments[$tag["attributes"]["id"]]; $conditional_html_output = nvweb_list_parse_conditional($conditional, $item, $conditional['nvlist_conditional_template'], $i, count($rs)); $item_html = str_replace($tag["full_tag"], $conditional_html_output, $item_html); $conditional_placeholder_tags = nvweb_tags_extract($item_html, 'nvlist_conditional_placeholder', true, true, 'UTF-8'); // selfclosing = true } // now parse the (remaining) common nvlist tags $template_tags = nvweb_tags_extract($item_html, 'nvlist', true, true, 'UTF-8'); // selfclosing = true if (empty($item_html)) { $item_html = array(); $item_html[] = '<div class="search-result-item">'; $item_html[] = ' <div class="search-result-title"><a href="' . $website->absolute_path() . $item->paths[$current['lang']] . '">' . $item->dictionary[$current['lang']]['title'] . '</a></div>'; $item_html[] = ' <div class="search-result-summary">' . core_string_cut($item->dictionary[$current['lang']]['section-main'], 300, '…') . '</div>'; $item_html[] = '</div>'; $item_html = implode("\n", $item_html); $out[] = $item_html; } else { // parse special template tags foreach ($template_tags as $tag) { $content = nvweb_list_parse_tag($tag, $item, $vars['source'], $i, $i + $offset, $total); $item_html = str_replace($tag['full_tag'], $content, $item_html); } $out[] = $item_html; } } if ($total == 0) { $search_results_empty_text = $theme->t("no_results_found"); if (isset($vars['no_results_found'])) { $search_results_empty_text = $theme->t($vars["no_results_found"]); } if (empty($search_results_empty_text) || $search_results_empty_text == 'no_results_found') { $search_results_empty_text = t(645, "No results found"); } // display the error message only if // 1) it's not empty // 2) the template is preventing the display of any error message in the search ( no_results_found="" ) if (!empty($search_results_empty_text) && (!isset($vars['no_results_found']) || isset($vars['no_results_found']) && !empty($vars['no_results_found']))) { $out[] = '<div class="search-results-empty">'; $out[] = $search_results_empty_text; $out[] = '</div>'; } } $archive = $_REQUEST['archive']; if (!empty($archive)) { $archive = 'archive=' . $archive . '&'; } if (isset($vars['paginator']) && $vars['paginator'] != 'false') { $search_url = '?' . $archive . $vars['request'] . '=' . $_REQUEST[$vars['request']] . '&page='; $out[] = nvweb_list_paginator($vars['paginator'], $_GET['page'], $total, $vars['items'], $vars, $search_url); } } return implode("\n", $out); }
function nvweb_list($vars = array()) { global $website; global $DB; global $current; global $cache; global $structure; global $webgets; global $theme; global $webuser; $out = array(); $webget = 'list'; $categories = array(); $exclude = ''; if ($current['type'] == 'item') { $categories = array($current['object']->category); } else { $categories = array($current['object']->id); } if (isset($vars['categories'])) { if ($vars['categories'] == 'all') { $categories = array(0); $vars['children'] = 'true'; } else { if ($vars['categories'] == 'parent') { $parent = $DB->query_single('parent', 'nv_structure', 'id = ' . intval($categories[0])); $categories = array($parent); } else { if ($vars['categories'] == 'nvlist_parent') { if ($vars['nvlist_parent_type'] === 'structure') { $categories = array($vars['nvlist_parent_item']->id); } } else { if (!is_numeric($vars['categories'])) { // if "categories" attribute has a comma, then we suppose it is a list of comma separated values // if not, then maybe we want to get the categories from a specific property of the current page if (strpos($vars['categories'], ',') === false) { $categories = nvweb_properties(array('property' => $vars['categories'])); } if (empty($categories) && @$vars['nvlist_parent_vars']['source'] == 'block_group') { $categories = nvweb_properties(array('mode' => 'block_group_block', 'property' => $vars['categories'], 'id' => $vars['nvlist_parent_item']->id, 'uid' => $vars['nvlist_parent_item']->uid)); } if (!is_array($categories)) { $categories = explode(',', $categories); $categories = array_filter($categories); // remove empty elements } } else { $categories = explode(',', $vars['categories']); $categories = array_filter($categories); // remove empty elements } } } } } if ($vars['children'] == 'true') { $categories = nvweb_menu_get_children($categories); } // if we have categories="x" children="true" [to get the children of a category, but not itself] if ($vars['children'] == 'only') { $children = nvweb_menu_get_children($categories); for ($c = 0; $c < count($categories); $c++) { array_shift($children); } $categories = $children; } if (!empty($vars['children']) && intval($vars['children']) > 0) { $children = nvweb_menu_get_children($categories, intval($vars['children'])); for ($c = 0; $c < count($categories); $c++) { array_shift($children); } $categories = $children; } if (empty($vars['items']) || $vars['items'] == '0') { $vars['items'] = 5000; //2147483647; // maximum integer // NOTE: having >5000 items on a page without a paginator is probably a bad idea... disagree? Contact Navigate CMS team! } else { if (!is_numeric($vars['items'])) { $max_items = ""; // the number of items is defined by a property $max_items = nvweb_properties(array('property' => $vars['items'])); if (empty($max_items) && @$vars['nvlist_parent_vars']['source'] == 'block_group') { $max_items = nvweb_properties(array('mode' => 'block_group_block', 'property' => $vars['items'], 'id' => $vars['nvlist_parent_item']->id, 'uid' => $vars['nvlist_parent_item']->uid)); } if (!empty($max_items)) { $vars['items'] = $max_items; } else { $vars['items'] = 500; } // default maximum } } if (!empty($vars['exclude'])) { $exclude = str_replace('current', $current['object']->id, $vars['exclude']); $exclude = explode(',', $exclude); $exclude = array_filter($exclude); if (!empty($exclude)) { if ($vars['source'] == 'structure' || $vars['source'] == 'category') { $exclude = 'AND s.id NOT IN(' . implode(',', $exclude) . ')'; } else { // item $exclude = 'AND i.id NOT IN(' . implode(',', $exclude) . ')'; } } else { $exclude = ''; } } // retrieve entries // calculate the offset of the first element to retrieve // Warning: the paginator applies on all paginated lists on a page (so right now there can only be one in a page) if (empty($_GET['page'])) { $_GET['page'] = 1; } $offset = intval($_GET['page'] - 1) * $vars['items']; // this list does not use paginator, so offset must be always zero if (!isset($vars['paginator']) || $vars['paginator'] == 'false') { $offset = 0; } $permission = !empty($_SESSION['APP_USER#' . APP_UNIQUE]) ? 1 : 0; // public access / webuser based / webuser groups based $access = 2; $access_extra = ''; if (!empty($current['webuser'])) { $access = 1; if (!empty($webuser->groups)) { $access_groups = array(); foreach ($webuser->groups as $wg) { if (empty($wg)) { continue; } $access_groups[] = 's.groups LIKE "%g' . $wg . '%"'; } if (!empty($access_groups)) { $access_extra = ' OR (s.access = 3 AND (' . implode(' OR ', $access_groups) . '))'; } } } // get order type: PARAMETER > NV TAG PROPERTY > DEFAULT (priority given in CMS) $order = @$_REQUEST['order']; if (empty($order)) { $order = @$vars['order']; } if (empty($order)) { // default order: latest $order = 'latest'; } $orderby = nvweb_list_get_orderby($order); $rs = NULL; // TODO: try to optimize nvlist generation to use less memory and increase the maximum number of items if (($vars['source'] == 'structure' || $vars['source'] == 'category') && !empty($categories)) { $orderby = str_replace('i.', 's.', $orderby); $visible = ''; if ($vars['filter'] == 'menu') { $visible = ' AND s.visible = 1 '; } $templates = ""; if (!empty($vars['templates'])) { $templates = explode(",", $vars['templates']); $templates = array_filter($templates); $templates = ' AND s.template IN ("' . implode('","', $templates) . '")'; } $DB->query(' SELECT SQL_CALC_FOUND_ROWS s.id, s.permission, s.date_published, s.date_unpublish, s.date_published as pdate, d.text as title, s.position as position FROM nv_structure s, nv_webdictionary d WHERE s.id IN(' . implode(",", $categories) . ') AND s.website = ' . $website->id . ' AND s.permission <= ' . $permission . ' AND (s.date_published = 0 OR s.date_published < ' . core_time() . ') AND (s.date_unpublish = 0 OR s.date_unpublish > ' . core_time() . ') AND (s.access = 0 OR s.access = ' . $access . $access_extra . ') AND d.website = s.website AND d.node_type = "structure" AND d.subtype = "title" AND d.node_id = s.id AND d.lang = ' . protect($current['lang']) . ' ' . $templates . ' ' . $visible . ' ' . $exclude . ' ' . $orderby . ' LIMIT ' . $vars['items'] . ' OFFSET ' . $offset); $rs = $DB->result(); $total = $DB->foundRows(); } else { if ($vars['source'] == 'block') { list($rs, $total) = nvweb_blocks(array('type' => $vars['type'], 'number' => $vars['items'], 'mode' => $order == 'random' ? 'random' : 'ordered', 'zone' => 'object')); } else { if ($vars['source'] == 'block_link') { // only useful if this nvlist is inside another nv list of source="block" $block_links = $vars['nvlist_parent_item']->trigger['trigger-links'][$current['lang']]; $rs = array(); if (!is_array($block_links)) { $block_links = array(); } foreach ($block_links as $b_key => $b_data) { if (!is_array($b_data)) { $b_data = array(); } $b_i = 0; foreach ($b_data as $b_ref => $b_value) { if (!isset($rs[$b_i])) { $rs[$b_i] = new stdClass(); } if (!isset($rs[$b_i]->id)) { $rs[$b_i]->id = $b_ref; } $rs[$b_i]->{$b_key} = $b_value; $b_i++; } } $total = count($rs); } else { if ($vars['source'] == 'block_group') { $bg = new block_group(); if (!empty($vars['type'])) { $bg->load_by_code($vars['type']); } if (!empty($bg) && !empty($bg->blocks)) { $rs = array(); foreach ($bg->blocks as $bgb) { unset($bgbo); switch ($bgb['type']) { case 'block': $bgbo = new block(); $bgbo->load($bgb['id']); if (empty($bgbo) || empty($bgbo->type)) { continue; } // check if we can display this block if (nvweb_object_enabled($bgbo)) { // check categories / exclusions if (!empty($bgbo->categories)) { $bgbo_cat_found = false; foreach ($categories as $list_cat) { if (in_array($list_cat, $bgbo->categories)) { $bgbo_cat_found = true; } } if (!$bgbo_cat_found) { // block categories don't match the current list categories, skip this block continue; } } if (!empty($bgbo->exclusions)) { foreach ($categories as $list_cat) { if (in_array($list_cat, $bgbo->exclusions)) { continue; } // skip this block } } $rs[] = $bgbo; } break; case 'block_group_block': $bgba = $theme->block_group_blocks($vars['type']); if (!empty($bgba[$bgb['id']])) { $bgbo = $bgba[$bgb['id']]; $bgbo->uid = $bgb['uid']; $rs[] = clone $bgbo; } break; case 'block_type': // a collection of blocks of the same type list($bgbos, $foo) = nvweb_blocks(array('type' => $bgb['id'], 'mode' => $order == 'random' ? 'random' : 'ordered', 'zone' => 'object')); // add the block type definition, with its title if (count($bgbos) > 0 && isset($bgb['title']) && !empty($bgb['title'])) { $bgb['_object_type'] = 'block_group_block_type'; $rs[] = (object) $bgb; } for ($i = 0; $i < count($bgbos); $i++) { $rs[] = $bgbos[$i]; } break; case 'extension': $rs[] = (object) $bgb; break; } } $total = count($rs); } } else { if ($vars['source'] == 'gallery') { if (!isset($vars['nvlist_parent_type'])) { // get gallery of the current item if ($current['type'] == 'item') { $galleries = $current['object']->galleries; if (!is_array($galleries)) { $galleries = mb_unserialize($galleries); } $rs = $galleries[0]; $total = count($rs); } else { if ($current['type'] == 'structure') { // we need the first item assigned to the structure $access_extra_items = str_replace('s.', 'i.', $access_extra); $templates = ""; if (!empty($vars['templates'])) { $templates = explode(",", $vars['templates']); $templates = array_filter($templates); $templates = ' AND i.template IN ("' . implode('","', $templates) . '")'; } // default source for retrieving items (embedded or not) $DB->query(' SELECT SQL_CALC_FOUND_ROWS i.id FROM nv_items i, nv_structure s, nv_webdictionary d WHERE i.category IN(' . implode(",", $categories) . ') AND i.website = ' . $website->id . ' AND i.permission <= ' . $permission . ' AND (i.date_published = 0 OR i.date_published < ' . core_time() . ') AND (i.date_unpublish = 0 OR i.date_unpublish > ' . core_time() . ') AND s.id = i.category AND (s.date_published = 0 OR s.date_published < ' . core_time() . ') AND (s.date_unpublish = 0 OR s.date_unpublish > ' . core_time() . ') AND s.permission <= ' . $permission . ' AND (s.access = 0 OR s.access = ' . $access . $access_extra . ') AND (i.access = 0 OR i.access = ' . $access . $access_extra_items . ') AND d.website = i.website AND d.node_type = "item" AND d.subtype = "title" AND d.node_id = i.id AND d.lang = ' . protect($current['lang']) . ' ' . $templates . ' ' . $exclude . ' ORDER BY i.position ASC LIMIT 1 '); $rs = $DB->result(); $tmp = new item(); $tmp->load($rs[0]->id); $rs = $tmp->galleries[0]; $total = count($rs); } } } else { if ($vars['nvlist_parent_type'] == 'item') { $pitem = $vars['nvlist_parent_item']; $rs = $pitem->galleries[0]; $total = count($rs); } } if ($total > 0) { $order = 'priority'; // display images using the assigned priority if (!empty($vars['order'])) { $order = $vars['order']; } $rs = nvweb_gallery_reorder($rs, $order); // prepare format to be parsed by nv list iterator $rs = array_map(function ($k, $v) { $v['file'] = $k; return $v; }, array_keys($rs), array_values($rs)); } } else { if ($vars['source'] == 'rss') { // url may be a property $rss_url = $vars['url']; if (strpos($vars['url'], "http") !== 0) { $rss_url = nvweb_properties(array('property' => $vars['url'])); } list($rs, $total) = nvweb_list_get_from_rss($rss_url, @$vars['cache'], $offset, $vars['items'], $permission, $order); } else { if ($vars['source'] == 'twitter') { list($rs, $total) = nvweb_list_get_from_twitter($vars['username'], @$vars['cache'], $offset, $vars['items'], $permission, $order); } else { if (!empty($vars['source'])) { // CUSTOM data source if ($vars['source'] == 'comment') { $vars['source'] = 'comments'; } $fname = 'nvweb_' . $vars['source'] . '_list'; if ($vars['source'] == 'website_comments') { $vars['source'] = 'comments'; } nvweb_webget_load($vars['source']); if (function_exists($fname)) { list($rs, $total) = $fname($offset, $vars['items'], $permission, $order, $vars); } } } } } } } } } $categories = array_filter($categories); // DATA SOURCE not given or ERROR ===> items if ((empty($vars['source']) || !is_numeric($total)) && !empty($categories)) { /* * TO DO: design decision ... lists should show items from published categories which has unpublished parent? * * Navigate CMS 1.6.7: NO * // we have to check all website UNPUBLISHED categories to keep the list query efficient // there are some cases: // a) Permission is beyond user's level [0=>public, 1=>private, 2=>hidden] // b) Date published is set and the value is before the current time (not yet published) // c) Date unpublish is set and the value is before the current time (no more published) // d) User account level not allowed [0=>everyone, 1=>signed in users, 2=>users NOT signed in] $DB->query(' SELECT id FROM nv_structure WHERE website = '.protect($website->id).' AND ( permission > '.$permission.' OR (date_published > 0 AND '.$website->current_time().' > date_published) OR (date_unpublish > 0 AND '.$website->current_time().' > date_unpublish) OR (access <> 0 AND access <> '.$access.') ) '); $hidden_categories = $DB->result('id'); // now we would have to mark the children categories also as unpublished */ $filters = ''; if (!empty($vars['filter'])) { $filters = nvweb_list_parse_filters($vars['filter'], 'items'); } // reuse structure.access permission $access_extra_items = str_replace('s.', 'i.', $access_extra); $embedded = $vars['embedded'] == 'true' ? '1' : '0'; $templates = ""; if (!empty($vars['templates'])) { $templates = explode(",", $vars['templates']); $templates = array_filter($templates); if ($embedded == '1') { $templates = ' AND s.template IN ("' . implode('","', $templates) . '")'; } else { $templates = ' AND i.template IN ("' . implode('","', $templates) . '")'; } } $columns_extra = ''; if ($vars['order'] == 'comments') { // we need to retrieve the number of comments to apply the order by clause $columns_extra = ', (SELECT COUNT(c.id) FROM nv_comments c WHERE i.id = c.item AND c.website = i.website AND c.status = 0) AS comments_published'; } // default source for retrieving items $query = ' SELECT SQL_CALC_FOUND_ROWS i.id, i.permission, i.date_published, i.date_unpublish, i.date_to_display, COALESCE(NULLIF(i.date_to_display, 0), i.date_created) as pdate, d.text as title, i.position as position, s.position ' . $columns_extra . ' FROM nv_items i, nv_structure s, nv_webdictionary d WHERE i.category IN(' . implode(",", $categories) . ') AND i.website = ' . $website->id . ' AND i.permission <= ' . $permission . ' AND i.embedding = ' . $embedded . ' AND (i.date_published = 0 OR i.date_published < ' . core_time() . ') AND (i.date_unpublish = 0 OR i.date_unpublish > ' . core_time() . ') AND s.id = i.category AND (s.date_published = 0 OR s.date_published < ' . core_time() . ') AND (s.date_unpublish = 0 OR s.date_unpublish > ' . core_time() . ') AND s.permission <= ' . $permission . ' AND (s.access = 0 OR s.access = ' . $access . $access_extra . ') AND (i.access = 0 OR i.access = ' . $access . $access_extra_items . ') AND d.website = i.website AND d.node_type = "item" AND d.subtype = "title" AND d.node_id = i.id AND d.lang = ' . protect($current['lang']) . ' ' . $filters . ' ' . $templates . ' ' . $exclude . ' ' . $orderby . ' LIMIT ' . $vars['items'] . ' OFFSET ' . $offset; $DB->query($query); $rs = $DB->result(); $total = $DB->foundRows(); } // now we have all elements that will be shown in the list // let's apply the nvlist template to each one for ($i = 0; $i < count($rs); $i++) { // ignore empty objects if ($vars['source'] != 'gallery' && empty($rs[$i]->id) || $vars['source'] == 'gallery' && empty($rs[$i]['file'])) { continue; } // prepare a standard $item with the current element if ($vars['source'] == 'comments' || $vars['source'] == 'comment') { $item = $rs[$i]; } else { if ($vars['source'] == 'structure' || $vars['source'] == 'category') { $item = new structure(); $item->load($rs[$i]->id); $item->date_to_display = $rs[$i]->pdate; } else { if ($vars['source'] == 'rss' || $vars['source'] == 'twitter' || $vars['source'] == 'block_link') { // item is virtually created $item = $rs[$i]; } else { if ($vars['source'] == 'block' || $vars['source'] == 'block_group') { if (get_class($rs[$i]) == 'block') { // standard block $item = $rs[$i]; } else { if (isset($rs[$i]->_object_type) && $rs[$i]->_object_type == "block_group_block_type") { // block type definition (mainly used to add a title before a list of blocks of the same type) $item = $rs[$i]; } else { if (isset($rs[$i]->extension)) { // extension block $item = block::extension_block($rs[$i]->extension, $rs[$i]->id); $item->type = "extension"; $item->extension = $rs[$i]->extension; $item->uid = $rs[$i]->uid; } else { // block from block group $item = new block(); $item->load_from_block_group($vars['type'], $rs[$i]->id, $rs[$i]->uid); } } } } else { if ($vars['source'] == 'gallery') { $item = $rs[$i]; } else { $item = new item(); $item->load($rs[$i]->id); // if the item comes from a custom source, save the original query result // this allows getting a special field without extra work ;) $item->_query = $rs[$i]; } } } } } // get the nv list template $item_html = $vars['template']; // first we need to isolate the nested nv lists/searches unset($nested_lists_fragments); list($item_html, $nested_lists_fragments) = nvweb_list_isolate_lists($item_html); // now, parse the nvlist_conditional tags (with html source code inside (and other nvlist tags)) unset($nested_condition_fragments); list($item_html, $nested_conditional_fragments) = nvweb_list_isolate_conditionals($item_html); $conditional_placeholder_tags = nvweb_tags_extract($item_html, 'nvlist_conditional_placeholder', true, true, 'UTF-8'); // selfclosing = true while (!empty($conditional_placeholder_tags)) { $tag = $conditional_placeholder_tags[0]; $conditional = $nested_conditional_fragments[$tag["attributes"]["id"]]; $conditional_html_output = nvweb_list_parse_conditional($conditional, $item, $conditional['nvlist_conditional_template'], $i, count($rs)); $item_html = str_replace($tag["full_tag"], $conditional_html_output, $item_html); $conditional_placeholder_tags = nvweb_tags_extract($item_html, 'nvlist_conditional_placeholder', true, true, 'UTF-8'); // selfclosing = true } // now, parse the (remaining) common nvlist tags (selfclosing tags) $template_tags_processed = 0; $template_tags = nvweb_tags_extract($item_html, 'nvlist', true, true, 'UTF-8'); // selfclosing = true while (!empty($template_tags)) { $tag = $template_tags[0]; // protect the "while" loop, maximum 500 nvlist tags parsed! $template_tags_processed++; if ($template_tags_processed > 500) { break; } $content = nvweb_list_parse_tag($tag, $item, $vars['source'], $i, $i + $offset, $total); $item_html = str_replace($tag['full_tag'], $content, $item_html); // html template has changed, the nvlist tags may have changed its positions $template_tags = nvweb_tags_extract($item_html, 'nvlist', true, true, 'UTF-8'); } // restore & process nested lists (if any) foreach ($nested_lists_fragments as $nested_list_uid => $nested_list_vars) { $nested_list_vars['nvlist_parent_vars'] = $vars; $nested_list_vars['nvlist_parent_type'] = $vars['source']; $nested_list_vars['nvlist_parent_item'] = $item; $content = nvweb_list($nested_list_vars); $item_html = str_replace('<!--#' . $nested_list_uid . '#-->', $content, $item_html); } $out[] = $item_html; } if (count($rs) == 0) { // special case, no results found // get the nv list template and parse only the conditional: <nvlist_conditional by="count" value="empty"> (or value=0) $item_html = $vars['template']; // now, parse the nvlist_conditional tags (with html source code inside (and other nvlist tags)) unset($nested_condition_fragments); list($item_html, $nested_conditional_fragments) = nvweb_list_isolate_conditionals($item_html); // remove all tags except (selfclosing) nvlist_conditional_placeholder $item_html = strip_tags($item_html, '<nvlist_conditional_placeholder>'); $conditional_placeholder_tags = nvweb_tags_extract($item_html, 'nvlist_conditional_placeholder', true, true, 'UTF-8'); // selfclosing=true while (!empty($conditional_placeholder_tags)) { $tag = $conditional_placeholder_tags[0]; $conditional = $nested_conditional_fragments[$tag["attributes"]["id"]]; $conditional_html_output = nvweb_list_parse_conditional($conditional, NULL, $conditional['nvlist_conditional_template'], $i, count($rs)); $item_html = str_replace($tag["full_tag"], $conditional_html_output, $item_html); $conditional_placeholder_tags = nvweb_tags_extract($item_html, 'nvlist_conditional_placeholder', true, true, 'UTF-8'); // selfclosing = true } $out[] = $item_html; } if (isset($vars['paginator']) && $vars['paginator'] != 'false') { $out[] = nvweb_list_paginator($vars['paginator'], $_GET['page'], $total, $vars['items'], $vars); } return implode("\n", $out); }