aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/inc
diff options
context:
space:
mode:
authorSatoshi Sahara <sahara.satoshi@gmail.com>2021-05-09 13:26:07 +0900
committerGitHub <noreply@github.com>2021-05-09 13:26:07 +0900
commit700ab9fdf1102a367a591bba2bc4a470ca345d2f (patch)
tree1e118d31fcf905132d7b3dc8aba2e21b4d1c0e5f /inc
parent871895a75d164d6a6389dbba8ae132577a744de4 (diff)
parent55c2f8c9858c38a70d317809fbfbee6439c10291 (diff)
downloaddokuwiki-700ab9fdf1102a367a591bba2bc4a470ca345d2f.tar.gz
dokuwiki-700ab9fdf1102a367a591bba2bc4a470ca345d2f.zip
Merge branch 'master' into revisionHandle3
Diffstat (limited to 'inc')
-rw-r--r--inc/Action/Admin.php7
-rw-r--r--inc/Action/Save.php5
-rw-r--r--inc/Extension/PluginController.php2
-rw-r--r--inc/File/MediaFile.php166
-rw-r--r--inc/Form/InputElement.php2
-rw-r--r--inc/HTTP/HTTPClient.php19
-rw-r--r--inc/JpegMeta.php148
-rw-r--r--inc/Logger.php2
-rw-r--r--inc/Remote/Api.php8
-rw-r--r--inc/Search/Indexer.php8
-rw-r--r--inc/Subscriptions/BulkSubscriptionSender.php2
-rw-r--r--inc/Ui/Admin.php10
-rw-r--r--inc/Ui/Media/Display.php119
-rw-r--r--inc/Ui/Media/DisplayRow.php93
-rw-r--r--inc/Ui/Media/DisplayTile.php54
-rw-r--r--inc/Ui/Revisions.php5
-rw-r--r--inc/auth.php38
-rw-r--r--inc/changelog.php14
-rw-r--r--inc/cli.php656
-rw-r--r--inc/common.php10
-rw-r--r--inc/fulltext.php15
-rw-r--r--inc/init.php5
-rw-r--r--inc/io.php2
-rw-r--r--inc/lang/de-informal/lang.php7
-rw-r--r--inc/lang/de-informal/onceexisted.txt3
-rw-r--r--inc/lang/de/lang.php2
-rw-r--r--inc/lang/en/lang.php1
-rw-r--r--inc/lang/es/lang.php2
-rw-r--r--inc/lang/fr/lang.php11
-rw-r--r--inc/lang/hy/admin.txt3
-rw-r--r--inc/lang/hy/adminplugins.txt1
-rw-r--r--inc/lang/hy/conflict.txt5
-rw-r--r--inc/lang/hy/denied.txt3
-rw-r--r--inc/lang/hy/diff.txt3
-rw-r--r--inc/lang/hy/draft.txt5
-rw-r--r--inc/lang/hy/edit.txt1
-rw-r--r--inc/lang/hy/editrev.txt2
-rw-r--r--inc/lang/hy/index.txt3
-rw-r--r--inc/lang/hy/lang.php133
-rw-r--r--inc/lang/it/lang.php2
-rw-r--r--inc/lang/pt/lang.php2
-rw-r--r--inc/lang/ru/lang.php1
-rw-r--r--inc/lang/sv/lang.php104
-rw-r--r--inc/lang/sv/onceexisted.txt3
-rw-r--r--inc/lang/tr/lang.php3
-rw-r--r--inc/lang/vi/lang.php5
-rw-r--r--inc/lang/vi/newpage.txt2
-rw-r--r--inc/lang/zh/lang.php1
-rw-r--r--inc/load.php5
-rw-r--r--inc/media.php232
-rw-r--r--inc/pageutils.php17
-rw-r--r--inc/parser/renderer.php2
-rw-r--r--inc/parser/xhtml.php8
-rw-r--r--inc/parserutils.php6
-rw-r--r--inc/search.php55
-rw-r--r--inc/template.php11
56 files changed, 966 insertions, 1068 deletions
diff --git a/inc/Action/Admin.php b/inc/Action/Admin.php
index 1c9afd6b9..aefa228e0 100644
--- a/inc/Action/Admin.php
+++ b/inc/Action/Admin.php
@@ -18,10 +18,7 @@ class Admin extends AbstractUserAction {
return AUTH_READ; // let in check later
}
- public function checkPreconditions() {
- parent::checkPreconditions();
- }
-
+ /** @inheritDoc */
public function preProcess() {
global $INPUT;
global $INFO;
@@ -38,8 +35,8 @@ class Admin extends AbstractUserAction {
}
}
+ /** @inheritDoc */
public function tplContent() {
tpl_admin();
}
-
}
diff --git a/inc/Action/Save.php b/inc/Action/Save.php
index 0b2472983..a577e379f 100644
--- a/inc/Action/Save.php
+++ b/inc/Action/Save.php
@@ -44,7 +44,10 @@ class Save extends AbstractAction {
throw new ActionException('edit');
}
//conflict check
- if($DATE != 0 && $INFO['meta']['date']['modified'] > $DATE) {
+ if($DATE != 0
+ && isset($INFO['meta']['date']['modified'])
+ && $INFO['meta']['date']['modified'] > $DATE
+ ) {
throw new ActionException('conflict');
}
diff --git a/inc/Extension/PluginController.php b/inc/Extension/PluginController.php
index 42aeac498..55fd299d8 100644
--- a/inc/Extension/PluginController.php
+++ b/inc/Extension/PluginController.php
@@ -274,7 +274,7 @@ class PluginController
$backup = $file . '.bak';
if (file_exists($backup)) @unlink($backup);
if (!@copy($file, $backup)) return false;
- if (!empty($conf['fperm'])) chmod($backup, $conf['fperm']);
+ if ($conf['fperm']) chmod($backup, $conf['fperm']);
}
//check if can open for writing, else restore
return io_saveFile($file, $out);
diff --git a/inc/File/MediaFile.php b/inc/File/MediaFile.php
new file mode 100644
index 000000000..4c27cc65c
--- /dev/null
+++ b/inc/File/MediaFile.php
@@ -0,0 +1,166 @@
+<?php
+
+namespace dokuwiki\File;
+
+use dokuwiki\Utf8\PhpString;
+
+class MediaFile
+{
+ protected $id;
+ protected $path;
+
+ protected $mime;
+ protected $ext;
+ protected $downloadable;
+
+ protected $width;
+ protected $height;
+ protected $meta;
+
+ /**
+ * MediaFile constructor.
+ * @param string $id
+ * @param string|int $rev optional revision
+ */
+ public function __construct($id, $rev = '')
+ {
+ $this->id = $id; //FIXME should it be cleaned?
+ $this->path = mediaFN($id, $rev);
+
+ list($this->ext, $this->mime, $this->downloadable) = mimetype($this->path, false);
+ }
+
+ /** @return string */
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /** @return string */
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /**
+ * The ID without namespace, used for display purposes
+ *
+ * @return string
+ */
+ public function getDisplayName()
+ {
+ return noNS($this->id);
+ }
+
+ /** @return string */
+ public function getMime()
+ {
+ if (!$this->mime) return 'application/octet-stream';
+ return $this->mime;
+ }
+
+ /** @return string */
+ public function getExtension()
+ {
+ return (string)$this->ext;
+ }
+
+ /**
+ * Similar to the extesion but does some clean up
+ *
+ * @return string
+ */
+ public function getIcoClass()
+ {
+ $ext = $this->getExtension();
+ if ($ext === '') $ext = 'file';
+ return preg_replace('/[^_\-a-z0-9]+/i', '_', $ext);
+ }
+
+ /**
+ * Should this file be downloaded instead being displayed inline?
+ *
+ * @return bool
+ */
+ public function isDownloadable()
+ {
+ return $this->downloadable;
+ }
+
+ /** @return int */
+ public function getFileSize()
+ {
+ return filesize($this->path);
+ }
+
+ /** @return int */
+ public function getLastModified()
+ {
+ return filemtime($this->path);
+ }
+
+ /** @return bool */
+ public function isWritable()
+ {
+ return is_writable($this->path);
+ }
+
+ /** @return bool */
+ public function isImage()
+ {
+ return (substr($this->mime, 0, 6) === 'image/');
+ }
+
+ /**
+ * initializes width and height for images when requested
+ */
+ protected function initSizes()
+ {
+ $this->width = 0;
+ $this->height = 0;
+ if (!$this->isImage()) return;
+ $info = getimagesize($this->path);
+ if ($info === false) return;
+ list($this->width, $this->height) = $info;
+ }
+
+ /**
+ * Returns the width if this is a supported image, 0 otherwise
+ *
+ * @return int
+ */
+ public function getWidth()
+ {
+ if ($this->width === null) $this->initSizes();
+ return $this->width;
+ }
+
+ /**
+ * Returns the height if this is a supported image, 0 otherwise
+ *
+ * @return int
+ */
+ public function getHeight()
+ {
+ if ($this->height === null) $this->initSizes();
+ return $this->height;
+ }
+
+ /**
+ * Returns the permissions the current user has on the file
+ *
+ * @todo doing this for each file within a namespace is a waste, we need to cache this somehow
+ * @return int
+ */
+ public function userPermission()
+ {
+ return auth_quickaclcheck(getNS($this->id).':*');
+ }
+
+ /** @return \JpegMeta */
+ public function getMeta()
+ {
+ if($this->meta === null) $this->meta = new \JpegMeta($this->path);
+ return $this->meta;
+ }
+}
diff --git a/inc/Form/InputElement.php b/inc/Form/InputElement.php
index 63be8aaa7..b7ace8a90 100644
--- a/inc/Form/InputElement.php
+++ b/inc/Form/InputElement.php
@@ -107,7 +107,7 @@ class InputElement extends Element
$name = array_keys($parsed);
$name = array_shift($name);
- if (is_array($parsed[$name])) {
+ if (isset($parsed[$name]) && is_array($parsed[$name])) {
$key = array_keys($parsed[$name]);
$key = array_shift($key);
} else {
diff --git a/inc/HTTP/HTTPClient.php b/inc/HTTP/HTTPClient.php
index 4aaf47168..3c0edf7ad 100644
--- a/inc/HTTP/HTTPClient.php
+++ b/inc/HTTP/HTTPClient.php
@@ -178,10 +178,9 @@ class HTTPClient {
// parse URL into bits
$uri = parse_url($url);
$server = $uri['host'];
- $path = $uri['path'];
- if(empty($path)) $path = '/';
+ $path = !empty($uri['path']) ? $uri['path'] : '/';
+ $uriPort = !empty($uri['port']) ? $uri['port'] : null;
if(!empty($uri['query'])) $path .= '?'.$uri['query'];
- if(!empty($uri['port'])) $port = $uri['port'];
if(isset($uri['user'])) $this->user = $uri['user'];
if(isset($uri['pass'])) $this->pass = $uri['pass'];
@@ -194,7 +193,7 @@ class HTTPClient {
$use_tls = $this->proxy_ssl;
}else{
$request_url = $path;
- if (!isset($port)) $port = ($uri['scheme'] == 'https') ? 443 : 80;
+ $port = $uriPort ?: ($uri['scheme'] == 'https' ? 443 : 80);
$use_tls = ($uri['scheme'] == 'https');
}
@@ -209,8 +208,8 @@ class HTTPClient {
// prepare headers
$headers = $this->headers;
- $headers['Host'] = $uri['host'];
- if(!empty($uri['port'])) $headers['Host'].= ':'.$uri['port'];
+ $headers['Host'] = $uri['host']
+ . ($uriPort ? ':' . $uriPort : '');
$headers['User-Agent'] = $this->agent;
$headers['Referer'] = $this->referer;
@@ -370,10 +369,10 @@ class HTTPClient {
// 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'];
+ $this->resp_headers['location'] = $uri['scheme'].'://'.$uri['host'].':'.$uriPort.
+ dirname($path).'/'.$this->resp_headers['location'];
}else{
- $this->resp_headers['location'] = $uri['scheme'].'://'.$uri['host'].':'.$uri['port'].
+ $this->resp_headers['location'] = $uri['scheme'].'://'.$uri['host'].':'.$uriPort.
$this->resp_headers['location'];
}
}
@@ -511,7 +510,7 @@ class HTTPClient {
if(!$this->useProxyForUrl($requesturl)) return false;
$requestinfo = parse_url($requesturl);
if($requestinfo['scheme'] != 'https') return false;
- if(!$requestinfo['port']) $requestinfo['port'] = 443;
+ if(empty($requestinfo['port'])) $requestinfo['port'] = 443;
// build request
$request = "CONNECT {$requestinfo['host']}:{$requestinfo['port']} HTTP/1.0".HTTP_NL;
diff --git a/inc/JpegMeta.php b/inc/JpegMeta.php
index 9ed1e2db4..9e6825d78 100644
--- a/inc/JpegMeta.php
+++ b/inc/JpegMeta.php
@@ -1317,79 +1317,81 @@ class JpegMeta {
$this->_info['file']['UnixTime'] = filemtime($this->_fileName);
// get image size directly from file
- $size = getimagesize($this->_fileName);
- $this->_info['file']['Width'] = $size[0];
- $this->_info['file']['Height'] = $size[1];
- // set mime types and formats
- // http://php.net/manual/en/function.getimagesize.php
- // http://php.net/manual/en/function.image-type-to-mime-type.php
- switch ($size[2]){
- case 1:
- $this->_info['file']['Mime'] = 'image/gif';
- $this->_info['file']['Format'] = 'GIF';
- break;
- case 2:
- $this->_info['file']['Mime'] = 'image/jpeg';
- $this->_info['file']['Format'] = 'JPEG';
- break;
- case 3:
- $this->_info['file']['Mime'] = 'image/png';
- $this->_info['file']['Format'] = 'PNG';
- break;
- case 4:
- $this->_info['file']['Mime'] = 'application/x-shockwave-flash';
- $this->_info['file']['Format'] = 'SWF';
- break;
- case 5:
- $this->_info['file']['Mime'] = 'image/psd';
- $this->_info['file']['Format'] = 'PSD';
- break;
- case 6:
- $this->_info['file']['Mime'] = 'image/bmp';
- $this->_info['file']['Format'] = 'BMP';
- break;
- case 7:
- $this->_info['file']['Mime'] = 'image/tiff';
- $this->_info['file']['Format'] = 'TIFF (Intel)';
- break;
- case 8:
- $this->_info['file']['Mime'] = 'image/tiff';
- $this->_info['file']['Format'] = 'TIFF (Motorola)';
- break;
- case 9:
- $this->_info['file']['Mime'] = 'application/octet-stream';
- $this->_info['file']['Format'] = 'JPC';
- break;
- case 10:
- $this->_info['file']['Mime'] = 'image/jp2';
- $this->_info['file']['Format'] = 'JP2';
- break;
- case 11:
- $this->_info['file']['Mime'] = 'application/octet-stream';
- $this->_info['file']['Format'] = 'JPX';
- break;
- case 12:
- $this->_info['file']['Mime'] = 'application/octet-stream';
- $this->_info['file']['Format'] = 'JB2';
- break;
- case 13:
- $this->_info['file']['Mime'] = 'application/x-shockwave-flash';
- $this->_info['file']['Format'] = 'SWC';
- break;
- case 14:
- $this->_info['file']['Mime'] = 'image/iff';
- $this->_info['file']['Format'] = 'IFF';
- break;
- case 15:
- $this->_info['file']['Mime'] = 'image/vnd.wap.wbmp';
- $this->_info['file']['Format'] = 'WBMP';
- break;
- case 16:
- $this->_info['file']['Mime'] = 'image/xbm';
- $this->_info['file']['Format'] = 'XBM';
- break;
- default:
- $this->_info['file']['Mime'] = 'image/unknown';
+ if ($size = getimagesize($this->_fileName)) {
+ $this->_info['file']['Width'] = $size[0];
+ $this->_info['file']['Height'] = $size[1];
+
+ // set mime types and formats
+ // http://php.net/manual/en/function.getimagesize.php
+ // http://php.net/manual/en/function.image-type-to-mime-type.php
+ switch ($size[2]) {
+ case 1:
+ $this->_info['file']['Mime'] = 'image/gif';
+ $this->_info['file']['Format'] = 'GIF';
+ break;
+ case 2:
+ $this->_info['file']['Mime'] = 'image/jpeg';
+ $this->_info['file']['Format'] = 'JPEG';
+ break;
+ case 3:
+ $this->_info['file']['Mime'] = 'image/png';
+ $this->_info['file']['Format'] = 'PNG';
+ break;
+ case 4:
+ $this->_info['file']['Mime'] = 'application/x-shockwave-flash';
+ $this->_info['file']['Format'] = 'SWF';
+ break;
+ case 5:
+ $this->_info['file']['Mime'] = 'image/psd';
+ $this->_info['file']['Format'] = 'PSD';
+ break;
+ case 6:
+ $this->_info['file']['Mime'] = 'image/bmp';
+ $this->_info['file']['Format'] = 'BMP';
+ break;
+ case 7:
+ $this->_info['file']['Mime'] = 'image/tiff';
+ $this->_info['file']['Format'] = 'TIFF (Intel)';
+ break;
+ case 8:
+ $this->_info['file']['Mime'] = 'image/tiff';
+ $this->_info['file']['Format'] = 'TIFF (Motorola)';
+ break;
+ case 9:
+ $this->_info['file']['Mime'] = 'application/octet-stream';
+ $this->_info['file']['Format'] = 'JPC';
+ break;
+ case 10:
+ $this->_info['file']['Mime'] = 'image/jp2';
+ $this->_info['file']['Format'] = 'JP2';
+ break;
+ case 11:
+ $this->_info['file']['Mime'] = 'application/octet-stream';
+ $this->_info['file']['Format'] = 'JPX';
+ break;
+ case 12:
+ $this->_info['file']['Mime'] = 'application/octet-stream';
+ $this->_info['file']['Format'] = 'JB2';
+ break;
+ case 13:
+ $this->_info['file']['Mime'] = 'application/x-shockwave-flash';
+ $this->_info['file']['Format'] = 'SWC';
+ break;
+ case 14:
+ $this->_info['file']['Mime'] = 'image/iff';
+ $this->_info['file']['Format'] = 'IFF';
+ break;
+ case 15:
+ $this->_info['file']['Mime'] = 'image/vnd.wap.wbmp';
+ $this->_info['file']['Format'] = 'WBMP';
+ break;
+ case 16:
+ $this->_info['file']['Mime'] = 'image/xbm';
+ $this->_info['file']['Format'] = 'XBM';
+ break;
+ default:
+ $this->_info['file']['Mime'] = 'image/unknown';
+ }
}
} else {
$this->_info['file'] = array();
diff --git a/inc/Logger.php b/inc/Logger.php
index 5923777df..a3999a6ea 100644
--- a/inc/Logger.php
+++ b/inc/Logger.php
@@ -40,7 +40,7 @@ class Logger
*/
static public function getInstance($facility = self::LOG_ERROR)
{
- if (self::$instances[$facility] === null) {
+ if (empty(self::$instances[$facility])) {
self::$instances[$facility] = new Logger($facility);
}
return self::$instances[$facility];
diff --git a/inc/Remote/Api.php b/inc/Remote/Api.php
index 3b526564d..749c2e6ea 100644
--- a/inc/Remote/Api.php
+++ b/inc/Remote/Api.php
@@ -92,7 +92,8 @@ class Api
if ($args === null) {
$args = array();
}
- list($type, $pluginName, /* $call */) = explode('.', $method, 3);
+ // Ensure we have at least one '.' in $method
+ list($type, $pluginName, /* $call */) = explode('.', $method . '.', 3);
if ($type === 'plugin') {
return $this->callPlugin($pluginName, $method, $args);
}
@@ -128,8 +129,9 @@ class Api
if (!array_key_exists($method, $customCalls)) {
throw new RemoteException('Method does not exist', -32603);
}
- $customCall = $customCalls[$method];
- return $this->callPlugin($customCall[0], $customCall[1], $args);
+ list($plugin, $method) = $customCalls[$method];
+ $fullMethod = "plugin.$plugin.$method";
+ return $this->callPlugin($plugin, $fullMethod, $args);
}
/**
diff --git a/inc/Search/Indexer.php b/inc/Search/Indexer.php
index a29e5b28b..ae3b12c57 100644
--- a/inc/Search/Indexer.php
+++ b/inc/Search/Indexer.php
@@ -942,7 +942,7 @@ class Indexer {
return false;
}
}
- if (!empty($conf['dperm'])) {
+ if ($conf['dperm']) {
chmod($lock, $conf['dperm']);
}
return $status;
@@ -1186,8 +1186,10 @@ class Indexer {
if ($tuple === '') continue;
list($key, $cnt) = explode('*', $tuple);
if (!$cnt) continue;
- $key = $keys[$key];
- if ($key === false || is_null($key)) continue;
+ if (isset($keys[$key])) {
+ $key = $keys[$key];
+ if ($key === false || is_null($key)) continue;
+ }
$result[$key] = $cnt;
}
return $result;
diff --git a/inc/Subscriptions/BulkSubscriptionSender.php b/inc/Subscriptions/BulkSubscriptionSender.php
index 672ef90f6..7341cd0a5 100644
--- a/inc/Subscriptions/BulkSubscriptionSender.php
+++ b/inc/Subscriptions/BulkSubscriptionSender.php
@@ -156,7 +156,7 @@ class BulkSubscriptionSender extends SubscriptionSender
return false;
}
- if (!empty($conf['dperm'])) {
+ if ($conf['dperm']) {
chmod($lock, $conf['dperm']);
}
return true;
diff --git a/inc/Ui/Admin.php b/inc/Ui/Admin.php
index 07146e598..d3bbc6503 100644
--- a/inc/Ui/Admin.php
+++ b/inc/Ui/Admin.php
@@ -28,9 +28,10 @@ class Admin extends Ui {
$this->menu = $this->getPluginList();
echo '<div class="ui-admin">';
echo p_locale_xhtml('admin');
- $this->showSecurityCheck();
+
$this->showMenu('admin');
$this->showMenu('manager');
+ $this->showSecurityCheck();
$this->showVersion();
$this->showMenu('other');
echo '</div>';
@@ -75,16 +76,15 @@ class Admin extends Ui {
* it verifies either:
* 'savedir' has been moved elsewhere, or
* has protection to prevent the webserver serving files from it
+ *
+ * The actual check is carried out via JavaScript. See behaviour.js
*/
protected function showSecurityCheck() {
global $conf;
if(substr($conf['savedir'], 0, 2) !== './') return;
$img = DOKU_URL . $conf['savedir'] .
'/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png';
- echo '<a style="border:none; float:right;"
- href="http://www.dokuwiki.org/security#web_access_security">
- <img src="' . $img . '" alt="Your data directory seems to be protected properly."
- onerror="this.parentNode.style.display=\'none\'" /></a>';
+ echo '<div id="security__check" data-src="' . $img . '"></div>';
}
/**
diff --git a/inc/Ui/Media/Display.php b/inc/Ui/Media/Display.php
new file mode 100644
index 000000000..16f2137b1
--- /dev/null
+++ b/inc/Ui/Media/Display.php
@@ -0,0 +1,119 @@
+<?php
+
+namespace dokuwiki\Ui\Media;
+
+use dokuwiki\File\MediaFile;
+
+class Display
+{
+ /** @var MediaFile */
+ protected $mediaFile;
+
+ /** @var string should IDs be shown relative to this namespace? Used in search results */
+ protected $relativeDisplay = null;
+
+ /** @var bool scroll to this file on display? */
+ protected $scrollIntoView = false;
+
+ /**
+ * Display constructor.
+ * @param MediaFile $mediaFile
+ */
+ public function __construct(MediaFile $mediaFile)
+ {
+ $this->mediaFile = $mediaFile;
+ }
+
+ /**
+ * Get the HTML to display a preview image if possible, otherwise show an icon
+ *
+ * @param int $w bounding box width to resize pixel based images to
+ * @param int $h bounding box height to resize pixel based images to
+ * @return string
+ */
+ public function getPreviewHtml($w, $h)
+ {
+ if ($this->mediaFile->isImage()) {
+ $src = ml($this->mediaFile->getId(), ['w' => $w, 'h' => $h]);
+ } else {
+ $src = $this->getIconUrl();
+ }
+
+ return '<img src="' . $src . '" alt="' . hsc($this->mediaFile->getDisplayName()) . '" loading="lazy" />';
+ }
+
+ /**
+ * Return the URL to the icon for this file
+ *
+ * @return string
+ */
+ public function getIconUrl()
+ {
+ $link = 'lib/images/fileicons/svg/' . $this->mediaFile->getIcoClass() . '.svg';
+ if (!file_exists(DOKU_INC . $link)) $link = 'lib/images/fileicons/svg/file.svg';
+ return DOKU_BASE . $link;
+ }
+
+ /**
+ * Show IDs relative to this namespace
+ *
+ * @param string|null $ns Use null to disable
+ */
+ public function relativeDisplay($ns)
+ {
+ $this->relativeDisplay = $ns;
+ }
+
+ /**
+ * Scroll to this file on display?
+ *
+ * @param bool $set
+ */
+ public function scrollIntoView($set = true)
+ {
+ $this->scrollIntoView = $set;
+ }
+
+ /** @return string */
+ protected function formatDate()
+ {
+ return dformat($this->mediaFile->getLastModified());
+ }
+
+ /**
+ * Output the image dimension if any
+ *
+ * @param string $empty what to show when no dimensions are available
+ * @return string
+ */
+ protected function formatDimensions($empty = '&#160;')
+ {
+ $w = $this->mediaFile->getWidth();
+ $h = $this->mediaFile->getHeight();
+ if ($w && $h) {
+ return $w . '&#215;' . $h;
+ } else {
+ return $empty;
+ }
+ }
+
+ /** @return string */
+ protected function formatFileSize()
+ {
+ return filesize_h($this->mediaFile->getFileSize());
+ }
+
+ /** @return string */
+ protected function formatDisplayName()
+ {
+ if ($this->relativeDisplay !== null) {
+ $id = $this->mediaFile->getId();
+ if (substr($id, 0, strlen($this->relativeDisplay)) == $this->relativeDisplay) {
+ $id = substr($id, strlen($this->relativeDisplay));
+ }
+ return ltrim($id, ':');
+ } else {
+ return $this->mediaFile->getDisplayName();
+ }
+ }
+}
diff --git a/inc/Ui/Media/DisplayRow.php b/inc/Ui/Media/DisplayRow.php
new file mode 100644
index 000000000..47feed088
--- /dev/null
+++ b/inc/Ui/Media/DisplayRow.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace dokuwiki\Ui\Media;
+
+use dokuwiki\Utf8\PhpString;
+
+/**
+ * Display a MediaFile in the Media Popup
+ */
+class DisplayRow extends DisplayTile
+{
+ /** @inheritDoc */
+ public function show()
+ {
+ global $lang;
+ // FIXME Zebra classes have been dropped and need to be readded via CSS
+
+ $id = $this->mediaFile->getId();
+ $class = 'select mediafile mf_' . $this->mediaFile->getIcoClass();
+ $info = trim($this->formatDimensions('') . ' ' . $this->formatDate() . ' ' . $this->formatFileSize());
+ $jump = $this->scrollIntoView ? 'id="scroll__here"' : '';
+
+ echo '<div title="' . $id . '" ' . $jump . '>';
+ echo '<a id="h_:' . $id . '" class="' . $class . '">' .
+ $this->formatDisplayName() .
+ '</a> ';
+ echo '<span class="info">(' . $info . ')</span>' . NL;
+
+ // view button
+ $link = ml($id, '', true);
+ echo ' <a href="' . $link . '" target="_blank"><img src="' . DOKU_BASE . 'lib/images/magnifier.png" ' .
+ 'alt="' . $lang['mediaview'] . '" title="' . $lang['mediaview'] . '" class="btn" /></a>';
+
+ // mediamanager button
+ $link = wl('', array('do' => 'media', 'image' => $id, 'ns' => getNS($id)));
+ echo ' <a href="' . $link . '" target="_blank"><img src="' . DOKU_BASE . 'lib/images/mediamanager.png" ' .
+ 'alt="' . $lang['btn_media'] . '" title="' . $lang['btn_media'] . '" class="btn" /></a>';
+
+ // delete button
+ if ($this->mediaFile->isWritable() && $this->mediaFile->userPermission() >= AUTH_DELETE) {
+ $link = DOKU_BASE . 'lib/exe/mediamanager.php?delete=' . rawurlencode($id) .
+ '&amp;sectok=' . getSecurityToken();
+ echo ' <a href="' . $link . '" class="btn_media_delete" title="' . $id . '">' .
+ '<img src="' . DOKU_BASE . 'lib/images/trash.png" alt="' . $lang['btn_delete'] . '" ' .
+ 'title="' . $lang['btn_delete'] . '" class="btn" /></a>';
+ }
+
+ echo '<div class="example" id="ex_' . str_replace(':', '_', $id) . '">';
+ echo $lang['mediausage'] . ' <code>{{:' . $id . '}}</code>';
+ echo '</div>';
+ if ($this->mediaFile->getWidth()) $this->showDetails();
+ echo '<div class="clearer"></div>' . NL;
+ echo '</div>' . NL;
+
+ }
+
+ /**
+ * Show Thumbnail and EXIF data
+ */
+ protected function showDetails()
+ {
+ $id = $this->mediaFile->getId();
+
+ echo '<div class="detail">';
+ echo '<div class="thumb">';
+ echo '<a id="d_:' . $id . '" class="select">';
+ echo $this->getPreviewHtml(120, 120);
+ echo '</a>';
+ echo '</div>';
+
+ // read EXIF/IPTC data
+ $t = $this->mediaFile->getMeta()->getField(array('IPTC.Headline', 'xmp.dc:title'));
+ $d = $this->mediaFile->getMeta()->getField(array(
+ 'IPTC.Caption',
+ 'EXIF.UserComment',
+ 'EXIF.TIFFImageDescription',
+ 'EXIF.TIFFUserComment',
+ ));
+ if (PhpString::strlen($d) > 250) $d = PhpString::substr($d, 0, 250) . '...';
+ $k = $this->mediaFile->getMeta()->getField(array('IPTC.Keywords', 'IPTC.Category', 'xmp.dc:subject'));
+
+ // print EXIF/IPTC data
+ if ($t || $d || $k) {
+ echo '<p>';
+ if ($t) echo '<strong>' . hsc($t) . '</strong><br />';
+ if ($d) echo hsc($d) . '<br />';
+ if ($t) echo '<em>' . hsc($k) . '</em>';
+ echo '</p>';
+ }
+ echo '</div>';
+ }
+
+}
diff --git a/inc/Ui/Media/DisplayTile.php b/inc/Ui/Media/DisplayTile.php
new file mode 100644
index 000000000..aff294b9b
--- /dev/null
+++ b/inc/Ui/Media/DisplayTile.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace dokuwiki\Ui\Media;
+
+use dokuwiki\File\MediaFile;
+
+/**
+ * Display a MediaFile in the FullScreen MediaManager
+ */
+class DisplayTile extends Display
+{
+ /** @var string URL to open this file in the media manager */
+ protected $mmUrl;
+
+ /** @inheritDoc */
+ public function __construct(MediaFile $mediaFile)
+ {
+ parent::__construct($mediaFile);
+
+ // FIXME we may want to integrate this function here or in another class
+ $this->mmUrl = media_managerURL([
+ 'image' => $this->mediaFile->getId(),
+ 'ns' => getNS($this->mediaFile->getId()),
+ 'tab_details' => 'view',
+ ]);
+ }
+
+ /**
+ * Display the tile
+ */
+ public function show()
+ {
+ $jump = $this->scrollIntoView ? 'id="scroll__here"' : '';
+
+ echo '<dl title="' . $this->mediaFile->getDisplayName() . '"' . $jump . '>';
+ echo '<dt>';
+ echo '<a id="l_:' . $this->mediaFile->getId() . '" class="image thumb" href="' . $this->mmUrl . '">';
+ echo $this->getPreviewHtml(90, 90);
+ echo '</a>';
+ echo '</dt>';
+
+ echo '<dd class="name">';
+ echo '<a href="' . $this->mmUrl . '" id="h_:' . $this->mediaFile->getId() . '">' .
+ $this->formatDisplayName() .
+ '</a>';
+ echo '</dd>';
+
+ echo '<dd class="size">' . $this->formatDimensions() . '</dd>';
+ echo '<dd class="date">' . $this->formatDate() . '</dd>';
+ echo '<dd class="filesize">' . $this->formatFileSize() . '</dd>';
+
+ echo '</dl>';
+ }
+}
diff --git a/inc/Ui/Revisions.php b/inc/Ui/Revisions.php
index 3385afab2..ca38a213a 100644
--- a/inc/Ui/Revisions.php
+++ b/inc/Ui/Revisions.php
@@ -17,7 +17,7 @@ abstract class Revisions extends Ui
/* @var ChangeLog */
protected $changelog; // PageChangeLog or MediaChangeLog object
- /**
+ /**
* Revisions Ui constructor
*
* @param string $id page id or media id
@@ -145,6 +145,9 @@ abstract class Revisions extends Ui
public function __construct(array $info)
{
+ if (!isset($info['current'])) {
+ $info['current'] = false;
+ }
$this->info = $info;
}
diff --git a/inc/auth.php b/inc/auth.php
index b9ed0b85e..bb0ad57dc 100644
--- a/inc/auth.php
+++ b/inc/auth.php
@@ -245,19 +245,21 @@ function auth_login($user, $pass, $sticky = false, $silent = false) {
// 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())
- ) {
-
- // he has session, cookie and browser right - let him in
- $INPUT->server->set('REMOTE_USER', $user);
- $USERINFO = $session['info']; //FIXME move all references to session
- return true;
+ if (isset($_SESSION[DOKU_COOKIE])) {
+ $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())
+ ) {
+
+ // he has session, cookie and browser right - let him in
+ $INPUT->server->set('REMOTE_USER', $user);
+ $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, true); //bind non-sticky to session
@@ -467,8 +469,14 @@ function auth_ismanager($user = null, $groups = null, $adminonly = false, $recac
$user = $INPUT->server->str('REMOTE_USER');
}
}
- if(is_null($groups)) {
- $groups = $USERINFO ? (array) $USERINFO['grps'] : array();
+ if (is_null($groups)) {
+ // checking the logged in user, or another one?
+ if ($USERINFO && $user === $INPUT->server->str('REMOTE_USER')) {
+ $groups = (array) $USERINFO['grps'];
+ } else {
+ $groups = $auth->getUserData($user);
+ $groups = $groups ? $groups['grps'] : [];
+ }
}
// prefer cached result
diff --git a/inc/changelog.php b/inc/changelog.php
index f02572e7f..d40b80432 100644
--- a/inc/changelog.php
+++ b/inc/changelog.php
@@ -38,7 +38,7 @@ function parseChangelogLine($line) {
}
/**
- * Add's an entry to the changelog and saves the metadata for the page
+ * Adds an entry to the changelog and saves the metadata for the page
*
* @param int $date Timestamp of the change
* @param String $id Name of the affected page
@@ -94,12 +94,12 @@ function addLogEntry($date, $id, $type=DOKU_CHANGE_TYPE_EDIT, $summary='', $extr
$wasReverted = ($type===DOKU_CHANGE_TYPE_REVERT);
// update metadata
if (!$wasRemoved) {
- $oldmeta = p_read_metadata($id);
+ $oldmeta = p_read_metadata($id)['persistent'];
$meta = array();
if (
$wasCreated && (
- empty($oldmeta['persistent']['date']['created']) ||
- $oldmeta['persistent']['date']['created'] === $created
+ empty($oldmeta['date']['created']) ||
+ $oldmeta['date']['created'] === $created
)
){
// newly created
@@ -108,11 +108,11 @@ function addLogEntry($date, $id, $type=DOKU_CHANGE_TYPE_EDIT, $summary='', $extr
$meta['creator'] = isset($INFO) ? $INFO['userinfo']['name'] : null;
$meta['user'] = $user;
}
- } elseif (($wasCreated || $wasReverted) && !empty($oldmeta['persistent']['date']['created'])) {
+ } elseif (($wasCreated || $wasReverted) && !empty($oldmeta['date']['created'])) {
// re-created / restored
- $meta['date']['created'] = $oldmeta['persistent']['date']['created'];
+ $meta['date']['created'] = $oldmeta['date']['created'];
$meta['date']['modified'] = $created; // use the files ctime here
- $meta['creator'] = $oldmeta['persistent']['creator'];
+ $meta['creator'] = isset($oldmeta['creator']) ? $oldmeta['creator'] : null;
if ($user) $meta['contributor'][$user] = isset($INFO) ? $INFO['userinfo']['name'] : null;
} elseif (!$minor) { // non-minor modification
$meta['date']['modified'] = $date;
diff --git a/inc/cli.php b/inc/cli.php
deleted file mode 100644
index cb4dabf04..000000000
--- a/inc/cli.php
+++ /dev/null
@@ -1,656 +0,0 @@
-<?php
-
-/**
- * Class DokuCLI
- *
- * All DokuWiki commandline scripts should inherit from this class and implement the abstract methods.
- *
- * @deprecated 2017-11-10
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-abstract class DokuCLI {
- /** @var string the executed script itself */
- protected $bin;
- /** @var DokuCLI_Options the option parser */
- protected $options;
- /** @var DokuCLI_Colors */
- public $colors;
-
- /**
- * constructor
- *
- * Initialize the arguments, set up helper classes and set up the CLI environment
- */
- public function __construct() {
- set_exception_handler(array($this, 'fatal'));
-
- $this->options = new DokuCLI_Options();
- $this->colors = new DokuCLI_Colors();
-
- dbg_deprecated('use \splitbrain\phpcli\CLI instead');
- $this->error('DokuCLI is deprecated, use \splitbrain\phpcli\CLI instead.');
- }
-
- /**
- * Register options and arguments on the given $options object
- *
- * @param DokuCLI_Options $options
- * @return void
- */
- abstract protected function setup(DokuCLI_Options $options);
-
- /**
- * Your main program
- *
- * Arguments and options have been parsed when this is run
- *
- * @param DokuCLI_Options $options
- * @return void
- */
- abstract protected function main(DokuCLI_Options $options);
-
- /**
- * Execute the CLI program
- *
- * Executes the setup() routine, adds default options, initiate the options parsing and argument checking
- * and finally executes main()
- */
- public function run() {
- if('cli' != php_sapi_name()) throw new DokuCLI_Exception('This has to be run from the command line');
-
- // setup
- $this->setup($this->options);
- $this->options->registerOption(
- 'no-colors',
- 'Do not use any colors in output. Useful when piping output to other tools or files.'
- );
- $this->options->registerOption(
- 'help',
- 'Display this help screen and exit immediately.',
- 'h'
- );
-
- // parse
- $this->options->parseOptions();
-
- // handle defaults
- if($this->options->getOpt('no-colors')) {
- $this->colors->disable();
- }
- if($this->options->getOpt('help')) {
- echo $this->options->help();
- exit(0);
- }
-
- // check arguments
- $this->options->checkArguments();
-
- // execute
- $this->main($this->options);
-
- exit(0);
- }
-
- /**
- * Exits the program on a fatal error
- *
- * @param Exception|string $error either an exception or an error message
- */
- public function fatal($error) {
- $code = 0;
- if(is_object($error) && is_a($error, 'Exception')) {
- /** @var Exception $error */
- $code = $error->getCode();
- $error = $error->getMessage();
- }
- if(!$code) $code = DokuCLI_Exception::E_ANY;
-
- $this->error($error);
- exit($code);
- }
-
- /**
- * Print an error message
- *
- * @param string $string
- */
- public function error($string) {
- $this->colors->ptln("E: $string", 'red', STDERR);
- }
-
- /**
- * Print a success message
- *
- * @param string $string
- */
- public function success($string) {
- $this->colors->ptln("S: $string", 'green', STDERR);
- }
-
- /**
- * Print an info message
- *
- * @param string $string
- */
- public function info($string) {
- $this->colors->ptln("I: $string", 'cyan', STDERR);
- }
-
-}
-
-/**
- * Class DokuCLI_Colors
- *
- * Handles color output on (Linux) terminals
- *
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-class DokuCLI_Colors {
- /** @var array known color names */
- protected $colors = array(
- 'reset' => "\33[0m",
- 'black' => "\33[0;30m",
- 'darkgray' => "\33[1;30m",
- 'blue' => "\33[0;34m",
- 'lightblue' => "\33[1;34m",
- 'green' => "\33[0;32m",
- 'lightgreen' => "\33[1;32m",
- 'cyan' => "\33[0;36m",
- 'lightcyan' => "\33[1;36m",
- 'red' => "\33[0;31m",
- 'lightred' => "\33[1;31m",
- 'purple' => "\33[0;35m",
- 'lightpurple' => "\33[1;35m",
- 'brown' => "\33[0;33m",
- 'yellow' => "\33[1;33m",
- 'lightgray' => "\33[0;37m",
- 'white' => "\33[1;37m",
- );
-
- /** @var bool should colors be used? */
- protected $enabled = true;
-
- /**
- * Constructor
- *
- * Tries to disable colors for non-terminals
- */
- public function __construct() {
- if(function_exists('posix_isatty') && !posix_isatty(STDOUT)) {
- $this->enabled = false;
- return;
- }
- if(!getenv('TERM')) {
- $this->enabled = false;
- return;
- }
- }
-
- /**
- * enable color output
- */
- public function enable() {
- $this->enabled = true;
- }
-
- /**
- * disable color output
- */
- public function disable() {
- $this->enabled = false;
- }
-
- /**
- * Convenience function to print a line in a given color
- *
- * @param string $line
- * @param string $color
- * @param resource $channel
- */
- public function ptln($line, $color, $channel = STDOUT) {
- $this->set($color);
- fwrite($channel, rtrim($line)."\n");
- $this->reset();
- }
-
- /**
- * Set the given color for consecutive output
- *
- * @param string $color one of the supported color names
- * @throws DokuCLI_Exception
- */
- public function set($color) {
- if(!$this->enabled) return;
- if(!isset($this->colors[$color])) throw new DokuCLI_Exception("No such color $color");
- echo $this->colors[$color];
- }
-
- /**
- * reset the terminal color
- */
- public function reset() {
- $this->set('reset');
- }
-}
-
-/**
- * Class DokuCLI_Options
- *
- * Parses command line options passed to the CLI script. Allows CLI scripts to easily register all accepted options and
- * commands and even generates a help text from this setup.
- *
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-class DokuCLI_Options {
- /** @var array keeps the list of options to parse */
- protected $setup;
-
- /** @var array store parsed options */
- protected $options = array();
-
- /** @var string current parsed command if any */
- protected $command = '';
-
- /** @var array passed non-option arguments */
- public $args = array();
-
- /** @var string the executed script */
- protected $bin;
-
- /**
- * Constructor
- */
- public function __construct() {
- $this->setup = array(
- '' => array(
- 'opts' => array(),
- 'args' => array(),
- 'help' => ''
- )
- ); // default command
-
- $this->args = $this->readPHPArgv();
- $this->bin = basename(array_shift($this->args));
-
- $this->options = array();
- }
-
- /**
- * Sets the help text for the tool itself
- *
- * @param string $help
- */
- public function setHelp($help) {
- $this->setup['']['help'] = $help;
- }
-
- /**
- * Register the names of arguments for help generation and number checking
- *
- * This has to be called in the order arguments are expected
- *
- * @param string $arg argument name (just for help)
- * @param string $help help text
- * @param bool $required is this a required argument
- * @param string $command if theses apply to a sub command only
- * @throws DokuCLI_Exception
- */
- public function registerArgument($arg, $help, $required = true, $command = '') {
- if(!isset($this->setup[$command])) throw new DokuCLI_Exception("Command $command not registered");
-
- $this->setup[$command]['args'][] = array(
- 'name' => $arg,
- 'help' => $help,
- 'required' => $required
- );
- }
-
- /**
- * This registers a sub command
- *
- * Sub commands have their own options and use their own function (not main()).
- *
- * @param string $command
- * @param string $help
- * @throws DokuCLI_Exception
- */
- public function registerCommand($command, $help) {
- if(isset($this->setup[$command])) throw new DokuCLI_Exception("Command $command already registered");
-
- $this->setup[$command] = array(
- 'opts' => array(),
- 'args' => array(),
- 'help' => $help
- );
-
- }
-
- /**
- * Register an option for option parsing and help generation
- *
- * @param string $long multi character option (specified with --)
- * @param string $help help text for this option
- * @param string|null $short one character option (specified with -)
- * @param bool|string $needsarg does this option require an argument? give it a name here
- * @param string $command what command does this option apply to
- * @throws DokuCLI_Exception
- */
- public function registerOption($long, $help, $short = null, $needsarg = false, $command = '') {
- if(!isset($this->setup[$command])) throw new DokuCLI_Exception("Command $command not registered");
-
- $this->setup[$command]['opts'][$long] = array(
- 'needsarg' => $needsarg,
- 'help' => $help,
- 'short' => $short
- );
-
- if($short) {
- if(strlen($short) > 1) throw new DokuCLI_Exception("Short options should be exactly one ASCII character");
-
- $this->setup[$command]['short'][$short] = $long;
- }
- }
-
- /**
- * Checks the actual number of arguments against the required number
- *
- * Throws an exception if arguments are missing. Called from parseOptions()
- *
- * @throws DokuCLI_Exception
- */
- public function checkArguments() {
- $argc = count($this->args);
-
- $req = 0;
- foreach($this->setup[$this->command]['args'] as $arg) {
- if(!$arg['required']) break; // last required arguments seen
- $req++;
- }
-
- if($req > $argc) throw new DokuCLI_Exception("Not enough arguments", DokuCLI_Exception::E_OPT_ARG_REQUIRED);
- }
-
- /**
- * Parses the given arguments for known options and command
- *
- * The given $args array should NOT contain the executed file as first item anymore! The $args
- * array is stripped from any options and possible command. All found otions can be accessed via the
- * getOpt() function
- *
- * Note that command options will overwrite any global options with the same name
- *
- * @throws DokuCLI_Exception
- */
- public function parseOptions() {
- $non_opts = array();
-
- $argc = count($this->args);
- for($i = 0; $i < $argc; $i++) {
- $arg = $this->args[$i];
-
- // The special element '--' means explicit end of options. Treat the rest of the arguments as non-options
- // and end the loop.
- if($arg == '--') {
- $non_opts = array_merge($non_opts, array_slice($this->args, $i + 1));
- break;
- }
-
- // '-' is stdin - a normal argument
- if($arg == '-') {
- $non_opts = array_merge($non_opts, array_slice($this->args, $i));
- break;
- }
-
- // first non-option
- if($arg[0] != '-') {
- $non_opts = array_merge($non_opts, array_slice($this->args, $i));
- break;
- }
-
- // long option
- if(strlen($arg) > 1 && $arg[1] == '-') {
- list($opt, $val) = explode('=', substr($arg, 2), 2);
-
- if(!isset($this->setup[$this->command]['opts'][$opt])) {
- throw new DokuCLI_Exception("No such option $arg", DokuCLI_Exception::E_UNKNOWN_OPT);
- }
-
- // argument required?
- if($this->setup[$this->command]['opts'][$opt]['needsarg']) {
- if(is_null($val) && $i + 1 < $argc && !preg_match('/^--?[\w]/', $this->args[$i + 1])) {
- $val = $this->args[++$i];
- }
- if(is_null($val)) {
- throw new DokuCLI_Exception("Option $arg requires an argument", DokuCLI_Exception::E_OPT_ARG_REQUIRED);
- }
- $this->options[$opt] = $val;
- } else {
- $this->options[$opt] = true;
- }
-
- continue;
- }
-
- // short option
- $opt = substr($arg, 1);
- if(!isset($this->setup[$this->command]['short'][$opt])) {
- throw new DokuCLI_Exception("No such option $arg", DokuCLI_Exception::E_UNKNOWN_OPT);
- } else {
- $opt = $this->setup[$this->command]['short'][$opt]; // store it under long name
- }
-
- // argument required?
- if($this->setup[$this->command]['opts'][$opt]['needsarg']) {
- $val = null;
- if($i + 1 < $argc && !preg_match('/^--?[\w]/', $this->args[$i + 1])) {
- $val = $this->args[++$i];
- }
- if(is_null($val)) {
- throw new DokuCLI_Exception("Option $arg requires an argument", DokuCLI_Exception::E_OPT_ARG_REQUIRED);
- }
- $this->options[$opt] = $val;
- } else {
- $this->options[$opt] = true;
- }
- }
-
- // parsing is now done, update args array
- $this->args = $non_opts;
-
- // if not done yet, check if first argument is a command and reexecute argument parsing if it is
- if(!$this->command && $this->args && isset($this->setup[$this->args[0]])) {
- // it is a command!
- $this->command = array_shift($this->args);
- $this->parseOptions(); // second pass
- }
- }
-
- /**
- * Get the value of the given option
- *
- * Please note that all options are accessed by their long option names regardless of how they were
- * specified on commandline.
- *
- * Can only be used after parseOptions() has been run
- *
- * @param string $option
- * @param bool|string $default what to return if the option was not set
- * @return bool|string
- */
- public function getOpt($option, $default = false) {
- if(isset($this->options[$option])) return $this->options[$option];
- return $default;
- }
-
- /**
- * Return the found command if any
- *
- * @return string
- */
- public function getCmd() {
- return $this->command;
- }
-
- /**
- * Builds a help screen from the available options. You may want to call it from -h or on error
- *
- * @return string
- */
- public function help() {
- $text = '';
-
- $hascommands = (count($this->setup) > 1);
- foreach($this->setup as $command => $config) {
- $hasopts = (bool) $this->setup[$command]['opts'];
- $hasargs = (bool) $this->setup[$command]['args'];
-
- if(!$command) {
- $text .= 'USAGE: '.$this->bin;
- } else {
- $text .= "\n$command";
- }
-
- if($hasopts) $text .= ' <OPTIONS>';
-
- foreach($this->setup[$command]['args'] as $arg) {
- if($arg['required']) {
- $text .= ' <'.$arg['name'].'>';
- } else {
- $text .= ' [<'.$arg['name'].'>]';
- }
- }
- $text .= "\n";
-
- if($this->setup[$command]['help']) {
- $text .= "\n";
- $text .= $this->tableFormat(
- array(2, 72),
- array('', $this->setup[$command]['help']."\n")
- );
- }
-
- if($hasopts) {
- $text .= "\n OPTIONS\n\n";
- foreach($this->setup[$command]['opts'] as $long => $opt) {
-
- $name = '';
- if($opt['short']) {
- $name .= '-'.$opt['short'];
- if($opt['needsarg']) $name .= ' <'.$opt['needsarg'].'>';
- $name .= ', ';
- }
- $name .= "--$long";
- if($opt['needsarg']) $name .= ' <'.$opt['needsarg'].'>';
-
- $text .= $this->tableFormat(
- array(2, 20, 52),
- array('', $name, $opt['help'])
- );
- $text .= "\n";
- }
- }
-
- if($hasargs) {
- $text .= "\n";
- foreach($this->setup[$command]['args'] as $arg) {
- $name = '<'.$arg['name'].'>';
-
- $text .= $this->tableFormat(
- array(2, 20, 52),
- array('', $name, $arg['help'])
- );
- }
- }
-
- if($command == '' && $hascommands) {
- $text .= "\nThis tool accepts a command as first parameter as outlined below:\n";
- }
- }
-
- return $text;
- }
-
- /**
- * Safely read the $argv PHP array across different PHP configurations.
- * Will take care on register_globals and register_argc_argv ini directives
- *
- * @throws DokuCLI_Exception
- * @return array the $argv PHP array or PEAR error if not registered
- */
- private function readPHPArgv() {
- global $argv;
- if(!is_array($argv)) {
- if(!@is_array($_SERVER['argv'])) {
- if(!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
- throw new DokuCLI_Exception(
- "Could not read cmd args (register_argc_argv=Off?)",
- DOKU_CLI_OPTS_ARG_READ
- );
- }
- return $GLOBALS['HTTP_SERVER_VARS']['argv'];
- }
- return $_SERVER['argv'];
- }
- return $argv;
- }
-
- /**
- * Displays text in multiple word wrapped columns
- *
- * @param int[] $widths list of column widths (in characters)
- * @param string[] $texts list of texts for each column
- * @return string
- */
- private function tableFormat($widths, $texts) {
- $wrapped = array();
- $maxlen = 0;
-
- foreach($widths as $col => $width) {
- $wrapped[$col] = explode("\n", wordwrap($texts[$col], $width - 1, "\n", true)); // -1 char border
- $len = count($wrapped[$col]);
- if($len > $maxlen) $maxlen = $len;
-
- }
-
- $out = '';
- for($i = 0; $i < $maxlen; $i++) {
- foreach($widths as $col => $width) {
- if(isset($wrapped[$col][$i])) {
- $val = $wrapped[$col][$i];
- } else {
- $val = '';
- }
- $out .= sprintf('%-'.$width.'s', $val);
- }
- $out .= "\n";
- }
- return $out;
- }
-}
-
-/**
- * Class DokuCLI_Exception
- *
- * The code is used as exit code for the CLI tool. This should probably be extended. Many cases just fall back to the
- * E_ANY code.
- *
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-class DokuCLI_Exception extends Exception {
- const E_ANY = -1; // no error code specified
- const E_UNKNOWN_OPT = 1; //Unrecognized option
- const E_OPT_ARG_REQUIRED = 2; //Option requires argument
- const E_OPT_ARG_DENIED = 3; //Option not allowed argument
- const E_OPT_ABIGUOUS = 4; //Option abiguous
- const E_ARG_READ = 5; //Could not read argv
-
- /**
- * @param string $message The Exception message to throw.
- * @param int $code The Exception code
- * @param Exception $previous The previous exception used for the exception chaining.
- */
- public function __construct($message = "", $code = 0, Exception $previous = null) {
- if(!$code) $code = DokuCLI_Exception::E_ANY;
- parent::__construct($message, $code, $previous);
- }
-}
diff --git a/inc/common.php b/inc/common.php
index 2910358c7..c56240a93 100644
--- a/inc/common.php
+++ b/inc/common.php
@@ -587,8 +587,10 @@ function ml($id = '', $more = '', $direct = true, $sep = '&amp;', $abs = false)
if(is_array($more)) {
// add token for resized images
- if(!empty($more['w']) || !empty($more['h']) || $isexternalimage){
- $more['tok'] = media_get_token($id,$more['w'],$more['h']);
+ $w = isset($more['w']) ? $more['w'] : null;
+ $h = isset($more['h']) ? $more['h'] : null;
+ if($w || $h || $isexternalimage){
+ $more['tok'] = media_get_token($id, $w, $h);
}
// strip defaults for shorter URLs
if(isset($more['cache']) && $more['cache'] == 'cache') unset($more['cache']);
@@ -820,7 +822,7 @@ function clientIP($single = false) {
if(empty($ip[$i])) unset($ip[$i]);
}
$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(empty($ip) || !$ip[0]) $ip[0] = '0.0.0.0'; // for some strange reason we don't have a IP
if(!$single) return join(',', $ip);
@@ -2079,7 +2081,7 @@ function set_doku_pref($pref, $val) {
}
$cookieVal = implode('#', $parts);
} else if ($orig === false && $val !== false) {
- $cookieVal = ($_COOKIE['DOKU_PREFS'] ? $_COOKIE['DOKU_PREFS'] . '#' : '') .
+ $cookieVal = (isset($_COOKIE['DOKU_PREFS']) ? $_COOKIE['DOKU_PREFS'] . '#' : '') .
rawurlencode($pref) . '#' . rawurlencode($val);
}
diff --git a/inc/fulltext.php b/inc/fulltext.php
index 79b2c4f8a..7c28a5962 100644
--- a/inc/fulltext.php
+++ b/inc/fulltext.php
@@ -80,7 +80,9 @@ function _ft_pageSearch(&$data) {
case 'W-:':
case 'W_:': // word
$word = substr($token, 3);
- $stack[] = (array) $lookup[$word];
+ if(isset($lookup[$word])) {
+ $stack[] = (array)$lookup[$word];
+ }
break;
case 'P+:':
case 'P-:': // phrase
@@ -266,6 +268,10 @@ function _ft_pageLookup(&$data){
$ns = cleanID($parsedQuery['ns'][0]) . ':';
$id = implode(' ', $parsedQuery['highlight']);
}
+ if (count($parsedQuery['notns']) > 0) {
+ $notns = cleanID($parsedQuery['notns'][0]) . ':';
+ $id = implode(' ', $parsedQuery['highlight']);
+ }
$in_ns = $data['in_ns'];
$in_title = $data['in_title'];
@@ -297,6 +303,13 @@ function _ft_pageLookup(&$data){
}
}
}
+ if (isset($notns)) {
+ foreach (array_keys($pages) as $p_id) {
+ if (strpos($p_id, $notns) === 0) {
+ unset($pages[$p_id]);
+ }
+ }
+ }
// discard hidden pages
// discard nonexistent pages
diff --git a/inc/init.php b/inc/init.php
index 5cf1b56e9..059d7060a 100644
--- a/inc/init.php
+++ b/inc/init.php
@@ -402,8 +402,9 @@ function init_creationmodes(){
unset($conf['dmask']);
unset($conf['fmask']);
unset($conf['umask']);
- unset($conf['fperm']);
- unset($conf['dperm']);
+
+ $conf['fperm'] = false;
+ $conf['dperm'] = false;
// get system umask, fallback to 0 if none available
$umask = @umask();
diff --git a/inc/io.php b/inc/io.php
index 1dfabe845..18eff6858 100644
--- a/inc/io.php
+++ b/inc/io.php
@@ -410,7 +410,7 @@ function io_lock($file){
if ((time() - $timeStart) > 3) break;
$locked = @mkdir($lockDir, $conf['dmode']);
if($locked){
- if(!empty($conf['dperm'])) chmod($lockDir, $conf['dperm']);
+ if($conf['dperm']) chmod($lockDir, $conf['dperm']);
break;
}
usleep(50);
diff --git a/inc/lang/de-informal/lang.php b/inc/lang/de-informal/lang.php
index e8b12f502..60a870c45 100644
--- a/inc/lang/de-informal/lang.php
+++ b/inc/lang/de-informal/lang.php
@@ -3,6 +3,8 @@
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
+ * @author MaWi <drmaxxis@gmail.com>
+ * @author lp <spam@lukpopp.ch>
* @author Martin <martin@andev.de>
* @author F. Mueller-Donath <j.felix@mueller-donath.de>
* @author Andreas Gohr <andi@splitbrain.org>
@@ -85,6 +87,7 @@ $lang['badpassconfirm'] = 'Das Passwort war falsch.';
$lang['minoredit'] = 'Kleine Änderung';
$lang['draftdate'] = 'Entwurf gespeichert am';
$lang['nosecedit'] = 'Diese Seite wurde in der Zwischenzeit geändert, da das Sektionsinfo veraltet ist. Die ganze Seite wird stattdessen geladen.';
+$lang['searchcreatepage'] = 'Falls der gesuchte Begriff nicht gefunden wurde, kannst du direkt eine neue, nach deiner Anfrage benannte Seite %s anlegen.';
$lang['search_fullresults'] = 'Volltextergebnisse';
$lang['js']['search_toggle_tools'] = 'Suchwerkzeuge umschalten';
$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.';
@@ -312,8 +315,11 @@ $lang['i_superuser'] = 'Benutzername des Administrators';
$lang['i_problems'] = 'Das Installationsprogramm hat unten aufgeführte Probleme festgestellt, die zunächst behoben werden müssen, bevor du mit der Installation fortfahren kannst.';
$lang['i_modified'] = 'Aus Sicherheitsgründen arbeitet dieses Skript nur mit einer neuen bzw. nicht modifizierten DokuWiki-Installation. Du solltest entweder alle Dateien noch einmal frisch installieren oder die <a href="http://dokuwiki.org/install">Dokuwiki-Installationsanleitung</a> konsultieren.';
$lang['i_funcna'] = 'Die PHP-Funktion <code>%s</code> ist nicht verfügbar. Unter Umständen wurde sie von deinem Hoster deaktiviert?';
+$lang['i_disabled'] = 'Es wurde von deinem Provider deaktiviert.';
+$lang['i_funcnmail'] = '<b>Hinweis:</b> Die PHP-Funktion "mail()" ist nicht verfügbar. %s Alternativ kansnt du das <a href="https://www.dokuwiki.org/plugin:smtp">SMTP-Plugin</a> installieren.';
$lang['i_phpver'] = 'Deine PHP-Version <code>%s</code> ist niedriger als die benötigte Version <code>%s</code>. Bitte aktualisiere deine PHP-Installation.';
$lang['i_mbfuncoverload'] = 'mbstring.func_overload muss in php.in deaktiviert werden um DokuWiki auszuführen.';
+$lang['i_urandom'] = 'DokuWiki kann keine kryptografisch sicheren Werte für Cookies generieren. Möglicherweise möchtest du die "open_basedir"-Einstellungen in der zutreffenden php.ini auf korrekten Zugriff auf <code>/ dev/urandom</ code> überprüfen.';
$lang['i_permfail'] = '<code>%s</code> ist nicht durch DokuWiki beschreibbar. Du musst die Berechtigungen dieses Ordners ändern!';
$lang['i_confexists'] = '<code>%s</code> existiert bereits';
$lang['i_writeerr'] = '<code>%s</code> konnte nicht erzeugt werden. Du solltest die Verzeichnis-/Datei-Rechte überprüfen und die Datei manuell anlegen.';
@@ -364,6 +370,7 @@ $lang['media_perm_upload'] = 'Du besitzt nicht die notwendigen Berechtigunge
$lang['media_update'] = 'Neue Version hochladen';
$lang['media_restore'] = 'Diese Version wiederherstellen';
$lang['media_acl_warning'] = 'Diese Liste ist möglicherweise nicht vollständig. Versteckte und durch ACL gesperrte Seiten werden nicht angezeigt.';
+$lang['email_fail'] = 'PHP-Funktion "mail ()" fehlt oder ist deaktiviert. Die folgende E-Mail wurde nicht gesendet:';
$lang['currentns'] = 'Aktueller Namensraum';
$lang['searchresult'] = 'Suchergebnis';
$lang['plainhtml'] = 'Reines HTML';
diff --git a/inc/lang/de-informal/onceexisted.txt b/inc/lang/de-informal/onceexisted.txt
new file mode 100644
index 000000000..c5408f479
--- /dev/null
+++ b/inc/lang/de-informal/onceexisted.txt
@@ -0,0 +1,3 @@
+======= Diese Seite existiert nicht mehr ======
+
+Du bist einem Link zu einer Seite gefolgt, den es nicht mehr gibt. Um zu sehen, wann und warum diese Seite gelöscht bzw. um ältere Versionen zu besichtigen oder zu laden, besuche [[?do=revisions|old revisions]]. \ No newline at end of file
diff --git a/inc/lang/de/lang.php b/inc/lang/de/lang.php
index 7e455b0f2..07fbb3b8f 100644
--- a/inc/lang/de/lang.php
+++ b/inc/lang/de/lang.php
@@ -3,6 +3,7 @@
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
+ * @author Markus Glaser <glaser@hallowelt.com>
* @author Axel Schwarzer <SchwarzerA@gmail.com>
* @author Andreas Gohr <andi@splitbrain.org>
* @author Eric Haberstroh <ehaberstroh@gmail.com>
@@ -148,6 +149,7 @@ $lang['js']['media_done_btn'] = 'Fertig';
$lang['js']['media_drop'] = 'Dateien hier hinziehen, um sie hochzuladen';
$lang['js']['media_cancel'] = 'Entfernen';
$lang['js']['media_overwrt'] = 'Existierende Dateien überschreiben';
+$lang['js']['data_insecure'] = 'WARNUNG: Es scheint, als wäre Ihr Datenverzeichnis nicht ausreichend geschützt. Bitte informieren Sie sich zur <a href="https://www.dokuwiki.org/security#web_access_security">Sicherheit von Webzugriffen in DokuWiki</a>';
$lang['search_exact_match'] = 'Genaue Treffer';
$lang['search_starts_with'] = 'Beginnt mit';
$lang['search_ends_with'] = 'Endet mit';
diff --git a/inc/lang/en/lang.php b/inc/lang/en/lang.php
index 000368ac2..9e56d6f84 100644
--- a/inc/lang/en/lang.php
+++ b/inc/lang/en/lang.php
@@ -171,6 +171,7 @@ $lang['js']['media_done_btn'] = 'Done';
$lang['js']['media_drop'] = 'Drop files here to upload';
$lang['js']['media_cancel'] = 'remove';
$lang['js']['media_overwrt'] = 'Overwrite existing files';
+$lang['js']['data_insecure'] = 'WARNING: It seems your data directory is not properly secured. Please read about <a href="https://www.dokuwiki.org/security#web_access_security">Web Access Security in DokuWiki</a>.';
$lang['rssfailed'] = 'An error occurred while fetching this feed: ';
$lang['nothingfound'] = 'Nothing was found.';
diff --git a/inc/lang/es/lang.php b/inc/lang/es/lang.php
index 6c5c448e3..f157fd5af 100644
--- a/inc/lang/es/lang.php
+++ b/inc/lang/es/lang.php
@@ -3,6 +3,7 @@
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
+ * @author Luna Frax <lunafrax@gmail.com>
* @author Domingo Redal <docxml@gmail.com>
* @author Liliana <lilianasaidon@gmail.com>
* @author Alex Cachinero <anarres@protonmail.com>
@@ -201,6 +202,7 @@ $lang['txt_upload'] = 'Selecciona el archivo a subir:';
$lang['txt_filename'] = 'Subir como (opcional):';
$lang['txt_overwrt'] = 'Sobreescribir archivo existente';
$lang['maxuploadsize'] = 'Peso máximo de %s por archivo';
+$lang['allowedmime'] = 'Lista de extensiones de archivo permitidas';
$lang['lockedby'] = 'Actualmente bloqueado por:';
$lang['lockexpire'] = 'El bloqueo expira en:';
$lang['rssfailed'] = 'Se ha producido un error mientras se leían los datos de este feed: ';
diff --git a/inc/lang/fr/lang.php b/inc/lang/fr/lang.php
index bf456383b..89b069eeb 100644
--- a/inc/lang/fr/lang.php
+++ b/inc/lang/fr/lang.php
@@ -3,9 +3,10 @@
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
+ * @author Olivier Humbert <trebmuh@tuxfamily.org>
+ * @author Nicolas Friedli <nicolas@theologique.ch>
* @author Schplurtz le Déboulonné <Schplurtz@laposte.net>
* @author Pierre Henriot <pierre.henriot@gmail.com>
- * @author Nicolas Friedli <nicolas@theologique.ch>
* @author PaliPalo <palipalo@hotmail.fr>
* @author Laurent Ponthieu <contact@coopindus.fr>
* @author Damien Regad <dregad@mantisbt.org>
@@ -43,7 +44,6 @@
* @author Pietroni <pietroni@informatique.univ-paris-diderot.fr>
* @author Floriang <antispam@floriang.eu>
* @author Eric <ericstevenart@netc.fr>
- * @author Olivier Humbert <trebmuh@tuxfamily.org>
*/
$lang['encoding'] = 'utf-8';
$lang['direction'] = 'ltr';
@@ -148,6 +148,7 @@ $lang['js']['media_done_btn'] = 'Terminé';
$lang['js']['media_drop'] = 'Déposez des fichiers ici pour les envoyer';
$lang['js']['media_cancel'] = 'supprimer';
$lang['js']['media_overwrt'] = 'Écraser les fichiers existants';
+$lang['js']['data_insecure'] = 'ATTENTION : votre répertoire de données ne semble pas correctement sécurisé. Veuillez lire <a href="https://www.dokuwiki.org/fr:security#securite_de_l_acces_web">Sécurité de l\'accès web (en français)</a> ou <a href="https://www.dokuwiki.org/security#web_access_security">Web Access Security in DokuWiki (en anglais)</a>.';
$lang['search_exact_match'] = 'Correspondance exacte';
$lang['search_starts_with'] = 'Commence par';
$lang['search_ends_with'] = 'Se termine par';
@@ -304,9 +305,9 @@ $lang['img_artist'] = 'Photographe:';
$lang['img_copyr'] = 'Copyright:';
$lang['img_format'] = 'Format:';
$lang['img_camera'] = 'Appareil photo:';
-$lang['img_keywords'] = 'Mots-clés:';
-$lang['img_width'] = 'Largeur:';
-$lang['img_height'] = 'Hauteur:';
+$lang['img_keywords'] = 'Mots-clés :';
+$lang['img_width'] = 'Largeur :';
+$lang['img_height'] = 'Hauteur :';
$lang['subscr_subscribe_success'] = '%s a été ajouté à la liste des abonnés à %s';
$lang['subscr_subscribe_error'] = 'Erreur à l\'ajout de %s à la liste des abonnés de %s';
$lang['subscr_subscribe_noaddress'] = 'Il n\'y a pas d\'adresse associée à votre identifiant, vous ne pouvez pas être ajouté à la liste des abonnés.';
diff --git a/inc/lang/hy/admin.txt b/inc/lang/hy/admin.txt
new file mode 100644
index 000000000..9b2eea7bb
--- /dev/null
+++ b/inc/lang/hy/admin.txt
@@ -0,0 +1,3 @@
+====== Ղեկավարում ======
+
+Ստորև կարող ես գտնել ԴոկուՎիքիում հասանելի ղեկավարման առաջադրանքները։ \ No newline at end of file
diff --git a/inc/lang/hy/adminplugins.txt b/inc/lang/hy/adminplugins.txt
new file mode 100644
index 000000000..253eac22e
--- /dev/null
+++ b/inc/lang/hy/adminplugins.txt
@@ -0,0 +1 @@
+===== Լրացուցիչ հավելումներ ===== \ No newline at end of file
diff --git a/inc/lang/hy/conflict.txt b/inc/lang/hy/conflict.txt
new file mode 100644
index 000000000..9b117f2fc
--- /dev/null
+++ b/inc/lang/hy/conflict.txt
@@ -0,0 +1,5 @@
+====== Գոյություն ունի նոր տարբերակ ======
+
+Գոյություն ունի խմբագրված փաստաթղթի նոր տարբերակ։ Քո խմբագրելու ընթացքում մեկ այլ օգտատեր փոփոխել է այս փաստաթուղթը։
+
+Դիտիր ստորև ցուցադրվող տարբերակները և որոշիր, որն ես ցանկանում պահպանել։ Եթե ընտրես «պահել», քո տարբերակը կպահպանվի։ Սեղմիր «չեղարկել»՝ ներկա տարբերակը պահպանելու համար; \ No newline at end of file
diff --git a/inc/lang/hy/denied.txt b/inc/lang/hy/denied.txt
new file mode 100644
index 000000000..c9ccc72bf
--- /dev/null
+++ b/inc/lang/hy/denied.txt
@@ -0,0 +1,3 @@
+====== Չի թույլատրվում ======
+
+Ցավոք, դու չունես բավարար իրավունքներ շարունակելու համար։ \ No newline at end of file
diff --git a/inc/lang/hy/diff.txt b/inc/lang/hy/diff.txt
new file mode 100644
index 000000000..5816dccf3
--- /dev/null
+++ b/inc/lang/hy/diff.txt
@@ -0,0 +1,3 @@
+====== Տարբերություններ ======
+
+Ցույց է տալիս էջի երկու տարբերակների միջև առկա տարբերությունները։ \ No newline at end of file
diff --git a/inc/lang/hy/draft.txt b/inc/lang/hy/draft.txt
new file mode 100644
index 000000000..123167aba
--- /dev/null
+++ b/inc/lang/hy/draft.txt
@@ -0,0 +1,5 @@
+====== Գտնվել է սևագիր տարբերակ ======
+
+Քո նախորդ խմբագրման սեսիան հաջողությամբ չի ավարտվել։ ԴոկուՎիքին քո աշխատանքի ընթացքում ավտոմատ պահպանել է սևագիր տարբերակ, որը դու այժմ կարող ես օգտագործել խմբագրումը շարունակելու համար։ Ստորև կարող ես գտնել վերջին սեսիայից պահպանված տվյալները։
+
+Խնդրում ենք, որոշիչ՝ ցանկանում ես //վերականգնել// կորսված խմբագրման սեսիան, //ջնջել// ավտոմատ պահպանված սևագիրը, թե //չեղարկել// խմբագրման գործընթացը։ \ No newline at end of file
diff --git a/inc/lang/hy/edit.txt b/inc/lang/hy/edit.txt
new file mode 100644
index 000000000..776e3f44c
--- /dev/null
+++ b/inc/lang/hy/edit.txt
@@ -0,0 +1 @@
+Խմբագրիր այս էջը և սեղմիր //Պահել//։ Կարդա [[wiki:syntax]] էջը այս վիքիի շարահյուսությանը ծանոթանալու համար։ Խնդրում ենք խմբագրել այս էջը միայն եթե կարող ես **բարելավել** այն։ Եթե ցանկանում ես փորձարկել, առաջին քայլերդ արա [[playground:playground|խաղահրապարակում]]։ \ No newline at end of file
diff --git a/inc/lang/hy/editrev.txt b/inc/lang/hy/editrev.txt
new file mode 100644
index 000000000..31d7d0ae5
--- /dev/null
+++ b/inc/lang/hy/editrev.txt
@@ -0,0 +1,2 @@
+**Դու բեռնել ես այս փաստաթղթի հին տարբերակ։** Եթե պահես այն, այս տվյալներով կստեղծես էջի նոր տարբեակ։
+---- \ No newline at end of file
diff --git a/inc/lang/hy/index.txt b/inc/lang/hy/index.txt
new file mode 100644
index 000000000..1b213836b
--- /dev/null
+++ b/inc/lang/hy/index.txt
@@ -0,0 +1,3 @@
+====== Կայքի քարտեզ ======
+
+Սա բոլոր առկա էջերի քարտեզն է, որը դասավորված է ըստ [[doku>namespaces|անվանատարածքների]]։ \ No newline at end of file
diff --git a/inc/lang/hy/lang.php b/inc/lang/hy/lang.php
new file mode 100644
index 000000000..0d253489b
--- /dev/null
+++ b/inc/lang/hy/lang.php
@@ -0,0 +1,133 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Davit Saroyan <saroyandavid@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '«';
+$lang['doublequoteclosing'] = '»';
+$lang['singlequoteopening'] = '«';
+$lang['singlequoteclosing'] = '»';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Խմբագրել էջը';
+$lang['btn_source'] = 'Ցուցադրել սկզբնաղբյուրը';
+$lang['btn_show'] = 'Ցուցադրել էջը';
+$lang['btn_create'] = 'Ստեղծել էջը';
+$lang['btn_search'] = 'Որոնել';
+$lang['btn_save'] = 'Պահել';
+$lang['btn_preview'] = 'Նախադիտել';
+$lang['btn_top'] = 'Վերադառնալ վեր';
+$lang['btn_newer'] = '<< ավել վաղ';
+$lang['btn_older'] = 'ավելի ուշ >>';
+$lang['btn_revs'] = 'Հին տարբերակներ';
+$lang['btn_recent'] = 'Վերջին փոփոխություններ';
+$lang['btn_upload'] = 'Վերբեռնել';
+$lang['btn_cancel'] = 'Չեղարկել';
+$lang['btn_index'] = 'Կայքի քարտեզ';
+$lang['btn_secedit'] = 'Խմբագրել';
+$lang['btn_login'] = 'Մուտք գործել';
+$lang['btn_logout'] = 'Դուրս գալ';
+$lang['btn_admin'] = 'Ադմին';
+$lang['btn_update'] = 'Թարմացնել';
+$lang['btn_delete'] = 'Ջնջել';
+$lang['btn_back'] = 'Հետ';
+$lang['btn_backlink'] = 'Հղվող էջեր';
+$lang['btn_subscribe'] = 'Կառավարել բաժանորդագրությունները';
+$lang['btn_profile'] = 'Թարմացնել հաշիվը';
+$lang['btn_reset'] = 'Վերագործարկել';
+$lang['btn_resendpwd'] = 'Սահմանել նոր գաղտնաբառ';
+$lang['btn_draft'] = 'Խմբագրել սևագիրը';
+$lang['btn_recover'] = 'Վերականգնել սևագիրը';
+$lang['btn_draftdel'] = 'Ջնջել սևագիրը';
+$lang['btn_revert'] = 'Վերականգնել';
+$lang['btn_register'] = 'Գրանցվել';
+$lang['btn_apply'] = 'Կիրառել';
+$lang['btn_media'] = 'Մեդիայի կառավարիչ';
+$lang['btn_deleteuser'] = 'Ջնջել իմ հաշիվը';
+$lang['btn_img_backto'] = 'Վերդառանալ %s';
+$lang['btn_mediaManager'] = 'Դիտել մեդիայի կառավարչում';
+$lang['loggedinas'] = 'Մուտք գործած որպես՝';
+$lang['user'] = 'Մասնակցային անուն';
+$lang['pass'] = 'Գաղտնաբառ';
+$lang['newpass'] = 'Նոր գաղտնաբառ';
+$lang['oldpass'] = 'Հաստատել ներկա գաղտնաբառը';
+$lang['passchk'] = 'կրկին';
+$lang['remember'] = 'Հիշել ինձ';
+$lang['fullname'] = 'Իրական անուն';
+$lang['email'] = 'Էլեկտրոնային հասցե';
+$lang['profile'] = 'Մասնակցային հաշիվ';
+$lang['badlogin'] = 'Մասնակցային անունն ու գաղտնաբառը ցավոք սխալ են';
+$lang['badpassconfirm'] = 'Գաղտնաբառը ցավոք սխալ է';
+$lang['minoredit'] = 'Աննշան փոփոխություններ';
+$lang['draftdate'] = 'Սևագրի ավտոմատ պահպանումը միացված է';
+$lang['searchcreatepage'] = 'Եթե չգտար ինչ փնտրում էին, կարող ես ստեղծել կամ խմբագրել %s էջը, որը համապատասխանում է հարցմանը։';
+$lang['search_fullresults'] = 'Ամբողջական տեքստի արդյունքներ';
+$lang['js']['search_toggle_tools'] = 'Ցուցադրել որոնման գործիքները';
+$lang['js']['notsavedyet'] = 'Չպահպանված փոփոխությունները կկորչեն';
+$lang['js']['searchmedia'] = 'Որոնել նիշքեր';
+$lang['js']['hidedetails'] = 'Թաքցնել տվյալները';
+$lang['js']['mediatitle'] = 'Հղման ընտրանքներ';
+$lang['js']['mediadisplay'] = 'Հղման տեսակ';
+$lang['js']['mediaalign'] = 'Դասավորություն';
+$lang['js']['mediasize'] = 'Պատկերի չափս';
+$lang['js']['mediatarget'] = 'Հղման թիրախ';
+$lang['js']['mediaclose'] = 'Փակել';
+$lang['js']['mediainsert'] = 'Ներդնել';
+$lang['js']['mediadisplayimg'] = 'Ցուցադրել պատկերը։';
+$lang['js']['mediadisplaylnk'] = 'Ցուցադրել միայն հղումը։';
+$lang['js']['mediasmall'] = 'Փոքր տարբերակ';
+$lang['js']['mediamedium'] = 'Միջին տարբերակ';
+$lang['js']['medialarge'] = 'Մեծ տարբերակ';
+$lang['js']['mediaoriginal'] = 'Բնօրինակ տարբերակ';
+$lang['js']['medialnk'] = 'Հղում դեպի մանրամասների էջ';
+$lang['js']['mediadirect'] = 'Ուղիղ հղում դեպի բնօրինակ';
+$lang['js']['medianolnk'] = 'Առանց հղում';
+$lang['js']['medianolink'] = 'Չհղել պատկերը';
+$lang['js']['medialeft'] = 'Պատկերը դասավորել ձախում';
+$lang['js']['mediaright'] = 'Պատկերը դասավորել աջում';
+$lang['js']['mediacenter'] = 'Պատկերը դասավորել մեջտեղում';
+$lang['js']['medianoalign'] = 'Առանց դասավորության';
+$lang['js']['linkwiz'] = 'Հղումների օգնական';
+$lang['js']['linkto'] = 'Հղում դեպի՝';
+$lang['js']['del_confirm'] = 'Ջնջե՞լ ընտրվածը։';
+$lang['js']['restore_confirm'] = 'Վերականգնե՞լ այս տրաբերակը։';
+$lang['js']['media_diff'] = 'Դիտել տարբերությունը՝ ';
+$lang['js']['media_diff_both'] = 'Կողք կողքի';
+$lang['js']['media_diff_portions'] = 'Սահեցնել';
+$lang['js']['media_select'] = 'Ընտրել նիշքեր…';
+$lang['js']['media_upload_btn'] = 'Վերբեռնել';
+$lang['js']['media_done_btn'] = 'Արված է';
+$lang['js']['media_drop'] = 'Վերբեռնելու համար նիշքերը գցել այստեղ';
+$lang['js']['media_cancel'] = 'ջնջել';
+$lang['js']['media_overwrt'] = 'Փոխարինել գոյություն ունեցող նիշքերը';
+$lang['search_exact_match'] = 'Նույնական';
+$lang['search_starts_with'] = 'Սկսում է';
+$lang['search_ends_with'] = 'Ավարտվում է';
+$lang['search_contains'] = 'Պարունակում է';
+$lang['search_custom_match'] = 'Ընտրովի';
+$lang['search_any_ns'] = 'Ցանկացած անվանատարածք';
+$lang['search_any_time'] = 'Ցանկացած ժամանակ';
+$lang['search_past_7_days'] = 'Անցյալ շաբաթ';
+$lang['search_past_month'] = 'Անցյալ ամիս';
+$lang['search_past_year'] = 'Անցյալ տարի';
+$lang['search_sort_by_hits'] = 'Դասավորել ըստ այցելումների';
+$lang['search_sort_by_mtime'] = 'Դասավորել ըստ վերջին փոփոխման';
+$lang['regmissing'] = 'Պետք է լրացնել բոլոր դաշտերը։';
+$lang['reguexists'] = 'Այս մասնակցային անունով օգտատեր արդեն գոյություն ունի։';
+$lang['regsuccess'] = 'Մասնակցային հաշիվը ստեղծվեց, գաղտնաբառը ուղարկվել է էլեկտրոնային հասցեին։';
+$lang['regsuccess2'] = 'Մասնակցային հաշիվը ստեղծվեց։';
+$lang['regfail'] = 'Մասնակցային հաշիվը հրանավոր չէ ստեղծել։';
+$lang['regbadpass'] = 'Առաջարկված երկու գաղտնաբառերը միմյանց չեն համապատասխանում, խնդրում ենք, նորից փորձել։';
+$lang['regpwmail'] = 'ԴոկուՎիքիի քո գաղտնաբառը';
+$lang['reghere'] = 'Դեռ հաշիվ չունե՞ս։ Գրանցվի՛ր։';
+$lang['profna'] = 'Այս վիքին չի աջակցում մասնակցային հաշվի փոփոխությունները';
+$lang['profnoempty'] = 'Դատարկ անունը կամ էլեկտրոնային հասցեն չի թույլատրվում։';
+$lang['profchanged'] = 'Մասնակցային հաշիվը հաջողությամբ թարմացվեց';
+$lang['profnodelete'] = 'Այս վիքիում հնարավոր չէ ջնջել օգտատերերին';
+$lang['profdeleteuser'] = 'Ջնջել հաշիվը';
+$lang['profdeleted'] = 'Քո մասնակցային հաշիվը ջնջվեց այս վիքիից';
+$lang['profconfdelete'] = 'Ցանկացնում եմ ջնջել իմ հաշիվը այս վիքիից։ <br/> Այս գործողությունը հնարավոր չէ չեղարկել։';
+$lang['profconfdeletemissing'] = 'Հաստատման վանդակը ընտրված չէ';
diff --git a/inc/lang/it/lang.php b/inc/lang/it/lang.php
index 8294101a4..7be236da4 100644
--- a/inc/lang/it/lang.php
+++ b/inc/lang/it/lang.php
@@ -3,6 +3,7 @@
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
+ * @author Dario <darioriso@virgilio.it>
* @author Filippo <abrickslife@gmail.com>
* @author Roberto Bellingeri <bellingeri@netguru.it>
* @author Eddy <eddy@mail.it>
@@ -180,6 +181,7 @@ $lang['txt_upload'] = 'Seleziona un file da caricare:';
$lang['txt_filename'] = 'Carica come (opzionale):';
$lang['txt_overwrt'] = 'Sovrascrivi file esistente';
$lang['maxuploadsize'] = 'Upload max. %s per ogni file.';
+$lang['allowedmime'] = 'Elenco delle estensioni di file consentite';
$lang['lockedby'] = 'Attualmente bloccato da:';
$lang['lockexpire'] = 'Il blocco scade alle:';
$lang['rssfailed'] = 'Si è verificato un errore cercando questo feed: ';
diff --git a/inc/lang/pt/lang.php b/inc/lang/pt/lang.php
index c00204232..f66cd23be 100644
--- a/inc/lang/pt/lang.php
+++ b/inc/lang/pt/lang.php
@@ -3,6 +3,7 @@
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
+ * @author Gustavo B. Schenkel <gustavo.schenkel@gmail.com>
* @author Paulo <pschopf@gmail.com>
* @author Mario AlexandTeixeira dos Santos <masterofclan@gmail.com>
* @author Maykon Oliveira <maykonoliveira850@gmail.com>
@@ -124,6 +125,7 @@ $lang['js']['media_done_btn'] = 'Feito';
$lang['js']['media_drop'] = 'Largue arquivo aqui para enviar';
$lang['js']['media_cancel'] = 'excluir';
$lang['js']['media_overwrt'] = 'Escrever por cima de arquivos existentes';
+$lang['js']['data_insecure'] = 'AVISO: Parece que seu diretório de dados não está devidamente protegido. Por favor leia sobre <a href="https://www.dokuwiki.org/security#web_access_security">Segurança de acesso à web em DokuWiki</a>.';
$lang['search_exact_match'] = 'Correspondência exata';
$lang['search_starts_with'] = 'Começa por';
$lang['search_ends_with'] = 'Termina em';
diff --git a/inc/lang/ru/lang.php b/inc/lang/ru/lang.php
index 7c855ceea..ca41a04ee 100644
--- a/inc/lang/ru/lang.php
+++ b/inc/lang/ru/lang.php
@@ -3,6 +3,7 @@
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
+ * @author Nikita <obraztsov568@gmail.com>
* @author Aleksandr Selivanov <alexgearbox@yandex.ru>
* @author Анатолий <anatol_m@mail.ru>
* @author Yuriy Skalko <yuriy.skalko@gmail.com>
diff --git a/inc/lang/sv/lang.php b/inc/lang/sv/lang.php
index 14864212e..f26071c5d 100644
--- a/inc/lang/sv/lang.php
+++ b/inc/lang/sv/lang.php
@@ -3,6 +3,7 @@
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
+ * @author Patrik K Lundberg <patrik.kotiranta.lundberg@gmail.com>
* @author Tor Härnqvist <tor@harnqvist.se>
* @author Joaquim Homrighausen <joho@webbplatsen.se>
* @author Per Foreby <per@foreby.se>
@@ -78,44 +79,9 @@ $lang['badpassconfirm'] = 'Ledsen, lösenordet var felaktigt';
$lang['minoredit'] = 'Små ändringar';
$lang['draftdate'] = 'Utkast automatiskt sparat';
$lang['nosecedit'] = 'Sidan ändrades medan du skrev, sektionsinformationen var inte uppdaterad. Laddar hela sidan istället.';
-$lang['regmissing'] = 'Du måste fylla i alla fälten.';
-$lang['reguexists'] = 'Det finns redan en användare med det användarnamnet.';
-$lang['regsuccess'] = 'Användarkontot skapat, lösenordet har skickats via e-post.';
-$lang['regsuccess2'] = 'Användarkontot skapat.';
-$lang['regfail'] = 'Användaren kunde inte skapas.';
-$lang['regmailfail'] = 'Ett fel uppstod när ditt lösenord skulle skickas via e-post. Var god kontakta administratören!';
-$lang['regbadmail'] = 'Den angivna e-postadressen verkar vara ogiltig - om du anser detta felaktigt, var god kontakta administratören';
-$lang['regbadpass'] = 'De två angivna lösenorden är inte identiska. Försök igen.';
-$lang['regpwmail'] = 'Ditt DokuWikilösenord';
-$lang['reghere'] = 'Har du inte ett konto än? Skaffa ett';
-$lang['profna'] = 'Denna wiki stödjer inte ändringar av profiler';
-$lang['profnochange'] = 'Ingenting ändrades, inget att göra.';
-$lang['profnoempty'] = 'Namn och e-postadress måste fyllas i.';
-$lang['profchanged'] = 'Användarprofilen uppdaterad.';
-$lang['profnodelete'] = 'Den här wiki:n stödjer ej borttagning av användare';
-$lang['profdeleteuser'] = 'Radera kontot';
-$lang['profdeleted'] = 'Ditt användarkonto har raderats från den här wiki:n';
-$lang['profconfdelete'] = 'Jag vill ta bort mitt konto/inlogg på den här wiki:n <br/> Denna åtgärd går ej att ångra.';
-$lang['profconfdeletemissing'] = 'Bekräftelse-kryssrutan är ej markerad';
-$lang['proffail'] = 'Användarprofilen uppdaterades ej.';
-$lang['pwdforget'] = 'Glömt ditt lösenord? Ordna ett nytt';
-$lang['resendna'] = 'Den här wikin stödjer inte utskick av lösenord.';
-$lang['resendpwd'] = 'Sätt lösenord för';
-$lang['resendpwdmissing'] = 'Du måste fylla i alla fält.';
-$lang['resendpwdnouser'] = 'Den här användaren hittas inte i databasen.';
-$lang['resendpwdbadauth'] = 'Den här verifieringskoden är inte giltig. Kontrollera att du använde hela verifieringslänken.';
-$lang['resendpwdconfirm'] = 'En verifieringslänk har skickats med e-post.';
-$lang['resendpwdsuccess'] = 'Ditt nya lösenord har skickats med e-post.';
-$lang['license'] = 'Om inte annat angivet, innehållet i denna wiki är licensierat under följande licenser:';
-$lang['licenseok'] = 'Notera: Genom att ändra i denna sidan så accepterar du att licensiera ditt bidrag under följande licenser:';
-$lang['searchmedia'] = 'Sök efter filnamn:';
-$lang['searchmedia_in'] = 'Sök i %s';
-$lang['txt_upload'] = 'Välj fil att ladda upp:';
-$lang['txt_filename'] = 'Ladda upp som (ej obligatoriskt):';
-$lang['txt_overwrt'] = 'Skriv över befintlig fil';
-$lang['maxuploadsize'] = 'Max %s per uppladdad fil.';
-$lang['lockedby'] = 'Låst av:';
-$lang['lockexpire'] = 'Lås upphör att gälla:';
+$lang['searchcreatepage'] = 'Om du inte hittade det du sökte så kan du skapa eller editera sidan %s som är döpt efter din sökning.';
+$lang['search_fullresults'] = 'Heltext resultat';
+$lang['js']['search_toggle_tools'] = 'Växla sökverktyg';
$lang['js']['willexpire'] = 'Ditt redigeringslås för detta dokument kommer snart att upphöra.\nFör att undvika versionskonflikter bör du förhandsgranska ditt dokument för att förlänga redigeringslåset.';
$lang['js']['notsavedyet'] = 'Det finns ändringar som inte är sparade.
Är du säker på att du vill fortsätta?';
@@ -142,6 +108,7 @@ $lang['js']['medianolink'] = 'Länka inte bilden';
$lang['js']['medialeft'] = 'Justera bilden till vänster.';
$lang['js']['mediaright'] = 'Justera bilden till höger.';
$lang['js']['mediacenter'] = 'Centrera bilden.';
+$lang['js']['medianoalign'] = 'Använd ingen justering';
$lang['js']['nosmblinks'] = 'Länkning till Windowsresurser fungerar bara med Microsofts Internet Explorer.
Du kan fortfarande klippa och klistra in länken om du använder en annan webbläsare än MSIE.';
$lang['js']['linkwiz'] = 'Snabbguide Länkar';
@@ -158,6 +125,57 @@ $lang['js']['media_done_btn'] = 'Färdig';
$lang['js']['media_drop'] = 'Släpp filer här för att ladda upp';
$lang['js']['media_cancel'] = 'ta bort';
$lang['js']['media_overwrt'] = 'Skriv över existerande filer';
+$lang['search_exact_match'] = 'Exakt träff';
+$lang['search_starts_with'] = 'Börjar med';
+$lang['search_ends_with'] = 'Slutar med';
+$lang['search_contains'] = 'Innehåller';
+$lang['search_custom_match'] = 'Anpassad';
+$lang['search_any_ns'] = 'Alla namespaces';
+$lang['search_any_time'] = 'Alla tider';
+$lang['search_past_7_days'] = 'Senaste veckan';
+$lang['search_past_month'] = 'Senaste månaden';
+$lang['search_past_year'] = 'Senaste året';
+$lang['search_sort_by_hits'] = 'Sortera efter träffar';
+$lang['search_sort_by_mtime'] = 'Sortera efter senast modifierad';
+$lang['regmissing'] = 'Du måste fylla i alla fälten.';
+$lang['reguexists'] = 'Det finns redan en användare med det användarnamnet.';
+$lang['regsuccess'] = 'Användarkontot skapat, lösenordet har skickats via e-post.';
+$lang['regsuccess2'] = 'Användarkontot skapat.';
+$lang['regfail'] = 'Användaren kunde inte skapas.';
+$lang['regmailfail'] = 'Ett fel uppstod när ditt lösenord skulle skickas via e-post. Var god kontakta administratören!';
+$lang['regbadmail'] = 'Den angivna e-postadressen verkar vara ogiltig - om du anser detta felaktigt, var god kontakta administratören';
+$lang['regbadpass'] = 'De två angivna lösenorden är inte identiska. Försök igen.';
+$lang['regpwmail'] = 'Ditt DokuWikilösenord';
+$lang['reghere'] = 'Har du inte ett konto än? Skaffa ett';
+$lang['profna'] = 'Denna wiki stödjer inte ändringar av profiler';
+$lang['profnochange'] = 'Ingenting ändrades, inget att göra.';
+$lang['profnoempty'] = 'Namn och e-postadress måste fyllas i.';
+$lang['profchanged'] = 'Användarprofilen uppdaterad.';
+$lang['profnodelete'] = 'Den här wiki:n stödjer ej borttagning av användare';
+$lang['profdeleteuser'] = 'Radera kontot';
+$lang['profdeleted'] = 'Ditt användarkonto har raderats från den här wiki:n';
+$lang['profconfdelete'] = 'Jag vill ta bort mitt konto/inlogg på den här wiki:n <br/> Denna åtgärd går ej att ångra.';
+$lang['profconfdeletemissing'] = 'Bekräftelse-kryssrutan är ej markerad';
+$lang['proffail'] = 'Användarprofilen uppdaterades ej.';
+$lang['pwdforget'] = 'Glömt ditt lösenord? Ordna ett nytt';
+$lang['resendna'] = 'Den här wikin stödjer inte utskick av lösenord.';
+$lang['resendpwd'] = 'Sätt lösenord för';
+$lang['resendpwdmissing'] = 'Du måste fylla i alla fält.';
+$lang['resendpwdnouser'] = 'Den här användaren hittas inte i databasen.';
+$lang['resendpwdbadauth'] = 'Den här verifieringskoden är inte giltig. Kontrollera att du använde hela verifieringslänken.';
+$lang['resendpwdconfirm'] = 'En verifieringslänk har skickats med e-post.';
+$lang['resendpwdsuccess'] = 'Ditt nya lösenord har skickats med e-post.';
+$lang['license'] = 'Om inte annat angivet, innehållet i denna wiki är licensierat under följande licenser:';
+$lang['licenseok'] = 'Notera: Genom att ändra i denna sidan så accepterar du att licensiera ditt bidrag under följande licenser:';
+$lang['searchmedia'] = 'Sök efter filnamn:';
+$lang['searchmedia_in'] = 'Sök i %s';
+$lang['txt_upload'] = 'Välj fil att ladda upp:';
+$lang['txt_filename'] = 'Ladda upp som (ej obligatoriskt):';
+$lang['txt_overwrt'] = 'Skriv över befintlig fil';
+$lang['maxuploadsize'] = 'Max %s per uppladdad fil.';
+$lang['allowedmime'] = 'Lista av alla tillåtna extensions';
+$lang['lockedby'] = 'Låst av:';
+$lang['lockexpire'] = 'Lås upphör att gälla:';
$lang['rssfailed'] = 'Ett fel uppstod när detta RSS-flöde skulle hämtas: ';
$lang['nothingfound'] = 'Inga filer hittades.';
$lang['mediaselect'] = 'Mediafiler';
@@ -192,10 +210,13 @@ $lang['diff'] = 'visa skillnader mot aktuell version';
$lang['diff2'] = 'Visa skillnader mellan valda versioner';
$lang['difflink'] = 'Länk till den här jämförelsesidan';
$lang['diff_type'] = 'Visa skillnader:';
+$lang['diff_inline'] = 'Exakt träff';
$lang['diff_side'] = 'Sida vid sida';
$lang['diffprevrev'] = 'Föregående version.';
$lang['diffnextrev'] = 'Nästa version.';
$lang['difflastrev'] = 'Senaste version.';
+$lang['diffbothprevrev'] = 'Börjar med';
+$lang['diffbothnextrev'] = 'Slutar med';
$lang['line'] = 'Rad';
$lang['breadcrumb'] = 'Spår:';
$lang['youarehere'] = 'Här är du:';
@@ -290,7 +311,11 @@ $lang['i_modified'] = 'Av säkerhetsskäl fungerar det här skriptet
Du får antingen packa upp det nedladdade paketet på nytt, eller konsultera de kompletta
<a href="http://dokuwiki.org/install">instruktionerna för installation av Dokuwiki</a>';
$lang['i_funcna'] = 'PHP-funktionen <code>%s</code> är inte tillgänglig. Kanske ditt webbhotell har avaktiverat den av någon anledning?';
+$lang['i_disabled'] = 'Det är avstängt av din leverantör.';
+$lang['i_funcnmail'] = '<b>Note:</b> PHP mail funktionen är inte tillgänglig. %s Om det är fortsatt otillgängligt kan du installera <a href="https://www.dokuwiki.org/plugin:smtp">smtp pluginet</a>';
$lang['i_phpver'] = 'Din PHP-version <code>%s</code> är lägre än vad som krävs <code>%s</code>. Du behöver uppgradera din PHP-installation.';
+$lang['i_mbfuncoverload'] = 'mbstring.func_overload måste inaktiveras i php.ini för att använda DokuWiki.';
+$lang['i_urandom'] = 'Innehåller';
$lang['i_permfail'] = '<code>%s</code> är inte skrivbar av DokuWiki. Du behöver ändra filskyddet på den här katalogen!';
$lang['i_confexists'] = '<code>%s</code> finns redan';
$lang['i_writeerr'] = 'Kan inte skapa <code>%s</code>. Kontrollera filskyddet på kataloger/filer och skapa filen manuellt.';
@@ -343,9 +368,12 @@ $lang['media_perm_upload'] = 'Du har tyvärr inte tillräckliga behörighete
$lang['media_update'] = 'Ladda upp ny version';
$lang['media_restore'] = 'Återställ denna version';
$lang['media_acl_warning'] = 'Listan kanske inte är ';
+$lang['email_fail'] = 'PHP mail() saknas eller är inaktiverad. Följande mejl skickades inte:';
$lang['currentns'] = 'Nuvarande namnrymd.';
$lang['searchresult'] = 'Sökresultat';
$lang['plainhtml'] = 'Ren HTML';
+$lang['wikimarkup'] = 'Wiki Markup';
$lang['page_nonexist_rev'] = 'Sidan fanns inte på %s. Den blev sedermera skapad på <a href="%s">%s</a>.';
+$lang['unable_to_parse_date'] = 'Oförmögen att processera i parameter "%s".';
$lang['email_signature_text'] = 'Detta meddelande har skapats av DokuWiki på
@DOKUWIKIURL@';
diff --git a/inc/lang/sv/onceexisted.txt b/inc/lang/sv/onceexisted.txt
new file mode 100644
index 000000000..56b894742
--- /dev/null
+++ b/inc/lang/sv/onceexisted.txt
@@ -0,0 +1,3 @@
+======= Den här sidan existerar inte längre ======
+
+Du har följt en länk till en sida som inte längre existerar. Du kan kontrollera följande lista [[?do=revisions|old revisions]] för att se när och varför den togs bort, gå till en äldre version för att återställa den. \ No newline at end of file
diff --git a/inc/lang/tr/lang.php b/inc/lang/tr/lang.php
index 27e867d25..e93af031f 100644
--- a/inc/lang/tr/lang.php
+++ b/inc/lang/tr/lang.php
@@ -3,6 +3,7 @@
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
+ * @author Eren <bosshyapma@protonmail.com>
* @author Hakan <hakandursun2009@gmail.com>
* @author mahir <mahirtakak@gmail.com>
* @author Selim Farsakoğlu <farsakogluselim@yahoo.de>
@@ -167,6 +168,7 @@ $lang['txt_upload'] = 'Yüklenecek dosyayı seç:';
$lang['txt_filename'] = 'Dosya adı (zorunlu değil):';
$lang['txt_overwrt'] = 'Mevcut dosyanın üstüne yaz';
$lang['maxuploadsize'] = 'Yükleme dosya başına en fazla %s';
+$lang['allowedmime'] = 'İzin verilen dosya uzantılarının listesi';
$lang['lockedby'] = 'Şu an şunun tarafından kilitli:';
$lang['lockexpire'] = 'Kilitin açılma tarihi:';
$lang['rssfailed'] = 'Bu beslemeyi çekerken hata oluştu: ';
@@ -302,6 +304,7 @@ $lang['i_superuser'] = 'Ana Kullanıcı';
$lang['i_problems'] = 'Kurulum sihirbazı aşağıda gösterilen sorunları buldu. Bunları düzeltmeden devam etmeniz mümkün değil.';
$lang['i_modified'] = 'Güzenlik sebebiyle bu script sadece yeni ve değiştirilmemiş bir Dokuwiki kurulumunda çalışır. Ya indirdiğiniz paketi yeniden açmalı ya da <a href="http://dokuwiki.org/install"> adresindeki Dokuwiki kurulum kılavuzu</a>na bakmalısınız.';
$lang['i_funcna'] = '<code>%s</code> PHP fonksiyonu bulunmamaktadır. Barındırma(Hosting) hizmetinde bu özellik kapatılmış olabilir.';
+$lang['i_disabled'] = 'Sağlayıcınız tarafından devre dışı bırakılmış.';
$lang['i_phpver'] = '<code>%s</code> PHP sürümü, gereken <code>%s</code> sürümünden daha düşük. PHP kurulumunu yükseltmeniz gerekmektedir.';
$lang['i_mbfuncoverload'] = 'DokuWiki\'nin çalışması için php.ini dosyasında mbstring.func_overload seçeneği kapalı (değeri 0) olarak ayarlanmalıdır.';
$lang['i_permfail'] = '<code>%s</code> Dokuwiki tarafından yazılabilir değil. İzin ayarlarını bu klasör için düzeltmeniz gerekmektedir!';
diff --git a/inc/lang/vi/lang.php b/inc/lang/vi/lang.php
index ed03832a5..455bd5639 100644
--- a/inc/lang/vi/lang.php
+++ b/inc/lang/vi/lang.php
@@ -109,6 +109,7 @@ $lang['js']['media_done_btn'] = 'Xong';
$lang['js']['media_drop'] = 'Kéo tập tin vào đây để tải lên';
$lang['js']['media_cancel'] = 'xóa';
$lang['js']['media_overwrt'] = 'Ghi đè các tập tin hiện có';
+$lang['js']['data_insecure'] = 'CẢNH BÁO: Có vẻ như đường dẫn dữ liệu của bạn không được bảo mật đúng cách. Xin vui lòng đọc <a href="https://www.dokuwiki.org/security#web_access_security">Web Access Security in DokuWiki</a>.';
$lang['search_exact_match'] = 'Khớp chính xác';
$lang['search_starts_with'] = 'Bắt đầu với';
$lang['search_ends_with'] = 'Kết thúc bằng';
@@ -130,7 +131,7 @@ $lang['regmailfail'] = 'Có vẻ như đã xảy ra lỗi khi gửi th
$lang['regbadmail'] = 'Địa chỉ thư điện tử được cung cấp có vẻ không hợp lệ - nếu bạn nghĩ đây là lỗi, hãy liên hệ với quản trị viên';
$lang['regbadpass'] = 'Hai mật khẩu đã nhập không giống nhau, vui lòng thử lại.';
$lang['regpwmail'] = 'Mật khẩu DokuWiki của bạn';
-$lang['reghere'] = 'Bạn chưa có tài khoản? Hãy lấy một cái';
+$lang['reghere'] = 'Bạn chưa có tài khoản? Hãy tạo một cái';
$lang['profna'] = 'Wiki này không hỗ trợ sửa đổi hồ sơ';
$lang['profnochange'] = 'Không có thay đổi, không có gì để làm.';
$lang['profnoempty'] = 'Không được bỏ trống tên hoặc địa chỉ thư điện tử.';
@@ -141,7 +142,7 @@ $lang['profdeleted'] = 'Tài khoản thành viên của bạn đã b
$lang['profconfdelete'] = 'Tôi muốn xóa tài khoản của tôi khỏi wiki này. <br/> Hành động này không thể hoàn tác.';
$lang['profconfdeletemissing'] = 'Hộp kiểm xác nhận chưa được đánh dấu';
$lang['proffail'] = 'Hồ sơ thành viên chưa được cập nhật.';
-$lang['pwdforget'] = 'Bạn quên mật khẩu? Thử một cái mới';
+$lang['pwdforget'] = 'Bạn quên mật khẩu? Tạo một cái mới';
$lang['resendna'] = 'Wiki này không hỗ trợ gửi lại mật khẩu.';
$lang['resendpwd'] = 'Đặt 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.';
diff --git a/inc/lang/vi/newpage.txt b/inc/lang/vi/newpage.txt
index 943c6c312..fa7cfbf06 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 đã truy cập vào một liên kết đến một đề tài chưa tồn tại. Nếu quyền cho phép, bạn có thể tạo nó bằng cách nhấp vào **Tạo trang này**.
+Bạn đã truy cập vào một liên kết đến một đề tài chưa tồn tại. Nếu quyền cho phép, bạn có thể tạo nó bằng cách nhấn vào **Tạo trang này**.
diff --git a/inc/lang/zh/lang.php b/inc/lang/zh/lang.php
index ff642abd6..1f63b505c 100644
--- a/inc/lang/zh/lang.php
+++ b/inc/lang/zh/lang.php
@@ -3,6 +3,7 @@
/**
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
+ * @author Lakejason0 <lakesarchive@outlook.com>
* @author Phy <dokuwiki@phy25.com>
* @author Jenxi <seow@jenxi.com>
* @author FENG.JIE <ahx@qq.com>
diff --git a/inc/load.php b/inc/load.php
index 68d425584..791f743d7 100644
--- a/inc/load.php
+++ b/inc/load.php
@@ -79,11 +79,6 @@ function load_autoload($name){
'Doku_Renderer_code' => DOKU_INC.'inc/parser/code.php',
'Doku_Renderer_xhtmlsummary' => DOKU_INC.'inc/parser/xhtmlsummary.php',
'Doku_Renderer_metadata' => DOKU_INC.'inc/parser/metadata.php',
-
- 'DokuCLI' => DOKU_INC.'inc/cli.php',
- 'DokuCLI_Options' => DOKU_INC.'inc/cli.php',
- 'DokuCLI_Colors' => DOKU_INC.'inc/cli.php',
-
);
if(isset($classes[$name])){
diff --git a/inc/media.php b/inc/media.php
index 4c87a2886..e0819d6d9 100644
--- a/inc/media.php
+++ b/inc/media.php
@@ -699,7 +699,7 @@ function media_filelist($ns,$auth=null,$jump='',$fullscreenview=false,$sort=fals
$dir = utf8_encodeFN(str_replace(':','/',$ns));
$data = array();
- search($data,$conf['mediadir'],'search_media',
+ search($data,$conf['mediadir'],'search_mediafiles',
array('showmsg'=>true,'depth'=>1),$dir,1,$sort);
if(!count($data)){
@@ -710,9 +710,17 @@ function media_filelist($ns,$auth=null,$jump='',$fullscreenview=false,$sort=fals
}
foreach($data as $item){
if (!$fullscreenview) {
- media_printfile($item,$auth,$jump);
+ //FIXME old call: media_printfile($item,$auth,$jump);
+ $display = new \dokuwiki\Ui\Media\DisplayRow($item);
+ $display->scrollIntoView($jump == $item->getID());
+ $display->show();
} else {
- media_printfile_thumbs($item,$auth,$jump);
+ //FIXME old call: media_printfile_thumbs($item,$auth,$jump);
+ echo '<li>';
+ $display = new \dokuwiki\Ui\Media\DisplayTile($item);
+ $display->scrollIntoView($jump == $item->getID());
+ $display->show();
+ echo '</li>';
}
}
if ($fullscreenview) echo '</ul>'.NL;
@@ -1348,7 +1356,7 @@ function media_searchlist($query,$ns,$auth=null,$fullscreen=false,$sort='natural
$pattern = '/'.$quoted.'/i';
search($evdata['data'],
$conf['mediadir'],
- 'search_media',
+ 'search_mediafiles',
array('showmsg'=>false,'pattern'=>$pattern),
$dir,
1,
@@ -1370,94 +1378,25 @@ function media_searchlist($query,$ns,$auth=null,$fullscreen=false,$sort='natural
echo '<ul class="' . _media_get_list_type() . '">';
}
foreach($evdata['data'] as $item){
- if (!$fullscreen) media_printfile($item,$item['perm'],'',true);
- else media_printfile_thumbs($item,$item['perm'],false,true);
+ if (!$fullscreen) {
+ // FIXME old call: media_printfile($item,$item['perm'],'',true);
+ $display = new \dokuwiki\Ui\Media\DisplayRow($item);
+ $display->relativeDisplay($ns);
+ $display->show();
+ } else {
+ // FIXME old call: media_printfile_thumbs($item,$item['perm'],false,true);
+ $display = new \dokuwiki\Ui\Media\DisplayTile($item);
+ $display->relativeDisplay($ns);
+ echo '<li>';
+ $display->show();
+ echo '</li>';
+ }
}
if ($fullscreen) echo '</ul>'.NL;
}
}
/**
- * Formats and prints one file in the list
- *
- * @param array $item
- * @param int $auth permission level
- * @param string $jump item id
- * @param bool $display_namespace
- */
-function media_printfile($item,$auth,$jump,$display_namespace=false){
- global $lang;
-
- // Prepare zebra coloring
- // I always wanted to use this variable name :-D
- static $twibble = 1;
- $twibble *= -1;
- $zebra = ($twibble == -1) ? 'odd' : 'even';
-
- // Automatically jump to recent action
- if($jump == $item['id']) {
- $jump = ' id="scroll__here" ';
- }else{
- $jump = '';
- }
-
- // Prepare fileicons
- list($ext) = mimetype($item['file'],false);
- $class = preg_replace('/[^_\-a-z0-9]+/i','_',$ext);
- $class = 'select mediafile mf_'.$class;
-
- // Prepare filename
- $file = utf8_decodeFN($item['file']);
-
- // Prepare info
- $info = '';
- if($item['isimg']){
- $info .= (int) $item['meta']->getField('File.Width');
- $info .= '&#215;';
- $info .= (int) $item['meta']->getField('File.Height');
- $info .= ' ';
- }
- $info .= '<i>'.dformat($item['mtime']).'</i>';
- $info .= ' ';
- $info .= filesize_h($item['size']);
-
- // output
- echo '<div class="'.$zebra.'"'.$jump.' title="'.hsc($item['id']).'">'.NL;
- if (!$display_namespace) {
- echo '<a id="h_:'.$item['id'].'" class="'.$class.'">'.hsc($file).'</a> ';
- } else {
- echo '<a id="h_:'.$item['id'].'" class="'.$class.'">'.hsc($item['id']).'</a><br/>';
- }
- echo '<span class="info">('.$info.')</span>'.NL;
-
- // view button
- $link = ml($item['id'],'',true);
- echo ' <a href="'.$link.'" target="_blank"><img src="'.DOKU_BASE.'lib/images/magnifier.png" '.
- 'alt="'.$lang['mediaview'].'" title="'.$lang['mediaview'].'" class="btn" /></a>';
-
- // mediamanager button
- $link = wl('',array('do'=>'media','image'=>$item['id'],'ns'=>getNS($item['id'])));
- echo ' <a href="'.$link.'" target="_blank"><img src="'.DOKU_BASE.'lib/images/mediamanager.png" '.
- 'alt="'.$lang['btn_media'].'" title="'.$lang['btn_media'].'" class="btn" /></a>';
-
- // delete button
- if($item['writable'] && $auth >= AUTH_DELETE){
- $link = DOKU_BASE.'lib/exe/mediamanager.php?delete='.rawurlencode($item['id']).
- '&amp;sectok='.getSecurityToken();
- echo ' <a href="'.$link.'" class="btn_media_delete" title="'.$item['id'].'">'.
- '<img src="'.DOKU_BASE.'lib/images/trash.png" alt="'.$lang['btn_delete'].'" '.
- 'title="'.$lang['btn_delete'].'" class="btn" /></a>';
- }
-
- echo '<div class="example" id="ex_'.str_replace(':','_',$item['id']).'">';
- echo $lang['mediausage'].' <code>{{:'.$item['id'].'}}</code>';
- echo '</div>';
- if($item['isimg']) media_printimgdetail($item);
- echo '<div class="clearer"></div>'.NL;
- echo '</div>'.NL;
-}
-
-/**
* Display a media icon
*
* @param string $filename media id
@@ -1477,127 +1416,6 @@ function media_printicon($filename, $size=''){
}
/**
- * Formats and prints one file in the list in the thumbnails view
- *
- * @author Kate Arzamastseva <pshns@ukr.net>
- *
- * @param array $item
- * @param int $auth permission level
- * @param bool|string $jump item id
- * @param bool $display_namespace
- */
-function media_printfile_thumbs($item,$auth,$jump=false,$display_namespace=false){
-
- // Prepare filename
- $file = utf8_decodeFN($item['file']);
-
- // output
- echo '<li><dl title="'.hsc($item['id']).'">'.NL;
-
- echo '<dt>';
- if($item['isimg']) {
- media_printimgdetail($item, true);
-
- } else {
- echo '<a id="d_:'.$item['id'].'" class="image" title="'.$item['id'].'" href="'.
- media_managerURL(['image' => hsc($item['id']), 'ns' => getNS($item['id']),
- 'tab_details' => 'view']).'">';
- echo media_printicon($item['id'], '32x32');
- echo '</a>';
- }
- echo '</dt>'.NL;
- if (!$display_namespace) {
- $name = hsc($file);
- } else {
- $name = hsc($item['id']);
- }
- echo '<dd class="name"><a href="'.media_managerURL(['image' => hsc($item['id']), 'ns' => getNS($item['id']),
- 'tab_details' => 'view']).'" id="h_:'.$item['id'].'">'.$name.'</a></dd>'.NL;
-
- if($item['isimg']){
- $size = '';
- $size .= (int) $item['meta']->getField('File.Width');
- $size .= '&#215;';
- $size .= (int) $item['meta']->getField('File.Height');
- echo '<dd class="size">'.$size.'</dd>'.NL;
- } else {
- echo '<dd class="size">&#160;</dd>'.NL;
- }
- $date = dformat($item['mtime']);
- echo '<dd class="date">'.$date.'</dd>'.NL;
- $filesize = filesize_h($item['size']);
- echo '<dd class="filesize">'.$filesize.'</dd>'.NL;
- echo '</dl></li>'.NL;
-}
-
-/**
- * Prints a thumbnail and metainfo
- *
- * @param array $item
- * @param bool $fullscreen
- */
-function media_printimgdetail($item, $fullscreen=false){
- // prepare thumbnail
- $size = $fullscreen ? 90 : 120;
-
- $w = (int) $item['meta']->getField('File.Width');
- $h = (int) $item['meta']->getField('File.Height');
- if($w>$size || $h>$size){
- if (!$fullscreen) {
- $ratio = $item['meta']->getResizeRatio($size);
- } else {
- $ratio = $item['meta']->getResizeRatio($size,$size);
- }
- $w = floor($w * $ratio);
- $h = floor($h * $ratio);
- }
- $src = ml($item['id'],array('w'=>$w,'h'=>$h,'t'=>$item['mtime']));
- $p = array();
- if (!$fullscreen) {
- // In fullscreen mediamanager view, image resizing is done via CSS.
- $p['width'] = $w;
- $p['height'] = $h;
- }
- $p['alt'] = $item['id'];
- $att = buildAttributes($p);
-
- // output
- if ($fullscreen) {
- echo '<a id="l_:'.$item['id'].'" class="image thumb" href="'.
- media_managerURL(['image' => hsc($item['id']), 'ns' => getNS($item['id']), 'tab_details' => 'view']).'">';
- echo '<img src="'.$src.'" '.$att.' />';
- echo '</a>';
- }
-
- if ($fullscreen) return;
-
- echo '<div class="detail">';
- echo '<div class="thumb">';
- echo '<a id="d_:'.$item['id'].'" class="select">';
- echo '<img src="'.$src.'" '.$att.' />';
- echo '</a>';
- echo '</div>';
-
- // read EXIF/IPTC data
- $t = $item['meta']->getField(array('IPTC.Headline','xmp.dc:title'));
- $d = $item['meta']->getField(array('IPTC.Caption','EXIF.UserComment',
- 'EXIF.TIFFImageDescription',
- 'EXIF.TIFFUserComment'));
- if(\dokuwiki\Utf8\PhpString::strlen($d) > 250) $d = \dokuwiki\Utf8\PhpString::substr($d,0,250).'...';
- $k = $item['meta']->getField(array('IPTC.Keywords','IPTC.Category','xmp.dc:subject'));
-
- // print EXIF/IPTC data
- if($t || $d || $k ){
- echo '<p>';
- if($t) echo '<strong>'.hsc($t).'</strong><br />';
- if($d) echo hsc($d).'<br />';
- if($t) echo '<em>'.hsc($k).'</em>';
- echo '</p>';
- }
- echo '</div>';
-}
-
-/**
* Build link based on the current, adding/rewriting parameters
*
* @author Kate Arzamastseva <pshns@ukr.net>
diff --git a/inc/pageutils.php b/inc/pageutils.php
index d4a8bb7c4..c281ffc5b 100644
--- a/inc/pageutils.php
+++ b/inc/pageutils.php
@@ -226,7 +226,7 @@ function noNSorNS($id) {
* Creates a XHTML valid linkid from a given headline title
*
* @param string $title The headline title
- * @param array|bool $check Existing IDs (title => number)
+ * @param array|bool $check Existing IDs
* @return string the title
*
* @author Andreas Gohr <andi@splitbrain.org>
@@ -241,15 +241,16 @@ function sectionID($title,&$check) {
}
if(is_array($check)){
- // make sure tiles are unique
- if (!array_key_exists ($title,$check)) {
- $check[$title] = 0;
- } else {
- $title .= ++ $check[$title];
+ $suffix=0;
+ $candidateTitle = $title;
+ while(in_array($candidateTitle, $check)){
+ $candidateTitle = $title . ++$suffix;
}
+ $check []= $candidateTitle;
+ return $candidateTitle;
+ } else {
+ return $title;
}
-
- return $title;
}
/**
diff --git a/inc/parser/renderer.php b/inc/parser/renderer.php
index e4eff2a62..c2055d647 100644
--- a/inc/parser/renderer.php
+++ b/inc/parser/renderer.php
@@ -889,7 +889,7 @@ abstract class Doku_Renderer extends Plugin {
$url = $url.rawurlencode($reference);
}
//handle as wiki links
- if($url[0] === ':') {
+ if($url && $url[0] === ':') {
$urlparam = null;
$id = $url;
if (strpos($url, '?') !== false) {
diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php
index f40b1c4b7..417b143c6 100644
--- a/inc/parser/xhtml.php
+++ b/inc/parser/xhtml.php
@@ -1249,7 +1249,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
$title = $reference;
}
}
- list($src, $hash) = explode('#', $src, 2);
+ // Squelch the warning in case there is no hash in the URL
+ @list($src, $hash) = explode('#', $src, 2);
$noLink = false;
if($src == '') {
// only output plaintext without link if there is no src
@@ -1657,6 +1658,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
)
) . '"';
$ret .= ' class="media'.$align.'"';
+ $ret .= ' loading="lazy"';
if($title) {
$ret .= ' title="'.$title.'"';
@@ -1886,7 +1888,9 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
$url = ml($file, '', true, '&');
$linkType = 'internalmedia';
}
- $title = $atts['title'] ? $atts['title'] : $this->_xmlEntities(\dokuwiki\Utf8\PhpString::basename(noNS($file)));
+ $title = !empty($atts['title'])
+ ? $atts['title']
+ : $this->_xmlEntities(\dokuwiki\Utf8\PhpString::basename(noNS($file)));
$out .= '<source src="'.hsc($url).'" type="'.$mime.'" />'.NL;
// alternative content (just a link to the file)
diff --git a/inc/parserutils.php b/inc/parserutils.php
index 846be54db..c9aacd91d 100644
--- a/inc/parserutils.php
+++ b/inc/parserutils.php
@@ -411,7 +411,7 @@ function p_set_metadata($id, $data, $render=false, $persistent=true){
function p_purge_metadata($id) {
$meta = p_read_metadata($id);
foreach($meta['current'] as $key => $value) {
- if(is_array($meta[$key])) {
+ if(isset($meta[$key]) && is_array($meta[$key])) {
$meta['current'][$key] = array();
} else {
$meta['current'][$key] = '';
@@ -463,7 +463,9 @@ function p_save_metadata($id, $meta) {
global $cache_metadata, $INFO;
if (isset($cache_metadata[$id])) $cache_metadata[$id] = $meta;
- if (!empty($INFO) && ($id == $INFO['id'])) { $INFO['meta'] = $meta['current']; }
+ if (!empty($INFO) && isset($INFO['id']) && ($id == $INFO['id'])) {
+ $INFO['meta'] = $meta['current'];
+ }
return io_saveFile(metaFN($id, '.meta'), serialize($meta));
}
diff --git a/inc/search.php b/inc/search.php
index 98be6cbf8..a33ba87c5 100644
--- a/inc/search.php
+++ b/inc/search.php
@@ -132,13 +132,14 @@ function search_qsearch(&$data,$base,$file,$type,$lvl,$opts){
*/
function search_index(&$data,$base,$file,$type,$lvl,$opts){
global $conf;
+ $ns = isset($opts['ns']) ? $opts['ns'] : '';
$opts = array(
'pagesonly' => true,
'listdirs' => true,
'listfiles' => empty($opts['nofiles']),
'sneakyacl' => $conf['sneaky_index'],
// Hacky, should rather use recmatch
- 'depth' => preg_match('#^'.preg_quote($file, '#').'(/|$)#','/'.$opts['ns']) ? 0 : -1
+ 'depth' => preg_match('#^'.preg_quote($file, '#').'(/|$)#','/'.$ns) ? 0 : -1
);
return search_universal($data, $base, $file, $type, $lvl, $opts);
@@ -233,6 +234,58 @@ function search_media(&$data,$base,$file,$type,$lvl,$opts){
}
/**
+ * List all mediafiles in a namespace
+ * $opts['depth'] recursion level, 0 for all
+ * $opts['showmsg'] shows message if invalid media id is used
+ * $opts['skipacl'] skip acl checking
+ * $opts['pattern'] check given pattern
+ * $opts['hash'] add hashes to result list
+ *
+ * @todo This is a temporary copy of search_media returning a list of MediaFile intances
+ *
+ * @param array $data
+ * @param string $base
+ * @param string $file
+ * @param string $type
+ * @param integer $lvl
+ * @param array $opts
+ *
+ * @return bool
+ */
+function search_mediafiles(&$data,$base,$file,$type,$lvl,$opts){
+
+ //we do nothing with directories
+ if($type == 'd') {
+ if(empty($opts['depth'])) return true; // recurse forever
+ $depth = substr_count($file,'/');
+ if($depth >= $opts['depth']) return false; // depth reached
+ return true;
+ }
+
+ $id = pathID($file,true);
+ if($id != cleanID($id)){
+ if($opts['showmsg'])
+ msg(hsc($id).' is not a valid file name for DokuWiki - skipped',-1);
+ return false; // skip non-valid files
+ }
+
+ //check ACL for namespace (we have no ACL for mediafiles)
+ $info['perm'] = auth_quickaclcheck(getNS($id).':*');
+ if(empty($opts['skipacl']) && $info['perm'] < AUTH_READ){
+ return false;
+ }
+
+ //check pattern filter
+ if(!empty($opts['pattern']) && !@preg_match($opts['pattern'], $id)){
+ return false;
+ }
+
+ $data[] = new \dokuwiki\File\MediaFile($id);
+ return false;
+}
+
+
+/**
* This function just lists documents (for RSS namespace export)
*
* @author Andreas Gohr <andi@splitbrain.org>
diff --git a/inc/template.php b/inc/template.php
index 68f0ba73d..9b7dfa5ab 100644
--- a/inc/template.php
+++ b/inc/template.php
@@ -297,7 +297,7 @@ function tpl_metaheaders($alt = true) {
}
}
- // setup robot tags apropriate for different modes
+ // setup robot tags appropriate for different modes
if(($ACT == 'show' || $ACT == 'export_xhtml') && !$REV) {
if($INFO['exists']) {
//delay indexing:
@@ -348,7 +348,6 @@ function tpl_metaheaders($alt = true) {
$jquery = getCdnUrls();
foreach($jquery as $src) {
$head['script'][] = array(
- 'charset' => 'utf-8',
'_data' => '',
'src' => $src,
) + ($conf['defer_js'] ? [ 'defer' => 'defer'] : []);
@@ -356,7 +355,7 @@ function tpl_metaheaders($alt = true) {
// load our javascript dispatcher
$head['script'][] = array(
- 'charset'=> 'utf-8', '_data'=> '',
+ '_data'=> '',
'src' => DOKU_BASE.'lib/exe/js.php'.'?t='.rawurlencode($conf['template']).'&tseed='.$tseed,
) + ($conf['defer_js'] ? [ 'defer' => 'defer'] : []);
@@ -1008,11 +1007,13 @@ function tpl_img_getTag($tags, $alt = '', $src = null) {
global $SRC;
if(is_null($src)) $src = $SRC;
+ if(is_null($src)) return $alt;
static $meta = null;
if(is_null($meta)) $meta = new JpegMeta($src);
if($meta === false) return $alt;
$info = cleanText($meta->getField($tags));
+ $meta = null; // garbage collect and close any file handles. See #3404
if($info == false) return $alt;
return $info;
}
@@ -1067,7 +1068,7 @@ function tpl_get_img_meta() {
if (!empty($tag[0])) {
$t = array($tag[0]);
}
- if(is_array($tag[3])) {
+ if(isset($tag[3]) && is_array($tag[3])) {
$t = array_merge($t,$tag[3]);
}
$value = tpl_img_getTag($t);
@@ -1272,7 +1273,7 @@ function tpl_getLang($id) {
}
}
}
- return $lang[$id];
+ return isset($lang[$id]) ? $lang[$id] : '';
}
/**