=====Page Administration Action=====
{{lastedit}}
This is the development page for the Page Administration action. The Page Administration module has been committed to the [[http://wush.net/websvn/wikka/listing.php?repname=wikka&path=%2Fbranches%2F1.1.6.4%2F 1.1.6.4 branch]] and will be available with the [[http://blog.wikkawiki.org/2007/11/23/pre-release-announcement-for-securityantispam-release-1164/ 1.1.6.4 release]]. **Documentation** http://docs.wikkawiki.org/PageAdministration
This action, inspired by the UserAdmin action, is meant to allow Wikka Administrators to manage pages and perform several maintenance operations.
It displays the standard PageIndex to non-admins.
>>**See also:**
~-AdminModules
~-RefactorWiki
~-MovePages
~-PageAdminPrune
~-Are you an administrator of this site ? --- Give it a [[PageAdminTest try]]
>><<**Table of Contents:**
~-""Current version""
~-""To do""
~-""The code""
~-""Styling options""<<
::c::
----
== Sample output ==
=====Page Administration=====
""
""
----
=== Current version ===
Latest available version: **0.4**.
**Features:**
~-displays a pageable, sortable and searchable list of pages;
~-displays detailed and clickable page statistics (revisions, comments, backlinks, referrers)
~-generates links to different handlers with titles;
~-shortens long pagenames and hostnames;
~-shows last edit notes (if available);
~-adds 'claim' links to pages with no owner;
~-shows plain-text username in owner/lastauthor fields if user has no homepage;
~-supports a bunch of configurable options (including max. length of displayed pagename, max. length of hostname, symbol for truncated text).
**Bugfixes and modifications:**
~-added constant section;
~-added titles to different form elements;
~-added configurable hostname and pagename length limit;
~-fixed problem with search keyword not read by pager;
~-added submit buttons after menus;
~-fixed invalid markup resulting in green text on the whole page.
~-using getCount() to retrieve the various counts --JW
~-various changes to prevent NOTICEs --JW
~-removed accesskey attributes (cause more problems than they solve) --JW
~-various other minor tweaks --JW
~-added icons and UI strings;
~-added several configurable options, including styling options (see below);
=== To do===
~-Mass-operations (mass-page deletion (''done as of 1.1.6.4''), mass-page rename, mass-page ACLs etc.);
~~-I have included a first MassaclsAction as a preview/draft/beta, like you want --AndreasTengicki
~-Handlers: add rename handler;
~-Page statistics: add page hits;
~~& Can I advocate for a "Page Hide/Unhide" option here?....H instead of Y or N for most recent works well. In some communities, particularly where there might be legal/administrative follow-ups to what was posted, it is quite useful to be able to "keep" the contents of the page in the database, but make them inaccessible to the wiki users. --GmBowen
~~~& Mike, as you can see this interface does not add any specific handler or page feature which is not already supported by Wikka: it is just a //hub// for existing handlers (the multiple-page operations will require new handlers, though). So if you want to propose something like a 'hide/unhide' handler, I suggest you open a dedicated page. -- DarTar
~~~&To be more precise, this action //does// include two forthcoming features (rename handler, page hits) but only as //placeholders//. The development of each of these functionalities should be take place elsewhere, not on this page. -- DarTar
~~~~&There might as well be a placeholer for a future "hide" or "lock" handler then. :) We certainly need //something// like that - see comments.--JavaWoman.
===The code ===
Save the code below as ##actions/pageadmin.php## and use it as ##""{{pageadmin}}""##.
**Note:** The code has been adapted to take advantage of the ##[[WikkaCountingRecords getCount()]]## and ##[[FormatUserMethod FormatUser()]]## methods, which are required for the action to work.
%%(php;1)
= $max)
{
// add $max to the list; then break out of the loop
$opts[] = $max;
break;
}
// when $limit is reached, it becomes the new start and increment for the next 'range'
$inc = $limit;
}
return $opts;
}
// restrict access to admins
if ($this->IsAdmin($this->GetUser())) {
// -------------------------------------
// set default values as constants
define('DEFAULT_RECORDS_LIMIT', '20'); # number of records per page
define('DEFAULT_MIN_RECORDS_DISPLAY', '5'); # min number of records
define('DEFAULT_RECORDS_RANGE',serialize(array('10','50','100','500','1000'))); #range array for records pager
define('DEFAULT_SORT_FIELD', 'time'); # sort field
define('DEFAULT_SORT_ORDER', 'desc'); # sort order, ascendant or descendant
define('DEFAULT_START', '0'); # start record
define('DEFAULT_SEARCH', ''); # keyword to restrict page search
define('DEFAULT_TAG_LENGTH', '12'); # max. length of displayed pagename
define('DEFAULT_URL_LENGTH', '15'); # max. length of displayed user host
define('DEFAULT_TERMINATOR', '…'); # standard symbol replacing truncated text (ellipsis) JW 2005-07-19
define('ALTERNATE_ROW_COLOR', '1'); # switch alternate row color
define('STAT_COLUMN_COLOR', '1'); # switch color for statistics columns
// -------------------------------------
// User-interface: icons
define('HITS_ICON', 'images/icons/16x16/stock_about.png');
define('REVISIONS_ICON', 'images/icons/16x16/stock_book_open.png');
define('COMMENTS_ICON', 'images/icons/16x16/stock_help-agent.png');
define('BACKLINKS_ICON', 'images/icons/16x16/stock_link.png');
define('REFERRERS_ICON', 'images/icons/16x16/stock_internet.png');
// -------------------------------------
// User-interface: strings
define('PAGE_TITLE','Page Administration');
define('FORM_LEGEND','Filter view:');
define('FORM_SEARCH_STRING_LABEL','Search page:');
define('FORM_SEARCH_STRING_TITLE','Enter a search string');
define('FORM_SEARCH_SUBMIT','Submit');
define('FORM_PAGER_LABEL_BEFORE','Show');
define('FORM_PAGER_TITLE','Select records-per-page limit');
define('FORM_PAGER_LABEL_AFTER','records per page');
define('FORM_PAGER_SUBMIT','Apply');
define('FORM_PAGER_LINK','Show records from %d to %d');
define('FORM_RESULT_INFO','Records');
define('FORM_RESULT_SORTED_BY','Sorted by:');
define('TABLE_HEADING_PAGENAME','Page Name');
define('TABLE_HEADING_PAGENAME_TITLE','Sort by page name');
define('TABLE_HEADING_OWNER','Owner');
define('TABLE_HEADING_OWNER_TITLE','Sort by page owner');
define('TABLE_HEADING_LASTAUTHOR','Last Author');
define('TABLE_HEADING_LASTAUTHOR_TITLE','Sort by last author');
define('TABLE_HEADING_LASTEDIT','Last Edit');
define('TABLE_HEADING_LASTEDIT_TITLE','Sort by edit time');
define('TABLE_SUMMARY','List of pages on this server');
define('TABLE_HEADING_HITS_TITLE','Hits');
define('TABLE_HEADING_REVISIONS_TITLE','Sort by number of revisions (DEBUG ONLY)');
define('TABLE_HEADING_COMMENTS_TITLE','Comments');
define('TABLE_HEADING_BACKLINKS_TITLE','Backlinks');
define('TABLE_HEADING_REFERRERS_TITLE','Referrers');
define('TABLE_HEADING_HITS_ALT','Hits');
define('TABLE_HEADING_REVISIONS_ALT','Revisions');
define('TABLE_HEADING_COMMENTS_ALT','Comments');
define('TABLE_HEADING_BACKLINKS_ALT','Backlinks');
define('TABLE_HEADING_REFERRERS_ALT','Referrers');
define('TABLE_HEADING_ACTIONS','Actions');
define('ACTION_EDIT_LINK_TITLE','Edit %s');
define('ACTION_DELETE_LINK_TITLE','Delete %s');
define('ACTION_CLONE_LINK_TITLE','Clone %s');
define('ACTION_RENAME_LINK_TITLE','Rename %s (DISABLED)');
define('ACTION_ACL_LINK_TITLE','Change Access Control List for %s');
define('ACTION_INFO_LINK_TITLE','Display information and statistics for %s');
define('ACTION_EDIT_LINK','edit');
define('ACTION_DELETE_LINK','delete');
define('ACTION_CLONE_LINK','clone');
define('ACTION_RENAME_LINK','rename');
define('ACTION_ACL_LINK','acl');
define('ACTION_INFO_LINK','info');
define('TAKE_OWNERSHIP_LINK','Take ownership of');
define('NO_OWNER','(Nobody)');
define('TABLE_CELL_HITS_TITLE','Hits for %s (%d)');
define('TABLE_CELL_REVISIONS_TITLE','Display revisions for %s (%d)');
define('TABLE_CELL_COMMENTS_TITLE','Display comments for %s (%d)');
define('TABLE_CELL_BACKLINKS_TITLE','Display pages linking to %s (%d)');
define('TABLE_CELL_REFERRERS_TITLE','Display external sites linking to %s (%d)');
define('SELECT_RECORD_TITLE','Select %s');
define('NO_EDIT_NOTE','[No edit note]');
define('CHECK_ALL_TITLE','Check all records');
define('CHECK_ALL','Check all');
define('UNCHECK_ALL_TITLE','Uncheck all records');
define('UNCHECK_ALL','Uncheck all');
define('FORM_MASSACTION_LEGEND','Mass-action');
define('FORM_MASSACTION_LABEL','With selected');
define('FORM_MASSACTION_SELECT_TITLE','Choose action to apply to selected records (DISABLED)');
define('FORM_MASSACTION_OPT_DELETE','Delete all');
define('FORM_MASSACTION_OPT_CLONE','Clone all');
define('FORM_MASSACTION_OPT_RENAME','Rename all');
define('FORM_MASSACTION_OPT_ACL','Change Access Control List');
define('FORM_MASSACTION_SUBMIT','Submit');
define('ERROR_NO_MATCHES','Sorry, there are no pages matching "%s"');
// -------------------------------------
// Initialize variables
$r = 1; #initialize row counter
$r_color = ALTERNATE_ROW_COLOR; #get alternate row color option
$c_color = STAT_COLUMN_COLOR; #get column color option
// record dropdown
$page_limits = unserialize(DEFAULT_RECORDS_RANGE);
// pager
$prev = '';
$next = '';
//override defaults with action parameters
if (is_array($vars)) {
foreach ($vars as $param => $value){
switch ($param) {
case 'colcolor':
$c_color = (preg_match('/[01]/',$value))? $value : STAT_COLUMN_COLOR;
break;
case 'rowcolor':
$r_color = (preg_match('/[01]/',$value))? $value : ALTERNATE_ROW_COLOR;
break;
}
}
}
//perform mass-operations if required (forthcoming)
if (isset($_GET['action']))
{
if ($_GET['action'] == 'massdelete')
{
echo $this->Action('massdelete');
}
elseif ($_GET['action'] == 'massrename')
{
echo $this->Action('massrename');
}
elseif ($_GET['action'] == 'massacls')
{
echo $this->Action('massacls');
}
}
else
{
// process URL variables
# JW 2005-07-19 some modifications to avoid notices but these are still not actually secure
// number of records per page
if (isset($_POST['l']))
$l = $_POST['l'];
elseif (isset($_GET['l']))
$l = $_GET['l'];
else
$l = DEFAULT_RECORDS_LIMIT;
// sort field
$sort = (isset($_GET['sort'])) ? $_GET['sort'] : DEFAULT_SORT_FIELD;
// sort order
$d = (isset($_GET['d'])) ? $_GET['d'] : DEFAULT_SORT_ORDER;
// start record
$s = (isset($_GET['s'])) ? $_GET['s'] : DEFAULT_START;
// search string
if (isset($_POST['q']))
$q = $_POST['q'];
elseif (isset($_GET['q']))
$q = $_GET['q'];
else
$q = DEFAULT_SEARCH;
// select all added JW 2005-07-19
$checked = '';
if (isset($_GET['selectall']))
{
$checked = (1 == $_GET['selectall']) ? ' checked="checked"' : '';
}
// restrict MySQL query by search string modified JW 2005-07-19
$where = ('' == $q) ? "`latest` = 'Y'" : "`tag` LIKE '%".$q."%' AND `latest` = 'Y'";
// get total number of pages
$numpages = $this->getCount('pages',$where);
// print page header
echo $this->Format('==== '.PAGE_TITLE.' ==== --- ');
// build pager form
$form1 = $this->FormOpen('','','post','page_admin_panel');
$form1 .= ''.$this->FormClose()."\n";
// print form
echo $form1;
// sort by counted values
switch($sort)
{
case 'edits': #alpha --- 'latest' needs to be disabled
//sample query:
//SELECT *, COUNT(*) as edits FROM `wikka1160_pages` GROUP BY tag ORDER BY edits DESC
$count = ', COUNT(*) as edits';
$group = 'GROUP BY tag';
$where = '1';
//$where = ('' == $q) ? "1" : "`tag` LIKE '%".$q."%'";
$table = 'pages';
break;
case 'comments': #to implement
/*
// SELECT wikka1160_pages.tag, COUNT( * ) AS comments FROM wikka1160_pages, wikka1160_comments WHERE wikka1160_pages.tag = wikka1160_comments.page_tag GROUP BY wikka1160_pages.tag ORDER BY comments DESC
$count = ', COUNT(*) as edits';
$group = 'GROUP BY tag';
$where = '1';
*/
break;
default:
$table = 'pages';
}
// get page list
$pagedata = $this->LoadAll("SELECT *".$count." FROM ".$this->config["table_prefix"].$table." WHERE ".
$where." ".$group." ORDER BY ".$sort." ".$d." LIMIT ".$s.", ".$l);
if ($pagedata)
{
// build table headers
$tagheader = ''.TABLE_HEADING_PAGENAME.'';
$ownerheader = ''.TABLE_HEADING_OWNER.'';
$userheader = ''.TABLE_HEADING_LASTAUTHOR.'';
$lasteditheader = ''.TABLE_HEADING_LASTEDIT.'';
$revisionsheader = '';
$htmlout = "
\n".
"\n
\n".
"
\n".
"
".$tagheader."
\n".
"
".$ownerheader."
\n".
"
".$userheader."
\n".
"
".$lasteditheader."
\n".
"
\n".
"
".$revisionsheader."
\n".
"
\n".
"
\n".
"
\n".
"
".TABLE_HEADING_ACTIONS."
\n".
"
\n\n";
// feed table with data
foreach($pagedata as $page)
{
// truncate long page names
$pagename = (strlen($page['tag']) > DEFAULT_TAG_LENGTH) ? substr($page['tag'], 0, DEFAULT_TAG_LENGTH).DEFAULT_TERMINATOR : $page['tag'];
// build handler links
$lastedit = $page['time'];
if ($pagename != $page['tag'])
{
$showpage = ''.$pagename.'';
}
else
{
$showpage = ''.$pagename.'';
}
$editpage = ''.ACTION_EDIT_LINK.'';
$deletepage = ''.ACTION_DELETE_LINK.'';
$clonepage = ''.ACTION_CLONE_LINK.'';
// renaming disabled
$renamepage = ''.ACTION_RENAME_LINK.'';
$aclpage = ''.ACTION_ACL_LINK.'';
$infopage = ''.ACTION_INFO_LINK.'';
// get page owner
if ($page['owner'])
{
// is the owner a registered user?
if ($this->LoadUser($page['owner']))
{
// does user's homepage exist?
if ($this->ExistsPage($page['owner']))
{
$owner = $this->Link($page['owner']);
}
else
{
$owner = $page['owner'];
}
}
else
{
$owner = $page['owner'];
}
}
else
{
// page has empty owner field: print claim link
$owner = $this->Link($page['tag'], 'claim','(Nobody)','','',TAKE_OWNERSHIP_LINK.' '.$page['tag']);
}
// get last author
if ($page['user'])
{
// is the author a registered user?
if ($this->LoadUser($page['user']))
{
// does user's homepage exist?
if ($this->ExistsPage($page['user']))
{
$user = $this->Link($page['user']);
}
else
{
$user = $page['user'];
}
}
else
{
// truncate long host names
$user = (strlen($page['user']) > DEFAULT_URL_LENGTH) ? substr($page['user'], 0, DEFAULT_URL_LENGTH).DEFAULT_TERMINATOR : $page['user'];
# added JW 2005-07-19
if ($user != $page['user'])
{
$user = ''.$user.'';
}
}
}
else
{
// page has empty user field
$user = NO_OWNER;
}
// get counts - JW 2005-07-19
$whereTag = "`tag` = '".$page['tag']."'";
$wherePageTag = "`page_tag` = '".$page['tag']."'";
$whereToTag = "`to_tag` = '".$page['tag']."'";
$hn = 0;
$rv = $this->getCount('pages',$whereTag);
$cn = $this->getCount('comments',$wherePageTag);
$bn = $this->getCount('links',$whereToTag);
$rn = $this->getCount('referrers',$wherePageTag);
// get page hits (forthcoming)
$hitspage = ($hn > 0) ? ''.$hn.'' : '0';
// get page revisions and create revision link if needed
$revpage = ($rv > 0) ? ''.$rv.'' : '0';
// get page comments and create comments link if needed
$commentspage = ($cn > 0) ? ''.$cn.'' : '0';
// get page backlinks and create backlinks link
$backlinkpage = ($bn > 0) ? ''.$bn.'' : '0';
// get page referrers and create referrer link
$refpage = ($rn > 0) ? ''.$rn.'' : '0';
// build table body
$htmlout .= "\n";
if ($r_color == 1) {
$htmlout .= "
'."\n";
// print the table
echo $this->FormOpen('','','get');
echo $htmlout;
// multiple-page operations (forthcoming) JW 2005-07-19 accesskey removed (causes more problems than it solves)
echo '';
echo $this->FormClose();
}
else
{
// no records matching the search string: print error message
echo '
'.sprintf(ERROR_NO_MATCHES, $q).'
';
}
}
}
else
{
// current user is not admin: show plain page index
echo $this->Action('pageindex');
}
?>
%%
===New CSS classes===
The styling of the tables requires a bunch of [[TableStyling new CSS classes]].
----
==== Styling options ====
The ##pageadmin## 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:** ##""{{pageadmin colcolor="0" rowcolor="0"}}""##
""