User Administration Module

Last edited by DarTar:
link to docs
Mon, 10 Mar 2008 11:12 UTC [diff]


This is the development page for the User Administration module. The User Administration module has been committed to the 1.1.6.4 branch and will be available with the 1.1.6.4 release. Documentation http://docs.wikkawiki.org/UserAdministration

This action is meant to allow Wikka Administrators to manage users and perform several maintenance operations.
It displays the standard LastUsers list to non-admins.

See also:
 


Why?

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 version

(2005-08-31): 0.5

Files needed
(2004-09-16):

To do




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
The code has also been adapted to take advantage of the getCount() method, which is required for the action to work.

  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     0.5
  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.'&sort='.$sort.'&d='.$d.'&s='.($s-$l)).'&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.'&sort='.$sort.'&d='.$d.'&s='.($s+$l)).'&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.'&sort=name&d=desc' : 'l='.$l.'&sort=name&d=asc')).'" title="'.TABLE_HEADING_USERNAME_TITLE.'">'.TABLE_HEADING_USERNAME.'</a>';
  281.             $emailheader = '<a href="'.$this->Href('','', (($sort == 'email' && $d == 'asc')? 'l='.$l.'&sort=email&d=desc' : 'l='.$l.'&sort=email&d=asc')).'" title="'.TABLE_HEADING_EMAIL_TITLE.'">'.TABLE_HEADING_EMAIL.'</a>';
  282.             $timeheader = '<a href="'.$this->Href('','', (($sort == 'signuptime' && $d == 'desc')? 'l='.$l.'&sort=signuptime&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.'&sort=ipaddress&d=asc' : 'l='.$l.'&sort=ipaddress&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> </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'].'&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'].'&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'].'&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'].'&action=delete').'">'.ACTION_DELETE_LINK.'</a>';
  318.                 $feedbackuser = '<a title="'.sprintf(ACTION_FEEDBACK_LINK_TITLE, $user['name']).'" href="'.$this->Href('','','user='.$user['name'].'&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.'&sort='.$sort.'&d='.$d.'&s='.$s.'&q='.$q.'&selectall=1').'" title="'.CHECK_ALL_TITLE.'">'.CHECK_ALL.'</a> | <a href="'.$this->Href('','','l='.$l.'&sort='.$sort.'&d='.$d.'&s='.$s.'&q='.$q.'&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 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:


No styling: {{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


Alternate rows only: {{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


Colored columns only: {{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


Alternate rows and colored columns: {{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