[ Index ]
 

Code source de b2evolution 2.1.0-beta

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/blogs/inc/items/model/ -> _item.funcs.php (source)

   1  <?php
   2  /**

   3   * This file implements Post handling functions.

   4   *

   5   * This file is part of the evoCore framework - {@link http://evocore.net/}

   6   * See also {@link http://sourceforge.net/projects/evocms/}.

   7   *

   8   * @copyright (c)2003-2007 by Francois PLANQUE - {@link http://fplanque.net/}

   9   * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.

  10   *

  11   * {@internal License choice

  12   * - If you have received this file as part of a package, please find the license.txt file in

  13   *   the same folder or the closest folder above for complete license terms.

  14   * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)

  15   *   then you must choose one of the following licenses before using the file:

  16   *   - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php

  17   *   - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php

  18   * }}

  19   *

  20   * {@internal Open Source relicensing agreement:

  21   * Daniel HAHLER grants Francois PLANQUE the right to license

  22   * Daniel HAHLER's contributions to this file and the b2evolution project

  23   * under any OSI approved OSS license (http://www.opensource.org/licenses/).

  24   * }}

  25   *

  26   * @package evocore

  27   *

  28   * {@internal Below is a list of authors who have contributed to design/coding of this file: }}

  29   * @author cafelog (team)

  30   * @author blueyed: Daniel HAHLER.

  31   * @author fplanque: Francois PLANQUE.

  32   * @author tswicegood: Travis SWICEGOOD.

  33   * @author vegarg: Vegar BERG GULDAL.

  34   *

  35   * @version $Id: _item.funcs.php,v 1.5 2007/09/23 18:57:15 fplanque Exp $

  36   */
  37  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  38  
  39  
  40  /**

  41   * Prepare the MainList object for displaying skins.

  42   *

  43   * @param integer max # of posts on the page

  44   */
  45  function init_MainList( $items_nb_limit )
  46  {
  47      global $MainList;
  48      global $Blog;
  49      global $timestamp_min, $timestamp_max;
  50      global $preview;
  51      global $disp;
  52      global $postIDlist, $postIDarray;
  53  
  54      $MainList = new ItemList2( $Blog, $timestamp_min, $timestamp_max, $items_nb_limit );    // COPY (FUNC)

  55  
  56      if( ! $preview )
  57      {
  58          if( $disp == 'page' )
  59          {    // Get  pages:
  60              $MainList->set_default_filters( array(
  61                      'types' => '1000',        // pages
  62                  ) );
  63          }
  64          // else: we are either in single or in page mode

  65  
  66          // pre_dump( $MainList->default_filters );

  67          $MainList->load_from_Request( false );
  68          // pre_dump( $MainList->filters );

  69          // echo '<br/>'.( $MainList->is_filtered() ? 'filtered' : 'NOT filtered' );

  70          // $MainList->dump_active_filters();

  71  
  72          // Run the query:

  73          $MainList->query();
  74  
  75          // Old style globals for category.funcs:

  76          $postIDlist = $MainList->get_page_ID_list();
  77          $postIDarray = $MainList->get_page_ID_array();
  78      }
  79      else
  80      {    // We want to preview a single post, we are going to fake a lot of things...
  81          $MainList->preview_from_request();
  82  
  83          // Legacy for the category display

  84          $cat_array = array();
  85      }
  86  
  87      param( 'more', 'integer', 0, true );
  88      param( 'page', 'integer', 1, true ); // Post page to show

  89      param( 'c',    'integer', 0, true ); // Display comments?

  90      param( 'tb',   'integer', 0, true ); // Display trackbacks?

  91      param( 'pb',   'integer', 0, true ); // Display pingbacks?

  92  }
  93  
  94  
  95  /**

  96   * Validate URL title

  97   *

  98   * Using title as a source if url title is empty

  99   *

 100   * @todo Use configurable char as seperator (see tracker)

 101   * @todo dh> Allow/Use more than 40 chars

 102   *

 103   * @param string url title to validate

 104   * @param string real title to use as a source if $urltitle is empty (encoded in $evo_charset)

 105   * @param integer ID of post

 106   * @return string validated url title

 107   */
 108  function urltitle_validate( $urltitle, $title, $post_ID = 0, $query_only = false,
 109                                                              $dbprefix = 'post_', $dbIDname = 'post_ID', $dbtable = 'T_items__item' )
 110  {
 111      global $DB;
 112  
 113      $urltitle = trim( $urltitle );
 114  
 115      if( empty( $urltitle ) )
 116      {
 117          if( ! empty($title) )
 118              $urltitle = $title;
 119          else
 120              $urltitle = 'title';
 121      }
 122  
 123      // echo 'starting with: '.$urltitle.'<br />';

 124  
 125      // Replace special chars/umlauts, if we can convert charsets:

 126      load_funcs('locales/_charset.funcs.php');
 127      $urltitle = replace_special_chars($urltitle);
 128  
 129      // Make everything lowercase

 130      $urltitle = strtolower( $urltitle );
 131  
 132      // Normalize to 40 chars + a number

 133      preg_match( '/^(.*?)((-|_)+([0-9]+))?$/', $urltitle, $matches );
 134      $urlbase = substr( $matches[1], 0, 40 );
 135      $urltitle = $urlbase;
 136      if( ! empty( $matches[4] ) )
 137      {
 138          $urltitle = $urlbase.'-'.$matches[4];
 139      }
 140  
 141  
 142      // CHECK FOR UNIQUENESS:

 143      // Find all occurrences of urltitle-number in the DB:

 144      $sql = 'SELECT '.$dbprefix.'urltitle
 145                        FROM '.$dbtable.'
 146                       WHERE '.$dbprefix."urltitle REGEXP '^".$urlbase."(-[0-9]+)?$'";
 147      if( $post_ID )
 148      {    // Ignore current post
 149          $sql .= ' AND '.$dbIDname.' <> '.$post_ID;
 150      }
 151      $exact_match = false;
 152      $highest_number = 0;
 153      foreach( $DB->get_results( $sql, ARRAY_A ) as $row )
 154      {
 155          $existing_urltitle = $row[$dbprefix.'urltitle'];
 156          // echo "existing = $existing_urltitle <br />";

 157          if( $existing_urltitle == $urltitle )
 158          { // We have an exact match, we'll have to change the number.
 159              $exact_match = true;
 160          }
 161          if( preg_match( '/-([0-9]+)$/', $existing_urltitle, $matches ) )
 162          { // This one has a number, we extract it:
 163              $existing_number = (integer) $matches[1];
 164              if( $existing_number > $highest_number )
 165              { // This is the new high
 166                  $highest_number = $existing_number;
 167              }
 168          }
 169      }
 170      // echo "highest existing number = $highest_number <br />";

 171  
 172      if( $exact_match && !$query_only )
 173      { // We got an exact match, we need to change the number:
 174          $urltitle = $urlbase.'-'.($highest_number + 1);
 175      }
 176  
 177      // echo "using = $urltitle <br />";

 178  
 179      return $urltitle;
 180  }
 181  
 182  
 183  /**

 184   * if global $postdata was not set it will be

 185   */
 186  function get_postdata($postid)
 187  {
 188      global $DB, $postdata, $show_statuses;
 189  
 190      if( !empty($postdata) && $postdata['ID'] == $postid )
 191      { // We are asking for postdata of current post in memory! (we're in the b2 loop)
 192          // Already in memory! This will be the case when generating permalink at display

 193          // (but not when sending trackbacks!)

 194          // echo "*** Accessing post data in memory! ***<br />\n";

 195          return($postdata);
 196      }
 197  
 198      // echo "*** Loading post data! ***<br>\n";

 199      // We have to load the post

 200      $sql = 'SELECT post_ID, post_creator_user_ID, post_datestart, post_datemodified, post_status, post_content, post_title,
 201                                              post_main_cat_ID, cat_blog_ID ';
 202      $sql .= ', post_locale, post_url, post_wordcount, post_comment_status, post_views ';
 203      $sql .= '    FROM T_items__item
 204                       INNER JOIN T_categories ON post_main_cat_ID = cat_ID
 205                       WHERE post_ID = '.$postid;
 206      // Restrict to the statuses we want to show:

 207      // echo $show_statuses;

 208      // fplanque: 2004-04-04: this should not be needed here. (and is indeed problematic when we want to

 209      // get a post before even knowning which blog it belongs to. We can think of putting a security check

 210      // back into the Item class)

 211      // $sql .= ' AND '.statuses_where_clause( $show_statuses );

 212  
 213      // echo $sql;

 214  
 215      if( $myrow = $DB->get_row( $sql ) )
 216      {
 217          $mypostdata = array (
 218              'ID' => $myrow->post_ID,
 219              'Author_ID' => $myrow->post_creator_user_ID,
 220              'Date' => $myrow->post_datestart,
 221              'Status' => $myrow->post_status,
 222              'Content' => $myrow->post_content,
 223              'Title' => $myrow->post_title,
 224              'Category' => $myrow->post_main_cat_ID,
 225              'Locale' => $myrow->post_locale,
 226              'Url' => $myrow->post_url,
 227              'Wordcount' => $myrow->post_wordcount,
 228              'views' => $myrow->post_views,
 229              'comment_status' => $myrow->post_comment_status,
 230              'Blog' => $myrow->cat_blog_ID,
 231              );
 232  
 233          // Caching is particularly useful when displaying a single post and you call single_post_title several times

 234          if( !isset( $postdata ) ) $postdata = $mypostdata;    // Will save time, next time :)

 235  
 236          return($mypostdata);
 237      }
 238  
 239      return false;
 240  }
 241  
 242  
 243  
 244  
 245  
 246  // @@@ These aren't template tags, do not edit them

 247  
 248  
 249  /**

 250   * Returns the number of the words in a string, sans HTML

 251   *

 252   * @param string

 253   * @return integer

 254   */
 255  function bpost_count_words($string)
 256  {
 257      $string = trim(strip_tags($string));
 258      if( function_exists( 'str_word_count' ) )
 259      { // PHP >= 4.3
 260          return str_word_count($string);
 261      }
 262  
 263      /* In case str_word_count() doesn't exist (to accomodate PHP < 4.3).

 264          (Code adapted from post by "brettNOSPAM at olwm dot NO_SPAM dot com" at

 265          PHP documentation page for str_word_count(). A better implementation

 266          probably exists.)

 267      */
 268      if($string == '')
 269      {
 270          return 0;
 271      }
 272  
 273      $pattern = "/[^(\w|\d|\'|\"|\.|\!|\?|;|,|\\|\/|\-\-|:|\&|@)]+/";
 274      $string = preg_replace($pattern, " ", $string);
 275      $string = count(explode(" ", $string));
 276  
 277      return $string;
 278  }
 279  
 280  
 281  /**

 282   * Construct the where clause to limit retrieved posts on their status

 283   *

 284   * @param Array statuses of posts we want to get

 285   */
 286  function statuses_where_clause( $show_statuses = '', $dbprefix = 'post_', $req_blog = NULL )
 287  {
 288      global $current_User, $blog;
 289  
 290      if( is_null($req_blog ) )
 291      {
 292          global $blog;
 293          $req_blog = $blog;
 294      }
 295  
 296      if( empty($show_statuses) )
 297          $show_statuses = array( 'published', 'protected', 'private' );
 298  
 299      $where = ' ( ';
 300      $or = '';
 301  
 302      if( ($key = array_search( 'private', $show_statuses )) !== false )
 303      { // Special handling for Private status:
 304          unset( $show_statuses[$key] );
 305          if( is_logged_in() )
 306          { // We need to be logged in to have a chance to see this:
 307              $where .= $or.' ( '.$dbprefix."status = 'private' AND ".$dbprefix.'creator_user_ID = '.$current_User->ID.' ) ';
 308              $or = ' OR ';
 309          }
 310      }
 311  
 312      if( $key = array_search( 'protected', $show_statuses ) )
 313      { // Special handling for Protected status:
 314          if( (!is_logged_in())
 315              || ($req_blog == 0) // No blog specified (ONgsb)
 316              || (!$current_User->check_perm( 'blog_ismember', 1, false, $req_blog )) )
 317          { // we are not allowed to see this if we are not a member of the current blog:
 318              unset( $show_statuses[$key] );
 319          }
 320      }
 321  
 322      // Remaining statuses:

 323      $other_statuses = '';
 324      $sep = '';
 325      foreach( $show_statuses as $other_status )
 326      {
 327          $other_statuses .= $sep.'\''.$other_status.'\'';
 328          $sep = ',';
 329      }
 330      if( strlen( $other_statuses ) )
 331      {
 332          $where .= $or.$dbprefix.'status IN ('. $other_statuses .') ';
 333      }
 334  
 335      $where .= ') ';
 336  
 337      // echo $where;

 338      return $where;
 339  }
 340  
 341  
 342  /**

 343   * Allow recursive category selection.

 344   *

 345   * @todo Allow to use a dropdown (select) to switch between blogs ( CSS / JS onchange - no submit.. )

 346   *

 347   * @param boolean

 348   * @param boolean true: use form fields, false: display only

 349   */
 350  function cat_select( $display_info = true, $form_fields = true )
 351  {
 352      global $allow_cross_posting, $cache_categories,
 353                      $blog, $current_blog_ID, $current_User, $edited_Item, $cat_select_form_fields;
 354  
 355      $r = '<div class="extracats"><div>';
 356  
 357      $cat_select_form_fields = $form_fields;
 358  
 359      cat_load_cache(); // make sure the caches are loaded

 360  
 361      $r .= '<table cellspacing="0" class="catselect">';
 362      $r .= cat_select_header();
 363  
 364      if( $allow_cross_posting >= 2 )
 365      { // If BLOG cross posting enabled, go through all blogs with cats:
 366      /**

 367           * @var BlogCache

 368           */
 369          $BlogCache = & get_Cache('BlogCache');
 370  
 371      /**

 372           * @var Blog

 373           */
 374          for( $l_Blog = & $BlogCache->get_first(); !is_null($l_Blog); $l_Blog = & $BlogCache->get_next() )
 375          { // run recursively through the cats
 376              if( ! blog_has_cats( $l_Blog->ID ) )
 377                  continue;
 378  
 379              if( ! $current_User->check_perm( 'blog_post_statuses', 'edit', false, $l_Blog->ID ) )
 380                  continue;
 381  
 382              $r .= '<tr class="group"><td colspan="3">'.$l_Blog->dget('name')."</td></tr>\n";
 383              $current_blog_ID = $l_Blog->ID;    // Global needed in callbacks

 384              $r .= cat_children( $cache_categories, $l_Blog->ID, NULL, 'cat_select_before_first',
 385                                          'cat_select_before_each', 'cat_select_after_each', 'cat_select_after_last', 1 );
 386          }
 387      }
 388      else
 389      { // BLOG Cross posting is disabled. Current blog only:
 390          $current_blog_ID = $blog;
 391          $r .= cat_children( $cache_categories, $current_blog_ID, NULL, 'cat_select_before_first',
 392                                      'cat_select_before_each', 'cat_select_after_each', 'cat_select_after_last', 1 );
 393  
 394      }
 395  
 396      $r .= '</table>';
 397  
 398      if( $current_User->check_perm( 'blog_cats', '', false, $blog ) )
 399      {
 400          $r .= '<p class="extracatnote"><a href="admin.php?ctrl=chapters&amp;action=new&amp;blog='.$blog.'">'.T_('Add a new category').' &raquo;</a></p>';
 401      }
 402  
 403      if( $display_info )
 404      {
 405          $r .= '<p class="extracatnote">'
 406                  .T_('Select main category in target blog and optionally check additional categories')
 407                  .'</p>';
 408  
 409          $r .= '<p class="extracatnote">';
 410          if( $allow_cross_posting >= 3 )
 411          {
 412              $r .= T_('Note: Moving posts across blogs is enabled. Use with caution.');
 413          }
 414          elseif( $allow_cross_posting >= 2 )
 415          {
 416              $r .= T_('Note: Cross posting among multiple blogs is enabled.');
 417          }
 418          elseif( $allow_cross_posting )
 419          {
 420              $r .= T_('Note: Cross posting among multiple blogs is currently disabled.');
 421          }
 422          else
 423          {
 424              $r .= T_('Note: Cross posting among multiple categories is currently disabled.');
 425          }
 426          $r .= '</p>';
 427      }
 428  
 429      $r .= '</div></div>';
 430  
 431      return $r;
 432  }
 433  
 434  /**

 435   * Header for {@link cat_select()}

 436   */
 437  function cat_select_header()
 438  {
 439      global $current_blog_ID, $blog, $allow_cross_posting;
 440  
 441      $r = '<thead><tr><th class="selector catsel_main">'.T_('Main').'</th>';
 442      if( $allow_cross_posting >= 1 )
 443      { // This is current blog or we allow moving posts accross blogs
 444          $r .= '<th class="selector catsel_extra">'.T_('Extra').'</th>';
 445      }
 446      $r .= '<th class="catsel_name">'.T_('Category').'</th></tr></thead>';
 447      return $r;
 448  }
 449  
 450  /**

 451   * callback to start sublist

 452   */
 453  function cat_select_before_first( $parent_cat_ID, $level )
 454  { // callback to start sublist
 455      return ''; // "\n<ul>\n";

 456  }
 457  
 458  /**

 459   * callback to display sublist element

 460   */
 461  function cat_select_before_each( $cat_ID, $level, $total_count )
 462  { // callback to display sublist element
 463      global $current_blog_ID, $blog, $post_extracats, $edited_Item;
 464      global $creating, $allow_cross_posting, $cat_select_level, $cat_select_form_fields;
 465      $this_cat = get_the_category_by_ID( $cat_ID );
 466      $r = "\n".'<tr class="'.( $total_count%2 ? 'odd' : 'even' ).'">';
 467  
 468      // RADIO for main cat:

 469      if( ($current_blog_ID == $blog) || ($allow_cross_posting > 2) )
 470      { // This is current blog or we allow moving posts accross blogs
 471          if( $cat_select_form_fields )
 472          {    // We want a form field:
 473              $r .= '<td class="selector catsel_main"><input type="radio" name="post_category" class="checkbox" title="'
 474                          .T_('Select as MAIN category').'" value="'.$cat_ID.'"';
 475              if( $cat_ID == $edited_Item->main_cat_ID )
 476              { // main cat of the Item or set as default main cat above
 477                  $r .= ' checked="checked"';
 478              }
 479              $r .= ' id="sel_maincat_'.$cat_ID.'"';
 480              $r .= ' onclick="check_extracat(this);" /></td>';
 481          }
 482          else
 483          {    // We just want info:
 484              $r .= '<td class="selector catsel_main">'.bullet( $cat_ID == $edited_Item->main_cat_ID ).'</td>';
 485          }
 486      }
 487      else
 488      { // Don't allow to select this cat as a main cat
 489          $r .= '<td class="selector catsel_main">&nbsp;</td>';
 490      }
 491  
 492      // CHECKBOX:

 493      if( $allow_cross_posting )
 494      { // We allow cross posting, display checkbox:
 495          if( $cat_select_form_fields )
 496          {    // We want a form field:
 497              $r .= '<td class="selector catsel_extra"><input type="checkbox" name="post_extracats[]" class="checkbox" title="'
 498                          .T_('Select as an additional category').'" value="'.$cat_ID.'"';
 499              // if( ($cat_ID == $edited_Item->main_cat_ID) || (in_array( $cat_ID, $post_extracats )) )  <--- We don't want to precheck the default cat because it will stay checked if we change the default main. On edit, the checkbox will always be in the array.

 500              if( (in_array( $cat_ID, $post_extracats )) )
 501              {
 502                  $r .= ' checked="checked"';
 503              }
 504              $r .= ' id="sel_extracat_'.$cat_ID.'"';
 505              $r .= ' /></td>';
 506          }
 507          else
 508          {    // We just want info:
 509              $r .= '<td class="selector catsel_main">'.bullet( ($cat_ID == $edited_Item->main_cat_ID) || (in_array( $cat_ID, $post_extracats )) ).'</td>';
 510          }
 511      }
 512  
 513      $r .= '<td class="catsel_name"><label'
 514                  .' for="'.( $allow_cross_posting
 515                                              ? 'sel_extracat_'.$cat_ID
 516                                              : 'sel_maincat_'.$cat_ID ).'"'
 517                  .' style="padding-left:'.($level-1).'em;">'.$this_cat['cat_name'].'</label>'
 518                  ."</td></tr>\n";
 519  
 520      return $r;
 521  }
 522  
 523  /**

 524   * callback after each sublist element

 525   */
 526  function cat_select_after_each( $cat_ID, $level )
 527  { // callback after each sublist element
 528      return '';
 529  }
 530  
 531  /**

 532   * callback to end sublist

 533   */
 534  function cat_select_after_last( $parent_cat_ID, $level )
 535  { // callback to end sublist
 536      return ''; // "</ul>\n";

 537  }
 538  
 539  
 540  /**

 541   * Used by the items & the comments controllers

 542   */
 543  function attach_browse_tabs()
 544  {
 545      global $AdminUI, $Blog, $current_User;
 546  
 547      $AdminUI->add_menu_entries(
 548              'items',
 549              array(
 550                      'full' => array(
 551                          'text' => T_('Full posts'),
 552                          'href' => 'admin.php?ctrl=items&amp;tab=full&amp;filter=restore&amp;blog='.$Blog->ID,
 553                          ),
 554                      'list' => array(
 555                          'text' => T_('Post list'),
 556                          'href' => 'admin.php?ctrl=items&amp;tab=list&amp;filter=restore&amp;blog='.$Blog->ID,
 557                          ),
 558                  )
 559          );
 560  
 561      if( $Blog->get_setting( 'use_workflow' ) )
 562      {    // We want to use workflow properties for this blog:
 563          $AdminUI->add_menu_entries(
 564                  'items',
 565                  array(
 566                          'tracker' => array(
 567                              'text' => T_('Tracker'),
 568                              'href' => 'admin.php?ctrl=items&amp;tab=tracker&amp;filter=restore&amp;blog='.$Blog->ID,
 569                              ),
 570                      )
 571              );
 572      }
 573  
 574      if( $current_User->check_perm( 'blog_comments', 'edit', false, $Blog->ID ) )
 575      {
 576          $AdminUI->add_menu_entries(
 577                  'items',
 578                  array(
 579                          'comments' => array(
 580                              'text' => T_('Comments'),
 581                              'href' => 'admin.php?ctrl=comments&amp;blog='.$Blog->ID,
 582                              ),
 583                      )
 584              );
 585      }
 586  }
 587  
 588  
 589  
 590  /**

 591   * Allow to select status/visibility

 592   */
 593  function visibility_select( & $Form, $post_status )
 594  {
 595      global $current_User, $Blog;
 596  
 597      $sharing_options = array();
 598  
 599      if( $current_User->check_perm( 'blog_post!published', 'edit', false, $Blog->ID ) )
 600          $sharing_options[] = array( 'published', T_('Published (Public)') );
 601  
 602      if( $current_User->check_perm( 'blog_post!protected', 'edit', false, $Blog->ID ) )
 603          $sharing_options[] = array( 'protected', T_('Protected (Members only)') );
 604  
 605      if( $current_User->check_perm( 'blog_post!private', 'edit', false, $Blog->ID ) )
 606          $sharing_options[] = array( 'private', T_('Private (You only)') );
 607  
 608      if( $current_User->check_perm( 'blog_post!draft', 'edit', false, $Blog->ID ) )
 609          $sharing_options[] = array( 'draft', T_('Draft (Not published!)') );
 610  
 611      if( $current_User->check_perm( 'blog_post!deprecated', 'edit', false, $Blog->ID ) )
 612          $sharing_options[] = array( 'deprecated', T_('Deprecated (Not published!)') );
 613  
 614      if( $current_User->check_perm( 'blog_post!redirected', 'edit', false, $Blog->ID ) )
 615          $sharing_options[] = array( 'redirected', T_('Redirected') );
 616  
 617      $Form->radio( 'post_status', $post_status, $sharing_options, '', true );
 618  }
 619  
 620  
 621  /*

 622   * $Log: _item.funcs.php,v $

 623   * Revision 1.5  2007/09/23 18:57:15  fplanque

 624   * filter handling fixes

 625   *

 626   * Revision 1.4  2007/09/07 20:11:18  fplanque

 627   * Better category selector

 628   *

 629   * Revision 1.3  2007/09/03 20:01:53  blueyed

 630   * Fixed "Add a new category »" link (blog param)

 631   *

 632   * Revision 1.2  2007/09/03 16:44:28  fplanque

 633   * chicago admin skin

 634   *

 635   * Revision 1.1  2007/06/25 11:00:25  fplanque

 636   * MODULES (refactored MVC)

 637   *

 638   * Revision 1.52  2007/05/28 01:33:22  fplanque

 639   * permissions/fixes

 640   *

 641   * Revision 1.51  2007/05/14 02:43:05  fplanque

 642   * Started renaming tables. There probably won't be a better time than 2.0.

 643   *

 644   * Revision 1.50  2007/05/13 20:44:11  fplanque

 645   * url fix

 646   *

 647   * Revision 1.49  2007/05/09 01:01:32  fplanque

 648   * permissions cleanup

 649   *

 650   * Revision 1.48  2007/05/07 18:03:28  fplanque

 651   * cleaned up skin code a little

 652   *

 653   * Revision 1.47  2007/04/26 00:11:11  fplanque

 654   * (c) 2007

 655   *

 656   * Revision 1.46  2007/03/26 14:21:30  fplanque

 657   * better defaults for pages implementation

 658   *

 659   * Revision 1.45  2007/03/26 12:59:18  fplanque

 660   * basic pages support

 661   *

 662   * Revision 1.44  2007/03/18 00:31:18  fplanque

 663   * Delegated MainList init to skin *pages* which need it.

 664   *

 665   * Revision 1.43  2007/03/11 23:56:02  fplanque

 666   * fixed some post editing oddities / variable cleanup (more could be done)

 667   *

 668   * Revision 1.42  2007/03/03 01:14:12  fplanque

 669   * new methods for navigating through posts in single item display mode

 670   *

 671   * Revision 1.41  2007/02/12 15:42:40  fplanque

 672   * public interface for looping over a cache

 673   *

 674   * Revision 1.40  2007/02/06 13:34:20  waltercruz

 675   * Changing double quotes to single quotes

 676   *

 677   * Revision 1.39  2006/12/23 23:37:35  fplanque

 678   * refactoring / Blog::get_default_cat_ID()

 679   *

 680   * Revision 1.38  2006/12/16 17:05:55  blueyed

 681   * todo

 682   *

 683   * Revision 1.37  2006/12/15 23:31:21  fplanque

 684   * reauthorized _ in urltitles.

 685   * No breaking of legacy permalinks.

 686   * - remains the default placeholder though.

 687   *

 688   * Revision 1.36  2006/12/12 23:23:30  fplanque

 689   * finished post editing v2.0

 690   *

 691   * Revision 1.35  2006/12/12 02:53:56  fplanque

 692   * Activated new item/comments controllers + new editing navigation

 693   * Some things are unfinished yet. Other things may need more testing.

 694   *

 695   * Revision 1.34  2006/12/11 17:26:21  fplanque

 696   * some cross-linking

 697   *

 698   * Revision 1.33  2006/12/04 21:20:27  blueyed

 699   * Abstracted convert_special_charsets() out of urltitle_validate()

 700   *

 701   * Revision 1.32  2006/12/03 22:23:26  fplanque

 702   * doc

 703   *

 704   * Revision 1.31  2006/11/24 18:27:24  blueyed

 705   * Fixed link to b2evo CVS browsing interface in file docblocks

 706   *

 707   * Revision 1.30  2006/11/23 00:37:35  blueyed

 708   * Added two more replacements in urltitle_validate and pass charset to htmlentities()

 709   */
 710  ?>


Généré le : Thu Nov 29 23:58:50 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics