Revision [10350]

This is an old revision of UserAdmin made by DarTar on 2005-08-01 14:31:56.

 

User Administration Module

Last edited by DarTar:
improved version of UserAdmin (1.2)
Mon, 01 Aug 2005 14:31 UTC [diff]

 

I've started writing some code for a user administration module. I think this might be interesting for wikka-based projects with a large number of registered users.
This action will enable Wikka administrators (or, in the future, users belonging to an Admin group) to have access to several user management functions from a single page:


The code below must be saved as actions/useradmin.php and can be used by adding {{useradmin}} in the body of a page.

Here's a preview of the interface (the email and IP fields are masked for privacy reasons)

sample output

User Administration


Filter view:

Records (857): 1-10 | 11-20
(Sorted by:signuptime, desc)
  User Name Email Signup Time Signup IP O E C Actions
HypeXR scott@xxxx.xx 2005-08-01 09:01:54 XX.XX.XX.XX 1 2 1 delete :: feedback
WiebTest wiebren.w@xxxx.xx 2005-07-31 19:35:26 XX.XX.XX.XX 0 0 0 delete :: feedback
DennyShimkoski denny@xxxx.xx 2005-07-31 00:22:58 XX.XX.XX.XX 6 38 1 delete :: feedback
RobinW wikka@xxxx.xx 2005-07-30 02:06:20 XX.XX.XX.XX 0 0 1 delete :: feedback
VictorManuelVarela vmvarela@xxxx.xx 2005-07-30 00:01:13 XX.XX.XX.XX 1 6 0 delete :: feedback
EniBevoli enibevoli@xxxx.xx 2005-07-29 12:13:44 XX.XX.XX.XX 0 4 1 delete :: feedback
MyPrivateWiki serayamaouche@xxxx.xx 2005-07-28 20:30:36 XX.XX.XX.XX 0 0 0 delete :: feedback
DaSt dstolars@xxxx.xx 2005-07-27 17:32:06 XX.XX.XX.XX 0 0 0 delete :: feedback
WikiSop mail-to-sophie@xxxx.xx 2005-07-27 14:59:07 XX.XX.XX.XX 0 0 0 delete :: feedback
Aragorn2005 mail.matthias.schulz@xxxx.xx 2005-07-27 08:48:46 XX.XX.XX.XX 0 0 0 delete :: feedback
Mass-action[Check all | Uncheck all]



Current features
(2005-08-31):
Files needed
(2004-09-16):


The code


actions/useradmin.php


Note: this action uses the ipaddress field that has been added as a beta antispam feature to this server. Lines relative to this field have been commented out in the code to allow installation on a native wikka package

  1. <?php
  2. /**
  3.  * Display a module for user management.
  4.  *
  5.  * This action allows admins to display information on registered users.
  6.  * Users can be searched, paged, filtered. User-related statistics are given,
  7.  * showing the number of commented, created and modified pages. A feedback
  8.  * handler allows admins to send an email to single users. If the current user
  9.  * is not an administrator, then the lastuser action is displayed instead.
  10.  *
  11.  * @package     Actions
  12.  * @name        Useradmin
  13.  *
  14.  * @author      {@link http://wikka.jsnx.com/DarTar Dario Taraborelli}
  15.  * @version     1.2
  16.  * @since       Wikka 1.1.X.X
  17.  *
  18.  * @input       integer $colcolor  optional: enables color for statistics columns
  19.  *              1: enables colored columns;
  20.  *              0: disables colored columns;
  21.  *              default: 1;
  22.  * @input       integer $rowcolor  optional: enables alternate row colors
  23.  *              1: enables colored rows;
  24.  *              0: disables colored rows;
  25.  *              default: 1;
  26.  *
  27.  * @output      A list of users registered on the current server.
  28.  *
  29.  * @todo
  30.  *          - mass-operations;
  31.  *          - deleting/banning users;
  32.  *          - integrate with other admin modules.
  33.  */
  34.  
  35. //utilities
  36.  
  37. /**
  38.  * Build an array of numbers consisting of 'ranges' with increasing step size in each 'range'.
  39.  *
  40.  * A list of numbers like this is useful for instance for a dropdown to choose
  41.  * a period expressed in number of days: a difference between 2 and 5 days may
  42.  * be significant while that between 92 and 95 may not be.
  43.  *
  44.  * @author      {@link http://wikka.jsnx.com/JavaWoman JavaWoman}
  45.  * @copyright   Copyright (c) 2005, Marjolein Katsma
  46.  * @license     http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
  47.  * @version     1.0
  48.  *
  49.  * @param   mixed   $limits required: single integer or array of integers;
  50.  *                  defines the upper limits of the ranges as well as the next step size
  51.  * @param   int     $max    required: upper limit for the whole list
  52.  *                  (will be included if smaller than the largest limit)
  53.  * @param   int     $firstinc optional: increment for the first range; default 1
  54.  * @return  array   resulting list of numbers
  55.  */
  56.  
  57. // utilities
  58. function optionRanges($limits, $max, $firstinc = 1)
  59. {
  60.     // initializations
  61.     if (is_int($limits)) $limits = array($limits);
  62.     if ($firstinc < 1) $firstinc = 1;
  63.     $opts = array();
  64.     $inc = $firstinc;
  65.  
  66.     // first element is the first increment
  67.     $opts[] = $inc;
  68.     // each $limit is the upper limit of a 'range'
  69.     foreach ($limits as $limit)
  70.     {
  71.         for ($i = $inc + $inc; $i <= $limit && $i < $max; $i += $inc)
  72.         {
  73.             $opts[] = $i;
  74.         }
  75.         // we quit at $max, even if there are more $limit elements
  76.         if ($limit >= $max)
  77.         {
  78.             // add $max to the list; then break out of the loop
  79.             $opts[] = $max;
  80.             break;
  81.         }
  82.         // when $limit is reached, it becomes the new start and increment for the next 'range'
  83.         $inc = $limit;
  84.     }
  85.  
  86.     return $opts;
  87. }
  88.  
  89. // restrict access to admins
  90. if ($this->IsAdmin($this->GetUser())) {
  91.  
  92.     // -------------------------------------
  93.     // set default values as constants
  94.     define('DEFAULT_RECORDS_LIMIT', '10'); # number of records per page
  95.     define('DEFAULT_MIN_RECORDS_DISPLAY', '5'); # min number of records
  96.     define('DEFAULT_RECORDS_RANGE',serialize(array('10','50','100','500','1000'))); #range array for records pager
  97.     define('DEFAULT_SORT_FIELD', 'signuptime'); # sort field
  98.     define('DEFAULT_SORT_ORDER', 'desc'); # sort order, ascendant or descendant
  99.     define('DEFAULT_START', '0'); # start record
  100.     define('DEFAULT_SEARCH', ''); # keyword to restrict search
  101.     define('ALTERNATE_ROW_COLOR', '1'); # switch alternate row color
  102.     define('STAT_COLUMN_COLOR', '1'); # switch color for statistics columns
  103.  
  104.     // -------------------------------------
  105.     // User-interface: icons
  106.    
  107.     define('OWNED_ICON', 'images/icons/16x16/stock_keyring.png');
  108.     define('EDITS_ICON', 'images/icons/16x16/text-editor.png');
  109.     define('COMMENTS_ICON', 'images/icons/16x16/stock_help-agent.png');
  110.  
  111.     // -------------------------------------
  112.     // User-interface: strings
  113.  
  114.     define('PAGE_TITLE','User Administration');
  115.     define('FORM_LEGEND','Filter view:');
  116.     define('FORM_SEARCH_STRING_LABEL','Search user:');
  117.     define('FORM_SEARCH_STRING_TITLE','Enter a search string');
  118.     define('FORM_SEARCH_SUBMIT','Submit');
  119.     define('FORM_PAGER_LABEL_BEFORE','Show');
  120.     define('FORM_PAGER_TITLE','Select records-per-page limit');
  121.     define('FORM_PAGER_LABEL_AFTER','records per page');
  122.     define('FORM_PAGER_SUBMIT','Apply');
  123.     define('FORM_PAGER_LINK','Show records from %d to %d');
  124.     define('FORM_RESULT_INFO','Records');
  125.     define('FORM_RESULT_SORTED_BY','Sorted by:');
  126.     define('TABLE_HEADING_USERNAME','User Name');
  127.     define('TABLE_HEADING_USERNAME_TITLE','Sort by user name');
  128.     define('TABLE_HEADING_EMAIL','Email');
  129.     define('TABLE_HEADING_EMAIL_TITLE','Sort by email');
  130.     define('TABLE_HEADING_SIGNUPTIME','Signup Time');
  131.     define('TABLE_HEADING_SIGNUPTIME_TITLE','Sort by signup time');
  132.     define('TABLE_HEADING_SIGNUPIP','Signup IP');
  133.     define('TABLE_HEADING_SIGNUPIP_TITLE','Sort by signup IP');
  134.     define('TABLE_SUMMARY','List of users registered on this server');
  135.     define('TABLE_HEADING_OWNED_TITLE','Owned Pages');
  136.     define('TABLE_HEADING_EDITS_TITLE','Page Edits');
  137.     define('TABLE_HEADING_COMMENTS_TITLE','Comments');
  138.     define('ACTION_DELETE_LINK_TITLE','Remove user %s');
  139.     define('ACTION_FEEDBACK_LINK_TITLE','Send feedback to user %s');
  140.     define('ACTION_DELETE_LINK','delete');
  141.     define('ACTION_FEEDBACK_LINK','feedback');
  142.     define('TABLE_CELL_OWNED_TITLE','Display pages owned by %s (%d)');
  143.     define('TABLE_CELL_EDITS_TITLE','Display page edits by %s (%d)');
  144.     define('TABLE_CELL_COMMENTS_TITLE','Display comments by %s (%d)');
  145.     define('SELECT_RECORD_TITLE','Select %s');
  146.     define('CHECK_ALL_TITLE','Check all records');
  147.     define('CHECK_ALL','Check all');
  148.     define('UNCHECK_ALL_TITLE','Uncheck all records');
  149.     define('UNCHECK_ALL','Uncheck all');
  150.     define('FORM_MASSACTION_LEGEND','Mass-action');
  151.     define('FORM_MASSACTION_LABEL','With selected');
  152.     define('FORM_MASSACTION_SELECT_TITLE','Choose action to apply to selected records');
  153.     define('FORM_MASSACTION_OPT_DELETE','Remove all');
  154.     define('FORM_MASSACTION_OPT_FEEDBACK','Send feedback to all');
  155.     define('FORM_MASSACTION_SUBMIT','Submit');
  156.     define('ERROR_NO_MATCHES','Sorry, there are no users matching "%s"');
  157.                
  158.     //initialize row & column colors variables
  159.     $r = 1; #initialize row counter
  160.     $r_color = ALTERNATE_ROW_COLOR; #get alternate row color option
  161.     $c_color = STAT_COLUMN_COLOR; #get column color option
  162.     // record dropdown
  163.     $user_limits = unserialize(DEFAULT_RECORDS_RANGE);
  164.     // pager
  165.     $prev = '';    
  166.     $next = '';    
  167.    
  168.     //override defaults with action parameters
  169.     if (is_array($vars))
  170.     {
  171.         foreach ($vars as $param => $value)
  172.         {
  173.             switch ($param)
  174.             {
  175.                 case 'colcolor':
  176.                     $c_color = (preg_match('/[01]/',$value))? $value : STAT_COLUMN_COLOR;
  177.                     break;
  178.                 case 'rowcolor':
  179.                     $r_color = (preg_match('/[01]/',$value))? $value : ALTERNATE_ROW_COLOR;
  180.                     break;
  181.             }
  182.         }
  183.     }
  184.    
  185.     //perform actions if required
  186.     if ($_GET['action'] == 'feedback' || $_REQUEST['mail'])
  187.     {
  188.         echo $this->Action('userfeedback');
  189.     }
  190.     elseif ($_GET['action'] == 'owned')
  191.     {
  192.         echo $this->Action('userpages');
  193.     }
  194.     elseif ($_GET['action'] == 'changes')
  195.     {
  196.         echo $this->Action('userchanges');
  197.     }
  198.     elseif ($_GET['action'] == 'comments')
  199.     {
  200.         echo $this->Action('usercomments');
  201.     }
  202.     else
  203.     {
  204.    
  205.         // process URL variables
  206.         # JW 2005-07-19 some modifications to avoid notices but these are still not actually secure
  207.    
  208.         // number of records per page
  209.         if (isset($_POST['l']))
  210.             $l = $_POST['l'];
  211.         elseif (isset($_GET['l']))
  212.             $l = $_GET['l'];
  213.         else
  214.             $l = DEFAULT_RECORDS_LIMIT;
  215.    
  216.         // sort field
  217.         $sort = (isset($_GET['sort'])) ? $_GET['sort'] : DEFAULT_SORT_FIELD;
  218.         // sort order
  219.         $d = (isset($_GET['d'])) ? $_GET['d'] : DEFAULT_SORT_ORDER;
  220.         // start record
  221.         $s = (isset($_GET['s'])) ? $_GET['s'] : DEFAULT_START;
  222.    
  223.         // search string
  224.         if (isset($_POST['q']))
  225.             $q = $_POST['q'];
  226.         elseif (isset($_GET['q']))
  227.             $q = $_GET['q'];
  228.         else
  229.             $q = DEFAULT_SEARCH;
  230.    
  231.         // select all
  232.         $checked = '';
  233.         if (isset($_GET['selectall']))
  234.         {
  235.             $checked = (1 == $_GET['selectall']) ? ' checked="checked"' : '';
  236.         }
  237.    
  238.         // restrict MySQL query by search string
  239.         $where = ('' == $q) ? "1" : "`name` LIKE '%".$q."%'";
  240.         // get total number of users
  241.         $numusers = $this->getCount('users', $where);
  242.    
  243.         // print page header
  244.         echo $this->Format('==== '.PAGE_TITLE.' ==== --- ');
  245.    
  246.         // build pager form
  247.         $form = $this->FormOpen('','','post','user_admin_panel');
  248.         $form .= '<fieldset><legend>'.FORM_LEGEND.'</legend>'."\n";
  249.         $form .= '<label for="q">'.FORM_SEARCH_STRING_LABEL.'</label> <input type ="text" id="q" name="q" title="'.FORM_SEARCH_STRING_TITLE.'" size="20" maxlength="50" value="'.$q.'"/> <input type="submit" value="'.FORM_SEARCH_SUBMIT.'" /><br />'."\n";
  250.         // ranged drop-down
  251.         $users_opts = optionRanges($user_limits,$numusers,DEFAULT_MIN_RECORDS_DISPLAY);
  252.         $form .= '<label for="l">'.FORM_PAGER_LABEL_BEFORE.'</label> '."\n";
  253.         $form .= '<select name="l" id="l" title="'.FORM_PAGER_TITLE.'">'."\n";
  254.         // build drop-down
  255.         foreach ($users_opts as $opt) {
  256.             $selected = ($opt == $l) ? ' selected="selected"' : '';
  257.             $form .= '<option value="'.$opt.'"'.$selected.'>'.$opt.'</option>'."\n";
  258.         }
  259.         $form .=  '</select> <label for="l">'.FORM_PAGER_LABEL_AFTER.'</label> <input type="submit" value="'.FORM_PAGER_SUBMIT.'" /><br />'."\n";
  260.    
  261.         // build pager links
  262.         if ($s > 0)
  263.             $prev = '<a href="' .$this->Href('','','l='.$l.'&amp;sort='.$sort.'&amp;d='.$d.'&amp;s='.($s-$l)).'&amp;q='.$q.'" title="'.sprintf(FORM_PAGER_LINK, ($s-$l+1), $s).'">'.($s-$l+1).'-'.$s.'</a> |  '."\n";
  264.         if ($numusers > ($s + $l))
  265.             $next = ' | <a href="'.$this->Href('','','l='.$l.'&amp;sort='.$sort.'&amp;d='.$d.'&amp;s='.($s+$l)).'&amp;q='.$q.'" title="'.sprintf(FORM_PAGER_LINK, ($s+$l+1), ($s+2*$l)).'">'.($s+$l+1).'-'.($s+2*$l).'</a>'."\n";
  266.         $form .= FORM_RESULT_INFO.' ('.$numusers.'): '.$prev.($s+1).'-'.($s+$l).$next.'<br />'."\n";
  267.         $form .= '('.FORM_RESULT_SORTED_BY.'<em>'.$sort.', '.$d.'</em>)'."\n";
  268.         $form .= '</fieldset>'.$this->FormClose()."\n";
  269.  
  270.         // print form
  271.         echo $form;
  272.    
  273.         // get user list
  274.         $userdata = $this->LoadAll("SELECT * FROM ".$this->config["table_prefix"]."users WHERE ".
  275.         $where." ORDER BY ".$sort." ".$d." limit ".$s.", ".$l);
  276.    
  277.         if ($userdata) {
  278.    
  279.             // build header links
  280.             $nameheader = '<a href="'.$this->Href('','', (($sort == 'name' && $d == 'asc')? 'l='.$l.'&amp;sort=name&amp;d=desc' : 'l='.$l.'&amp;sort=name&amp;d=asc')).'" title="'.TABLE_HEADING_USERNAME_TITLE.'">'.TABLE_HEADING_USERNAME.'</a>';
  281.             $emailheader = '<a href="'.$this->Href('','', (($sort == 'email' && $d == 'asc')? 'l='.$l.'&amp;sort=email&amp;d=desc' : 'l='.$l.'&amp;sort=email&amp;d=asc')).'" title="'.TABLE_HEADING_EMAIL_TITLE.'">'.TABLE_HEADING_EMAIL.'</a>';
  282.             $timeheader = '<a href="'.$this->Href('','', (($sort == 'signuptime' && $d == 'desc')? 'l='.$l.'&amp;sort=signuptime&amp;d=asc' : 'l='.$l.'')).'" title="'.TABLE_HEADING_SIGNUPTIME_TITLE.'">'.TABLE_HEADING_SIGNUPTIME.'</a>';
  283.  
  284.             /*$ipheader = '<a href="'.$this->Href('','', (($sort == 'ipaddress' && $d == 'desc')? 'l='.$l.'&amp;sort=ipaddress&amp;d=asc' : 'l='.$l.'&amp;sort=ipaddress&amp;d=desc')).'" title="'.TABLE_HEADING_SIGNUPIP_TITLE.'">'.TABLE_HEADING_SIGNUPIP.'</a>'; # installed as beta feature at wikka.jsnx.com  */
  285.    
  286.             // build table headers
  287.             $htmlout = "<table summary=\"".TABLE_SUMMARY."\" border=\"1px\" id=\"admin_table\">\n<thead>\n".
  288.             "  <tr>\n".
  289.                 "    <th>&nbsp;</th>\n".
  290.                 "    <th>".$nameheader."</th>\n".
  291.                 "    <th>".$emailheader."</th>\n".
  292.                 "    <th>".$timeheader."</th>\n".
  293.                 /* "    <th>".$ipheader."</th>\n". # installed as beta feature at wikka.jsnx.com */
  294.                 "    <th class=\"number ".(($c_color == 1)? ' c1' : '')."\" title=\"".TABLE_HEADING_OWNED_TITLE."\"><img src=\"".OWNED_ICON."\" alt=\"O\"/></th>\n".
  295.                 "    <th class=\"number ".(($c_color == 1)? ' c2' : '')."\" title=\"".TABLE_HEADING_EDITS_TITLE."\"><img src=\"".EDITS_ICON."\" alt=\"E\"/></th>\n".
  296.                 "    <th class=\"number ".(($c_color == 1)? ' c3' : '')."\" title=\"".TABLE_HEADING_COMMENTS_TITLE."\"><img src=\"".COMMENTS_ICON."\" alt=\"C\"/></th>\n".
  297.                 "    <th class=\"center\">Actions</th>\n".
  298.                     "  </tr>\n</thead>\n";
  299.    
  300.             // print user table
  301.             foreach($userdata as $user) {
  302.    
  303.                 // get counts  
  304.                 $where_owned    = "`owner` = '".$user['name']."' AND latest = 'Y'";
  305.                 $where_changes  = "`user` = '".$user['name']."'";
  306.                 $where_comments = "`user` = '".$user['name']."'";
  307.                 $numowned = $this->getCount('pages', $where_owned);
  308.                 $numchanges = $this->getCount('pages', $where_changes);
  309.                 $numcomments = $this->getCount('comments', $where_comments);
  310.        
  311.                 // build statistics links if needed
  312.                 $ownedlink = ($numowned > 0)? '<a title="'.sprintf(TABLE_CELL_OWNED_TITLE,$user['name'],$numowned).'" href="'.$this->Href('','','user='.$user['name'].'&amp;action=owned').'">'.$numowned.'</a>' : '0';
  313.                 $changeslink = ($numchanges > 0)? '<a title="'.sprintf(TABLE_CELL_EDITS_TITLE,$user['name'],$numchanges).'" href="'.$this->Href('','','user='.$user['name'].'&amp;action=changes').'">'.$numchanges.'</a>' : '0';
  314.                 $commentslink = ($numcomments > 0)? '<a title="'.sprintf(TABLE_CELL_COMMENTS_TITLE,$user['name'],$numcomments).'" href="'.$this->Href('','','user='.$user['name'].'&amp;action=comments').'">'.$numcomments.'</a>' : '0';
  315.  
  316.                 // build handler links
  317.                 $deleteuser = '<a title="'.sprintf(ACTION_DELETE_LINK_TITLE, $user['name']).'" href="'.$this->Href('','','user='.$user['name'].'&amp;action=delete').'">'.ACTION_DELETE_LINK.'</a>';
  318.                 $feedbackuser = '<a title="'.sprintf(ACTION_FEEDBACK_LINK_TITLE, $user['name']).'" href="'.$this->Href('','','user='.$user['name'].'&amp;action=feedback').'">'.ACTION_FEEDBACK_LINK.'</a>';
  319.    
  320.                 // build table body
  321.                 $htmlout .= "<tbody>\n";
  322.                 if ($r_color == 1) {
  323.                     $htmlout .= "<tr ".(($r%2)? '' : 'class="alt"').">\n"; #enable alternate row color
  324.                 } else {
  325.                     $htmlout .= "<tr>\n"; #disable alternate row color
  326.                 }
  327.                 $htmlout .= "   <td><input type=\"checkbox\" id=\"".$user['id']."\"".$checked." title=\"".sprintf(SELECT_RECORD_TITLE,$user['name'])."\"/></td>\n".
  328.                 "   <td>".(($this->ExistsPage($user['name']))? $this->Link($user['name']) : $user['name'])."</td>\n". #check if userpage exists
  329.                 "   <td>".$user['email']."</td>\n".
  330.                 "   <td class=\"time\">".$user['signuptime']."</td>\n".
  331.                 /* "    <td>".$user['ipaddress']."</td>\n". # installed as beta feature at wikka.jsnx.com */
  332.                 "   <td class=\"number".(($c_color == 1)? ' c1' : '')."\">".$ownedlink."</td>\n".  #set column color
  333.                 "   <td class=\"number".(($c_color == 1)? ' c2' : '')."\">".$changeslink."</td>\n". #set column color
  334.                 "   <td class=\"number".(($c_color == 1)? ' c3' : '')."\">".$commentslink."</td>\n".   #set column color
  335.                 "   <td class=\"center\">".$deleteuser." :: ".$feedbackuser."</td>\n";
  336.                 $htmlout .= "  </tr>\n</tbody>\n";
  337.    
  338.                 //increase row counter    ----- alternate row colors
  339.                 if ($r_color == 1) $r++;
  340.                 }
  341.             $htmlout .= "</table>\n";
  342.             // print the table
  343.             echo $this->FormOpen('','','get');
  344.             echo $htmlout;
  345.            
  346.             // multiple-user operations (forthcoming)       JW 2005-07-19 accesskey removed (causes more problems than it solves)
  347.             echo '<fieldset><legend>'.FORM_MASSACTION_LEGEND.'</legend>';
  348.             echo '[<a href="'.$this->Href('','','l='.$l.'&amp;sort='.$sort.'&amp;d='.$d.'&amp;s='.$s.'&amp;q='.$q.'&amp;selectall=1').'" title="'.CHECK_ALL_TITLE.'">'.CHECK_ALL.'</a> | <a href="'.$this->Href('','','l='.$l.'&amp;sort='.$sort.'&amp;d='.$d.'&amp;s='.$s.'&amp;q='.$q.'&amp;selectall=0').'" title="'.UNCHECK_ALL_TITLE.'">'.UNCHECK_ALL.'</a>]<br />';
  349.             echo '<label for="action" >'.FORM_MASSACTION_LABEL.'</label> <select title="'.FORM_MASSACTION_SELECT_TITLE.'" id="action" name="action">';
  350.             echo '<option value="" selected="selected">---</option>';
  351.             echo '<option value="massdelete">'.FORM_MASSACTION_OPT_DELETE.'</option>';
  352.             echo '<option value="massfeedback">'.FORM_MASSACTION_OPT_FEEDBACK.'</option>';
  353.             echo '</select> <input type="submit" value="'.FORM_MASSACTION_SUBMIT.'" />';
  354.             echo '</fieldset>';
  355.             echo $this->FormClose();
  356.         }
  357.         else
  358.         {
  359.             // no records matching the search string: print error message
  360.             echo '<p><span class="error">'.sprintf(ERROR_NO_MATCHES, $q).'</span></p>';
  361.         }
  362.     }
  363. } else {
  364.     // user is not admin
  365.     echo $this->Action('lastusers');
  366. }
  367. ?>


New CSS classes


The styling of the tables requires a bunch of TableStyling new CSS classes.


Styling options


The useradmin action accepts two optional styling parameters:

colcolor

Enables color for statistics columns
1: enables colored columns (default);
0: disables colored columns;

rowcolor

Enables alternate row colors
1: enables colored rows (default);
0: disables colored rows;

The following examples show how the table is rendered using these two parameters:


{{useradmin colcolor="0" rowcolor="0"}}
  User Name Email Signup Time Signup IP O E C Actions
HypeXR scott@xxxx.xx 2005-08-01 09:01:54 XX.XX.XX.XX 1 2 1 delete :: feedback
WiebTest wiebren.w@xxxx.xx 2005-07-31 19:35:26 XX.XX.XX.XX 0 0 0 delete :: feedback
DennyShimkoski denny@xxxx.xx 2005-07-31 00:22:58 XX.XX.XX.XX 6 38 1 delete :: feedback


{{useradmin colcolor="0"}}
  User Name Email Signup Time Signup IP O E C Actions
HypeXR scott@xxxx.xx 2005-08-01 09:01:54 XX.XX.XX.XX 1 2 1 delete :: feedback
WiebTest wiebren.w@xxxx.xx 2005-07-31 19:35:26 XX.XX.XX.XX 0 0 0 delete :: feedback
DennyShimkoski denny@xxxx.xx 2005-07-31 00:22:58 XX.XX.XX.XX 6 38 1 delete :: feedback


{{useradmin rowcolor="0"}}
  User Name Email Signup Time Signup IP O E C Actions
HypeXR scott@xxxx.xx 2005-08-01 09:01:54 XX.XX.XX.XX 1 2 1 delete :: feedback
WiebTest wiebren.w@xxxx.xx 2005-07-31 19:35:26 XX.XX.XX.XX 0 0 0 delete :: feedback
DennyShimkoski denny@xxxx.xx 2005-07-31 00:22:58 XX.XX.XX.XX 6 38 1 delete :: feedback


{{useradmin}}
  User Name Email Signup Time Signup IP O E C Actions
HypeXR scott@xxxx.xx 2005-08-01 09:01:54 XX.XX.XX.XX 1 2 1 delete :: feedback
WiebTest wiebren.w@xxxx.xx 2005-07-31 19:35:26 XX.XX.XX.XX 0 0 0 delete :: feedback
DennyShimkoski denny@xxxx.xx 2005-07-31 00:22:58 XX.XX.XX.XX 6 38 1 delete :: feedback






CategoryDevelopmentActions CategoryDevelopmentAdmin
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki