b2evolution PHP Cross Reference Blogging Systems

Source: /inc/chapters/chapters.ctrl.php - 586 lines - 17820 bytes - Summary - Text - Print

Description: This file implements ther UI controler for chapters management. This file is part of the evoCore framework - {@link http://evocore.net/} See also {@link http://sourceforge.net/projects/evocms/}.

   1  <?php
   2  /**
   3   * This file implements ther UI controler for chapters management.
   4   *
   5   * This file is part of the evoCore framework - {@link http://evocore.net/}
   6   * See also {@link http://sourceforge.net/projects/evocms/}.
   7   *
   8   * @copyright (c)2003-2014 by Francois Planque - {@link http://fplanque.com/}
   9   *
  10   * {@internal License choice
  11   * - If you have received this file as part of a package, please find the license.txt file in
  12   *   the same folder or the closest folder above for complete license terms.
  13   * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
  14   *   then you must choose one of the following licenses before using the file:
  15   *   - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
  16   *   - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
  17   * }}
  18   *
  19   * @package admin
  20   *
  21   * @version $Id: chapters.ctrl.php 6136 2014-03-08 07:59:48Z manuel $
  22   */
  23  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  24  
  25  
  26  if( valid_blog_requested() )
  27  {
  28      $current_User->check_perm( 'blog_cats', 'edit', true, $blog );
  29      $edited_Blog = & $Blog;
  30  }
  31  else
  32  {
  33      $action = 'nil';
  34  }
  35  
  36  $restrict_title = T_('Cannot delete category');     //&laquo;%s&raquo;
  37  
  38  // This must be initialized to false before checking the delete restrictions
  39  $checked_delete = false;
  40  
  41  load_class( 'chapters/model/_chaptercache.class.php', 'ChapterCache' );
  42  $GenericCategoryCache = new ChapterCache();
  43  
  44  
  45  // Restrict to chapters of the specific blog:
  46  $subset_ID = $blog;
  47  
  48  $list_view_path = 'chapters/views/_chapter_list.view.php';
  49  $permission_to_edit = $current_User->check_perm( 'blog_cats', '', false, $blog );
  50  
  51  // The form will be on its own page:
  52  $form_below_list = false;
  53  $edit_view_path = 'chapters/views/_chapter.form.php';
  54  
  55  
  56  // ---- Below is a modified generic category list editor: -----
  57  
  58  
  59  // fp> this is an example of where we could benefit from controler classes which could be derived
  60  // fp> we basically need to add a "move" action.
  61  /*
  62  class Controler
  63  {
  64      method get_params() // and init object
  65      method do_action()
  66      method display_payload()
  67  }
  68  the $AdminUI->foo() structural calls would move to the dispatcher.
  69  */
  70  // fp> TODO: find 4 other cases before refactoring this way. (fp)
  71  
  72  param( 'action', 'string', 'list' );
  73  
  74  // Init fadeout result array:
  75  $result_fadeout = array();
  76  
  77  if( param( $GenericCategoryCache->dbIDname, 'integer', NULL, true, false, false ) )
  78  {
  79      if( ($edited_GenericCategory = & $GenericCategoryCache->get_by_ID( ${$GenericCategoryCache->dbIDname}, false, true, $subset_ID )) === false )
  80      {    // We could not find the element to edit:
  81          unset( $edited_GenericCategory );
  82          $Messages->add( sprintf( T_('Requested &laquo;%s&raquo; object does not exist any longer.'), T_('Category') ), 'error' );
  83          $action = 'nil';
  84      }
  85  }
  86  
  87  if( !is_null( param( $GenericCategoryCache->dbprefix.'parent_ID', 'integer', NULL ) ) )
  88  {
  89      $edited_parent_GenericElement = & $GenericCategoryCache->get_by_ID( ${$GenericCategoryCache->dbprefix.'parent_ID'}, false, true, $subset_ID );
  90      if( $edited_parent_GenericElement === false )
  91      { // Parent generic category doesn't exist any longer.
  92          unset( $GenericCategoryCache->dbIDname );
  93          $Messages->add( sprintf( T_('Requested &laquo;%s&raquo; object does not exist any longer.'), T_('Category') ), 'error' );
  94          $action = 'nil';
  95      }
  96  }
  97  
  98  // Init fadeout result array of IDs:
  99  $result_fadeout = array();
 100  
 101  /**
 102   * Check locked elements
 103   */
 104  if( !empty( $locked_IDs )
 105          && in_array( $action, array( 'edit', 'update', 'delete' ) )
 106          && in_array( $$GenericCategoryCache->dbIDname, $locked_IDs ) )
 107  {
 108      $Messages->add( T_('This element is locked and cannot be edited!') );
 109      $action = 'list';
 110  }
 111  
 112  // Check that action request is not a CSRF hacked request and user has permission for the action
 113  switch( $action )
 114  {
 115      case 'create':
 116      case 'update':
 117      case 'delete':
 118      case 'make_default':
 119      case 'set_meta':
 120      case 'unset_meta':
 121      case 'lock':
 122      case 'unlock':
 123          // Check that this action request is not a CSRF hacked request:
 124          $Session->assert_received_crumb( 'element' );
 125          /* NO BREAK */
 126      case 'new':
 127      case 'move':
 128      case 'edit':
 129          if( ! $permission_to_edit )
 130          {
 131              debug_die( 'No permission to edit' );
 132          }
 133          break;
 134  }
 135  
 136  
 137  /**
 138   * Get url to redirect after chapter editing
 139   *
 140   * @param string Redirect Page: 'front', 'manual', 'list'
 141   * @param integer Parent ID
 142   * @param integer Chapter ID
 143   * @return string URL
 144   */
 145  function get_chapter_redirect_url( $redirect_page, $parent_ID, $chapter_ID = 0 )
 146  {
 147      global $admin_url, $blog;
 148  
 149      if( $redirect_page == 'front' )
 150      { // Get Chapter for front page redirect
 151          if( empty( $chapter_ID ) )
 152          { // Chapter ID is invalid, redirect to chapters list
 153              $redirect_page = 'list';
 154          }
 155          else
 156          {
 157              $ChapterCache = & get_ChapterCache();
 158              $Chapter = & $ChapterCache->get_by_ID( $chapter_ID, false, false );
 159              if( $Chapter === false )
 160              { // Chapter doesn't exist anymore, redirect to chapters list
 161                  $redirect_page = 'list';
 162              }
 163          }
 164      }
 165  
 166      switch( $redirect_page )
 167      {
 168          case 'front':
 169              // Redirect to front-office
 170              $redirect_url = $Chapter->get_permanent_url( NULL, NULL, 1, NULL, '&' );
 171              break;
 172  
 173          case 'manual':
 174              // Redirect to manual pages
 175              $redirect_url = $admin_url.'?ctrl=items&blog='.$blog.'&tab=manual';
 176              if( !empty( $parent_ID ) )
 177              { // Open parent category to display new created category
 178                  $redirect_url .= '&cat_ID='.$parent_ID;
 179              }
 180              break;
 181  
 182          default: // 'list'
 183              // Redirect to chapters list
 184              $redirect_url = $admin_url.'?ctrl=chapters&blog='.$blog;
 185              break;
 186      }
 187  
 188      return $redirect_url;
 189  }
 190  
 191  
 192  /**
 193   * Perform action:
 194   */
 195  switch( $action )
 196  {
 197      case 'new':
 198          // New action
 199  
 200          $edited_GenericCategory = & $GenericCategoryCache->new_obj( NULL, $subset_ID );
 201          $edited_GenericCategory->blog_ID = $edited_Blog->ID;
 202  
 203          if( isset( $edited_parent_GenericElement ) )
 204          {
 205              $edited_GenericCategory->parent_ID = $edited_parent_GenericElement->ID;
 206              $edited_GenericCategory->parent_name = $edited_parent_GenericElement->name;
 207          }
 208          else
 209          {
 210              $edited_GenericCategory->parent_name = T_('Root');
 211          }
 212  
 213          break;
 214  
 215  
 216      case 'move': // EXTENSION
 217           if( ! $Settings->get('allow_moving_chapters') )
 218           {
 219              debug_die( 'Moving of chapters is disabled' );
 220          }
 221          /* NO BREAK */
 222      case 'edit':
 223          // Edit element form...:
 224          // Make sure we got an ID:
 225          param( $GenericCategoryCache->dbIDname, 'integer', true );
 226  
 227          // Get the page number we come from:
 228          $previous_page = param( 'results'.$GenericCategoryCache->dbprefix.'page', 'integer', 1, true );
 229  
 230          break;
 231  
 232  
 233      case 'create':
 234          // Insert new element...:
 235  
 236          $edited_GenericCategory = & $GenericCategoryCache->new_obj( NULL, $subset_ID );
 237  
 238          // load data from request
 239          if( $edited_GenericCategory->load_from_Request() )
 240          {    // We could load data from form without errors:
 241              // Insert in DB:
 242              if( $edited_GenericCategory->dbinsert() !== false )
 243              {
 244                  $Messages->add( T_('New chapter created.'), 'success' );
 245                  // Add the ID of the new element to the result fadeout
 246                  $result_fadeout[$edited_GenericCategory->dbIDname][] = $edited_GenericCategory->ID;
 247                  $action = 'list';
 248                  // We want to highlight the edited object on next list display:
 249                  $Session->set( 'fadeout_array', array($edited_GenericCategory->ID) );
 250  
 251                  // Redirect so that a reload doesn't write to the DB twice:
 252                  $redirect_to = get_chapter_redirect_url( param( 'redirect_page', 'string', '' ), $edited_GenericCategory->parent_ID, $edited_GenericCategory->ID );
 253                  header_redirect( $redirect_to, 303 ); // Will EXIT
 254                  // We have EXITed already at this point!!
 255              }
 256          }
 257          break;
 258  
 259  
 260      case 'update':
 261          // Make sure we got an ID:
 262  
 263          param( $GenericCategoryCache->dbIDname, 'integer', true );
 264  
 265          // LOAD FORM DATA:
 266          if( $edited_GenericCategory->load_from_Request() )
 267          {    // We could load data from form without errors:
 268              // Update in DB:
 269              if( $edited_GenericCategory->dbupdate() !== false )
 270              {
 271                  $Messages->add( T_('Chapter updated.'), 'success' ); //ToDO change htis
 272              }
 273              // Add the ID of the updated element to the result fadeout
 274              $result_fadeout[$edited_GenericCategory->dbIDname][] = $edited_GenericCategory->ID;
 275  
 276              // We want to highlight the edited object on next list display:
 277              $Session->set( 'fadeout_array', array($edited_GenericCategory->ID));
 278  
 279              // Redirect so that a reload doesn't write to the DB twice:
 280              $redirect_to = get_chapter_redirect_url( param( 'redirect_page', 'string', '' ), $edited_GenericCategory->parent_ID, $edited_GenericCategory->ID );
 281              header_redirect( $redirect_to, 303 ); // Will EXIT
 282              // We have EXITed already at this point!!
 283          }
 284          else
 285          {
 286              // Get the page number we come from:
 287              $previous_page = param( 'results'.$GenericCategoryCache->dbprefix.'page', 'integer', 1, true );
 288          }
 289          break;
 290  
 291  
 292      case 'update_move':
 293          // Check that this action request is not a CSRF hacked request:
 294          $Session->assert_received_crumb( 'element' );
 295  
 296          // EXTENSION
 297          if( ! $Settings->get('allow_moving_chapters') )
 298          {
 299              debug_die( 'Moving of chapters is disabled' );
 300          }
 301  
 302          // Make sure we got an ID:
 303          param( $GenericCategoryCache->dbIDname, 'integer', true );
 304  
 305          // Control permission to edit source blog:
 306          $edited_Blog = & $edited_GenericCategory->get_Blog();
 307          if( ! $current_User->check_perm( 'blog_cats', '', false, $edited_Blog->ID ) )
 308          {
 309              debug_die( 'No permission to edit source collection.' );
 310              /* die */
 311          }
 312  
 313          // Control permission to edit destination blog:
 314          param( 'cat_coll_ID', 'integer', true );
 315          if( ! $current_User->check_perm( 'blog_cats', '', false, $cat_coll_ID ) )
 316          {
 317              // fp> TODO: prevent move in UI.
 318              $Messages->add( 'No permission to edit destination blog.', 'error' );    // NO TRANS b/c temporary
 319              break;
 320          }
 321  
 322          if( $cat_coll_ID == $edited_Blog->ID )
 323          {
 324              $Messages->add( T_('Category has not been moved.'), 'note' );
 325              break;
 326          }
 327  
 328          // Do the actual move! (This WILL reset the cache!)
 329          $GenericCategoryCache->move_Chapter_subtree( $edited_GenericCategory->ID, $subset_ID, $cat_coll_ID );
 330  
 331          $dest_Blog = & $BlogCache->get_by_ID( $cat_coll_ID );
 332          $Messages->add( /* TRANS: first %s is the moved category's name, the second one the new parent category */ sprintf( T_('The category &laquo;%s&raquo; has been moved (with children) to &laquo;%s&raquo;\'s root. You may want to nest it in another parent category below...'), $edited_GenericCategory->dget('name'), $dest_Blog->dget( 'shortname' )  ), 'success' );
 333  
 334          header_redirect( url_add_param( $admin_url, 'ctrl=chapters&action=edit&blog='.$cat_coll_ID.'&cat_ID='.$cat_ID, '&' ) );    // will save $Messages
 335          /* EXIT */
 336  
 337          // In case we changed the redirect someday:
 338          unset($edited_GenericCategory);
 339          $cat_ID = NULL;
 340          $action = 'list';
 341          break;
 342  
 343  
 344      case 'delete':
 345          // Delete entry:
 346  
 347          param( $GenericCategoryCache->dbIDname, 'integer', true );
 348  
 349          if( param( 'confirm', 'integer', 0 ) )
 350          { // confirmed, Delete from DB:
 351              $parent_ID = $edited_GenericCategory->parent_ID;
 352              $msg = sprintf( T_('Chapter &laquo;%s&raquo; deleted.'), $edited_GenericCategory->dget( 'name' ) );
 353              $GenericCategoryCache->dbdelete_by_ID( $edited_GenericCategory->ID );
 354              unset($edited_GenericCategory);
 355              forget_param( $GenericCategoryCache->dbIDname );
 356              $Messages->add( $msg, 'success' );
 357  
 358              // Redirect so that a reload doesn't write to the DB twice:
 359              $redirect_to = get_chapter_redirect_url( param( 'redirect_page', 'string', '' ), $parent_ID );
 360              header_redirect( $redirect_to, 303 ); // Will EXIT
 361              // We have EXITed already at this point!!
 362          }
 363          else
 364          {    // not confirmed, Check for restrictions:
 365              // TODO: dh> allow to delete a category which has links (and unbreak those after confirmation).
 366              // Get the page number we come from:
 367              $previous_page = param( 'results_'.$GenericCategoryCache->dbprefix.'page', 'integer', 1, true );
 368              if( ! $edited_GenericCategory->check_delete( sprintf( T_('Cannot delete element &laquo;%s&raquo;'), $edited_GenericCategory->dget( 'name' ) ) ) )
 369              {    // There are restrictions:
 370                  $action = 'edit';
 371              }
 372          }
 373          break;
 374  
 375      case 'make_default':
 376          // Make category as default
 377  
 378          $edited_Blog->set_setting( 'default_cat_ID', $edited_GenericCategory->ID );
 379          $edited_Blog->dbsave();
 380          break;
 381  
 382      case 'set_meta':
 383          // Make category as meta category
 384  
 385          // Start serializable transaction because a category can be meta only if it has no posts
 386          $DB->begin( 'SERIALIZABLE' );
 387  
 388          // Category can be set as meta if it has no posts
 389          $result = !$edited_GenericCategory->has_posts();
 390          $edited_GenericCategory->set( 'meta', '1' );
 391  
 392          // Save category
 393          if( $result && $edited_GenericCategory->dbsave() )
 394          { // Category has no posts and it was saved successful
 395              $Messages->add( sprintf( T_('The category &laquo;%s&raquo; was made as meta category.'), $edited_GenericCategory->dget('name') ), 'success' );
 396              $DB->commit();
 397          }
 398          else
 399          {
 400              $Messages->add( sprintf( T_('The category &laquo;%s&raquo; cannot be set as meta category. You must remove the posts it contains first.'), $edited_GenericCategory->dget('name') ) );
 401              $DB->rollback();
 402          }
 403  
 404          // Redirect so that a reload doesn't write to the DB twice:
 405          header_redirect( '?ctrl=chapters&blog='.$blog, 303 ); // Will EXIT
 406          // We have EXITed already at this point!!
 407          break;
 408  
 409      case 'unset_meta':
 410          // Revert to simple category
 411  
 412          $edited_GenericCategory->set( 'meta', '0' );
 413          if( $edited_GenericCategory->dbsave() )
 414          {
 415              $Messages->add( sprintf( T_('The category &laquo;%s&raquo; was reverted from meta category.'), $edited_GenericCategory->dget('name') ), 'success' );
 416          }
 417          else
 418          {
 419              $Messages->add( sprintf( T_('The category &laquo;%s&raquo; couldn\'t be reverted from meta category.'), $edited_GenericCategory->dget('name') ), 'error' );
 420          }
 421  
 422          // Redirect so that a reload doesn't write to the DB twice:
 423          header_redirect( '?ctrl=chapters&blog='.$blog, 303 ); // Will EXIT
 424          // We have EXITed already at this point!!
 425          break;
 426  
 427      case 'lock':
 428          // Lock category
 429  
 430          $edited_GenericCategory->set( 'lock', '1' );
 431          if( $edited_GenericCategory->dbsave() )
 432          {
 433              $Messages->add( sprintf( T_('The category &laquo;%s&raquo; was locked.'), $edited_GenericCategory->dget('name') ), 'success' );
 434          }
 435          else
 436          {
 437              $Messages->add( sprintf( T_('The category &laquo;%s&raquo; couldn\'t be locked.'), $edited_GenericCategory->dget('name') ), 'error' );
 438          }
 439  
 440          // Redirect so that a reload doesn't write to the DB twice:
 441          header_redirect( '?ctrl=chapters&blog='.$blog, 303 ); // Will EXIT
 442          // We have EXITed already at this point!!
 443          break;
 444  
 445      case 'unlock':
 446          // Unlock category
 447  
 448          $edited_GenericCategory->set( 'lock', '0' );
 449          if( $edited_GenericCategory->dbsave() )
 450          {
 451              $Messages->add( sprintf( T_('The category &laquo;%s&raquo; was unlocked.'), $edited_GenericCategory->dget('name') ), 'success' );
 452          }
 453          else
 454          {
 455              $Messages->add( sprintf( T_('The category &laquo;%s&raquo; couldn\'t be unlocked.'), $edited_GenericCategory->dget('name') ), 'error' );
 456          }
 457  
 458          // Redirect so that a reload doesn't write to the DB twice:
 459          header_redirect( '?ctrl=chapters&blog='.$blog, 303 ); // Will EXIT
 460          // We have EXITed already at this point!!
 461          break;
 462  }
 463  
 464  /**
 465   * Display page header, menus & messages:
 466   */
 467  $AdminUI->set_coll_list_params( 'blog_cats', 'edit',
 468          array( 'ctrl' => $ctrl ),    NULL );
 469  
 470  
 471  /**
 472   * We need make this call to build menu for all modules
 473   */
 474  $AdminUI->set_path( 'items' );
 475  
 476  /*
 477   * Add sub menu entries:
 478   * We do this here instead of _header because we need to include all filter params into regenerate_url()
 479   */
 480  attach_browse_tabs();
 481  
 482  $AdminUI->set_path( 'items', 'settings', 'chapters' );
 483  
 484  $AdminUI->breadcrumbpath_init();
 485  $AdminUI->breadcrumbpath_add( T_('Contents'), '?ctrl=items&amp;blog=$blog$&amp;tab=full&amp;filter=restore' );
 486  $AdminUI->breadcrumbpath_add( T_('Settings'), '?ctrl=chapters&amp;blog=$blog$' );
 487  $AdminUI->breadcrumbpath_add( T_('Categories'), '?ctrl=chapters&amp;blog=$blog$' );
 488  
 489  // Display <html><head>...</head> section! (Note: should be done early if actions do not redirect)
 490  $AdminUI->disp_html_head();
 491  
 492  // Display title, menu, messages, etc. (Note: messages MUST be displayed AFTER the actions)
 493  $AdminUI->disp_body_top();
 494  
 495  
 496  /**
 497   * Display payload:
 498   */
 499  switch( $action )
 500  {
 501      case 'nil':
 502          // Do nothing
 503          break;
 504  
 505      case 'move':
 506          // EXTENSION TO GENERIC:
 507          // Move to another blog:
 508          // Begin payload block:
 509          $AdminUI->disp_payload_begin();
 510  
 511          $AdminUI->disp_view( 'chapters/views/_chapter_move.form.php' );
 512  
 513          // End payload block:
 514          $AdminUI->disp_payload_end();
 515          break;
 516  
 517      case 'new':
 518      case 'copy':
 519      case 'create':
 520      case 'edit':
 521      case 'update':
 522      case 'delete':
 523          // Begin payload block:
 524          $AdminUI->disp_payload_begin();
 525  
 526          param( 'redirect_page', 'string', '', true );
 527  
 528          if( $action == 'delete' )
 529          {    // We need to ask for confirmation:
 530              $edited_GenericCategory->confirm_delete(
 531                      sprintf( T_('Delete element &laquo;%s&raquo;?'),  $edited_GenericCategory->dget( 'name' ) ),
 532                      'element', $action, get_memorized( 'action' ) );
 533          }
 534  
 535          if( $form_below_list )
 536          {
 537              // Display list VIEW before form view:
 538              if( !empty( $list_view_path ) )
 539              {
 540                  $AdminUI->disp_view( $list_view_path );
 541              }
 542              else
 543              {
 544                  $AdminUI->disp_view( 'generic/_generic_recursive_list.inc.php' );
 545              }
 546          }
 547  
 548          // Display category edit form:
 549          if( !empty( $edit_view_path ) )
 550          {
 551              $AdminUI->disp_view( $edit_view_path );
 552          }
 553          else
 554          {
 555              $AdminUI->disp_view( 'generic/_generic_category.form.php' );
 556          }
 557  
 558          // End payload block:
 559          $AdminUI->disp_payload_end();
 560          break;
 561  
 562      case 'list':
 563      default:
 564          // Begin payload block:
 565          $AdminUI->disp_payload_begin();
 566  
 567          // Display list VIEW:
 568          if( !empty( $list_view_path ) )
 569          {
 570              $AdminUI->disp_view( $list_view_path );
 571          }
 572          else
 573          {
 574              $AdminUI->disp_view( 'generic/_generic_recursive_list.inc.php' );
 575          }
 576  
 577          // End payload block:
 578          $AdminUI->disp_payload_end();
 579          break;
 580  }
 581  
 582  
 583  // Display body bottom, debug info and close </html>:
 584  $AdminUI->disp_global_footer();
 585  
 586  ?>

title

Description

title

Description

title

Description

title

title

Body