Textpattern PHP Cross Reference Content Management Systems

Source: /textpattern/include/txp_admin.php - 794 lines - 24227 bytes - Summary - Text - Print

Description: Users panel.

   1  <?php
   2  
   3  /*
   4   * Textpattern Content Management System
   5   * https://textpattern.com/
   6   *
   7   * Copyright (C) 2020 The Textpattern Development Team
   8   *
   9   * This file is part of Textpattern.
  10   *
  11   * Textpattern is free software; you can redistribute it and/or
  12   * modify it under the terms of the GNU General Public License
  13   * as published by the Free Software Foundation, version 2.
  14   *
  15   * Textpattern is distributed in the hope that it will be useful,
  16   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18   * GNU General Public License for more details.
  19   *
  20   * You should have received a copy of the GNU General Public License
  21   * along with Textpattern. If not, see <https://www.gnu.org/licenses/>.
  22   */
  23  
  24  /**
  25   * Users panel.
  26   *
  27   * @package Admin\Admin
  28   */
  29  
  30  use Textpattern\Search\Filter;
  31  
  32  if (!defined('txpinterface')) {
  33      die('txpinterface is undefined.');
  34  }
  35  
  36  $levels = get_groups();
  37  
  38  if ($event == 'admin') {
  39      require_privs('admin');
  40  
  41      $available_steps = array(
  42          'admin_multi_edit'    => true,
  43          'admin_change_pageby' => true,
  44          'author_list'         => false,
  45          'author_edit'         => false,
  46          'author_save'         => true,
  47          'author_save_new'     => true,
  48          'change_pass'         => true,
  49          'new_pass_form'       => false,
  50      );
  51  
  52      if ($step && bouncer($step, $available_steps)) {
  53          $step();
  54      } else {
  55          author_list();
  56      }
  57  }
  58  
  59  /**
  60   * Updates a user.
  61   */
  62  
  63  function author_save()
  64  {
  65      global $txp_user;
  66  
  67      require_privs('admin.edit.own');
  68  
  69      extract(psa(array(
  70          'privs',
  71          'name',
  72          'RealName',
  73          'email',
  74          'language',
  75      )));
  76  
  77      $privs = assert_int($privs);
  78  
  79      if (!is_valid_email($email)) {
  80          $fullEdit = has_privs('admin.list') ? false : true;
  81          author_edit(array(gTxt('email_required'), E_ERROR), $fullEdit);
  82  
  83          return;
  84      }
  85  
  86      $rs = update_user($name, $email, $RealName);
  87  
  88      if ($rs && $language) {
  89          safe_upsert(
  90              'txp_prefs',
  91              "val = '".doSlash($language)."',
  92              event = 'admin',
  93              html = 'text_input',
  94              type = ".PREF_HIDDEN.",
  95              position = 0",
  96              array(
  97                  'name'      => 'language_ui',
  98                  'user_name' => doSlash((string) $name)
  99              )
 100          );
 101      }
 102  
 103      if (has_privs('admin.edit') && $rs && ($txp_user === $name || change_user_group($name, $privs))) {
 104          author_list(gTxt('author_updated', array('{name}' => $RealName)));
 105  
 106          return;
 107      } elseif ($rs && has_privs('admin.edit.own')) {
 108          $msg = gTxt('author_updated', array('{name}' => $RealName));
 109      } else {
 110          $msg = array(gTxt('author_save_failed'), E_ERROR);
 111      }
 112  
 113      if (has_privs('admin.edit')) {
 114          author_edit($msg);
 115      } elseif (has_privs('admin.edit.own')) {
 116          author_list($msg);
 117      }
 118  }
 119  
 120  /**
 121   * Changes current user's password.
 122   */
 123  
 124  function change_pass()
 125  {
 126      global $txp_user;
 127  
 128      extract(psa(array('current_pass', 'new_pass')));
 129  
 130      if (empty($new_pass)) {
 131          new_pass_form(array(gTxt('password_required'), E_ERROR));
 132  
 133          return;
 134      }
 135  
 136      if (txp_validate($txp_user, $current_pass)) {
 137          $rs = change_user_password($txp_user, $new_pass);
 138  
 139          if ($rs) {
 140              $message = gTxt('password_changed');
 141              author_list($message);
 142          }
 143      } else {
 144          new_pass_form(array(gTxt('password_invalid'), E_ERROR));
 145      }
 146  }
 147  
 148  /**
 149   * Creates a new user.
 150   */
 151  
 152  function author_save_new()
 153  {
 154      require_privs('admin.edit');
 155  
 156      extract(psa(array(
 157          'privs',
 158          'name',
 159          'email',
 160          'RealName',
 161          'language',
 162      )));
 163  
 164      $privs = assert_int($privs);
 165  
 166      if (is_valid_username($name) && is_valid_email($email)) {
 167          if (user_exists($name)) {
 168              author_edit(array(gTxt('author_already_exists', array('{name}' => $name)), E_ERROR));
 169  
 170              return;
 171          }
 172  
 173          $password = Txp::get('\Textpattern\Password\Random')->generate(PASSWORD_LENGTH);
 174  
 175          $rs = create_user($name, $email, $password, $RealName, $privs);
 176  
 177          if ($rs) {
 178              if ($language) {
 179                  safe_upsert(
 180                      'txp_prefs',
 181                      "val = '".doSlash($language)."',
 182                      event = 'admin',
 183                      html = 'text_input',
 184                      type = ".PREF_HIDDEN.",
 185                      position = 0",
 186                      array(
 187                          'name'      => 'language_ui',
 188                          'user_name' => doSlash((string) $name)
 189                      )
 190                  );
 191              }
 192  
 193              $message = send_account_activation($name);
 194  
 195              author_list($message);
 196  
 197              return;
 198          }
 199      }
 200  
 201      author_edit(array(gTxt('error_adding_new_author'), E_ERROR));
 202  }
 203  
 204  /**
 205   * Lists user groups as a &lt;select&gt; input.
 206   *
 207   * @param  int $priv Selected option
 208   * @return string HTML
 209   */
 210  
 211  function privs($priv = '')
 212  {
 213      global $levels;
 214  
 215      return selectInput('privs', $levels, $priv, '', '', 'privileges');
 216  }
 217  
 218  /**
 219   * Translates a numeric ID to a human-readable user group.
 220   *
 221   * @param  int $priv The group
 222   * @return string
 223   */
 224  
 225  function get_priv_level($priv)
 226  {
 227      global $levels;
 228  
 229      return $levels[$priv];
 230  }
 231  
 232  /**
 233   * Password changing form.
 234   *
 235   * @param string|array $message The activity message
 236   */
 237  
 238  function new_pass_form($message = '')
 239  {
 240      pagetop(gTxt('tab_site_admin'), $message);
 241  
 242      echo form(
 243          hed(gTxt('change_password'), 2).
 244          inputLabel(
 245              'current_pass',
 246              fInput('password',
 247                  array(
 248                      'name'         => 'current_pass',
 249                      'autocomplete' => 'current-password',
 250                  ), '', 'txp-maskable', '', '', INPUT_REGULAR, '', 'current_pass', false, true),
 251              'current_password', '', array('class' => 'txp-form-field edit-admin-current-password')
 252          ).
 253          inputLabel(
 254              'new_pass',
 255              fInput('password',
 256                  array(
 257                      'name'         => 'new_pass',
 258                      'autocomplete' => 'new-password',
 259                  ), '', 'txp-maskable', '', '', INPUT_REGULAR, '', 'new_pass', false, true).
 260              n.tag(
 261                  checkbox('unmask', 1, false, 0, 'show_password').
 262                  n.tag(gTxt('show_password'), 'label', array('for' => 'show_password')),
 263                  'div', array('class' => 'edit-admin-show-password')),
 264              'new_password', '', array('class' => 'txp-form-field edit-admin-new-password')
 265          ).
 266          graf(
 267              sLink('admin', '', gTxt('cancel'), 'txp-button').
 268              fInput('submit', 'change_pass', gTxt('submit'), 'publish'),
 269              array('class' => 'txp-edit-actions')
 270          ).
 271          eInput('admin').
 272          sInput('change_pass'),
 273      '', '', 'post', 'txp-edit', '', 'change_password');
 274  }
 275  
 276  /**
 277   * The main panel listing all authors.
 278   *
 279   * @param string|array $message The activity message
 280   */
 281  
 282  function author_list($message = '')
 283  {
 284      global $event, $txp_user, $levels;
 285  
 286      $buttons = author_edit_buttons();
 287  
 288      // User list.
 289      if (has_privs('admin.list')) {
 290          pagetop(gTxt('tab_site_admin'), $message);
 291  
 292          if (is_disabled('mail')) {
 293              echo graf(
 294                  span(null, array('class' => 'ui-icon ui-icon-alert')).' '.
 295                  gTxt('warn_mail_unavailable'),
 296                  array('class' => 'alert-block warning')
 297              );
 298          }
 299          extract(gpsa(array(
 300              'page',
 301              'sort',
 302              'dir',
 303              'crit',
 304              'search_method',
 305          )));
 306  
 307          if ($sort === '') {
 308              $sort = get_pref('admin_sort_column', 'name');
 309          } else {
 310              if (!in_array($sort, array('name', 'RealName', 'email', 'privs', 'last_login'))) {
 311                  $sort = 'name';
 312              }
 313  
 314              set_pref('admin_sort_column', $sort, 'admin', PREF_HIDDEN, '', 0, PREF_PRIVATE);
 315          }
 316  
 317          if ($dir === '') {
 318              $dir = get_pref('admin_sort_dir', 'asc');
 319          } else {
 320              $dir = ($dir == 'desc') ? "desc" : "asc";
 321              set_pref('admin_sort_dir', $dir, 'admin', PREF_HIDDEN, '', 0, PREF_PRIVATE);
 322          }
 323  
 324          $sort_sql = $sort.' '.$dir;
 325  
 326          $switch_dir = ($dir == 'desc') ? 'asc' : 'desc';
 327  
 328          $search = new Filter($event,
 329              array(
 330                  'login' => array(
 331                      'column' => 'txp_users.name',
 332                      'label'  => gTxt('login_name'),
 333                  ),
 334                  'RealName' => array(
 335                      'column' => 'txp_users.RealName',
 336                      'label'  => gTxt('real_name'),
 337                  ),
 338                  'email' => array(
 339                      'column' => 'txp_users.email',
 340                      'label'  => gTxt('email'),
 341                  ),
 342                  'privs' => array(
 343                      'column' => array('txp_users.privs'),
 344                      'label'  => gTxt('privileges'),
 345                      'type'   => 'boolean',
 346                  ),
 347              )
 348          );
 349  
 350          $search->setAliases('privs', $levels);
 351  
 352          list($criteria, $crit, $search_method) = $search->getFilter(array('login' => array('can_list' => true)));
 353  
 354          $search_render_options = array('placeholder' => 'search_users');
 355  
 356          $total = getCount('txp_users', $criteria);
 357  
 358          $searchBlock =
 359              n.tag(
 360                  $search->renderForm('author_list', $search_render_options),
 361                  'div', array(
 362                      'class' => 'txp-layout-4col-3span',
 363                      'id'    => 'users_control',
 364                  )
 365              );
 366  
 367          $createBlock = n.tag(implode(n, $buttons), 'div', array('class' => 'txp-control-panel'));
 368  
 369          $contentBlock = '';
 370  
 371          $paginator = new \Textpattern\Admin\Paginator($event, 'author');
 372          $limit = $paginator->getLimit();
 373  
 374          list($page, $offset, $numPages) = pager($total, $limit, $page);
 375  
 376          if ($total < 1) {
 377              if ($crit !== '') {
 378                  $contentBlock .=
 379                      graf(
 380                          span(null, array('class' => 'ui-icon ui-icon-info')).' '.
 381                          gTxt('no_results_found'),
 382                          array('class' => 'alert-block information')
 383                      );
 384              }
 385          } else {
 386              $use_multi_edit = (has_privs('admin.edit') && ($total > 1 or safe_count('txp_users', "1 = 1") > 1));
 387  
 388              $rs = safe_rows_start(
 389                  "*, UNIX_TIMESTAMP(last_access) AS last_login",
 390                  'txp_users',
 391                  "$criteria ORDER BY $sort_sql LIMIT $offset, $limit"
 392              );
 393  
 394              if ($rs) {
 395                  $contentBlock .=
 396                      n.tag_start('form', array(
 397                          'class'  => 'multi_edit_form',
 398                          'id'     => 'users_form',
 399                          'name'   => 'longform',
 400                          'method' => 'post',
 401                          'action' => 'index.php',
 402                      )).
 403                      n.tag_start('div', array(
 404                          'class'      => 'txp-listtables',
 405                          'tabindex'   => 0,
 406                          'aria-label' => gTxt('list'),
 407                      )).
 408                      n.tag_start('table', array('class' => 'txp-list')).
 409                      n.tag_start('thead').
 410                      tr(
 411                          (
 412                              ($use_multi_edit)
 413                              ? hCell(
 414                                  fInput('checkbox', 'select_all', 0, '', '', '', '', '', 'select_all'),
 415                                      '', ' class="txp-list-col-multi-edit" scope="col" title="'.gTxt('toggle_all_selected').'"'
 416                              )
 417                              : hCell('', '', ' class="txp-list-col-multi-edit" scope="col"')
 418                          ).
 419                          column_head(
 420                              'login_name', 'name', 'admin', true, $switch_dir, '', '',
 421                                  (('name' == $sort) ? "$dir " : '').'txp-list-col-login-name name'
 422                          ).
 423                          column_head(
 424                              'real_name', 'RealName', 'admin', true, $switch_dir, '', '',
 425                                  (('RealName' == $sort) ? "$dir " : '').'txp-list-col-real-name name'
 426                          ).
 427                          column_head(
 428                              'email', 'email', 'admin', true, $switch_dir, '', '',
 429                                  (('email' == $sort) ? "$dir " : '').'txp-list-col-email'
 430                          ).
 431                          column_head(
 432                              'privileges', 'privs', 'admin', true, $switch_dir, '', '',
 433                                  (('privs' == $sort) ? "$dir " : '').'txp-list-col-privs'
 434                          ).
 435                          column_head(
 436                              'last_login', 'last_login', 'admin', true, $switch_dir, '', '',
 437                                  (('last_login' == $sort) ? "$dir " : '').'txp-list-col-last-login date'
 438                          )
 439                      ).
 440                      n.tag_end('thead').
 441                      n.tag_start('tbody');
 442  
 443                  while ($a = nextRow($rs)) {
 444                      extract(doSpecial($a));
 445  
 446                      $contentBlock .= tr(
 447                          td(
 448                              ((has_privs('admin.edit') && $txp_user != $a['name']) ? fInput('checkbox', 'selected[]', $a['name'], 'checkbox') : ''), '', 'txp-list-col-multi-edit'
 449                          ).
 450                          hCell(
 451                              ((has_privs('admin.edit') || (has_privs('admin.edit.own') && $txp_user === $a['name'])) ? eLink('admin', 'author_edit', 'user_id', $user_id, $name) : $name), '', ' class="txp-list-col-login-name name" scope="row"'
 452                          ).
 453                          td(
 454                              $RealName, '', 'txp-list-col-real-name name'
 455                          ).
 456                          td(
 457                              href($email, 'mailto:'.$email), '', 'txp-list-col-email'
 458                          ).
 459                          td(
 460                              get_priv_level($privs), '', 'txp-list-col-privs'
 461                          ).
 462                          td(
 463                              ($last_login ? safe_strftime('%b&#160;%Y', $last_login) : ''), '', 'txp-list-col-last-login date'
 464                          )
 465                      );
 466                  }
 467  
 468                  $contentBlock .=
 469                      n.tag_end('tbody').
 470                      n.tag_end('table').
 471                      n.tag_end('div'). // End of .txp-listtables.
 472                      (
 473                          ($use_multi_edit)
 474                          ? author_multiedit_form($page, $sort, $dir, $crit, $search_method)
 475                          : ''
 476                      ).
 477                      tInput().
 478                      n.tag_end('form');
 479              }
 480          }
 481  
 482          $pageBlock = $paginator->render().
 483          nav_form('admin', $page, $numPages, $sort, $dir, $crit, $search_method, $total, $limit);
 484  
 485          $table = new \Textpattern\Admin\Table('users');
 486          echo $table->render(compact('total', 'crit') + array('heading' => 'tab_site_admin'), $searchBlock, $createBlock, $contentBlock, $pageBlock);
 487  
 488      } elseif (has_privs('admin.edit.own')) {
 489          echo author_edit($message, true);
 490      } else {
 491          require_privs('admin.edit');
 492      }
 493  }
 494  
 495  /**
 496   * Create additional UI buttons.
 497   */
 498  function author_edit_buttons()
 499  {
 500      $buttons = array();
 501  
 502      // New author button.
 503      if (has_privs('admin.edit')) {
 504          $buttons[] = sLink('admin', 'author_edit', gTxt('create_author'), 'txp-button');
 505      }
 506  
 507      // Change password button.
 508      $buttons[] = sLink('admin', 'new_pass_form', gTxt('change_password'), 'txp-button');
 509  
 510      return $buttons;
 511  }
 512  
 513  /**
 514   * Renders the user edit panel.
 515   *
 516   * @param string|array $message  The activity message
 517   * @param bool         $fullEdit Whether the user has full edit permissions or not
 518   */
 519  
 520  function author_edit($message = '', $fullEdit = false)
 521  {
 522      global $step, $txp_user;
 523  
 524      require_privs('admin.edit.own');
 525  
 526      pagetop(gTxt('tab_site_admin'), $message);
 527  
 528      $vars = array('user_id', 'name', 'RealName', 'email', 'privs');
 529      $rs = array();
 530      $out = array();
 531  
 532      extract(gpsa($vars));
 533  
 534      if (has_privs('admin.edit')) {
 535          if ($user_id) {
 536              $user_id = assert_int($user_id);
 537              $rs = safe_row("*", 'txp_users', "user_id = '$user_id'");
 538  
 539              extract($rs);
 540              $is_edit = true;
 541          } else {
 542              $is_edit = false;
 543          }
 544      } else {
 545          $rs = safe_row("*", 'txp_users', "name = '".doSlash($txp_user)."'");
 546          extract($rs);
 547          $is_edit = true;
 548      }
 549  
 550      if (!$is_edit) {
 551          $out[] = hed(gTxt('create_author'), 2);
 552      } else {
 553          $out[] = hed(gTxt('edit_author'), 2);
 554      }
 555  
 556      if ($is_edit) {
 557          $out[] = inputLabel(
 558              'login_name',
 559              strong(txpspecialchars($name)),
 560              '', '', array('class' => 'txp-form-field edit-admin-login-name')
 561          );
 562      } elseif (has_privs('admin.edit')) {
 563          $out[] = inputLabel(
 564              'login_name',
 565              fInput('text', 'name', $name, '', '', '', INPUT_REGULAR, '', 'login_name', false, true),
 566              'login_name', 'create_author', array('class' => 'txp-form-field edit-admin-login-name')
 567          );
 568      }
 569  
 570      // Get author's current admin language, if defined,
 571      $txpLang = Txp::get('\Textpattern\L10n\Lang');
 572      $langList = $txpLang->languageList();
 573      $authorLang = safe_field('val', 'txp_prefs', "name='language_ui' AND user_name = '".doSlash($name)."'");
 574      $authorLang = in_array($authorLang, $txpLang->installed()) ? $authorLang : ($is_edit? null : TEXTPATTERN_DEFAULT_LANG);
 575  
 576      if (count($langList) > 1) {
 577          $langField = inputLabel(
 578              'language',
 579              selectInput('language', $langList, $authorLang, true, false, 'language'),
 580              'active_language_ui', '', array('class' => 'txp-form-field edit-admin-language')
 581          );
 582      } else {
 583          $langField = hInput('language', $authorLang);
 584      }
 585  
 586      $out[] = inputLabel(
 587              'real_name',
 588              fInput('text', 'RealName', $RealName, '', '', '', INPUT_REGULAR, '', 'real_name'),
 589              'real_name', '', array('class' => 'txp-form-field edit-admin-name')
 590          ).
 591          inputLabel(
 592              'login_email',
 593              fInput('email', 'email', $email, '', '', '', INPUT_REGULAR, '', 'login_email', false, true),
 594              'email', '', array('class' => 'txp-form-field edit-admin-email')
 595          );
 596  
 597      if (has_privs('admin.edit') && $txp_user != $name) {
 598          $out[] = inputLabel(
 599              'privileges',
 600              privs($privs),
 601              'privileges', 'about_privileges', array('class' => 'txp-form-field edit-admin-privileges')
 602          );
 603      } else {
 604          $out[] = inputLabel(
 605              'privileges',
 606              strong(get_priv_level($privs)),
 607              '', '', array('class' => 'txp-form-field edit-admin-privileges')
 608          ).
 609          hInput('privs', $privs);
 610      }
 611  
 612      $out[] = $langField;
 613      $out[] = pluggable_ui('author_ui', 'extend_detail_form', '', $rs).
 614          graf(
 615              ($fullEdit ? '' : sLink('admin', '', gTxt('cancel'), 'txp-button')).
 616              fInput('submit', '', gTxt('save'), 'publish'),
 617              array('class' => 'txp-edit-actions')
 618          ).
 619          eInput('admin');
 620  
 621      if ($is_edit) {
 622          $out[] = hInput('user_id', $user_id).
 623              hInput('name', $name).
 624              sInput('author_save');
 625      } else {
 626          $out[] = sInput('author_save_new');
 627      }
 628  
 629      echo n.'<div class="txp-layout">'.
 630          n.tag(
 631              hed(gTxt('tab_site_account'), 1, array('class' => 'txp-heading')),
 632              'div', array('class' => 'txp-layout-1col')
 633          ).
 634          n.tag_start('div', array(
 635              'class' => 'txp-layout-1col',
 636              'id'    => 'users_container',
 637          )).
 638          ($fullEdit
 639              ? n.tag(implode(n, author_edit_buttons()), 'div', array('class' => 'txp-control-panel'))
 640              : ''
 641          );
 642  
 643      if (!$is_edit) {
 644          echo form(join('', $out), '', '', 'post', 'txp-edit', '', 'user_edit', '', false);
 645      } else {
 646          echo form(join('', $out), '', '', 'post', 'txp-edit', '', 'user_edit');
 647      }
 648  
 649      echo n.tag_end('div'). // End of .txp-layout-1col.
 650          n.'</div>'; // End of .txp-layout.
 651  }
 652  
 653  /**
 654   * Updates pageby value.
 655   */
 656  
 657  function admin_change_pageby()
 658  {
 659      global $event;
 660  
 661      Txp::get('\Textpattern\Admin\Paginator', $event, 'author')->change();
 662      author_list();
 663  }
 664  
 665  /**
 666   * Renders multi-edit form.
 667   *
 668   * @param  int    $page          The page
 669   * @param  string $sort          The sorting value
 670   * @param  string $dir           The sorting direction
 671   * @param  string $crit          The search string
 672   * @param  string $search_method The search method
 673   * @return string HTML
 674   */
 675  
 676  function author_multiedit_form($page, $sort, $dir, $crit, $search_method)
 677  {
 678      $privileges = privs();
 679      $users = safe_column("name", 'txp_users', "1 = 1");
 680  
 681      $methods = array(
 682          'changeprivilege'  => array(
 683              'label' => gTxt('changeprivilege'),
 684              'html'  => $privileges,
 685          ),
 686          'resetpassword'    => gTxt('resetpassword'),
 687          'resendactivation' => gTxt('resend_activation'),
 688      );
 689  
 690      if (count($users) > 1) {
 691          $methods['delete'] = array(
 692              'label' => gTxt('delete'),
 693              'html'  => tag(gTxt('assign_assets_to'), 'label', array('for' => 'assign_assets')).
 694                  selectInput('assign_assets', $users, '', true, '', 'assign_assets'),
 695          );
 696      }
 697  
 698      return multi_edit($methods, 'admin', 'admin_multi_edit', $page, $sort, $dir, $crit, $search_method);
 699  }
 700  
 701  /**
 702   * Processes multi-edit actions.
 703   *
 704   * Accessing requires 'admin.edit' privileges.
 705   */
 706  
 707  function admin_multi_edit()
 708  {
 709      global $txp_user;
 710  
 711      require_privs('admin.edit');
 712  
 713      $selected = ps('selected');
 714      $method = ps('edit_method');
 715      $changed = array();
 716      $msg = '';
 717  
 718      if (!$selected || !is_array($selected)) {
 719          return author_list();
 720      }
 721  
 722      $clause = '';
 723  
 724      if ($method === 'resetpassword') {
 725          $clause = " AND last_access IS NOT NULL";
 726      } elseif ($method === 'resendactivation') {
 727          $clause = " AND last_access IS NULL";
 728      }
 729  
 730      $names = safe_column(
 731          "name",
 732          'txp_users',
 733          "name IN (".join(',', quote_list($selected)).") AND name != '".doSlash($txp_user)."'".$clause
 734      );
 735  
 736      if (!$names) {
 737          return author_list();
 738      }
 739  
 740      switch ($method) {
 741          case 'delete':
 742              $assign_assets = ps('assign_assets');
 743  
 744              if (!$assign_assets) {
 745                  $msg = array('must_reassign_assets', E_ERROR);
 746              } elseif (in_array($assign_assets, $names)) {
 747                  $msg = array('cannot_assign_assets_to_deletee', E_ERROR);
 748              } elseif (remove_user($names, $assign_assets)) {
 749                  $changed = $names;
 750                  callback_event('authors_deleted', '', 0, $changed);
 751                  $msg = 'author_deleted';
 752              }
 753  
 754              break;
 755  
 756          case 'changeprivilege':
 757              if (change_user_group($names, ps('privs'))) {
 758                  $changed = $names;
 759                  $msg = 'author_updated';
 760              }
 761  
 762              break;
 763  
 764          case 'resetpassword':
 765              foreach ($names as $name) {
 766                  send_reset_confirmation_request($name);
 767                  $changed[] = $name;
 768              }
 769  
 770              $msg = 'password_reset_confirmation_request_sent';
 771              break;
 772  
 773          case 'resendactivation':
 774              foreach ($names as $name) {
 775                  send_account_activation($name);
 776                  $changed[] = $name;
 777              }
 778  
 779              $msg = 'resend_activation_request_sent';
 780              break;
 781      }
 782  
 783      if (is_array($msg)) {
 784          list($msg, $err) = $msg;
 785      } else {
 786          $err = 0;
 787      }
 788  
 789      if ($changed) {
 790          return author_list(array(gTxt($msg, array('{name}' => txpspecialchars(join(', ', $changed)))), $err));
 791      }
 792  
 793      author_list(array(gTxt($msg), $err));
 794  }

title

Description

title

Description

title

Description

title

title

Body