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