/**
  * list sections as topics in a forum
  *
  * @param resource the SQL result
  * @return string the rendered text
  **/
 function layout($result)
 {
     global $context;
     // empty list
     if (!SQL::count($result)) {
         $output = array();
         return $output;
     }
     // output as a string
     $text = '';
     // build a list of sections
     $family = '';
     $first = TRUE;
     while ($item = SQL::fetch($result)) {
         // change the family
         if ($item['family'] != $family) {
             $family = $item['family'];
             // close last table only if a section has been already listed
             if (!$first) {
                 $text .= Skin::table_suffix();
             }
             // show the family
             $text .= '<h2><span>' . $family . '&nbsp;</span></h2>' . "\n" . Skin::table_prefix('yabb') . Skin::table_row(array(i18n::s('Board'), 'center=' . i18n::s('Topics'), i18n::s('Last post')), 'header');
         } elseif ($first) {
             $text .= Skin::table_prefix('yabb');
             $text .= Skin::table_row(array(i18n::s('Board'), 'center=' . i18n::s('Topics'), i18n::s('Last post')), 'header');
         }
         // done with this case
         $first = FALSE;
         // reset everything
         $prefix = $label = $suffix = $icon = '';
         // signal restricted and private sections
         if ($item['active'] == 'N') {
             $prefix .= PRIVATE_FLAG;
         } elseif ($item['active'] == 'R') {
             $prefix .= RESTRICTED_FLAG;
         }
         // indicate the id in the hovering popup
         $hover = i18n::s('View the section');
         if (Surfer::is_member()) {
             $hover .= ' [section=' . $item['id'] . ']';
         }
         // the url to view this item
         $url = Sections::get_permalink($item);
         // use the title as a link to the page
         $title =& Skin::build_link($url, Codes::beautify_title($item['title']), 'basic', $hover);
         // also use a clickable thumbnail, if any
         if ($item['thumbnail_url']) {
             $prefix = Skin::build_link($url, '<img src="' . $item['thumbnail_url'] . '" alt="" title="' . encode_field($hover) . '" class="left_image" />', 'basic', $hover) . $prefix;
         }
         // flag sections updated recently
         if ($item['expiry_date'] > NULL_DATE && $item['expiry_date'] <= $context['now']) {
             $suffix = EXPIRED_FLAG . ' ';
         } elseif ($item['create_date'] >= $context['fresh']) {
             $suffix = NEW_FLAG . ' ';
         } elseif ($item['edit_date'] >= $context['fresh']) {
             $suffix = UPDATED_FLAG . ' ';
         }
         // board introduction
         if ($item['introduction']) {
             $suffix .= '<br style="clear: none;" />' . Codes::beautify_introduction($item['introduction']);
         }
         // more details
         $details = '';
         $more = array();
         // board moderators
         if ($moderators = Sections::list_editors_by_name($item, 0, 7, 'comma5')) {
             $more[] = sprintf(i18n::ns('Moderator: %s', 'Moderators: %s', count($moderators)), $moderators);
         }
         // children boards
         if ($children =& Sections::list_by_title_for_anchor('section:' . $item['id'], 0, COMPACT_LIST_SIZE, 'comma')) {
             $more[] = sprintf(i18n::ns('Child board: %s', 'Child boards: %s', count($children)), Skin::build_list($children, 'comma'));
         }
         // as a compact list
         if (count($more)) {
             $details .= '<ul class="compact">';
             foreach ($more as $list_item) {
                 $details .= '<li>' . $list_item . '</li>' . "\n";
             }
             $details .= '</ul>' . "\n";
         }
         // all details
         if ($details) {
             $details = BR . '<span class="details">' . $details . "</span>\n";
         }
         // count posts here, and in children sections
         $anchors = Sections::get_branch_at_anchor('section:' . $item['id']);
         if (!($count = Articles::count_for_anchor($anchors))) {
             $count = 0;
         }
         // get last post
         $last_post = '--';
         $article =& Articles::get_newest_for_anchor($anchors, TRUE);
         if ($article['id']) {
             // flag articles updated recently
             if ($article['expiry_date'] > NULL_DATE && $article['expiry_date'] <= $context['now']) {
                 $flag = EXPIRED_FLAG . ' ';
             } elseif ($article['create_date'] >= $context['fresh']) {
                 $flag = NEW_FLAG . ' ';
             } elseif ($article['edit_date'] >= $context['fresh']) {
                 $flag = UPDATED_FLAG . ' ';
             } else {
                 $flag = '';
             }
             // title
             $last_post = Skin::build_link(Articles::get_permalink($article), Codes::beautify_title($article['title']), 'article');
             // last editor
             if ($article['edit_date']) {
                 // find a name, if any
                 if ($article['edit_name']) {
                     // label the action
                     if (isset($article['edit_action'])) {
                         $action = Anchors::get_action_label($article['edit_action']);
                     } else {
                         $action = i18n::s('edited');
                     }
                     // name of last editor
                     $user = sprintf(i18n::s('%s by %s'), $action, Users::get_link($article['edit_name'], $article['edit_address'], $article['edit_id']));
                 }
                 $last_post .= $flag . BR . '<span class="tiny">' . $user . ' ' . Skin::build_date($article['edit_date']) . '</span>';
             }
         }
         // this is another row of the output
         $text .= Skin::table_row(array($prefix . $title . $suffix . $details, 'center=' . $count, $last_post));
     }
     // end of processing
     SQL::free($result);
     $text .= Skin::table_suffix();
     return $text;
 }
Exemple #2
0
 /**
  * render a compact list of voted pages
  *
  * @param string the anchor (e.g. 'section:123')
  * @param string layout to use
  * @return string the rendered text
  **/
 public static function render_voted($anchor = '', $layout = 'simple')
 {
     global $context;
     // we return some text;
     $text = '';
     // number of items to display
     $count = COMPACT_LIST_SIZE;
     if (($position = strpos($anchor, ',')) !== FALSE) {
         $count = (int) trim(substr($anchor, $position + 1));
         if (!$count) {
             $count = COMPACT_LIST_SIZE;
         }
         $anchor = trim(substr($anchor, 0, $position));
     }
     // scope is limited to current surfer
     if ($anchor == 'self' && Surfer::get_id()) {
         $anchor = 'user:'******'section:') === 0) {
         // look at this branch of the content tree
         $anchors = Sections::get_branch_at_anchor($anchor);
         // query the database and layout that stuff
         $text =& Articles::list_for_anchor_by('rating', $anchors, 0, $count, $layout);
         // scope is limited to pages of one surfer
     } elseif (strpos($anchor, 'user:'******'rating', substr($anchor, 5), 0, $count, $layout);
     } else {
         $text =& Articles::list_by('rating', 0, $count, $layout);
     }
     // we have an array to format
     if (is_array($text)) {
         $text =& Skin::build_list($text, $layout);
     }
     // job done
     return $text;
 }
Exemple #3
0
 /**
  * search for some keywords in sub-sections
  *
  * This function also searches in sub-sections, with up to three levels of depth.
  *
  * @see search.php
  *
  * Modification dates are taken into account to prefer freshest information.
  *
  * @link http://www.artfulcode.net/articles/full-text-searching-mysql/
  *
  * @param int the id of the section to look in
  * @param string the search string
  * @param float maximum score to look at
  * @param int the number of items to display
  * @param mixed the layout, if any
  * @return NULL on error, else an ordered array of array($score, $summary)
  */
 public static function &search_in_section($section_id, $pattern, $offset = 1.0, $count = 10, $layout = 'search')
 {
     global $context;
     // sanity check
     if (!($pattern = trim($pattern))) {
         $output = NULL;
         return $output;
     }
     // limit the scope of the request
     $where = Sections::get_sql_where();
     // search is restricted to one section
     $sections_where = '';
     if ($section_id) {
         // look within this branch of the content tree
         $anchors = Sections::get_branch_at_anchor('section:' . $section_id);
         // the full set of sections searched
         $where .= " AND (sections.id IN (" . str_replace('section:', '', join(", ", $anchors)) . "))";
     }
     // only consider live sections
     $where .= " AND ((sections.expiry_date is NULL) " . "OR (sections.expiry_date <= '" . NULL_DATE . "') OR (sections.expiry_date > '" . $context['now'] . "'))";
     // how to compute the score for sections
     $score = "(MATCH(title, introduction, description)" . " AGAINST('" . SQL::escape($pattern) . "' IN BOOLEAN MODE)" . "/SQRT(GREATEST(1.1, DATEDIFF(NOW(), edit_date))))";
     // the list of articles
     $query = "SELECT sections.*," . " " . $score . " AS score" . " FROM " . SQL::table_name('sections') . " AS sections" . " WHERE (" . $score . " < " . $offset . ") AND (" . $score . " > 0)" . " AND (" . $where . ")" . " ORDER BY score DESC" . " LIMIT " . $count;
     $output =& Sections::list_selected(SQL::query($query), $layout);
     return $output;
 }
Exemple #4
0
     $layout = new Layout_articles();
 } else {
     $layout = Layouts::new_($item['articles_layout'], 'article');
 }
 // avoid links to this page
 if (is_object($layout)) {
     $layout->set_focus('section:' . $item['id']);
 }
 // the maximum number of articles per page
 if (is_object($layout)) {
     $items_per_page = $layout->items_per_page();
 } else {
     $items_per_page = ARTICLES_PER_PAGE;
 }
 // sub-sections targeting the main area
 if ($anchors = Sections::get_branch_at_anchor('section:' . $item['id'])) {
     // use ordering options set for the section
     if (preg_match('/\\barticles_by_([a-z_]+)\\b/i', $item['options'], $matches)) {
         $order = $matches[1];
     } else {
         $order = 'edition';
     }
     $items =& Articles::list_for_anchor_by($order, $anchors, 0, $items_per_page, $layout);
     // actually render the html for the section
     $content = '';
     if (is_array($items) && is_string($item['articles_layout']) && $item['articles_layout'] == 'compact') {
         $content .= Skin::build_list($items, 'compact');
     } elseif (is_array($items)) {
         $content .= Skin::build_list($items, 'decorated');
     } elseif (is_string($items)) {
         $content .= $items;
Exemple #5
0
 /**
  * search for some keywords articles anchored to one precise section 
  * (and its subsections) or array of sections.
  *
  * This function also searches in sub-sections, with up to three levels of depth.
  *
  * @see search.php
  *
  * Modification dates are taken into account to prefer freshest information.
  *
  * @link http://www.artfulcode.net/articles/full-text-searching-mysql/
  *
  * @param mixed the id of the section or array of sections to look in 
  * @param string the search string
  * @param float maximum score to look at
  * @param int the number of items to display
  * @param mixed the layout, if any
  * @return NULL on error, else an ordered array of array($score, $summary)
  */
 public static function &search_in_section($section_id, $pattern, $offset = 1.0, $count = 10, $layout = 'search')
 {
     global $context;
     // sanity check
     if (!($pattern = trim($pattern))) {
         $output = NULL;
         return $output;
     }
     // restrict the query to addressable content
     $where = Articles::get_sql_where();
     // search is restricted to one section
     if (is_numeric($section_id)) {
         // look for children
         $anchors = Sections::get_branch_at_anchor('section:' . $section_id);
         // the full set of sections searched
         $where .= " AND (anchor IN ('" . join("', '", $anchors) . "'))";
     } elseif (is_array($section_id)) {
         $where .= " AND (anchor IN ('" . join("', '", $section_id) . "'))";
     }
     // anonymous surfers and subscribers will see only published articles
     if (!Surfer::is_member()) {
         $where .= " AND NOT ((publish_date is NULL) OR (publish_date <= '0000-00-00'))" . " AND (publish_date < '" . $context['now'] . "')";
     }
     // only consider live articles
     $where .= " AND ((expiry_date is NULL) " . "OR (expiry_date <= '" . NULL_DATE . "') OR (expiry_date > '" . $context['now'] . "'))";
     // how to compute the score for articles
     $score = "(MATCH(title, source, introduction, overlay, description)" . " AGAINST('" . SQL::escape($pattern) . "' IN BOOLEAN MODE)" . "/SQRT(GREATEST(1.1, DATEDIFF(NOW(), edit_date))))";
     // the list of articles
     $query = "SELECT *, " . $score . " AS score FROM " . SQL::table_name('articles') . " AS articles" . " WHERE (" . $where . ") AND (" . $score . " < " . $offset . ") AND (" . $score . " > 0)" . " ORDER BY score DESC" . " LIMIT " . $count;
     $output =& Articles::list_selected(SQL::query($query), $layout);
     return $output;
 }
 /**
  * list articles as slashdot do
  *
  * @param resource the SQL result
  * @return string the rendered text
  *
  * @see layouts/layout.php
  **/
 function layout($result)
 {
     global $context;
     // we return some text
     $text = '';
     // empty list
     if (!SQL::count($result)) {
         return $text;
     }
     // layout in a table
     $text = Skin::table_prefix('wide');
     // 'even' is used for title rows, 'odd' for detail rows
     $class_title = 'odd';
     $class_detail = 'even';
     // build a list of sections
     $family = '';
     include_once $context['path_to_root'] . 'articles/article.php';
     include_once $context['path_to_root'] . 'comments/comments.php';
     include_once $context['path_to_root'] . 'links/links.php';
     while ($item = SQL::fetch($result)) {
         // change the family
         if ($item['family'] != $family) {
             $family = $item['family'];
             // show the family
             $text .= Skin::table_suffix() . '<h2><span>' . $family . '&nbsp;</span></h2>' . "\n" . Skin::table_prefix('wide');
         }
         // document this section
         $content = $prefix = $title = $suffix = $icon = '';
         $menu = array();
         // permalink
         $url = Sections::get_permalink($item);
         // get the anchor
         $anchor = Anchors::get($item['anchor']);
         // get the related overlay, if any
         $overlay = Overlay::load($item, 'section:' . $item['id']);
         // use the title to label the link
         if (is_object($overlay)) {
             $title = Codes::beautify_title($overlay->get_text('title', $item));
         } else {
             $title = Codes::beautify_title($item['title']);
         }
         // signal restricted and private sections
         if ($item['active'] == 'N') {
             $prefix .= PRIVATE_FLAG;
         } elseif ($item['active'] == 'R') {
             $prefix .= RESTRICTED_FLAG;
         }
         // this is another row of the output
         $text .= '<tr class="' . $class_title . '"><th>' . $prefix . Skin::build_link($url, $title, 'basic', i18n::s('View the section')) . $suffix . '</th></tr>' . "\n";
         // document most recent page here
         $content = $prefix = $title = $suffix = $icon = '';
         $menu = array();
         // branches of this tree
         $anchors = Sections::get_branch_at_anchor('section:' . $item['id']);
         // get last post
         $article =& Articles::get_newest_for_anchor($anchors, TRUE);
         if ($article['id']) {
             // permalink
             $url = Articles::get_permalink($article);
             // get the anchor
             $anchor = Anchors::get($article['anchor']);
             // get the related overlay, if any
             $overlay = Overlay::load($item, 'section:' . $item['id']);
             // use the title to label the link
             if (is_object($overlay)) {
                 $title = Codes::beautify_title($overlay->get_text('title', $article));
             } else {
                 $title = Codes::beautify_title($article['title']);
             }
             // signal restricted and private articles
             if ($article['active'] == 'N') {
                 $prefix .= PRIVATE_FLAG;
             } elseif ($article['active'] == 'R') {
                 $prefix .= RESTRICTED_FLAG;
             }
             // the icon to put aside
             if ($article['thumbnail_url']) {
                 $icon = $article['thumbnail_url'];
             }
             // the icon to put aside
             if (!$icon && is_callable(array($anchor, 'get_bullet_url'))) {
                 $icon = $anchor->get_bullet_url();
             }
             if ($icon) {
                 $icon = '<a href="' . $context['url_to_root'] . $url . '"><img src="' . $icon . '" class="right_image" alt="" title="' . encode_field(i18n::s('View the page')) . '" /></a>';
             }
             // the introductory text
             if ($article['introduction']) {
                 $content .= Codes::beautify_introduction($article['introduction']);
             } elseif (!is_object($overlay)) {
                 $handle = new Article();
                 $handle->load_by_content($article);
                 $content .= $handle->get_teaser('teaser');
             }
             // insert overlay data, if any
             if (is_object($overlay)) {
                 $content .= $overlay->get_text('list', $article);
             }
             // link to description, if any
             if (trim($article['description'])) {
                 $menu[] = Skin::build_link($url, i18n::s('Read more') . MORE_IMG, 'span', i18n::s('View the page'));
             }
             // info on related files
             if ($count = Files::count_for_anchor('article:' . $article['id'])) {
                 $menu[] = sprintf(i18n::ns('%d file', '%d files', $count), $count);
             }
             // info on related comments
             if ($count = Comments::count_for_anchor('article:' . $article['id'])) {
                 $menu[] = sprintf(i18n::ns('%d comment', '%d comments', $count), $count);
             }
             // discuss
             if (Comments::allow_creation($article, $anchor)) {
                 $menu[] = Skin::build_link(Comments::get_url('article:' . $article['id'], 'comment'), i18n::s('Discuss'), 'span');
             }
             // the main anchor link
             if (is_object($anchor) && (!isset($this->focus) || $article['anchor'] != $this->focus)) {
                 $menu[] = Skin::build_link($anchor->get_url(), ucfirst($anchor->get_title()), 'span', i18n::s('View the section'));
             }
             // list up to three categories by title, if any
             if ($items =& Members::list_categories_by_title_for_member('article:' . $article['id'], 0, 3, 'raw')) {
                 foreach ($items as $id => $attributes) {
                     $menu[] = Skin::build_link(Categories::get_permalink($attributes), $attributes['title'], 'span');
                 }
             }
             // append a menu
             $content .= '<p>' . Skin::finalize_list($menu, 'menu') . '</p>';
             // this is another row of the output
             $text .= '<tr class="' . $class_detail . '"><td>' . '<h3 class="top"><span>' . Skin::build_link($url, $prefix . $title . $suffix, 'basic', i18n::s('View the page')) . '</span></h3>' . '<div class="content">' . $icon . $content . '</div>' . '</td></tr>' . "\n";
         }
     }
     // end of processing
     SQL::free($result);
     $text .= Skin::table_suffix();
     return $text;
 }
Exemple #7
0
 /**
  * render a compact list of recent modifications
  *
  * The provided anchor can reference:
  * - a section 'section:123'
  * - a category 'category:456'
  * - a user 'user:789'
  * - 'self'
  * - nothing
  *
  * @param string the anchor (e.g. 'section:123')
  * @param string layout to use
  * @return string the rendered text
  **/
 public static function render_updated($layout = 'simple', $anchor = '')
 {
     global $context;
     // we return some text;
     $text = '';
     // number of items to display
     $count = COMPACT_LIST_SIZE;
     if (($position = strpos($anchor, ',')) !== FALSE) {
         $count = (int) trim(substr($anchor, $position + 1));
         if (!$count) {
             $count = COMPACT_LIST_SIZE;
         }
         $anchor = trim(substr($anchor, 0, $position));
     }
     // scope is limited to current surfer
     if ($anchor == 'self' && Surfer::get_id()) {
         $anchor = 'user:'******'section:') === 0) {
         // look at this branch of the content tree
         $anchors = Sections::get_branch_at_anchor($anchor);
         // query the database and layout that stuff
         $text = Articles::list_for_anchor_by('edition', $anchors, 0, $count, $layout);
         // scope is limited to one category
     } elseif (strpos($anchor, 'category:') === 0) {
         // first level of depth
         $anchors = array();
         // get sections linked to this category
         if ($topics = Members::list_sections_by_title_for_anchor($anchor, 0, 50, 'raw')) {
             foreach ($topics as $id => $not_used) {
                 $anchors = array_merge($anchors, array('section:' . $id));
             }
         }
         // second level of depth
         if (count($topics) && count($anchors) < 2000) {
             $topics = Sections::get_children_of_anchor($anchors);
             $anchors = array_merge($anchors, $topics);
         }
         // third level of depth
         if (count($topics) && count($anchors) < 2000) {
             $topics = Sections::get_children_of_anchor($anchors);
             $anchors = array_merge($anchors, $topics);
         }
         // fourth level of depth
         if (count($topics) && count($anchors) < 2000) {
             $topics = Sections::get_children_of_anchor($anchors);
             $anchors = array_merge($anchors, $topics);
         }
         // fifth level of depth
         if (count($topics) && count($anchors) < 2000) {
             $topics = Sections::get_children_of_anchor($anchors);
             $anchors = array_merge($anchors, $topics);
         }
         // the category itself is an anchor
         $anchors[] = $anchor;
         // ensure anchors are referenced only once
         $anchors = array_unique($anchors);
         // query the database and layout that stuff
         $text = Members::list_articles_by_date_for_anchor($anchors, 0, $count, $layout);
         // scope is limited to pages of one surfer
     } elseif (strpos($anchor, 'user:'******'edition', substr($anchor, 5), 0, $count, $layout);
     } else {
         $text = Articles::list_by('edition', 0, $count, $layout);
     }
     // we have an array to format
     if (is_array($text)) {
         $text = Skin::build_list($text, $layout);
     }
     // job done
     return $text;
 }