b2evolution

Multilingual multiuser multiblog engine

b2evolution Technical Documentation (Version 2.4) [ class tree: evocore ] [ index: evocore ] [ all elements ]

Source for file _itemlistlight.class.php

Documentation is available at _itemlistlight.class.php

  1. <?php
  2. /**
  3.  * This file implements the ItemListLight class.
  4.  *
  5.  * This object handles item/post/article lists WITHOUT FULL FUNCTIONNALITY
  6.  * but with a LOWER MEMORY FOOTPRINT.
  7.  *
  8.  * This file is part of the evoCore framework - {@link http://evocore.net/}
  9.  * See also {@link http://sourceforge.net/projects/evocms/}.
  10.  *
  11.  * @copyright (c)2003-2008 by Francois PLANQUE - {@link http://fplanque.net/}
  12.  *
  13.  *  {@internal License choice
  14.  *  - If you have received this file as part of a package, please find the license.txt file in
  15.  *    the same folder or the closest folder above for complete license terms.
  16.  *  - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
  17.  *    then you must choose one of the following licenses before using the file:
  18.  *    - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
  19.  *    - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
  20.  *  }}}
  21.  *
  22.  *  {@internal Open Source relicensing agreement:
  23.  *  }}}
  24.  *
  25.  * @package evocore
  26.  *
  27.  *  {@internal Below is a list of authors who have contributed to design/coding of this file: }}
  28.  * @author fplanque: Francois PLANQUE.
  29.  *
  30.  * @version $Id: _itemlistlight.class.php,v 1.19.2.1 2009/03/16 11:33:12 tblue246 Exp $
  31.  */
  32. if!defined('EVO_MAIN_INIT') ) die'Please, do not access this page directly.' );
  33.  
  34. load_class('_core/model/dataobjects/_dataobjectcache.class.php');
  35. load_class('_core/model/dataobjects/_dataobjectlist2.class.php');
  36. load_class('items/model/_item.class.php');
  37. load_funcs('items/model/_item.funcs.php');
  38.  
  39. /**
  40.  * Item List Class LIGHT
  41.  *
  42.  * Contrary to ItemList2, we only do 1 query here and we extract only a few selected params.
  43.  * Basically all we want is being able to generate permalinks.
  44.  *
  45.  * @package evocore
  46.  */
  47. {
  48.     /**
  49.      * SQL object for the Query
  50.      */
  51.     var $ItemQuery;
  52.  
  53.     /**
  54.      * Blog object this ItemList refers to
  55.      */
  56.     var $Blog;
  57.  
  58.     /**
  59.      * list unit: 'posts' or 'days'
  60.      */
  61.     var $unit;
  62.  
  63.     /**
  64.      * Did we request a single post?
  65.      */
  66.      var $single_post = false;
  67.  
  68.     /**
  69.      * Last date that has been output by date_if_changed()
  70.      */
  71.     var $last_displayed_date = '';
  72.  
  73.     /**
  74.      * Lazy filled
  75.      * @access private
  76.      */
  77.     var $advertised_start_date;
  78.     var $advertised_stop_date;
  79.     /**
  80.      * Anti infinite loops:
  81.      */
  82.     var $getting_adv_start_date = false;
  83.     var $getting_adv_stop_date = false;
  84.  
  85.     var $group_by_cat = 0;
  86.  
  87.  
  88.     /**
  89.      * Constructor
  90.      *
  91.      * @todo  add param for saved session filter set
  92.      *
  93.      * @param Blog 
  94.      * @param mixed Default filter set: Do not show posts before this timestamp, can be 'now'
  95.      * @param mixed Default filter set: Do not show posts after this timestamp, can be 'now'
  96.      * @param integer|NULLLimit
  97.      * @param string name of cache to be used (for table prefix info)
  98.      * @param string prefix to differentiate page/order params when multiple Results appear one same page
  99.      * @param array restrictions for itemlist (position, contact, firm, ...) key: restriction name, value: ID of the restriction
  100.      */
  101.     function ItemListLight(
  102.             $Blog,
  103.             $timestamp_min NULL,       // Do not show posts before this timestamp
  104.             $timestamp_max NULL,            // Do not show posts after this timestamp
  105.             $limit 20,
  106.             $cache_name 'ItemCacheLight',     // name of cache to be used (for table prefix info)
  107.             $param_prefix '',
  108.             $filterset_name '',                // Name to be used when saving the filterset (leave empty to use default for collection)
  109.             $restrict_to array()            // Restrict the item list to a position, or contact, firm..... /* not used yet(?) */
  110.         )
  111.     {
  112.         global $Settings;
  113.  
  114.         // Call parent constructor:
  115.         parent::DataObjectList2get_Cache($cache_name)$limit$param_prefixNULL );
  116.  
  117.         // The SQL Query object:
  118.         $this->ItemQuery = new ItemQuery$this->Cache->dbtablename$this->Cache->dbprefix$this->Cache->dbIDname );
  119.  
  120.         $this->Blog = $Blog;
  121.  
  122.         if!empty$filterset_name ) )
  123.         {    // Set the filterset_name with the filterset_name param
  124.             $this->filterset_name 'ItemList_filters_'.$filterset_name;
  125.         }
  126.         else
  127.         {    // Set a generic filterset_name
  128.             $this->filterset_name 'ItemList_filters_coll'.$this->Blog->ID;
  129.         }
  130.  
  131.         $this->page_param = $param_prefix.'paged';
  132.  
  133.         $this->restrict_to $restrict_to;
  134.  
  135.         // Initialize the default filter set:
  136.         $this->set_default_filtersarray(
  137.                 'filter_preset' => NULL,
  138.                 'ts_min' => $timestamp_min,
  139.                 'ts_max' => $timestamp_max,
  140.                 'ts_created_max' => NULL,
  141.                 'cat_array' => array(),
  142.                 'cat_modifier' => NULL,
  143.                 'cat_focus' => 'wide',                    // Search in extra categories, not just main cat
  144.                 'tags' => NULL,
  145.                 'authors' => NULL,
  146.                 'assignees' => NULL,
  147.                 'author_assignee' => NULL,
  148.                 'lc' => 'all',                                    // Filter on requested locale
  149.                 'keywords' => NULL,
  150.                 'phrase' => 'AND',
  151.                 'exact' => 0,
  152.                 'post_ID' => NULL,
  153.                 'post_ID_list' => NULL,
  154.                 'post_title' => NULL,
  155.                 'ymdhms' => NULL,
  156.                 'week' => NULL,
  157.                 'ymdhms_min' => NULL,
  158.                 'ymdhms_max' => NULL,
  159.                 'statuses' => NULL,
  160.                 'types' => '-1000',                            // All types except pages
  161.                 'visibility_array' => array'published''protected''private' ),
  162.                 'orderby' => $this->Blog->get_setting('orderby'),
  163.                 'order' => $this->Blog->get_setting('orderdir'),
  164.                 'unit' => $this->Blog->get_setting('what_to_show'),
  165.                 'posts' => $this->limit,
  166.                 'page' => 1,
  167.             ) );
  168.     }
  169.  
  170.  
  171.     /**
  172.      * Set default filter values we always want to use if not individually specified otherwise:
  173.      *
  174.      * @param array default filters to be merged with the class defaults
  175.      * @param array default filters for each preset, to be merged with general default filters if the preset is used
  176.      */
  177.     function set_default_filters$default_filters$preset_filters array() )
  178.     {
  179.         $this->default_filters = array_merge$this->default_filters$default_filters );
  180.         $this->preset_filters $preset_filters;
  181.     }
  182.  
  183.  
  184.     /**
  185.      * Set/Activate filterset
  186.      *
  187.      * This will also set back the GLOBALS !!! needed for regenerate_url().
  188.      *
  189.      * @param array 
  190.      * @param boolean 
  191.      */
  192.     function set_filters$filters$memorize true )
  193.     {
  194.         if!empty$filters ) )
  195.         // Activate the filterset (fallback to default filter when a value is not set):
  196.             $this->filters = array_merge$this->default_filters$filters );
  197.         }
  198.  
  199.         // Activate preset filters if necessary:
  200.         $this->activate_preset_filters();
  201.  
  202.         // Funky oldstyle params:
  203.         $this->limit = $this->filters['posts']// for compatibility with parent class
  204.         $this->page = $this->filters['page'];
  205.  
  206.  
  207.         if$memorize )
  208.         {    // set back the GLOBALS !!! needed for regenerate_url() :
  209.  
  210.             /*
  211.              * Selected filter preset:
  212.              */
  213.             memorize_param$this->param_prefix.'filter_preset''string'$this->default_filters['filter_preset']$this->filters['filter_preset');  // List of authors to restrict to
  214.  
  215.  
  216.             /*
  217.              * Blog & Chapters/categories restrictions:
  218.              */
  219.             // Get chapters/categories (and compile those values right away)
  220.             memorize_param'cat''/^[*\-]?([0-9]+(,[0-9]+)*)?$/'$this->default_filters['cat_modifier']$this->filters['cat_modifier');  // List of authors to restrict to
  221.             memorize_param'catsel''array'$this->default_filters['cat_array']$this->filters['cat_array');
  222.             memorize_param$this->param_prefix.'cat_focus''string'$this->default_filters['cat_focus']$this->filters['cat_focus');  // Categories to search on
  223.             // TEMP until we get this straight:
  224.             // fp> this would only be used for the categories widget and setting it here overwtrites the interesting values when a post list widget is tirggered
  225.             // fp> if we need it here we want to use a $set_globals params to this function
  226.             // global $cat_array, $cat_modifier;
  227.             // $cat_array = $this->default_filters['cat_array'];
  228.             // $cat_modifier = $this->default_filters['cat_modifier'];
  229.  
  230.  
  231.             /*
  232.              * Restrict to selected tags:
  233.              */
  234.             memorize_param$this->param_prefix.'tags''string'$this->default_filters['tags']$this->filters['tags');
  235.  
  236.  
  237.             /*
  238.              * Restrict to selected authors:
  239.              */
  240.             memorize_param$this->param_prefix.'author''string'$this->default_filters['authors']$this->filters['authors');  // List of authors to restrict to
  241.  
  242.             /*
  243.              * Restrict to selected assignees:
  244.              */
  245.             memorize_param$this->param_prefix.'assgn''string'$this->default_filters['assignees']$this->filters['assignees');  // List of assignees to restrict to
  246.  
  247.             /*
  248.              * Restrict to selected author OR assignee:
  249.              */
  250.             memorize_param$this->param_prefix.'author_assignee''string'$this->default_filters['author_assignee']$this->filters['author_assignee');
  251.  
  252.             /*
  253.              * Restrict to selected locale:
  254.              */
  255.             memorize_param$this->param_prefix.'lc''string'$this->default_filters['lc']$this->filters['lc');  // Locale to restrict to
  256.  
  257.             /*
  258.              * Restrict to selected statuses:
  259.              */
  260.             memorize_param$this->param_prefix.'status''string'$this->default_filters['statuses']$this->filters['statuses');  // List of statuses to restrict to
  261.  
  262.             /*
  263.              * Restrict to selected item type:
  264.              */
  265.             memorize_param$this->param_prefix.'types''integer'$this->default_filters['types']$this->filters['types');  // List of item types to restrict to
  266.  
  267.             /*
  268.              * Restrict by keywords
  269.              */
  270.             memorize_param$this->param_prefix.'s''string'$this->default_filters['keywords']$this->filters['keywords');             // Search string
  271.             memorize_param$this->param_prefix.'sentence''string'$this->default_filters['phrase']$this->filters['phrase')// Search for sentence or for words
  272.             memorize_param$this->param_prefix.'exact''integer'$this->default_filters['exact']$this->filters['exact');     // Require exact match of title or contents
  273.  
  274.             /*
  275.              * Specific Item selection?
  276.              */
  277.             memorize_param$this->param_prefix.'m''/^\d{4}(0[1-9]|1[0-2])?(?(1)(0[1-9]|[12][0-9]|3[01])?)(?(2)([01][0-9]|2[0-3])?)(?(3)([0-5][0-9]){0,2})$/'$this->default_filters['ymdhms']$this->filters['ymdhms');          // YearMonth(Day) to display
  278.             memorize_param$this->param_prefix.'w''/^(0?[0-9]|[1-4][0-9]|5[0-3])$/'$this->default_filters['week']$this->filters['week');            // Week number
  279.             memorize_param$this->param_prefix.'dstart''integer'$this->default_filters['ymdhms_min']$this->filters['ymdhms_min')// YearMonth(Day) to start at
  280.             memorize_param$this->param_prefix.'dstop''integer'$this->default_filters['ymdhms_max']$this->filters['ymdhms_max')// YearMonth(Day) to start at
  281.  
  282.             // TODO: show_past/future should probably be wired on dstart/dstop instead on timestamps -> get timestamps out of filter perimeter
  283.             ifis_null($this->default_filters['ts_min'])
  284.                 && is_null($this->default_filters['ts_max') )
  285.             {    // We have not set a strict default -> we allow overridding:
  286.                 memorize_param$this->param_prefix.'show_past''integer'0($this->filters['ts_min'== 'now');
  287.                 memorize_param$this->param_prefix.'show_future''integer'0($this->filters['ts_max'== 'now');
  288.             }
  289.  
  290.             /*
  291.              * Restrict to the statuses we want to show:
  292.              */
  293.             // Note: oftentimes, $show_statuses will have been preset to a more restrictive set of values
  294.             memorize_param$this->param_prefix.'show_statuses''array'$this->default_filters['visibility_array']$this->filters['visibility_array');    // Array of sharings to restrict to
  295.  
  296.             /*
  297.              * OLD STYLE orders:
  298.              */
  299.             memorize_param$this->param_prefix.'order''string'$this->default_filters['order']$this->filters['order');           // ASC or DESC
  300.             memorize_param$this->param_prefix.'orderby''string'$this->default_filters['orderby']$this->filters['orderby');  // list of fields to order by (TODO: change that crap)
  301.  
  302.             /*
  303.              * Paging limits:
  304.              */
  305.             memorize_param$this->param_prefix.'unit''string'$this->default_filters['unit']$this->filters['unit');            // list unit: 'posts' or 'days'
  306.  
  307.             memorize_param$this->param_prefix.'posts''integer'$this->default_filters['posts']$this->filters['posts');             // # of units to display on the page
  308.  
  309.             // 'paged'
  310.             memorize_param$this->page_param'integer'1$this->filters['page');      // List page number in paged display
  311.         }
  312.     }
  313.  
  314.  
  315.     /**
  316.      * Init filter params from Request params
  317.      *
  318.      * @param boolean do we want to use saved filters ?
  319.      * @return boolean true if we could apply a filterset based on Request params (either explicit or reloaded)
  320.      */
  321.     function load_from_Request$use_filters true )
  322.     {
  323.         // fp> 2007-09-23> Let's always start with clean filters.
  324.         // If we don't do this, then $this->filters will end up with filters in a different order than $this->default_filters.
  325.         // And orders are different, then $this->is_filtered() will say it's filtered even if it's not.
  326.         $this->filters = $this->default_filters;
  327.  
  328.         if$use_filters )
  329.         {
  330.             // Do we want to restore filters or do we want to create a new filterset
  331.             $filter_action param$this->param_prefix.'filter''string''save' );
  332.             // echo ' filter action: ['.$filter_action.'] ';
  333.             switch$filter_action )
  334.             {
  335.                 case 'restore':
  336.                     return $this->restore_filterset();
  337.                     /* BREAK */
  338.  
  339.                 case 'reset':
  340.                     // We want to reset the memorized filterset:
  341.                     global $Session;
  342.                     $Session->delete$this->filterset_name );
  343.  
  344.                     // Memorize global variables:
  345.                     $this->set_filtersarray()true );
  346.  
  347.                     // We have applied no filterset:
  348.                     return false;
  349.                     /* BREAK */
  350.             }
  351.  
  352.             /**
  353.              * Filter preset
  354.              */
  355.             $this->filters['filter_preset'param$this->param_prefix.'filter_preset''string'$this->default_filters['filter_preset']true );
  356.  
  357.             // Activate preset default filters if necessary:
  358.             $this->activate_preset_filters();
  359.         }
  360.  
  361.  
  362.         // fp> TODO: param( 'loc', 'string', '', true );                            // Locale of the posts (all by default)
  363.  
  364.  
  365.         /*
  366.          * Blog & Chapters/categories restrictions:
  367.          */
  368.         // Get chapters/categories (and compile those values right away)
  369.         param_compile_cat_array/* TODO: check $this->Blog->ID == 1 ? 0 :*/ $this->Blog->ID,
  370.                                 $this->default_filters['cat_modifier']$this->default_filters['cat_array');
  371.  
  372.         $this->filters['cat_array'get_param'cat_array' );
  373.         $this->filters['cat_modifier'get_param'cat_modifier' );
  374.  
  375.         $this->filters['cat_focus'param$this->param_prefix.'cat_focus''string'$this->default_filters['cat_focus']true );
  376.  
  377.  
  378.         /*
  379.          * Restrict to selected tags:
  380.          */
  381.         $this->filters['tags'param$this->param_prefix.'tag''string'$this->default_filters['tags']true );
  382.  
  383.  
  384.         /*
  385.          * Restrict to selected authors:
  386.          */
  387.         $this->filters['authors'param$this->param_prefix.'author''/^-?[0-9]+(,[0-9]+)*$/'$this->default_filters['authors']true );      // List of authors to restrict to
  388.  
  389.  
  390.         /*
  391.          * Restrict to selected assignees:
  392.          */
  393.         $this->filters['assignees'param$this->param_prefix.'assgn''/^(-|-[0-9]+|[0-9]+)(,[0-9]+)*$/'$this->default_filters['assignees']true );      // List of assignees to restrict to
  394.  
  395.  
  396.         /*
  397.          * Restrict to selected author or assignee:
  398.          */
  399.         $this->filters['author_assignee'param$this->param_prefix.'author_assignee''/^[0-9]+$/'$this->default_filters['author_assignee']true );
  400.  
  401.  
  402.         /*
  403.          * Restrict to selected locale:
  404.          */
  405.         $this->filters['lc'param$this->param_prefix.'lc''string'$this->default_filters['lc']true );
  406.  
  407.  
  408.         /*
  409.          * Restrict to selected statuses:
  410.          */
  411.         $this->filters['statuses'param$this->param_prefix.'status''/^(-|-[0-9]+|[0-9]+)(,[0-9]+)*$/'$this->default_filters['statuses']true );      // List of statuses to restrict to
  412.  
  413.         /*
  414.          * Restrict to selected types:
  415.          */
  416.         $this->filters['types'param$this->param_prefix.'types''/^(-|-[0-9]+|[0-9]+)(,[0-9]+)*$/'$this->default_filters['types']true );      // List of types to restrict to
  417.  
  418.  
  419.         /*
  420.          * Restrict by keywords
  421.          */
  422.         $this->filters['keywords'param$this->param_prefix.'s''string'$this->default_filters['keywords']true );         // Search string
  423.         $this->filters['phrase'param$this->param_prefix.'sentence''string'$this->default_filters['phrase']true );         // Search for sentence or for words
  424.         $this->filters['exact'param$this->param_prefix.'exact''integer'$this->default_filters['exact']true );        // Require exact match of title or contents
  425.  
  426.  
  427.         /*
  428.          * Specific Item selection?
  429.          */
  430.         $this->filters['post_ID'param$this->param_prefix.'p''integer'$this->default_filters['post_ID');          // Specific post number to display
  431.         $this->filters['post_title'param$this->param_prefix.'title''string'$this->default_filters['post_title');      // urtitle of post to display
  432.  
  433.  
  434.         /*
  435.          * multiple Item selection ?
  436.          */
  437.         $this->filters['post_ID_list'param$this->param_prefix.'pl''string'$this->default_filters['post_ID_list');  // Specific list of post numbers to display
  438.  
  439.  
  440.         $this->single_post = !empty($this->filters['post_ID']|| !empty($this->filters['post_title']);
  441.  
  442.  
  443.         /*
  444.          * If a timeframe is specified in the querystring, restrict to that timeframe:
  445.          */
  446.         $this->filters['ymdhms'param$this->param_prefix.'m''/^\d{4}(0[1-9]|1[0-2])?(?(1)(0[1-9]|[12][0-9]|3[01])?)(?(2)([01][0-9]|2[0-3])?)(?(3)([0-5][0-9]){0,2})$/'$this->default_filters['ymdhms']true );          // YearMonth(Day) to display
  447.         $this->filters['week'param$this->param_prefix.'w''/^(0?[0-9]|[1-4][0-9]|5[0-3])$/'$this->default_filters['week']true );            // Week number
  448.  
  449.         $this->filters['ymdhms_min'param_compact_date$this->param_prefix.'dstart'$this->default_filters['ymdhms_min']trueT_'Invalid date' ) )// YearMonth(Day) to start at
  450.         $this->filters['ymdhms_max'param_compact_date$this->param_prefix.'dstop'$this->default_filters['ymdhms_max']trueT_'Invalid date' ) )// YearMonth(Day) to stop at
  451.  
  452.  
  453.         // TODO: show_past/future should probably be wired on dstart/dstop instead on timestamps -> get timestamps out of filter perimeter
  454.         // So far, these act as SILENT filters. They will not advertise their filtering in titles etc.
  455.         $this->filters['ts_min'$this->default_filters['ts_min'];
  456.         $this->filters['ts_max'$this->default_filters['ts_max'];
  457.         ifis_null($this->default_filters['ts_min'])
  458.             && is_null($this->default_filters['ts_max') )
  459.         {    // We have not set a strict default -> we allow overridding:
  460.             $show_past param$this->param_prefix.'show_past''integer'0true );
  461.             $show_future param$this->param_prefix.'show_future''integer'0true );
  462.             if$show_past != $show_future )
  463.             {    // There is a point in overridding:
  464.                 $this->filters['ts_min'$show_past == 'now' '';
  465.                 $this->filters['ts_max'$show_future == 'now' '';
  466.             }
  467.         }
  468.  
  469.         /*
  470.          * Restrict to the statuses we want to show:
  471.          */
  472.         // Note: oftentimes, $show_statuses will have been preset to a more restrictive set of values
  473.         $this->filters['visibility_array'param$this->param_prefix.'show_statuses''array'$this->default_filters['visibility_array']
  474.                         truefalsetruefalse );    // Array of sharings to restrict to
  475.  
  476.         /*
  477.          * Ordering:
  478.          */
  479.         $this->filters['order'param$this->param_prefix.'order''/^(ASC|asc|DESC|desc)$/'$this->default_filters['order']true );        // ASC or DESC
  480.         $this->filters['orderby'param$this->param_prefix.'orderby''/^([A-Za-z0-9_]+([ ,][A-Za-z0-9_]+)*)?$/'$this->default_filters['orderby']true );   // list of fields to order by (TODO: change that crap)
  481.  
  482.         /*
  483.          * Paging limits:
  484.          */
  485.         $this->filters['unit'param$this->param_prefix.'unit''string'$this->default_filters['unit']true );            // list unit: 'posts' or 'days'
  486.  
  487.         $this->filters['posts'param$this->param_prefix.'posts''integer'$this->default_filters['posts']true );             // # of units to display on the page
  488.         $this->limit = $this->filters['posts']// for compatibility with parent class
  489.  
  490.         // 'paged'
  491.         $this->filters['page'param$this->page_param'integer'1true );      // List page number in paged display
  492.         $this->page = $this->filters['page'];
  493.  
  494.         ifparam_errors_detected() )
  495.         {
  496.             return false;
  497.         }
  498.  
  499.         if$this->single_post )
  500.         {    // We have requested a specific post
  501.             // Do not attempt to save or load any filterset:
  502.             return true;
  503.         }
  504.  
  505.         //echo ' Got filters from URL?:'.($this->is_filtered() ? 'YES' : 'NO');
  506.         //pre_dump( $this->default_filters );
  507.         //pre_dump( $this->filters );
  508.  
  509.         if$use_filters && $filter_action == 'save' )
  510.         {
  511.             $this->save_filterset();
  512.         }
  513.  
  514.         return true;
  515.     }
  516.  
  517.  
  518.     /**
  519.      * Activate preset default filters if necessary
  520.      *
  521.      */
  522.     function activate_preset_filters()
  523.     {
  524.         $filter_preset $this->filters['filter_preset'];
  525.  
  526.         ifempty$filter_preset ) )
  527.         // No filter preset, there are no additional defaults to use:
  528.             return;
  529.         }
  530.  
  531.         // Override general defaults with the specific defaults for the preset:
  532.         $this->default_filters = array_merge$this->default_filters$this->preset_filters[$filter_preset);
  533.  
  534.         // Save the name of the preset in order for is_filtered() to work properly:
  535.         $this->default_filters['filter_preset'$this->filters['filter_preset'];
  536.     }
  537.  
  538.  
  539.     /**
  540.      * Save current filterset to session.
  541.      */
  542.     function save_filterset()
  543.     {
  544.         /**
  545.          * @var Session
  546.          */
  547.         global $Session$Debuglog;
  548.  
  549.         $Debuglog->add'Saving filterset <strong>'.$this->filterset_name.'</strong>''filters' );
  550.  
  551.         $Session->set$this->filterset_name$this->filters );
  552.     }
  553.  
  554.  
  555.     /**
  556.      * Load previously saved filterset from session.
  557.      *
  558.      * @return boolean true if we could restore something
  559.      */
  560.     function restore_filterset()
  561.     {
  562.       /**
  563.        * @var Session
  564.        */
  565.         global $Session;
  566.       /**
  567.        * @var Request
  568.        */
  569.  
  570.         global $Debuglog;
  571.  
  572.         $filters $Session->get$this->filterset_name );
  573.  
  574.         /*
  575.         fp> 2007-09-26> even if there are no filters, we need to "set" them in order to set global variables like $show_statuses
  576.         if( empty($filters) )
  577.         { // We have no saved filters:
  578.             return false;
  579.         }
  580.         */
  581.  
  582.         ifempty($filters) )
  583.         // set_filters() expects array
  584.             $filters array();
  585.         }
  586.  
  587.         $Debuglog->add'Restoring filterset <strong>'.$this->filterset_name.'</strong>''filters' );
  588.  
  589.         // Restore filters:
  590.         $this->set_filters$filters );
  591.  
  592.         return true;
  593.     }
  594.  
  595.  
  596.     /**
  597.      *
  598.      *
  599.      * @todo count?
  600.      */
  601.     function query_init()
  602.     {
  603.         global $current_User;
  604.  
  605.         ifempty$this->filters ) )
  606.         {    // Filters have not been set before, we'll use the default filterset:
  607.             // If there is a preset filter, we need to activate its specific defaults:
  608.             $this->filters['filter_preset'param$this->param_prefix.'filter_preset''string'$this->default_filters['filter_preset']true );
  609.             $this->activate_preset_filters();
  610.  
  611.             // Use the default filters:
  612.             $this->set_filters$this->default_filters );
  613.         }
  614.  
  615.  
  616.         // echo '<br />ItemListLight query';
  617.         //pre_dump( $this->filters );
  618.  
  619.         // GENERATE THE QUERY:
  620.  
  621.         /*
  622.          * filtering stuff:
  623.          */
  624.         $this->ItemQuery->where_chapter2$this->Blog$this->filters['cat_array']$this->filters['cat_modifier'],
  625.                                                                             $this->filters['cat_focus');
  626.         $this->ItemQuery->where_tags$this->filters['tags');
  627.         $this->ItemQuery->where_author$this->filters['authors');
  628.         $this->ItemQuery->where_assignees$this->filters['assignees');
  629.         $this->ItemQuery->where_author_assignee$this->filters['author_assignee');
  630.         $this->ItemQuery->where_locale$this->filters['lc');
  631.         $this->ItemQuery->where_statuses$this->filters['statuses');
  632.         $this->ItemQuery->where_types$this->filters['types');
  633.         $this->ItemQuery->where_keywords$this->filters['keywords']$this->filters['phrase']$this->filters['exact');
  634.         $this->ItemQuery->where_ID$this->filters['post_ID']$this->filters['post_title');
  635.         $this->ItemQuery->where_ID_list$this->filters['post_ID_list');
  636.         $this->ItemQuery->where_datestart$this->filters['ymdhms']$this->filters['week'],
  637.                                            $this->filters['ymdhms_min']$this->filters['ymdhms_max'],
  638.                                            $this->filters['ts_min']$this->filters['ts_max');
  639.         $this->ItemQuery->where_datecreated$this->filters['ts_created_max');
  640.         $this->ItemQuery->where_visibility$this->filters['visibility_array');
  641.  
  642.         /*
  643.          * ORDER BY stuff:
  644.          */
  645.         $order $this->filters['order'];
  646.         ifstrtoupper$order == 'RAND' )
  647.         {
  648.             $order_by 'RAND()';
  649.         }
  650.         else
  651.         {
  652.             $orderby str_replace' '','$this->filters['orderby');
  653.             $orderby_array explode','$orderby );
  654.  
  655.             // Format each order param with default column names:
  656.             $orderby_array preg_replace'#^(.+)$#'$this->Cache->dbprefix.'$1 '.$order$orderby_array );
  657.             // walter>fp> $order_cols_to_select = $orderby_array;
  658.  
  659.             // Add an ID parameter to make sure there is no ambiguity in ordering on similar items:
  660.             $orderby_array[$this->Cache->dbIDname.' '.$order;
  661.  
  662.             $order_by implode', '$orderby_array );
  663.         }
  664.  
  665.  
  666.         $this->ItemQuery->order_by$order_by );
  667.  
  668.  
  669.  
  670.         /*
  671.          * GET TOTAL ROW COUNT:
  672.          */
  673.         if$this->single_post )   // p or title
  674.         // Single post: no paging required!
  675.             $this->total_rows = 1;
  676.             $this->total_pages = 1;
  677.             $this->page = 1;
  678.         }
  679.         /*
  680.         elseif( !empty($this->filters['ymdhms']) // no restriction if we request a month... some permalinks may point to the archive!
  681.         */
  682.         elseif$this->filters['unit'== 'days'    // We are going to limit to x days: no limit
  683.                   || $this->filters['unit'== 'all' )     // We want ALL results!
  684.         {
  685.             $this->total_rows = NULL// unknown!
  686.             $this->total_pages = 1;
  687.             $this->page = 1;
  688.         }
  689.         elseif$this->filters['unit'== 'posts' )
  690.         {
  691.             /*
  692.              * TODO: The result is incorrect when using AND on categories
  693.              * We would need to use a HAVING close and thyen COUNT, which would be a subquery
  694.              * This is nto compatible with mysql 3.23
  695.              * We need fallback code.
  696.              */
  697.             $sql_count '
  698.                 SELECT COUNT( DISTINCT '.$this->Cache->dbIDname.') '
  699.                     .$this->ItemQuery->get_from()
  700.                     .$this->ItemQuery->get_where();
  701.  
  702.             //echo $DB->format_query( $sql_count );
  703.  
  704.             parent::count_total_rows$sql_count );
  705.             //echo '<br />'.$this->total_rows;
  706.         }
  707.         else
  708.         {
  709.             debug_die'Unhandled LIMITING mode in ItemList:'.$this->filters['unit'].' (paged mode is obsolete)' );
  710.         }
  711.  
  712.  
  713.         /*
  714.          * Paging LIMITs:
  715.          */
  716.         if$this->single_post )   // p or title
  717.         // Single post: no paging required!
  718.         }
  719.         /*
  720.             fp> 2007-11-25 : a very high post count can now be configured in the admin for this. Default is 100.
  721.             elseif( !empty($this->filters['ymdhms']) )
  722.             { // no restriction if we request a month... some permalinks may point to the archive!
  723.                 // echo 'ARCHIVE - no limits';
  724.             }
  725.         */
  726.         elseif$this->filters['unit'== 'all' )
  727.         {    // We want ALL results!
  728.         }
  729.         elseif$this->filters['unit'== 'posts' )
  730.         {
  731.             // TODO: dh> check if $limit is NULL!? - though it should not arrive at $page>1 then..
  732.             // echo 'LIMIT POSTS ';
  733.             $pgstrt '';
  734.             if$this->page > )
  735.             // We have requested a specific page number
  736.                 $pgstrt (intval($this->page-1$this->limit', ';
  737.             }
  738.             $this->ItemQuery->LIMIT$pgstrt.$this->limit );
  739.         }
  740.         elseif$this->filters['unit'== 'days' )
  741.         // We are going to limit to x days:
  742.             // echo 'LIMIT DAYS ';
  743.             ifempty$this->filters['ymdhms_min') )
  744.             // We have no start date, we'll display the last x days:
  745.                 if!empty($this->filters['keywords'])
  746.                     || !empty($this->filters['cat_array'])
  747.                     || !empty($this->filters['authors']) )
  748.                 // We are in DAYS mode but we can't restrict on these! (TODO: ?)
  749.                     $limits '';
  750.                 }
  751.                 else
  752.                 // We are going to limit to LAST x days:
  753.                     $lastpostdate $this->get_lastpostdate();
  754.                     $lastpostdate mysql2date('Y-m-d 00:00:00',$lastpostdate);
  755.                     $lastpostdate mysql2date('U',$lastpostdate);
  756.                     // go back x days
  757.                     $otherdate date('Y-m-d H:i:s'($lastpostdate (($this->limit-186400)));
  758.                     $this->ItemQuery->WHERE_and$this->Cache->dbprefix.'datestart > \''$otherdate.'\'' );
  759.                 }
  760.             }
  761.             else
  762.             // We have a start date, we'll display x days starting from that point:
  763.                 // $dstart_mysql has been calculated earlier
  764.  
  765.                 // TODO: this is redundant with previous dstart processing:
  766.                 // Add trailing 0s: YYYYMMDDHHMMSS
  767.                 $dstart0 $this->filters['ymdhms_min'].'00000000000000';
  768.  
  769.                 $dstart_mysql substr($dstart0,0,4).'-'.substr($dstart0,4,2).'-'.substr($dstart0,6,2).' '
  770.                                                 .substr($dstart0,8,2).':'.substr($dstart0,10,2).':'.substr($dstart0,12,2);
  771.                 $dstart_ts mysql2timestamp$dstart_mysql );
  772.                 // go forward x days
  773.                 $enddate_ts date('Y-m-d H:i:s'($dstart_ts ($this->limit * 86400)));
  774.                 $this->ItemQuery->WHERE_and$this->Cache->dbprefix.'datestart < \''$enddate_ts.'\'' );
  775.             }
  776.         }
  777.         else
  778.             debug_die'Unhandled LIMITING mode in ItemList:'.$this->filters['unit'].' (paged mode is obsolete)' );
  779.     }
  780.  
  781.  
  782.   /**
  783.      * Run Query: GET DATA ROWS *** LIGHT ***
  784.      *
  785.      * Contrary to ItemList2, we only do 1 query here and we extract only a few selected params.
  786.      * Basically all we want is being able to generate permalinks.
  787.      */
  788.     function query()
  789.     {
  790.         global $DB;
  791.  
  792.         if!is_null$this->rows ) )
  793.         // Query has already executed:
  794.             return;
  795.         }
  796.  
  797.         // INNIT THE QUERY:
  798.         $this->query_init();
  799.  
  800.         // QUERY:
  801.         $this->sql = 'SELECT DISTINCT '.$this->Cache->dbIDname.', post_datestart, post_datemodified, post_title, post_url,
  802.                                     post_excerpt, post_urltitle, post_main_cat_ID, post_ptyp_ID '
  803.                                     .$this->ItemQuery->get_from()
  804.                                     .$this->ItemQuery->get_where()
  805.                                     .$this->ItemQuery->get_group_by()
  806.                                     .$this->ItemQuery->get_order_by()
  807.                                     .$this->ItemQuery->get_limit();
  808.  
  809.         // echo $DB->format_query( $this->sql );
  810.  
  811.         parent::queryfalsefalsefalse'ItemListLight::query()' );
  812.     }
  813.  
  814.  
  815.  
  816.  
  817.     /**
  818.      * Get datetime of the last post/item
  819.      * @todo dh> Optimize this, if this can be said after having done {@link query()} already.
  820.      * @todo dh> Cache result
  821.      * @todo dh> Add $dateformat param
  822.      * @return string 'Y-m-d H:i:s' formatted; If there are no items this will be {@link $localtimenow}.
  823.      */
  824.     function get_lastpostdate()
  825.     {
  826.         global $localtimenow$DB;
  827.  
  828.         ifempty$this->filters ) )
  829.         {    // Filters have no been set before, we'll use the default filterset:
  830.             // echo ' Query:Setting default filterset ';
  831.             $this->set_filters$this->default_filters );
  832.         }
  833.  
  834.         // GENERATE THE QUERY:
  835.  
  836.         // The SQL Query object:
  837.         $lastpost_ItemQuery new ItemQuery$this->Cache->dbtablename$this->Cache->dbprefix$this->Cache->dbIDname );
  838.  
  839.         /*
  840.          * filtering stuff:
  841.          */
  842.         $lastpost_ItemQuery->where_chapter2$this->Blog$this->filters['cat_array']$this->filters['cat_modifier'],
  843.                                                                                  $this->filters['cat_focus']  );
  844.         $lastpost_ItemQuery->where_author$this->filters['authors');
  845.         $lastpost_ItemQuery->where_assignees$this->filters['assignees');
  846.         $lastpost_ItemQuery->where_locale$this->filters['lc');
  847.         $lastpost_ItemQuery->where_statuses$this->filters['statuses');
  848.         $lastpost_ItemQuery->where_types$this->filters['types');
  849.         $lastpost_ItemQuery->where_keywords$this->filters['keywords']$this->filters['phrase']$this->filters['exact');
  850.         $lastpost_ItemQuery->where_ID$this->filters['post_ID']$this->filters['post_title');
  851.         $lastpost_ItemQuery->where_datestart$this->filters['ymdhms']$this->filters['week'],
  852.                                            $this->filters['ymdhms_min']$this->filters['ymdhms_max'],
  853.                                            $this->filters['ts_min']$this->filters['ts_max');
  854.         $lastpost_ItemQuery->where_visibility$this->filters['visibility_array');
  855.  
  856.         /*
  857.          * order by stuff:
  858.          * LAST POST FIRST!!! (That's the whole point!)
  859.          */
  860.         $lastpost_ItemQuery->order_by$this->Cache->dbprefix.'datestart DESC' );
  861.  
  862.         /*
  863.          * Paging limits:
  864.          * ONLY THE LAST POST!!!
  865.          */
  866.         $lastpost_ItemQuery->LIMIT'1' );
  867.  
  868.         // Select the datestart:
  869.         $lastpost_ItemQuery->select$this->Cache->dbprefix.'datestart' );
  870.  
  871.         $lastpostdate $DB->get_var$lastpost_ItemQuery->get()00'Get last post date' );
  872.  
  873.         ifempty$lastpostdate ) )
  874.         {
  875.             // echo 'we have no last item';
  876.             $lastpostdate date('Y-m-d H:i:s'$localtimenow);
  877.         }
  878.  
  879.         // echo $lastpostdate;
  880.  
  881.         return $lastpostdate;
  882.     }
  883.  
  884.  
  885.     /**
  886.      * Generate a title for the current list, depending on its filtering params
  887.      *
  888.      * @todo cleanup some displays
  889.      * @todo implement HMS part of YMDHMS
  890.      *
  891.      * @return array 
  892.      */
  893.     function get_filter_titles$ignore array()$params array() )
  894.     {
  895.         global $month$post_statuses;
  896.  
  897.         $params array_mergearray(
  898.                 'category_text' => T_('Category').': ',
  899.                 'categories_text' => T_('Categories').': ',
  900.                 // 'tag_text' => T_('Tag').': ',
  901.                 'tags_text' => T_('Tags').': ',
  902.             )$params );
  903.  
  904.         ifempty$this->filters ) )
  905.         {    // Filters have no been set before, we'll use the default filterset:
  906.             // echo ' setting default filterset ';
  907.             $this->set_filters$this->default_filters );
  908.         }
  909.  
  910.         $title_array array();
  911.  
  912.         if$this->single_post )
  913.         {    // We have requested a specific post:
  914.             // Should be in first position
  915.             $Item $this->get_by_idx);
  916.  
  917.             ifis_null($Item) )
  918.             {
  919.                 $title_array[T_('Invalid request');
  920.             }
  921.             else
  922.             {
  923.                 $title_array[$Item->get('title');
  924.             }
  925.             return $title_array;
  926.         }
  927.  
  928.  
  929.         // CATEGORIES:
  930.         if!empty($this->filters['cat_array']) )
  931.         // We have requested specific categories...
  932.             $cat_names array();
  933.             foreach$this->filters['cat_array'as $cat_ID )
  934.             {
  935.                 if( ($my_cat get_the_category_by_ID$cat_IDfalse ) ) !== false )
  936.                 // It is almost never meaningful to die over an invalid cat when generating title
  937.                     $cat_names[$my_cat['cat_name'];
  938.                 }
  939.             }
  940.             if$this->filters['cat_modifier'== '*' )
  941.             {
  942.                 $cat_names_string implode' + '$cat_names );
  943.             }
  944.             else
  945.             {
  946.                 $cat_names_string implode', '$cat_names );
  947.             }
  948.             if!empty$cat_names_string ) )
  949.             {
  950.                 if$this->filters['cat_modifier'== '-' )
  951.                 {
  952.                     $cat_names_string T_('All but ').' '.$cat_names_string;
  953.                     $title_array['cats'$params['categories_text'].$cat_names_string;
  954.                 }
  955.                 else
  956.                 {
  957.                     ifcount($this->filters['cat_array'])
  958.                         $title_array['cats'$params['categories_text'].$cat_names_string;
  959.                     else
  960.                         $title_array['cats'$params['category_text'].$cat_names_string;
  961.                 }
  962.             }
  963.         }
  964.  
  965.  
  966.         // ARCHIVE TIMESLOT:
  967.         if!empty($this->filters['ymdhms']) )
  968.         {    // We have asked for a specific timeframe:
  969.  
  970.             $my_year substr($this->filters['ymdhms'],0,4);
  971.  
  972.             ifstrlen($this->filters['ymdhms'])
  973.             // We have requested a month too:
  974.                 $my_month T_($month[substr($this->filters['ymdhms'],4,2)]);
  975.             }
  976.             else
  977.             {
  978.                 $my_month '';
  979.             }
  980.  
  981.             // Requested a day?
  982.             $my_day substr($this->filters['ymdhms'],6,2);
  983.  
  984.             $arch T_('Archives for').': '.$my_month.' '.$my_year;
  985.  
  986.             if!empty$my_day ) )
  987.             {    // We also want to display a day
  988.                 $arch .= "$my_day";
  989.             }
  990.  
  991.             if!empty($this->filters['week']|| ($this->filters['week'=== 0) ) // Note: week # can be 0
  992.             {    // We also want to display a week number
  993.                 $arch .= ', '.T_('week').' '.$this->filters['week'];
  994.             }
  995.  
  996.             $title_array['ymdhms'$arch;
  997.         }
  998.  
  999.  
  1000.         // KEYWORDS:
  1001.         if!empty($this->filters['keywords']) )
  1002.         {
  1003.             $title_array['keywords'T_('Keyword(s)').': '.$this->filters['keywords'];
  1004.         }
  1005.  
  1006.  
  1007.         // TAGS:
  1008.         if!empty($this->filters['tags']) )
  1009.         {
  1010.             $title_array[$params['tags_text'].$this->filters['tags'];
  1011.         }
  1012.  
  1013.  
  1014.         // AUTHORS:
  1015.         if!empty($this->filters['authors']) )
  1016.         {
  1017.             $title_array[T_('Author(s)').': '.$this->filters['authors'];
  1018.         }
  1019.  
  1020.  
  1021.         // ASSIGNEES:
  1022.         if!empty($this->filters['assignees']) )
  1023.         {
  1024.             if$this->filters['assignees'== '-' )
  1025.             {
  1026.                 $title_array[T_('Not assigned');
  1027.             }
  1028.             else
  1029.             {
  1030.                 $title_array[T_('Assigned to').': '.$this->filters['assignees'];
  1031.             }
  1032.         }
  1033.  
  1034.  
  1035.         // LOCALE:
  1036.         if$this->filters['lc'!= 'all' )
  1037.         {
  1038.             $title_array[T_('Locale').': '.$this->filters['lc'];
  1039.         }
  1040.  
  1041.  
  1042.         // EXTRA STATUSES:
  1043.         if!empty($this->filters['statuses']) )
  1044.         {
  1045.             if$this->filters['statuses'== '-' )
  1046.             {
  1047.                 $title_array[T_('Without status');
  1048.             }
  1049.             else
  1050.             {
  1051.                 $title_array[T_('Status(es)').': '.$this->filters['statuses'];
  1052.             }
  1053.         }
  1054.  
  1055.  
  1056.         // SHOW STATUSES
  1057.         ifcount$this->filters['visibility_array'5
  1058.             && !in_array'visibility'$ignore ) )
  1059.         {
  1060.             $status_titles array();
  1061.             foreach$this->filters['visibility_array'as $status )
  1062.             {
  1063.                 $status_titles[T_$post_statuses[$status);
  1064.             }
  1065.             $title_array[T_('Visibility').': '.implode', '$status_titles );
  1066.         }
  1067.  
  1068.  
  1069.         // START AT
  1070.         if!empty($this->filters['ymdhms_min') )
  1071.         {
  1072.             $title_array['ymdhms_min'T_('Start at').': '.$this->filters['ymdhms_min';
  1073.         }
  1074.         if!empty($this->filters['ts_min') )
  1075.         {
  1076.             if$this->filters['ts_min'== 'now' )
  1077.             {
  1078.                 $title_array['ts_min'T_('Hide past');
  1079.             }
  1080.             else
  1081.             {
  1082.                 $title_array['ts_min'T_('Start at').': '.$this->filters['ts_min'];
  1083.             }
  1084.         }
  1085.  
  1086.  
  1087.         // STOP AT
  1088.         if!empty($this->filters['ymdhms_max') )
  1089.         {
  1090.             $title_array['ymdhms_max'T_('Stop at').': '.$this->filters['ymdhms_max'];
  1091.         }
  1092.         if!empty($this->filters['ts_max') )
  1093.         {
  1094.             if$this->filters['ts_max'== 'now' )
  1095.             {
  1096.                 if!in_array'hide_future'$ignore ) )
  1097.                 {
  1098.                     $title_array['ts_max'T_('Hide future');
  1099.                 }
  1100.             }
  1101.             else
  1102.             {
  1103.                 $title_array['ts_max'T_('Stop at').': '.$this->filters['ts_max'];
  1104.             }
  1105.         }
  1106.  
  1107.  
  1108.         // LIMIT TO
  1109.         if$this->single_post )   // p or title
  1110.         // Single post: no paging required!
  1111.         }
  1112.         elseif!empty($this->filters['ymdhms']) )
  1113.         // no restriction if we request a month... some permalinks may point to the archive!
  1114.         }
  1115.         elseif$this->filters['unit'== 'posts' || $this->filters['unit'== 'all' )
  1116.         // We're going to page, so there's no real limit here...
  1117.         }
  1118.         elseif$this->filters['unit'== 'days' )
  1119.         // We are going to limit to x days:
  1120.             // echo 'LIMIT DAYS ';
  1121.             ifempty$this->filters['ymdhms_min') )
  1122.             // We have no start date, we'll display the last x days:
  1123.                 if!empty($this->filters['keywords'])
  1124.                     || !empty($this->filters['cat_array'])
  1125.                     || !empty($this->filters['authors']) )
  1126.                 // We are in DAYS mode but we can't restrict on these! (TODO: ?)
  1127.                 }
  1128.                 else
  1129.                 // We are going to limit to LAST x days:
  1130.                     // TODO: rename 'posts' to 'limit'
  1131.                     $title_array['posts'sprintfT_('Limited to %d last days')$this->limit );
  1132.                 }
  1133.             }
  1134.             else
  1135.             // We have a start date, we'll display x days starting from that point:
  1136.                 $title_array['posts'sprintfT_('Limited to %d days')$this->limit );
  1137.             }
  1138.         }
  1139.         else
  1140.             debug_die'Unhandled LIMITING mode in ItemList:'.$this->filters['unit'].' (paged mode is obsolete)' );
  1141.  
  1142.  
  1143.         return $title_array;
  1144.     }
  1145.  
  1146.  
  1147.     /**
  1148.      * return total number of posts
  1149.      *
  1150.      * This is basically just a stub for backward compatibility
  1151.      *
  1152.      * @deprecated
  1153.      */
  1154.     function get_total_num_posts()
  1155.     {
  1156.         return $this->total_rows;
  1157.     }
  1158.  
  1159.  
  1160.     /**
  1161.      * If the list is sorted by category...
  1162.      *
  1163.      * Note: this only supports one level of categories (nested cats will be flatened)
  1164.      */
  1165.     function get_category_group()
  1166.     {
  1167.         global $row;
  1168.  
  1169.         ifempty$this->current_Obj ) )
  1170.         {    // Very first call
  1171.             // Do a normal get_next()
  1172.             parent::get_next();
  1173.         }
  1174.  
  1175.         ifempty$this->current_Obj ) )
  1176.         {    // We have reached the end of the list
  1177.             return $this->current_Obj;
  1178.         }
  1179.  
  1180.         $this->group_by_cat = 1;
  1181.  
  1182.         // Memorize main cat
  1183.         $this->main_cat_ID $this->current_Obj->main_cat_ID;
  1184.  
  1185.         return $this->current_Obj;
  1186.     }
  1187.  
  1188.  
  1189.     /**
  1190.      * If the list is sorted by category...
  1191.       *
  1192.       * This is basically just a stub for backward compatibility
  1193.      */
  1194.     function get_item()
  1195.     {
  1196.         if$this->group_by_cat == )
  1197.         {    // This is the first call to get_item() after get_category_group()
  1198.             $this->group_by_cat = 2;
  1199.             // Return the object we already got in get_category_group():
  1200.             return $this->current_Obj;
  1201.         }
  1202.  
  1203.         $Item $this->get_next();
  1204.  
  1205.         if!empty($Item&& $this->group_by_cat == && $Item->main_cat_ID != $this->main_cat_ID )
  1206.         {    // We have just hit a new category!
  1207.             $this->group_by_cat == 0// For info only.
  1208.             $r false;
  1209.             return $r;
  1210.         }
  1211.  
  1212.         //pre_dump( $Item );
  1213.  
  1214.         return $Item;
  1215.     }
  1216.  
  1217.  
  1218.     /**
  1219.      * Get the adverstised start date (does not include timestamp_min)
  1220.      *
  1221.      * Note: there is a priority order in the params to determine the start date:
  1222.      *  -dstart
  1223.      *  -week + m
  1224.      *  -m
  1225.      *  -dstop - x days
  1226.      * @see ItemQuery::where_datestart()
  1227.      */
  1228.     function get_advertised_start_date()
  1229.     {
  1230.         if$this->getting_adv_start_date )
  1231.         {    // We would be entering an infinite loop, stop now:
  1232.             // We cannot determine a start date, save an empty string (to differentiate from NULL)
  1233.             $this->advertised_start_date '';
  1234.  
  1235.             // Reset anti infinite loop:
  1236.             $this->getting_adv_start_date = false;
  1237.  
  1238.             return $this->advertised_start_date;
  1239.         }
  1240.  
  1241.         // Anti infinite loop:
  1242.         $this->getting_adv_start_date = true;
  1243.  
  1244.  
  1245.         ifis_null$this->advertised_start_date ) )
  1246.         {    // We haven't determined the start date yet:
  1247.  
  1248.             if!empty$this->filters['ymdhms_min') )
  1249.             {    // We have requested start date (8 digits)
  1250.                 $m $this->filters['ymdhms_min'];
  1251.                 $this->advertised_start_date mktime000substr($m,4,2)substr($m,6,2)substr($m,0,4) );
  1252.             }
  1253.             elseif!is_null($this->filters['week'])         // note: 0 is a valid week number
  1254.                         && !empty$this->filters['ymdhms') )
  1255.             {    // we want to restrict on a specific week
  1256.                 $this->advertised_start_date get_start_date_for_weeksubstr($this->filters['ymdhms'],0,4)$this->filters['week']locale_startofweek() );
  1257.             }
  1258.             elseifstrlen$this->filters['ymdhms'>= )
  1259.             {    // We have requested an interval
  1260.                 $m $this->filters['ymdhms'].'0101';
  1261.                 $this->advertised_start_date mktime000substr($m,4,2)substr($m,6,2)substr($m,0,4) );
  1262.             }
  1263.             elseif$this->filters['unit'== 'days'
  1264.                         && ($stop_date $this->get_advertised_stop_date()) != '' )
  1265.             {    // We want to restrict on a specific number of days after the start date:
  1266.                 $this->advertised_start_date $stop_date ($this->limit-186400;
  1267.             }
  1268.             else
  1269.             {    // We cannot determine a start date, save an empty string (to differentiate from NULL)
  1270.                 $this->advertised_start_date '';
  1271.             }
  1272.  
  1273.         }
  1274.  
  1275.         // Reset anti infinite loop:
  1276.         $this->getting_adv_start_date = false;
  1277.  
  1278.         return $this->advertised_start_date;
  1279.     }
  1280.  
  1281.  
  1282.     /**
  1283.      * Get the adverstised stop date (does not include timestamp_max)
  1284.      *
  1285.      * Note: there is a priority order in the params to determine the stop date.
  1286.      *  -dstop
  1287.      *  -week + m
  1288.      *  -m
  1289.      *  -dstart + x days
  1290.      */
  1291.     function get_advertised_stop_date()
  1292.     {
  1293.         if$this->getting_adv_stop_date )
  1294.         {    // We would be entering an infinite loop, stop now:
  1295.             // We cannot determine a stop date, save an empty string (to differentiate from NULL)
  1296.             $this->advertised_stop_date = '';
  1297.  
  1298.             // Reset anti infinite loop:
  1299.             $this->getting_adv_stop_date = false;
  1300.  
  1301.             return $this->advertised_stop_date;
  1302.         }
  1303.  
  1304.         // Anti infinite loop:
  1305.         $this->getting_adv_stop_date = true;
  1306.  
  1307.  
  1308.         ifis_null$this->advertised_stop_date ) )
  1309.         {    // We haven't determined the stop date yet:
  1310.  
  1311.             if!empty$this->filters['ymdhms_max') )
  1312.             {    // We have requested an end date (8 digits)
  1313.                 $m $this->filters['ymdhms_max'];
  1314.                 $this->advertised_stop_date = mktime000substr($m,4,2)substr($m,6,2)substr($m,0,4) );
  1315.             }
  1316.             elseif!is_null($this->filters['week'])         // note: 0 is a valid week number
  1317.                         && !empty$this->filters['ymdhms') )
  1318.             {    // we want to restrict on a specific week
  1319.                 $this->advertised_stop_date = get_start_date_for_weeksubstr($this->filters['ymdhms'],0,4)$this->filters['week']locale_startofweek() );
  1320.                 $this->advertised_stop_date += 518400// + 6 days
  1321.             }
  1322.             elseif!empty$this->filters['ymdhms') )
  1323.             {    // We want to restrict on an interval:
  1324.                 ifstrlen$this->filters['ymdhms'>= )
  1325.                 {    // We have requested a day interval
  1326.                     $m $this->filters['ymdhms'];
  1327.                     $this->advertised_stop_date = mktime000substr($m,4,2)substr($m,6,2)substr($m,0,4) );
  1328.                 }
  1329.                 elseifstrlen$this->filters['ymdhms'== )
  1330.                 // We want to go to the end of the month:
  1331.                     $m $this->filters['ymdhms'];
  1332.                     $this->advertised_stop_date = mktime000substr($m,4,2)+10substr($m,0,4) )// 0th day of next mont = last day of month
  1333.                 }
  1334.                 elseifstrlen$this->filters['ymdhms'== )
  1335.                 // We want to go to the end of the year:
  1336.                     $m $this->filters['ymdhms'];
  1337.                     $this->advertised_stop_date = mktime0001231substr($m,0,4) );
  1338.                 }
  1339.             }
  1340.             elseif$this->filters['unit'== 'days'
  1341.                         && ($start_date $this->get_advertised_start_date()) != '' )
  1342.             {    // We want to restrict on a specific number of days after the start date:
  1343.                 $this->advertised_stop_date = $start_date ($this->limit-186400;
  1344.             }
  1345.             else
  1346.             {    // We cannot determine a stop date, save an empty string (to differentiate from NULL)
  1347.                 $this->advertised_stop_date = '';
  1348.             }
  1349.  
  1350.         }
  1351.  
  1352.         // Reset anti infinite loop:
  1353.         $this->getting_adv_stop_date = false;
  1354.  
  1355.         return $this->advertised_stop_date;
  1356.     }
  1357.  
  1358.  
  1359.     /**
  1360.      * Make sure date displaying starts at the beginning of the current filter interval
  1361.      *
  1362.      * Note: we're talking about strict dates (no times involved)
  1363.      */
  1364.     function set_start_date)
  1365.     {
  1366.         $start_date $this->get_advertised_start_date();
  1367.  
  1368.         if!empty$start_date ) )
  1369.         {    // Memorize the last displayed as the day BEFORE the one we're going to display
  1370.             //echo ' start at='.date( locale_datefmt(), $start_date );
  1371.             $this->last_displayed_date = $start_date 86400;
  1372.         }
  1373.     }
  1374.  
  1375.  
  1376.     /**
  1377.      * Template function: display potentially remaining empty days until the end of the filter interval
  1378.      *
  1379.      * @param string string to display before the date (if changed)
  1380.      * @param string string to display after the date (if changed)
  1381.      * @param string date/time format: leave empty to use locale default time format
  1382.      */
  1383.     function dates_to_end$before_empty_day '<h2>'$after_empty_day '</h2>'$format '' )
  1384.     {
  1385.         $stop_date $this->get_advertised_stop_date();
  1386.  
  1387.         if!is_null$stop_date ) )
  1388.         {    // There is a stop date, we want to display days:
  1389.             //echo ' - stop at='.date( locale_datefmt(), $stop_date );
  1390.             //echo ' - last displayed='.date( locale_datefmt(), $this->last_displayed_date );
  1391.             while$this->last_displayed_date < $stop_date )
  1392.             {
  1393.                 $this->last_displayed_date += 86400;    // Add one day's worth of seconds
  1394.                 echo date_sprintf$before_empty_day$this->last_displayed_date )
  1395.                         .date_i18n$format$this->last_displayed_date )
  1396.                         .date_sprintf$after_empty_day$this->last_displayed_date );
  1397.             }
  1398.         }
  1399.     }
  1400.  
  1401.  
  1402.     /**
  1403.      * Template tag: Display the date if it has changed since last call
  1404.      *
  1405.      * Optionally also displays empty dates in between.
  1406.      *
  1407.      * @param array 
  1408.      */
  1409.     function date_if_changed$params array() )
  1410.     {
  1411.         if$this->current_Obj->ptyp_ID == 1000 )
  1412.         {    // This is not applicable to pages
  1413.             return;
  1414.         }
  1415.  
  1416.         // Make sure we are not missing any param:
  1417.         $params array_mergearray(
  1418.                 'before'      => '<h2>',
  1419.                 'after'       => '</h2>',
  1420.                 'empty_day_display' => false,
  1421.                 'empty_day_before' => '<h2>',
  1422.                 'empty_day_after'  => '</h2>',
  1423.                 'date_format' => '#',
  1424.             )$params );
  1425.  
  1426.         // Get a timestamp for the date WITHOUT the time:
  1427.         $current_item_date mysql2datestamp$this->current_Obj->issue_date );
  1428.  
  1429.         if$current_item_date != $this->last_displayed_date )
  1430.         {    // Date has changed...
  1431.  
  1432.  
  1433.             if$params['date_format'== '#' )
  1434.             {    // No format specified, use default locale format:
  1435.                 $params['date_format'locale_datefmt();
  1436.             }
  1437.  
  1438.             if$params['empty_day_display'&& !empty($this->last_displayed_date) )
  1439.             {    // We want to display ALL dates from the previous to the current:
  1440.                 while$this->last_displayed_date < $current_item_date-86400 )
  1441.                 {
  1442.                     $this->last_displayed_date += 86400;    // Add one day's worth of seconds
  1443.                     echo date_sprintf$params['empty_day_before']$this->last_displayed_date )
  1444.                             .date_i18n$params['date_format']$this->last_displayed_date )
  1445.                             .date_sprintf$params['empty_day_after']$this->last_displayed_date );
  1446.                 }
  1447.             }
  1448.  
  1449.             // Display the new current date:
  1450.             echo date_sprintf$params['before']$this->last_displayed_date )
  1451.                     .date_i18n$params['date_format']$current_item_date )
  1452.                     .date_sprintf$params['after']$this->last_displayed_date );
  1453.  
  1454.             $this->last_displayed_date = $current_item_date;
  1455.         }
  1456.     }
  1457.  
  1458.  
  1459.     /**
  1460.      * Template tag
  1461.      */
  1462.     function page_links$params array() )
  1463.     {
  1464.         global $generating_static;
  1465.  
  1466.         $default_params array(
  1467.                 'block_start' => '<p class="center">',
  1468.                 'block_end' => '</p>',
  1469.                 'block_single' => '',
  1470.                 'links_format' => '#',
  1471.                 'page_url' => ''// All generated links will refer to the current page
  1472.                 'prev_text' => '&lt;&lt;',
  1473.                 'next_text' => '&gt;&gt;',
  1474.                 'no_prev_text' => '',
  1475.                 'no_next_text' => '',
  1476.                 'list_prev_text' => '...',
  1477.                 'list_next_text' => '...',
  1478.                 'list_span' => 11,
  1479.                 'scroll_list_range' => 5,
  1480.             );
  1481.       if!empty($generating_static) )
  1482.       {    // When generating a static page, act as if we were currently on the blog main page:
  1483.           $default_params['page_url'$this->Blog->get('url');
  1484.         }
  1485.  
  1486.         // Use defaults + overrides:
  1487.         $params array_merge$default_params$params );
  1488.  
  1489.         if$this->total_pages <= )
  1490.         {    // Single page:
  1491.             echo $params['block_single'];
  1492.             return;
  1493.         }
  1494.  
  1495.         if$params['links_format'== '#' )
  1496.         {
  1497.             $params['links_format''$prev$ $first$ $list_prev$ $list$ $list_next$ $last$ $next$';
  1498.         }
  1499.  
  1500.          if$this->Blog->get_setting'paged_nofollowto' ) )
  1501.         {    // We prefer robots not to follow to pages:
  1502.             $this-> nofollow_pagenav = true;
  1503.         }
  1504.  
  1505.         echo $params['block_start'];
  1506.         echo $this->replace_vars$params['links_format']$params );
  1507.         echo $params['block_end'];
  1508.     }
  1509.  
  1510.  
  1511. }
  1512.  
  1513. /*
  1514.  * $Log: _itemlistlight.class.php,v $
  1515.  * Revision 1.19.2.1  2009/03/16 11:33:12  tblue246
  1516.  * Validate w and m params -> fix possible PHP notice
  1517.  *
  1518.  * Revision 1.19  2008/01/21 09:35:31  fplanque
  1519.  * (c) 2008
  1520.  *
  1521.  * Revision 1.18  2007/12/26 23:12:00  yabs
  1522.  * changing RANDOM to RAND
  1523.  *
  1524.  * Revision 1.17  2007/12/26 17:53:24  fplanque
  1525.  * minor
  1526.  *
  1527.  * Revision 1.16  2007/12/26 11:27:47  yabs
  1528.  * added post_ID_list to filters
  1529.  *
  1530.  * Revision 1.15  2007/12/24 10:37:19  yabs
  1531.  * adding random order
  1532.  *
  1533.  * Revision 1.14  2007/11/27 22:31:57  fplanque
  1534.  * debugged blog moderation
  1535.  *
  1536.  * Revision 1.13  2007/11/25 14:28:17  fplanque
  1537.  * additional SEO settings
  1538.  *
  1539.  * Revision 1.12  2007/11/24 21:41:12  fplanque
  1540.  * additional SEO settings
  1541.  *
  1542.  * Revision 1.11  2007/11/11 23:43:37  blueyed
  1543.  * Proper fix for array_merge warnings (http://forums.b2evolution.net/viewtopic.php?t=12944); Props Afwas
  1544.  *
  1545.  * Revision 1.10  2007/11/03 21:04:27  fplanque
  1546.  * skin cleanup
  1547.  *
  1548.  * Revision 1.9  2007/11/01 03:19:34  blueyed
  1549.  * Fix for array_merge in PHP5, props yettyn
  1550.  *
  1551.  * Revision 1.8  2007/10/10 09:02:36  fplanque
  1552.  * PHP5 fix
  1553.  *
  1554.  * Revision 1.7  2007/10/01 01:06:31  fplanque
  1555.  * Skin/template functions cleanup.
  1556.  *
  1557.  * Revision 1.6  2007/09/26 20:26:36  fplanque
  1558.  * improved ItemList filters
  1559.  *
  1560.  * Revision 1.5  2007/09/23 18:57:15  fplanque
  1561.  * filter handling fixes
  1562.  *
  1563.  * Revision 1.4  2007/09/19 20:03:18  yabs
  1564.  * minor bug fix ( http://forums.b2evolution.net/viewtopic.php?p=60493#60493 )
  1565.  *
  1566.  * Revision 1.3  2007/09/03 16:46:58  fplanque
  1567.  * minor
  1568.  *
  1569.  * Revision 1.2  2007/06/29 00:24:43  fplanque
  1570.  * $cat_array cleanup tentative
  1571.  *
  1572.  * Revision 1.1  2007/06/25 11:00:27  fplanque
  1573.  * MODULES (refactored MVC)
  1574.  *
  1575.  * Revision 1.8  2007/06/21 00:44:37  fplanque
  1576.  * linkblog now a widget
  1577.  *
  1578.  * Revision 1.7  2007/05/27 00:35:26  fplanque
  1579.  * tag display + tag filtering
  1580.  *
  1581.  * Revision 1.6  2007/05/13 22:53:31  fplanque
  1582.  * allow feeds restricted to post excerpts
  1583.  *
  1584.  * Revision 1.5  2007/05/13 22:02:09  fplanque
  1585.  * removed bloated $object_def
  1586.  *
  1587.  * Revision 1.4  2007/03/26 14:21:30  fplanque
  1588.  * better defaults for pages implementation
  1589.  *
  1590.  * Revision 1.3  2007/03/26 12:59:18  fplanque
  1591.  * basic pages support
  1592.  *
  1593.  * Revision 1.2  2007/03/19 21:57:36  fplanque
  1594.  * ItemLists: $cat_focus and $unit extensions
  1595.  *
  1596.  * Revision 1.1  2007/03/18 03:43:19  fplanque
  1597.  * EXPERIMENTAL
  1598.  * Splitting Item/ItemLight and ItemList/ItemListLight
  1599.  * Goal: Handle Items with less footprint than with their full content
  1600.  * (will be even worse with multiple languages/revisions per Item)
  1601.  *
  1602.  * Revision 1.53  2007/03/18 01:39:54  fplanque
  1603.  * renamed _main.php to main.page.php to comply with 2.0 naming scheme.
  1604.  * (more to come)
  1605.  *
  1606.  * Revision 1.52  2007/03/12 14:02:41  waltercruz
  1607.  * Adding the columns in order by to the query to satisfy the SQL Standarts
  1608.  *
  1609.  * Revision 1.51  2007/03/03 03:37:56  fplanque
  1610.  * extended prev/next item links
  1611.  *
  1612.  * Revision 1.50  2007/03/03 01:14:12  fplanque
  1613.  * new methods for navigating through posts in single item display mode
  1614.  *
  1615.  * Revision 1.49  2007/01/26 04:49:17  fplanque
  1616.  * cleanup
  1617.  *
  1618.  * Revision 1.48  2007/01/23 09:25:40  fplanque
  1619.  * Configurable sort order.
  1620.  *
  1621.  * Revision 1.47  2007/01/20 23:05:11  blueyed
  1622.  * todos
  1623.  *
  1624.  * Revision 1.46  2007/01/19 21:48:09  blueyed
  1625.  * Fixed possible notice in preview_from_request()
  1626.  *
  1627.  * Revision 1.45  2006/12/17 23:42:38  fplanque
  1628.  * Removed special behavior of blog #1. Any blog can now aggregate any other combination of blogs.
  1629.  * Look into Advanced Settings for the aggregating blog.
  1630.  * There may be side effects and new bugs created by this. Please report them :]
  1631.  *
  1632.  * Revision 1.44  2006/12/05 00:01:15  fplanque
  1633.  * enhanced photoblog skin
  1634.  *
  1635.  * Revision 1.43  2006/12/04 18:16:50  fplanque
  1636.  * Each blog can now have its own "number of page/days to display" settings
  1637.  *
  1638.  * Revision 1.42  2006/11/28 00:33:01  blueyed
  1639.  * Removed DB::compString() (never used) and DB::get_list() (just a macro and better to have in the 4 used places directly; Cleanup/normalization; no extended regexp, when not needed!
  1640.  *
  1641.  * Revision 1.41  2006/11/24 18:27:24  blueyed
  1642.  * Fixed link to b2evo CVS browsing interface in file docblocks
  1643.  *
  1644.  * Revision 1.40  2006/11/17 00:19:22  blueyed
  1645.  * Switch to user locale for validating item_issue_date, because it uses T_()
  1646.  *
  1647.  * Revision 1.39  2006/11/17 00:09:15  blueyed
  1648.  * TODO: error/E_NOTICE with invalid issue date
  1649.  *
  1650.  * Revision 1.38  2006/11/12 02:13:19  blueyed
  1651.  * doc, whitespace
  1652.  *
  1653.  * Revision 1.37  2006/11/11 17:33:50  blueyed
  1654.  * doc
  1655.  *
  1656.  * Revision 1.36  2006/11/04 19:38:53  blueyed
  1657.  * Fixes for hook move
  1658.  *
  1659.  * Revision 1.35  2006/11/02 16:00:42  blueyed
  1660.  * Moved AppendItemPreviewTransact hook, so it can throw error messages
  1661.  *
  1662.  * Revision 1.34  2006/10/31 00:33:26  blueyed
  1663.  * Fixed item_issue_date for preview
  1664.  *
  1665.  * Revision 1.33  2006/10/10 17:09:39  blueyed
  1666.  * doc
  1667.  *
  1668.  * Revision 1.32  2006/10/08 22:35:01  blueyed
  1669.  * TODO: limit===NULL handling
  1670.  *
  1671.  * Revision 1.31  2006/10/05 01:17:36  blueyed
  1672.  * Removed unnecessary/doubled call to Item::update_renderers_from_Plugins()
  1673.  *
  1674.  * Revision 1.30  2006/10/05 01:06:36  blueyed
  1675.  * Removed dirty "hack"; added ItemApplyAsRenderer hook instead.
  1676.  */
  1677. ?>

Documentation generated on Sat, 06 Mar 2010 03:36:11 +0100 by phpDocumentor 1.4.2. This site is hosted and maintained by Daniel HAHLER (Contact).