From b78bf706e2ab1d34498beea00b7ecfda11944eee Mon Sep 17 00:00:00 2001 From: romain Date: Mon, 30 Jan 2012 19:58:55 +0100 Subject: Added support for the %GROUP% wildcard. %GROUP% is the same as %USER% except it's done on each group a user is in. %USER% and %GROUP% cannot be mixed on an ACL line. --- conf/dokuwiki.php | 2 ++ inc/auth.php | 12 +++++++++++- lib/plugins/acl/admin.php | 4 ++-- lib/plugins/config/lang/en/lang.php | 2 ++ lib/plugins/config/lang/fr/lang.php | 2 ++ lib/plugins/config/settings/config.metadata.php | 2 ++ 6 files changed, 21 insertions(+), 3 deletions(-) mode change 100644 => 100755 conf/dokuwiki.php diff --git a/conf/dokuwiki.php b/conf/dokuwiki.php old mode 100644 new mode 100755 index 7a7e4bf1a..2beb65600 --- a/conf/dokuwiki.php +++ b/conf/dokuwiki.php @@ -69,6 +69,8 @@ $conf['iexssprotect']= 1; // check for JavaScript and HTML in up /* Authentication Options - read http://www.splitbrain.org/dokuwiki/wiki:acl */ $conf['useacl'] = 0; //Use Access Control Lists to restrict access? +$conf['usewildcards'] = 1; //Use ACL wildcards +$conf['groupwildcards'] = 1; //More specifically, use %GROUP% wildcard $conf['autopasswd'] = 1; //autogenerate passwords and email them to user $conf['authtype'] = 'plain'; //which authentication backend should be used $conf['passcrypt'] = 'smd5'; //Used crypt method (smd5,md5,sha1,ssha,crypt,mysql,my411) diff --git a/inc/auth.php b/inc/auth.php index e0f58e5f2..88d2caf1b 100644 --- a/inc/auth.php +++ b/inc/auth.php @@ -120,17 +120,26 @@ function auth_setup(){ */ function auth_loadACL(){ global $config_cascade; + global $conf; + global $USERINFO; if(!is_readable($config_cascade['acl']['default'])) return array(); $acl = file($config_cascade['acl']['default']); //support user wildcard - if(isset($_SERVER['REMOTE_USER'])){ + if(isset($_SERVER['REMOTE_USER']) && $conf['use_wildcards']){ $len = count($acl); for($i=0; $i<$len; $i++){ if($acl[$i]{0} == '#') continue; list($id,$rest) = preg_split('/\s+/',$acl[$i],2); + if($conf['groups_wilcards'] && (strstr($id, '%GROUP%') || strstr($rest, '%GROUP%'))){ + foreach($USERINFO['grps'] as $grp){ + $nid = str_replace('%GROUP%',cleanID($grp),$id); + $nrest = str_replace('%GROUP%',auth_nameencode($grp),$rest); + $acl[] = "$nid\t$nrest"; + } + } $id = str_replace('%USER%',cleanID($_SERVER['REMOTE_USER']),$id); $rest = str_replace('%USER%',auth_nameencode($_SERVER['REMOTE_USER']),$rest); $acl[$i] = "$id\t$rest"; @@ -607,6 +616,7 @@ function auth_nameencode($name,$skip_group=false){ // never encode wildcard FS#1955 if($name == '%USER%') return $name; + if($name == '%GROUP%') return $name; if (!isset($cache[$name][$skip_group])) { if($skip_group && $name{0} =='@'){ diff --git a/lib/plugins/acl/admin.php b/lib/plugins/acl/admin.php index a6b0624bc..4d2be8dd0 100644 --- a/lib/plugins/acl/admin.php +++ b/lib/plugins/acl/admin.php @@ -84,7 +84,7 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin { $this->who = '@'.ltrim($auth->cleanGroup($who),'@'); }elseif($_REQUEST['acl_t'] == '__u__' && $who){ $this->who = ltrim($who,'@'); - if($this->who != '%USER%'){ #keep wildcard as is + if($this->who != '%USER%' && $this->who != '%GROUP%'){ #keep wildcard as is $this->who = $auth->cleanUser($this->who); } }elseif($_REQUEST['acl_t'] && @@ -140,7 +140,7 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin { if ($who!='@ALL') { $who = '@'.ltrim($auth->cleanGroup($who),'@'); } - } elseif ($who != '%USER%'){ #keep wildcard as is + } elseif ($who != '%USER%' && $who != '%GROUP%'){ #keep wildcard as is $who = $auth->cleanUser($who); } $who = auth_nameencode($who,true); diff --git a/lib/plugins/config/lang/en/lang.php b/lib/plugins/config/lang/en/lang.php index 74ec56345..3d3a6d426 100644 --- a/lib/plugins/config/lang/en/lang.php +++ b/lib/plugins/config/lang/en/lang.php @@ -95,6 +95,8 @@ $lang['showuseras'] = 'What to display when showing the user that last edited a /* Authentication Options */ $lang['useacl'] = 'Use access control lists'; +$lang['usewildcards'] = 'Use the wildcard %USER% for ACL'; +$lang['groupwildcards'] = 'Use the wildcard %GROUP% for ACL'; $lang['autopasswd'] = 'Autogenerate passwords'; $lang['authtype'] = 'Authentication backend'; $lang['passcrypt'] = 'Password encryption method'; diff --git a/lib/plugins/config/lang/fr/lang.php b/lib/plugins/config/lang/fr/lang.php index 8dcd21032..efa5b8f67 100644 --- a/lib/plugins/config/lang/fr/lang.php +++ b/lib/plugins/config/lang/fr/lang.php @@ -83,6 +83,8 @@ $lang['mailguard'] = 'Brouiller les adresses de courriel'; $lang['iexssprotect'] = 'Vérifier la présence de code JavaScript ou HTML malveillant dans les fichiers envoyés'; $lang['showuseras'] = 'Qu\'afficher en montrant les utilisateurs qui ont récemment modifié la page'; $lang['useacl'] = 'Utiliser les listes de contrôle d\'accès (ACL)'; +$lang['usewildcards'] = 'Utiliser le joker %USER% dans les ACL'; +$lang['groupwildcards'] = 'Utiliser le joker %GROUP% dans les ACL'; $lang['autopasswd'] = 'Auto-générer les mots de passe'; $lang['authtype'] = 'Mécanisme d\'authentification'; $lang['passcrypt'] = 'Méthode de chiffrement des mots de passe'; diff --git a/lib/plugins/config/settings/config.metadata.php b/lib/plugins/config/settings/config.metadata.php index 96451e857..bb034f2db 100644 --- a/lib/plugins/config/settings/config.metadata.php +++ b/lib/plugins/config/settings/config.metadata.php @@ -123,6 +123,8 @@ $meta['refshow'] = array('numeric'); $meta['_authentication'] = array('fieldset'); $meta['useacl'] = array('onoff'); +$meta['usewildcards'] = array('onoff'); +$meta['groupwildcards'] = array('onoff'); $meta['autopasswd'] = array('onoff'); $meta['authtype'] = array('authtype'); $meta['passcrypt'] = array('multichoice','_choices' => array('smd5','md5','apr1','sha1','ssha','crypt','mysql','my411','kmd5','pmd5','hmd5')); -- cgit v1.2.3 From 8f50749b133eb2da6dc2d69adc4fb163ed9d41c2 Mon Sep 17 00:00:00 2001 From: Aorimn Date: Mon, 30 Jan 2012 20:08:23 +0100 Subject: Change default groupwildcards option to 0 not to change behavior of already installed wikis --- conf/dokuwiki.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/dokuwiki.php b/conf/dokuwiki.php index 2beb65600..2d6c1ce68 100755 --- a/conf/dokuwiki.php +++ b/conf/dokuwiki.php @@ -69,8 +69,8 @@ $conf['iexssprotect']= 1; // check for JavaScript and HTML in up /* Authentication Options - read http://www.splitbrain.org/dokuwiki/wiki:acl */ $conf['useacl'] = 0; //Use Access Control Lists to restrict access? -$conf['usewildcards'] = 1; //Use ACL wildcards -$conf['groupwildcards'] = 1; //More specifically, use %GROUP% wildcard +$conf['usewildcards'] = 1; //Use ACL wildcard %USER% +$conf['groupwildcards'] = 0; //More specifically, use %GROUP% wildcard $conf['autopasswd'] = 1; //autogenerate passwords and email them to user $conf['authtype'] = 'plain'; //which authentication backend should be used $conf['passcrypt'] = 'smd5'; //Used crypt method (smd5,md5,sha1,ssha,crypt,mysql,my411) -- cgit v1.2.3 From 16cc7ed7a97c7525c006a0355bd0c1277c256cab Mon Sep 17 00:00:00 2001 From: Anika Henke Date: Sun, 8 Apr 2012 16:20:09 +0100 Subject: removed names from footnotes and removed anchors from headings altogether --- inc/parser/xhtml.php | 10 +++++----- lib/tpl/default/design.css | 5 ----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php index 4345b494f..69060a3b4 100644 --- a/inc/parser/xhtml.php +++ b/inc/parser/xhtml.php @@ -109,7 +109,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer { // open the footnote and set the anchor and backlink $this->doc .= '
'; - $this->doc .= ''; + $this->doc .= ''; $this->doc .= $id.') '.DOKU_LF; // get any other footnotes that use the same markup @@ -118,7 +118,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer { if (count($alt)) { foreach ($alt as $ref) { // set anchor and backlink for the other footnotes - $this->doc .= ', '; + $this->doc .= ', '; $this->doc .= ($ref+1).') '.DOKU_LF; } } @@ -181,9 +181,9 @@ class Doku_Renderer_xhtml extends Doku_Renderer { if ($level <= $conf['maxseclevel']) { $this->doc .= ' class="' . $this->startSectionEdit($pos, 'section', $text) . '"'; } - $this->doc .= '>'; + $this->doc .= ' id="'.$hid.'">'; $this->doc .= $this->_xmlEntities($text); - $this->doc .= "".DOKU_LF; + $this->doc .= "".DOKU_LF; } function section_open($level) { @@ -316,7 +316,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer { } // output the footnote reference and link - $this->doc .= ''.$id.')'; + $this->doc .= ''.$id.')'; } function listu_open() { diff --git a/lib/tpl/default/design.css b/lib/tpl/default/design.css index a94f814aa..6e249372b 100644 --- a/lib/tpl/default/design.css +++ b/lib/tpl/default/design.css @@ -265,11 +265,6 @@ div.dokuwiki a:active { text-decoration: underline; } -div.dokuwiki h1 a, -div.dokuwiki h2 a, -div.dokuwiki h3 a, -div.dokuwiki h4 a, -div.dokuwiki h5 a, div.dokuwiki a.nolink { color: __text__ !important; text-decoration: none !important; -- cgit v1.2.3 From 940db3a35fd0feb1f5540a789e79c4a3e192c115 Mon Sep 17 00:00:00 2001 From: Anika Henke Date: Sun, 8 Apr 2012 16:28:39 +0100 Subject: use abbr instead of deprecated acronym --- inc/parser/xhtml.php | 4 ++-- lib/tpl/default/design.css | 2 +- lib/tpl/default/print.css | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php index 69060a3b4..157d0d76a 100644 --- a/inc/parser/xhtml.php +++ b/inc/parser/xhtml.php @@ -471,8 +471,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer { $title = $this->_xmlEntities($this->acronyms[$acronym]); - $this->doc .= ''.$this->_xmlEntities($acronym).''; + $this->doc .= ''.$this->_xmlEntities($acronym).''; } else { $this->doc .= $this->_xmlEntities($acronym); diff --git a/lib/tpl/default/design.css b/lib/tpl/default/design.css index 6e249372b..1124cfe92 100644 --- a/lib/tpl/default/design.css +++ b/lib/tpl/default/design.css @@ -382,7 +382,7 @@ div.dokuwiki img.middle { vertical-align: middle; } -div.dokuwiki acronym { +div.dokuwiki abbr { cursor: help; border-bottom: 1px dotted __text__; } diff --git a/lib/tpl/default/print.css b/lib/tpl/default/print.css index 45b60aad2..4387dc4bf 100644 --- a/lib/tpl/default/print.css +++ b/lib/tpl/default/print.css @@ -200,7 +200,7 @@ a.fn_bot { font-weight: bold; } -acronym { +abbr { border: 0; } -- cgit v1.2.3 From 3c86b7ebf3316c3566a7f6fed683a484036d1c3b Mon Sep 17 00:00:00 2001 From: Anika Henke Date: Sun, 8 Apr 2012 17:35:06 +0100 Subject: removed align attribute from images and inserted them only in the feed (FS#1351) can someone with better regex skills please revise this? --- feed.php | 4 ++++ inc/parser/xhtml.php | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/feed.php b/feed.php index 98d5ef2e8..dafbb3c07 100644 --- a/feed.php +++ b/feed.php @@ -324,6 +324,10 @@ function rss_buildItems(&$rss,&$data,$opt){ // no TOC in feeds $content = preg_replace('/().*()/s','',$content); + // add alignment for images + $content = preg_replace('/class="medialeft"/s', 'class="medialeft" align="left"', $content); + $content = preg_replace('/class="mediaright"/s', 'class="mediaright" align="right"', $content); + // make URLs work when canonical is not set, regexp instead of rerendering! if(!$conf['canonical']){ $base = preg_quote(DOKU_REL,'/'); diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php index 157d0d76a..4514a18a4 100644 --- a/inc/parser/xhtml.php +++ b/inc/parser/xhtml.php @@ -1075,10 +1075,6 @@ class Doku_Renderer_xhtml extends Doku_Renderer { $ret .= ' Date: Sun, 8 Apr 2012 17:45:05 +0100 Subject: renamed smiley image class to 'icon' (FS#1970) --- inc/parser/xhtml.php | 2 +- lib/tpl/default/design.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php index 4514a18a4..119ac3f01 100644 --- a/inc/parser/xhtml.php +++ b/inc/parser/xhtml.php @@ -483,7 +483,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer { if ( array_key_exists($smiley, $this->smileys) ) { $title = $this->_xmlEntities($this->smileys[$smiley]); $this->doc .= ''.
+                ''; } else { $this->doc .= $this->_xmlEntities($smiley); diff --git a/lib/tpl/default/design.css b/lib/tpl/default/design.css index 1124cfe92..9d2cc1844 100644 --- a/lib/tpl/default/design.css +++ b/lib/tpl/default/design.css @@ -378,7 +378,7 @@ div.dokuwiki img.mediacenter { } /* smileys */ -div.dokuwiki img.middle { +div.dokuwiki img.icon { vertical-align: middle; } -- cgit v1.2.3 From 0607bfee2c4334d31415541abb89026e77c7628a Mon Sep 17 00:00:00 2001 From: Anika Henke Date: Sun, 8 Apr 2012 20:01:24 +0100 Subject: added some wanting classes --- inc/html.php | 17 ++++++++-------- lib/tpl/default/_mediamanager.css | 6 +++--- lib/tpl/dokuwiki/css/_edit.css | 27 ++++++++++++++------------ lib/tpl/dokuwiki/css/_recent.css | 41 +++++++++++++-------------------------- lib/tpl/dokuwiki/css/mobile.css | 3 +-- lib/tpl/dokuwiki/css/rtl.css | 14 ++++++------- 6 files changed, 48 insertions(+), 60 deletions(-) diff --git a/inc/html.php b/inc/html.php index b233e1d92..f3f042ea1 100644 --- a/inc/html.php +++ b/inc/html.php @@ -449,7 +449,7 @@ function html_revisions($first=0, $media_id = false){ if (!$media_id) print p_locale_xhtml('revisions'); - $params = array('id' => 'page__revisions'); + $params = array('id' => 'page__revisions', 'class' => 'changes'); if ($media_id) $params['action'] = media_managerURL(array('image' => $media_id), '&'); $form = new Doku_Form($params); @@ -664,12 +664,13 @@ function html_recent($first=0, $show_changes='both'){ if (getNS($ID) != '') print '

' . sprintf($lang['recent_global'], getNS($ID), wl('', 'do=recent')) . '

'; - $form = new Doku_Form(array('id' => 'dw__recent', 'method' => 'GET')); + $form = new Doku_Form(array('id' => 'dw__recent', 'method' => 'GET', 'class' => 'changes')); $form->addHidden('sectok', null); $form->addHidden('do', 'recent'); $form->addHidden('id', $ID); if ($conf['mediarevisions']) { + $form->addElement('
'); $form->addElement(form_makeListboxField( 'show_changes', array( @@ -682,6 +683,7 @@ function html_recent($first=0, $show_changes='both'){ array('class'=>'quickselect'))); $form->addElement(form_makeButton('submit', 'recent', $lang['btn_apply'])); + $form->addElement('
'); } $form->addElement(form_makeOpenTag('ul')); @@ -1381,7 +1383,7 @@ function html_edit(){ } $form->addHidden('target', $data['target']); - $form->addElement(form_makeOpenTag('div', array('id'=>'wiki__editbar'))); + $form->addElement(form_makeOpenTag('div', array('id'=>'wiki__editbar', 'class'=>'editBar'))); $form->addElement(form_makeOpenTag('div', array('id'=>'size__ctl'))); $form->addElement(form_makeCloseTag('div')); if ($wr) { @@ -1413,13 +1415,12 @@ function html_edit(){ echo 'textChanged = ' . ($mod ? 'true' : 'false'); echo '//-->' . NL; } ?> -
+
-
-
- +
+
Date: Mon, 9 Apr 2012 14:15:29 +0100 Subject: load only one stylesheet for all modes instead of three Instead of three stylesheets for 'all', 'screen' and 'print' modes, they are all loaded into a single stylesheet by wrapping all screen styles in a "@media screen {}" and all print styles in a "@media print {}". The 'all' mode is not wrapped in anything. Potential issues with existing CSS: If any of your screen or print CSS files already contain any "@media" syntax, the CSS will probably break. In that case please add any CSS with "@media" in it to the 'all' mode instead! Also, the 'rtl' mode is hereby deprecated. Please just prefix any RTL styles within your normal CSS files with "[dir=rtl]". This also fixes that RTL styles cannot be added for 'all' or 'print' modes. --- inc/template.php | 6 +-- lib/exe/css.php | 125 +++++++++++++++++++++++++++------------------ lib/tpl/dokuwiki/style.ini | 4 +- 3 files changed, 79 insertions(+), 56 deletions(-) diff --git a/inc/template.php b/inc/template.php index ab6aa925f..131f34020 100644 --- a/inc/template.php +++ b/inc/template.php @@ -354,12 +354,8 @@ function tpl_metaheaders($alt=true){ } // load stylesheets - $head['link'][] = array('rel'=>'stylesheet', 'media'=>'screen', 'type'=>'text/css', + $head['link'][] = array('rel'=>'stylesheet', 'type'=>'text/css', 'href'=>DOKU_BASE.'lib/exe/css.php?t='.$conf['template'].'&tseed='.$tseed); - $head['link'][] = array('rel'=>'stylesheet', 'media'=>'all', 'type'=>'text/css', - 'href'=>DOKU_BASE.'lib/exe/css.php?s=all&t='.$conf['template'].'&tseed='.$tseed); - $head['link'][] = array('rel'=>'stylesheet', 'media'=>'print', 'type'=>'text/css', - 'href'=>DOKU_BASE.'lib/exe/css.php?s=print&t='.$conf['template'].'&tseed='.$tseed); // make $INFO and other vars available to JavaScripts $json = new JSON(); diff --git a/lib/exe/css.php b/lib/exe/css.php index 69b512205..5468376c6 100644 --- a/lib/exe/css.php +++ b/lib/exe/css.php @@ -9,6 +9,7 @@ if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../'); if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching) if(!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT',1); // we gzip ourself here +if(!defined('NL')) define('NL',"\n"); require_once(DOKU_INC.'inc/init.php'); // Main (don't run when UNIT test) @@ -30,10 +31,12 @@ function css_out(){ global $lang; global $config_cascade; - $mediatype = 'screen'; - if (isset($_REQUEST['s']) && - in_array($_REQUEST['s'], array('all', 'print', 'feed'))) { - $mediatype = $_REQUEST['s']; + if (isset($_REQUEST['s']) && ($_REQUEST['s'] == 'feed')) { + $mediatypes = array('feed'); + $type = 'feed'; + } else { + $mediatypes = array('screen', 'all', 'print'); + $type = ''; } $tpl = trim(preg_replace('/[^\w-]+/','',$_REQUEST['t'])); @@ -46,7 +49,7 @@ function css_out(){ } // The generated script depends on some dynamic options - $cache = new cache('styles'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].DOKU_BASE.$tplinc.$mediatype,'.css'); + $cache = new cache('styles'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].DOKU_BASE.$tplinc.$type,'.css'); // load template styles $tplstyles = array(); @@ -57,57 +60,79 @@ function css_out(){ } } - // Array of needed files and their web locations, the latter ones - // are needed to fix relative paths in the stylesheets - $files = array(); - // load core styles - $files[DOKU_INC.'lib/styles/'.$mediatype.'.css'] = DOKU_BASE.'lib/styles/'; - // load jQuery-UI theme - $files[DOKU_INC.'lib/scripts/jquery/jquery-ui-theme/smoothness.css'] = DOKU_BASE.'lib/scripts/jquery/jquery-ui-theme/'; - // load plugin styles - $files = array_merge($files, css_pluginstyles($mediatype)); - // load template styles - if (isset($tplstyles[$mediatype])) { - $files = array_merge($files, $tplstyles[$mediatype]); - } - // 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']; - } - // load user styles - if(isset($config_cascade['userstyle'][$mediatype])){ - $files[$config_cascade['userstyle'][$mediatype]] = DOKU_BASE; - } - // load rtl styles - // @todo: this currently adds the rtl styles only to the 'screen' media type - // but 'print' and 'all' should also be supported - if ($mediatype=='screen') { - if($lang['direction'] == 'rtl'){ - if (isset($tplstyles['rtl'])) $files = array_merge($files, $tplstyles['rtl']); + // start output buffering + ob_start(); + + foreach($mediatypes as $mediatype) { + // Array of needed files and their web locations, the latter ones + // are needed to fix relative paths in the stylesheets + $files = array(); + // load core styles + $files[DOKU_INC.'lib/styles/'.$mediatype.'.css'] = DOKU_BASE.'lib/styles/'; + // load jQuery-UI theme + if ($mediatype == 'screen') { + //$files[DOKU_INC.'lib/scripts/jquery/jquery-ui-theme/smoothness.css'] = DOKU_BASE.'lib/scripts/jquery/jquery-ui-theme/'; + } + // load plugin styles + $files = array_merge($files, css_pluginstyles($mediatype)); + // load template styles + if (isset($tplstyles[$mediatype])) { + $files = array_merge($files, $tplstyles[$mediatype]); + } + // 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']; + } + // load user styles + if(isset($config_cascade['userstyle'][$mediatype])){ + $files[$config_cascade['userstyle'][$mediatype]] = DOKU_BASE; + } + // load rtl styles + // note: this adds the rtl styles only to the 'screen' media type + // @deprecated 2012-04-09: rtl will cease to be a mode of its own, + // 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 = array_merge($files, $tplstyles['rtl']); + } } - } - $cache_files = array_merge(array_keys($files), getConfigFiles('main')); - $cache_files[] = $tplinc.'style.ini'; - $cache_files[] = __FILE__; + $cache_files = array_merge(array_keys($files), getConfigFiles('main')); + $cache_files[] = $tplinc.'style.ini'; + $cache_files[] = __FILE__; - // check cache age & handle conditional request - // This may exit if a cache can be used - http_cached($cache->cache, - $cache->useCache(array('files' => $cache_files))); + // check cache age & handle conditional request + // This may exit if a cache can be used + http_cached($cache->cache, + $cache->useCache(array('files' => $cache_files))); - // start output buffering and build the stylesheet - ob_start(); + // build the stylesheet - // print the default classes for interwiki links and file downloads - css_interwiki(); - css_filetypes(); + // print the default classes for interwiki links and file downloads + if ($mediatype == 'screen') { + css_interwiki(); + css_filetypes(); + } - // load files - foreach($files as $file => $location){ - print css_loadfile($file, $location); + // load files + $css_content = ''; + foreach($files as $file => $location){ + $css_content .= css_loadfile($file, $location); + } + switch ($mediatype) { + case 'screen': + print NL.'@media screen { /* START screen styles */'.NL.$css_content.NL.'} /* /@media END screen styles */'.NL; + break; + case 'print': + print NL.'@media print { /* START print styles */'.NL.$css_content.NL.'} /* /@media END print styles */'.NL; + break; + case 'all': + case 'feed': + default: + print NL.'/* START rest styles */ '.NL.$css_content.NL.'/* END rest styles */'.NL; + break; + } } - // end output buffering and get contents $css = ob_get_contents(); ob_end_clean(); @@ -275,6 +300,8 @@ function css_pluginstyles($mediatype='screen'){ if ($mediatype=='screen') { $list[DOKU_PLUGIN."$p/style.css"] = DOKU_BASE."lib/plugins/$p/"; } + // @deprecated 2012-04-09: rtl will cease to be a mode of its own, + // please use "[dir=rtl]" in any css file in all, screen or print mode instead if($lang['direction'] == 'rtl'){ $list[DOKU_PLUGIN."$p/rtl.css"] = DOKU_BASE."lib/plugins/$p/"; } diff --git a/lib/tpl/dokuwiki/style.ini b/lib/tpl/dokuwiki/style.ini index b8e55bcc8..b52d7e652 100644 --- a/lib/tpl/dokuwiki/style.ini +++ b/lib/tpl/dokuwiki/style.ini @@ -29,10 +29,10 @@ css/design.css = screen css/pagetools.css = screen css/content.css = screen css/includes.css = screen -css/mobile.css = screen css/rtl.css = screen -css/print.css = print +css/mobile.css = all +css/print.css = print ; This section is used to configure some placeholder values used in -- cgit v1.2.3 From 57b34425d6b0c774aaa255035325b58e6d18a9e7 Mon Sep 17 00:00:00 2001 From: Anika Henke Date: Mon, 9 Apr 2012 14:16:48 +0100 Subject: moved the mobile part of the rtl styles (including @media) into mobile.css --- lib/tpl/dokuwiki/css/mobile.css | 42 +++++++++++++++++++++++++ lib/tpl/dokuwiki/css/rtl.css | 68 +++-------------------------------------- 2 files changed, 46 insertions(+), 64 deletions(-) diff --git a/lib/tpl/dokuwiki/css/mobile.css b/lib/tpl/dokuwiki/css/mobile.css index b923c811c..6aacb4674 100644 --- a/lib/tpl/dokuwiki/css/mobile.css +++ b/lib/tpl/dokuwiki/css/mobile.css @@ -27,6 +27,11 @@ margin-left: 0; } +[dir=rtl] .hasSidebar #dokuwiki__content, +[dir=rtl] .hasSidebar #dokuwiki__content > .pad { + margin-right: 0; +} + /* toc */ .dokuwiki div.toc { float: none; @@ -35,6 +40,11 @@ border-left-width: 0; border-bottom: 1px solid __border__; } +[dir=rtl] .dokuwiki div.toc { + float: none; + margin: 0 0 1em 0; + border-right-width: 0; +} .dokuwiki div.tocheader { padding: 0 0 .5em; } @@ -68,6 +78,9 @@ .dokuwiki form.changes ul { padding-left: 0; } +[dir=rtl] .dokuwiki form.changes ul { + padding-right: 0; +} } /* /@media */ @@ -102,10 +115,19 @@ padding-left: 0; margin: 0; } +[dir=rtl] #dokuwiki__header ul.a11y.skip { + left: auto !important; + right: 0 !important; + float: left; + padding-right: 0; +} #dokuwiki__header ul.a11y.skip li { margin-left: .35em; display: inline; } +[dir=rtl] #dokuwiki__header ul.a11y.skip li { + margin: 0 .35em 0 0; +} #dokuwiki__header .headings, #dokuwiki__header .tools { @@ -114,9 +136,18 @@ width: auto; margin-bottom: .5em; } +[dir=rtl] #dokuwiki__header .headings, +[dir=rtl] #dokuwiki__header .tools { + float: none; + text-align: right; + width: auto; +} #dokuwiki__sitetools { text-align: left; } +[dir=rtl] #dokuwiki__sitetools { + text-align: right; +} #dokuwiki__usertools, #dokuwiki__sitetools ul, #dokuwiki__sitetools h3, @@ -132,6 +163,11 @@ margin: 0 .2em .2em 0; width: 49%; } +[dir=rtl] #dokuwiki__sitetools form.search { + float: right; + margin: 0 0 .2em .2em; +} + #dokuwiki__sitetools form.search input.edit { width: 100% !important; } @@ -147,6 +183,9 @@ float: right; width: 49%; } +[dir=rtl] #dokuwiki__header .mobileTools { + float: left; +} #dokuwiki__header .mobileTools select { padding: .3em .1em; width: 100% !important; @@ -177,6 +216,9 @@ .dokuwiki label.block { text-align: left; } +[dir=rtl] .dokuwiki label.block { + text-align: right; +} .dokuwiki label.block span { display: block; } diff --git a/lib/tpl/dokuwiki/css/rtl.css b/lib/tpl/dokuwiki/css/rtl.css index f36591548..2a8336b7f 100644 --- a/lib/tpl/dokuwiki/css/rtl.css +++ b/lib/tpl/dokuwiki/css/rtl.css @@ -255,6 +255,10 @@ float: left; text-align: left; } +[dir=rtl] #dokuwiki__header .tools li { + margin-right: 1em; + margin-left: 0; +} [dir=rtl] #dokuwiki__aside { float: right; @@ -525,67 +529,3 @@ [dir=rtl] .JSpopup ol { padding-right: 0; } - - -/*____________ mobile ____________*/ - -@media only screen and (max-width: 768px), only screen and (max-device-width: 960px) { - - -[dir=rtl] .hasSidebar #dokuwiki__content, -[dir=rtl] .hasSidebar #dokuwiki__content > .pad { - margin-right: 0; -} - -[dir=rtl] .dokuwiki div.toc { - float: none; - margin: 0 0 1em 0; - border-right-width: 0; -} - -[dir=rtl] .dokuwiki form.changes ul { - padding-right: 0; -} - - -} /* /@media */ - -@media only screen and (max-width: 480px), only screen and (max-device-width: 480px) { - - -[dir=rtl] #dokuwiki__header ul.a11y.skip { - left: auto !important; - right: 0 !important; - float: left; - padding-right: 0; -} -[dir=rtl] #dokuwiki__header ul.a11y.skip li { - margin: 0 .35em 0 0; -} - -[dir=rtl] #dokuwiki__header .headings, -[dir=rtl] #dokuwiki__header .tools { - float: none; - text-align: right; - width: auto; -} -[dir=rtl] #dokuwiki__sitetools { - text-align: right; -} - -[dir=rtl] #dokuwiki__sitetools form.search { - float: right; - margin: 0 0 .2em .2em; -} - -[dir=rtl] #dokuwiki__header .mobileTools { - float: left; -} - -[dir=rtl] .dokuwiki label.block { - text-align: right; -} - - - -} /* /@media */ -- cgit v1.2.3 From 6322e09da839741cbf92ac5201e51e41a05b5191 Mon Sep 17 00:00:00 2001 From: Anika Henke Date: Mon, 9 Apr 2012 14:29:50 +0100 Subject: minor changes to gradients: quotes around data-uris and commented css solution --- lib/tpl/dokuwiki/css/basic.css | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/tpl/dokuwiki/css/basic.css b/lib/tpl/dokuwiki/css/basic.css index c8e0c435e..9c69a1196 100644 --- a/lib/tpl/dokuwiki/css/basic.css +++ b/lib/tpl/dokuwiki/css/basic.css @@ -17,7 +17,7 @@ body { color: __text__; background-color: __background_site__; background-image: url(images/page-background.svg); - background-image: linear-gradient( top, __background_neu__ 0%, __background_alt__ 1em, __background_site__ 4em); + /*background-image: linear-gradient( top, __background_neu__ 0%, __background_alt__ 1em, __background_site__ 4em);*/ background-size: 1px 10em; background-repeat: repeat-x; margin: 0; @@ -330,8 +330,8 @@ button, .qq-upload-button { color: #333; background-color: #eee; - background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPgo8bGluZWFyR3JhZGllbnQgaWQ9Imc4MjQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkZGRkYiIG9mZnNldD0iMCIvPjxzdG9wIHN0b3AtY29sb3I9IiNGNEY0RjQiIG9mZnNldD0iMC4zIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0VFRUVFRSIgb2Zmc2V0PSIwLjk5Ii8+PHN0b3Agc3RvcC1jb2xvcj0iI0NDQ0NDQyIgb2Zmc2V0PSIuOTkiLz4KPC9saW5lYXJHcmFkaWVudD4KPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNnODI0KSIgLz4KPC9zdmc+); - background: linear-gradient( top, #ffffff 0%, #f4f4f4 30%, #eeeeee 99%, #cccccc 99%); + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPgo8bGluZWFyR3JhZGllbnQgaWQ9Imc4MjQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkZGRkYiIG9mZnNldD0iMCIvPjxzdG9wIHN0b3AtY29sb3I9IiNGNEY0RjQiIG9mZnNldD0iMC4zIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0VFRUVFRSIgb2Zmc2V0PSIwLjk5Ii8+PHN0b3Agc3RvcC1jb2xvcj0iI0NDQ0NDQyIgb2Zmc2V0PSIuOTkiLz4KPC9saW5lYXJHcmFkaWVudD4KPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNnODI0KSIgLz4KPC9zdmc+"); + /*background: linear-gradient( top, #ffffff 0%, #f4f4f4 30%, #eeeeee 99%, #cccccc 99%);*/ border: 1px solid #ccc; border-radius: 2px; padding: .1em .5em; @@ -353,8 +353,8 @@ button:focus, .qq-upload-button:hover { border-color: #999; background-color: #ddd; - background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPgo8bGluZWFyR3JhZGllbnQgaWQ9Imc2NzAiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkZGRkYiIG9mZnNldD0iMCIvPjxzdG9wIHN0b3AtY29sb3I9IiNGNEY0RjQiIG9mZnNldD0iMC4zIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0RERERERCIgb2Zmc2V0PSIwLjk5Ii8+PHN0b3Agc3RvcC1jb2xvcj0iI0JCQkJCQiIgb2Zmc2V0PSIuOTkiLz4KPC9saW5lYXJHcmFkaWVudD4KPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNnNjcwKSIgLz4KPC9zdmc+); - background: linear-gradient( top, #ffffff 0%, #f4f4f4 30%, #dddddd 99%, #bbbbbb 99%); + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPgo8bGluZWFyR3JhZGllbnQgaWQ9Imc2NzAiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkZGRkYiIG9mZnNldD0iMCIvPjxzdG9wIHN0b3AtY29sb3I9IiNGNEY0RjQiIG9mZnNldD0iMC4zIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0RERERERCIgb2Zmc2V0PSIwLjk5Ii8+PHN0b3Agc3RvcC1jb2xvcj0iI0JCQkJCQiIgb2Zmc2V0PSIuOTkiLz4KPC9saW5lYXJHcmFkaWVudD4KPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNnNjcwKSIgLz4KPC9zdmc+"); + /*background: linear-gradient( top, #ffffff 0%, #f4f4f4 30%, #dddddd 99%, #bbbbbb 99%);*/ } input::-moz-focus-inner, -- cgit v1.2.3 From 49e5a707012739fbb9dc8ee53daaa3784c9a0fc1 Mon Sep 17 00:00:00 2001 From: Anika Henke Date: Mon, 9 Apr 2012 15:03:01 +0100 Subject: moved contents of rtl.css into other CSS files --- lib/tpl/dokuwiki/css/_admin.css | 12 + lib/tpl/dokuwiki/css/_edit.css | 13 + lib/tpl/dokuwiki/css/_forms.css | 9 + lib/tpl/dokuwiki/css/_imgdetail.css | 8 + lib/tpl/dokuwiki/css/_links.css | 10 + lib/tpl/dokuwiki/css/_media_popup.css | 64 +++- lib/tpl/dokuwiki/css/_modal.css | 11 + lib/tpl/dokuwiki/css/_recent.css | 3 + lib/tpl/dokuwiki/css/_search.css | 8 + lib/tpl/dokuwiki/css/_toc.css | 18 ++ lib/tpl/dokuwiki/css/basic.css | 35 +++ lib/tpl/dokuwiki/css/content.css | 16 + lib/tpl/dokuwiki/css/design.css | 80 +++++ lib/tpl/dokuwiki/css/pagetools.css | 121 ++++++++ lib/tpl/dokuwiki/css/rtl.css | 531 ---------------------------------- lib/tpl/dokuwiki/css/structure.css | 23 ++ lib/tpl/dokuwiki/style.ini | 1 - 17 files changed, 425 insertions(+), 538 deletions(-) delete mode 100644 lib/tpl/dokuwiki/css/rtl.css diff --git a/lib/tpl/dokuwiki/css/_admin.css b/lib/tpl/dokuwiki/css/_admin.css index e4664367c..c8f3694b5 100644 --- a/lib/tpl/dokuwiki/css/_admin.css +++ b/lib/tpl/dokuwiki/css/_admin.css @@ -9,6 +9,9 @@ list-style-type: none; font-size: 1.125em; } +[dir=rtl] .dokuwiki ul.admin_tasks { + float: right; +} .dokuwiki ul.admin_tasks li { padding-left: 35px; @@ -18,6 +21,11 @@ background: transparent none no-repeat scroll 0 0; color: inherit; } +[dir=rtl] .dokuwiki ul.admin_tasks li { + padding-left: 0; + padding-right: 35px; + background-position: right 0; +} .dokuwiki ul.admin_tasks li.admin_acl { background-image: url(../../images/admin/acl.png); @@ -45,3 +53,7 @@ color: __text_neu__; background-color: inherit; } +[dir=rtl] .dokuwiki #admin__version { + clear: right; + float: left; +} diff --git a/lib/tpl/dokuwiki/css/_edit.css b/lib/tpl/dokuwiki/css/_edit.css index 0a5106575..374ddeb96 100644 --- a/lib/tpl/dokuwiki/css/_edit.css +++ b/lib/tpl/dokuwiki/css/_edit.css @@ -20,6 +20,9 @@ color: __text_alt__; background-color: inherit; } +[dir=rtl] #draft__status { + float: left; +} #tool__bar { float: left; } @@ -67,6 +70,9 @@ div.picker button.toolbutton { #size__ctl { float: right; } +[dir=rtl] #size__ctl { + float: left; +} #size__ctl img { cursor: pointer; } @@ -76,6 +82,10 @@ div.picker button.toolbutton { display: inline; margin-right: 1em; } +[dir=rtl] .dokuwiki .editBar .editButtons { + margin-right: 0; + margin-left: 1em; +} .dokuwiki .editBar .editButtons input { } @@ -115,6 +125,9 @@ div.picker button.toolbutton { float: right; margin-top: -1.4em; } +[dir=rtl] .dokuwiki .secedit { + float: left; +} .dokuwiki .secedit input.button { font-size: 75%; } diff --git a/lib/tpl/dokuwiki/css/_forms.css b/lib/tpl/dokuwiki/css/_forms.css index 0c82f5f8c..fb07e989a 100644 --- a/lib/tpl/dokuwiki/css/_forms.css +++ b/lib/tpl/dokuwiki/css/_forms.css @@ -23,12 +23,18 @@ text-align: right; font-weight: bold; } +[dir=rtl] .dokuwiki label.block { + text-align: left; +} .dokuwiki label.simple { display: block; text-align: left; font-weight: normal; } +[dir=rtl] .dokuwiki label.simple { + text-align: right; +} .dokuwiki label.block input.edit { width: 50%; @@ -75,6 +81,9 @@ text-align: left; margin: 0.5em 0; } +[dir=rtl] #subscribe__form fieldset { + text-align: right; +} #subscribe__form label { display: block; diff --git a/lib/tpl/dokuwiki/css/_imgdetail.css b/lib/tpl/dokuwiki/css/_imgdetail.css index a3e0f55f5..a07400028 100644 --- a/lib/tpl/dokuwiki/css/_imgdetail.css +++ b/lib/tpl/dokuwiki/css/_imgdetail.css @@ -12,9 +12,17 @@ float: left; margin: 0 1.5em .5em 0; } +[dir=rtl] #dokuwiki__detail div.content img { + float: right; + margin-right: 0; + margin-left: 1.5em; +} #dokuwiki__detail div.img_detail { float: left; } +[dir=rtl] #dokuwiki__detail div.content div.img_detail { + float: right +} #dokuwiki__detail div.img_detail h2 { } diff --git a/lib/tpl/dokuwiki/css/_links.css b/lib/tpl/dokuwiki/css/_links.css index 6b19c3a24..ef34a6706 100644 --- a/lib/tpl/dokuwiki/css/_links.css +++ b/lib/tpl/dokuwiki/css/_links.css @@ -63,3 +63,13 @@ .dokuwiki a.interwiki { padding: 0 0 0 17px; } + +/* RTL corrections; if link icons don't work as expected, remove the following lines */ +[dir=rtl] .dokuwiki a.urlextern, +[dir=rtl] .dokuwiki a.windows, +[dir=rtl] .dokuwiki a.mail, +[dir=rtl] .dokuwiki a.interwiki, +[dir=rtl] .dokuwiki a.mediafile { + background-position: right center; + padding: 0 17px 0 0; +} diff --git a/lib/tpl/dokuwiki/css/_media_popup.css b/lib/tpl/dokuwiki/css/_media_popup.css index 0469c8e60..c776e6b8a 100644 --- a/lib/tpl/dokuwiki/css/_media_popup.css +++ b/lib/tpl/dokuwiki/css/_media_popup.css @@ -22,6 +22,12 @@ html.popup { left: 0; border-right: 1px solid __border__; } +[dir=rtl] #mediamgr__aside { + left: auto; + right: 0; + border-right-width: 0; + border-left: 1px solid __border__; +} #mediamgr__aside .pad { padding: .5em; } @@ -33,6 +39,10 @@ html.popup { position: absolute; right: 0; } +[dir=rtl] #mediamgr__content { + right: auto; + left: 0; +} #mediamgr__content .pad { padding: .5em; } @@ -57,6 +67,10 @@ html.popup { #media__opts input { margin-right: .3em; } +[dir=rtl] #media__opts input { + margin-right: 0; + margin-left: .3em; +} #media__opts label { } @@ -65,22 +79,38 @@ html.popup { #media__tree ul { padding-left: .2em; } +[dir=rtl] #media__tree ul { + padding-left: 0; + padding-right: .2em; +} #media__tree ul li { clear: left; list-style-type: none; list-style-image: none; margin-left: 0; } +[dir=rtl] #media__tree ul li { + clear: right; + margin-right: 0; +} #media__tree ul li img { float: left; padding: .5em .3em 0 0; } +[dir=rtl] #media__tree ul li img { + float: right; + padding: .5em 0 0 .3em; +} #media__tree ul li div.li { display: inline; } #media__tree ul li li { margin-left: 1.5em; } +[dir=rtl] #media__tree ul li li { + margin-left: 0; + margin-right: 1.5em; +} /* right side ********************************************************************/ @@ -125,6 +155,10 @@ html.popup { margin-right: 1.5em; font-weight: bold; } +[dir=rtl] #media__content a.mediafile { + margin-right: 0; + margin-left: 1.5em; +} #media__content span.info { } #media__content img.btn { @@ -144,6 +178,10 @@ html.popup { float: left; margin: 0 .5em 0 18px; } +[dir=rtl] #media__content div.detail div.thumb { + float: right; + margin: 0 18px 0 .5em; +} #media__content div.detail div.thumb a { display: block; cursor: pointer; @@ -155,17 +193,17 @@ html.popup { /*____________ media search ____________*/ -form#dw__mediasearch { +#dw__mediasearch { } -form#dw__mediasearch p { +#dw__mediasearch p { } -form#dw__mediasearch label { +#dw__mediasearch label { } -form#dw__mediasearch label span { +#dw__mediasearch label span { } -form#dw__mediasearch input.edit { +#dw__mediasearch input.edit { } -form#dw__mediasearch input.button { +#dw__mediasearch input.button { } @@ -180,6 +218,9 @@ form#dw__mediasearch input.button { margin-bottom: .5em; overflow: hidden; } +[dir=rtl] #media__content form.meta div.metafield { + clear: right; +} #media__content form.meta label { display: block; @@ -188,11 +229,18 @@ form#dw__mediasearch input.button { font-weight: bold; clear: left; } +[dir=rtl] #media__content form.meta label { + float: right; + clear: right; +} #media__content form.meta .edit { float: left; width: 70%; margin: 0; } +[dir=rtl] #media__content form.meta .edit { + float: right; +} #media__content form.meta textarea.edit { /* needed because of IE8 hack in _edit.css for textarea.edit: */ max-width: 70%; @@ -203,3 +251,7 @@ form#dw__mediasearch input.button { clear: left; margin: .2em 0 0 25%; } +[dir=rtl] #media__content form.meta div.buttons { + clear: right; + margin: .2em 25% 0 0; +} diff --git a/lib/tpl/dokuwiki/css/_modal.css b/lib/tpl/dokuwiki/css/_modal.css index 125f702a8..a3d3be194 100644 --- a/lib/tpl/dokuwiki/css/_modal.css +++ b/lib/tpl/dokuwiki/css/_modal.css @@ -13,6 +13,10 @@ #link__wiz { } +[dir=rtl] #link__wiz_close { + float: left; +} + #link__wiz_result { background-color: __background__; width: 293px; @@ -23,6 +27,9 @@ text-align: left; line-height: 1; } +[dir=rtl] #link__wiz_result { + text-align: right; +} #link__wiz_result div { padding: 3px 3px 3px 0; @@ -34,6 +41,10 @@ min-height: 16px; background: transparent 3px center no-repeat; } +[dir=rtl] #link__wiz_result div a { + padding: 3px 22px 3px 3px; + background-position: 257px 3px; +} #link__wiz_result div.type_u a { background-image: url(../../images/up.png); diff --git a/lib/tpl/dokuwiki/css/_recent.css b/lib/tpl/dokuwiki/css/_recent.css index 426e06fb4..d73bb9463 100644 --- a/lib/tpl/dokuwiki/css/_recent.css +++ b/lib/tpl/dokuwiki/css/_recent.css @@ -14,6 +14,9 @@ list-style: none; margin-left: 0; } +[dir=rtl] .dokuwiki form.changes ul li { + margin-right: 0; +} .dokuwiki form.changes ul li span, .dokuwiki form.changes ul li a { vertical-align: middle; diff --git a/lib/tpl/dokuwiki/css/_search.css b/lib/tpl/dokuwiki/css/_search.css index c124c1e86..446efe331 100644 --- a/lib/tpl/dokuwiki/css/_search.css +++ b/lib/tpl/dokuwiki/css/_search.css @@ -25,6 +25,9 @@ width: 12em; margin: 0 1.5em; } +[dir=rtl] .dokuwiki div.search_quickresult ul li { + float: right; +} /*____________ search results ____________*/ @@ -78,6 +81,11 @@ text-align: left; display: none; } +[dir=rtl] .dokuwiki form.search div.ajax_qsearch { + left: auto; + right: -13.5em; + text-align: right; +} .dokuwiki form.search div.ajax_qsearch strong { display: block; margin-bottom: .3em; diff --git a/lib/tpl/dokuwiki/css/_toc.css b/lib/tpl/dokuwiki/css/_toc.css index b78817523..f89bce6c1 100644 --- a/lib/tpl/dokuwiki/css/_toc.css +++ b/lib/tpl/dokuwiki/css/_toc.css @@ -14,6 +14,10 @@ background-color: __background_alt__; color: inherit; } +[dir=rtl] .dokuwiki div.toc { + float: left; + margin: 0 1.4em 1.4em 0; +} /*____________ toc header ____________*/ @@ -27,6 +31,10 @@ float: right; margin: 0 .2em; } +[dir=rtl] .dokuwiki .toc span.toc_open, +[dir=rtl] .dokuwiki .toc span.toc_close { + float: left; +} /*____________ toc list ____________*/ @@ -49,6 +57,10 @@ .dokuwiki #toc__inside ul ul { padding-left: 1em; } +[dir=rtl] .dokuwiki #toc__inside ul ul { + padding-left: 0; + padding-right: 1em; +} .dokuwiki #toc__inside ul ul li { } .dokuwiki #toc__inside ul li a { @@ -66,6 +78,9 @@ .dokuwiki ul.idx { padding-left: 0; } +[dir=rtl] .dokuwiki ul.idx { + padding-right: 0; +} .dokuwiki ul.idx li { list-style-image: url(images/bullet.png); } @@ -75,3 +90,6 @@ .dokuwiki ul.idx li.closed { list-style-image: url(images/closed.png); } +[dir=rtl] .dokuwiki ul.idx li.closed { + list-style-image: url(images/closed-rtl.png); +} diff --git a/lib/tpl/dokuwiki/css/basic.css b/lib/tpl/dokuwiki/css/basic.css index 9c69a1196..e7590dbb7 100644 --- a/lib/tpl/dokuwiki/css/basic.css +++ b/lib/tpl/dokuwiki/css/basic.css @@ -370,3 +370,38 @@ button[readonly] { cursor: auto; } +/*____________ rtl corrections ____________*/ + +[dir=rtl] caption, +[dir=rtl] td, +[dir=rtl] th { + text-align: right; +} + +[dir=rtl] ul, +[dir=rtl] ol { + padding: 0 1.5em 0 0; +} +[dir=rtl] li, +[dir=rtl] dd { + margin: 0 1.5em 0 0; +} +[dir=rtl] blockquote { + border-width: 0 .25em 0 0; +} + +[dir=rtl] h1, +[dir=rtl] h2, +[dir=rtl] h3, +[dir=rtl] h4, +[dir=rtl] h5, +[dir=rtl] h6, +[dir=rtl] caption, +[dir=rtl] legend { + clear: right; +} + +[dir=rtl] .a11y { + left: auto; + right: -9000px; +} diff --git a/lib/tpl/dokuwiki/css/content.css b/lib/tpl/dokuwiki/css/content.css index 7cb7c6edf..ebeb4e17e 100644 --- a/lib/tpl/dokuwiki/css/content.css +++ b/lib/tpl/dokuwiki/css/content.css @@ -19,6 +19,17 @@ .dokuwiki.page div.level3 {margin-left: 2em;} .dokuwiki.page div.level4 {margin-left: 3em;} .dokuwiki.page div.level5 {margin-left: 4em;} + +[dir=rtl] .dokuwiki .page h1 {margin-left: 0; margin-right: 0;} +[dir=rtl] .dokuwiki .page h2 {margin-left: 0; margin-right: .666em;} +[dir=rtl] .dokuwiki .page h3 {margin-left: 0; margin-right: 1.776em;} +[dir=rtl] .dokuwiki .page h4 {margin-left: 0; margin-right: 3em;} +[dir=rtl] .dokuwiki .page h5 {margin-left: 0; margin-right: 4.5712em;} +[dir=rtl] .dokuwiki .page div.level1 {margin-left: 0; margin-right: 0;} +[dir=rtl] .dokuwiki .page div.level2 {margin-left: 0; margin-right: 1em;} +[dir=rtl] .dokuwiki .page div.level3 {margin-left: 0; margin-right: 2em;} +[dir=rtl] .dokuwiki .page div.level4 {margin-left: 0; margin-right: 3em;} +[dir=rtl] .dokuwiki .page div.level5 {margin-left: 0; margin-right: 4em;} */ /* hx margin-left = (1 / font-size) * .levelx-margin */ @@ -133,6 +144,11 @@ margin-bottom: -1px; float: left; } +[dir=rtl] .dokuwiki dl.code dt, +[dir=rtl] .dokuwiki dl.file dt { + margin-left: 0; + margin-right: 1em; +} .dokuwiki dl.code dt a, .dokuwiki dl.file dt a { background-color: transparent; diff --git a/lib/tpl/dokuwiki/css/design.css b/lib/tpl/dokuwiki/css/design.css index 8617c6c48..f73985ed7 100644 --- a/lib/tpl/dokuwiki/css/design.css +++ b/lib/tpl/dokuwiki/css/design.css @@ -23,6 +23,11 @@ float: left; margin-right: .5em; } +[dir=rtl] #dokuwiki__header h1 img { + float: right; + margin-left: .5em; + margin-right: 0; +} #dokuwiki__header h1 span { display: block; padding-top: 10px; @@ -78,6 +83,10 @@ list-style: none; display: inline; } +[dir=rtl] #dokuwiki__header .tools li { + margin-right: 1em; + margin-left: 0; +} #dokuwiki__header .tools form.search div.ajax_qsearch li { font-size: 1em; margin-left: 0; @@ -99,6 +108,11 @@ text-align: right; width: 100%; } +[dir=rtl] #dokuwiki__usertools { + text-align: left; + left: 40px; + right: auto; +} #dokuwiki__usertools ul { margin: 0 auto; padding: 0; @@ -113,6 +127,9 @@ #dokuwiki__sitetools { text-align: right; } +[dir=rtl] #dokuwiki__sitetools { + text-align: left; +} #dokuwiki__sitetools form.search { display: block; @@ -123,6 +140,9 @@ width: 18em; padding: .35em 22px .35em .1em; } +[dir=rtl] #dokuwiki__sitetools form.search input.edit { + padding: .35em .1em .35em 22px; +} #dokuwiki__sitetools form.search input.button { background: transparent url(images/search.png) no-repeat 0 0; border-width: 0; @@ -133,6 +153,11 @@ box-shadow: none; padding: 0; } +[dir=rtl] #dokuwiki__sitetools form.search input.button { + background-position: 5px 0; + margin-left: 0; + margin-right: -20px; +} #dokuwiki__sitetools ul { margin-top: 0.5em; @@ -223,6 +248,10 @@ #dokuwiki__aside ol { padding-left: 0; } +[dir=rtl] #dokuwiki__aside ul, +[dir=rtl] #dokuwiki__aside ol { + padding-right: 0; +} #dokuwiki__aside li ul, #dokuwiki__aside li ol { margin-bottom: 0; @@ -248,6 +277,10 @@ overflow: hidden; padding: 1em 1em 0; } +[dir=rtl] .dokuwiki .pageId { + right: auto; + left: -1em; +} .dokuwiki .pageId span { font-size: 0.875em; border: solid __background_alt__; @@ -277,6 +310,9 @@ font-size: 0.875em; text-align: right; } +[dir=rtl] .dokuwiki .docInfo { + text-align: left; +} /*____________ misc ____________*/ @@ -314,16 +350,35 @@ border-bottom-left-radius: 4px; border-left-width: 1px; } +[dir=rtl] .dokuwiki div.toolbar button.toolbutton:first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + border-left-width: 0; + border-right-width: 1px; +} .dokuwiki div.toolbar button.toolbutton:last-child { border-top-right-radius: 4px; border-bottom-right-radius: 4px; } +[dir=rtl] .dokuwiki div.toolbar button.toolbutton:last-child { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-left-width: 1px; +} .dokuwiki div.section_highlight { margin: -3em -2em -.01em -2em; padding: 3em 1em .01em 1em; border-width: 0 1em; } +[dir=rtl] .dokuwiki div.section_highlight { + margin-right: -2em; + border-right-width: 1em; +} .dokuwiki textarea.edit { font-family: Consolas, "Andale Mono WT", "Andale Mono", "Bitstream Vera Sans Mono", "Liberation Mono", Monaco, "Courier New", monospace; @@ -344,6 +399,11 @@ background: __background__; color: inherit; } +[dir=rtl] .dokuwiki div.toc { + margin: -2em 1.4em .5em -2em; + border-left-width: 0; + border-right: 1px solid __border__; +} .dokuwiki div.tocheader { padding: .5em 1em; @@ -376,6 +436,9 @@ .dokuwiki #toc__inside ul { padding: 0 0 0 1.2em; } +[dir=rtl] .dokuwiki #toc__inside ul { + padding: 0 1.5em 0 0; +} .dokuwiki #toc__inside ul li { list-style-image: url(images/toc-bullet.png); } @@ -409,9 +472,18 @@ text-align: right; clear: left; } +[dir=rtl] #dokuwiki__detail div.img_detail dl dt { + float: right; + text-align: left; + clear: right; +} #dokuwiki__detail div.img_detail dl dd { margin-left: 9.5em; } +[dir=rtl] #dokuwiki__detail div.img_detail dl dd { + margin-left: 0; + margin-right: 9.5em; +} /*____________ JS popup ____________*/ @@ -435,6 +507,10 @@ .JSpopup ol { padding-left: 0; } +[dir=rtl] .JSpopup ul, +[dir=rtl] .JSpopup ol { + padding-right: 0; +} /* footer @@ -457,6 +533,10 @@ font-size: 100%; } +[dir=rtl] #dokuwiki__footer .license img { + margin: 0 0 0 .5em; +} + #dokuwiki__footer div.buttons a img { opacity: 0.5; } diff --git a/lib/tpl/dokuwiki/css/pagetools.css b/lib/tpl/dokuwiki/css/pagetools.css index e301b084d..f691d82a7 100644 --- a/lib/tpl/dokuwiki/css/pagetools.css +++ b/lib/tpl/dokuwiki/css/pagetools.css @@ -20,6 +20,10 @@ /* move the tools just outside of the site */ right: 40px; } +[dir=rtl] #dokuwiki__usertools { + right: auto; + left: 40px; +} #dokuwiki__pagetools { @@ -28,6 +32,10 @@ /* on same vertical level as first headline, because .page has 2em padding */ top: 2em; } +[dir=rtl] #dokuwiki__pagetools { + right: auto; + left: -40px; +} #dokuwiki__pagetools div.tools { position: fixed; @@ -42,6 +50,11 @@ /* add transparent border to prevent jumping when proper border is added on hover */ border: 1px solid transparent; } +[dir=rtl] #dokuwiki__pagetools ul { + right: auto; + left: 0; + text-align: left; +} #dokuwiki__pagetools ul li { padding: 0; @@ -62,6 +75,10 @@ border: 1px solid transparent; white-space: nowrap; } +[dir=rtl] #dokuwiki__pagetools ul li a { + padding: 5px 5px 5px 40px; + background-position: left 0; +} /* hide labels accessibly when neither on hover nor on focus */ #dokuwiki__pagetools ul li a span { @@ -77,6 +94,10 @@ border-radius: 2px; box-shadow: 2px 2px 2px __text_alt__; } +[dir=rtl] #dokuwiki__pagetools:hover ul, +[dir=rtl] #dokuwiki__pagetools ul li a:focus { + box-shadow: -2px 2px 2px __text_alt__; +} #dokuwiki__pagetools:hover ul li a span, #dokuwiki__pagetools ul li a:focus span { @@ -103,6 +124,14 @@ #dokuwiki__pagetools ul li a.edit:focus { background-position: right -45px; } +[dir=rtl] #dokuwiki__pagetools ul li a.edit { + background-position: left 0; +} +[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 -45px; +} #dokuwiki__pagetools ul li a.create { background-position: right -90px; @@ -112,6 +141,14 @@ #dokuwiki__pagetools ul li a.create:focus { background-position: right -135px; } +[dir=rtl] #dokuwiki__pagetools ul li a.create { + background-position: left -90px; +} +[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 -135px; +} #dokuwiki__pagetools ul li a.show { background-position: right -270px; @@ -121,6 +158,14 @@ #dokuwiki__pagetools ul li a.show:focus { background-position: right -315px; } +[dir=rtl] #dokuwiki__pagetools ul li a.show { + background-position: left -270px; +} +[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 -315px; +} #dokuwiki__pagetools ul li a.source { background-position: right -360px; @@ -130,6 +175,14 @@ #dokuwiki__pagetools ul li a.source:focus { background-position: right -405px; } +[dir=rtl] #dokuwiki__pagetools ul li a.source { + background-position: left -360px; +} +[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 -405px; +} #dokuwiki__pagetools ul li a.draft { background-position: right -180px; @@ -139,6 +192,14 @@ #dokuwiki__pagetools ul li a.draft:focus { background-position: right -225px; } +[dir=rtl] #dokuwiki__pagetools ul li a.draft { + background-position: left -180px; +} +[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 -225px; +} #dokuwiki__pagetools ul li a.revs { background-position: right -540px; @@ -149,6 +210,15 @@ .mode_revisions #dokuwiki__pagetools ul li a.revs { background-position: right -585px; } +[dir=rtl] #dokuwiki__pagetools ul li a.revs { + background-position: left -540px; +} +[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, +.mode_revisions [dir=rtl] #dokuwiki__pagetools ul li a.revs { + background-position: left -585px; +} #dokuwiki__pagetools ul li a.backlink { background-position: right -630px; @@ -159,6 +229,15 @@ .mode_backlink #dokuwiki__pagetools ul li a.backlink { background-position: right -675px; } +[dir=rtl] #dokuwiki__pagetools ul li a.backlink { + background-position: left -630px; +} +[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, +.mode_backlink [dir=rtl] #dokuwiki__pagetools ul li a.backlink { + background-position: left -675px; +} #dokuwiki__pagetools ul li a.top { background-position: right -810px; @@ -168,6 +247,14 @@ #dokuwiki__pagetools ul li a.top:focus { background-position: right -855px; } +[dir=rtl] #dokuwiki__pagetools ul li a.top { + background-position: left -810px; +} +[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 -855px; +} #dokuwiki__pagetools ul li a.revert { background-position: right -450px; @@ -178,6 +265,15 @@ .mode_revert #dokuwiki__pagetools ul li a.revert { background-position: right -495px; } +[dir=rtl] #dokuwiki__pagetools ul li a.revert { + background-position: left -450px; +} +[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, +.mode_revert [dir=rtl] #dokuwiki__pagetools ul li a.revert { + background-position: left -495px; +} #dokuwiki__pagetools ul li a.subscribe { background-position: right -720px; @@ -188,6 +284,15 @@ .mode_subscribe #dokuwiki__pagetools ul li a.subscribe { background-position: right -765px; } +[dir=rtl] #dokuwiki__pagetools ul li a.subscribe { + background-position: left -720px; +} +[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, +.mode_subscribe [dir=rtl] #dokuwiki__pagetools ul li a.subscribe { + background-position: left -765px; +} #dokuwiki__pagetools ul li a.mediaManager { background-position: right -900px; @@ -197,6 +302,14 @@ #dokuwiki__pagetools ul li a.mediaManager:focus { background-position: right -945px; } +[dir=rtl] #dokuwiki__pagetools ul li a.mediaManager { + background-position: left -900px; +} +[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 -945px; +} #dokuwiki__pagetools ul li a.back { background-position: right -990px; @@ -206,3 +319,11 @@ #dokuwiki__pagetools ul li a.back:focus { background-position: right -1035px; } +[dir=rtl] #dokuwiki__pagetools ul li a.back { + background-position: left -990px; +} +[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 -1035px; +} diff --git a/lib/tpl/dokuwiki/css/rtl.css b/lib/tpl/dokuwiki/css/rtl.css deleted file mode 100644 index 2a8336b7f..000000000 --- a/lib/tpl/dokuwiki/css/rtl.css +++ /dev/null @@ -1,531 +0,0 @@ -/** - * This file provides layout and design corrections for right-to-left - * languages. - * - * @author Anika Henke - */ - -/*____________ basic ____________*/ - -[dir=rtl] caption, -[dir=rtl] td, -[dir=rtl] th { - text-align: right; -} - -[dir=rtl] ul, -[dir=rtl] ol { - padding: 0 1.5em 0 0; -} -[dir=rtl] li, -[dir=rtl] dd { - margin: 0 1.5em 0 0; -} -[dir=rtl] blockquote { - border-width: 0 .25em 0 0; -} - -[dir=rtl] h1, -[dir=rtl] h2, -[dir=rtl] h3, -[dir=rtl] h4, -[dir=rtl] h5, -[dir=rtl] h6, -[dir=rtl] caption, -[dir=rtl] legend { - clear: right; -} - -[dir=rtl] .a11y { - left: auto; - right: -9000px; -} - - -/*____________ _imgdetail ____________*/ - -[dir=rtl] #dokuwiki__detail div.content img { - float: right; - margin-right: 0; - margin-left: 1.5em; -} -[dir=rtl] #dokuwiki__detail div.content div.img_detail { - float: right -} - - -/*____________ _mediamanager ____________*/ - -[dir=rtl] #mediamgr__aside { - left: auto; - right: 0; - border-right-width: 0; - border-left: 1px solid __border__; -} -[dir=rtl] #mediamgr__content { - right: auto; - left: 0; -} - -[dir=rtl] #media__opts input { - margin-right: 0; - margin-left: .3em; -} - -[dir=rtl] #media__tree ul { - padding-left: 0; - padding-right: .2em; -} -[dir=rtl] #media__tree ul li { - clear: right; - margin-right: 0; -} -[dir=rtl] #media__tree ul li img { - float: right; - padding: .5em 0 0 .3em; -} -[dir=rtl] #media__tree ul li li { - margin-left: 0; - margin-right: 1.5em; -} - -[dir=rtl] #media__content a.mediafile { - margin-right: 0; - margin-left: 1.5em; -} -[dir=rtl] #media__content div.detail div.thumb { - float: right; - margin: 0 18px 0 .5em; -} -[dir=rtl] #media__content form.meta div.metafield { - clear: right; -} -[dir=rtl] #media__content form.meta label { - float: right; - clear: right; -} -[dir=rtl] #media__content form.meta .edit { - float: right; -} -[dir=rtl] #media__content form.meta div.buttons { - clear: right; - margin: .2em 25% 0 0; -} - - -/*____________ _links ____________*/ - -/* if link icons don't work as expected, remove the following lines */ -[dir=rtl] .dokuwiki a.urlextern, -[dir=rtl] .dokuwiki a.windows, -[dir=rtl] .dokuwiki a.mail, -[dir=rtl] .dokuwiki a.interwiki, -[dir=rtl] .dokuwiki a.mediafile { - background-position: right center; - padding: 0 17px 0 0; -} - - -/*____________ _toc ____________*/ - -[dir=rtl] .dokuwiki div.toc { - float: left; - margin: 0 1.4em 1.4em 0; -} -[dir=rtl] .dokuwiki .toc span.toc_open, -[dir=rtl] .dokuwiki .toc span.toc_close { - float: left; -} -[dir=rtl] .dokuwiki #toc__inside ul ul { - padding-left: 0; - padding-right: 1em; -} - -[dir=rtl] .dokuwiki ul.idx { - padding-right: 0; -} -[dir=rtl] .dokuwiki ul.idx li.closed { - list-style-image: url(images/closed-rtl.png); -} - - -/*____________ _footnotes ____________*/ - - -/*____________ _search ____________*/ - -[dir=rtl] .dokuwiki div.search_quickresult ul li { - float: right; -} -[dir=rtl] .dokuwiki form.search div.ajax_qsearch { - left: auto; - right: -13.5em; - text-align: right; -} - - -/*____________ _recent ____________*/ - -[dir=rtl] .dokuwiki form.changes ul li { - margin-right: 0; -} - - -/*____________ _diff ____________*/ - - -/*____________ _edit ____________*/ - -[dir=rtl] #draft__status { - float: left; -} -[dir=rtl] #size__ctl { - float: left; -} -[dir=rtl] #size__ctl img { - cursor: pointer; -} -[dir=rtl] .dokuwiki .editBar .editButtons { - margin-right: 0; - margin-left: 1em; -} - -[dir=rtl] .dokuwiki .secedit { - float: left; -} - - -/*____________ _modal ____________*/ - -[dir=rtl] #link__wiz_close { - float: left; -} -[dir=rtl] #link__wiz_result { - text-align: right; -} -[dir=rtl] #link__wiz_result div.type_u, -[dir=rtl] #link__wiz_result div.type_f, -[dir=rtl] #link__wiz_result div.type_d { - padding: 3px 22px 3px 3px; - background-position: 257px 3px; -} - - -/*____________ _forms ____________*/ - -[dir=rtl] .dokuwiki label.block { - text-align: left; -} -[dir=rtl] .dokuwiki label.simple { - text-align: right; -} - -[dir=rtl] form#subscribe__form fieldset { - text-align: right; -} - - -/*____________ _admin ____________*/ - -[dir=rtl] .dokuwiki ul.admin_tasks { - float: right; -} -[dir=rtl] .dokuwiki ul.admin_tasks li { - padding-left: 0; - padding-right: 35px; - background-position: right 0; -} - -[dir=rtl] .dokuwiki #admin__version { - clear: right; - float: left; -} - - -/*____________ includes ____________*/ - - -/*____________ structure ____________*/ - -[dir=rtl] #dokuwiki__header .headings { - float: right; - text-align: right; -} -[dir=rtl] #dokuwiki__header .tools { - float: left; - text-align: left; -} -[dir=rtl] #dokuwiki__header .tools li { - margin-right: 1em; - margin-left: 0; -} - -[dir=rtl] #dokuwiki__aside { - float: right; -} -[dir=rtl] #dokuwiki__aside > .pad { - margin: 0 0 0 1.5em; -} - -[dir=rtl] .hasSidebar #dokuwiki__content { - float: left; - margin-left: 0; - margin-right: -__sidebar_width__; -} -[dir=rtl] .hasSidebar #dokuwiki__content > .pad { - margin-left: 0; - margin-right: __sidebar_width__; -} - -/*____________ design ____________*/ - -[dir=rtl] #dokuwiki__header h1 img { - float: right; - margin-left: .5em; - margin-right: 0; -} - -[dir=rtl] #dokuwiki__sitetools form.search input.edit { - padding: .35em .1em .35em 22px; -} -[dir=rtl] #dokuwiki__sitetools form.search input.button { - background-position: 5px 0; - margin-left: 0; - margin-right: -20px; -} - -[dir=rtl] #dokuwiki__usertools { - text-align: left; - left: 40px; - right: auto; -} - -[dir=rtl] #dokuwiki__sitetools { - text-align: left; -} - -[dir=rtl] #dokuwiki__aside ul, #dokuwiki__aside ol { - padding-right: 0; -} - -[dir=rtl] .dokuwiki .pageId { - right: auto; - left: -1em; -} - -[dir=rtl] .dokuwiki .docInfo { - text-align: left; -} - -[dir=rtl] .dokuwiki div.toolbar button.toolbutton:first-child { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; - border-left-width: 0; - border-right-width: 1px; -} -[dir=rtl] .dokuwiki div.toolbar button.toolbutton:last-child { - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; - border-top-right-radius: 0; - border-bottom-right-radius: 0; - border-left-width: 1px; -} - -[dir=rtl] .dokuwiki div.section_highlight { - margin-right: -2em; - border-right-width: 1em; -} - -[dir=rtl] #dokuwiki__footer .license img { - margin: 0 0 0 .5em; -} - -[dir=rtl] .dokuwiki div.toc { - margin: -2em 1.4em .5em -2em; - border-left-width: 0; - border-right: 1px solid __border__; -} -[dir=rtl] .dokuwiki #toc__inside ul { - padding: 0 1.5em 0 0; -} - -[dir=rtl] #dokuwiki__detail div.img_detail dl dt { - float: right; - text-align: left; - clear: right; -} -[dir=rtl] #dokuwiki__detail div.img_detail dl dd { - margin-left: 0; - margin-right: 9.5em; -} - - -/*____________ pagetools ____________*/ - -[dir=rtl] #dokuwiki__usertools { - right: auto; - left: 40px; -} - -[dir=rtl] #dokuwiki__pagetools { - right: auto; - left: -40px; -} - -[dir=rtl] #dokuwiki__pagetools ul { - right: auto; - left: 0; - text-align: left; -} - -[dir=rtl] #dokuwiki__pagetools ul li a { - padding: 5px 5px 5px 40px; - background-position: left 0; -} - -[dir=rtl] #dokuwiki__pagetools:hover ul, -[dir=rtl] #dokuwiki__pagetools ul li a:focus { - box-shadow: -2px 2px 2px __text_alt__; -} - -/* all available icons in sprite */ -[dir=rtl] #dokuwiki__pagetools ul li a.edit { - background-position: left 0; -} -[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 -45px; -} - -[dir=rtl] #dokuwiki__pagetools ul li a.create { - background-position: left -90px; -} -[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 -135px; -} - -[dir=rtl] #dokuwiki__pagetools ul li a.show { - background-position: left -270px; -} -[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 -315px; -} - -[dir=rtl] #dokuwiki__pagetools ul li a.source { - background-position: left -360px; -} -[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 -405px; -} - -[dir=rtl] #dokuwiki__pagetools ul li a.draft { - background-position: left -180px; -} -[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 -225px; -} - -[dir=rtl] #dokuwiki__pagetools ul li a.revs { - background-position: left -540px; -} -[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, -.mode_revisions [dir=rtl] #dokuwiki__pagetools ul li a.revs { - background-position: left -585px; -} - -[dir=rtl] #dokuwiki__pagetools ul li a.backlink { - background-position: left -630px; -} -[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, -.mode_backlink [dir=rtl] #dokuwiki__pagetools ul li a.backlink { - background-position: left -675px; -} - -[dir=rtl] #dokuwiki__pagetools ul li a.top { - background-position: left -810px; -} -[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 -855px; -} - -[dir=rtl] #dokuwiki__pagetools ul li a.revert { - background-position: left -450px; -} -[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, -.mode_revert [dir=rtl] #dokuwiki__pagetools ul li a.revert { - background-position: left -495px; -} - -[dir=rtl] #dokuwiki__pagetools ul li a.subscribe { - background-position: left -720px; -} -[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, -.mode_subscribe [dir=rtl] #dokuwiki__pagetools ul li a.subscribe { - background-position: left -765px; -} - -[dir=rtl] #dokuwiki__pagetools ul li a.mediaManager { - background-position: left -900px; -} -[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 -945px; -} - -[dir=rtl] #dokuwiki__pagetools ul li a.back { - background-position: left -990px; -} -[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 -1035px; -} - - -/*____________ content ____________*/ - -/* section indenting -[dir=rtl] .dokuwiki .page h1 {margin-left: 0; margin-right: 0;} -[dir=rtl] .dokuwiki .page h2 {margin-left: 0; margin-right: .666em;} -[dir=rtl] .dokuwiki .page h3 {margin-left: 0; margin-right: 1.776em;} -[dir=rtl] .dokuwiki .page h4 {margin-left: 0; margin-right: 3em;} -[dir=rtl] .dokuwiki .page h5 {margin-left: 0; margin-right: 4.5712em;} -[dir=rtl] .dokuwiki .page div.level1 {margin-left: 0; margin-right: 0;} -[dir=rtl] .dokuwiki .page div.level2 {margin-left: 0; margin-right: 1em;} -[dir=rtl] .dokuwiki .page div.level3 {margin-left: 0; margin-right: 2em;} -[dir=rtl] .dokuwiki .page div.level4 {margin-left: 0; margin-right: 3em;} -[dir=rtl] .dokuwiki .page div.level5 {margin-left: 0; margin-right: 4em;} -*/ - -[dir=rtl] .dokuwiki dl.code dt, -[dir=rtl] .dokuwiki dl.file dt { - margin-left: 0; - margin-right: 1em; -} - -[dir=rtl] .JSpopup ul, -[dir=rtl] .JSpopup ol { - padding-right: 0; -} diff --git a/lib/tpl/dokuwiki/css/structure.css b/lib/tpl/dokuwiki/css/structure.css index 9cca1aa3b..5e2eab3bc 100644 --- a/lib/tpl/dokuwiki/css/structure.css +++ b/lib/tpl/dokuwiki/css/structure.css @@ -23,10 +23,18 @@ body { #dokuwiki__header .headings { float: left; } + [dir=rtl] #dokuwiki__header .headings { + float: right; + text-align: right; + } #dokuwiki__header .tools { float: right; text-align: right; } + [dir=rtl] #dokuwiki__header .tools { + float: left; + text-align: left; + } #dokuwiki__site .wrapper { position: relative; @@ -38,18 +46,33 @@ body { position: relative; display: block; } + [dir=rtl] #dokuwiki__aside { + float: right; + } #dokuwiki__aside > .pad { margin: 0 1.5em 0 0; } + [dir=rtl] #dokuwiki__aside > .pad { + margin: 0 0 0 1.5em; + } .hasSidebar #dokuwiki__content { float: right; margin-left: -__sidebar_width__; width: 100%; } + [dir=rtl] .hasSidebar #dokuwiki__content { + float: left; + margin-left: 0; + margin-right: -__sidebar_width__; + } .hasSidebar #dokuwiki__content > .pad { margin-left: __sidebar_width__; } + [dir=rtl] .hasSidebar #dokuwiki__content > .pad { + margin-left: 0; + margin-right: __sidebar_width__; + } #dokuwiki__footer { clear: both; diff --git a/lib/tpl/dokuwiki/style.ini b/lib/tpl/dokuwiki/style.ini index b52d7e652..08d1a4273 100644 --- a/lib/tpl/dokuwiki/style.ini +++ b/lib/tpl/dokuwiki/style.ini @@ -29,7 +29,6 @@ css/design.css = screen css/pagetools.css = screen css/content.css = screen css/includes.css = screen -css/rtl.css = screen css/mobile.css = all css/print.css = print -- cgit v1.2.3 From d5acc30de20298eb6ed7545e70484599c4d95867 Mon Sep 17 00:00:00 2001 From: Anika Henke Date: Mon, 9 Apr 2012 17:36:33 +0100 Subject: rewrote and improved HTML for TOC Attention: Template authors need to adjust their CSS! Original structure: div.toc > div#toc__header.tocheader.toctoggle > span#toc__toggle.toc_close|toc_open > span div#toc__inside > ul.toc > li.level1 > div.li > span.li > a.toc New structure: div#dw__toc.open|close > h3 > strong > span ul.toc > li.toc > div.li > a --- inc/html.php | 11 +++++------ lib/scripts/page.js | 16 ++++++++-------- lib/tpl/default/design.css | 33 ++++++++++++++++----------------- lib/tpl/default/print.css | 2 +- lib/tpl/default/rtl.css | 18 ++++++++++++------ lib/tpl/dokuwiki/css/_toc.css | 30 ++++++++++++++---------------- lib/tpl/dokuwiki/css/design.css | 26 ++++++++++++-------------- lib/tpl/dokuwiki/css/print.css | 2 +- 8 files changed, 69 insertions(+), 69 deletions(-) diff --git a/inc/html.php b/inc/html.php index f3f042ea1..787f96caa 100644 --- a/inc/html.php +++ b/inc/html.php @@ -1712,11 +1712,11 @@ function html_TOC($toc){ if(!count($toc)) return ''; global $lang; $out = ''.DOKU_LF; - $out .= '
'.DOKU_LF; - $out .= '
'; + $out .= '
'.DOKU_LF; + $out .= '

'; $out .= $lang['toc']; - $out .= '

'.DOKU_LF; - $out .= '
'.DOKU_LF; + $out .= ''.DOKU_LF; + $out .= '
'.DOKU_LF; $out .= html_buildlist($toc,'toc','html_list_toc','html_li_default',true); $out .= '
'.DOKU_LF.'
'.DOKU_LF; $out .= ''.DOKU_LF; @@ -1733,8 +1733,7 @@ function html_list_toc($item){ $link = $item['link']; } - return ''. - hsc($item['title']).''; + return ''.hsc($item['title']).''; } /** diff --git a/lib/scripts/page.js b/lib/scripts/page.js index 5da4a9cc0..6e7d7faf7 100644 --- a/lib/scripts/page.js +++ b/lib/scripts/page.js @@ -96,26 +96,26 @@ dw_page = { * Adds the toggle switch to the TOC */ initTocToggle: function() { - var $header, $clicky, $toc, $tocul, setClicky; - $header = jQuery('#toc__header'); + var $wrapper, $header, $clicky, $toc, $tocul, setClicky; + $wrapper = jQuery('#dw__toc'); + $header = jQuery('h3', $wrapper); if(!$header.length) { return; } - $toc = jQuery('#toc__inside'); - $tocul = $toc.children('ul.toc'); + $toc = jQuery('div', $wrapper).first(); + $tocul = jQuery('ul', $toc); setClicky = function(hiding){ if(hiding){ $clicky.html('+'); - $clicky[0].className = 'toc_open'; + $wrapper.addClass('close').removeClass('open'); }else{ $clicky.html(''); - $clicky[0].className = 'toc_close'; + $wrapper.addClass('open').removeClass('close'); } }; - $clicky = jQuery(document.createElement('span')) - .attr('id','toc__toggle'); + $clicky = jQuery(document.createElement('strong')); $header.css('cursor','pointer') .click(function () { var hidden; diff --git a/lib/tpl/default/design.css b/lib/tpl/default/design.css index 9d2cc1844..48438527e 100644 --- a/lib/tpl/default/design.css +++ b/lib/tpl/default/design.css @@ -547,7 +547,7 @@ div.dokuwiki table.inline td { /* ---------- table of contents ------------------- */ -div.dokuwiki div.toc { +div.dokuwiki #dw__toc { margin: 1.2em 0 0 2em; float: right; width: 200px; @@ -555,46 +555,45 @@ div.dokuwiki div.toc { clear: both; } -div.dokuwiki div.tocheader { +div.dokuwiki #dw__toc h3 { border: 1px solid __border__; background-color: __background_alt__; text-align: left; font-weight: bold; padding: 3px; - margin-bottom: 2px; + margin: 0 0 2px 0; + font-size: 1em; } -div.dokuwiki span.toc_open, -div.dokuwiki span.toc_close { +div.dokuwiki #dw__toc h3 strong { border: 0.4em solid __background_alt__; float: right; display: block; margin: 0.4em 3px 0 0; } -div.dokuwiki span.toc_open span, -div.dokuwiki span.toc_close span { +div.dokuwiki #dw__toc h3 strong span { display: none; } -div.dokuwiki span.toc_open { +div.dokuwiki #dw__toc.close h3 strong { margin-top: 0.4em; border-top: 0.4em solid __text__; } -div.dokuwiki span.toc_close { +div.dokuwiki #dw__toc.open h3 strong { margin-top: 0; border-bottom: 0.4em solid __text__; } -div.dokuwiki #toc__inside { +div.dokuwiki #dw__toc > div { border: 1px solid __border__; background-color: __background__; text-align: left; padding: 0.5em 0 0.7em 0; } -div.dokuwiki ul.toc { +div.dokuwiki #dw__toc ul { list-style-type: none; list-style-image: none; line-height: 1.2em; @@ -602,23 +601,23 @@ div.dokuwiki ul.toc { margin: 0; } -div.dokuwiki ul.toc li { +div.dokuwiki #dw__toc ul li { background: transparent url(images/tocdot2.gif) 0 0.6em no-repeat; padding-left: 0.4em; } -div.dokuwiki ul.toc li.clear { +div.dokuwiki #dw__toc ul li.clear { background-image: none; padding-left: 0.4em; } -div.dokuwiki a.toc:link, -div.dokuwiki a.toc:visited { +div.dokuwiki #dw__toc a:link, +div.dokuwiki #dw__toc a:visited { color: __extern__; } -div.dokuwiki a.toc:hover, -div.dokuwiki a.toc:active { +div.dokuwiki #dw__toc a:hover, +div.dokuwiki #dw__toc a:active { color: __text__; } diff --git a/lib/tpl/default/print.css b/lib/tpl/default/print.css index 4387dc4bf..f83e8c97c 100644 --- a/lib/tpl/default/print.css +++ b/lib/tpl/default/print.css @@ -224,5 +224,5 @@ table.inline td { border: 1px solid #000000; } -.toc, .footerinc, .header, .bar, .user { display: none; } +#dw__toc, .footerinc, .header, .bar, .user { display: none; } diff --git a/lib/tpl/default/rtl.css b/lib/tpl/default/rtl.css index 82c85839b..32a8ddb6d 100644 --- a/lib/tpl/default/rtl.css +++ b/lib/tpl/default/rtl.css @@ -89,30 +89,36 @@ div.dokuwiki div.level4 { margin-left: 0px; margin-right: 63px; } div.dokuwiki div.level5 { margin-left: 0px; margin-right: 83px; } /* TOC control */ -div.dokuwiki div.toc { +div.dokuwiki #dw__toc { float: left; + margin: 1.2em 2em 0 0; } -div.dokuwiki div.tocheader { +div.dokuwiki #dw__toc h3 { text-align: right; } -div.dokuwiki #toc__inside { +div.dokuwiki #dw__toc h3 strong { + float: left; + margin: 0.4em 0 0 3px; +} + +div.dokuwiki #dw__toc > div { text-align: right; } -div.dokuwiki ul.toc { +div.dokuwiki #dw__toc ul { padding: 0; padding-right: 1em; } -div.dokuwiki ul.toc li { +div.dokuwiki #dw__toc ul li { background-position: right 0.6em; padding-right: 0.4em; direction: rtl; } -div.dokuwiki ul.toc li.clear { +div.dokuwiki #dw__toc ul li.clear { padding-right: 0.4em; } diff --git a/lib/tpl/dokuwiki/css/_toc.css b/lib/tpl/dokuwiki/css/_toc.css index f89bce6c1..e62bb0a7a 100644 --- a/lib/tpl/dokuwiki/css/_toc.css +++ b/lib/tpl/dokuwiki/css/_toc.css @@ -7,68 +7,66 @@ ********************************************************************/ /* toc container */ -.dokuwiki div.toc { +#dw__toc { float: right; margin: 0 0 1.4em 1.4em; width: 12em; background-color: __background_alt__; color: inherit; } -[dir=rtl] .dokuwiki div.toc { +[dir=rtl] #dw__toc { float: left; margin: 0 1.4em 1.4em 0; } /*____________ toc header ____________*/ -.dokuwiki div.tocheader { +#dw__toc h3 { padding: .2em .5em; font-weight: bold; } -.dokuwiki .toc span.toc_open, -.dokuwiki .toc span.toc_close { +#dw__toc h3 strong { float: right; margin: 0 .2em; } -[dir=rtl] .dokuwiki .toc span.toc_open, -[dir=rtl] .dokuwiki .toc span.toc_close { +[dir=rtl] #dw__toc h3 strong { float: left; } /*____________ toc list ____________*/ -.dokuwiki #toc__inside { +#dw__toc > div { padding: .2em .5em; } -.dokuwiki #toc__inside ul { +#dw__toc ul { padding: 0; margin: 0; } -.dokuwiki #toc__inside ul li { +#dw__toc ul li { list-style: none; padding: 0; margin: 0; line-height: 1.1; } -.dokuwiki #toc__inside ul li div.li { +#dw__toc ul li div.li { padding: .15em 0; } -.dokuwiki #toc__inside ul ul { +#dw__toc ul ul { padding-left: 1em; } -[dir=rtl] .dokuwiki #toc__inside ul ul { +[dir=rtl] #dw__toc ul ul { padding-left: 0; padding-right: 1em; } -.dokuwiki #toc__inside ul ul li { +#dw__toc ul ul li { } -.dokuwiki #toc__inside ul li a { +#dw__toc ul li a { } /* in case of toc list jumping one level (e.g. if heading level 3 follows directly after heading level 1) */ -.dokuwiki #toc__inside ul li.clear { +#dw__toc ul li.clear { } diff --git a/lib/tpl/dokuwiki/css/design.css b/lib/tpl/dokuwiki/css/design.css index f73985ed7..8ebeca6da 100644 --- a/lib/tpl/dokuwiki/css/design.css +++ b/lib/tpl/dokuwiki/css/design.css @@ -392,60 +392,58 @@ /*____________ changes to _toc ____________*/ -.dokuwiki div.toc { +#dw__toc { margin: -2em -2em .5em 1.4em; width: __sidebar_width__; border-left: 1px solid __border__; background: __background__; color: inherit; } -[dir=rtl] .dokuwiki div.toc { +[dir=rtl] #dw__toc { margin: -2em 1.4em .5em -2em; border-left-width: 0; border-right: 1px solid __border__; } -.dokuwiki div.tocheader { +#dw__toc h3 { padding: .5em 1em; margin-bottom: 0; font-size: .875em; letter-spacing: .1em; } -.dokuwiki .toc span.toc_open, -.dokuwiki .toc span.toc_close { +#dw__toc h3 strong { background: transparent url(images/toc-arrows.png) 0 0; width: 8px; height: 5px; margin: .4em 0 0; } -.dokuwiki .toc span.toc_open { +#dw__toc.close strong { background-position: 0 -5px; } -.dokuwiki .toc span.toc_open span, -.dokuwiki .toc span.toc_close span { +#dw__toc strong span { display: none; } -.dokuwiki #toc__inside { +#dw__toc > div { font-size: 0.875em; padding: .5em 1em 1em; } -.dokuwiki #toc__inside ul { +#dw__toc ul { padding: 0 0 0 1.2em; } -[dir=rtl] .dokuwiki #toc__inside ul { +[dir=rtl] #dw__toc ul { padding: 0 1.5em 0 0; } -.dokuwiki #toc__inside ul li { +#dw__toc ul li { list-style-image: url(images/toc-bullet.png); } -.dokuwiki #toc__inside ul li.clear { +#dw__toc ul li.clear { list-style: none; } -.dokuwiki #toc__inside ul li div.li { +#dw__toc ul li div.li { padding: .2em 0; } diff --git a/lib/tpl/dokuwiki/css/print.css b/lib/tpl/dokuwiki/css/print.css index f4f81d741..f6bf64dd9 100644 --- a/lib/tpl/dokuwiki/css/print.css +++ b/lib/tpl/dokuwiki/css/print.css @@ -21,7 +21,7 @@ div.error, #dokuwiki__header .tools, #dokuwiki__aside, .dokuwiki .breadcrumbs, -.dokuwiki .toc, +#dw__toc, .dokuwiki .secedit, #dokuwiki__pagetools, #dokuwiki__footer { -- cgit v1.2.3 From 91b05b6bf9cb9fd3aeced777159422f4e8114a9c Mon Sep 17 00:00:00 2001 From: Anika Henke Date: Mon, 9 Apr 2012 19:06:15 +0100 Subject: improved HTML for search results Attention: Template authors need to adjust their CSS! Original structure: div.search_result > a.wikilink1 > span.search_cnt br div.search_snippet New structure: dl.search_results > dt > a.wikilink1 dd --- inc/html.php | 16 ++++++++++------ lib/tpl/default/design.css | 14 +++++++++++--- lib/tpl/dokuwiki/css/_search.css | 20 ++++++++++++++------ 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/inc/html.php b/inc/html.php index 787f96caa..c3e345cb0 100644 --- a/inc/html.php +++ b/inc/html.php @@ -323,11 +323,11 @@ function html_search(){ flush(); //show progressbar - print '
'.NL; + print '
'.NL; print ''.NL; - print '
'.NL; + print '
'.NL; flush(); //do quick pagesearch @@ -363,20 +363,24 @@ function html_search(){ //do fulltext search $data = ft_pageSearch($QUERY,$regex); if(count($data)){ + print '
'; $num = 1; foreach($data as $id => $cnt){ - print '
'; + print '
'; print html_wikilink(':'.$id,useHeading('navigation')?null:$id,$regex); if($cnt !== 0){ - print ': '.$cnt.' '.$lang['hits'].'
'; + print ': '.$cnt.' '.$lang['hits'].''; + } + print '
'; + if($cnt !== 0){ if($num < FT_SNIPPET_NUMBER){ // create snippets for the first number of matches only - print '
'.ft_snippet($id,$regex).'
'; + print '
'.ft_snippet($id,$regex).'
'; } $num++; } - print '
'; flush(); } + print '
'; }else{ print '
'.$lang['nothingfound'].'
'; } diff --git a/lib/tpl/default/design.css b/lib/tpl/default/design.css index 48438527e..300b62a15 100644 --- a/lib/tpl/default/design.css +++ b/lib/tpl/default/design.css @@ -706,12 +706,20 @@ div.insitu-footnote { } /* --------------- search result formating --------------- */ -div.dokuwiki .search_result { - margin-bottom: 6px; +#dw__loading { + text-align: center; + margin-bottom: 1em; +} + +div.dokuwiki .search_results { padding: 0 10px 0 30px; } -div.dokuwiki .search_snippet { +div.dokuwiki .search_results dt { + margin-bottom: 3px; +} +div.dokuwiki .search_results dd { + margin-bottom: 6px; color: __text_other__; font-size: 12px; margin-left: 20px; diff --git a/lib/tpl/dokuwiki/css/_search.css b/lib/tpl/dokuwiki/css/_search.css index 446efe331..0090308c9 100644 --- a/lib/tpl/dokuwiki/css/_search.css +++ b/lib/tpl/dokuwiki/css/_search.css @@ -8,6 +8,8 @@ /* loading gif */ #dw__loading { + text-align: center; + margin-bottom: 1.4em; } /*____________ matching pagenames ____________*/ @@ -31,14 +33,20 @@ /*____________ search results ____________*/ -/* container for one search result */ -.dokuwiki div.search_result { - margin-bottom: 1.4em; +.dokuwiki dl.search_results { + margin-bottom: 1.2em; +} + +/* search heading */ +.dokuwiki dl.search_results dt { + font-weight: normal; + margin-bottom: .2em; } /* search snippet */ -.dokuwiki div.search_result div.search_snippet { +.dokuwiki dl.search_results dd { color: __text_alt__; background-color: inherit; + margin: 0 0 1.2em 0; } /* search hit in normal text */ @@ -47,11 +55,11 @@ background-color: __highlight__; } /* search hit in search results */ -.dokuwiki div.search_result strong.search_hit { +.dokuwiki .search_results strong.search_hit { font-weight: normal; } /* ellipsis separating snippets */ -.dokuwiki div.search_result .search_sep { +.dokuwiki .search_results .search_sep { color: __text__; background-color: inherit; } -- cgit v1.2.3 From 3d2fd76a6a87ddf4a45c05091799c09500265307 Mon Sep 17 00:00:00 2001 From: Anika Henke Date: Mon, 9 Apr 2012 19:08:20 +0100 Subject: added accidentally removed jquery-ui styles back again --- lib/exe/css.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/exe/css.php b/lib/exe/css.php index 5468376c6..1b2b0c86b 100644 --- a/lib/exe/css.php +++ b/lib/exe/css.php @@ -71,7 +71,7 @@ function css_out(){ $files[DOKU_INC.'lib/styles/'.$mediatype.'.css'] = DOKU_BASE.'lib/styles/'; // load jQuery-UI theme if ($mediatype == 'screen') { - //$files[DOKU_INC.'lib/scripts/jquery/jquery-ui-theme/smoothness.css'] = DOKU_BASE.'lib/scripts/jquery/jquery-ui-theme/'; + $files[DOKU_INC.'lib/scripts/jquery/jquery-ui-theme/smoothness.css'] = DOKU_BASE.'lib/scripts/jquery/jquery-ui-theme/'; } // load plugin styles $files = array_merge($files, css_pluginstyles($mediatype)); -- cgit v1.2.3 From c8388e443bcd0c09a0b142b31819d48abd559aa0 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 20 Apr 2012 17:20:17 +0200 Subject: made TOC togling script more generic Instead of a dedicated function to toggle the TOC we now have a function that allows to use this functionality everywhere. This will be used to toggle the sidebar in the mobile view (in an upcoming patch). Note, this required some changes to the CSS (to make it more generic). The CSS is still located in the TOC sections but should probably be moved into its own section instead. --- lib/scripts/page.js | 57 ++++++++++++++++++++++++++--------------- lib/tpl/default/design.css | 10 +++++--- lib/tpl/default/rtl.css | 3 ++- lib/tpl/dokuwiki/css/_toc.css | 6 +++-- lib/tpl/dokuwiki/css/design.css | 8 +++--- lib/tpl/dokuwiki/main.php | 11 +++++--- 6 files changed, 61 insertions(+), 34 deletions(-) diff --git a/lib/scripts/page.js b/lib/scripts/page.js index 6e7d7faf7..84af1f18b 100644 --- a/lib/scripts/page.js +++ b/lib/scripts/page.js @@ -10,7 +10,7 @@ dw_page = { init: function(){ dw_page.sectionHighlight(); jQuery('a.fn_top').mouseover(dw_page.footnoteDisplay); - dw_page.initTocToggle(); + dw_page.makeToggle('#dw__toc h3','#dw__toc > div'); }, /** @@ -93,47 +93,64 @@ dw_page = { }, /** - * Adds the toggle switch to the TOC + * Makes an element foldable by clicking its handle + * + * This is used for the TOC toggling, but can be used for other elements + * as well. A state indicator is inserted into the handle and can be styled + * by CSS. + * + * @param selector handle What should be clicked to toggle + * @param selector content This element will be toggled */ - initTocToggle: function() { - var $wrapper, $header, $clicky, $toc, $tocul, setClicky; - $wrapper = jQuery('#dw__toc'); - $header = jQuery('h3', $wrapper); - if(!$header.length) { - return; - } - $toc = jQuery('div', $wrapper).first(); - $tocul = jQuery('ul', $toc); + makeToggle: function(handle, content){ + var $handle, $content, $clicky, $child, setClicky; + $handle = jQuery(handle); + if(!$handle.length) return; + $content = jQuery(content); + if(!$content.length) return; + + // we animate the children + $child = $content.children(); + // class/display toggling setClicky = function(hiding){ if(hiding){ $clicky.html('+'); - $wrapper.addClass('close').removeClass('open'); + $handle.addClass('toggle_open'); + $handle.removeClass('toggle_close'); }else{ $clicky.html(''); - $wrapper.addClass('open').removeClass('close'); + $handle.addClass('toggle_close'); + $handle.removeClass('toggle_open'); } }; - $clicky = jQuery(document.createElement('strong')); - $header.css('cursor','pointer') + // the state indicator + $clicky = jQuery(document.createElement('strong')) + .addClass('toggle'); + + // click function + $handle.css('cursor','pointer') .click(function () { var hidden; - // Assert that $toc instantly takes the whole TOC space - $toc.css('height', $toc.height()).show(); + // Assert that content instantly takes the whole space + $content.css('height', $content.height()).show(); - hidden = $tocul.stop(true, true).is(':hidden'); + // stop any running animation and get current state + hidden = $child.stop(true, true).is(':hidden'); + // update the state setClicky(!hidden); // Start animation and assure that $toc is hidden/visible - $tocul.dw_toggle(hidden, function () { - $toc.toggle(hidden); + $child.dw_toggle(hidden, function () { + $content.toggle(hidden); }); }) .prepend($clicky); + // initial state setClicky(); } }; diff --git a/lib/tpl/default/design.css b/lib/tpl/default/design.css index 300b62a15..44ccc0343 100644 --- a/lib/tpl/default/design.css +++ b/lib/tpl/default/design.css @@ -565,23 +565,25 @@ div.dokuwiki #dw__toc h3 { font-size: 1em; } -div.dokuwiki #dw__toc h3 strong { +div.dokuwiki .toggle_close .toggle, +div.dokuwiki .toggle_open .toggle { border: 0.4em solid __background_alt__; float: right; display: block; margin: 0.4em 3px 0 0; } -div.dokuwiki #dw__toc h3 strong span { +div.dokuwiki .toggle_open .toggle span, +div.dokuwiki .toggle_close .toggle span { display: none; } -div.dokuwiki #dw__toc.close h3 strong { +div.dokuwiki .toggle_close .toggle { margin-top: 0.4em; border-top: 0.4em solid __text__; } -div.dokuwiki #dw__toc.open h3 strong { +div.dokuwiki .toggle_open .toggle { margin-top: 0; border-bottom: 0.4em solid __text__; } diff --git a/lib/tpl/default/rtl.css b/lib/tpl/default/rtl.css index 32a8ddb6d..b9dd82902 100644 --- a/lib/tpl/default/rtl.css +++ b/lib/tpl/default/rtl.css @@ -98,7 +98,8 @@ div.dokuwiki #dw__toc h3 { text-align: right; } -div.dokuwiki #dw__toc h3 strong { +div.dokuwiki .toggle_close .toggle, +div.dokuwiki .toggle_open .toggle { float: left; margin: 0.4em 0 0 3px; } diff --git a/lib/tpl/dokuwiki/css/_toc.css b/lib/tpl/dokuwiki/css/_toc.css index e62bb0a7a..71cc4096a 100644 --- a/lib/tpl/dokuwiki/css/_toc.css +++ b/lib/tpl/dokuwiki/css/_toc.css @@ -26,11 +26,13 @@ font-weight: bold; } -#dw__toc h3 strong { +.toggle_open .toggle, +.toggle_close .toggle { float: right; margin: 0 .2em; } -[dir=rtl] #dw__toc h3 strong { +[dir=rtl] .toggle_open .toggle, +[dir=rtl] .toggle_close .toggle { float: left; } diff --git a/lib/tpl/dokuwiki/css/design.css b/lib/tpl/dokuwiki/css/design.css index 8ebeca6da..2d0af6ad1 100644 --- a/lib/tpl/dokuwiki/css/design.css +++ b/lib/tpl/dokuwiki/css/design.css @@ -412,17 +412,19 @@ letter-spacing: .1em; } -#dw__toc h3 strong { +.toggle_open .toggle, +.toggle_close .toggle { background: transparent url(images/toc-arrows.png) 0 0; width: 8px; height: 5px; margin: .4em 0 0; } -#dw__toc.close strong { +.toggle_close .toggle { background-position: 0 -5px; } -#dw__toc strong span { +.toggle_open .toggle span, +.toggle_close .toggle span { display: none; } diff --git a/lib/tpl/dokuwiki/main.php b/lib/tpl/dokuwiki/main.php index 57c94f174..5e8eb7517 100644 --- a/lib/tpl/dokuwiki/main.php +++ b/lib/tpl/dokuwiki/main.php @@ -37,10 +37,13 @@ $showSidebar = $conf['sidebar'] && page_exists($conf['sidebar']) && ($ACT=='show
- - - - +
+
+ + + + +
-- cgit v1.2.3 From 290a80647ab295141f3bae29efd1b1691c5bab01 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 20 Apr 2012 18:04:37 +0200 Subject: mobile styles for the TOC structure changes --- lib/tpl/dokuwiki/css/mobile.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/tpl/dokuwiki/css/mobile.css b/lib/tpl/dokuwiki/css/mobile.css index 6aacb4674..34955888c 100644 --- a/lib/tpl/dokuwiki/css/mobile.css +++ b/lib/tpl/dokuwiki/css/mobile.css @@ -33,22 +33,22 @@ } /* toc */ -.dokuwiki div.toc { +#dw__toc { float: none; margin: 0 0 1em 0; width: auto; border-left-width: 0; border-bottom: 1px solid __border__; } -[dir=rtl] .dokuwiki div.toc { +[dir=rtl] #dw__toc { float: none; margin: 0 0 1em 0; border-right-width: 0; } -.dokuwiki div.tocheader { +#dw__toc h3 { padding: 0 0 .5em; } -.dokuwiki #toc__inside { +#dw__toc > div { padding: .2em 0 .5em; } -- cgit v1.2.3 From 5dcb125169a39581162871578f00a8da6c7c10dd Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 20 Apr 2012 18:18:41 +0200 Subject: collapse sidebar in mobile view FS#2473 --- lib/tpl/dokuwiki/css/mobile.css | 22 ++++++++++++++++++++++ lib/tpl/dokuwiki/main.php | 2 +- lib/tpl/dokuwiki/script.js | 9 +++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 lib/tpl/dokuwiki/script.js diff --git a/lib/tpl/dokuwiki/css/mobile.css b/lib/tpl/dokuwiki/css/mobile.css index 34955888c..31a0a87c8 100644 --- a/lib/tpl/dokuwiki/css/mobile.css +++ b/lib/tpl/dokuwiki/css/mobile.css @@ -14,10 +14,30 @@ width: 100%; float: none; } + #dokuwiki__aside > .pad { margin: 0 0 .5em; + + /* style like the page */ + background: __background__; + color: inherit; + border: 1px solid #eee; + box-shadow: 0 0 .5em #999; + border-radius: 2px; + padding: 1em; + margin-bottom: .5em; + overflow: hidden; + word-wrap: break-word; +} + +#dokuwiki__aside h3.aside { + padding: 0 0 .5em; + font-size: .875em; + letter-spacing: .1em; + border-bottom: 1px solid __border__; } + .hasSidebar #dokuwiki__content { float: none; margin-left: 0; @@ -45,6 +65,7 @@ margin: 0 0 1em 0; border-right-width: 0; } + #dw__toc h3 { padding: 0 0 .5em; } @@ -194,6 +215,7 @@ /*____________ content ____________*/ +#dokuwiki__aside > .pad, .dokuwiki div.page { padding: .5em; } diff --git a/lib/tpl/dokuwiki/main.php b/lib/tpl/dokuwiki/main.php index 5e8eb7517..4883cc5f0 100644 --- a/lib/tpl/dokuwiki/main.php +++ b/lib/tpl/dokuwiki/main.php @@ -37,7 +37,7 @@ $showSidebar = $conf['sidebar'] && page_exists($conf['sidebar']) && ($ACT=='show
-
+

diff --git a/lib/tpl/dokuwiki/script.js b/lib/tpl/dokuwiki/script.js new file mode 100644 index 000000000..dd9c17561 --- /dev/null +++ b/lib/tpl/dokuwiki/script.js @@ -0,0 +1,9 @@ +jQuery(function(){ + // check if we are in mobile mode + if(jQuery('div.mobileTools').css('display') == 'none') return; + + // toc and sidebar hiding + dw_page.makeToggle('#dokuwiki__aside h3.aside','#dokuwiki__aside div.aside'); + jQuery('#dw__toc > h3').click(); + jQuery('#dokuwiki__aside h3.aside').removeClass('a11y').click(); +}); -- cgit v1.2.3 From 48722ac855c79944285cbe8958fe5ed03bd835ed Mon Sep 17 00:00:00 2001 From: Anika Henke Date: Sun, 22 Apr 2012 21:19:59 +0100 Subject: improved toc changes and sidebar toggling --- inc/html.php | 2 +- lib/scripts/page.js | 11 +++++------ lib/tpl/default/design.css | 10 ++++------ lib/tpl/default/rtl.css | 3 +-- lib/tpl/dokuwiki/css/_toc.css | 8 +++----- lib/tpl/dokuwiki/css/design.css | 13 +++++++------ lib/tpl/dokuwiki/css/mobile.css | 41 +++++++++++++++++++---------------------- lib/tpl/dokuwiki/css/print.css | 1 + lib/tpl/dokuwiki/main.php | 4 ++-- lib/tpl/dokuwiki/script.js | 7 ++++--- 10 files changed, 47 insertions(+), 53 deletions(-) diff --git a/inc/html.php b/inc/html.php index c3e345cb0..0b297a347 100644 --- a/inc/html.php +++ b/inc/html.php @@ -1717,7 +1717,7 @@ function html_TOC($toc){ global $lang; $out = ''.DOKU_LF; $out .= '
'.DOKU_LF; - $out .= '

'; + $out .= '

'; $out .= $lang['toc']; $out .= '

'.DOKU_LF; $out .= '
'.DOKU_LF; diff --git a/lib/scripts/page.js b/lib/scripts/page.js index 84af1f18b..74dec37fb 100644 --- a/lib/scripts/page.js +++ b/lib/scripts/page.js @@ -116,18 +116,17 @@ dw_page = { setClicky = function(hiding){ if(hiding){ $clicky.html('+'); - $handle.addClass('toggle_open'); - $handle.removeClass('toggle_close'); + $handle.addClass('closed'); + $handle.removeClass('open'); }else{ $clicky.html(''); - $handle.addClass('toggle_close'); - $handle.removeClass('toggle_open'); + $handle.addClass('open'); + $handle.removeClass('closed'); } }; // the state indicator - $clicky = jQuery(document.createElement('strong')) - .addClass('toggle'); + $clicky = jQuery(document.createElement('strong')); // click function $handle.css('cursor','pointer') diff --git a/lib/tpl/default/design.css b/lib/tpl/default/design.css index 44ccc0343..3405ec258 100644 --- a/lib/tpl/default/design.css +++ b/lib/tpl/default/design.css @@ -565,25 +565,23 @@ div.dokuwiki #dw__toc h3 { font-size: 1em; } -div.dokuwiki .toggle_close .toggle, -div.dokuwiki .toggle_open .toggle { +div.dokuwiki .toggle strong { border: 0.4em solid __background_alt__; float: right; display: block; margin: 0.4em 3px 0 0; } -div.dokuwiki .toggle_open .toggle span, -div.dokuwiki .toggle_close .toggle span { +div.dokuwiki .toggle span { display: none; } -div.dokuwiki .toggle_close .toggle { +div.dokuwiki .toggle.closed strong { margin-top: 0.4em; border-top: 0.4em solid __text__; } -div.dokuwiki .toggle_open .toggle { +div.dokuwiki .toggle.open strong { margin-top: 0; border-bottom: 0.4em solid __text__; } diff --git a/lib/tpl/default/rtl.css b/lib/tpl/default/rtl.css index b9dd82902..8b2837874 100644 --- a/lib/tpl/default/rtl.css +++ b/lib/tpl/default/rtl.css @@ -98,8 +98,7 @@ div.dokuwiki #dw__toc h3 { text-align: right; } -div.dokuwiki .toggle_close .toggle, -div.dokuwiki .toggle_open .toggle { +div.dokuwiki .toggle strong { float: left; margin: 0.4em 0 0 3px; } diff --git a/lib/tpl/dokuwiki/css/_toc.css b/lib/tpl/dokuwiki/css/_toc.css index 71cc4096a..0d1b976d1 100644 --- a/lib/tpl/dokuwiki/css/_toc.css +++ b/lib/tpl/dokuwiki/css/_toc.css @@ -21,18 +21,16 @@ /*____________ toc header ____________*/ -#dw__toc h3 { +.dokuwiki h3.toggle { padding: .2em .5em; font-weight: bold; } -.toggle_open .toggle, -.toggle_close .toggle { +.dokuwiki .toggle strong { float: right; margin: 0 .2em; } -[dir=rtl] .toggle_open .toggle, -[dir=rtl] .toggle_close .toggle { +[dir=rtl] .dokuwiki .toggle strong { float: left; } diff --git a/lib/tpl/dokuwiki/css/design.css b/lib/tpl/dokuwiki/css/design.css index 2d0af6ad1..1bc667fb5 100644 --- a/lib/tpl/dokuwiki/css/design.css +++ b/lib/tpl/dokuwiki/css/design.css @@ -405,26 +405,27 @@ border-right: 1px solid __border__; } -#dw__toc h3 { +.dokuwiki h3.toggle { padding: .5em 1em; margin-bottom: 0; font-size: .875em; letter-spacing: .1em; } +#dokuwiki__aside h3.toggle { + display: none; +} -.toggle_open .toggle, -.toggle_close .toggle { +.dokuwiki .toggle strong { background: transparent url(images/toc-arrows.png) 0 0; width: 8px; height: 5px; margin: .4em 0 0; } -.toggle_close .toggle { +.dokuwiki .toggle.closed strong { background-position: 0 -5px; } -.toggle_open .toggle span, -.toggle_close .toggle span { +.dokuwiki .toggle strong span { display: none; } diff --git a/lib/tpl/dokuwiki/css/mobile.css b/lib/tpl/dokuwiki/css/mobile.css index 31a0a87c8..b57b60e9b 100644 --- a/lib/tpl/dokuwiki/css/mobile.css +++ b/lib/tpl/dokuwiki/css/mobile.css @@ -15,10 +15,10 @@ float: none; } -#dokuwiki__aside > .pad { +#dokuwiki__aside > .pad, +[dir=rtl] #dokuwiki__aside > .pad { margin: 0 0 .5em; - - /* style like the page */ + /* style like .page */ background: __background__; color: inherit; border: 1px solid #eee; @@ -26,18 +26,8 @@ border-radius: 2px; padding: 1em; margin-bottom: .5em; - overflow: hidden; - word-wrap: break-word; } -#dokuwiki__aside h3.aside { - padding: 0 0 .5em; - font-size: .875em; - letter-spacing: .1em; - border-bottom: 1px solid __border__; -} - - .hasSidebar #dokuwiki__content { float: none; margin-left: 0; @@ -66,10 +56,11 @@ border-right-width: 0; } -#dw__toc h3 { - padding: 0 0 .5em; +.dokuwiki h3.toggle { + padding: 0 .5em .5em 0; } -#dw__toc > div { +#dw__toc > div, +#dokuwiki__aside div.content { padding: .2em 0 .5em; } @@ -77,12 +68,6 @@ .dokuwiki div.page { padding: 1em; } -.dokuwiki .pageId span { - border-width: 0; - background-color: __background_site__; - color: __text_alt__; - box-shadow: 0 0 0; -} /* _edit */ .dokuwiki div.section_highlight { @@ -123,6 +108,18 @@ padding: .5em 0; } +#dokuwiki__aside h3.toggle { + font-size: 1em; +} +#dokuwiki__aside h3.toggle.closed { + margin-bottom: 0; + padding-bottom: 0; +} +#dokuwiki__aside h3.toggle.open { + border-bottom: 1px solid __border__; +} + + /*____________ header ____________*/ #dokuwiki__header ul.a11y.skip { diff --git a/lib/tpl/dokuwiki/css/print.css b/lib/tpl/dokuwiki/css/print.css index f6bf64dd9..9f43f5131 100644 --- a/lib/tpl/dokuwiki/css/print.css +++ b/lib/tpl/dokuwiki/css/print.css @@ -22,6 +22,7 @@ div.error, #dokuwiki__aside, .dokuwiki .breadcrumbs, #dw__toc, +h3.toggle, .dokuwiki .secedit, #dokuwiki__pagetools, #dokuwiki__footer { diff --git a/lib/tpl/dokuwiki/main.php b/lib/tpl/dokuwiki/main.php index 4883cc5f0..d8e85850f 100644 --- a/lib/tpl/dokuwiki/main.php +++ b/lib/tpl/dokuwiki/main.php @@ -37,8 +37,8 @@ $showSidebar = $conf['sidebar'] && page_exists($conf['sidebar']) && ($ACT=='show
-

-
+

+
diff --git a/lib/tpl/dokuwiki/script.js b/lib/tpl/dokuwiki/script.js index dd9c17561..b31d3dc08 100644 --- a/lib/tpl/dokuwiki/script.js +++ b/lib/tpl/dokuwiki/script.js @@ -3,7 +3,8 @@ jQuery(function(){ if(jQuery('div.mobileTools').css('display') == 'none') return; // toc and sidebar hiding - dw_page.makeToggle('#dokuwiki__aside h3.aside','#dokuwiki__aside div.aside'); - jQuery('#dw__toc > h3').click(); - jQuery('#dokuwiki__aside h3.aside').removeClass('a11y').click(); + dw_page.makeToggle('#dokuwiki__aside h3.toggle','#dokuwiki__aside div.content'); + + jQuery('#dw__toc h3.toggle').click(); + jQuery('#dokuwiki__aside h3.toggle').show().click(); }); -- cgit v1.2.3 From 1a8210512cfe2f8454a731834871ebcbe6d42596 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 23 Apr 2012 12:51:25 +0200 Subject: match on img tag in feed's img align replacement this should avoid false positive matches on user content (which is already escaped at this point) --- feed.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feed.php b/feed.php index dafbb3c07..4e46c254d 100644 --- a/feed.php +++ b/feed.php @@ -325,8 +325,8 @@ function rss_buildItems(&$rss,&$data,$opt){ $content = preg_replace('/().*()/s','',$content); // add alignment for images - $content = preg_replace('/class="medialeft"/s', 'class="medialeft" align="left"', $content); - $content = preg_replace('/class="mediaright"/s', 'class="mediaright" align="right"', $content); + $content = preg_replace('/( Date: Sat, 16 Jun 2012 02:30:00 -0400 Subject: Reference static variable through 'self::' as you're supposed to. --- inc/HTTPClient.php | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index 26bee52a7..bb87056e2 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -284,11 +284,11 @@ class HTTPClient { // already connected? $connectionId = $this->_uniqueConnectionId($server,$port); - $this->_debug('connection pool', $this->connections); + $this->_debug('connection pool', self::$connections); $socket = null; - if (isset($this->connections[$connectionId])) { + if (isset(self::$connections[$connectionId])) { $this->_debug('reusing connection', $connectionId); - $socket = $this->connections[$connectionId]; + $socket = self::$connections[$connectionId]; } if (is_null($socket) || feof($socket)) { $this->_debug('opening connection', $connectionId); @@ -302,9 +302,9 @@ class HTTPClient { // keep alive? if ($this->keep_alive) { - $this->connections[$connectionId] = $socket; + self::$connections[$connectionId] = $socket; } else { - unset($this->connections[$connectionId]); + unset(self::$connections[$connectionId]); } } @@ -333,7 +333,7 @@ class HTTPClient { if(time()-$start > $this->timeout){ $this->status = -100; $this->error = sprintf('Timeout while sending request (%.3fs)',$this->_time() - $this->start); - unset($this->connections[$connectionId]); + unset(self::$connections[$connectionId]); return false; } @@ -348,7 +348,7 @@ class HTTPClient { if($ret === false){ $this->status = -100; $this->error = 'Failed writing to socket'; - unset($this->connections[$connectionId]); + unset(self::$connections[$connectionId]); return false; } $written += $ret; @@ -363,12 +363,12 @@ class HTTPClient { if(time()-$start > $this->timeout){ $this->status = -100; $this->error = sprintf('Timeout while reading headers (%.3fs)',$this->_time() - $this->start); - unset($this->connections[$connectionId]); + unset(self::$connections[$connectionId]); return false; } if(feof($socket)){ $this->error = 'Premature End of File (socket)'; - unset($this->connections[$connectionId]); + unset(self::$connections[$connectionId]); return false; } usleep(1000); @@ -382,7 +382,7 @@ class HTTPClient { if($match[1] > $this->max_bodysize){ $this->error = 'Reported content length exceeds allowed response size'; if ($this->max_bodysize_abort) - unset($this->connections[$connectionId]); + unset(self::$connections[$connectionId]); return false; } } @@ -390,7 +390,7 @@ class HTTPClient { // get Status if (!preg_match('/^HTTP\/(\d\.\d)\s*(\d+).*?\n/', $r_headers, $m)) { $this->error = 'Server returned bad answer'; - unset($this->connections[$connectionId]); + unset(self::$connections[$connectionId]); return false; } $this->status = $m[2]; @@ -419,7 +419,7 @@ class HTTPClient { // close the connection because we don't handle content retrieval here // that's the easiest way to clean up the connection fclose($socket); - unset($this->connections[$connectionId]); + unset(self::$connections[$connectionId]); if (empty($this->resp_headers['location'])){ $this->error = 'Redirect but no Location Header found'; @@ -448,7 +448,7 @@ class HTTPClient { // check if headers are as expected if($this->header_regexp && !preg_match($this->header_regexp,$r_headers)){ $this->error = 'The received headers did not match the given regexp'; - unset($this->connections[$connectionId]); + unset(self::$connections[$connectionId]); return false; } @@ -460,13 +460,13 @@ class HTTPClient { do { if(feof($socket)){ $this->error = 'Premature End of File (socket)'; - unset($this->connections[$connectionId]); + unset(self::$connections[$connectionId]); return false; } if(time()-$start > $this->timeout){ $this->status = -100; $this->error = sprintf('Timeout while reading chunk (%.3fs)',$this->_time() - $this->start); - unset($this->connections[$connectionId]); + unset(self::$connections[$connectionId]); return false; } $byte = fread($socket,1); @@ -484,7 +484,7 @@ class HTTPClient { if($this->max_bodysize && strlen($r_body) > $this->max_bodysize){ $this->error = 'Allowed response size exceeded'; if ($this->max_bodysize_abort){ - unset($this->connections[$connectionId]); + unset(self::$connections[$connectionId]); return false; } else { break; @@ -497,7 +497,7 @@ class HTTPClient { if(time()-$start > $this->timeout){ $this->status = -100; $this->error = sprintf('Timeout while reading response (%.3fs)',$this->_time() - $this->start); - unset($this->connections[$connectionId]); + unset(self::$connections[$connectionId]); return false; } $r_body .= fread($socket,4096); @@ -505,7 +505,7 @@ class HTTPClient { if($this->max_bodysize && $r_size > $this->max_bodysize){ $this->error = 'Allowed response size exceeded'; if ($this->max_bodysize_abort) { - unset($this->connections[$connectionId]); + unset(self::$connections[$connectionId]); return false; } else { break; @@ -525,7 +525,7 @@ class HTTPClient { // close socket $status = socket_get_status($socket); fclose($socket); - unset($this->connections[$connectionId]); + unset(self::$connections[$connectionId]); } // decode gzip if needed -- cgit v1.2.3 From a09831ea8abf0abcf3e7f72f0974dc5e0fc301c8 Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Sat, 16 Jun 2012 02:34:47 -0400 Subject: Avoid strict warnings about unset array keys. --- inc/HTTPClient.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index bb87056e2..524dd9a2c 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -227,7 +227,7 @@ class HTTPClient { $path = $uri['path']; if(empty($path)) $path = '/'; if(!empty($uri['query'])) $path .= '?'.$uri['query']; - if(isset($uri['port']) && !empty($uri['port'])) $port = $uri['port']; + if(!empty($uri['port'])) $port = $uri['port']; if(isset($uri['user'])) $this->user = $uri['user']; if(isset($uri['pass'])) $this->pass = $uri['pass']; @@ -249,7 +249,7 @@ class HTTPClient { // prepare headers $headers = $this->headers; $headers['Host'] = $uri['host']; - if($uri['port']) $headers['Host'].= ':'.$uri['port']; + if(!empty($uri['port'])) $headers['Host'].= ':'.$uri['port']; $headers['User-Agent'] = $this->agent; $headers['Referer'] = $this->referer; if ($this->keep_alive) { @@ -583,7 +583,7 @@ class HTTPClient { $lines = explode("\n",$string); array_shift($lines); //skip first line (status) foreach($lines as $line){ - list($key, $val) = explode(':',$line,2); + @list($key, $val) = explode(':',$line,2); $key = trim($key); $val = trim($val); $key = strtolower($key); -- cgit v1.2.3 From fc6c2b2f78f7278af30dd2dd0758e90ae771322e Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Sat, 16 Jun 2012 03:23:17 -0400 Subject: Correct handling of chunked transfer encoding. (FS#2535) --- inc/HTTPClient.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index 524dd9a2c..a07d263dd 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -456,7 +456,7 @@ class HTTPClient { $r_body = ''; if(preg_match('/transfer\-(en)?coding:\s*chunked\r\n/i',$r_headers)){ do { - unset($chunk_size); + $chunk_size = ''; do { if(feof($socket)){ $this->error = 'Premature End of File (socket)'; @@ -471,13 +471,17 @@ class HTTPClient { } $byte = fread($socket,1); $chunk_size .= $byte; - } while (preg_match('/[a-zA-Z0-9]/',$byte)); // read chunksize including \r + } while (preg_match('/^[a-zA-Z0-9]?$/',$byte)); // read chunksize including \r $byte = fread($socket,1); // readtrailing \n $chunk_size = hexdec($chunk_size); if ($chunk_size) { - $this_chunk = fread($socket,$chunk_size); - $r_body .= $this_chunk; + $read_size = $chunk_size; + while ($read_size > 0) { + $this_chunk = fread($socket,$read_size); + $r_body .= $this_chunk; + $read_size -= strlen($this_chunk); + } $byte = fread($socket,2); // read trailing \r\n } -- cgit v1.2.3 From 189ba183ccac1cf7a2d02756895207c48431f70b Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Sat, 16 Jun 2012 23:02:26 -0400 Subject: Raise an exception on socket errors. This is the first step in refactoring the socket reader to be more resilient and easier to debug. --- inc/HTTPClient.php | 352 +++++++++++++++++++++++++---------------------------- 1 file changed, 167 insertions(+), 185 deletions(-) diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index a07d263dd..f11621f6a 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -61,6 +61,8 @@ class DokuHTTPClient extends HTTPClient { } +class HTTPClientException extends Exception { } + /** * This class implements a basic HTTP client * @@ -308,220 +310,200 @@ class HTTPClient { } } - //set blocking - stream_set_blocking($socket,1); - - // build request - $request = "$method $request_url HTTP/".$this->http.HTTP_NL; - $request .= $this->_buildHeaders($headers); - $request .= $this->_getCookies(); - $request .= HTTP_NL; - $request .= $data; - - $this->_debug('request',$request); - - // select parameters - $sel_r = null; - $sel_w = array($socket); - $sel_e = null; - - // send request - $towrite = strlen($request); - $written = 0; - while($written < $towrite){ - // check timeout - if(time()-$start > $this->timeout){ - $this->status = -100; - $this->error = sprintf('Timeout while sending request (%.3fs)',$this->_time() - $this->start); - unset(self::$connections[$connectionId]); - return false; - } - - // wait for stream ready or timeout (1sec) - if(@stream_select($sel_r,$sel_w,$sel_e,1) === false){ - usleep(1000); - continue; - } - - // write to stream - $ret = fwrite($socket, substr($request,$written,4096)); - if($ret === false){ - $this->status = -100; - $this->error = 'Failed writing to socket'; - unset(self::$connections[$connectionId]); - return false; - } - $written += $ret; - } - - // continue non-blocking - stream_set_blocking($socket,0); + try { + //set blocking + stream_set_blocking($socket,1); + + // build request + $request = "$method $request_url HTTP/".$this->http.HTTP_NL; + $request .= $this->_buildHeaders($headers); + $request .= $this->_getCookies(); + $request .= HTTP_NL; + $request .= $data; + + $this->_debug('request',$request); + + // select parameters + $sel_r = null; + $sel_w = array($socket); + $sel_e = null; + + // send request + $towrite = strlen($request); + $written = 0; + while($written < $towrite){ + // check timeout + if(time()-$start > $this->timeout) + throw new HTTPClientException(sprintf('Timeout while sending request (%.3fs)',$this->_time() - $this->start), -100); + + // wait for stream ready or timeout (1sec) + if(@stream_select($sel_r,$sel_w,$sel_e,1) === false){ + usleep(1000); + continue; + } - // read headers from socket - $r_headers = ''; - do{ - if(time()-$start > $this->timeout){ - $this->status = -100; - $this->error = sprintf('Timeout while reading headers (%.3fs)',$this->_time() - $this->start); - unset(self::$connections[$connectionId]); - return false; - } - if(feof($socket)){ - $this->error = 'Premature End of File (socket)'; - unset(self::$connections[$connectionId]); - return false; + // write to stream + $ret = fwrite($socket, substr($request,$written,4096)); + if($ret === false) + throw new HTTPClientException('Failed writing to socket', -100); + $written += $ret; } - usleep(1000); - $r_headers .= fgets($socket,1024); - }while(!preg_match('/\r?\n\r?\n$/',$r_headers)); - $this->_debug('response headers',$r_headers); + // continue non-blocking + stream_set_blocking($socket,0); - // check if expected body size exceeds allowance - if($this->max_bodysize && preg_match('/\r?\nContent-Length:\s*(\d+)\r?\n/i',$r_headers,$match)){ - if($match[1] > $this->max_bodysize){ - $this->error = 'Reported content length exceeds allowed response size'; - if ($this->max_bodysize_abort) - unset(self::$connections[$connectionId]); - return false; + // read headers from socket + $r_headers = ''; + do{ + if(time()-$start > $this->timeout) + throw new HTTPClientException(sprintf('Timeout while reading headers (%.3fs)',$this->_time() - $this->start), -100); + if(feof($socket)) + throw new HTTPClientException('Premature End of File (socket)'); + usleep(1000); + $r_headers .= fgets($socket,1024); + }while(!preg_match('/\r?\n\r?\n$/',$r_headers)); + + $this->_debug('response headers',$r_headers); + + // check if expected body size exceeds allowance + if($this->max_bodysize && preg_match('/\r?\nContent-Length:\s*(\d+)\r?\n/i',$r_headers,$match)){ + if($match[1] > $this->max_bodysize){ + if ($this->max_bodysize_abort) + throw new HTTPClientException('Reported content length exceeds allowed response size'); + else + $this->error = 'Reported content length exceeds allowed response size'; + } } - } - // get Status - if (!preg_match('/^HTTP\/(\d\.\d)\s*(\d+).*?\n/', $r_headers, $m)) { - $this->error = 'Server returned bad answer'; - unset(self::$connections[$connectionId]); - return false; - } - $this->status = $m[2]; - - // handle headers and cookies - $this->resp_headers = $this->_parseHeaders($r_headers); - if(isset($this->resp_headers['set-cookie'])){ - foreach ((array) $this->resp_headers['set-cookie'] as $cookie){ - list($cookie) = explode(';',$cookie,2); - list($key,$val) = explode('=',$cookie,2); - $key = trim($key); - if($val == 'deleted'){ - if(isset($this->cookies[$key])){ - unset($this->cookies[$key]); + // get Status + if (!preg_match('/^HTTP\/(\d\.\d)\s*(\d+).*?\n/', $r_headers, $m)) + throw new HTTPClientException('Server returned bad answer'); + + $this->status = $m[2]; + + // handle headers and cookies + $this->resp_headers = $this->_parseHeaders($r_headers); + if(isset($this->resp_headers['set-cookie'])){ + foreach ((array) $this->resp_headers['set-cookie'] as $cookie){ + list($cookie) = explode(';',$cookie,2); + list($key,$val) = explode('=',$cookie,2); + $key = trim($key); + if($val == 'deleted'){ + if(isset($this->cookies[$key])){ + unset($this->cookies[$key]); + } + }elseif($key){ + $this->cookies[$key] = $val; } - }elseif($key){ - $this->cookies[$key] = $val; } } - } - $this->_debug('Object headers',$this->resp_headers); + $this->_debug('Object headers',$this->resp_headers); - // check server status code to follow redirect - if($this->status == 301 || $this->status == 302 ){ - // close the connection because we don't handle content retrieval here - // that's the easiest way to clean up the connection - fclose($socket); - unset(self::$connections[$connectionId]); + // check server status code to follow redirect + if($this->status == 301 || $this->status == 302 ){ + if (empty($this->resp_headers['location'])){ + throw new HTTPClientException('Redirect but no Location Header found'); + }elseif($this->redirect_count == $this->max_redirect){ + throw new HTTPClientException('Maximum number of redirects exceeded'); + }else{ + // close the connection because we don't handle content retrieval here + // that's the easiest way to clean up the connection + fclose($socket); + unset(self::$connections[$connectionId]); - if (empty($this->resp_headers['location'])){ - $this->error = 'Redirect but no Location Header found'; - return false; - }elseif($this->redirect_count == $this->max_redirect){ - $this->error = 'Maximum number of redirects exceeded'; - return false; - }else{ - $this->redirect_count++; - $this->referer = $url; - // handle non-RFC-compliant relative redirects - if (!preg_match('/^http/i', $this->resp_headers['location'])){ - if($this->resp_headers['location'][0] != '/'){ - $this->resp_headers['location'] = $uri['scheme'].'://'.$uri['host'].':'.$uri['port']. - dirname($uri['path']).'/'.$this->resp_headers['location']; - }else{ - $this->resp_headers['location'] = $uri['scheme'].'://'.$uri['host'].':'.$uri['port']. - $this->resp_headers['location']; + $this->redirect_count++; + $this->referer = $url; + // handle non-RFC-compliant relative redirects + if (!preg_match('/^http/i', $this->resp_headers['location'])){ + if($this->resp_headers['location'][0] != '/'){ + $this->resp_headers['location'] = $uri['scheme'].'://'.$uri['host'].':'.$uri['port']. + dirname($uri['path']).'/'.$this->resp_headers['location']; + }else{ + $this->resp_headers['location'] = $uri['scheme'].'://'.$uri['host'].':'.$uri['port']. + $this->resp_headers['location']; + } } + // perform redirected request, always via GET (required by RFC) + return $this->sendRequest($this->resp_headers['location'],array(),'GET'); } - // perform redirected request, always via GET (required by RFC) - return $this->sendRequest($this->resp_headers['location'],array(),'GET'); } - } - // check if headers are as expected - if($this->header_regexp && !preg_match($this->header_regexp,$r_headers)){ - $this->error = 'The received headers did not match the given regexp'; - unset(self::$connections[$connectionId]); - return false; - } + // check if headers are as expected + if($this->header_regexp && !preg_match($this->header_regexp,$r_headers)) + throw new HTTPClientException('The received headers did not match the given regexp'); - //read body (with chunked encoding if needed) - $r_body = ''; - if(preg_match('/transfer\-(en)?coding:\s*chunked\r\n/i',$r_headers)){ - do { - $chunk_size = ''; + //read body (with chunked encoding if needed) + $r_body = ''; + if(preg_match('/transfer\-(en)?coding:\s*chunked\r\n/i',$r_headers)){ + stream_set_blocking($socket,1); do { - if(feof($socket)){ - $this->error = 'Premature End of File (socket)'; - unset(self::$connections[$connectionId]); - return false; + $chunk_size = ''; + do { + if(feof($socket)) + throw new HTTPClientException('Premature End of File (socket)'); + if(time()-$start > $this->timeout) + throw new HTTPClientException(sprintf('Timeout while reading chunk (%.3fs)',$this->_time() - $this->start), -100); + $byte = fread($socket,1); + $chunk_size .= $byte; + } while (preg_match('/^[a-zA-Z0-9]?$/',$byte)); // read chunksize including \r + + $byte = fread($socket,1); // readtrailing \n + $chunk_size = hexdec($chunk_size); + if ($chunk_size) { + $read_size = $chunk_size; + while ($read_size > 0) { + $this_chunk = fread($socket,$read_size); + $r_body .= $this_chunk; + $read_size -= strlen($this_chunk); + } + $byte = fread($socket,2); // read trailing \r\n + } + + if($this->max_bodysize && strlen($r_body) > $this->max_bodysize){ + if ($this->max_bodysize_abort) + throw new HTTPClientException('Allowed response size exceeded'); + $this->error = 'Allowed response size exceeded'; + break; } + } while ($chunk_size); + stream_set_blocking($socket,0); + }else{ + // read entire socket + while (!feof($socket)) { if(time()-$start > $this->timeout){ $this->status = -100; - $this->error = sprintf('Timeout while reading chunk (%.3fs)',$this->_time() - $this->start); + $this->error = sprintf('Timeout while reading response (%.3fs)',$this->_time() - $this->start); unset(self::$connections[$connectionId]); return false; } - $byte = fread($socket,1); - $chunk_size .= $byte; - } while (preg_match('/^[a-zA-Z0-9]?$/',$byte)); // read chunksize including \r - - $byte = fread($socket,1); // readtrailing \n - $chunk_size = hexdec($chunk_size); - if ($chunk_size) { - $read_size = $chunk_size; - while ($read_size > 0) { - $this_chunk = fread($socket,$read_size); - $r_body .= $this_chunk; - $read_size -= strlen($this_chunk); - } - $byte = fread($socket,2); // read trailing \r\n - } - - if($this->max_bodysize && strlen($r_body) > $this->max_bodysize){ - $this->error = 'Allowed response size exceeded'; - if ($this->max_bodysize_abort){ - unset(self::$connections[$connectionId]); - return false; - } else { - break; + $r_body .= fread($socket,4096); + $r_size = strlen($r_body); + if($this->max_bodysize && $r_size > $this->max_bodysize){ + $this->error = 'Allowed response size exceeded'; + if ($this->max_bodysize_abort) { + unset(self::$connections[$connectionId]); + return false; + } else { + break; + } } - } - } while ($chunk_size); - }else{ - // read entire socket - while (!feof($socket)) { - if(time()-$start > $this->timeout){ - $this->status = -100; - $this->error = sprintf('Timeout while reading response (%.3fs)',$this->_time() - $this->start); - unset(self::$connections[$connectionId]); - return false; - } - $r_body .= fread($socket,4096); - $r_size = strlen($r_body); - if($this->max_bodysize && $r_size > $this->max_bodysize){ - $this->error = 'Allowed response size exceeded'; - if ($this->max_bodysize_abort) { - unset(self::$connections[$connectionId]); - return false; - } else { + if(isset($this->resp_headers['content-length']) && + !isset($this->resp_headers['transfer-encoding']) && + $this->resp_headers['content-length'] == $r_size){ + // we read the content-length, finish here break; } } - if(isset($this->resp_headers['content-length']) && - !isset($this->resp_headers['transfer-encoding']) && - $this->resp_headers['content-length'] == $r_size){ - // we read the content-length, finish here - break; - } } + + } catch (HTTPClientException $err) { + $this->error = $err->getMessage(); + if ($err->getCode()) + $this->status = $err->getCode(); + unset(self::$connections[$connectionId]); + fclose($socket); + return false; } if (!$this->keep_alive || -- cgit v1.2.3 From 62699eac09eab66c5c19413bf629daf9d5d6247d Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Sun, 17 Jun 2012 01:06:18 -0400 Subject: Utility functions for reading from a socket. Reading from a socket is handled by functions that encapsulate the error handling and timeout conditions. _readData reads blocks of data. _readLine reads a single line. --- inc/HTTPClient.php | 113 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 75 insertions(+), 38 deletions(-) diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index f11621f6a..ab41257bd 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -281,9 +281,6 @@ class HTTPClient { $headers['Proxy-Authorization'] = 'Basic '.base64_encode($this->proxy_user.':'.$this->proxy_pass); } - // stop time - $start = time(); - // already connected? $connectionId = $this->_uniqueConnectionId($server,$port); $this->_debug('connection pool', self::$connections); @@ -333,8 +330,9 @@ class HTTPClient { $written = 0; while($written < $towrite){ // check timeout - if(time()-$start > $this->timeout) - throw new HTTPClientException(sprintf('Timeout while sending request (%.3fs)',$this->_time() - $this->start), -100); + $time_used = $this->_time() - $this->start; + if($time_used > $this->timeout) + throw new HTTPClientException(sprintf('Timeout while sending request (%.3fs)',$time_used), -100); // wait for stream ready or timeout (1sec) if(@stream_select($sel_r,$sel_w,$sel_e,1) === false){ @@ -355,13 +353,9 @@ class HTTPClient { // read headers from socket $r_headers = ''; do{ - if(time()-$start > $this->timeout) - throw new HTTPClientException(sprintf('Timeout while reading headers (%.3fs)',$this->_time() - $this->start), -100); - if(feof($socket)) - throw new HTTPClientException('Premature End of File (socket)'); - usleep(1000); - $r_headers .= fgets($socket,1024); - }while(!preg_match('/\r?\n\r?\n$/',$r_headers)); + $r_line = $this->_readLine($socket, 'headers'); + $r_headers .= $r_line; + }while($r_line != "\r\n" && $r_line != "\n"); $this->_debug('response headers',$r_headers); @@ -436,28 +430,19 @@ class HTTPClient { //read body (with chunked encoding if needed) $r_body = ''; if(preg_match('/transfer\-(en)?coding:\s*chunked\r\n/i',$r_headers)){ - stream_set_blocking($socket,1); do { $chunk_size = ''; do { - if(feof($socket)) - throw new HTTPClientException('Premature End of File (socket)'); - if(time()-$start > $this->timeout) - throw new HTTPClientException(sprintf('Timeout while reading chunk (%.3fs)',$this->_time() - $this->start), -100); - $byte = fread($socket,1); + $byte = $this->_readData($socket, 1, 'chunk'); $chunk_size .= $byte; } while (preg_match('/^[a-zA-Z0-9]?$/',$byte)); // read chunksize including \r - - $byte = fread($socket,1); // readtrailing \n + $byte = $this->_readData($socket, 1, 'chunk'); // readtrailing \n $chunk_size = hexdec($chunk_size); + + // TODO: validate max_bodysize here to avoid the costly read if ($chunk_size) { - $read_size = $chunk_size; - while ($read_size > 0) { - $this_chunk = fread($socket,$read_size); - $r_body .= $this_chunk; - $read_size -= strlen($this_chunk); - } - $byte = fread($socket,2); // read trailing \r\n + $r_body .= $this->_readData($socket, $chunk_size, 'chunk'); + $byte = $this->_readData($socket, 2, 'chunk'); // read trailing \r\n } if($this->max_bodysize && strlen($r_body) > $this->max_bodysize){ @@ -467,24 +452,16 @@ class HTTPClient { break; } } while ($chunk_size); - stream_set_blocking($socket,0); }else{ // read entire socket while (!feof($socket)) { - if(time()-$start > $this->timeout){ - $this->status = -100; - $this->error = sprintf('Timeout while reading response (%.3fs)',$this->_time() - $this->start); - unset(self::$connections[$connectionId]); - return false; - } - $r_body .= fread($socket,4096); + $r_body .= $this->_readData($socket, 0, 'response', true); $r_size = strlen($r_body); if($this->max_bodysize && $r_size > $this->max_bodysize){ - $this->error = 'Allowed response size exceeded'; if ($this->max_bodysize_abort) { - unset(self::$connections[$connectionId]); - return false; + throw new HTTPClientException('Allowed response size exceeded'); } else { + $this->error = 'Allowed response size exceeded'; break; } } @@ -532,6 +509,66 @@ class HTTPClient { return true; } + /** + * Safely read data from a socket + * + * Reads up to a given number of bytes or throws an exception if the + * response times out or ends prematurely. If the number of bytes to + * read is negative, then it will read up to the absolute value, but + * may read less. A value of 0 returns an arbitrarily sized block, + * and a positive value will return exactly that many bytes. + * + * @param handle $socket An open socket handle in non-blocking mode + * @param int $nbytes Number of bytes to read + * @param string $message Description of what is being read + * @param bool $ignore_eof End-of-file is not an error if this is set + * @author Tom N Harris + */ + function _readData($socket, $nbytes, $message, $ignore_eof = false) { + $r_data = ''; + $to_read = $nbytes ? $nbytes : 4096; + if ($to_read < 0) $to_read = -$to_read; + do { + $time_used = $this->_time() - $this->start; + if ($time_used > $this->timeout) + throw new HTTPClientException( + sprintf('Timeout while reading %s (%.3fs)', $message, $time_used), + -100); + if(!$ignore_eof && feof($socket)) + throw new HTTPClientException("Premature End of File (socket) while reading $message"); + //usleep(1000); + $bytes = fread($socket, $to_read); + $r_data .= $bytes; + $to_read -= strlen($bytes); + } while (strlen($r_data) < $nbytes); + return $r_data; + } + + /** + * Safely read a \n-terminated line from a socket + * + * Always returns a complete line, including the terminating \n. + * + * @param handle $socket An open socket handle in non-blocking mode + * @param string $message Description of what is being read + * @author Tom N Harris + */ + function _readLine($socket, $message) { + $r_data = ''; + do { + $time_used = $this->_time() - $this->start; + if ($time_used > $this->timeout) + throw new HTTPClientException( + sprintf('Timeout while reading %s (%.3fs)', $message, $time_used), + -100); + if(feof($socket)) + throw new HTTPClientException("Premature End of File (socket) while reading $message"); + usleep(1000); + $r_data .= fgets($socket, 1024); + } while (!preg_match('/\n$/',$r_data)); + return $r_data; + } + /** * print debug info * -- cgit v1.2.3 From d37a395509092f21060e2a042a2be0ea759f6d0b Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Tue, 19 Jun 2012 03:17:21 -0400 Subject: Unit test for HTTPClient chunked encoding --- _test/tests/inc/httpclient_http.test.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/_test/tests/inc/httpclient_http.test.php b/_test/tests/inc/httpclient_http.test.php index 9cae3736a..cf8137152 100644 --- a/_test/tests/inc/httpclient_http.test.php +++ b/_test/tests/inc/httpclient_http.test.php @@ -176,5 +176,15 @@ class httpclient_http_test extends DokuWikiTest { $this->assertArrayHasKey('foo',$http->resp_headers); $this->assertEquals('bar',$http->resp_headers['foo']); } + + /** + * @group internet + */ + function test_chunked(){ + $http = new HTTPClient(); + $data = $http->get('http://whoopdedo.org/cgi-bin/chunked/2550'); + $this->assertFalse($data === false, 'HTTP response'); + $this->assertEquals(2550,strlen($data)); + } } //Setup VIM: ex: et ts=4 : -- cgit v1.2.3 From 50d1968dceb92179b9a581e34a84d516b81511ce Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Tue, 19 Jun 2012 22:40:39 -0400 Subject: Utility function for writing to a socket --- inc/HTTPClient.php | 71 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index ab41257bd..ea9b42862 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -308,8 +308,8 @@ class HTTPClient { } try { - //set blocking - stream_set_blocking($socket,1); + //set non-blocking + stream_set_blocking($socket, false); // build request $request = "$method $request_url HTTP/".$this->http.HTTP_NL; @@ -319,36 +319,7 @@ class HTTPClient { $request .= $data; $this->_debug('request',$request); - - // select parameters - $sel_r = null; - $sel_w = array($socket); - $sel_e = null; - - // send request - $towrite = strlen($request); - $written = 0; - while($written < $towrite){ - // check timeout - $time_used = $this->_time() - $this->start; - if($time_used > $this->timeout) - throw new HTTPClientException(sprintf('Timeout while sending request (%.3fs)',$time_used), -100); - - // wait for stream ready or timeout (1sec) - if(@stream_select($sel_r,$sel_w,$sel_e,1) === false){ - usleep(1000); - continue; - } - - // write to stream - $ret = fwrite($socket, substr($request,$written,4096)); - if($ret === false) - throw new HTTPClientException('Failed writing to socket', -100); - $written += $ret; - } - - // continue non-blocking - stream_set_blocking($socket,0); + $this->_sendData($socket, $request, 'request'); // read headers from socket $r_headers = ''; @@ -509,6 +480,42 @@ class HTTPClient { return true; } + /** + * Safely write data to a socket + * + * @param handle $socket An open socket handle + * @param string $data The data to write + * @param string $message Description of what is being read + * @author Tom N Harris + */ + function _sendData($socket, $data, $message) { + // select parameters + $sel_r = null; + $sel_w = array($socket); + $sel_e = null; + + // send request + $towrite = strlen($data); + $written = 0; + while($written < $towrite){ + // check timeout + $time_used = $this->_time() - $this->start; + if($time_used > $this->timeout) + throw new HTTPClientException(sprintf('Timeout while sending %s (%.3fs)',$message, $time_used), -100); + if(feof($socket)) + throw new HTTPClientException("Socket disconnected while writing $message"); + + // wait for stream ready or timeout + if(@stream_select($sel_r, $sel_w, $sel_e, $this->timeout - $time_used) !== false){ + // write to stream + $nbytes = fwrite($socket, substr($data,$written,4096)); + if($nbytes === false) + throw new HTTPClientException("Failed writing to socket while sending $message", -100); + $written += $nbytes; + } + } + } + /** * Safely read data from a socket * -- cgit v1.2.3 From 288188afa98cd0ff65b2c2bf529fba0bff15f634 Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Tue, 19 Jun 2012 23:42:00 -0400 Subject: HTTP headers are already parsed, there is no need for regexp --- inc/HTTPClient.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index ea9b42862..534ba220c 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -400,7 +400,8 @@ class HTTPClient { //read body (with chunked encoding if needed) $r_body = ''; - if(preg_match('/transfer\-(en)?coding:\s*chunked\r\n/i',$r_headers)){ + if((isset($this->resp_headers['transfer-encoding']) && $this->resp_headers['transfer-encoding'] == 'chunked') + || (isset($this->resp_headers['transfer-coding']) && $this->resp_headers['transfer-coding'] == 'chunked')){ do { $chunk_size = ''; do { -- cgit v1.2.3 From 24f112d0c2604958ac73923f758d9d37f229ff11 Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Wed, 20 Jun 2012 00:52:10 -0400 Subject: Efficiently wait on sockets --- inc/HTTPClient.php | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index 534ba220c..f6ab91f4f 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -507,7 +507,8 @@ class HTTPClient { throw new HTTPClientException("Socket disconnected while writing $message"); // wait for stream ready or timeout - if(@stream_select($sel_r, $sel_w, $sel_e, $this->timeout - $time_used) !== false){ + self::selecttimeout($this->timeout - $time_used, $sec, $usec); + if(@stream_select($sel_r, $sel_w, $sel_e, $sec, $usec) !== false){ // write to stream $nbytes = fwrite($socket, substr($data,$written,4096)); if($nbytes === false) @@ -533,6 +534,11 @@ class HTTPClient { * @author Tom N Harris */ function _readData($socket, $nbytes, $message, $ignore_eof = false) { + // select parameters + $sel_r = array($socket); + $sel_w = null; + $sel_e = null; + $r_data = ''; $to_read = $nbytes ? $nbytes : 4096; if ($to_read < 0) $to_read = -$to_read; @@ -544,10 +550,16 @@ class HTTPClient { -100); if(!$ignore_eof && feof($socket)) throw new HTTPClientException("Premature End of File (socket) while reading $message"); - //usleep(1000); - $bytes = fread($socket, $to_read); - $r_data .= $bytes; - $to_read -= strlen($bytes); + + // wait for stream ready or timeout + self::selecttimeout($this->timeout - $time_used, $sec, $usec); + if(@stream_select($sel_r, $sel_w, $sel_e, $sec, $usec) !== false){ + $bytes = fread($socket, $to_read); + if($bytes === false) + throw new HTTPClientException("Failed reading from socket while reading $message", -100); + $r_data .= $bytes; + $to_read -= strlen($bytes); + } } while (strlen($r_data) < $nbytes); return $r_data; } @@ -562,6 +574,11 @@ class HTTPClient { * @author Tom N Harris */ function _readLine($socket, $message) { + // select parameters + $sel_r = array($socket); + $sel_w = null; + $sel_e = null; + $r_data = ''; do { $time_used = $this->_time() - $this->start; @@ -571,8 +588,12 @@ class HTTPClient { -100); if(feof($socket)) throw new HTTPClientException("Premature End of File (socket) while reading $message"); - usleep(1000); - $r_data .= fgets($socket, 1024); + + // wait for stream ready or timeout + self::selecttimeout($this->timeout - $time_used, $sec, $usec); + if(@stream_select($sel_r, $sel_w, $sel_e, $sec, $usec) !== false){ + $r_data = fgets($socket, 1024); + } } while (!preg_match('/\n$/',$r_data)); return $r_data; } @@ -597,11 +618,19 @@ class HTTPClient { /** * Return current timestamp in microsecond resolution */ - function _time(){ + static function _time(){ list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); } + /** + * Calculate seconds and microseconds + */ + static function selecttimeout($time, &$sec, &$usec){ + $sec = floor($time); + $usec = (int)(($time - $sec) * 1000000); + } + /** * convert given header string to Header array * -- cgit v1.2.3 From fbf63b6e769b92fc1964c09132dfc937910d04f3 Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Wed, 20 Jun 2012 01:29:15 -0400 Subject: Validate the size of a chunk before reading from the socket --- inc/HTTPClient.php | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index f6ab91f4f..901c46ec9 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -404,25 +404,26 @@ class HTTPClient { || (isset($this->resp_headers['transfer-coding']) && $this->resp_headers['transfer-coding'] == 'chunked')){ do { $chunk_size = ''; - do { - $byte = $this->_readData($socket, 1, 'chunk'); + while (preg_match('/^[a-zA-Z0-9]?$/',$byte=$this->_readData($socket,1,'chunk'))){ + // read chunksize until \r $chunk_size .= $byte; - } while (preg_match('/^[a-zA-Z0-9]?$/',$byte)); // read chunksize including \r + if (strlen($chunk_size) > 128) // set an abritrary limit on the size of chunks + throw new HTTPClientException('Allowed response size exceeded'); + } $byte = $this->_readData($socket, 1, 'chunk'); // readtrailing \n $chunk_size = hexdec($chunk_size); - // TODO: validate max_bodysize here to avoid the costly read - if ($chunk_size) { - $r_body .= $this->_readData($socket, $chunk_size, 'chunk'); - $byte = $this->_readData($socket, 2, 'chunk'); // read trailing \r\n - } - - if($this->max_bodysize && strlen($r_body) > $this->max_bodysize){ + if($this->max_bodysize && $chunk_size+strlen($r_body) > $this->max_bodysize){ if ($this->max_bodysize_abort) throw new HTTPClientException('Allowed response size exceeded'); $this->error = 'Allowed response size exceeded'; break; } + + if ($chunk_size) { + $r_body .= $this->_readData($socket, $chunk_size, 'chunk'); + $byte = $this->_readData($socket, 2, 'chunk'); // read trailing \r\n + } } while ($chunk_size); }else{ // read entire socket -- cgit v1.2.3 From 769b429a77368df14e3753f624466f658e971df6 Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Wed, 20 Jun 2012 03:00:18 -0400 Subject: HTTPClient will read up to max_bodysize if it can --- _test/tests/inc/httpclient_http.test.php | 6 ++++++ inc/HTTPClient.php | 10 ++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/_test/tests/inc/httpclient_http.test.php b/_test/tests/inc/httpclient_http.test.php index cf8137152..c3ee182dc 100644 --- a/_test/tests/inc/httpclient_http.test.php +++ b/_test/tests/inc/httpclient_http.test.php @@ -124,6 +124,12 @@ class httpclient_http_test extends DokuWikiTest { $http->max_bodysize = 250; $data = $http->get($this->server.'/stream/30'); $this->assertTrue($data === false, 'HTTP response'); + $http->max_bodysize_abort = false; + $data = $http->get($this->server.'/stream/30'); + $this->assertFalse($data === false, 'HTTP response'); + /* the current implementation will read in max_bodysize blocks, + and aborts if the response is larger, thus a limit of 2*max_bodysize */ + $this->assertLessThanOrEqual(500,strlen($data)); } /** diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index 901c46ec9..b5e665cb1 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -402,6 +402,7 @@ class HTTPClient { $r_body = ''; if((isset($this->resp_headers['transfer-encoding']) && $this->resp_headers['transfer-encoding'] == 'chunked') || (isset($this->resp_headers['transfer-coding']) && $this->resp_headers['transfer-coding'] == 'chunked')){ + $abort = false; do { $chunk_size = ''; while (preg_match('/^[a-zA-Z0-9]?$/',$byte=$this->_readData($socket,1,'chunk'))){ @@ -417,18 +418,19 @@ class HTTPClient { if ($this->max_bodysize_abort) throw new HTTPClientException('Allowed response size exceeded'); $this->error = 'Allowed response size exceeded'; - break; + $chunk_size = $this->max_bodysize - strlen($r_body); + $abort = true; } - if ($chunk_size) { + if ($chunk_size > 0) { $r_body .= $this->_readData($socket, $chunk_size, 'chunk'); $byte = $this->_readData($socket, 2, 'chunk'); // read trailing \r\n } - } while ($chunk_size); + } while ($chunk_size && !$abort); }else{ // read entire socket while (!feof($socket)) { - $r_body .= $this->_readData($socket, 0, 'response', true); + $r_body .= $this->_readData($socket, -$this->max_bodysize, 'response', true); $r_size = strlen($r_body); if($this->max_bodysize && $r_size > $this->max_bodysize){ if ($this->max_bodysize_abort) { -- cgit v1.2.3 From b3b97ef358f9141bc1f1b3ebec799a0ad0771f7e Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Wed, 20 Jun 2012 03:11:57 -0400 Subject: Skip over chunk extensions that nobody uses because RFC2616 says so --- inc/HTTPClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index b5e665cb1..73f5b89b4 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -411,7 +411,7 @@ class HTTPClient { if (strlen($chunk_size) > 128) // set an abritrary limit on the size of chunks throw new HTTPClientException('Allowed response size exceeded'); } - $byte = $this->_readData($socket, 1, 'chunk'); // readtrailing \n + $this->_readLine($socket, 'chunk'); // readtrailing \n $chunk_size = hexdec($chunk_size); if($this->max_bodysize && $chunk_size+strlen($r_body) > $this->max_bodysize){ -- cgit v1.2.3 From b16544225947102f664769aaeb02bd59a25fbaa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EB=AA=85=EC=A7=84?= Date: Fri, 22 Jun 2012 09:56:20 +0200 Subject: Korean language update --- inc/lang/ko/backlinks.txt | 2 +- inc/lang/ko/conflict.txt | 2 +- inc/lang/ko/diff.txt | 4 +- inc/lang/ko/draft.txt | 4 +- inc/lang/ko/edit.txt | 3 +- inc/lang/ko/install.html | 10 ++--- inc/lang/ko/lang.php | 72 ++++++++++++++++---------------- inc/lang/ko/mailtext.txt | 2 +- inc/lang/ko/preview.txt | 2 +- inc/lang/ko/read.txt | 2 +- inc/lang/ko/register.txt | 2 +- inc/lang/ko/resetpwd.txt | 2 +- inc/lang/ko/revisions.txt | 4 +- inc/lang/ko/searchpage.txt | 2 +- inc/lang/ko/subscr_digest.txt | 3 +- inc/lang/ko/subscr_list.txt | 3 +- inc/lang/ko/subscr_single.txt | 2 +- inc/lang/ko/uploadmail.txt | 2 +- lib/plugins/acl/lang/ko/help.txt | 4 +- lib/plugins/acl/lang/ko/lang.php | 2 +- lib/plugins/config/lang/ko/intro.txt | 7 ++-- lib/plugins/config/lang/ko/lang.php | 56 ++++++++++++------------- lib/plugins/plugin/lang/ko/lang.php | 12 +++--- lib/plugins/popularity/lang/ko/intro.txt | 2 +- lib/plugins/popularity/lang/ko/lang.php | 4 +- lib/plugins/revert/lang/ko/intro.txt | 2 +- lib/plugins/revert/lang/ko/lang.php | 4 +- lib/plugins/usermanager/lang/ko/lang.php | 10 ++--- 28 files changed, 111 insertions(+), 115 deletions(-) diff --git a/inc/lang/ko/backlinks.txt b/inc/lang/ko/backlinks.txt index 5c512e19d..ce77ca5a7 100644 --- a/inc/lang/ko/backlinks.txt +++ b/inc/lang/ko/backlinks.txt @@ -1,3 +1,3 @@ -====== 이전 링크 ====== +====== 가리키는 링크 ====== 현재 문서를 가리키는 링크가 있는 문서 목록입니다. diff --git a/inc/lang/ko/conflict.txt b/inc/lang/ko/conflict.txt index bd41ebf75..43988a62b 100644 --- a/inc/lang/ko/conflict.txt +++ b/inc/lang/ko/conflict.txt @@ -2,4 +2,4 @@ 편집한 문서의 새 버전이 있습니다. 당신이 편집하고 있는 동안 다른 사람이 같은 파일을 편집하였을 경우 이런 일이 생길 수 있습니다. -아래의 차이점을 철저하게 검토하고 어떤 버전을 저장하실지 결정하십시오. **저장**을 선택하시면, 당신의 버전이 저장됩니다. **취소** 를 선택하시면 현재 버전이 유지됩니다. \ No newline at end of file +아래의 차이를 철저하게 검토하고 어떤 버전을 저장하실지 결정하십시오. **저장**을 선택하면, 당신의 버전이 저장됩니다. **취소**를 선택하면 현재 버전이 유지됩니다. \ No newline at end of file diff --git a/inc/lang/ko/diff.txt b/inc/lang/ko/diff.txt index 29189e9f0..76b488d90 100644 --- a/inc/lang/ko/diff.txt +++ b/inc/lang/ko/diff.txt @@ -1,3 +1,3 @@ -====== 차이점 ====== +====== 차이 ====== -이 문서의 선택한 이전 버전과 현재 버전 사이의 차이점을 보여줍니다. \ No newline at end of file +이 문서의 선택한 이전 버전과 현재 버전 사이의 차이를 보여줍니다. \ No newline at end of file diff --git a/inc/lang/ko/draft.txt b/inc/lang/ko/draft.txt index a20bfb535..861834e5d 100644 --- a/inc/lang/ko/draft.txt +++ b/inc/lang/ko/draft.txt @@ -1,5 +1,5 @@ -====== 문서 초안이 있습니다. ====== +====== 문서 초안 있음 ====== 이 문서의 마지막 편집 세션은 정상적으로 끝나지 않았습니다. DokuWiki는 작업 도중 자동으로 저장된 문서 초안을 사용하여 편집을 계속 할 수 있습니다. 마지막 세션 동안 저장된 문서 초안을 아래에서 볼 수 있습니다. -비정상적으로 끝난 편집 세션을 //복구//할지 여부를 결정하고, 자동으로 저장되었던 초안을 //삭제//하거나 편집 과정을 취소하기 바랍니다. \ No newline at end of file +비정상적으로 끝난 편집 세션을 **복구**할지 여부를 결정하고, 자동으로 저장되었던 초안을 **삭제**하거나 편집 과정을 **취소**하기 바랍니다. \ No newline at end of file diff --git a/inc/lang/ko/edit.txt b/inc/lang/ko/edit.txt index 606c8429c..f52326a33 100644 --- a/inc/lang/ko/edit.txt +++ b/inc/lang/ko/edit.txt @@ -1,2 +1 @@ -문서를 편집하고 **저장**을 누르세요. 위키 구문은 [[wiki:syntax]] 또는 [[wiki:ko_syntax|(한국어) 구문]]을 참고하세요. 이 문서를 **더 낫게 만들 자신이 있을** 때에만 편집하십시오. 연습을 하고 싶다면 먼저 [[playground:playground|연습장]]에 가서 연습하세요. - +문서를 편집하고 **저장**을 누르세요. 위키 구문은 [[wiki:syntax]] 또는 [[wiki:ko_syntax|(한국어) 구문]]을 참고하세요. 이 문서를 **더 좋게 만들 자신이 있을 때**에만 편집하세요. 연습을 하고 싶다면 먼저 [[playground:playground|연습장]]에 가서 연습하세요. diff --git a/inc/lang/ko/install.html b/inc/lang/ko/install.html index 6113d38b1..f73b91294 100644 --- a/inc/lang/ko/install.html +++ b/inc/lang/ko/install.html @@ -8,8 +8,8 @@

현재 설치 과정중에 관리자로 로그인 후 DokuWiki의 관리 메뉴(플러그인 설치, 사용자 관리, 위키 문서 접근 권한 관리, 옵션 설정)를 가능하게 ACL에 대한 환경 설정을 수행합니다. 이 것은 DokuWiki가 동작하는데 필요한 사항은 아니지만, 어쨌든 더 쉽게 관리자가 관리할 수 있도록 해줍니다.

-

숙련된 사용자들이나 특별한 설치 과정이 필요한 경우에 다음 링크들을 참고하기 바랍니다: -설치 과정(한국어) -과 환경 설정(한국어), -설치 과정(영어) -과 환경 설정(영어)

+

숙련된 사용자나 특별한 설치 과정이 필요한 경우에 다음 링크를 참고하기 바랍니다: +설치 과정 (한국어) +과 환경 설정 (한국어), +설치 과정 (영어) +과 환경 설정 (영어)

diff --git a/inc/lang/ko/lang.php b/inc/lang/ko/lang.php index 469e85bd6..7b4e30a49 100644 --- a/inc/lang/ko/lang.php +++ b/inc/lang/ko/lang.php @@ -40,7 +40,7 @@ $lang['btn_admin'] = '관리'; $lang['btn_update'] = '변경'; $lang['btn_delete'] = '삭제'; $lang['btn_back'] = '뒤로'; -$lang['btn_backlink'] = '이전 링크'; +$lang['btn_backlink'] = '가리키는 링크'; $lang['btn_backtomedia'] = '미디어 파일 선택으로 돌아가기'; $lang['btn_subscribe'] = '구독 관리'; $lang['btn_profile'] = '개인 정보 변경'; @@ -66,21 +66,21 @@ $lang['profile'] = '개인 정보'; $lang['badlogin'] = '잘못된 사용자 이름이거나 비밀번호입니다.'; $lang['minoredit'] = '사소한 바뀜'; $lang['draftdate'] = '문서 초안 자동 저장 시간'; -$lang['nosecedit'] = '문서가 수정되어 세션 정보가 달라져 문서 전부를 다시 읽습니다.'; +$lang['nosecedit'] = '문서가 수정되어 세션 정보의 유효 시간이 지나 문서 전부를 다시 읽습니다.'; $lang['regmissing'] = '모든 항목을 입력해야 합니다.'; $lang['reguexists'] = '같은 이름을 사용하는 사용자가 있습니다.'; $lang['regsuccess'] = '사용자를 만들었으며 비밀번호는 이메일로 보냈습니다.'; $lang['regsuccess2'] = '사용자를 만들었습니다.'; $lang['regmailfail'] = '비밀번호를 이메일로 전송할 때 오류가 발생했습니다. 관리자에게 문의하기 바랍니다!'; -$lang['regbadmail'] = '이메일 주소가 잘못됐습니다. - 오류라고 생각하면 관리자에게 문의하기 바랍니다.'; -$lang['regbadpass'] = '새 비밀번호들이 일치하지 않습니다. 다시 입력하기 바랍니다.'; +$lang['regbadmail'] = '이메일 주소가 잘못됐습니다 - 오류라고 생각하면 관리자에게 문의하기 바랍니다.'; +$lang['regbadpass'] = '새 비밀번호가 일치하지 않습니다. 다시 입력하기 바랍니다.'; $lang['regpwmail'] = 'DokuWiki 비밀번호'; -$lang['reghere'] = '아직 등록하지 않았다면 등록하기 바랍니다.'; -$lang['profna'] = '이 위키는 개인 정보 수정을 허용하지 않습니다.'; +$lang['reghere'] = '계정이 없나요? 계정을 등록할 수 있습니다'; +$lang['profna'] = '이 위키는 개인 정보 수정을 허용하지 않습니다'; $lang['profnochange'] = '바뀐 사항이 없습니다.'; $lang['profnoempty'] = '이름이나 이메일 주소가 비었습니다.'; $lang['profchanged'] = '개인 정보가 성공적으로 바뀌었습니다.'; -$lang['pwdforget'] = '비밀번호를 잊어버렸나요? 새로 발급받을 수 있습니다.'; +$lang['pwdforget'] = '비밀번호를 잊으셨나요? 새로 발급받을 수 있습니다'; $lang['resendna'] = '이 위키는 비밀번호 재발급을 지원하지 않습니다.'; $lang['resendpwd'] = '다음으로 새 비밀번호 전송'; $lang['resendpwdmissing'] = '모든 비밀번호를 입력해야 합니다.'; @@ -88,12 +88,12 @@ $lang['resendpwdnouser'] = '등록된 사용자가 아닙니다.'; $lang['resendpwdbadauth'] = '인증 코드가 잘못됐습니다. 잘못된 링크인지 확인 바랍니다.'; $lang['resendpwdconfirm'] = '확인 링크를 이메일로 보냈습니다.'; $lang['resendpwdsuccess'] = '새로운 비밀번호를 이메일로 보냈습니다.'; -$lang['license'] = '이 위키의 내용은 다음의 라이선스에 따릅니다:'; +$lang['license'] = '별도로 라이선스를 알리지 않을 경우, 이 위키의 내용은 다음의 라이선스에 따릅니다:'; $lang['licenseok'] = '참고: 이 문서를 편집할 경우 다음의 라이선스에 동의함을 의미합니다:'; $lang['searchmedia'] = '파일 이름 찾기:'; $lang['searchmedia_in'] = '%s에서 찾기'; -$lang['txt_upload'] = '올릴 파일을 선택합니다.'; -$lang['txt_filename'] = '올릭 파일 이름을 입력합니다. (선택 사항)'; +$lang['txt_upload'] = '올릴 파일 선택'; +$lang['txt_filename'] = '올릴 파일 이름 입력 (선택 사항)'; $lang['txt_overwrt'] = '이전 파일을 새로운 파일로 덮어쓰기'; $lang['maxuploadsize'] = '최대 올리기 용량. 파일당 %s'; $lang['lockedby'] = '현재 잠겨진 사용자'; @@ -124,7 +124,7 @@ $lang['js']['medialeft'] = '왼쪽 배치'; $lang['js']['mediaright'] = '오른쪽 배치'; $lang['js']['mediacenter'] = '가운데 배치'; $lang['js']['medianoalign'] = '배치 없음'; -$lang['js']['nosmblinks'] = '윈도우 공유 파일과의 연결은 MS 인터넷 익스플로러에서만 동작합니다.\n그러나 링크를 복사하거나 붙여넣기를 할 수 있습니다.'; +$lang['js']['nosmblinks'] = '윈도우 공유 파일과의 연결은 마이크로소프트 인터넷 익스플로러에서만 동작합니다.\n그러나 링크를 복사하거나 붙여넣기를 할 수 있습니다.'; $lang['js']['linkwiz'] = '링크 마법사'; $lang['js']['linkto'] = '다음으로 연결:'; $lang['js']['del_confirm'] = '정말 선택된 항목을 삭제하겠습니까?'; @@ -133,7 +133,7 @@ $lang['js']['media_diff'] = '차이 보기:'; $lang['js']['media_diff_both'] = '나란히 보기'; $lang['js']['media_diff_opacity'] = '겹쳐 보기'; $lang['js']['media_diff_portions'] = '쪼개 보기'; -$lang['js']['media_select'] = '파일 선택...'; +$lang['js']['media_select'] = '파일 선택…'; $lang['js']['media_upload_btn'] = '올리기'; $lang['js']['media_done_btn'] = '완료'; $lang['js']['media_drop'] = '올릴 파일을 끌어넣으세요'; @@ -147,24 +147,24 @@ $lang['uploadsucc'] = '올리기 성공'; $lang['uploadfail'] = '올리기 실패. 잘못된 권한 때문일지도 모릅니다.'; $lang['uploadwrong'] = '올리기 거부. 금지된 확장자입니다!'; $lang['uploadexist'] = '파일이 이미 존재합니다.'; -$lang['uploadbadcontent'] = '올린 파일이 파일 확장자 %s와 일치하지 않습니다.'; +$lang['uploadbadcontent'] = '올린 파일이 %s 파일 확장자와 일치하지 않습니다.'; $lang['uploadspam'] = '스팸 차단 목록이 올리기를 취소했습니다.'; $lang['uploadxss'] = '악성 코드의 가능성이 있어 올리기를 취소했습니다.'; $lang['uploadsize'] = '올린 파일이 너무 큽니다. (최대 %s)'; $lang['deletesucc'] = '"%s" 파일이 삭제되었습니다.'; -$lang['deletefail'] = '"%s" 파일을 삭제할 수 없습니다. - 삭제 권한이 있는지 확인하기 바랍니다.'; -$lang['mediainuse'] = '"%s" 파일을 삭제할 수 없습니다. - 아직 사용 중입니다.'; +$lang['deletefail'] = '"%s" 파일을 삭제할 수 없습니다 - 삭제 권한이 있는지 확인하기 바랍니다.'; +$lang['mediainuse'] = '"%s" 파일을 삭제할 수 없습니다 - 아직 사용 중입니다.'; $lang['namespaces'] = '이름공간'; $lang['mediafiles'] = '사용 가능한 파일 목록'; $lang['accessdenied'] = '이 문서를 볼 권한이 없습니다.'; $lang['mediausage'] = '이 파일을 참고하려면 다음 문법을 사용하기 바랍니다:'; $lang['mediaview'] = '원본 파일 보기'; -$lang['mediaroot'] = '루트(root)'; -$lang['mediaupload'] = '파일을 현재 이름공간으로 올립니다. 하위 이름공간으로 만들려면 파일 이름 앞에 콜론(:)으로 구분되는 이름을 붙이면 됩니다.'; -$lang['mediaextchange'] = '파일 확장자가 .%s에서 .%s으로 바뀌었습니다!'; +$lang['mediaroot'] = '루트 (root)'; +$lang['mediaupload'] = '파일을 현재 이름공간으로 올립니다. 하위 이름공간으로 만들려면 선택한 파일 이름 앞에 콜론(:)으로 구분되는 이름을 붙이면 됩니다. 파일을 드래그 앤 드롭하여 선택할 수 있습니다.'; +$lang['mediaextchange'] = '파일 확장자가 .%s에서 .%s(으)로 바뀌었습니다!'; $lang['reference'] = '참고'; $lang['ref_inuse'] = '다음 문서에서 아직 사용 중이므로 파일을 삭제할 수 없습니다:'; -$lang['ref_hidden'] = '문서의 일부 참고는 읽을 수 있는 권한이 없습니다.'; +$lang['ref_hidden'] = '문서의 일부 참고는 읽을 수 있는 권한이 없습니다'; $lang['hits'] = '조회 수'; $lang['quickhits'] = '일치하는 문서 이름'; $lang['toc'] = '목차'; @@ -186,19 +186,19 @@ $lang['created'] = '새로 만듦'; $lang['restored'] = '이전 버전 복구 (%s)'; $lang['external_edit'] = '외부 편집기'; $lang['summary'] = '편집 요약'; -$lang['noflash'] = '이 컨텐츠를 표시하기 위해서 Adobe Flash 플러그인이 필요합니다.'; +$lang['noflash'] = '이 콘텐츠를 표시하기 위해서 Adobe Flash 플러그인이 필요합니다.'; $lang['download'] = '조각 다운로드'; $lang['tools'] = '도구'; $lang['user_tools'] = '사용자 도구'; $lang['site_tools'] = '사이트 도구'; $lang['page_tools'] = '문서 도구'; -$lang['skip_to_content'] = '컨텐츠 넘기기'; +$lang['skip_to_content'] = '콘텐츠 넘기기'; $lang['mail_newpage'] = '문서 추가:'; $lang['mail_changed'] = '문서 바뀜:'; $lang['mail_subscribe_list'] = '이름공간에서 바뀐 문서:'; $lang['mail_new_user'] = '새로운 사용자:'; $lang['mail_upload'] = '파일 첨부:'; -$lang['changes_type'] = '차이점 보기'; +$lang['changes_type'] = '차이 보기'; $lang['pages_changes'] = '문서'; $lang['media_changes'] = '미디어 파일'; $lang['both_changes'] = '미디어 파일과 문서 모두'; @@ -212,7 +212,7 @@ $lang['qb_h2'] = '2단계 문단 제목'; $lang['qb_h3'] = '3단계 문단 제목'; $lang['qb_h4'] = '4단계 문단 제목'; $lang['qb_h5'] = '5단계 문단 제목'; -$lang['qb_h'] = '제목'; +$lang['qb_h'] = '문단 제목'; $lang['qb_hs'] = '문단 제목 선택'; $lang['qb_hplus'] = '상위 문단 제목'; $lang['qb_hminus'] = '하위 문단 제목'; @@ -259,15 +259,15 @@ $lang['subscr_m_unsubscribe'] = '구독 취소'; $lang['subscr_m_subscribe'] = '구독'; $lang['subscr_m_receive'] = '받기'; $lang['subscr_style_every'] = '모든 바뀜을 이메일로 받기'; -$lang['subscr_style_digest'] = '각 문서의 바뀜을 요약 (매 %.2f 일 마다)'; -$lang['subscr_style_list'] = '마지막 이메일 이후 바뀐 문서의 목록 (매 %.2f 일 마다)'; +$lang['subscr_style_digest'] = '각 문서의 바뀜을 요약 (매 %.2f일 마다)'; +$lang['subscr_style_list'] = '마지막 이메일 이후 바뀐 문서의 목록 (매 %.2f일 마다)'; $lang['authmodfailed'] = '잘못된 사용자 인증 설정입니다. 관리자에게 문의하기 바랍니다.'; $lang['authtempfail'] = '사용자 인증이 일시적으로 불가능합니다. 만일 계속해서 문제가 발생하면 관리자에게 문의하기 바랍니다.'; -$lang['authpwdexpire'] = '현재 비밀번호를 설정한지 %d 일이 지났습니다. 새로 설정해주시기 바랍니다.'; +$lang['authpwdexpire'] = '현재 비밀번호를 설정한지 %d일이 지났습니다. 새로 설정해주시기 바랍니다.'; $lang['i_chooselang'] = '사용할 언어를 선택하세요'; $lang['i_installer'] = 'DokuWiki 설치'; $lang['i_wikiname'] = '위키 이름'; -$lang['i_enableacl'] = 'ACL 기능 사용 (권장 사항)'; +$lang['i_enableacl'] = 'ACL 기능 사용 (권장)'; $lang['i_superuser'] = '슈퍼 유저'; $lang['i_problems'] = '설치 중 아래와 같은 문제가 발생했습니다. 문제를 해결한 후 설치를 계속하기 바랍니다.'; $lang['i_modified'] = '보안 상의 이유로 이 스크립트는 수정되지 않은 새 Dokuwiki 설치에서만 동작됩니다. @@ -287,14 +287,14 @@ $lang['i_pol1'] = '공개 위키 (누구나 읽을 수 있지만, $lang['i_pol2'] = '닫힌 위키 (등록된 사용자만 읽기, 쓰기, 업로드가 가능합니다.)'; $lang['i_retry'] = '다시 시도'; $lang['i_license'] = '내용을 배포하기 위한 라이선스를 선택하세요:'; -$lang['recent_global'] = '%s 이름공간을 구독 중입니다. 전체 위키 최근 바뀜도 볼 수 있습니다.'; -$lang['years'] = '%d 년 전'; -$lang['months'] = '%d 개월 전'; -$lang['weeks'] = '%d 주 전'; -$lang['days'] = '%d 일 전'; -$lang['hours'] = '%d 시간 전'; -$lang['minutes'] = '%d 분 전'; -$lang['seconds'] = '%d 초 전'; +$lang['recent_global'] = '%s 이름공간을 구독 중입니다. 전체 위키의 최근 바뀜도 볼 수 있습니다.'; +$lang['years'] = '%d년 전'; +$lang['months'] = '%d개월 전'; +$lang['weeks'] = '%d주 전'; +$lang['days'] = '%d일 전'; +$lang['hours'] = '%d시간 전'; +$lang['minutes'] = '%d분 전'; +$lang['seconds'] = '%d초 전'; $lang['wordblock'] = '스팸 문구를 포함하고 있어서 저장되지 않았습니다.'; $lang['media_uploadtab'] = '올리기'; $lang['media_searchtab'] = '찾기'; @@ -319,4 +319,4 @@ $lang['media_perm_read'] = '이 파일을 읽을 권한이 없습니다.'; $lang['media_perm_upload'] = '파일을 올릴 권한이 없습니다.'; $lang['media_update'] = '새 버전 올리기'; $lang['media_restore'] = '이 버전으로 되돌리기'; -$lang['plugin_install_err'] = '플러그인 설치가 잘못되었습니다. 플러그인 디렉토리 \'%s\'를 \'%s\'로 바꾸십시오.'; +$lang['plugin_install_err'] = '플러그인 설치가 잘못되었습니다. 플러그인 디렉토리 \'%s\'(을)를 \'%s\'(으)로 바꾸십시오.'; diff --git a/inc/lang/ko/mailtext.txt b/inc/lang/ko/mailtext.txt index ead9d5695..219fe6e0b 100644 --- a/inc/lang/ko/mailtext.txt +++ b/inc/lang/ko/mailtext.txt @@ -1,4 +1,4 @@ -DokuWiki 문서가 추가 또는 변경되었습니다. 제세한 정보는 다음과 같습니다: +DokuWiki 문서가 추가 또는 변경되었습니다. 자세한 정보는 다음과 같습니다: 날짜 : @DATE@ 브라우저 : @BROWSER@ diff --git a/inc/lang/ko/preview.txt b/inc/lang/ko/preview.txt index fec01dc43..6563874ee 100644 --- a/inc/lang/ko/preview.txt +++ b/inc/lang/ko/preview.txt @@ -1,3 +1,3 @@ ====== 미리 보기 ====== -이것은 입력한 내용이 어떻게 보일지 미리 보여줍니다. 아직 **저장되지 않았다**는 점을 기억하십시오! \ No newline at end of file +이것은 입력한 내용이 어떻게 보일지 미리 보여줍니다. 아직 **저장되지 않았다**는 점을 기억해두십시오! \ No newline at end of file diff --git a/inc/lang/ko/read.txt b/inc/lang/ko/read.txt index 2daa39060..9b2ec822f 100644 --- a/inc/lang/ko/read.txt +++ b/inc/lang/ko/read.txt @@ -1,2 +1,2 @@ -이 문서는 읽기 전용입니다. 소스를 볼 수는 있지만, 수정할 수는 없습니다. 문제가 있다고 생각하면 관리자에게 문의하십시오. +이 문서는 읽기 전용입니다. 내용을 볼 수는 있지만, 수정할 수는 없습니다. 문제가 있다고 생각하면 관리자에게 문의하십시오. diff --git a/inc/lang/ko/register.txt b/inc/lang/ko/register.txt index e60368a74..6509bed91 100644 --- a/inc/lang/ko/register.txt +++ b/inc/lang/ko/register.txt @@ -1,3 +1,3 @@ ====== 새 사용자 등록 ====== -이 위키에 새 계정을 만드려면 아래의 모든 내용을 입력하세요. **올바른 이메일 주소**를 사용하세요. 비밀번호를 입력하는 곳이 없다면 비밀번호는 이 이메일로 보내집니다. 사용자 이름은 올바른 [[doku>pagename|pagename]] 이어야 합니다. \ No newline at end of file +이 위키에 새 계정을 만드려면 아래의 모든 내용을 입력하세요. **올바른 이메일 주소**를 사용하세요. 비밀번호를 입력하는 곳이 없다면 비밀번호는 이 이메일로 보내집니다. 사용자 이름은 올바른 [[doku>pagename|pagename]]이어야 합니다. \ No newline at end of file diff --git a/inc/lang/ko/resetpwd.txt b/inc/lang/ko/resetpwd.txt index bea380f83..ed909456f 100644 --- a/inc/lang/ko/resetpwd.txt +++ b/inc/lang/ko/resetpwd.txt @@ -1,3 +1,3 @@ ====== 새 비밀번호 설정 ====== -이 위키의 계정의 새 비밀번호를 입력하세요. \ No newline at end of file +이 위키 계정의 새 비밀번호를 입력하세요. \ No newline at end of file diff --git a/inc/lang/ko/revisions.txt b/inc/lang/ko/revisions.txt index 639b36c00..64733d86d 100644 --- a/inc/lang/ko/revisions.txt +++ b/inc/lang/ko/revisions.txt @@ -1,3 +1,3 @@ -====== 이전 판 ====== +====== 이전 버전 ====== -이 문서의 이전 판은 다음과 같습니다. 이전 판으로 돌아가려면, 아래에서 선택한 다음 **문서 편집**을 클릭하고 나서 저장하세요. \ No newline at end of file +이 문서의 이전 버전은 다음과 같습니다. 이전 버전으로 돌아가려면, 아래에서 선택한 다음 **문서 편집**을 클릭하고 나서 저장하세요. \ No newline at end of file diff --git a/inc/lang/ko/searchpage.txt b/inc/lang/ko/searchpage.txt index 92faeb010..2e8502b13 100644 --- a/inc/lang/ko/searchpage.txt +++ b/inc/lang/ko/searchpage.txt @@ -1,5 +1,5 @@ ====== 찾기 ====== -아래에서 찾기 결과를 볼 수 있습니다. 만일 원하는 것을 찾지 못하였다면, **해당 버튼**을 사용하여 쿼리 내용과 같은 이름의 문서를 만들거나 편집할 수 있습니다. +아래에서 찾기 결과를 볼 수 있습니다. 만일 원하는 것을 찾지 못하였다면, **문서 만들기**나 **문서 편집** 버튼을 사용하여 쿼리 내용과 같은 이름의 문서를 만들거나 편집할 수 있습니다. ===== 결과 ===== \ No newline at end of file diff --git a/inc/lang/ko/subscr_digest.txt b/inc/lang/ko/subscr_digest.txt index 667d0ce2c..13459428f 100644 --- a/inc/lang/ko/subscr_digest.txt +++ b/inc/lang/ko/subscr_digest.txt @@ -1,8 +1,7 @@ 안녕하세요! @TITLE@ 위키의 @PAGE@ 문서가 바뀌었습니다. - -차이점은 다음과 같습니다: +바뀐 점은 다음과 같습니다: -------------------------------------------------------- @DIFF@ diff --git a/inc/lang/ko/subscr_list.txt b/inc/lang/ko/subscr_list.txt index a3709cbd4..68adf0de9 100644 --- a/inc/lang/ko/subscr_list.txt +++ b/inc/lang/ko/subscr_list.txt @@ -1,8 +1,7 @@ 안녕하세요! @TITLE@ 위키의 @PAGE@ 문서가 바뀌었습니다. - -차이점은 다음과 같습니다: +바뀐 점은 다음과 같습니다: -------------------------------------------------------- @DIFF@ diff --git a/inc/lang/ko/subscr_single.txt b/inc/lang/ko/subscr_single.txt index 23973ed99..6bd1885e6 100644 --- a/inc/lang/ko/subscr_single.txt +++ b/inc/lang/ko/subscr_single.txt @@ -1,7 +1,7 @@ 안녕하세요! @TITLE@ 위키의 @PAGE@ 문서가 바뀌었습니다. -차이점은 다음과 같습니다: +바뀐 점은 다음과 같습니다: -------------------------------------------------------- @DIFF@ diff --git a/inc/lang/ko/uploadmail.txt b/inc/lang/ko/uploadmail.txt index 8195c189a..675c0bd3f 100644 --- a/inc/lang/ko/uploadmail.txt +++ b/inc/lang/ko/uploadmail.txt @@ -1,4 +1,4 @@ -DokuWiki가 파일을 올렸습니다. +DokuWiki가 파일을 올렸습니다. 자세한 정보는 다음과 같습니다: 파일 : @MEDIA@ 이전 버전 : @OLD@ diff --git a/lib/plugins/acl/lang/ko/help.txt b/lib/plugins/acl/lang/ko/help.txt index d022a0913..377636682 100644 --- a/lib/plugins/acl/lang/ko/help.txt +++ b/lib/plugins/acl/lang/ko/help.txt @@ -6,6 +6,6 @@ 위쪽 입력 양식에서 선택된 사용자와 그룹의 접근 권한을 보거나 바꿀 수 있습니다. -아래 테이블에서 현재 설정된 모든 접근 제어 규칙들을 볼 수 있으며, 즉시 여러 규칙들을 삭제하거나 바꿀 수 있습니다. +아래 테이블에서 현재 설정된 모든 접근 제어 규칙을 볼 수 있으며, 즉시 여러 규칙을 삭제하거나 바꿀 수 있습니다. -DokuWiki에서 접근 제어가 어떻게 동작되는지 알려면 [[doku>acl|ACL 공식 문서]]를 읽어보기 바랍니다. \ No newline at end of file +DokuWiki에서 접근 제어가 어떻게 동작되는지 알아보려면 [[doku>acl|ACL 공식 문서]]를 읽어보기 바랍니다. \ No newline at end of file diff --git a/lib/plugins/acl/lang/ko/lang.php b/lib/plugins/acl/lang/ko/lang.php index 5465461fa..c8e1ce5cc 100644 --- a/lib/plugins/acl/lang/ko/lang.php +++ b/lib/plugins/acl/lang/ko/lang.php @@ -27,7 +27,7 @@ $lang['p_group_id'] = '%s 그룹 구성원은 $lang['p_group_ns'] = '%s 그룹 구성원은 현재 %s: %s 이름공간 접근이 가능합니다.'; $lang['p_choose_id'] = '%s 문서 접근 권한을 보거나 바꾸려면 사용자그룹을 위 양식에 입력하기 바랍니다.'; $lang['p_choose_ns'] = '%s 이름공간 접근 권한을 보거나 바꾸려면 사용자그룹을 위 양식에 입력하기 바랍니다.'; -$lang['p_inherited'] = '참고: 권한이 명시적으로 설정되지 않았으므로 다른 그룹들이나 상위 이름공간으로부터 가져왔습니다.'; +$lang['p_inherited'] = '참고: 권한이 명시적으로 설정되지 않았으므로 다른 그룹이나 상위 이름공간으로부터 가져왔습니다.'; $lang['p_isadmin'] = '참고: 슈퍼유저로 설정되어 있으므로 선택된 그룹이나 사용자는 언제나 모든 접근 권한을 가집니다.'; $lang['p_include'] = '더 높은 접근 권한은 하위를 포함합니다. 문서가 아닌 이름공간에는 만들기, 올리기, 삭제 권한만 적용됩니다.'; $lang['current'] = '현재 ACL 규칙'; diff --git a/lib/plugins/config/lang/ko/intro.txt b/lib/plugins/config/lang/ko/intro.txt index 895a8c79e..f6b76ecfc 100644 --- a/lib/plugins/config/lang/ko/intro.txt +++ b/lib/plugins/config/lang/ko/intro.txt @@ -1,8 +1,7 @@ ====== 환경 설정 관리 ====== -DokuWiki 설치할 때 설정을 변경하기 위해 사용하는 페이지입니다. 각 설정에 대한 자세한 도움말이 필요하다면 [[doku>ko:config|설정 문서 (한국어)]]와 [[doku>config|설정 문서(영어)]]를 참고하세요. +DokuWiki 설치할 때 설정을 변경하기 위해 사용하는 페이지입니다. 각 설정에 대한 자세한 도움말이 필요하다면 [[doku>ko:config|설정 문서 (한국어)]]와 [[doku>config|설정 문서 (영어)]]를 참고하세요. -플러그인에 대한 자세한 정보가 필요하다면 [[doku>plugin:config|플러그인 설정]] 문서를 참고하세요. 붉은 배경색으로 보이는 설정은 이 플러그인에서 변경하지 못하도록 되어있습니다. 파란 배경색으로 보이는 설정은 기본 설정값을 가지고 있습니다. 하얀색 배경색으로 보이는 설정은 특별한 설치를 위해 설정되어 있습니다. 파란색과 하얀색 배경으로 된 설정은 수정 가능합니다. - -이 페이지를 끝내기 전에 **저장**버튼을 누르지 않으면 설정값은 적용되지 않습니다. +플러그인에 대한 자세한 정보가 필요하다면 [[doku>plugin:config|플러그인 설정]] 문서를 참고하세요. 빨간 배경색으로 보이는 설정은 이 플러그인에서 변경하지 못하도록 되어있습니다. 파란 배경색으로 보이는 설정은 기본 설정값을 가지고 있습니다. 하얀 배경색으로 보이는 설정은 특별한 설치를 위해 설정되어 있습니다. 파란색과 하얀색 배경으로 된 설정은 수정이 가능합니다. +이 페이지를 끝내기 전에 **저장** 버튼을 누르지 않으면 설정값은 적용되지 않습니다. diff --git a/lib/plugins/config/lang/ko/lang.php b/lib/plugins/config/lang/ko/lang.php index 191c08de6..5f90044e4 100644 --- a/lib/plugins/config/lang/ko/lang.php +++ b/lib/plugins/config/lang/ko/lang.php @@ -13,7 +13,7 @@ */ $lang['menu'] = '환경 설정'; $lang['error'] = '잘못된 값 때문에 설정을 변경할 수 없습니다. 수정한 값을 검토하고 확인을 누르세요. -
잘못된 값은 붉은 선으로 둘러싸여 있습니다.'; +
잘못된 값은 빨간 선으로 둘러싸여 있습니다.'; $lang['updated'] = '설정이 성공적으로 변경되었습니다.'; $lang['nochoice'] = '(다른 선택이 불가능합니다.)'; $lang['locked'] = '환경 설정 파일을 수정할 수 없습니다. 의도한 행동이 아니라면,
@@ -42,22 +42,22 @@ $lang['_template_sufix'] = '템플릿 설정'; $lang['_msg_setting_undefined'] = '설정되지 않은 메타데이터.'; $lang['_msg_setting_no_class'] = '설정되지 않은 클래스.'; $lang['_msg_setting_no_default'] = '기본값 없음.'; -$lang['title'] = '위키 제목(위키 이름)'; +$lang['title'] = '위키 제목 (위키 이름)'; $lang['start'] = '각 이름공간에서 사용할 시작 문서 이름'; $lang['lang'] = '인터페이스 언어'; -$lang['template'] = '템플릿(위키 디자인)'; -$lang['tagline'] = '태그 라인(템플릿이 지원할 때에 한함)'; -$lang['sidebar'] = '사이드바 문서 이름(템플릿이 지원할 때에 한함). 비워두면 사이드바를 비활성화함'; -$lang['license'] = '컨텐트에 어떤 라이선스를 적용하겠습니까?'; +$lang['template'] = '템플릿 (위키 디자인)'; +$lang['tagline'] = '태그 라인 (템플릿이 지원할 때에 한함)'; +$lang['sidebar'] = '사이드바 문서 이름 (템플릿이 지원할 때에 한함). 비워두면 사이드바를 비활성화'; +$lang['license'] = '콘텐츠에 어떤 라이선스를 적용하겠습니까?'; $lang['savedir'] = '데이타 저장 디렉토리'; -$lang['basedir'] = '서버 경로(예를 들어 /dokuwiki/). 자동 감지를 하려면 비우세요.'; -$lang['baseurl'] = '서버 URL(예를 들어 http://www.yourserver.com). 자동 감지를 하려면 비우세요.'; -$lang['cookiedir'] = '쿠키 위치. 비워두면 기본 url 위치로 지정됩니다.'; +$lang['basedir'] = '서버 경로 (예를 들어 /dokuwiki/). 자동 감지를 하려면 비우세요.'; +$lang['baseurl'] = '서버 URL (예를 들어 http://www.yourserver.com). 자동 감지를 하려면 비우세요.'; +$lang['cookiedir'] = '쿠키 위치. 비워두면 기본 URL 위치로 지정됩니다.'; $lang['dmode'] = '디렉토리 생성 모드'; $lang['fmode'] = '파일 생성 모드'; $lang['allowdebug'] = '디버그 허용 필요하지 않으면 금지!'; $lang['recent'] = '최근 바뀐 문서당 항목 수'; -$lang['recent_days'] = '최근 바뀐 문서 기준 시간(날짜)'; +$lang['recent_days'] = '최근 바뀐 문서 기준 시간 (날짜)'; $lang['breadcrumbs'] = '위치 "추적" 수. 0으로 설정하면 비활성화함.'; $lang['youarehere'] = '계층형 위치 추적 (다음 위의 옵션을 비활성화하고 싶습니다)'; $lang['fullpath'] = '문서 하단에 전체 경로 보여주기'; @@ -75,7 +75,7 @@ $lang['useheading'] = '문서 이름으로 첫 문단 제목 사용'; $lang['sneaky_index'] = '기본적으로 DokuWiki는 색인 목록에 모든 이름공간을 보여줍니다. 이 옵션을 설정하면 사용자가 읽기 권한을 가지고 있지 않은 이름공간은 보여주지 않습니다. 접근 가능한 하위 이름공간을 보이지 않게 설정하면 자동으로 설정됩니다. 특정 ACL 설정은 색인 사용이 불가능하게 할 수도 있습니다.'; $lang['hidepages'] = '사이트맵과 기타 자동 색인과 같은 찾기에서 정규 표현식과 일치하는 문서 숨기기'; -$lang['useacl'] = '접근 제어 목록(ACL) 사용'; +$lang['useacl'] = '접근 제어 목록 (ACL) 사용'; $lang['autopasswd'] = '자동으로 만들어진 비밀번호'; $lang['authtype'] = '인증 백-엔드'; $lang['passcrypt'] = '비밀번호 암호화 방법'; @@ -84,25 +84,25 @@ $lang['superuser'] = '슈퍼 유저 - ACL 설정과 상관없이 모 $lang['manager'] = '관리자 - 관리 기능을 사용할 수 있는 그룹이나 사용자. 사용자1,@그룹1,사용자2 쉼표로 구분한 목록'; $lang['profileconfirm'] = '개인 정보를 바꿀 때 비밀번호 다시 확인'; $lang['rememberme'] = '항상 로그인 정보 저장 허용 (기억하기)'; -$lang['disableactions'] = 'DokuWiki 활동 금지'; +$lang['disableactions'] = 'DokuWiki 활동 비활성화'; $lang['disableactions_check'] = '검사'; $lang['disableactions_subscription'] = '구독 신청/해지'; $lang['disableactions_wikicode'] = '내용 보기/원시 내보대기'; -$lang['disableactions_other'] = '다른 활동(쉼표로 구분)'; -$lang['auth_security_timeout'] = '인증 보안 초과 시간(초)'; +$lang['disableactions_other'] = '다른 활동 (쉼표로 구분)'; +$lang['auth_security_timeout'] = '인증 보안 초과 시간 (초)'; $lang['securecookie'] = 'HTTPS로 보내진 쿠키는 HTTPS에만 적용 할까요? 위키의 로그인 페이지만 SSL로 암호화하고 위키 문서는 그렇지 않은 경우 비활성화 합니다.'; $lang['remote'] = '원격 API를 활성화 합니다. 이 항목을 허용하면 XML-RPC 및 기타 메카니즘을 통해 다른 어플리케이션으로 접근가능합니다.'; $lang['remoteuser'] = '이 항목에 입력된 쉼표로 나눠진 그룹이나 사용자에게 원격 API 접근을 제한합니다. 빈칸으로 두면 모두에게 허용합니다.'; $lang['usewordblock'] = '금지 단어를 사용해 스팸 막기'; $lang['relnofollow'] = '외부 링크에 rel="nofollow" 사용'; -$lang['indexdelay'] = '색인 연기 시간(초)'; +$lang['indexdelay'] = '색인 연기 시간 (초)'; $lang['mailguard'] = '이메일 주소를 알아볼 수 없게 하기'; $lang['iexssprotect'] = '올린 파일의 악성 자바스크립트, HTML 코드 가능성 여부를 검사'; $lang['usedraft'] = '편집하는 동안 자동으로 문서 초안 저장'; $lang['htmlok'] = 'HTML 내장 허용'; $lang['phpok'] = 'PHP 내장 허용'; -$lang['locktime'] = '쵀대 파일 잠금 시간(초)'; -$lang['cachetime'] = '최대 캐쉬 생존 시간(초)'; +$lang['locktime'] = '최대 파일 잠금 시간(초)'; +$lang['cachetime'] = '최대 캐시 생존 시간 (초)'; $lang['target____wiki'] = '내부 링크에 대한 타겟 창'; $lang['target____interwiki'] = '인터위키 링크에 대한 타겟 창'; $lang['target____extern'] = '외부 링크에 대한 타겟 창'; @@ -114,7 +114,7 @@ $lang['refshow'] = '위의 설정이 활성화되었을 때 보여 $lang['gdlib'] = 'GD 라이브러리 버전'; $lang['im_convert'] = 'ImageMagick 변환 도구 위치'; $lang['jpg_quality'] = 'JPG 압축 품질 (0-100)'; -$lang['fetchsize'] = 'fetch.php가 외부에서 다운로드할 수도 있는 최대 크기(바이트)'; +$lang['fetchsize'] = 'fetch.php가 외부에서 다운로드할 수도 있는 최대 크기 (바이트)'; $lang['subscribers'] = '사용자가 이메일로 문서 바뀜에 구독하도록 허용'; $lang['subscribe_time'] = '구독 목록과 요약이 보내질 경과 시간 (초); 이 것은 recent_days에서 설정된 시간보다 작아야 합니다.'; $lang['notify'] = '항상 이 이메일 주소로 바뀜 알림을 보냄'; @@ -122,15 +122,15 @@ $lang['registernotify'] = '항상 새 사용자한테 이 이메일 주 $lang['mailfrom'] = '자동으로 보내지는 메일 발신자'; $lang['mailprefix'] = '자동으로 보내지는 메일의 제목 말머리 내용. 비웠을 경우 위키 제목 사용'; $lang['htmlmail'] = '용량은 조금 더 크지만 보기 좋은 HTML 태그가 포함된 메일을 발송합니다. 텍스트만의 메일을 보내고자하면 비활성화하세요.'; -$lang['sitemap'] = '구글 사이트맵 생성(날짜). 0일 경우 비활성화'; -$lang['rss_type'] = 'XML 피드 타잎'; +$lang['sitemap'] = '구글 사이트맵 생성 (날짜). 0일 경우 비활성화'; +$lang['rss_type'] = 'XML 피드 타입'; $lang['rss_linkto'] = 'XML 피드 링크 정보'; $lang['rss_content'] = 'XML 피드 항목에 표시되는 내용은?'; -$lang['rss_update'] = 'XML 피드 갱신 주기(초)'; +$lang['rss_update'] = 'XML 피드 업데이트 주기 (초)'; $lang['rss_show_summary'] = 'XML 피드 제목에서 요약정보 보여주기'; $lang['rss_media'] = '어떤 규격으로 XML 피드를 받아보시겠습니까?'; $lang['updatecheck'] = '업데이트와 보안 문제를 검사할까요? 이 기능을 사용하려면 DokuWiki를 update.dokuwiki.org에 연결해야 합니다.'; -$lang['userewrite'] = 'URL rewriting기능 사용'; +$lang['userewrite'] = '멋진 URL 사용'; $lang['useslash'] = 'URL에서 이름 구분자로 슬래시 문자 사용'; $lang['sepchar'] = '문서 이름 단어 구분자'; $lang['canonical'] = '완전한 canonical URL 사용'; @@ -179,10 +179,10 @@ $lang['rss_type_o_rss2'] = 'RSS 2.0'; $lang['rss_type_o_atom'] = 'Atom 0.3'; $lang['rss_type_o_atom1'] = 'Atom 1.0'; $lang['rss_content_o_abstract'] = '개요'; -$lang['rss_content_o_diff'] = '통합 차이점 목록'; -$lang['rss_content_o_htmldiff'] = 'HTML 차이점 목록 형식'; -$lang['rss_content_o_html'] = '최대로 HTML 페이지 내용'; -$lang['rss_linkto_o_diff'] = '차이점 보기'; +$lang['rss_content_o_diff'] = '통합 차이 목록'; +$lang['rss_content_o_htmldiff'] = 'HTML 차이 목록 형식'; +$lang['rss_content_o_html'] = '최대 HTML 페이지 내용'; +$lang['rss_linkto_o_diff'] = '차이 보기'; $lang['rss_linkto_o_page'] = '바뀐 문서 보기'; $lang['rss_linkto_o_rev'] = '바뀐 목록 보기'; $lang['rss_linkto_o_current'] = '현재 문서 보기'; @@ -195,10 +195,10 @@ $lang['xsendfile_o_2'] = '표준 X-Sendfile 헤더'; $lang['xsendfile_o_3'] = '비공개 Nginx X-Accel-Redirect 헤더'; $lang['showuseras_o_loginname'] = '로그인 이름'; $lang['showuseras_o_username'] = '사용자 이름'; -$lang['showuseras_o_email'] = '사용자 이메일 주소(메일 주소 보호 설정에 따라 안보일 수 있음)'; +$lang['showuseras_o_email'] = '사용자 이메일 주소 (메일 주소 보호 설정에 따라 안보일 수 있음)'; $lang['showuseras_o_email_link'] = 'mailto: link로 표현될 사용자 이메일 주소'; $lang['useheading_o_0'] = '아니오'; $lang['useheading_o_navigation'] = '둘러보기에만'; $lang['useheading_o_content'] = '위키 내용에만'; $lang['useheading_o_1'] = '항상'; -$lang['readdircache'] = 'readdir 캐쉬를 위한 최대 시간 (초)'; +$lang['readdircache'] = 'readdir 캐시를 위한 최대 시간 (초)'; diff --git a/lib/plugins/plugin/lang/ko/lang.php b/lib/plugins/plugin/lang/ko/lang.php index 9e1fbfcae..4fc6fd1d9 100644 --- a/lib/plugins/plugin/lang/ko/lang.php +++ b/lib/plugins/plugin/lang/ko/lang.php @@ -22,18 +22,18 @@ $lang['btn_download'] = '다운로드'; $lang['btn_enable'] = '저장'; $lang['url'] = 'URL'; $lang['installed'] = '설치됨:'; -$lang['lastupdate'] = '최근 업데이트됨:'; +$lang['lastupdate'] = '가장 나중에 업데이트됨:'; $lang['source'] = '내용:'; $lang['unknown'] = '알 수 없음'; $lang['updating'] = '업데이트 중 ...'; -$lang['updated'] = '%s 플러그인이 성공적으로 업데이트했습니다.'; -$lang['updates'] = '다음 플러그인들이 성공적으로 업데이트했습니다:'; +$lang['updated'] = '%s 플러그인을 성공적으로 업데이트했습니다'; +$lang['updates'] = '다음 플러그인을 성공적으로 업데이트했습니다'; $lang['update_none'] = '업데이트를 찾을 수 없습니다.'; $lang['deleting'] = '삭제 중 ...'; $lang['deleted'] = '%s 플러그인이 삭제되었습니다.'; $lang['downloading'] = '다운로드 중 ...'; $lang['downloaded'] = '%s 플러그인이 성공적으로 설치되었습니다.'; -$lang['downloads'] = '다음 플러그인들이 성공적으로 설치되었습니다:'; +$lang['downloads'] = '다음 플러그인이 성공적으로 설치되었습니다:'; $lang['download_none'] = '플러그인이 없거나 다운로드 또는 설치 중에 알 수 없는 문제가 발생했습니다.'; $lang['plugin'] = '플러그인:'; $lang['components'] = '구성 요소'; @@ -46,7 +46,7 @@ $lang['author'] = '만든이:'; $lang['www'] = '웹:'; $lang['error'] = '알 수 없는 문제가 발생했습니다.'; $lang['error_download'] = '플러그인 파일을 다운로드 할 수 없습니다: %s'; -$lang['error_badurl'] = '잘못된 URL 같습니다. - URL에서 파일 이름을 알 수 없습니다.'; +$lang['error_badurl'] = '잘못된 URL 같습니다 - URL에서 파일 이름을 알 수 없습니다.'; $lang['error_dircreate'] = '다운로드를 받기 위한 임시 디렉토리를 만들 수 없습니다.'; $lang['error_decompress'] = '플러그인 관리자가 다운로드 받은 파일을 압축을 풀 수 없습니다. 잘못 다운로드 받았을 수도 있으니 다시 한번 시도해보기 바랍니다. 또는 압축 포맷을 알 수 없는 경우에는 다운로드한 후 수동으로 직접 설치하기 바랍니다.'; $lang['error_copy'] = '플러그인을 설치하는 동안 파일 복사하는 데 오류가 발생했습니다. %s: 디스크가 꽉 찼거나 파일 접근 권한이 잘못된 경우입니다. 플러그인 설치가 부분적으로만 이루어졌을 것입니다. 설치가 불완전합니다.'; @@ -55,4 +55,4 @@ $lang['enabled'] = '%s 플러그인을 활성화했습니다.'; $lang['notenabled'] = '%s 플러그인을 활성화할 수 없습니다. 파일 권한을 확인하십시오.'; $lang['disabled'] = '%s 플러그인을 비활성화했습니다.'; $lang['notdisabled'] = '%s 플러그인을 비활성화할 수 없습니다. 파일 권한을 확인하십시오.'; -$lang['packageinstalled'] = '플러그인 패키지(%d 개의 플러그인: %s)가 성공적으로 설치되었습니다.'; +$lang['packageinstalled'] = '플러그인 패키지(플러그인 %d개: %s)가 성공적으로 설치되었습니다.'; diff --git a/lib/plugins/popularity/lang/ko/intro.txt b/lib/plugins/popularity/lang/ko/intro.txt index 79841fb2b..0af7ee2cc 100644 --- a/lib/plugins/popularity/lang/ko/intro.txt +++ b/lib/plugins/popularity/lang/ko/intro.txt @@ -1,6 +1,6 @@ ====== 인기도 조사 ====== -설치된 위키의 익명 정보를 DokuWiki 개발자들에게 보냅니다. 이 [[doku>popularity|기능]]은 DokuWiki가 실제 사용자들에게 어떻게 사용되는지 DokuWiki 개발자들에게 알려줌으로써 이 후 개발 시 참고가 됩니다. +설치된 위키의 익명 정보를 DokuWiki 개발자에게 보냅니다. 이 [[doku>popularity|기능]]은 DokuWiki가 실제 사용자에게 어떻게 사용되는지 DokuWiki 개발자에게 알려줌으로써 이 후 개발 시 참고가 됩니다. 설치된 위키가 커짐에 따라서 이 과정을 반복할 필요가 있습니다. 반복된 데이타는 익명 ID로 구별되어집니다. diff --git a/lib/plugins/popularity/lang/ko/lang.php b/lib/plugins/popularity/lang/ko/lang.php index 33a0c88f7..5e6966402 100644 --- a/lib/plugins/popularity/lang/ko/lang.php +++ b/lib/plugins/popularity/lang/ko/lang.php @@ -13,7 +13,7 @@ $lang['name'] = '인기도 조사 (불러오는데 시간이 걸릴 수 있습니다.)'; $lang['submit'] = '자료 보내기'; $lang['autosubmit'] = '자료를 자동으로 매달 한번씩 보내기'; -$lang['submissionFailed'] = '다음과 같은 이유로 자료 전송에 실패했습니다 :'; +$lang['submissionFailed'] = '다음과 같은 이유로 자료 전송에 실패했습니다:'; $lang['submitDirectly'] = '아래의 양식에 맞춰 수동으로 작성된 자료를 보낼 수 있습니다'; -$lang['autosubmitError'] = '다음과 같은 이유로 자동 자료 전송에 실패했습니다 :'; +$lang['autosubmitError'] = '다음과 같은 이유로 자동 자료 전송에 실패했습니다:'; $lang['lastSent'] = '자료가 전송되었습니다'; diff --git a/lib/plugins/revert/lang/ko/intro.txt b/lib/plugins/revert/lang/ko/intro.txt index 7fc310eee..30813fe49 100644 --- a/lib/plugins/revert/lang/ko/intro.txt +++ b/lib/plugins/revert/lang/ko/intro.txt @@ -1,3 +1,3 @@ ====== 복구 관리자 ====== -스팸 공격으로 부터 자동으로 복구하는데 이 페이지가 도움이 될 수 있습니다. 스팸 공격받은 문서 목록을 찾으려면 문자열을 입력하기 바랍니다(예를 들어 스팸 URL), 그 후 찾은 문서가 스팸 공격을 받았는지 확인하고 복구합니다. +스팸 공격으로 부터 자동으로 복구하는데 이 페이지가 도움이 될 수 있습니다. 스팸 공격받은 문서 목록을 찾으려면 문자열을 입력하기 바랍니다 (예를 들어 스팸 URL), 그 후 찾은 문서가 스팸 공격을 받았는지 확인하고 복구합니다. diff --git a/lib/plugins/revert/lang/ko/lang.php b/lib/plugins/revert/lang/ko/lang.php index c51af470e..90cba9bce 100644 --- a/lib/plugins/revert/lang/ko/lang.php +++ b/lib/plugins/revert/lang/ko/lang.php @@ -13,9 +13,9 @@ $lang['menu'] = '복구 관리자'; $lang['filter'] = '스팸 문서 찾기'; $lang['revert'] = '선택한 문서 복구'; -$lang['reverted'] = '%s를 %s 버전으로 복구'; +$lang['reverted'] = '%s 버전을 %s 버전으로 복구'; $lang['removed'] = '%s 삭제'; -$lang['revstart'] = '복구 작업을 시작합니다. 오랜 시간이 걸릴 수 있습니다. 완료되기 전에 스크립트 시간 초과가 발생한다면 더 작은 작업들로 나누어서 복구하기 바랍니다.'; +$lang['revstart'] = '복구 작업을 시작합니다. 오랜 시간이 걸릴 수 있습니다. 완료되기 전에 스크립트 시간 초과가 발생한다면 더 작은 작업으로 나누어서 복구하기 바랍니다.'; $lang['revstop'] = '복구 작업이 성공적으로 끝났습니다.'; $lang['note1'] = '참고: 대소문자 구별하여 찾습니다.'; $lang['note2'] = '참고: 이 문서는 %s 스팸 단어를 포함하지 않은 최근 이전 버전으로 복구됩니다. '; diff --git a/lib/plugins/usermanager/lang/ko/lang.php b/lib/plugins/usermanager/lang/ko/lang.php index cae81798f..3754fea90 100644 --- a/lib/plugins/usermanager/lang/ko/lang.php +++ b/lib/plugins/usermanager/lang/ko/lang.php @@ -13,7 +13,7 @@ $lang['menu'] = '사용자 관리자'; $lang['noauth'] = '(사용자 인증이 불가능합니다.)'; $lang['nosupport'] = '(사용자 관리가 지원되지 않습니다.)'; -$lang['badauth'] = '유효하지 않은 인증 메카니즘입니다.'; +$lang['badauth'] = '잘못된 인증 메카니즘'; $lang['user_id'] = '사용자'; $lang['user_pass'] = '비밀번호'; $lang['user_name'] = '실제 이름'; @@ -23,7 +23,7 @@ $lang['field'] = '항목'; $lang['value'] = '값'; $lang['add'] = '추가'; $lang['delete'] = '삭제'; -$lang['delete_selected'] = '삭제 선택'; +$lang['delete_selected'] = '선택 삭제'; $lang['edit'] = '수정'; $lang['edit_prompt'] = '이 사용자 수정'; $lang['modify'] = '바뀜 저장'; @@ -31,9 +31,9 @@ $lang['search'] = '찾기'; $lang['search_prompt'] = '찾기 실행'; $lang['clear'] = '찾기 필터 초기화'; $lang['filter'] = '필터'; -$lang['summary'] = '찾은 사용자 보기(%1$d-%2$d 중 %3$d). 전체 사용자 %4$d 명.'; -$lang['nonefound'] = '찾은 사용자가 없습니다. 전체 사용자 %d 명.'; -$lang['delete_ok'] = '사용자 %d명이 삭제되었습니다.'; +$lang['summary'] = '찾은 사용자 %3$d 중 %1$d-%2$d 보기. 전체 사용자 %4$d명.'; +$lang['nonefound'] = '찾은 사용자가 없습니다. 전체 사용자 %d명.'; +$lang['delete_ok'] = '사용자 %d명이 삭제되었습니다'; $lang['delete_fail'] = '사용자 %d명의 삭제가 실패했습니다.'; $lang['update_ok'] = '사용자 변경을 성공했습니다.'; $lang['update_fail'] = '사용자 변경을 실패했습니다.'; -- cgit v1.2.3 From 1731f979e843c43888c2c26142db87b4801bd98e Mon Sep 17 00:00:00 2001 From: Nguyen The Hung Date: Fri, 22 Jun 2012 10:01:44 +0200 Subject: Vietnamese language update --- inc/lang/vi/backlinks.txt | 4 +- inc/lang/vi/conflict.txt | 2 +- inc/lang/vi/denied.txt | 2 +- inc/lang/vi/edit.txt | 2 +- inc/lang/vi/editrev.txt | 2 +- inc/lang/vi/lang.php | 186 +++++++++++++++++++++++++++++-- inc/lang/vi/login.txt | 2 +- inc/lang/vi/mailtext.txt | 2 +- inc/lang/vi/newpage.txt | 2 +- inc/lang/vi/norev.txt | 2 +- inc/lang/vi/password.txt | 2 +- inc/lang/vi/preview.txt | 2 +- inc/lang/vi/read.txt | 2 +- inc/lang/vi/revisions.txt | 2 +- inc/lang/vi/searchpage.txt | 2 +- lib/plugins/acl/lang/vi/help.txt | 12 ++ lib/plugins/acl/lang/vi/lang.php | 35 +++++- lib/plugins/config/lang/vi/lang.php | 5 + lib/plugins/plugin/lang/vi/lang.php | 5 + lib/plugins/popularity/lang/vi/lang.php | 5 + lib/plugins/revert/lang/vi/lang.php | 5 + lib/plugins/usermanager/lang/vi/lang.php | 5 + 22 files changed, 255 insertions(+), 33 deletions(-) create mode 100644 lib/plugins/acl/lang/vi/help.txt create mode 100644 lib/plugins/config/lang/vi/lang.php create mode 100644 lib/plugins/plugin/lang/vi/lang.php create mode 100644 lib/plugins/popularity/lang/vi/lang.php create mode 100644 lib/plugins/revert/lang/vi/lang.php create mode 100644 lib/plugins/usermanager/lang/vi/lang.php diff --git a/inc/lang/vi/backlinks.txt b/inc/lang/vi/backlinks.txt index 231ab5d8c..eee624d96 100644 --- a/inc/lang/vi/backlinks.txt +++ b/inc/lang/vi/backlinks.txt @@ -1,3 +1,3 @@ -====== Nối về trước ====== +====== Liên kết đến trang vừa xem ====== -Đây là danh sách các trang hình như đã nối vào trang này. +Đây là danh sách các trang có liên kết đến trang vừa xem. diff --git a/inc/lang/vi/conflict.txt b/inc/lang/vi/conflict.txt index 0df1ddbe4..646dcbc45 100644 --- a/inc/lang/vi/conflict.txt +++ b/inc/lang/vi/conflict.txt @@ -2,4 +2,4 @@ Trang bạn đang biên soạn có một phiên bản mới hơn. Việc này xảy ra khi một bạn đổi trang ấy khi bạn đang biên soạn trang này. -Xem kỹ những thay đổi dưới đây, rồi quyết định giữ phiên bản nào. Nếu chọn ''bảo lưu'', phiên bản của bạn được giữ lại. Bấm ''huỷ'' để giữ phiên bản kia. +Xem kỹ những thay đổi dưới đây, rồi quyết định giữ phiên bản nào. Nếu chọn ''Lưu'', phiên bản của bạn được giữ lại. Bấm ''huỷ'' để giữ phiên bản kia. diff --git a/inc/lang/vi/denied.txt b/inc/lang/vi/denied.txt index e70ed5d5f..35acaeb62 100644 --- a/inc/lang/vi/denied.txt +++ b/inc/lang/vi/denied.txt @@ -1,3 +1,3 @@ ====== Không được phép vào ====== -Rất tiếc là bạn không được phép để tiếp tục. Bạn quen đăng nhập hay sao? +Rất tiếc là bạn không được phép để tiếp tục. Bạn quên đăng nhập hay sao? diff --git a/inc/lang/vi/edit.txt b/inc/lang/vi/edit.txt index b00316a7c..1c16f903c 100644 --- a/inc/lang/vi/edit.txt +++ b/inc/lang/vi/edit.txt @@ -1 +1 @@ -Biên soạn trang này và bấm ''Bảo lưu''. Xem [[wiki:syntax]] về cú pháp của Wiki. Xin bạn biên soạn trang này nếu bạn có thể **cải tiến** nó. Nếu bạn muốn thí nghiệm, bạn có thể tập những bước đầu ở [[playground:playground]]. +Biên soạn trang này và bấm ''Lưu''. Xem [[wiki:syntax:vi|cú pháp của Wiki]] để biết cách soạn thảo. Xin bạn biên soạn trang này nếu bạn có thể **cải tiến** nó. Nếu bạn muốn thử nghiệm, bạn có thể thử ở [[playground:playground| chỗ thử]]. diff --git a/inc/lang/vi/editrev.txt b/inc/lang/vi/editrev.txt index 076466c06..8a2031c4d 100644 --- a/inc/lang/vi/editrev.txt +++ b/inc/lang/vi/editrev.txt @@ -1,2 +1,2 @@ -**Bạn đã nạp một phiên bản cũ của văn kiện!** Nếu bảo lưu, bạn sẽ tạo phiên bản với dữ kiện này. +**Bạn đã nạp một phiên bản cũ của văn bản!** Nếu lưu nó, bạn sẽ tạo phiên bản mới với dữ kiện này. ---- diff --git a/inc/lang/vi/lang.php b/inc/lang/vi/lang.php index 361e51e84..c9179f6b3 100644 --- a/inc/lang/vi/lang.php +++ b/inc/lang/vi/lang.php @@ -5,8 +5,16 @@ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author James Do */ -$lang['encoding'] = 'utf-8'; -$lang['direction'] = 'ltr'; + + + +$lang['encoding'] = 'utf-8'; +$lang['direction'] = 'ltr'; +$lang['doublequoteopening'] = '“'; //“ +$lang['doublequoteclosing'] = '”'; //” +$lang['singlequoteopening'] = '‘'; //‘ +$lang['singlequoteclosing'] = '’'; //’ +$lang['apostrophe'] = '’'; //’ $lang['btn_edit'] = 'Biên soạn trang này'; $lang['btn_source'] = 'Xem mã nguồn'; @@ -16,6 +24,8 @@ $lang['btn_search'] = 'Tìm'; $lang['btn_save'] = 'Lưu'; $lang['btn_preview']= 'Duyệt trước'; $lang['btn_top'] = 'Trở lên trên'; +$lang['btn_newer'] = '<< mới hơn'; +$lang['btn_older'] = 'cũ hơn >>'; $lang['btn_revs'] = 'Các phiên bản cũ'; $lang['btn_recent'] = 'Thay đổi gần đây'; $lang['btn_upload'] = 'Tải lên'; @@ -27,41 +37,126 @@ $lang['btn_logout'] = 'Thoát'; $lang['btn_admin'] = 'Quản lý'; $lang['btn_update'] = 'Cập nhật'; $lang['btn_delete'] = 'Xoá'; +$lang['btn_back'] = 'Quay lại'; +$lang['btn_backlink'] = "Liên kết tới đây"; +$lang['btn_profile'] = 'Cập nhật hồ sơ'; +$lang['btn_reset'] = 'Làm lại'; +$lang['btn_resendpwd'] = 'Gửi mật khẩu mới'; +$lang['btn_draft'] = 'Sửa bản nháp'; +$lang['btn_recover'] = 'Phục hồi bản nháp'; +$lang['btn_draftdel'] = 'Xóa bản nháp'; +$lang['btn_revert'] = 'Phục hồi'; $lang['btn_register'] = 'Đăng ký'; +$lang['btn_apply'] = 'Chấp nhận'; +$lang['btn_media'] = 'Quản lý tệp tin'; $lang['loggedinas'] = 'Username đang dùng'; $lang['user'] = 'Username'; -$lang['pass'] = 'Password'; +$lang['pass'] = 'Mật khẩu'; +$lang['newpass'] = 'Mật khẩu mới'; +$lang['oldpass'] = 'Nhập lại mật khẩu hiện tại'; +$lang['passchk'] = 'lần nữa'; $lang['remember'] = 'Lưu username/password lại'; $lang['fullname'] = 'Họ và tên'; $lang['email'] = 'E-Mail'; +$lang['profile'] = 'Hồ sơ thành viên'; $lang['badlogin'] = 'Username hoặc password không đúng.'; +$lang['minoredit'] = 'Minor Changes'; +$lang['draftdate'] = 'Bản nháp được tự động lưu lúc'; // full dformat date will be added +$lang['nosecedit'] = 'Các trang web đã được thay đổi trong khi chờ đợi, phần thông tin quá hạn đã được thay thế bằng trang đầy đủ.'; $lang['regmissing'] = 'Bạn cần điền vào tất cả các trường'; $lang['reguexists'] = 'Bạn khác đã dùng username này rồi.'; $lang['regsuccess'] = 'Đã tạo username, và đã gởi password.'; +$lang['regsuccess2'] = 'Thành viên vừa được tạo.'; $lang['regmailfail']= 'Không gởi password được. Xin bạn liên hệ với người quản lý.'; $lang['regbadmail'] = 'Email hình như không đúng. Xin bạn liên hệ với người quản lý.'; +$lang['regbadpass'] = 'Hai mật khẩu đưa ra là không giống nhau, xin vui lòng thử lại.'; $lang['regpwmail'] = 'Password DokuWiki của bạn là'; -$lang['reghere'] = 'Xin bạn đăng ký username nếu chưa có.'; +$lang['reghere'] = 'Xin bạn đăng ký username nếu chưa có'; + +$lang['profna'] = 'Wiki này không hỗ trợ sửa đổi hồ sơ cá nhân'; +$lang['profnochange'] = 'Không có thay đổi, không có gì để làm.'; +$lang['profnoempty'] = 'Không được để trống tên hoặc địa chỉ email.'; +$lang['profchanged'] = 'Cập nhật hồ sơ thành viên thành công.'; +$lang['pwdforget'] = 'Bạn quên mật khẩu? Tạo lại mật khẩu mới'; +$lang['resendna'] = 'Wiki này không hỗ trợ gửi lại mật khẩu.'; +$lang['resendpwd'] = 'Gửi mật khẩu mới cho'; +$lang['resendpwdmissing'] = 'Xin lỗi, bạn phải điền vào tất cả các trường.'; +$lang['resendpwdnouser'] = 'Xin lỗi, chúng tôi không thể tìm thấy thành viên này trong cơ sở dữ liệu của chúng tôi.'; +$lang['resendpwdbadauth'] = 'Xin lỗi, mã này xác thực không hợp lệ. Hãy chắc chắn rằng bạn sử dụng liên kết xác nhận đầy đủ.'; +$lang['resendpwdconfirm'] = 'Một liên kết xác nhận đã được gửi bằng email.'; +$lang['resendpwdsuccess'] = 'Mật khẩu mới của bạn đã được gửi bằng email.'; + +$lang['license'] = 'Trừ khi có ghi chú khác, nội dung trên wiki này được cấp phép theo giấy phép sau đây:'; +$lang['licenseok'] = 'Lưu ý: Bằng cách chỉnh sửa trang này, bạn đồng ý cấp giấy phép nội dung của bạn theo giấy phép sau:'; + +$lang['searchmedia'] = 'Tìm tên file:'; +$lang['searchmedia_in'] = 'Tìm ở %s'; $lang['txt_upload'] = 'Chọn tệp để tải lên'; $lang['txt_filename'] = 'Điền wikiname (tuỳ ý)'; +$lang['txt_overwrt'] = 'Ghi đè file trùng'; $lang['lockedby'] = 'Đang khoá bởi'; -$lang['lockexpire'] = 'Khoá sẽ hết hạn vào lúc'; -$lang['js']['willexpire'] = 'Khoá của bạn để biên soạn trang này sẽ hết hạn trong vòng 1 phút.\nĐể tránh xung đột, bạn nên bấm nút xem trước để lập lại thời gian khoá'; +$lang['lockexpire'] = 'Sẽ được mở khóa vào lúc'; +$lang['js']['willexpire'] = 'Trong một phút nữa bài viết sẽ được mở khóa để cho phép người khác chỉnh sửa.\nĐể tránh xung đột, bạn nên bấm nút Duyệt trước để lập lại thời gian khoá bài'; $lang['js']['notsavedyet'] = "Hiện có những thay đổi chưa được bảo lưu, và sẽ mất.\nBạn thật sự muốn tiếp tục?"; -$lang['rssfailed'] = 'Rút nguồn này gặp phải lỗi'; +$lang['js']['searchmedia'] = 'Tìm kiếm tập tin'; +$lang['js']['keepopen'] = 'Giữ cửa sổ đang mở trên lựa chọn'; +$lang['js']['hidedetails'] = 'Ẩn thông tin chi tiết'; +$lang['js']['mediatitle'] = 'Thiết lập liên kết'; +$lang['js']['mediadisplay'] = 'Kiểu liên kết'; +$lang['js']['mediaalign'] = 'Sắp hàng'; +$lang['js']['mediasize'] = 'Cỡ ảnh'; +$lang['js']['mediatarget'] = 'Đích của liên kết'; +$lang['js']['mediaclose'] = 'Đóng'; +$lang['js']['mediainsert'] = 'Chèn'; +$lang['js']['mediadisplayimg'] = 'Hiển thị ảnh.'; +$lang['js']['mediadisplaylnk'] = 'Chỉ hiển thị liên kết.'; +$lang['js']['mediasmall'] = 'Nhỏ'; +$lang['js']['mediamedium'] = 'Vừa'; +$lang['js']['medialarge'] = 'To'; +$lang['js']['mediaoriginal'] = 'Kích cỡ gốc'; +$lang['js']['medialnk'] = 'Liên kết tới trang chi tiết'; +$lang['js']['mediadirect'] = 'Liên kết trực tiếp tới ảnh gốc'; +$lang['js']['medianolnk'] = 'Không liên kết'; +$lang['js']['medianolink'] = 'Không liên kết tới ảnh'; +$lang['js']['medialeft'] = 'Căn ảnh sang trái.'; +$lang['js']['mediaright'] = 'Căn ảnh sang phải.'; +$lang['js']['mediacenter'] = 'Cản ảnh ra giữa.'; +$lang['js']['medianoalign'] = 'Không căn.'; +$lang['js']['nosmblinks'] = "Nối với các Windows shares chỉ có hiệu lực với Microsoft Internet Explorer.\nBạn vẫn có thể sao và chép các mốc nối."; +$lang['js']['linkwiz'] = 'Hộp thoại liên kết'; +$lang['js']['linkto'] = 'Liên kết tới:'; +$lang['js']['del_confirm']= 'Xoá mục này?'; +$lang['js']['restore_confirm'] = 'Sẵn sàng phục hồi phiên bản này?'; +$lang['js']['media_diff'] = 'So sánh:'; +$lang['js']['media_select'] = 'Chọn nhiều file…'; +$lang['js']['media_upload_btn'] = 'Tải lên'; +$lang['js']['media_done_btn'] = 'Xong'; +$lang['js']['media_drop'] = 'Kéo các file vào đây để tải lên'; +$lang['js']['media_overwrt'] = 'Ghi đè các file trùng'; + +$lang['rssfailed'] = 'Nguồn này gặp phải lỗi'; $lang['nothingfound']= 'Không tìm được gì'; -$lang['mediaselect'] = 'Chọn tệp media'; +$lang['mediaselect'] = 'Xem'; $lang['fileupload'] = 'Tải lên tệp media'; $lang['uploadsucc'] = 'Tải lên thành công'; -$lang['uploadfail'] = 'Tải lên thất bại. Có thể vì không đủ phép?'; +$lang['uploadfail'] = 'Tải lên thất bại. Có thể vì không đủ quyền?'; $lang['uploadwrong'] = 'Tải lên bị từ chối. Cấm tải loại tệp này'; -$lang['namespaces'] = 'Đề tài'; +$lang['uploadexist'] = 'Tệp tin bị trùng. Chưa có gì xảy ra.'; +$lang['namespaces'] = 'Thư mục'; $lang['mediafiles'] = 'Tệp có sẵn ở'; +$lang['accessdenied'] = 'Bạn không được phép xem trang này.'; +$lang['mediausage'] = 'Sử dụng cú pháp sau đây để dẫn đến tập tin này:'; +$lang['mediaview'] = 'Xem tệp gốc'; +$lang['mediaroot'] = 'thư mục gốc'; +$lang['mediaupload'] = 'Tải một tập tin lên thư mục hiện tại ở đây. Để tạo thư mục con, thêm nó vào trước tên tập tin của bạn, phân cách bằng dấu hai chấm sau khi bạn chọn các tập tin. File còn có thể được lựa chọn bằng cách kéo và thả.'; +$lang['mediaextchange'] = 'Phần mở rộng thay đổi từ .%s thành .%s!'; +$lang['ref_inuse'] = 'Không thể xóa tập tin vì nó đang được sử dụng cho các trang sau:'; +$lang['ref_hidden'] = 'Một số tài liệu sử dụng cho trang này bạn không được cấp phép truy cập.'; $lang['hits'] = 'Trùng'; $lang['quickhits'] = 'Trang trùng hợp'; @@ -69,24 +164,36 @@ $lang['toc'] = 'Nội dung'; $lang['current'] = 'hiện tại'; $lang['yours'] = 'Phiên bản hiện tại'; $lang['diff'] = 'cho xem khác biệt với phiên bản hiện tại'; +$lang['diff2'] = 'Sự khác biệt giữa các bản được lựa chọn'; +$lang['difflink'] = 'Liên kết để xem bản so sánh này'; +$lang['diff_type'] = 'Xem sự khác biệt:'; +$lang['diff_inline'] = 'Nội tuyến'; +$lang['diff_side'] = 'Xếp cạnh nhau'; $lang['line'] = 'Dòng'; $lang['breadcrumb'] = 'Trang đã xem'; +$lang['youarehere'] = 'Bạn đang ở đây'; $lang['lastmod'] = 'Thời điểm thay đổi'; $lang['by'] = 'do'; $lang['deleted'] = 'bị xoá'; $lang['created'] = 'được tạo ra'; $lang['restored'] = 'phiên bản cũ đã được khôi phục'; +$lang['external_edit'] = 'external edit'; $lang['summary'] = 'Tóm tắt biên soạn'; +$lang['noflash'] = 'Adobe Flash Plugin cần được cài để có thể xem nội dung này.'; $lang['mail_newpage'] = 'Trang được thêm:'; $lang['mail_changed'] = 'Trang thay đổi:'; -$lang['js']['nosmblinks'] = "Nối với các Windows shares chỉ có hiệu lực với Microsoft Internet Explorer.\nBạn vẫn có thể sao và chép các mốc nối."; +$lang['changes_type'] = 'Xem thay đổi của'; +$lang['pages_changes'] = 'Trang'; +$lang['media_changes'] = 'Tệp media'; +$lang['both_changes'] = 'Cả trang và các tập tin media'; $lang['qb_bold'] = 'Chữ đậm'; $lang['qb_italic'] = 'Chữ nghiêng'; $lang['qb_underl'] = 'Chữ gạch dưới'; $lang['qb_code'] = 'Chữ mã nguồn'; +$lang['qb_strike'] = 'Strike-through Text'; $lang['qb_h1'] = 'Đầu đề cấp 1'; $lang['qb_h2'] = 'Đầu đề cấp 2'; $lang['qb_h3'] = 'Đầu đề cấp 3'; @@ -100,7 +207,62 @@ $lang['qb_ul'] = 'Điểm trong danh sách không đánh số'; $lang['qb_media'] = 'Thêm ảnh và tệp khác'; $lang['qb_sig'] = 'Đặt chữ ký'; -$lang['js']['del_confirm']= 'Xoá mục này?'; +$lang['metaedit'] = 'Sửa Metadata'; +$lang['metasaveerr'] = 'Thất bại khi viết metadata'; +$lang['metasaveok'] = 'Metadata đã được lưu'; +$lang['img_backto'] = 'Quay lại'; +$lang['img_title'] = 'Tiêu đề'; +$lang['img_caption'] = 'Ghi chú'; +$lang['img_date'] = 'Ngày'; +$lang['img_fname'] = 'Tên file'; +$lang['img_fsize'] = 'Kích cỡ'; +$lang['img_artist'] = 'Người chụp'; +$lang['img_copyr'] = 'Bản quyền'; +$lang['img_format'] = 'Định dạng'; +$lang['img_camera'] = 'Camera'; +$lang['img_keywords'] = 'Từ khóa'; +$lang['img_width'] = 'Rộng'; +$lang['img_height'] = 'Cao'; +$lang['img_manager'] = 'Xem trong trình quản lý tệp media'; + +/* installer strings */ +$lang['i_chooselang'] = 'Chọn ngôn ngữ'; +$lang['i_retry'] = 'Thử lại'; + +$lang['years'] = 'cách đây %d năm'; +$lang['months'] = 'cách đây %d tháng'; +$lang['weeks'] = 'cách đây %d tuần'; +$lang['days'] = 'cách đây %d ngày'; +$lang['hours'] = 'cách đây %d giờ'; +$lang['minutes'] = 'cách đây %d phút'; +$lang['seconds'] = 'cách đây %d giây'; + +$lang['wordblock'] = 'Thay đổi của bạn đã không được lưu lại bởi vì nó có chứa văn bản bị chặn (spam).'; + +$lang['media_uploadtab'] = 'Tải lên'; +$lang['media_searchtab'] = 'Tìm'; +$lang['media_file'] = 'Tệp'; +$lang['media_viewtab'] = 'Xem'; +$lang['media_edittab'] = 'Sửa'; +$lang['media_historytab'] = 'Lịch sử'; +$lang['media_list_thumbs'] = 'Ảnh thu nhỏ'; +$lang['media_list_rows'] = 'Dòng'; +$lang['media_sort_name'] = 'Tên'; +$lang['media_sort_date'] = 'Ngày'; +$lang['media_namespaces'] = 'Chọn thư mục'; +$lang['media_files'] = 'Các tệp trong %s'; +$lang['media_upload'] = 'Tải lên %s'; +$lang['media_search'] = 'Tìm ở %s'; +$lang['media_view'] = '%s'; +$lang['media_viewold'] = '%s ở %s'; +$lang['media_edit'] = 'Sửa %s'; +$lang['media_history'] = 'Lịch sử của %s'; +$lang['media_meta_edited'] = 'đã sửa metadata'; +$lang['media_perm_read'] = 'Sorry, bạn không đủ quyền truy cập.'; +$lang['media_perm_upload'] = 'Xin lỗi, bạn không đủ quyền để upload file lên.'; +$lang['media_update'] = 'Tải lên phiên bản mới'; +$lang['media_restore'] = 'Phục hồi phiên bản này'; +$lang['plugin_install_err'] = "Plugin không được cài đặt chính xác.Đổi tên thư mục plugin '%s' thành '%s'."; //Setup VIM: ex: et ts=2 : diff --git a/inc/lang/vi/login.txt b/inc/lang/vi/login.txt index 4265a79df..71a8b1a01 100644 --- a/inc/lang/vi/login.txt +++ b/inc/lang/vi/login.txt @@ -1,3 +1,3 @@ ====== Đăng nhập ====== -Hiện bạn chưa đăng nhập! Điền vào những chi tiết chứng minh ở phía dưới. Máy của bạn cần đặt chế độ nhận cookies để đăng nhập. +Hiện bạn chưa đăng nhập! Hãy khai báo thông tin đăng nhập vào ô ở phía dưới. Máy của bạn cần đặt chế độ nhận cookies để đăng nhập. diff --git a/inc/lang/vi/mailtext.txt b/inc/lang/vi/mailtext.txt index 3fcdf5595..836e02d24 100644 --- a/inc/lang/vi/mailtext.txt +++ b/inc/lang/vi/mailtext.txt @@ -12,5 +12,5 @@ User : @USER@ @DIFF@ -- -This mail was generated by DokuWiki at +Điện thư này tạo bởi DokuWiki ở @DOKUWIKIURL@ diff --git a/inc/lang/vi/newpage.txt b/inc/lang/vi/newpage.txt index b03bb5224..93f474b18 100644 --- a/inc/lang/vi/newpage.txt +++ b/inc/lang/vi/newpage.txt @@ -1,3 +1,3 @@ ====== Chưa có đề tài này ====== -Bạn vừa nối vào một đề tài chưa có. Bạn có tạo đề tài này bằng cách bấm vào nút ''Tạo trang này''. +Bạn kết nối vào một đề tài chưa có. Bạn có tạo đề tài này bằng cách bấm vào nút ''Tạo trang này'' ở góc trên, bên trái cửa sổ này. Nếu bạn không thấy nút này, thay vào đó là nút ''Xem mã nguồn'' chứng tỏ bạn không có quyền biên tập trang này, hãy đăng nhập thử xem bạn có quyền biên tập trang không. Nếu bạn nghĩ đây là một lỗi, hãy báo cho người quản trị. diff --git a/inc/lang/vi/norev.txt b/inc/lang/vi/norev.txt index 0fa27d898..224bd1db0 100644 --- a/inc/lang/vi/norev.txt +++ b/inc/lang/vi/norev.txt @@ -1,3 +1,3 @@ ====== Phiên bản chưa có ====== -Chưa có phiên bản được chỉ định. Xin bấm nút ''Phiên bản cũ'' để xem danh sách các phiên bản của văn kiện này. +Chưa có phiên bản được chỉ định. Xin bấm nút ''Phiên bản cũ'' để xem danh sách các phiên bản của văn bản này. diff --git a/inc/lang/vi/password.txt b/inc/lang/vi/password.txt index 589bbf067..798a20d33 100644 --- a/inc/lang/vi/password.txt +++ b/inc/lang/vi/password.txt @@ -6,4 +6,4 @@ Username: @LOGIN@ Password: @PASSWORD@ -- -Điện thư này xuất phát từ DokuWiki tại @DOKUWIKIURL@. +Điện thư này xuất phát từ @DOKUWIKIURL@. diff --git a/inc/lang/vi/preview.txt b/inc/lang/vi/preview.txt index 81069a2c4..f02a25142 100644 --- a/inc/lang/vi/preview.txt +++ b/inc/lang/vi/preview.txt @@ -1,3 +1,3 @@ ====== Xem trước ====== -Văn kiện của bạn sẽ thể hiện như sau. Nên nhớ: Văn kiện này **chưa được bảo lưu**! +Văn bản của bạn sẽ thể hiện như sau. Nên nhớ: Văn bản này **chưa được lưu**! diff --git a/inc/lang/vi/read.txt b/inc/lang/vi/read.txt index ffeffc7bf..eec69966b 100644 --- a/inc/lang/vi/read.txt +++ b/inc/lang/vi/read.txt @@ -1 +1 @@ -Trang này chỉ được đọc thôi. Bạn có thể xem mã nguồn, nhưng không được thay đổi. Xin bạn hỏi người quản lý nếu không đúng. +Trang này chỉ được đọc thôi. Bạn có thể xem mã nguồn, nhưng không được thay đổi. Hãy báo lại người quản lý nếu hệ thống hoạt động không đúng. diff --git a/inc/lang/vi/revisions.txt b/inc/lang/vi/revisions.txt index 943e3fff1..b9e9779ee 100644 --- a/inc/lang/vi/revisions.txt +++ b/inc/lang/vi/revisions.txt @@ -1,3 +1,3 @@ ====== Phiên bản cũ ====== -Sau đây là các phiên bản cũ của văn kiện này. Để quây về một phiên bản cũ, chọn ở phía dưới, bấm vào ''Biên soạn trang này'' để bảo lưu. +Sau đây là các phiên bản cũ của văn bản này. Để quay về một phiên bản cũ, bạn hãy chọn nó từ danh sách dưới đây, sau đó bấm vào nút ''Phục hồi'' hoặc nhấp nút ''Biên soạn trang này'' và lưu nó lại. diff --git a/inc/lang/vi/searchpage.txt b/inc/lang/vi/searchpage.txt index 821ca9f7b..7ded7a808 100644 --- a/inc/lang/vi/searchpage.txt +++ b/inc/lang/vi/searchpage.txt @@ -1,5 +1,5 @@ ====== Tìm ====== -Sau đây là kết quả của câu hỏi của bạn. Nếu bạn không thấy được những gì bạn đang tìm, bạn có thể một trang mới, cùng tên câu hỏi của bạn, bằng cách bấm vào nút ''Biên soạn trang này''. +Sau đây là kết quả mà bạn đã tìm. Nếu bạn không thấy được những gì bạn đang tìm, bạn có thể tạo một trang mới bằng cách bấm vào nút ''Biên soạn trang này'', khi đó bạn sẽ có 1 trang mới với tên trang chính là tuwfw khóa bạn đã tìm kiếm. ===== Kết quả ===== diff --git a/lib/plugins/acl/lang/vi/help.txt b/lib/plugins/acl/lang/vi/help.txt new file mode 100644 index 000000000..23e258678 --- /dev/null +++ b/lib/plugins/acl/lang/vi/help.txt @@ -0,0 +1,12 @@ +=== Trợ giúp nhanh: === + +Trang này giúp bạn thêm hoặc xóa quyền được cấp cho 1 thư mục hoặc trang wiki của bạn. + +Của sổ bên trái hiển thị tất cả các thư mục và trang văn bản. + +Khung trên đây cho phép bạn xem và sửa quyền của một nhóm hoặc thành viên đã chọn. + +Bảng bên dưới hiển thị tất cả các quyền được cấp. Bạn có thể sửa hoặc hóa các quyền đó một cách nhanh chóng. + +Đọc [[doku>acl|tài liệu chính thức về ACL]] sẽ giúp bạn hiểu hơn về cách phân quyền ở DokuWiki. + diff --git a/lib/plugins/acl/lang/vi/lang.php b/lib/plugins/acl/lang/vi/lang.php index 6237f79ba..ddf764dca 100644 --- a/lib/plugins/acl/lang/vi/lang.php +++ b/lib/plugins/acl/lang/vi/lang.php @@ -3,19 +3,42 @@ * vietnamese language file * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) - * @author James Do + * @author NukeViet */ -$lang['admin_acl'] = 'Quản lý phép truy nhật {Access Control List}'; +$lang['admin_acl'] = 'Quản lý danh sách quyền truy cập'; $lang['acl_group'] = 'Nhóm'; -$lang['acl_user'] = 'Người'; -$lang['acl_perms'] = 'Phép truy nhập cho'; +$lang['acl_user'] = 'Thành viên'; +$lang['acl_perms'] = 'Cấp phép cho'; $lang['page'] = 'Trang'; -$lang['namespace'] = 'Không gian tên'; +$lang['namespace'] = 'Thư mục'; +$lang['btn_select'] = 'Chọn'; + +$lang['p_user_id'] = 'Thành viên %s hiện tại được cấp phép cho trang %s: %s.'; +$lang['p_user_ns'] = 'Thành viên %s hiện tại được cấp phép cho thư mục %s: %s.'; +$lang['p_group_id'] = 'Thành viên trong nhóm %s hiện tại được cấp phép cho trang %s: %s.'; +$lang['p_group_ns'] = 'Thành viên trong nhóm %s hiện tại được cấp phép cho thư mục %s: %s.'; + +$lang['p_choose_id'] = 'Hãy nhập tên thành viên hoặc nhóm vào ô trên đây để xem hoặc sửa quyền đã thiết đặt cho trang %s.'; +$lang['p_choose_ns'] = 'Hãy nhập tên thành viên hoặc nhóm vào ô trên đây để xem hoặc sửa quyền đã thiết đặt cho thư mục %s.'; + + +$lang['p_inherited'] = 'Ghi chú: Có những quyền không được thể hiện ở đây nhưng nó được cấp phép từ những nhóm hoặc thư mục cấp cao.'; +$lang['p_isadmin'] = 'Ghi chú: Nhóm hoặc thành viên này luôn được cấp đủ quyền vì họ là Quản trị tối cao'; +$lang['p_include'] = 'Một số quyền thấp được thể hiện ở mức cao hơn. Quyền tạo, tải lên và xóa chỉ dành cho thư mục, không dành cho trang.'; + +$lang['current'] = 'Danh sách quyền truy cập hiện tại'; +$lang['where'] = 'Trang/Thư mục'; +$lang['who'] = 'Thành viên/Nhóm'; +$lang['perm'] = 'Quyền'; + +$lang['acl_perm0'] = 'Không'; $lang['acl_perm1'] = 'Đọc'; -$lang['acl_perm2'] = 'Biên soạn'; +$lang['acl_perm2'] = 'Sửa'; $lang['acl_perm4'] = 'Tạo'; $lang['acl_perm8'] = 'Tải lên'; +$lang['acl_perm16'] = 'Xóa'; $lang['acl_new'] = 'Thêm mục mới'; +$lang['acl_mod'] = 'Sửa'; //Setup VIM: ex: et ts=2 : diff --git a/lib/plugins/config/lang/vi/lang.php b/lib/plugins/config/lang/vi/lang.php new file mode 100644 index 000000000..2933d8875 --- /dev/null +++ b/lib/plugins/config/lang/vi/lang.php @@ -0,0 +1,5 @@ + Date: Fri, 22 Jun 2012 10:03:21 +0200 Subject: Dutch language update --- inc/lang/nl/edit.txt | 2 +- inc/lang/nl/lang.php | 17 ++++-- inc/lang/nl/mailwrap.html | 13 +++++ lib/plugins/config/lang/nl/lang.php | 111 +++++++++++++++++++----------------- 4 files changed, 87 insertions(+), 56 deletions(-) create mode 100644 inc/lang/nl/mailwrap.html diff --git a/inc/lang/nl/edit.txt b/inc/lang/nl/edit.txt index e539050bc..9718d0900 100644 --- a/inc/lang/nl/edit.txt +++ b/inc/lang/nl/edit.txt @@ -1 +1 @@ -Pas de pagina aan en klik op ''Opslaan''. Zie [[wiki:syntax]] voor de Wiki syntax. Pas de pagina allen aan als hij **verbeterd** kan worden. Als je iets wilt uitproberen kun je spelen in de [[playground:playground|zandbak]]. +Pas de pagina aan en klik op ''Opslaan''. Zie [[wiki:syntax]] voor de Wiki-syntax. Pas de pagina allen aan als hij **verbeterd** kan worden. Als je iets wilt uitproberen kun je spelen in de [[playground:playground|zandbak]]. diff --git a/inc/lang/nl/lang.php b/inc/lang/nl/lang.php index 4644f5e5d..911ffdc10 100644 --- a/inc/lang/nl/lang.php +++ b/inc/lang/nl/lang.php @@ -51,6 +51,7 @@ $lang['btn_backtomedia'] = 'Terug naar Bestandsselectie'; $lang['btn_subscribe'] = 'Inschrijven wijzigingen'; $lang['btn_profile'] = 'Profiel aanpassen'; $lang['btn_reset'] = 'Wissen'; +$lang['btn_resendpwd'] = 'Nieuw wachtwoord bepalen'; $lang['btn_draft'] = 'Bewerk concept'; $lang['btn_recover'] = 'Herstel concept'; $lang['btn_draftdel'] = 'Verwijder concept'; @@ -87,6 +88,7 @@ $lang['profnoempty'] = 'Een lege gebruikersnaam of e-mailadres is niet $lang['profchanged'] = 'Gebruikersprofiel succesvol aangepast'; $lang['pwdforget'] = 'Je wachtwoord vergeten? Vraag een nieuw wachtwoord aan'; $lang['resendna'] = 'Deze wiki ondersteunt het verzenden van wachtwoorden niet'; +$lang['resendpwd'] = 'Nieuw wachtwoord bepalen voor'; $lang['resendpwdmissing'] = 'Sorry, je moet alle velden invullen.'; $lang['resendpwdnouser'] = 'Sorry, we kunnen deze gebruikersnaam niet vinden in onze database.'; $lang['resendpwdbadauth'] = 'Sorry, deze authentiecatiecode is niet geldig. Controleer of je de volledige bevestigings-link hebt gebruikt.'; @@ -99,6 +101,7 @@ $lang['searchmedia_in'] = 'Zoek in %s'; $lang['txt_upload'] = 'Selecteer een bestand om te uploaden'; $lang['txt_filename'] = 'Vul nieuwe naam in (optioneel)'; $lang['txt_overwrt'] = 'Overschrijf bestaand bestand'; +$lang['maxuploadsize'] = 'Max %s per bestand'; $lang['lockedby'] = 'Momenteel in gebruik door'; $lang['lockexpire'] = 'Exclusief gebruiksrecht vervalt op'; $lang['js']['willexpire'] = 'Je exclusieve gebruiksrecht voor het aanpassen van deze pagina verloopt over een minuut.\nKlik op de Voorbeeld-knop om het exclusieve gebruiksrecht te verlengen.'; @@ -193,6 +196,11 @@ $lang['external_edit'] = 'Externe bewerking'; $lang['summary'] = 'Samenvatting wijziging'; $lang['noflash'] = 'De Adobe Flash Plugin is vereist om de pagina te kunnen weergeven.'; $lang['download'] = 'Download fragment'; +$lang['tools'] = 'Hulpmiddelen'; +$lang['user_tools'] = 'Gebruikershulpmiddelen'; +$lang['site_tools'] = 'Site-hulpmiddelen'; +$lang['page_tools'] = 'Paginahulpmiddelen'; +$lang['skip_to_content'] = 'spring naar tekst'; $lang['mail_newpage'] = 'pagina toegevoegd:'; $lang['mail_changed'] = 'pagina aangepast:'; $lang['mail_subscribe_list'] = 'Pagina\'s veranderd in namespace:'; @@ -200,8 +208,8 @@ $lang['mail_new_user'] = 'nieuwe gebruiker:'; $lang['mail_upload'] = 'bestand geüpload:'; $lang['changes_type'] = 'Bekijk wijzigingen van'; $lang['pages_changes'] = 'Pagina\'s'; -$lang['media_changes'] = 'Media bestanden'; -$lang['both_changes'] = 'Zowel pagina\'s als media bestanden'; +$lang['media_changes'] = 'Mediabestanden'; +$lang['both_changes'] = 'Zowel pagina\'s als mediabestanden'; $lang['qb_bold'] = 'Vette tekst'; $lang['qb_italic'] = 'Cursieve tekst'; $lang['qb_underl'] = 'Onderstreepte tekst'; @@ -244,7 +252,7 @@ $lang['img_camera'] = 'Camera'; $lang['img_keywords'] = 'Trefwoorden'; $lang['img_width'] = 'Breedte'; $lang['img_height'] = 'Hoogte'; -$lang['img_manager'] = 'In media beheerder bekijken'; +$lang['img_manager'] = 'In mediabeheerder bekijken'; $lang['subscr_subscribe_success'] = '%s is ingeschreven voor %s'; $lang['subscr_subscribe_error'] = 'Fout bij inschrijven van %s voor %s'; $lang['subscr_subscribe_noaddress'] = 'Er is geen emailadres geassocieerd met uw account, u kunt daardoor niet worden ingeschreven.'; @@ -263,6 +271,7 @@ $lang['subscr_style_digest'] = 'Samenvattings-email met wijzigingen per pagina $lang['subscr_style_list'] = 'Lijst van veranderde pagina\'s sinds laatste email (elke %.2f dagen)'; $lang['authmodfailed'] = 'Ongeldige gebruikersauthenticatie-configuratie. Informeer de wikibeheerder.'; $lang['authtempfail'] = 'Gebruikersauthenticatie is tijdelijk niet beschikbaar. Als deze situatie zich blijft voordoen, informeer dan de wikibeheerder.'; +$lang['authpwdexpire'] = 'Je wachtwoord verloopt in %d dagen, je moet het binnenkort veranderen'; $lang['i_chooselang'] = 'Kies je taal'; $lang['i_installer'] = 'DokuWiki Installer'; $lang['i_wikiname'] = 'Wikinaam'; @@ -304,7 +313,7 @@ $lang['media_list_thumbs'] = 'Miniatuurweergaven'; $lang['media_list_rows'] = 'Regels'; $lang['media_sort_name'] = 'Naam'; $lang['media_sort_date'] = 'Datum'; -$lang['media_namespaces'] = 'Kies naamruimte'; +$lang['media_namespaces'] = 'Kies namespace'; $lang['media_files'] = 'Bestanden in %s'; $lang['media_upload'] = 'Upload naar %s'; $lang['media_search'] = 'Zoeken in %s'; diff --git a/inc/lang/nl/mailwrap.html b/inc/lang/nl/mailwrap.html new file mode 100644 index 000000000..2ffe19a88 --- /dev/null +++ b/inc/lang/nl/mailwrap.html @@ -0,0 +1,13 @@ + + + @TITLE@ + + + + + @HTMLBODY@ + +

+ Deze mail is gegenereerd door DokuWiki op @DOKUWIKIURL@. + + \ No newline at end of file diff --git a/lib/plugins/config/lang/nl/lang.php b/lib/plugins/config/lang/nl/lang.php index 77b8d6a1a..e0c9d7d7c 100644 --- a/lib/plugins/config/lang/nl/lang.php +++ b/lib/plugins/config/lang/nl/lang.php @@ -36,6 +36,8 @@ $lang['_anti_spam'] = 'Anti-spaminstellingen'; $lang['_editing'] = 'Pagina-wijzigingsinstellingen'; $lang['_links'] = 'Link-instellingen'; $lang['_media'] = 'Media-instellingen'; +$lang['_notifications'] = 'Meldingsinstellingen'; +$lang['_syndication'] = 'Syndication-instellingen'; $lang['_advanced'] = 'Geavanceerde instellingen'; $lang['_network'] = 'Netwerkinstellingen'; $lang['_plugin_sufix'] = 'Plugin-instellingen'; @@ -43,26 +45,29 @@ $lang['_template_sufix'] = 'Sjabloon-instellingen'; $lang['_msg_setting_undefined'] = 'Geen metadata voor deze instelling.'; $lang['_msg_setting_no_class'] = 'Geen class voor deze instelling.'; $lang['_msg_setting_no_default'] = 'Geen standaard waarde.'; -$lang['fmode'] = 'Bestandaanmaak-modus (file creation mode)'; -$lang['dmode'] = 'Directory-aanmaak-modus (directory creation mode)'; +$lang['title'] = 'Titel van de wiki'; +$lang['start'] = 'Naam startpagina'; $lang['lang'] = 'Taal'; +$lang['template'] = 'Sjabloon ofwel het design van de wiki.'; +$lang['tagline'] = 'Ondertitel (als het sjabloon dat ondersteunt)'; +$lang['sidebar'] = 'Zijbalk-paginanaam (als het sjabloon dat ondersteunt), leeg veld betekent geen zijbalk'; +$lang['license'] = 'Onder welke licentie zou je tekst moeten worden gepubliceerd?'; +$lang['savedir'] = 'Directory om data op te slaan'; $lang['basedir'] = 'Basisdirectory'; $lang['baseurl'] = 'Basis-URL'; -$lang['savedir'] = 'Directory om data op te slaan'; $lang['cookiedir'] = 'Cookie pad. Laat leeg om de basis URL te gebruiken.'; -$lang['start'] = 'Naam startpagina'; -$lang['title'] = 'Titel van de wiki'; -$lang['template'] = 'Sjabloon'; -$lang['license'] = 'Onder welke licentie zou je tekst moeten worden gepubliceerd?'; -$lang['fullpath'] = 'Volledig pad van pagina\'s in de footer weergeven'; +$lang['dmode'] = 'Directory-aanmaak-modus (directory creation mode)'; +$lang['fmode'] = 'Bestandaanmaak-modus (file creation mode)'; +$lang['allowdebug'] = 'Debug toestaan uitzetten indien niet noodzakelijk!'; $lang['recent'] = 'Recente wijzigingen'; +$lang['recent_days'] = 'Hoeveel recente wijzigingen bewaren (dagen)'; $lang['breadcrumbs'] = 'Aantal broodkruimels'; $lang['youarehere'] = 'Hierarchische broodkruimels'; +$lang['fullpath'] = 'Volledig pad van pagina\'s in de footer weergeven'; $lang['typography'] = 'Breng typografische wijzigingen aan'; -$lang['htmlok'] = 'Embedded HTML toestaan'; -$lang['phpok'] = 'Embedded PHP toestaan'; $lang['dformat'] = 'Datum formaat (zie de PHP strftime functie)'; $lang['signature'] = 'Ondertekening'; +$lang['showuseras'] = 'Hoe de gebruiker die de pagina het laatst wijzigde weergeven'; $lang['toptoclevel'] = 'Bovenste niveau voor inhoudsopgave'; $lang['tocminheads'] = 'Minimum aantal koppen dat bepaald of een index gemaakt wordt'; $lang['maxtoclevel'] = 'Laagste niveau voor inhoudsopgave'; @@ -70,16 +75,8 @@ $lang['maxseclevel'] = 'Laagste sectiewijzigingsniveau'; $lang['camelcase'] = 'CamelCase gebruiken voor links'; $lang['deaccent'] = 'Paginanamen ontdoen van vreemde tekens'; $lang['useheading'] = 'Eerste kopje voor paginanaam gebruiken'; -$lang['refcheck'] = 'Controleer verwijzingen naar media'; -$lang['refshow'] = 'Aantal te tonen mediaverwijzingen'; -$lang['allowdebug'] = 'Debug toestaan uitzetten indien niet noodzakelijk!'; -$lang['mediarevisions'] = 'Media revisies activeren?'; -$lang['usewordblock'] = 'Blokkeer spam op basis van woordenlijst'; -$lang['indexdelay'] = 'Uitstel voor indexeren (sec)'; -$lang['relnofollow'] = 'Gebruik rel="nofollow" voor externe links'; -$lang['mailguard'] = 'E-mailadressen onherkenbaar maken'; -$lang['iexssprotect'] = 'Controleer geüploade bestanden op mogelijk schadelijke JavaScript of HTML code'; -$lang['showuseras'] = 'Hoe de gebruiker die de pagina het laatst wijzigde weergeven'; +$lang['sneaky_index'] = 'Met de standaardinstellingen zal DokuWiki alle namespaces laten zien in de index. Het inschakelen van deze optie zorgt ervoor dat de namespaces waar de gebruiker geen leestoegang tot heeft, verborgen worden. Dit kan resulteren in het verbergen van subnamespaces waar de gebruiker wel toegang to heeft. Dit kan de index onbruikbaar maken met bepaalde ACL-instellingen.'; +$lang['hidepages'] = 'Verberg deze pagina\'s (regular expressions)'; $lang['useacl'] = 'Gebruik access control lists'; $lang['autopasswd'] = 'Zelf wachtwoorden genereren'; $lang['authtype'] = 'Authenticatiemechanisme'; @@ -88,64 +85,76 @@ $lang['defaultgroup'] = 'Standaardgroep'; $lang['superuser'] = 'Superuser - een groep of gebruiker of kommalijst (gebruiker1,@groep1,gebruiker2) met volledige toegang tot alle pagina\'s en functies, ongeacht de ACL instellingen'; $lang['manager'] = 'Beheerder - een groep of gebruiker of kommalijst (gebruiker1,@groep1,gebruiker2) met toegang tot bepaalde beheersfunctionaliteit'; $lang['profileconfirm'] = 'Bevestig profielwijzigingen met wachtwoord'; +$lang['rememberme'] = 'Permanente login cookie toestaan (onthoud mij)'; $lang['disableactions'] = 'Aangevinkte DokuWiki-akties uitschakelen'; $lang['disableactions_check'] = 'Controleer'; $lang['disableactions_subscription'] = 'Inschrijven/opzeggen'; $lang['disableactions_wikicode'] = 'Bron bekijken/exporteer rauw'; $lang['disableactions_other'] = 'Andere akties (gescheiden door komma\'s)'; -$lang['sneaky_index'] = 'Met de standaardinstellingen zal DokuWiki alle namespaces laten zien in de index. Het inschakelen van deze optie zorgt ervoor dat de namespaces waar de gebruiker geen leestoegang tot heeft, verborgen worden. Dit kan resulteren in het verbergen van subnamespaces waar de gebruiker wel toegang to heeft. Dit kan de index onbruikbaar maken met bepaalde ACL-instellingen.'; $lang['auth_security_timeout'] = 'Authenticatiebeveiligings-timeout (seconden)'; $lang['securecookie'] = 'Moeten cookies die via HTTPS gezet zijn alleen via HTTPS verzonden worden door de browser? Zet deze optie uit als alleen het inloggen op de wiki beveiligd is, maar het gebruik verder niet.'; +$lang['remote'] = 'Activeer het remote API-systeem. Hiermee kunnen andere applicaties de wiki benaderen via XML-RPC of andere mechanismen.'; +$lang['remoteuser'] = 'Beperk toegang tot de remote API tot deze komma-lijst van groepen of gebruikers. Leeg betekent toegang voor iedereen.'; +$lang['usewordblock'] = 'Blokkeer spam op basis van woordenlijst'; +$lang['relnofollow'] = 'Gebruik rel="nofollow" voor externe links'; +$lang['indexdelay'] = 'Uitstel voor indexeren (sec)'; +$lang['mailguard'] = 'E-mailadressen onherkenbaar maken'; +$lang['iexssprotect'] = 'Controleer geüploade bestanden op mogelijk schadelijke JavaScript of HTML code'; +$lang['usedraft'] = 'Sla automatisch een concept op tijdens het wijzigen'; +$lang['htmlok'] = 'Embedded HTML toestaan'; +$lang['phpok'] = 'Embedded PHP toestaan'; +$lang['locktime'] = 'Maximum leeftijd voor lockbestanden (sec)'; +$lang['cachetime'] = 'Maximum leeftijd voor cache (sec)'; +$lang['target____wiki'] = 'Doelvenster voor interne links'; +$lang['target____interwiki'] = 'Doelvenster voor interwiki-links'; +$lang['target____extern'] = 'Doelvenster voor externe links'; +$lang['target____media'] = 'Doelvenster voor medialinks'; +$lang['target____windows'] = 'Doelvenster voor windows links'; +$lang['mediarevisions'] = 'Media revisies activeren?'; +$lang['refcheck'] = 'Controleer verwijzingen naar media'; +$lang['refshow'] = 'Aantal te tonen mediaverwijzingen'; +$lang['gdlib'] = 'Versie GD Lib '; +$lang['im_convert'] = 'Path naar ImageMagick\'s convert tool'; +$lang['jpg_quality'] = 'JPG compressiekwaliteit (0-100)'; +$lang['fetchsize'] = 'Maximum grootte (bytes) die fetch.php mag downloaden van buiten'; +$lang['subscribers'] = 'Ondersteuning pagina-inschrijving aanzetten'; +$lang['subscribe_time'] = 'Inschrijvingsmeldingen en samenvattingen worden na deze tijdsduur (in seconden) verzonden. Deze waarde dient kleiner te zijn dan de tijd ingevuld bij "Hoeveel recente wijzigingen bewaren (dagen)"'; +$lang['notify'] = 'Stuur e-mailnotificaties naar dit adres'; +$lang['registernotify'] = 'Stuur informatie over nieuw aangemelde gebruikers naar dit e-mailadres'; +$lang['mailfrom'] = 'E-mailadres voor automatische e-mail'; +$lang['mailprefix'] = 'Te gebruiken voorvoegsel voor onderwerp automatische email'; +$lang['htmlmail'] = 'Zend multipart HTML e-mail. Dit ziet er beter uit, maar is groter. Uitschakelen betekent e-mail in platte tekst.'; +$lang['sitemap'] = 'Genereer Google sitemap (dagen). 0 betekent uitschakelen.'; +$lang['rss_type'] = 'XML feed type'; +$lang['rss_linkto'] = 'XML feed linkt naar'; +$lang['rss_content'] = 'Wat moet er in de XML feed items weergegeven worden?'; +$lang['rss_update'] = 'XML feed verversingsinterval (sec)'; +$lang['rss_show_summary'] = 'XML feed samenvatting in titel weergeven'; +$lang['rss_media'] = 'Welk type verandering moet in de XML feed worden weergegeven?'; $lang['updatecheck'] = 'Controleer op nieuwe versies en beveiligingswaarschuwingen? DokuWiki moet hiervoor contact opnemen met update.dokuwiki.org.'; $lang['userewrite'] = 'Gebruik nette URL\'s'; $lang['useslash'] = 'Gebruik slash (/) als scheiding tussen namepaces in URL\'s'; -$lang['usedraft'] = 'Sla automatisch een concept op tijdens het wijzigen'; $lang['sepchar'] = 'Woordscheider in paginanamen'; $lang['canonical'] = 'Herleid URL\'s tot hun basisvorm'; $lang['fnencode'] = 'Methode om niet-ASCII bestandsnamen te coderen.'; $lang['autoplural'] = 'Controleer op meervoudsvormen in links'; $lang['compression'] = 'Compressiemethode voor attic-bestanden'; -$lang['cachetime'] = 'Maximum leeftijd voor cache (sec)'; -$lang['locktime'] = 'Maximum leeftijd voor lockbestanden (sec)'; -$lang['fetchsize'] = 'Maximum grootte (bytes) die fetch.php mag downloaden van buiten'; -$lang['notify'] = 'Stuur e-mailnotificaties naar dit adres'; -$lang['registernotify'] = 'Stuur informatie over nieuw aangemelde gebruikers naar dit e-mailadres'; -$lang['mailfrom'] = 'E-mailadres voor automatische e-mail'; -$lang['mailprefix'] = 'Te gebruiken voorvoegsel voor onderwerp automatische email'; $lang['gzip_output'] = 'Gebruik gzip Content-Encoding voor xhtml'; -$lang['gdlib'] = 'Versie GD Lib '; -$lang['im_convert'] = 'Path naar ImageMagick\'s convert tool'; -$lang['jpg_quality'] = 'JPG compressiekwaliteit (0-100)'; -$lang['subscribers'] = 'Ondersteuning pagina-inschrijving aanzetten'; -$lang['subscribe_time'] = 'Inschrijvingsmeldingen en samenvattingen worden na deze tijdsduur (in seconden) verzonden. Deze waarde dient kleiner te zijn dan de tijd ingevuld bij "Hoeveel recente wijzigingen bewaren (dagen)"'; $lang['compress'] = 'Compacte CSS en javascript output'; $lang['cssdatauri'] = 'Maximale omvang in bytes van in CSS gelinkte afbeeldingen die bij de stylesheet moeten worden ingesloten ter reductie van de HTTP request header overhead. Deze techniek werkt niet in IE7 en ouder! 400 tot 600 is een geschikte omvang. Stel de omvang in op 0 om deze functionaliteit uit te schakelen.'; -$lang['hidepages'] = 'Verberg deze pagina\'s (regular expressions)'; $lang['send404'] = 'Stuur "HTTP 404/Page Not Found" voor niet-bestaande pagina\'s'; -$lang['sitemap'] = 'Genereer Google sitemap (dagen)'; $lang['broken_iua'] = 'Is de ignore_user_abort functie onbruikbaar op uw systeem? Dit kan een onbruikbare zoekindex tot gevolg hebben. IIS+PHP/CGI staat hier bekend om. Zie Bug 852 voor meer informatie.'; $lang['xsendfile'] = 'Gebruik de X-Sendfile header om de webserver statische content te laten versturen? De webserver moet dit wel ondersteunen.'; $lang['renderer_xhtml'] = 'Weergavesysteem voor de standaard (xhtml) wiki-uitvoer'; $lang['renderer__core'] = '%s (dokuwiki core)'; $lang['renderer__plugin'] = '%s (plugin)'; -$lang['rememberme'] = 'Permanente login cookie toestaan (onthoud mij)'; -$lang['rss_type'] = 'XML feed type'; -$lang['rss_linkto'] = 'XML feed linkt naar'; -$lang['rss_content'] = 'Wat moet er in de XML feed items weergegeven worden?'; -$lang['rss_update'] = 'XML feed verversingsinterval (sec)'; -$lang['recent_days'] = 'Hoeveel recente wijzigingen bewaren (dagen)'; -$lang['rss_show_summary'] = 'XML feed samenvatting in titel weergeven'; -$lang['target____wiki'] = 'Doelvenster voor interne links'; -$lang['target____interwiki'] = 'Doelvenster voor interwiki-links'; -$lang['target____extern'] = 'Doelvenster voor externe links'; -$lang['target____media'] = 'Doelvenster voor medialinks'; -$lang['target____windows'] = 'Doelvenster voor windows links'; +$lang['dnslookups'] = 'DokuWiki zoekt de hostnamen van IP-adressen van gebruikers die pagina wijzigen op. Schakel deze optie uit als je geen of een langzame DNS server hebt.'; $lang['proxy____host'] = 'Proxy server'; $lang['proxy____port'] = 'Proxy port'; $lang['proxy____user'] = 'Proxy gebruikersnaam'; $lang['proxy____pass'] = 'Proxy wachtwoord'; -$lang['proxy____ssl'] = 'Gebruik SSL om een connectie te maken met de proxy'; -$lang['proxy____except'] = 'Reguliere expressie om URL\'s te bepalen waarvoor de proxy overgeslaan moet worden.'; +$lang['proxy____ssl'] = 'Gebruik SSL om een verbinding te maken met de proxy'; +$lang['proxy____except'] = 'Reguliere expressie om URL\'s te bepalen waarvoor de proxy overgeslagen moet worden.'; $lang['safemodehack'] = 'Safemode hack aanzetten'; $lang['ftp____host'] = 'FTP server voor safemode hack'; $lang['ftp____port'] = 'FTP port voor safemode hack'; @@ -185,7 +194,7 @@ $lang['xsendfile_o_0'] = 'niet gebruiken'; $lang['xsendfile_o_1'] = 'Eigen lighttpd header (voor release 1.5)'; $lang['xsendfile_o_2'] = 'Standaard X-Sendfile header'; $lang['xsendfile_o_3'] = 'Propritary Nginx X-Accel-Redirect header'; -$lang['showuseras_o_loginname'] = 'loginnaam'; +$lang['showuseras_o_loginname'] = 'Loginnaam'; $lang['showuseras_o_username'] = 'Volledige naam'; $lang['showuseras_o_email'] = 'E-mailadres (onherkenbaar gemaakt volgens mailguard-instelling)'; $lang['showuseras_o_email_link'] = 'E-mailadres als mailto: link'; -- cgit v1.2.3 From 4d18e93617feab03d64a5e20ea2585a869b3e86a Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 23 Jun 2012 12:52:34 +0200 Subject: fixed wrong comparison in Mailer::dump() --- inc/Mailer.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/Mailer.class.php b/inc/Mailer.class.php index 507150d00..93845497e 100644 --- a/inc/Mailer.class.php +++ b/inc/Mailer.class.php @@ -566,7 +566,7 @@ class Mailer { public function dump(){ $this->cleanHeaders(); $body = $this->prepareBody(); - if($body === 'false') return false; + if($body === false) return false; $headers = $this->prepareHeaders(); return $headers.MAILHEADER_EOL.$body; -- cgit v1.2.3 From 4c89a7f6d57c5017beea08f1e2d3658397495e96 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 23 Jun 2012 13:13:40 +0200 Subject: another bad comparison fixed --- inc/Mailer.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/Mailer.class.php b/inc/Mailer.class.php index 93845497e..7661eaa75 100644 --- a/inc/Mailer.class.php +++ b/inc/Mailer.class.php @@ -629,7 +629,7 @@ class Mailer { // make the body $body = $this->prepareBody(); - if($body === 'false') return false; + if($body === false) return false; // cook the headers $headers = $this->prepareHeaders(); -- cgit v1.2.3 From a89c75afdfc7a502d725e217e1a4731862384c02 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 23 Jun 2012 13:22:31 +0200 Subject: some code beautification --- inc/Mailer.class.php | 294 ++++++++++++++++++++++++++------------------------- 1 file changed, 150 insertions(+), 144 deletions(-) diff --git a/inc/Mailer.class.php b/inc/Mailer.class.php index 7661eaa75..fccf1dad9 100644 --- a/inc/Mailer.class.php +++ b/inc/Mailer.class.php @@ -11,20 +11,24 @@ // end of line for mail lines - RFC822 says CRLF but postfix (and other MTAs?) // think different -if(!defined('MAILHEADER_EOL')) define('MAILHEADER_EOL',"\n"); +if(!defined('MAILHEADER_EOL')) define('MAILHEADER_EOL', "\n"); #define('MAILHEADER_ASCIIONLY',1); +/** + * Mail Handling + */ class Mailer { - protected $headers = array(); - protected $attach = array(); - protected $html = ''; - protected $text = ''; + protected $headers = array(); + protected $attach = array(); + protected $html = ''; + protected $text = ''; - protected $boundary = ''; - protected $partid = ''; - protected $sendparam= null; + protected $boundary = ''; + protected $partid = ''; + protected $sendparam = null; + /** @var EmailAddressValidator */ protected $validator = null; protected $allowhtml = true; @@ -33,38 +37,38 @@ class Mailer { * * Initializes the boundary strings and part counters */ - public function __construct(){ + public function __construct() { global $conf; - $server = parse_url(DOKU_URL,PHP_URL_HOST); + $server = parse_url(DOKU_URL, PHP_URL_HOST); - $this->partid = md5(uniqid(rand(),true)).'@'.$server; - $this->boundary = '----------'.md5(uniqid(rand(),true)); + $this->partid = md5(uniqid(rand(), true)).'@'.$server; + $this->boundary = '----------'.md5(uniqid(rand(), true)); - $listid = join('.',array_reverse(explode('/',DOKU_BASE))).$server; - $listid = strtolower(trim($listid,'.')); + $listid = join('.', array_reverse(explode('/', DOKU_BASE))).$server; + $listid = strtolower(trim($listid, '.')); - $this->allowhtml = (bool) $conf['htmlmail']; + $this->allowhtml = (bool)$conf['htmlmail']; // add some default headers for mailfiltering FS#2247 - $this->setHeader('X-Mailer','DokuWiki '.getVersion()); + $this->setHeader('X-Mailer', 'DokuWiki '.getVersion()); $this->setHeader('X-DokuWiki-User', $_SERVER['REMOTE_USER']); $this->setHeader('X-DokuWiki-Title', $conf['title']); $this->setHeader('X-DokuWiki-Server', $server); $this->setHeader('X-Auto-Response-Suppress', 'OOF'); - $this->setHeader('List-Id',$conf['title'].' <'.$listid.'>'); + $this->setHeader('List-Id', $conf['title'].' <'.$listid.'>'); } /** * Attach a file * - * @param $path Path to the file to attach - * @param $mime Mimetype of the attached file - * @param $name The filename to use - * @param $embed Unique key to reference this file from the HTML part + * @param string $path Path to the file to attach + * @param string $mime Mimetype of the attached file + * @param string $name The filename to use + * @param string $embed Unique key to reference this file from the HTML part */ - public function attachFile($path,$mime,$name='',$embed=''){ - if(!$name){ + public function attachFile($path, $mime, $name = '', $embed = '') { + if(!$name) { $name = basename($path); } @@ -79,14 +83,14 @@ class Mailer { /** * Attach a file * - * @param $path The file contents to attach - * @param $mime Mimetype of the attached file - * @param $name The filename to use - * @param $embed Unique key to reference this file from the HTML part + * @param string $data The file contents to attach + * @param string $mime Mimetype of the attached file + * @param string $name The filename to use + * @param string $embed Unique key to reference this file from the HTML part */ - public function attachContent($data,$mime,$name='',$embed=''){ - if(!$name){ - list($junk,$ext) = split('/',$mime); + public function attachContent($data, $mime, $name = '', $embed = '') { + if(!$name) { + list(, $ext) = explode('/', $mime); $name = count($this->attach).".$ext"; } @@ -101,18 +105,18 @@ class Mailer { /** * Callback function to automatically embed images referenced in HTML templates */ - protected function autoembed_cb($matches){ + protected function autoembed_cb($matches) { static $embeds = 0; $embeds++; // get file and mime type $media = cleanID($matches[1]); - list($ext, $mime) = mimetype($media); - $file = mediaFN($media); + list(, $mime) = mimetype($media); + $file = mediaFN($media); if(!file_exists($file)) return $matches[0]; //bad reference, keep as is // attach it and set placeholder - $this->attachFile($file,$mime,'','autoembed'.$embeds); + $this->attachFile($file, $mime, '', 'autoembed'.$embeds); return '%%autoembed'.$embeds.'%%'; } @@ -125,18 +129,18 @@ class Mailer { * @param string $value the value of the header * @param bool $clean remove all non-ASCII chars and line feeds? */ - public function setHeader($header,$value,$clean=true){ - $header = str_replace(' ','-',ucwords(strtolower(str_replace('-',' ',$header)))); // streamline casing - if($clean){ - $header = preg_replace('/[^\w \-\.\+\@]+/','',$header); - $value = preg_replace('/[^\w \-\.\+\@<>]+/','',$value); + public function setHeader($header, $value, $clean = true) { + $header = str_replace(' ', '-', ucwords(strtolower(str_replace('-', ' ', $header)))); // streamline casing + if($clean) { + $header = preg_replace('/[^\w \-\.\+\@]+/', '', $header); + $value = preg_replace('/[^\w \-\.\+\@<>]+/', '', $value); } // empty value deletes $value = trim($value); - if($value === ''){ + if($value === '') { if(isset($this->headers[$header])) unset($this->headers[$header]); - }else{ + } else { $this->headers[$header] = $value; } } @@ -147,7 +151,7 @@ class Mailer { * Whatever is set here is directly passed to PHP's mail() command as last * parameter. Depending on the PHP setup this might break mailing alltogether */ - public function setParameters($param){ + public function setParameters($param) { $this->sendparam = $param; } @@ -166,38 +170,40 @@ class Mailer { * @param array $html the HTML body, leave null to create it from $text * @param bool $wrap wrap the HTML in the default header/Footer */ - public function setBody($text, $textrep=null, $htmlrep=null, $html=null, $wrap=true){ + public function setBody($text, $textrep = null, $htmlrep = null, $html = null, $wrap = true) { global $INFO; global $conf; - $htmlrep = (array) $htmlrep; - $textrep = (array) $textrep; + $htmlrep = (array)$htmlrep; + $textrep = (array)$textrep; // create HTML from text if not given - if(is_null($html)){ + if(is_null($html)) { $html = $text; $html = hsc($html); - $html = preg_replace('/^-----*$/m','
',$html); + $html = preg_replace('/^-----*$/m', '
', $html); $html = nl2br($html); } - if($wrap){ - $wrap = rawLocale('mailwrap','html'); - $html = preg_replace('/\n--
.*$/s','',$html); //strip signature - $html = str_replace('@HTMLBODY@',$html,$wrap); + if($wrap) { + $wrap = rawLocale('mailwrap', 'html'); + $html = preg_replace('/\n--
.*$/s', '', $html); //strip signature + $html = str_replace('@HTMLBODY@', $html, $wrap); } // copy over all replacements missing for HTML (autolink URLs) - foreach($textrep as $key => $value){ + foreach($textrep as $key => $value) { if(isset($htmlrep[$key])) continue; - if(preg_match('/^https?:\/\//i',$value)){ + if(preg_match('/^https?:\/\//i', $value)) { $htmlrep[$key] = ''.hsc($value).''; - }else{ + } else { $htmlrep[$key] = hsc($value); } } // embed media from templates - $html = preg_replace_callback('/@MEDIA\(([^\)]+)\)@/', - array($this,'autoembed_cb'),$html); + $html = preg_replace_callback( + '/@MEDIA\(([^\)]+)\)@/', + array($this, 'autoembed_cb'), $html + ); // prepare default replacements $ip = clientIP(); @@ -213,7 +219,7 @@ class Mailer { 'NAME' => $INFO['userinfo']['name'], 'MAIL' => $INFO['userinfo']['mail'], ); - $trep = array_merge($trep,(array) $textrep); + $trep = array_merge($trep, (array)$textrep); $hrep = array( 'DATE' => ''.hsc(dformat()).'', 'BROWSER' => hsc($_SERVER['HTTP_USER_AGENT']), @@ -224,16 +230,16 @@ class Mailer { 'USER' => hsc($_SERVER['REMOTE_USER']), 'NAME' => hsc($INFO['userinfo']['name']), 'MAIL' => ''. - hsc($INFO['userinfo']['mail']).'', + hsc($INFO['userinfo']['mail']).'', ); - $hrep = array_merge($hrep,(array) $htmlrep); + $hrep = array_merge($hrep, (array)$htmlrep); // Apply replacements - foreach ($trep as $key => $substitution) { - $text = str_replace('@'.strtoupper($key).'@',$substitution, $text); + foreach($trep as $key => $substitution) { + $text = str_replace('@'.strtoupper($key).'@', $substitution, $text); } - foreach ($hrep as $key => $substitution) { - $html = str_replace('@'.strtoupper($key).'@',$substitution, $html); + foreach($hrep as $key => $substitution) { + $html = str_replace('@'.strtoupper($key).'@', $substitution, $html); } $this->setHTML($html); @@ -247,7 +253,7 @@ class Mailer { * * You probably want to use setBody() instead */ - public function setHTML($html){ + public function setHTML($html) { $this->html = $html; } @@ -256,7 +262,7 @@ class Mailer { * * You probably want to use setBody() instead */ - public function setText($text){ + public function setText($text) { $this->text = $text; } @@ -266,7 +272,7 @@ class Mailer { * @see setAddress * @param string $address Multiple adresses separated by commas */ - public function to($address){ + public function to($address) { $this->setHeader('To', $address, false); } @@ -276,7 +282,7 @@ class Mailer { * @see setAddress * @param string $address Multiple adresses separated by commas */ - public function cc($address){ + public function cc($address) { $this->setHeader('Cc', $address, false); } @@ -286,7 +292,7 @@ class Mailer { * @see setAddress * @param string $address Multiple adresses separated by commas */ - public function bcc($address){ + public function bcc($address) { $this->setHeader('Bcc', $address, false); } @@ -299,7 +305,7 @@ class Mailer { * @see setAddress * @param string $address from address */ - public function from($address){ + public function from($address) { $this->setHeader('From', $address, false); } @@ -308,7 +314,7 @@ class Mailer { * * @param string $subject the mail subject */ - public function subject($subject){ + public function subject($subject) { $this->headers['Subject'] = $subject; } @@ -322,65 +328,65 @@ class Mailer { * setAddress("föö , me@somewhere.com","TBcc"); * * @param string $address Multiple adresses separated by commas - * @param string returns the prepared header (can contain multiple lines) + * @return bool|string the prepared header (can contain multiple lines) */ - public function cleanAddress($address){ + public function cleanAddress($address) { // No named recipients for To: in Windows (see FS#652) $names = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? false : true; - $address = preg_replace('/[\r\n\0]+/',' ',$address); // remove attack vectors + $address = preg_replace('/[\r\n\0]+/', ' ', $address); // remove attack vectors $headers = ''; - $parts = explode(',',$address); - foreach ($parts as $part){ + $parts = explode(',', $address); + foreach($parts as $part) { $part = trim($part); // parse address - if(preg_match('#(.*?)<(.*?)>#',$part,$matches)){ + if(preg_match('#(.*?)<(.*?)>#', $part, $matches)) { $text = trim($matches[1]); $addr = $matches[2]; - }else{ + } else { $addr = $part; } // skip empty ones - if(empty($addr)){ + if(empty($addr)) { continue; } // FIXME: is there a way to encode the localpart of a emailaddress? - if(!utf8_isASCII($addr)){ - msg(htmlspecialchars("E-Mail address <$addr> is not ASCII"),-1); + if(!utf8_isASCII($addr)) { + msg(htmlspecialchars("E-Mail address <$addr> is not ASCII"), -1); continue; } - if(is_null($this->validator)){ - $this->validator = new EmailAddressValidator(); + if(is_null($this->validator)) { + $this->validator = new EmailAddressValidator(); $this->validator->allowLocalAddresses = true; } - if(!$this->validator->check_email_address($addr)){ - msg(htmlspecialchars("E-Mail address <$addr> is not valid"),-1); + if(!$this->validator->check_email_address($addr)) { + msg(htmlspecialchars("E-Mail address <$addr> is not valid"), -1); continue; } // text was given - if(!empty($text) && $names){ + if(!empty($text) && $names) { // add address quotes $addr = "<$addr>"; - if(defined('MAILHEADER_ASCIIONLY')){ + if(defined('MAILHEADER_ASCIIONLY')) { $text = utf8_deaccent($text); $text = utf8_strip($text); } - if(!utf8_isASCII($text)){ + if(!utf8_isASCII($text)) { $text = '=?UTF-8?B?'.base64_encode($text).'?='; } - }else{ + } else { $text = ''; } // add to header comma seperated - if($headers != ''){ + if($headers != '') { $headers .= ', '; } $headers .= $text.' '.$addr; @@ -397,30 +403,30 @@ class Mailer { * * Replaces placeholders in the HTML with the correct CIDs */ - protected function prepareAttachments(){ + protected function prepareAttachments() { $mime = ''; $part = 1; // embedded attachments - foreach($this->attach as $media){ + foreach($this->attach as $media) { // create content id $cid = 'part'.$part.'.'.$this->partid; // replace wildcards - if($media['embed']){ - $this->html = str_replace('%%'.$media['embed'].'%%','cid:'.$cid,$this->html); + if($media['embed']) { + $this->html = str_replace('%%'.$media['embed'].'%%', 'cid:'.$cid, $this->html); } $mime .= '--'.$this->boundary.MAILHEADER_EOL; $mime .= 'Content-Type: '.$media['mime'].';'.MAILHEADER_EOL; $mime .= 'Content-Transfer-Encoding: base64'.MAILHEADER_EOL; $mime .= "Content-ID: <$cid>".MAILHEADER_EOL; - if($media['embed']){ + if($media['embed']) { $mime .= 'Content-Disposition: inline; filename="'.$media['name'].'"'.MAILHEADER_EOL; - }else{ + } else { $mime .= 'Content-Disposition: attachment; filename="'.$media['name'].'"'.MAILHEADER_EOL; } $mime .= MAILHEADER_EOL; //end of headers - $mime .= chunk_split(base64_encode($media['data']),74,MAILHEADER_EOL); + $mime .= chunk_split(base64_encode($media['data']), 74, MAILHEADER_EOL); $part++; } @@ -434,16 +440,15 @@ class Mailer { * * @return string the prepared mail body, false on errors */ - protected function prepareBody(){ - global $conf; + protected function prepareBody() { // no HTML mails allowed? remove HTML body - if(!$this->allowhtml){ + if(!$this->allowhtml) { $this->html = ''; } // check for body - if(!$this->text && !$this->html){ + if(!$this->text && !$this->html) { return false; } @@ -452,28 +457,28 @@ class Mailer { $body = ''; - if(!$this->html && !count($this->attach)){ // we can send a simple single part message - $this->headers['Content-Type'] = 'text/plain; charset=UTF-8'; + if(!$this->html && !count($this->attach)) { // we can send a simple single part message + $this->headers['Content-Type'] = 'text/plain; charset=UTF-8'; $this->headers['Content-Transfer-Encoding'] = 'base64'; - $body .= chunk_split(base64_encode($this->text),74,MAILHEADER_EOL); - }else{ // multi part it is + $body .= chunk_split(base64_encode($this->text), 74, MAILHEADER_EOL); + } else { // multi part it is $body .= "This is a multi-part message in MIME format.".MAILHEADER_EOL; // prepare the attachments $attachments = $this->prepareAttachments(); // do we have alternative text content? - if($this->text && $this->html){ + if($this->text && $this->html) { $this->headers['Content-Type'] = 'multipart/alternative;'.MAILHEADER_EOL. - ' boundary="'.$this->boundary.'XX"'; + ' boundary="'.$this->boundary.'XX"'; $body .= '--'.$this->boundary.'XX'.MAILHEADER_EOL; $body .= 'Content-Type: text/plain; charset=UTF-8'.MAILHEADER_EOL; $body .= 'Content-Transfer-Encoding: base64'.MAILHEADER_EOL; $body .= MAILHEADER_EOL; - $body .= chunk_split(base64_encode($this->text),74,MAILHEADER_EOL); + $body .= chunk_split(base64_encode($this->text), 74, MAILHEADER_EOL); $body .= '--'.$this->boundary.'XX'.MAILHEADER_EOL; $body .= 'Content-Type: multipart/related;'.MAILHEADER_EOL. - ' boundary="'.$this->boundary.'"'.MAILHEADER_EOL; + ' boundary="'.$this->boundary.'"'.MAILHEADER_EOL; $body .= MAILHEADER_EOL; } @@ -481,13 +486,13 @@ class Mailer { $body .= 'Content-Type: text/html; charset=UTF-8'.MAILHEADER_EOL; $body .= 'Content-Transfer-Encoding: base64'.MAILHEADER_EOL; $body .= MAILHEADER_EOL; - $body .= chunk_split(base64_encode($this->html),74,MAILHEADER_EOL); + $body .= chunk_split(base64_encode($this->html), 74, MAILHEADER_EOL); $body .= MAILHEADER_EOL; $body .= $attachments; $body .= '--'.$this->boundary.'--'.MAILHEADER_EOL; // close open multipart/alternative boundary - if($this->text && $this->html){ + if($this->text && $this->html) { $body .= '--'.$this->boundary.'XX--'.MAILHEADER_EOL; } } @@ -498,47 +503,47 @@ class Mailer { /** * Cleanup and encode the headers array */ - protected function cleanHeaders(){ + protected function cleanHeaders() { global $conf; // clean up addresses if(empty($this->headers['From'])) $this->from($conf['mailfrom']); - $addrs = array('To','From','Cc','Bcc'); - foreach($addrs as $addr){ - if(isset($this->headers[$addr])){ + $addrs = array('To', 'From', 'Cc', 'Bcc'); + foreach($addrs as $addr) { + if(isset($this->headers[$addr])) { $this->headers[$addr] = $this->cleanAddress($this->headers[$addr]); } } - if(isset($this->headers['Subject'])){ + if(isset($this->headers['Subject'])) { // add prefix to subject - if(empty($conf['mailprefix'])){ + if(empty($conf['mailprefix'])) { if(utf8_strlen($conf['title']) < 20) { $prefix = '['.$conf['title'].']'; - }else{ + } else { $prefix = '['.utf8_substr($conf['title'], 0, 20).'...]'; } - }else{ + } else { $prefix = '['.$conf['mailprefix'].']'; } $len = strlen($prefix); - if(substr($this->headers['Subject'],0,$len) != $prefix){ + if(substr($this->headers['Subject'], 0, $len) != $prefix) { $this->headers['Subject'] = $prefix.' '.$this->headers['Subject']; } // encode subject - if(defined('MAILHEADER_ASCIIONLY')){ + if(defined('MAILHEADER_ASCIIONLY')) { $this->headers['Subject'] = utf8_deaccent($this->headers['Subject']); $this->headers['Subject'] = utf8_strip($this->headers['Subject']); } - if(!utf8_isASCII($this->headers['Subject'])){ + if(!utf8_isASCII($this->headers['Subject'])) { $this->headers['Subject'] = '=?UTF-8?B?'.base64_encode($this->headers['Subject']).'?='; } } // wrap headers - foreach($this->headers as $key => $val){ - $this->headers[$key] = wordwrap($val,78,MAILHEADER_EOL.' '); + foreach($this->headers as $key => $val) { + $this->headers[$key] = wordwrap($val, 78, MAILHEADER_EOL.' '); } } @@ -547,9 +552,9 @@ class Mailer { * * @returns string the headers */ - protected function prepareHeaders(){ + protected function prepareHeaders() { $headers = ''; - foreach($this->headers as $key => $val){ + foreach($this->headers as $key => $val) { $headers .= "$key: $val".MAILHEADER_EOL; } return $headers; @@ -563,9 +568,9 @@ class Mailer { * * @return string the mail, false on errors */ - public function dump(){ + public function dump() { $this->cleanHeaders(); - $body = $this->prepareBody(); + $body = $this->prepareBody(); if($body === false) return false; $headers = $this->prepareHeaders(); @@ -580,13 +585,13 @@ class Mailer { * @triggers MAIL_MESSAGE_SEND * @return bool true if the mail was successfully passed to the MTA */ - public function send(){ + public function send() { $success = false; // prepare hook data $data = array( // pass the whole mail class to plugin - 'mail' => $this, + 'mail' => $this, // pass references for backward compatibility 'to' => &$this->headers['To'], 'cc' => &$this->headers['Cc'], @@ -594,7 +599,7 @@ class Mailer { 'from' => &$this->headers['From'], 'subject' => &$this->headers['Subject'], 'body' => &$this->text, - 'params' => &$this->sendparams, + 'params' => &$this->sendparam, 'headers' => '', // plugins shouldn't use this // signal if we mailed successfully to AFTER event 'success' => &$success, @@ -602,47 +607,48 @@ class Mailer { // do our thing if BEFORE hook approves $evt = new Doku_Event('MAIL_MESSAGE_SEND', $data); - if ($evt->advise_before(true)) { + if($evt->advise_before(true)) { // clean up before using the headers $this->cleanHeaders(); // any recipients? - if(trim($this->headers['To']) === '' && - trim($this->headers['Cc']) === '' && - trim($this->headers['Bcc']) === '') return false; + if(trim($this->headers['To']) === '' && + trim($this->headers['Cc']) === '' && + trim($this->headers['Bcc']) === '' + ) return false; // The To: header is special - if(isset($this->headers['To'])){ + if(isset($this->headers['To'])) { $to = $this->headers['To']; unset($this->headers['To']); - }else{ + } else { $to = ''; } // so is the subject - if(isset($this->headers['Subject'])){ + if(isset($this->headers['Subject'])) { $subject = $this->headers['Subject']; unset($this->headers['Subject']); - }else{ + } else { $subject = ''; } // make the body - $body = $this->prepareBody(); + $body = $this->prepareBody(); if($body === false) return false; // cook the headers $headers = $this->prepareHeaders(); // add any headers set by legacy plugins - if(trim($data['headers'])){ + if(trim($data['headers'])) { $headers .= MAILHEADER_EOL.trim($data['headers']); } // send the thing - if(is_null($this->sendparam)){ - $success = @mail($to,$subject,$body,$headers); - }else{ - $success = @mail($to,$subject,$body,$headers,$this->sendparam); + if(is_null($this->sendparam)) { + $success = @mail($to, $subject, $body, $headers); + } else { + $success = @mail($to, $subject, $body, $headers, $this->sendparam); } } // any AFTER actions? -- cgit v1.2.3 From e3736c26cc7f6820143784f2552ad05de43b9ed1 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 23 Jun 2012 13:44:47 +0200 Subject: some phpdoc updates --- inc/utf8.php | 59 ++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/inc/utf8.php b/inc/utf8.php index 54986e14e..7b7c19c6b 100644 --- a/inc/utf8.php +++ b/inc/utf8.php @@ -103,9 +103,9 @@ if(!function_exists('utf8_substr')){ * * @author Harry Fuecks * @author Chris Smith - * @param string - * @param integer number of UTF-8 characters offset (from left) - * @param integer (optional) length in UTF-8 characters from offset + * @param string $str + * @param int $offset number of UTF-8 characters offset (from left) + * @param int $length (optional) length in UTF-8 characters from offset * @return mixed string or false if failure */ function utf8_substr($str, $offset, $length = null) { @@ -221,6 +221,8 @@ if(!function_exists('utf8_ltrim')){ * * @author Andreas Gohr * @see ltrim() + * @param string $str + * @param string $charlist * @return string */ function utf8_ltrim($str,$charlist=''){ @@ -239,6 +241,8 @@ if(!function_exists('utf8_rtrim')){ * * @author Andreas Gohr * @see rtrim() + * @param string $str + * @param string $charlist * @return string */ function utf8_rtrim($str,$charlist=''){ @@ -257,6 +261,8 @@ if(!function_exists('utf8_trim')){ * * @author Andreas Gohr * @see trim() + * @param string $str + * @param string $charlist * @return string */ function utf8_trim($str,$charlist='') { @@ -348,7 +354,7 @@ if(!function_exists('utf8_ucwords')){ * You don't need to call this yourself * * @author Harry Fuecks - * @param array of matches corresponding to a single word + * @param array $matches matches corresponding to a single word * @return string with first char of the word in uppercase * @see utf8_ucwords * @see utf8_strtoupper @@ -408,9 +414,9 @@ if(!function_exists('utf8_stripspecials')){ * @param string $string The UTF8 string to strip of special chars * @param string $repl Replace special with this string * @param string $additional Additional chars to strip (used in regexp char class) + * @return string */ function utf8_stripspecials($string,$repl='',$additional=''){ - global $UTF8_SPECIAL_CHARS; global $UTF8_SPECIAL_CHARS2; static $specials = null; @@ -493,7 +499,7 @@ if(!function_exists('utf8_unhtml')){ * @author Tom N Harris * @param string $str UTF-8 encoded string * @param boolean $entities Flag controlling decoding of named entities. - * @return UTF-8 encoded string with numeric (and named) entities replaced. + * @return string UTF-8 encoded string with numeric (and named) entities replaced. */ function utf8_unhtml($str, $entities=null) { static $decoder = null; @@ -509,6 +515,12 @@ if(!function_exists('utf8_unhtml')){ } if(!function_exists('utf8_decode_numeric')){ + /** + * Decodes numeric HTML entities to their correct UTF-8 characters + * + * @param $ent string A numeric entity + * @return string + */ function utf8_decode_numeric($ent) { switch ($ent[2]) { case 'X': @@ -524,16 +536,37 @@ if(!function_exists('utf8_decode_numeric')){ } if(!class_exists('utf8_entity_decoder')){ + /** + * Encapsulate HTML entity decoding tables + */ class utf8_entity_decoder { var $table; + + /** + * Initializes the decoding tables + */ function __construct() { $table = get_html_translation_table(HTML_ENTITIES); $table = array_flip($table); $this->table = array_map(array(&$this,'makeutf8'), $table); } + + /** + * Wrapper aorund unicode_to_utf8() + * + * @param $c string + * @return mixed + */ function makeutf8($c) { return unicode_to_utf8(array(ord($c))); } + + /** + * Decodes any HTML entity to it's correct UTF-8 char equivalent + * + * @param $ent string An entity + * @return string + */ function decode($ent) { if ($ent[1] == '#') { return utf8_decode_numeric($ent); @@ -562,8 +595,8 @@ if(!function_exists('utf8_to_unicode')){ * * @author * @author Harry Fuecks - * @param string UTF-8 encoded string - * @param boolean Check for invalid sequences? + * @param string $str UTF-8 encoded string + * @param boolean $strict Check for invalid sequences? * @return mixed array of unicode code points or false if UTF-8 invalid * @see unicode_to_utf8 * @link http://hsivonen.iki.fi/php-utf8/ @@ -735,8 +768,8 @@ if(!function_exists('unicode_to_utf8')){ * output buffering to concatenate the UTF-8 string (faster) as well as * reference the array by it's keys * - * @param array of unicode code points representing a string - * @param boolean Check for invalid sequences? + * @param array $arr of unicode code points representing a string + * @param boolean $strict Check for invalid sequences? * @return mixed UTF-8 string or false if array contains invalid code points * @author * @author Harry Fuecks @@ -855,8 +888,8 @@ if(!function_exists('utf8_bad_replace')){ * * @author Harry Fuecks * @see http://www.w3.org/International/questions/qa-forms-utf-8 - * @param string to search - * @param string to replace bad bytes with (defaults to '?') - use ASCII + * @param string $str to search + * @param string $replace to replace bad bytes with (defaults to '?') - use ASCII * @return string */ function utf8_bad_replace($str, $replace = '') { @@ -1000,7 +1033,7 @@ if(!UTF8_MBSTRING){ /** * UTF-8 Case lookup table * - * This lookuptable defines the lower case letters to their correspponding + * This lookuptable defines the lower case letters to their corresponding * upper case letter in UTF-8 * * @author Andreas Gohr -- cgit v1.2.3 From 29fbab8dda3a6c084b02400830218b57bd39aeee Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 23 Jun 2012 14:08:40 +0200 Subject: code cleanup --- inc/PassHash.class.php | 277 +++++++++++++++++++++++++------------------------ 1 file changed, 142 insertions(+), 135 deletions(-) diff --git a/inc/PassHash.class.php b/inc/PassHash.class.php index d825057f0..f85766723 100644 --- a/inc/PassHash.class.php +++ b/inc/PassHash.class.php @@ -16,65 +16,67 @@ class PassHash { * match true is is returned else false * * @author Andreas Gohr + * @param $clear string Clear-Text password + * @param $hash string Hash to compare against * @return bool */ - function verify_hash($clear,$hash){ - $method=''; - $salt=''; - $magic=''; + function verify_hash($clear, $hash) { + $method = ''; + $salt = ''; + $magic = ''; //determine the used method and salt $len = strlen($hash); - if(preg_match('/^\$1\$([^\$]{0,8})\$/',$hash,$m)){ + if(preg_match('/^\$1\$([^\$]{0,8})\$/', $hash, $m)) { $method = 'smd5'; $salt = $m[1]; $magic = '1'; - }elseif(preg_match('/^\$apr1\$([^\$]{0,8})\$/',$hash,$m)){ + } elseif(preg_match('/^\$apr1\$([^\$]{0,8})\$/', $hash, $m)) { $method = 'apr1'; $salt = $m[1]; $magic = 'apr1'; - }elseif(preg_match('/^\$P\$(.{31})$/',$hash,$m)){ + } elseif(preg_match('/^\$P\$(.{31})$/', $hash, $m)) { $method = 'pmd5'; $salt = $m[1]; $magic = 'P'; - }elseif(preg_match('/^\$H\$(.{31})$/',$hash,$m)){ + } elseif(preg_match('/^\$H\$(.{31})$/', $hash, $m)) { $method = 'pmd5'; $salt = $m[1]; $magic = 'H'; - }elseif(preg_match('/^sha1\$(.{5})\$/',$hash,$m)){ + } elseif(preg_match('/^sha1\$(.{5})\$/', $hash, $m)) { $method = 'djangosha1'; $salt = $m[1]; - }elseif(preg_match('/^md5\$(.{5})\$/',$hash,$m)){ + } elseif(preg_match('/^md5\$(.{5})\$/', $hash, $m)) { $method = 'djangomd5'; $salt = $m[1]; - }elseif(preg_match('/^\$2a\$(.{2})\$/',$hash,$m)){ + } elseif(preg_match('/^\$2a\$(.{2})\$/', $hash, $m)) { $method = 'bcrypt'; $salt = $hash; - }elseif(substr($hash,0,6) == '{SSHA}'){ + } elseif(substr($hash, 0, 6) == '{SSHA}') { $method = 'ssha'; - $salt = substr(base64_decode(substr($hash, 6)),20); - }elseif(substr($hash,0,6) == '{SMD5}'){ + $salt = substr(base64_decode(substr($hash, 6)), 20); + } elseif(substr($hash, 0, 6) == '{SMD5}') { $method = 'lsmd5'; - $salt = substr(base64_decode(substr($hash, 6)),16); - }elseif($len == 32){ + $salt = substr(base64_decode(substr($hash, 6)), 16); + } elseif($len == 32) { $method = 'md5'; - }elseif($len == 40){ + } elseif($len == 40) { $method = 'sha1'; - }elseif($len == 16){ + } elseif($len == 16) { $method = 'mysql'; - }elseif($len == 41 && $hash[0] == '*'){ + } elseif($len == 41 && $hash[0] == '*') { $method = 'my411'; - }elseif($len == 34){ + } elseif($len == 34) { $method = 'kmd5'; $salt = $hash; - }else{ + } else { $method = 'crypt'; - $salt = substr($hash,0,2); + $salt = substr($hash, 0, 2); } //crypt and compare $call = 'hash_'.$method; - if($this->$call($clear,$salt,$magic) === $hash){ + if($this->$call($clear, $salt, $magic) === $hash) { return true; } return false; @@ -83,13 +85,14 @@ class PassHash { /** * Create a random salt * - * @param int $len - The length of the salt + * @param int $len The length of the salt + * @return string */ - public function gen_salt($len=32){ + public function gen_salt($len = 32) { $salt = ''; $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; - for($i=0; $i<$len; $i++){ - $salt .= $chars[mt_rand(0,61)]; + for($i = 0; $i < $len; $i++) { + $salt .= $chars[mt_rand(0, 61)]; } return $salt; } @@ -100,12 +103,12 @@ class PassHash { * If $salt is not null, the value is kept, but the lenght restriction is * applied. * - * @param stringref $salt - The salt, pass null if you want one generated - * @param int $len - The length of the salt + * @param string &$salt The salt, pass null if you want one generated + * @param int $len The length of the salt */ - public function init_salt(&$salt,$len=32){ + public function init_salt(&$salt, $len = 32) { if(is_null($salt)) $salt = $this->gen_salt($len); - if(strlen($salt) > $len) $salt = substr($salt,0,$len); + if(strlen($salt) > $len) $salt = substr($salt, 0, $len); } // Password hashing methods follow below @@ -122,36 +125,37 @@ class PassHash { * @author Andreas Gohr * @author * @link http://de.php.net/manual/en/function.crypt.php#73619 - * @param string $clear - the clear text to hash - * @param string $salt - the salt to use, null for random - * @param string $magic - the hash identifier (apr1 or 1) - * @returns string - hashed password + * @param string $clear The clear text to hash + * @param string $salt The salt to use, null for random + * @return string Hashed password */ - public function hash_smd5($clear, $salt=null){ - $this->init_salt($salt,8); + public function hash_smd5($clear, $salt = null) { + $this->init_salt($salt, 8); - if(defined('CRYPT_MD5') && CRYPT_MD5){ - return crypt($clear,'$1$'.$salt.'$'); - }else{ + if(defined('CRYPT_MD5') && CRYPT_MD5) { + return crypt($clear, '$1$'.$salt.'$'); + } else { // Fall back to PHP-only implementation return $this->hash_apr1($clear, $salt, '1'); } } - /** * Password hashing method 'lsmd5' * * Uses salted MD5 hashs. Salt is 8 bytes long. * * This is the format used by LDAP. + * + * @param string $clear The clear text to hash + * @param string $salt The salt to use, null for random + * @return string Hashed password */ - public function hash_lsmd5($clear, $salt=null){ - $this->init_salt($salt,8); + public function hash_lsmd5($clear, $salt = null) { + $this->init_salt($salt, 8); return "{SMD5}".base64_encode(md5($clear.$salt, true).$salt); } - /** * Password hashing method 'apr1' * @@ -161,17 +165,17 @@ class PassHash { * * @author * @link http://de.php.net/manual/en/function.crypt.php#73619 - * @param string $clear - the clear text to hash - * @param string $salt - the salt to use, null for random - * @param string $magic - the hash identifier (apr1 or 1) - * @returns string - hashed password + * @param string $clear The clear text to hash + * @param string $salt The salt to use, null for random + * @param string $magic The hash identifier (apr1 or 1) + * @return string Hashed password */ - public function hash_apr1($clear, $salt=null, $magic='apr1'){ - $this->init_salt($salt,8); + public function hash_apr1($clear, $salt = null, $magic = 'apr1') { + $this->init_salt($salt, 8); - $len = strlen($clear); + $len = strlen($clear); $text = $clear.'$'.$magic.'$'.$salt; - $bin = pack("H32", md5($clear.$salt.$clear)); + $bin = pack("H32", md5($clear.$salt.$clear)); for($i = $len; $i > 0; $i -= 16) { $text .= substr($bin, 0, min(16, $i)); } @@ -181,22 +185,24 @@ class PassHash { $bin = pack("H32", md5($text)); for($i = 0; $i < 1000; $i++) { $new = ($i & 1) ? $clear : $bin; - if ($i % 3) $new .= $salt; - if ($i % 7) $new .= $clear; + if($i % 3) $new .= $salt; + if($i % 7) $new .= $clear; $new .= ($i & 1) ? $bin : $clear; $bin = pack("H32", md5($new)); } $tmp = ''; - for ($i = 0; $i < 5; $i++) { + for($i = 0; $i < 5; $i++) { $k = $i + 6; $j = $i + 12; - if ($j == 16) $j = 5; + if($j == 16) $j = 5; $tmp = $bin[$i].$bin[$k].$bin[$j].$tmp; } $tmp = chr(0).chr(0).$bin[11].$tmp; - $tmp = strtr(strrev(substr(base64_encode($tmp), 2)), - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); + $tmp = strtr( + strrev(substr(base64_encode($tmp), 2)), + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + ); return '$'.$magic.'$'.$salt.'$'.$tmp; } @@ -205,10 +211,10 @@ class PassHash { * * Uses MD5 hashs. * - * @param string $clear - the clear text to hash - * @returns string - hashed password + * @param string $clear The clear text to hash + * @return string Hashed password */ - public function hash_md5($clear){ + public function hash_md5($clear) { return md5($clear); } @@ -217,10 +223,10 @@ class PassHash { * * Uses SHA1 hashs. * - * @param string $clear - the clear text to hash - * @returns string - hashed password + * @param string $clear The clear text to hash + * @return string Hashed password */ - public function hash_sha1($clear){ + public function hash_sha1($clear) { return sha1($clear); } @@ -229,12 +235,12 @@ class PassHash { * * Uses salted SHA1 hashs. Salt is 4 bytes long. * - * @param string $clear - the clear text to hash - * @param string $salt - the salt to use, null for random - * @returns string - hashed password + * @param string $clear The clear text to hash + * @param string $salt The salt to use, null for random + * @return string Hashed password */ - public function hash_ssha($clear, $salt=null){ - $this->init_salt($salt,4); + public function hash_ssha($clear, $salt = null) { + $this->init_salt($salt, 4); return '{SSHA}'.base64_encode(pack("H*", sha1($clear.$salt)).$salt); } @@ -243,13 +249,13 @@ class PassHash { * * Uses salted crypt hashs. Salt is 2 bytes long. * - * @param string $clear - the clear text to hash - * @param string $salt - the salt to use, null for random - * @returns string - hashed password + * @param string $clear The clear text to hash + * @param string $salt The salt to use, null for random + * @return string Hashed password */ - public function hash_crypt($clear, $salt=null){ - $this->init_salt($salt,2); - return crypt($clear,$salt); + public function hash_crypt($clear, $salt = null) { + $this->init_salt($salt, 2); + return crypt($clear, $salt); } /** @@ -259,16 +265,16 @@ class PassHash { * * @link http://www.php.net/mysql * @author - * @param string $clear - the clear text to hash - * @returns string - hashed password + * @param string $clear The clear text to hash + * @return string Hashed password */ - public function hash_mysql($clear){ - $nr=0x50305735; - $nr2=0x12345671; - $add=7; + public function hash_mysql($clear) { + $nr = 0x50305735; + $nr2 = 0x12345671; + $add = 7; $charArr = preg_split("//", $clear); - foreach ($charArr as $char) { - if (($char == '') || ($char == ' ') || ($char == '\t')) continue; + foreach($charArr as $char) { + if(($char == '') || ($char == ' ') || ($char == '\t')) continue; $charVal = ord($char); $nr ^= ((($nr & 63) + $add) * $charVal) + ($nr << 8); $nr2 += ($nr2 << 8) ^ $nr; @@ -282,10 +288,10 @@ class PassHash { * * Uses SHA1 hashs. This method is used by MySQL 4.11 and above * - * @param string $clear - the clear text to hash - * @returns string - hashed password + * @param string $clear The clear text to hash + * @return string Hashed password */ - public function hash_my411($clear){ + public function hash_my411($clear) { return '*'.sha1(pack("H*", sha1($clear))); } @@ -297,16 +303,16 @@ class PassHash { * Salt is 2 bytes long, but stored at position 16, so you need to pass at * least 18 bytes. You can pass the crypted hash as salt. * - * @param string $clear - the clear text to hash - * @param string $salt - the salt to use, null for random - * @returns string - hashed password + * @param string $clear The clear text to hash + * @param string $salt The salt to use, null for random + * @return string Hashed password */ - public function hash_kmd5($clear, $salt=null){ + public function hash_kmd5($clear, $salt = null) { $this->init_salt($salt); - $key = substr($salt, 16, 2); - $hash1 = strtolower(md5($key . md5($clear))); - $hash2 = substr($hash1, 0, 16) . $key . substr($hash1, 16); + $key = substr($salt, 16, 2); + $hash1 = strtolower(md5($key.md5($clear))); + $hash2 = substr($hash1, 0, 16).$key.substr($hash1, 16); return $hash2; } @@ -321,54 +327,55 @@ class PassHash { * an exception. * * @link http://www.openwall.com/phpass/ - * @param string $clear - the clear text to hash - * @param string $salt - the salt to use, null for random - * @param string $magic - the hash identifier (P or H) - * @param int $compute - the iteration count for new passwords - * @returns string - hashed password + * @param string $clear The clear text to hash + * @param string $salt The salt to use, null for random + * @param string $magic The hash identifier (P or H) + * @param int $compute The iteration count for new passwords + * @throws Exception + * @return string Hashed password */ - public function hash_pmd5($clear, $salt=null, $magic='P',$compute=8){ + public function hash_pmd5($clear, $salt = null, $magic = 'P', $compute = 8) { $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; - if(is_null($salt)){ + if(is_null($salt)) { $this->init_salt($salt); $salt = $itoa64[$compute].$salt; // prefix iteration count } $iterc = $salt[0]; // pos 0 of salt is iteration count - $iter = strpos($itoa64,$iterc); + $iter = strpos($itoa64, $iterc); - if($iter > 30){ + if($iter > 30) { throw new Exception("Too high iteration count ($iter) in ". - __class__.'::'.__function__); + __CLASS__.'::'.__FUNCTION__); } $iter = 1 << $iter; - $salt = substr($salt,1,8); + $salt = substr($salt, 1, 8); // iterate - $hash = md5($salt . $clear, true); + $hash = md5($salt.$clear, true); do { - $hash = md5($hash . $clear, true); - } while (--$iter); + $hash = md5($hash.$clear, true); + } while(--$iter); // encode $output = ''; - $count = 16; - $i = 0; + $count = 16; + $i = 0; do { $value = ord($hash[$i++]); $output .= $itoa64[$value & 0x3f]; - if ($i < $count) + if($i < $count) $value |= ord($hash[$i]) << 8; $output .= $itoa64[($value >> 6) & 0x3f]; - if ($i++ >= $count) + if($i++ >= $count) break; - if ($i < $count) + if($i < $count) $value |= ord($hash[$i]) << 16; $output .= $itoa64[($value >> 12) & 0x3f]; - if ($i++ >= $count) + if($i++ >= $count) break; $output .= $itoa64[($value >> 18) & 0x3f]; - } while ($i < $count); + } while($i < $count); return '$'.$magic.'$'.$iterc.$salt.$output; } @@ -376,7 +383,7 @@ class PassHash { /** * Alias for hash_pmd5 */ - public function hash_hmd5($clear, $salt=null, $magic='H', $compute=8){ + public function hash_hmd5($clear, $salt = null, $magic = 'H', $compute = 8) { return $this->hash_pmd5($clear, $salt, $magic, $compute); } @@ -387,12 +394,12 @@ class PassHash { * This is used by the Django Python framework * * @link http://docs.djangoproject.com/en/dev/topics/auth/#passwords - * @param string $clear - the clear text to hash - * @param string $salt - the salt to use, null for random - * @returns string - hashed password + * @param string $clear The clear text to hash + * @param string $salt The salt to use, null for random + * @return string Hashed password */ - public function hash_djangosha1($clear, $salt=null){ - $this->init_salt($salt,5); + public function hash_djangosha1($clear, $salt = null) { + $this->init_salt($salt, 5); return 'sha1$'.$salt.'$'.sha1($salt.$clear); } @@ -403,16 +410,15 @@ class PassHash { * This is used by the Django Python framework * * @link http://docs.djangoproject.com/en/dev/topics/auth/#passwords - * @param string $clear - the clear text to hash - * @param string $salt - the salt to use, null for random - * @returns string - hashed password + * @param string $clear The clear text to hash + * @param string $salt The salt to use, null for random + * @return string Hashed password */ - public function hash_djangomd5($clear, $salt=null){ - $this->init_salt($salt,5); + public function hash_djangomd5($clear, $salt = null) { + $this->init_salt($salt, 5); return 'md5$'.$salt.'$'.md5($salt.$clear); } - /** * Passwordhashing method 'bcrypt' * @@ -424,20 +430,21 @@ class PassHash { * will break. When no salt is given, the iteration count can be set * through the $compute variable. * - * @param string $clear - the clear text to hash - * @param string $salt - the salt to use, null for random - * @param int $compute - the iteration count (between 4 and 31) - * @returns string - hashed password + * @param string $clear The clear text to hash + * @param string $salt The salt to use, null for random + * @param int $compute The iteration count (between 4 and 31) + * @throws Exception + * @return string Hashed password */ - public function hash_bcrypt($clear, $salt=null, $compute=8){ - if(!defined('CRYPT_BLOWFISH') || CRYPT_BLOWFISH != 1){ + public function hash_bcrypt($clear, $salt = null, $compute = 8) { + if(!defined('CRYPT_BLOWFISH') || CRYPT_BLOWFISH != 1) { throw new Exception('This PHP installation has no bcrypt support'); } - if(is_null($salt)){ + if(is_null($salt)) { if($compute < 4 || $compute > 31) $compute = 8; $salt = '$2a$'.str_pad($compute, 2, '0', STR_PAD_LEFT).'$'. - $this->gen_salt(22); + $this->gen_salt(22); } return crypt($clear, $salt); -- cgit v1.2.3 From 3791b5891b0644625c7b05b63fc27fc5086a0f2c Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 23 Jun 2012 14:55:21 +0200 Subject: use more secure password hash for admin pass FS#2536 --- conf/users.auth.php.dist | 2 +- install.php | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/conf/users.auth.php.dist b/conf/users.auth.php.dist index 6576eeb5f..df3c78482 100644 --- a/conf/users.auth.php.dist +++ b/conf/users.auth.php.dist @@ -6,5 +6,5 @@ # # Format: # -# user:MD5password:Real Name:email:groups,comma,seperated +# login:passwordhash:Real Name:email:groups,comma,seperated diff --git a/install.php b/install.php index bd43c6f99..80e9ad407 100644 --- a/install.php +++ b/install.php @@ -9,6 +9,8 @@ if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/'); if(!defined('DOKU_CONF')) define('DOKU_CONF',DOKU_INC.'conf/'); if(!defined('DOKU_LOCAL')) define('DOKU_LOCAL',DOKU_INC.'conf/'); +require_once(DOKU_INC.'inc/PassHash.class.php'); + // check for error reporting override or set error reporting to sane values if (!defined('DOKU_E_LEVEL')) { error_reporting(E_ALL ^ E_NOTICE); } else { error_reporting(DOKU_E_LEVEL); } @@ -50,6 +52,7 @@ $dokuwiki_hash = array( '2011-05-25' => '4241865472edb6fa14a1227721008072', '2011-11-10' => 'b46ff19a7587966ac4df61cbab1b8b31', '2012-01-25' => '72c083c73608fc43c586901fd5dabb74', + 'devel' => 'eb0b3fc90056fbc12bac6f49f7764df3' ); @@ -318,9 +321,13 @@ EOT; $ok = $ok && fileWrite(DOKU_LOCAL.'local.php',$output); if ($d['acl']) { + // hash the password + $phash = new PassHash(); + $pass = $phash->hash_smd5($d['password']); + // create users.auth.php - // --- user:MD5password:Real Name:email:groups,comma,seperated - $output = join(":",array($d['superuser'], md5($d['password']), $d['fullname'], $d['email'], 'admin,user')); + // --- user:SMD5password:Real Name:email:groups,comma,seperated + $output = join(":",array($d['superuser'], $pass, $d['fullname'], $d['email'], 'admin,user')); $output = @file_get_contents(DOKU_CONF.'users.auth.php.dist')."\n$output\n"; $ok = $ok && fileWrite(DOKU_LOCAL.'users.auth.php', $output); -- cgit v1.2.3 From 89177306a2278255d6a2203b5fff4a839183d3cd Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 24 Jun 2012 14:00:49 +0200 Subject: Introducing a $_REQUEST/POST/GET wrapper This new wrapper ensures types are correct and accessed parameters are actually set (with custom default fallbacks). The wrapper is available in the global $INPUT variable. It accesses $_REQUEST by default. If POST or GET is required, the post and get members can be used: $INPUT->int('foo',false); // access $_REQUEST['foo'], default false $INPUT->post->int('foo'); // access $_POST['foo'], default 0 $INPUT->get->int('foo'); // access $_GET['foo'], default 0 The codebase still needs to be updated to make use of this. --- inc/Input.class.php | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++ inc/init.php | 4 ++ inc/load.php | 1 + 3 files changed, 152 insertions(+) create mode 100644 inc/Input.class.php diff --git a/inc/Input.class.php b/inc/Input.class.php new file mode 100644 index 000000000..f1967599f --- /dev/null +++ b/inc/Input.class.php @@ -0,0 +1,147 @@ + + */ +class Input { + + /** @var PostInput Access $_POST parameters */ + public $post; + /** @var GetInput Access $_GET parameters */ + public $get; + + protected $access; + + /** + * Intilizes the Input class and it subcomponents + */ + function __construct() { + $this->access = &$_REQUEST; + $this->post = new PostInput(); + $this->get = new GetInput(); + } + + /** + * Access a request parameter without any type conversion + * + * @param string $name Parameter name + * @param mixed $default Default to return if parameter isn't set + * @return mixed + */ + public function param($name, $default = null) { + if(!isset($this->access[$name])) return $default; + return $this->access[$name]; + } + + /** + * Get a reference to a request parameter + * + * This avoids copying data in memory, when the parameter is not set it will be created + * and intialized with the given $default value before a reference is returned + * + * @param string $name Parameter name + * @param mixed $default Initialize parameter with if not set + * @return &mixed + */ + public function &ref($name, $default = '') { + if(!isset($this->access[$name])) { + $this->access[$name] = $default; + } + + $ref = &$this->access[$name]; + return $ref; + } + + /** + * Access a request parameter as int + * + * @param string $name Parameter name + * @param mixed $default Default to return if parameter isn't set or is an array + * @return int + */ + public function int($name, $default = 0) { + if(!isset($this->access[$name])) return $default; + if(is_array($this->access[$name])) return $default; + + return (int) $this->access[$name]; + } + + /** + * Access a request parameter as string + * + * @param string $name Parameter name + * @param mixed $default Default to return if parameter isn't set or is an array + * @return string + */ + public function str($name, $default = '') { + if(!isset($this->access[$name])) return $default; + if(is_array($this->access[$name])) return $default; + + return (string) $this->access[$name]; + } + + /** + * Access a request parameter as bool + * + * @param string $name Parameter name + * @param mixed $default Default to return if parameter isn't set + * @return bool + */ + public function bool($name, $default = '') { + if(!isset($this->access[$name])) return $default; + + return (bool) $this->access[$name]; + } + + /** + * Access a request parameter as array + * + * @param string $name Parameter name + * @param mixed $default Default to return if parameter isn't set + * @return array + */ + public function arr($name, $default = array()) { + if(!isset($this->access[$name])) return $default; + + return (array) $this->access[$name]; + } + +} + +/** + * Internal class used for $_POST access in Input class + */ +class PostInput extends Input { + protected $access; + + /** + * Initialize the $access array, remove subclass members + */ + function __construct() { + $this->access = &$_POST; + unset ($this->post); + unset ($this->get); + } +} + +/** + * Internal class used for $_GET access in Input class + */ +class GetInput extends Input { + protected $access; + + /** + * Initialize the $access array, remove subclass members + */ + function __construct() { + $this->access = &$_GET; + unset ($this->post); + unset ($this->get); + } +} \ No newline at end of file diff --git a/inc/init.php b/inc/init.php index 403fbe4ab..1907aea09 100644 --- a/inc/init.php +++ b/inc/init.php @@ -197,6 +197,10 @@ if (empty($plugin_controller_class)) $plugin_controller_class = 'Doku_Plugin_Con // load libraries require_once(DOKU_INC.'inc/load.php'); +// input handle class +global $INPUT; +$INPUT = new Input(); + // initialize plugin controller $plugin_controller = new $plugin_controller_class(); diff --git a/inc/load.php b/inc/load.php index 7a410e452..b676518e7 100644 --- a/inc/load.php +++ b/inc/load.php @@ -62,6 +62,7 @@ function load_autoload($name){ 'Doku_Event' => DOKU_INC.'inc/events.php', 'Doku_Event_Handler' => DOKU_INC.'inc/events.php', 'EmailAddressValidator' => DOKU_INC.'inc/EmailAddressValidator.php', + 'Input' => DOKU_INC.'inc/Input.class.php', 'JpegMeta' => DOKU_INC.'inc/JpegMeta.php', 'SimplePie' => DOKU_INC.'inc/SimplePie.php', 'FeedParser' => DOKU_INC.'inc/FeedParser.php', -- cgit v1.2.3 From fd50d5c713878b03fdcd8d21f8209f968fe55646 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 24 Jun 2012 14:35:23 +0200 Subject: added has() method to input class --- inc/Input.class.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/inc/Input.class.php b/inc/Input.class.php index f1967599f..7665c609e 100644 --- a/inc/Input.class.php +++ b/inc/Input.class.php @@ -27,6 +27,19 @@ class Input { $this->get = new GetInput(); } + /** + * Check if a parameter was set + * + * Basically a wrapper around isset + * + * @see isset + * @param $name Parameter name + * @return bool + */ + public function has($name) { + return isset($this->access[$name]); + } + /** * Access a request parameter without any type conversion * -- cgit v1.2.3 From dbd7dc8e229b08ed2adb060d445a5516c94f3c5d Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 24 Jun 2012 14:42:45 +0200 Subject: use INPUT wrapper in doku.php --- doku.php | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/doku.php b/doku.php index 97e594cb3..63756d6e2 100644 --- a/doku.php +++ b/doku.php @@ -4,6 +4,8 @@ * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Andreas Gohr + * + * @global Input $INPUT */ // update message version @@ -27,29 +29,26 @@ if (isset($_SERVER['HTTP_X_DOKUWIKI_DO'])){ require_once(DOKU_INC.'inc/init.php'); //import variables -$_REQUEST['id'] = str_replace("\xC2\xAD",'',$_REQUEST['id']); //soft-hyphen -$QUERY = trim($_REQUEST['id']); +$_REQUEST['id'] = str_replace("\xC2\xAD",'',$INPUT->str('id')); //soft-hyphen +$QUERY = trim($INPUT->str('id')); $ID = getID(); // deprecated 2011-01-14 $NS = getNS($ID); -$REV = $_REQUEST['rev']; -$IDX = $_REQUEST['idx']; -$DATE = $_REQUEST['date']; -$RANGE = $_REQUEST['range']; -$HIGH = $_REQUEST['s']; +$REV = $INPUT->int('rev'); +$IDX = $INPUT->str('idx'); +$DATE = $INPUT->int('date'); +$RANGE = $INPUT->str('range'); +$HIGH = $INPUT->param('s'); if(empty($HIGH)) $HIGH = getGoogleQuery(); -if (isset($_POST['wikitext'])) { - $TEXT = cleanText($_POST['wikitext']); +if ($INPUT->post->has('wikitext')) { + $TEXT = cleanText($INPUT->post->str('wikitext')); } -$PRE = cleanText(substr($_POST['prefix'], 0, -1)); -$SUF = cleanText($_POST['suffix']); -$SUM = $_REQUEST['summary']; - -//sanitize revision -$REV = preg_replace('/[^0-9]/','',$REV); +$PRE = cleanText(substr($INPUT->post->str('prefix'), 0, -1)); +$SUF = cleanText($INPUT->post->str('suffix')); +$SUM = $INPUT->post->str('summary'); //make infos about the selected page available $INFO = pageinfo(); -- cgit v1.2.3 From 514144657a25baed120871a6cee217d67da99b38 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 24 Jun 2012 14:43:51 +0200 Subject: code beautification --- doku.php | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/doku.php b/doku.php index 63756d6e2..4499bc197 100644 --- a/doku.php +++ b/doku.php @@ -13,13 +13,13 @@ $updateVersion = 36.1; // xdebug_start_profiling(); -if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/'); +if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__).'/'); -if (isset($_SERVER['HTTP_X_DOKUWIKI_DO'])){ +if(isset($_SERVER['HTTP_X_DOKUWIKI_DO'])) { $ACT = trim(strtolower($_SERVER['HTTP_X_DOKUWIKI_DO'])); -} elseif (!empty($_REQUEST['idx'])) { +} elseif(!empty($_REQUEST['idx'])) { $ACT = 'index'; -} elseif (isset($_REQUEST['do'])) { +} elseif(isset($_REQUEST['do'])) { $ACT = $_REQUEST['do']; } else { $ACT = 'show'; @@ -29,12 +29,12 @@ if (isset($_SERVER['HTTP_X_DOKUWIKI_DO'])){ require_once(DOKU_INC.'inc/init.php'); //import variables -$_REQUEST['id'] = str_replace("\xC2\xAD",'',$INPUT->str('id')); //soft-hyphen -$QUERY = trim($INPUT->str('id')); -$ID = getID(); +$_REQUEST['id'] = str_replace("\xC2\xAD", '', $INPUT->str('id')); //soft-hyphen +$QUERY = trim($INPUT->str('id')); +$ID = getID(); // deprecated 2011-01-14 -$NS = getNS($ID); +$NS = getNS($ID); $REV = $INPUT->int('rev'); $IDX = $INPUT->str('idx'); @@ -43,12 +43,12 @@ $RANGE = $INPUT->str('range'); $HIGH = $INPUT->param('s'); if(empty($HIGH)) $HIGH = getGoogleQuery(); -if ($INPUT->post->has('wikitext')) { - $TEXT = cleanText($INPUT->post->str('wikitext')); +if($INPUT->post->has('wikitext')) { + $TEXT = cleanText($INPUT->post->str('wikitext')); } -$PRE = cleanText(substr($INPUT->post->str('prefix'), 0, -1)); -$SUF = cleanText($INPUT->post->str('suffix')); -$SUM = $INPUT->post->str('summary'); +$PRE = cleanText(substr($INPUT->post->str('prefix'), 0, -1)); +$SUF = cleanText($INPUT->post->str('suffix')); +$SUM = $INPUT->post->str('summary'); //make infos about the selected page available $INFO = pageinfo(); @@ -57,28 +57,28 @@ $INFO = pageinfo(); $JSINFO['id'] = $ID; $JSINFO['namespace'] = (string) $INFO['namespace']; - // handle debugging -if($conf['allowdebug'] && $ACT == 'debug'){ +if($conf['allowdebug'] && $ACT == 'debug') { html_debug(); exit; } //send 404 for missing pages if configured or ID has special meaning to bots if(!$INFO['exists'] && - ($conf['send404'] || preg_match('/^(robots\.txt|sitemap\.xml(\.gz)?|favicon\.ico|crossdomain\.xml)$/',$ID)) && - ($ACT == 'show' || (!is_array($ACT) && substr($ACT,0,7) == 'export_')) ){ + ($conf['send404'] || preg_match('/^(robots\.txt|sitemap\.xml(\.gz)?|favicon\.ico|crossdomain\.xml)$/', $ID)) && + ($ACT == 'show' || (!is_array($ACT) && substr($ACT, 0, 7) == 'export_')) +) { header('HTTP/1.0 404 Not Found'); } //prepare breadcrumbs (initialize a static var) -if ($conf['breadcrumbs']) breadcrumbs(); +if($conf['breadcrumbs']) breadcrumbs(); // check upstream checkUpdateMessages(); $tmp = array(); // No event data -trigger_event('DOKUWIKI_STARTED',$tmp); +trigger_event('DOKUWIKI_STARTED', $tmp); //close session session_write_close(); -- cgit v1.2.3 From f9aa73bff850a3d60a1f3df02e5e97741051bc60 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 24 Jun 2012 14:59:43 +0200 Subject: code cleanup --- feed.php | 340 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 183 insertions(+), 157 deletions(-) diff --git a/feed.php b/feed.php index 98d5ef2e8..a54c30978 100644 --- a/feed.php +++ b/feed.php @@ -4,9 +4,11 @@ * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Andreas Gohr + * + * @global array $conf */ -if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/'); +if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__).'/'); require_once(DOKU_INC.'inc/init.php'); //close session @@ -17,8 +19,8 @@ $opt = rss_parseOptions(); // the feed is dynamic - we need a cache for each combo // (but most people just use the default feed so it's still effective) -$cache = getCacheName(join('',array_values($opt)).$_SERVER['REMOTE_USER'],'.feed'); -$key = join('', array_values($opt)) . $_SERVER['REMOTE_USER']; +$cache = getCacheName(join('', array_values($opt)).$_SERVER['REMOTE_USER'], '.feed'); +$key = join('', array_values($opt)).$_SERVER['REMOTE_USER']; $cache = new cache($key, '.feed'); // prepare cache depends @@ -39,34 +41,36 @@ if($cache->useCache($depends)) { exit; } else { http_conditionalRequest(time()); - } +} // create new feed -$rss = new DokuWikiFeedCreator(); -$rss->title = $conf['title'].(($opt['namespace']) ? ' '.$opt['namespace'] : ''); -$rss->link = DOKU_URL; +$rss = new DokuWikiFeedCreator(); +$rss->title = $conf['title'].(($opt['namespace']) ? ' '.$opt['namespace'] : ''); +$rss->link = DOKU_URL; $rss->syndicationURL = DOKU_URL.'feed.php'; $rss->cssStyleSheet = DOKU_URL.'lib/exe/css.php?s=feed'; -$image = new FeedImage(); +$image = new FeedImage(); $image->title = $conf['title']; -$image->url = tpl_getMediaFile('favicon.ico', true); -$image->link = DOKU_URL; -$rss->image = $image; - -$data = null; -$modes = array('list' => 'rssListNamespace', - 'search' => 'rssSearch', - 'recent' => 'rssRecentChanges'); -if (isset($modes[$opt['feed_mode']])) { +$image->url = tpl_getMediaFile('favicon.ico', true); +$image->link = DOKU_URL; +$rss->image = $image; + +$data = null; +$modes = array( + 'list' => 'rssListNamespace', + 'search' => 'rssSearch', + 'recent' => 'rssRecentChanges' +); +if(isset($modes[$opt['feed_mode']])) { $data = $modes[$opt['feed_mode']]($opt); } else { $eventData = array( 'opt' => &$opt, 'data' => &$data, ); - $event = new Doku_Event('FEED_MODE_UNKNOWN', $eventData); - if ($event->advise_before(true)) { + $event = new Doku_Event('FEED_MODE_UNKNOWN', $eventData); + if($event->advise_before(true)) { echo sprintf('Unknown feed mode %s', hsc($opt['feed_mode'])); exit; } @@ -74,7 +78,7 @@ if (isset($modes[$opt['feed_mode']])) { } rss_buildItems($rss, $data, $opt); -$feed = $rss->createFeed($opt['feed_type'],'utf-8'); +$feed = $rss->createFeed($opt['feed_type'], 'utf-8'); // save cachefile $cache->storeCache($feed); @@ -89,51 +93,55 @@ print $feed; * * @author Andreas Gohr */ -function rss_parseOptions(){ +function rss_parseOptions() { global $conf; $opt = array(); foreach(array( - // Basic feed properties - // Plugins may probably want to add new values to these - // properties for implementing own feeds - - // One of: list, search, recent - 'feed_mode' => array('mode', 'recent'), - // One of: diff, page, rev, current - 'link_to' => array('linkto', $conf['rss_linkto']), - // One of: abstract, diff, htmldiff, html - 'item_content' => array('content', $conf['rss_content']), - - // Special feed properties - // These are only used by certain feed_modes - - // String, used for feed title, in list and rc mode - 'namespace' => array('ns', null), - // Positive integer, only used in rc mode - 'items' => array('num', $conf['recent']), - // Boolean, only used in rc mode - 'show_minor' => array('minor', false), - // String, only used in search mode - 'search_query' => array('q', null), - // One of: pages, media, both - 'content_type' => array('view', $conf['rss_media']) - - ) as $name => $val) { + // Basic feed properties + // Plugins may probably want to add new values to these + // properties for implementing own feeds + + // One of: list, search, recent + 'feed_mode' => array('mode', 'recent'), + // One of: diff, page, rev, current + 'link_to' => array('linkto', $conf['rss_linkto']), + // One of: abstract, diff, htmldiff, html + 'item_content' => array('content', $conf['rss_content']), + + // Special feed properties + // These are only used by certain feed_modes + + // String, used for feed title, in list and rc mode + 'namespace' => array('ns', null), + // Positive integer, only used in rc mode + 'items' => array('num', $conf['recent']), + // Boolean, only used in rc mode + 'show_minor' => array('minor', false), + // String, only used in search mode + 'search_query' => array('q', null), + // One of: pages, media, both + 'content_type' => array('view', $conf['rss_media']) + + ) as $name => $val) { $opt[$name] = (isset($_REQUEST[$val[0]]) && !empty($_REQUEST[$val[0]])) - ? $_REQUEST[$val[0]] : $val[1]; + ? $_REQUEST[$val[0]] : $val[1]; } - $opt['items'] = max(0, (int) $opt['items']); - $opt['show_minor'] = (bool) $opt['show_minor']; + $opt['items'] = max(0, (int) $opt['items']); + $opt['show_minor'] = (bool) $opt['show_minor']; - $opt['guardmail'] = ($conf['mailguard'] != '' && $conf['mailguard'] != 'none'); + $opt['guardmail'] = ($conf['mailguard'] != '' && $conf['mailguard'] != 'none'); - $type = valid_input_set('type', array('rss','rss2','atom','atom1','rss1', - 'default' => $conf['rss_type']), - $_REQUEST); - switch ($type){ + $type = valid_input_set( + 'type', array( + 'rss', 'rss2', 'atom', 'atom1', 'rss1', + 'default' => $conf['rss_type'] + ), + $_REQUEST + ); + switch($type) { case 'rss': $opt['feed_type'] = 'RSS0.91'; $opt['mime_type'] = 'text/xml'; @@ -166,26 +174,27 @@ function rss_parseOptions(){ * Add recent changed pages to a feed object * * @author Andreas Gohr - * @param object $rss - the FeedCreator Object - * @param array $data - the items to add - * @param array $opt - the feed options + * @param FeedCreator $rss the FeedCreator Object + * @param array $data the items to add + * @param array $opt the feed options */ -function rss_buildItems(&$rss,&$data,$opt){ +function rss_buildItems(&$rss, &$data, $opt) { global $conf; global $lang; + /* @var auth_basic $auth */ global $auth; $eventData = array( - 'rss' => &$rss, + 'rss' => &$rss, 'data' => &$data, - 'opt' => &$opt, + 'opt' => &$opt, ); - $event = new Doku_Event('FEED_DATA_PROCESS', $eventData); - if ($event->advise_before(false)){ - foreach($data as $ditem){ - if(!is_array($ditem)){ + $event = new Doku_Event('FEED_DATA_PROCESS', $eventData); + if($event->advise_before(false)) { + foreach($data as $ditem) { + if(!is_array($ditem)) { // not an array? then only a list of IDs was given - $ditem = array( 'id' => $ditem ); + $ditem = array('id' => $ditem); } $item = new FeedItem(); @@ -195,88 +204,104 @@ function rss_buildItems(&$rss,&$data,$opt){ } // add date - if($ditem['date']){ + if($ditem['date']) { $date = $ditem['date']; - }elseif($meta['date']['modified']){ + } elseif($meta['date']['modified']) { $date = $meta['date']['modified']; - }else{ + } else { $date = @filemtime(wikiFN($id)); } - if($date) $item->date = date('r',$date); + if($date) $item->date = date('r', $date); // add title - if($conf['useheading'] && $meta['title']){ + if($conf['useheading'] && $meta['title']) { $item->title = $meta['title']; - }else{ + } else { $item->title = $ditem['id']; } - if($conf['rss_show_summary'] && !empty($ditem['sum'])){ + if($conf['rss_show_summary'] && !empty($ditem['sum'])) { $item->title .= ' - '.strip_tags($ditem['sum']); } // add item link - switch ($opt['link_to']){ + switch($opt['link_to']) { case 'page': - if ($ditem['media']) { - $item->link = media_managerURL(array('image' => $id, - 'ns' => getNS($id), - 'rev' => $date), '&', true); + if($ditem['media']) { + $item->link = media_managerURL( + array( + 'image' => $id, + 'ns' => getNS($id), + 'rev' => $date + ), '&', true + ); } else { - $item->link = wl($id,'rev='.$date,true,'&', true); + $item->link = wl($id, 'rev='.$date, true, '&', true); } break; case 'rev': - if ($ditem['media']) { - $item->link = media_managerURL(array('image' => $id, - 'ns' => getNS($id), - 'rev' => $date, - 'tab_details' => 'history'), '&', true); + if($ditem['media']) { + $item->link = media_managerURL( + array( + 'image' => $id, + 'ns' => getNS($id), + 'rev' => $date, + 'tab_details' => 'history' + ), '&', true + ); } else { - $item->link = wl($id,'do=revisions&rev='.$date,true,'&'); + $item->link = wl($id, 'do=revisions&rev='.$date, true, '&'); } break; case 'current': - if ($ditem['media']) { - $item->link = media_managerURL(array('image' => $id, - 'ns' => getNS($id)), '&', true); + if($ditem['media']) { + $item->link = media_managerURL( + array( + 'image' => $id, + 'ns' => getNS($id) + ), '&', true + ); } else { - $item->link = wl($id, '', true,'&'); + $item->link = wl($id, '', true, '&'); } break; case 'diff': default: - if ($ditem['media']) { - $item->link = media_managerURL(array('image' => $id, - 'ns' => getNS($id), - 'rev' => $date, - 'tab_details' => 'history', - 'mediado' => 'diff'), '&', true); + if($ditem['media']) { + $item->link = media_managerURL( + array( + 'image' => $id, + 'ns' => getNS($id), + 'rev' => $date, + 'tab_details' => 'history', + 'mediado' => 'diff' + ), '&', true + ); } else { - $item->link = wl($id,'rev='.$date.'&do=diff',true,'&'); + $item->link = wl($id, 'rev='.$date.'&do=diff', true, '&'); } } // add item content - switch ($opt['item_content']){ + switch($opt['item_content']) { case 'diff': case 'htmldiff': - if ($ditem['media']) { - $revs = getRevisions($id, 0, 1, 8192, true); - $rev = $revs[0]; + if($ditem['media']) { + $revs = getRevisions($id, 0, 1, 8192, true); + $rev = $revs[0]; $src_r = ''; $src_l = ''; - if ($size = media_image_preview_size($id, false, new JpegMeta(mediaFN($id)), 300)) { - $more = 'w='.$size[0].'&h='.$size[1].'t='.@filemtime(mediaFN($id)); + if($size = media_image_preview_size($id, false, new JpegMeta(mediaFN($id)), 300)) { + $more = 'w='.$size[0].'&h='.$size[1].'t='.@filemtime(mediaFN($id)); $src_r = ml($id, $more); } - if ($rev && $size = media_image_preview_size($id, $rev, new JpegMeta(mediaFN($id, $rev)), 300)){ - $more = 'rev='.$rev.'&w='.$size[0].'&h='.$size[1]; + if($rev && $size = media_image_preview_size($id, $rev, new JpegMeta(mediaFN($id, $rev)), 300)) { + $more = 'rev='.$rev.'&w='.$size[0].'&h='.$size[1]; $src_l = ml($id, $more); } $content = ''; - if ($src_r) { - $content = ''; + if($src_r) { + $content = '
'; $content .= ''; $content .= ''; $content .= ''; + return ''; } function contextLine($line) { @@ -1132,8 +1132,8 @@ class InlineDiffFormatter extends DiffFormatter { // Preserve whitespaces by converting some to non-breaking spaces. // Do not convert all of them to allow word-wrap. $val = parent::format($diff); - $val = str_replace(' ','  ', $val); - $val = preg_replace('/ (?=<)|(?<=[ >]) /', ' ', $val); + $val = str_replace(' ','  ', $val); + $val = preg_replace('/ (?=<)|(?<=[ >]) /', ' ', $val); return $val; } diff --git a/inc/JpegMeta.php b/inc/JpegMeta.php index 5c043fb6b..ac29bca66 100644 --- a/inc/JpegMeta.php +++ b/inc/JpegMeta.php @@ -2972,7 +2972,7 @@ class JpegMeta { elseif ($c == 62) $ascii .= '>'; elseif ($c == 32) - $ascii .= ' '; + $ascii .= ' '; elseif ($c > 32) $ascii .= chr($c); else diff --git a/inc/html.php b/inc/html.php index 738b1f1b4..f9712d975 100644 --- a/inc/html.php +++ b/inc/html.php @@ -327,7 +327,7 @@ function html_search(){ //show progressbar print '
'.NL; - print ''.NL; print '
'.NL; @@ -389,7 +389,7 @@ function html_search(){ } //hide progressbar - print ''.NL; flush(); @@ -494,7 +494,7 @@ function html_revisions($first=0, $media_id = false){ if (!$media_id) { $form->addElement(form_makeOpenTag('span', array('class' => 'sum'))); - $form->addElement(' – '); + $form->addElement(' – '); $form->addElement(htmlspecialchars($INFO['sum'])); $form->addElement(form_makeCloseTag('span')); } @@ -573,7 +573,7 @@ function html_revisions($first=0, $media_id = false){ if ($info['sum']) { $form->addElement(form_makeOpenTag('span', array('class' => 'sum'))); - if (!$media_id) $form->addElement(' – '); + if (!$media_id) $form->addElement(' – '); $form->addElement(htmlspecialchars($info['sum'])); $form->addElement(form_makeCloseTag('span')); } @@ -765,7 +765,7 @@ function html_recent($first=0, $show_changes='both'){ $form->addElement(html_wikilink(':'.$recent['id'],useHeading('navigation')?null:$recent['id'])); } $form->addElement(form_makeOpenTag('span', array('class' => 'sum'))); - $form->addElement(' – '.htmlspecialchars($recent['sum'])); + $form->addElement(' – '.htmlspecialchars($recent['sum'])); $form->addElement(form_makeCloseTag('span')); $form->addElement(form_makeOpenTag('span', array('class' => 'user'))); @@ -1418,7 +1418,7 @@ function html_edit(){ if ($wr) { // sets changed to true when previewed - echo '' . NL; } ?> diff --git a/inc/media.php b/inc/media.php index 2462a1deb..e1d5d511e 100644 --- a/inc/media.php +++ b/inc/media.php @@ -1442,7 +1442,7 @@ function media_printfile_thumbs($item,$auth,$jump=false,$display_namespace=false $size .= (int) $item['meta']->getField('File.Height'); echo '
'.$size.'
'.NL; } else { - echo '
 
'.NL; + echo '
 
'.NL; } $date = dformat($item['mtime']); echo '
'.$date.'
'.NL; @@ -1723,7 +1723,7 @@ function media_nstree_li($item){ if($item['open']){ $class .= ' open'; $img = DOKU_BASE.'lib/images/minus.gif'; - $alt = '−'; + $alt = '−'; }else{ $class .= ' closed'; $img = DOKU_BASE.'lib/images/plus.gif'; diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php index 119ac3f01..2f09dbd4f 100644 --- a/inc/parser/xhtml.php +++ b/inc/parser/xhtml.php @@ -549,7 +549,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer { global $ID; $name = $this->_getLinkTitle($name, $hash, $isImage); $hash = $this->_headerToLink($hash); - $title = $ID.' ↵'; + $title = $ID.' ↵'; $this->doc .= ''; $this->doc .= $name; $this->doc .= ''; diff --git a/inc/template.php b/inc/template.php index c9e899034..41da64d2e 100644 --- a/inc/template.php +++ b/inc/template.php @@ -714,7 +714,7 @@ function tpl_searchform($ajax=true,$autocomplete=true){ * * @author Andreas Gohr */ -function tpl_breadcrumbs($sep='•'){ +function tpl_breadcrumbs($sep='•'){ global $lang; global $conf; @@ -757,7 +757,7 @@ function tpl_breadcrumbs($sep='•'){ * @author * @todo May behave strangely in RTL languages */ -function tpl_youarehere($sep=' » '){ +function tpl_youarehere($sep=' » '){ global $conf; global $ID; global $lang; @@ -843,7 +843,7 @@ function tpl_pageinfo($ret=false){ if($INFO['exists']){ $out = ''; $out .= $fn; - $out .= ' · '; + $out .= ' · '; $out .= $lang['lastmod']; $out .= ': '; $out .= $date; @@ -854,7 +854,7 @@ function tpl_pageinfo($ret=false){ $out .= ' ('.$lang['external_edit'].')'; } if($INFO['locked']){ - $out .= ' · '; + $out .= ' · '; $out .= $lang['lockedby']; $out .= ': '; $out .= editorinfo($INFO['locked']); diff --git a/install.php b/install.php index a1d406209..3d9fddbb2 100644 --- a/install.php +++ b/install.php @@ -78,7 +78,7 @@ header('Content-Type: text/html; charset=utf-8'); select.text, input.text { width: 30em; margin: 0 0.5em; } a {text-decoration: none} -
'.$rev.''.$lang['current'].'
'; @@ -287,57 +312,57 @@ function rss_buildItems(&$rss,&$data,$opt){ } else { require_once(DOKU_INC.'inc/DifferenceEngine.php'); $revs = getRevisions($id, 0, 1); - $rev = $revs[0]; - - if($rev){ - $df = new Diff(explode("\n",htmlspecialchars(rawWiki($id,$rev))), - explode("\n",htmlspecialchars(rawWiki($id,'')))); - }else{ - $df = new Diff(array(''), - explode("\n",htmlspecialchars(rawWiki($id,'')))); + $rev = $revs[0]; + + if($rev) { + $df = new Diff(explode("\n", htmlspecialchars(rawWiki($id, $rev))), + explode("\n", htmlspecialchars(rawWiki($id, '')))); + } else { + $df = new Diff(array(''), + explode("\n", htmlspecialchars(rawWiki($id, '')))); } - if($opt['item_content'] == 'htmldiff'){ - $tdf = new TableDiffFormatter(); - $content = ''; + if($opt['item_content'] == 'htmldiff') { + $tdf = new TableDiffFormatter(); + $content = '
'; $content .= ''; $content .= ''; $content .= $tdf->format($df); $content .= '
'.$rev.''.$lang['current'].'
'; - }else{ - $udf = new UnifiedDiffFormatter(); + } else { + $udf = new UnifiedDiffFormatter(); $content = "
\n".$udf->format($df)."\n
"; } } break; case 'html': - if ($ditem['media']) { - if ($size = media_image_preview_size($id, false, new JpegMeta(mediaFN($id)))) { - $more = 'w='.$size[0].'&h='.$size[1].'t='.@filemtime(mediaFN($id)); - $src = ml($id, $more); + if($ditem['media']) { + if($size = media_image_preview_size($id, false, new JpegMeta(mediaFN($id)))) { + $more = 'w='.$size[0].'&h='.$size[1].'t='.@filemtime(mediaFN($id)); + $src = ml($id, $more); $content = ''.$id.''; } else { $content = ''; } } else { - $content = p_wiki_xhtml($id,$date,false); + $content = p_wiki_xhtml($id, $date, false); // no TOC in feeds - $content = preg_replace('/().*()/s','',$content); + $content = preg_replace('/().*()/s', '', $content); // make URLs work when canonical is not set, regexp instead of rerendering! - if(!$conf['canonical']){ - $base = preg_quote(DOKU_REL,'/'); - $content = preg_replace('/('; } else { $content = ''; @@ -350,12 +375,12 @@ function rss_buildItems(&$rss,&$data,$opt){ // add user # FIXME should the user be pulled from metadata as well? - $user = @$ditem['user']; // the @ spares time repeating lookup + $user = @$ditem['user']; // the @ spares time repeating lookup $item->author = ''; - if($user && $conf['useacl'] && $auth){ + if($user && $conf['useacl'] && $auth) { $userInfo = $auth->getUserData($user); - if ($userInfo){ - switch ($conf['showuseras']){ + if($userInfo) { + switch($conf['showuseras']) { case 'username': $item->author = $userInfo['name']; break; @@ -366,35 +391,37 @@ function rss_buildItems(&$rss,&$data,$opt){ } else { $item->author = $user; } - if($userInfo && !$opt['guardmail']){ + if($userInfo && !$opt['guardmail']) { $item->authorEmail = $userInfo['mail']; - }else{ + } else { //cannot obfuscate because some RSS readers may check validity $item->authorEmail = $user.'@'.$ditem['ip']; } - }elseif($user){ + } elseif($user) { // this happens when no ACL but some Apache auth is used $item->author = $user; $item->authorEmail = $user.'@'.$ditem['ip']; - }else{ + } else { $item->authorEmail = 'anonymous@'.$ditem['ip']; } // add category if(isset($meta['subject'])) { $item->category = $meta['subject']; - }else{ + } else { $cat = getNS($id); if($cat) $item->category = $cat; } // finally add the item to the feed object, after handing it to registered plugins - $evdata = array('item' => &$item, - 'opt' => &$opt, - 'ditem' => &$ditem, - 'rss' => &$rss); - $evt = new Doku_Event('FEED_ITEM_ADD', $evdata); - if ($evt->advise_before()){ + $evdata = array( + 'item' => &$item, + 'opt' => &$opt, + 'ditem' => &$ditem, + 'rss' => &$rss + ); + $evt = new Doku_Event('FEED_ITEM_ADD', $evdata); + if($evt->advise_before()) { $rss->addItem($item); } $evt->advise_after(); // for completeness @@ -403,20 +430,19 @@ function rss_buildItems(&$rss,&$data,$opt){ $event->advise_after(); } - /** * Add recent changed pages to the feed object * * @author Andreas Gohr */ -function rssRecentChanges($opt){ +function rssRecentChanges($opt) { global $conf; $flags = RECENTS_SKIP_DELETED; if(!$opt['show_minor']) $flags += RECENTS_SKIP_MINORS; if($opt['content_type'] == 'media' && $conf['mediarevisions']) $flags += RECENTS_MEDIA_CHANGES; if($opt['content_type'] == 'both' && $conf['mediarevisions']) $flags += RECENTS_MEDIA_PAGES_MIXED; - $recents = getRecents(0,$opt['items'],$opt['namespace'],$flags); + $recents = getRecents(0, $opt['items'], $opt['namespace'], $flags); return $recents; } @@ -425,16 +451,16 @@ function rssRecentChanges($opt){ * * @author Andreas Gohr */ -function rssListNamespace($opt){ +function rssListNamespace($opt) { require_once(DOKU_INC.'inc/search.php'); global $conf; - $ns=':'.cleanID($opt['namespace']); - $ns=str_replace(':','/',$ns); + $ns = ':'.cleanID($opt['namespace']); + $ns = str_replace(':', '/', $ns); $data = array(); sort($data); - search($data,$conf['datadir'],'search_list','',$ns); + search($data, $conf['datadir'], 'search_list', '', $ns); return $data; } @@ -444,11 +470,11 @@ function rssListNamespace($opt){ * * @author Andreas Gohr */ -function rssSearch($opt){ - if(!$opt['search_query']) return; +function rssSearch($opt) { + if(!$opt['search_query']) return array(); require_once(DOKU_INC.'inc/fulltext.php'); - $data = ft_pageSearch($opt['search_query'],$poswords); + $data = ft_pageSearch($opt['search_query'], $poswords); $data = array_keys($data); return $data; -- cgit v1.2.3 From c4e18ef950a64e41101f06da0c4ca2e45bb21fb7 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 24 Jun 2012 15:16:47 +0200 Subject: added 3rd parameter to Input methods This allows to treat empty parameters as default --- inc/Input.class.php | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/inc/Input.class.php b/inc/Input.class.php index 7665c609e..878f29550 100644 --- a/inc/Input.class.php +++ b/inc/Input.class.php @@ -33,7 +33,7 @@ class Input { * Basically a wrapper around isset * * @see isset - * @param $name Parameter name + * @param string $name Parameter name * @return bool */ public function has($name) { @@ -45,10 +45,12 @@ class Input { * * @param string $name Parameter name * @param mixed $default Default to return if parameter isn't set + * @param bool $nonempty Return $default if parameter is set but empty() * @return mixed */ - public function param($name, $default = null) { + public function param($name, $default = null, $nonempty = false) { if(!isset($this->access[$name])) return $default; + if($nonempty && empty($this->access[$name])) return $default; return $this->access[$name]; } @@ -58,12 +60,13 @@ class Input { * This avoids copying data in memory, when the parameter is not set it will be created * and intialized with the given $default value before a reference is returned * - * @param string $name Parameter name - * @param mixed $default Initialize parameter with if not set + * @param string $name Parameter name + * @param mixed $default Initialize parameter with if not set + * @param bool $nonempty Init with $default if parameter is set but empty() * @return &mixed */ - public function &ref($name, $default = '') { - if(!isset($this->access[$name])) { + public function &ref($name, $default = '', $nonempty = false) { + if(!isset($this->access[$name]) || ($nonempty && empty($this->access[$name]))) { $this->access[$name] = $default; } @@ -76,11 +79,13 @@ class Input { * * @param string $name Parameter name * @param mixed $default Default to return if parameter isn't set or is an array + * @param bool $nonempty Return $default if parameter is set but empty() * @return int */ - public function int($name, $default = 0) { + public function int($name, $default = 0, $nonempty = false) { if(!isset($this->access[$name])) return $default; if(is_array($this->access[$name])) return $default; + if($nonempty && empty($this->access[$name])) return $default; return (int) $this->access[$name]; } @@ -90,11 +95,13 @@ class Input { * * @param string $name Parameter name * @param mixed $default Default to return if parameter isn't set or is an array + * @param bool $nonempty Return $default if parameter is set but empty() * @return string */ - public function str($name, $default = '') { + public function str($name, $default = '', $nonempty = false) { if(!isset($this->access[$name])) return $default; if(is_array($this->access[$name])) return $default; + if($nonempty && empty($this->access[$name])) return $default; return (string) $this->access[$name]; } @@ -104,10 +111,12 @@ class Input { * * @param string $name Parameter name * @param mixed $default Default to return if parameter isn't set + * @param bool $nonempty Return $default if parameter is set but empty() * @return bool */ - public function bool($name, $default = '') { + public function bool($name, $default = '', $nonempty = false) { if(!isset($this->access[$name])) return $default; + if($nonempty && empty($this->access[$name])) return $default; return (bool) $this->access[$name]; } @@ -117,10 +126,12 @@ class Input { * * @param string $name Parameter name * @param mixed $default Default to return if parameter isn't set + * @param bool $nonempty Return $default if parameter is set but empty() * @return array */ - public function arr($name, $default = array()) { + public function arr($name, $default = array(), $nonempty = false) { if(!isset($this->access[$name])) return $default; + if($nonempty && empty($this->access[$name])) return $default; return (array) $this->access[$name]; } -- cgit v1.2.3 From 8fbb9b1406a6a8bb097209155e1b1142fa556260 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 24 Jun 2012 15:17:38 +0200 Subject: added Input wrapper to feed.php --- feed.php | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/feed.php b/feed.php index a54c30978..09a204fe2 100644 --- a/feed.php +++ b/feed.php @@ -6,6 +6,7 @@ * @author Andreas Gohr * * @global array $conf + * @global Input $INPUT */ if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__).'/'); @@ -26,7 +27,7 @@ $cache = new cache($key, '.feed'); // prepare cache depends $depends['files'] = getConfigFiles('main'); $depends['age'] = $conf['rss_update']; -$depends['purge'] = isset($_REQUEST['purge']); +$depends['purge'] = $INPUT->bool('purge'); // check cacheage and deliver if nothing has changed since last // time or the update interval has not passed, also handles conditional requests @@ -95,6 +96,7 @@ print $feed; */ function rss_parseOptions() { global $conf; + global $INPUT; $opt = array(); @@ -104,29 +106,28 @@ function rss_parseOptions() { // properties for implementing own feeds // One of: list, search, recent - 'feed_mode' => array('mode', 'recent'), + 'feed_mode' => array('str', 'mode', 'recent'), // One of: diff, page, rev, current - 'link_to' => array('linkto', $conf['rss_linkto']), + 'link_to' => array('str', 'linkto', $conf['rss_linkto']), // One of: abstract, diff, htmldiff, html - 'item_content' => array('content', $conf['rss_content']), + 'item_content' => array('str', 'content', $conf['rss_content']), // Special feed properties // These are only used by certain feed_modes // String, used for feed title, in list and rc mode - 'namespace' => array('ns', null), + 'namespace' => array('str', 'ns', null), // Positive integer, only used in rc mode - 'items' => array('num', $conf['recent']), + 'items' => array('int', 'num', $conf['recent']), // Boolean, only used in rc mode - 'show_minor' => array('minor', false), + 'show_minor' => array('bool', 'minor', false), // String, only used in search mode - 'search_query' => array('q', null), + 'search_query' => array('str', 'q', null), // One of: pages, media, both - 'content_type' => array('view', $conf['rss_media']) + 'content_type' => array('str', 'view', $conf['rss_media']) ) as $name => $val) { - $opt[$name] = (isset($_REQUEST[$val[0]]) && !empty($_REQUEST[$val[0]])) - ? $_REQUEST[$val[0]] : $val[1]; + $opt[$name] = $INPUT->$val[0]($val[1], $val[2], true); } $opt['items'] = max(0, (int) $opt['items']); -- cgit v1.2.3 From ff1769defb9de14a80792aed16652451a29f03da Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 24 Jun 2012 15:21:26 +0200 Subject: another input wrapper fix --- inc/parserutils.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/parserutils.php b/inc/parserutils.php index 9384929bf..25d7cf131 100644 --- a/inc/parserutils.php +++ b/inc/parserutils.php @@ -739,7 +739,7 @@ function p_get_first_heading($id, $render=METADATA_RENDER_USING_SIMPLE_CACHE){ * @author Andreas Gohr */ function p_xhtml_cached_geshi($code, $language, $wrapper='pre') { - global $conf, $config_cascade; + global $conf, $config_cascade, $INPUT; $language = strtolower($language); // remove any leading or trailing blank lines @@ -747,7 +747,7 @@ function p_xhtml_cached_geshi($code, $language, $wrapper='pre') { $cache = getCacheName($language.$code,".code"); $ctime = @filemtime($cache); - if($ctime && !$_REQUEST['purge'] && + if($ctime && !$INPUT->bool('purge') && $ctime > filemtime(DOKU_INC.'inc/geshi.php') && // geshi changed $ctime > @filemtime(DOKU_INC.'inc/geshi/'.$language.'.php') && // language syntax definition changed $ctime > filemtime(reset($config_cascade['main']['default']))){ // dokuwiki changed -- cgit v1.2.3 From ab5d26daf90483fc0ed3437c64011a5e8475970f Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 24 Jun 2012 16:07:18 +0200 Subject: code cleanup --- inc/auth.php | 596 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 320 insertions(+), 276 deletions(-) diff --git a/inc/auth.php b/inc/auth.php index ed0e2dcf7..8489c2265 100644 --- a/inc/auth.php +++ b/inc/auth.php @@ -12,13 +12,13 @@ if(!defined('DOKU_INC')) die('meh.'); // some ACL level defines -define('AUTH_NONE',0); -define('AUTH_READ',1); -define('AUTH_EDIT',2); -define('AUTH_CREATE',4); -define('AUTH_UPLOAD',8); -define('AUTH_DELETE',16); -define('AUTH_ADMIN',255); +define('AUTH_NONE', 0); +define('AUTH_READ', 1); +define('AUTH_EDIT', 2); +define('AUTH_CREATE', 4); +define('AUTH_UPLOAD', 8); +define('AUTH_DELETE', 16); +define('AUTH_ADMIN', 255); /** * Initialize the auth system. @@ -29,26 +29,28 @@ define('AUTH_ADMIN',255); * * @todo backend loading maybe should be handled by the class autoloader * @todo maybe split into multiple functions at the XXX marked positions + * @triggers AUTH_LOGIN_CHECK + * @return bool */ -function auth_setup(){ +function auth_setup() { global $conf; + /* @var auth_basic $auth */ global $auth; global $AUTH_ACL; global $lang; - global $config_cascade; $AUTH_ACL = array(); if(!$conf['useacl']) return false; // load the the backend auth functions and instantiate the auth object XXX - if (@file_exists(DOKU_INC.'inc/auth/'.$conf['authtype'].'.class.php')) { + if(@file_exists(DOKU_INC.'inc/auth/'.$conf['authtype'].'.class.php')) { require_once(DOKU_INC.'inc/auth/basic.class.php'); require_once(DOKU_INC.'inc/auth/'.$conf['authtype'].'.class.php'); $auth_class = "auth_".$conf['authtype']; - if (class_exists($auth_class)) { + if(class_exists($auth_class)) { $auth = new $auth_class(); - if ($auth->success == false) { + if($auth->success == false) { // degrade to unauthenticated user unset($auth); auth_logoff(); @@ -61,14 +63,14 @@ function auth_setup(){ nice_die($lang['authmodfailed']); } - if(!$auth) return; + if(!$auth) return false; // do the login either by cookie or provided credentials XXX - if (!isset($_REQUEST['u'])) $_REQUEST['u'] = ''; - if (!isset($_REQUEST['p'])) $_REQUEST['p'] = ''; - if (!isset($_REQUEST['r'])) $_REQUEST['r'] = ''; + if(!isset($_REQUEST['u'])) $_REQUEST['u'] = ''; + if(!isset($_REQUEST['p'])) $_REQUEST['p'] = ''; + if(!isset($_REQUEST['r'])) $_REQUEST['r'] = ''; $_REQUEST['http_credentials'] = false; - if (!$conf['rememberme']) $_REQUEST['r'] = false; + if(!$conf['rememberme']) $_REQUEST['r'] = false; // handle renamed HTTP_AUTHORIZATION variable (can happen when a fix like // the one presented at @@ -77,48 +79,50 @@ function auth_setup(){ if(isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION']; // streamline HTTP auth credentials (IIS/rewrite -> mod_php) - if(isset($_SERVER['HTTP_AUTHORIZATION'])){ - list($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']) = + if(isset($_SERVER['HTTP_AUTHORIZATION'])) { + list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6))); } // if no credentials were given try to use HTTP auth (for SSO) - if(empty($_REQUEST['u']) && empty($_COOKIE[DOKU_COOKIE]) && !empty($_SERVER['PHP_AUTH_USER'])){ - $_REQUEST['u'] = $_SERVER['PHP_AUTH_USER']; - $_REQUEST['p'] = $_SERVER['PHP_AUTH_PW']; + if(empty($_REQUEST['u']) && empty($_COOKIE[DOKU_COOKIE]) && !empty($_SERVER['PHP_AUTH_USER'])) { + $_REQUEST['u'] = $_SERVER['PHP_AUTH_USER']; + $_REQUEST['p'] = $_SERVER['PHP_AUTH_PW']; $_REQUEST['http_credentials'] = true; } // apply cleaning $_REQUEST['u'] = $auth->cleanUser($_REQUEST['u']); - if(isset($_REQUEST['authtok'])){ + if(isset($_REQUEST['authtok'])) { // when an authentication token is given, trust the session auth_validateToken($_REQUEST['authtok']); - }elseif(!is_null($auth) && $auth->canDo('external')){ + } elseif(!is_null($auth) && $auth->canDo('external')) { // external trust mechanism in place - $auth->trustExternal($_REQUEST['u'],$_REQUEST['p'],$_REQUEST['r']); - }else{ + $auth->trustExternal($_REQUEST['u'], $_REQUEST['p'], $_REQUEST['r']); + } else { $evdata = array( - 'user' => $_REQUEST['u'], - 'password' => $_REQUEST['p'], - 'sticky' => $_REQUEST['r'], - 'silent' => $_REQUEST['http_credentials'], - ); + 'user' => $_REQUEST['u'], + 'password' => $_REQUEST['p'], + 'sticky' => $_REQUEST['r'], + 'silent' => $_REQUEST['http_credentials'], + ); trigger_event('AUTH_LOGIN_CHECK', $evdata, 'auth_login_wrapper'); } //load ACL into a global array XXX $AUTH_ACL = auth_loadACL(); + + return true; } /** * Loads the ACL setup and handle user wildcards * * @author Andreas Gohr - * @returns array + * @return array */ -function auth_loadACL(){ +function auth_loadACL() { global $config_cascade; if(!is_readable($config_cascade['acl']['default'])) return array(); @@ -126,24 +130,32 @@ function auth_loadACL(){ $acl = file($config_cascade['acl']['default']); //support user wildcard - if(isset($_SERVER['REMOTE_USER'])){ + if(isset($_SERVER['REMOTE_USER'])) { $len = count($acl); - for($i=0; $i<$len; $i++){ + for($i = 0; $i < $len; $i++) { if($acl[$i]{0} == '#') continue; - list($id,$rest) = preg_split('/\s+/',$acl[$i],2); - $id = str_replace('%USER%',cleanID($_SERVER['REMOTE_USER']),$id); - $rest = str_replace('%USER%',auth_nameencode($_SERVER['REMOTE_USER']),$rest); + list($id, $rest) = preg_split('/\s+/', $acl[$i], 2); + $id = str_replace('%USER%', cleanID($_SERVER['REMOTE_USER']), $id); + $rest = str_replace('%USER%', auth_nameencode($_SERVER['REMOTE_USER']), $rest); $acl[$i] = "$id\t$rest"; } } return $acl; } +/** + * Event hook callback for AUTH_LOGIN_CHECK + * + * @param $evdata + * @return bool + */ function auth_login_wrapper($evdata) { - return auth_login($evdata['user'], - $evdata['password'], - $evdata['sticky'], - $evdata['silent']); + return auth_login( + $evdata['user'], + $evdata['password'], + $evdata['sticky'], + $evdata['silent'] + ); } /** @@ -175,53 +187,56 @@ function auth_login_wrapper($evdata) { * @param bool $silent Don't show error on bad auth * @return bool true on successful auth */ -function auth_login($user,$pass,$sticky=false,$silent=false){ +function auth_login($user, $pass, $sticky = false, $silent = false) { global $USERINFO; global $conf; global $lang; + /* @var auth_basic $auth */ global $auth; + $sticky ? $sticky = true : $sticky = false; //sanity check - if (!$auth) return false; + if(!$auth) return false; - if(!empty($user)){ + if(!empty($user)) { //usual login - if ($auth->checkPass($user,$pass)){ + if($auth->checkPass($user, $pass)) { // make logininfo globally available $_SERVER['REMOTE_USER'] = $user; - $secret = auth_cookiesalt(!$sticky); //bind non-sticky to session - auth_setCookie($user,PMA_blowfish_encrypt($pass,$secret),$sticky); + $secret = auth_cookiesalt(!$sticky); //bind non-sticky to session + auth_setCookie($user, PMA_blowfish_encrypt($pass, $secret), $sticky); return true; - }else{ + } else { //invalid credentials - log off - if(!$silent) msg($lang['badlogin'],-1); + if(!$silent) msg($lang['badlogin'], -1); auth_logoff(); return false; } - }else{ + } else { // read cookie information - list($user,$sticky,$pass) = auth_getCookie(); - if($user && $pass){ + list($user, $sticky, $pass) = auth_getCookie(); + if($user && $pass) { // we got a cookie - see if we can trust it // get session info $session = $_SESSION[DOKU_COOKIE]['auth']; if(isset($session) && - $auth->useSessionCache($user) && - ($session['time'] >= time()-$conf['auth_security_timeout']) && - ($session['user'] == $user) && - ($session['pass'] == sha1($pass)) && //still crypted - ($session['buid'] == auth_browseruid()) ){ + $auth->useSessionCache($user) && + ($session['time'] >= time() - $conf['auth_security_timeout']) && + ($session['user'] == $user) && + ($session['pass'] == sha1($pass)) && //still crypted + ($session['buid'] == auth_browseruid()) + ) { // he has session, cookie and browser right - let him in $_SERVER['REMOTE_USER'] = $user; - $USERINFO = $session['info']; //FIXME move all references to session + $USERINFO = $session['info']; //FIXME move all references to session return true; } // no we don't trust it yet - recheck pass but silent $secret = auth_cookiesalt(!$sticky); //bind non-sticky to session - $pass = PMA_blowfish_decrypt($pass,$secret); - return auth_login($user,$pass,$sticky,true); + $pass = PMA_blowfish_decrypt($pass, $secret); + return auth_login($user, $pass, $sticky, true); } } //just to be sure @@ -239,8 +254,8 @@ function auth_login($user,$pass,$sticky=false,$silent=false){ * @param string $token The authentication token * @return boolean true (or will exit on failure) */ -function auth_validateToken($token){ - if(!$token || $token != $_SESSION[DOKU_COOKIE]['auth']['token']){ +function auth_validateToken($token) { + if(!$token || $token != $_SESSION[DOKU_COOKIE]['auth']['token']) { // bad token header("HTTP/1.0 401 Unauthorized"); print 'Invalid auth token - maybe the session timed out'; @@ -250,7 +265,7 @@ function auth_validateToken($token){ // still here? trust the session data global $USERINFO; $_SERVER['REMOTE_USER'] = $_SESSION[DOKU_COOKIE]['auth']['user']; - $USERINFO = $_SESSION[DOKU_COOKIE]['auth']['info']; + $USERINFO = $_SESSION[DOKU_COOKIE]['auth']['info']; return true; } @@ -262,7 +277,7 @@ function auth_validateToken($token){ * @author Andreas Gohr * @return string The auth token */ -function auth_createToken(){ +function auth_createToken() { $token = md5(mt_rand()); @session_start(); // reopen the session if needed $_SESSION[DOKU_COOKIE]['auth']['token'] = $token; @@ -281,14 +296,14 @@ function auth_createToken(){ * * @return string a MD5 sum of various browser headers */ -function auth_browseruid(){ - $ip = clientIP(true); - $uid = ''; +function auth_browseruid() { + $ip = clientIP(true); + $uid = ''; $uid .= $_SERVER['HTTP_USER_AGENT']; $uid .= $_SERVER['HTTP_ACCEPT_ENCODING']; $uid .= $_SERVER['HTTP_ACCEPT_LANGUAGE']; $uid .= $_SERVER['HTTP_ACCEPT_CHARSET']; - $uid .= substr($ip,0,strpos($ip,'.')); + $uid .= substr($ip, 0, strpos($ip, '.')); return md5($uid); } @@ -304,15 +319,15 @@ function auth_browseruid(){ * @param bool $addsession if true, the sessionid is added to the salt * @return string */ -function auth_cookiesalt($addsession=false){ +function auth_cookiesalt($addsession = false) { global $conf; $file = $conf['metadir'].'/_htcookiesalt'; $salt = io_readFile($file); - if(empty($salt)){ - $salt = uniqid(rand(),true); - io_saveFile($file,$salt); + if(empty($salt)) { + $salt = uniqid(rand(), true); + io_saveFile($file, $salt); } - if($addsession){ + if($addsession) { $salt .= session_id(); } return $salt; @@ -327,10 +342,10 @@ function auth_cookiesalt($addsession=false){ * @author Andreas Gohr * @param bool $keepbc - when true, the breadcrumb data is not cleared */ -function auth_logoff($keepbc=false){ +function auth_logoff($keepbc = false) { global $conf; global $USERINFO; - global $INFO, $ID; + /* @var auth_basic $auth */ global $auth; // make sure the session is writable (it usually is) @@ -346,13 +361,13 @@ function auth_logoff($keepbc=false){ unset($_SESSION[DOKU_COOKIE]['bc']); if(isset($_SERVER['REMOTE_USER'])) unset($_SERVER['REMOTE_USER']); - $USERINFO=null; //FIXME + $USERINFO = null; //FIXME $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir']; - if (version_compare(PHP_VERSION, '5.2.0', '>')) { - setcookie(DOKU_COOKIE,'',time()-600000,$cookieDir,'',($conf['securecookie'] && is_ssl()),true); - }else{ - setcookie(DOKU_COOKIE,'',time()-600000,$cookieDir,'',($conf['securecookie'] && is_ssl())); + if(version_compare(PHP_VERSION, '5.2.0', '>')) { + setcookie(DOKU_COOKIE, '', time() - 600000, $cookieDir, '', ($conf['securecookie'] && is_ssl()), true); + } else { + setcookie(DOKU_COOKIE, '', time() - 600000, $cookieDir, '', ($conf['securecookie'] && is_ssl())); } if($auth) $auth->logOff(); @@ -368,32 +383,34 @@ function auth_logoff($keepbc=false){ * * @author Andreas Gohr * @see auth_isadmin - * @param string user - Username - * @param array groups - List of groups the user is in - * @param bool adminonly - when true checks if user is admin + * @param string $user Username + * @param array $groups List of groups the user is in + * @param bool $adminonly when true checks if user is admin + * @return bool */ -function auth_ismanager($user=null,$groups=null,$adminonly=false){ +function auth_ismanager($user = null, $groups = null, $adminonly = false) { global $conf; global $USERINFO; + /* @var auth_basic $auth */ global $auth; - if (!$auth) return false; + if(!$auth) return false; if(is_null($user)) { - if (!isset($_SERVER['REMOTE_USER'])) { + if(!isset($_SERVER['REMOTE_USER'])) { return false; } else { $user = $_SERVER['REMOTE_USER']; } } - if(is_null($groups)){ + if(is_null($groups)) { $groups = (array) $USERINFO['grps']; } // check superuser match - if(auth_isMember($conf['superuser'],$user, $groups)) return true; + if(auth_isMember($conf['superuser'], $user, $groups)) return true; if($adminonly) return false; // check managers - if(auth_isMember($conf['manager'],$user, $groups)) return true; + if(auth_isMember($conf['manager'], $user, $groups)) return true; return false; } @@ -406,13 +423,15 @@ function auth_ismanager($user=null,$groups=null,$adminonly=false){ * The info is available through $INFO['isadmin'], too * * @author Andreas Gohr - * @see auth_ismanager + * @see auth_ismanager() + * @param string $user Username + * @param array $groups List of groups the user is in + * @return bool */ -function auth_isadmin($user=null,$groups=null){ - return auth_ismanager($user,$groups,true); +function auth_isadmin($user = null, $groups = null) { + return auth_ismanager($user, $groups, true); } - /** * Match a user and his groups against a comma separated list of * users and groups to determine membership status @@ -424,31 +443,32 @@ function auth_isadmin($user=null,$groups=null){ * @param $groups array groups the user is member of * @return bool true for membership acknowledged */ -function auth_isMember($memberlist,$user,array $groups){ +function auth_isMember($memberlist, $user, array $groups) { + /* @var auth_basic $auth */ global $auth; - if (!$auth) return false; + if(!$auth) return false; // clean user and groups - if(!$auth->isCaseSensitive()){ - $user = utf8_strtolower($user); - $groups = array_map('utf8_strtolower',$groups); + if(!$auth->isCaseSensitive()) { + $user = utf8_strtolower($user); + $groups = array_map('utf8_strtolower', $groups); } - $user = $auth->cleanUser($user); - $groups = array_map(array($auth,'cleanGroup'),$groups); + $user = $auth->cleanUser($user); + $groups = array_map(array($auth, 'cleanGroup'), $groups); // extract the memberlist - $members = explode(',',$memberlist); - $members = array_map('trim',$members); + $members = explode(',', $memberlist); + $members = array_map('trim', $members); $members = array_unique($members); $members = array_filter($members); // compare cleaned values - foreach($members as $member){ + foreach($members as $member) { if(!$auth->isCaseSensitive()) $member = utf8_strtolower($member); - if($member[0] == '@'){ - $member = $auth->cleanGroup(substr($member,1)); + if($member[0] == '@') { + $member = $auth->cleanGroup(substr($member, 1)); if(in_array($member, $groups)) return true; - }else{ + } else { $member = $auth->cleanUser($member); if($member == $user) return true; } @@ -468,12 +488,12 @@ function auth_isMember($memberlist,$user,array $groups){ * @param string $id page ID (needs to be resolved and cleaned) * @return int permission level */ -function auth_quickaclcheck($id){ +function auth_quickaclcheck($id) { global $conf; global $USERINFO; # if no ACL is used always return upload rights if(!$conf['useacl']) return AUTH_UPLOAD; - return auth_aclcheck($id,$_SERVER['REMOTE_USER'],$USERINFO['grps']); + return auth_aclcheck($id, $_SERVER['REMOTE_USER'], $USERINFO['grps']); } /** @@ -487,106 +507,110 @@ function auth_quickaclcheck($id){ * @param array $groups Array of groups the user is in * @return int permission level */ -function auth_aclcheck($id,$user,$groups){ +function auth_aclcheck($id, $user, $groups) { global $conf; global $AUTH_ACL; + /* @var auth_basic $auth */ global $auth; // if no ACL is used always return upload rights if(!$conf['useacl']) return AUTH_UPLOAD; - if (!$auth) return AUTH_NONE; + if(!$auth) return AUTH_NONE; //make sure groups is an array if(!is_array($groups)) $groups = array(); //if user is superuser or in superusergroup return 255 (acl_admin) - if(auth_isadmin($user,$groups)) { return AUTH_ADMIN; } + if(auth_isadmin($user, $groups)) { + return AUTH_ADMIN; + } $ci = ''; if(!$auth->isCaseSensitive()) $ci = 'ui'; - $user = $auth->cleanUser($user); - $groups = array_map(array($auth,'cleanGroup'),(array)$groups); - $user = auth_nameencode($user); + $user = $auth->cleanUser($user); + $groups = array_map(array($auth, 'cleanGroup'), (array) $groups); + $user = auth_nameencode($user); //prepend groups with @ and nameencode $cnt = count($groups); - for($i=0; $i<$cnt; $i++){ + for($i = 0; $i < $cnt; $i++) { $groups[$i] = '@'.auth_nameencode($groups[$i]); } - $ns = getNS($id); - $perm = -1; + $ns = getNS($id); + $perm = -1; - if($user || count($groups)){ + if($user || count($groups)) { //add ALL group $groups[] = '@ALL'; //add User if($user) $groups[] = $user; - }else{ + } else { $groups[] = '@ALL'; } //check exact match first - $matches = preg_grep('/^'.preg_quote($id,'/').'\s+(\S+)\s+/'.$ci,$AUTH_ACL); - if(count($matches)){ - foreach($matches as $match){ - $match = preg_replace('/#.*$/','',$match); //ignore comments - $acl = preg_split('/\s+/',$match); - if (!in_array($acl[1], $groups)) { + $matches = preg_grep('/^'.preg_quote($id, '/').'\s+(\S+)\s+/'.$ci, $AUTH_ACL); + if(count($matches)) { + foreach($matches as $match) { + $match = preg_replace('/#.*$/', '', $match); //ignore comments + $acl = preg_split('/\s+/', $match); + if(!in_array($acl[1], $groups)) { continue; } if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL! - if($acl[2] > $perm){ + if($acl[2] > $perm) { $perm = $acl[2]; } } - if($perm > -1){ + if($perm > -1) { //we had a match - return it return $perm; } } //still here? do the namespace checks - if($ns){ + if($ns) { $path = $ns.':*'; - }else{ + } else { $path = '*'; //root document } - do{ - $matches = preg_grep('/^'.preg_quote($path,'/').'\s+(\S+)\s+/'.$ci,$AUTH_ACL); - if(count($matches)){ - foreach($matches as $match){ - $match = preg_replace('/#.*$/','',$match); //ignore comments - $acl = preg_split('/\s+/',$match); - if (!in_array($acl[1], $groups)) { + do { + $matches = preg_grep('/^'.preg_quote($path, '/').'\s+(\S+)\s+/'.$ci, $AUTH_ACL); + if(count($matches)) { + foreach($matches as $match) { + $match = preg_replace('/#.*$/', '', $match); //ignore comments + $acl = preg_split('/\s+/', $match); + if(!in_array($acl[1], $groups)) { continue; } if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL! - if($acl[2] > $perm){ + if($acl[2] > $perm) { $perm = $acl[2]; } } //we had a match - return it - if ($perm != -1) { + if($perm != -1) { return $perm; } } //get next higher namespace - $ns = getNS($ns); + $ns = getNS($ns); - if($path != '*'){ + if($path != '*') { $path = $ns.':*'; if($path == ':*') $path = '*'; - }else{ + } else { //we did this already //looks like there is something wrong with the ACL //break here msg('No ACL setup yet! Denying access to everyone.'); return AUTH_NONE; } - }while(1); //this should never loop endless + } while(1); //this should never loop endless + return AUTH_NONE; } /** @@ -602,7 +626,7 @@ function auth_aclcheck($id,$user,$groups){ * @author Andreas Gohr * @see rawurldecode() */ -function auth_nameencode($name,$skip_group=false){ +function auth_nameencode($name, $skip_group = false) { global $cache_authname; $cache =& $cache_authname; $name = (string) $name; @@ -610,13 +634,17 @@ function auth_nameencode($name,$skip_group=false){ // never encode wildcard FS#1955 if($name == '%USER%') return $name; - if (!isset($cache[$name][$skip_group])) { - if($skip_group && $name{0} =='@'){ - $cache[$name][$skip_group] = '@'.preg_replace('/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/e', - "'%'.dechex(ord(substr('\\1',-1)))",substr($name,1)); - }else{ - $cache[$name][$skip_group] = preg_replace('/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/e', - "'%'.dechex(ord(substr('\\1',-1)))",$name); + if(!isset($cache[$name][$skip_group])) { + if($skip_group && $name{0} == '@') { + $cache[$name][$skip_group] = '@'.preg_replace( + '/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/e', + "'%'.dechex(ord(substr('\\1',-1)))", substr($name, 1) + ); + } else { + $cache[$name][$skip_group] = preg_replace( + '/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/e', + "'%'.dechex(ord(substr('\\1',-1)))", $name + ); } } @@ -631,20 +659,20 @@ function auth_nameencode($name,$skip_group=false){ * * @return string pronouncable password */ -function auth_pwgen(){ +function auth_pwgen() { $pw = ''; $c = 'bcdfghjklmnprstvwz'; //consonants except hard to speak ones - $v = 'aeiou'; //vowels - $a = $c.$v; //both + $v = 'aeiou'; //vowels + $a = $c.$v; //both //use two syllables... - for($i=0;$i < 2; $i++){ - $pw .= $c[rand(0, strlen($c)-1)]; - $pw .= $v[rand(0, strlen($v)-1)]; - $pw .= $a[rand(0, strlen($a)-1)]; + for($i = 0; $i < 2; $i++) { + $pw .= $c[rand(0, strlen($c) - 1)]; + $pw .= $v[rand(0, strlen($v) - 1)]; + $pw .= $a[rand(0, strlen($a) - 1)]; } //... and add a nice number - $pw .= rand(10,99); + $pw .= rand(10, 99); return $pw; } @@ -653,16 +681,16 @@ function auth_pwgen(){ * Sends a password to the given user * * @author Andreas Gohr - * + * @param string $user Login name of the user + * @param string $password The new password in clear text * @return bool true on success */ -function auth_sendPassword($user,$password){ - global $conf; +function auth_sendPassword($user, $password) { global $lang; + /* @var auth_basic $auth */ global $auth; - if (!$auth) return false; + if(!$auth) return false; - $hdrs = ''; $user = $auth->cleanUser($user); $userinfo = $auth->getUserData($user); @@ -670,15 +698,15 @@ function auth_sendPassword($user,$password){ $text = rawLocale('password'); $trep = array( - 'FULLNAME' => $userinfo['name'], - 'LOGIN' => $user, - 'PASSWORD' => $password - ); + 'FULLNAME' => $userinfo['name'], + 'LOGIN' => $user, + 'PASSWORD' => $password + ); $mail = new Mailer(); $mail->to($userinfo['name'].' <'.$userinfo['mail'].'>'); $mail->subject($lang['regpwmail']); - $mail->setBody($text,$trep); + $mail->setBody($text, $trep); return $mail->send(); } @@ -688,12 +716,12 @@ function auth_sendPassword($user,$password){ * This registers a new user - Data is read directly from $_POST * * @author Andreas Gohr - * * @return bool true on success, false on any error */ -function register(){ +function register() { global $lang; global $conf; + /* @var auth_basic $auth */ global $auth; if(!$_POST['save']) return false; @@ -703,61 +731,63 @@ function register(){ $_POST['login'] = trim($auth->cleanUser($_POST['login'])); //clean fullname and email - $_POST['fullname'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/','',$_POST['fullname'])); - $_POST['email'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/','',$_POST['email'])); + $_POST['fullname'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $_POST['fullname'])); + $_POST['email'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $_POST['email'])); - if( empty($_POST['login']) || + if(empty($_POST['login']) || empty($_POST['fullname']) || - empty($_POST['email']) ){ - msg($lang['regmissing'],-1); + empty($_POST['email']) + ) { + msg($lang['regmissing'], -1); return false; } - if ($conf['autopasswd']) { - $pass = auth_pwgen(); // automatically generate password - } elseif (empty($_POST['pass']) || - empty($_POST['passchk'])) { - msg($lang['regmissing'], -1); // complain about missing passwords + if($conf['autopasswd']) { + $pass = auth_pwgen(); // automatically generate password + } elseif(empty($_POST['pass']) || + empty($_POST['passchk']) + ) { + msg($lang['regmissing'], -1); // complain about missing passwords return false; - } elseif ($_POST['pass'] != $_POST['passchk']) { - msg($lang['regbadpass'], -1); // complain about misspelled passwords + } elseif($_POST['pass'] != $_POST['passchk']) { + msg($lang['regbadpass'], -1); // complain about misspelled passwords return false; } else { - $pass = $_POST['pass']; // accept checked and valid password + $pass = $_POST['pass']; // accept checked and valid password } //check mail - if(!mail_isvalid($_POST['email'])){ - msg($lang['regbadmail'],-1); + if(!mail_isvalid($_POST['email'])) { + msg($lang['regbadmail'], -1); return false; } //okay try to create the user - if(!$auth->triggerUserMod('create', array($_POST['login'],$pass,$_POST['fullname'],$_POST['email']))){ - msg($lang['reguexists'],-1); + if(!$auth->triggerUserMod('create', array($_POST['login'], $pass, $_POST['fullname'], $_POST['email']))) { + msg($lang['reguexists'], -1); return false; } // create substitutions for use in notification email $substitutions = array( - 'NEWUSER' => $_POST['login'], - 'NEWNAME' => $_POST['fullname'], - 'NEWEMAIL' => $_POST['email'], - ); + 'NEWUSER' => $_POST['login'], + 'NEWNAME' => $_POST['fullname'], + 'NEWEMAIL' => $_POST['email'], + ); - if (!$conf['autopasswd']) { - msg($lang['regsuccess2'],1); + if(!$conf['autopasswd']) { + msg($lang['regsuccess2'], 1); notify('', 'register', '', $_POST['login'], false, $substitutions); return true; } // autogenerated password? then send him the password - if (auth_sendPassword($_POST['login'],$pass)){ - msg($lang['regsuccess'],1); + if(auth_sendPassword($_POST['login'], $pass)) { + msg($lang['regsuccess'], 1); notify('', 'register', '', $_POST['login'], false, $substitutions); return true; - }else{ - msg($lang['regmailfail'],-1); + } else { + msg($lang['regmailfail'], -1); return false; } } @@ -771,61 +801,66 @@ function updateprofile() { global $conf; global $INFO; global $lang; + /* @var auth_basic $auth */ global $auth; if(empty($_POST['save'])) return false; if(!checkSecurityToken()) return false; if(!actionOK('profile')) { - msg($lang['profna'],-1); + msg($lang['profna'], -1); return false; } - if ($_POST['newpass'] != $_POST['passchk']) { - msg($lang['regbadpass'], -1); // complain about misspelled passwords + if($_POST['newpass'] != $_POST['passchk']) { + msg($lang['regbadpass'], -1); // complain about misspelled passwords return false; } //clean fullname and email - $_POST['fullname'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/','',$_POST['fullname'])); - $_POST['email'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/','',$_POST['email'])); + $_POST['fullname'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $_POST['fullname'])); + $_POST['email'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $_POST['email'])); - if ((empty($_POST['fullname']) && $auth->canDo('modName')) || - (empty($_POST['email']) && $auth->canDo('modMail'))) { - msg($lang['profnoempty'],-1); + if((empty($_POST['fullname']) && $auth->canDo('modName')) || + (empty($_POST['email']) && $auth->canDo('modMail')) + ) { + msg($lang['profnoempty'], -1); return false; } - if (!mail_isvalid($_POST['email']) && $auth->canDo('modMail')){ - msg($lang['regbadmail'],-1); + if(!mail_isvalid($_POST['email']) && $auth->canDo('modMail')) { + msg($lang['regbadmail'], -1); return false; } - if ($_POST['fullname'] != $INFO['userinfo']['name'] && $auth->canDo('modName')) $changes['name'] = $_POST['fullname']; - if ($_POST['email'] != $INFO['userinfo']['mail'] && $auth->canDo('modMail')) $changes['mail'] = $_POST['email']; - if (!empty($_POST['newpass']) && $auth->canDo('modPass')) $changes['pass'] = $_POST['newpass']; + $changes = array(); + if($_POST['fullname'] != $INFO['userinfo']['name'] && $auth->canDo('modName')) $changes['name'] = $_POST['fullname']; + if($_POST['email'] != $INFO['userinfo']['mail'] && $auth->canDo('modMail')) $changes['mail'] = $_POST['email']; + if(!empty($_POST['newpass']) && $auth->canDo('modPass')) $changes['pass'] = $_POST['newpass']; - if (!count($changes)) { + if(!count($changes)) { msg($lang['profnochange'], -1); return false; } - if ($conf['profileconfirm']) { - if (!$auth->checkPass($_SERVER['REMOTE_USER'], $_POST['oldpass'])) { - msg($lang['badlogin'],-1); + if($conf['profileconfirm']) { + if(!$auth->checkPass($_SERVER['REMOTE_USER'], $_POST['oldpass'])) { + msg($lang['badlogin'], -1); return false; } } - if ($result = $auth->triggerUserMod('modify', array($_SERVER['REMOTE_USER'], $changes))) { + if($result = $auth->triggerUserMod('modify', array($_SERVER['REMOTE_USER'], $changes))) { // update cookie and session with the changed data - if ($changes['pass']){ - list($user,$sticky,$pass) = auth_getCookie(); - $pass = PMA_blowfish_encrypt($changes['pass'],auth_cookiesalt(!$sticky)); - auth_setCookie($_SERVER['REMOTE_USER'],$pass,(bool)$sticky); + if($changes['pass']) { + list( /*user*/, $sticky, /*pass*/) = auth_getCookie(); + $pass = PMA_blowfish_encrypt($changes['pass'], auth_cookiesalt(!$sticky)); + auth_setCookie($_SERVER['REMOTE_USER'], $pass, (bool) $sticky); } return true; } + + return false; } /** @@ -842,68 +877,69 @@ function updateprofile() { * * @return bool true on success, false on any error */ -function act_resendpwd(){ +function act_resendpwd() { global $lang; global $conf; + /* @var auth_basic $auth */ global $auth; if(!actionOK('resendpwd')) { - msg($lang['resendna'],-1); + msg($lang['resendna'], -1); return false; } - $token = preg_replace('/[^a-f0-9]+/','',$_REQUEST['pwauth']); + $token = preg_replace('/[^a-f0-9]+/', '', $_REQUEST['pwauth']); - if($token){ + if($token) { // we're in token phase - get user info from token $tfile = $conf['cachedir'].'/'.$token{0}.'/'.$token.'.pwauth'; - if(!@file_exists($tfile)){ - msg($lang['resendpwdbadauth'],-1); + if(!@file_exists($tfile)) { + msg($lang['resendpwdbadauth'], -1); unset($_REQUEST['pwauth']); return false; } // token is only valid for 3 days - if( (time() - filemtime($tfile)) > (3*60*60*24) ){ - msg($lang['resendpwdbadauth'],-1); + if((time() - filemtime($tfile)) > (3 * 60 * 60 * 24)) { + msg($lang['resendpwdbadauth'], -1); unset($_REQUEST['pwauth']); @unlink($tfile); return false; } - $user = io_readfile($tfile); + $user = io_readfile($tfile); $userinfo = $auth->getUserData($user); if(!$userinfo['mail']) { msg($lang['resendpwdnouser'], -1); return false; } - if(!$conf['autopasswd']){ // we let the user choose a password + if(!$conf['autopasswd']) { // we let the user choose a password // password given correctly? if(!isset($_REQUEST['pass']) || $_REQUEST['pass'] == '') return false; - if($_REQUEST['pass'] != $_REQUEST['passchk']){ - msg($lang['regbadpass'],-1); + if($_REQUEST['pass'] != $_REQUEST['passchk']) { + msg($lang['regbadpass'], -1); return false; } $pass = $_REQUEST['pass']; - if (!$auth->triggerUserMod('modify', array($user,array('pass' => $pass)))) { - msg('error modifying user data',-1); + if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { + msg('error modifying user data', -1); return false; } - }else{ // autogenerate the password and send by mail + } else { // autogenerate the password and send by mail $pass = auth_pwgen(); - if (!$auth->triggerUserMod('modify', array($user,array('pass' => $pass)))) { - msg('error modifying user data',-1); + if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { + msg('error modifying user data', -1); return false; } - if (auth_sendPassword($user,$pass)) { - msg($lang['resendpwdsuccess'],1); + if(auth_sendPassword($user, $pass)) { + msg($lang['resendpwdsuccess'], 1); } else { - msg($lang['regmailfail'],-1); + msg($lang['regmailfail'], -1); } } @@ -915,7 +951,7 @@ function act_resendpwd(){ if(!$_POST['save']) return false; - if (empty($_POST['login'])) { + if(empty($_POST['login'])) { msg($lang['resendpwdmissing'], -1); return false; } else { @@ -931,30 +967,29 @@ function act_resendpwd(){ // generate auth token $token = md5(auth_cookiesalt().$user); //secret but user based $tfile = $conf['cachedir'].'/'.$token{0}.'/'.$token.'.pwauth'; - $url = wl('',array('do'=>'resendpwd','pwauth'=>$token),true,'&'); + $url = wl('', array('do'=> 'resendpwd', 'pwauth'=> $token), true, '&'); - io_saveFile($tfile,$user); + io_saveFile($tfile, $user); $text = rawLocale('pwconfirm'); $trep = array( - 'FULLNAME' => $userinfo['name'], - 'LOGIN' => $user, - 'CONFIRM' => $url - ); + 'FULLNAME' => $userinfo['name'], + 'LOGIN' => $user, + 'CONFIRM' => $url + ); $mail = new Mailer(); $mail->to($userinfo['name'].' <'.$userinfo['mail'].'>'); $mail->subject($lang['regpwmail']); - $mail->setBody($text,$trep); - if($mail->send()){ - msg($lang['resendpwdconfirm'],1); - }else{ - msg($lang['regmailfail'],-1); + $mail->setBody($text, $trep); + if($mail->send()) { + msg($lang['resendpwdconfirm'], 1); + } else { + msg($lang['regmailfail'], -1); } return true; } - - return false; // never reached + // never reached } /** @@ -964,32 +999,37 @@ function act_resendpwd(){ * is chosen. * * @author Andreas Gohr + * @param string $clear The clear text password + * @param string $method The hashing method + * @param string $salt A salt, null for random * @return string The crypted password */ -function auth_cryptPassword($clear,$method='',$salt=null){ +function auth_cryptPassword($clear, $method = '', $salt = null) { global $conf; if(empty($method)) $method = $conf['passcrypt']; - $pass = new PassHash(); - $call = 'hash_'.$method; + $pass = new PassHash(); + $call = 'hash_'.$method; - if(!method_exists($pass,$call)){ - msg("Unsupported crypt method $method",-1); + if(!method_exists($pass, $call)) { + msg("Unsupported crypt method $method", -1); return false; } - return $pass->$call($clear,$salt); + return $pass->$call($clear, $salt); } /** * Verifies a cleartext password against a crypted hash * - * @author Andreas Gohr - * @return bool + * @author Andreas Gohr + * @param string $clear The clear text password + * @param string $crypt The hash to compare with + * @return bool true if both match */ -function auth_verifyPassword($clear,$crypt){ +function auth_verifyPassword($clear, $crypt) { $pass = new PassHash(); - return $pass->verify_hash($clear,$crypt); + return $pass->verify_hash($clear, $crypt); } /** @@ -998,23 +1038,25 @@ function auth_verifyPassword($clear,$crypt){ * @param string $user username * @param string $pass encrypted password * @param bool $sticky whether or not the cookie will last beyond the session + * @return bool */ -function auth_setCookie($user,$pass,$sticky) { +function auth_setCookie($user, $pass, $sticky) { global $conf; + /* @var auth_basic $auth */ global $auth; global $USERINFO; - if (!$auth) return false; + if(!$auth) return false; $USERINFO = $auth->getUserData($user); // set cookie - $cookie = base64_encode($user).'|'.((int) $sticky).'|'.base64_encode($pass); + $cookie = base64_encode($user).'|'.((int) $sticky).'|'.base64_encode($pass); $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir']; - $time = $sticky ? (time()+60*60*24*365) : 0; //one year - if (version_compare(PHP_VERSION, '5.2.0', '>')) { - setcookie(DOKU_COOKIE,$cookie,$time,$cookieDir,'',($conf['securecookie'] && is_ssl()),true); - }else{ - setcookie(DOKU_COOKIE,$cookie,$time,$cookieDir,'',($conf['securecookie'] && is_ssl())); + $time = $sticky ? (time() + 60 * 60 * 24 * 365) : 0; //one year + if(version_compare(PHP_VERSION, '5.2.0', '>')) { + setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', ($conf['securecookie'] && is_ssl()), true); + } else { + setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', ($conf['securecookie'] && is_ssl())); } // set session $_SESSION[DOKU_COOKIE]['auth']['user'] = $user; @@ -1022,6 +1064,8 @@ function auth_setCookie($user,$pass,$sticky) { $_SESSION[DOKU_COOKIE]['auth']['buid'] = auth_browseruid(); $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO; $_SESSION[DOKU_COOKIE]['auth']['time'] = time(); + + return true; } /** @@ -1029,15 +1073,15 @@ function auth_setCookie($user,$pass,$sticky) { * * @returns array */ -function auth_getCookie(){ - if (!isset($_COOKIE[DOKU_COOKIE])) { +function auth_getCookie() { + if(!isset($_COOKIE[DOKU_COOKIE])) { return array(null, null, null); } - list($user,$sticky,$pass) = explode('|',$_COOKIE[DOKU_COOKIE],3); + list($user, $sticky, $pass) = explode('|', $_COOKIE[DOKU_COOKIE], 3); $sticky = (bool) $sticky; $pass = base64_decode($pass); $user = base64_decode($user); - return array($user,$sticky,$pass); + return array($user, $sticky, $pass); } //Setup VIM: ex: et ts=2 : -- cgit v1.2.3 From a12aaeb7e914180a4c67ca7456771b6d99d9c535 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 24 Jun 2012 16:54:43 +0200 Subject: allow setting values via input class --- inc/Input.class.php | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/inc/Input.class.php b/inc/Input.class.php index 878f29550..aa402c646 100644 --- a/inc/Input.class.php +++ b/inc/Input.class.php @@ -54,6 +54,16 @@ class Input { return $this->access[$name]; } + /** + * Sets a parameter + * + * @param string $name Parameter name + * @param mixed $value Value to set + */ + public function set($name, $value) { + $this->access[$name] = $value; + } + /** * Get a reference to a request parameter * @@ -61,13 +71,13 @@ class Input { * and intialized with the given $default value before a reference is returned * * @param string $name Parameter name - * @param mixed $default Initialize parameter with if not set + * @param mixed $default If parameter is not set, initialize with this value * @param bool $nonempty Init with $default if parameter is set but empty() * @return &mixed */ public function &ref($name, $default = '', $nonempty = false) { if(!isset($this->access[$name]) || ($nonempty && empty($this->access[$name]))) { - $this->access[$name] = $default; + $this->set($name, $default); } $ref = &$this->access[$name]; @@ -114,7 +124,7 @@ class Input { * @param bool $nonempty Return $default if parameter is set but empty() * @return bool */ - public function bool($name, $default = '', $nonempty = false) { + public function bool($name, $default = false, $nonempty = false) { if(!isset($this->access[$name])) return $default; if($nonempty && empty($this->access[$name])) return $default; @@ -152,10 +162,22 @@ class PostInput extends Input { unset ($this->post); unset ($this->get); } + + /** + * Sets a parameter in $_POST and $_REQUEST + * + * @param string $name Parameter name + * @param mixed $value Value to set + */ + public function set($name, $value) { + parent::set($name, $value); + $_REQUEST[$name] = $value; + } } /** * Internal class used for $_GET access in Input class + */ class GetInput extends Input { protected $access; @@ -168,4 +190,15 @@ class GetInput extends Input { unset ($this->post); unset ($this->get); } + + /** + * Sets a parameter in $_GET and $_REQUEST + * + * @param string $name Parameter name + * @param mixed $value Value to set + */ + public function set($name, $value) { + parent::set($name, $value); + $_REQUEST[$name] = $value; + } } \ No newline at end of file -- cgit v1.2.3 From d720a82c905d624b7fd40132514ae662a410c949 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 24 Jun 2012 20:09:35 +0200 Subject: remove() implemented for Input class --- inc/Input.class.php | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/inc/Input.class.php b/inc/Input.class.php index aa402c646..62c2688c8 100644 --- a/inc/Input.class.php +++ b/inc/Input.class.php @@ -30,7 +30,8 @@ class Input { /** * Check if a parameter was set * - * Basically a wrapper around isset + * Basically a wrapper around isset. When called on the $post and $get subclasses, + * the parameter is set to $_POST or $_GET and to $_REQUEST * * @see isset * @param string $name Parameter name @@ -40,6 +41,29 @@ class Input { return isset($this->access[$name]); } + /** + * Remove a parameter from the superglobals + * + * Basically a wrapper around unset. When NOT called on the $post and $get subclasses, + * the parameter will also be removed from $_POST or $_GET + * + * @see isset + * @param string $name Parameter name + * @return bool + */ + public function remove($name) { + if(isset($this->access[$name])) { + unset($this->access[$name]); + } + // also remove from sub classes + if(isset($this->post) && isset($_POST[$name])) { + unset($_POST[$name]); + } + if(isset($this->get) && isset($_GET[$name])) { + unset($_GET[$name]); + } + } + /** * Access a request parameter without any type conversion * -- cgit v1.2.3 From bcc94b2c17efc51fd78a25db43058d10e685679d Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 24 Jun 2012 20:11:43 +0200 Subject: Input wrapper for auth.php --- inc/auth.php | 97 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/inc/auth.php b/inc/auth.php index 8489c2265..dc1fc5b32 100644 --- a/inc/auth.php +++ b/inc/auth.php @@ -36,6 +36,8 @@ function auth_setup() { global $conf; /* @var auth_basic $auth */ global $auth; + /* @var Input $INPUT */ + global $INPUT; global $AUTH_ACL; global $lang; $AUTH_ACL = array(); @@ -66,11 +68,8 @@ function auth_setup() { if(!$auth) return false; // do the login either by cookie or provided credentials XXX - if(!isset($_REQUEST['u'])) $_REQUEST['u'] = ''; - if(!isset($_REQUEST['p'])) $_REQUEST['p'] = ''; - if(!isset($_REQUEST['r'])) $_REQUEST['r'] = ''; - $_REQUEST['http_credentials'] = false; - if(!$conf['rememberme']) $_REQUEST['r'] = false; + $INPUT->set('http_credentials', false); + if(!$conf['rememberme']) $INPUT->set('r', false); // handle renamed HTTP_AUTHORIZATION variable (can happen when a fix like // the one presented at @@ -85,27 +84,27 @@ function auth_setup() { } // if no credentials were given try to use HTTP auth (for SSO) - if(empty($_REQUEST['u']) && empty($_COOKIE[DOKU_COOKIE]) && !empty($_SERVER['PHP_AUTH_USER'])) { - $_REQUEST['u'] = $_SERVER['PHP_AUTH_USER']; - $_REQUEST['p'] = $_SERVER['PHP_AUTH_PW']; - $_REQUEST['http_credentials'] = true; + if(!$INPUT->str('u') && empty($_COOKIE[DOKU_COOKIE]) && !empty($_SERVER['PHP_AUTH_USER'])) { + $INPUT->set('u', $_SERVER['PHP_AUTH_USER']); + $INPUT->set('p', $_SERVER['PHP_AUTH_PW']); + $INPUT->set('http_credentials', true); } // apply cleaning - $_REQUEST['u'] = $auth->cleanUser($_REQUEST['u']); + $INPUT->set('u', $auth->cleanUser($INPUT->str('u'))); - if(isset($_REQUEST['authtok'])) { + if($INPUT->str('authtok')) { // when an authentication token is given, trust the session - auth_validateToken($_REQUEST['authtok']); + auth_validateToken($INPUT->str('authtok')); } elseif(!is_null($auth) && $auth->canDo('external')) { // external trust mechanism in place - $auth->trustExternal($_REQUEST['u'], $_REQUEST['p'], $_REQUEST['r']); + $auth->trustExternal($INPUT->str('u'), $INPUT->str('p'), $INPUT->bool('r')); } else { $evdata = array( - 'user' => $_REQUEST['u'], - 'password' => $_REQUEST['p'], - 'sticky' => $_REQUEST['r'], - 'silent' => $_REQUEST['http_credentials'], + 'user' => $INPUT->str('u'), + 'password' => $INPUT->str('p'), + 'sticky' => $INPUT->bool('r'), + 'silent' => $INPUT->bool('http_credentials') ); trigger_event('AUTH_LOGIN_CHECK', $evdata, 'auth_login_wrapper'); } @@ -799,12 +798,13 @@ function register() { */ function updateprofile() { global $conf; - global $INFO; global $lang; /* @var auth_basic $auth */ global $auth; + /* @var Input $INPUT */ + global $INPUT; - if(empty($_POST['save'])) return false; + if(!$INPUT->post->bool('save')) return false; if(!checkSecurityToken()) return false; if(!actionOK('profile')) { @@ -812,39 +812,48 @@ function updateprofile() { return false; } - if($_POST['newpass'] != $_POST['passchk']) { - msg($lang['regbadpass'], -1); // complain about misspelled passwords + $changes = array(); + $changes['pass'] = $INPUT->post->str('newpass'); + $changes['name'] = $INPUT->post->str('fullname'); + $changes['mail'] = $INPUT->post->str('email'); + + // check misspelled passwords + if($changes['pass'] != $INPUT->post->str('passchk')) { + msg($lang['regbadpass'], -1); return false; } - //clean fullname and email - $_POST['fullname'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $_POST['fullname'])); - $_POST['email'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $_POST['email'])); + // clean fullname and email + $changes['name'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $changes['name'])); + $changes['mail'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $changes['mail'])); - if((empty($_POST['fullname']) && $auth->canDo('modName')) || - (empty($_POST['email']) && $auth->canDo('modMail')) + // no empty name and email (except the backend doesn't support them) + if((empty($changes['name']) && $auth->canDo('modName')) || + (empty($changes['mail']) && $auth->canDo('modMail')) ) { msg($lang['profnoempty'], -1); return false; } - - if(!mail_isvalid($_POST['email']) && $auth->canDo('modMail')) { + if(!mail_isvalid($changes['mail']) && $auth->canDo('modMail')) { msg($lang['regbadmail'], -1); return false; } - $changes = array(); - if($_POST['fullname'] != $INFO['userinfo']['name'] && $auth->canDo('modName')) $changes['name'] = $_POST['fullname']; - if($_POST['email'] != $INFO['userinfo']['mail'] && $auth->canDo('modMail')) $changes['mail'] = $_POST['email']; - if(!empty($_POST['newpass']) && $auth->canDo('modPass')) $changes['pass'] = $_POST['newpass']; + $changes = array_filter($changes); + // check for unavailable capabilities + if(!$auth->canDo('modName')) unset($changes['name']); + if(!$auth->canDo('modMail')) unset($changes['mail']); + if(!$auth->canDo('modPass')) unset($changes['pass']); + + // anything to do? if(!count($changes)) { msg($lang['profnochange'], -1); return false; } if($conf['profileconfirm']) { - if(!$auth->checkPass($_SERVER['REMOTE_USER'], $_POST['oldpass'])) { + if(!$auth->checkPass($_SERVER['REMOTE_USER'], $INPUT->post->str('oldpass'))) { msg($lang['badlogin'], -1); return false; } @@ -882,13 +891,15 @@ function act_resendpwd() { global $conf; /* @var auth_basic $auth */ global $auth; + /* @var Input $INPUT */ + global $INPUT; if(!actionOK('resendpwd')) { msg($lang['resendna'], -1); return false; } - $token = preg_replace('/[^a-f0-9]+/', '', $_REQUEST['pwauth']); + $token = preg_replace('/[^a-f0-9]+/', '', $INPUT->str('pwauth')); if($token) { // we're in token phase - get user info from token @@ -896,13 +907,13 @@ function act_resendpwd() { $tfile = $conf['cachedir'].'/'.$token{0}.'/'.$token.'.pwauth'; if(!@file_exists($tfile)) { msg($lang['resendpwdbadauth'], -1); - unset($_REQUEST['pwauth']); + $INPUT->remove('pwauth'); return false; } // token is only valid for 3 days if((time() - filemtime($tfile)) > (3 * 60 * 60 * 24)) { msg($lang['resendpwdbadauth'], -1); - unset($_REQUEST['pwauth']); + $INPUT->remove('pwauth'); @unlink($tfile); return false; } @@ -915,14 +926,16 @@ function act_resendpwd() { } if(!$conf['autopasswd']) { // we let the user choose a password + $pass = $INPUT->str('pass'); + // password given correctly? - if(!isset($_REQUEST['pass']) || $_REQUEST['pass'] == '') return false; - if($_REQUEST['pass'] != $_REQUEST['passchk']) { + if(!$pass) return false; + if($pass != $INPUT->str('passchk')) { msg($lang['regbadpass'], -1); return false; } - $pass = $_REQUEST['pass']; + // change it if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) { msg('error modifying user data', -1); return false; @@ -949,13 +962,13 @@ function act_resendpwd() { } else { // we're in request phase - if(!$_POST['save']) return false; + if(!$INPUT->post->bool('save')) return false; - if(empty($_POST['login'])) { + if(!$INPUT->post->str('login')) { msg($lang['resendpwdmissing'], -1); return false; } else { - $user = trim($auth->cleanUser($_POST['login'])); + $user = trim($auth->cleanUser($INPUT->post->str('login'))); } $userinfo = $auth->getUserData($user); -- cgit v1.2.3 From 4b530faa88b9afb8467805a9dde8204b9b0bd9fa Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Sun, 24 Jun 2012 18:24:07 -0400 Subject: validate inputs to install form --- install.php | 100 ++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 37 deletions(-) diff --git a/install.php b/install.php index 80e9ad407..698cd64c4 100644 --- a/install.php +++ b/install.php @@ -29,8 +29,10 @@ if (get_magic_quotes_gpc() && !defined('MAGIC_QUOTES_STRIPPED')) { // language strings require_once(DOKU_INC.'inc/lang/en/lang.php'); -$LC = preg_replace('/[^a-z\-]+/','',$_REQUEST['l']); -if(!$LC) $LC = 'en'; +if(isset($_REQUEST['l']) && !is_array($_REQUEST['l'])) { + $LC = preg_replace('/[^a-z\-]+/','',$_REQUEST['l']); +} +if(empty($LC)) $LC = 'en'; if($LC && $LC != 'en' ) { require_once(DOKU_INC.'inc/lang/'.$LC.'/lang.php'); } @@ -56,7 +58,6 @@ $dokuwiki_hash = array( ); - // begin output header('Content-Type: text/html; charset=utf-8'); ?> @@ -131,17 +132,16 @@ header('Content-Type: text/html; charset=utf-8'); }elseif(!check_configs()){ echo '

'.$lang['i_modified'].'

'; print_errors(); - }elseif($_REQUEST['submit']){ - if(!check_data($_REQUEST['d'])){ - print_errors(); - print_form($_REQUEST['d']); - }elseif(!store_data($_REQUEST['d'])){ + }elseif(check_data($_REQUEST['d'])){ + // check_data has sanitized all input parameters + if(!store_data($_REQUEST['d'])){ echo '

'.$lang['i_failure'].'

'; print_errors(); }else{ echo '

'.$lang['i_success'].'

'; } }else{ + print_errors(); print_form($_REQUEST['d']); } ?> @@ -252,41 +252,65 @@ function print_retry() { * @author Andreas Gohr */ function check_data(&$d){ + static $form_default = array( + 'title' => '', + 'acl' => '0', + 'superuser' => '', + 'fullname' => '', + 'email' => '', + 'password' => '', + 'confirm' => '', + 'policy' => '0', + 'license' => 'cc-by-sa' + ); global $lang; global $error; + if(!is_array($d)) $d = array(); + foreach($d as $k => $v) { + if(is_array($v)) + unset($d[$k]); + else + $d[$k] = (string)$v; + } + //autolowercase the username - $d['superuser'] = strtolower($d['superuser']); + $d['superuser'] = isset($d['superuser']) ? strtolower($d['superuser']) : ""; - $ok = true; + $ok = false; - // check input - if(empty($d['title'])){ - $error[] = sprintf($lang['i_badval'],$lang['i_wikiname']); - $ok = false; - } - if($d['acl']){ - if(!preg_match('/^[a-z0-9_]+$/',$d['superuser'])){ - $error[] = sprintf($lang['i_badval'],$lang['i_superuser']); - $ok = false; - } - if(empty($d['password'])){ - $error[] = sprintf($lang['i_badval'],$lang['pass']); - $ok = false; - } - if($d['confirm'] != $d['password']){ - $error[] = sprintf($lang['i_badval'],$lang['passchk']); - $ok = false; - } - if(empty($d['fullname']) || strstr($d['fullname'],':')){ - $error[] = sprintf($lang['i_badval'],$lang['fullname']); + if(isset($_REQUEST['submit'])) { + $ok = true; + + // check input + if(empty($d['title'])){ + $error[] = sprintf($lang['i_badval'],$lang['i_wikiname']); $ok = false; } - if(empty($d['email']) || strstr($d['email'],':') || !strstr($d['email'],'@')){ - $error[] = sprintf($lang['i_badval'],$lang['email']); - $ok = false; + if(isset($d['acl'])){ + if(!preg_match('/^[a-z0-9_]+$/',$d['superuser'])){ + $error[] = sprintf($lang['i_badval'],$lang['i_superuser']); + $ok = false; + } + if(empty($d['password'])){ + $error[] = sprintf($lang['i_badval'],$lang['pass']); + $ok = false; + } + elseif(!isset($d['confirm']) || $d['confirm'] != $d['password']){ + $error[] = sprintf($lang['i_badval'],$lang['passchk']); + $ok = false; + } + if(empty($d['fullname']) || strstr($d['fullname'],':')){ + $error[] = sprintf($lang['i_badval'],$lang['fullname']); + $ok = false; + } + if(empty($d['email']) || strstr($d['email'],':') || !strstr($d['email'],'@')){ + $error[] = sprintf($lang['i_badval'],$lang['email']); + $ok = false; + } } } + $d = array_merge($form_default, $d); return $ok; } @@ -531,11 +555,13 @@ function langsel(){ */ function print_errors(){ global $error; - echo '
    '; - foreach ($error as $err){ - echo "
  • $err
  • "; + if(!empty($error)) { + echo '
      '; + foreach ($error as $err){ + echo "
    • $err
    • "; + } + echo '
    '; } - echo '
'; } /** -- cgit v1.2.3 From 591acd873d64abb271864b581c48ca419aa5d329 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 25 Jun 2012 00:37:21 +0200 Subject: some Input class fixes and unit tests --- _test/tests/inc/input.test.php | 206 +++++++++++++++++++++++++++++++++++++++++ inc/Input.class.php | 10 +- 2 files changed, 210 insertions(+), 6 deletions(-) create mode 100644 _test/tests/inc/input.test.php diff --git a/_test/tests/inc/input.test.php b/_test/tests/inc/input.test.php new file mode 100644 index 000000000..627af3a2b --- /dev/null +++ b/_test/tests/inc/input.test.php @@ -0,0 +1,206 @@ + array('foo', 'bar'), + 'string' => 'foo', + 'int' => '17', + 'zero' => '0', + 'one' => '1', + 'empty' => '', + 'emptya' => array() + ); + + public function test_str() { + $_REQUEST = $this->data; + $_POST = $this->data; + $_GET = $this->data; + $_GET['get'] = 1; + $_POST['post'] = 1; + $INPUT = new Input(); + + $this->assertSame('foo', $INPUT->str('string')); + $this->assertSame('', $INPUT->str('none')); + $this->assertSame('', $INPUT->str('empty')); + $this->assertSame('foo', $INPUT->str('none', 'foo')); + $this->assertSame('', $INPUT->str('empty', 'foo')); + $this->assertSame('foo', $INPUT->str('empty', 'foo', true)); + + $this->assertSame(false, $INPUT->str('get', false)); + $this->assertSame(false, $INPUT->str('post', false)); + + $this->assertSame('foo', $INPUT->post->str('string')); + $this->assertSame('', $INPUT->post->str('none')); + $this->assertSame('', $INPUT->post->str('empty')); + $this->assertSame('foo', $INPUT->post->str('none', 'foo')); + $this->assertSame('', $INPUT->post->str('empty', 'foo')); + $this->assertSame('foo', $INPUT->post->str('empty', 'foo', true)); + + $this->assertSame(false, $INPUT->post->str('get', false)); + $this->assertSame('1', $INPUT->post->str('post', false)); + + $this->assertSame('foo', $INPUT->get->str('string')); + $this->assertSame('', $INPUT->get->str('none')); + $this->assertSame('', $INPUT->get->str('empty')); + $this->assertSame('foo', $INPUT->get->str('none', 'foo')); + $this->assertSame('', $INPUT->get->str('empty', 'foo')); + $this->assertSame('foo', $INPUT->get->str('empty', 'foo', true)); + + $this->assertSame(false, $INPUT->get->str('post', false)); + $this->assertSame('1', $INPUT->get->str('get', false)); + + $this->assertSame('', $INPUT->str('array')); + } + + public function test_int() { + $_REQUEST = $this->data; + $_POST = $this->data; + $_GET = $this->data; + $_GET['get'] = 1; + $_POST['post'] = 1; + $INPUT = new Input(); + + $this->assertSame(17, $INPUT->int('int')); + $this->assertSame(0, $INPUT->int('none')); + $this->assertSame(0, $INPUT->int('empty')); + $this->assertSame(42, $INPUT->int('none', 42)); + $this->assertSame(0, $INPUT->int('zero', 42)); + $this->assertSame(42, $INPUT->int('zero', 42, true)); + + $this->assertSame(false, $INPUT->int('get', false)); + $this->assertSame(false, $INPUT->int('post', false)); + + $this->assertSame(17, $INPUT->post->int('int')); + $this->assertSame(0, $INPUT->post->int('none')); + $this->assertSame(0, $INPUT->post->int('empty')); + $this->assertSame(42, $INPUT->post->int('none', 42)); + $this->assertSame(0, $INPUT->post->int('zero', 42)); + $this->assertSame(42, $INPUT->post->int('zero', 42, true)); + + $this->assertSame(false, $INPUT->post->int('get', false)); + $this->assertSame(1, $INPUT->post->int('post', false)); + + $this->assertSame(17, $INPUT->post->int('int')); + $this->assertSame(0, $INPUT->post->int('none')); + $this->assertSame(0, $INPUT->post->int('empty')); + $this->assertSame(42, $INPUT->post->int('none', 42)); + $this->assertSame(0, $INPUT->post->int('zero', 42)); + $this->assertSame(42, $INPUT->post->int('zero', 42, true)); + + $this->assertSame(false, $INPUT->get->int('post', false)); + $this->assertSame(1, $INPUT->get->int('get', false)); + + $this->assertSame(0, $INPUT->int('array')); + } + + public function test_arr() { + $_REQUEST = $this->data; + $_POST = $this->data; + $_GET = $this->data; + $_GET['get'] = array(1, 2); + $_POST['post'] = array(1, 2); + $INPUT = new Input(); + + $this->assertSame(array('foo', 'bar'), $INPUT->arr('array')); + $this->assertSame(array(), $INPUT->arr('none')); + $this->assertSame(array(), $INPUT->arr('empty')); + $this->assertSame(array(1, 2), $INPUT->arr('none', array(1, 2))); + $this->assertSame(array(), $INPUT->arr('emptya', array(1, 2))); + $this->assertSame(array(1, 2), $INPUT->arr('emptya', array(1, 2), true)); + + $this->assertSame(false, $INPUT->arr('get', false)); + $this->assertSame(false, $INPUT->arr('post', false)); + + $this->assertSame(array('foo', 'bar'), $INPUT->post->arr('array')); + $this->assertSame(array(), $INPUT->post->arr('none')); + $this->assertSame(array(), $INPUT->post->arr('empty')); + $this->assertSame(array(1, 2), $INPUT->post->arr('none', array(1, 2))); + $this->assertSame(array(), $INPUT->post->arr('emptya', array(1, 2))); + $this->assertSame(array(1, 2), $INPUT->post->arr('emptya', array(1, 2), true)); + + $this->assertSame(false, $INPUT->post->arr('get', false)); + $this->assertSame(array(1, 2), $INPUT->post->arr('post', false)); + + $this->assertSame(array('foo', 'bar'), $INPUT->get->arr('array')); + $this->assertSame(array(), $INPUT->get->arr('none')); + $this->assertSame(array(), $INPUT->get->arr('empty')); + $this->assertSame(array(1, 2), $INPUT->get->arr('none', array(1, 2))); + $this->assertSame(array(), $INPUT->get->arr('emptya', array(1, 2))); + $this->assertSame(array(1, 2), $INPUT->get->arr('emptya', array(1, 2), true)); + + $this->assertSame(array(1, 2), $INPUT->get->arr('get', false)); + $this->assertSame(false, $INPUT->get->arr('post', false)); + } + + public function test_bool() { + $_REQUEST = $this->data; + $_POST = $this->data; + $_GET = $this->data; + $_GET['get'] = '1'; + $_POST['post'] = '1'; + $INPUT = new Input(); + + $this->assertSame(true, $INPUT->bool('one')); + $this->assertSame(false, $INPUT->bool('zero')); + + $this->assertSame(false, $INPUT->bool('get')); + $this->assertSame(false, $INPUT->bool('post')); + + $this->assertSame(true, $INPUT->post->bool('one')); + $this->assertSame(false, $INPUT->post->bool('zero')); + + $this->assertSame(false, $INPUT->post->bool('get')); + $this->assertSame(true, $INPUT->post->bool('post')); + } + + public function test_remove() { + $_REQUEST = $this->data; + $_POST = $this->data; + $_GET = $this->data; + $INPUT = new Input(); + + $INPUT->remove('string'); + $this->assertNull($_REQUEST['string']); + $this->assertNull($_POST['string']); + $this->assertNull($_GET['string']); + + $INPUT->post->remove('int'); + $this->assertNull($_POST['int']); + $this->assertEquals(17, $_GET['int']); + $this->assertEquals(17, $_REQUEST['int']); + } + + public function test_set(){ + $_REQUEST = $this->data; + $_POST = $this->data; + $_GET = $this->data; + $INPUT = new Input(); + + $INPUT->set('test','foo'); + $this->assertEquals('foo',$_REQUEST['test']); + $this->assertNull($_POST['test']); + $this->assertNull($_GET['test']); + + $INPUT->get->set('test2','foo'); + $this->assertEquals('foo',$_GET['test2']); + $this->assertEquals('foo',$_REQUEST['test2']); + $this->assertNull($_POST['test']); + } + + public function test_ref(){ + $_REQUEST = $this->data; + $_POST = $this->data; + $_GET = $this->data; + $INPUT = new Input(); + + $test = &$INPUT->ref('string'); + $this->assertEquals('foo',$test); + $_REQUEST['string'] = 'bla'; + $this->assertEquals('bla',$test); + } + +} \ No newline at end of file diff --git a/inc/Input.class.php b/inc/Input.class.php index 62c2688c8..1ea5e031f 100644 --- a/inc/Input.class.php +++ b/inc/Input.class.php @@ -104,8 +104,7 @@ class Input { $this->set($name, $default); } - $ref = &$this->access[$name]; - return $ref; + return $this->access[$name]; } /** @@ -143,6 +142,8 @@ class Input { /** * Access a request parameter as bool * + * Note: $nonempty is here for interface consistency and makes not much sense for booleans + * * @param string $name Parameter name * @param mixed $default Default to return if parameter isn't set * @param bool $nonempty Return $default if parameter is set but empty() @@ -165,6 +166,7 @@ class Input { */ public function arr($name, $default = array(), $nonempty = false) { if(!isset($this->access[$name])) return $default; + if(!is_array($this->access[$name])) return $default; if($nonempty && empty($this->access[$name])) return $default; return (array) $this->access[$name]; @@ -183,8 +185,6 @@ class PostInput extends Input { */ function __construct() { $this->access = &$_POST; - unset ($this->post); - unset ($this->get); } /** @@ -211,8 +211,6 @@ class GetInput extends Input { */ function __construct() { $this->access = &$_GET; - unset ($this->post); - unset ($this->get); } /** -- cgit v1.2.3 From ed85653424b3ac0935aad110ecc9798d5e3e9b72 Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Sun, 24 Jun 2012 19:13:59 -0400 Subject: enable ACL by default on install --- install.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install.php b/install.php index 698cd64c4..a1d406209 100644 --- a/install.php +++ b/install.php @@ -213,7 +213,7 @@ function print_form($d){

'None', 'url'=>'')); - if(!isset($d['license'])) $d['license'] = 'cc-by-sa'; + if(empty($d['license'])) $d['license'] = 'cc-by-sa'; foreach($license as $key => $lic){ echo '
'.$mail.''; default: return hsc($username); @@ -1451,20 +1466,21 @@ function editorinfo($username){ * * @author Andreas Gohr * @param string $type - type of image 'badge' or 'button' + * @return string */ -function license_img($type){ +function license_img($type) { global $license; global $conf; if(!$conf['license']) return ''; if(!is_array($license[$conf['license']])) return ''; - $lic = $license[$conf['license']]; - $try = array(); + $lic = $license[$conf['license']]; + $try = array(); $try[] = 'lib/images/license/'.$type.'/'.$conf['license'].'.png'; $try[] = 'lib/images/license/'.$type.'/'.$conf['license'].'.gif'; - if(substr($conf['license'],0,3) == 'cc-'){ + if(substr($conf['license'], 0, 3) == 'cc-') { $try[] = 'lib/images/license/'.$type.'/cc.png'; } - foreach($try as $src){ + foreach($try as $src) { if(@file_exists(DOKU_INC.$src)) return $src; } return ''; @@ -1476,12 +1492,15 @@ function license_img($type){ * If the memory_get_usage() function is not available the * function just assumes $bytes of already allocated memory * - * @param int $mem Size of memory you want to allocate in bytes - * @param int $used already allocated memory (see above) * @author Filip Oscadal * @author Andreas Gohr + * + * @param int $mem Size of memory you want to allocate in bytes + * @param int $bytes + * @internal param int $used already allocated memory (see above) + * @return bool */ -function is_mem_available($mem,$bytes=1048576){ +function is_mem_available($mem, $bytes = 1048576) { $limit = trim(ini_get('memory_limit')); if(empty($limit)) return true; // no limit set! @@ -1489,13 +1508,13 @@ function is_mem_available($mem,$bytes=1048576){ $limit = php_to_byte($limit); // get used memory if possible - if(function_exists('memory_get_usage')){ + if(function_exists('memory_get_usage')) { $used = memory_get_usage(); - }else{ + } else { $used = $bytes; } - if($used+$mem > $limit){ + if($used + $mem > $limit) { return false; } @@ -1510,10 +1529,10 @@ function is_mem_available($mem,$bytes=1048576){ * @link http://support.microsoft.com/kb/q176113/ * @author Andreas Gohr */ -function send_redirect($url){ +function send_redirect($url) { //are there any undisplayed messages? keep them in session for display global $MSG; - if (isset($MSG) && count($MSG) && !defined('NOSESSION')){ + if(isset($MSG) && count($MSG) && !defined('NOSESSION')) { //reopen session, store data and close session again @session_start(); $_SESSION[DOKU_COOKIE]['msg'] = $MSG; @@ -1524,22 +1543,23 @@ function send_redirect($url){ // work around IE bug // http://www.ianhoar.com/2008/11/16/internet-explorer-6-and-redirected-anchor-links/ - list($url,$hash) = explode('#',$url); - if($hash){ - if(strpos($url,'?')){ + list($url, $hash) = explode('#', $url); + if($hash) { + if(strpos($url, '?')) { $url = $url.'&#'.$hash; - }else{ + } else { $url = $url.'?&#'.$hash; } } // check if running on IIS < 6 with CGI-PHP - if( isset($_SERVER['SERVER_SOFTWARE']) && isset($_SERVER['GATEWAY_INTERFACE']) && - (strpos($_SERVER['GATEWAY_INTERFACE'],'CGI') !== false) && + if(isset($_SERVER['SERVER_SOFTWARE']) && isset($_SERVER['GATEWAY_INTERFACE']) && + (strpos($_SERVER['GATEWAY_INTERFACE'], 'CGI') !== false) && (preg_match('|^Microsoft-IIS/(\d)\.\d$|', trim($_SERVER['SERVER_SOFTWARE']), $matches)) && - $matches[1] < 6 ){ + $matches[1] < 6 + ) { header('Refresh: 0;url='.$url); - }else{ + } else { header('Location: '.$url); } exit; @@ -1559,12 +1579,14 @@ function send_redirect($url){ * or $_GET) * @param string $exc The text of the raised exception * + * @throws Exception + * @return mixed * @author Adrian Lang */ function valid_input_set($param, $valid_values, $array, $exc = '') { - if (isset($array[$param]) && in_array($array[$param], $valid_values)) { + if(isset($array[$param]) && in_array($array[$param], $valid_values)) { return $array[$param]; - } elseif (isset($valid_values['default'])) { + } elseif(isset($valid_values['default'])) { return $valid_values['default']; } else { throw new Exception($exc); @@ -1575,12 +1597,12 @@ function valid_input_set($param, $valid_values, $array, $exc = '') { * Read a preference from the DokuWiki cookie */ function get_doku_pref($pref, $default) { - if (strpos($_COOKIE['DOKU_PREFS'], $pref) !== false) { + if(strpos($_COOKIE['DOKU_PREFS'], $pref) !== false) { $parts = explode('#', $_COOKIE['DOKU_PREFS']); $cnt = count($parts); - for ($i = 0; $i < $cnt; $i+=2){ - if ($parts[$i] == $pref) { - return $parts[$i+1]; + for($i = 0; $i < $cnt; $i += 2) { + if($parts[$i] == $pref) { + return $parts[$i + 1]; } } } diff --git a/inc/init.php b/inc/init.php index 1907aea09..a28050736 100644 --- a/inc/init.php +++ b/inc/init.php @@ -3,7 +3,9 @@ * Initialize some defaults needed for DokuWiki */ -// start timing Dokuwiki execution +/** + * timing Dokuwiki execution + */ function delta_time($start=0) { return microtime(true)-((float)$start); } -- cgit v1.2.3 From 90f1b7bd60332450b32e4ec0b189ddb0ab11fdf8 Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Wed, 27 Jun 2012 02:30:15 -0400 Subject: Input wrapper for action.php --- inc/actions.php | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/inc/actions.php b/inc/actions.php index e85cbfccc..0c35bc88c 100644 --- a/inc/actions.php +++ b/inc/actions.php @@ -20,6 +20,7 @@ function act_dispatch(){ global $ID; global $INFO; global $QUERY; + global $INPUT; global $lang; global $conf; @@ -131,14 +132,14 @@ function act_dispatch(){ //handle admin tasks if($ACT == 'admin'){ // retrieve admin plugin name from $_REQUEST['page'] - if (!empty($_REQUEST['page'])) { + if (($page = $INPUT->str('page', '', true)) != '') { $pluginlist = plugin_list('admin'); - if (in_array($_REQUEST['page'], $pluginlist)) { + if (in_array($page, $pluginlist)) { // attempt to load the plugin - if ($plugin =& plugin_load('admin',$_REQUEST['page']) !== null){ + if ($plugin =& plugin_load('admin',$page) !== null){ if($plugin->forAdminOnly() && !$INFO['isadmin']){ // a manager tried to load a plugin that's for admins only - unset($_REQUEST['page']); + $INPUT->remove('page'); msg('For admins only',-1); }else{ $plugin->handle(); @@ -300,13 +301,14 @@ function act_draftdel($act){ function act_draftsave($act){ global $INFO; global $ID; + global $INPUT; global $conf; - if($conf['usedraft'] && $_POST['wikitext']){ + if($conf['usedraft'] && $INPUT->post->has('wikitext')) { $draft = array('id' => $ID, - 'prefix' => substr($_POST['prefix'], 0, -1), - 'text' => $_POST['wikitext'], - 'suffix' => $_POST['suffix'], - 'date' => (int) $_POST['date'], + 'prefix' => substr($INPUT->post->str('prefix'), 0, -1), + 'text' => $INPUT->post->str('wikitext'), + 'suffix' => $INPUT->post->str('suffix'), + 'date' => $INPUT->post->int('date'), 'client' => $INFO['client'], ); $cname = getCacheName($draft['client'].$ID,'.draft'); @@ -335,6 +337,7 @@ function act_save($act){ global $SUM; global $lang; global $INFO; + global $INPUT; //spam check if(checkwordblock()) { @@ -346,7 +349,7 @@ function act_save($act){ return 'conflict'; //save it - saveWikiText($ID,con($PRE,$TEXT,$SUF,1),$SUM,$_REQUEST['minor']); //use pretty mode for con + saveWikiText($ID,con($PRE,$TEXT,$SUF,1),$SUM,$INPUT->bool('minor')); //use pretty mode for con //unlock it unlock($ID); @@ -669,6 +672,7 @@ function act_subscription($act){ global $lang; global $INFO; global $ID; + global $INPUT; // subcriptions work for logged in users only if(!$_SERVER['REMOTE_USER']) return 'show'; @@ -676,8 +680,8 @@ function act_subscription($act){ // get and preprocess data. $params = array(); foreach(array('target', 'style', 'action') as $param) { - if (isset($_REQUEST["sub_$param"])) { - $params[$param] = $_REQUEST["sub_$param"]; + if ($INPUT->has("sub_$param")) { + $params[$param] = $INPUT->str("sub_$param"); } } -- cgit v1.2.3 From 7d01a0eac854c623a74ff7936d5eba9413aefe79 Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Wed, 27 Jun 2012 02:48:49 -0400 Subject: more INPUT wrapper uses: cache purge, sectok, getID --- inc/cache.php | 3 ++- inc/common.php | 3 ++- inc/pageutils.php | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/inc/cache.php b/inc/cache.php index ff78e37ae..204c6f006 100644 --- a/inc/cache.php +++ b/inc/cache.php @@ -84,7 +84,8 @@ class cache { * it should only overwrite a dependency when the new value is more stringent than the old */ function _addDependencies() { - if (isset($_REQUEST['purge'])) $this->depends['purge'] = true; // purge requested + global $INPUT; + if ($INPUT->has('purge')) $this->depends['purge'] = true; // purge requested } /** diff --git a/inc/common.php b/inc/common.php index 768260bbf..02ed2432b 100644 --- a/inc/common.php +++ b/inc/common.php @@ -63,9 +63,10 @@ function getSecurityToken() { * Check the secret CSRF token */ function checkSecurityToken($token = null) { + global $INPUT; if(!$_SERVER['REMOTE_USER']) return true; // no logged in user, no need for a check - if(is_null($token)) $token = $_REQUEST['sectok']; + if(is_null($token)) $token = $INPUT->str('sectok'); if(getSecurityToken() != $token) { msg('Security Token did not match. Possible CSRF attack.', -1); return false; diff --git a/inc/pageutils.php b/inc/pageutils.php index c94d14624..95f791364 100644 --- a/inc/pageutils.php +++ b/inc/pageutils.php @@ -19,9 +19,10 @@ * @author Andreas Gohr */ function getID($param='id',$clean=true){ + global $INPUT; global $conf; - $id = isset($_REQUEST[$param]) ? $_REQUEST[$param] : null; + $id = $INPUT->str($param); //construct page id from request URI if(empty($id) && $conf['userewrite'] == 2){ -- cgit v1.2.3 From 44b0470cb5f4a7e78a12354f552748afe03861b9 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Wed, 27 Jun 2012 23:13:49 +0200 Subject: compressed new template graphics with tinypng.org --- lib/tpl/dokuwiki/images/apple-touch-icon.png | Bin 17728 -> 6399 bytes lib/tpl/dokuwiki/images/bullet.png | Bin 199 -> 112 bytes lib/tpl/dokuwiki/images/button-dw.png | Bin 404 -> 398 bytes lib/tpl/dokuwiki/images/button-rss.png | Bin 191 -> 180 bytes lib/tpl/dokuwiki/images/closed-rtl.png | Bin 170 -> 118 bytes lib/tpl/dokuwiki/images/closed.png | Bin 165 -> 119 bytes lib/tpl/dokuwiki/images/email.png | Bin 630 -> 502 bytes lib/tpl/dokuwiki/images/external-link.png | Bin 947 -> 758 bytes lib/tpl/dokuwiki/images/logo.png | Bin 12212 -> 3820 bytes lib/tpl/dokuwiki/images/open.png | Bin 174 -> 118 bytes lib/tpl/dokuwiki/images/pagetools-sprite.png | Bin 8178 -> 5931 bytes lib/tpl/dokuwiki/images/resizecol.png | Bin 225 -> 158 bytes lib/tpl/dokuwiki/images/search.png | Bin 400 -> 316 bytes lib/tpl/dokuwiki/images/sitetools.png | Bin 3186 -> 2225 bytes lib/tpl/dokuwiki/images/toc-arrows.png | Bin 322 -> 225 bytes lib/tpl/dokuwiki/images/toc-bullet.png | Bin 211 -> 121 bytes lib/tpl/dokuwiki/images/unc.png | Bin 553 -> 517 bytes 17 files changed, 0 insertions(+), 0 deletions(-) diff --git a/lib/tpl/dokuwiki/images/apple-touch-icon.png b/lib/tpl/dokuwiki/images/apple-touch-icon.png index 45fa4e7b0..fb5f108c0 100644 Binary files a/lib/tpl/dokuwiki/images/apple-touch-icon.png and b/lib/tpl/dokuwiki/images/apple-touch-icon.png differ diff --git a/lib/tpl/dokuwiki/images/bullet.png b/lib/tpl/dokuwiki/images/bullet.png index 5da537443..5e557b334 100644 Binary files a/lib/tpl/dokuwiki/images/bullet.png and b/lib/tpl/dokuwiki/images/bullet.png differ diff --git a/lib/tpl/dokuwiki/images/button-dw.png b/lib/tpl/dokuwiki/images/button-dw.png index 97272d968..8d6aea898 100644 Binary files a/lib/tpl/dokuwiki/images/button-dw.png and b/lib/tpl/dokuwiki/images/button-dw.png differ diff --git a/lib/tpl/dokuwiki/images/button-rss.png b/lib/tpl/dokuwiki/images/button-rss.png index f2438043f..b7cddadec 100644 Binary files a/lib/tpl/dokuwiki/images/button-rss.png and b/lib/tpl/dokuwiki/images/button-rss.png differ diff --git a/lib/tpl/dokuwiki/images/closed-rtl.png b/lib/tpl/dokuwiki/images/closed-rtl.png index 85ebd59e1..caa027e34 100644 Binary files a/lib/tpl/dokuwiki/images/closed-rtl.png and b/lib/tpl/dokuwiki/images/closed-rtl.png differ diff --git a/lib/tpl/dokuwiki/images/closed.png b/lib/tpl/dokuwiki/images/closed.png index 3691ebc17..e3bd0f9e9 100644 Binary files a/lib/tpl/dokuwiki/images/closed.png and b/lib/tpl/dokuwiki/images/closed.png differ diff --git a/lib/tpl/dokuwiki/images/email.png b/lib/tpl/dokuwiki/images/email.png index 4ba4aad2f..5128be895 100644 Binary files a/lib/tpl/dokuwiki/images/email.png and b/lib/tpl/dokuwiki/images/email.png differ diff --git a/lib/tpl/dokuwiki/images/external-link.png b/lib/tpl/dokuwiki/images/external-link.png index 60fc8716b..084135f95 100644 Binary files a/lib/tpl/dokuwiki/images/external-link.png and b/lib/tpl/dokuwiki/images/external-link.png differ diff --git a/lib/tpl/dokuwiki/images/logo.png b/lib/tpl/dokuwiki/images/logo.png index 8b794dd64..35640279c 100644 Binary files a/lib/tpl/dokuwiki/images/logo.png and b/lib/tpl/dokuwiki/images/logo.png differ diff --git a/lib/tpl/dokuwiki/images/open.png b/lib/tpl/dokuwiki/images/open.png index 40ff129be..5f2d408c5 100644 Binary files a/lib/tpl/dokuwiki/images/open.png and b/lib/tpl/dokuwiki/images/open.png differ diff --git a/lib/tpl/dokuwiki/images/pagetools-sprite.png b/lib/tpl/dokuwiki/images/pagetools-sprite.png index bbd7fd361..898f0f4a6 100644 Binary files a/lib/tpl/dokuwiki/images/pagetools-sprite.png and b/lib/tpl/dokuwiki/images/pagetools-sprite.png differ diff --git a/lib/tpl/dokuwiki/images/resizecol.png b/lib/tpl/dokuwiki/images/resizecol.png index f0111507c..b5aeec004 100644 Binary files a/lib/tpl/dokuwiki/images/resizecol.png and b/lib/tpl/dokuwiki/images/resizecol.png differ diff --git a/lib/tpl/dokuwiki/images/search.png b/lib/tpl/dokuwiki/images/search.png index 2adfc7357..1ab7866fb 100644 Binary files a/lib/tpl/dokuwiki/images/search.png and b/lib/tpl/dokuwiki/images/search.png differ diff --git a/lib/tpl/dokuwiki/images/sitetools.png b/lib/tpl/dokuwiki/images/sitetools.png index 62a17a0c3..dc5764647 100644 Binary files a/lib/tpl/dokuwiki/images/sitetools.png and b/lib/tpl/dokuwiki/images/sitetools.png differ diff --git a/lib/tpl/dokuwiki/images/toc-arrows.png b/lib/tpl/dokuwiki/images/toc-arrows.png index 9f441eb26..4a353e4f6 100644 Binary files a/lib/tpl/dokuwiki/images/toc-arrows.png and b/lib/tpl/dokuwiki/images/toc-arrows.png differ diff --git a/lib/tpl/dokuwiki/images/toc-bullet.png b/lib/tpl/dokuwiki/images/toc-bullet.png index a6f0169c3..fc771b97e 100644 Binary files a/lib/tpl/dokuwiki/images/toc-bullet.png and b/lib/tpl/dokuwiki/images/toc-bullet.png differ diff --git a/lib/tpl/dokuwiki/images/unc.png b/lib/tpl/dokuwiki/images/unc.png index 6dd3d365c..f2aca8815 100644 Binary files a/lib/tpl/dokuwiki/images/unc.png and b/lib/tpl/dokuwiki/images/unc.png differ -- cgit v1.2.3 From 8243e61012e1d4f5614a32a3d5d9e81c50036f1c Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Wed, 27 Jun 2012 19:09:58 -0400 Subject: Limit size of reads when max_bodysize is set or content-length is present --- inc/HTTPClient.php | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index 73f5b89b4..c3ccfbbf2 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -427,25 +427,25 @@ class HTTPClient { $byte = $this->_readData($socket, 2, 'chunk'); // read trailing \r\n } } while ($chunk_size && !$abort); + }elseif($this->max_bodysize){ + // read just over the max_bodysize + $r_body = $this->_readData($socket, $this->max_bodysize+1, 'response', true); + if(strlen($r_body) > $this->max_bodysize){ + if ($this->max_bodysize_abort) { + throw new HTTPClientException('Allowed response size exceeded'); + } else { + $this->error = 'Allowed response size exceeded'; + } + } + }elseif(isset($this->resp_headers['content-length']) && + !isset($this->resp_headers['transfer-encoding'])){ + // read up to the content-length + $r_body = $this->_readData($socket, $this->resp_headers['content-length'], 'response', true); }else{ // read entire socket + $r_size = 0; while (!feof($socket)) { - $r_body .= $this->_readData($socket, -$this->max_bodysize, 'response', true); - $r_size = strlen($r_body); - if($this->max_bodysize && $r_size > $this->max_bodysize){ - if ($this->max_bodysize_abort) { - throw new HTTPClientException('Allowed response size exceeded'); - } else { - $this->error = 'Allowed response size exceeded'; - break; - } - } - if(isset($this->resp_headers['content-length']) && - !isset($this->resp_headers['transfer-encoding']) && - $this->resp_headers['content-length'] == $r_size){ - // we read the content-length, finish here - break; - } + $r_body .= $this->_readData($socket, 0, 'response', true); } } @@ -525,10 +525,8 @@ class HTTPClient { * Safely read data from a socket * * Reads up to a given number of bytes or throws an exception if the - * response times out or ends prematurely. If the number of bytes to - * read is negative, then it will read up to the absolute value, but - * may read less. A value of 0 returns an arbitrarily sized block, - * and a positive value will return exactly that many bytes. + * response times out or ends prematurely. If $nbytes is 0, an arbitrarily + * sized block will be read. * * @param handle $socket An open socket handle in non-blocking mode * @param int $nbytes Number of bytes to read @@ -543,16 +541,19 @@ class HTTPClient { $sel_e = null; $r_data = ''; - $to_read = $nbytes ? $nbytes : 4096; - if ($to_read < 0) $to_read = -$to_read; + if ($nbytes <= 0) $nbytes = 4096; + $to_read = $nbytes; do { $time_used = $this->_time() - $this->start; if ($time_used > $this->timeout) throw new HTTPClientException( sprintf('Timeout while reading %s (%.3fs)', $message, $time_used), -100); - if(!$ignore_eof && feof($socket)) - throw new HTTPClientException("Premature End of File (socket) while reading $message"); + if(feof($socket)) { + if(!$ignore_eof) + throw new HTTPClientException("Premature End of File (socket) while reading $message"); + break; + } // wait for stream ready or timeout self::selecttimeout($this->timeout - $time_used, $sec, $usec); -- cgit v1.2.3 From a6ba0720629e19619b1d72aa7aadea28a533f856 Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Wed, 27 Jun 2012 19:38:46 -0400 Subject: Avoid timeout when content-length is 0 --- inc/HTTPClient.php | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index c3ccfbbf2..a25846c31 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -445,7 +445,7 @@ class HTTPClient { // read entire socket $r_size = 0; while (!feof($socket)) { - $r_body .= $this->_readData($socket, 0, 'response', true); + $r_body .= $this->_readData($socket, 4096, 'response', true); } } @@ -525,8 +525,7 @@ class HTTPClient { * Safely read data from a socket * * Reads up to a given number of bytes or throws an exception if the - * response times out or ends prematurely. If $nbytes is 0, an arbitrarily - * sized block will be read. + * response times out or ends prematurely. * * @param handle $socket An open socket handle in non-blocking mode * @param int $nbytes Number of bytes to read @@ -541,7 +540,8 @@ class HTTPClient { $sel_e = null; $r_data = ''; - if ($nbytes <= 0) $nbytes = 4096; + // Does not return immediately so timeout and eof can be checked + if ($nbytes < 0) $nbytes = 0; $to_read = $nbytes; do { $time_used = $this->_time() - $this->start; @@ -555,16 +555,18 @@ class HTTPClient { break; } - // wait for stream ready or timeout - self::selecttimeout($this->timeout - $time_used, $sec, $usec); - if(@stream_select($sel_r, $sel_w, $sel_e, $sec, $usec) !== false){ - $bytes = fread($socket, $to_read); - if($bytes === false) - throw new HTTPClientException("Failed reading from socket while reading $message", -100); - $r_data .= $bytes; - $to_read -= strlen($bytes); + if ($to_read > 0) { + // wait for stream ready or timeout + self::selecttimeout($this->timeout - $time_used, $sec, $usec); + if(@stream_select($sel_r, $sel_w, $sel_e, $sec, $usec) !== false){ + $bytes = fread($socket, $to_read); + if($bytes === false) + throw new HTTPClientException("Failed reading from socket while reading $message", -100); + $r_data .= $bytes; + $to_read -= strlen($bytes); + } } - } while (strlen($r_data) < $nbytes); + } while ($to_read > 0 && strlen($r_data) < $nbytes); return $r_data; } -- cgit v1.2.3 From 0189bd8669742c5290a4f6538f954b81554e26d2 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 28 Jun 2012 16:43:01 +0200 Subject: make sure all globals are available in test requests --- _test/core/TestRequest.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/_test/core/TestRequest.php b/_test/core/TestRequest.php index 9047f7e88..66760b1e0 100644 --- a/_test/core/TestRequest.php +++ b/_test/core/TestRequest.php @@ -46,6 +46,11 @@ class TestRequest { $post = $_POST; $request = $_REQUEST; + // import all defined globals into the function scope + foreach(array_keys($GLOBALS) as $glb){ + global $$glb; + } + // fake environment global $default_server_vars; $_SERVER = array_merge($default_server_vars, $this->server); @@ -58,9 +63,6 @@ class TestRequest { global $output_buffer; $output_buffer = ''; - // make globals available as were in a function context here FIXME: any others needed? - global $INPUT; - // now execute dokuwiki and grep the output header_remove(); ob_start('ob_start_callback'); -- cgit v1.2.3 From 5d0aaf958325f500ce69cfb79e69eb0d8f83fdeb Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 28 Jun 2012 17:17:24 +0200 Subject: treat empty string inputs as unset for int and bool --- _test/tests/inc/input.test.php | 12 +++++++++++- inc/Input.class.php | 5 ++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/_test/tests/inc/input.test.php b/_test/tests/inc/input.test.php index 627af3a2b..761b7ddbc 100644 --- a/_test/tests/inc/input.test.php +++ b/_test/tests/inc/input.test.php @@ -95,6 +95,11 @@ class input_test extends DokuWikiTest { $this->assertSame(1, $INPUT->get->int('get', false)); $this->assertSame(0, $INPUT->int('array')); + + $this->assertSame(0, $INPUT->int('zero', -1)); + $this->assertSame(-1, $INPUT->int('empty', -1)); + $this->assertSame(-1, $INPUT->int('zero', -1, true)); + $this->assertSame(-1, $INPUT->int('empty', -1, true)); } public function test_arr() { @@ -155,6 +160,11 @@ class input_test extends DokuWikiTest { $this->assertSame(false, $INPUT->post->bool('get')); $this->assertSame(true, $INPUT->post->bool('post')); + + $this->assertSame(false, $INPUT->bool('zero', -1)); + $this->assertSame(-1, $INPUT->bool('empty', -1)); + $this->assertSame(-1, $INPUT->bool('zero', -1, true)); + $this->assertSame(-1, $INPUT->bool('empty', -1, true)); } public function test_remove() { @@ -203,4 +213,4 @@ class input_test extends DokuWikiTest { $this->assertEquals('bla',$test); } -} \ No newline at end of file +} diff --git a/inc/Input.class.php b/inc/Input.class.php index 1ea5e031f..f4174404a 100644 --- a/inc/Input.class.php +++ b/inc/Input.class.php @@ -118,6 +118,7 @@ class Input { public function int($name, $default = 0, $nonempty = false) { if(!isset($this->access[$name])) return $default; if(is_array($this->access[$name])) return $default; + if($this->access[$name] === '') return $default; if($nonempty && empty($this->access[$name])) return $default; return (int) $this->access[$name]; @@ -151,6 +152,8 @@ class Input { */ public function bool($name, $default = false, $nonempty = false) { if(!isset($this->access[$name])) return $default; + if(is_array($this->access[$name])) return $default; + if($this->access[$name] === '') return $default; if($nonempty && empty($this->access[$name])) return $default; return (bool) $this->access[$name]; @@ -223,4 +226,4 @@ class GetInput extends Input { parent::set($name, $value); $_REQUEST[$name] = $value; } -} \ No newline at end of file +} -- cgit v1.2.3 From bfd0f5975e6e3578b4fa0c712e9779a0861fdc72 Mon Sep 17 00:00:00 2001 From: Tom N Harris Date: Thu, 28 Jun 2012 22:04:10 -0400 Subject: Input wrapper for exe scripts --- lib/exe/css.php | 8 ++++---- lib/exe/detail.php | 4 ++-- lib/exe/fetch.php | 8 ++++---- lib/exe/indexer.php | 7 ++++--- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/exe/css.php b/lib/exe/css.php index 69b512205..5cc4ab830 100644 --- a/lib/exe/css.php +++ b/lib/exe/css.php @@ -29,14 +29,14 @@ function css_out(){ global $conf; global $lang; global $config_cascade; + global $INPUT; $mediatype = 'screen'; - if (isset($_REQUEST['s']) && - in_array($_REQUEST['s'], array('all', 'print', 'feed'))) { - $mediatype = $_REQUEST['s']; + if (in_array($INPUT->str('s'), array('all', 'print', 'feed'))) { + $mediatype = $INPUT->str('s'); } - $tpl = trim(preg_replace('/[^\w-]+/','',$_REQUEST['t'])); + $tpl = trim(preg_replace('/[^\w-]+/','',$INPUT->str('t'))); if($tpl){ $tplinc = DOKU_INC.'lib/tpl/'.$tpl.'/'; $tpldir = DOKU_BASE.'lib/tpl/'.$tpl.'/'; diff --git a/lib/exe/detail.php b/lib/exe/detail.php index 35186f5dd..ea46bc037 100644 --- a/lib/exe/detail.php +++ b/lib/exe/detail.php @@ -6,9 +6,9 @@ require_once(DOKU_INC.'inc/init.php'); session_write_close(); $IMG = getID('media'); -$ID = cleanID($_REQUEST['id']); +$ID = cleanID($INPUT->str('id')); -if($conf['allowdebug'] && $_REQUEST['debug']){ +if($conf['allowdebug'] && $INPUT->has('debug')){ print '
';
     foreach(explode(' ','basedir userewrite baseurl useslash') as $x){
         print '$'."conf['$x'] = '".$conf[$x]."';\n";
diff --git a/lib/exe/fetch.php b/lib/exe/fetch.php
index 143d40f22..60843460e 100644
--- a/lib/exe/fetch.php
+++ b/lib/exe/fetch.php
@@ -17,10 +17,10 @@
 
   //get input
   $MEDIA  = stripctl(getID('media',false)); // no cleaning except control chars - maybe external
-  $CACHE  = calc_cache($_REQUEST['cache']);
-  $WIDTH  = (int) $_REQUEST['w'];
-  $HEIGHT = (int) $_REQUEST['h'];
-  $REV   = (int) @$_REQUEST['rev'];
+  $CACHE  = calc_cache($INPUT->str('cache'));
+  $WIDTH  = $INPUT->int('w');
+  $HEIGHT = $INPUT->int('h');
+  $REV    = &$INPUT->ref('rev');
   //sanitize revision
   $REV = preg_replace('/[^0-9]/','',$REV);
 
diff --git a/lib/exe/indexer.php b/lib/exe/indexer.php
index 738a29503..e149770c0 100644
--- a/lib/exe/indexer.php
+++ b/lib/exe/indexer.php
@@ -20,10 +20,10 @@ if(!$defer){
     sendGIF(); // send gif
 }
 
-$ID = cleanID($_REQUEST['id']);
+$ID = cleanID($INPUT->str('id'));
 
 // Catch any possible output (e.g. errors)
-$output = isset($_REQUEST['debug']) && $conf['allowdebug'];
+$output = $INPUT->has('debug') && $conf['allowdebug'];
 if(!$output) ob_start();
 
 // run one of the jobs
@@ -261,7 +261,8 @@ function sendDigest() {
  * @author Harry Fuecks 
  */
 function sendGIF(){
-    if(isset($_REQUEST['debug'])){
+    global $INPUT;
+    if($INPUT->has('debug')){
         header('Content-Type: text/plain');
         return;
     }
-- 
cgit v1.2.3


From 8108113c244529ec54f11271a6a15e3d1e0a048f Mon Sep 17 00:00:00 2001
From: Tom N Harris 
Date: Thu, 28 Jun 2012 22:15:56 -0400
Subject: Input validation for media manager

---
 inc/media.php            | 66 +++++++++++++++++++++++++++++-------------------
 lib/exe/mediamanager.php | 35 +++++++++++++------------
 2 files changed, 57 insertions(+), 44 deletions(-)

diff --git a/inc/media.php b/inc/media.php
index 2462a1deb..6c92225ff 100644
--- a/inc/media.php
+++ b/inc/media.php
@@ -226,8 +226,9 @@ function media_delete($id,$auth){
  */
 function media_upload_xhr($ns,$auth){
     if(!checkSecurityToken()) return false;
+    global $INPUT;
 
-    $id = $_GET['qqfile'];
+    $id = $INPUT->get->str('qqfile');
     list($ext,$mime,$dl) = mimetype($id);
     $input = fopen("php://input", "r");
     if (!($tmp = io_mktmpdir())) return false;
@@ -247,7 +248,7 @@ function media_upload_xhr($ns,$auth){
             'mime' => $mime,
             'ext'  => $ext),
         $ns.':'.$id,
-        (($_REQUEST['ow'] == 'checked') ? true : false),
+        (($INPUT->get->str('ow') == 'checked') ? true : false),
         $auth,
         'copy'
     );
@@ -270,9 +271,10 @@ function media_upload_xhr($ns,$auth){
 function media_upload($ns,$auth,$file=false){
     if(!checkSecurityToken()) return false;
     global $lang;
+    global $INPUT;
 
     // get file and id
-    $id   = $_POST['mediaid'];
+    $id   = $INPUT->post->str('mediaid');
     if (!$file) $file = $_FILES['upload'];
     if(empty($id)) $id = $file['name'];
 
@@ -294,7 +296,7 @@ function media_upload($ns,$auth,$file=false){
     $res = media_save(array('name' => $file['tmp_name'],
                             'mime' => $imime,
                             'ext'  => $iext), $ns.':'.$id,
-                      $_REQUEST['ow'], $auth, 'move_uploaded_file');
+                      $INPUT->post->bool('ow'), $auth, 'move_uploaded_file');
     if (is_array($res)) {
         msg($res[0], $res[1]);
         return false;
@@ -641,7 +643,9 @@ function media_tabs_details($image, $selected_tab = ''){
  * @author Kate Arzamastseva 
  */
 function media_tab_files_options(){
-    global $lang, $NS;
+    global $lang;
+    global $NS;
+    global $INPUT;
     $form = new Doku_Form(array('class' => 'options', 'method' => 'get',
                                 'action' => wl($ID)));
     $media_manager_params = media_managerURL(array(), '', false, true);
@@ -649,8 +653,8 @@ function media_tab_files_options(){
         $form->addHidden($pKey, $pVal);
     }
     $form->addHidden('sectok', null);
-    if (isset($_REQUEST['q'])) {
-        $form->addHidden('q', $_REQUEST['q']);
+    if ($INPUT->has('q')) {
+        $form->addHidden('q', $INPUT->str('q'));
     }
     $form->addElement('