b2evolution PHP Cross Reference Blogging Systems

Source: /inc/items/items.ctrl.php - 1651 lines - 51682 bytes - Summary - Text - Print

Description: This file implements the UI controller for managing posts. b2evolution - {@link http://b2evolution.net/} Released under GNU GPL License - {@link http://b2evolution.net/about/license.html}

   1  <?php
   2  /**
   3   * This file implements the UI controller for managing posts.
   4   *
   5   * b2evolution - {@link http://b2evolution.net/}
   6   * Released under GNU GPL License - {@link http://b2evolution.net/about/license.html}
   7   * @copyright (c)2003-2014 by Francois Planque - {@link http://fplanque.com/}
   8   *
   9   * {@internal Open Source relicensing agreement:
  10   * }}
  11   *
  12   * @todo dh> AFAICS there are three params used for "item ID": "p", "post_ID"
  13   *       and "item_ID". This should get cleaned up.
  14   *       Side effect: "post_ID required" error if you switch tabs (expert/simple),
  15   *       after an error is display (e.g. entering an invalid issue time).
  16   *       (related to $tab_switch_params)
  17   * fp> Yes, it's a mess...
  18   *     Ironically the correct name would be itm_ID (which is what the DB uses,
  19   *     except for the Items table which should actually also use itm_ prefixes instead of post_
  20   *     ... a lot of history lead to this :p
  21   *
  22   * @package admin
  23   *
  24   * {@internal Below is a list of authors who have contributed to design/coding of this file: }}
  25   * @author fplanque: Francois PLANQUE.
  26   *
  27   * @version $Id: items.ctrl.php 6136 2014-03-08 07:59:48Z manuel $
  28   */
  29  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  30  
  31  /**
  32   * @var AdminUI
  33   */
  34  global $AdminUI;
  35  
  36  /**
  37   * @var UserSettings
  38   */
  39  global $UserSettings;
  40  
  41  /**
  42   * @var User
  43   */
  44  global $current_User;
  45  
  46  /**
  47   * @var Blog
  48   */
  49  global $Blog;
  50  
  51  global $dispatcher;
  52  
  53  $action = param_action( 'list' );
  54  
  55  $AdminUI->set_path( 'items' );    // Sublevel may be attached below
  56  
  57  
  58  /*
  59   * Init the objects we want to work on.
  60   *
  61   * Autoselect a blog where we have PERMISSION to browse (preferably the last used blog):
  62   * Note: for some actions, we'll get the blog from the post ID
  63   */
  64  
  65  $mass_create = param( 'mass_create', 'integer' );
  66  if( $action == 'new_switchtab' && !empty( $mass_create ) )
  67  {    // Replace action with mass create action
  68      $action = 'new_mass';
  69  }
  70  
  71  // for post from files
  72  if( $action == 'group_action' )
  73  { // Get the real action from the select:
  74      $action = param( 'group_action', 'string', '' );
  75  }
  76  
  77  
  78  switch( $action )
  79  {
  80      case 'edit':
  81      case 'history':
  82      case 'history_details':
  83      case 'history_compare':
  84      case 'history_restore':
  85          // Load post to edit:
  86          param( 'p', 'integer', true, true );
  87          $ItemCache = & get_ItemCache();
  88          $edited_Item = & $ItemCache->get_by_ID( $p );
  89  
  90          // Load the blog we're in:
  91          $Blog = & $edited_Item->get_Blog();
  92          set_working_blog( $Blog->ID );
  93  
  94          // Where are we going to redirect to?
  95          param( 'redirect_to', 'url', url_add_param( $admin_url, 'ctrl=items&filter=restore&blog='.$Blog->ID.'&highlight='.$edited_Item->ID, '&' ) );
  96          break;
  97  
  98      case 'mass_edit' :
  99          break;
 100  
 101      case 'update_edit' :
 102      case 'update' :
 103      case 'update_publish' :
 104      case 'publish' :
 105      case 'publish_now' :
 106      case 'restrict' :
 107      case 'deprecate' :
 108      case 'delete' :
 109      // Note: we need to *not* use $p in the cases above or it will conflict with the list display
 110      case 'edit_switchtab' : // this gets set as action by JS, when we switch tabs
 111          // Load post to edit:
 112          param ( 'post_ID', 'integer', true, true );
 113          $ItemCache = & get_ItemCache ();
 114          $edited_Item = & $ItemCache->get_by_ID ( $post_ID );
 115  
 116          // Load the blog we're in:
 117          $Blog = & $edited_Item->get_Blog();
 118          set_working_blog( $Blog->ID );
 119  
 120          // Where are we going to redirect to?
 121          param( 'redirect_to', 'url', url_add_param( $admin_url, 'ctrl=items&filter=restore&blog='.$Blog->ID.'&highlight='.$edited_Item->ID, '&' ) );
 122  
 123          // What form button has been pressed?
 124          param( 'save', 'string', '' );
 125          $exit_after_save = ( $action != 'update_edit' );
 126          break;
 127  
 128      case 'mass_save' :
 129          param( 'redirect_to', 'url', url_add_param( $admin_url, 'ctrl=items&filter=restore&blog=' . $Blog->ID, '&' ) );
 130          break;
 131  
 132      case 'new' :
 133      case 'new_switchtab' : // this gets set as action by JS, when we switch tabs
 134      case 'new_mass' :
 135      case 'copy' :
 136      case 'create_edit' :
 137      case 'create' :
 138      case 'create_publish' :
 139      case 'list' :
 140          if( $action == 'list' )
 141          {    // We only need view permission
 142              $selected = autoselect_blog( 'blog_ismember', 'view' );
 143          }
 144          else
 145          {    // We need posting permission
 146              $selected = autoselect_blog( 'blog_post_statuses', 'edit' );
 147          }
 148  
 149          if( ! $selected  )
 150          { // No blog could be selected
 151              $Messages->add( T_('Sorry, you have no permission to post yet.'), 'error' );
 152              $action = 'nil';
 153          }
 154          else
 155          {
 156              if( set_working_blog( $selected ) )    // set $blog & memorize in user prefs
 157              {    // Selected a new blog:
 158                  $BlogCache = & get_BlogCache();
 159                  $Blog = & $BlogCache->get_by_ID( $blog );
 160              }
 161  
 162              // Where are we going to redirect to?
 163              param( 'redirect_to', 'url', url_add_param( $admin_url, 'ctrl=items&filter=restore&blog='.$Blog->ID, '&' ) );
 164  
 165              // What form buttton has been pressed?
 166              param( 'save', 'string', '' );
 167              $exit_after_save = ( $action != 'create_edit' );
 168          }
 169          break;
 170  
 171      case 'make_posts_pre':
 172          // form for edit several posts
 173          break;
 174  
 175      case 'make_posts_from_files':
 176          // Make posts with selected images:
 177  
 178          // Check that this action request is not a CSRF hacked request:
 179          $Session->assert_received_crumb( 'file' );
 180  
 181          $FileRootCache = & get_FileRootCache();
 182          // getting root
 183          $root = param("root");
 184  
 185          $fm_FileRoot = & $FileRootCache->get_by_ID($root, true);
 186  
 187          // fp> TODO: this block should move to a general level
 188          // Try to go to the right blog:
 189          if( $fm_FileRoot->type == 'collection' )
 190          {
 191              set_working_blog( $fm_FileRoot->in_type_ID );
 192        // Load the blog we're in:
 193              $Blog = & $BlogCache->get_by_ID( $blog );
 194          }
 195          // ---
 196  
 197  
 198          if( empty( $Blog ) )
 199          {
 200              $Messages->add( T_('No destination blog is selected.'), 'error' );
 201              break;
 202          }
 203          //$Blog->disp('name');
 204  
 205          // Get default status (includes PERM CHECK):
 206          $item_status = $Blog->get_allowed_item_status();
 207          if( empty($item_status) )
 208          {
 209              $Messages->add( T_('Sorry, you have no permission to post into this blog.'), 'error' );
 210              break;
 211          }
 212  
 213          //print_r($_POST);die();
 214          load_class( 'files/model/_filelist.class.php', 'FileList' );
 215          $selected_Filelist = new Filelist( $fm_FileRoot, false );
 216          $fm_selected = param( "fm_selected" , "array" );
 217  //        print_r($fm_selected);
 218          foreach( $fm_selected as $l_source_path )
 219          {
 220              // echo '<br>'.$l_source_path;
 221              $selected_Filelist->add_by_subpath( urldecode($l_source_path), true );
 222          }
 223          // make sure we have loaded metas for all files in selection!
 224          $selected_Filelist->load_meta();
 225  
 226          // Ready to create post(s):
 227          load_class( 'items/model/_item.class.php', 'Item' );
 228  
 229          $fileNum =0;
 230          $cat_Array=param("category","array");
 231          $title_Array=param("post_title","array");
 232          while( $l_File = & $selected_Filelist->get_next() )
 233          {
 234              // Create a post:
 235              $edited_Item = new Item();
 236              $edited_Item->set( 'status', $item_status );
 237  
 238  
 239              // replacing category if selected at preview screen
 240              if ( isset($cat_Array[$fileNum]) )
 241              {
 242                  // checking if selected "same as above" category option
 243                  if ( $cat_Array[$fileNum]!='same' )
 244                  { // Use a selected category ID
 245                      $edited_Item->set( 'main_cat_ID', $cat_Array[$fileNum] );
 246                  }
 247                  else
 248                  { // Get a category ID from previous item
 249                      $cat_Array[$fileNum] = $cat_Array[$fileNum-1];
 250                      $edited_Item->set( 'main_cat_ID', $cat_Array[$fileNum-1] );
 251                  }
 252              }
 253              else
 254              { // Use default category ID if it was not selected on the form
 255                  $edited_Item->set( 'main_cat_ID', $Blog->get_default_cat_ID() );
 256              }
 257  
 258              $title = $l_File->get('title');
 259              if( empty($title) )
 260              {
 261                  $title = $l_File->get('name');
 262              }
 263  
 264              $edited_Item->set( 'title', $title );
 265  
 266              // replacing category if selected at preview screen
 267              if (isset($title_Array[$fileNum])) {
 268                  $edited_Item->set( 'title', $title_Array[$fileNum] );
 269              }
 270  
 271              $DB->begin( 'SERIALIZABLE' );
 272  
 273              // INSERT NEW POST INTO DB:
 274              if( $edited_Item->dbinsert() )
 275              {
 276                  // echo '<br>file meta: '.$l_File->meta;
 277                  if(    $l_File->meta == 'notfound' )
 278                  {    // That file has no meta data yet, create it now!
 279                      $l_File->dbsave();
 280                  }
 281  
 282                  // Let's make the link!
 283                  $edited_Link = new Link();
 284                  $edited_Link->set( 'itm_ID', $edited_Item->ID );
 285                  $edited_Link->set( 'file_ID', $l_File->ID );
 286                  $edited_Link->set( 'position', 'teaser' );
 287                  $edited_Link->set( 'order', 1 );
 288                  $edited_Link->dbinsert();
 289  
 290                  $DB->commit();
 291  
 292                  // Invalidate blog's media BlockCache
 293                  BlockCache::invalidate_key( 'media_coll_ID', $edited_Item->get_blog_ID() );
 294  
 295                  $Messages->add( sprintf( T_('&laquo;%s&raquo; has been posted.'), $l_File->dget('name') ), 'success' );
 296                  $fileNum++;
 297              }
 298              else
 299              {
 300                  $DB->rollback();
 301                  $Messages->add( sprintf( T_('&laquo;%s&raquo; couldn\'t be posted.'), $l_File->dget('name') ), 'error' );
 302              }
 303          }
 304  
 305          // Note: we redirect without restoring filter. This should allow to see the new files.
 306          // &filter=restore
 307          header_redirect( $dispatcher.'?ctrl=items&blog='.$blog );    // Will save $Messages
 308  
 309          // Note: we should have EXITED here. In case we don't (error, or sth...)
 310  
 311          // Reset stuff so it doesn't interfere with upcomming display
 312          unset( $edited_Item );
 313          unset( $edited_Link );
 314          $selected_Filelist = new Filelist( $fm_Filelist->get_FileRoot(), false );
 315          break;
 316  
 317  
 318      default:
 319          debug_die( 'unhandled action 1:'.htmlspecialchars($action) );
 320  }
 321  
 322  $AdminUI->breadcrumbpath_init();
 323  $AdminUI->breadcrumbpath_add( T_('Contents'), '?ctrl=items&amp;blog=$blog$&amp;tab=full&amp;filter=restore' );
 324  
 325  /**
 326   * Perform action:
 327   */
 328  switch( $action )
 329  {
 330      case 'nil':
 331          // Do nothing
 332          break;
 333  
 334      case 'new':
 335      case 'new_mass':
 336          // $set_issue_date = 'now';
 337          $item_issue_date = date_i18n( locale_datefmt(), $localtimenow );
 338          $item_issue_time = date( 'H:i:s', $localtimenow );
 339          // pre_dump( $item_issue_date, $item_issue_time );
 340      case 'new_switchtab': // this gets set as action by JS, when we switch tabs
 341          // New post form  (can be a bookmarklet form if mode == bookmarklet )
 342  
 343          // We don't check the following earlier, because we want the blog switching buttons to be available:
 344          if( ! blog_has_cats( $blog ) )
 345          {
 346              break;
 347          }
 348  
 349          load_class( 'items/model/_item.class.php', 'Item' );
 350          $edited_Item = new Item();
 351  
 352          $edited_Item->set('main_cat_ID', $Blog->get_default_cat_ID());
 353  
 354          // We use the request variables to fill the edit form, because we need to be able to pass those values
 355          // from tab to tab via javascript when the editor wants to switch views...
 356          // Also used by bookmarklet
 357          $edited_Item->load_from_Request( true ); // needs Blog set
 358  
 359          // Set default locations from current user
 360          $edited_Item->set_creator_location( 'country' );
 361          $edited_Item->set_creator_location( 'region' );
 362          $edited_Item->set_creator_location( 'subregion' );
 363          $edited_Item->set_creator_location( 'city' );
 364  
 365          $edited_Item->status = param( 'post_status', 'string', NULL );        // 'published' or 'draft' or ...
 366          // We know we can use at least one status,
 367          // but we need to make sure the requested/default one is ok:
 368          $edited_Item->status = $Blog->get_allowed_item_status ( $edited_Item->status );
 369  
 370          // Check if new category was started to create. If yes then set up parameters for next page
 371          check_categories_nosave ( $post_category, $post_extracats );
 372  
 373          $edited_Item->set ( 'main_cat_ID', $post_category );
 374          if( $edited_Item->main_cat_ID && ( get_allow_cross_posting() < 2 ) && $edited_Item->get_blog_ID() != $blog )
 375          { // the main cat is not in the list of categories; this happens, if the user switches blogs during editing:
 376              $edited_Item->set('main_cat_ID', $Blog->get_default_cat_ID());
 377          }
 378          $post_extracats = param( 'post_extracats', 'array/integer', $post_extracats );
 379  
 380          param( 'item_tags', 'string', '' );
 381  
 382          // Trackback addresses (never saved into item)
 383          param( 'trackback_url', 'string', '' );
 384  
 385          // Page title:
 386          switch( param( 'item_typ_ID', 'integer', 1 ) )
 387          {
 388              case 1000:
 389                  $title = T_('New page');
 390                  break;
 391  
 392              case 1600:
 393                  $title = T_('New intro');
 394                  break;
 395  
 396              case 2000:
 397                  $title = T_('New podcast episode');
 398                  break;
 399  
 400              case 3000:
 401                  $title = T_('New link');
 402                  break;
 403  
 404              case 4000:
 405                  $title = T_('New advertisement');
 406                  break;
 407  
 408              default:
 409                  $title = T_('New post');
 410                  break;
 411          }
 412  
 413          $AdminUI->breadcrumbpath_add( $title, '?ctrl=items&amp;action=new&amp;blog='.$Blog->ID.'&amp;item_typ_ID='.$item_typ_ID );
 414  
 415          $AdminUI->title_titlearea = $title.': ';;
 416  
 417          // Params we need for tab switching:
 418          $tab_switch_params = 'blog='.$blog;
 419          break;
 420  
 421  
 422      case 'copy': // Duplicate post
 423          $item_ID = param( 'p', 'integer', true );
 424          $ItemCache = &get_ItemCache();
 425          $edited_Item = & $ItemCache->get_by_ID( $item_ID );
 426  
 427          $edited_Item->load_Blog();
 428          $item_status = $edited_Item->Blog->get_allowed_item_status();
 429  
 430          $edited_Item->set( 'status', $item_status );
 431          $edited_Item->set( 'dateset', 0 );    // Date not explicitly set yet
 432          $edited_Item->set( 'issue_date', date( 'Y-m-d H:i:s', $localtimenow ) );
 433  
 434          // Set post comment status and extracats
 435          $post_comment_status = $edited_Item->get( 'comment_status' );
 436          $post_extracats = postcats_get_byID( $p );
 437  
 438          // Check if new category was started to create. If yes then set up parameters for next page
 439          check_categories_nosave ( $post_category, $post_extracats );
 440  
 441          // Page title:
 442          switch( $edited_Item->ptyp_ID )
 443          {
 444              case 1000:
 445                  $title = T_('Duplicate page');
 446                  break;
 447  
 448              case 1600:
 449                  $title = T_('Duplicate intro');
 450                  break;
 451  
 452              case 2000:
 453                  $title = T_('Duplicate podcast episode');
 454                  break;
 455  
 456              case 3000:
 457                  $title = T_('Duplicate link');
 458                  break;
 459  
 460              case 4000:
 461                  $title = T_('Duplicate advertisement');
 462                  break;
 463  
 464              default:
 465                  $title = T_('Duplicate post');
 466                  break;
 467          }
 468  
 469          $AdminUI->breadcrumbpath_add( $title, '?ctrl=items&amp;action=copy&amp;blog='.$Blog->ID.'&amp;p='.$edited_Item->ID );
 470  
 471          $AdminUI->title_titlearea = $title.': ';
 472  
 473          // Params we need for tab switching:
 474          $tab_switch_params = 'blog='.$blog;
 475          break;
 476  
 477  
 478      case 'edit_switchtab': // this gets set as action by JS, when we switch tabs
 479          // This is somewhat in between new and edit...
 480  
 481          // Check permission based on DB status:
 482          $current_User->check_perm( 'item_post!CURSTATUS', 'edit', true, $edited_Item );
 483  
 484          $edited_Item->status = param( 'post_status', 'string', NULL );        // 'published' or 'draft' or ...
 485          // We know we can use at least one status,
 486          // but we need to make sure the requested/default one is ok:
 487          $edited_Item->status = $Blog->get_allowed_item_status( $edited_Item->status );
 488  
 489          // We use the request variables to fill the edit form, because we need to be able to pass those values
 490          // from tab to tab via javascript when the editor wants to switch views...
 491          $edited_Item->load_from_Request ( true ); // needs Blog set
 492  
 493          // Check if new category was started to create. If yes then set up parameters for next page
 494          check_categories_nosave ( $post_category, $post_extracats );
 495  
 496          $edited_Item->set ( 'main_cat_ID', $post_category );
 497          if( $edited_Item->main_cat_ID && ( get_allow_cross_posting() < 2 ) && $edited_Item->get_blog_ID() != $blog )
 498          { // the main cat is not in the list of categories; this happens, if the user switches blogs during editing:
 499              $edited_Item->set('main_cat_ID', $Blog->get_default_cat_ID());
 500          }
 501          $post_extracats = param( 'post_extracats', 'array/integer', $post_extracats );
 502  
 503          param( 'item_tags', 'string', '' );
 504  
 505          // Trackback addresses (never saved into item)
 506          param( 'trackback_url', 'string', '' );
 507  
 508          // Page title:
 509          $AdminUI->title_titlearea = sprintf( T_('Editing post #%d: %s'), $edited_Item->ID, $Blog->get('name') );
 510  
 511          $AdminUI->breadcrumbpath_add( sprintf( T_('Post #%s'), $edited_Item->ID ), '?ctrl=items&amp;blog='.$Blog->ID.'&amp;p='.$edited_Item->ID );
 512          $AdminUI->breadcrumbpath_add( T_('Edit'), '?ctrl=items&amp;action=edit&amp;blog='.$Blog->ID.'&amp;p='.$edited_Item->ID );
 513  
 514          // Params we need for tab switching:
 515          $tab_switch_params = 'p='.$edited_Item->ID;
 516          break;
 517  
 518      case 'history':
 519          // Check permission:
 520          $current_User->check_perm( 'item_post!CURSTATUS', 'edit', true, $edited_Item );
 521          break;
 522  
 523      case 'history_details':
 524          // Check permission:
 525          $current_User->check_perm( 'item_post!CURSTATUS', 'edit', true, $edited_Item );
 526  
 527          // get revision param, but it is possible that it is not a number because current version sign is 'C'
 528          param( 'r', 'integer', 0, false, false, true, false );
 529  
 530          $Revision = $edited_Item->get_revision( $r );
 531          break;
 532  
 533      case 'history_compare':
 534          // Check that this action request is not a CSRF hacked request:
 535          $Session->assert_received_crumb( 'item' );
 536  
 537          // Check permission:
 538          $current_User->check_perm( 'item_post!CURSTATUS', 'edit', true, $edited_Item );
 539  
 540          param( 'r1', 'integer', 0 );
 541          $r2 = (int)param( 'r2', 'string', 0 );
 542  
 543          $Revision_1 = $edited_Item->get_revision( $r1 );
 544          $Revision_2 = $edited_Item->get_revision( $r2 );
 545  
 546          load_class( '_core/model/_diff.class.php', 'Diff' );
 547  
 548          // Compare the titles of two revisions
 549          $revisions_difference_title = new Diff( explode( "\n", $Revision_1->iver_title ), explode( "\n", $Revision_2->iver_title ) );
 550          $format = new TitleDiffFormatter();
 551          $revisions_difference_title = $format->format( $revisions_difference_title );
 552  
 553          // Compare the contents of two revisions
 554          $revisions_difference_content = new Diff( explode( "\n", $Revision_1->iver_content ), explode( "\n", $Revision_2->iver_content ) );
 555          $format = new TableDiffFormatter();
 556          $revisions_difference_content = $format->format( $revisions_difference_content );
 557  
 558          break;
 559  
 560      case 'history_restore':
 561          // Check that this action request is not a CSRF hacked request:
 562          $Session->assert_received_crumb( 'item' );
 563  
 564          // Check permission:
 565          $current_User->check_perm( 'item_post!CURSTATUS', 'edit', true, $edited_Item );
 566  
 567          param( 'r', 'integer', 0 );
 568  
 569          if( $r > 0 )
 570          {    // Update item only from revisions ($r == 0 for current version)
 571              $Revision = $edited_Item->get_revision( $r );
 572  
 573              $edited_Item->set( 'status', $Revision->iver_status );
 574              $edited_Item->set( 'title', $Revision->iver_title );
 575              $edited_Item->set( 'content', $Revision->iver_content );
 576  
 577              if( $edited_Item->dbupdate() )
 578              {    // Item updated
 579                  $Messages->add( sprintf( T_('Item has been restored from revision #%s'), $r ), 'success' );
 580              }
 581          }
 582  
 583          header_redirect( regenerate_url( 'action', 'action=history', '', '&' ) );
 584          break;
 585  
 586      case 'edit':
 587          // Check permission:
 588          $current_User->check_perm( 'item_post!CURSTATUS', 'edit', true, $edited_Item );
 589  
 590          $post_comment_status = $edited_Item->get( 'comment_status' );
 591          $post_extracats = postcats_get_byID( $p ); // NOTE: dh> using $edited_Item->get_Chapters here instead fails (empty list, since no postIDlist).
 592  
 593          $item_tags = implode( ', ', $edited_Item->get_tags() );
 594          $trackback_url = '';
 595  
 596          // Page title:
 597          $AdminUI->title_titlearea = sprintf( T_('Editing post #%d: %s'), $edited_Item->ID, $Blog->get('name') );
 598  
 599          $AdminUI->breadcrumbpath_add( sprintf( T_('Post #%s'), $edited_Item->ID ), '?ctrl=items&amp;blog='.$Blog->ID.'&amp;p='.$edited_Item->ID );
 600          $AdminUI->breadcrumbpath_add( T_('Edit'), '?ctrl=items&amp;action=edit&amp;blog='.$Blog->ID.'&amp;p='.$edited_Item->ID );
 601  
 602          // Params we need for tab switching:
 603          $tab_switch_params = 'p='.$edited_Item->ID;
 604          break;
 605  
 606  
 607      case 'create_edit':
 608      case 'create':
 609      case 'create_publish':
 610          // Check that this action request is not a CSRF hacked request:
 611          $Session->assert_received_crumb( 'item' );
 612  
 613          // We need early decoding of these in order to check permissions:
 614          param( 'post_status', 'string', 'published' );
 615  
 616          if( $action == 'create_publish' )
 617          { // load publish status from param, because a post can be published to many status
 618              $post_status = load_publish_status( true );
 619          }
 620  
 621          // Check if new category was started to create. If yes check if it is valid.
 622          check_categories ( $post_category, $post_extracats );
 623  
 624          // Check permission on statuses:
 625          $current_User->check_perm( 'cats_post!'.$post_status, 'create', true, $post_extracats );
 626          // Check permission on post type:
 627          check_perm_posttype( $post_extracats );
 628  
 629          // CREATE NEW POST:
 630          load_class( 'items/model/_item.class.php', 'Item' );
 631          $edited_Item = new Item();
 632  
 633          // Set the params we already got:
 634          $edited_Item->set( 'status', $post_status );
 635          $edited_Item->set( 'main_cat_ID', $post_category );
 636          $edited_Item->set( 'extra_cat_IDs', $post_extracats );
 637  
 638          // Set object params:
 639          $edited_Item->load_from_Request( /* editing? */ ($action == 'create_edit'), /* creating? */ true );
 640  
 641          $Plugins->trigger_event ( 'AdminBeforeItemEditCreate', array ('Item' => & $edited_Item ) );
 642  
 643          if( !empty( $mass_create ) )
 644          {    // ------ MASS CREATE ------
 645              $Items = & create_multiple_posts( $edited_Item, param( 'paragraphs_linebreak', 'boolean', 0 ) );
 646              if( empty( $Items ) )
 647              {
 648                  param_error( 'content', T_( 'Content must not be empty.' ) );
 649              }
 650          }
 651  
 652          $result = !$Messages->has_errors();
 653  
 654          if( $result )
 655          { // There are no validation errors
 656              if( isset( $Items ) && !empty( $Items ) )
 657              {    // We can create multiple posts from single post
 658                  foreach( $Items as $edited_Item )
 659                  {    // INSERT NEW POST INTO DB:
 660                      $result = $edited_Item->dbinsert();
 661                  }
 662              }
 663              else
 664              {    // INSERT NEW POST INTO DB:
 665                  $result = $edited_Item->dbinsert();
 666              }
 667              if( !$result )
 668              { // Add error message
 669                  $Messages->add( T_('Couldn\'t create the new post'), 'error' );
 670              }
 671          }
 672  
 673          if( !$result )
 674          { // could not insert the new post ( validation errors or unsuccessful db insert )
 675              if( !empty( $mass_create ) )
 676              {
 677                  $action = 'new_mass';
 678              }
 679              // Params we need for tab switching:
 680              $tab_switch_params = 'blog='.$blog;
 681              break;
 682          }
 683  
 684          param( 'is_attachments', 'string' );
 685          if( !empty( $is_attachments ) && $is_attachments === 'true' )
 686          { // Set session variable to dynamically create js popup:
 687              $Session->set('create_edit_attachment', true);
 688          }
 689  
 690          // post post-publishing operations:
 691          param( 'trackback_url', 'string' );
 692          if( !empty( $trackback_url ) )
 693          {
 694              if( $edited_Item->status != 'published' )
 695              {
 696                  $Messages->add( T_('Post not publicly published: skipping trackback...'), 'note' );
 697              }
 698              else
 699              { // trackback now:
 700                  load_funcs('comments/_trackback.funcs.php');
 701                  trackbacks( $trackback_url, $edited_Item );
 702              }
 703          }
 704  
 705          // Execute or schedule notifications & pings:
 706          $edited_Item->handle_post_processing( true, $exit_after_save );
 707  
 708          $Messages->add( T_('Post has been created.'), 'success' );
 709  
 710          if( ! $exit_after_save )
 711          {    // We want to continue editing...
 712              $tab_switch_params = 'p='.$edited_Item->ID;
 713              $action = 'edit';    // It's basically as if we had updated
 714              break;
 715          }
 716  
 717          // We want to highlight the edited object on next list display:
 718          $Session->set( 'fadeout_array', array( 'item-'.$edited_Item->ID ) );
 719  
 720          if( $edited_Item->status == 'published' )
 721          {    // fp> I noticed that after publishing a new post, I always want to see how the blog looks like
 722              // If anyone doesn't want that, we can make this optional...
 723              // sam2kb> Please make this optional, this is really annoying when you create more than one post or when you publish draft images created from FM.
 724  
 725              // Where do we want to go after publishing?
 726              if( $edited_Item->Blog->get_setting( 'enable_goto_blog' ) == 'blog' )
 727              {    // go to blog:
 728                  $edited_Item->load_Blog();
 729                  $redirect_to = $edited_Item->Blog->gen_blogurl();
 730              }
 731              elseif( $edited_Item->Blog->get_setting( 'enable_goto_blog' ) == 'post' )
 732              {    // redirect to post page:
 733                  $redirect_to = $edited_Item->get_permanent_url();
 734              }
 735              else// 'no'
 736              {    // redirect to posts list:
 737                  header_redirect( regenerate_url( '', '&highlight='.$edited_Item->ID, '', '&' ) );
 738              }
 739          }
 740  
 741          // REDIRECT / EXIT
 742          header_redirect( $redirect_to );
 743          // Switch to list mode:
 744          // $action = 'list';
 745          //init_list_mode();
 746          break;
 747  
 748  
 749      case 'update_edit':
 750      case 'update':
 751      case 'update_publish':
 752          // Check that this action request is not a CSRF hacked request:
 753          $Session->assert_received_crumb( 'item' );
 754  
 755          // Check edit permission:
 756          $current_User->check_perm( 'item_post!CURSTATUS', 'edit', true, $edited_Item );
 757  
 758          // We need early decoding of these in order to check permissions:
 759          param( 'post_status', 'string', 'published' );
 760  
 761          if( $action == 'update_publish' )
 762          { // load publish status from param, because a post can be published to many status
 763              $post_status = load_publish_status();
 764          }
 765  
 766          // Check if new category was started to create.  If yes check if it is valid.
 767          $isset_category = check_categories( $post_category, $post_extracats );
 768  
 769          // Check permission on statuses:
 770          $current_User->check_perm( 'cats_post!'.$post_status, 'edit', true, $post_extracats );
 771          // Check permission on post type:
 772          check_perm_posttype( $post_extracats );
 773  
 774          // Is this post already published?
 775          $was_published = $edited_Item->status == 'published';
 776  
 777          // UPDATE POST:
 778          // Set the params we already got:
 779          $edited_Item->set( 'status', $post_status );
 780  
 781          if( $isset_category )
 782          { // we change the categories only if the check was succesfull
 783              $edited_Item->set( 'main_cat_ID', $post_category );
 784              $edited_Item->set( 'extra_cat_IDs', $post_extracats );
 785          }
 786  
 787          // Set object params:
 788          $edited_Item->load_from_Request( false );
 789  
 790          $Plugins->trigger_event( 'AdminBeforeItemEditUpdate', array( 'Item' => & $edited_Item ) );
 791  
 792          // Params we need for tab switching (in case of error or if we save&edit)
 793          $tab_switch_params = 'p='.$edited_Item->ID;
 794  
 795          if( $Messages->has_errors() )
 796          {    // There have been some validation errors:
 797              break;
 798          }
 799  
 800          // UPDATE POST IN DB:
 801          if( !$edited_Item->dbupdate() )
 802          { // Could not update successful
 803              $Messages->add( T_('The post couldn\'t be updated.'), 'error' );
 804              break;
 805          }
 806  
 807          // post post-publishing operations:
 808          param( 'trackback_url', 'string' );
 809          if( !empty( $trackback_url ) )
 810          {
 811              if( $edited_Item->status != 'published' )
 812              {
 813                  $Messages->add( T_('Post not publicly published: skipping trackback...'), 'note' );
 814              }
 815              else
 816              { // trackback now:
 817                  load_funcs('comments/_trackback.funcs.php');
 818                  trackbacks( $trackback_url, $edited_Item );
 819              }
 820          }
 821  
 822          // Execute or schedule notifications & pings:
 823          $edited_Item->handle_post_processing( false, $exit_after_save );
 824  
 825          $Messages->add( T_('Post has been updated.'), 'success' );
 826  
 827          if( ! $exit_after_save )
 828          { // We want to continue editing...
 829              break;
 830          }
 831  
 832          /* fp> I noticed that after publishing a new post, I always want
 833           *     to see how the blog looks like. If anyone doesn't want that,
 834           *     we can make this optional...
 835           */
 836          $edited_Item->load_Blog();
 837          if( $edited_Item->status == 'redirected' )
 838          { // If a post is in "Redirected" status we should show the posts list
 839              $blog_redirect_setting = 'no';
 840          }
 841          elseif( ! $was_published && $edited_Item->status == 'published' )
 842          { // The post's last status wasn't "published", but we're going to publish it now.
 843              $blog_redirect_setting = $edited_Item->Blog->get_setting( 'enable_goto_blog' );
 844          }
 845          else
 846          { // The post was changed
 847              $blog_redirect_setting = $edited_Item->Blog->get_setting( 'editing_goto_blog' );
 848          }
 849  
 850          if( $blog_redirect_setting == 'blog' )
 851          { // go to blog:
 852              $edited_Item->load_Blog();
 853              $redirect_to = $edited_Item->Blog->gen_blogurl();
 854          }
 855          elseif( $blog_redirect_setting == 'post' )
 856          { // redirect to post page:
 857              $redirect_to = $edited_Item->get_permanent_url();
 858          }
 859          else// $blog_redirect_setting == 'no'
 860          { // redirect to posts list
 861              // Set highlight
 862              $Session->set( 'highlight_id', $edited_Item->ID );
 863              header_redirect( regenerate_url( '', '&highlight='.$edited_Item->ID, '', '&' ) );
 864          }
 865  
 866  
 867          // REDIRECT / EXIT
 868          header_redirect( $redirect_to, 303 );
 869          /* EXITED */
 870          break;
 871  
 872      case 'mass_save' :
 873          // Check that this action request is not a CSRF hacked request:
 874          $Session->assert_received_crumb ( 'item' );
 875  
 876          init_list_mode ();
 877          $ItemList->query ();
 878  
 879          global $DB;
 880  
 881          $update_nr = 0;
 882  
 883          while ( $Item = & $ItemList->get_item () )
 884          {    // check user permission
 885              $current_User->check_perm( 'item_post!CURSTATUS', 'edit', true, $Item );
 886  
 887              // Not allow html content on post titles
 888              $title = param ( 'mass_title_' . $Item->ID, 'htmlspecialchars', NULL );
 889              $urltitle = param ( 'mass_urltitle_' . $Item->ID, 'string', NULL );
 890              $titletag = param ( 'mass_titletag_' . $Item->ID, 'string', NULL );
 891  
 892              if ($title != NULL)
 893              {
 894                  $Item->set ( 'title', $title );
 895              }
 896  
 897              if ($urltitle != NULL)
 898              {
 899                  $Item->set ( 'urltitle', $urltitle );
 900              }
 901  
 902              if ($titletag != NULL)
 903              {
 904                  $Item->set ( 'titletag', $titletag );
 905              }
 906  
 907              if( $Item->dbupdate ())
 908              {
 909                  $update_nr++;    // successfully updated post number
 910              }
 911          }
 912  
 913          if( $update_nr > 0 )
 914          {
 915              $Messages->add( $update_nr == 1 ?
 916                  T_('One post has been updated!') :
 917                  sprintf( T_('%d posts have been updated!'), $update_nr ), 'success' );
 918          }
 919          else
 920          {
 921              $Messages->add( T_('No update executed!') );
 922          }
 923          // REDIRECT / EXIT
 924          header_redirect ( $redirect_to, 303 );
 925          /* EXITED */
 926          break;
 927  
 928      case 'publish' :
 929      case 'publish_now' :
 930          // Publish NOW:
 931  
 932          // Check that this action request is not a CSRF hacked request:
 933          $Session->assert_received_crumb( 'item' );
 934  
 935          $post_status = ( $action == 'publish_now' ) ? 'published' : param( 'post_status', 'string', 'published' );
 936          // Check permissions:
 937          /* TODO: Check extra categories!!! */
 938          $current_User->check_perm( 'item_post!'.$post_status, 'edit', true, $edited_Item );
 939          $edited_Item->set( 'status', $post_status );
 940  
 941          if( $action == 'publish_now' )
 942          { // Update post dates
 943              $current_User->check_perm( 'blog_edit_ts', 'edit', true, $Blog->ID );
 944              // fp> TODO: remove seconds ONLY if date is in the future
 945              $edited_Item->set( 'datestart', remove_seconds($localtimenow) );
 946              $edited_Item->set( 'datemodified', date('Y-m-d H:i:s', $localtimenow) );
 947          }
 948  
 949          // UPDATE POST IN DB:
 950          $edited_Item->dbupdate();
 951  
 952          // Execute or schedule notifications & pings:
 953          $edited_Item->handle_post_processing( false );
 954  
 955          // Set the success message corresponding for the new status
 956          switch( $edited_Item->status )
 957          {
 958              case 'published':
 959                  $success_message = T_('Post has been published.');
 960                  break;
 961              case 'community':
 962                  $success_message = T_('The post is now visible by the community.');
 963                  break;
 964              case 'protected':
 965                  $success_message = T_('The post is now visible by the members.');
 966                  break;
 967              case 'review':
 968                  $success_message = T_('The post is now visible by moderators.');
 969                  break;
 970              default:
 971                  $success_message = T_('Post has been updated.');
 972                  break;
 973          }
 974          $Messages->add( $success_message, 'success' );
 975  
 976          // fp> I noticed that after publishing a new post, I always want to see how the blog looks like
 977          // If anyone doesn't want that, we can make this optional...
 978  
 979          // REDIRECT / EXIT
 980          if( $action == 'publish' && !empty( $redirect_to ) && ( strpos( $redirect_to, $admin_url ) !== 0 ) )
 981          { // We clicked publish button from the front office
 982              header_redirect( $redirect_to );
 983          }
 984          elseif( $edited_Item->Blog->get_setting( 'enable_goto_blog' ) == 'blog' )
 985          {    // Redirect to blog:
 986              $edited_Item->load_Blog();
 987              header_redirect( $edited_Item->Blog->gen_blogurl() );
 988          }
 989          elseif( $edited_Item->Blog->get_setting( 'enable_goto_blog' ) == 'post' )
 990          {    // Redirect to post page:
 991              header_redirect( $edited_Item->get_permanent_url() );
 992          }
 993          else// 'no'
 994          {    // Redirect to posts list:
 995              header_redirect( regenerate_url( '', '&highlight='.$edited_Item->ID, '', '&' ) );
 996          }
 997          // Switch to list mode:
 998          // $action = 'list';
 999          // init_list_mode();
1000          break;
1001  
1002      case 'restrict':
1003          // Check that this action request is not a CSRF hacked request:
1004          $Session->assert_received_crumb( 'item' );
1005  
1006          $post_status = param( 'post_status', 'string', true );
1007          // Check permissions:
1008          $current_User->check_perm( 'item_post!'.$post_status, 'moderate', true, $edited_Item );
1009  
1010          $edited_Item->set( 'status', $post_status );
1011  
1012          // UPDATE POST IN DB:
1013          $edited_Item->dbupdate();
1014  
1015          $Messages->add( T_('Post has been restricted.'), 'success' );
1016  
1017          // REDIRECT / EXIT
1018          header_redirect( $redirect_to );
1019          break;
1020  
1021      case 'deprecate':
1022          // Check that this action request is not a CSRF hacked request:
1023          $Session->assert_received_crumb( 'item' );
1024  
1025          $post_status = 'deprecated';
1026          // Check permissions:
1027          /* TODO: Check extra categories!!! */
1028          $current_User->check_perm( 'item_post!'.$post_status, 'edit', true, $edited_Item );
1029  
1030          $edited_Item->set( 'status', $post_status );
1031          $edited_Item->set( 'datemodified', date('Y-m-d H:i:s',$localtimenow) );
1032  
1033          // UPDATE POST IN DB:
1034          $edited_Item->dbupdate();
1035  
1036          $Messages->add( T_('Post has been deprecated.'), 'success' );
1037  
1038          // REDIRECT / EXIT
1039          header_redirect( $redirect_to );
1040          // Switch to list mode:
1041          // $action = 'list';
1042          // init_list_mode();
1043          break;
1044  
1045  
1046      case 'delete':
1047          // Delete an Item:
1048  
1049          // Check that this action request is not a CSRF hacked request:
1050          $Session->assert_received_crumb( 'item' );
1051  
1052          // Check permission:
1053          $current_User->check_perm( 'blog_del_post', '', true, $blog );
1054  
1055          // fp> TODO: non javascript confirmation
1056          // $AdminUI->title = T_('Deleting post...');
1057  
1058          $Plugins->trigger_event( 'AdminBeforeItemEditDelete', array( 'Item' => & $edited_Item ) );
1059  
1060          if( ! $Messages->has_errors() )
1061          {    // There have been no validation errors:
1062              // DELETE POST FROM DB:
1063              $edited_Item->dbdelete();
1064  
1065              $Messages->add( T_('Post has been deleted.'), 'success' );
1066          }
1067  
1068          // REDIRECT / EXIT
1069          header_redirect( $redirect_to );
1070          // Switch to list mode:
1071          // $action = 'list';
1072          // init_list_mode();
1073          break;
1074  
1075  
1076      case 'mass_edit' :
1077          init_list_mode ();
1078          break;
1079  
1080  
1081      case 'list':
1082          init_list_mode();
1083  
1084          if( $ItemList->single_post )
1085          {    // We have requested to view a SINGLE specific post:
1086              $action = 'view';
1087          }
1088          break;
1089  
1090      case 'make_posts_pre':
1091          // Make posts with selected images action:
1092          break;
1093  
1094      default:
1095          debug_die( 'unhandled action 2: '.htmlspecialchars($action) );
1096  }
1097  
1098  
1099  /**
1100   * Initialize list mode; Several actions need this.
1101   */
1102  function init_list_mode()
1103  {
1104      global $tab, $Blog, $UserSettings, $ItemList, $AdminUI, $posttypes_perms;
1105  
1106      // set default itemslist param prefix
1107      $items_list_param_prefix = 'items_';
1108  
1109      if ( param( 'p', 'integer', NULL ) || param( 'title', 'string', NULL ) )
1110      {    // Single post requested, do not filter any post types. If the user
1111          // has clicked a post link on the dashboard and previously has selected
1112          // a tab which would filter this post, it wouldn't be displayed now.
1113          $tab = 'full';
1114          // in case of single item view params prefix must be empty
1115          $items_list_param_prefix = NULL;
1116      }
1117      else
1118      {    // Store/retrieve preferred tab from UserSettings:
1119          $UserSettings->param_Request( 'tab', 'pref_browse_tab', 'string', NULL, true /* memorize */, true /* force */ );
1120      }
1121  
1122      /*
1123       * Init list of posts to display:
1124       */
1125      load_class( 'items/model/_itemlist.class.php', 'ItemList2' );
1126  
1127      if( !empty( $tab ) && !empty( $items_list_param_prefix ) )
1128      {    // Use different param prefix for each tab
1129          $items_list_param_prefix .= substr( $tab, 0, 7 ).'_';
1130      }
1131      // Create empty List:
1132      $ItemList = new ItemList2( $Blog, NULL, NULL, $UserSettings->get('results_per_page'), 'ItemCache', $items_list_param_prefix, $tab /* filterset name */ ); // COPY (func)
1133  
1134      $ItemList->set_default_filters( array(
1135              'visibility_array' => get_visibility_statuses('keys'),
1136          ) );
1137  
1138      if( $Blog->get_setting('orderby') == 'RAND' )
1139      {    // Do not display random posts in backoffice for easy management
1140          $ItemList->set_default_filters( array(
1141                  'orderby' => 'datemodified',
1142              ) );
1143      }
1144  
1145      switch( $tab )
1146      {
1147          case 'full':
1148              $ItemList->set_default_filters( array(
1149                      'types' => NULL, // All types (suited for tab with full posts)
1150                  ) );
1151              // $AdminUI->breadcrumbpath_add( T_('All items'), '?ctrl=items&amp;blog=$blog$&amp;tab='.$tab.'&amp;filter=restore' );
1152  
1153              // require colorbox js
1154              require_js_helper( 'colorbox' );
1155              break;
1156  
1157          case 'manual':
1158              if( $Blog->get( 'type' ) != 'manual' )
1159              {    // Display this tab only for manual blogs
1160                  global $admin_url;
1161                  header_redirect( $admin_url.'?ctrl=items&blog='.$Blog->ID.'&tab=list&filter=restore' );
1162              }
1163  
1164              $AdminUI->breadcrumbpath_add( T_('Manual Pages'), '?ctrl=items&amp;blog=$blog$&amp;tab='.$tab.'&amp;filter=restore' );
1165              break;
1166  
1167          case 'list':
1168              // Nothing special
1169              $AdminUI->breadcrumbpath_add( T_('Regular posts'), '?ctrl=items&amp;blog=$blog$&amp;tab='.$tab.'&amp;filter=restore' );
1170              break;
1171  
1172          case 'pages':
1173              $ItemList->set_default_filters( array(
1174                      'types' => implode(',',$posttypes_perms['page']), // Pages
1175                  ) );
1176              $AdminUI->breadcrumbpath_add( T_('Pages'), '?ctrl=items&amp;blog=$blog$&amp;tab='.$tab.'&amp;filter=restore' );
1177              break;
1178  
1179          case 'intros':
1180              $ItemList->set_default_filters( array(
1181                      'types' => implode(',',$posttypes_perms['intro']), // Intros
1182                  ) );
1183              $AdminUI->breadcrumbpath_add( T_('Intro posts'), '?ctrl=items&amp;blog=$blog$&amp;tab='.$tab.'&amp;filter=restore' );
1184              break;
1185  
1186          case 'podcasts':
1187              $ItemList->set_default_filters( array(
1188                      'types' => implode(',',$posttypes_perms['podcast']), // Podcasts
1189                  ) );
1190              $AdminUI->breadcrumbpath_add( T_('Podcasts'), '?ctrl=items&amp;blog=$blog$&amp;tab='.$tab.'&amp;filter=restore' );
1191              break;
1192  
1193          case 'links':
1194              $ItemList->set_default_filters( array(
1195                      'types' => '3000', // Links
1196                  ) );
1197              $AdminUI->breadcrumbpath_add( T_('Links'), '?ctrl=items&amp;blog=$blog$&amp;tab='.$tab.'&amp;filter=restore' );
1198              break;
1199  
1200          case 'ads':
1201              $ItemList->set_default_filters( array(
1202                      'types' => '4000', // Advertisements
1203                  ) );
1204              $AdminUI->breadcrumbpath_add( T_('Advertisements'), '?ctrl=items&amp;blog=$blog$&amp;tab='.$tab.'&amp;filter=restore' );
1205              break;
1206  
1207          case 'tracker':
1208              // In tracker mode, we want a different default sort:
1209              $ItemList->set_default_filters( array(
1210                      'orderby' => 'priority',
1211                      'order' => 'ASC' ) );
1212              break;
1213  
1214          default:
1215              // Delete the pref_browse_tab setting so that the default
1216              // (full) gets used the next time the user wants to browse
1217              // a blog and we don't run into the same error again.
1218              $UserSettings->delete( 'pref_browse_tab' );
1219              $UserSettings->dbupdate();
1220              debug_die( 'Unknown filterset ['.$tab.']' );
1221      }
1222  
1223      // Init filter params:
1224      if( ! $ItemList->load_from_Request() )
1225      { // If we could not init a filterset from request
1226          // typically happens when we could no fall back to previously saved filterset...
1227          // echo ' no filterset!';
1228      }
1229  }
1230  
1231  /**
1232   * Configure page navigation:
1233   */
1234  switch( $action )
1235  {
1236      case 'new':
1237      case 'new_switchtab': // this gets set as action by JS, when we switch tabs
1238      case 'copy':
1239      case 'create_edit':
1240      case 'create':
1241      case 'create_publish':
1242          // Generate available blogs list:
1243          $AdminUI->set_coll_list_params( 'blog_post_statuses', 'edit',
1244                          array( 'ctrl' => 'items', 'action' => 'new' ), NULL, '',
1245                          'return b2edit_reload( document.getElementById(\'item_checkchanges\'), \''.$dispatcher.'\', %s )' );
1246  
1247          // We don't check the following earlier, because we want the blog switching buttons to be available:
1248          if( ! blog_has_cats( $blog ) )
1249          {
1250              $error_message = T_('Since this blog has no categories, you cannot post into it.');
1251              if( $current_User->check_perm( 'blog_cats', 'edit', false, $blog ) )
1252              { // If current user has a permission to create a category
1253                  global $admin_url;
1254                  $error_message .= ' '.sprintf( T_('You must <a %s>create categories</a> first.'), 'href="'.$admin_url.'?ctrl=chapters&amp;blog='.$blog.'"');
1255              }
1256              $Messages->add( $error_message, 'error' );
1257              $action = 'nil';
1258              break;
1259          }
1260  
1261          /* NOBREAK */
1262  
1263      case 'edit':
1264      case 'edit_switchtab': // this gets set as action by JS, when we switch tabs
1265      case 'update_edit':
1266      case 'update': // on error
1267      case 'update_publish': // on error
1268          // Get tab ("simple" or "expert") from Request or UserSettings:
1269          $tab = $UserSettings->param_Request( 'tab', 'pref_edit_tab', 'string', NULL, true /* memorize */, true /* force */ );
1270  
1271          $AdminUI->add_menu_entries( 'items', get_item_edit_modes( $blog, $action, $dispatcher, $tab_switch_params ) );
1272  
1273          // Generate available blogs list:
1274          $AdminUI->set_coll_list_params( 'blog_ismember', 'view', array( 'ctrl' => 'items', 'filter' => 'restore' ) );
1275  
1276          switch( $action )
1277          {
1278              case 'edit':
1279              case 'edit_switchtab': // this gets set as action by JS, when we switch tabs
1280              case 'update_edit':
1281              case 'update': // on error
1282              case 'update_publish': // on error
1283                  if( $current_User->check_perm( 'item_post!CURSTATUS', 'delete', false, $edited_Item ) )
1284                  {    // User has permissions to delete this post
1285                      $AdminUI->global_icon( T_('Delete this post'), 'delete', '?ctrl=items&amp;action=delete&amp;post_ID='.$edited_Item->ID.'&amp;'.url_crumb('item'),
1286                           ' '.T_('Delete'), 4, 3, array(
1287                                   'onclick' => 'return confirm(\''.TS_('You are about to delete this post!\\nThis cannot be undone!').'\')',
1288                                   'style' => 'margin-right: 3ex;',    // Avoid misclicks by all means!
1289                           ) );
1290                  }
1291  
1292                  $AdminUI->global_icon( T_('Permanent link to full entry'), 'permalink', $edited_Item->get_permanent_url(),
1293                          ' '.T_('Permalink'), 4, 3, array(
1294                                   'style' => 'margin-right: 3ex',
1295                           ) );
1296                  break;
1297          }
1298  
1299          $AdminUI->global_icon( T_('Cancel editing!'), 'close', $redirect_to, T_('Cancel'), 4, 2 );
1300  
1301          init_tokeninput_js();
1302  
1303          break;
1304  
1305      case 'new_mass':
1306  
1307          $AdminUI->set_coll_list_params( 'blog_post_statuses', 'edit',
1308                          array( 'ctrl' => 'items', 'action' => 'new' ), NULL, '',
1309                          'return b2edit_reload( document.getElementById(\'item_checkchanges\'), \''.$dispatcher.'\', %s )' );
1310  
1311          // We don't check the following earlier, because we want the blog switching buttons to be available:
1312          if( ! blog_has_cats( $blog ) )
1313          {
1314              $error_message = T_('Since this blog has no categories, you cannot post into it.');
1315              if( $current_User->check_perm( 'blog_cats', 'edit', false, $blog ) )
1316              { // If current user has a permission to create a category
1317                  global $admin_url;
1318                  $error_message .= ' '.sprintf( T_('You must <a %s>create categories</a> first.'), 'href="'.$admin_url.'?ctrl=chapters&amp;blog='.$blog.'"');
1319              }
1320              $Messages->add( $error_message, 'error' );
1321              $action = 'nil';
1322              break;
1323          }
1324  
1325      break;
1326  
1327      case 'view':
1328          // We're displaying a SINGLE specific post:
1329          $item_ID = param( 'p', 'integer', true );
1330  
1331          $AdminUI->title_titlearea = T_('View post & comments');
1332  
1333          // Generate available blogs list:
1334          $AdminUI->set_coll_list_params( 'blog_ismember', 'view', array( 'ctrl' => 'items', 'tab' => $tab, 'filter' => 'restore' ) );
1335  
1336          $AdminUI->breadcrumbpath_add( sprintf( T_('Post #%s'), $item_ID ), '?ctrl=items&amp;blog='.$Blog->ID.'&amp;p='.$item_ID );
1337          $AdminUI->breadcrumbpath_add( T_('View post & comments'), '?ctrl=items&amp;blog='.$Blog->ID.'&amp;p='.$item_ID );
1338          break;
1339  
1340      case 'list':
1341          // We're displaying a list of posts:
1342  
1343          $AdminUI->title_titlearea = T_('Browse blog');
1344  
1345          // Generate available blogs list:
1346          $AdminUI->set_coll_list_params( 'blog_ismember', 'view', array( 'ctrl' => 'items', 'tab' => $tab, 'filter' => 'restore' ) );
1347  
1348          /*
1349           * Add sub menu entries:
1350           * We do this here instead of _header because we need to include all filter params into regenerate_url()
1351           */
1352          attach_browse_tabs();
1353  
1354          break;
1355  }
1356  
1357  if( !empty($tab) )
1358  {
1359      $AdminUI->append_path_level( $tab );
1360  
1361      if( in_array( $tab, array( 'expert', 'full', 'list', 'pages', 'intros', 'podcasts', 'links', 'ads' ) ) )
1362      { // Init JS to autcomplete the user logins
1363          init_autocomplete_login_js( 'rsc_url' );
1364      }
1365  }
1366  
1367  // Load the date picker style for _item_simple.form.php and _item_expert.form.php
1368  require_css( 'ui.datepicker.css' );
1369  // Load the appropriate blog navigation styles (including calendar, comment forms...):
1370  require_css( $rsc_url.'css/blog_base.css' ); // Default styles for the blog navigation
1371  // Load jquery ui css for tag autocomplete
1372  require_css( $rsc_url.'css/jquery/smoothness/jquery-ui.css' );
1373  require_js( 'communication.js' ); // auto requires jQuery
1374  init_plugins_js();
1375  
1376  // Load the appropriate ITEM/POST styles depending on the blog's skin:
1377  // It's possible that we have no Blog on the restricted admin interface, when current User doesn't have permission to any blog
1378  if( !empty( $Blog ) )
1379  { // set blog skin ID if the Blog is set
1380      $blog_sking_ID = $Blog->get_skin_ID();
1381      if( ! empty( $blog_sking_ID ) )
1382      {
1383          $SkinCache = & get_SkinCache();
1384          /**
1385           * @var Skin
1386           */
1387          $Skin = $SkinCache->get_by_ID( $blog_sking_ID );
1388          require_css( 'basic_styles.css', 'blog' ); // the REAL basic styles
1389          require_css( 'item_base.css', 'blog' ); // Default styles for the post CONTENT
1390          require_css( $skins_url.$Skin->folder.'/item.css' ); // fp> TODO: this needs to be a param... "of course" -- if none: else item_default.css ?
1391          // else: $item_css_url = $rsc_url.'css/item_base.css';
1392      }
1393      // else item_default.css ? is it still possible to have no skin set?
1394  }
1395  
1396  
1397  // Display <html><head>...</head> section! (Note: should be done early if actions do not redirect)
1398  $AdminUI->disp_html_head();
1399  
1400  // Display title, menu, messages, etc. (Note: messages MUST be displayed AFTER the actions)
1401  $AdminUI->disp_body_top( $mode != 'iframe' );    // do NOT display stupid messages in iframe (UGLY UGLY UGLY!!!!)
1402  
1403  
1404  /*
1405   * Display payload:
1406   */
1407  switch( $action )
1408  {
1409      case 'nil':
1410          // Do nothing
1411          break;
1412  
1413      case 'new_switchtab': // this gets set as action by JS, when we switch tabs
1414      case 'edit_switchtab': // this gets set as action by JS, when we switch tabs
1415          $bozo_start_modified = true;    // We want to start with a form being already modified
1416      case 'new':
1417      case 'copy':
1418      case 'create_edit':
1419      case 'create':
1420      case 'create_publish':
1421      case 'edit':
1422      case 'update_edit':
1423      case 'update':    // on error
1424      case 'update_publish':    // on error
1425          // Begin payload block:
1426          $AdminUI->disp_payload_begin();
1427  
1428          // We never allow HTML in titles, so we always encode and decode special chars.
1429          $item_title = htmlspecialchars_decode( $edited_Item->title );
1430  
1431          if( $Blog->get_setting( 'allow_html_post' ) )
1432          {    // HTML is allowed for this post, we have HTML in the DB and we can edit it:
1433              $item_content = $edited_Item->content;
1434          }
1435          else
1436          {    // HTML is disallowed for this post, content is encoded in DB and we need to decode it for editing:
1437              $item_content = htmlspecialchars_decode( $edited_Item->content );
1438          }
1439  
1440          // Format content for editing, if we were not already in editing...
1441          $Plugins_admin = & get_Plugins_admin();
1442          $edited_Item->load_Blog();
1443          $params = array( 'object_type' => 'Item', 'object_Blog' => & $edited_Item->Blog );
1444          $Plugins_admin->unfilter_contents( $item_title /* by ref */, $item_content /* by ref */, $edited_Item->get_renderers_validated(), $params );
1445  
1446          // Display VIEW:
1447          switch( $tab )
1448          {
1449              case 'simple':
1450                  $AdminUI->disp_view( 'items/views/_item_simple.form.php' );
1451                  break;
1452  
1453              case 'expert':
1454              default:
1455                  $AdminUI->disp_view( 'items/views/_item_expert.form.php' );
1456                  break;
1457          }
1458  
1459          // End payload block:
1460          $AdminUI->disp_payload_end();
1461          break;
1462  
1463  
1464      case 'new_mass':
1465          // Begin payload block:
1466          $AdminUI->disp_payload_begin();
1467  
1468          // We never allow HTML in titles, so we always encode and decode special chars.
1469          $item_title = htmlspecialchars_decode( $edited_Item->title );
1470  
1471          if( $Blog->get_setting( 'allow_html_post' ) )
1472          { // HTML is allowed for this post, we have HTML in the DB and we can edit it:
1473              $item_content = $edited_Item->content;
1474          }
1475          else
1476          { // HTML is disallowed for this post, content is encoded in DB and we need to decode it for editing:
1477              $item_content = htmlspecialchars_decode( $edited_Item->content );
1478          }
1479  
1480          // Format content for editing, if we were not already in editing...
1481          $Plugins_admin = & get_Plugins_admin();
1482          $edited_Item->load_Blog();
1483          $params = array( 'object_type' => 'Item', 'object_Blog' => & $edited_Item->Blog );
1484          $Plugins_admin->unfilter_contents( $item_title /* by ref */, $item_content /* by ref */, $edited_Item->get_renderers_validated(), $params );
1485  
1486          $AdminUI->disp_view( 'items/views/_item_mass.form.php' );
1487  
1488          // End payload block:
1489          $AdminUI->disp_payload_end();
1490  
1491          break;
1492  
1493  
1494      case 'view':
1495      case 'delete':
1496          // View a single post:
1497  
1498          // Memorize 'p' in case we reload while changing some display settings
1499          memorize_param( 'p', 'integer', NULL );
1500  
1501           // Begin payload block:
1502          $AdminUI->disp_payload_begin();
1503  
1504          // We use the "full" view for displaying single posts:
1505          $AdminUI->disp_view( 'items/views/_item_list_full.view.php' );
1506  
1507          // End payload block:
1508          $AdminUI->disp_payload_end();
1509  
1510          break;
1511  
1512      case 'history':
1513          memorize_param( 'action', 'string', NULL );
1514  
1515          // Begin payload block:
1516          $AdminUI->disp_payload_begin();
1517  
1518          // view:
1519          $AdminUI->disp_view( 'items/views/_item_history.view.php' );
1520  
1521          // End payload block:
1522          $AdminUI->disp_payload_end();
1523          break;
1524  
1525      case 'history_details':
1526          // Begin payload block:
1527          $AdminUI->disp_payload_begin();
1528  
1529          // view:
1530          $AdminUI->disp_view( 'items/views/_item_history_details.view.php' );
1531  
1532          // End payload block:
1533          $AdminUI->disp_payload_end();
1534          break;
1535  
1536      case 'history_compare':
1537          // Begin payload block:
1538          $AdminUI->disp_payload_begin();
1539  
1540          // view:
1541          $AdminUI->disp_view( 'items/views/_item_history_compare.view.php' );
1542  
1543          // End payload block:
1544          $AdminUI->disp_payload_end();
1545          break;
1546  
1547      case 'mass_edit' :
1548          // Begin payload block:
1549          $AdminUI->disp_payload_begin ();
1550  
1551          // view:
1552          $AdminUI->disp_view ( 'items/views/_item_mass_edit.view.php' );
1553  
1554          // End payload block:
1555          $AdminUI->disp_payload_end ();
1556          break;
1557  
1558      case 'make_posts_pre':
1559          // Make posts with selected images action:
1560  
1561          $FileRootCache = & get_FileRootCache();
1562          // getting root
1563          $root = param("root");
1564          global $fm_FileRoot;
1565          $fm_FileRoot = & $FileRootCache->get_by_ID($root, true);
1566  
1567          // Begin payload block:
1568          $AdminUI->disp_payload_begin();
1569          // Check that this action request is not a CSRF hacked request:
1570          $Session->assert_received_crumb( 'file' );
1571  
1572          $AdminUI->disp_view( 'items/views/_file_create_posts.form.php' );
1573          // End payload block:
1574          $AdminUI->disp_payload_end();
1575          break;
1576  
1577      case 'list':
1578      default:
1579          // Begin payload block:
1580          $AdminUI->disp_payload_begin();
1581  
1582          // fplanque> Note: this is depressing, but I have to put a table back here
1583          // just because IE supports standards really badly! :'(
1584          echo '<table class="browse" cellspacing="0" cellpadding="0" border="0"><tr>';
1585  
1586          echo '<td class="browse_left_col">';
1587  
1588              switch( $tab )
1589              {
1590                  case 'tracker':
1591                      // Display VIEW:
1592                      $AdminUI->disp_view( 'items/views/_item_list_track.view.php' );
1593                      break;
1594  
1595                  case 'full':
1596                      // Display VIEW:
1597                      $AdminUI->disp_view( 'items/views/_item_list_full.view.php' );
1598                      break;
1599  
1600                  case 'manual':
1601                      // Display VIEW:
1602                      $AdminUI->disp_view( 'items/views/_item_list_manual.view.php' );
1603                      break;
1604  
1605                  case 'list':
1606                  case 'pages':
1607                  case 'intros':
1608                  case 'podcasts':
1609                  default:
1610                      // Display VIEW:
1611                      $AdminUI->disp_view( 'items/views/_item_list_table.view.php' );
1612                      break;
1613              }
1614  
1615              // TODO: a specific field for the backoffice, at the bottom of the page
1616              // would be used for moderation rules.
1617              if( $Blog->get( 'notes' ) )
1618              {
1619                  $block_item_Widget = new Widget( 'block_item' );
1620                  $block_item_Widget->title = T_('Notes');
1621                  // show a quicklink to edit if user has permission:
1622  /* fp> TODO: use an action icon (will appear on the right)
1623                  if( $current_User->check_perm( 'blog_properties', 'edit', false, $blog ) )
1624                      $block_item_Widget->title .=    ' <a href="?ctrl=coll_settings&amp;tab=advanced&amp;blog='.$Blog->ID.'#ffield_blog_notes">'.get_icon( 'edit' ).'</a>';
1625  */
1626                  $block_item_Widget->disp_template_replaced( 'block_start' );
1627                  $Blog->disp( 'notes', 'htmlbody' );
1628                  $block_item_Widget->disp_template_replaced( 'block_end' );
1629              }
1630  
1631          echo '</td>';
1632  
1633          if( $tab != 'manual' )
1634          {
1635              echo '<td class="browse_right_col">';
1636                  // Display VIEW:
1637                  $AdminUI->disp_view( 'items/views/_item_list_sidebar.view.php' );
1638              echo '</td>';
1639          }
1640  
1641          echo '</tr></table>';
1642  
1643          // End payload block:
1644          $AdminUI->disp_payload_end();
1645          break;
1646  }
1647  
1648  // Display body bottom, debug info and close </html>:
1649  $AdminUI->disp_global_footer();
1650  
1651  ?>

title

Description

title

Description

title

Description

title

title

Body