summaryrefslogtreecommitdiff
path: root/inc
diff options
context:
space:
mode:
authorMartin Doucha <next_ghost@quick.cz>2012-07-06 14:02:10 +0200
committerMartin Doucha <next_ghost@quick.cz>2012-07-06 14:02:10 +0200
commit27849ebfc6b61fbb42ec6deb9c99ff548c40b4ac (patch)
tree5c231dfd7978a65522f56fd3be29bfe9679a64a7 /inc
parent3fb0e07d018fc6c8d173bd4a8a58c77ba00290fb (diff)
parent4ba05e11e88dd654689b0f6333b1427e03d1b0fe (diff)
downloadrpg-27849ebfc6b61fbb42ec6deb9c99ff548c40b4ac.tar.gz
rpg-27849ebfc6b61fbb42ec6deb9c99ff548c40b4ac.tar.bz2
Merge branch 'master' of git://github.com/splitbrain/dokuwiki
Diffstat (limited to 'inc')
-rw-r--r--inc/DifferenceEngine.php10
-rw-r--r--inc/HTTPClient.php466
-rw-r--r--inc/Input.class.php229
-rw-r--r--inc/JpegMeta.php2
-rw-r--r--inc/Mailer.class.php298
-rw-r--r--inc/PassHash.class.php277
-rw-r--r--inc/actions.php28
-rw-r--r--inc/auth.php658
-rw-r--r--inc/cache.php3
-rw-r--r--inc/common.php835
-rw-r--r--inc/config_cascade.php2
-rw-r--r--inc/form.php5
-rw-r--r--inc/html.php110
-rw-r--r--inc/init.php8
-rw-r--r--inc/lang/bg/lang.php8
-rw-r--r--inc/lang/bg/mailtext.txt2
-rw-r--r--inc/lang/bg/mailwrap.html13
-rw-r--r--inc/lang/de-informal/lang.php21
-rw-r--r--inc/lang/de-informal/mailwrap.html13
-rw-r--r--inc/lang/de-informal/resetpwd.txt4
-rw-r--r--inc/lang/de/lang.php1
-rw-r--r--inc/lang/de/mailwrap.html13
-rw-r--r--inc/lang/ko/backlinks.txt2
-rw-r--r--inc/lang/ko/conflict.txt2
-rw-r--r--inc/lang/ko/diff.txt4
-rw-r--r--inc/lang/ko/draft.txt4
-rw-r--r--inc/lang/ko/edit.txt3
-rw-r--r--inc/lang/ko/install.html10
-rw-r--r--inc/lang/ko/lang.php72
-rw-r--r--inc/lang/ko/mailtext.txt2
-rw-r--r--inc/lang/ko/preview.txt2
-rw-r--r--inc/lang/ko/read.txt2
-rw-r--r--inc/lang/ko/register.txt2
-rw-r--r--inc/lang/ko/resetpwd.txt2
-rw-r--r--inc/lang/ko/revisions.txt4
-rw-r--r--inc/lang/ko/searchpage.txt2
-rw-r--r--inc/lang/ko/subscr_digest.txt3
-rw-r--r--inc/lang/ko/subscr_list.txt3
-rw-r--r--inc/lang/ko/subscr_single.txt2
-rw-r--r--inc/lang/ko/uploadmail.txt2
-rw-r--r--inc/lang/nl/edit.txt2
-rw-r--r--inc/lang/nl/lang.php17
-rw-r--r--inc/lang/nl/mailwrap.html13
-rw-r--r--inc/lang/ru/lang.php4
-rw-r--r--inc/lang/ru/resetpwd.txt3
-rw-r--r--inc/lang/vi/backlinks.txt4
-rw-r--r--inc/lang/vi/conflict.txt2
-rw-r--r--inc/lang/vi/denied.txt2
-rw-r--r--inc/lang/vi/edit.txt2
-rw-r--r--inc/lang/vi/editrev.txt2
-rw-r--r--inc/lang/vi/lang.php186
-rw-r--r--inc/lang/vi/login.txt2
-rw-r--r--inc/lang/vi/mailtext.txt2
-rw-r--r--inc/lang/vi/newpage.txt2
-rw-r--r--inc/lang/vi/norev.txt2
-rw-r--r--inc/lang/vi/password.txt2
-rw-r--r--inc/lang/vi/preview.txt2
-rw-r--r--inc/lang/vi/read.txt2
-rw-r--r--inc/lang/vi/revisions.txt2
-rw-r--r--inc/lang/vi/searchpage.txt2
-rw-r--r--inc/load.php1
-rw-r--r--inc/media.php71
-rw-r--r--inc/pageutils.php27
-rw-r--r--inc/parser/code.php3
-rw-r--r--inc/parser/xhtml.php22
-rw-r--r--inc/parserutils.php4
-rw-r--r--inc/template.php28
-rw-r--r--inc/utf8.php59
68 files changed, 2171 insertions, 1428 deletions
diff --git a/inc/DifferenceEngine.php b/inc/DifferenceEngine.php
index 0a7ce8e7c..1b68cf6d3 100644
--- a/inc/DifferenceEngine.php
+++ b/inc/DifferenceEngine.php
@@ -1039,8 +1039,8 @@ class TableDiffFormatter 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(' ','&nbsp; ', $val);
- $val = preg_replace('/ (?=<)|(?<=[ >]) /', '&nbsp;', $val);
+ $val = str_replace(' ','&#160; ', $val);
+ $val = preg_replace('/ (?=<)|(?<=[ >]) /', '&#160;', $val);
return $val;
}
@@ -1078,7 +1078,7 @@ class TableDiffFormatter extends DiffFormatter {
}
function emptyLine() {
- return '<td colspan="2">&nbsp;</td>';
+ return '<td colspan="2">&#160;</td>';
}
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(' ','&nbsp; ', $val);
- $val = preg_replace('/ (?=<)|(?<=[ >]) /', '&nbsp;', $val);
+ $val = str_replace(' ','&#160; ', $val);
+ $val = preg_replace('/ (?=<)|(?<=[ >]) /', '&#160;', $val);
return $val;
}
diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php
index 26bee52a7..a25846c31 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
*
@@ -227,7 +229,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 +251,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) {
@@ -279,16 +281,13 @@ 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', $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,222 +301,161 @@ class HTTPClient {
// keep alive?
if ($this->keep_alive) {
- $this->connections[$connectionId] = $socket;
+ self::$connections[$connectionId] = $socket;
} else {
- unset($this->connections[$connectionId]);
- }
- }
-
- //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($this->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($this->connections[$connectionId]);
- return false;
+ unset(self::$connections[$connectionId]);
}
- $written += $ret;
}
- // continue non-blocking
- stream_set_blocking($socket,0);
-
- // 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($this->connections[$connectionId]);
- return false;
- }
- if(feof($socket)){
- $this->error = 'Premature End of File (socket)';
- unset($this->connections[$connectionId]);
- return false;
- }
- 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){
- $this->error = 'Reported content length exceeds allowed response size';
- if ($this->max_bodysize_abort)
- unset($this->connections[$connectionId]);
- return false;
+ try {
+ //set non-blocking
+ stream_set_blocking($socket, false);
+
+ // 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);
+ $this->_sendData($socket, $request, 'request');
+
+ // read headers from socket
+ $r_headers = '';
+ do{
+ $r_line = $this->_readLine($socket, 'headers');
+ $r_headers .= $r_line;
+ }while($r_line != "\r\n" && $r_line != "\n");
+
+ $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($this->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);
- // 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($this->connections[$connectionId]);
+ $this->_debug('Object headers',$this->resp_headers);
- 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'];
+ // 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]);
+
+ $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($this->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 {
- unset($chunk_size);
+ //read body (with chunked encoding if needed)
+ $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 {
- if(feof($socket)){
- $this->error = 'Premature End of File (socket)';
- unset($this->connections[$connectionId]);
- return false;
+ $chunk_size = '';
+ while (preg_match('/^[a-zA-Z0-9]?$/',$byte=$this->_readData($socket,1,'chunk'))){
+ // read chunksize until \r
+ $chunk_size .= $byte;
+ if (strlen($chunk_size) > 128) // set an abritrary limit on the size of chunks
+ throw new HTTPClientException('Allowed response size exceeded');
}
- if(time()-$start > $this->timeout){
- $this->status = -100;
- $this->error = sprintf('Timeout while reading chunk (%.3fs)',$this->_time() - $this->start);
- unset($this->connections[$connectionId]);
- return false;
+ $this->_readLine($socket, 'chunk'); // readtrailing \n
+ $chunk_size = hexdec($chunk_size);
+
+ 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';
+ $chunk_size = $this->max_bodysize - strlen($r_body);
+ $abort = true;
}
- $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) {
- $this_chunk = fread($socket,$chunk_size);
- $r_body .= $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($this->connections[$connectionId]);
- return false;
- } else {
- break;
+ 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);
- }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($this->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';
+ } 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) {
- unset($this->connections[$connectionId]);
- return false;
+ throw new HTTPClientException('Allowed response size exceeded');
} else {
- break;
+ $this->error = 'Allowed response size exceeded';
}
}
- 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;
+ }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, 4096, 'response', true);
}
}
+
+ } 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 ||
@@ -525,7 +463,7 @@ class HTTPClient {
// close socket
$status = socket_get_status($socket);
fclose($socket);
- unset($this->connections[$connectionId]);
+ unset(self::$connections[$connectionId]);
}
// decode gzip if needed
@@ -547,6 +485,126 @@ class HTTPClient {
}
/**
+ * 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 <tnharris@whoopdedo.org>
+ */
+ 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
+ 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)
+ throw new HTTPClientException("Failed writing to socket while sending $message", -100);
+ $written += $nbytes;
+ }
+ }
+ }
+
+ /**
+ * 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.
+ *
+ * @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 <tnharris@whoopdedo.org>
+ */
+ function _readData($socket, $nbytes, $message, $ignore_eof = false) {
+ // select parameters
+ $sel_r = array($socket);
+ $sel_w = null;
+ $sel_e = null;
+
+ $r_data = '';
+ // 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;
+ if ($time_used > $this->timeout)
+ throw new HTTPClientException(
+ sprintf('Timeout while reading %s (%.3fs)', $message, $time_used),
+ -100);
+ if(feof($socket)) {
+ if(!$ignore_eof)
+ throw new HTTPClientException("Premature End of File (socket) while reading $message");
+ break;
+ }
+
+ 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 ($to_read > 0 && 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 <tnharris@whoopdedo.org>
+ */
+ 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;
+ 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");
+
+ // 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;
+ }
+
+ /**
* print debug info
*
* @author Andreas Gohr <andi@splitbrain.org>
@@ -566,12 +624,20 @@ 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
*
* All Keys are lowercased.
@@ -583,7 +649,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);
diff --git a/inc/Input.class.php b/inc/Input.class.php
new file mode 100644
index 000000000..f4174404a
--- /dev/null
+++ b/inc/Input.class.php
@@ -0,0 +1,229 @@
+<?php
+
+/**
+ * Encapsulates access to the $_REQUEST array, making sure used parameters are initialized and
+ * have the correct type.
+ *
+ * All function access the $_REQUEST array by default, if you want to access $_POST or $_GET
+ * explicitly use the $post and $get members.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+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();
+ }
+
+ /**
+ * Check if a parameter was set
+ *
+ * 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
+ * @return bool
+ */
+ public function has($name) {
+ 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
+ *
+ * @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, $nonempty = false) {
+ if(!isset($this->access[$name])) return $default;
+ if($nonempty && empty($this->access[$name])) return $default;
+ 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
+ *
+ * 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 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->set($name, $default);
+ }
+
+ return $this->access[$name];
+ }
+
+ /**
+ * 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
+ * @param bool $nonempty Return $default if parameter is set but empty()
+ * @return int
+ */
+ 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];
+ }
+
+ /**
+ * 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
+ * @param bool $nonempty Return $default if parameter is set but empty()
+ * @return string
+ */
+ 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];
+ }
+
+ /**
+ * 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()
+ * @return bool
+ */
+ 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];
+ }
+
+ /**
+ * Access a request parameter as array
+ *
+ * @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(), $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];
+ }
+
+}
+
+/**
+ * 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;
+ }
+
+ /**
+ * 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;
+
+ /**
+ * Initialize the $access array, remove subclass members
+ */
+ function __construct() {
+ $this->access = &$_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;
+ }
+}
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 .= '&gt;';
elseif ($c == 32)
- $ascii .= '&nbsp;';
+ $ascii .= '&#160;';
elseif ($c > 32)
$ascii .= chr($c);
else
diff --git a/inc/Mailer.class.php b/inc/Mailer.class.php
index 507150d00..c85e61395 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('/[^a-zA-Z0-9_ \-\.\+\@]+/', '', $header);
+ $value = preg_replace('/[^a-zA-Z0-9_ \-\.\+\@<>]+/', '', $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','<hr >',$html);
+ $html = preg_replace('/^-----*$/m', '<hr >', $html);
$html = nl2br($html);
}
- if($wrap){
- $wrap = rawLocale('mailwrap','html');
- $html = preg_replace('/\n-- <br \/>.*$/s','',$html); //strip signature
- $html = str_replace('@HTMLBODY@',$html,$wrap);
+ if($wrap) {
+ $wrap = rawLocale('mailwrap', 'html');
+ $html = preg_replace('/\n-- <br \/>.*$/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] = '<a href="'.hsc($value).'">'.hsc($value).'</a>';
- }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' => '<i>'.hsc(dformat()).'</i>',
'BROWSER' => hsc($_SERVER['HTTP_USER_AGENT']),
@@ -224,16 +230,16 @@ class Mailer {
'USER' => hsc($_SERVER['REMOTE_USER']),
'NAME' => hsc($INFO['userinfo']['name']),
'MAIL' => '<a href="mailto:"'.hsc($INFO['userinfo']['mail']).'">'.
- hsc($INFO['userinfo']['mail']).'</a>',
+ hsc($INFO['userinfo']['mail']).'</a>',
);
- $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öö <foo@bar.com>, 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,10 +568,10 @@ class Mailer {
*
* @return string the mail, false on errors
*/
- public function dump(){
+ public function dump() {
$this->cleanHeaders();
- $body = $this->prepareBody();
- if($body === 'false') return false;
+ $body = $this->prepareBody();
+ if($body === false) return false;
$headers = $this->prepareHeaders();
return $headers.MAILHEADER_EOL.$body;
@@ -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();
- if($body === 'false') return false;
+ $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?
diff --git a/inc/PassHash.class.php b/inc/PassHash.class.php
index d825057f0..13be479cc 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 <andi@splitbrain.org>
+ * @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 <andi@splitbrain.org>
* @author <mikey_nich at hotmail dot com>
* @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 && $salt !== '') {
+ 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 <mikey_nich at hotmail dot com>
* @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 <soren at byu dot edu>
- * @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);
diff --git a/inc/actions.php b/inc/actions.php
index 4376af5f9..d4bd5b20e 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();
@@ -309,13 +310,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');
@@ -344,6 +346,7 @@ function act_save($act){
global $SUM;
global $lang;
global $INFO;
+ global $INPUT;
//spam check
if(checkwordblock()) {
@@ -355,7 +358,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);
@@ -678,6 +681,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';
@@ -685,8 +689,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");
}
}
diff --git a/inc/auth.php b/inc/auth.php
index ed0e2dcf7..cedfdee36 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,30 @@ 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;
+ /* @var Input $INPUT */
+ global $INPUT;
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 +65,11 @@ 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'] = '';
- $_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
@@ -77,73 +78,93 @@ 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'];
- $_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']);
- }elseif(!is_null($auth) && $auth->canDo('external')){
+ 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']);
- }else{
+ $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');
}
//load ACL into a global array XXX
$AUTH_ACL = auth_loadACL();
+
+ return true;
}
/**
* Loads the ACL setup and handle user wildcards
*
* @author Andreas Gohr <andi@splitbrain.org>
- * @returns array
+ * @return array
*/
-function auth_loadACL(){
+function auth_loadACL() {
global $config_cascade;
+ 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'])){
- $len = count($acl);
- for($i=0; $i<$len; $i++){
- if($acl[$i]{0} == '#') continue;
- list($id,$rest) = preg_split('/\s+/',$acl[$i],2);
+ $out = array();
+ foreach($acl as $line) {
+ $line = trim($line);
+ if($line{0} == '#') continue;
+ list($id,$rest) = preg_split('/\s+/',$line,2);
+
+ if(strstr($line, '%GROUP%')){
+ foreach((array) $USERINFO['grps'] as $grp){
+ $nid = str_replace('%GROUP%',cleanID($grp),$id);
+ $nrest = str_replace('%GROUP%','@'.auth_nameencode($grp),$rest);
+ $out[] = "$nid\t$nrest";
+ }
+ } else {
$id = str_replace('%USER%',cleanID($_SERVER['REMOTE_USER']),$id);
$rest = str_replace('%USER%',auth_nameencode($_SERVER['REMOTE_USER']),$rest);
- $acl[$i] = "$id\t$rest";
+ $out[] = "$id\t$rest";
}
}
- return $acl;
+
+ return $out;
}
+/**
+ * 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 +196,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 +263,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 +274,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 +286,7 @@ function auth_validateToken($token){
* @author Andreas Gohr <andi@splitbrain.org>
* @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 +305,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 +328,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 +351,10 @@ function auth_cookiesalt($addsession=false){
* @author Andreas Gohr <andi@splitbrain.org>
* @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 +370,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 +392,34 @@ function auth_logoff($keepbc=false){
*
* @author Andreas Gohr <andi@splitbrain.org>
* @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 +432,15 @@ function auth_ismanager($user=null,$groups=null,$adminonly=false){
* The info is available through $INFO['isadmin'], too
*
* @author Andreas Gohr <andi@splitbrain.org>
- * @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 +452,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 +497,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']);
}
/**
@@ -482,111 +511,115 @@ function auth_quickaclcheck($id){
*
* @author Andreas Gohr <andi@splitbrain.org>
*
- * @param string $id page ID (needs to be resolved and cleaned)
- * @param string $user Username
- * @param array $groups Array of groups the user is in
+ * @param string $id page ID (needs to be resolved and cleaned)
+ * @param string $user Username
+ * @param array|null $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,21 +635,26 @@ function auth_aclcheck($id,$user,$groups){
* @author Andreas Gohr <gohr@cosmocode.de>
* @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;
// 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} =='@'){
- $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 +669,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 +691,16 @@ function auth_pwgen(){
* Sends a password to the given user
*
* @author Andreas Gohr <andi@splitbrain.org>
- *
+ * @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 +708,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 +726,12 @@ function auth_sendPassword($user,$password){
* This registers a new user - Data is read directly from $_POST
*
* @author Andreas Gohr <andi@splitbrain.org>
- *
* @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 +741,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;
}
}
@@ -769,63 +809,78 @@ 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')) {
- msg($lang['profna'],-1);
+ msg($lang['profna'], -1);
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'))) {
- msg($lang['profnoempty'],-1);
+ // 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')){
- msg($lang['regbadmail'],-1);
+ if(!mail_isvalid($changes['mail']) && $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_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']);
- if (!count($changes)) {
+ // anything to do?
+ 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'], $INPUT->post->str('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 +897,73 @@ 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;
+ /* @var Input $INPUT */
+ global $INPUT;
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]+/', '', $INPUT->str('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);
- unset($_REQUEST['pwauth']);
+ if(!@file_exists($tfile)) {
+ msg($lang['resendpwdbadauth'], -1);
+ $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']);
+ if((time() - filemtime($tfile)) > (3 * 60 * 60 * 24)) {
+ msg($lang['resendpwdbadauth'], -1);
+ $INPUT->remove('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
+ $pass = $INPUT->str('pass');
+
// password given correctly?
- if(!isset($_REQUEST['pass']) || $_REQUEST['pass'] == '') return false;
- if($_REQUEST['pass'] != $_REQUEST['passchk']){
- msg($lang['regbadpass'],-1);
+ if(!$pass) return false;
+ if($pass != $INPUT->str('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);
+ // change it
+ 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);
}
}
@@ -913,13 +973,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);
@@ -931,30 +991,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 +1023,37 @@ function act_resendpwd(){
* is chosen.
*
* @author Andreas Gohr <andi@splitbrain.org>
+ * @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 <andi@splitbrain.org>
- * @return bool
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @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 +1062,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 +1088,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 +1097,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 :
diff --git a/inc/cache.php b/inc/cache.php
index e598baa47..e0d08c971 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 cd0780730..02ed2432b 100644
--- a/inc/common.php
+++ b/inc/common.php
@@ -11,11 +11,11 @@ if(!defined('DOKU_INC')) die('meh.');
/**
* These constants are used with the recents function
*/
-define('RECENTS_SKIP_DELETED',2);
-define('RECENTS_SKIP_MINORS',4);
-define('RECENTS_SKIP_SUBSPACES',8);
-define('RECENTS_MEDIA_CHANGES',16);
-define('RECENTS_MEDIA_PAGES_MIXED',32);
+define('RECENTS_SKIP_DELETED', 2);
+define('RECENTS_SKIP_MINORS', 4);
+define('RECENTS_SKIP_SUBSPACES', 8);
+define('RECENTS_MEDIA_CHANGES', 16);
+define('RECENTS_MEDIA_PAGES_MIXED', 32);
/**
* Wrapper around htmlspecialchars()
@@ -23,7 +23,7 @@ define('RECENTS_MEDIA_PAGES_MIXED',32);
* @author Andreas Gohr <andi@splitbrain.org>
* @see htmlspecialchars()
*/
-function hsc($string){
+function hsc($string) {
return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
}
@@ -34,7 +34,7 @@ function hsc($string){
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function ptln($string,$indent=0){
+function ptln($string, $indent = 0) {
echo str_repeat(' ', $indent)."$string\n";
}
@@ -43,8 +43,8 @@ function ptln($string,$indent=0){
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function stripctl($string){
- return preg_replace('/[\x00-\x1F]+/s','',$string);
+function stripctl($string) {
+ return preg_replace('/[\x00-\x1F]+/s', '', $string);
}
/**
@@ -55,19 +55,20 @@ function stripctl($string){
* @link http://christ1an.blogspot.com/2007/04/preventing-csrf-efficiently.html
* @return string
*/
-function getSecurityToken(){
+function getSecurityToken() {
return md5(auth_cookiesalt().session_id().$_SERVER['REMOTE_USER']);
}
/**
* Check the secret CSRF token
*/
-function checkSecurityToken($token=null){
+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(getSecurityToken() != $token){
- msg('Security Token did not match. Possible CSRF attack.',-1);
+ if(is_null($token)) $token = $INPUT->str('sectok');
+ if(getSecurityToken() != $token) {
+ msg('Security Token did not match. Possible CSRF attack.', -1);
return false;
}
return true;
@@ -78,13 +79,10 @@ function checkSecurityToken($token=null){
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function formSecurityToken($print=true){
+function formSecurityToken($print = true) {
$ret = '<div class="no"><input type="hidden" name="sectok" value="'.getSecurityToken().'" /></div>'."\n";
- if($print){
- echo $ret;
- }else{
- return $ret;
- }
+ if($print) echo $ret;
+ return $ret;
}
/**
@@ -93,7 +91,7 @@ function formSecurityToken($print=true){
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function pageinfo(){
+function pageinfo() {
global $ID;
global $REV;
global $RANGE;
@@ -102,32 +100,32 @@ function pageinfo(){
// include ID & REV not redundant, as some parts of DokuWiki may temporarily change $ID, e.g. p_wiki_xhtml
// FIXME ... perhaps it would be better to ensure the temporary changes weren't necessary
- $info['id'] = $ID;
+ $info['id'] = $ID;
$info['rev'] = $REV;
// set info about manager/admin status.
$info['isadmin'] = false;
$info['ismanager'] = false;
- if(isset($_SERVER['REMOTE_USER'])){
- $info['userinfo'] = $USERINFO;
- $info['perm'] = auth_quickaclcheck($ID);
- $info['subscribed'] = get_info_subscribed();
- $info['client'] = $_SERVER['REMOTE_USER'];
+ if(isset($_SERVER['REMOTE_USER'])) {
+ $info['userinfo'] = $USERINFO;
+ $info['perm'] = auth_quickaclcheck($ID);
+ $info['subscribed'] = get_info_subscribed();
+ $info['client'] = $_SERVER['REMOTE_USER'];
- if($info['perm'] == AUTH_ADMIN){
+ if($info['perm'] == AUTH_ADMIN) {
$info['isadmin'] = true;
$info['ismanager'] = true;
- }elseif(auth_ismanager()){
+ } elseif(auth_ismanager()) {
$info['ismanager'] = true;
}
// if some outside auth were used only REMOTE_USER is set
- if(!$info['userinfo']['name']){
+ if(!$info['userinfo']['name']) {
$info['userinfo']['name'] = $_SERVER['REMOTE_USER'];
}
- }else{
- $info['perm'] = auth_aclcheck($ID,'',null);
+ } else {
+ $info['perm'] = auth_aclcheck($ID, '', null);
$info['subscribed'] = false;
$info['client'] = clientIP(true);
}
@@ -136,76 +134,76 @@ function pageinfo(){
$info['locked'] = checklock($ID);
$info['filepath'] = fullpath(wikiFN($ID));
$info['exists'] = @file_exists($info['filepath']);
- if($REV){
+ if($REV) {
//check if current revision was meant
- if($info['exists'] && (@filemtime($info['filepath'])==$REV)){
+ if($info['exists'] && (@filemtime($info['filepath']) == $REV)) {
$REV = '';
- }elseif($RANGE){
+ } elseif($RANGE) {
//section editing does not work with old revisions!
$REV = '';
$RANGE = '';
- msg($lang['nosecedit'],0);
- }else{
+ msg($lang['nosecedit'], 0);
+ } else {
//really use old revision
- $info['filepath'] = fullpath(wikiFN($ID,$REV));
+ $info['filepath'] = fullpath(wikiFN($ID, $REV));
$info['exists'] = @file_exists($info['filepath']);
}
}
$info['rev'] = $REV;
- if($info['exists']){
+ if($info['exists']) {
$info['writable'] = (is_writable($info['filepath']) &&
- ($info['perm'] >= AUTH_EDIT));
- }else{
+ ($info['perm'] >= AUTH_EDIT));
+ } else {
$info['writable'] = ($info['perm'] >= AUTH_CREATE);
}
- $info['editable'] = ($info['writable'] && empty($info['locked']));
- $info['lastmod'] = @filemtime($info['filepath']);
+ $info['editable'] = ($info['writable'] && empty($info['locked']));
+ $info['lastmod'] = @filemtime($info['filepath']);
//load page meta data
$info['meta'] = p_get_metadata($ID);
//who's the editor
- if($REV){
+ if($REV) {
$revinfo = getRevisionInfo($ID, $REV, 1024);
- }else{
- if (is_array($info['meta']['last_change'])) {
+ } else {
+ if(is_array($info['meta']['last_change'])) {
$revinfo = $info['meta']['last_change'];
} else {
$revinfo = getRevisionInfo($ID, $info['lastmod'], 1024);
// cache most recent changelog line in metadata if missing and still valid
- if ($revinfo!==false) {
+ if($revinfo !== false) {
$info['meta']['last_change'] = $revinfo;
p_set_metadata($ID, array('last_change' => $revinfo));
}
}
}
//and check for an external edit
- if($revinfo!==false && $revinfo['date']!=$info['lastmod']){
+ if($revinfo !== false && $revinfo['date'] != $info['lastmod']) {
// cached changelog line no longer valid
- $revinfo = false;
+ $revinfo = false;
$info['meta']['last_change'] = $revinfo;
p_set_metadata($ID, array('last_change' => $revinfo));
}
- $info['ip'] = $revinfo['ip'];
- $info['user'] = $revinfo['user'];
- $info['sum'] = $revinfo['sum'];
+ $info['ip'] = $revinfo['ip'];
+ $info['user'] = $revinfo['user'];
+ $info['sum'] = $revinfo['sum'];
// See also $INFO['meta']['last_change'] which is the most recent log line for page $ID.
// Use $INFO['meta']['last_change']['type']===DOKU_CHANGE_TYPE_MINOR_EDIT in place of $info['minor'].
- if($revinfo['user']){
+ if($revinfo['user']) {
$info['editor'] = $revinfo['user'];
- }else{
+ } else {
$info['editor'] = $revinfo['ip'];
}
// draft
- $draft = getCacheName($info['client'].$ID,'.draft');
- if(@file_exists($draft)){
- if(@filemtime($draft) < @filemtime(wikiFN($ID))){
+ $draft = getCacheName($info['client'].$ID, '.draft');
+ if(@file_exists($draft)) {
+ if(@filemtime($draft) < @filemtime(wikiFN($ID))) {
// remove stale draft
@unlink($draft);
- }else{
+ } else {
$info['draft'] = $draft;
}
}
@@ -221,14 +219,14 @@ function pageinfo(){
*
* @author Andreas Gohr
*/
-function buildURLparams($params, $sep='&amp;'){
+function buildURLparams($params, $sep = '&amp;') {
$url = '';
$amp = false;
- foreach($params as $key => $val){
+ foreach($params as $key => $val) {
if($amp) $url .= $sep;
$url .= rawurlencode($key).'=';
- $url .= rawurlencode((string)$val);
+ $url .= rawurlencode((string) $val);
$amp = true;
}
return $url;
@@ -241,29 +239,28 @@ function buildURLparams($params, $sep='&amp;'){
*
* @author Andreas Gohr
*/
-function buildAttributes($params,$skipempty=false){
- $url = '';
+function buildAttributes($params, $skipempty = false) {
+ $url = '';
$white = false;
- foreach($params as $key => $val){
+ foreach($params as $key => $val) {
if($key{0} == '_') continue;
if($val === '' && $skipempty) continue;
if($white) $url .= ' ';
$url .= $key.'="';
- $url .= htmlspecialchars ($val);
+ $url .= htmlspecialchars($val);
$url .= '"';
$white = true;
}
return $url;
}
-
/**
* This builds the breadcrumb trail and returns it as array
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function breadcrumbs(){
+function breadcrumbs() {
// we prepare the breadcrumbs early for quick session closing
static $crumbs = null;
if($crumbs != null) return $crumbs;
@@ -276,30 +273,30 @@ function breadcrumbs(){
$crumbs = isset($_SESSION[DOKU_COOKIE]['bc']) ? $_SESSION[DOKU_COOKIE]['bc'] : array();
//we only save on show and existing wiki documents
$file = wikiFN($ID);
- if($ACT != 'show' || !@file_exists($file)){
+ if($ACT != 'show' || !@file_exists($file)) {
$_SESSION[DOKU_COOKIE]['bc'] = $crumbs;
return $crumbs;
}
// page names
$name = noNSorNS($ID);
- if (useHeading('navigation')) {
+ if(useHeading('navigation')) {
// get page title
- $title = p_get_first_heading($ID,METADATA_RENDER_USING_SIMPLE_CACHE);
- if ($title) {
+ $title = p_get_first_heading($ID, METADATA_RENDER_USING_SIMPLE_CACHE);
+ if($title) {
$name = $title;
}
}
//remove ID from array
- if (isset($crumbs[$ID])) {
+ if(isset($crumbs[$ID])) {
unset($crumbs[$ID]);
}
//add to array
$crumbs[$ID] = $name;
//reduce size
- while(count($crumbs) > $conf['breadcrumbs']){
+ while(count($crumbs) > $conf['breadcrumbs']) {
array_shift($crumbs);
}
//save to session
@@ -318,18 +315,19 @@ function breadcrumbs(){
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function idfilter($id,$ue=true){
+function idfilter($id, $ue = true) {
global $conf;
- if ($conf['useslash'] && $conf['userewrite']){
- $id = strtr($id,':','/');
- }elseif (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' &&
- $conf['userewrite']) {
- $id = strtr($id,':',';');
- }
- if($ue){
+ if($conf['useslash'] && $conf['userewrite']) {
+ $id = strtr($id, ':', '/');
+ } elseif(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' &&
+ $conf['userewrite']
+ ) {
+ $id = strtr($id, ':', ';');
+ }
+ if($ue) {
$id = rawurlencode($id);
- $id = str_replace('%3A',':',$id); //keep as colon
- $id = str_replace('%2F','/',$id); //keep as slash
+ $id = str_replace('%3A', ':', $id); //keep as colon
+ $id = str_replace('%2F', '/', $id); //keep as slash
}
return $id;
}
@@ -342,33 +340,33 @@ function idfilter($id,$ue=true){
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function wl($id='',$urlParameters='',$absolute=false,$separator='&amp;'){
+function wl($id = '', $urlParameters = '', $absolute = false, $separator = '&amp;') {
global $conf;
- if(is_array($urlParameters)){
- $urlParameters = buildURLparams($urlParameters,$separator);
- }else{
- $urlParameters = str_replace(',',$separator,$urlParameters);
+ if(is_array($urlParameters)) {
+ $urlParameters = buildURLparams($urlParameters, $separator);
+ } else {
+ $urlParameters = str_replace(',', $separator, $urlParameters);
}
- if ($id === '') {
+ if($id === '') {
$id = $conf['start'];
}
$id = idfilter($id);
- if($absolute){
+ if($absolute) {
$xlink = DOKU_URL;
- }else{
+ } else {
$xlink = DOKU_BASE;
}
- if($conf['userewrite'] == 2){
+ if($conf['userewrite'] == 2) {
$xlink .= DOKU_SCRIPT.'/'.$id;
if($urlParameters) $xlink .= '?'.$urlParameters;
- }elseif($conf['userewrite']){
+ } elseif($conf['userewrite']) {
$xlink .= $id;
if($urlParameters) $xlink .= '?'.$urlParameters;
- }elseif($id){
+ } elseif($id) {
$xlink .= DOKU_SCRIPT.'?id='.$id;
if($urlParameters) $xlink .= $separator.$urlParameters;
- }else{
+ } else {
$xlink .= DOKU_SCRIPT;
if($urlParameters) $xlink .= '?'.$urlParameters;
}
@@ -383,29 +381,29 @@ function wl($id='',$urlParameters='',$absolute=false,$separator='&amp;'){
*
* @author Ben Coburn <btcoburn@silicodon.net>
*/
-function exportlink($id='',$format='raw',$more='',$abs=false,$sep='&amp;'){
+function exportlink($id = '', $format = 'raw', $more = '', $abs = false, $sep = '&amp;') {
global $conf;
- if(is_array($more)){
- $more = buildURLparams($more,$sep);
- }else{
- $more = str_replace(',',$sep,$more);
+ if(is_array($more)) {
+ $more = buildURLparams($more, $sep);
+ } else {
+ $more = str_replace(',', $sep, $more);
}
$format = rawurlencode($format);
- $id = idfilter($id);
- if($abs){
+ $id = idfilter($id);
+ if($abs) {
$xlink = DOKU_URL;
- }else{
+ } else {
$xlink = DOKU_BASE;
}
- if($conf['userewrite'] == 2){
+ if($conf['userewrite'] == 2) {
$xlink .= DOKU_SCRIPT.'/'.$id.'?do=export_'.$format;
if($more) $xlink .= $sep.$more;
- }elseif($conf['userewrite'] == 1){
+ } elseif($conf['userewrite'] == 1) {
$xlink .= '_export/'.$format.'/'.$id;
if($more) $xlink .= '?'.$more;
- }else{
+ } else {
$xlink .= DOKU_SCRIPT.'?do=export_'.$format.$sep.'id='.$id;
if($more) $xlink .= $sep.$more;
}
@@ -421,42 +419,43 @@ function exportlink($id='',$format='raw',$more='',$abs=false,$sep='&amp;'){
* The $more parameter should always be given as array, the function then
* will strip default parameters to produce even cleaner URLs
*
- * @param string $id - the media file id or URL
- * @param mixed $more - string or array with additional parameters
- * @param boolean $direct - link to detail page if false
- * @param string $sep - URL parameter separator
- * @param boolean $abs - Create an absolute URL
+ * @param string $id the media file id or URL
+ * @param mixed $more string or array with additional parameters
+ * @param bool $direct link to detail page if false
+ * @param string $sep URL parameter separator
+ * @param bool $abs Create an absolute URL
+ * @return string
*/
-function ml($id='',$more='',$direct=true,$sep='&amp;',$abs=false){
+function ml($id = '', $more = '', $direct = true, $sep = '&amp;', $abs = false) {
global $conf;
- if(is_array($more)){
+ if(is_array($more)) {
// strip defaults for shorter URLs
if(isset($more['cache']) && $more['cache'] == 'cache') unset($more['cache']);
if(!$more['w']) unset($more['w']);
if(!$more['h']) unset($more['h']);
if(isset($more['id']) && $direct) unset($more['id']);
- $more = buildURLparams($more,$sep);
- }else{
- $more = str_replace('cache=cache','',$more); //skip default
- $more = str_replace(',,',',',$more);
- $more = str_replace(',',$sep,$more);
+ $more = buildURLparams($more, $sep);
+ } else {
+ $more = str_replace('cache=cache', '', $more); //skip default
+ $more = str_replace(',,', ',', $more);
+ $more = str_replace(',', $sep, $more);
}
- if($abs){
+ if($abs) {
$xlink = DOKU_URL;
- }else{
+ } else {
$xlink = DOKU_BASE;
}
// external URLs are always direct without rewriting
- if(preg_match('#^(https?|ftp)://#i',$id)){
+ if(preg_match('#^(https?|ftp)://#i', $id)) {
$xlink .= 'lib/exe/fetch.php';
// add hash:
- $xlink .= '?hash='.substr(md5(auth_cookiesalt().$id),0,6);
- if($more){
+ $xlink .= '?hash='.substr(md5(auth_cookiesalt().$id), 0, 6);
+ if($more) {
$xlink .= $sep.$more;
$xlink .= $sep.'media='.rawurlencode($id);
- }else{
+ } else {
$xlink .= $sep.'media='.rawurlencode($id);
}
return $xlink;
@@ -465,29 +464,29 @@ function ml($id='',$more='',$direct=true,$sep='&amp;',$abs=false){
$id = idfilter($id);
// decide on scriptname
- if($direct){
- if($conf['userewrite'] == 1){
+ if($direct) {
+ if($conf['userewrite'] == 1) {
$script = '_media';
- }else{
+ } else {
$script = 'lib/exe/fetch.php';
}
- }else{
- if($conf['userewrite'] == 1){
+ } else {
+ if($conf['userewrite'] == 1) {
$script = '_detail';
- }else{
+ } else {
$script = 'lib/exe/detail.php';
}
}
// build URL based on rewrite mode
- if($conf['userewrite']){
+ if($conf['userewrite']) {
$xlink .= $script.'/'.$id;
if($more) $xlink .= '?'.$more;
- }else{
- if($more){
+ } else {
+ if($more) {
$xlink .= $script.'?'.$more;
$xlink .= $sep.'media='.$id;
- }else{
+ } else {
$xlink .= $script.'?media='.$id;
}
}
@@ -495,15 +494,13 @@ function ml($id='',$more='',$direct=true,$sep='&amp;',$abs=false){
return $xlink;
}
-
-
/**
* Just builds a link to a script
*
* @todo maybe obsolete
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function script($script='doku.php'){
+function script($script = 'doku.php') {
return DOKU_BASE.DOKU_SCRIPT;
}
@@ -531,7 +528,7 @@ function script($script='doku.php'){
* @param string $text - optional text to check, if not given the globals are used
* @return bool - true if a spam word was found
*/
-function checkwordblock($text=''){
+function checkwordblock($text = '') {
global $TEXT;
global $PRE;
global $SUF;
@@ -543,32 +540,32 @@ function checkwordblock($text=''){
if(!$text) $text = "$PRE $TEXT $SUF";
// we prepare the text a tiny bit to prevent spammers circumventing URL checks
- $text = preg_replace('!(\b)(www\.[\w.:?\-;,]+?\.[\w.:?\-;,]+?[\w/\#~:.?+=&%@\!\-.:?\-;,]+?)([.:?\-;,]*[^\w/\#~:.?+=&%@\!\-.:?\-;,])!i','\1http://\2 \2\3',$text);
+ $text = preg_replace('!(\b)(www\.[\w.:?\-;,]+?\.[\w.:?\-;,]+?[\w/\#~:.?+=&%@\!\-.:?\-;,]+?)([.:?\-;,]*[^\w/\#~:.?+=&%@\!\-.:?\-;,])!i', '\1http://\2 \2\3', $text);
$wordblocks = getWordblocks();
// how many lines to read at once (to work around some PCRE limits)
- if(version_compare(phpversion(),'4.3.0','<')){
+ if(version_compare(phpversion(), '4.3.0', '<')) {
// old versions of PCRE define a maximum of parenthesises even if no
// backreferences are used - the maximum is 99
// this is very bad performancewise and may even be too high still
$chunksize = 40;
- }else{
+ } else {
// read file in chunks of 200 - this should work around the
// MAX_PATTERN_SIZE in modern PCRE
$chunksize = 200;
}
- while($blocks = array_splice($wordblocks,0,$chunksize)){
+ while($blocks = array_splice($wordblocks, 0, $chunksize)) {
$re = array();
// build regexp from blocks
- foreach($blocks as $block){
- $block = preg_replace('/#.*$/','',$block);
+ foreach($blocks as $block) {
+ $block = preg_replace('/#.*$/', '', $block);
$block = trim($block);
if(empty($block)) continue;
- $re[] = $block;
+ $re[] = $block;
}
- if(count($re) && preg_match('#('.join('|',$re).')#si',$text,$matches)) {
+ if(count($re) && preg_match('#('.join('|', $re).')#si', $text, $matches)) {
// prepare event data
- $data['matches'] = $matches;
+ $data['matches'] = $matches;
$data['userinfo']['ip'] = $_SERVER['REMOTE_ADDR'];
if($_SERVER['REMOTE_USER']) {
$data['userinfo']['user'] = $_SERVER['REMOTE_USER'];
@@ -592,42 +589,43 @@ function checkwordblock($text=''){
* a routable public address, prefering the ones suplied in the X
* headers
*
- * @param boolean $single If set only a single IP is returned
* @author Andreas Gohr <andi@splitbrain.org>
+ * @param boolean $single If set only a single IP is returned
+ * @return string
*/
-function clientIP($single=false){
- $ip = array();
+function clientIP($single = false) {
+ $ip = array();
$ip[] = $_SERVER['REMOTE_ADDR'];
if(!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
- $ip = array_merge($ip,explode(',',str_replace(' ','',$_SERVER['HTTP_X_FORWARDED_FOR'])));
+ $ip = array_merge($ip, explode(',', str_replace(' ', '', $_SERVER['HTTP_X_FORWARDED_FOR'])));
if(!empty($_SERVER['HTTP_X_REAL_IP']))
- $ip = array_merge($ip,explode(',',str_replace(' ','',$_SERVER['HTTP_X_REAL_IP'])));
+ $ip = array_merge($ip, explode(',', str_replace(' ', '', $_SERVER['HTTP_X_REAL_IP'])));
// some IPv4/v6 regexps borrowed from Feyd
// see: http://forums.devnetwork.net/viewtopic.php?f=38&t=53479
- $dec_octet = '(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|[0-9])';
- $hex_digit = '[A-Fa-f0-9]';
- $h16 = "{$hex_digit}{1,4}";
+ $dec_octet = '(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|[0-9])';
+ $hex_digit = '[A-Fa-f0-9]';
+ $h16 = "{$hex_digit}{1,4}";
$IPv4Address = "$dec_octet\\.$dec_octet\\.$dec_octet\\.$dec_octet";
- $ls32 = "(?:$h16:$h16|$IPv4Address)";
+ $ls32 = "(?:$h16:$h16|$IPv4Address)";
$IPv6Address =
"(?:(?:{$IPv4Address})|(?:".
- "(?:$h16:){6}$ls32" .
- "|::(?:$h16:){5}$ls32" .
- "|(?:$h16)?::(?:$h16:){4}$ls32" .
- "|(?:(?:$h16:){0,1}$h16)?::(?:$h16:){3}$ls32" .
- "|(?:(?:$h16:){0,2}$h16)?::(?:$h16:){2}$ls32" .
- "|(?:(?:$h16:){0,3}$h16)?::(?:$h16:){1}$ls32" .
- "|(?:(?:$h16:){0,4}$h16)?::$ls32" .
- "|(?:(?:$h16:){0,5}$h16)?::$h16" .
- "|(?:(?:$h16:){0,6}$h16)?::" .
- ")(?:\\/(?:12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))?)";
+ "(?:$h16:){6}$ls32".
+ "|::(?:$h16:){5}$ls32".
+ "|(?:$h16)?::(?:$h16:){4}$ls32".
+ "|(?:(?:$h16:){0,1}$h16)?::(?:$h16:){3}$ls32".
+ "|(?:(?:$h16:){0,2}$h16)?::(?:$h16:){2}$ls32".
+ "|(?:(?:$h16:){0,3}$h16)?::(?:$h16:){1}$ls32".
+ "|(?:(?:$h16:){0,4}$h16)?::$ls32".
+ "|(?:(?:$h16:){0,5}$h16)?::$h16".
+ "|(?:(?:$h16:){0,6}$h16)?::".
+ ")(?:\\/(?:12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))?)";
// remove any non-IP stuff
- $cnt = count($ip);
+ $cnt = count($ip);
$match = array();
- for($i=0; $i<$cnt; $i++){
- if(preg_match("/^$IPv4Address$/",$ip[$i],$match) || preg_match("/^$IPv6Address$/",$ip[$i],$match)) {
+ for($i = 0; $i < $cnt; $i++) {
+ if(preg_match("/^$IPv4Address$/", $ip[$i], $match) || preg_match("/^$IPv6Address$/", $ip[$i], $match)) {
$ip[$i] = $match[0];
} else {
$ip[$i] = '';
@@ -637,14 +635,14 @@ function clientIP($single=false){
$ip = array_values(array_unique($ip));
if(!$ip[0]) $ip[0] = '0.0.0.0'; // for some strange reason we don't have a IP
- if(!$single) return join(',',$ip);
+ if(!$single) return join(',', $ip);
// decide which IP to use, trying to avoid local addresses
$ip = array_reverse($ip);
- foreach($ip as $i){
- if(preg_match('/^(::1|[fF][eE]80:|127\.|10\.|192\.168\.|172\.((1[6-9])|(2[0-9])|(3[0-1]))\.)/',$i)){
+ foreach($ip as $i) {
+ if(preg_match('/^(::1|[fF][eE]80:|127\.|10\.|192\.168\.|172\.((1[6-9])|(2[0-9])|(3[0-1]))\.)/', $i)) {
continue;
- }else{
+ } else {
return $i;
}
}
@@ -659,42 +657,42 @@ function clientIP($single=false){
*
* @link http://www.brainhandles.com/2007/10/15/detecting-mobile-browsers/#code
*/
-function clientismobile(){
+function clientismobile() {
if(isset($_SERVER['HTTP_X_WAP_PROFILE'])) return true;
- if(preg_match('/wap\.|\.wap/i',$_SERVER['HTTP_ACCEPT'])) return true;
+ if(preg_match('/wap\.|\.wap/i', $_SERVER['HTTP_ACCEPT'])) return true;
if(!isset($_SERVER['HTTP_USER_AGENT'])) return false;
$uamatches = 'midp|j2me|avantg|docomo|novarra|palmos|palmsource|240x320|opwv|chtml|pda|windows ce|mmp\/|blackberry|mib\/|symbian|wireless|nokia|hand|mobi|phone|cdm|up\.b|audio|SIE\-|SEC\-|samsung|HTC|mot\-|mitsu|sagem|sony|alcatel|lg|erics|vx|NEC|philips|mmm|xx|panasonic|sharp|wap|sch|rover|pocket|benq|java|pt|pg|vox|amoi|bird|compal|kg|voda|sany|kdd|dbt|sendo|sgh|gradi|jb|\d\d\di|moto';
- if(preg_match("/$uamatches/i",$_SERVER['HTTP_USER_AGENT'])) return true;
+ if(preg_match("/$uamatches/i", $_SERVER['HTTP_USER_AGENT'])) return true;
return false;
}
-
/**
* Convert one or more comma separated IPs to hostnames
*
* If $conf['dnslookups'] is disabled it simply returns the input string
*
* @author Glen Harris <astfgl@iamnota.org>
- * @returns a comma separated list of hostnames
+ * @param string $ips comma separated list of IP addresses
+ * @return string a comma separated list of hostnames
*/
-function gethostsbyaddrs($ips){
+function gethostsbyaddrs($ips) {
global $conf;
if(!$conf['dnslookups']) return $ips;
$hosts = array();
- $ips = explode(',',$ips);
+ $ips = explode(',', $ips);
if(is_array($ips)) {
- foreach($ips as $ip){
+ foreach($ips as $ip) {
$hosts[] = gethostbyaddr(trim($ip));
}
- return join(',',$hosts);
+ return join(',', $hosts);
} else {
return gethostbyaddr(trim($ips));
}
@@ -707,7 +705,7 @@ function gethostsbyaddrs($ips){
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function checklock($id){
+function checklock($id) {
global $conf;
$lock = wikiLockFN($id);
@@ -715,14 +713,14 @@ function checklock($id){
if(!@file_exists($lock)) return false;
//lockfile expired
- if((time() - filemtime($lock)) > $conf['locktime']){
+ if((time() - filemtime($lock)) > $conf['locktime']) {
@unlink($lock);
return false;
}
//my own lock
- list($ip,$session) = explode("\n",io_readFile($lock));
- if($ip == $_SERVER['REMOTE_USER'] || $ip == clientIP() || $session == session_id()){
+ list($ip, $session) = explode("\n", io_readFile($lock));
+ if($ip == $_SERVER['REMOTE_USER'] || $ip == clientIP() || $session == session_id()) {
return false;
}
@@ -734,18 +732,18 @@ function checklock($id){
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function lock($id){
+function lock($id) {
global $conf;
- if($conf['locktime'] == 0){
+ if($conf['locktime'] == 0) {
return;
}
$lock = wikiLockFN($id);
- if($_SERVER['REMOTE_USER']){
- io_saveFile($lock,$_SERVER['REMOTE_USER']);
- }else{
- io_saveFile($lock,clientIP()."\n".session_id());
+ if($_SERVER['REMOTE_USER']) {
+ io_saveFile($lock, $_SERVER['REMOTE_USER']);
+ } else {
+ io_saveFile($lock, clientIP()."\n".session_id());
}
}
@@ -753,13 +751,14 @@ function lock($id){
* Unlock a page if it was locked by the user
*
* @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $id page id to unlock
* @return bool true if a lock was removed
*/
-function unlock($id){
+function unlock($id) {
$lock = wikiLockFN($id);
- if(@file_exists($lock)){
- list($ip,$session) = explode("\n",io_readFile($lock));
- if($ip == $_SERVER['REMOTE_USER'] || $ip == clientIP() || $session == session_id()){
+ if(@file_exists($lock)) {
+ list($ip, $session) = explode("\n", io_readFile($lock));
+ if($ip == $_SERVER['REMOTE_USER'] || $ip == clientIP() || $session == session_id()) {
@unlink($lock);
return true;
}
@@ -773,8 +772,8 @@ function unlock($id){
* @see formText() for 2crlf conversion
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function cleanText($text){
- $text = preg_replace("/(\015\012)|(\015)/","\012",$text);
+function cleanText($text) {
+ $text = preg_replace("/(\015\012)|(\015)/", "\012", $text);
return $text;
}
@@ -786,8 +785,8 @@ function cleanText($text){
* @see cleanText() for 2unix conversion
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function formText($text){
- $text = str_replace("\012","\015\012",$text);
+function formText($text) {
+ $text = str_replace("\012", "\015\012", $text);
return htmlspecialchars($text);
}
@@ -796,8 +795,8 @@ function formText($text){
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function rawLocale($id,$ext='txt'){
- return io_readFile(localeFN($id,$ext));
+function rawLocale($id, $ext = 'txt') {
+ return io_readFile(localeFN($id, $ext));
}
/**
@@ -805,7 +804,7 @@ function rawLocale($id,$ext='txt'){
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function rawWiki($id,$rev=''){
+function rawWiki($id, $rev = '') {
return io_readWikiPage(wikiFN($id, $rev), $id, $rev);
}
@@ -815,34 +814,33 @@ function rawWiki($id,$rev=''){
* @triggers COMMON_PAGETPL_LOAD
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function pageTemplate($id){
+function pageTemplate($id) {
global $conf;
- if (is_array($id)) $id = $id[0];
+ if(is_array($id)) $id = $id[0];
// prepare initial event data
$data = array(
- 'id' => $id, // the id of the page to be created
- 'tpl' => '', // the text used as template
- 'tplfile' => '', // the file above text was/should be loaded from
- 'doreplace' => true // should wildcard replacements be done on the text?
+ 'id' => $id, // the id of the page to be created
+ 'tpl' => '', // the text used as template
+ 'tplfile' => '', // the file above text was/should be loaded from
+ 'doreplace' => true // should wildcard replacements be done on the text?
);
- $evt = new Doku_Event('COMMON_PAGETPL_LOAD',$data);
- if($evt->advise_before(true)){
+ $evt = new Doku_Event('COMMON_PAGETPL_LOAD', $data);
+ if($evt->advise_before(true)) {
// the before event might have loaded the content already
- if(empty($data['tpl'])){
+ if(empty($data['tpl'])) {
// if the before event did not set a template file, try to find one
- if(empty($data['tplfile'])){
+ if(empty($data['tplfile'])) {
$path = dirname(wikiFN($id));
- $tpl = '';
- if(@file_exists($path.'/_template.txt')){
+ if(@file_exists($path.'/_template.txt')) {
$data['tplfile'] = $path.'/_template.txt';
- }else{
+ } else {
// search upper namespaces for templates
- $len = strlen(rtrim($conf['datadir'],'/'));
- while (strlen($path) >= $len){
- if(@file_exists($path.'/__template.txt')){
+ $len = strlen(rtrim($conf['datadir'], '/'));
+ while(strlen($path) >= $len) {
+ if(@file_exists($path.'/__template.txt')) {
$data['tplfile'] = $path.'/__template.txt';
break;
}
@@ -868,6 +866,12 @@ function pageTemplate($id){
* @author Andreas Gohr <andi@splitbrain.org>
*/
function parsePageTemplate(&$data) {
+ /**
+ * @var string $id the id of the page to be created
+ * @var string $tpl the text used as template
+ * @var string $tplfile the file above text was/should be loaded from
+ * @var bool $doreplace should wildcard replacements be done on the text?
+ */
extract($data);
global $USERINFO;
@@ -877,39 +881,41 @@ function parsePageTemplate(&$data) {
$file = noNS($id);
$page = strtr($file, $conf['sepchar'], ' ');
- $tpl = str_replace(array(
- '@ID@',
- '@NS@',
- '@FILE@',
- '@!FILE@',
- '@!FILE!@',
- '@PAGE@',
- '@!PAGE@',
- '@!!PAGE@',
- '@!PAGE!@',
- '@USER@',
- '@NAME@',
- '@MAIL@',
- '@DATE@',
- ),
- array(
- $id,
- getNS($id),
- $file,
- utf8_ucfirst($file),
- utf8_strtoupper($file),
- $page,
- utf8_ucfirst($page),
- utf8_ucwords($page),
- utf8_strtoupper($page),
- $_SERVER['REMOTE_USER'],
- $USERINFO['name'],
- $USERINFO['mail'],
- $conf['dformat'],
- ), $tpl);
+ $tpl = str_replace(
+ array(
+ '@ID@',
+ '@NS@',
+ '@FILE@',
+ '@!FILE@',
+ '@!FILE!@',
+ '@PAGE@',
+ '@!PAGE@',
+ '@!!PAGE@',
+ '@!PAGE!@',
+ '@USER@',
+ '@NAME@',
+ '@MAIL@',
+ '@DATE@',
+ ),
+ array(
+ $id,
+ getNS($id),
+ $file,
+ utf8_ucfirst($file),
+ utf8_strtoupper($file),
+ $page,
+ utf8_ucfirst($page),
+ utf8_ucwords($page),
+ utf8_strtoupper($page),
+ $_SERVER['REMOTE_USER'],
+ $USERINFO['name'],
+ $USERINFO['mail'],
+ $conf['dformat'],
+ ), $tpl
+ );
// we need the callback to work around strftime's char limit
- $tpl = preg_replace_callback('/%./',create_function('$m','return strftime($m[0]);'),$tpl);
+ $tpl = preg_replace_callback('/%./', create_function('$m', 'return strftime($m[0]);'), $tpl);
$data['tpl'] = $tpl;
return $tpl;
}
@@ -924,17 +930,17 @@ function parsePageTemplate(&$data) {
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function rawWikiSlices($range,$id,$rev=''){
+function rawWikiSlices($range, $id, $rev = '') {
$text = io_readWikiPage(wikiFN($id, $rev), $id, $rev);
// Parse range
- list($from,$to) = explode('-',$range,2);
+ list($from, $to) = explode('-', $range, 2);
// Make range zero-based, use defaults if marker is missing
$from = !$from ? 0 : ($from - 1);
$to = !$to ? strlen($text) : ($to - 1);
$slices[0] = substr($text, 0, $from);
- $slices[1] = substr($text, $from, $to-$from);
+ $slices[1] = substr($text, $from, $to - $from);
$slices[2] = substr($text, $to);
return $slices;
}
@@ -948,14 +954,16 @@ function rawWikiSlices($range,$id,$rev=''){
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function con($pre,$text,$suf,$pretty=false){
- if($pretty){
- if ($pre !== '' && substr($pre, -1) !== "\n" &&
- substr($text, 0, 1) !== "\n") {
+function con($pre, $text, $suf, $pretty = false) {
+ if($pretty) {
+ if($pre !== '' && substr($pre, -1) !== "\n" &&
+ substr($text, 0, 1) !== "\n"
+ ) {
$pre .= "\n";
}
- if ($suf !== '' && substr($text, -1) !== "\n" &&
- substr($suf, 0, 1) !== "\n") {
+ if($suf !== '' && substr($text, -1) !== "\n" &&
+ substr($suf, 0, 1) !== "\n"
+ ) {
$text .= "\n";
}
}
@@ -970,7 +978,7 @@ function con($pre,$text,$suf,$pretty=false){
* @author Andreas Gohr <andi@splitbrain.org>
* @author Ben Coburn <btcoburn@silicodon.net>
*/
-function saveWikiText($id,$text,$summary,$minor=false){
+function saveWikiText($id, $text, $summary, $minor = false) {
/* Note to developers:
This code is subtle and delicate. Test the behavior of
the attic and changelog with dokuwiki and external edits
@@ -981,31 +989,31 @@ function saveWikiText($id,$text,$summary,$minor=false){
global $lang;
global $REV;
// ignore if no changes were made
- if($text == rawWiki($id,'')){
+ if($text == rawWiki($id, '')) {
return;
}
- $file = wikiFN($id);
- $old = @filemtime($file); // from page
- $wasRemoved = (trim($text) == ''); // check for empty or whitespace only
- $wasCreated = !@file_exists($file);
- $wasReverted = ($REV==true);
- $newRev = false;
- $oldRev = getRevisions($id, -1, 1, 1024); // from changelog
- $oldRev = (int)(empty($oldRev)?0:$oldRev[0]);
- if(!@file_exists(wikiFN($id, $old)) && @file_exists($file) && $old>=$oldRev) {
+ $file = wikiFN($id);
+ $old = @filemtime($file); // from page
+ $wasRemoved = (trim($text) == ''); // check for empty or whitespace only
+ $wasCreated = !@file_exists($file);
+ $wasReverted = ($REV == true);
+ $newRev = false;
+ $oldRev = getRevisions($id, -1, 1, 1024); // from changelog
+ $oldRev = (int) (empty($oldRev) ? 0 : $oldRev[0]);
+ if(!@file_exists(wikiFN($id, $old)) && @file_exists($file) && $old >= $oldRev) {
// add old revision to the attic if missing
saveOldRevision($id);
// add a changelog entry if this edit came from outside dokuwiki
- if ($old>$oldRev) {
- addLogEntry($old, $id, DOKU_CHANGE_TYPE_EDIT, $lang['external_edit'], '', array('ExternalEdit'=>true));
+ if($old > $oldRev) {
+ addLogEntry($old, $id, DOKU_CHANGE_TYPE_EDIT, $lang['external_edit'], '', array('ExternalEdit'=> true));
// remove soon to be stale instructions
$cache = new cache_instructions($id, $file);
$cache->removeCache();
}
}
- if ($wasRemoved){
+ if($wasRemoved) {
// Send "update" event with empty data, so plugins can react to page deletion
$data = array(array($file, '', false), getNS($id), noNS($id), false);
trigger_event('IO_WIKIPAGE_WRITE', $data);
@@ -1024,37 +1032,40 @@ function saveWikiText($id,$text,$summary,$minor=false){
// remove empty namespaces
io_sweepNS($id, 'datadir');
io_sweepNS($id, 'mediadir');
- }else{
+ } else {
// save file (namespace dir is created in io_writeWikiPage)
io_writeWikiPage($file, $text, $id);
// pre-save the revision, to keep the attic in sync
$newRev = saveOldRevision($id);
- $del = false;
+ $del = false;
}
// select changelog line type
$extra = '';
- $type = DOKU_CHANGE_TYPE_EDIT;
- if ($wasReverted) {
- $type = DOKU_CHANGE_TYPE_REVERT;
+ $type = DOKU_CHANGE_TYPE_EDIT;
+ if($wasReverted) {
+ $type = DOKU_CHANGE_TYPE_REVERT;
$extra = $REV;
- }
- else if ($wasCreated) { $type = DOKU_CHANGE_TYPE_CREATE; }
- else if ($wasRemoved) { $type = DOKU_CHANGE_TYPE_DELETE; }
- else if ($minor && $conf['useacl'] && $_SERVER['REMOTE_USER']) { $type = DOKU_CHANGE_TYPE_MINOR_EDIT; } //minor edits only for logged in users
+ } else if($wasCreated) {
+ $type = DOKU_CHANGE_TYPE_CREATE;
+ } else if($wasRemoved) {
+ $type = DOKU_CHANGE_TYPE_DELETE;
+ } else if($minor && $conf['useacl'] && $_SERVER['REMOTE_USER']) {
+ $type = DOKU_CHANGE_TYPE_MINOR_EDIT;
+ } //minor edits only for logged in users
addLogEntry($newRev, $id, $type, $summary, $extra);
// send notify mails
- notify($id,'admin',$old,$summary,$minor);
- notify($id,'subscribers',$old,$summary,$minor);
+ notify($id, 'admin', $old, $summary, $minor);
+ notify($id, 'subscribers', $old, $summary, $minor);
// update the purgefile (timestamp of the last time anything within the wiki was changed)
- io_saveFile($conf['cachedir'].'/purgefile',time());
+ io_saveFile($conf['cachedir'].'/purgefile', time());
// if useheading is enabled, purge the cache of all linking pages
- if(useHeading('content')){
+ if(useHeading('content')) {
$pages = ft_backlinks($id);
- foreach ($pages as $page) {
+ foreach($pages as $page) {
$cache = new cache_renderer($page, wikiFN($page), 'xhtml');
$cache->removeCache();
}
@@ -1067,12 +1078,12 @@ function saveWikiText($id,$text,$summary,$minor=false){
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function saveOldRevision($id){
+function saveOldRevision($id) {
global $conf;
$oldf = wikiFN($id);
if(!@file_exists($oldf)) return '';
$date = filemtime($oldf);
- $newf = wikiFN($id,$date);
+ $newf = wikiFN($id, $date);
io_writeWikiPage($newf, rawWiki($id), $id, $date);
return $date;
}
@@ -1080,72 +1091,75 @@ function saveOldRevision($id){
/**
* Sends a notify mail on page change or registration
*
- * @param string $id The changed page
- * @param string $who Who to notify (admin|subscribers|register)
- * @param int $rev Old page revision
- * @param string $summary What changed
- * @param boolean $minor Is this a minor edit?
- * @param array $replace Additional string substitutions, @KEY@ to be replaced by value
+ * @param string $id The changed page
+ * @param string $who Who to notify (admin|subscribers|register)
+ * @param int|string $rev Old page revision
+ * @param string $summary What changed
+ * @param boolean $minor Is this a minor edit?
+ * @param array $replace Additional string substitutions, @KEY@ to be replaced by value
*
+ * @return bool
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function notify($id,$who,$rev='',$summary='',$minor=false,$replace=array()){
+function notify($id, $who, $rev = '', $summary = '', $minor = false, $replace = array()) {
global $lang;
global $conf;
global $INFO;
global $DIFF_INLINESTYLES;
// decide if there is something to do, eg. whom to mail
- if($who == 'admin'){
- if(empty($conf['notify'])) return; //notify enabled?
+ if($who == 'admin') {
+ if(empty($conf['notify'])) return false; //notify enabled?
$text = rawLocale('mailtext');
$to = $conf['notify'];
$bcc = '';
- }elseif($who == 'subscribers'){
- if(!$conf['subscribers']) return; //subscribers enabled?
- if($conf['useacl'] && $_SERVER['REMOTE_USER'] && $minor) return; //skip minors
+ } elseif($who == 'subscribers') {
+ if(!$conf['subscribers']) return false; //subscribers enabled?
+ if($conf['useacl'] && $_SERVER['REMOTE_USER'] && $minor) return false; //skip minors
$data = array('id' => $id, 'addresslist' => '', 'self' => false);
- trigger_event('COMMON_NOTIFY_ADDRESSLIST', $data,
- 'subscription_addresslist');
+ trigger_event(
+ 'COMMON_NOTIFY_ADDRESSLIST', $data,
+ 'subscription_addresslist'
+ );
$bcc = $data['addresslist'];
- if(empty($bcc)) return;
+ if(empty($bcc)) return false;
$to = '';
$text = rawLocale('subscr_single');
- }elseif($who == 'register'){
- if(empty($conf['registernotify'])) return;
+ } elseif($who == 'register') {
+ if(empty($conf['registernotify'])) return false;
$text = rawLocale('registermail');
$to = $conf['registernotify'];
$bcc = '';
- }else{
- return; //just to be safe
+ } else {
+ return false; //just to be safe
}
// prepare replacements (keys not set in hrep will be taken from trep)
$trep = array(
- 'NEWPAGE' => wl($id,'',true,'&'),
+ 'NEWPAGE' => wl($id, '', true, '&'),
'PAGE' => $id,
'SUMMARY' => $summary
);
- $trep = array_merge($trep,$replace);
+ $trep = array_merge($trep, $replace);
$hrep = array();
// prepare content
- if($who == 'register'){
- $subject = $lang['mail_new_user'].' '.$summary;
- }elseif($rev){
+ if($who == 'register') {
+ $subject = $lang['mail_new_user'].' '.$summary;
+ } elseif($rev) {
$subject = $lang['mail_changed'].' '.$id;
- $trep['OLDPAGE'] = wl($id,"rev=$rev",true,'&');
- $df = new Diff(explode("\n",rawWiki($id,$rev)),
- explode("\n",rawWiki($id)));
+ $trep['OLDPAGE'] = wl($id, "rev=$rev", true, '&');
+ $df = new Diff(explode("\n", rawWiki($id, $rev)),
+ explode("\n", rawWiki($id)));
$dformat = new UnifiedDiffFormatter();
$tdiff = $dformat->format($df);
$DIFF_INLINESTYLES = true;
- $dformat = new InlineDiffFormatter();
- $hdiff = $dformat->format($df);
- $hdiff = '<table>'.$hdiff.'</table>';
+ $dformat = new InlineDiffFormatter();
+ $hdiff = $dformat->format($df);
+ $hdiff = '<table>'.$hdiff.'</table>';
$DIFF_INLINESTYLES = false;
- }else{
+ } else {
$subject = $lang['mail_newpage'].' '.$id;
$trep['OLDPAGE'] = '---';
$tdiff = rawWiki($id);
@@ -1159,11 +1173,11 @@ function notify($id,$who,$rev='',$summary='',$minor=false,$replace=array()){
$mail->to($to);
$mail->bcc($bcc);
$mail->subject($subject);
- $mail->setBody($text,$trep,$hrep);
- if($who == 'subscribers'){
+ $mail->setBody($text, $trep, $hrep);
+ if($who == 'subscribers') {
$mail->setHeader(
'List-Unsubscribe',
- '<'.wl($id,array('do'=>'subscribe'),true,'&').'>',
+ '<'.wl($id, array('do'=> 'subscribe'), true, '&').'>',
false
);
}
@@ -1176,8 +1190,8 @@ function notify($id,$who,$rev='',$summary='',$minor=false,$replace=array()){
* @author Andreas Gohr <andi@splitbrain.org>
* @author Todd Augsburger <todd@rollerorgans.com>
*/
-function getGoogleQuery(){
- if (!isset($_SERVER['HTTP_REFERER'])) {
+function getGoogleQuery() {
+ if(!isset($_SERVER['HTTP_REFERER'])) {
return '';
}
$url = parse_url($_SERVER['HTTP_REFERER']);
@@ -1187,21 +1201,21 @@ function getGoogleQuery(){
// temporary workaround against PHP bug #49733
// see http://bugs.php.net/bug.php?id=49733
if(UTF8_MBSTRING) $enc = mb_internal_encoding();
- parse_str($url['query'],$query);
+ parse_str($url['query'], $query);
if(UTF8_MBSTRING) mb_internal_encoding($enc);
$q = '';
if(isset($query['q']))
- $q = $query['q']; // google, live/msn, aol, ask, altavista, alltheweb, gigablast
+ $q = $query['q']; // google, live/msn, aol, ask, altavista, alltheweb, gigablast
elseif(isset($query['p']))
- $q = $query['p']; // yahoo
+ $q = $query['p']; // yahoo
elseif(isset($query['query']))
- $q = $query['query']; // lycos, netscape, clusty, hotbot
- elseif(preg_match("#a9\.com#i",$url['host'])) // a9
- $q = urldecode(ltrim($url['path'],'/'));
+ $q = $query['query']; // lycos, netscape, clusty, hotbot
+ elseif(preg_match("#a9\.com#i", $url['host'])) // a9
+ $q = urldecode(ltrim($url['path'], '/'));
if($q === '') return '';
- $q = preg_split('/[\s\'"\\\\`()\]\[?:!\.{};,#+*<>\\/]+/',$q,-1,PREG_SPLIT_NO_EMPTY);
+ $q = preg_split('/[\s\'"\\\\`()\]\[?:!\.{};,#+*<>\\/]+/', $q, -1, PREG_SPLIT_NO_EMPTY);
return $q;
}
@@ -1211,19 +1225,19 @@ function getGoogleQuery(){
* @deprecated No longer used
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function setCorrectLocale(){
+function setCorrectLocale() {
global $conf;
global $lang;
$enc = strtoupper($lang['encoding']);
- foreach ($lang['locales'] as $loc){
+ foreach($lang['locales'] as $loc) {
//try locale
- if(@setlocale(LC_ALL,$loc)) return;
+ if(@setlocale(LC_ALL, $loc)) return;
//try loceale with encoding
- if(@setlocale(LC_ALL,"$loc.$enc")) return;
+ if(@setlocale(LC_ALL, "$loc.$enc")) return;
}
//still here? try to set from environment
- @setlocale(LC_ALL,"");
+ @setlocale(LC_ALL, "");
}
/**
@@ -1235,17 +1249,17 @@ function setCorrectLocale(){
* @author Aidan Lister <aidan@php.net>
* @version 1.0.0
*/
-function filesize_h($size, $dec = 1){
+function filesize_h($size, $dec = 1) {
$sizes = array('B', 'KB', 'MB', 'GB');
$count = count($sizes);
- $i = 0;
+ $i = 0;
- while ($size >= 1024 && ($i < $count - 1)) {
+ while($size >= 1024 && ($i < $count - 1)) {
$size /= 1024;
$i++;
}
- return round($size, $dec) . ' ' . $sizes[$i];
+ return round($size, $dec).' '.$sizes[$i];
}
/**
@@ -1253,27 +1267,27 @@ function filesize_h($size, $dec = 1){
*
* @author Andreas Gohr <gohr@cosmocode.de>
*/
-function datetime_h($dt){
+function datetime_h($dt) {
global $lang;
$ago = time() - $dt;
- if($ago > 24*60*60*30*12*2){
- return sprintf($lang['years'], round($ago/(24*60*60*30*12)));
+ if($ago > 24 * 60 * 60 * 30 * 12 * 2) {
+ return sprintf($lang['years'], round($ago / (24 * 60 * 60 * 30 * 12)));
}
- if($ago > 24*60*60*30*2){
- return sprintf($lang['months'], round($ago/(24*60*60*30)));
+ if($ago > 24 * 60 * 60 * 30 * 2) {
+ return sprintf($lang['months'], round($ago / (24 * 60 * 60 * 30)));
}
- if($ago > 24*60*60*7*2){
- return sprintf($lang['weeks'], round($ago/(24*60*60*7)));
+ if($ago > 24 * 60 * 60 * 7 * 2) {
+ return sprintf($lang['weeks'], round($ago / (24 * 60 * 60 * 7)));
}
- if($ago > 24*60*60*2){
- return sprintf($lang['days'], round($ago/(24*60*60)));
+ if($ago > 24 * 60 * 60 * 2) {
+ return sprintf($lang['days'], round($ago / (24 * 60 * 60)));
}
- if($ago > 60*60*2){
- return sprintf($lang['hours'], round($ago/(60*60)));
+ if($ago > 60 * 60 * 2) {
+ return sprintf($lang['hours'], round($ago / (60 * 60)));
}
- if($ago > 60*2){
- return sprintf($lang['minutes'], round($ago/(60)));
+ if($ago > 60 * 2) {
+ return sprintf($lang['minutes'], round($ago / (60)));
}
return sprintf($lang['seconds'], $ago);
}
@@ -1287,15 +1301,15 @@ function datetime_h($dt){
* @see datetime_h
* @author Andreas Gohr <gohr@cosmocode.de>
*/
-function dformat($dt=null,$format=''){
+function dformat($dt = null, $format = '') {
global $conf;
if(is_null($dt)) $dt = time();
$dt = (int) $dt;
if(!$format) $format = $conf['dformat'];
- $format = str_replace('%f',datetime_h($dt),$format);
- return strftime($format,$dt);
+ $format = str_replace('%f', datetime_h($dt), $format);
+ return strftime($format, $dt);
}
/**
@@ -1304,11 +1318,12 @@ function dformat($dt=null,$format=''){
* @author <ungu at terong dot com>
* @link http://www.php.net/manual/en/function.date.php#54072
* @param int $int_date: current date in UNIX timestamp
+ * @return string
*/
function date_iso8601($int_date) {
- $date_mod = date('Y-m-d\TH:i:s', $int_date);
+ $date_mod = date('Y-m-d\TH:i:s', $int_date);
$pre_timezone = date('O', $int_date);
- $time_zone = substr($pre_timezone, 0, 3).":".substr($pre_timezone, 3, 2);
+ $time_zone = substr($pre_timezone, 0, 3).":".substr($pre_timezone, 3, 2);
$date_mod .= $time_zone;
return $date_mod;
}
@@ -1322,16 +1337,16 @@ function date_iso8601($int_date) {
function obfuscate($email) {
global $conf;
- switch ($conf['mailguard']) {
+ switch($conf['mailguard']) {
case 'visible' :
$obfuscate = array('@' => ' [at] ', '.' => ' [dot] ', '-' => ' [dash] ');
return strtr($email, $obfuscate);
case 'hex' :
$encode = '';
- $len = strlen($email);
- for ($x=0; $x < $len; $x++){
- $encode .= '&#x' . bin2hex($email{$x}).';';
+ $len = strlen($email);
+ for($x = 0; $x < $len; $x++) {
+ $encode .= '&#x'.bin2hex($email{$x}).';';
}
return $encode;
@@ -1346,8 +1361,8 @@ function obfuscate($email) {
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function unslash($string,$char="'"){
- return str_replace('\\'.$char,$char,$string);
+function unslash($string, $char = "'") {
+ return str_replace('\\'.$char, $char, $string);
}
/**
@@ -1356,10 +1371,10 @@ function unslash($string,$char="'"){
* @author <gilthans dot NO dot SPAM at gmail dot com>
* @link http://de3.php.net/manual/en/ini.core.php#79564
*/
-function php_to_byte($v){
- $l = substr($v, -1);
+function php_to_byte($v) {
+ $l = substr($v, -1);
$ret = substr($v, 0, -1);
- switch(strtoupper($l)){
+ switch(strtoupper($l)) {
case 'P':
$ret *= 1024;
case 'T':
@@ -1370,10 +1385,10 @@ function php_to_byte($v){
$ret *= 1024;
case 'K':
$ret *= 1024;
- break;
+ break;
default;
$ret *= 10;
- break;
+ break;
}
return $ret;
}
@@ -1381,8 +1396,8 @@ function php_to_byte($v){
/**
* Wrapper around preg_quote adding the default delimiter
*/
-function preg_quote_cb($string){
- return preg_quote($string,'/');
+function preg_quote_cb($string) {
+ return preg_quote($string, '/');
}
/**
@@ -1398,14 +1413,15 @@ function preg_quote_cb($string){
* @param int $max maximum chars you want for the whole string
* @param int $min minimum number of chars to have left for middle shortening
* @param string $char the shortening character to use
+ * @return string
*/
-function shorten($keep,$short,$max,$min=9,$char='…'){
+function shorten($keep, $short, $max, $min = 9, $char = '…') {
$max = $max - utf8_strlen($keep);
if($max < $min) return $keep;
$len = utf8_strlen($short);
if($len <= $max) return $keep.$short;
- $half = floor($max/2);
- return $keep.utf8_substr($short,0,$half-1).$char.utf8_substr($short,$len-$half);
+ $half = floor($max / 2);
+ return $keep.utf8_substr($short, 0, $half - 1).$char.utf8_substr($short, $len - $half);
}
/**
@@ -1414,11 +1430,11 @@ function shorten($keep,$short,$max,$min=9,$char='…'){
*
* @author Andy Webber <dokuwiki AT andywebber DOT com>
*/
-function editorinfo($username){
+function editorinfo($username) {
global $conf;
global $auth;
- switch($conf['showuseras']){
+ switch($conf['showuseras']) {
case 'username':
case 'email':
case 'email_link':
@@ -1429,13 +1445,13 @@ function editorinfo($username){
}
if(isset($info) && $info) {
- switch($conf['showuseras']){
+ switch($conf['showuseras']) {
case 'username':
return hsc($info['name']);
case 'email':
return obfuscate($info['mail']);
case 'email_link':
- $mail=obfuscate($info['mail']);
+ $mail = obfuscate($info['mail']);
return '<a href="mailto:'.$mail.'">'.$mail.'</a>';
default:
return hsc($username);
@@ -1451,20 +1467,21 @@ function editorinfo($username){
*
* @author Andreas Gohr <andi@splitbrain.org>
* @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 +1493,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 <webmaster@illusionsoftworks.cz>
* @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @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 +1509,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 +1530,10 @@ function is_mem_available($mem,$bytes=1048576){
* @link http://support.microsoft.com/kb/q176113/
* @author Andreas Gohr <andi@splitbrain.org>
*/
-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 +1544,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 +1580,14 @@ function send_redirect($url){
* or $_GET)
* @param string $exc The text of the raised exception
*
+ * @throws Exception
+ * @return mixed
* @author Adrian Lang <lang@cosmocode.de>
*/
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 +1598,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/config_cascade.php b/inc/config_cascade.php
index e4a3df353..e1ab0eead 100644
--- a/inc/config_cascade.php
+++ b/inc/config_cascade.php
@@ -50,6 +50,8 @@ $config_cascade = array_merge(
),
'userstyle' => array(
'screen' => DOKU_CONF.'userstyle.css',
+ // @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
'rtl' => DOKU_CONF.'userrtl.css',
'print' => DOKU_CONF.'userprint.css',
'feed' => DOKU_CONF.'userfeed.css',
diff --git a/inc/form.php b/inc/form.php
index e74c52c5d..bdf520a2e 100644
--- a/inc/form.php
+++ b/inc/form.php
@@ -295,8 +295,9 @@ class Doku_Form {
*/
function addRadioSet($name, $entries) {
- $value = (isset($_POST[$name]) && isset($entries[$_POST[$name]])) ?
- $_POST[$name] : key($entries);
+ global $INPUT;
+ $value = (array_key_exists($INPUT->post->str($name), $entries)) ?
+ $INPUT->str($name) : key($entries);
foreach($entries as $val => $cap) {
$data = ($value === $val) ? array('checked' => 'checked') : array();
$this->addElement(form_makeRadioField($name, $val, $cap, '', '', $data));
diff --git a/inc/html.php b/inc/html.php
index be5666353..0afdb1820 100644
--- a/inc/html.php
+++ b/inc/html.php
@@ -46,6 +46,7 @@ function html_login(){
global $lang;
global $conf;
global $ID;
+ global $INPUT;
print p_locale_xhtml('login');
print '<div class="centeralign">'.NL;
@@ -53,7 +54,7 @@ function html_login(){
$form->startFieldset($lang['btn_login']);
$form->addHidden('id', $ID);
$form->addHidden('do', 'login');
- $form->addElement(form_makeTextField('u', ((!$_REQUEST['http_credentials']) ? $_REQUEST['u'] : ''), $lang['user'], 'focus__this', 'block'));
+ $form->addElement(form_makeTextField('u', ((!$INPUT->bool('http_credentials')) ? $INPUT->str('u') : ''), $lang['user'], 'focus__this', 'block'));
$form->addElement(form_makePasswordField('p', $lang['pass'], '', 'block'));
if($conf['rememberme']) {
$form->addElement(form_makeCheckboxField('r', '1', $lang['remember'], 'remember__me', 'simple'));
@@ -229,12 +230,12 @@ function html_show($txt=null){
//PreviewHeader
echo '<br id="scroll__here" />';
echo p_locale_xhtml('preview');
- echo '<div class="preview">';
+ echo '<div class="preview"><div class="pad">';
$html = html_secedit(p_render('xhtml',p_get_instructions($txt),$info),$secedit);
if($INFO['prependTOC']) $html = tpl_toc(true).$html;
echo $html;
echo '<div class="clearer"></div>';
- echo '</div>';
+ echo '</div></div>';
}else{
if ($REV) print p_locale_xhtml('showrev');
@@ -326,11 +327,11 @@ function html_search(){
flush();
//show progressbar
- print '<div class="centeralign" id="dw__loading">'.NL;
- print '<script type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--'.NL;
+ print '<div id="dw__loading">'.NL;
+ print '<script type="text/javascript"><!--//--><![CDATA[//><!--'.NL;
print 'showLoadBar();'.NL;
print '//--><!]]></script>'.NL;
- print '<br /></div>'.NL;
+ print '</div>'.NL;
flush();
//do quick pagesearch
@@ -366,26 +367,30 @@ function html_search(){
//do fulltext search
$data = ft_pageSearch($QUERY,$regex);
if(count($data)){
+ print '<dl class="search_results">';
$num = 1;
foreach($data as $id => $cnt){
- print '<div class="search_result">';
+ print '<dt>';
print html_wikilink(':'.$id,useHeading('navigation')?null:$id,$regex);
if($cnt !== 0){
- print ': <span class="search_cnt">'.$cnt.' '.$lang['hits'].'</span><br />';
+ print ': '.$cnt.' '.$lang['hits'].'';
+ }
+ print '</dt>';
+ if($cnt !== 0){
if($num < FT_SNIPPET_NUMBER){ // create snippets for the first number of matches only
- print '<div class="search_snippet">'.ft_snippet($id,$regex).'</div>';
+ print '<dd>'.ft_snippet($id,$regex).'</dd>';
}
$num++;
}
- print '</div>';
flush();
}
+ print '</dl>';
}else{
print '<div class="nothing">'.$lang['nothingfound'].'</div>';
}
//hide progressbar
- print '<script type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--'.NL;
+ print '<script type="text/javascript"><!--//--><![CDATA[//><!--'.NL;
print 'hideLoadBar("dw__loading");'.NL;
print '//--><!]]></script>'.NL;
flush();
@@ -452,7 +457,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);
@@ -490,7 +495,7 @@ function html_revisions($first=0, $media_id = false){
if (!$media_id) {
$form->addElement(form_makeOpenTag('span', array('class' => 'sum')));
- $form->addElement(' &ndash; ');
+ $form->addElement(' – ');
$form->addElement(htmlspecialchars($INFO['sum']));
$form->addElement(form_makeCloseTag('span'));
}
@@ -569,7 +574,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(' &ndash; ');
+ if (!$media_id) $form->addElement(' – ');
$form->addElement(htmlspecialchars($info['sum']));
$form->addElement(form_makeCloseTag('span'));
}
@@ -667,12 +672,13 @@ function html_recent($first=0, $show_changes='both'){
if (getNS($ID) != '')
print '<div class="level1"><p>' . sprintf($lang['recent_global'], getNS($ID), wl('', 'do=recent')) . '</p></div>';
- $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('<div class="changeType">');
$form->addElement(form_makeListboxField(
'show_changes',
array(
@@ -685,6 +691,7 @@ function html_recent($first=0, $show_changes='both'){
array('class'=>'quickselect')));
$form->addElement(form_makeButton('submit', 'recent', $lang['btn_apply']));
+ $form->addElement('</div>');
}
$form->addElement(form_makeOpenTag('ul'));
@@ -759,7 +766,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(' &ndash; '.htmlspecialchars($recent['sum']));
+ $form->addElement(' – '.htmlspecialchars($recent['sum']));
$form->addElement(form_makeCloseTag('span'));
$form->addElement(form_makeOpenTag('span', array('class' => 'user')));
@@ -1070,8 +1077,9 @@ function html_diff($text='',$intro=true,$type=null){
global $REV;
global $lang;
global $conf;
+ global $INPUT;
- if(!$type) $type = $_REQUEST['difftype'];
+ if(!$type) $type = $INPUT->str('difftype');
if($type != 'inline') $type = 'sidebyside';
// we're trying to be clever here, revisions to compare can be either
@@ -1079,16 +1087,17 @@ function html_diff($text='',$intro=true,$type=null){
// array in rev2.
$rev1 = $REV;
- if(is_array($_REQUEST['rev2'])){
- $rev1 = (int) $_REQUEST['rev2'][0];
- $rev2 = (int) $_REQUEST['rev2'][1];
+ $rev2 = $INPUT->ref('rev2');
+ if(is_array($rev2)){
+ $rev1 = (int) $rev2[0];
+ $rev2 = (int) $rev2[1];
if(!$rev1){
$rev1 = $rev2;
unset($rev2);
}
}else{
- $rev2 = (int) $_REQUEST['rev2'];
+ $rev2 = $INPUT->int('rev2');
}
$r_minor = '';
@@ -1246,6 +1255,7 @@ function html_register(){
global $lang;
global $conf;
global $ID;
+ global $INPUT;
print p_locale_xhtml('register');
print '<div class="centeralign">'.NL;
@@ -1253,13 +1263,13 @@ function html_register(){
$form->startFieldset($lang['btn_register']);
$form->addHidden('do', 'register');
$form->addHidden('save', '1');
- $form->addElement(form_makeTextField('login', $_POST['login'], $lang['user'], '', 'block', array('size'=>'50')));
+ $form->addElement(form_makeTextField('login', $INPUT->post->str('login'), $lang['user'], '', 'block', array('size'=>'50')));
if (!$conf['autopasswd']) {
$form->addElement(form_makePasswordField('pass', $lang['pass'], '', 'block', array('size'=>'50')));
$form->addElement(form_makePasswordField('passchk', $lang['passchk'], '', 'block', array('size'=>'50')));
}
- $form->addElement(form_makeTextField('fullname', $_POST['fullname'], $lang['fullname'], '', 'block', array('size'=>'50')));
- $form->addElement(form_makeTextField('email', $_POST['email'], $lang['email'], '', 'block', array('size'=>'50')));
+ $form->addElement(form_makeTextField('fullname', $INPUT->post->str('fullname'), $lang['fullname'], '', 'block', array('size'=>'50')));
+ $form->addElement(form_makeTextField('email', $INPUT->post->str('email'), $lang['email'], '', 'block', array('size'=>'50')));
$form->addElement(form_makeButton('submit', '', $lang['btn_register']));
$form->endFieldset();
html_form('register', $form);
@@ -1276,26 +1286,27 @@ function html_register(){
function html_updateprofile(){
global $lang;
global $conf;
+ global $INPUT;
global $ID;
global $INFO;
global $auth;
print p_locale_xhtml('updateprofile');
- if (empty($_POST['fullname'])) $_POST['fullname'] = $INFO['userinfo']['name'];
- if (empty($_POST['email'])) $_POST['email'] = $INFO['userinfo']['mail'];
+ $fullname = $INPUT->post->str('fullname', $INFO['userinfo']['name'], true);
+ $email = $INPUT->post->str('email', $INFO['userinfo']['mail'], true);
print '<div class="centeralign">'.NL;
$form = new Doku_Form(array('id' => 'dw__register'));
$form->startFieldset($lang['profile']);
$form->addHidden('do', 'profile');
$form->addHidden('save', '1');
- $form->addElement(form_makeTextField('fullname', $_SERVER['REMOTE_USER'], $lang['user'], '', 'block', array('size'=>'50', 'disabled'=>'disabled')));
+ $form->addElement(form_makeTextField('login', $_SERVER['REMOTE_USER'], $lang['user'], '', 'block', array('size'=>'50', 'disabled'=>'disabled')));
$attr = array('size'=>'50');
if (!$auth->canDo('modName')) $attr['disabled'] = 'disabled';
- $form->addElement(form_makeTextField('fullname', $_POST['fullname'], $lang['fullname'], '', 'block', $attr));
+ $form->addElement(form_makeTextField('fullname', $fullname, $lang['fullname'], '', 'block', $attr));
$attr = array('size'=>'50');
if (!$auth->canDo('modMail')) $attr['disabled'] = 'disabled';
- $form->addElement(form_makeTextField('email', $_POST['email'], $lang['email'], '', 'block', $attr));
+ $form->addElement(form_makeTextField('email', $email, $lang['email'], '', 'block', $attr));
$form->addElement(form_makeTag('br'));
if ($auth->canDo('modPass')) {
$form->addElement(form_makePasswordField('newpass', $lang['newpass'], '', 'block', array('size'=>'50')));
@@ -1320,6 +1331,7 @@ function html_updateprofile(){
* @triggers HTML_EDITFORM_OUTPUT
*/
function html_edit(){
+ global $INPUT;
global $ID;
global $REV;
global $DATE;
@@ -1332,8 +1344,8 @@ function html_edit(){
global $TEXT;
global $RANGE;
- if (isset($_REQUEST['changecheck'])) {
- $check = $_REQUEST['changecheck'];
+ if ($INPUT->has('changecheck')) {
+ $check = $INPUT->str('changecheck');
} elseif(!$INFO['exists']){
// $TEXT has been loaded from page template
$check = md5('');
@@ -1368,8 +1380,8 @@ function html_edit(){
$data = array('form' => $form,
'wr' => $wr,
'media_manager' => true,
- 'target' => (isset($_REQUEST['target']) && $wr &&
- $RANGE !== '') ? $_REQUEST['target'] : 'section',
+ 'target' => ($INPUT->has('target') && $wr &&
+ $RANGE !== '') ? $INPUT->str('target') : 'section',
'intro_locale' => $include);
if ($data['target'] !== 'section') {
@@ -1384,7 +1396,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) {
@@ -1412,17 +1424,16 @@ function html_edit(){
if ($wr) {
// sets changed to true when previewed
- echo '<script type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--'. NL;
+ echo '<script type="text/javascript"><!--//--><![CDATA[//><!--'. NL;
echo 'textChanged = ' . ($mod ? 'true' : 'false');
echo '//--><!]]></script>' . NL;
} ?>
- <div style="width:99%;">
+ <div class="editBox">
<div class="toolbar">
- <div id="draft__status"><?php if(!empty($INFO['draft'])) echo $lang['draftdate'].' '.dformat();?></div>
- <div id="tool__bar"><?php if ($wr && $data['media_manager']){?><a href="<?php echo DOKU_BASE?>lib/exe/mediamanager.php?ns=<?php echo $INFO['namespace']?>"
- target="_blank"><?php echo $lang['mediaselect'] ?></a><?php }?></div>
-
+ <div id="draft__status"><?php if(!empty($INFO['draft'])) echo $lang['draftdate'].' '.dformat();?></div>
+ <div id="tool__bar"><?php if ($wr && $data['media_manager']){?><a href="<?php echo DOKU_BASE?>lib/exe/mediamanager.php?ns=<?php echo $INFO['namespace']?>"
+ target="_blank"><?php echo $lang['mediaselect'] ?></a><?php }?></div>
</div>
<?php
@@ -1456,6 +1467,7 @@ function html_edit_form($param) {
function html_minoredit(){
global $conf;
global $lang;
+ global $INPUT;
// minor edits are for logged in users only
if(!$conf['useacl'] || !$_SERVER['REMOTE_USER']){
return false;
@@ -1463,7 +1475,7 @@ function html_minoredit(){
$p = array();
$p['tabindex'] = 3;
- if(!empty($_REQUEST['minor'])) $p['checked']='checked';
+ if($INPUT->bool('minor')) $p['checked']='checked';
return form_makeCheckboxField('minor', '1', $lang['minoredit'], 'minoredit', 'nowrap', $p);
}
@@ -1669,8 +1681,9 @@ function html_resendpwd() {
global $lang;
global $conf;
global $ID;
+ global $INPUT;
- $token = preg_replace('/[^a-f0-9]+/','',$_REQUEST['pwauth']);
+ $token = preg_replace('/[^a-f0-9]+/','',$INPUT->str('pwauth'));
if(!$conf['autopasswd'] && $token){
print p_locale_xhtml('resetpwd');
@@ -1695,7 +1708,7 @@ function html_resendpwd() {
$form->addHidden('do', 'resendpwd');
$form->addHidden('save', '1');
$form->addElement(form_makeTag('br'));
- $form->addElement(form_makeTextField('login', $_POST['login'], $lang['user'], '', 'block'));
+ $form->addElement(form_makeTextField('login', $INPUT->post->str('login'), $lang['user'], '', 'block'));
$form->addElement(form_makeTag('br'));
$form->addElement(form_makeTag('br'));
$form->addElement(form_makeButton('submit', '', $lang['btn_resendpwd']));
@@ -1714,11 +1727,11 @@ function html_TOC($toc){
if(!count($toc)) return '';
global $lang;
$out = '<!-- TOC START -->'.DOKU_LF;
- $out .= '<div class="toc">'.DOKU_LF;
- $out .= '<div class="tocheader toctoggle" id="toc__header">';
+ $out .= '<div id="dw__toc">'.DOKU_LF;
+ $out .= '<h3 class="toggle">';
$out .= $lang['toc'];
- $out .= '</div>'.DOKU_LF;
- $out .= '<div id="toc__inside">'.DOKU_LF;
+ $out .= '</h3>'.DOKU_LF;
+ $out .= '<div>'.DOKU_LF;
$out .= html_buildlist($toc,'toc','html_list_toc','html_li_default',true);
$out .= '</div>'.DOKU_LF.'</div>'.DOKU_LF;
$out .= '<!-- TOC END -->'.DOKU_LF;
@@ -1735,8 +1748,7 @@ function html_list_toc($item){
$link = $item['link'];
}
- return '<span class="li"><a href="'.$link.'" class="toc">'.
- hsc($item['title']).'</a></span>';
+ return '<a href="'.$link.'">'.hsc($item['title']).'</a>';
}
/**
diff --git a/inc/init.php b/inc/init.php
index 403fbe4ab..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);
}
@@ -197,6 +199,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/lang/bg/lang.php b/inc/lang/bg/lang.php
index 7a246024d..562dc78b3 100644
--- a/inc/lang/bg/lang.php
+++ b/inc/lang/bg/lang.php
@@ -9,8 +9,8 @@
*/
$lang['encoding'] = 'utf-8';
$lang['direction'] = 'ltr';
-$lang['doublequoteopening'] = '“'; //&ldquo;
-$lang['doublequoteclosing'] = '”'; //&rdquo;
+$lang['doublequoteopening'] = '"'; //&ldquo;
+$lang['doublequoteclosing'] = '"'; //&rdquo;
$lang['singlequoteopening'] = '‘'; //&lsquo;
$lang['singlequoteclosing'] = '’'; //&rsquo;
$lang['apostrophe'] = '’'; //&rsquo;
@@ -98,6 +98,7 @@ $lang['searchmedia_in'] = 'Търсене в %s';
$lang['txt_upload'] = 'Изберете файл за качване';
$lang['txt_filename'] = 'Качи като (незадължително)';
$lang['txt_overwrt'] = 'Презапиши съществуващите файлове';
+$lang['maxuploadsize'] = 'Макс. размер за отделните файлове е %s.';
$lang['lockedby'] = 'В момента е заключена от';
$lang['lockexpire'] = 'Ще бъде отключена на';
@@ -161,7 +162,7 @@ $lang['deletefail'] = '"%s" не може да бъде изтрит
$lang['mediainuse'] = 'Файлът "%s" не бе изтрит - все още се ползва.';
$lang['namespaces'] = 'Именни пространства';
$lang['mediafiles'] = 'Налични файлове в';
-$lang['accessdenied'] = 'Нямате разрешение да преглеждате страницата.';
+$lang['accessdenied'] = 'Нямате необходимите права за преглеждане на страницата.';
$lang['mediausage'] = 'Ползвайте следния синтаксис, за да упоменете файла:';
$lang['mediaview'] = 'Преглед на оригиналния файл';
$lang['mediaroot'] = 'root';
@@ -290,7 +291,6 @@ $lang['i_superuser'] = 'Супер потребител';
$lang['i_problems'] = 'Открити са проблеми, които възпрепятстват инсталирането. Ще можете да продължите след като отстраните долуизброените проблеми.';
$lang['i_modified'] = 'Поради мерки за сигурност инсталаторът работи само с нови и непроменени инсталационни файлове.
Трябва да разархивирате отново файловете от сваления архив или да се посъветвате с <a href="http://dokuwiki.org/install">Инструкциите за инсталиране на Dokuwiki</a>.';
-
$lang['i_funcna'] = 'PHP функцията <code>%s</code> не е достъпна. Може би е забранена от доставчика на хостинг.';
$lang['i_phpver'] = 'Инсталираната версия <code>%s</code> на PHP е по-стара от необходимата <code>%s</code>. Актуализирайте PHP инсталацията.';
$lang['i_permfail'] = '<code>%s</code> не е достъпна за писане от DokuWiki. Трябва да промените правата за достъп до директорията!';
diff --git a/inc/lang/bg/mailtext.txt b/inc/lang/bg/mailtext.txt
index ad0024a8d..a5f0cbd92 100644
--- a/inc/lang/bg/mailtext.txt
+++ b/inc/lang/bg/mailtext.txt
@@ -1,4 +1,4 @@
-Страница във DokuWiki е добавена или променена. Ето детайлите:
+Страница в DokuWiki е добавена или променена. Ето детайлите:
Дата : @DATE@
Браузър : @BROWSER@
diff --git a/inc/lang/bg/mailwrap.html b/inc/lang/bg/mailwrap.html
new file mode 100644
index 000000000..26b0a1e6a
--- /dev/null
+++ b/inc/lang/bg/mailwrap.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+ <title>@TITLE@</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+</head>
+<body>
+
+@HTMLBODY@
+
+<br /><hr />
+<small>Писмото е генерирано от DokuWiki на адрес @DOKUWIKIURL@.</small>
+</body>
+</html>
diff --git a/inc/lang/de-informal/lang.php b/inc/lang/de-informal/lang.php
index 61e5ef3d8..37469522f 100644
--- a/inc/lang/de-informal/lang.php
+++ b/inc/lang/de-informal/lang.php
@@ -16,7 +16,7 @@
* @author Alexander Fischer <tbanus@os-forge.net>
* @author Juergen Schwarzer <jschwarzer@freenet.de>
* @author Marcel Metz <marcel_metz@gmx.de>
- * @author Matthias Schulte <mailinglist@lupo49.de>
+ * @author Matthias Schulte <dokuwiki@lupo49.de>
* @author Christian Wichmann <nospam@zone0.de>
* @author Pierre Corell <info@joomla-praxis.de>
*/
@@ -104,6 +104,7 @@ $lang['searchmedia_in'] = 'Suche in %s';
$lang['txt_upload'] = 'Datei zum Hochladen auswählen';
$lang['txt_filename'] = 'Hochladen als (optional)';
$lang['txt_overwrt'] = 'Bestehende Datei überschreiben';
+$lang['maxuploadsize'] = 'Max. %s pro Datei-Upload.';
$lang['lockedby'] = 'Momentan gesperrt von';
$lang['lockexpire'] = 'Sperre läuft ab am';
$lang['js']['willexpire'] = 'Die Sperre zur Bearbeitung dieser Seite läuft in einer Minute ab.\nUm Bearbeitungskonflikte zu vermeiden, solltest du sie durch einen Klick auf den Vorschau-Knopf verlängern.';
@@ -196,6 +197,11 @@ $lang['external_edit'] = 'Externe Bearbeitung';
$lang['summary'] = 'Zusammenfassung';
$lang['noflash'] = 'Das <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> wird benötigt, um diesen Inhalt anzuzeigen.';
$lang['download'] = 'Download-Teil';
+$lang['tools'] = 'Werkzeuge';
+$lang['user_tools'] = 'Benutzer-Werkzeuge';
+$lang['site_tools'] = 'Webseiten-Werkzeuge';
+$lang['page_tools'] = 'Seiten-Werkzeuge';
+$lang['skip_to_content'] = 'zum Inhalt springen';
$lang['mail_newpage'] = 'Neue Seite:';
$lang['mail_changed'] = 'Seite geändert:';
$lang['mail_subscribe_list'] = 'Seite hat sich im Namespace geändert:';
@@ -248,13 +254,13 @@ $lang['img_keywords'] = 'Schlagwörter';
$lang['img_width'] = 'Breite';
$lang['img_height'] = 'Höhe';
$lang['img_manager'] = 'Im Medien-Manager anzeigen';
-$lang['subscr_subscribe_success'] = 'Die Seite %s wurde zur Abonnementenliste von %s hinzugefügt';
-$lang['subscr_subscribe_error'] = 'Fehler beim Hinzufügen von %s zur Abonnementenliste von %s';
+$lang['subscr_subscribe_success'] = 'Die Seite %s wurde zur Abonnementliste von %s hinzugefügt';
+$lang['subscr_subscribe_error'] = 'Fehler beim Hinzufügen von %s zur Abonnementliste von %s';
$lang['subscr_subscribe_noaddress'] = 'In deinem Account ist keine E-Mail-Adresse hinterlegt. Dadurch kann die Seite nicht abonniert werden';
-$lang['subscr_unsubscribe_success'] = 'Die Seite %s wurde von der Abonnementenliste von %s entfernt';
-$lang['subscr_unsubscribe_error'] = 'Fehler beim Entfernen von %s von der Abonnementenliste von %s';
-$lang['subscr_already_subscribed'] = '%s ist bereits auf der Abonnementenliste von %s';
-$lang['subscr_not_subscribed'] = '%s ist nicht auf der Abonnementenliste von %s';
+$lang['subscr_unsubscribe_success'] = 'Die Seite %s wurde von der Abonnementliste von %s entfernt';
+$lang['subscr_unsubscribe_error'] = 'Fehler beim Entfernen von %s von der Abonnementliste von %s';
+$lang['subscr_already_subscribed'] = '%s ist bereits auf der Abonnementliste von %s';
+$lang['subscr_not_subscribed'] = '%s ist nicht auf der Abonnementliste von %s';
$lang['subscr_m_not_subscribed'] = 'Du hast kein Abonnement von dieser Seite oder dem Namensraum.';
$lang['subscr_m_new_header'] = 'Abonnementen hinzufügen';
$lang['subscr_m_current_header'] = 'Aktive Abonnements';
@@ -266,6 +272,7 @@ $lang['subscr_style_digest'] = 'E-Mail mit zusammengefasster Übersicht der Se
$lang['subscr_style_list'] = 'Auflistung aller geänderten Seiten seit der letzten E-Mail (alle %.2f Tage)';
$lang['authmodfailed'] = 'Benutzerüberprüfung nicht möglich. Bitte wende dich an den Admin.';
$lang['authtempfail'] = 'Benutzerüberprüfung momentan nicht möglich. Falls das Problem andauert, wende dich an den Admin.';
+$lang['authpwdexpire'] = 'Dein Passwort läuft in %d Tag(en) ab, du solltest es es bald ändern.';
$lang['i_chooselang'] = 'Wähle deine Sprache';
$lang['i_installer'] = 'DokuWiki-Installation';
$lang['i_wikiname'] = 'Wiki-Name';
diff --git a/inc/lang/de-informal/mailwrap.html b/inc/lang/de-informal/mailwrap.html
new file mode 100644
index 000000000..420fdf83e
--- /dev/null
+++ b/inc/lang/de-informal/mailwrap.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+ <title>@TITLE@</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+</head>
+<body>
+
+@HTMLBODY@
+
+<br /><hr />
+<small>Diese Mail kommt vom DokuWiki auf @DOKUWIKIURL@.</small>
+</body>
+</html>
diff --git a/inc/lang/de-informal/resetpwd.txt b/inc/lang/de-informal/resetpwd.txt
new file mode 100644
index 000000000..8423bd801
--- /dev/null
+++ b/inc/lang/de-informal/resetpwd.txt
@@ -0,0 +1,4 @@
+====== Neues Passwort setzen ======
+
+Bitte gib ein neues Passwort für deinen Wiki-Zugang ein.
+
diff --git a/inc/lang/de/lang.php b/inc/lang/de/lang.php
index cfbe04396..4ea75157b 100644
--- a/inc/lang/de/lang.php
+++ b/inc/lang/de/lang.php
@@ -106,6 +106,7 @@ $lang['searchmedia_in'] = 'Suche in %s';
$lang['txt_upload'] = 'Datei zum Hochladen auswählen';
$lang['txt_filename'] = 'Hochladen als (optional)';
$lang['txt_overwrt'] = 'Bestehende Datei überschreiben';
+$lang['maxuploadsize'] = 'Max. %s pro Datei-Upload.';
$lang['lockedby'] = 'Momentan gesperrt von';
$lang['lockexpire'] = 'Sperre läuft ab am';
$lang['js']['willexpire'] = 'Die Sperre zur Bearbeitung dieser Seite läuft in einer Minute ab.\nUm Bearbeitungskonflikte zu vermeiden, sollten Sie sie durch einen Klick auf den Vorschau-Knopf verlängern.';
diff --git a/inc/lang/de/mailwrap.html b/inc/lang/de/mailwrap.html
new file mode 100644
index 000000000..420fdf83e
--- /dev/null
+++ b/inc/lang/de/mailwrap.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+ <title>@TITLE@</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+</head>
+<body>
+
+@HTMLBODY@
+
+<br /><hr />
+<small>Diese Mail kommt vom DokuWiki auf @DOKUWIKIURL@.</small>
+</body>
+</html>
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 @@
<p>현재 설치 과정중에 관리자로 로그인 후 DokuWiki의 관리 메뉴(플러그인 설치, 사용자 관리, 위키 문서 접근 권한 관리, 옵션 설정)를 가능하게 <acronym title="접근 제어 목록">ACL</acronym>에 대한 환경 설정을 수행합니다.
이 것은 DokuWiki가 동작하는데 필요한 사항은 아니지만, 어쨌든 더 쉽게 관리자가 관리할 수 있도록 해줍니다.</p>
-<p>숙련된 사용자들이나 특별한 설치 과정이 필요한 경우에 다음 링크들을 참고하기 바랍니다:
-<a href="http://dokuwiki.org/ko:install">설치 과정(한국어)</a>
-과 <a href="http://dokuwiki.org/ko:config">환경 설정(한국어),</a>
-<a href="http://dokuwiki.org/install">설치 과정(영어)</a>
-과 <a href="http://dokuwiki.org/config">환경 설정(영어)</a></p>
+<p>숙련된 사용자나 특별한 설치 과정이 필요한 경우에 다음 링크를 참고하기 바랍니다:
+<a href="http://dokuwiki.org/ko:install">설치 과정 (한국어)</a>
+과 <a href="http://dokuwiki.org/ko:config">환경 설정 (한국어),</a>
+<a href="http://dokuwiki.org/install">설치 과정 (영어)</a>
+과 <a href="http://dokuwiki.org/config">환경 설정 (영어)</a></p>
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'] = '이 컨텐츠를 표시하기 위해서 <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash 플러그인</a>이 필요합니다.';
+$lang['noflash'] = '이 콘텐츠를 표시하기 위해서 <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash 플러그인</a>이 필요합니다.';
$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'] = '<b>%s</b> 이름공간을 구독 중입니다. <a href="%s">전체 위키 최근 바뀜도 볼 수</a> 있습니다.';
-$lang['years'] = '%d 년 전';
-$lang['months'] = '%d 개월 전';
-$lang['weeks'] = '%d 주 전';
-$lang['days'] = '%d 일 전';
-$lang['hours'] = '%d 시간 전';
-$lang['minutes'] = '%d 분 전';
-$lang['seconds'] = '%d 초 전';
+$lang['recent_global'] = '<b>%s</b> 이름공간을 구독 중입니다. <a href="%s">전체 위키의 최근 바뀜도 볼 수</a> 있습니다.';
+$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/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 <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> 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 @@
+<html>
+ <head>
+ <title>@TITLE@</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ </head>
+ <body>
+
+ @HTMLBODY@
+
+ <br /><hr />
+ <small>Deze mail is gegenereerd door DokuWiki op @DOKUWIKIURL@.</small>
+ </body>
+ </html> \ No newline at end of file
diff --git a/inc/lang/ru/lang.php b/inc/lang/ru/lang.php
index 94af441b7..4c3d26b1d 100644
--- a/inc/lang/ru/lang.php
+++ b/inc/lang/ru/lang.php
@@ -55,6 +55,7 @@ $lang['btn_backtomedia'] = 'Вернуться к выбору медиа
$lang['btn_subscribe'] = 'Подписаться (все правки)';
$lang['btn_profile'] = 'Профиль';
$lang['btn_reset'] = 'Сброс';
+$lang['btn_resendpwd'] = 'Установить новый пароль';
$lang['btn_draft'] = 'Править черновик';
$lang['btn_recover'] = 'Восстановить черновик';
$lang['btn_draftdel'] = 'Удалить черновик';
@@ -91,6 +92,7 @@ $lang['profnoempty'] = 'Логин и адрес электронно
$lang['profchanged'] = 'Профиль пользователя успешно обновлён.';
$lang['pwdforget'] = 'Забыли пароль? Получите новый';
$lang['resendna'] = 'Данная вики не поддерживает повторную отправку пароля.';
+$lang['resendpwd'] = 'Установить новый пароль для';
$lang['resendpwdmissing'] = 'Вы должны заполнить все поля формы.';
$lang['resendpwdnouser'] = 'Пользователь с таким логином не обнаружен в нашей базе данных.';
$lang['resendpwdbadauth'] = 'Извините, неверный код авторизации. Убедитесь, что вы полностью скопировали ссылку. ';
@@ -103,6 +105,7 @@ $lang['searchmedia_in'] = 'Поиск в %s';
$lang['txt_upload'] = 'Выберите файл для загрузки';
$lang['txt_filename'] = 'Введите имя файла в вики (необязательно)';
$lang['txt_overwrt'] = 'Перезаписать существующий файл';
+$lang['maxuploadsize'] = 'Максимальный размер загружаемого файла %s';
$lang['lockedby'] = 'В данный момент заблокирован';
$lang['lockexpire'] = 'Блокировка истекает в';
$lang['js']['willexpire'] = 'Ваша блокировка этой страницы на редактирование истекает в течении минуты.\nЧтобы предотвратить конфликты используйте кнопку "Просмотр" для сброса таймера блокировки.';
@@ -270,6 +273,7 @@ $lang['subscr_style_digest'] = 'сводка изменений по кажд
$lang['subscr_style_list'] = 'перечислять изменившиеся страницы с прошлого уведомления';
$lang['authmodfailed'] = 'Неправильная конфигурация аутентификации пользователя. Пожалуйста, сообщите об этом своему администратору вики.';
$lang['authtempfail'] = 'Аутентификация пользователей временно недоступна. Если проблема продолжается какое-то время, пожалуйста, сообщите об этом своему администратору вики.';
+$lang['authpwdexpire'] = 'Действие вашего пароля истекает через %d дней. Вы должны изменить его как можно скорее';
$lang['i_chooselang'] = 'Выберите свой язык/Choose your language';
$lang['i_installer'] = 'Установка «ДокуВики»';
$lang['i_wikiname'] = 'Название вики';
diff --git a/inc/lang/ru/resetpwd.txt b/inc/lang/ru/resetpwd.txt
new file mode 100644
index 000000000..81a46a7d3
--- /dev/null
+++ b/inc/lang/ru/resetpwd.txt
@@ -0,0 +1,3 @@
+====== Установка нового пароля ======
+
+Пожалуйста введите новый пароль для вашей учетной записи для этой вики.
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 <jdo@myrealbox.com>
*/
-$lang['encoding'] = 'utf-8';
-$lang['direction'] = 'ltr';
+
+
+
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“'; //&ldquo;
+$lang['doublequoteclosing'] = '”'; //&rdquo;
+$lang['singlequoteopening'] = '‘'; //&lsquo;
+$lang['singlequoteclosing'] = '’'; //&rsquo;
+$lang['apostrophe'] = '’'; //&rsquo;
$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'] = '<a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> 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/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',
diff --git a/inc/media.php b/inc/media.php
index 2462a1deb..43bbd2560 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 <pshns@ukr.net>
*/
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('<ul>'.NL);
foreach(array('list' => array('listType', array('thumbs', 'rows')),
@@ -694,9 +698,10 @@ function _media_get_list_type() {
}
function _media_get_display_param($param, $values) {
- if (isset($_REQUEST[$param]) && in_array($_REQUEST[$param], $values)) {
+ global $INPUT;
+ if (in_array($INPUT->str($param), $values)) {
// FIXME: Set cookie
- return $_REQUEST[$param];
+ return $INPUT->str($param);
} else {
$val = get_doku_pref($param, $values['default']);
if (!in_array($val, $values)) {
@@ -746,10 +751,10 @@ function media_tab_upload($ns,$auth=null,$jump='') {
*/
function media_tab_search($ns,$auth=null) {
global $lang;
+ global $INPUT;
- $do = $_REQUEST['mediado'];
- $query = $_REQUEST['q'];
- if (!$query) $query = '';
+ $do = $INPUT->str('mediado');
+ $query = $INPUT->str('q');
echo '<div class="search">'.NL;
media_searchform($ns, $query, true);
@@ -801,14 +806,16 @@ function media_tab_edit($image, $ns, $auth=null) {
*/
function media_tab_history($image, $ns, $auth=null) {
global $lang;
+ global $INPUT;
+
if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*");
- $do = $_REQUEST['mediado'];
+ $do = $INPUT->str('mediado');
if ($auth >= AUTH_READ && $image) {
if ($do == 'diff'){
media_diff($image, $ns, $auth);
} else {
- $first = isset($_REQUEST['first']) ? intval($_REQUEST['first']) : 0;
+ $first = $INPUT->int('first');
html_revisions($first, $image);
}
} else {
@@ -1002,21 +1009,23 @@ function media_details($image, $auth, $rev=false, $meta=false) {
function media_diff($image, $ns, $auth, $fromajax = false) {
global $lang;
global $conf;
+ global $INPUT;
if ($auth < AUTH_READ || !$image || !$conf['mediarevisions']) return '';
- $rev1 = (int) $_REQUEST['rev'];
+ $rev1 = $INPUT->int('rev');
- if(is_array($_REQUEST['rev2'])){
- $rev1 = (int) $_REQUEST['rev2'][0];
- $rev2 = (int) $_REQUEST['rev2'][1];
+ $rev2 = $INPUT->ref('rev2');
+ if(is_array($rev2)){
+ $rev1 = (int) $rev2[0];
+ $rev2 = (int) $rev2[1];
if(!$rev1){
$rev1 = $rev2;
unset($rev2);
}
}else{
- $rev2 = (int) $_REQUEST['rev2'];
+ $rev2 = $INPUT->int('rev2');
}
if ($rev1 && !file_exists(mediaFN($image, $rev1))) $rev1 = false;
@@ -1071,7 +1080,9 @@ function _media_file_diff($data) {
* @author Kate Arzamastseva <pshns@ukr.net>
*/
function media_file_diff($image, $l_rev, $r_rev, $ns, $auth, $fromajax){
- global $lang, $config_cascade;
+ global $lang;
+ global $config_cascade;
+ global $INPUT;
$l_meta = new JpegMeta(mediaFN($image, $l_rev));
$r_meta = new JpegMeta(mediaFN($image, $r_rev));
@@ -1082,7 +1093,7 @@ function media_file_diff($image, $l_rev, $r_rev, $ns, $auth, $fromajax){
$r_size = media_image_preview_size($image, $r_rev, $r_meta);
$is_img = ($l_size && $r_size && ($l_size[0] >= 30 || $r_size[0] >= 30));
- $difftype = $_REQUEST['difftype'];
+ $difftype = $INPUT->str('difftype');
if (!$fromajax) {
$form = new Doku_Form(array(
@@ -1442,7 +1453,7 @@ function media_printfile_thumbs($item,$auth,$jump=false,$display_namespace=false
$size .= (int) $item['meta']->getField('File.Height');
echo '<dd class="size">'.$size.'</dd>'.NL;
} else {
- echo '<dd class="size">&nbsp;</dd>'.NL;
+ echo '<dd class="size">&#160;</dd>'.NL;
}
$date = dformat($item['mtime']);
echo '<dd class="date">'.$date.'</dd>'.NL;
@@ -1527,11 +1538,12 @@ function media_printimgdetail($item, $fullscreen=false){
function media_managerURL($params=false, $amp='&amp;', $abs=false, $params_array=false) {
global $conf;
global $ID;
+ global $INPUT;
$gets = array('do' => 'media');
$media_manager_params = array('tab_files', 'tab_details', 'image', 'ns', 'list', 'sort');
foreach ($media_manager_params as $x) {
- if (isset($_REQUEST[$x])) $gets[$x] = $_REQUEST[$x];
+ if ($INPUT->has($x)) $gets[$x] = $INPUT->str($x);
}
if ($params) {
@@ -1555,7 +1567,9 @@ function media_managerURL($params=false, $amp='&amp;', $abs=false, $params_array
* @author Kate Arzamastseva <pshns@ukr.net>
*/
function media_uploadform($ns, $auth, $fullscreen = false){
- global $lang, $conf;
+ global $lang;
+ global $conf;
+ global $INPUT;
if($auth < AUTH_UPLOAD) {
echo '<div class="nothing">'.$lang['media_perm_upload'].'</div>'.NL;
@@ -1565,9 +1579,9 @@ function media_uploadform($ns, $auth, $fullscreen = false){
$update = false;
$id = '';
- if ($auth >= $auth_ow && $fullscreen && $_REQUEST['mediado'] == 'update') {
+ if ($auth >= $auth_ow && $fullscreen && $INPUT->str('mediado') == 'update') {
$update = true;
- $id = cleanID($_REQUEST['image']);
+ $id = cleanID($INPUT->str('image'));
}
// The default HTML upload form
@@ -1697,12 +1711,13 @@ function media_nstree($ns){
* @author Andreas Gohr <andi@splitbrain.org>
*/
function media_nstree_item($item){
+ global $INPUT;
$pos = strrpos($item['id'], ':');
$label = substr($item['id'], $pos > 0 ? $pos + 1 : 0);
if(!$item['label']) $item['label'] = $label;
$ret = '';
- if (!($_REQUEST['do'] == 'media'))
+ if (!($INPUT->str('do') == 'media'))
$ret .= '<a href="'.DOKU_BASE.'lib/exe/mediamanager.php?ns='.idfilter($item['id']).'" class="idx_dir">';
else $ret .= '<a href="'.media_managerURL(array('ns' => idfilter($item['id'], false), 'tab_files' => 'files'))
.'" class="idx_dir">';
@@ -1723,7 +1738,7 @@ function media_nstree_li($item){
if($item['open']){
$class .= ' open';
$img = DOKU_BASE.'lib/images/minus.gif';
- $alt = '&minus;';
+ $alt = '−';
}else{
$class .= ' closed';
$img = DOKU_BASE.'lib/images/plus.gif';
diff --git a/inc/pageutils.php b/inc/pageutils.php
index c94d14624..5e741c491 100644
--- a/inc/pageutils.php
+++ b/inc/pageutils.php
@@ -19,9 +19,10 @@
* @author Andreas Gohr <andi@splitbrain.org>
*/
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){
@@ -622,3 +623,27 @@ function utf8_decodeFN($file){
return urldecode($file);
}
+/**
+ * Find a page in the current namespace (determined from $ID) or any
+ * higher namespace
+ *
+ * Used for sidebars, but can be used other stuff as well
+ *
+ * @todo add event hook
+ * @param string $page the pagename you're looking for
+ * @return string|false the full page id of the found page, false if any
+ */
+function page_findnearest($page){
+ global $ID;
+
+ $ns = $ID;
+ do {
+ $ns = getNS($ns);
+ $pageid = ltrim("$ns:$page",':');
+ if(page_exists($pageid)){
+ return $pageid;
+ }
+ } while($ns);
+
+ return false;
+}
diff --git a/inc/parser/code.php b/inc/parser/code.php
index 4d94dcf4e..ff44a4e1e 100644
--- a/inc/parser/code.php
+++ b/inc/parser/code.php
@@ -16,11 +16,12 @@ class Doku_Renderer_code extends Doku_Renderer {
* When the correct block was found it exits the script.
*/
function code($text, $language = NULL, $filename='' ) {
+ global $INPUT;
if(!$language) $language = 'txt';
if(!$filename) $filename = 'snippet.'.$language;
$filename = basename($filename);
- if($this->_codeblock == $_REQUEST['codeblock']){
+ if($this->_codeblock == $INPUT->str('codeblock')){
header("Content-Type: text/plain; charset=utf-8");
header("Content-Disposition: attachment; filename=$filename");
header("X-Robots-Tag: noindex");
diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php
index 4345b494f..2f09dbd4f 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 .= '<div class="fn">';
- $this->doc .= '<sup><a href="#fnt__'.$id.'" id="fn__'.$id.'" name="fn__'.$id.'" class="fn_bot">';
+ $this->doc .= '<sup><a href="#fnt__'.$id.'" id="fn__'.$id.'" class="fn_bot">';
$this->doc .= $id.')</a></sup> '.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 .= ', <sup><a href="#fnt__'.($ref+1).'" id="fn__'.($ref+1).'" name="fn__'.($ref+1).'" class="fn_bot">';
+ $this->doc .= ', <sup><a href="#fnt__'.($ref+1).'" id="fn__'.($ref+1).'" class="fn_bot">';
$this->doc .= ($ref+1).')</a></sup> '.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 .= '><a name="'.$hid.'" id="'.$hid.'">';
+ $this->doc .= ' id="'.$hid.'">';
$this->doc .= $this->_xmlEntities($text);
- $this->doc .= "</a></h$level>".DOKU_LF;
+ $this->doc .= "</h$level>".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 .= '<sup><a href="#fn__'.$id.'" name="fnt__'.$id.'" id="fnt__'.$id.'" class="fn_top">'.$id.')</a></sup>';
+ $this->doc .= '<sup><a href="#fn__'.$id.'" id="fnt__'.$id.'" class="fn_top">'.$id.')</a></sup>';
}
function listu_open() {
@@ -471,8 +471,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
$title = $this->_xmlEntities($this->acronyms[$acronym]);
- $this->doc .= '<acronym title="'.$title
- .'">'.$this->_xmlEntities($acronym).'</acronym>';
+ $this->doc .= '<abbr title="'.$title
+ .'">'.$this->_xmlEntities($acronym).'</abbr>';
} else {
$this->doc .= $this->_xmlEntities($acronym);
@@ -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 .= '<img src="'.DOKU_BASE.'lib/images/smileys/'.$this->smileys[$smiley].
- '" class="middle" alt="'.
+ '" class="icon" alt="'.
$this->_xmlEntities($smiley).'" />';
} else {
$this->doc .= $this->_xmlEntities($smiley);
@@ -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.' &crarr;';
+ $title = $ID.' ↵';
$this->doc .= '<a href="#'.$hash.'" title="'.$title.'" class="wikilink1">';
$this->doc .= $name;
$this->doc .= '</a>';
@@ -1075,10 +1075,6 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
$ret .= '<img src="'.ml($src,array('w'=>$width,'h'=>$height,'cache'=>$cache)).'"';
$ret .= ' class="media'.$align.'"';
- // make left/right alignment for no-CSS view work (feeds)
- if($align == 'right') $ret .= ' align="right"';
- if($align == 'left') $ret .= ' align="left"';
-
if ($title) {
$ret .= ' title="' . $title . '"';
$ret .= ' alt="' . $title .'"';
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 <andi@splitbrain.org>
*/
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
diff --git a/inc/template.php b/inc/template.php
index d007f47ef..76d4d4bbe 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();
@@ -596,7 +592,7 @@ function tpl_get_action($type) {
$accesskey = 'x';
break;
case 'top':
- $accesskey = 'x';
+ $accesskey = 't';
$params = array();
$id = '#dokuwiki__top';
break;
@@ -718,7 +714,7 @@ function tpl_searchform($ajax=true,$autocomplete=true){
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function tpl_breadcrumbs($sep='&bull;'){
+function tpl_breadcrumbs($sep='•'){
global $lang;
global $conf;
@@ -761,7 +757,7 @@ function tpl_breadcrumbs($sep='&bull;'){
* @author <fredrik@averpil.com>
* @todo May behave strangely in RTL languages
*/
-function tpl_youarehere($sep=' &raquo; '){
+function tpl_youarehere($sep=' » '){
global $conf;
global $ID;
global $lang;
@@ -847,7 +843,7 @@ function tpl_pageinfo($ret=false){
if($INFO['exists']){
$out = '';
$out .= $fn;
- $out .= ' &middot; ';
+ $out .= ' · ';
$out .= $lang['lastmod'];
$out .= ': ';
$out .= $date;
@@ -858,7 +854,7 @@ function tpl_pageinfo($ret=false){
$out .= ' ('.$lang['external_edit'].')';
}
if($INFO['locked']){
- $out .= ' &middot; ';
+ $out .= ' · ';
$out .= $lang['lockedby'];
$out .= ': ';
$out .= editorinfo($INFO['locked']);
@@ -1398,6 +1394,18 @@ function tpl_include_page($pageid,$print=true){
if(!$print) return $html;
echo $html;
+ return $html;
+}
+
+/**
+ * Include the sidebar, will check current namespaces first
+ */
+function tpl_sidebar($print=true){
+ global $conf;
+
+ $sidebar = page_findnearest($conf['sidebar']);
+ if($sidebar) return tpl_include_page($sidebar, $print);
+ return '';
}
/**
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 <hfuecks@gmail.com>
* @author Chris Smith <chris@jalakai.co.uk>
- * @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 <andi@splitbrain.org>
* @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 <andi@splitbrain.org>
* @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 <andi@splitbrain.org>
* @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 <tnharris@whoopdedo.org>
* @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 <hsivonen@iki.fi>
* @author Harry Fuecks <hfuecks@gmail.com>
- * @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 <hsivonen@iki.fi>
* @author Harry Fuecks <hfuecks@gmail.com>
@@ -855,8 +888,8 @@ if(!function_exists('utf8_bad_replace')){
*
* @author Harry Fuecks <hfuecks@gmail.com>
* @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 <andi@splitbrain.org>