Textpattern PHP Cross Reference Content Management Systems

Source: /textpattern/include/txp_form.php - 599 lines - 17387 bytes - Summary - Text - Print

Description: Forms 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   * Forms panel.
  27   *
  28   * @package Admin\Form
  29   */
  30  
  31  if (!defined('txpinterface')) {
  32      die('txpinterface is undefined.');
  33  }
  34  
  35  /**
  36   * List of essential forms.
  37   *
  38   * @global array $essential_forms
  39   */
  40  
  41  $essential_forms = array(
  42      'comments',
  43      'comments_display',
  44      'comment_form',
  45      'default',
  46      'plainlinks',
  47      'files',
  48  );
  49  
  50  /**
  51   * List of form types.
  52   *
  53   * @global array $form_types
  54   */
  55  
  56  $form_types = array(
  57      'article'  => gTxt('article'),
  58      'misc'     => gTxt('misc'),
  59      'comment'  => gTxt('comment'),
  60      'category' => gTxt('category'),
  61      'file'     => gTxt('file'),
  62      'link'     => gTxt('link'),
  63      'section'  => gTxt('section'),
  64  );
  65  
  66  if ($event == 'form') {
  67      require_privs('form');
  68  
  69      bouncer($step, array(
  70          'form_edit'       => false,
  71          'form_create'     => false,
  72          'form_delete'     => true,
  73          'form_multi_edit' => true,
  74          'form_save'       => true,
  75          'tagbuild'        => false,
  76      ));
  77  
  78      switch (strtolower($step)) {
  79          case '':
  80              form_edit();
  81              break;
  82          case 'form_edit':
  83              form_edit();
  84              break;
  85          case 'form_create':
  86              form_create();
  87              break;
  88          case 'form_delete':
  89              form_delete();
  90              break;
  91          case 'form_multi_edit':
  92              form_multi_edit();
  93              break;
  94          case 'form_save':
  95              form_save();
  96              break;
  97          case 'tagbuild':
  98              echo form_tagbuild();
  99              break;
 100      }
 101  }
 102  
 103  /**
 104   * Renders a list of form templates.
 105   *
 106   * This function returns a list of form templates, wrapped in a multi-edit
 107   * form widget.
 108   *
 109   * @param  string $curname The selected form
 110   * @return string HTML
 111   */
 112  
 113  function form_list($curname)
 114  {
 115      global $essential_forms, $form_types;
 116  
 117      $criteria = 1;
 118      $criteria .= callback_event('admin_criteria', 'form_list', 0, $criteria);
 119  
 120      $rs = safe_rows_start(
 121          "name, type",
 122          'txp_form',
 123          "$criteria ORDER BY FIELD(type, ".join(',', quote_list(array_keys($form_types))).") ASC, name ASC"
 124      );
 125  
 126      if ($rs) {
 127          $prev_type = null;
 128          $group_out = array();
 129  
 130          while ($a = nextRow($rs)) {
 131              extract($a);
 132              $active = ($curname === $name);
 133  
 134              if ($prev_type !== $type) {
 135                  if ($prev_type !== null) {
 136                      $group_out = tag(n.join(n, $group_out).n, 'ul', array(
 137                          'class' => 'switcher-list',
 138                      ));
 139  
 140                      $out[] = wrapRegion($prev_type.'_forms_group', $group_out, 'form_'.$prev_type, $form_types[$prev_type], 'form_'.$prev_type);
 141                  }
 142  
 143                  $prev_type = $type;
 144                  $group_out = array();
 145              }
 146  
 147              $editlink = eLink('form', 'form_edit', 'name', $name, $name);
 148  
 149              if (!in_array($name, $essential_forms)) {
 150                  $modbox = span(
 151                      checkbox('selected_forms[]', txpspecialchars($name), false), array('class' => 'switcher-action'));
 152              } else {
 153                  $modbox = '';
 154              }
 155  
 156              $group_out[] = tag(n.$modbox.$editlink.n, 'li', array(
 157                  'class' => $active ? 'active' : '',
 158              ));
 159          }
 160  
 161          if ($prev_type !== null) {
 162              $group_out = tag(n.join(n, $group_out).n, 'ul', array(
 163                  'class' => 'switcher-list',
 164              ));
 165  
 166              $out[] = wrapRegion($prev_type.'_forms_group', $group_out, 'form_'.$prev_type, $form_types[$prev_type], 'form_'.$prev_type);
 167          }
 168  
 169          $methods = array(
 170              'changetype' => array('label' => gTxt('changetype'), 'html' => formTypes('', false, 'changetype')),
 171              'delete'     => gTxt('delete'),
 172          );
 173  
 174          $out[] = multi_edit($methods, 'form', 'form_multi_edit');
 175  
 176          return form(join('', $out), '', '', 'post', '', '', 'allforms_form');
 177      }
 178  }
 179  
 180  /**
 181   * Processes multi-edit actions.
 182   */
 183  
 184  function form_multi_edit()
 185  {
 186      $method = ps('edit_method');
 187      $forms = ps('selected_forms');
 188      $affected = array();
 189  
 190      if ($forms && is_array($forms)) {
 191          if ($method == 'delete') {
 192              foreach ($forms as $name) {
 193                  if (form_delete($name)) {
 194                      $affected[] = $name;
 195                  }
 196              }
 197  
 198              callback_event('forms_deleted', '', 0, $affected);
 199  
 200              $message = gTxt('forms_deleted', array('{list}' => join(', ', $affected)));
 201  
 202              form_edit($message);
 203          }
 204  
 205          if ($method == 'changetype') {
 206              $new_type = ps('type');
 207  
 208              foreach ($forms as $name) {
 209                  if (form_set_type($name, $new_type)) {
 210                      $affected[] = $name;
 211                  }
 212              }
 213  
 214              $message = gTxt('forms_updated', array('{list}' => join(', ', $affected)));
 215  
 216              form_edit($message);
 217          }
 218      } else {
 219          form_edit();
 220      }
 221  }
 222  
 223  /**
 224   * Creates a new form.
 225   *
 226   * Directs requests back to the main editor panel, armed with a
 227   * 'form_create' step.
 228   */
 229  
 230  function form_create()
 231  {
 232      form_edit();
 233  }
 234  
 235  /**
 236   * Renders the main Form editor panel.
 237   *
 238   * @param string|array $message The activity message
 239   */
 240  
 241  function form_edit($message = '')
 242  {
 243      global $event, $step, $essential_forms;
 244  
 245      pagetop(gTxt('edit_forms'), $message);
 246  
 247      extract(array_map('assert_string', gpsa(array(
 248          'copy',
 249          'save_error',
 250          'savenew',
 251      ))));
 252  
 253      $name = sanitizeForPage(assert_string(gps('name')));
 254      $type = assert_string(gps('type'));
 255      $newname = sanitizeForPage(assert_string(gps('newname')));
 256  
 257      if ($step == 'form_delete' || empty($name) && $step != 'form_create' && !$savenew) {
 258          $name = 'default';
 259      } elseif (((($copy || $savenew) && $newname) || ($newname && $newname !== $name)) && !$save_error) {
 260          $name = $newname;
 261      }
 262  
 263      $Form = gps('Form');
 264  
 265      if (!$save_error) {
 266          $rs = safe_row("*", 'txp_form', "name = '".doSlash($name)."'");
 267          extract($rs);
 268      }
 269  
 270      if (in_array($name, $essential_forms)) {
 271          $name_widgets = inputLabel(
 272              'new_form',
 273              fInput('text', 'newname', $name, 'input-medium', '', '', INPUT_MEDIUM, '', 'new_form', true),
 274              'form_name',
 275              array('', 'instructions_form_name'),
 276              array('class' => 'txp-form-field name')
 277          );
 278  
 279          $type_widgets = inputLabel(
 280              'type',
 281              formTypes($type, false, 'type', true),
 282              'form_type',
 283              array('', 'instructions_form_type'),
 284              array('class' => 'txp-form-field type')
 285          );
 286      } else {
 287          $name_widgets = inputLabel(
 288              'new_form',
 289              fInput('text', 'newname', $name, 'input-medium', '', '', INPUT_MEDIUM, '', 'new_form', false, true),
 290              'form_name',
 291              array('', 'instructions_form_name'),
 292              array('class' => 'txp-form-field name')
 293          );
 294  
 295          $type_widgets = inputLabel(
 296              'type',
 297              formTypes($type, false),
 298              'form_type',
 299              array('', 'instructions_form_type'),
 300              array('class' => 'txp-form-field type')
 301          );
 302      }
 303  
 304      if ($name === '') {
 305          $name_widgets .= hInput('savenew', 'savenew');
 306      } else {
 307          $name_widgets .= hInput('name', $name);
 308      }
 309  
 310      $name_widgets .= eInput('form').sInput('form_save');
 311  
 312      $actionsExtras = '';
 313  
 314      if ($name) {
 315          $actionsExtras .= href('<span class="ui-icon ui-icon-copy"></span> '.gTxt('duplicate'), '#', array(
 316              'class'     => 'txp-clone',
 317              'data-form' => 'form_form',
 318          ));
 319      }
 320  
 321      $actions = graf(
 322          sLink('form', 'form_create', '<span class="ui-icon ui-extra-icon-new-document"></span> '.gTxt('create_new_form'), 'txp-new').
 323          $actionsExtras,
 324          array('class' => 'txp-actions txp-actions-inline')
 325      );
 326  
 327      $buttons = graf(
 328          tag_void('input', array(
 329              'class'  => 'publish',
 330              'type'   => 'submit',
 331              'method' => 'post',
 332              'value'  =>  gTxt('save'),
 333          )), ' class="txp-save"'
 334      );
 335  
 336      $listActions = graf(
 337          href('<span class="ui-icon ui-icon-arrowthickstop-1-s"></span> '.gTxt('expand_all'), '#', array(
 338              'class'         => 'txp-expand-all',
 339              'aria-controls' => 'allforms_form',
 340          )).
 341          href('<span class="ui-icon ui-icon-arrowthickstop-1-n"></span> '.gTxt('collapse_all'), '#', array(
 342              'class'         => 'txp-collapse-all',
 343              'aria-controls' => 'allforms_form',
 344          )), array('class' => 'txp-actions')
 345      );
 346  
 347      echo n.'<div class="txp-layout">'.
 348          n.tag(
 349              hed(gTxt('tab_forms').popHelp('forms_overview'), 1, array('class' => 'txp-heading')),
 350              'div', array('class' => 'txp-layout-1col')
 351          );
 352  
 353      // Forms create/switcher column.
 354      echo n.tag(
 355          $listActions.n.
 356          form_list($name).n,
 357          'div', array(
 358              'class' => 'txp-layout-4col-alt',
 359              'id'    => 'content_switcher',
 360              'role'  => 'region',
 361          )
 362      );
 363  
 364      // Forms code columm.
 365      echo n.tag(
 366          form(
 367              $actions.
 368              $name_widgets.
 369              $type_widgets.
 370              inputLabel(
 371                  'form',
 372                  '<textarea class="code" id="form" name="Form" cols="'.INPUT_LARGE.'" rows="'.TEXTAREA_HEIGHT_LARGE.'" dir="ltr">'.txpspecialchars($Form).'</textarea>',
 373                  array(
 374                      'form_code',
 375                      n.href('<span class="ui-icon ui-extra-icon-code"></span> '.gTxt('tagbuilder'), '#', array('class' => 'txp-tagbuilder-dialog')),
 376                  ),
 377                  array('', 'instructions_form_code'),
 378                  array('class' => 'txp-form-field'),
 379                  array('div', 'div')
 380              ).
 381              $buttons
 382              , '', '', 'post', '', '', 'form_form'),
 383          'div', array(
 384              'class' => 'txp-layout-4col-3span',
 385              'id'    => 'main_content',
 386              'role'  => 'region',
 387          )
 388      );
 389  
 390      // Tag builder dialog.
 391      echo n.tag(
 392          form_tagbuild(),
 393          'div', array(
 394              'class'      => 'txp-tagbuilder-content',
 395              'id'         => 'tagbuild_links',
 396              'aria-label' => gTxt('tagbuilder'),
 397              'title'      => gTxt('tagbuilder'),
 398          ));
 399  
 400      echo n.'</div>'; // End of .txp-layout.
 401  }
 402  
 403  /**
 404   * Saves a form template.
 405   */
 406  
 407  function form_save()
 408  {
 409      global $essential_forms, $form_types;
 410  
 411      extract(doSlash(array_map('assert_string', psa(array(
 412          'savenew',
 413          'Form',
 414          'type',
 415          'copy',
 416      )))));
 417  
 418      $name = sanitizeForPage(assert_string(ps('name')));
 419      $newname = sanitizeForPage(assert_string(ps('newname')));
 420  
 421      $save_error = false;
 422      $message = '';
 423  
 424      if (in_array($name, $essential_forms)) {
 425          $newname = $name;
 426          $type = fetch('type', 'txp_form', 'name', $newname);
 427          $_POST['newname'] = $newname;
 428      }
 429  
 430      if (!$newname) {
 431          $message = array(gTxt('form_name_invalid'), E_ERROR);
 432          $save_error = true;
 433      } else {
 434          if (!isset($form_types[$type])) {
 435              $message = array(gTxt('form_type_missing'), E_ERROR);
 436              $save_error = true;
 437          } else {
 438              if ($copy && $name === $newname) {
 439                  $newname .= '_copy';
 440                  $_POST['newname'] = $newname;
 441              }
 442  
 443              $exists = safe_field("name", 'txp_form', "name = '".doSlash($newname)."'");
 444  
 445              if ($newname !== $name && $exists !== false) {
 446                  $message = array(gTxt('form_already_exists', array('{name}' => $newname)), E_ERROR);
 447                  if ($savenew) {
 448                      $_POST['newname'] = '';
 449                  }
 450  
 451                  $save_error = true;
 452              } else {
 453                  if ($savenew or $copy) {
 454                      if ($newname) {
 455                          if (safe_insert(
 456                                  'txp_form',
 457                                  "Form = '$Form',
 458                                  type = '$type',
 459                                  name = '".doSlash($newname)."'"
 460                          )) {
 461                              update_lastmod('form_created', compact('newname', 'name', 'type', 'Form'));
 462                              $message = gTxt('form_created', array('{name}' => $newname));
 463                          } else {
 464                              $message = array(gTxt('form_save_failed'), E_ERROR);
 465                              $save_error = true;
 466                          }
 467                      } else {
 468                          $message = array(gTxt('form_name_invalid'), E_ERROR);
 469                          $save_error = true;
 470                      }
 471                  } else {
 472                      if (safe_update(
 473                              'txp_form',
 474                              "Form = '$Form',
 475                              type = '$type',
 476                              name = '".doSlash($newname)."'",
 477                              "name = '".doSlash($name)."'"
 478                      )) {
 479                          update_lastmod('form_saved', compact('newname', 'name', 'type', 'Form'));
 480                          $message = gTxt('form_updated', array('{name}' => $name));
 481                      } else {
 482                          $message = array(gTxt('form_save_failed'), E_ERROR);
 483                          $save_error = true;
 484                      }
 485                  }
 486              }
 487          }
 488      }
 489  
 490      if ($save_error === true) {
 491          $_POST['save_error'] = '1';
 492      } else {
 493          callback_event('form_saved', '', 0, $name, $newname);
 494      }
 495  
 496      form_edit($message);
 497  }
 498  
 499  /**
 500   * Deletes a form template with the given name.
 501   *
 502   * @param  string $name The form template
 503   * @return bool FALSE on error
 504   */
 505  
 506  function form_delete($name)
 507  {
 508      global $essential_forms;
 509  
 510      if (in_array($name, $essential_forms)) {
 511          return false;
 512      }
 513  
 514      $name = doSlash($name);
 515  
 516      return safe_delete('txp_form', "name = '$name'");
 517  }
 518  
 519  /**
 520   * Changes a form template's type.
 521   *
 522   * @param  string $name The form template
 523   * @param  string $type The new type
 524   * @return bool FALSE on error
 525   */
 526  
 527  function form_set_type($name, $type)
 528  {
 529      global $essential_forms, $form_types;
 530  
 531      if (in_array($name, $essential_forms) || !isset($form_types[$type])) {
 532          return false;
 533      }
 534  
 535      $name = doSlash($name);
 536      $type = doSlash($type);
 537  
 538      return safe_update('txp_form', "type = '$type'", "name = '$name'");
 539  }
 540  
 541  /**
 542   * Renders a &lt;select&gt; input listing all form types.
 543   *
 544   * @param  string $type        The selected option
 545   * @param  bool   $blank_first If TRUE, the list defaults to an empty selection
 546   * @param  string $id          HTML id attribute value
 547   * @param  bool   $disabled    If TRUE renders the select disabled
 548   * @return string HTML
 549   * @access private
 550   */
 551  
 552  function formTypes($type, $blank_first = true, $id = 'type', $disabled = false)
 553  {
 554      global $form_types;
 555  
 556      return selectInput('type', $form_types, $type, $blank_first, '', $id, false, $disabled);
 557  }
 558  
 559  /**
 560   * Return a list of tag builder tags.
 561   *
 562   * @return HTML
 563   */
 564  
 565  function form_tagbuild()
 566  {
 567      $listActions = graf(
 568          href('<span class="ui-icon ui-icon-arrowthickstop-1-s"></span> '.gTxt('expand_all'), '#', array(
 569              'class'         => 'txp-expand-all',
 570              'aria-controls' => 'tagbuild_links',
 571          )).
 572          href('<span class="ui-icon ui-icon-arrowthickstop-1-n"></span> '.gTxt('collapse_all'), '#', array(
 573              'class'         => 'txp-collapse-all',
 574              'aria-controls' => 'tagbuild_links',
 575          )), array('class' => 'txp-actions')
 576      );
 577  
 578      // Generate the tagbuilder links.
 579      // Format of each entry is popTagLink -> array ( gTxt string, class/ID ).
 580      $tagbuild_items = array(
 581          'article'         => array('articles', 'article-tags'),
 582          'link'            => array('links', 'link-tags'),
 583          'comment'         => array('comments', 'comment-tags'),
 584          'comment_details' => array('comment_details', 'comment-detail-tags'),
 585          'comment_form'    => array('comment_form', 'comment-form-tags'),
 586          'search_result'   => array('search_results_form', 'search-result-tags'),
 587          'file_download'   => array('file_download_tags', 'file-tags'),
 588          'category'        => array('category_tags', 'category-tags'),
 589          'section'         => array('section_tags', 'section-tags'),
 590      );
 591  
 592      $tagbuild_links = '';
 593  
 594      foreach ($tagbuild_items as $tb => $item) {
 595          $tagbuild_links .= wrapRegion($item[1].'_group', popTagLinks($tb), $item[1], $item[0], $item[1]);
 596      }
 597  
 598      return $listActions.$tagbuild_links;
 599  }

title

Description

title

Description

title

Description

title

title

Body