Textpattern PHP Cross Reference Content Management Systems

Source: /textpattern/include/txp_page.php - 392 lines - 11187 bytes - Summary - Text - Print

Description: Pages panel.

   1  <?php
   2  
   3  /*
   4   * Textpattern Content Management System
   5   * http://textpattern.com
   6   *
   7   * Copyright (C) 2005 Dean Allen
   8   * Copyright (C) 2016 The Textpattern Development Team
   9   *
  10   * This file is part of Textpattern.
  11   *
  12   * Textpattern is free software; you can redistribute it and/or
  13   * modify it under the terms of the GNU General Public License
  14   * as published by the Free Software Foundation, version 2.
  15   *
  16   * Textpattern is distributed in the hope that it will be useful,
  17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19   * GNU General Public License for more details.
  20   *
  21   * You should have received a copy of the GNU General Public License
  22   * along with Textpattern. If not, see <http://www.gnu.org/licenses/>.
  23   */
  24  
  25  /**
  26   * Pages panel.
  27   *
  28   * @package Admin\Page
  29   */
  30  
  31  if (!defined('txpinterface')) {
  32      die('txpinterface is undefined.');
  33  }
  34  
  35  if ($event == 'page') {
  36      require_privs('page');
  37  
  38      bouncer($step, array(
  39          'page_edit'   => false,
  40          'page_save'   => true,
  41          'page_delete' => true,
  42          'tagbuild'    => false,
  43      ));
  44  
  45      switch (strtolower($step)) {
  46          case '':
  47              page_edit();
  48              break;
  49          case 'page_edit':
  50              page_edit();
  51              break;
  52          case 'page_save':
  53              page_save();
  54              break;
  55          case 'page_delete':
  56              page_delete();
  57              break;
  58          case 'page_new':
  59              page_new();
  60              break;
  61          case 'tagbuild':
  62              echo page_tagbuild();
  63              break;
  64      }
  65  }
  66  
  67  /**
  68   * The main Page editor panel.
  69   *
  70   * @param string|array $message The activity message
  71   */
  72  
  73  function page_edit($message = '')
  74  {
  75      global $event, $step;
  76  
  77      pagetop(gTxt('edit_pages'), $message);
  78  
  79      extract(array_map('assert_string', gpsa(array(
  80          'copy',
  81          'save_error',
  82          'savenew',
  83      ))));
  84  
  85      $name = sanitizeForPage(assert_string(gps('name')));
  86      $newname = sanitizeForPage(assert_string(gps('newname')));
  87  
  88      if ($step == 'page_delete' || empty($name) && $step != 'page_new' && !$savenew) {
  89          $name = safe_field("page", 'txp_section', "name = 'default'");
  90      } elseif (((($copy || $savenew) && $newname) || ($newname && ($newname != $name))) && !$save_error) {
  91          $name = $newname;
  92      }
  93  
  94      $titleblock = inputLabel(
  95          'new_page',
  96          fInput('text', 'newname', $name, 'input-medium', '', '', INPUT_MEDIUM, '', 'new_page', false, true),
  97          'page_name',
  98          array('', 'instructions_page_name'),
  99          array('class' => 'txp-form-field name')
 100      );
 101  
 102      if ($name === '') {
 103          $titleblock .= hInput('savenew', 'savenew');
 104      } else {
 105          $titleblock .= hInput('name', $name);
 106      }
 107  
 108      $titleblock .= eInput('page').sInput('page_save');
 109  
 110      $html = (!$save_error) ? fetch('user_html', 'txp_page', 'name', $name) : gps('html');
 111  
 112      echo n.'<div class="txp-layout">'.
 113          n.tag(
 114              hed(gTxt('tab_pages'), 1, array('class' => 'txp-heading')),
 115              'div', array('class' => 'txp-layout-1col')
 116          );
 117  
 118      // Pages create/switcher column.
 119  
 120      $actionsExtras = '';
 121  
 122      if ($name) {
 123          $actionsExtras .= href('<span class="ui-icon ui-icon-copy"></span> '.gTxt('duplicate'), '#', array(
 124              'class'     => 'txp-clone',
 125              'data-form' => 'page_form',
 126          ));
 127      }
 128  
 129      $actions = graf(
 130          sLink('page', 'page_new', '<span class="ui-icon ui-extra-icon-new-document"></span> '.gTxt('create_new_page'), 'txp-new').
 131          $actionsExtras,
 132          array('class' => 'txp-actions txp-actions-inline')
 133      );
 134  
 135      $buttons = graf(
 136          tag_void('input', array(
 137              'class'  => 'publish',
 138              'type'   => 'submit',
 139              'method' => 'post',
 140              'value'  =>  gTxt('save'),
 141          )), ' class="txp-save"'
 142      );
 143  
 144      echo n.tag(
 145          page_list($name).n,
 146          'div', array(
 147              'class' => 'txp-layout-4col-alt',
 148              'id'    => 'content_switcher',
 149              'role'  => 'region',
 150          )
 151      );
 152  
 153      // Pages code columm.
 154  
 155      echo n.tag(
 156          form(
 157              $actions.
 158              $titleblock.
 159              inputLabel(
 160                  'html',
 161                  '<textarea class="code" id="html" name="html" cols="'.INPUT_LARGE.'" rows="'.TEXTAREA_HEIGHT_LARGE.'" dir="ltr">'.txpspecialchars($html).'</textarea>',
 162                  array(
 163                      'page_code',
 164                      n.href('<span class="ui-icon ui-extra-icon-code"></span> '.gTxt('tagbuilder'), '#', array('class' => 'txp-tagbuilder-dialog')),
 165                  ),
 166                  array('', 'instructions_page_code'),
 167                  array('class' => 'txp-form-field'),
 168                  array('div', 'div')
 169              ).
 170              $buttons
 171              , '', '', 'post', '', '', 'page_form'),
 172          'div', array(
 173              'class' => 'txp-layout-4col-3span',
 174              'id'    => 'main_content',
 175              'role'  => 'region',
 176          )
 177      );
 178  
 179      // Tag builder dialog.
 180      echo n.tag(
 181          page_tagbuild(),
 182          'div', array(
 183              'class'      => 'txp-tagbuilder-content',
 184              'id'         => 'tagbuild_links',
 185              'aria-label' => gTxt('tagbuilder'),
 186              'title'      => gTxt('tagbuilder'),
 187      ));
 188  
 189      echo n.'</div>'; // End of .txp-layout.
 190  }
 191  
 192  /**
 193   * Renders a list of page templates.
 194   *
 195   * @param  string $current The selected template
 196   * @return string HTML
 197   */
 198  
 199  function page_list($current)
 200  {
 201      $out = array();
 202      $protected = safe_column("DISTINCT page", 'txp_section', "1 = 1") + array('error_default');
 203  
 204      $criteria = 1;
 205      $criteria .= callback_event('admin_criteria', 'page_list', 0, $criteria);
 206  
 207      $rs = safe_rows_start("name", 'txp_page', "$criteria ORDER BY name ASC");
 208  
 209      if ($rs) {
 210          while ($a = nextRow($rs)) {
 211              extract($a);
 212              $active = ($current === $name);
 213  
 214              $edit = eLink('page', '', 'name', $name, $name);
 215  
 216              if (!in_array($name, $protected)) {
 217                  $edit .= dLink('page', 'page_delete', 'name', $name);
 218              }
 219  
 220              $out[] = tag($edit, 'li', array(
 221                  'class' => $active ? 'active' : '',
 222              ));
 223          }
 224  
 225          $out = tag(join(n, $out), 'ul', array(
 226              'class' => 'switcher-list',
 227          ));
 228  
 229          return wrapGroup('all_pages', $out, 'all_pages');
 230      }
 231  }
 232  
 233  /**
 234   * Deletes a page template.
 235   */
 236  
 237  function page_delete()
 238  {
 239      $name = ps('name');
 240      $count = safe_count('txp_section', "page = '".doSlash($name)."'");
 241      $message = '';
 242  
 243      if ($name == 'error_default') {
 244          return page_edit();
 245      }
 246  
 247      if ($count) {
 248          $message = array(gTxt('page_used_by_section', array('{name}' => $name, '{count}' => $count)), E_WARNING);
 249      } else {
 250          if (safe_delete('txp_page', "name = '".doSlash($name)."'")) {
 251              callback_event('page_deleted', '', 0, $name);
 252              $message = gTxt('page_deleted', array('{name}' => $name));
 253          }
 254      }
 255  
 256      page_edit($message);
 257  }
 258  
 259  /**
 260   * Saves or clones a page template.
 261   */
 262  
 263  function page_save()
 264  {
 265      extract(doSlash(array_map('assert_string', psa(array(
 266          'savenew',
 267          'html',
 268          'copy',
 269      )))));
 270  
 271      $name = sanitizeForPage(assert_string(ps('name')));
 272      $newname = sanitizeForPage(assert_string(ps('newname')));
 273  
 274      $save_error = false;
 275      $message = '';
 276  
 277      if (!$newname) {
 278          $message = array(gTxt('page_name_invalid'), E_ERROR);
 279          $save_error = true;
 280      } else {
 281          if ($copy && ($name === $newname)) {
 282              $newname .= '_copy';
 283              $_POST['newname'] = $newname;
 284          }
 285  
 286          $exists = safe_field("name", 'txp_page', "name = '".doSlash($newname)."'");
 287  
 288          if ($newname !== $name && $exists !== false) {
 289              $message = array(gTxt('page_already_exists', array('{name}' => $newname)), E_ERROR);
 290              if ($savenew) {
 291                  $_POST['newname'] = '';
 292              }
 293  
 294              $save_error = true;
 295          } else {
 296              if ($savenew or $copy) {
 297                  if ($newname) {
 298                      if (safe_insert('txp_page', "name = '".doSlash($newname)."', user_html = '$html'")) {
 299                          update_lastmod('page_created', compact('newname', 'name', 'html'));
 300                          $message = gTxt('page_created', array('{name}' => $newname));
 301                      } else {
 302                          $message = array(gTxt('page_save_failed'), E_ERROR);
 303                          $save_error = true;
 304                      }
 305                  } else {
 306                      $message = array(gTxt('page_name_invalid'), E_ERROR);
 307                      $save_error = true;
 308                  }
 309              } else {
 310                  if (safe_update('txp_page', "user_html = '$html', name = '".doSlash($newname)."'", "name = '".doSlash($name)."'")) {
 311                      safe_update('txp_section', "page = '".doSlash($newname)."'", "page = '".doSlash($name)."'");
 312                      update_lastmod('page_saved', compact('newname', 'name', 'html'));
 313                      $message = gTxt('page_updated', array('{name}' => $name));
 314                  } else {
 315                      $message = array(gTxt('page_save_failed'), E_ERROR);
 316                      $save_error = true;
 317                  }
 318              }
 319          }
 320      }
 321  
 322      if ($save_error === true) {
 323          $_POST['save_error'] = '1';
 324      } else {
 325          callback_event('page_saved', '', 0, $name, $newname);
 326      }
 327  
 328      page_edit($message);
 329  }
 330  
 331  /**
 332   * Directs requests to page_edit() armed with a 'page_new' step.
 333   *
 334   * @see page_edit()
 335   */
 336  
 337  function page_new()
 338  {
 339      page_edit();
 340  }
 341  
 342  /**
 343   * Return a list of tag builder tags.
 344   *
 345   * @return HTML
 346   */
 347  
 348  function page_tagbuild()
 349  {
 350      $listActions = graf(
 351          href('<span class="ui-icon ui-icon-arrowthickstop-1-s"></span> '.gTxt('expand_all'), '#', array(
 352              'class'         => 'txp-expand-all',
 353              'aria-controls' => 'tagbuild_links',
 354          )).
 355          href('<span class="ui-icon ui-icon-arrowthickstop-1-n"></span> '.gTxt('collapse_all'), '#', array(
 356              'class'         => 'txp-collapse-all',
 357              'aria-controls' => 'tagbuild_links',
 358          )), array('class' => 'txp-actions')
 359      );
 360  
 361      // Format of each entry is popTagLink -> array ( gTxt() string, class/ID).
 362      $tagbuild_items = array(
 363          'page_article'     => array('page_article_hed','article-tags'),
 364          'page_article_nav' => array('page_article_nav_hed', 'article-nav-tags'),
 365          'page_nav'         => array('page_nav_hed', 'nav-tags'),
 366          'page_xml'         => array('page_xml_hed', 'xml-tags'),
 367          'page_misc'        => array('page_misc_hed', 'misc-tags'),
 368          'page_file'        => array('page_file_hed', 'file-tags'),
 369      );
 370  
 371      $tagbuild_links = '';
 372  
 373      foreach ($tagbuild_items as $tb => $item) {
 374          $tagbuild_links .= wrapRegion($item[1].'_group', taglinks($tb), $item[1], $item[0], 'page_'.$item[1]);
 375      }
 376  
 377      return $listActions.$tagbuild_links;
 378  }
 379  
 380  /**
 381   * Renders a list of tag builder options.
 382   *
 383   * @param  string $type
 384   * @return HTML
 385   * @access private
 386   * @see    popTagLinks()
 387   */
 388  
 389  function taglinks($type)
 390  {
 391      return popTagLinks($type);
 392  }

title

Description

title

Description

title

Description

title

title

Body