summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/exe/css.php155
-rw-r--r--lib/exe/mediamanager.php7
-rw-r--r--lib/plugins/acl/admin.php2
-rw-r--r--lib/plugins/acl/lang/nl/lang.php4
-rw-r--r--lib/plugins/auth.php12
-rw-r--r--lib/plugins/authad/conf/metadata.php24
-rw-r--r--lib/plugins/authad/lang/nl/settings.php5
-rw-r--r--lib/plugins/authldap/conf/metadata.php32
-rw-r--r--lib/plugins/authldap/lang/nl/settings.php5
-rw-r--r--lib/plugins/authmysql/conf/metadata.php64
-rw-r--r--lib/plugins/authmysql/lang/nl/settings.php5
-rw-r--r--lib/plugins/authpgsql/conf/metadata.php60
-rw-r--r--lib/plugins/authpgsql/lang/nl/settings.php5
-rw-r--r--lib/plugins/plugin/lang/nl/lang.php5
-rw-r--r--lib/plugins/popularity/lang/nl/lang.php5
-rw-r--r--lib/plugins/revert/lang/nl/lang.php5
-rw-r--r--lib/plugins/usermanager/admin.php249
-rw-r--r--lib/plugins/usermanager/lang/en/import.txt9
-rw-r--r--lib/plugins/usermanager/lang/en/lang.php18
-rw-r--r--lib/plugins/usermanager/lang/nl/lang.php5
-rw-r--r--lib/plugins/usermanager/style.css9
-rw-r--r--lib/tpl/dokuwiki/css/pagetools.less321
22 files changed, 574 insertions, 432 deletions
diff --git a/lib/exe/css.php b/lib/exe/css.php
index 83972d407..9e1e22e1a 100644
--- a/lib/exe/css.php
+++ b/lib/exe/css.php
@@ -40,43 +40,32 @@ function css_out(){
$type = '';
}
+ // decide from where to get the template
$tpl = trim(preg_replace('/[^\w-]+/','',$INPUT->str('t')));
- if($tpl){
- $tplinc = DOKU_INC.'lib/tpl/'.$tpl.'/';
- $tpldir = DOKU_BASE.'lib/tpl/'.$tpl.'/';
- }else{
- $tplinc = tpl_incdir();
- $tpldir = tpl_basedir();
- }
-
- // used style.ini file
- $styleini = css_styleini($tplinc);
+ if(!$tpl) $tpl = $conf['template'];
// The generated script depends on some dynamic options
- $cache = new cache('styles'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].DOKU_BASE.$tplinc.$type,'.css');
+ $cache = new cache('styles'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].DOKU_BASE.$tpl.$type,'.css');
- // load template styles
- $tplstyles = array();
- if ($styleini) {
- foreach($styleini['stylesheets'] as $file => $mode) {
- $tplstyles[$mode][$tplinc.$file] = $tpldir;
- }
- }
+ // load styl.ini
+ $styleini = css_styleini($tpl);
// if old 'default' userstyle setting exists, make it 'screen' userstyle for backwards compatibility
if (isset($config_cascade['userstyle']['default'])) {
$config_cascade['userstyle']['screen'] = $config_cascade['userstyle']['default'];
}
- // Array of needed files and their web locations, the latter ones
- // are needed to fix relative paths in the stylesheets
- $files = array();
-
+ // cache influencers
+ $tplinc = tpl_basedir($tpl);
$cache_files = getConfigFiles('main');
$cache_files[] = $tplinc.'style.ini';
- $cache_files[] = $tplinc.'style.local.ini';
+ $cache_files[] = $tplinc.'style.local.ini'; // @deprecated
+ $cache_files[] = DOKU_CONF."tpl/$tpl/style.ini";
$cache_files[] = __FILE__;
+ // Array of needed files and their web locations, the latter ones
+ // are needed to fix relative paths in the stylesheets
+ $files = array();
foreach($mediatypes as $mediatype) {
$files[$mediatype] = array();
// load core styles
@@ -88,8 +77,8 @@ function css_out(){
// load plugin styles
$files[$mediatype] = array_merge($files[$mediatype], css_pluginstyles($mediatype));
// load template styles
- if (isset($tplstyles[$mediatype])) {
- $files[$mediatype] = array_merge($files[$mediatype], $tplstyles[$mediatype]);
+ if (isset($styleini['stylesheets'][$mediatype])) {
+ $files[$mediatype] = array_merge($files[$mediatype], $styleini['stylesheets'][$mediatype]);
}
// load user styles
if(isset($config_cascade['userstyle'][$mediatype])){
@@ -101,7 +90,7 @@ function css_out(){
// please use "[dir=rtl]" in any css file in all, screen or print mode instead
if ($mediatype=='screen') {
if($lang['direction'] == 'rtl'){
- if (isset($tplstyles['rtl'])) $files[$mediatype] = array_merge($files[$mediatype], $tplstyles['rtl']);
+ if (isset($styleini['stylesheets']['rtl'])) $files[$mediatype] = array_merge($files[$mediatype], $styleini['stylesheets']['rtl']);
if (isset($config_cascade['userstyle']['rtl'])) $files[$mediatype][$config_cascade['userstyle']['rtl']] = DOKU_BASE;
}
}
@@ -154,7 +143,7 @@ function css_out(){
ob_end_clean();
// apply style replacements
- $css = css_applystyle($css,$tplinc);
+ $css = css_applystyle($css, $styleini['replacements']);
// parse less
$css = css_parseless($css);
@@ -200,7 +189,6 @@ function css_parseless($css) {
// walk upwards to last include
$lines = explode("\n", $css);
- $count = count($lines);
for($i=$lno-1; $i>=0; $i--){
if(preg_match('/\/(\* XXXXXXXXX )(.*?)( XXXXXXXXX \*)\//', $lines[$i], $m)){
// we found it, add info to message
@@ -238,50 +226,97 @@ function css_parseless($css) {
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function css_applystyle($css,$tplinc){
- $styleini = css_styleini($tplinc);
-
- if($styleini){
- // we convert ini replacements to LESS variable names
- // and build a list of variable: value; pairs
- $less = '';
- foreach($styleini['replacements'] as $key => $value){
- $lkey = trim($key, '_');
- $lkey = '@ini_'.$lkey;
- $less .= "$lkey: $value;\n";
-
- $styleini['replacements'][$key] = $lkey;
- }
+function css_applystyle($css, $replacements) {
+ // we convert ini replacements to LESS variable names
+ // and build a list of variable: value; pairs
+ $less = '';
+ foreach((array) $replacements as $key => $value) {
+ $lkey = trim($key, '_');
+ $lkey = '@ini_'.$lkey;
+ $less .= "$lkey: $value;\n";
+
+ $replacements[$key] = $lkey;
+ }
- // we now replace all old ini replacements with LESS variables
- $css = strtr($css, $styleini['replacements']);
+ // we now replace all old ini replacements with LESS variables
+ $css = strtr($css, $replacements);
- // now prepend the list of LESS variables as the very first thing
- $css = $less.$css;
- }
+ // now prepend the list of LESS variables as the very first thing
+ $css = $less.$css;
return $css;
}
/**
- * Get contents of merged style.ini and style.local.ini as an array.
+ * Load style ini contents
+ *
+ * Loads and merges style.ini files from template and config and prepares
+ * the stylesheet modes
*
- * @author Anika Henke <anika@selfthinker.org>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $tpl the used template
+ * @return array with keys 'stylesheets' and 'replacements'
*/
-function css_styleini($tplinc) {
- $styleini = array();
+function css_styleini($tpl) {
+ $stylesheets = array(); // mode, file => base
+ $replacements = array(); // placeholder => value
+
+ // load template's style.ini
+ $incbase = tpl_incdir($tpl);
+ $webbase = tpl_basedir($tpl);
+ $ini = $incbase.'style.ini';
+ if(file_exists($ini)){
+ $data = parse_ini_file($ini, true);
+
+ // stylesheets
+ if(is_array($data['stylesheets'])) foreach($data['stylesheets'] as $file => $mode){
+ $stylesheets[$mode][$incbase.$file] = $webbase;
+ }
+
+ // replacements
+ if(is_array($data['replacements'])){
+ $replacements = array_merge($replacements, $data['replacements']);
+ }
+ }
- foreach (array($tplinc.'style.ini', $tplinc.'style.local.ini') as $ini) {
- $tmp = (@file_exists($ini)) ? parse_ini_file($ini, true) : array();
+ // load template's style.local.ini
+ // @deprecated 2013-08-03
+ $ini = $incbase.'style.local.ini';
+ if(file_exists($ini)){
+ $data = parse_ini_file($ini, true);
- foreach($tmp as $key => $value) {
- if(array_key_exists($key, $styleini) && is_array($value)) {
- $styleini[$key] = array_merge($styleini[$key], $tmp[$key]);
- } else {
- $styleini[$key] = $value;
- }
+ // stylesheets
+ if(is_array($data['stylesheets'])) foreach($data['stylesheets'] as $file => $mode){
+ $stylesheets[$mode][$incbase.$file] = $webbase;
+ }
+
+ // replacements
+ if(is_array($data['replacements'])){
+ $replacements = array_merge($replacements, $data['replacements']);
}
}
- return $styleini;
+
+ // load configs's style.ini
+ $webbase = DOKU_BASE;
+ $ini = DOKU_CONF."tpl/$tpl/style.ini";
+ $incbase = dirname($ini).'/';
+ if(file_exists($ini)){
+ $data = parse_ini_file($ini, true);
+
+ // stylesheets
+ if(is_array($data['stylesheets'])) foreach($data['stylesheets'] as $file => $mode){
+ $stylesheets[$mode][$incbase.$file] = $webbase;
+ }
+
+ // replacements
+ if(is_array($data['replacements'])){
+ $replacements = array_merge($replacements, $data['replacements']);
+ }
+ }
+
+ return array(
+ 'stylesheets' => $stylesheets,
+ 'replacements' => $replacements
+ );
}
/**
diff --git a/lib/exe/mediamanager.php b/lib/exe/mediamanager.php
index 66e5ddc82..d9e4a6b04 100644
--- a/lib/exe/mediamanager.php
+++ b/lib/exe/mediamanager.php
@@ -29,12 +29,13 @@
$IMG = null;
}
- global $INFO;
+ global $INFO, $JSINFO;
$INFO = !empty($INFO) ? array_merge($INFO, mediainfo()) : mediainfo();
+ $JSINFO = array('id' => '', 'namespace' => '');
$AUTH = $INFO['perm']; // shortcut for historical reasons
- trigger_event('MEDIAMANAGER_STARTED',$tmp=array());
- session_write_close(); //close session
+ trigger_event('MEDIAMANAGER_STARTED',$tmp=array());
+ session_write_close(); //close session
// do not display the manager if user does not have read access
if($AUTH < AUTH_READ && !$fullscreen) {
diff --git a/lib/plugins/acl/admin.php b/lib/plugins/acl/admin.php
index 0d9cd742a..50377da81 100644
--- a/lib/plugins/acl/admin.php
+++ b/lib/plugins/acl/admin.php
@@ -724,7 +724,7 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin {
static $label = 0; //number labels
$ret = '';
- if($ispage && $setperm > AUTH_EDIT) $perm = AUTH_EDIT;
+ if($ispage && $setperm > AUTH_EDIT) $setperm = AUTH_EDIT;
foreach(array(AUTH_NONE,AUTH_READ,AUTH_EDIT,AUTH_CREATE,AUTH_UPLOAD,AUTH_DELETE) as $perm){
$label += 1;
diff --git a/lib/plugins/acl/lang/nl/lang.php b/lib/plugins/acl/lang/nl/lang.php
index 567eb46dc..e3a95e779 100644
--- a/lib/plugins/acl/lang/nl/lang.php
+++ b/lib/plugins/acl/lang/nl/lang.php
@@ -1,8 +1,8 @@
<?php
+
/**
- * dutch language file
- *
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
* @author François Kooman <fkooman.tuxed.net>
* @author Jack van Klaren <dokuwiki@afentoe.xs4all.nl>
* @author Riny Heijdendael <riny@heijdendael.nl>
diff --git a/lib/plugins/auth.php b/lib/plugins/auth.php
index ec8ed7e58..dc66d6380 100644
--- a/lib/plugins/auth.php
+++ b/lib/plugins/auth.php
@@ -55,6 +55,18 @@ class DokuWiki_Auth_Plugin extends DokuWiki_Plugin {
}
/**
+ * Available Capabilities. [ DO NOT OVERRIDE ]
+ *
+ * For introspection/debugging
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @return array
+ */
+ public function getCapabilities(){
+ return array_keys($this->cando);
+ }
+
+ /**
* Capability check. [ DO NOT OVERRIDE ]
*
* Checks the capabilities set in the $this->cando array and
diff --git a/lib/plugins/authad/conf/metadata.php b/lib/plugins/authad/conf/metadata.php
index fbc3f163c..7b4f895d0 100644
--- a/lib/plugins/authad/conf/metadata.php
+++ b/lib/plugins/authad/conf/metadata.php
@@ -1,14 +1,14 @@
<?php
-$meta['account_suffix'] = array('string');
-$meta['base_dn'] = array('string');
-$meta['domain_controllers'] = array('string');
-$meta['sso'] = array('onoff');
-$meta['admin_username'] = array('string');
-$meta['admin_password'] = array('password');
-$meta['real_primarygroup'] = array('onoff');
-$meta['use_ssl'] = array('onoff');
-$meta['use_tls'] = array('onoff');
-$meta['debug'] = array('onoff');
-$meta['expirywarn'] = array('numeric', '_min'=>0);
-$meta['additional'] = array('string');
+$meta['account_suffix'] = array('string','_caution' => 'danger');
+$meta['base_dn'] = array('string','_caution' => 'danger');
+$meta['domain_controllers'] = array('string','_caution' => 'danger');
+$meta['sso'] = array('onoff','_caution' => 'danger');
+$meta['admin_username'] = array('string','_caution' => 'danger');
+$meta['admin_password'] = array('password','_caution' => 'danger');
+$meta['real_primarygroup'] = array('onoff','_caution' => 'danger');
+$meta['use_ssl'] = array('onoff','_caution' => 'danger');
+$meta['use_tls'] = array('onoff','_caution' => 'danger');
+$meta['debug'] = array('onoff','_caution' => 'security');
+$meta['expirywarn'] = array('numeric', '_min'=>0,'_caution' => 'danger');
+$meta['additional'] = array('string','_caution' => 'danger');
diff --git a/lib/plugins/authad/lang/nl/settings.php b/lib/plugins/authad/lang/nl/settings.php
index 933566d18..8f5c84043 100644
--- a/lib/plugins/authad/lang/nl/settings.php
+++ b/lib/plugins/authad/lang/nl/settings.php
@@ -1,7 +1,8 @@
<?php
+
/**
- * Dutch language file
- *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
*/
$lang['account_suffix'] = 'Je account domeinnaam. Bijv <code>@mijn.domein.org</code>';
$lang['base_dn'] = 'Je basis DN. Bijv. <code>DC=mijn,DC=domein,DC=org</code>';
diff --git a/lib/plugins/authldap/conf/metadata.php b/lib/plugins/authldap/conf/metadata.php
index a3256628c..6aa53c40d 100644
--- a/lib/plugins/authldap/conf/metadata.php
+++ b/lib/plugins/authldap/conf/metadata.php
@@ -1,19 +1,19 @@
<?php
-$meta['server'] = array('string');
-$meta['port'] = array('numeric');
-$meta['usertree'] = array('string');
-$meta['grouptree'] = array('string');
-$meta['userfilter'] = array('string');
-$meta['groupfilter'] = array('string');
-$meta['version'] = array('numeric');
-$meta['starttls'] = array('onoff');
-$meta['referrals'] = array('onoff');
-$meta['deref'] = array('multichoice','_choices' => array(0,1,2,3));
-$meta['binddn'] = array('string');
-$meta['bindpw'] = array('password');
+$meta['server'] = array('string','_caution' => 'danger');
+$meta['port'] = array('numeric','_caution' => 'danger');
+$meta['usertree'] = array('string','_caution' => 'danger');
+$meta['grouptree'] = array('string','_caution' => 'danger');
+$meta['userfilter'] = array('string','_caution' => 'danger');
+$meta['groupfilter'] = array('string','_caution' => 'danger');
+$meta['version'] = array('numeric','_caution' => 'danger');
+$meta['starttls'] = array('onoff','_caution' => 'danger');
+$meta['referrals'] = array('onoff','_caution' => 'danger');
+$meta['deref'] = array('multichoice','_choices' => array(0,1,2,3),'_caution' => 'danger');
+$meta['binddn'] = array('string','_caution' => 'danger');
+$meta['bindpw'] = array('password','_caution' => 'danger');
//$meta['mapping']['name'] unsupported in config manager
//$meta['mapping']['grps'] unsupported in config manager
-$meta['userscope'] = array('multichoice','_choices' => array('sub','one','base'));
-$meta['groupscope'] = array('multichoice','_choices' => array('sub','one','base'));
-$meta['groupkey'] = array('string');
-$meta['debug'] = array('onoff'); \ No newline at end of file
+$meta['userscope'] = array('multichoice','_choices' => array('sub','one','base'),'_caution' => 'danger');
+$meta['groupscope'] = array('multichoice','_choices' => array('sub','one','base'),'_caution' => 'danger');
+$meta['groupkey'] = array('string','_caution' => 'danger');
+$meta['debug'] = array('onoff','_caution' => 'security'); \ No newline at end of file
diff --git a/lib/plugins/authldap/lang/nl/settings.php b/lib/plugins/authldap/lang/nl/settings.php
index 274c3b7fc..958bd4d6f 100644
--- a/lib/plugins/authldap/lang/nl/settings.php
+++ b/lib/plugins/authldap/lang/nl/settings.php
@@ -1,7 +1,8 @@
<?php
+
/**
- * Dutch language file
- *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
*/
$lang['server'] = 'Je LDAP server. Ofwel servernaam (<code>localhost</code>) of volledige URL (<code>ldap://server.tld:389</code>)';
$lang['port'] = 'LDAP server poort als hiervoor geen volledige URL is opgegeven';
diff --git a/lib/plugins/authmysql/conf/metadata.php b/lib/plugins/authmysql/conf/metadata.php
index 05d150fdf..54d6f1404 100644
--- a/lib/plugins/authmysql/conf/metadata.php
+++ b/lib/plugins/authmysql/conf/metadata.php
@@ -1,34 +1,34 @@
<?php
-$meta['server'] = array('string');
-$meta['user'] = array('string');
-$meta['password'] = array('password');
-$meta['database'] = array('string');
-$meta['charset'] = array('string');
-$meta['debug'] = array('multichoice','_choices' => array(0,1,2));
-$meta['forwardClearPass'] = array('onoff');
-$meta['TablesToLock'] = array('array');
-$meta['checkPass'] = array('');
-$meta['getUserInfo'] = array('');
-$meta['getGroups'] = array('');
-$meta['getUsers'] = array('');
-$meta['FilterLogin'] = array('string');
-$meta['FilterName'] = array('string');
-$meta['FilterEmail'] = array('string');
-$meta['FilterGroup'] = array('string');
-$meta['SortOrder'] = array('string');
-$meta['addUser'] = array('');
-$meta['addGroup'] = array('');
-$meta['addUserGroup'] = array('');
-$meta['delGroup'] = array('');
-$meta['getUserID'] = array('');
-$meta['delUser'] = array('');
-$meta['delUserRefs'] = array('');
-$meta['updateUser'] = array('string');
-$meta['UpdateLogin'] = array('string');
-$meta['UpdatePass'] = array('string');
-$meta['UpdateEmail'] = array('string');
-$meta['UpdateName'] = array('string');
-$meta['UpdateTarget'] = array('string');
-$meta['delUserGroup'] = array('');
-$meta['getGroupID'] = array(''); \ No newline at end of file
+$meta['server'] = array('string','_caution' => 'danger');
+$meta['user'] = array('string','_caution' => 'danger');
+$meta['password'] = array('password','_caution' => 'danger');
+$meta['database'] = array('string','_caution' => 'danger');
+$meta['charset'] = array('string','_caution' => 'danger');
+$meta['debug'] = array('multichoice','_choices' => array(0,1,2),'_caution' => 'security');
+$meta['forwardClearPass'] = array('onoff','_caution' => 'danger');
+$meta['TablesToLock'] = array('array','_caution' => 'danger');
+$meta['checkPass'] = array('','_caution' => 'danger');
+$meta['getUserInfo'] = array('','_caution' => 'danger');
+$meta['getGroups'] = array('','_caution' => 'danger');
+$meta['getUsers'] = array('','_caution' => 'danger');
+$meta['FilterLogin'] = array('string','_caution' => 'danger');
+$meta['FilterName'] = array('string','_caution' => 'danger');
+$meta['FilterEmail'] = array('string','_caution' => 'danger');
+$meta['FilterGroup'] = array('string','_caution' => 'danger');
+$meta['SortOrder'] = array('string','_caution' => 'danger');
+$meta['addUser'] = array('','_caution' => 'danger');
+$meta['addGroup'] = array('','_caution' => 'danger');
+$meta['addUserGroup'] = array('','_caution' => 'danger');
+$meta['delGroup'] = array('','_caution' => 'danger');
+$meta['getUserID'] = array('','_caution' => 'danger');
+$meta['delUser'] = array('','_caution' => 'danger');
+$meta['delUserRefs'] = array('','_caution' => 'danger');
+$meta['updateUser'] = array('string','_caution' => 'danger');
+$meta['UpdateLogin'] = array('string','_caution' => 'danger');
+$meta['UpdatePass'] = array('string','_caution' => 'danger');
+$meta['UpdateEmail'] = array('string','_caution' => 'danger');
+$meta['UpdateName'] = array('string','_caution' => 'danger');
+$meta['UpdateTarget'] = array('string','_caution' => 'danger');
+$meta['delUserGroup'] = array('','_caution' => 'danger');
+$meta['getGroupID'] = array('','_caution' => 'danger'); \ No newline at end of file
diff --git a/lib/plugins/authmysql/lang/nl/settings.php b/lib/plugins/authmysql/lang/nl/settings.php
index dc85b7eee..39fa32112 100644
--- a/lib/plugins/authmysql/lang/nl/settings.php
+++ b/lib/plugins/authmysql/lang/nl/settings.php
@@ -1,7 +1,8 @@
<?php
+
/**
- * Dutch language file
- *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
*/
$lang['server'] = 'Je MySQL server';
$lang['user'] = 'MySql gebruikersnaam';
diff --git a/lib/plugins/authpgsql/conf/metadata.php b/lib/plugins/authpgsql/conf/metadata.php
index d52a17865..fbd051270 100644
--- a/lib/plugins/authpgsql/conf/metadata.php
+++ b/lib/plugins/authpgsql/conf/metadata.php
@@ -1,33 +1,33 @@
<?php
-$meta['server'] = array('string');
-$meta['port'] = array('numeric');
-$meta['user'] = array('string');
-$meta['password'] = array('password');
-$meta['database'] = array('string');
-$meta['debug'] = array('onoff');
-$meta['forwardClearPass'] = array('onoff');
-$meta['checkPass'] = array('');
-$meta['getUserInfo'] = array('');
+$meta['server'] = array('string','_caution' => 'danger');
+$meta['port'] = array('numeric','_caution' => 'danger');
+$meta['user'] = array('string','_caution' => 'danger');
+$meta['password'] = array('password','_caution' => 'danger');
+$meta['database'] = array('string','_caution' => 'danger');
+$meta['debug'] = array('onoff','_caution' => 'security');
+$meta['forwardClearPass'] = array('onoff','_caution' => 'danger');
+$meta['checkPass'] = array('','_caution' => 'danger');
+$meta['getUserInfo'] = array('','_caution' => 'danger');
$meta['getGroups'] = array('');
-$meta['getUsers'] = array('');
-$meta['FilterLogin'] = array('string');
-$meta['FilterName'] = array('string');
-$meta['FilterEmail'] = array('string');
-$meta['FilterGroup'] = array('string');
-$meta['SortOrder'] = array('string');
-$meta['addUser'] = array('');
-$meta['addGroup'] = array('');
-$meta['addUserGroup'] = array('');
-$meta['delGroup'] = array('');
-$meta['getUserID'] = array('');
-$meta['delUser'] = array('');
-$meta['delUserRefs'] = array('');
-$meta['updateUser'] = array('string');
-$meta['UpdateLogin'] = array('string');
-$meta['UpdatePass'] = array('string');
-$meta['UpdateEmail'] = array('string');
-$meta['UpdateName'] = array('string');
-$meta['UpdateTarget'] = array('string');
-$meta['delUserGroup'] = array('');
-$meta['getGroupID'] = array(''); \ No newline at end of file
+$meta['getUsers'] = array('','_caution' => 'danger');
+$meta['FilterLogin'] = array('string','_caution' => 'danger');
+$meta['FilterName'] = array('string','_caution' => 'danger');
+$meta['FilterEmail'] = array('string','_caution' => 'danger');
+$meta['FilterGroup'] = array('string','_caution' => 'danger');
+$meta['SortOrder'] = array('string','_caution' => 'danger');
+$meta['addUser'] = array('','_caution' => 'danger');
+$meta['addGroup'] = array('','_caution' => 'danger');
+$meta['addUserGroup'] = array('','_caution' => 'danger');
+$meta['delGroup'] = array('','_caution' => 'danger');
+$meta['getUserID'] = array('','_caution' => 'danger');
+$meta['delUser'] = array('','_caution' => 'danger');
+$meta['delUserRefs'] = array('','_caution' => 'danger');
+$meta['updateUser'] = array('string','_caution' => 'danger');
+$meta['UpdateLogin'] = array('string','_caution' => 'danger');
+$meta['UpdatePass'] = array('string','_caution' => 'danger');
+$meta['UpdateEmail'] = array('string','_caution' => 'danger');
+$meta['UpdateName'] = array('string','_caution' => 'danger');
+$meta['UpdateTarget'] = array('string','_caution' => 'danger');
+$meta['delUserGroup'] = array('','_caution' => 'danger');
+$meta['getGroupID'] = array('','_caution' => 'danger'); \ No newline at end of file
diff --git a/lib/plugins/authpgsql/lang/nl/settings.php b/lib/plugins/authpgsql/lang/nl/settings.php
index 4e6c007c6..496017f1c 100644
--- a/lib/plugins/authpgsql/lang/nl/settings.php
+++ b/lib/plugins/authpgsql/lang/nl/settings.php
@@ -1,7 +1,8 @@
<?php
+
/**
- * Dutch language file
- *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
*/
$lang['server'] = 'Je PostgrSQL server';
$lang['port'] = 'Je PostgreSQL server poort';
diff --git a/lib/plugins/plugin/lang/nl/lang.php b/lib/plugins/plugin/lang/nl/lang.php
index 10db78411..1317e44f2 100644
--- a/lib/plugins/plugin/lang/nl/lang.php
+++ b/lib/plugins/plugin/lang/nl/lang.php
@@ -1,7 +1,8 @@
<?php
+
/**
- * Dutch language file
- *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
* @author Wouter Schoot <wouter@schoot.org>
* @author John de Graaff <john@de-graaff.net>
* @author Niels Schoot <niels.schoot@quintiq.com>
diff --git a/lib/plugins/popularity/lang/nl/lang.php b/lib/plugins/popularity/lang/nl/lang.php
index b32ad9eb6..dda4a1d7f 100644
--- a/lib/plugins/popularity/lang/nl/lang.php
+++ b/lib/plugins/popularity/lang/nl/lang.php
@@ -1,7 +1,8 @@
<?php
+
/**
- * Dutch language file
- *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
* @author Wouter Schoot <wouter@schoot.org>
* @author Niels Schoot <niels.schoot@quintiq.com>
* @author Dion Nicolaas <dion@nicolaas.net>
diff --git a/lib/plugins/revert/lang/nl/lang.php b/lib/plugins/revert/lang/nl/lang.php
index 0a2880105..882675b81 100644
--- a/lib/plugins/revert/lang/nl/lang.php
+++ b/lib/plugins/revert/lang/nl/lang.php
@@ -1,7 +1,8 @@
<?php
+
/**
- * Dutch language file
- *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
* @author Wouter Schoot <wouter@schoot.org>
* @author John de Graaff <john@de-graaff.net>
* @author Niels Schoot <niels.schoot@quintiq.com>
diff --git a/lib/plugins/usermanager/admin.php b/lib/plugins/usermanager/admin.php
index 3c8d38c5e..762daa6b9 100644
--- a/lib/plugins/usermanager/admin.php
+++ b/lib/plugins/usermanager/admin.php
@@ -30,6 +30,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin {
var $_edit_user = ''; // set to user selected for editing
var $_edit_userdata = array();
var $_disabled = ''; // if disabled set to explanatory string
+ var $_import_failures = array();
/**
* Constructor
@@ -49,6 +50,11 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin {
$this->_auth = & $auth;
}
+
+ // attempt to retrieve any import failures from the session
+ if ($_SESSION['import_failures']){
+ $this->_import_failures = $_SESSION['import_failures'];
+ }
}
/**
@@ -101,6 +107,9 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin {
case "search" : $this->_setFilter($param);
$this->_start = 0;
break;
+ case "export" : $this->_export(); break;
+ case "import" : $this->_import(); break;
+ case "importfails" : $this->_downloadImportFailures(); break;
}
$this->_user_total = $this->_auth->canDo('getUserCount') ? $this->_auth->getUserCount($this->_filter) : -1;
@@ -133,6 +142,7 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin {
$delete_disable = $this->_auth->canDo('delUser') ? '' : 'disabled="disabled"';
$editable = $this->_auth->canDo('UserMod');
+ $export_label = empty($this->_filter) ? $this->lang['export_all'] : $this->lang[export_filtered];
print $this->locale_xhtml('intro');
print $this->locale_xhtml('list');
@@ -196,7 +206,10 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin {
ptln(" <input type=\"submit\" name=\"fn[next]\" ".$page_buttons['next']." class=\"button\" value=\"".$this->lang['next']."\" />");
ptln(" <input type=\"submit\" name=\"fn[last]\" ".$page_buttons['last']." class=\"button\" value=\"".$this->lang['last']."\" />");
ptln(" </span>");
- ptln(" <input type=\"submit\" name=\"fn[search][clear]\" class=\"button\" value=\"".$this->lang['clear']."\" />");
+ if (!empty($this->_filter)) {
+ ptln(" <input type=\"submit\" name=\"fn[search][clear]\" class=\"button\" value=\"".$this->lang['clear']."\" />");
+ }
+ ptln(" <input type=\"submit\" name=\"fn[export]\" class=\"button\" value=\"".$export_label."\" />");
ptln(" <input type=\"hidden\" name=\"do\" value=\"admin\" />");
ptln(" <input type=\"hidden\" name=\"page\" value=\"usermanager\" />");
@@ -233,6 +246,10 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin {
ptln(" </div>");
ptln("</div>");
}
+
+ if ($this->_auth->canDo('addUser')) {
+ $this->_htmlImportForm();
+ }
ptln("</div>");
}
@@ -353,6 +370,59 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin {
}
}
+ function _htmlImportForm($indent=0) {
+ global $ID;
+
+ $failure_download_link = wl($ID,array('do'=>'admin','page'=>'usermanager','fn[importfails]'=>1));
+
+ ptln('<div class="level2 import_users">',$indent);
+ print $this->locale_xhtml('import');
+ ptln(' <form action="'.wl($ID).'" method="post" enctype="multipart/form-data">',$indent);
+ formSecurityToken();
+ ptln(' <label>User list file (csv): <input type="file" name="import" /></label>',$indent);
+ ptln(' <input type="submit" name="fn[import]" value="'.$this->lang['import'].'" />',$indent);
+ ptln(' <input type="hidden" name="do" value="admin" />',$indent);
+ ptln(' <input type="hidden" name="page" value="usermanager" />',$indent);
+
+ $this->_htmlFilterSettings($indent+4);
+ ptln(' </form>',$indent);
+ ptln('</div>');
+
+ // list failures from the previous import
+ if ($this->_import_failures) {
+ $digits = strlen(count($this->_import_failures));
+ ptln('<div class="level3 import_failures">',$indent);
+ ptln(' <h3>Most Recent Import - Failures</h3>');
+ ptln(' <table class="import_failures">',$indent);
+ ptln(' <thead>',$indent);
+ ptln(' <tr>',$indent);
+ ptln(' <th class="line">'.$this->lang['line'].'</th>',$indent);
+ ptln(' <th class="error">'.$this->lang['error'].'</th>',$indent);
+ ptln(' <th class="userid">'.$this->lang['user_id'].'</th>',$indent);
+ ptln(' <th class="username">'.$this->lang['user_name'].'</th>',$indent);
+ ptln(' <th class="usermail">'.$this->lang['user_mail'].'</th>',$indent);
+ ptln(' <th class="usergroups">'.$this->lang['user_groups'].'</th>',$indent);
+ ptln(' </tr>',$indent);
+ ptln(' </thead>',$indent);
+ ptln(' <tbody>',$indent);
+ foreach ($this->_import_failures as $line => $failure) {
+ ptln(' <tr>',$indent);
+ ptln(' <td class="lineno"> '.sprintf('%0'.$digits.'d',$line).' </td>',$indent);
+ ptln(' <td class="error">' .$failure['error'].' </td>', $indent);
+ ptln(' <td class="field userid"> '.hsc($failure['user'][0]).' </td>',$indent);
+ ptln(' <td class="field username"> '.hsc($failure['user'][2]).' </td>',$indent);
+ ptln(' <td class="field usermail"> '.hsc($failure['user'][3]).' </td>',$indent);
+ ptln(' <td class="field usergroups"> '.hsc($failure['user'][4]).' </td>',$indent);
+ ptln(' </tr>',$indent);
+ }
+ ptln(' </tbody>',$indent);
+ ptln(' </table>',$indent);
+ ptln(' <p><a href="'.$failure_download_link.'">Download Failures as CSV for correction</a></p>');
+ ptln('</div>');
+ }
+
+ }
+
function _addUser(){
global $INPUT;
if (!checkSecurityToken()) return false;
@@ -542,12 +612,16 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin {
/**
* send password change notification email
*/
- function _notifyUser($user, $password) {
+ function _notifyUser($user, $password, $status_alert=true) {
if ($sent = auth_sendPassword($user,$password)) {
- msg($this->lang['notify_ok'], 1);
+ if ($status_alert) {
+ msg($this->lang['notify_ok'], 1);
+ }
} else {
- msg($this->lang['notify_fail'], -1);
+ if ($status_alert) {
+ msg($this->lang['notify_fail'], -1);
+ }
}
return $sent;
@@ -635,4 +709,171 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin {
return $buttons;
}
+
+ /*
+ * export a list of users in csv format using the current filter criteria
+ */
+ function _export() {
+ // list of users for export - based on current filter criteria
+ $user_list = $this->_auth->retrieveUsers(0, 0, $this->_filter);
+ $column_headings = array(
+ $this->lang["user_id"],
+ $this->lang["user_name"],
+ $this->lang["user_mail"],
+ $this->lang["user_groups"]
+ );
+
+ // ==============================================================================================
+ // GENERATE OUTPUT
+ // normal headers for downloading...
+ header('Content-type: text/csv;charset=utf-8');
+ header('Content-Disposition: attachment; filename="wikiusers.csv"');
+# // for debugging assistance, send as text plain to the browser
+# header('Content-type: text/plain;charset=utf-8');
+
+ // output the csv
+ $fd = fopen('php://output','w');
+ fputcsv($fd, $column_headings);
+ foreach ($user_list as $user => $info) {
+ $line = array($user, $info['name'], $info['mail'], join(',',$info['grps']));
+ fputcsv($fd, $line);
+ }
+ fclose($fd);
+ die;
+ }
+
+ /*
+ * import a file of users in csv format
+ *
+ * csv file should have 4 columns, user_id, full name, email, groups (comma separated)
+ */
+ function _import() {
+ // check we are allowed to add users
+ if (!checkSecurityToken()) return false;
+ if (!$this->_auth->canDo('addUser')) return false;
+
+ // check file uploaded ok.
+ if (empty($_FILES['import']['size']) || !empty($FILES['import']['error']) && is_uploaded_file($FILES['import']['tmp_name'])) {
+ msg($this->lang['import_error_upload'],-1);
+ return false;
+ }
+ // retrieve users from the file
+ $this->_import_failures = array();
+ $import_success_count = 0;
+ $import_fail_count = 0;
+ $line = 0;
+ $fd = fopen($_FILES['import']['tmp_name'],'r');
+ if ($fd) {
+ while($csv = fgets($fd)){
+ if (!utf8_check($csv)) {
+ $csv = utf8_encode($csv);
+ }
+ $raw = str_getcsv($csv);
+ $error = ''; // clean out any errors from the previous line
+ // data checks...
+ if (1 == ++$line) {
+ if ($raw[0] == 'user_id' || $raw[0] == $this->lang['user_id']) continue; // skip headers
+ }
+ if (count($raw) < 4) { // need at least four fields
+ $import_fail_count++;
+ $error = sprintf($this->lang['import_error_fields'], count($raw));
+ $this->_import_failures[$line] = array('error' => $error, 'user' => $raw, 'orig' => $csv);
+ continue;
+ }
+ array_splice($raw,1,0,auth_pwgen()); // splice in a generated password
+ $clean = $this->_cleanImportUser($raw, $error);
+ if ($clean && $this->_addImportUser($clean, $error)) {
+ $sent = $this->_notifyUser($clean[0],$clean[1],false);
+ if (!$sent){
+ msg(sprintf($this->lang['import_notify_fail'],$clean[0],$clean[3]),-1);
+ }
+ $import_success_count++;
+ } else {
+ $import_fail_count++;
+ $this->_import_failures[$line] = array('error' => $error, 'user' => $raw, 'orig' => $csv);
+ }
+ }
+ msg(sprintf($this->lang['import_success_count'], ($import_success_count+$import_fail_count), $import_success_count),($import_success_count ? 1 : -1));
+ if ($import_fail_count) {
+ msg(sprintf($this->lang['import_failure_count'], $import_fail_count),-1);
+ }
+ } else {
+ msg($this->lang['import_error_readfail'],-1);
+ }
+
+ // save import failures into the session
+ if (!headers_sent()) {
+ session_start();
+ $_SESSION['import_failures'] = $this->_import_failures;
+ session_write_close();
+ }
+ }
+
+ function _cleanImportUser($candidate, & $error){
+ global $INPUT;
+
+ // kludgy ....
+ $INPUT->set('userid', $candidate[0]);
+ $INPUT->set('userpass', $candidate[1]);
+ $INPUT->set('username', $candidate[2]);
+ $INPUT->set('usermail', $candidate[3]);
+ $INPUT->set('usergroups', $candidate[4]);
+
+ $cleaned = $this->_retrieveUser();
+ list($user,$pass,$name,$mail,$grps) = $cleaned;
+ if (empty($user)) {
+ $error = $this->lang['import_error_baduserid'];
+ return false;
+ }
+
+ // no need to check password, handled elsewhere
+
+ if (!($this->_auth->canDo('modName') xor empty($name))){
+ $error = $this->lang['import_error_badname'];
+ return false;
+ }
+
+ if ($this->_auth->canDo('modMail')) {
+ if (empty($mail) || !mail_isvalid($mail)) {
+ $error = $this->lang['import_error_badmail'];
+ return false;
+ }
+ } else {
+ if (!empty($mail)) {
+ $error = $this->lang['import_error_badmail'];
+ return false;
+ }
+ }
+
+ return $cleaned;
+ }
+
+ function _addImportUser($user, & $error){
+ if (!$this->_auth->triggerUserMod('create', $user)) {
+ $error = $this->lang['import_error_create'];
+ return false;
+ }
+
+ return true;
+ }
+
+ function _downloadImportFailures(){
+
+ // ==============================================================================================
+ // GENERATE OUTPUT
+ // normal headers for downloading...
+ header('Content-type: text/csv;charset=utf-8');
+ header('Content-Disposition: attachment; filename="importfails.csv"');
+# // for debugging assistance, send as text plain to the browser
+# header('Content-type: text/plain;charset=utf-8');
+
+ // output the csv
+ $fd = fopen('php://output','w');
+ foreach ($this->_import_failures as $line => $fail) {
+ fputs($fd, $fail['orig']);
+ }
+ fclose($fd);
+ die;
+ }
+
}
diff --git a/lib/plugins/usermanager/lang/en/import.txt b/lib/plugins/usermanager/lang/en/import.txt
new file mode 100644
index 000000000..2087083e0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/en/import.txt
@@ -0,0 +1,9 @@
+===== Bulk User Import =====
+
+Requires a CSV file of users with at least four columns.
+The columns must contain, in order: user-id, full name, email address and groups.
+The CSV fields should be separated by commas (,) and strings delimited by quotation marks (""). Backslash (\) can be used for escaping.
+For an example of a suitable file, try the "Export Users" function above.
+Duplicate user-ids will be ignored.
+
+A password will be generated and emailed to each successfully imported user.
diff --git a/lib/plugins/usermanager/lang/en/lang.php b/lib/plugins/usermanager/lang/en/lang.php
index 189a1db20..69119e196 100644
--- a/lib/plugins/usermanager/lang/en/lang.php
+++ b/lib/plugins/usermanager/lang/en/lang.php
@@ -31,6 +31,11 @@ $lang['search'] = 'Search';
$lang['search_prompt'] = 'Perform search';
$lang['clear'] = 'Reset Search Filter';
$lang['filter'] = 'Filter';
+$lang['export_all'] = 'Export All Users (CSV)';
+$lang['export_filtered'] = 'Export Filtered User list (CSV)';
+$lang['import'] = 'Import New Users';
+$lang['line'] = 'Line no.';
+$lang['error'] = 'Error message';
$lang['summary'] = 'Displaying users %1$d-%2$d of %3$d found. %4$d users total.';
$lang['nonefound'] = 'No users found. %d users total.';
@@ -56,3 +61,16 @@ $lang['add_fail'] = 'User addition failed';
$lang['notify_ok'] = 'Notification email sent';
$lang['notify_fail'] = 'Notification email could not be sent';
+// import errors
+$lang['import_success_count'] = 'User Import: %d users found, %d imported successfully.';
+$lang['import_failure_count'] = 'User Import: %d failed. Failures are listed below.';
+$lang['import_error_fields'] = "Insufficient fields, found %d, require 4.";
+$lang['import_error_baduserid'] = "User-id missing";
+$lang['import_error_badname'] = 'Bad name';
+$lang['import_error_badmail'] = 'Bad email address';
+$lang['import_error_upload'] = 'Import Failed. The csv file could not be uploaded or is empty.';
+$lang['import_error_readfail'] = 'Import Failed. Unable to read uploaded file.';
+$lang['import_error_create'] = 'Unable to create the user';
+$lang['import_notify_fail'] = 'Notification message could not be sent for imported user, %s with email %s.';
+
+
diff --git a/lib/plugins/usermanager/lang/nl/lang.php b/lib/plugins/usermanager/lang/nl/lang.php
index e960e9a14..e1bf126fb 100644
--- a/lib/plugins/usermanager/lang/nl/lang.php
+++ b/lib/plugins/usermanager/lang/nl/lang.php
@@ -1,7 +1,8 @@
<?php
+
/**
- * Dutch language file
- *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
* @author Wouter Schoot <wouter@schoot.org>
* @author John de Graaff <john@de-graaff.net>
* @author Niels Schoot <niels.schoot@quintiq.com>
diff --git a/lib/plugins/usermanager/style.css b/lib/plugins/usermanager/style.css
index 506bd7928..2874b4f1c 100644
--- a/lib/plugins/usermanager/style.css
+++ b/lib/plugins/usermanager/style.css
@@ -21,4 +21,13 @@
color: #ccc!important;
border-color: #ccc!important;
}
+#user__manager .import_users {
+ margin-top: 1.4em;
+}
+#user__manager .import_failures {
+ margin-top: 1.4em;
+}
+#user__manager .import_failures td.lineno {
+ text-align: center;
+}
/* IE won't understand but doesn't require it */
diff --git a/lib/tpl/dokuwiki/css/pagetools.less b/lib/tpl/dokuwiki/css/pagetools.less
index b65e6fc0d..ecb3038c3 100644
--- a/lib/tpl/dokuwiki/css/pagetools.less
+++ b/lib/tpl/dokuwiki/css/pagetools.less
@@ -163,262 +163,71 @@
/*____________ all available icons in sprite ____________*/
-#dokuwiki__pagetools ul li a.edit:before {
- margin-top: -90px;
-}
-#dokuwiki__pagetools ul li a.edit {
- background-position: right -90px;
-}
-#dokuwiki__pagetools ul li a.edit:hover,
-#dokuwiki__pagetools ul li a.edit:active,
-#dokuwiki__pagetools ul li a.edit:focus {
- background-position: right -135px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.edit {
- background-position: left -90px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.edit:hover,
-[dir=rtl] #dokuwiki__pagetools ul li a.edit:active,
-[dir=rtl] #dokuwiki__pagetools ul li a.edit:focus {
- background-position: left -135px;
-}
-
-#dokuwiki__pagetools ul li a.create:before {
- margin-top: -180px;
-}
-#dokuwiki__pagetools ul li a.create {
- background-position: right -180px;
-}
-#dokuwiki__pagetools ul li a.create:hover,
-#dokuwiki__pagetools ul li a.create:active,
-#dokuwiki__pagetools ul li a.create:focus {
- background-position: right -225px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.create {
- background-position: left -180px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.create:hover,
-[dir=rtl] #dokuwiki__pagetools ul li a.create:active,
-[dir=rtl] #dokuwiki__pagetools ul li a.create:focus {
- background-position: left -225px;
-}
-
-#dokuwiki__pagetools ul li a.show {
- background-position: right -360px;
-}
-#dokuwiki__pagetools ul li a.show:before {
- margin-top: -360px;
-}
-#dokuwiki__pagetools ul li a.show:hover,
-#dokuwiki__pagetools ul li a.show:active,
-#dokuwiki__pagetools ul li a.show:focus {
- background-position: right -405px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.show {
- background-position: left -360px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.show:hover,
-[dir=rtl] #dokuwiki__pagetools ul li a.show:active,
-[dir=rtl] #dokuwiki__pagetools ul li a.show:focus {
- background-position: left -405px;
-}
-
-#dokuwiki__pagetools ul li a.source {
- background-position: right -450px;
-}
-#dokuwiki__pagetools ul li a.source:before {
- margin-top: -450px;
-}
-#dokuwiki__pagetools ul li a.source:hover,
-#dokuwiki__pagetools ul li a.source:active,
-#dokuwiki__pagetools ul li a.source:focus {
- background-position: right -495px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.source {
- background-position: left -450px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.source:hover,
-[dir=rtl] #dokuwiki__pagetools ul li a.source:active,
-[dir=rtl] #dokuwiki__pagetools ul li a.source:focus {
- background-position: left -495px;
-}
-
-#dokuwiki__pagetools ul li a.draft {
- background-position: right -270px;
-}
-#dokuwiki__pagetools ul li a.draft:before {
- margin-top: -270px;
-}
-#dokuwiki__pagetools ul li a.draft:hover,
-#dokuwiki__pagetools ul li a.draft:active,
-#dokuwiki__pagetools ul li a.draft:focus {
- background-position: right -315px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.draft {
- background-position: left -270px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.draft:hover,
-[dir=rtl] #dokuwiki__pagetools ul li a.draft:active,
-[dir=rtl] #dokuwiki__pagetools ul li a.draft:focus {
- background-position: left -315px;
-}
-
-#dokuwiki__pagetools ul li a.revs {
- background-position: right -630px;
-}
-#dokuwiki__pagetools ul li a.revs:before {
- margin-top: -630px;
-}
-#dokuwiki__pagetools ul li a.revs:hover,
-#dokuwiki__pagetools ul li a.revs:active,
-#dokuwiki__pagetools ul li a.revs:focus,
-.mode_revisions #dokuwiki__pagetools ul li a.revs {
- background-position: right -675px;
-}
-.mode_revisions #dokuwiki__pagetools ul li a.revs:before {
- margin-top: -675px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.revs {
- background-position: left -630px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.revs:hover,
-[dir=rtl] #dokuwiki__pagetools ul li a.revs:active,
-[dir=rtl] #dokuwiki__pagetools ul li a.revs:focus,
-[dir=rtl] .mode_revisions #dokuwiki__pagetools ul li a.revs {
- background-position: left -675px;
-}
-
-#dokuwiki__pagetools ul li a.backlink {
- background-position: right -720px;
-}
-#dokuwiki__pagetools ul li a.backlink:before {
- margin-top: -720px;
-}
-#dokuwiki__pagetools ul li a.backlink:hover,
-#dokuwiki__pagetools ul li a.backlink:active,
-#dokuwiki__pagetools ul li a.backlink:focus,
-.mode_backlink #dokuwiki__pagetools ul li a.backlink {
- background-position: right -765px;
-}
-.mode_backlink #dokuwiki__pagetools ul li a.backlink:before {
- margin-top: -765px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.backlink {
- background-position: left -720px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.backlink:hover,
-[dir=rtl] #dokuwiki__pagetools ul li a.backlink:active,
-[dir=rtl] #dokuwiki__pagetools ul li a.backlink:focus,
-[dir=rtl] .mode_backlink #dokuwiki__pagetools ul li a.backlink {
- background-position: left -765px;
-}
-
-#dokuwiki__pagetools ul li a.top {
- background-position: right -900px;
-}
-#dokuwiki__pagetools ul li a.top:before{
- margin-top: -900px;
-}
-#dokuwiki__pagetools ul li a.top:hover,
-#dokuwiki__pagetools ul li a.top:active,
-#dokuwiki__pagetools ul li a.top:focus {
- background-position: right -945px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.top {
- background-position: left -900px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.top:hover,
-[dir=rtl] #dokuwiki__pagetools ul li a.top:active,
-[dir=rtl] #dokuwiki__pagetools ul li a.top:focus {
- background-position: left -945px;
-}
+@pagetools_icon_space: -90px;
-#dokuwiki__pagetools ul li a.revert {
- background-position: right -540px;
-}
-#dokuwiki__pagetools ul li a.revert:before {
- margin-top: -540px;
-}
-#dokuwiki__pagetools ul li a.revert:hover,
-#dokuwiki__pagetools ul li a.revert:active,
-#dokuwiki__pagetools ul li a.revert:focus,
-.mode_revert #dokuwiki__pagetools ul li a.revert {
- background-position: right -585px;
-}
-.mode_revert #dokuwiki__pagetools ul li a.revert:before {
- margin-top: -540px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.revert {
- background-position: left -540px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.revert:hover,
-[dir=rtl] #dokuwiki__pagetools ul li a.revert:active,
-[dir=rtl] #dokuwiki__pagetools ul li a.revert:focus,
-[dir=rtl] .mode_revert #dokuwiki__pagetools ul li a.revert {
- background-position: left -585px;
-}
-
-#dokuwiki__pagetools ul li a.subscribe {
- background-position: right -810px;
-}
-#dokuwiki__pagetools ul li a.subscribe:before {
- margin-top: -810px;
-}
-#dokuwiki__pagetools ul li a.subscribe:hover,
-#dokuwiki__pagetools ul li a.subscribe:active,
-#dokuwiki__pagetools ul li a.subscribe:focus,
-.mode_subscribe #dokuwiki__pagetools ul li a.subscribe {
- background-position: right -855px;
-}
-.mode_subscribe #dokuwiki__pagetools ul li a.subscribe:before {
- margin-top: -855px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.subscribe {
- background-position: left -810px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.subscribe:hover,
-[dir=rtl] #dokuwiki__pagetools ul li a.subscribe:active,
-[dir=rtl] #dokuwiki__pagetools ul li a.subscribe:focus,
-[dir=rtl] .mode_subscribe #dokuwiki__pagetools ul li a.subscribe {
- background-position: left -855px;
-}
-
-#dokuwiki__pagetools ul li a.mediaManager {
- background-position: right -990px;
-}
-#dokuwiki__pagetools ul li a.mediaManager:before {
- margin-top: -990px;
-}
-#dokuwiki__pagetools ul li a.mediaManager:hover,
-#dokuwiki__pagetools ul li a.mediaManager:active,
-#dokuwiki__pagetools ul li a.mediaManager:focus {
- background-position: right -1035px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.mediaManager {
- background-position: left -990px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.mediaManager:hover,
-[dir=rtl] #dokuwiki__pagetools ul li a.mediaManager:active,
-[dir=rtl] #dokuwiki__pagetools ul li a.mediaManager:focus {
- background-position: left -1035px;
+/**
+ * page tools without highlighting
+ *
+ * @param string @action The action class
+ * @param int @position Position in the page tools sprite
+ */
+.pagetools-item(@action, @position) {
+ @position-active: (@position+0.5);
+
+ #dokuwiki__pagetools ul li a.@{action} {
+ background-position: right @pagetools_icon_space * @position;
+
+ &:before {
+ margin-top: @pagetools_icon_space * @position;
+ }
+ &:hover,
+ &:active,
+ &:focus {
+ background-position: right @pagetools_icon_space * @position-active;
+ }
+ }
+ [dir=rtl] #dokuwiki__pagetools ul li a.@{action} {
+ background-position: left @pagetools_icon_space * @position;
+
+ &:hover,
+ &:active,
+ &:focus {
+ background-position: left @pagetools_icon_space * @position-active;
+ }
+ }
}
-#dokuwiki__pagetools ul li a.back {
- background-position: right -1080px;
-}
-#dokuwiki__pagetools ul li a.back:before {
- margin-top: -1080px;
-}
-#dokuwiki__pagetools ul li a.back:hover,
-#dokuwiki__pagetools ul li a.back:active,
-#dokuwiki__pagetools ul li a.back:focus {
- background-position: right -1125px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.back {
- background-position: left -1080px;
-}
-[dir=rtl] #dokuwiki__pagetools ul li a.back:hover,
-[dir=rtl] #dokuwiki__pagetools ul li a.back:active,
-[dir=rtl] #dokuwiki__pagetools ul li a.back:focus {
- background-position: left -1125px;
-}
+/**
+ * page tools with highlighting
+ *
+ * @param string @action The action class
+ * @param int @position Position in the page tools sprite
+ * @param string @mode The mode in which this tool should be highlighted
+ */
+.pagetools-item(@action, @position, @mode) {
+ .pagetools-item(@action, @position);
+ @position-active: (@position+0.5);
+
+ .mode_@{mode} #dokuwiki__pagetools ul li a.@{action} {
+ background-position: right @pagetools_icon_space * @position-active;
+ &:before {
+ margin-top: @pagetools_icon_space * @position-active;
+ }
+ }
+ [dir=rtl] .mode_@{mode} #dokuwiki__pagetools ul li a.@{action} {
+ background-position: left @pagetools_icon_space * @position-active;
+ }
+}
+
+.pagetools-item(edit, 1);
+.pagetools-item(create, 2);
+.pagetools-item(show, 4);
+.pagetools-item(source, 5);
+.pagetools-item(draft, 3);
+.pagetools-item(revs, 7, revisions);
+.pagetools-item(backlink, 8, backlink);
+.pagetools-item(top, 10);
+.pagetools-item(revert, 6, revert);
+.pagetools-item(subscribe, 9, subscribe);
+.pagetools-item(mediaManager, 11);
+.pagetools-item(back, 12);