b2evolution PHP Cross Reference Blogging Systems

Source: /inc/skins/_skin.funcs.php - 1291 lines - 37651 bytes - Summary - Text - Print

Description: This file implements Template tags for use withing skins. This file is part of the b2evolution/evocms project - {@link http://b2evolution.net/}. See also {@link http://sourceforge.net/projects/evocms/}.

   1  <?php
   2  /**
   3   * This file implements Template tags for use withing skins.
   4   *
   5   * This file is part of the b2evolution/evocms project - {@link http://b2evolution.net/}.
   6   * See also {@link http://sourceforge.net/projects/evocms/}.
   7   *
   8   * @copyright (c)2003-2014 by Francois Planque - {@link http://fplanque.com/}.
   9   * Parts of this file are copyright (c)2004-2005 by Daniel HAHLER - {@link http://thequod.de/contact}.
  10   *
  11   * @license http://b2evolution.net/about/license.html GNU General Public License (GPL)
  12   *
  13   * {@internal Open Source relicensing agreement:
  14   * Daniel HAHLER grants Francois PLANQUE the right to license
  15   * Daniel HAHLER's contributions to this file and the b2evolution project
  16   * under any OSI approved OSS license (http://www.opensource.org/licenses/).
  17   * }}
  18   *
  19   * @package evocore
  20   *
  21   * {@internal Below is a list of authors who have contributed to design/coding of this file: }}
  22   * @author blueyed: Daniel HAHLER.
  23   * @author fplanque: Francois PLANQUE.
  24   *
  25   * @version $Id: _skin.funcs.php 6136 2014-03-08 07:59:48Z manuel $
  26   */
  27  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  28  
  29  
  30  // DEBUG: (Turn switch on or off to log debug info for specified category)
  31  $GLOBALS['debug_skins'] = true;
  32  
  33  
  34  /**
  35   * Template tag. Initializes internal states for the most common skin displays.
  36   *
  37   * For more specific skins, this function should not be called and
  38   * equivalent code should be customized within the skin.
  39   *
  40   * @param string What are we going to display. Most of the time the global $disp should be passed.
  41   */
  42  function skin_init( $disp )
  43  {
  44      /**
  45       * @var Blog
  46       */
  47      global $Blog;
  48  
  49      /**
  50       * @var Item
  51       */
  52      global $Item;
  53  
  54      /**
  55       * @var Skin
  56       */
  57      global $Skin;
  58  
  59      global $robots_index;
  60      global $seo_page_type;
  61  
  62      global $redir, $ReqURL, $ReqURI, $m, $w, $preview;
  63  
  64      global $Chapter;
  65      global $Debuglog;
  66  
  67      /**
  68       * @var ItemList2
  69       */
  70      global $MainList;
  71  
  72      /**
  73       * This will give more detail when $disp == 'posts'; otherwise it will have the same content as $disp
  74       * @var string
  75       */
  76      global $disp_detail, $Settings;
  77  
  78      global $Timer;
  79  
  80      global $Messages, $PageCache;
  81  
  82      $Timer->resume( 'skin_init' );
  83  
  84      if( empty($disp_detail) )
  85      {
  86          $disp_detail = $disp;
  87      }
  88  
  89      $Debuglog->add('skin_init: '.$disp, 'skins' );
  90  
  91      // This is the main template; it may be used to display very different things.
  92      // Do inits depending on current $disp:
  93      switch( $disp )
  94      {
  95          case 'posts':
  96          case 'single':
  97          case 'page':
  98          case 'feedback-popup':
  99          case 'search':
 100              // We need to load posts for this display:
 101  
 102              // Note: even if we request the same post as $Item above, the following will do more restrictions (dates, etc.)
 103              // Init the MainList object:
 104              init_MainList( $Blog->get_setting('posts_per_page') );
 105  
 106              // Init post navigation
 107              $post_navigation = $Skin->get_post_navigation();
 108              if( empty( $post_navigation ) )
 109              {
 110                  $post_navigation = $Blog->get_setting( 'post_navigation' );
 111              }
 112              break;
 113      }
 114  
 115      // SEO stuff & redirects if necessary:
 116      $seo_page_type = NULL;
 117      switch( $disp )
 118      {
 119          // CONTENT PAGES:
 120          case 'single':
 121          case 'page':
 122              if( ( ! $preview ) && ( empty( $Item ) ) )
 123              { // No Item, incorrect request and incorrect state of the application, a 404 redirect should have already happened
 124                  debug_die( 'Invalid page URL!' );
 125              }
 126  
 127              init_ajax_forms( 'blog' ); // auto requires jQuery
 128              init_ratings_js( 'blog' );
 129              init_voting_comment_js( 'blog' );
 130              init_scrollwide_js( 'blog' ); // Add jQuery Wide Scroll plugin
 131  
 132              if( $disp == 'single' )
 133              {
 134                  $seo_page_type = 'Single post page';
 135              }
 136              else
 137              {
 138                  $seo_page_type = '"Page" page';
 139              }
 140  
 141              // Check if the post has 'redirected' status:
 142              if( ! $preview && $Item->status == 'redirected' && $redir == 'yes' )
 143              {    // $redir=no here allows to force a 'single post' URL for commenting
 144                  // Redirect to the URL specified in the post:
 145                  $Debuglog->add( 'Redirecting to post URL ['.$Item->url.'].' );
 146                  header_redirect( $Item->url, true );
 147              }
 148  
 149              // Check if we want to redirect to a canonical URL for the post
 150              // Please document encountered problems.
 151              if( ! $preview
 152                      && (( $Blog->get_setting( 'canonical_item_urls' ) && $redir == 'yes' )
 153                                  || $Blog->get_setting( 'relcanonical_item_urls' ) ) )
 154              {    // We want to redirect to the Item's canonical URL:
 155  
 156                  $canonical_url = $Item->get_permanent_url( '', '', '&' );
 157                  if( preg_match( '|[&?](page=\d+)|', $ReqURI, $page_param ) )
 158                  {    // A certain post page has been requested, keep only this param and discard all others:
 159                      $canonical_url = url_add_param( $canonical_url, $page_param[1], '&' );
 160                  }
 161                  if( preg_match( '|[&?](mode=quote&[qcp]+=\d+)|', $ReqURI, $page_param ) )
 162                  {    // A quote of comment/post, keep only these params and discard all others:
 163                      $canonical_url = url_add_param( $canonical_url, $page_param[1], '&' );
 164                  }
 165  
 166                  if( ! is_same_url( $ReqURL, $canonical_url ) )
 167                  {    // The requested URL does not look like the canonical URL for this post...
 168                      // url difference was resolved
 169                      $url_resolved = false;
 170                      // Check if the difference is because of an allowed post navigation param
 171                      if( preg_match( '|[&?]cat=(\d+)|', $ReqURI, $cat_param ) )
 172                      { // A category post navigation param is set
 173                          $extended_url = '';
 174                          if( ( $post_navigation == 'same_category' ) && ( isset( $cat_param[1] ) ) )
 175                          { // navigatie through posts from the same category
 176                              $category_ids = postcats_get_byID( $Item->ID );
 177                              if( in_array($cat_param[1], $category_ids ) )
 178                              { // cat param is one of this Item categories
 179                                  $extended_url = $Item->add_navigation_param( $canonical_url, $post_navigation, $cat_param[1], '&' );
 180                                  // Set MainList navigation target to the requested category
 181                                  $MainList->nav_target = $cat_param[1];
 182                              }
 183                          }
 184                          $url_resolved = is_same_url( $ReqURL, $extended_url );
 185                      }
 186  
 187                      if( !$url_resolved && $Blog->get_setting( 'canonical_item_urls' ) && $redir == 'yes' && ( ! $Item->check_cross_post_nav( 'auto', $Blog->ID ) ) )
 188                      {    // REDIRECT TO THE CANONICAL URL:
 189                          $Debuglog->add( 'Redirecting to canonical URL ['.$canonical_url.'].' );
 190                          header_redirect( $canonical_url, true );
 191                      }
 192                      else
 193                      {    // Use rel="canoncial":
 194                          add_headline( '<link rel="canonical" href="'.$canonical_url.'" />' );
 195                      }
 196                      // EXITED.
 197                  }
 198              }
 199  
 200              if( ! $MainList->result_num_rows )
 201              {    // There is nothing to display for this page, don't index it!
 202                  $robots_index = false;
 203              }
 204              break;
 205  
 206          case 'posts':
 207              init_ajax_forms( 'blog' ); // auto requires jQuery
 208              init_scrollwide_js( 'blog' ); // Add jQuery Wide Scroll plugin
 209              // fp> if we add this here, we have to exetnd the inner if()
 210              // init_ratings_js( 'blog' );
 211  
 212              // Get list of active filters:
 213              $active_filters = $MainList->get_active_filters();
 214  
 215              if( !empty($active_filters) )
 216              {    // The current page is being filtered...
 217  
 218                  if( array_diff( $active_filters, array( 'page' ) ) == array() )
 219                  { // This is just a follow "paged" page
 220                      $disp_detail = 'posts-next';
 221                      $seo_page_type = 'Next page';
 222                      if( $Blog->get_setting( 'paged_noindex' ) )
 223                      {    // We prefer robots not to index category pages:
 224                          $robots_index = false;
 225                      }
 226                  }
 227                  elseif( array_diff( $active_filters, array( 'cat_array', 'cat_modifier', 'cat_focus', 'posts', 'page' ) ) == array() )
 228                  { // This is a category page
 229                      $disp_detail = 'posts-cat';
 230                      $seo_page_type = 'Category page';
 231                      if( $Blog->get_setting( 'chapter_noindex' ) )
 232                      {    // We prefer robots not to index category pages:
 233                          $robots_index = false;
 234                      }
 235  
 236                      global $cat, $catsel;
 237                      if( empty( $catsel ) && preg_match( '~^[0-9]+$~', $cat ) )
 238                      {    // We are on a single cat page:
 239                          // NOTE: we must have selected EXACTLY ONE CATEGORY through the cat parameter
 240                          // BUT: - this can resolve to including children
 241                          //      - selecting exactly one cat through catsel[] is NOT OK since not equivalent (will exclude children)
 242                          // echo 'SINGLE CAT PAGE';
 243                          if( ( $Blog->get_setting( 'canonical_cat_urls' ) && $redir == 'yes' )
 244                              || $Blog->get_setting( 'relcanonical_cat_urls' ) )
 245                          { // Check if the URL was canonical:
 246                              if( !isset( $Chapter ) )
 247                              {
 248                                  $ChapterCache = & get_ChapterCache();
 249                                  /**
 250                                   * @var Chapter
 251                                   */
 252                                  $Chapter = & $ChapterCache->get_by_ID( $MainList->filters['cat_array'][0], false );
 253                              }
 254  
 255                              if( $Chapter )
 256                              {
 257                                  if( $Chapter->parent_ID )
 258                                  {    // This is a sub-category page (i-e: not a level 1 category)
 259                                      $disp_detail = 'posts-subcat';
 260                                  }
 261  
 262                                  $canonical_url = $Chapter->get_permanent_url( NULL, NULL, $MainList->get_active_filter('page'), NULL, '&' );
 263                                  if( ! is_same_url($ReqURL, $canonical_url) )
 264                                  {    // fp> TODO: we're going to lose the additional params, it would be better to keep them...
 265                                      // fp> what additional params actually?
 266                                      if( $Blog->get_setting( 'canonical_cat_urls' ) && $redir == 'yes' )
 267                                      {    // REDIRECT TO THE CANONICAL URL:
 268                                          header_redirect( $canonical_url, true );
 269                                      }
 270                                      else
 271                                      {    // Use rel="canonical":
 272                                          add_headline( '<link rel="canonical" href="'.$canonical_url.'" />' );
 273                                      }
 274                                  }
 275                              }
 276                          }
 277  
 278                          if( $post_navigation == 'same_category' )
 279                          { // Category is set and post navigation should go through the same category, set navigation target param
 280                              $MainList->nav_target = $cat;
 281                          }
 282                      }
 283                  }
 284                  elseif( array_diff( $active_filters, array( 'tags', 'posts', 'page' ) ) == array() )
 285                  { // This is a tag page
 286                      $disp_detail = 'posts-tag';
 287                      $seo_page_type = 'Tag page';
 288                      if( $Blog->get_setting( 'tag_noindex' ) )
 289                      {    // We prefer robots not to index tag pages:
 290                          $robots_index = false;
 291                      }
 292  
 293                      if( ( $Blog->get_setting( 'canonical_tag_urls' ) && $redir == 'yes' )
 294                              || $Blog->get_setting( 'relcanonical_tag_urls' ) )
 295                      { // Check if the URL was canonical:
 296                          $canonical_url = $Blog->gen_tag_url( $MainList->get_active_filter('tags'), $MainList->get_active_filter('page'), '&' );
 297                          if( ! is_same_url($ReqURL, $canonical_url) )
 298                          {
 299                              if( $Blog->get_setting( 'canonical_tag_urls' ) && $redir == 'yes' )
 300                              {    // REDIRECT TO THE CANONICAL URL:
 301                                  header_redirect( $canonical_url, true );
 302                              }
 303                              else
 304                              {    // Use rel="canoncial":
 305                                  add_headline( '<link rel="canonical" href="'.$canonical_url.'" />' );
 306                              }
 307                          }
 308                      }
 309                  }
 310                  elseif( array_diff( $active_filters, array( 'ymdhms', 'week', 'posts', 'page' ) ) == array() ) // fp> added 'posts' 2009-05-19; can't remember why it's not in there
 311                  { // This is an archive page
 312                      // echo 'archive page';
 313                      $disp_detail = 'posts-date';
 314                      $seo_page_type = 'Date archive page';
 315  
 316                      if( ($Blog->get_setting( 'canonical_archive_urls' ) && $redir == 'yes' )
 317                              || $Blog->get_setting( 'relcanonical_archive_urls' ) )
 318                      { // Check if the URL was canonical:
 319                          $canonical_url =  $Blog->gen_archive_url( substr( $m, 0, 4 ), substr( $m, 4, 2 ), substr( $m, 6, 2 ), $w, '&', $MainList->get_active_filter('page') );
 320                          if( ! is_same_url($ReqURL, $canonical_url) )
 321                          {
 322                              if( $Blog->get_setting( 'canonical_archive_urls' ) && $redir == 'yes' )
 323                              {    // REDIRECT TO THE CANONICAL URL:
 324                                  header_redirect( $canonical_url, true );
 325                              }
 326                              else
 327                              {    // Use rel="canoncial":
 328                                  add_headline( '<link rel="canonical" href="'.$canonical_url.'" />' );
 329                              }
 330                          }
 331                      }
 332  
 333                      if( $Blog->get_setting( 'archive_noindex' ) )
 334                      {    // We prefer robots not to index archive pages:
 335                          $robots_index = false;
 336                      }
 337                  }
 338                  else
 339                  {    // Other filtered pages:
 340                      // pre_dump( $active_filters );
 341                      $disp_detail = 'posts-filtered';
 342                      $seo_page_type = 'Other filtered page';
 343                      if( $Blog->get_setting( 'filtered_noindex' ) )
 344                      {    // We prefer robots not to index other filtered pages:
 345                          $robots_index = false;
 346                      }
 347                  }
 348              }
 349              else
 350              {    // This is the default blog page
 351                  $disp_detail = 'posts-default';
 352                  $seo_page_type = 'Default page';
 353                  if( ($Blog->get_setting( 'canonical_homepage' ) && $redir == 'yes' )
 354                          || $Blog->get_setting( 'relcanonical_homepage' ) )
 355                  { // Check if the URL was canonical:
 356                      $canonical_url = $Blog->gen_blogurl();
 357                      if( ! is_same_url($ReqURL, $canonical_url) )
 358                      {
 359                          if( $Blog->get_setting( 'canonical_homepage' ) && $redir == 'yes' )
 360                          {    // REDIRECT TO THE CANONICAL URL:
 361                              header_redirect( $canonical_url, true );
 362                          }
 363                          else
 364                          {    // Use rel="canoncial":
 365                              add_headline( '<link rel="canonical" href="'.$canonical_url.'" />' );
 366                          }
 367                      }
 368                  }
 369  
 370                  if( $Blog->get_setting( 'default_noindex' ) )
 371                  {    // We prefer robots not to index archive pages:
 372                      $robots_index = false;
 373                  }
 374              }
 375  
 376              break;
 377  
 378          case 'search':
 379              $seo_page_type = 'Search page';
 380              if( $Blog->get_setting( 'filtered_noindex' ) )
 381              {    // We prefer robots not to index these pages:
 382                  $robots_index = false;
 383              }
 384              break;
 385  
 386          // SPECIAL FEATURE PAGES:
 387          case 'feedback-popup':
 388              $seo_page_type = 'Comment popup';
 389              if( $Blog->get_setting( $disp.'_noindex' ) )
 390              {    // We prefer robots not to index these pages:
 391                  $robots_index = false;
 392              }
 393              break;
 394  
 395          case 'arcdir':
 396              $seo_page_type = 'Date archive directory';
 397              if( $Blog->get_setting( $disp.'_noindex' ) )
 398              {    // We prefer robots not to index these pages:
 399                  $robots_index = false;
 400              }
 401              break;
 402  
 403          case 'catdir':
 404              $seo_page_type = 'Category directory';
 405              if( $Blog->get_setting( $disp.'_noindex' ) )
 406              {    // We prefer robots not to index these pages:
 407                  $robots_index = false;
 408              }
 409              break;
 410  
 411          case 'msgform':
 412              init_ajax_forms( 'blog' ); // auto requires jQuery
 413  
 414              $seo_page_type = 'Contact form';
 415              if( $Blog->get_setting( $disp.'_noindex' ) )
 416              {    // We prefer robots not to index these pages:
 417                  $robots_index = false;
 418              }
 419              break;
 420  
 421          case 'messages':
 422          case 'contacts':
 423          case 'threads':
 424              init_results_js( 'blog' ); // Add functions to work with Results tables
 425              // just in case some robot would be logged in:
 426              $seo_page_type = 'Messaging module';
 427              $robots_index = false;
 428              break;
 429  
 430          case 'login':
 431              global $Plugins, $transmit_hashed_password;
 432  
 433              $seo_page_type = 'Login form';
 434              $robots_index = false;
 435              require_js( 'functions.js', 'blog' );
 436  
 437              $transmit_hashed_password = (bool)$Settings->get('js_passwd_hashing') && !(bool)$Plugins->trigger_event_first_true('LoginAttemptNeedsRawPassword');
 438              if( $transmit_hashed_password )
 439              { // Include JS for client-side password hashing:
 440                  require_js( 'sha1_md5.js', 'blog' );
 441              }
 442              break;
 443  
 444          case 'register':
 445              if( is_logged_in() )
 446              { // If user is logged in the register form should not be displayed. In this case redirect to the blog home page.
 447                  $Messages->add( T_( 'You are already logged in.' ), 'note' );
 448                  header_redirect( $Blog->gen_blogurl(), false );
 449              }
 450              $seo_page_type = 'Register form';
 451              $robots_index = false;
 452              break;
 453  
 454          case 'lostpassword':
 455              if( is_logged_in() )
 456              { // If user is logged in the lost password form should not be displayed. In this case redirect to the blog home page.
 457                  $Messages->add( T_( 'You are already logged in.' ), 'note' );
 458                  header_redirect( $Blog->gen_blogurl(), false );
 459              }
 460              $seo_page_type = 'Lost password form';
 461              $robots_index = false;
 462              break;
 463  
 464          case 'profile':
 465              global $rsc_url;
 466              require_css( $rsc_url.'css/jquery/smoothness/jquery-ui.css' );
 467              init_userfields_js( 'blog' );
 468          case 'avatar':
 469          case 'pwdchange':
 470          case 'userprefs':
 471          case 'subs':
 472              $seo_page_type = 'Special feature page';
 473              if( $Blog->get_setting( 'special_noindex' ) )
 474              {    // We prefer robots not to index these pages:
 475                  $robots_index = false;
 476              }
 477              break;
 478  
 479          case 'users':
 480              $seo_page_type = 'Users list';
 481              $robots_index = false;
 482              global $rsc_url;
 483              require_css( $rsc_url.'css/jquery/smoothness/jquery-ui.css' );
 484              init_results_js( 'blog' ); // Add functions to work with Results tables
 485              break;
 486  
 487          case 'user':
 488              $seo_page_type = 'User display';
 489              if( is_logged_in() )
 490              {    // Used for combo_box contacts groups
 491                  require_js( 'form_extensions.js', 'blog' );
 492              }
 493              break;
 494  
 495          case 'edit':
 496              init_datepicker_js( 'blog' );
 497              require_js( 'admin.js', 'blog' );
 498              init_inskin_editing( 'blog' );
 499              init_plugins_js( 'blog' );
 500              break;
 501  
 502          case 'edit_comment':
 503              init_plugins_js( 'blog' );
 504              break;
 505  
 506          case 'useritems':
 507          case 'usercomments':
 508              global $inc_path, $display_params, $viewed_User;
 509  
 510              // get user_ID because we want it in redirect_to in case we need to ask for login.
 511              $user_ID = param( 'user_ID', 'integer', true, true );
 512              if( empty( $user_ID ) )
 513              {
 514                  bad_request_die( sprintf( T_('Parameter &laquo;%s&raquo; is required!'), 'user_ID' ) );
 515              }
 516              // set where to redirect in case of error
 517              $error_redirect_to = empty( $Blog ) ? $baseurl : $Blog->gen_blogurl();
 518  
 519              if( !is_logged_in() )
 520              { // Redirect to the login page if not logged in and allow anonymous user setting is OFF
 521                  $Messages->add( T_('You must log in to view this user profile.') );
 522                  header_redirect( get_login_url( 'cannot see user' ), 302 );
 523                  // will have exited
 524              }
 525  
 526              if( is_logged_in() && ( !check_user_status( 'can_view_user', $user_ID ) ) )
 527              { // user is logged in, but his/her status doesn't permit to view user profile
 528                  if( check_user_status( 'can_be_validated' ) )
 529                  { // user is logged in but his/her account is not active yet
 530                      // Redirect to the account activation page
 531                      $Messages->add( T_('You must activate your account before you can view this user profile. <b>See below:</b>') );
 532                      header_redirect( get_activate_info_url(), 302 );
 533                      // will have exited
 534                  }
 535  
 536                  $Messages->add( T_('Your account status currently does not permit to view this user profile.') );
 537                  header_redirect( $error_redirect_to, 302 );
 538                  // will have exited
 539              }
 540  
 541              if( !empty( $user_ID ) )
 542              {
 543                  $UserCache = & get_UserCache();
 544                  $viewed_User = $UserCache->get_by_ID( $user_ID, false );
 545  
 546                  if( empty( $viewed_User ) )
 547                  {
 548                      $Messages->add( T_('The requested user does not exist!') );
 549                      header_redirect( $error_redirect_to );
 550                      // will have exited
 551                  }
 552  
 553                  if( $viewed_User->check_status( 'is_closed' ) )
 554                  {
 555                      $Messages->add( T_('The requested user account is closed!') );
 556                      header_redirect( $error_redirect_to );
 557                      // will have exited
 558                  }
 559              }
 560  
 561              // Require results.css to display thread query results in a table
 562              require_css( 'results.css' ); // Results/tables styles
 563  
 564              // Require functions.js to show/hide a panel with filters
 565              require_js( 'functions.js', 'blog' );
 566              // Include this file to expand/collapse the filters panel when JavaScript is disabled
 567              require_once $inc_path.'_filters.inc.php';
 568  
 569              $display_params = !empty( $Skin ) ? $Skin->get_template( 'Results' ) : NULL;
 570  
 571              if( $disp == 'useritems' )
 572              { // Init items list
 573                  global $user_ItemList;
 574  
 575                  $param_prefix = 'useritems_';
 576                  $page = param( $param_prefix.'paged', 'integer', 1 );
 577                  $orderby = param( $param_prefix.'orderby', 'string', $Blog->get_setting('orderby') );
 578                  $order = param( $param_prefix.'order', 'string', $Blog->get_setting('orderdir') );
 579                  $useritems_Blog = NULL;
 580                  $user_ItemList = new ItemList2( $useritems_Blog, NULL, NULL, NULL, 'ItemCache', $param_prefix );
 581                  $user_ItemList->load_from_Request();
 582                  $user_ItemList->set_filters( array(
 583                          'page'          => $page,
 584                          'authors'       => $user_ID,
 585                          'orderby'       => str_replace( $param_prefix, '', $orderby ),
 586                          'order'         => str_replace( $param_prefix, '', $order ),
 587                      ) );
 588                  $user_ItemList->query();
 589              }
 590              else // $disp == 'usercomments'
 591              { // Init comments list
 592                  global $user_CommentList;
 593  
 594                  $param_prefix = 'usercmts_';
 595                  $page = param( $param_prefix.'paged', 'integer', 1 );
 596                  $orderby = param( $param_prefix.'orderby', 'string', 'date' );
 597                  $order = param( $param_prefix.'order', 'string', $Blog->get_setting('orderdir') );
 598  
 599                  $user_CommentList = new CommentList2( NULL, NULL, 'CommentCache', $param_prefix );
 600                  $user_CommentList->load_from_Request();
 601                  $user_CommentList->set_filters( array(
 602                          'page'          => $page,
 603                          'author_IDs'    => $user_ID,
 604                          'orderby'       => str_replace( $param_prefix, '', $orderby ),
 605                          'order'         => str_replace( $param_prefix, '', $order ),
 606                      ) );
 607                  $user_CommentList->query();
 608              }
 609              break;
 610  
 611          case 'comments':
 612              if( !$Blog->get_setting( 'comments_latest' ) )
 613              { // If latest comments page is disabled - Display 404 page with error message
 614                  $Messages->add( T_('This feature is disabled.'), 'error' );
 615                  global $disp;
 616                  $disp = '404';
 617              }
 618              else
 619              {
 620                  break;
 621              }
 622  
 623          case '404':
 624              // We have a 404 unresolved content error
 625              // How do we want do deal with it?
 626              skin_404_header();
 627              // This MAY or MAY not have exited -- will exit on 30x redirect, otherwise will return here.
 628              // Just in case some dumb robot needs extra directives on this:
 629              $robots_index = false;
 630              break;
 631      }
 632  
 633      if( !empty( $_SERVER['HTTP_USER_AGENT'] ) )
 634      {    // Detect IE browser version
 635          preg_match( '/msie (\d+)/i', $_SERVER['HTTP_USER_AGENT'], $browser_ie );
 636          if( count( $browser_ie ) == 2 && $browser_ie[1] < 7 )
 637          {    // IE < 7
 638              require_css( 'ie6.css', 'relative' );
 639              $Messages->add( T_('Your web browser is too old. For this site to work correctly, we recommend you use a more recent browser.'), 'note' );
 640          }
 641      }
 642  
 643      // dummy var for backward compatibility with versions < 2.4.1 -- prevents "Undefined variable"
 644      global $global_Cache, $credit_links;
 645      $credit_links = $global_Cache->get( 'creds' );
 646  
 647      $Timer->pause( 'skin_init' );
 648  
 649      // Check if user is logged in with a not active account, and display an error message if required
 650      check_allow_disp( $disp );
 651  
 652      // initialize Blog enabled widgets, before displaying anything
 653      init_blog_widgets( $Blog->ID );
 654  
 655      // Initialize displaying....
 656      $Timer->start( 'Skin:display_init' );
 657      $Skin->display_init();
 658      $Timer->pause( 'Skin:display_init' );
 659  
 660      // Send default headers:
 661      // See comments inside of this function:
 662      headers_content_mightcache( 'text/html' );        // In most situations, you do NOT want to cache dynamic content!
 663      // Never allow Messages to be cached!
 664      if( $Messages->count() && ( !empty( $PageCache ) ) )
 665      { // Abort PageCache collect
 666          $PageCache->abort_collect();
 667      }
 668  }
 669  
 670  
 671  /**
 672   * Initialize skin for AJAX request
 673   *
 674   * @param string Skin name
 675   * @param string What are we going to display. Most of the time the global $disp should be passed.
 676   */
 677  function skin_init_ajax( $skin_name, $disp )
 678  {
 679      if( is_ajax_content() )
 680      {    // AJAX request
 681          if( empty( $skin_name ) )
 682          {    // Don't initialize without skin name
 683              return false;
 684          }
 685  
 686          global $ads_current_skin_path, $skins_path;
 687  
 688          // Init path for current skin
 689          $ads_current_skin_path = $skins_path.$skin_name.'/';
 690  
 691          // This is the main template; it may be used to display very different things.
 692          // Do inits depending on current $disp:
 693          skin_init( $disp );
 694      }
 695  
 696      return true;
 697  }
 698  
 699  
 700  /**
 701   * Tells if we are on the default blog page
 702   *
 703   * @return boolean
 704   */
 705  function is_default_page()
 706  {
 707      global $disp_detail;
 708      return ($disp_detail == 'posts-default' );
 709  }
 710  
 711  
 712  /**
 713   * Template tag. Include a sub-template at the current position
 714   *
 715   */
 716  function skin_include( $template_name, $params = array() )
 717  {
 718      if( is_ajax_content( $template_name ) )
 719      {    // When we request ajax content for results table we need to hide wrapper data (header, footer & etc)
 720          return;
 721      }
 722  
 723      global $skins_path, $ads_current_skin_path, $disp;
 724  
 725      // Globals that may be needed by the template:
 726      global $Blog, $MainList, $Item;
 727      global $Plugins, $Skin;
 728      global $current_User, $Hit, $Session, $Settings;
 729      global $skin_url, $htsrv_url, $htsrv_url_sensitive;
 730      global $samedomain_htsrv_url, $secure_htsrv_url;
 731      global $credit_links, $skin_links, $francois_links, $fplanque_links, $skinfaktory_links;
 732      /**
 733      * @var Log
 734      */
 735      global $Debuglog;
 736      global $Timer;
 737  
 738      $timer_name = 'skin_include('.$template_name.')';
 739      $Timer->resume( $timer_name );
 740  
 741      if( $template_name == '$disp$' )
 742      { // This is a special case.
 743          // We are going to include a template based on $disp:
 744  
 745          // Default display handlers:
 746          $disp_handlers = array(
 747                  'disp_404'            => '_404_not_found.disp.php',
 748                  'disp_arcdir'         => '_arcdir.disp.php',
 749                  'disp_catdir'         => '_catdir.disp.php',
 750                  'disp_comments'       => '_comments.disp.php',
 751                  'disp_feedback-popup' => '_feedback_popup.disp.php',
 752                  'disp_help'           => '_help.disp.php',
 753                  'disp_login'          => '_login.disp.php',
 754                  'disp_register'       => '_register.disp.php',
 755                  'disp_activateinfo'   => '_activateinfo.disp.php',
 756                  'disp_lostpassword'   => '_lostpassword.disp.php',
 757                  'disp_mediaidx'       => '_mediaidx.disp.php',
 758                  'disp_msgform'        => '_msgform.disp.php',
 759                  'disp_threads'        => '_threads.disp.php',
 760                  'disp_contacts'       => '_threads.disp.php',
 761                  'disp_messages'       => '_messages.disp.php',
 762                  'disp_page'           => '_page.disp.php',
 763                  'disp_postidx'        => '_postidx.disp.php',
 764                  'disp_posts'          => '_posts.disp.php',
 765                  'disp_profile'        => '_profile.disp.php',
 766                  'disp_avatar'         => '_profile.disp.php',
 767                  'disp_pwdchange'      => '_profile.disp.php',
 768                  'disp_userprefs'      => '_profile.disp.php',
 769                  'disp_subs'           => '_profile.disp.php',
 770                  'disp_search'         => '_search.disp.php',
 771                  'disp_single'         => '_single.disp.php',
 772                  'disp_sitemap'        => '_sitemap.disp.php',
 773                  'disp_user'           => '_user.disp.php',
 774                  'disp_users'          => '_users.disp.php',
 775                  'disp_edit'           => '_edit.disp.php',
 776                  'disp_edit_comment'   => '_edit_comment.disp.php',
 777                  'disp_closeaccount'   => '_closeaccount.disp.php',
 778                  'disp_module_form'    => '_module_form.disp.php',
 779                  'disp_useritems'      => '_useritems.disp.php',
 780                  'disp_usercomments'   => '_usercomments.disp.php',
 781              );
 782  
 783          // Add plugin disp handlers:
 784          if( $disp_Plugins = $Plugins->get_list_by_event( 'GetHandledDispModes' ) )
 785          {
 786              foreach( $disp_Plugins as $disp_Plugin )
 787              { // Go through whole list of plugins providing disps
 788                  if( $plugin_modes = $Plugins->call_method( $disp_Plugin->ID, 'GetHandledDispModes', $disp_handlers ) )
 789                  { // plugin handles some custom disp modes
 790                      foreach( $plugin_modes as $plugin_mode )
 791                      {
 792                          $disp_handlers[$plugin_mode] = '#'.$disp_Plugin->ID;
 793                      }
 794                  }
 795              }
 796          }
 797  
 798          // Allow skin overrides as well as additional disp modes (This can be used in the famou shopping cart scenario...)
 799          $disp_handlers = array_merge( $disp_handlers, $params );
 800  
 801          if( !isset( $disp_handlers['disp_'.$disp] ) )
 802          {
 803              global $Messages;
 804              $Messages->add( sprintf( 'Unhandled disp type [%s]', htmlspecialchars( $disp ) ) );
 805              $Messages->display();
 806              $Timer->pause( $timer_name );
 807              $disp = '404';
 808          }
 809  
 810          $template_name = $disp_handlers['disp_'.$disp];
 811  
 812          if( empty( $template_name ) )
 813          {    // The caller asked not to display this handler
 814              $Timer->pause( $timer_name );
 815              return;
 816          }
 817  
 818      }
 819  
 820      $disp_handled = false;
 821  
 822      if( $template_name[0] == '#' )
 823      {    // This disp mode is handled by a plugin:
 824          $plug_ID = substr( $template_name, 1 );
 825          $disp_params = array( 'disp' => $disp );
 826          $Plugins->call_method( $plug_ID, 'HandleDispMode', $disp_params );
 827          $disp_handled = true;
 828      }
 829  
 830      elseif( file_exists( $ads_current_skin_path.$template_name ) )
 831      {    // The skin has a customized handler, use that one instead:
 832  
 833          $file = $ads_current_skin_path.$template_name;
 834          $Debuglog->add('skin_include ('.($Item ? 'Item #'.$Item->ID : '-').'): '.rel_path_to_base($file), 'skins');
 835          require $file;
 836          $disp_handled = true;
 837      }
 838  
 839      elseif( file_exists( $skins_path.$template_name ) )
 840      {    // Use the default template:
 841          global $Debuglog;
 842          $file = $skins_path.$template_name;
 843          $Debuglog->add('skin_include ('.($Item ? 'Item #'.$Item->ID : '-').'): '.rel_path_to_base($file), 'skins');
 844          require $file;
 845          $disp_handled = true;
 846      }
 847  
 848      if( ! $disp_handled )
 849      { // nothing handled the disp mode
 850          printf( '<div class="skin_error">Sub template [%s] not found.</div>', $template_name );
 851          if( !empty($current_User) && $current_User->level == 10 )
 852          {
 853              printf( '<div class="skin_error">User level 10 help info: [%s]</div>', $ads_current_skin_path.$template_name );
 854          }
 855      }
 856  
 857      $Timer->pause( $timer_name );
 858  }
 859  
 860  
 861  /**
 862   * Template tag. Output HTML base tag to current skin.
 863   *
 864   * This is needed for relative css and img includes.
 865   */
 866  function skin_base_tag()
 867  {
 868      global $skins_url, $skin, $Blog, $disp;
 869  
 870      if( ! empty( $Blog ) )
 871      {    // We are displaying a blog:
 872          if( ! empty( $skin ) )
 873          {    // We are using a skin:
 874              $base_href = $Blog->get_local_skins_url().$skin.'/';
 875          }
 876          else
 877          { // No skin used:
 878              $base_href = $Blog->gen_baseurl();
 879          }
 880      }
 881      else
 882      {    // We are displaying a general page that is not specific to a blog:
 883          global $baseurl;
 884          $base_href = $baseurl;
 885      }
 886  
 887      $target = NULL;
 888      if( !empty($disp) && strpos( $disp, '-popup' ) )
 889      {    // We are (normally) displaying in a popup window, we need most links to open a new window!
 890          $target = '_blank';
 891      }
 892  
 893      base_tag( $base_href, $target );
 894  }
 895  
 896  
 897  /**
 898   * Template tag
 899   *
 900   * Note for future mods: we do NOT want to repeat identical content on multiple pages.
 901   */
 902  function skin_description_tag()
 903  {
 904      global $Blog, $disp, $disp_detail, $MainList, $Chapter;
 905  
 906      $r = '';
 907  
 908      if( is_default_page() )
 909      {
 910          if( ! empty( $Blog ) )
 911          {    // Description for the blog:
 912              $r = $Blog->get( 'shortdesc' );
 913          }
 914      }
 915      elseif( $disp_detail == 'posts-cat' || $disp_detail == 'posts-subcat' )
 916      {
 917          if( $Blog->get_setting( 'categories_meta_description' ) && ( ! empty( $Chapter ) ) )
 918          {
 919              $r = $Chapter->get( 'description' );
 920          }
 921      }
 922      elseif( in_array( $disp, array( 'single', 'page' ) ) )
 923      {    // custom desc for the current single post:
 924          $Item = & $MainList->get_by_idx( 0 );
 925          if( is_null( $Item ) )
 926          {    // This is not an object (happens on an invalid request):
 927              return;
 928          }
 929  
 930          $r = $Item->get_metadesc();
 931  
 932          if( empty( $r )&& $Blog->get_setting( 'excerpts_meta_description' ) )
 933          {    // Fall back to excerpt for the current single post:
 934              // Replace line breaks with single space
 935              $r = preg_replace( '|[\r\n]+|', ' ', $Item->get('excerpt') );
 936          }
 937      }
 938  
 939      if( !empty($r) )
 940      {
 941          echo '<meta name="description" content="'.format_to_output( $r, 'htmlattr' )."\" />\n";
 942      }
 943  }
 944  
 945  
 946  /**
 947   * Template tag
 948   *
 949   * Note for future mods: we do NOT want to repeat identical content on multiple pages.
 950   */
 951  function skin_keywords_tag()
 952  {
 953      global $Blog, $disp, $MainList;
 954  
 955      $r = '';
 956  
 957      if( is_default_page() )
 958      {
 959          if( !empty($Blog) )
 960          {
 961              $r = $Blog->get('keywords');
 962          }
 963      }
 964      elseif( in_array( $disp, array( 'single', 'page' ) ) )
 965      {    // custom keywords for the current single post:
 966          $Item = & $MainList->get_by_idx( 0 );
 967          if( is_null( $Item ) )
 968          {    // This is not an object (happens on an invalid request):
 969              return;
 970          }
 971  
 972          $r = $Item->get_custom_headers();
 973  
 974  
 975          if( empty( $r ) && $Blog->get_setting( 'tags_meta_keywords' ) )
 976          {    // Fall back to tags for the current single post:
 977              $r = implode( ', ', $Item->get_tags() );
 978          }
 979  
 980      }
 981  
 982      if( !empty($r) )
 983      {
 984          echo '<meta name="keywords" content="'.format_to_output( $r, 'htmlattr' )."\" />\n";
 985      }
 986  }
 987  
 988  
 989  /**
 990   * Sends the desired HTTP response header in case of a "404".
 991   */
 992  function skin_404_header()
 993  {
 994      global $Blog;
 995  
 996      // We have a 404 unresolved content error
 997      // How do we want do deal with it?
 998      switch( $resp_code = $Blog->get_setting( '404_response' ) )
 999      {
1000          case '404':
1001              header_http_response('404 Not Found');
1002              break;
1003  
1004          case '410':
1005              header_http_response('410 Gone');
1006              break;
1007  
1008          case '301':
1009          case '302':
1010          case '303':
1011              // Redirect to home page:
1012              header_redirect( $Blog->get('url'), intval($resp_code) );
1013              // THIS WILL EXIT!
1014              break;
1015  
1016          default:
1017              // Will result in a 200 OK
1018      }
1019  }
1020  
1021  
1022  /**
1023   * Template tag. Output content-type header
1024   * For backward compatibility
1025   *
1026   * @see skin_content_meta()
1027   *
1028   * @param string content-type; override for RSS feeds
1029   */
1030  function skin_content_header( $type = 'text/html' )
1031  {
1032      header_content_type( $type );
1033  }
1034  
1035  
1036  /**
1037   * Template tag. Output content-type http_equiv meta tag
1038   *
1039   * @see skin_content_header()
1040   *
1041   * @param string content-type; override for RSS feeds
1042   */
1043  function skin_content_meta( $type = 'text/html' )
1044  {
1045      global $io_charset;
1046  
1047      echo '<meta http-equiv="Content-Type" content="'.$type.'; charset='.$io_charset.'" />'."\n";
1048  }
1049  
1050  
1051  /**
1052   * Template tag. Display a Widget.
1053   *
1054   * This load the widget class, instantiates it, and displays it.
1055   *
1056   * @param array
1057   */
1058  function skin_widget( $params )
1059  {
1060      global $inc_path;
1061  
1062      if( empty( $params['widget'] ) )
1063      {
1064          echo 'No widget code provided!';
1065          return false;
1066      }
1067  
1068      $widget_code = $params['widget'];
1069      unset( $params['widget'] );
1070  
1071      if( ! file_exists( $inc_path.'widgets/widgets/_'.$widget_code.'.widget.php' ) )
1072      {    // For some reason, that widget doesn't seem to exist... (any more?)
1073          echo "Invalid widget code provided [$widget_code]!";
1074          return false;
1075      }
1076      require_once $inc_path.'widgets/widgets/_'.$widget_code.'.widget.php';
1077  
1078      $widget_classname = $widget_code.'_Widget';
1079  
1080      /**
1081       * @var ComponentWidget
1082       */
1083      $Widget = new $widget_classname();    // COPY !!
1084  
1085      return $Widget->display( $params );
1086  }
1087  
1088  
1089  /**
1090   * Display a container
1091   *
1092   * @param string
1093   * @param array
1094   */
1095  function skin_container( $sco_name, $params = array() )
1096  {
1097      global $Skin;
1098  
1099      $Skin->container( $sco_name, $params );
1100  }
1101  
1102  
1103  /**
1104   * Install a skin
1105   *
1106   * @todo do not install if skin doesn't exist. Important for upgrade. Need to NOT fail if ZERO skins installed though :/
1107   *
1108   * @param string Skin folder
1109   * @return Skin
1110   */
1111  function & skin_install( $skin_folder )
1112  {
1113      $SkinCache = & get_SkinCache();
1114      $Skin = & $SkinCache->new_obj( NULL, $skin_folder );
1115  
1116      $Skin->install();
1117  
1118      return $Skin;
1119  }
1120  
1121  
1122  /**
1123   * Checks if a skin is provided by a plugin.
1124   *
1125   * Used by front-end.
1126   *
1127   * @uses Plugin::GetProvidedSkins()
1128   * @return false|integer False in case no plugin provides the skin or ID of the first plugin that provides it.
1129   */
1130  function skin_provided_by_plugin( $name )
1131  {
1132      static $plugin_skins;
1133      if( ! isset($plugin_skins) || ! isset($plugin_skins[$name]) )
1134      {
1135          global $Plugins;
1136  
1137          $plugin_r = $Plugins->trigger_event_first_return('GetProvidedSkins', NULL, array('in_array'=>$name));
1138          if( $plugin_r )
1139          {
1140              $plugin_skins[$name] = $plugin_r['plugin_ID'];
1141          }
1142          else
1143          {
1144              $plugin_skins[$name] = false;
1145          }
1146      }
1147  
1148      return $plugin_skins[$name];
1149  }
1150  
1151  
1152  /**
1153   * Checks if a skin exists. This can either be a regular skin directory
1154   * or can be in the list {@link Plugin::GetProvidedSkins()}.
1155   *
1156   * Used by front-end.
1157   *
1158   * @param skin name (directory name)
1159   * @return boolean true is exists, false if not
1160   */
1161  function skin_exists( $name, $filename = 'index.main.php' )
1162  {
1163      global $skins_path;
1164  
1165      if( skin_file_exists( $name, $filename ) )
1166      {
1167          return true;
1168      }
1169  
1170      // Check list provided by plugins:
1171      if( skin_provided_by_plugin($name) )
1172      {
1173          return true;
1174      }
1175  
1176      return false;
1177  }
1178  
1179  
1180  /**
1181   * Checks if a specific file exists for a skin.
1182   *
1183   * @param skin name (directory name)
1184   * @param file name
1185   * @return boolean true is exists, false if not
1186   */
1187  function skin_file_exists( $name, $filename = 'index.main.php' )
1188  {
1189      global $skins_path;
1190  
1191      if( is_readable( $skins_path.$name.'/'.$filename ) )
1192      {
1193          return true;
1194      }
1195  
1196      return false;
1197  }
1198  
1199  
1200  /**
1201   * Check if a skin is installed.
1202   *
1203   * This can either be a regular skin or a skin provided by a plugin.
1204   *
1205   * @param Skin name (directory name)
1206   * @return boolean True if the skin is installed, false otherwise.
1207   */
1208  function skin_installed( $name )
1209  {
1210      $SkinCache = & get_SkinCache();
1211  
1212      if( skin_provided_by_plugin( $name ) || $SkinCache->get_by_folder( $name, false ) )
1213      {
1214          return true;
1215      }
1216  
1217      return false;
1218  }
1219  
1220  
1221  /**
1222   * Display a blog skin setting fieldset which can be normal, mobile or tablet ( used on _coll_skin_settings.form.php )
1223   *
1224   * @param object Form
1225   * @param integer skin ID
1226   * @param array display params
1227   */
1228  function display_skin_fieldset( & $Form, $skin_ID, $display_params )
1229  {
1230      $Form->begin_fieldset( $display_params[ 'fieldset_title' ].get_manual_link('blog_skin_settings').' '.$display_params[ 'fieldset_links' ] );
1231  
1232      if( !$skin_ID )
1233      { // The skin ID is empty use the same as normal skin ID
1234          echo '<div style="font-weight:bold;padding:0.5ex;">'.T_('Same as normal skin.').'</div>';
1235      }
1236      else
1237      {
1238          $SkinCache = & get_SkinCache();
1239          $edited_Skin = $SkinCache->get_by_ID( $skin_ID );
1240  
1241          echo '<div style="float:left;width:30%">';
1242          $disp_params = array( 'skinshot_class' => 'coll_settings_skinshot' );
1243          Skin::disp_skinshot( $edited_Skin->folder, $edited_Skin->name, $disp_params );
1244  
1245          $Form->info( T_('Skin name'), $edited_Skin->name );
1246  
1247          if( isset($edited_Skin->version) )
1248          {
1249                  $Form->info( T_('Skin version'), $edited_Skin->version );
1250          }
1251  
1252          $Form->info( T_('Skin type'), $edited_Skin->type );
1253  
1254          if( $skin_containers = $edited_Skin->get_containers() )
1255          {
1256              $container_ul = '<ul><li>'.implode( '</li><li>', $skin_containers ).'</li></ul>';
1257          }
1258          else
1259          {
1260              $container_ul = '-';
1261          }
1262          $Form->info( T_('Containers'), $container_ul );
1263  
1264          echo '</div>';
1265          echo '<div style="margin-left:30%">';
1266  
1267          $skin_params = $edited_Skin->get_param_definitions( $tmp_params = array('for_editing'=>true) );
1268  
1269          if( empty($skin_params) )
1270          {    // Advertise this feature!!
1271              echo '<p>'.T_('This skin does not provide any configurable settings.').'</p>';
1272          }
1273          else
1274          {
1275              load_funcs( 'plugins/_plugin.funcs.php' );
1276  
1277              // Loop through all widget params:
1278              foreach( $skin_params as $l_name => $l_meta )
1279              {
1280                  // Display field:
1281                  autoform_display_field( $l_name, $l_meta, $Form, 'Skin', $edited_Skin );
1282              }
1283          }
1284  
1285          echo '</div>';
1286      }
1287  
1288      $Form->end_fieldset();
1289  }
1290  
1291  ?>

title

Description

title

Description

title

Description

title

title

Body