Merge remote-tracking branch 'splitbrain/master'
This commit is contained in:
commit
0bd5b90b4c
|
@ -0,0 +1,15 @@
|
|||
; http://editorconfig.org/
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[inc/{geshi,phpseclib}/**]
|
||||
; Use editor default (possible autodetection).
|
||||
indent_style =
|
||||
indent_size =
|
||||
trim_trailing_whitespace = false
|
||||
insert_final_newline = false
|
|
@ -4,3 +4,11 @@
|
|||
*.gif binary
|
||||
*.ico binary
|
||||
*.xcf binary
|
||||
|
||||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
||||
.editorconfig export-ignore
|
||||
.travis.yml export-ignore
|
||||
_test export-ignore
|
||||
_cs export-ignore
|
||||
lib/plugins/testing export-ignore
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
/conf/lang/*
|
||||
/conf/plugin_lang/*
|
||||
/conf/plugins.local.*
|
||||
/conf/tpl/*
|
||||
.htaccess
|
||||
*.swp
|
||||
*.bak
|
||||
|
@ -26,25 +27,23 @@
|
|||
/data/media_attic/*
|
||||
/data/meta/*
|
||||
/data/pages/*
|
||||
/data/tmp/*
|
||||
!/data/pages/wiki/dokuwiki.txt
|
||||
!/data/pages/wiki/syntax.txt
|
||||
!/data/pages/wiki/welcome.txt
|
||||
/data/tmp/*
|
||||
/lib/tpl/*
|
||||
!/lib/tpl/default
|
||||
!/lib/tpl/dokuwiki
|
||||
!/lib/tpl/index.php
|
||||
/lib/plugins/*
|
||||
!/lib/plugins/acl
|
||||
!/lib/plugins/authad
|
||||
!/lib/plugins/authldap
|
||||
!/lib/plugins/authmysql
|
||||
!/lib/plugins/authpgsql
|
||||
!/lib/plugins/authplain
|
||||
!/lib/plugins/acl
|
||||
!/lib/plugins/config
|
||||
!/lib/plugins/extension
|
||||
!/lib/plugins/info
|
||||
!/lib/plugins/plugin
|
||||
!/lib/plugins/popularity
|
||||
!/lib/plugins/revert
|
||||
!/lib/plugins/safefnrecode
|
||||
|
@ -52,5 +51,8 @@
|
|||
!/lib/plugins/usermanager
|
||||
!/lib/plugins/action.php
|
||||
!/lib/plugins/admin.php
|
||||
!/lib/plugins/auth.php
|
||||
!/lib/plugins/index.html
|
||||
!/lib/plugins/remote.php
|
||||
!/lib/plugins/syntax.php
|
||||
lib/images/*/local/*
|
||||
|
|
|
@ -9,4 +9,4 @@ notifications:
|
|||
- "chat.freenode.net#dokuwiki"
|
||||
on_success: change
|
||||
on_failure: change
|
||||
script: cd _test && phpunit --stderr
|
||||
script: cd _test && phpunit --verbose --stderr
|
||||
|
|
56
_test/README
56
_test/README
|
@ -9,35 +9,28 @@ This is the test suite to automatically test various parts of DokuWiki.
|
|||
|
||||
===== PHPUnit Installation ======
|
||||
|
||||
==== via PEAR installer ====
|
||||
You can install phpunit through your distribution's package manager or simply
|
||||
download the newest phar file into the _test directory:
|
||||
|
||||
pear config-set auto_discover 1
|
||||
pear install pear.phpunit.de/PHPUnit
|
||||
|
||||
==== via Composer ====
|
||||
|
||||
Include a composer.json file in your project, which can be as minimal as:
|
||||
|
||||
<code>
|
||||
{
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "3.7.*"
|
||||
}
|
||||
}
|
||||
</code>
|
||||
|
||||
==== via PHP archive (PHAR) ====
|
||||
|
||||
Download http://pear.phpunit.de/get/phpunit.phar and make it executable on your system.
|
||||
cd _test/
|
||||
wget https://phar.phpunit.de/phpunit.phar
|
||||
|
||||
|
||||
===== Running all tests =====
|
||||
|
||||
Just change to the ''_test'' directory and run phpunit:
|
||||
Just change to the ''_test'' directory and run phpunit (depending on your install
|
||||
method):
|
||||
|
||||
cd _test/
|
||||
phpunit
|
||||
|
||||
or
|
||||
|
||||
cd _test/
|
||||
php phpunit.phar
|
||||
|
||||
===== Troubleshooting =====
|
||||
|
||||
PHPUnit will fail on some systems with a //headers already sent// error.
|
||||
This is a known problem with PHPUnit, the error can be avoided by passing the
|
||||
'--stderr' flag to phpunit:
|
||||
|
@ -46,8 +39,10 @@ This is a known problem with PHPUnit, the error can be avoided by passing the
|
|||
|
||||
On windows you may have to enable OpenSSL support for https tests.
|
||||
Some of them point to httpclient_http.tests.php on the failure.
|
||||
To enable HTTPS support copy the ''libeay32.dll'' and ''ssleay32.dll'' to your ''windows\system32'' folder
|
||||
and add the following line to your php.ini in the extension section:
|
||||
To enable HTTPS support copy the ''libeay32.dll'' and ''ssleay32.dll''
|
||||
to your ''windows\system32'' folder and add the following line to your php.ini
|
||||
in the extension section:
|
||||
|
||||
<code ini>
|
||||
extension=php_openssl.dll
|
||||
</code>
|
||||
|
@ -56,13 +51,13 @@ extension=php_openssl.dll
|
|||
|
||||
You can run a single test file by providing it as an argument to phpunit:
|
||||
|
||||
phpunit --stderr tests/inc/common_cleanText.test.php
|
||||
phpunit tests/inc/common_cleanText.test.php
|
||||
|
||||
You can also use groups to exclude certain test from running. For example use
|
||||
the following command to avoid long running test or tests accessing the
|
||||
Internet.
|
||||
|
||||
phpunit --stderr --exclude-group slow,internet
|
||||
phpunit --exclude-group slow,internet
|
||||
|
||||
===== Create new Tests =====
|
||||
|
||||
|
@ -71,23 +66,10 @@ folder. Please respect the folder structure and naming convention. Inside the
|
|||
file, implement a class, extending 'DokuWikiTest'. Every method, starting
|
||||
with 'test' will be called as a test (e.g. 'testIfThisIsValid');
|
||||
|
||||
|
||||
===== TODO for the test framework =====
|
||||
|
||||
* test cross platform compatibility: especially test windows
|
||||
* update http://www.dokuwiki.org/devel:unittesting
|
||||
* optional: add helper methods to TestRequest for easy form submission
|
||||
* createForm(), ...
|
||||
* check PHP Unit test_helpers https://github.com/sebastianbergmann/php-test-helpers
|
||||
|
||||
|
||||
===== Migration Protocol =====
|
||||
|
||||
The following tests were not migrated:
|
||||
|
||||
* inc/indexer_idx_indexlengths (fs dependencies)
|
||||
* inc/mail_send (integration test)
|
||||
* inc/parser/parser_formatting
|
||||
* inc/parser/xhtml_htmlphp (runkit)
|
||||
* inc/parser/xhtml_links
|
||||
|
||||
|
|
|
@ -115,5 +115,8 @@ abstract class DokuWikiTest extends PHPUnit_Framework_TestCase {
|
|||
// reload language
|
||||
$local = $conf['lang'];
|
||||
trigger_event('INIT_LANG_LOAD', $local, 'init_lang', true);
|
||||
|
||||
global $INPUT;
|
||||
$INPUT = new Input();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,13 +44,18 @@ class TestRequest {
|
|||
* @return TestResponse the resulting output of the request
|
||||
*/
|
||||
public function execute($uri='/doku.php') {
|
||||
global $INPUT;
|
||||
global $ID;
|
||||
global $INFO;
|
||||
|
||||
// save old environment
|
||||
$server = $_SERVER;
|
||||
$session = $_SESSION;
|
||||
$get = $_GET;
|
||||
$post = $_POST;
|
||||
$request = $_REQUEST;
|
||||
|
||||
$input = $INPUT;
|
||||
|
||||
// prepare the right URI
|
||||
$this->setUri($uri);
|
||||
|
||||
|
@ -74,6 +79,7 @@ class TestRequest {
|
|||
// now execute dokuwiki and grep the output
|
||||
header_remove();
|
||||
ob_start('ob_start_callback');
|
||||
$INPUT = new Input();
|
||||
include(DOKU_INC.$this->script);
|
||||
ob_end_flush();
|
||||
|
||||
|
@ -89,6 +95,7 @@ class TestRequest {
|
|||
$_GET = $get;
|
||||
$_POST = $post;
|
||||
$_REQUEST = $request;
|
||||
$INPUT = $input;
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit
|
||||
bootstrap="bootstrap.php"
|
||||
convertNoticesToExceptions="false">
|
||||
convertNoticesToExceptions="false"
|
||||
colors="true"
|
||||
stderr="true"
|
||||
>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="DokuWiki Tests">
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* most tests are in auth_password.test.php
|
||||
*/
|
||||
class PassHash_test extends PHPUnit_Framework_TestCase {
|
||||
class PassHash_test extends DokuWikiTest {
|
||||
|
||||
function test_hmac(){
|
||||
// known hashes taken from https://code.google.com/p/yii/issues/detail?id=1942
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
class auth_password_test extends PHPUnit_Framework_TestCase {
|
||||
class auth_password_test extends DokuWikiTest {
|
||||
|
||||
// hashes for the password foo$method, using abcdefgh as salt
|
||||
var $passes = array(
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class cache_use_test
|
||||
*
|
||||
* Tests if caching can actually be used
|
||||
*/
|
||||
class cache_use_test extends DokuWikiTest {
|
||||
/** @var cache_renderer $cache */
|
||||
private $cache;
|
||||
|
||||
function setUp() {
|
||||
global $ID, $conf;
|
||||
parent::setUp();
|
||||
|
||||
$ID = 'cached';
|
||||
$file = wikiFN($ID);
|
||||
$conf['cachetime'] = 0; // ensure the value is not -1, which disables caching
|
||||
|
||||
saveWikiText($ID, 'Content', 'Created');
|
||||
|
||||
$this->cache = new cache_renderer($ID, $file, 'xhtml');
|
||||
$this->cache->storeCache('Test');
|
||||
|
||||
// set the modification times explicitly (overcome Issue #694)
|
||||
$time = time();
|
||||
touch($file, $time-1);
|
||||
touch($this->cache->cache, $time);
|
||||
}
|
||||
|
||||
function test_use() {
|
||||
$this->assertTrue($this->cache->useCache());
|
||||
}
|
||||
|
||||
/**
|
||||
* In all the following tests the cache should not be usable
|
||||
* as such, they are meaningless if test_use didn't pass.
|
||||
*
|
||||
* @depends test_use
|
||||
*/
|
||||
function test_purge() {
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
$INPUT->set('purge',1);
|
||||
|
||||
$this->assertFalse($this->cache->useCache());
|
||||
$this->assertNotEmpty($this->cache->depends['purge']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends test_use
|
||||
*/
|
||||
function test_filedependency() {
|
||||
// give the dependent src file the same mtime as the cache
|
||||
touch($this->cache->file, filemtime($this->cache->cache));
|
||||
$this->assertFalse($this->cache->useCache());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends test_use
|
||||
*/
|
||||
function test_age() {
|
||||
// need to age both our source file & the cache
|
||||
$age = 10;
|
||||
$time = time() - $age - 1; // older than age
|
||||
|
||||
touch($this->cache->file, $time - 1);
|
||||
touch($this->cache->cache, $time);
|
||||
|
||||
$this->assertFalse($this->cache->useCache(array('age' => $age)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends test_use
|
||||
*/
|
||||
function test_confnocaching() {
|
||||
global $conf;
|
||||
$conf['cachetime'] = -1; // disables renderer caching
|
||||
|
||||
$this->assertFalse($this->cache->useCache());
|
||||
$this->assertNotEmpty($this->cache->_nocache);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
/**
|
||||
* Tests for requesting revisions of a page with getRevisions()
|
||||
*
|
||||
* This class uses the files:
|
||||
* - data/pages/mailinglist.txt
|
||||
* - data/meta/mailinglist.changes
|
||||
*/
|
||||
class changelog_getrevisionsaround_test extends DokuWikiTest {
|
||||
|
||||
/**
|
||||
* list of revisions in mailinglist.changes
|
||||
*/
|
||||
private $revsexpected = array(
|
||||
1374261194, //current page
|
||||
1371579614, 1368622240,
|
||||
1368622195, 1368622152,
|
||||
1368612599, 1368612506,
|
||||
1368609772, 1368575634,
|
||||
1363436892, 1362527164,
|
||||
1362527046, 1362526861,
|
||||
1362526767, 1362526167,
|
||||
1362526119, 1362526039,
|
||||
1362525926, 1362525899,
|
||||
1362525359, 1362525145,
|
||||
1362524799, 1361901536,
|
||||
1360110636
|
||||
);
|
||||
private $pageid = 'mailinglist';
|
||||
|
||||
function setup() {
|
||||
parent::setup();
|
||||
global $cache_revinfo;
|
||||
$cache =& $cache_revinfo;
|
||||
if(isset($cache['nonexist'])) {
|
||||
unset($cache['nonexist']);
|
||||
}
|
||||
if(isset($cache['mailinglist'])) {
|
||||
unset($cache['mailinglist']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* no nonexist.changes meta file available
|
||||
*/
|
||||
function test_changemetadatanotexists() {
|
||||
$rev1 = 1362526767;
|
||||
$rev2 = 1362527164;
|
||||
$max = 50;
|
||||
$id = 'nonexist';
|
||||
$revsexpected = array(array(), array());
|
||||
|
||||
$pagelog = new PageChangeLog($id, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Surrounding revisions of rev1 and rev2 overlaps
|
||||
*/
|
||||
function test_request_overlapping() {
|
||||
$rev1 = 1362526767;
|
||||
$rev2 = 1362527164;
|
||||
$max = 10;
|
||||
$revsexpected = array(
|
||||
array_slice($this->revsexpected, 8, 11),
|
||||
array_slice($this->revsexpected, 5, 11)
|
||||
);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 20);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Surrounding revisions of rev1 and rev2 don't overlap.
|
||||
*/
|
||||
function test_request_non_overlapping() {
|
||||
$rev1 = 1362525899;
|
||||
$rev2 = 1368612599;
|
||||
$max = 10;
|
||||
$revsexpected = array(
|
||||
array_slice($this->revsexpected, 13, 11),
|
||||
array_slice($this->revsexpected, 0, 11)
|
||||
);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 20);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
/**
|
||||
* rev1 and rev2 are at start and end of the changelog.
|
||||
* Should return still a number of revisions equal to max
|
||||
*/
|
||||
function test_request_first_last() {
|
||||
$rev1 = 1360110636;
|
||||
$rev2 = 1374261194;
|
||||
$max = 10;
|
||||
$revsexpected = array(
|
||||
array_slice($this->revsexpected, 13, 11),
|
||||
array_slice($this->revsexpected, 0, 11)
|
||||
);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
//todo: number of revisions on the left side is not (yet) completed until max number
|
||||
$revsexpected = array(
|
||||
array_slice($this->revsexpected, 18, 6),
|
||||
array_slice($this->revsexpected, 0, 11)
|
||||
);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 20);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Number of requested revisions is larger than available revisions,
|
||||
* so returns whole log
|
||||
*/
|
||||
function test_request_wholelog() {
|
||||
$rev1 = 1362525899;
|
||||
$rev2 = 1368612599;
|
||||
$max = 50;
|
||||
$revsexpected = array($this->revsexpected, $this->revsexpected);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 20);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
/**
|
||||
* When rev1 > rev2, their order is changed
|
||||
*/
|
||||
function test_request_wrong_order_revs() {
|
||||
$rev1 = 1362527164;
|
||||
$rev2 = 1362526767;
|
||||
$max = 10;
|
||||
$revsexpected = array(
|
||||
array_slice($this->revsexpected, 8, 11),
|
||||
array_slice($this->revsexpected, 5, 11)
|
||||
);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 20);
|
||||
$revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,418 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Tests for requesting revisioninfo of a revision of a page with getRevisionInfo()
|
||||
*
|
||||
* This class uses the files:
|
||||
* - data/pages/mailinglist.txt
|
||||
* - data/meta/mailinglist.changes
|
||||
*/
|
||||
class changelog_getrelativerevision_test extends DokuWikiTest {
|
||||
|
||||
private $logline = "1362525899 127.0.0.1 E mailinglist pubcie [Data entry] \n";
|
||||
private $pageid = 'mailinglist';
|
||||
|
||||
function setup() {
|
||||
parent::setup();
|
||||
global $cache_revinfo;
|
||||
$cache =& $cache_revinfo;
|
||||
if(isset($cache['nonexist'])) {
|
||||
unset($cache['nonexist']);
|
||||
}
|
||||
if(isset($cache['mailinglist'])) {
|
||||
unset($cache['mailinglist']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* no nonexist.changes meta file available
|
||||
*/
|
||||
function test_changemetadatanotexists() {
|
||||
$rev = 1362525899;
|
||||
$dir = 1;
|
||||
$id = 'nonexist';
|
||||
$revsexpected = false;
|
||||
|
||||
$pagelog = new PageChangeLog($id, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
/**
|
||||
* no nonexist.changes meta file available
|
||||
*/
|
||||
function test_nodirection() {
|
||||
$rev = 1362525899;
|
||||
$dir = 0;
|
||||
$revsexpected = false;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
/**
|
||||
* start at exact current revision of mailinglist page
|
||||
*
|
||||
*/
|
||||
function test_startatexactcurrentrev() {
|
||||
$rev = 1385051947;
|
||||
$dir = 1;
|
||||
$revsexpectedpos = false;
|
||||
$revsexpectedneg = 1374261194;
|
||||
|
||||
//set a known timestamp
|
||||
touch(wikiFN($this->pageid), $rev);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revsexpectedpos, $revs);
|
||||
|
||||
$revs = $pagelog->getRelativeRevision($rev, -$dir);
|
||||
$this->assertEquals($revsexpectedneg, $revs);
|
||||
}
|
||||
|
||||
/**
|
||||
* start at exact last revision of mailinglist page
|
||||
*
|
||||
*/
|
||||
function test_startatexactlastrev() {
|
||||
$rev = 1360110636;
|
||||
$dir = 1;
|
||||
$revsexpectedpos = 1361901536;
|
||||
$revsexpectedneg = false;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revsexpectedpos, $revs);
|
||||
|
||||
$revs = $pagelog->getRelativeRevision($rev, -$dir);
|
||||
$this->assertEquals($revsexpectedneg, $revs);
|
||||
}
|
||||
|
||||
/**
|
||||
* start at exact one before last revision of mailinglist page
|
||||
*
|
||||
*/
|
||||
function test_requestlastrevisions() {
|
||||
$rev = 1361901536;
|
||||
$dir = -1;
|
||||
$revsexpectedlast = 1360110636;
|
||||
$revsexpectedbeforelast = false;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revsexpectedlast, $revs);
|
||||
|
||||
$revs = $pagelog->getRelativeRevision($rev, 2 * $dir);
|
||||
$this->assertEquals($revsexpectedbeforelast, $revs);
|
||||
}
|
||||
|
||||
/**
|
||||
* request existing rev and check cache
|
||||
*/
|
||||
function test_requestrev_checkcache() {
|
||||
$rev = 1362525359;
|
||||
$dir = 1;
|
||||
$revexpected = 1362525899;
|
||||
$infoexpected = parseChangelogLine($this->logline);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
|
||||
//checked info returned from cache
|
||||
$info = $pagelog->getRevisionInfo($revfound);
|
||||
$this->assertEquals($infoexpected, $info);
|
||||
}
|
||||
|
||||
/**
|
||||
* request existing rev
|
||||
*/
|
||||
function test_requestnextrev() {
|
||||
$rev = 1362525899;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
|
||||
$dir = 1;
|
||||
$revexpected = 1362525926;
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
|
||||
$dir = 2;
|
||||
$revexpected = 1362526039;
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
|
||||
$dir = -1;
|
||||
$revexpected = 1362525359;
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
|
||||
$dir = -2;
|
||||
$revexpected = 1362525145;
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
}
|
||||
|
||||
/**
|
||||
* request existing rev with chucked reading
|
||||
*/
|
||||
function test_requestnextrev_chuncked() {
|
||||
$rev = 1362525899;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
|
||||
$dir = 1;
|
||||
$revexpected = 1362525926;
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
|
||||
$dir = 2;
|
||||
$revexpected = 1362526039;
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
|
||||
$dir = -1;
|
||||
$revexpected = 1362525359;
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
|
||||
$dir = -2;
|
||||
$revexpected = 1362525145;
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* request existing rev with chucked reading, chunk size smaller than line length
|
||||
*/
|
||||
function test_requestnextrev_chunkshorterthanlines() {
|
||||
$rev = 1362525899;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 20);
|
||||
|
||||
$dir = 1;
|
||||
$revexpected = 1362525926;
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
|
||||
$dir = 2;
|
||||
$revexpected = 1362526039;
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
|
||||
$dir = -1;
|
||||
$revexpected = 1362525359;
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
|
||||
$dir = -2;
|
||||
$revexpected = 1362525145;
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
}
|
||||
|
||||
/**
|
||||
* request existing rev
|
||||
*/
|
||||
function test_requestnextfifthrev() {
|
||||
$rev = 1362525899;
|
||||
$dir = 5;
|
||||
$revexpected = 1362526767;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
}
|
||||
|
||||
/**
|
||||
* request existing rev with chucked reading
|
||||
*/
|
||||
function test_requestnextfifthrev_chuncked() {
|
||||
$rev = 1362525899;
|
||||
$dir = 5;
|
||||
$revexpected = 1362526767;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
}
|
||||
|
||||
/**
|
||||
* request existing rev
|
||||
*/
|
||||
function test_requestprevrev() {
|
||||
$rev = 1362525899;
|
||||
$dir1 = -1;
|
||||
$dir5 = -5;
|
||||
$revexpected1 = 1362525359;
|
||||
$revexpected5 = 1360110636;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revfound1 = $pagelog->getRelativeRevision($rev, $dir1);
|
||||
$this->assertEquals($revexpected1, $revfound1);
|
||||
|
||||
$revfound5 = $pagelog->getRelativeRevision($rev, $dir5);
|
||||
$this->assertEquals($revexpected5, $revfound5);
|
||||
}
|
||||
|
||||
/**
|
||||
* request existing rev with chucked reading
|
||||
*/
|
||||
function test_requestprevrev_chuncked() {
|
||||
$rev = 1362525899;
|
||||
$dir1 = -1;
|
||||
$dir5 = -5;
|
||||
$revexpected1 = 1362525359;
|
||||
$revexpected5 = 1360110636;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revfound1 = $pagelog->getRelativeRevision($rev, $dir1);
|
||||
$this->assertEquals($revexpected1, $revfound1);
|
||||
|
||||
$revfound5 = $pagelog->getRelativeRevision($rev, $dir5);
|
||||
$this->assertEquals($revexpected5, $revfound5);
|
||||
}
|
||||
|
||||
/**
|
||||
* request after recentest version in changelog
|
||||
*/
|
||||
function test_requestrecentestlogline_next() {
|
||||
$rev = 1374261194;
|
||||
$dir = 1;
|
||||
$revexpected = false;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
}
|
||||
|
||||
/**
|
||||
* request after recentest version in changelog, with chuncked reading
|
||||
*/
|
||||
function test_requestrecentestlogline_next_chuncked() {
|
||||
$rev = 1374261194;
|
||||
$dir = 1;
|
||||
$revexpected = false;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
}
|
||||
|
||||
/**
|
||||
* request before current version
|
||||
*/
|
||||
function test_requestrecentestlogline_prev() {
|
||||
$rev = 1374261194;
|
||||
$dir = -1;
|
||||
$revexpected = 1371579614;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
}
|
||||
|
||||
/**
|
||||
* request before current version, with chuncked reading
|
||||
*/
|
||||
function test_requestrecentestlogline_prev_chuncked() {
|
||||
$rev = 1374261194;
|
||||
$dir = -1;
|
||||
$revexpected = 1371579614;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request negative revision
|
||||
* looks in positive direction, so it catches the oldest revision
|
||||
*/
|
||||
function test_negativerev_posdir() {
|
||||
$rev = -10;
|
||||
$dir = 1;
|
||||
$revexpected = 1360110636;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request negative revision
|
||||
* looks in negative direction, but there is nothing
|
||||
*/
|
||||
function test_negativerev_negdir() {
|
||||
$rev = -10;
|
||||
$dir = -1;
|
||||
$revexpected = false;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start at non existing revision somewhere between existing revisions
|
||||
*/
|
||||
function test_startatnotexistingrev_next() {
|
||||
$rev = 1362525890;
|
||||
$dir = 1;
|
||||
$revexpected = 1362525899;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start at non existing revision somewhere between existing revisions
|
||||
*/
|
||||
function test_startatnotexistingrev_prev() {
|
||||
$rev = 1362525890;
|
||||
$dir = -1;
|
||||
$revexpected = 1362525359;
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revfound = $pagelog->getRelativeRevision($rev, $dir);
|
||||
$this->assertEquals($revexpected, $revfound);
|
||||
}
|
||||
|
||||
function test_iscurrentpagerevision() {
|
||||
$rev = 1385051947;
|
||||
$currentexpected = true;
|
||||
|
||||
//set a known timestamp
|
||||
touch(wikiFN($this->pageid), $rev);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$current = $pagelog->isCurrentRevision($rev);
|
||||
$this->assertEquals($currentexpected, $current);
|
||||
}
|
||||
|
||||
function test_isnotcurrentpagerevision() {
|
||||
$rev = 1385051947;
|
||||
$not_current_rev = $rev - 1;
|
||||
$currentexpected = false;
|
||||
|
||||
//set a known timestamp
|
||||
touch(wikiFN($this->pageid), $rev);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$current = $pagelog->isCurrentRevision($not_current_rev);
|
||||
$this->assertEquals($currentexpected, $current);
|
||||
}
|
||||
|
||||
function test_notexistingcurrentpage() {
|
||||
$rev = 1385051947;
|
||||
$currentexpected = false;
|
||||
|
||||
$pagelog = new PageChangeLog('nonexistingpage', $chunk_size = 8192);
|
||||
$current = $pagelog->isCurrentRevision($rev);
|
||||
$this->assertEquals($currentexpected, $current);
|
||||
}
|
||||
}
|
|
@ -21,7 +21,7 @@ class changelog_getrevisionsinfo_test extends DokuWikiTest {
|
|||
unset($cache['nonexist']);
|
||||
}
|
||||
if(isset($cache['mailinglist'])) {
|
||||
unset($cache['nonexist']);
|
||||
unset($cache['mailinglist']);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,11 +29,12 @@ class changelog_getrevisionsinfo_test extends DokuWikiTest {
|
|||
* no nonexist.changes meta file available
|
||||
*/
|
||||
function test_changemetadatanotexists() {
|
||||
$rev = 1362525899;
|
||||
$id = 'nonexist';
|
||||
$rev = 1362525899;
|
||||
$id = 'nonexist';
|
||||
$revsexpected = false;
|
||||
|
||||
$revs = getRevisionInfo($id, $rev, $chunk_size = 8192, $media = false);
|
||||
$pagelog = new PageChangeLog($id, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisionInfo($rev);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
|
@ -41,13 +42,14 @@ class changelog_getrevisionsinfo_test extends DokuWikiTest {
|
|||
* request existing rev
|
||||
*/
|
||||
function test_requestrev() {
|
||||
$rev = 1362525899;
|
||||
$rev = 1362525899;
|
||||
$infoexpected = parseChangelogLine($this->logline);
|
||||
|
||||
$info = getRevisionInfo($this->pageid, $rev, $chunk_size = 8192, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$info = $pagelog->getRevisionInfo($rev);
|
||||
$this->assertEquals($infoexpected, $info);
|
||||
//returns cached value
|
||||
$info = getRevisionInfo($this->pageid, $rev, $chunk_size = 8192, $media = false);
|
||||
$info = $pagelog->getRevisionInfo($rev);
|
||||
$this->assertEquals($infoexpected, $info);
|
||||
}
|
||||
|
||||
|
@ -55,10 +57,23 @@ class changelog_getrevisionsinfo_test extends DokuWikiTest {
|
|||
* request existing rev with chucked reading
|
||||
*/
|
||||
function test_requestrev_chuncked() {
|
||||
$rev = 1362525899;
|
||||
$rev = 1362525899;
|
||||
$infoexpected = parseChangelogLine($this->logline);
|
||||
|
||||
$info = getRevisionInfo($this->pageid, $rev, $chunk_size = 512, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$info = $pagelog->getRevisionInfo($rev);
|
||||
$this->assertEquals($infoexpected, $info);
|
||||
}
|
||||
|
||||
/**
|
||||
* request existing rev with chucked reading
|
||||
*/
|
||||
function test_requestrev_chunckedsmallerthanlinelength() {
|
||||
$rev = 1362525899;
|
||||
$infoexpected = parseChangelogLine($this->logline);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 20);
|
||||
$info = $pagelog->getRevisionInfo($rev);
|
||||
$this->assertEquals($infoexpected, $info);
|
||||
}
|
||||
|
||||
|
@ -66,13 +81,14 @@ class changelog_getrevisionsinfo_test extends DokuWikiTest {
|
|||
* request current version
|
||||
*/
|
||||
function test_requestrecentestlogline() {
|
||||
$rev = 1374261194;
|
||||
$rev = 1374261194;
|
||||
$infoexpected = parseChangelogLine($this->firstlogline);
|
||||
|
||||
$info = getRevisionInfo($this->pageid, $rev, $chunk_size = 8192, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$info = $pagelog->getRevisionInfo($rev);
|
||||
$this->assertEquals($infoexpected, $info);
|
||||
//returns cached value
|
||||
$info = getRevisionInfo($this->pageid, $rev, $chunk_size = 8192, $media = false);
|
||||
$info = $pagelog->getRevisionInfo($rev);
|
||||
$this->assertEquals($infoexpected, $info);
|
||||
}
|
||||
|
||||
|
@ -80,10 +96,11 @@ class changelog_getrevisionsinfo_test extends DokuWikiTest {
|
|||
* request current version, with chuncked reading
|
||||
*/
|
||||
function test_requestrecentestlogline_chuncked() {
|
||||
$rev = 1374261194;
|
||||
$rev = 1374261194;
|
||||
$infoexpected = parseChangelogLine($this->firstlogline);
|
||||
|
||||
$info = getRevisionInfo($this->pageid, $rev, $chunk_size = 512, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$info = $pagelog->getRevisionInfo($rev);
|
||||
$this->assertEquals($infoexpected, $info);
|
||||
}
|
||||
|
||||
|
@ -93,7 +110,8 @@ class changelog_getrevisionsinfo_test extends DokuWikiTest {
|
|||
function test_negativerev() {
|
||||
$rev = -10;
|
||||
|
||||
$info = getRevisionInfo($this->pageid, $rev, $chunk_size = 8192, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$info = $pagelog->getRevisionInfo($rev);
|
||||
$this->assertEquals(false, $info);
|
||||
}
|
||||
|
||||
|
@ -103,7 +121,8 @@ class changelog_getrevisionsinfo_test extends DokuWikiTest {
|
|||
function test_notexistingrev() {
|
||||
$rev = 1362525890;
|
||||
|
||||
$info = getRevisionInfo($this->pageid, $rev, $chunk_size = 8192, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$info = $pagelog->getRevisionInfo($rev);
|
||||
$this->assertEquals(false, $info);
|
||||
}
|
||||
|
||||
|
@ -111,10 +130,11 @@ class changelog_getrevisionsinfo_test extends DokuWikiTest {
|
|||
* sometimes chuncksize is set to true
|
||||
*/
|
||||
function test_chuncksizetrue() {
|
||||
$rev = 1362525899;
|
||||
$rev = 1362525899;
|
||||
$infoexpected = parseChangelogLine($this->logline);
|
||||
|
||||
$info = getRevisionInfo($this->pageid, $rev, true);
|
||||
$pagelog = new PageChangeLog($this->pageid, true);
|
||||
$info = $pagelog->getRevisionInfo($rev);
|
||||
$this->assertEquals($infoexpected, $info);
|
||||
}
|
||||
}
|
|
@ -36,7 +36,7 @@ class changelog_getrevisions_test extends DokuWikiTest {
|
|||
unset($cache['nonexist']);
|
||||
}
|
||||
if(isset($cache['mailinglist'])) {
|
||||
unset($cache['nonexist']);
|
||||
unset($cache['mailinglist']);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,11 +45,12 @@ class changelog_getrevisions_test extends DokuWikiTest {
|
|||
*/
|
||||
function test_changemetadatanotexists() {
|
||||
$first = 0;
|
||||
$num = 1;
|
||||
$id = 'nonexist';
|
||||
|
||||
$revs = getRevisions($id, $first, $num, $chunk_size = 8192, $media = false);
|
||||
$num = 1;
|
||||
$id = 'nonexist';
|
||||
$revsexpected = array();
|
||||
|
||||
$pagelog = new PageChangeLog($id, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
|
@ -58,14 +59,20 @@ class changelog_getrevisions_test extends DokuWikiTest {
|
|||
* (so skips first line which belongs to the current existing page)
|
||||
*/
|
||||
function test_requestlastrev() {
|
||||
$first = 0;
|
||||
$num = 1;
|
||||
$first = 0;
|
||||
$num = 1;
|
||||
$revsexpected = array($this->revsexpected[1]);
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 8192, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 512, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 20);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
|
@ -74,14 +81,20 @@ class changelog_getrevisions_test extends DokuWikiTest {
|
|||
* (so skips first line which belongs to the current existing page)
|
||||
*/
|
||||
function test_requestonebutlastrev() {
|
||||
$first = 1;
|
||||
$num = 1;
|
||||
$first = 1;
|
||||
$num = 1;
|
||||
$revsexpected = array($this->revsexpected[2]);
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 8192, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 512, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 20);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
|
@ -90,14 +103,20 @@ class changelog_getrevisions_test extends DokuWikiTest {
|
|||
* (so skips first line of current existing page)
|
||||
*/
|
||||
function test_requestrevswithoffset() {
|
||||
$first = 10;
|
||||
$num = 5;
|
||||
$first = 10;
|
||||
$num = 5;
|
||||
$revsexpected = array_slice($this->revsexpected, $first + 1, $num);
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 8192, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 512, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 20);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
|
@ -105,14 +124,16 @@ class changelog_getrevisions_test extends DokuWikiTest {
|
|||
* first = -1 requests recentest logline, without skipping
|
||||
*/
|
||||
function test_requestrecentestlogline() {
|
||||
$first = -1;
|
||||
$num = 1;
|
||||
$first = -1;
|
||||
$num = 1;
|
||||
$revsexpected = array($this->revsexpected[0]);
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 8192, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 512, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
|
@ -120,11 +141,12 @@ class changelog_getrevisions_test extends DokuWikiTest {
|
|||
* chunck size = 0 skips chuncked loading
|
||||
*/
|
||||
function test_wholefile() {
|
||||
$first = 0;
|
||||
$num = 1000;
|
||||
$first = 0;
|
||||
$num = 1000;
|
||||
$revsexpected = array_slice($this->revsexpected, 1);
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 0, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 0);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
|
@ -132,14 +154,16 @@ class changelog_getrevisions_test extends DokuWikiTest {
|
|||
* Negative range returns no result
|
||||
*/
|
||||
function test_negativenum() {
|
||||
$first = 0;
|
||||
$num = -10;
|
||||
$first = 0;
|
||||
$num = -10;
|
||||
$revsexpected = array();
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 8192, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 512, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
|
@ -147,14 +171,16 @@ class changelog_getrevisions_test extends DokuWikiTest {
|
|||
* Negative range returns no result
|
||||
*/
|
||||
function test_negativennumoffset() {
|
||||
$first = 2;
|
||||
$num = -10;
|
||||
$first = 2;
|
||||
$num = -10;
|
||||
$revsexpected = array();
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 8192, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 512, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
|
@ -162,14 +188,16 @@ class changelog_getrevisions_test extends DokuWikiTest {
|
|||
* zero range returns no result
|
||||
*/
|
||||
function test_zeronum() {
|
||||
$first = 5;
|
||||
$num = 0;
|
||||
$first = 5;
|
||||
$num = 0;
|
||||
$revsexpected = array();
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 8192, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 512, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
|
@ -177,11 +205,12 @@ class changelog_getrevisions_test extends DokuWikiTest {
|
|||
* get oldest revisions
|
||||
*/
|
||||
function test_requestlargeoffset() {
|
||||
$first = 22;
|
||||
$num = 50;
|
||||
$first = 22;
|
||||
$num = 50;
|
||||
$revsexpected = array_slice($this->revsexpected, $first + 1);
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 8192, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
|
@ -189,11 +218,12 @@ class changelog_getrevisions_test extends DokuWikiTest {
|
|||
* request with too large offset and range
|
||||
*/
|
||||
function test_requesttoolargenumberrevs() {
|
||||
$first = 50;
|
||||
$num = 50;
|
||||
$first = 50;
|
||||
$num = 50;
|
||||
$revsexpected = array();
|
||||
|
||||
$revs = getRevisions($this->pageid, $first, $num, $chunk_size = 8192, $media = false);
|
||||
$pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
|
||||
$revs = $pagelog->getRevisions($first, $num);
|
||||
$this->assertEquals($revsexpected, $revs);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
class cli_options extends DokuWikiTest {
|
||||
|
||||
function test_simpleshort() {
|
||||
$options = new DokuCLI_Options();
|
||||
$options->registerOption('exclude', 'exclude files', 'x', 'file');
|
||||
|
||||
$options->args = array('-x', 'foo', 'bang');
|
||||
$options->parseOptions();
|
||||
|
||||
$this->assertEquals('foo', $options->getOpt('exclude'));
|
||||
$this->assertEquals(array('bang'), $options->args);
|
||||
$this->assertFalse($options->getOpt('nothing'));
|
||||
}
|
||||
|
||||
function test_simplelong1() {
|
||||
$options = new DokuCLI_Options();
|
||||
$options->registerOption('exclude', 'exclude files', 'x', 'file');
|
||||
|
||||
$options->args = array('--exclude', 'foo', 'bang');
|
||||
$options->parseOptions();
|
||||
|
||||
$this->assertEquals('foo', $options->getOpt('exclude'));
|
||||
$this->assertEquals(array('bang'), $options->args);
|
||||
$this->assertFalse($options->getOpt('nothing'));
|
||||
}
|
||||
|
||||
function test_simplelong2() {
|
||||
$options = new DokuCLI_Options();
|
||||
$options->registerOption('exclude', 'exclude files', 'x', 'file');
|
||||
|
||||
$options->args = array('--exclude=foo', 'bang');
|
||||
$options->parseOptions();
|
||||
|
||||
$this->assertEquals('foo', $options->getOpt('exclude'));
|
||||
$this->assertEquals(array('bang'), $options->args);
|
||||
$this->assertFalse($options->getOpt('nothing'));
|
||||
}
|
||||
|
||||
function test_complex() {
|
||||
$options = new DokuCLI_Options();
|
||||
|
||||
$options->registerOption('plugins', 'run on plugins only', 'p');
|
||||
$options->registerCommand('status', 'display status info');
|
||||
$options->registerOption('long', 'display long lines', 'l', false, 'status');
|
||||
|
||||
$options->args = array('-p', 'status', '--long', 'foo');
|
||||
$options->parseOptions();
|
||||
|
||||
$this->assertEquals('status', $options->getCmd());
|
||||
$this->assertTrue($options->getOpt('plugins'));
|
||||
$this->assertTrue($options->getOpt('long'));
|
||||
$this->assertEquals(array('foo'), $options->args);
|
||||
}
|
||||
}
|
|
@ -38,6 +38,7 @@ class common_pageinfo_test extends DokuWikiTest {
|
|||
$info['writable'] = true;
|
||||
$info['editable'] = true;
|
||||
$info['lastmod'] = false;
|
||||
$info['currentrev'] = false;
|
||||
$info['meta'] = array();
|
||||
$info['ip'] = null;
|
||||
$info['user'] = null;
|
||||
|
@ -77,6 +78,7 @@ class common_pageinfo_test extends DokuWikiTest {
|
|||
$info['filepath'] = $filename;
|
||||
$info['exists'] = true;
|
||||
$info['lastmod'] = $rev;
|
||||
$info['currentrev'] = $rev;
|
||||
$info['meta'] = p_get_metadata($ID);
|
||||
|
||||
$this->assertEquals($info, pageinfo());
|
||||
|
@ -101,6 +103,7 @@ class common_pageinfo_test extends DokuWikiTest {
|
|||
$info['filepath'] = $filename;
|
||||
$info['exists'] = true;
|
||||
$info['lastmod'] = $rev;
|
||||
$info['currentrev'] = $rev;
|
||||
$info['meta'] = p_get_metadata($ID);
|
||||
$info['rev'] = '';
|
||||
|
||||
|
@ -131,6 +134,7 @@ class common_pageinfo_test extends DokuWikiTest {
|
|||
$info['namespace'] = 'wiki';
|
||||
$info['meta'] = p_get_metadata($ID);
|
||||
$info['rev'] = $REV;
|
||||
$info['currentrev'] = $rev;
|
||||
$info['filepath'] = str_replace('pages','attic',substr($filename,0,-3).$REV.'.txt.gz');
|
||||
|
||||
$this->assertEquals($info, pageinfo());
|
||||
|
@ -153,6 +157,7 @@ class common_pageinfo_test extends DokuWikiTest {
|
|||
$info['namespace'] = 'wiki';
|
||||
$info['exists'] = true;
|
||||
$info['lastmod'] = $rev;
|
||||
$info['currentrev'] = $rev;
|
||||
$info['meta'] = p_get_metadata($ID);
|
||||
$info['filepath'] = $filename;
|
||||
|
||||
|
@ -197,6 +202,7 @@ class common_pageinfo_test extends DokuWikiTest {
|
|||
$info['filepath'] = $filename;
|
||||
$info['exists'] = true;
|
||||
$info['lastmod'] = $rev;
|
||||
$info['currentrev'] = $rev;
|
||||
$info['meta'] = p_get_metadata($ID); // need $INFO set correctly for addLogEntry()
|
||||
|
||||
global $INFO;
|
||||
|
@ -226,6 +232,7 @@ class common_pageinfo_test extends DokuWikiTest {
|
|||
touch($filename,$now);
|
||||
|
||||
$info['lastmod'] = $now;
|
||||
$info['currentrev'] = $now;
|
||||
$info['meta']['last_change'] = false;
|
||||
$info['ip'] = null;
|
||||
$info['user'] = null;
|
||||
|
@ -251,6 +258,7 @@ class common_pageinfo_test extends DokuWikiTest {
|
|||
$info['filepath'] = $filename;
|
||||
$info['exists'] = true;
|
||||
$info['lastmod'] = $rev;
|
||||
$info['currentrev'] = $rev;
|
||||
$info['meta'] = p_get_metadata($ID);
|
||||
|
||||
// setup a draft, make it more recent than the current page
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
class common_stripsourcemaps_test extends DokuWikiTest {
|
||||
|
||||
function test_all() {
|
||||
|
||||
$text = <<<EOL
|
||||
//@ sourceMappingURL=/foo/bar/xxx.map
|
||||
//# sourceMappingURL=/foo/bar/xxx.map
|
||||
/*@ sourceMappingURL=/foo/bar/xxx.map */
|
||||
/*# sourceMappingURL=/foo/bar/xxx.map */
|
||||
bang
|
||||
EOL;
|
||||
|
||||
$expect = <<<EOL
|
||||
//
|
||||
//
|
||||
/**/
|
||||
/**/
|
||||
bang
|
||||
EOL;
|
||||
|
||||
stripsourcemaps($text);
|
||||
|
||||
|
||||
$this->assertEquals($expect, $text);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,15 +1,22 @@
|
|||
<?php
|
||||
|
||||
require_once (__DIR__ . '/httpclient_mock.php');
|
||||
|
||||
class httpclient_http_test extends DokuWikiTest {
|
||||
protected $server = 'http://httpbin.org';
|
||||
|
||||
|
||||
/**
|
||||
* @group internet
|
||||
*/
|
||||
function test_simpleget(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$data = $http->get($this->server.'/get?foo=bar');
|
||||
$this->assertFalse($data === false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertFalse($data === false, 'HTTP response '.$http->error);
|
||||
$resp = json_decode($data, true);
|
||||
$this->assertTrue(is_array($resp), 'JSON response');
|
||||
$this->assertArrayHasKey('args',$resp);
|
||||
|
@ -20,9 +27,13 @@ class httpclient_http_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_dget(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$data = $http->dget($this->server.'/get',array('foo'=>'bar'));
|
||||
$this->assertFalse($data === false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertFalse($data === false, 'HTTP response '.$http->error);
|
||||
$resp = json_decode($data, true);
|
||||
$this->assertTrue(is_array($resp), 'JSON response');
|
||||
$this->assertArrayHasKey('args',$resp);
|
||||
|
@ -33,9 +44,13 @@ class httpclient_http_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_gzip(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$data = $http->get($this->server.'/gzip');
|
||||
$this->assertFalse($data === false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertFalse($data === false, 'HTTP response '.$http->error);
|
||||
$resp = json_decode($data, true);
|
||||
$this->assertTrue(is_array($resp), 'JSON response');
|
||||
$this->assertArrayHasKey('gzipped',$resp);
|
||||
|
@ -46,9 +61,13 @@ class httpclient_http_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_simplepost(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$data = $http->post($this->server.'/post',array('foo'=>'bar'));
|
||||
$this->assertFalse($data === false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertFalse($data === false, 'HTTP response '.$http->error);
|
||||
$resp = json_decode($data, true);
|
||||
$this->assertTrue(is_array($resp), 'JSON response');
|
||||
$this->assertArrayHasKey('form',$resp);
|
||||
|
@ -59,9 +78,13 @@ class httpclient_http_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_redirect(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$data = $http->get($this->server.'/redirect/3');
|
||||
$this->assertFalse($data === false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertFalse($data === false, 'HTTP response '.$http->error);
|
||||
$resp = json_decode($data, true);
|
||||
$this->assertTrue(is_array($resp), 'JSON response');
|
||||
$this->assertArrayHasKey('url',$resp);
|
||||
|
@ -72,9 +95,13 @@ class httpclient_http_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_relredirect(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$data = $http->get($this->server.'/relative-redirect/3');
|
||||
$this->assertFalse($data === false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertFalse($data === false, 'HTTP response '.$http->error);
|
||||
$resp = json_decode($data, true);
|
||||
$this->assertTrue(is_array($resp), 'JSON response');
|
||||
$this->assertArrayHasKey('url',$resp);
|
||||
|
@ -85,9 +112,13 @@ class httpclient_http_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_redirectfail(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$data = $http->get($this->server.'/redirect/5');
|
||||
$this->assertTrue($data === false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertTrue($data === false, 'HTTP response '.$http->error);
|
||||
$this->assertEquals('Maximum number of redirects exceeded',$http->error);
|
||||
}
|
||||
|
||||
|
@ -95,11 +126,19 @@ class httpclient_http_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_cookies(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$http->get($this->server.'/cookies/set/foo/bar');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertEquals(array('foo' => 'bar'), $http->cookies);
|
||||
$data = $http->get($this->server.'/cookies');
|
||||
$this->assertFalse($data === false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertFalse($data === false, 'HTTP response '.$http->error);
|
||||
$resp = json_decode($data, true);
|
||||
$this->assertTrue(is_array($resp), 'JSON response');
|
||||
$this->assertArrayHasKey('cookies',$resp);
|
||||
|
@ -110,9 +149,13 @@ class httpclient_http_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_teapot(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$data = $http->get($this->server.'/status/418');
|
||||
$this->assertTrue($data === false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertTrue($data === false, 'HTTP response '.$http->error);
|
||||
$this->assertEquals(418,$http->status);
|
||||
}
|
||||
|
||||
|
@ -120,18 +163,26 @@ class httpclient_http_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_maxbody(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$http->max_bodysize = 250;
|
||||
|
||||
// this should abort completely
|
||||
$data = $http->get($this->server.'/stream/30');
|
||||
$this->assertTrue($data === false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertTrue($data === false, 'HTTP response '.$http->error);
|
||||
|
||||
// this should read just the needed bytes
|
||||
$http->max_bodysize_abort = false;
|
||||
$http->keep_alive = false;
|
||||
$data = $http->get($this->server.'/stream/30');
|
||||
$this->assertFalse($data === false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertFalse($data === false, 'HTTP response '.$http->error);
|
||||
/* should read no more than max_bodysize+1 */
|
||||
$this->assertLessThanOrEqual(251,strlen($data));
|
||||
}
|
||||
|
@ -140,24 +191,36 @@ class httpclient_http_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_maxbodyok(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$http->max_bodysize = 500*1024;
|
||||
$data = $http->get($this->server.'/stream/5');
|
||||
$this->assertTrue($data !== false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertTrue($data !== false, 'HTTP response '.$http->error);
|
||||
$http->max_bodysize_abort = false;
|
||||
$data = $http->get($this->server.'/stream/5');
|
||||
$this->assertTrue($data !== false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertTrue($data !== false, 'HTTP response '.$http->error);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group internet
|
||||
*/
|
||||
function test_basicauth(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$http->user = 'user';
|
||||
$http->pass = 'pass';
|
||||
$data = $http->get($this->server.'/basic-auth/user/pass');
|
||||
$this->assertFalse($data === false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertFalse($data === false, 'HTTP response '.$http->error);
|
||||
$resp = json_decode($data, true);
|
||||
$this->assertTrue(is_array($resp), 'JSON response');
|
||||
$this->assertEquals(array('authenticated'=>true,'user'=>'user'), $resp);
|
||||
|
@ -167,11 +230,15 @@ class httpclient_http_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_basicauthfail(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$http->user = 'user';
|
||||
$http->pass = 'invalid';
|
||||
$data = $http->get($this->server.'/basic-auth/user/pass');
|
||||
$this->assertTrue($data === false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertTrue($data === false, 'HTTP response '.$http->error);
|
||||
$this->assertEquals(401,$http->status);
|
||||
}
|
||||
|
||||
|
@ -179,10 +246,10 @@ class httpclient_http_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_timeout(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$http->timeout = 5;
|
||||
$data = $http->get($this->server.'/delay/10');
|
||||
$this->assertTrue($data === false, 'HTTP response');
|
||||
$this->assertTrue($data === false, 'HTTP response '.$http->error);
|
||||
$this->assertEquals(-100,$http->status);
|
||||
}
|
||||
|
||||
|
@ -190,9 +257,13 @@ class httpclient_http_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_headers(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$data = $http->get($this->server.'/response-headers?baz=&foo=bar');
|
||||
$this->assertFalse($data === false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertFalse($data === false, 'HTTP response '.$http->error);
|
||||
$resp = json_decode($data, true);
|
||||
$this->assertTrue(is_array($resp), 'JSON response');
|
||||
$this->assertArrayHasKey('baz',$http->resp_headers);
|
||||
|
@ -204,9 +275,13 @@ class httpclient_http_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_chunked(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$data = $http->get('http://whoopdedo.org/cgi-bin/chunked/2550');
|
||||
$this->assertFalse($data === false, 'HTTP response');
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertFalse($data === false, 'HTTP response '.$http->error);
|
||||
$this->assertEquals(2550,strlen($data));
|
||||
}
|
||||
|
||||
|
@ -216,13 +291,17 @@ class httpclient_http_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_wikimatrix(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
$data = $http->get('http://www.wikimatrix.org/cfeed/dokuwiki/-/-');
|
||||
$this->assertTrue($data !== false, $http->error);
|
||||
if($http->noconnection()) {
|
||||
$this->markTestSkipped('connection timed out');
|
||||
return;
|
||||
}
|
||||
$this->assertTrue($data !== false, 'HTTP response '.$http->error);
|
||||
}
|
||||
|
||||
function test_postencode(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
|
||||
|
||||
// check simple data
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
require_once (__DIR__ . '/httpclient_mock.php');
|
||||
|
||||
class httpclient_http_proxy_test extends DokuWikiTest {
|
||||
protected $url = 'http://test.dokuwiki.org/README';
|
||||
|
||||
|
@ -7,7 +9,7 @@ class httpclient_http_proxy_test extends DokuWikiTest {
|
|||
* @group internet
|
||||
*/
|
||||
function test_simpleget(){
|
||||
$http = new HTTPClient();
|
||||
$http = new HTTPMockClient();
|
||||
// proxy provided by Andrwe Lord Weber <dokuwiki@andrwe.org>
|
||||
$http->proxy_host = 'proxy.andrwe.org';
|
||||
$http->proxy_port = 8080;
|
||||
|
@ -16,5 +18,4 @@ class httpclient_http_proxy_test extends DokuWikiTest {
|
|||
$this->assertFalse($data === false, 'HTTP response '.$http->error);
|
||||
$this->assertTrue(strpos($data,'DokuWiki') !== false, 'response content');
|
||||
}
|
||||
|
||||
}
|
|
@ -12,4 +12,19 @@ class httpclient_https_proxy_test extends httpclient_http_proxy_test {
|
|||
}
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @group internet
|
||||
*/
|
||||
function test_connectfail(){
|
||||
$http = new HTTPMockClient();
|
||||
// proxy provided by Andrwe Lord Weber <dokuwiki@andrwe.org>
|
||||
$http->proxy_host = 'proxy.andrwe.org';
|
||||
$http->proxy_port = 8080;
|
||||
|
||||
// the proxy accepts connections to dokuwiki.org only - the connect call should fail
|
||||
$data = $http->get('https://www.google.com');
|
||||
$this->assertFalse($data);
|
||||
$this->assertEquals(-150, $http->status);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
/**
|
||||
* Class HTTPMockClient
|
||||
*
|
||||
* Does not really mock the client, it still does real connections but will retry failed connections
|
||||
* to work around shaky connectivity.
|
||||
*/
|
||||
class HTTPMockClient extends HTTPClient {
|
||||
protected $tries;
|
||||
|
||||
/**
|
||||
* Sets shorter timeout
|
||||
*/
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
$this->timeout = 8; // slightly faster timeouts
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the connection timed out
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function noconnection() {
|
||||
return ($this->tries === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retries sending the request multiple times
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $data
|
||||
* @param string $method
|
||||
* @return bool
|
||||
*/
|
||||
function sendRequest($url, $data = '', $method = 'GET') {
|
||||
$this->tries = 2; // configures the number of retries
|
||||
$return = false;
|
||||
while($this->tries) {
|
||||
$return = parent::sendRequest($url, $data, $method);
|
||||
if($this->status != -100) break;
|
||||
$this->tries--;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
}
|
|
@ -214,6 +214,25 @@ class input_test extends DokuWikiTest {
|
|||
$this->assertEquals('bla',$test);
|
||||
}
|
||||
|
||||
public function test_valid(){
|
||||
$_REQUEST = $this->data;
|
||||
$_POST = $this->data;
|
||||
$_GET = $this->data;
|
||||
$INPUT = new Input();
|
||||
|
||||
$valids = array(17, 'foo');
|
||||
$this->assertSame(null, $INPUT->valid('nope', $valids));
|
||||
$this->assertSame('bang', $INPUT->valid('nope', $valids, 'bang'));
|
||||
$this->assertSame(17, $INPUT->valid('int', $valids));
|
||||
$this->assertSame('foo', $INPUT->valid('string', $valids));
|
||||
$this->assertSame(null, $INPUT->valid('array', $valids));
|
||||
|
||||
$valids = array(true);
|
||||
$this->assertSame(true, $INPUT->valid('string', $valids));
|
||||
$this->assertSame(true, $INPUT->valid('one', $valids));
|
||||
$this->assertSame(null, $INPUT->valid('zero', $valids));
|
||||
}
|
||||
|
||||
public function test_extract(){
|
||||
$_REQUEST = $this->data;
|
||||
$_POST = $this->data;
|
||||
|
|
|
@ -4,7 +4,7 @@ class io_rmdir_test extends DokuWikiTest {
|
|||
|
||||
function test_nopes(){
|
||||
// set up test dir
|
||||
$dir = io_mktmpdir();
|
||||
$dir = realpath(io_mktmpdir());
|
||||
$top = dirname($dir);
|
||||
$this->assertTrue($dir !== false);
|
||||
$this->assertTrue(is_dir($dir));
|
||||
|
|
|
@ -191,7 +191,10 @@ class mailer_test extends DokuWikiTest {
|
|||
// ask message lint if it is okay
|
||||
$html = new HTTPClient();
|
||||
$results = $html->post('http://tools.ietf.org/tools/msglint/msglint', array('msg'=>$msg));
|
||||
$this->assertTrue($results !== false);
|
||||
if($results === false) {
|
||||
$this->markTestSkipped('no response from validator');
|
||||
return;
|
||||
}
|
||||
|
||||
// parse the result lines
|
||||
$lines = explode("\n", $results);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require_once DOKU_INC . 'inc/parser/parser.php';
|
||||
require_once DOKU_INC . 'inc/parser/handler.php';
|
||||
|
||||
abstract class TestOfDoku_Parser extends PHPUnit_Framework_TestCase {
|
||||
abstract class TestOfDoku_Parser extends DokuWikiTest {
|
||||
|
||||
var $P;
|
||||
var $H;
|
||||
|
|
|
@ -10,8 +10,9 @@ class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
|
|||
}
|
||||
|
||||
function testSingleQuoteOpening() {
|
||||
$raw = "Foo 'hello Bar";
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse("Foo 'hello Bar");
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
|
@ -23,12 +24,13 @@ class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls, 'wikitext => '.$raw);
|
||||
}
|
||||
|
||||
function testSingleQuoteOpeningSpecial() {
|
||||
$raw = "Foo said:'hello Bar";
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse("Foo said:'hello Bar");
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
|
@ -40,12 +42,13 @@ class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls, 'wikitext => '.$raw);
|
||||
}
|
||||
|
||||
function testSingleQuoteClosing() {
|
||||
$raw = "Foo hello' Bar";
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse("Foo hello' Bar");
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
|
@ -57,12 +60,13 @@ class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls, 'wikitext => '.$raw);
|
||||
}
|
||||
|
||||
function testSingleQuoteClosingSpecial() {
|
||||
$raw = "Foo hello') Bar";
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse("Foo hello') Bar");
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
|
@ -74,12 +78,13 @@ class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls, 'wikitext => '.$raw);
|
||||
}
|
||||
|
||||
function testSingleQuotes() {
|
||||
$raw = "Foo 'hello' Bar";
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse("Foo 'hello' Bar");
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
|
@ -93,12 +98,13 @@ class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls, 'wikitext => '.$raw);
|
||||
}
|
||||
|
||||
function testApostrophe() {
|
||||
$raw = "hey it's fine weather today";
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse("hey it's fine weather today");
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
|
@ -110,13 +116,14 @@ class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls, 'wikitext => '.$raw);
|
||||
}
|
||||
|
||||
|
||||
function testSingleQuotesSpecial() {
|
||||
$raw = "Foo ('hello') Bar";
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse("Foo ('hello') Bar");
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
|
@ -130,12 +137,13 @@ class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls, 'wikitext => '.$raw);
|
||||
}
|
||||
|
||||
function testDoubleQuoteOpening() {
|
||||
$raw = 'Foo "hello Bar';
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse('Foo "hello Bar');
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
|
@ -147,12 +155,13 @@ class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls, 'wikitext => '.$raw);
|
||||
}
|
||||
|
||||
function testDoubleQuoteOpeningSpecial() {
|
||||
$raw = 'Foo said:"hello Bar';
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse('Foo said:"hello Bar');
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
|
@ -164,12 +173,14 @@ class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls, 'wikitext => '.$raw);
|
||||
}
|
||||
|
||||
function testDoubleQuoteClosing() {
|
||||
$raw = 'Foo hello" Bar';
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse('Foo hello" Bar');
|
||||
$this->H->status['doublequote'] = 1;
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
|
@ -181,12 +192,14 @@ class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls, 'wikitext => '.$raw);
|
||||
}
|
||||
|
||||
function testDoubleQuoteClosingSpecial() {
|
||||
$raw = 'Foo hello") Bar';
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse('Foo hello") Bar');
|
||||
$this->H->status['doublequote'] = 1;
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
|
@ -198,12 +211,31 @@ class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls, 'wikitext => '.$raw);
|
||||
}
|
||||
function testDoubleQuoteClosingSpecial2() {
|
||||
$raw = 'Foo hello") Bar';
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->H->status['doublequote'] = 0;
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
array('p_open',array()),
|
||||
array('cdata',array("\n".'Foo hello')),
|
||||
array('doublequoteopening',array()),
|
||||
array('cdata',array(') Bar')),
|
||||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls, 'wikitext => '.$raw);
|
||||
}
|
||||
|
||||
function testDoubleQuotes() {
|
||||
$raw = 'Foo "hello" Bar';
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse('Foo "hello" Bar');
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
|
@ -217,12 +249,13 @@ class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls, 'wikitext => '.$raw);
|
||||
}
|
||||
|
||||
function testDoubleQuotesSpecial() {
|
||||
$raw = 'Foo ("hello") Bar';
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse('Foo ("hello") Bar');
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
|
@ -236,12 +269,54 @@ class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls, 'wikitext => '.$raw);
|
||||
}
|
||||
|
||||
function testAllQuotes() {
|
||||
function testDoubleQuotesEnclosingBrackets() {
|
||||
$raw = 'Foo "{hello}" Bar';
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse('There was written "He thought \'It\'s a man\'s world\'".');
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
array('p_open',array()),
|
||||
array('cdata',array("\n".'Foo ')),
|
||||
array('doublequoteopening',array()),
|
||||
array('cdata',array('{hello}')),
|
||||
array('doublequoteclosing',array()),
|
||||
array('cdata',array(' Bar')),
|
||||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls,'wikitext - '.$raw);
|
||||
}
|
||||
|
||||
function testDoubleQuotesEnclosingLink() {
|
||||
$raw = 'Foo "[[www.domain.com]]" Bar';
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
array('p_open',array()),
|
||||
array('cdata',array("\n".'Foo ')),
|
||||
array('doublequoteopening',array()),
|
||||
array('cdata',array('[[www.domain.com]]')),
|
||||
array('doublequoteclosing',array()),
|
||||
array('cdata',array(' Bar')),
|
||||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls,'wikitext => '.$raw);
|
||||
}
|
||||
|
||||
|
||||
function testAllQuotes() {
|
||||
$raw = 'There was written "He thought \'It\'s a man\'s world\'".';
|
||||
$this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
|
||||
$this->P->parse($raw);
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
|
@ -262,7 +337,7 @@ class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls,'wikitext => '.$raw);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ def');
|
|||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
}
|
||||
|
||||
function testTableWinEOL() {
|
||||
|
@ -84,7 +84,7 @@ def');
|
|||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
}
|
||||
|
||||
function testEmptyTable() {
|
||||
|
@ -109,7 +109,7 @@ def');
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
}
|
||||
|
||||
function testTableHeaders() {
|
||||
|
@ -143,7 +143,152 @@ def');
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
|
||||
}
|
||||
|
||||
function testTableHead() {
|
||||
$this->P->addMode('table',new Doku_Parser_Mode_Table());
|
||||
$this->P->parse('
|
||||
abc
|
||||
^ X ^ Y ^ Z ^
|
||||
| x | y | z |
|
||||
def');
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
array('p_open',array()),
|
||||
array('cdata',array("\n\nabc")),
|
||||
array('p_close',array()),
|
||||
array('table_open',array(3, 2, 6)),
|
||||
array('tablethead_open',array()),
|
||||
array('tablerow_open',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' X ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' Y ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' Z ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tablerow_close',array()),
|
||||
array('tablethead_close',array()),
|
||||
array('tablerow_open',array()),
|
||||
array('tablecell_open',array(1,NULL,1)),
|
||||
array('cdata',array(' x ')),
|
||||
array('tablecell_close',array()),
|
||||
array('tablecell_open',array(1,NULL,1)),
|
||||
array('cdata',array(' y ')),
|
||||
array('tablecell_close',array()),
|
||||
array('tablecell_open',array(1,NULL,1)),
|
||||
array('cdata',array(' z ')),
|
||||
array('tablecell_close',array()),
|
||||
array('tablerow_close',array()),
|
||||
array('table_close',array(33)),
|
||||
array('p_open',array()),
|
||||
array('cdata',array('def')),
|
||||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
|
||||
}
|
||||
|
||||
function testTableHeadOneRowTable() {
|
||||
$this->P->addMode('table',new Doku_Parser_Mode_Table());
|
||||
$this->P->parse('
|
||||
abc
|
||||
^ X ^ Y ^ Z ^
|
||||
def');
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
array('p_open',array()),
|
||||
array('cdata',array("\n\nabc")),
|
||||
array('p_close',array()),
|
||||
array('table_open',array(3, 1, 6)),
|
||||
array('tablerow_open',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' X ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' Y ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' Z ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tablerow_close',array()),
|
||||
array('table_close',array(19)),
|
||||
array('p_open',array()),
|
||||
array('cdata',array('def')),
|
||||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
|
||||
}
|
||||
|
||||
function testTableHeadMultiline() {
|
||||
$this->P->addMode('table',new Doku_Parser_Mode_Table());
|
||||
$this->P->parse('
|
||||
abc
|
||||
^ X1 ^ Y1 ^ Z1 ^
|
||||
^ X2 ^ Y2 ^ Z2 ^
|
||||
| A | B | C |
|
||||
def');
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
array('p_open',array()),
|
||||
array('cdata',array("\n\nabc")),
|
||||
array('p_close',array()),
|
||||
array('table_open',array(3, 3, 6)),
|
||||
array('tablethead_open',array()),
|
||||
array('tablerow_open',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' X1 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' Y1 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' Z1 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tablerow_close',array()),
|
||||
array('tablerow_open',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' X2 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' Y2 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' Z2 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tablerow_close',array()),
|
||||
array('tablethead_close',array()),
|
||||
array('tablerow_open',array()),
|
||||
array('tablecell_open',array(1,NULL,1)),
|
||||
array('cdata',array(' A ')),
|
||||
array('tablecell_close',array()),
|
||||
array('tablecell_open',array(1,NULL,1)),
|
||||
array('cdata',array(' B ')),
|
||||
array('tablecell_close',array()),
|
||||
array('tablecell_open',array(1,NULL,1)),
|
||||
array('cdata',array(' C ')),
|
||||
array('tablecell_close',array()),
|
||||
array('tablerow_close',array()),
|
||||
array('table_close',array(53)),
|
||||
array('p_open',array()),
|
||||
array('cdata',array('def')),
|
||||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
|
||||
}
|
||||
|
||||
|
@ -178,7 +323,7 @@ def');
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
}
|
||||
|
||||
function testCellSpan() {
|
||||
|
@ -220,7 +365,7 @@ def');
|
|||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
}
|
||||
|
||||
function testCellRowSpan() {
|
||||
|
@ -268,7 +413,7 @@ def');
|
|||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
}
|
||||
|
||||
function testCellRowSpanFirstRow() {
|
||||
|
@ -326,9 +471,134 @@ def');
|
|||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
}
|
||||
|
||||
function testRowSpanTableHead() {
|
||||
$this->P->addMode('table',new Doku_Parser_Mode_Table());
|
||||
$this->P->parse('
|
||||
abc
|
||||
^ X1 ^ Y1 ^ Z1 ^
|
||||
^ X2 ^ ::: ^ Z2 ^
|
||||
| A3 | B3 | C3 |
|
||||
def');
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
array('p_open',array()),
|
||||
array('cdata',array("\n\nabc")),
|
||||
array('p_close',array()),
|
||||
array('table_open',array(3, 3, 6)),
|
||||
array('tablethead_open',array()),
|
||||
array('tablerow_open',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' X1 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tableheader_open',array(1,NULL,2)),
|
||||
array('cdata',array(' Y1 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' Z1 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tablerow_close',array()),
|
||||
array('tablerow_open',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' X2 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' Z2 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tablerow_close',array()),
|
||||
array('tablethead_close',array()),
|
||||
array('tablerow_open',array()),
|
||||
array('tablecell_open',array(1,NULL,1)),
|
||||
array('cdata',array(' A3 ')),
|
||||
array('tablecell_close',array()),
|
||||
array('tablecell_open',array(1,NULL,1)),
|
||||
array('cdata',array(' B3 ')),
|
||||
array('tablecell_close',array()),
|
||||
array('tablecell_open',array(1,NULL,1)),
|
||||
array('cdata',array(' C3 ')),
|
||||
array('tablecell_close',array()),
|
||||
array('tablerow_close',array()),
|
||||
array('table_close',array(57)),
|
||||
array('p_open',array()),
|
||||
array('cdata',array('def')),
|
||||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
|
||||
}
|
||||
|
||||
function testRowSpanAcrossTableHeadBoundary() {
|
||||
$this->P->addMode('table',new Doku_Parser_Mode_Table());
|
||||
$this->P->parse('
|
||||
abc
|
||||
^ X1 ^ Y1 ^ Z1 ^
|
||||
^ X2 ^ ::: ^ Z2 ^
|
||||
| A3 | ::: | C3 |
|
||||
| A4 | ::: | C4 |
|
||||
def');
|
||||
|
||||
$calls = array (
|
||||
array('document_start',array()),
|
||||
array('p_open',array()),
|
||||
array('cdata',array("\n\nabc")),
|
||||
array('p_close',array()),
|
||||
array('table_open',array(3, 4, 6)),
|
||||
array('tablethead_open',array()),
|
||||
array('tablerow_open',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' X1 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tableheader_open',array(1,NULL,2)),
|
||||
array('cdata',array(' Y1 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' Z1 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tablerow_close',array()),
|
||||
array('tablerow_open',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' X2 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tableheader_open',array(1,NULL,1)),
|
||||
array('cdata',array(' Z2 ')),
|
||||
array('tableheader_close',array()),
|
||||
array('tablerow_close',array()),
|
||||
array('tablethead_close',array()),
|
||||
array('tablerow_open',array()),
|
||||
array('tablecell_open',array(1,NULL,1)),
|
||||
array('cdata',array(' A3 ')),
|
||||
array('tablecell_close',array()),
|
||||
array('tablecell_open',array(1,NULL,2)),
|
||||
array('cdata',array('')),
|
||||
array('tablecell_close',array()),
|
||||
array('tablecell_open',array(1,NULL,1)),
|
||||
array('cdata',array(' C3 ')),
|
||||
array('tablecell_close',array()),
|
||||
array('tablerow_close',array()),
|
||||
array('tablerow_open',array()),
|
||||
array('tablecell_open',array(1,NULL,1)),
|
||||
array('cdata',array(' A4 ')),
|
||||
array('tablecell_close',array()),
|
||||
array('tablecell_open',array(1,NULL,1)),
|
||||
array('cdata',array(' C4 ')),
|
||||
array('tablecell_close',array()),
|
||||
array('tablerow_close',array()),
|
||||
array('table_close',array(76)),
|
||||
array('p_open',array()),
|
||||
array('cdata',array('def')),
|
||||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
|
||||
}
|
||||
|
||||
function testCellAlignmentFormatting() {
|
||||
$this->P->addMode('table',new Doku_Parser_Mode_Table());
|
||||
$this->P->addMode('strong',new Doku_Parser_Mode_Formatting('strong'));
|
||||
|
@ -365,7 +635,7 @@ def');
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
|
||||
}
|
||||
|
||||
|
@ -411,7 +681,7 @@ def');
|
|||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
}
|
||||
|
||||
// This is really a failing test - formatting able to spread across cols
|
||||
|
@ -466,7 +736,7 @@ def');
|
|||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
}
|
||||
|
||||
// This is really a failing test - unformatted able to spread across cols
|
||||
|
@ -517,7 +787,7 @@ def');
|
|||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
}
|
||||
|
||||
function testTableLinebreak() {
|
||||
|
@ -565,7 +835,7 @@ def');
|
|||
array('document_end',array()),
|
||||
);
|
||||
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
}
|
||||
|
||||
// This is really a failing test - footnote able to spread across cols
|
||||
|
@ -624,7 +894,7 @@ def');
|
|||
array('p_close',array()),
|
||||
array('document_end',array()),
|
||||
);
|
||||
$this->assertEquals(array_map('stripbyteindex',$this->H->calls),$calls);
|
||||
$this->assertEquals($calls,array_map('stripbyteindex',$this->H->calls));
|
||||
}
|
||||
|
||||
function testTable_FS1833() {
|
||||
|
@ -646,4 +916,3 @@ def');
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
require_once DOKU_INC . 'inc/parser/renderer.php';
|
||||
|
||||
/**
|
||||
* Tests for Doku_Renderer::_resolveInterWiki()
|
||||
*/
|
||||
class Test_resolveInterwiki extends DokuWikiTest {
|
||||
|
||||
function testDefaults() {
|
||||
$Renderer = new Doku_Renderer();
|
||||
$Renderer->interwiki = getInterwiki();
|
||||
$Renderer->interwiki['scheme'] = '{SCHEME}://example.com';
|
||||
$Renderer->interwiki['withslash'] = '/test';
|
||||
$Renderer->interwiki['onlytext'] = ':onlytext{NAME}'; //with {URL} double urlencoded
|
||||
$Renderer->interwiki['withquery'] = ':anyns:{NAME}?do=edit';
|
||||
|
||||
$tests = array(
|
||||
// shortcut, reference and expected
|
||||
array('wp', 'foo @+%/#txt', 'http://en.wikipedia.org/wiki/foo @+%/#txt'),
|
||||
array('amazon', 'foo @+%/#txt', 'http://www.amazon.com/exec/obidos/ASIN/foo%20%40%2B%25%2F/splitbrain-20/#txt'),
|
||||
array('doku', 'foo @+%/#txt', 'http://www.dokuwiki.org/foo%20%40%2B%25%2F#txt'),
|
||||
array('coral', 'http://example.com:83/path/naar/?query=foo%20%40%2B%25%2F', 'http://example.com.83.nyud.net:8090/path/naar/?query=foo%20%40%2B%25%2F'),
|
||||
array('scheme', 'ftp://foo @+%/#txt', 'ftp://example.com#txt'),
|
||||
//relative url
|
||||
array('withslash', 'foo @+%/#txt', '/testfoo%20%40%2B%25%2F#txt'),
|
||||
array('skype', 'foo @+%/#txt', 'skype:foo @+%/#txt'),
|
||||
//dokuwiki id's
|
||||
array('onlytext', 'foo @+%#txt', DOKU_BASE.'doku.php?id=onlytextfoo#txt'),
|
||||
array('user', 'foo @+%#txt', DOKU_BASE.'doku.php?id=user:foo#txt'),
|
||||
array('withquery', 'foo @+%#txt', DOKU_BASE.'doku.php?id=anyns:foo&do=edit#txt')
|
||||
);
|
||||
|
||||
foreach($tests as $test) {
|
||||
$url = $Renderer->_resolveInterWiki($test[0], $test[1]);
|
||||
|
||||
$this->assertEquals($test[2], $url);
|
||||
}
|
||||
}
|
||||
|
||||
function testNonexisting() {
|
||||
$Renderer = new Doku_Renderer();
|
||||
$Renderer->interwiki = getInterwiki();
|
||||
|
||||
$shortcut = 'nonexisting';
|
||||
$reference = 'foo @+%/';
|
||||
$url = $Renderer->_resolveInterWiki($shortcut, $reference);
|
||||
$expected = 'http://www.google.com/search?q=foo%20%40%2B%25%2F&btnI=lucky';
|
||||
|
||||
$this->assertEquals($expected, $url);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
class parserutils_get_renderer_test extends DokuWikiTest {
|
||||
|
||||
private $plugin_controller;
|
||||
|
||||
// test default behaviour / usual settings
|
||||
function test_p_get_renderer_normal() {
|
||||
global $conf;
|
||||
|
||||
$old_conf = $conf;
|
||||
$conf['renderer_xhtml'] = 'xhtml';
|
||||
|
||||
$this->assertInstanceOf('Doku_Renderer_xhtml', p_get_renderer('xhtml'));
|
||||
|
||||
$conf = $old_conf;
|
||||
}
|
||||
|
||||
// test get a renderer plugin
|
||||
function test_p_get_renderer_plugin() {
|
||||
global $conf;
|
||||
global $plugin_controller;
|
||||
|
||||
$old_conf = $conf;
|
||||
$conf['renderer_xhtml'] = 'get_renderer_test';
|
||||
$this->plugin_controller = $plugin_controller;
|
||||
$plugin_controller = $this;
|
||||
|
||||
$this->assertInstanceOf('renderer_plugin_test', p_get_renderer('xhtml'));
|
||||
|
||||
$conf = $old_conf;
|
||||
$plugin_controller = $this->plugin_controller;
|
||||
}
|
||||
|
||||
// test fallback succeeds
|
||||
function test_p_get_renderer_fallback() {
|
||||
global $conf;
|
||||
|
||||
$old_conf = $conf;
|
||||
$conf['renderer_xhtml'] = 'badvalue';
|
||||
|
||||
$this->assertInstanceOf('Doku_Renderer_xhtml', p_get_renderer('xhtml'));
|
||||
|
||||
$conf = $old_conf;
|
||||
}
|
||||
|
||||
// test fallback fails
|
||||
function test_p_get_renderer_fallback_fail() {
|
||||
global $conf;
|
||||
|
||||
$old_conf = $conf;
|
||||
$conf['renderer_junk'] = 'badvalue';
|
||||
|
||||
$this->assertNull(p_get_renderer('junk'));
|
||||
|
||||
$conf = $old_conf;
|
||||
}
|
||||
|
||||
// wrapper function for the fake plugin controller, return $this for the fake syntax of this test
|
||||
function load($type,$name,$new=false,$disabled=false){
|
||||
if ($name == 'get_renderer_test') {
|
||||
return new renderer_plugin_test();
|
||||
} else {
|
||||
return $this->plugin_controller->load($type, $name, $new, $disabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
require_once DOKU_INC . 'inc/parser/xhtml.php';
|
||||
|
||||
class renderer_plugin_test extends Doku_Renderer_xhtml {
|
||||
|
||||
function canRender($format) {
|
||||
return ($format=='xhtml');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim:ts=4:sw=4:et:
|
|
@ -1,6 +1,38 @@
|
|||
<?php
|
||||
|
||||
class Tar_TestCase extends DokuWikiTest {
|
||||
/**
|
||||
* file extensions that several tests use
|
||||
*/
|
||||
protected $extensions = array('tar');
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
if (extension_loaded('zlib')) {
|
||||
$this->extensions[] = 'tgz';
|
||||
}
|
||||
if (extension_loaded('bz2')) {
|
||||
$this->extensions[] = 'tbz';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dependency for tests needing zlib extension to pass
|
||||
*/
|
||||
public function test_ext_zlib() {
|
||||
if (!extension_loaded('zlib')) {
|
||||
$this->markTestSkipped('skipping all zlib tests. Need zlib extension');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dependency for tests needing zlib extension to pass
|
||||
*/
|
||||
public function test_ext_bz2() {
|
||||
if (!extension_loaded('bz2')) {
|
||||
$this->markTestSkipped('skipping all bzip2 tests. Need bz2 extension');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* simple test that checks that the given filenames and contents can be grepped from
|
||||
|
@ -58,8 +90,6 @@ class Tar_TestCase extends DokuWikiTest {
|
|||
$tar->addData('another/testdata3.txt', 'testcontent3');
|
||||
$tar->close();
|
||||
|
||||
copy ($tmp, '/tmp/test.tar');
|
||||
|
||||
$this->assertTrue(filesize($tmp) > 30); //arbitrary non-zero number
|
||||
$data = file_get_contents($tmp);
|
||||
|
||||
|
@ -89,7 +119,7 @@ copy ($tmp, '/tmp/test.tar');
|
|||
public function test_tarcontent() {
|
||||
$dir = dirname(__FILE__).'/tar';
|
||||
|
||||
foreach(array('tar', 'tgz', 'tbz') as $ext) {
|
||||
foreach($this->extensions as $ext) {
|
||||
$tar = new Tar();
|
||||
$file = "$dir/test.$ext";
|
||||
|
||||
|
@ -112,7 +142,7 @@ copy ($tmp, '/tmp/test.tar');
|
|||
$dir = dirname(__FILE__).'/tar';
|
||||
$out = sys_get_temp_dir().'/dwtartest'.md5(time());
|
||||
|
||||
foreach(array('tar', 'tgz', 'tbz') as $ext) {
|
||||
foreach($this->extensions as $ext) {
|
||||
$tar = new Tar();
|
||||
$file = "$dir/test.$ext";
|
||||
|
||||
|
@ -138,7 +168,7 @@ copy ($tmp, '/tmp/test.tar');
|
|||
$dir = dirname(__FILE__).'/tar';
|
||||
$out = sys_get_temp_dir().'/dwtartest'.md5(time());
|
||||
|
||||
foreach(array('tar', 'tgz', 'tbz') as $ext) {
|
||||
foreach($this->extensions as $ext) {
|
||||
$tar = new Tar();
|
||||
$file = "$dir/test.$ext";
|
||||
|
||||
|
@ -164,7 +194,7 @@ copy ($tmp, '/tmp/test.tar');
|
|||
$dir = dirname(__FILE__).'/tar';
|
||||
$out = sys_get_temp_dir().'/dwtartest'.md5(time());
|
||||
|
||||
foreach(array('tar', 'tgz', 'tbz') as $ext) {
|
||||
foreach($this->extensions as $ext) {
|
||||
$tar = new Tar();
|
||||
$file = "$dir/test.$ext";
|
||||
|
||||
|
@ -190,7 +220,7 @@ copy ($tmp, '/tmp/test.tar');
|
|||
$dir = dirname(__FILE__).'/tar';
|
||||
$out = sys_get_temp_dir().'/dwtartest'.md5(time());
|
||||
|
||||
foreach(array('tar', 'tgz', 'tbz') as $ext) {
|
||||
foreach($this->extensions as $ext) {
|
||||
$tar = new Tar();
|
||||
$file = "$dir/test.$ext";
|
||||
|
||||
|
@ -215,7 +245,7 @@ copy ($tmp, '/tmp/test.tar');
|
|||
$dir = dirname(__FILE__).'/tar';
|
||||
$out = sys_get_temp_dir().'/dwtartest'.md5(time());
|
||||
|
||||
foreach(array('tar', 'tgz', 'tbz') as $ext) {
|
||||
foreach($this->extensions as $ext) {
|
||||
$tar = new Tar();
|
||||
$file = "$dir/test.$ext";
|
||||
|
||||
|
@ -249,6 +279,9 @@ copy ($tmp, '/tmp/test.tar');
|
|||
$this->assertEquals(Tar::COMPRESS_BZIP, $tar->filetype('foo.tar.bz2'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends test_ext_zlib
|
||||
*/
|
||||
public function test_longpathextract() {
|
||||
$dir = dirname(__FILE__).'/tar';
|
||||
$out = sys_get_temp_dir().'/dwtartest'.md5(time());
|
||||
|
@ -338,6 +371,7 @@ copy ($tmp, '/tmp/test.tar');
|
|||
|
||||
/**
|
||||
* Extract a tarbomomb
|
||||
* @depends test_ext_zlib
|
||||
*/
|
||||
public function test_tarbomb() {
|
||||
$dir = dirname(__FILE__).'/tar';
|
||||
|
|
|
@ -5,7 +5,7 @@ if(!defined('UTF8_NOMBSTRING')) define('UTF8_NOMBSTRING',1);
|
|||
/**
|
||||
* @group slow
|
||||
*/
|
||||
class utf8_romanize_test extends PHPUnit_Framework_TestCase {
|
||||
class utf8_romanize_test extends DokuWikiTest {
|
||||
|
||||
/**
|
||||
* Check Japanese romanization
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
// use no mbstring help here
|
||||
if(!defined('UTF8_NOMBSTRING')) define('UTF8_NOMBSTRING',1);
|
||||
|
||||
class utf8_strtolower_test extends DokuWikiTest {
|
||||
|
||||
function test_givens(){
|
||||
$data = array(
|
||||
'Αρχιτεκτονική Μελέτη' => 'αρχιτεκτονική μελέτη', // FS#2173
|
||||
);
|
||||
|
||||
foreach($data as $input => $expected) {
|
||||
$this->assertEquals($expected, utf8_strtolower($input));
|
||||
}
|
||||
|
||||
// just make sure our data was correct
|
||||
if(function_exists('mb_strtolower')) {
|
||||
foreach($data as $input => $expected) {
|
||||
$this->assertEquals($expected, mb_strtolower($input, 'utf-8'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,41 +10,70 @@ class css_css_compress_test extends DokuWikiTest {
|
|||
* line *test*
|
||||
* check
|
||||
*/';
|
||||
$this->assertEquals(css_compress($text), '');
|
||||
$this->assertEquals('', css_compress($text));
|
||||
}
|
||||
|
||||
function test_mlcom2(){
|
||||
$text = '#comment/* */ {
|
||||
color: lime;
|
||||
}';
|
||||
$this->assertEquals(css_compress($text), '#comment/* */{color:lime;}');
|
||||
$this->assertEquals('#comment/* */{color:lime;}', css_compress($text));
|
||||
}
|
||||
|
||||
function test_slcom1(){
|
||||
$text = '// this is a comment';
|
||||
$this->assertEquals(css_compress($text), '');
|
||||
$this->assertEquals('', css_compress($text));
|
||||
}
|
||||
|
||||
function test_slcom2(){
|
||||
$text = '#foo {
|
||||
color: lime; // another comment
|
||||
}';
|
||||
$this->assertEquals(css_compress($text), '#foo{color:lime;}');
|
||||
$this->assertEquals('#foo{color:lime;}', css_compress($text));
|
||||
}
|
||||
|
||||
function test_slcom3(){
|
||||
$text = '#foo {
|
||||
background-image: url(http://foo.bar/baz.jpg);
|
||||
background-image: url(http://foo.bar/baz.jpg); // this is a comment
|
||||
}';
|
||||
$this->assertEquals(css_compress($text), '#foo{background-image:url(http://foo.bar/baz.jpg);}');
|
||||
$this->assertEquals('#foo{background-image:url(http://foo.bar/baz.jpg);}', css_compress($text));
|
||||
}
|
||||
|
||||
function test_slcom4(){
|
||||
$text = '#foo {
|
||||
background-image: url(http://foo.bar/baz.jpg); background-image: url(http://foo.bar/baz.jpg); // this is a comment
|
||||
}';
|
||||
$this->assertEquals('#foo{background-image:url(http://foo.bar/baz.jpg);background-image:url(http://foo.bar/baz.jpg);}', css_compress($text));
|
||||
}
|
||||
|
||||
function test_slcom5(){
|
||||
$text = '#foo {
|
||||
background-image: url(http://foo.bar/baz.jpg); // background-image: url(http://foo.bar/baz.jpg); this is all commented
|
||||
}';
|
||||
$this->assertEquals('#foo{background-image:url(http://foo.bar/baz.jpg);}', css_compress($text));
|
||||
}
|
||||
|
||||
function test_slcom6(){
|
||||
$text = '#foo {
|
||||
background-image: url(//foo.bar/baz.jpg); // background-image: url(http://foo.bar/baz.jpg); this is all commented
|
||||
}';
|
||||
$this->assertEquals('#foo{background-image:url(//foo.bar/baz.jpg);}', css_compress($text));
|
||||
}
|
||||
|
||||
function test_slcom7(){
|
||||
$text = '#foo a[href ^="https://"], #foo a[href ^=\'https://\'] {
|
||||
background-image: url(//foo.bar/baz.jpg); // background-image: url(http://foo.bar/baz.jpg); this is \'all\' "commented"
|
||||
}';
|
||||
$this->assertEquals('#foo a[href ^="https://"],#foo a[href ^=\'https://\']{background-image:url(//foo.bar/baz.jpg);}', css_compress($text));
|
||||
}
|
||||
|
||||
|
||||
function test_hack(){
|
||||
$text = '/* Mac IE will not see this and continue with inline-block */
|
||||
/* \\*/
|
||||
display: inline;
|
||||
/* */';
|
||||
$this->assertEquals(css_compress($text), '/* \\*/display:inline;/* */');
|
||||
$this->assertEquals('/* \\*/display:inline;/* */', css_compress($text));
|
||||
}
|
||||
|
||||
function test_hack2(){
|
||||
|
@ -54,12 +83,12 @@ class css_css_compress_test extends DokuWikiTest {
|
|||
height: 450px;
|
||||
}
|
||||
/**/';
|
||||
$this->assertEquals(css_compress($text), '/*\\*/* html .page{height:450px;}/**/');
|
||||
$this->assertEquals('/*\\*/* html .page{height:450px;}/**/', css_compress($text));
|
||||
}
|
||||
|
||||
function test_nl1(){
|
||||
$text = "a{left:20px;\ntop:20px}";
|
||||
$this->assertEquals(css_compress($text), 'a{left:20px;top:20px}');
|
||||
$this->assertEquals('a{left:20px;top:20px}', css_compress($text));
|
||||
}
|
||||
|
||||
function test_shortening() {
|
||||
|
@ -102,6 +131,13 @@ class css_css_compress_test extends DokuWikiTest {
|
|||
$this->assertEquals($expected, $input);
|
||||
}
|
||||
|
||||
function test_data() {
|
||||
$input = 'list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);';
|
||||
$expect = 'list-style-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);';
|
||||
|
||||
$this->assertEquals($expect, css_compress($input));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Setup VIM: ex: et ts=4 :
|
||||
|
|
|
@ -33,7 +33,7 @@ class InttestsBasicTest extends DokuWikiTest {
|
|||
$response = $request->execute();
|
||||
|
||||
$this->assertTrue(
|
||||
strpos($response->getContent(), 'DokuWiki') >= 0,
|
||||
strpos($response->getContent(), 'DokuWiki') !== false,
|
||||
'DokuWiki was not a word in the output'
|
||||
);
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ class InttestsBasicTest extends DokuWikiTest {
|
|||
$this->assertEquals('wiki:dokuwiki', $request->getPost('id'));
|
||||
|
||||
// output check
|
||||
$this->assertTrue(strpos($response->getContent(), 'Andreas Gohr') >= 0);
|
||||
$this->assertTrue(strpos($response->getContent(), 'Andreas Gohr') !== false);
|
||||
}
|
||||
|
||||
function testPostGet() {
|
||||
|
@ -84,7 +84,7 @@ class InttestsBasicTest extends DokuWikiTest {
|
|||
$this->assertEquals('wiki:dokuwiki', $request->getGet('id'));
|
||||
|
||||
// output check
|
||||
$this->assertTrue(strpos($response->getContent(), 'Andreas Gohr') >= 0);
|
||||
$this->assertTrue(strpos($response->getContent(), 'Andreas Gohr') !== false);
|
||||
}
|
||||
|
||||
function testGet() {
|
||||
|
@ -116,7 +116,7 @@ class InttestsBasicTest extends DokuWikiTest {
|
|||
$this->assertEquals('bar', $request->getGet('test'));
|
||||
|
||||
// output check
|
||||
$this->assertTrue(strpos($response->getContent(), 'Andreas Gohr') >= 0);
|
||||
$this->assertTrue(strpos($response->getContent(), 'Andreas Gohr') !== false);
|
||||
}
|
||||
|
||||
function testScripts() {
|
||||
|
@ -168,5 +168,13 @@ class InttestsBasicTest extends DokuWikiTest {
|
|||
$response = new TestResponse('',array_slice($this->some_headers,0,-2)); // slice off the last two headers to leave no status header
|
||||
$this->assertNull($response->getStatusCode());
|
||||
}
|
||||
|
||||
function testINPUT() {
|
||||
$request = new TestRequest();
|
||||
$response = $request->get(array('id' => 'mailinglist'), '/doku.php');
|
||||
|
||||
// output check
|
||||
$this->assertTrue(strpos($response->getContent(), 'Netiquette') !== false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
663
bin/dwpage.php
663
bin/dwpage.php
|
@ -1,378 +1,317 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
#------------------------------------------------------------------------------
|
||||
if ('cli' != php_sapi_name()) die();
|
||||
if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__).'/../').'/');
|
||||
define('NOSESSION', 1);
|
||||
require_once(DOKU_INC.'inc/init.php');
|
||||
|
||||
ini_set('memory_limit','128M');
|
||||
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
|
||||
require_once DOKU_INC.'inc/init.php';
|
||||
require_once DOKU_INC.'inc/common.php';
|
||||
require_once DOKU_INC.'inc/cliopts.php';
|
||||
/**
|
||||
* Checkout and commit pages from the command line while maintaining the history
|
||||
*/
|
||||
class PageCLI extends DokuCLI {
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
function usage($action) {
|
||||
switch ( $action ) {
|
||||
case 'checkout':
|
||||
print "Usage: dwpage.php [opts] checkout <wiki:page> [working_file]
|
||||
protected $force = false;
|
||||
protected $username = '';
|
||||
|
||||
Checks out a file from the repository, using the wiki id and obtaining
|
||||
a lock for the page.
|
||||
If a working_file is specified, this is where the page is copied to.
|
||||
Otherwise defaults to the same as the wiki page in the current
|
||||
working directory.
|
||||
/**
|
||||
* Register options and arguments on the given $options object
|
||||
*
|
||||
* @param DokuCLI_Options $options
|
||||
* @return void
|
||||
*/
|
||||
protected function setup(DokuCLI_Options $options) {
|
||||
/* global */
|
||||
$options->registerOption(
|
||||
'force',
|
||||
'force obtaining a lock for the page (generally bad idea)',
|
||||
'f'
|
||||
);
|
||||
$options->registerOption(
|
||||
'user',
|
||||
'work as this user. defaults to current CLI user',
|
||||
'u'
|
||||
);
|
||||
$options->setHelp(
|
||||
'Utility to help command line Dokuwiki page editing, allow '.
|
||||
'pages to be checked out for editing then committed after changes'
|
||||
);
|
||||
|
||||
EXAMPLE
|
||||
$ ./dwpage.php checkout wiki:syntax ./new_syntax.txt
|
||||
/* checkout command */
|
||||
$options->registerCommand(
|
||||
'checkout',
|
||||
'Checks out a file from the repository, using the wiki id and obtaining '.
|
||||
'a lock for the page. '."\n".
|
||||
'If a working_file is specified, this is where the page is copied to. '.
|
||||
'Otherwise defaults to the same as the wiki page in the current '.
|
||||
'working directory.'
|
||||
);
|
||||
$options->registerArgument(
|
||||
'wikipage',
|
||||
'The wiki page to checkout',
|
||||
true,
|
||||
'checkout'
|
||||
);
|
||||
$options->registerArgument(
|
||||
'workingfile',
|
||||
'How to name the local checkout',
|
||||
false,
|
||||
'checkout'
|
||||
);
|
||||
|
||||
OPTIONS
|
||||
-h, --help=<action>: get help
|
||||
-f: force obtaining a lock for the page (generally bad idea)
|
||||
";
|
||||
break;
|
||||
case 'commit':
|
||||
print "Usage: dwpage.php [opts] -m \"Msg\" commit <working_file> <wiki:page>
|
||||
/* commit command */
|
||||
$options->registerCommand(
|
||||
'commit',
|
||||
'Checks in the working_file into the repository using the specified '.
|
||||
'wiki id, archiving the previous version.'
|
||||
);
|
||||
$options->registerArgument(
|
||||
'workingfile',
|
||||
'The local file to commit',
|
||||
true,
|
||||
'commit'
|
||||
);
|
||||
$options->registerArgument(
|
||||
'wikipage',
|
||||
'The wiki page to create or update',
|
||||
true,
|
||||
'commit'
|
||||
);
|
||||
$options->registerOption(
|
||||
'message',
|
||||
'Summary describing the change (required)',
|
||||
'm',
|
||||
'summary',
|
||||
'commit'
|
||||
);
|
||||
$options->registerOption(
|
||||
'trivial',
|
||||
'minor change',
|
||||
't',
|
||||
false,
|
||||
'commit'
|
||||
);
|
||||
|
||||
Checks in the working_file into the repository using the specified
|
||||
wiki id, archiving the previous version.
|
||||
/* lock command */
|
||||
$options->registerCommand(
|
||||
'lock',
|
||||
'Obtains or updates a lock for a wiki page'
|
||||
);
|
||||
$options->registerArgument(
|
||||
'wikipage',
|
||||
'The wiki page to lock',
|
||||
true,
|
||||
'lock'
|
||||
);
|
||||
|
||||
EXAMPLE
|
||||
$ ./dwpage.php -m \"Some message\" commit ./new_syntax.txt wiki:syntax
|
||||
|
||||
OPTIONS
|
||||
-h, --help=<action>: get help
|
||||
-f: force obtaining a lock for the page (generally bad idea)
|
||||
-t, trivial: minor change
|
||||
-m (required): Summary message describing the change
|
||||
";
|
||||
break;
|
||||
case 'lock':
|
||||
print "Usage: dwpage.php [opts] lock <wiki:page>
|
||||
|
||||
Obtains or updates a lock for a wiki page
|
||||
|
||||
EXAMPLE
|
||||
$ ./dwpage.php lock wiki:syntax
|
||||
|
||||
OPTIONS
|
||||
-h, --help=<action>: get help
|
||||
-f: force obtaining a lock for the page (generally bad idea)
|
||||
";
|
||||
break;
|
||||
case 'unlock':
|
||||
print "Usage: dwpage.php [opts] unlock <wiki:page>
|
||||
|
||||
Removes a lock for a wiki page.
|
||||
|
||||
EXAMPLE
|
||||
$ ./dwpage.php unlock wiki:syntax
|
||||
|
||||
OPTIONS
|
||||
-h, --help=<action>: get help
|
||||
-f: force obtaining a lock for the page (generally bad idea)
|
||||
";
|
||||
break;
|
||||
default:
|
||||
print "Usage: dwpage.php [opts] <action>
|
||||
|
||||
Utility to help command line Dokuwiki page editing, allow
|
||||
pages to be checked out for editing then committed after changes
|
||||
|
||||
Normal operation would be;
|
||||
|
||||
|
||||
|
||||
ACTIONS
|
||||
checkout: see $ dwpage.php --help=checkout
|
||||
commit: see $ dwpage.php --help=commit
|
||||
lock: see $ dwpage.php --help=lock
|
||||
|
||||
OPTIONS
|
||||
-h, --help=<action>: get help
|
||||
e.g. $ ./dwpage.php -hcommit
|
||||
e.g. $ ./dwpage.php --help=commit
|
||||
";
|
||||
break;
|
||||
/* unlock command */
|
||||
$options->registerCommand(
|
||||
'unlock',
|
||||
'Removes a lock for a wiki page.'
|
||||
);
|
||||
$options->registerArgument(
|
||||
'wikipage',
|
||||
'The wiki page to unlock',
|
||||
true,
|
||||
'unlock'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
function getUser() {
|
||||
$user = getenv('USER');
|
||||
if (empty ($user)) {
|
||||
$user = getenv('USERNAME');
|
||||
} else {
|
||||
/**
|
||||
* Your main program
|
||||
*
|
||||
* Arguments and options have been parsed when this is run
|
||||
*
|
||||
* @param DokuCLI_Options $options
|
||||
* @return void
|
||||
*/
|
||||
protected function main(DokuCLI_Options $options) {
|
||||
$this->force = $options->getOpt('force', false);
|
||||
$this->username = $options->getOpt('user', $this->getUser());
|
||||
|
||||
$command = $options->getCmd();
|
||||
switch($command) {
|
||||
case 'checkout':
|
||||
$wiki_id = array_shift($options->args);
|
||||
$localfile = array_shift($options->args);
|
||||
$this->commandCheckout($wiki_id, $localfile);
|
||||
break;
|
||||
case 'commit':
|
||||
$localfile = array_shift($options->args);
|
||||
$wiki_id = array_shift($options->args);
|
||||
$this->commandCommit(
|
||||
$localfile,
|
||||
$wiki_id,
|
||||
$options->getOpt('message', ''),
|
||||
$options->getOpt('trivial', false)
|
||||
);
|
||||
break;
|
||||
case 'lock':
|
||||
$wiki_id = array_shift($options->args);
|
||||
$this->obtainLock($wiki_id);
|
||||
$this->success("$wiki_id locked");
|
||||
break;
|
||||
case 'unlock':
|
||||
$wiki_id = array_shift($options->args);
|
||||
$this->clearLock($wiki_id);
|
||||
$this->success("$wiki_id unlocked");
|
||||
break;
|
||||
default:
|
||||
echo $options->help();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check out a file
|
||||
*
|
||||
* @param string $wiki_id
|
||||
* @param string $localfile
|
||||
*/
|
||||
protected function commandCheckout($wiki_id, $localfile) {
|
||||
global $conf;
|
||||
|
||||
$wiki_id = cleanID($wiki_id);
|
||||
$wiki_fn = wikiFN($wiki_id);
|
||||
|
||||
if(!file_exists($wiki_fn)) {
|
||||
$this->fatal("$wiki_id does not yet exist");
|
||||
}
|
||||
|
||||
if(empty($localfile)) {
|
||||
$localfile = getcwd().'/'.utf8_basename($wiki_fn);
|
||||
}
|
||||
|
||||
if(!file_exists(dirname($localfile))) {
|
||||
$this->fatal("Directory ".dirname($localfile)." does not exist");
|
||||
}
|
||||
|
||||
if(stristr(realpath(dirname($localfile)), realpath($conf['datadir'])) !== false) {
|
||||
$this->fatal("Attempt to check out file into data directory - not allowed");
|
||||
}
|
||||
|
||||
$this->obtainLock($wiki_id);
|
||||
|
||||
if(!copy($wiki_fn, $localfile)) {
|
||||
$this->clearLock($wiki_id);
|
||||
$this->fatal("Unable to copy $wiki_fn to $localfile");
|
||||
}
|
||||
|
||||
$this->success("$wiki_id > $localfile");
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a file as a new page revision
|
||||
*
|
||||
* @param string $localfile
|
||||
* @param string $wiki_id
|
||||
* @param string $message
|
||||
* @param bool $minor
|
||||
*/
|
||||
protected function commandCommit($localfile, $wiki_id, $message, $minor) {
|
||||
$wiki_id = cleanID($wiki_id);
|
||||
$message = trim($message);
|
||||
|
||||
if(!file_exists($localfile)) {
|
||||
$this->fatal("$localfile does not exist");
|
||||
}
|
||||
|
||||
if(!is_readable($localfile)) {
|
||||
$this->fatal("Cannot read from $localfile");
|
||||
}
|
||||
|
||||
if(!$message) {
|
||||
$this->fatal("Summary message required");
|
||||
}
|
||||
|
||||
$this->obtainLock($wiki_id);
|
||||
|
||||
saveWikiText($wiki_id, file_get_contents($localfile), $message, $minor);
|
||||
|
||||
$this->clearLock($wiki_id);
|
||||
|
||||
$this->success("$localfile > $wiki_id");
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock the given page or exit
|
||||
*
|
||||
* @param string $wiki_id
|
||||
*/
|
||||
protected function obtainLock($wiki_id) {
|
||||
if($this->force) $this->deleteLock($wiki_id);
|
||||
|
||||
$_SERVER['REMOTE_USER'] = $this->username;
|
||||
if(checklock($wiki_id)) {
|
||||
$this->error("Page $wiki_id is already locked by another user");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
lock($wiki_id);
|
||||
|
||||
$_SERVER['REMOTE_USER'] = '_'.$this->username.'_';
|
||||
if(checklock($wiki_id) != $this->username) {
|
||||
$this->error("Unable to obtain lock for $wiki_id ");
|
||||
var_dump(checklock($wiki_id));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the lock on the given page
|
||||
*
|
||||
* @param string $wiki_id
|
||||
*/
|
||||
protected function clearLock($wiki_id) {
|
||||
if($this->force) $this->deleteLock($wiki_id);
|
||||
|
||||
$_SERVER['REMOTE_USER'] = $this->username;
|
||||
if(checklock($wiki_id)) {
|
||||
$this->error("Page $wiki_id is locked by another user");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
unlock($wiki_id);
|
||||
|
||||
if(file_exists(wikiLockFN($wiki_id))) {
|
||||
$this->error("Unable to clear lock for $wiki_id");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forcefully remove a lock on the page given
|
||||
*
|
||||
* @param string $wiki_id
|
||||
*/
|
||||
protected function deleteLock($wiki_id) {
|
||||
$wikiLockFN = wikiLockFN($wiki_id);
|
||||
|
||||
if(file_exists($wikiLockFN)) {
|
||||
if(!unlink($wikiLockFN)) {
|
||||
$this->error("Unable to delete $wikiLockFN");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current user's username from the environment
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getUser() {
|
||||
$user = getenv('USER');
|
||||
if(empty ($user)) {
|
||||
$user = getenv('USERNAME');
|
||||
} else {
|
||||
return $user;
|
||||
}
|
||||
if(empty ($user)) {
|
||||
$user = 'admin';
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
if (empty ($user)) {
|
||||
$user = 'admin';
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
function getSuppliedArgument($OPTS, $short, $long) {
|
||||
$arg = $OPTS->get($short);
|
||||
if ( is_null($arg) ) {
|
||||
$arg = $OPTS->get($long);
|
||||
}
|
||||
return $arg;
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
function obtainLock($WIKI_ID) {
|
||||
|
||||
global $USERNAME;
|
||||
|
||||
if ( !file_exists(wikiFN($WIKI_ID)) ) {
|
||||
fwrite( STDERR, "$WIKI_ID does not yet exist\n");
|
||||
}
|
||||
|
||||
$_SERVER['REMOTE_USER'] = $USERNAME;
|
||||
if ( checklock($WIKI_ID) ) {
|
||||
fwrite( STDERR, "Page $WIKI_ID is already locked by another user\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
lock($WIKI_ID);
|
||||
|
||||
$_SERVER['REMOTE_USER'] = '_'.$USERNAME.'_';
|
||||
|
||||
if ( checklock($WIKI_ID) != $USERNAME ) {
|
||||
|
||||
fwrite( STDERR, "Unable to obtain lock for $WIKI_ID\n" );
|
||||
exit(1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
function clearLock($WIKI_ID) {
|
||||
|
||||
global $USERNAME ;
|
||||
|
||||
if ( !file_exists(wikiFN($WIKI_ID)) ) {
|
||||
fwrite( STDERR, "$WIKI_ID does not yet exist\n");
|
||||
}
|
||||
|
||||
$_SERVER['REMOTE_USER'] = $USERNAME;
|
||||
if ( checklock($WIKI_ID) ) {
|
||||
fwrite( STDERR, "Page $WIKI_ID is locked by another user\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
unlock($WIKI_ID);
|
||||
|
||||
if ( file_exists(wikiLockFN($WIKI_ID)) ) {
|
||||
fwrite( STDERR, "Unable to clear lock for $WIKI_ID\n" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
function deleteLock($WIKI_ID) {
|
||||
|
||||
$wikiLockFN = wikiLockFN($WIKI_ID);
|
||||
|
||||
if ( file_exists($wikiLockFN) ) {
|
||||
if ( !unlink($wikiLockFN) ) {
|
||||
fwrite( STDERR, "Unable to delete $wikiLockFN\n" );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
$USERNAME = getUser();
|
||||
$CWD = getcwd();
|
||||
$SYSTEM_ID = '127.0.0.1';
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
$OPTS = Doku_Cli_Opts::getOptions(
|
||||
__FILE__,
|
||||
'h::fm:u:s:t',
|
||||
array(
|
||||
'help==',
|
||||
'user=',
|
||||
'system=',
|
||||
'trivial',
|
||||
)
|
||||
);
|
||||
|
||||
if ( $OPTS->isError() ) {
|
||||
print $OPTS->getMessage()."\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( $OPTS->has('h') or $OPTS->has('help') or !$OPTS->hasArgs() ) {
|
||||
usage(getSuppliedArgument($OPTS,'h','help'));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ( $OPTS->has('u') or $OPTS->has('user') ) {
|
||||
$USERNAME = getSuppliedArgument($OPTS,'u','user');
|
||||
}
|
||||
|
||||
if ( $OPTS->has('s') or $OPTS->has('system') ) {
|
||||
$SYSTEM_ID = getSuppliedArgument($OPTS,'s','system');
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
switch ( $OPTS->arg(0) ) {
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
case 'checkout':
|
||||
|
||||
$WIKI_ID = $OPTS->arg(1);
|
||||
|
||||
if ( !$WIKI_ID ) {
|
||||
fwrite( STDERR, "Wiki page ID required\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$WIKI_FN = wikiFN($WIKI_ID);
|
||||
|
||||
if ( !file_exists($WIKI_FN) ) {
|
||||
fwrite( STDERR, "$WIKI_ID does not yet exist\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$TARGET_FN = $OPTS->arg(2);
|
||||
|
||||
if ( empty($TARGET_FN) ) {
|
||||
$TARGET_FN = getcwd().'/'.utf8_basename($WIKI_FN);
|
||||
}
|
||||
|
||||
if ( !file_exists(dirname($TARGET_FN)) ) {
|
||||
fwrite( STDERR, "Directory ".dirname($TARGET_FN)." does not exist\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( stristr( realpath(dirname($TARGET_FN)), realpath($conf['datadir']) ) !== false ) {
|
||||
fwrite( STDERR, "Attempt to check out file into data directory - not allowed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( $OPTS->has('f') ) {
|
||||
deleteLock($WIKI_ID);
|
||||
}
|
||||
|
||||
obtainLock($WIKI_ID);
|
||||
|
||||
# Need to lock the file first?
|
||||
if ( !copy($WIKI_FN, $TARGET_FN) ) {
|
||||
fwrite( STDERR, "Unable to copy $WIKI_FN to $TARGET_FN\n");
|
||||
clearLock($WIKI_ID);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
print "$WIKI_ID > $TARGET_FN\n";
|
||||
exit(0);
|
||||
|
||||
break;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
case 'commit':
|
||||
|
||||
$TARGET_FN = $OPTS->arg(1);
|
||||
|
||||
if ( !$TARGET_FN ) {
|
||||
fwrite( STDERR, "Target filename required\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( !file_exists($TARGET_FN) ) {
|
||||
fwrite( STDERR, "$TARGET_FN does not exist\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( !is_readable($TARGET_FN) ) {
|
||||
fwrite( STDERR, "Cannot read from $TARGET_FN\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$WIKI_ID = $OPTS->arg(2);
|
||||
|
||||
if ( !$WIKI_ID ) {
|
||||
fwrite( STDERR, "Wiki page ID required\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( !$OPTS->has('m') ) {
|
||||
fwrite( STDERR, "Summary message required\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( $OPTS->has('f') ) {
|
||||
deleteLock($WIKI_ID);
|
||||
}
|
||||
|
||||
$_SERVER['REMOTE_USER'] = $USERNAME;
|
||||
if ( checklock($WIKI_ID) ) {
|
||||
fwrite( STDERR, "$WIKI_ID is locked by another user\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
obtainLock($WIKI_ID);
|
||||
|
||||
saveWikiText($WIKI_ID, file_get_contents($TARGET_FN), $OPTS->get('m'), $OPTS->has('t'));
|
||||
|
||||
clearLock($WIKI_ID);
|
||||
|
||||
exit(0);
|
||||
|
||||
break;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
case 'lock':
|
||||
|
||||
$WIKI_ID = $OPTS->arg(1);
|
||||
|
||||
if ( !$WIKI_ID ) {
|
||||
fwrite( STDERR, "Wiki page ID required\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( $OPTS->has('f') ) {
|
||||
deleteLock($WIKI_ID);
|
||||
}
|
||||
|
||||
obtainLock($WIKI_ID);
|
||||
|
||||
print "Locked : $WIKI_ID\n";
|
||||
exit(0);
|
||||
|
||||
break;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
case 'unlock':
|
||||
|
||||
$WIKI_ID = $OPTS->arg(1);
|
||||
|
||||
if ( !$WIKI_ID ) {
|
||||
fwrite( STDERR, "Wiki page ID required\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( $OPTS->has('f') ) {
|
||||
deleteLock($WIKI_ID);
|
||||
} else {
|
||||
clearLock($WIKI_ID);
|
||||
}
|
||||
|
||||
print "Unlocked : $WIKI_ID\n";
|
||||
exit(0);
|
||||
|
||||
break;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
default:
|
||||
|
||||
fwrite( STDERR, "Invalid action ".$OPTS->arg(0)."\n" );
|
||||
exit(1);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Main
|
||||
$cli = new PageCLI();
|
||||
$cli->run();
|
|
@ -0,0 +1,334 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__).'/../').'/');
|
||||
define('NOSESSION', 1);
|
||||
require_once(DOKU_INC.'inc/init.php');
|
||||
|
||||
/**
|
||||
* Easily manage DokuWiki git repositories
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*/
|
||||
class GitToolCLI extends DokuCLI {
|
||||
|
||||
/**
|
||||
* Register options and arguments on the given $options object
|
||||
*
|
||||
* @param DokuCLI_Options $options
|
||||
* @return void
|
||||
*/
|
||||
protected function setup(DokuCLI_Options $options) {
|
||||
$options->setHelp(
|
||||
"Manage git repositories for DokuWiki and its plugins and templates.\n\n".
|
||||
"$> ./bin/gittool.php clone gallery template:ach\n".
|
||||
"$> ./bin/gittool.php repos\n".
|
||||
"$> ./bin/gittool.php origin -v"
|
||||
);
|
||||
|
||||
$options->registerArgument(
|
||||
'command',
|
||||
'Command to execute. See below',
|
||||
true
|
||||
);
|
||||
|
||||
$options->registerCommand(
|
||||
'clone',
|
||||
'Tries to install a known plugin or template (prefix with template:) via git. Uses the DokuWiki.org '.
|
||||
'plugin repository to find the proper git repository. Multiple extensions can be given as parameters'
|
||||
);
|
||||
$options->registerArgument(
|
||||
'extension',
|
||||
'name of the extension to install, prefix with \'template:\' for templates',
|
||||
true,
|
||||
'clone'
|
||||
);
|
||||
|
||||
$options->registerCommand(
|
||||
'install',
|
||||
'The same as clone, but when no git source repository can be found, the extension is installed via '.
|
||||
'download'
|
||||
);
|
||||
$options->registerArgument(
|
||||
'extension',
|
||||
'name of the extension to install, prefix with \'template:\' for templates',
|
||||
true,
|
||||
'install'
|
||||
);
|
||||
|
||||
$options->registerCommand(
|
||||
'repos',
|
||||
'Lists all git repositories found in this DokuWiki installation'
|
||||
);
|
||||
|
||||
$options->registerCommand(
|
||||
'*',
|
||||
'Any unknown commands are assumed to be arguments to git and will be executed in all repositories '.
|
||||
'found within this DokuWiki installation'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Your main program
|
||||
*
|
||||
* Arguments and options have been parsed when this is run
|
||||
*
|
||||
* @param DokuCLI_Options $options
|
||||
* @return void
|
||||
*/
|
||||
protected function main(DokuCLI_Options $options) {
|
||||
$command = $options->getCmd();
|
||||
if(!$command) $command = array_shift($options->args);
|
||||
|
||||
switch($command) {
|
||||
case '':
|
||||
echo $options->help();
|
||||
break;
|
||||
case 'clone':
|
||||
$this->cmd_clone($options->args);
|
||||
break;
|
||||
case 'install':
|
||||
$this->cmd_install($options->args);
|
||||
break;
|
||||
case 'repo':
|
||||
case 'repos':
|
||||
$this->cmd_repos();
|
||||
break;
|
||||
default:
|
||||
$this->cmd_git($command, $options->args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to install the given extensions using git clone
|
||||
*
|
||||
* @param $extensions
|
||||
*/
|
||||
public function cmd_clone($extensions) {
|
||||
$errors = array();
|
||||
$succeeded = array();
|
||||
|
||||
foreach($extensions as $ext) {
|
||||
$repo = $this->getSourceRepo($ext);
|
||||
|
||||
if(!$repo) {
|
||||
$this->error("could not find a repository for $ext");
|
||||
$errors[] = $ext;
|
||||
} else {
|
||||
if($this->cloneExtension($ext, $repo)) {
|
||||
$succeeded[] = $ext;
|
||||
} else {
|
||||
$errors[] = $ext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
if($succeeded) $this->success('successfully cloned the following extensions: '.join(', ', $succeeded));
|
||||
if($errors) $this->error('failed to clone the following extensions: '.join(', ', $errors));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to install the given extensions using git clone with fallback to install
|
||||
*
|
||||
* @param $extensions
|
||||
*/
|
||||
public function cmd_install($extensions) {
|
||||
$errors = array();
|
||||
$succeeded = array();
|
||||
|
||||
foreach($extensions as $ext) {
|
||||
$repo = $this->getSourceRepo($ext);
|
||||
|
||||
if(!$repo) {
|
||||
$this->info("could not find a repository for $ext");
|
||||
if($this->downloadExtension($ext)) {
|
||||
$succeeded[] = $ext;
|
||||
} else {
|
||||
$errors[] = $ext;
|
||||
}
|
||||
} else {
|
||||
if($this->cloneExtension($ext, $repo)) {
|
||||
$succeeded[] = $ext;
|
||||
} else {
|
||||
$errors[] = $ext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
if($succeeded) $this->success('successfully installed the following extensions: '.join(', ', $succeeded));
|
||||
if($errors) $this->error('failed to install the following extensions: '.join(', ', $errors));
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given git command in every repository
|
||||
*
|
||||
* @param $cmd
|
||||
* @param $arg
|
||||
*/
|
||||
public function cmd_git($cmd, $arg) {
|
||||
$repos = $this->findRepos();
|
||||
|
||||
$shell = array_merge(array('git', $cmd), $arg);
|
||||
$shell = array_map('escapeshellarg', $shell);
|
||||
$shell = join(' ', $shell);
|
||||
|
||||
foreach($repos as $repo) {
|
||||
if(!@chdir($repo)) {
|
||||
$this->error("Could not change into $repo");
|
||||
continue;
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
$this->info("executing $shell in $repo");
|
||||
$ret = 0;
|
||||
system($shell, $ret);
|
||||
|
||||
if($ret == 0) {
|
||||
$this->success("git succeeded in $repo");
|
||||
} else {
|
||||
$this->error("git failed in $repo");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply lists the repositories
|
||||
*/
|
||||
public function cmd_repos() {
|
||||
$repos = $this->findRepos();
|
||||
foreach($repos as $repo) {
|
||||
echo "$repo\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Install extension from the given download URL
|
||||
*
|
||||
* @param string $ext
|
||||
* @return bool
|
||||
*/
|
||||
private function downloadExtension($ext) {
|
||||
/** @var helper_plugin_extension_extension $plugin */
|
||||
$plugin = plugin_load('helper', 'extension_extension');
|
||||
if(!$ext) die("extension plugin not available, can't continue");
|
||||
$plugin->setExtension($ext);
|
||||
|
||||
$url = $plugin->getDownloadURL();
|
||||
if(!$url) {
|
||||
$this->error("no download URL for $ext");
|
||||
return false;
|
||||
}
|
||||
|
||||
$ok = false;
|
||||
try {
|
||||
$this->info("installing $ext via download from $url");
|
||||
$ok = $plugin->installFromURL($url);
|
||||
} catch(Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
|
||||
if($ok) {
|
||||
$this->success("installed $ext via download");
|
||||
return true;
|
||||
} else {
|
||||
$this->success("failed to install $ext via download");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the extension from the given repository
|
||||
*
|
||||
* @param string $ext
|
||||
* @param string $repo
|
||||
* @return bool
|
||||
*/
|
||||
private function cloneExtension($ext, $repo) {
|
||||
if(substr($ext, 0, 9) == 'template:') {
|
||||
$target = fullpath(tpl_incdir().'../'.substr($ext, 9));
|
||||
} else {
|
||||
$target = DOKU_PLUGIN.$ext;
|
||||
}
|
||||
|
||||
$this->info("cloning $ext from $repo to $target");
|
||||
$ret = 0;
|
||||
system("git clone $repo $target", $ret);
|
||||
if($ret === 0) {
|
||||
$this->success("cloning of $ext succeeded");
|
||||
return true;
|
||||
} else {
|
||||
$this->error("cloning of $ext failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all git repositories in this DokuWiki install
|
||||
*
|
||||
* Looks in root, template and plugin directories only.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function findRepos() {
|
||||
$this->info('Looking for .git directories');
|
||||
$data = array_merge(
|
||||
glob(DOKU_INC.'.git', GLOB_ONLYDIR),
|
||||
glob(DOKU_PLUGIN.'*/.git', GLOB_ONLYDIR),
|
||||
glob(fullpath(tpl_incdir().'../').'/*/.git', GLOB_ONLYDIR)
|
||||
);
|
||||
|
||||
if(!$data) {
|
||||
$this->error('Found no .git directories');
|
||||
} else {
|
||||
$this->success('Found '.count($data).' .git directories');
|
||||
}
|
||||
$data = array_map('fullpath', array_map('dirname', $data));
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the repository for the given extension
|
||||
*
|
||||
* @param $extension
|
||||
* @return bool|string
|
||||
*/
|
||||
private function getSourceRepo($extension) {
|
||||
/** @var helper_plugin_extension_extension $ext */
|
||||
$ext = plugin_load('helper', 'extension_extension');
|
||||
if(!$ext) die("extension plugin not available, can't continue");
|
||||
$ext->setExtension($extension);
|
||||
|
||||
$repourl = $ext->getSourcerepoURL();
|
||||
if(!$repourl) return false;
|
||||
|
||||
// match github repos
|
||||
if(preg_match('/github\.com\/([^\/]+)\/([^\/]+)/i', $repourl, $m)) {
|
||||
$user = $m[1];
|
||||
$repo = $m[2];
|
||||
return 'https://github.com/'.$user.'/'.$repo.'.git';
|
||||
}
|
||||
|
||||
// match gitorious repos
|
||||
if(preg_match('/gitorious.org\/([^\/]+)\/([^\/]+)?/i', $repourl, $m)) {
|
||||
$user = $m[1];
|
||||
$repo = $m[2];
|
||||
if(!$repo) $repo = $user;
|
||||
|
||||
return 'https://git.gitorious.org/'.$user.'/'.$repo.'.git';
|
||||
}
|
||||
|
||||
// match bitbucket repos - most people seem to use mercurial there though
|
||||
if(preg_match('/bitbucket\.org\/([^\/]+)\/([^\/]+)/i', $repourl, $m)) {
|
||||
$user = $m[1];
|
||||
$repo = $m[2];
|
||||
return 'https://bitbucket.org/'.$user.'/'.$repo.'.git';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Main
|
||||
$cli = new GitToolCLI();
|
||||
$cli->run();
|
185
bin/indexer.php
185
bin/indexer.php
|
@ -1,98 +1,103 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
if ('cli' != php_sapi_name()) die();
|
||||
|
||||
ini_set('memory_limit','128M');
|
||||
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
|
||||
if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__).'/../').'/');
|
||||
define('NOSESSION', 1);
|
||||
require_once(DOKU_INC.'inc/init.php');
|
||||
require_once(DOKU_INC.'inc/cliopts.php');
|
||||
session_write_close();
|
||||
|
||||
// handle options
|
||||
$short_opts = 'hcuq';
|
||||
$long_opts = array('help', 'clear', 'update', 'quiet');
|
||||
$OPTS = Doku_Cli_Opts::getOptions(__FILE__,$short_opts,$long_opts);
|
||||
if ( $OPTS->isError() ) {
|
||||
fwrite( STDERR, $OPTS->getMessage() . "\n");
|
||||
_usage();
|
||||
exit(1);
|
||||
}
|
||||
$CLEAR = false;
|
||||
$QUIET = false;
|
||||
$INDEXER = null;
|
||||
foreach ($OPTS->options as $key => $val) {
|
||||
switch ($key) {
|
||||
case 'h':
|
||||
case 'help':
|
||||
_usage();
|
||||
exit;
|
||||
case 'c':
|
||||
case 'clear':
|
||||
$CLEAR = true;
|
||||
break;
|
||||
case 'q':
|
||||
case 'quiet':
|
||||
$QUIET = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Action
|
||||
|
||||
if($CLEAR) _clearindex();
|
||||
_update();
|
||||
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
function _usage() {
|
||||
print "Usage: indexer.php <options>
|
||||
|
||||
Updates the searchindex by indexing all new or changed pages
|
||||
when the -c option is given the index is cleared first.
|
||||
|
||||
OPTIONS
|
||||
-h, --help show this help and exit
|
||||
-c, --clear clear the index before updating
|
||||
-q, --quiet don't produce any output
|
||||
";
|
||||
}
|
||||
|
||||
function _update(){
|
||||
global $conf;
|
||||
$data = array();
|
||||
_quietecho("Searching pages... ");
|
||||
search($data,$conf['datadir'],'search_allpages',array('skipacl' => true));
|
||||
_quietecho(count($data)." pages found.\n");
|
||||
|
||||
foreach($data as $val){
|
||||
_index($val['id']);
|
||||
}
|
||||
}
|
||||
|
||||
function _index($id){
|
||||
global $CLEAR;
|
||||
global $QUIET;
|
||||
|
||||
_quietecho("$id... ");
|
||||
idx_addPage($id, !$QUIET, $CLEAR);
|
||||
_quietecho("done.\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all index files
|
||||
* Update the Search Index from command line
|
||||
*/
|
||||
function _clearindex(){
|
||||
_quietecho("Clearing index... ");
|
||||
idx_get_indexer()->clear();
|
||||
_quietecho("done.\n");
|
||||
class IndexerCLI extends DokuCLI {
|
||||
|
||||
private $quiet = false;
|
||||
private $clear = false;
|
||||
|
||||
/**
|
||||
* Register options and arguments on the given $options object
|
||||
*
|
||||
* @param DokuCLI_Options $options
|
||||
* @return void
|
||||
*/
|
||||
protected function setup(DokuCLI_Options $options) {
|
||||
$options->setHelp(
|
||||
'Updates the searchindex by indexing all new or changed pages. When the -c option is '.
|
||||
'given the index is cleared first.'
|
||||
);
|
||||
|
||||
$options->registerOption(
|
||||
'clear',
|
||||
'clear the index before updating',
|
||||
'c'
|
||||
);
|
||||
$options->registerOption(
|
||||
'quiet',
|
||||
'don\'t produce any output',
|
||||
'q'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Your main program
|
||||
*
|
||||
* Arguments and options have been parsed when this is run
|
||||
*
|
||||
* @param DokuCLI_Options $options
|
||||
* @return void
|
||||
*/
|
||||
protected function main(DokuCLI_Options $options) {
|
||||
$this->clear = $options->getOpt('clear');
|
||||
$this->quiet = $options->getOpt('quiet');
|
||||
|
||||
if($this->clear) $this->clearindex();
|
||||
|
||||
$this->update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the index
|
||||
*/
|
||||
function update() {
|
||||
global $conf;
|
||||
$data = array();
|
||||
$this->quietecho("Searching pages... ");
|
||||
search($data, $conf['datadir'], 'search_allpages', array('skipacl' => true));
|
||||
$this->quietecho(count($data)." pages found.\n");
|
||||
|
||||
foreach($data as $val) {
|
||||
$this->index($val['id']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Index the given page
|
||||
*
|
||||
* @param string $id
|
||||
*/
|
||||
function index($id) {
|
||||
$this->quietecho("$id... ");
|
||||
idx_addPage($id, !$this->quiet, $this->clear);
|
||||
$this->quietecho("done.\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all index files
|
||||
*/
|
||||
function clearindex() {
|
||||
$this->quietecho("Clearing index... ");
|
||||
idx_get_indexer()->clear();
|
||||
$this->quietecho("done.\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Print message if not supressed
|
||||
*
|
||||
* @param string $msg
|
||||
*/
|
||||
function quietecho($msg) {
|
||||
if(!$this->quiet) echo $msg;
|
||||
}
|
||||
}
|
||||
|
||||
function _quietecho($msg) {
|
||||
global $QUIET;
|
||||
if(!$QUIET) echo $msg;
|
||||
}
|
||||
|
||||
//Setup VIM: ex: et ts=2 :
|
||||
// Main
|
||||
$cli = new IndexerCLI();
|
||||
$cli->run();
|
|
@ -1,5 +1,10 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__).'/../').'/');
|
||||
define('NOSESSION', 1);
|
||||
require_once(DOKU_INC.'inc/init.php');
|
||||
|
||||
|
||||
/**
|
||||
* A simple commandline tool to render some DokuWiki syntax with a given
|
||||
* renderer.
|
||||
|
@ -9,59 +14,48 @@
|
|||
* DokuWiki markup
|
||||
*
|
||||
* @license GPL2
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*/
|
||||
if ('cli' != php_sapi_name()) die();
|
||||
class RenderCLI extends DokuCLI {
|
||||
|
||||
ini_set('memory_limit','128M');
|
||||
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
|
||||
define('NOSESSION',1);
|
||||
require_once(DOKU_INC.'inc/init.php');
|
||||
require_once(DOKU_INC.'inc/common.php');
|
||||
require_once(DOKU_INC.'inc/parserutils.php');
|
||||
require_once(DOKU_INC.'inc/cliopts.php');
|
||||
/**
|
||||
* Register options and arguments on the given $options object
|
||||
*
|
||||
* @param DokuCLI_Options $options
|
||||
* @return void
|
||||
*/
|
||||
protected function setup(DokuCLI_Options $options) {
|
||||
$options->setHelp(
|
||||
'A simple commandline tool to render some DokuWiki syntax with a given renderer.'.
|
||||
"\n\n".
|
||||
'This may not work for plugins that expect a certain environment to be '.
|
||||
'set up before rendering, but should work for most or even all standard '.
|
||||
'DokuWiki markup'
|
||||
);
|
||||
$options->registerOption('renderer', 'The renderer mode to use. Defaults to xhtml', 'r', 'mode');
|
||||
}
|
||||
|
||||
// handle options
|
||||
$short_opts = 'hr:';
|
||||
$long_opts = array('help','renderer:');
|
||||
$OPTS = Doku_Cli_Opts::getOptions(__FILE__,$short_opts,$long_opts);
|
||||
if ( $OPTS->isError() ) {
|
||||
fwrite( STDERR, $OPTS->getMessage() . "\n");
|
||||
_usage();
|
||||
exit(1);
|
||||
}
|
||||
$RENDERER = 'xhtml';
|
||||
foreach ($OPTS->options as $key => $val) {
|
||||
switch ($key) {
|
||||
case 'h':
|
||||
case 'help':
|
||||
_usage();
|
||||
exit;
|
||||
case 'r':
|
||||
case 'renderer':
|
||||
$RENDERER = $val;
|
||||
/**
|
||||
* Your main program
|
||||
*
|
||||
* Arguments and options have been parsed when this is run
|
||||
*
|
||||
* @param DokuCLI_Options $options
|
||||
* @throws DokuCLI_Exception
|
||||
* @return void
|
||||
*/
|
||||
protected function main(DokuCLI_Options $options) {
|
||||
$renderer = $options->getOpt('renderer', 'xhtml');
|
||||
|
||||
// do the action
|
||||
$source = stream_get_contents(STDIN);
|
||||
$info = array();
|
||||
$result = p_render($renderer, p_get_instructions($source), $info);
|
||||
if(is_null($result)) throw new DokuCLI_Exception("No such renderer $renderer");
|
||||
echo $result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// do the action
|
||||
$source = stream_get_contents(STDIN);
|
||||
$info = array();
|
||||
$result = p_render($RENDERER,p_get_instructions($source),$info);
|
||||
if(is_null($result)) die("No such renderer $RENDERER\n");
|
||||
echo $result;
|
||||
|
||||
/**
|
||||
* Print usage info
|
||||
*/
|
||||
function _usage(){
|
||||
print "Usage: render.php <options>
|
||||
|
||||
Reads DokuWiki syntax from STDIN and renders it with the given renderer
|
||||
to STDOUT
|
||||
|
||||
OPTIONS
|
||||
-h, --help show this help and exit
|
||||
-r, --renderer <renderer> the render mode (default: xhtml)
|
||||
";
|
||||
}
|
||||
// Main
|
||||
$cli = new RenderCLI();
|
||||
$cli->run();
|
|
@ -1,148 +1,110 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__).'/../').'/');
|
||||
define('NOSESSION', 1);
|
||||
require_once(DOKU_INC.'inc/init.php');
|
||||
|
||||
|
||||
/**
|
||||
* Strip unwanted languages from the DokuWiki install
|
||||
*
|
||||
* @author Martin 'E.T.' Misuth <et.github@ethome.sk>
|
||||
* Remove unwanted languages from a DokuWiki install
|
||||
*/
|
||||
if ('cli' != php_sapi_name()) die();
|
||||
class StripLangsCLI extends DokuCLI {
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
|
||||
require_once DOKU_INC.'inc/cliopts.php';
|
||||
/**
|
||||
* Register options and arguments on the given $options object
|
||||
*
|
||||
* @param DokuCLI_Options $options
|
||||
* @return void
|
||||
*/
|
||||
protected function setup(DokuCLI_Options $options) {
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
function usage($show_examples = false) {
|
||||
print "Usage: striplangs.php [-h [-x]] [-e] [-k lang1[,lang2]..[,langN]]
|
||||
$options->setHelp(
|
||||
'Remove all languages from the installation, besides the ones specified. English language '.
|
||||
'is never removed!'
|
||||
);
|
||||
|
||||
Removes all languages from the installation, besides the ones
|
||||
after the -k option. English language is never removed!
|
||||
|
||||
OPTIONS
|
||||
-h, --help get this help
|
||||
-x, --examples get also usage examples
|
||||
-k, --keep comma separated list of languages, -e is always implied
|
||||
-e, --english keeps english, dummy to use without -k\n";
|
||||
if ( $show_examples ) {
|
||||
print "\n
|
||||
EXAMPLES
|
||||
Strips all languages, but keeps 'en' and 'de':
|
||||
striplangs -k de
|
||||
|
||||
Strips all but 'en','ca-valencia','cs','de','is','sk':
|
||||
striplangs --keep ca-valencia,cs,de,is,sk
|
||||
|
||||
Strips all but 'en':
|
||||
striplangs -e
|
||||
|
||||
No option specified, prints usage and throws error:
|
||||
striplangs\n";
|
||||
$options->registerOption(
|
||||
'keep',
|
||||
'Comma separated list of languages to keep in addition to English.',
|
||||
'k'
|
||||
);
|
||||
$options->registerOption(
|
||||
'english-only',
|
||||
'Remove all languages except English',
|
||||
'e'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getSuppliedArgument($OPTS, $short, $long) {
|
||||
$arg = $OPTS->get($short);
|
||||
if ( is_null($arg) ) {
|
||||
$arg = $OPTS->get($long);
|
||||
/**
|
||||
* Your main program
|
||||
*
|
||||
* Arguments and options have been parsed when this is run
|
||||
*
|
||||
* @param DokuCLI_Options $options
|
||||
* @return void
|
||||
*/
|
||||
protected function main(DokuCLI_Options $options) {
|
||||
if($options->getOpt('keep')) {
|
||||
$keep = explode(',', $options->getOpt('keep'));
|
||||
if(!in_array('en', $keep)) $keep[] = 'en';
|
||||
} elseif($options->getOpt('english-only')) {
|
||||
$keep = array('en');
|
||||
} else {
|
||||
echo $options->help();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Kill all language directories in /inc/lang and /lib/plugins besides those in $langs array
|
||||
$this->stripDirLangs(realpath(dirname(__FILE__).'/../inc/lang'), $keep);
|
||||
$this->processExtensions(realpath(dirname(__FILE__).'/../lib/plugins'), $keep);
|
||||
$this->processExtensions(realpath(dirname(__FILE__).'/../lib/tpl'), $keep);
|
||||
}
|
||||
return $arg;
|
||||
}
|
||||
|
||||
function processPlugins($path, $keep_langs) {
|
||||
if (is_dir($path)) {
|
||||
$entries = scandir($path);
|
||||
/**
|
||||
* Strip languages from extensions
|
||||
*
|
||||
* @param string $path path to plugin or template dir
|
||||
* @param array $keep_langs languages to keep
|
||||
*/
|
||||
protected function processExtensions($path, $keep_langs) {
|
||||
if(is_dir($path)) {
|
||||
$entries = scandir($path);
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
if ($entry != "." && $entry != "..") {
|
||||
if ( is_dir($path.'/'.$entry) ) {
|
||||
foreach($entries as $entry) {
|
||||
if($entry != "." && $entry != "..") {
|
||||
if(is_dir($path.'/'.$entry)) {
|
||||
|
||||
$plugin_langs = $path.'/'.$entry.'/lang';
|
||||
$plugin_langs = $path.'/'.$entry.'/lang';
|
||||
|
||||
if ( is_dir( $plugin_langs ) ) {
|
||||
stripDirLangs($plugin_langs, $keep_langs);
|
||||
if(is_dir($plugin_langs)) {
|
||||
$this->stripDirLangs($plugin_langs, $keep_langs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function stripDirLangs($path, $keep_langs) {
|
||||
$dir = dir($path);
|
||||
/**
|
||||
* Strip languages from path
|
||||
*
|
||||
* @param string $path path to lang dir
|
||||
* @param array $keep_langs languages to keep
|
||||
*/
|
||||
protected function stripDirLangs($path, $keep_langs) {
|
||||
$dir = dir($path);
|
||||
|
||||
while(($cur_dir = $dir->read()) !== false) {
|
||||
if( $cur_dir != '.' and $cur_dir != '..' and is_dir($path.'/'.$cur_dir)) {
|
||||
while(($cur_dir = $dir->read()) !== false) {
|
||||
if($cur_dir != '.' and $cur_dir != '..' and is_dir($path.'/'.$cur_dir)) {
|
||||
|
||||
if ( !in_array($cur_dir, $keep_langs, true ) ) {
|
||||
killDir($path.'/'.$cur_dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
$dir->close();
|
||||
}
|
||||
|
||||
function killDir($dir) {
|
||||
if (is_dir($dir)) {
|
||||
$entries = scandir($dir);
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
if ($entry != "." && $entry != "..") {
|
||||
if ( is_dir($dir.'/'.$entry) ) {
|
||||
killDir($dir.'/'.$entry);
|
||||
} else {
|
||||
unlink($dir.'/'.$entry);
|
||||
if(!in_array($cur_dir, $keep_langs, true)) {
|
||||
io_rmdir($path.'/'.$cur_dir, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
reset($entries);
|
||||
rmdir($dir);
|
||||
$dir->close();
|
||||
}
|
||||
}
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
// handle options
|
||||
$short_opts = 'hxk:e';
|
||||
$long_opts = array('help', 'examples', 'keep=','english');
|
||||
|
||||
$OPTS = Doku_Cli_Opts::getOptions(__FILE__, $short_opts, $long_opts);
|
||||
|
||||
if ( $OPTS->isError() ) {
|
||||
fwrite( STDERR, $OPTS->getMessage() . "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// handle '--examples' option
|
||||
$show_examples = ( $OPTS->has('x') or $OPTS->has('examples') ) ? true : false;
|
||||
|
||||
// handle '--help' option
|
||||
if ( $OPTS->has('h') or $OPTS->has('help') ) {
|
||||
usage($show_examples);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// handle both '--keep' and '--english' options
|
||||
if ( $OPTS->has('k') or $OPTS->has('keep') ) {
|
||||
$preserved_langs = getSuppliedArgument($OPTS,'k','keep');
|
||||
$langs = explode(',', $preserved_langs);
|
||||
|
||||
// ! always enforce 'en' lang when using '--keep' (DW relies on it)
|
||||
if ( !isset($langs['en']) ) {
|
||||
$langs[]='en';
|
||||
}
|
||||
} elseif ( $OPTS->has('e') or $OPTS->has('english') ) {
|
||||
// '--english' was specified strip everything besides 'en'
|
||||
$langs = array ('en');
|
||||
} else {
|
||||
// no option was specified, print usage but don't do anything as
|
||||
// this run might not be intented
|
||||
usage();
|
||||
print "\n
|
||||
ERROR
|
||||
No option specified, use either -h -x to get more info,
|
||||
or -e to strip every language besides english.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Kill all language directories in /inc/lang and /lib/plugins besides those in $langs array
|
||||
stripDirLangs(realpath(dirname(__FILE__).'/../inc/lang'), $langs);
|
||||
processPlugins(realpath(dirname(__FILE__).'/../lib/plugins'), $langs);
|
||||
$cli = new StripLangsCLI();
|
||||
$cli->run();
|
|
@ -1,134 +1,133 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
if ('cli' != php_sapi_name()) die();
|
||||
if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__).'/../').'/');
|
||||
define('NOSESSION', 1);
|
||||
require_once(DOKU_INC.'inc/init.php');
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
ini_set('memory_limit','128M');
|
||||
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
|
||||
require_once DOKU_INC.'inc/init.php';
|
||||
require_once DOKU_INC.'inc/common.php';
|
||||
require_once DOKU_INC.'inc/search.php';
|
||||
require_once DOKU_INC.'inc/cliopts.php';
|
||||
/**
|
||||
* Find wanted pages
|
||||
*/
|
||||
class WantedPagesCLI extends DokuCLI {
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
function usage() {
|
||||
print "Usage: wantedpages.php [wiki:namespace]
|
||||
const DIR_CONTINUE = 1;
|
||||
const DIR_NS = 2;
|
||||
const DIR_PAGE = 3;
|
||||
|
||||
Outputs a list of wanted pages (pages which have
|
||||
internal links but do not yet exist).
|
||||
|
||||
If the optional [wiki:namespace] is not provided,
|
||||
defaults to the root wiki namespace
|
||||
|
||||
OPTIONS
|
||||
-h, --help get help
|
||||
";
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
define ('DW_DIR_CONTINUE',1);
|
||||
define ('DW_DIR_NS',2);
|
||||
define ('DW_DIR_PAGE',3);
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
function dw_dir_filter($entry, $basepath) {
|
||||
if ($entry == '.' || $entry == '..' ) {
|
||||
return DW_DIR_CONTINUE;
|
||||
}
|
||||
if ( is_dir($basepath . '/' . $entry) ) {
|
||||
if ( strpos($entry, '_') === 0 ) {
|
||||
return DW_DIR_CONTINUE;
|
||||
}
|
||||
return DW_DIR_NS;
|
||||
}
|
||||
if ( preg_match('/\.txt$/',$entry) ) {
|
||||
return DW_DIR_PAGE;
|
||||
}
|
||||
return DW_DIR_CONTINUE;
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
function dw_get_pages($dir) {
|
||||
static $trunclen = null;
|
||||
if ( !$trunclen ) {
|
||||
global $conf;
|
||||
$trunclen = strlen($conf['datadir'].':');
|
||||
/**
|
||||
* Register options and arguments on the given $options object
|
||||
*
|
||||
* @param DokuCLI_Options $options
|
||||
* @return void
|
||||
*/
|
||||
protected function setup(DokuCLI_Options $options) {
|
||||
$options->setHelp(
|
||||
'Outputs a list of wanted pages (pages which have internal links but do not yet exist).'
|
||||
);
|
||||
$options->registerArgument(
|
||||
'namespace',
|
||||
'The namespace to lookup. Defaults to root namespace',
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
if ( !is_dir($dir) ) {
|
||||
fwrite( STDERR, "Unable to read directory $dir\n");
|
||||
exit(1);
|
||||
}
|
||||
/**
|
||||
* Your main program
|
||||
*
|
||||
* Arguments and options have been parsed when this is run
|
||||
*
|
||||
* @param DokuCLI_Options $options
|
||||
* @return void
|
||||
*/
|
||||
protected function main(DokuCLI_Options $options) {
|
||||
|
||||
$pages = array();
|
||||
$dh = opendir($dir);
|
||||
while ( false !== ( $entry = readdir($dh) ) ) {
|
||||
$status = dw_dir_filter($entry, $dir);
|
||||
if ( $status == DW_DIR_CONTINUE ) {
|
||||
continue;
|
||||
} else if ( $status == DW_DIR_NS ) {
|
||||
$pages = array_merge($pages, dw_get_pages($dir . '/' . $entry));
|
||||
if($options->args) {
|
||||
$startdir = dirname(wikiFN($options->args[0].':xxx'));
|
||||
} else {
|
||||
$page = array(
|
||||
'id' => pathID(substr($dir.'/'.$entry,$trunclen)),
|
||||
'file'=> $dir.'/'.$entry,
|
||||
);
|
||||
$pages[] = $page;
|
||||
$startdir = dirname(wikiFN('xxx'));
|
||||
}
|
||||
|
||||
$this->info("searching $startdir");
|
||||
|
||||
$wanted_pages = array();
|
||||
|
||||
foreach($this->get_pages($startdir) as $page) {
|
||||
$wanted_pages = array_merge($wanted_pages, $this->internal_links($page));
|
||||
}
|
||||
$wanted_pages = array_unique($wanted_pages);
|
||||
sort($wanted_pages);
|
||||
|
||||
foreach($wanted_pages as $page) {
|
||||
print $page."\n";
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
return $pages;
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
function dw_internal_links($page) {
|
||||
global $conf;
|
||||
$instructions = p_get_instructions(file_get_contents($page['file']));
|
||||
$links = array();
|
||||
$cns = getNS($page['id']);
|
||||
$exists = false;
|
||||
foreach($instructions as $ins){
|
||||
if($ins[0] == 'internallink' || ($conf['camelcase'] && $ins[0] == 'camelcaselink') ){
|
||||
$mid = $ins[1][0];
|
||||
resolve_pageid($cns,$mid,$exists);
|
||||
if ( !$exists ) {
|
||||
list($mid) = explode('#',$mid); //record pages without hashs
|
||||
$links[] = $mid;
|
||||
protected function dir_filter($entry, $basepath) {
|
||||
if($entry == '.' || $entry == '..') {
|
||||
return WantedPagesCLI::DIR_CONTINUE;
|
||||
}
|
||||
if(is_dir($basepath.'/'.$entry)) {
|
||||
if(strpos($entry, '_') === 0) {
|
||||
return WantedPagesCLI::DIR_CONTINUE;
|
||||
}
|
||||
return WantedPagesCLI::DIR_NS;
|
||||
}
|
||||
if(preg_match('/\.txt$/', $entry)) {
|
||||
return WantedPagesCLI::DIR_PAGE;
|
||||
}
|
||||
return WantedPagesCLI::DIR_CONTINUE;
|
||||
}
|
||||
|
||||
protected function get_pages($dir) {
|
||||
static $trunclen = null;
|
||||
if(!$trunclen) {
|
||||
global $conf;
|
||||
$trunclen = strlen($conf['datadir'].':');
|
||||
}
|
||||
|
||||
if(!is_dir($dir)) {
|
||||
throw new DokuCLI_Exception("Unable to read directory $dir");
|
||||
}
|
||||
|
||||
$pages = array();
|
||||
$dh = opendir($dir);
|
||||
while(false !== ($entry = readdir($dh))) {
|
||||
$status = $this->dir_filter($entry, $dir);
|
||||
if($status == WantedPagesCLI::DIR_CONTINUE) {
|
||||
continue;
|
||||
} else if($status == WantedPagesCLI::DIR_NS) {
|
||||
$pages = array_merge($pages, $this->get_pages($dir.'/'.$entry));
|
||||
} else {
|
||||
$page = array(
|
||||
'id' => pathID(substr($dir.'/'.$entry, $trunclen)),
|
||||
'file' => $dir.'/'.$entry,
|
||||
);
|
||||
$pages[] = $page;
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
return $pages;
|
||||
}
|
||||
|
||||
function internal_links($page) {
|
||||
global $conf;
|
||||
$instructions = p_get_instructions(file_get_contents($page['file']));
|
||||
$links = array();
|
||||
$cns = getNS($page['id']);
|
||||
$exists = false;
|
||||
foreach($instructions as $ins) {
|
||||
if($ins[0] == 'internallink' || ($conf['camelcase'] && $ins[0] == 'camelcaselink')) {
|
||||
$mid = $ins[1][0];
|
||||
resolve_pageid($cns, $mid, $exists);
|
||||
if(!$exists) {
|
||||
list($mid) = explode('#', $mid); //record pages without hashs
|
||||
$links[] = $mid;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $links;
|
||||
}
|
||||
return $links;
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
$OPTS = Doku_Cli_Opts::getOptions(__FILE__,'h',array('help'));
|
||||
|
||||
if ( $OPTS->isError() ) {
|
||||
fwrite( STDERR, $OPTS->getMessage() . "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( $OPTS->has('h') or $OPTS->has('help') ) {
|
||||
usage();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
$START_DIR = $conf['datadir'];
|
||||
|
||||
if ( $OPTS->numArgs() == 1 ) {
|
||||
$START_DIR .= '/' . $OPTS->arg(0);
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
$WANTED_PAGES = array();
|
||||
|
||||
foreach ( dw_get_pages($START_DIR) as $WIKI_PAGE ) {
|
||||
$WANTED_PAGES = array_merge($WANTED_PAGES,dw_internal_links($WIKI_PAGE));
|
||||
}
|
||||
$WANTED_PAGES = array_unique($WANTED_PAGES);
|
||||
sort($WANTED_PAGES);
|
||||
|
||||
foreach ( $WANTED_PAGES as $WANTED_PAGE ) {
|
||||
print $WANTED_PAGE."\n";
|
||||
}
|
||||
exit(0);
|
||||
// Main
|
||||
$cli = new WantedPagesCLI();
|
||||
$cli->run();
|
|
@ -24,12 +24,13 @@ amazon.de http://www.amazon.de/exec/obidos/ASIN/{URL}/splitbrain-21/
|
|||
amazon.uk http://www.amazon.co.uk/exec/obidos/ASIN/
|
||||
paypal https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=
|
||||
phpfn http://www.php.net/{NAME}
|
||||
coral http://{HOST}.{PORT}.nyud.net:8090/{PATH}?{QUERY}
|
||||
coral http://{HOST}.{PORT}.nyud.net:8090{PATH}?{QUERY}
|
||||
freecache http://freecache.org/{NAME}
|
||||
sb http://www.splitbrain.org/go/
|
||||
skype skype:{NAME}
|
||||
google.de http://www.google.de/search?q=
|
||||
go http://www.google.com/search?q={URL}&btnI=lucky
|
||||
user :user:{NAME}
|
||||
|
||||
# To support VoIP/SIP links
|
||||
callto callto://{NAME}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* following contents:
|
||||
* fieldname - Where data will be saved (EXIF or IPTC field)
|
||||
* label - key to lookup in the $lang var, if not found printed as is
|
||||
* htmltype - 'text' or 'textarea'
|
||||
* htmltype - 'text', 'textarea' or 'date'
|
||||
* lookups - array additional fields to lookup the data (EXIF or IPTC fields)
|
||||
*
|
||||
* The fields are not ordered continously to make inserting additional items
|
||||
|
|
|
@ -2,6 +2,164 @@
|
|||
# but were removed later. An up to date DokuWiki should not have any of
|
||||
# the files installed
|
||||
|
||||
# removed in 2014-05-05
|
||||
lib/images/fileicons/audio.png
|
||||
lib/plugins/acl/lang/hi/lang.php
|
||||
lib/plugins/acl/lang/id-ni/lang.php
|
||||
lib/plugins/acl/lang/lb/lang.php
|
||||
lib/plugins/acl/lang/ms/lang.php
|
||||
lib/plugins/authad/lang/lv/settings.php
|
||||
lib/plugins/authldap/lang/lv/settings.php
|
||||
lib/plugins/authmysql/lang/fi/settings.php
|
||||
lib/plugins/authmysql/lang/lv/settings.php
|
||||
lib/plugins/authpgsql/lang/fi/settings.php
|
||||
lib/plugins/authpgsql/lang/it/settings.php
|
||||
lib/plugins/authpgsql/lang/lv/settings.php
|
||||
lib/plugins/authpgsql/lang/pl/settings.php
|
||||
lib/plugins/config/lang/hr/lang.php
|
||||
lib/plugins/config/lang/id/lang.php
|
||||
lib/plugins/config/lang/kk/lang.php
|
||||
lib/plugins/config/lang/lb/lang.php
|
||||
lib/plugins/config/lang/mk/lang.php
|
||||
lib/plugins/config/lang/ms/lang.php
|
||||
lib/plugins/config/lang/vi/lang.php
|
||||
lib/plugins/plugin/admin.php
|
||||
lib/plugins/plugin/classes/ap_delete.class.php
|
||||
lib/plugins/plugin/classes/ap_download.class.php
|
||||
lib/plugins/plugin/classes/ap_enable.class.php
|
||||
lib/plugins/plugin/classes/ap_info.class.php
|
||||
lib/plugins/plugin/classes/ap_manage.class.php
|
||||
lib/plugins/plugin/classes/ap_update.class.php
|
||||
lib/plugins/plugin/lang/af/lang.php
|
||||
lib/plugins/plugin/lang/ar/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/ar/lang.php
|
||||
lib/plugins/plugin/lang/bg/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/bg/lang.php
|
||||
lib/plugins/plugin/lang/ca-valencia/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/ca-valencia/lang.php
|
||||
lib/plugins/plugin/lang/ca/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/ca/lang.php
|
||||
lib/plugins/plugin/lang/cs/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/cs/lang.php
|
||||
lib/plugins/plugin/lang/da/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/da/lang.php
|
||||
lib/plugins/plugin/lang/de-informal/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/de-informal/lang.php
|
||||
lib/plugins/plugin/lang/de/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/de/lang.php
|
||||
lib/plugins/plugin/lang/el/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/el/lang.php
|
||||
lib/plugins/plugin/lang/en/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/en/lang.php
|
||||
lib/plugins/plugin/lang/eo/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/eo/lang.php
|
||||
lib/plugins/plugin/lang/es/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/es/lang.php
|
||||
lib/plugins/plugin/lang/et/lang.php
|
||||
lib/plugins/plugin/lang/eu/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/eu/lang.php
|
||||
lib/plugins/plugin/lang/fa/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/fa/lang.php
|
||||
lib/plugins/plugin/lang/fi/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/fi/lang.php
|
||||
lib/plugins/plugin/lang/fr/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/fr/lang.php
|
||||
lib/plugins/plugin/lang/gl/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/gl/lang.php
|
||||
lib/plugins/plugin/lang/he/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/he/lang.php
|
||||
lib/plugins/plugin/lang/hi/lang.php
|
||||
lib/plugins/plugin/lang/hr/lang.php
|
||||
lib/plugins/plugin/lang/hu/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/hu/lang.php
|
||||
lib/plugins/plugin/lang/ia/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/ia/lang.php
|
||||
lib/plugins/plugin/lang/id-ni/lang.php
|
||||
lib/plugins/plugin/lang/id/lang.php
|
||||
lib/plugins/plugin/lang/is/lang.php
|
||||
lib/plugins/plugin/lang/it/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/it/lang.php
|
||||
lib/plugins/plugin/lang/ja/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/ja/lang.php
|
||||
lib/plugins/plugin/lang/kk/lang.php
|
||||
lib/plugins/plugin/lang/ko/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/ko/lang.php
|
||||
lib/plugins/plugin/lang/la/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/la/lang.php
|
||||
lib/plugins/plugin/lang/lb/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/lb/lang.php
|
||||
lib/plugins/plugin/lang/lt/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/lt/lang.php
|
||||
lib/plugins/plugin/lang/lv/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/lv/lang.php
|
||||
lib/plugins/plugin/lang/mk/lang.php
|
||||
lib/plugins/plugin/lang/mr/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/mr/lang.php
|
||||
lib/plugins/plugin/lang/ms/lang.php
|
||||
lib/plugins/plugin/lang/ne/lang.php
|
||||
lib/plugins/plugin/lang/nl/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/nl/lang.php
|
||||
lib/plugins/plugin/lang/no/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/no/lang.php
|
||||
lib/plugins/plugin/lang/pl/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/pl/lang.php
|
||||
lib/plugins/plugin/lang/pt-br/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/pt-br/lang.php
|
||||
lib/plugins/plugin/lang/pt/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/pt/lang.php
|
||||
lib/plugins/plugin/lang/ro/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/ro/lang.php
|
||||
lib/plugins/plugin/lang/ru/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/ru/lang.php
|
||||
lib/plugins/plugin/lang/sk/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/sk/lang.php
|
||||
lib/plugins/plugin/lang/sl/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/sl/lang.php
|
||||
lib/plugins/plugin/lang/sq/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/sq/lang.php
|
||||
lib/plugins/plugin/lang/sr/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/sr/lang.php
|
||||
lib/plugins/plugin/lang/sv/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/sv/lang.php
|
||||
lib/plugins/plugin/lang/th/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/th/lang.php
|
||||
lib/plugins/plugin/lang/tr/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/tr/lang.php
|
||||
lib/plugins/plugin/lang/uk/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/uk/lang.php
|
||||
lib/plugins/plugin/lang/vi/lang.php
|
||||
lib/plugins/plugin/lang/zh-tw/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/zh-tw/lang.php
|
||||
lib/plugins/plugin/lang/zh/admin_plugin.txt
|
||||
lib/plugins/plugin/lang/zh/lang.php
|
||||
lib/plugins/plugin/plugin.info.txt
|
||||
lib/plugins/plugin/style.css
|
||||
lib/plugins/popularity/lang/et/lang.php
|
||||
lib/plugins/popularity/lang/hr/lang.php
|
||||
lib/plugins/popularity/lang/id/lang.php
|
||||
lib/plugins/popularity/lang/kk/lang.php
|
||||
lib/plugins/popularity/lang/lb/lang.php
|
||||
lib/plugins/popularity/lang/mk/lang.php
|
||||
lib/plugins/popularity/lang/ms/lang.php
|
||||
lib/plugins/popularity/lang/vi/lang.php
|
||||
lib/plugins/revert/lang/af/lang.php
|
||||
lib/plugins/revert/lang/hi/lang.php
|
||||
lib/plugins/revert/lang/hr/lang.php
|
||||
lib/plugins/revert/lang/id-ni/lang.php
|
||||
lib/plugins/revert/lang/id/lang.php
|
||||
lib/plugins/revert/lang/kk/lang.php
|
||||
lib/plugins/revert/lang/lb/lang.php
|
||||
lib/plugins/revert/lang/lt/lang.php
|
||||
lib/plugins/revert/lang/mk/lang.php
|
||||
lib/plugins/revert/lang/ms/lang.php
|
||||
lib/plugins/revert/lang/vi/lang.php
|
||||
lib/plugins/usermanager/lang/hi/lang.php
|
||||
lib/plugins/usermanager/lang/hr/lang.php
|
||||
lib/plugins/usermanager/lang/id-ni/lang.php
|
||||
lib/plugins/usermanager/lang/lb/lang.php
|
||||
lib/plugins/usermanager/lang/ms/lang.php
|
||||
lib/plugins/usermanager/lang/vi/lang.php
|
||||
|
||||
# removed in 2013-11-18
|
||||
lib/images/arrow_down.gif
|
||||
lib/images/arrow_up.gif
|
||||
|
|
|
@ -6,7 +6,7 @@ Read the [[doku>manual|DokuWiki Manual]] to unleash the full power of DokuWiki.
|
|||
|
||||
===== Download =====
|
||||
|
||||
DokuWiki is available at http://www.splitbrain.org/go/dokuwiki
|
||||
DokuWiki is available at http://download.dokuwiki.org/
|
||||
|
||||
|
||||
===== Read More =====
|
||||
|
@ -24,7 +24,7 @@ All documentation and additional information besides the [[syntax|syntax descrip
|
|||
**Installing DokuWiki**
|
||||
|
||||
* [[doku>requirements|System Requirements]]
|
||||
* [[http://www.splitbrain.org/go/dokuwiki|Download DokuWiki]] :!:
|
||||
* [[http://download.dokuwiki.org/|Download DokuWiki]] :!:
|
||||
* [[doku>changes|Change Log]]
|
||||
* [[doku>Install|How to install or upgrade]] :!:
|
||||
* [[doku>config|Configuration]]
|
||||
|
@ -50,7 +50,7 @@ All documentation and additional information besides the [[syntax|syntax descrip
|
|||
* [[doku>mailinglist|Join the mailing list]]
|
||||
* [[http://forum.dokuwiki.org|Check out the user forum]]
|
||||
* [[doku>irc|Talk to other users in the IRC channel]]
|
||||
* [[http://bugs.splitbrain.org/index.php?project=1|Submit bugs and feature wishes]]
|
||||
* [[https://github.com/splitbrain/dokuwiki/issues|Submit bugs and feature wishes]]
|
||||
* [[http://www.wikimatrix.org/forum/viewforum.php?id=10|Share your experiences in the WikiMatrix forum]]
|
||||
* [[doku>thanks|Some humble thanks]]
|
||||
|
||||
|
|
|
@ -121,9 +121,9 @@ By using four or more dashes, you can make a horizontal line:
|
|||
|
||||
----
|
||||
|
||||
===== Images and Other Files =====
|
||||
===== Media Files =====
|
||||
|
||||
You can include external and internal [[doku>images]] with curly brackets. Optionally you can specify the size of them.
|
||||
You can include external and internal [[doku>images|images, videos and audio files]] with curly brackets. Optionally you can specify the size of them.
|
||||
|
||||
Real size: {{wiki:dokuwiki-128.png}}
|
||||
|
||||
|
@ -157,10 +157,31 @@ Of course, you can add a title (displayed as a tooltip by most browsers), too.
|
|||
|
||||
{{ wiki:dokuwiki-128.png |This is the caption}}
|
||||
|
||||
If you specify a filename (external or internal) that is not an image (''gif, jpeg, png''), then it will be displayed as a link instead.
|
||||
|
||||
For linking an image to another page see [[#Image Links]] above.
|
||||
|
||||
==== Supported Media Formats ====
|
||||
|
||||
DokuWiki can embed the following media formats directly.
|
||||
|
||||
| Image | ''gif'', ''jpg'', ''png'' |
|
||||
| Video | ''webm'', ''ogv'', ''mp4'' |
|
||||
| Audio | ''ogg'', ''mp3'', ''wav'' |
|
||||
| Flash | ''swf'' |
|
||||
|
||||
If you specify a filename that is not a supported media format, then it will be displayed as a link instead.
|
||||
|
||||
==== Fallback Formats ====
|
||||
|
||||
Unfortunately not all browsers understand all video and audio formats. To mitigate the problem, you can upload your file in different formats for maximum browser compatibility.
|
||||
|
||||
For example consider this embedded mp4 video:
|
||||
|
||||
{{video.mp4|A funny video}}
|
||||
|
||||
When you upload a ''video.webm'' and ''video.ogv'' next to the referenced ''video.mp4'', DokuWiki will automatically add them as alternatives so that one of the three files is understood by your browser.
|
||||
|
||||
Additionally DokuWiki supports a "poster" image which will be shown before the video has started. That image needs to have the same filename as the video and be either a jpg or png file. In the example above a ''video.jpg'' file would work.
|
||||
|
||||
===== Lists =====
|
||||
|
||||
Dokuwiki supports ordered and unordered lists. To create a list item, indent your text by two spaces and use a ''*'' for unordered lists or a ''-'' for ordered ones.
|
||||
|
|
2
doku.php
2
doku.php
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
|
||||
// update message version
|
||||
$updateVersion = 43;
|
||||
$updateVersion = 45;
|
||||
|
||||
// xdebug_start_profiling();
|
||||
|
||||
|
|
50
feed.php
50
feed.php
|
@ -15,13 +15,19 @@ require_once(DOKU_INC.'inc/init.php');
|
|||
//close session
|
||||
session_write_close();
|
||||
|
||||
//feed disabled?
|
||||
if(!actionOK('rss')) {
|
||||
http_status(404);
|
||||
echo '<error>RSS feed is disabled.</error>';
|
||||
exit;
|
||||
}
|
||||
|
||||
// get params
|
||||
$opt = rss_parseOptions();
|
||||
|
||||
// the feed is dynamic - we need a cache for each combo
|
||||
// (but most people just use the default feed so it's still effective)
|
||||
$cache = getCacheName(join('', array_values($opt)).$_SERVER['REMOTE_USER'], '.feed');
|
||||
$key = join('', array_values($opt)).$_SERVER['REMOTE_USER'];
|
||||
$key = join('', array_values($opt)).'$'.$_SERVER['REMOTE_USER'].'$'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'];
|
||||
$cache = new cache($key, '.feed');
|
||||
|
||||
// prepare cache depends
|
||||
|
@ -121,6 +127,8 @@ function rss_parseOptions() {
|
|||
'items' => array('int', 'num', $conf['recent']),
|
||||
// Boolean, only used in rc mode
|
||||
'show_minor' => array('bool', 'minor', false),
|
||||
// String, only used in list mode
|
||||
'sort' => array('str', 'sort', 'natural'),
|
||||
// String, only used in search mode
|
||||
'search_query' => array('str', 'q', null),
|
||||
// One of: pages, media, both
|
||||
|
@ -132,15 +140,14 @@ function rss_parseOptions() {
|
|||
|
||||
$opt['items'] = max(0, (int) $opt['items']);
|
||||
$opt['show_minor'] = (bool) $opt['show_minor'];
|
||||
$opt['sort'] = valid_input_set('sort', array('default' => 'natural', 'date'), $opt);
|
||||
|
||||
$opt['guardmail'] = ($conf['mailguard'] != '' && $conf['mailguard'] != 'none');
|
||||
|
||||
$type = valid_input_set(
|
||||
'type', array(
|
||||
'rss', 'rss2', 'atom', 'atom1', 'rss1',
|
||||
'default' => $conf['rss_type']
|
||||
),
|
||||
$_REQUEST
|
||||
$type = $INPUT->valid(
|
||||
'type',
|
||||
array( 'rss', 'rss2', 'atom', 'atom1', 'rss1'),
|
||||
$conf['rss_type']
|
||||
);
|
||||
switch($type) {
|
||||
case 'rss':
|
||||
|
@ -182,7 +189,7 @@ function rss_parseOptions() {
|
|||
function rss_buildItems(&$rss, &$data, $opt) {
|
||||
global $conf;
|
||||
global $lang;
|
||||
/* @var auth_basic $auth */
|
||||
/* @var DokuWiki_Auth_Plugin $auth */
|
||||
global $auth;
|
||||
|
||||
$eventData = array(
|
||||
|
@ -293,18 +300,19 @@ function rss_buildItems(&$rss, &$data, $opt) {
|
|||
case 'diff':
|
||||
case 'htmldiff':
|
||||
if($ditem['media']) {
|
||||
$revs = getRevisions($id, 0, 1, 8192, true);
|
||||
$medialog = new MediaChangeLog($id);
|
||||
$revs = $medialog->getRevisions(0, 1);
|
||||
$rev = $revs[0];
|
||||
$src_r = '';
|
||||
$src_l = '';
|
||||
|
||||
if($size = media_image_preview_size($id, false, new JpegMeta(mediaFN($id)), 300)) {
|
||||
$more = 'w='.$size[0].'&h='.$size[1].'t='.@filemtime(mediaFN($id));
|
||||
$src_r = ml($id, $more);
|
||||
$more = 'w='.$size[0].'&h='.$size[1].'&t='.@filemtime(mediaFN($id));
|
||||
$src_r = ml($id, $more, true, '&', true);
|
||||
}
|
||||
if($rev && $size = media_image_preview_size($id, $rev, new JpegMeta(mediaFN($id, $rev)), 300)) {
|
||||
$more = 'rev='.$rev.'&w='.$size[0].'&h='.$size[1];
|
||||
$src_l = ml($id, $more);
|
||||
$src_l = ml($id, $more, true, '&', true);
|
||||
}
|
||||
$content = '';
|
||||
if($src_r) {
|
||||
|
@ -318,7 +326,8 @@ function rss_buildItems(&$rss, &$data, $opt) {
|
|||
|
||||
} else {
|
||||
require_once(DOKU_INC.'inc/DifferenceEngine.php');
|
||||
$revs = getRevisions($id, 0, 1);
|
||||
$pagelog = new PageChangeLog($id);
|
||||
$revs = $pagelog->getRevisions(0, 1);
|
||||
$rev = $revs[0];
|
||||
|
||||
if($rev) {
|
||||
|
@ -347,8 +356,8 @@ function rss_buildItems(&$rss, &$data, $opt) {
|
|||
case 'html':
|
||||
if($ditem['media']) {
|
||||
if($size = media_image_preview_size($id, false, new JpegMeta(mediaFN($id)))) {
|
||||
$more = 'w='.$size[0].'&h='.$size[1].'t='.@filemtime(mediaFN($id));
|
||||
$src = ml($id, $more);
|
||||
$more = 'w='.$size[0].'&h='.$size[1].'&t='.@filemtime(mediaFN($id));
|
||||
$src = ml($id, $more, true, '&', true);
|
||||
$content = '<img src="'.$src.'" alt="'.$id.'" />';
|
||||
} else {
|
||||
$content = '';
|
||||
|
@ -378,8 +387,8 @@ function rss_buildItems(&$rss, &$data, $opt) {
|
|||
default:
|
||||
if($ditem['media']) {
|
||||
if($size = media_image_preview_size($id, false, new JpegMeta(mediaFN($id)))) {
|
||||
$more = 'w='.$size[0].'&h='.$size[1].'t='.@filemtime(mediaFN($id));
|
||||
$src = ml($id, $more);
|
||||
$more = 'w='.$size[0].'&h='.$size[1].'&t='.@filemtime(mediaFN($id));
|
||||
$src = ml($id, $more, true, '&', true);
|
||||
$content = '<img src="'.$src.'" alt="'.$id.'" />';
|
||||
} else {
|
||||
$content = '';
|
||||
|
@ -399,6 +408,7 @@ function rss_buildItems(&$rss, &$data, $opt) {
|
|||
if($userInfo) {
|
||||
switch($conf['showuseras']) {
|
||||
case 'username':
|
||||
case 'username_link':
|
||||
$item->author = $userInfo['name'];
|
||||
break;
|
||||
default:
|
||||
|
@ -473,7 +483,7 @@ function rssListNamespace($opt) {
|
|||
global $conf;
|
||||
|
||||
$ns = ':'.cleanID($opt['namespace']);
|
||||
$ns = str_replace(':', '/', $ns);
|
||||
$ns = utf8_encodeFN(str_replace(':', '/', $ns));
|
||||
|
||||
$data = array();
|
||||
$search_opts = array(
|
||||
|
@ -481,7 +491,7 @@ function rssListNamespace($opt) {
|
|||
'pagesonly' => true,
|
||||
'listfiles' => true
|
||||
);
|
||||
search($data, $conf['datadir'], 'search_universal', $search_opts, $ns);
|
||||
search($data, $conf['datadir'], 'search_universal', $search_opts, $ns, $lvl = 1, $opt['sort']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@ class EmailAddressValidator {
|
|||
|
||||
/**
|
||||
* Check email address validity
|
||||
* @param strEmailAddress Email address to be checked
|
||||
* @return True if email is valid, false if not
|
||||
* @param string $strEmailAddress Email address to be checked
|
||||
* @return bool True if email is valid, false if not
|
||||
*/
|
||||
public function check_email_address($strEmailAddress) {
|
||||
|
||||
|
@ -82,8 +82,8 @@ class EmailAddressValidator {
|
|||
|
||||
/**
|
||||
* Checks email section before "@" symbol for validity
|
||||
* @param strLocalPortion Text to be checked
|
||||
* @return True if local portion is valid, false if not
|
||||
* @param string $strLocalPortion Text to be checked
|
||||
* @return bool True if local portion is valid, false if not
|
||||
*/
|
||||
protected function check_local_portion($strLocalPortion) {
|
||||
// Local portion can only be from 1 to 64 characters, inclusive.
|
||||
|
@ -113,8 +113,8 @@ class EmailAddressValidator {
|
|||
|
||||
/**
|
||||
* Checks email section after "@" symbol for validity
|
||||
* @param strDomainPortion Text to be checked
|
||||
* @return True if domain portion is valid, false if not
|
||||
* @param string $strDomainPortion Text to be checked
|
||||
* @return bool True if domain portion is valid, false if not
|
||||
*/
|
||||
protected function check_domain_portion($strDomainPortion) {
|
||||
// Total domain can only be from 1 to 255 characters, inclusive
|
||||
|
@ -172,10 +172,10 @@ class EmailAddressValidator {
|
|||
|
||||
/**
|
||||
* Check given text length is between defined bounds
|
||||
* @param strText Text to be checked
|
||||
* @param intMinimum Minimum acceptable length
|
||||
* @param intMaximum Maximum acceptable length
|
||||
* @return True if string is within bounds (inclusive), false if not
|
||||
* @param string $strText Text to be checked
|
||||
* @param int $intMinimum Minimum acceptable length
|
||||
* @param int $intMaximum Maximum acceptable length
|
||||
* @return bool True if string is within bounds (inclusive), false if not
|
||||
*/
|
||||
protected function check_text_length($strText, $intMinimum, $intMaximum) {
|
||||
// Minimum and maximum are both inclusive
|
||||
|
|
|
@ -35,6 +35,19 @@ class DokuHTTPClient extends HTTPClient {
|
|||
$this->proxy_pass = conf_decodeString($conf['proxy']['pass']);
|
||||
$this->proxy_ssl = $conf['proxy']['ssl'];
|
||||
$this->proxy_except = $conf['proxy']['except'];
|
||||
|
||||
// allow enabling debugging via URL parameter (if debugging allowed)
|
||||
if($conf['allowdebug']) {
|
||||
if(
|
||||
isset($_REQUEST['httpdebug']) ||
|
||||
(
|
||||
isset($_SERVER['HTTP_REFERER']) &&
|
||||
strpos($_SERVER['HTTP_REFERER'], 'httpdebug') !== false
|
||||
)
|
||||
) {
|
||||
$this->debug = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,6 +74,9 @@ class DokuHTTPClient extends HTTPClient {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Class HTTPClientException
|
||||
*/
|
||||
class HTTPClientException extends Exception { }
|
||||
|
||||
/**
|
||||
|
@ -249,12 +265,17 @@ class HTTPClient {
|
|||
if (empty($port)) $port = 8080;
|
||||
}else{
|
||||
$request_url = $path;
|
||||
$server = $server;
|
||||
if (!isset($port)) $port = ($uri['scheme'] == 'https') ? 443 : 80;
|
||||
}
|
||||
|
||||
// add SSL stream prefix if needed - needs SSL support in PHP
|
||||
if($port == 443 || $this->proxy_ssl) $server = 'ssl://'.$server;
|
||||
if($port == 443 || $this->proxy_ssl) {
|
||||
if(!in_array('ssl', stream_get_transports())) {
|
||||
$this->status = -200;
|
||||
$this->error = 'This PHP version does not support SSL - cannot connect to server';
|
||||
}
|
||||
$server = 'ssl://'.$server;
|
||||
}
|
||||
|
||||
// prepare headers
|
||||
$headers = $this->headers;
|
||||
|
@ -274,7 +295,6 @@ class HTTPClient {
|
|||
}
|
||||
}
|
||||
$headers['Content-Length'] = strlen($data);
|
||||
$rmethod = 'POST';
|
||||
}elseif($method == 'GET'){
|
||||
$data = ''; //no data allowed on GET requests
|
||||
}
|
||||
|
@ -304,11 +324,18 @@ class HTTPClient {
|
|||
}
|
||||
|
||||
// try establish a CONNECT tunnel for SSL
|
||||
if($this->_ssltunnel($socket, $request_url)){
|
||||
// no keep alive for tunnels
|
||||
$this->keep_alive = false;
|
||||
// tunnel is authed already
|
||||
if(isset($headers['Proxy-Authentication'])) unset($headers['Proxy-Authentication']);
|
||||
try {
|
||||
if($this->_ssltunnel($socket, $request_url)){
|
||||
// no keep alive for tunnels
|
||||
$this->keep_alive = false;
|
||||
// tunnel is authed already
|
||||
if(isset($headers['Proxy-Authentication'])) unset($headers['Proxy-Authentication']);
|
||||
}
|
||||
} catch (HTTPClientException $e) {
|
||||
$this->status = $e->getCode();
|
||||
$this->error = $e->getMessage();
|
||||
fclose($socket);
|
||||
return false;
|
||||
}
|
||||
|
||||
// keep alive?
|
||||
|
@ -330,7 +357,7 @@ class HTTPClient {
|
|||
|
||||
try {
|
||||
//set non-blocking
|
||||
stream_set_blocking($socket, false);
|
||||
stream_set_blocking($socket, 0);
|
||||
|
||||
// build request
|
||||
$request = "$method $request_url HTTP/".$this->http.HTTP_NL;
|
||||
|
@ -363,7 +390,7 @@ class HTTPClient {
|
|||
|
||||
// get Status
|
||||
if (!preg_match('/^HTTP\/(\d\.\d)\s*(\d+).*?\n/', $r_headers, $m))
|
||||
throw new HTTPClientException('Server returned bad answer');
|
||||
throw new HTTPClientException('Server returned bad answer '.$r_headers);
|
||||
|
||||
$this->status = $m[2];
|
||||
|
||||
|
@ -445,7 +472,7 @@ class HTTPClient {
|
|||
|
||||
if ($chunk_size > 0) {
|
||||
$r_body .= $this->_readData($socket, $chunk_size, 'chunk');
|
||||
$byte = $this->_readData($socket, 2, 'chunk'); // read trailing \r\n
|
||||
$this->_readData($socket, 2, 'chunk'); // read trailing \r\n
|
||||
}
|
||||
} while ($chunk_size && !$abort);
|
||||
}elseif(isset($this->resp_headers['content-length']) && !isset($this->resp_headers['transfer-encoding'])){
|
||||
|
@ -467,7 +494,6 @@ class HTTPClient {
|
|||
$r_body = $this->_readData($socket, $this->max_bodysize, 'response (content-length limited)', true);
|
||||
}else{
|
||||
// read entire socket
|
||||
$r_size = 0;
|
||||
while (!feof($socket)) {
|
||||
$r_body .= $this->_readData($socket, 4096, 'response (unlimited)', true);
|
||||
}
|
||||
|
@ -496,7 +522,6 @@ class HTTPClient {
|
|||
if (!$this->keep_alive ||
|
||||
(isset($this->resp_headers['connection']) && $this->resp_headers['connection'] == 'Close')) {
|
||||
// close socket
|
||||
$status = socket_get_status($socket);
|
||||
fclose($socket);
|
||||
unset(self::$connections[$connectionId]);
|
||||
}
|
||||
|
@ -526,6 +551,7 @@ class HTTPClient {
|
|||
*
|
||||
* @param resource &$socket
|
||||
* @param string &$requesturl
|
||||
* @throws HTTPClientException when a tunnel is needed but could not be established
|
||||
* @return bool true if a tunnel was established
|
||||
*/
|
||||
function _ssltunnel(&$socket, &$requesturl){
|
||||
|
@ -538,7 +564,7 @@ class HTTPClient {
|
|||
$request = "CONNECT {$requestinfo['host']}:{$requestinfo['port']} HTTP/1.0".HTTP_NL;
|
||||
$request .= "Host: {$requestinfo['host']}".HTTP_NL;
|
||||
if($this->proxy_user) {
|
||||
'Proxy-Authorization Basic '.base64_encode($this->proxy_user.':'.$this->proxy_pass).HTTP_NL;
|
||||
$request .= 'Proxy-Authorization: Basic '.base64_encode($this->proxy_user.':'.$this->proxy_pass).HTTP_NL;
|
||||
}
|
||||
$request .= HTTP_NL;
|
||||
|
||||
|
@ -559,7 +585,8 @@ class HTTPClient {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
throw new HTTPClientException('Failed to establish secure proxy connection', -150);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,6 +15,8 @@ class Input {
|
|||
public $post;
|
||||
/** @var GetInput Access $_GET parameters */
|
||||
public $get;
|
||||
/** @var ServerInput Access $_SERVER parameters */
|
||||
public $server;
|
||||
|
||||
protected $access;
|
||||
|
||||
|
@ -25,6 +27,7 @@ class Input {
|
|||
$this->access = &$_REQUEST;
|
||||
$this->post = new PostInput();
|
||||
$this->get = new GetInput();
|
||||
$this->server = new ServerInput();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -140,6 +143,26 @@ class Input {
|
|||
return (string) $this->access[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Access a request parameter and make sure it is has a valid value
|
||||
*
|
||||
* Please note that comparisons to the valid values are not done typesafe (request vars
|
||||
* are always strings) however the function will return the correct type from the $valids
|
||||
* array when an match was found.
|
||||
*
|
||||
* @param string $name Parameter name
|
||||
* @param array $valids Array of valid values
|
||||
* @param mixed $default Default to return if parameter isn't set or not valid
|
||||
* @return null|mixed
|
||||
*/
|
||||
public function valid($name, $valids, $default = null) {
|
||||
if(!isset($this->access[$name])) return $default;
|
||||
if(is_array($this->access[$name])) return $default; // we don't allow arrays
|
||||
$found = array_search($this->access[$name], $valids);
|
||||
if($found !== false) return $valids[$found]; // return the valid value for type safety
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access a request parameter as bool
|
||||
*
|
||||
|
@ -260,3 +283,18 @@ class GetInput extends Input {
|
|||
$_REQUEST[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal class used for $_SERVER access in Input class
|
||||
*/
|
||||
class ServerInput extends Input {
|
||||
protected $access;
|
||||
|
||||
/**
|
||||
* Initialize the $access array, remove subclass members
|
||||
*/
|
||||
function __construct() {
|
||||
$this->access = &$_SERVER;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2929,7 +2929,8 @@ class JpegMeta {
|
|||
$length = strlen($data) - $pos;
|
||||
}
|
||||
|
||||
return substr($data, $pos, $length);
|
||||
$rv = substr($data, $pos, $length);
|
||||
return $rv;
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
|
|
@ -39,6 +39,8 @@ class Mailer {
|
|||
*/
|
||||
public function __construct() {
|
||||
global $conf;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
$server = parse_url(DOKU_URL, PHP_URL_HOST);
|
||||
if(strpos($server,'.') === false) $server = $server.'.localhost';
|
||||
|
@ -53,7 +55,7 @@ class Mailer {
|
|||
|
||||
// add some default headers for mailfiltering FS#2247
|
||||
$this->setHeader('X-Mailer', 'DokuWiki');
|
||||
$this->setHeader('X-DokuWiki-User', $_SERVER['REMOTE_USER']);
|
||||
$this->setHeader('X-DokuWiki-User', $INPUT->server->str('REMOTE_USER'));
|
||||
$this->setHeader('X-DokuWiki-Title', $conf['title']);
|
||||
$this->setHeader('X-DokuWiki-Server', $server);
|
||||
$this->setHeader('X-Auto-Response-Suppress', 'OOF');
|
||||
|
@ -181,6 +183,9 @@ class Mailer {
|
|||
public function setBody($text, $textrep = null, $htmlrep = null, $html = null, $wrap = true) {
|
||||
global $INFO;
|
||||
global $conf;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
$htmlrep = (array)$htmlrep;
|
||||
$textrep = (array)$textrep;
|
||||
|
||||
|
@ -218,24 +223,24 @@ class Mailer {
|
|||
$cip = gethostsbyaddrs($ip);
|
||||
$trep = array(
|
||||
'DATE' => dformat(),
|
||||
'BROWSER' => $_SERVER['HTTP_USER_AGENT'],
|
||||
'BROWSER' => $INPUT->server->str('HTTP_USER_AGENT'),
|
||||
'IPADDRESS' => $ip,
|
||||
'HOSTNAME' => $cip,
|
||||
'TITLE' => $conf['title'],
|
||||
'DOKUWIKIURL' => DOKU_URL,
|
||||
'USER' => $_SERVER['REMOTE_USER'],
|
||||
'USER' => $INPUT->server->str('REMOTE_USER'),
|
||||
'NAME' => $INFO['userinfo']['name'],
|
||||
'MAIL' => $INFO['userinfo']['mail'],
|
||||
);
|
||||
$trep = array_merge($trep, (array)$textrep);
|
||||
$hrep = array(
|
||||
'DATE' => '<i>'.hsc(dformat()).'</i>',
|
||||
'BROWSER' => hsc($_SERVER['HTTP_USER_AGENT']),
|
||||
'BROWSER' => hsc($INPUT->server->str('HTTP_USER_AGENT')),
|
||||
'IPADDRESS' => '<code>'.hsc($ip).'</code>',
|
||||
'HOSTNAME' => '<code>'.hsc($cip).'</code>',
|
||||
'TITLE' => hsc($conf['title']),
|
||||
'DOKUWIKIURL' => '<a href="'.DOKU_URL.'">'.DOKU_URL.'</a>',
|
||||
'USER' => hsc($_SERVER['REMOTE_USER']),
|
||||
'USER' => hsc($INPUT->server->str('REMOTE_USER')),
|
||||
'NAME' => hsc($INFO['userinfo']['name']),
|
||||
'MAIL' => '<a href="mailto:"'.hsc($INFO['userinfo']['mail']).'">'.
|
||||
hsc($INFO['userinfo']['mail']).'</a>',
|
||||
|
@ -277,7 +282,7 @@ class Mailer {
|
|||
/**
|
||||
* Add the To: recipients
|
||||
*
|
||||
* @see setAddress
|
||||
* @see cleanAddress
|
||||
* @param string|array $address Multiple adresses separated by commas or as array
|
||||
*/
|
||||
public function to($address) {
|
||||
|
@ -287,7 +292,7 @@ class Mailer {
|
|||
/**
|
||||
* Add the Cc: recipients
|
||||
*
|
||||
* @see setAddress
|
||||
* @see cleanAddress
|
||||
* @param string|array $address Multiple adresses separated by commas or as array
|
||||
*/
|
||||
public function cc($address) {
|
||||
|
@ -297,7 +302,7 @@ class Mailer {
|
|||
/**
|
||||
* Add the Bcc: recipients
|
||||
*
|
||||
* @see setAddress
|
||||
* @see cleanAddress
|
||||
* @param string|array $address Multiple adresses separated by commas or as array
|
||||
*/
|
||||
public function bcc($address) {
|
||||
|
@ -310,7 +315,7 @@ class Mailer {
|
|||
* This is set to $conf['mailfrom'] when not specified so you shouldn't need
|
||||
* to call this function
|
||||
*
|
||||
* @see setAddress
|
||||
* @see cleanAddress
|
||||
* @param string $address from address
|
||||
*/
|
||||
public function from($address) {
|
||||
|
@ -333,9 +338,9 @@ class Mailer {
|
|||
* for headers. Addresses may not contain Non-ASCII data!
|
||||
*
|
||||
* Example:
|
||||
* setAddress("föö <foo@bar.com>, me@somewhere.com","TBcc");
|
||||
* cc("föö <foo@bar.com>, me@somewhere.com","TBcc");
|
||||
*
|
||||
* @param string|array $address Multiple adresses separated by commas or as array
|
||||
* @param string|array $addresses Multiple adresses separated by commas or as array
|
||||
* @return bool|string the prepared header (can contain multiple lines)
|
||||
*/
|
||||
public function cleanAddress($addresses) {
|
||||
|
@ -522,7 +527,7 @@ class Mailer {
|
|||
|
||||
// clean up addresses
|
||||
if(empty($this->headers['From'])) $this->from($conf['mailfrom']);
|
||||
$addrs = array('To', 'From', 'Cc', 'Bcc');
|
||||
$addrs = array('To', 'From', 'Cc', 'Bcc', 'Reply-To', 'Sender');
|
||||
foreach($addrs as $addr) {
|
||||
if(isset($this->headers[$addr])) {
|
||||
$this->headers[$addr] = $this->cleanAddress($this->headers[$addr]);
|
||||
|
|
|
@ -378,7 +378,8 @@ class RemoteAPICore {
|
|||
throw new RemoteException('The requested page does not exist', 121);
|
||||
}
|
||||
|
||||
$info = getRevisionInfo($id, $time, 1024);
|
||||
$pagelog = new PageChangeLog($id, 1024);
|
||||
$info = $pagelog->getRevisionInfo($time);
|
||||
|
||||
$data = array(
|
||||
'name' => $id,
|
||||
|
@ -650,11 +651,12 @@ class RemoteAPICore {
|
|||
throw new RemoteException('Empty page ID', 131);
|
||||
}
|
||||
|
||||
$revisions = getRevisions($id, $first, $conf['recent']+1);
|
||||
$pagelog = new PageChangeLog($id);
|
||||
$revisions = $pagelog->getRevisions($first, $conf['recent']+1);
|
||||
|
||||
if(count($revisions)==0 && $first!=0) {
|
||||
$first=0;
|
||||
$revisions = getRevisions($id, $first, $conf['recent']+1);
|
||||
$revisions = $pagelog->getRevisions($first, $conf['recent']+1);
|
||||
}
|
||||
|
||||
if(count($revisions)>0 && $first==0) {
|
||||
|
@ -676,7 +678,8 @@ class RemoteAPICore {
|
|||
// case this can lead to less pages being returned than
|
||||
// specified via $conf['recent']
|
||||
if($time){
|
||||
$info = getRevisionInfo($id, $time, 1024);
|
||||
$pagelog->setChunkSize(1024);
|
||||
$info = $pagelog->getRevisionInfo($time);
|
||||
if(!empty($info)) {
|
||||
$data['user'] = $info['user'];
|
||||
$data['ip'] = $info['ip'];
|
||||
|
|
|
@ -131,9 +131,9 @@ class Sitemapper {
|
|||
|
||||
$encoded_sitemap_url = urlencode(wl('', array('do' => 'sitemap'), true, '&'));
|
||||
$ping_urls = array(
|
||||
'google' => 'http://www.google.com/webmasters/sitemaps/ping?sitemap='.$encoded_sitemap_url,
|
||||
'yahoo' => 'http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=dokuwiki&url='.$encoded_sitemap_url,
|
||||
'google' => 'http://www.google.com/webmasters/sitemaps/ping?sitemap='.$encoded_sitemap_url,
|
||||
'microsoft' => 'http://www.bing.com/webmaster/ping.aspx?siteMap='.$encoded_sitemap_url,
|
||||
'yandex' => 'http://blogs.yandex.ru/pings/?status=success&url='.$encoded_sitemap_url
|
||||
);
|
||||
|
||||
$data = array('ping_urls' => $ping_urls,
|
||||
|
|
|
@ -26,6 +26,8 @@ class TarLib {
|
|||
public $_result = true;
|
||||
|
||||
function __construct($file, $comptype = TarLib::COMPRESS_AUTO, $complevel = 9) {
|
||||
dbg_deprecated('class Tar');
|
||||
|
||||
if(!$file) $this->error('__construct', '$file');
|
||||
|
||||
$this->file = $file;
|
||||
|
|
|
@ -20,6 +20,7 @@ function act_dispatch(){
|
|||
global $ID;
|
||||
global $INFO;
|
||||
global $QUERY;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
global $lang;
|
||||
global $conf;
|
||||
|
@ -94,7 +95,7 @@ function act_dispatch(){
|
|||
|
||||
// user profile changes
|
||||
if (in_array($ACT, array('profile','profile_delete'))) {
|
||||
if(!$_SERVER['REMOTE_USER']) {
|
||||
if(!$INPUT->server->str('REMOTE_USER')) {
|
||||
$ACT = 'login';
|
||||
} else {
|
||||
switch ($ACT) {
|
||||
|
@ -190,7 +191,7 @@ function act_dispatch(){
|
|||
unset($evt);
|
||||
|
||||
// when action 'show', the intial not 'show' and POST, do a redirect
|
||||
if($ACT == 'show' && $preact != 'show' && strtolower($_SERVER['REQUEST_METHOD']) == 'post'){
|
||||
if($ACT == 'show' && $preact != 'show' && strtolower($INPUT->server->str('REQUEST_METHOD')) == 'post'){
|
||||
act_redirect($ID,$preact);
|
||||
}
|
||||
|
||||
|
@ -414,6 +415,8 @@ function act_revert($act){
|
|||
global $ID;
|
||||
global $REV;
|
||||
global $lang;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
// FIXME $INFO['writable'] currently refers to the attic version
|
||||
// global $INFO;
|
||||
// if (!$INFO['writable']) {
|
||||
|
@ -445,7 +448,7 @@ function act_revert($act){
|
|||
session_write_close();
|
||||
|
||||
// when done, show current page
|
||||
$_SERVER['REQUEST_METHOD'] = 'post'; //should force a redirect
|
||||
$INPUT->server->set('REQUEST_METHOD','post'); //should force a redirect
|
||||
$REV = '';
|
||||
return 'show';
|
||||
}
|
||||
|
@ -493,17 +496,20 @@ function act_redirect_execute($opts){
|
|||
function act_auth($act){
|
||||
global $ID;
|
||||
global $INFO;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
//already logged in?
|
||||
if(isset($_SERVER['REMOTE_USER']) && $act=='login'){
|
||||
if($INPUT->server->has('REMOTE_USER') && $act=='login'){
|
||||
return 'show';
|
||||
}
|
||||
|
||||
//handle logout
|
||||
if($act=='logout'){
|
||||
$lockedby = checklock($ID); //page still locked?
|
||||
if($lockedby == $_SERVER['REMOTE_USER'])
|
||||
if($lockedby == $INPUT->server->str('REMOTE_USER')){
|
||||
unlock($ID); //try to unlock
|
||||
}
|
||||
|
||||
// do the logout stuff
|
||||
auth_logoff();
|
||||
|
@ -697,7 +703,7 @@ function act_sitemap($act) {
|
|||
|
||||
// Send file
|
||||
//use x-sendfile header to pass the delivery to compatible webservers
|
||||
if (http_sendfile($sitemap)) exit;
|
||||
http_sendfile($sitemap);
|
||||
|
||||
readfile($sitemap);
|
||||
exit;
|
||||
|
@ -719,10 +725,11 @@ function act_subscription($act){
|
|||
global $lang;
|
||||
global $INFO;
|
||||
global $ID;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
// subcriptions work for logged in users only
|
||||
if(!$_SERVER['REMOTE_USER']) return 'show';
|
||||
if(!$INPUT->server->str('REMOTE_USER')) return 'show';
|
||||
|
||||
// get and preprocess data.
|
||||
$params = array();
|
||||
|
@ -733,7 +740,7 @@ function act_subscription($act){
|
|||
}
|
||||
|
||||
// any action given? if not just return and show the subscription page
|
||||
if(!$params['action'] || !checkSecurityToken()) return $act;
|
||||
if(empty($params['action']) || !checkSecurityToken()) return $act;
|
||||
|
||||
// Handle POST data, may throw exception.
|
||||
trigger_event('ACTION_HANDLE_SUBSCRIBE', $params, 'subscription_handle_post');
|
||||
|
@ -745,9 +752,9 @@ function act_subscription($act){
|
|||
// Perform action.
|
||||
$sub = new Subscription();
|
||||
if($action == 'unsubscribe'){
|
||||
$ok = $sub->remove($target, $_SERVER['REMOTE_USER'], $style);
|
||||
$ok = $sub->remove($target, $INPUT->server->str('REMOTE_USER'), $style);
|
||||
}else{
|
||||
$ok = $sub->add($target, $_SERVER['REMOTE_USER'], $style);
|
||||
$ok = $sub->add($target, $INPUT->server->str('REMOTE_USER'), $style);
|
||||
}
|
||||
|
||||
if($ok) {
|
||||
|
@ -776,6 +783,8 @@ function act_subscription($act){
|
|||
function subscription_handle_post(&$params) {
|
||||
global $INFO;
|
||||
global $lang;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
// Get and validate parameters.
|
||||
if (!isset($params['target'])) {
|
||||
|
@ -806,7 +815,7 @@ function subscription_handle_post(&$params) {
|
|||
}
|
||||
if ($is === false) {
|
||||
throw new Exception(sprintf($lang['subscr_not_subscribed'],
|
||||
$_SERVER['REMOTE_USER'],
|
||||
$INPUT->server->str('REMOTE_USER'),
|
||||
prettyprint_id($target)));
|
||||
}
|
||||
// subscription_set deletes a subscription if style = null.
|
||||
|
|
78
inc/auth.php
78
inc/auth.php
|
@ -131,6 +131,8 @@ function auth_setup() {
|
|||
function auth_loadACL() {
|
||||
global $config_cascade;
|
||||
global $USERINFO;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
if(!is_readable($config_cascade['acl']['default'])) return array();
|
||||
|
||||
|
@ -145,10 +147,10 @@ function auth_loadACL() {
|
|||
// substitute user wildcard first (its 1:1)
|
||||
if(strstr($line, '%USER%')){
|
||||
// if user is not logged in, this ACL line is meaningless - skip it
|
||||
if (!isset($_SERVER['REMOTE_USER'])) continue;
|
||||
if (!$INPUT->server->has('REMOTE_USER')) continue;
|
||||
|
||||
$id = str_replace('%USER%',cleanID($_SERVER['REMOTE_USER']),$id);
|
||||
$rest = str_replace('%USER%',auth_nameencode($_SERVER['REMOTE_USER']),$rest);
|
||||
$id = str_replace('%USER%',cleanID($INPUT->server->str('REMOTE_USER')),$id);
|
||||
$rest = str_replace('%USER%',auth_nameencode($INPUT->server->str('REMOTE_USER')),$rest);
|
||||
}
|
||||
|
||||
// substitute group wildcard (its 1:m)
|
||||
|
@ -217,6 +219,8 @@ function auth_login($user, $pass, $sticky = false, $silent = false) {
|
|||
global $lang;
|
||||
/* @var DokuWiki_Auth_Plugin $auth */
|
||||
global $auth;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
$sticky ? $sticky = true : $sticky = false; //sanity check
|
||||
|
||||
|
@ -226,7 +230,7 @@ function auth_login($user, $pass, $sticky = false, $silent = false) {
|
|||
//usual login
|
||||
if($auth->checkPass($user, $pass)) {
|
||||
// make logininfo globally available
|
||||
$_SERVER['REMOTE_USER'] = $user;
|
||||
$INPUT->server->set('REMOTE_USER', $user);
|
||||
$secret = auth_cookiesalt(!$sticky, true); //bind non-sticky to session
|
||||
auth_setCookie($user, auth_encrypt($pass, $secret), $sticky);
|
||||
return true;
|
||||
|
@ -253,7 +257,7 @@ function auth_login($user, $pass, $sticky = false, $silent = false) {
|
|||
) {
|
||||
|
||||
// he has session, cookie and browser right - let him in
|
||||
$_SERVER['REMOTE_USER'] = $user;
|
||||
$INPUT->server->set('REMOTE_USER', $user);
|
||||
$USERINFO = $session['info']; //FIXME move all references to session
|
||||
return true;
|
||||
}
|
||||
|
@ -288,7 +292,10 @@ function auth_validateToken($token) {
|
|||
}
|
||||
// still here? trust the session data
|
||||
global $USERINFO;
|
||||
$_SERVER['REMOTE_USER'] = $_SESSION[DOKU_COOKIE]['auth']['user'];
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
$INPUT->server->set('REMOTE_USER',$_SESSION[DOKU_COOKIE]['auth']['user']);
|
||||
$USERINFO = $_SESSION[DOKU_COOKIE]['auth']['info'];
|
||||
return true;
|
||||
}
|
||||
|
@ -321,11 +328,14 @@ function auth_createToken() {
|
|||
* @return string a MD5 sum of various browser headers
|
||||
*/
|
||||
function auth_browseruid() {
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
$ip = clientIP(true);
|
||||
$uid = '';
|
||||
$uid .= $_SERVER['HTTP_USER_AGENT'];
|
||||
$uid .= $_SERVER['HTTP_ACCEPT_ENCODING'];
|
||||
$uid .= $_SERVER['HTTP_ACCEPT_CHARSET'];
|
||||
$uid .= $INPUT->server->str('HTTP_USER_AGENT');
|
||||
$uid .= $INPUT->server->str('HTTP_ACCEPT_ENCODING');
|
||||
$uid .= $INPUT->server->str('HTTP_ACCEPT_CHARSET');
|
||||
$uid .= substr($ip, 0, strpos($ip, '.'));
|
||||
$uid = strtolower($uid);
|
||||
return md5($uid);
|
||||
|
@ -511,6 +521,8 @@ function auth_logoff($keepbc = false) {
|
|||
global $USERINFO;
|
||||
/* @var DokuWiki_Auth_Plugin $auth */
|
||||
global $auth;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
// make sure the session is writable (it usually is)
|
||||
@session_start();
|
||||
|
@ -523,16 +535,11 @@ function auth_logoff($keepbc = false) {
|
|||
unset($_SESSION[DOKU_COOKIE]['auth']['info']);
|
||||
if(!$keepbc && isset($_SESSION[DOKU_COOKIE]['bc']))
|
||||
unset($_SESSION[DOKU_COOKIE]['bc']);
|
||||
if(isset($_SERVER['REMOTE_USER']))
|
||||
unset($_SERVER['REMOTE_USER']);
|
||||
$INPUT->server->remove('REMOTE_USER');
|
||||
$USERINFO = null; //FIXME
|
||||
|
||||
$cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
|
||||
if(version_compare(PHP_VERSION, '5.2.0', '>')) {
|
||||
setcookie(DOKU_COOKIE, '', time() - 600000, $cookieDir, '', ($conf['securecookie'] && is_ssl()), true);
|
||||
} else {
|
||||
setcookie(DOKU_COOKIE, '', time() - 600000, $cookieDir, '', ($conf['securecookie'] && is_ssl()));
|
||||
}
|
||||
setcookie(DOKU_COOKIE, '', time() - 600000, $cookieDir, '', ($conf['securecookie'] && is_ssl()), true);
|
||||
|
||||
if($auth) $auth->logOff();
|
||||
}
|
||||
|
@ -557,13 +564,16 @@ function auth_ismanager($user = null, $groups = null, $adminonly = false) {
|
|||
global $USERINFO;
|
||||
/* @var DokuWiki_Auth_Plugin $auth */
|
||||
global $auth;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
|
||||
if(!$auth) return false;
|
||||
if(is_null($user)) {
|
||||
if(!isset($_SERVER['REMOTE_USER'])) {
|
||||
if(!$INPUT->server->has('REMOTE_USER')) {
|
||||
return false;
|
||||
} else {
|
||||
$user = $_SERVER['REMOTE_USER'];
|
||||
$user = $INPUT->server->str('REMOTE_USER');
|
||||
}
|
||||
}
|
||||
if(is_null($groups)) {
|
||||
|
@ -655,9 +665,11 @@ function auth_isMember($memberlist, $user, array $groups) {
|
|||
function auth_quickaclcheck($id) {
|
||||
global $conf;
|
||||
global $USERINFO;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
# if no ACL is used always return upload rights
|
||||
if(!$conf['useacl']) return AUTH_UPLOAD;
|
||||
return auth_aclcheck($id, $_SERVER['REMOTE_USER'], $USERINFO['grps']);
|
||||
return auth_aclcheck($id, $INPUT->server->str('REMOTE_USER'), $USERINFO['grps']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -845,6 +857,12 @@ function auth_nameencode($name, $skip_group = false) {
|
|||
return $cache[$name][$skip_group];
|
||||
}
|
||||
|
||||
/**
|
||||
* callback encodes the matches
|
||||
*
|
||||
* @param array $matches first complete match, next matching subpatterms
|
||||
* @return string
|
||||
*/
|
||||
function auth_nameencode_callback($matches) {
|
||||
return '%'.dechex(ord(substr($matches[1],-1)));
|
||||
}
|
||||
|
@ -1056,18 +1074,18 @@ function updateprofile() {
|
|||
}
|
||||
|
||||
if($conf['profileconfirm']) {
|
||||
if(!$auth->checkPass($_SERVER['REMOTE_USER'], $INPUT->post->str('oldpass'))) {
|
||||
if(!$auth->checkPass($INPUT->server->str('REMOTE_USER'), $INPUT->post->str('oldpass'))) {
|
||||
msg($lang['badpassconfirm'], -1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if($result = $auth->triggerUserMod('modify', array($_SERVER['REMOTE_USER'], $changes))) {
|
||||
if($result = $auth->triggerUserMod('modify', array($INPUT->server->str('REMOTE_USER'), $changes))) {
|
||||
// update cookie and session with the changed data
|
||||
if($changes['pass']) {
|
||||
list( /*user*/, $sticky, /*pass*/) = auth_getCookie();
|
||||
$pass = auth_encrypt($changes['pass'], auth_cookiesalt(!$sticky, true));
|
||||
auth_setCookie($_SERVER['REMOTE_USER'], $pass, (bool) $sticky);
|
||||
auth_setCookie($INPUT->server->str('REMOTE_USER'), $pass, (bool) $sticky);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1075,6 +1093,11 @@ function updateprofile() {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the current logged-in user
|
||||
*
|
||||
* @return bool true on success, false on any error
|
||||
*/
|
||||
function auth_deleteprofile(){
|
||||
global $conf;
|
||||
global $lang;
|
||||
|
@ -1098,13 +1121,13 @@ function auth_deleteprofile(){
|
|||
}
|
||||
|
||||
if($conf['profileconfirm']) {
|
||||
if(!$auth->checkPass($_SERVER['REMOTE_USER'], $INPUT->post->str('oldpass'))) {
|
||||
if(!$auth->checkPass($INPUT->server->str('REMOTE_USER'), $INPUT->post->str('oldpass'))) {
|
||||
msg($lang['badpassconfirm'], -1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$deleted[] = $_SERVER['REMOTE_USER'];
|
||||
$deleted[] = $INPUT->server->str('REMOTE_USER');
|
||||
if($auth->triggerUserMod('delete', array($deleted))) {
|
||||
// force and immediate logout including removing the sticky cookie
|
||||
auth_logoff();
|
||||
|
@ -1308,11 +1331,8 @@ function auth_setCookie($user, $pass, $sticky) {
|
|||
$cookie = base64_encode($user).'|'.((int) $sticky).'|'.base64_encode($pass);
|
||||
$cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
|
||||
$time = $sticky ? (time() + 60 * 60 * 24 * 365) : 0; //one year
|
||||
if(version_compare(PHP_VERSION, '5.2.0', '>')) {
|
||||
setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', ($conf['securecookie'] && is_ssl()), true);
|
||||
} else {
|
||||
setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', ($conf['securecookie'] && is_ssl()));
|
||||
}
|
||||
setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', ($conf['securecookie'] && is_ssl()), true);
|
||||
|
||||
// set session
|
||||
$_SESSION[DOKU_COOKIE]['auth']['user'] = $user;
|
||||
$_SESSION[DOKU_COOKIE]['auth']['pass'] = sha1($pass);
|
||||
|
|
127
inc/cache.php
127
inc/cache.php
|
@ -8,16 +8,25 @@
|
|||
|
||||
if(!defined('DOKU_INC')) die('meh.');
|
||||
|
||||
/**
|
||||
* Generic handling of caching
|
||||
*/
|
||||
class cache {
|
||||
var $key = ''; // primary identifier for this item
|
||||
var $ext = ''; // file ext for cache data, secondary identifier for this item
|
||||
var $cache = ''; // cache file name
|
||||
var $depends = array(); // array containing cache dependency information,
|
||||
// used by _useCache to determine cache validity
|
||||
public $key = ''; // primary identifier for this item
|
||||
public $ext = ''; // file ext for cache data, secondary identifier for this item
|
||||
public $cache = ''; // cache file name
|
||||
public $depends = array(); // array containing cache dependency information,
|
||||
// used by _useCache to determine cache validity
|
||||
|
||||
var $_event = ''; // event to be triggered during useCache
|
||||
var $_time;
|
||||
var $_nocache = false; // if set to true, cache will not be used or stored
|
||||
|
||||
function cache($key,$ext) {
|
||||
/**
|
||||
* @param string $key primary identifier
|
||||
* @param string $ext file extension
|
||||
*/
|
||||
public function cache($key,$ext) {
|
||||
$this->key = $key;
|
||||
$this->ext = $ext;
|
||||
$this->cache = getCacheName($key,$ext);
|
||||
|
@ -26,7 +35,7 @@ class cache {
|
|||
/**
|
||||
* public method to determine whether the cache can be used
|
||||
*
|
||||
* to assist in cetralisation of event triggering and calculation of cache statistics,
|
||||
* to assist in centralisation of event triggering and calculation of cache statistics,
|
||||
* don't override this function override _useCache()
|
||||
*
|
||||
* @param array $depends array of cache dependencies, support dependecies:
|
||||
|
@ -36,7 +45,7 @@ class cache {
|
|||
*
|
||||
* @return bool true if cache can be used, false otherwise
|
||||
*/
|
||||
function useCache($depends=array()) {
|
||||
public function useCache($depends=array()) {
|
||||
$this->depends = $depends;
|
||||
$this->_addDependencies();
|
||||
|
||||
|
@ -55,12 +64,15 @@ class cache {
|
|||
* age - expire cache if older than age (seconds)
|
||||
* files - expire cache if any file in this array was updated more recently than the cache
|
||||
*
|
||||
* Note that this function needs to be public as it is used as callback for the event handler
|
||||
*
|
||||
* can be overridden
|
||||
*
|
||||
* @return bool see useCache()
|
||||
*/
|
||||
function _useCache() {
|
||||
public function _useCache() {
|
||||
|
||||
if ($this->_nocache) return false; // caching turned off
|
||||
if (!empty($this->depends['purge'])) return false; // purge requested?
|
||||
if (!($this->_time = @filemtime($this->cache))) return false; // cache exists?
|
||||
|
||||
|
@ -83,7 +95,7 @@ class cache {
|
|||
* it should not remove any existing dependencies and
|
||||
* it should only overwrite a dependency when the new value is more stringent than the old
|
||||
*/
|
||||
function _addDependencies() {
|
||||
protected function _addDependencies() {
|
||||
global $INPUT;
|
||||
if ($INPUT->has('purge')) $this->depends['purge'] = true; // purge requested
|
||||
}
|
||||
|
@ -94,7 +106,7 @@ class cache {
|
|||
* @param bool $clean true to clean line endings, false to leave line endings alone
|
||||
* @return string cache contents
|
||||
*/
|
||||
function retrieveCache($clean=true) {
|
||||
public function retrieveCache($clean=true) {
|
||||
return io_readFile($this->cache, $clean);
|
||||
}
|
||||
|
||||
|
@ -104,14 +116,16 @@ class cache {
|
|||
* @param string $data the data to be cached
|
||||
* @return bool true on success, false otherwise
|
||||
*/
|
||||
function storeCache($data) {
|
||||
public function storeCache($data) {
|
||||
if ($this->_nocache) return false;
|
||||
|
||||
return io_savefile($this->cache, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove any cached data associated with this cache instance
|
||||
*/
|
||||
function removeCache() {
|
||||
public function removeCache() {
|
||||
@unlink($this->cache);
|
||||
}
|
||||
|
||||
|
@ -122,7 +136,7 @@ class cache {
|
|||
* @param bool $success result of this cache use attempt
|
||||
* @return bool pass-thru $success value
|
||||
*/
|
||||
function _stats($success) {
|
||||
protected function _stats($success) {
|
||||
global $conf;
|
||||
static $stats = null;
|
||||
static $file;
|
||||
|
@ -157,14 +171,24 @@ class cache {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parser caching
|
||||
*/
|
||||
class cache_parser extends cache {
|
||||
|
||||
var $file = ''; // source file for cache
|
||||
var $mode = ''; // input mode (represents the processing the input file will undergo)
|
||||
public $file = ''; // source file for cache
|
||||
public $mode = ''; // input mode (represents the processing the input file will undergo)
|
||||
public $page = '';
|
||||
|
||||
var $_event = 'PARSER_CACHE_USE';
|
||||
|
||||
function cache_parser($id, $file, $mode) {
|
||||
/**
|
||||
*
|
||||
* @param string $id page id
|
||||
* @param string $file source file for cache
|
||||
* @param string $mode input mode
|
||||
*/
|
||||
public function cache_parser($id, $file, $mode) {
|
||||
if ($id) $this->page = $id;
|
||||
$this->file = $file;
|
||||
$this->mode = $mode;
|
||||
|
@ -172,24 +196,25 @@ class cache_parser extends cache {
|
|||
parent::cache($file.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'],'.'.$mode);
|
||||
}
|
||||
|
||||
function _useCache() {
|
||||
/**
|
||||
* method contains cache use decision logic
|
||||
*
|
||||
* @return bool see useCache()
|
||||
*/
|
||||
public function _useCache() {
|
||||
|
||||
if (!@file_exists($this->file)) return false; // source exists?
|
||||
return parent::_useCache();
|
||||
}
|
||||
|
||||
function _addDependencies() {
|
||||
global $conf, $config_cascade;
|
||||
|
||||
$this->depends['age'] = isset($this->depends['age']) ?
|
||||
min($this->depends['age'],$conf['cachetime']) : $conf['cachetime'];
|
||||
protected function _addDependencies() {
|
||||
|
||||
// parser cache file dependencies ...
|
||||
$files = array($this->file, // ... source
|
||||
$files = array($this->file, // ... source
|
||||
DOKU_INC.'inc/parser/parser.php', // ... parser
|
||||
DOKU_INC.'inc/parser/handler.php', // ... handler
|
||||
);
|
||||
$files = array_merge($files, getConfigFiles('main')); // ... wiki settings
|
||||
$files = array_merge($files, getConfigFiles('main')); // ... wiki settings
|
||||
|
||||
$this->depends['files'] = !empty($this->depends['files']) ? array_merge($files, $this->depends['files']) : $files;
|
||||
parent::_addDependencies();
|
||||
|
@ -197,8 +222,17 @@ class cache_parser extends cache {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Caching of data of renderer
|
||||
*/
|
||||
class cache_renderer extends cache_parser {
|
||||
function _useCache() {
|
||||
|
||||
/**
|
||||
* method contains cache use decision logic
|
||||
*
|
||||
* @return bool see useCache()
|
||||
*/
|
||||
public function _useCache() {
|
||||
global $conf;
|
||||
|
||||
if (!parent::_useCache()) return false;
|
||||
|
@ -231,7 +265,19 @@ class cache_renderer extends cache_parser {
|
|||
return true;
|
||||
}
|
||||
|
||||
function _addDependencies() {
|
||||
protected function _addDependencies() {
|
||||
global $conf;
|
||||
|
||||
// default renderer cache file 'age' is dependent on 'cachetime' setting, two special values:
|
||||
// -1 : do not cache (should not be overridden)
|
||||
// 0 : cache never expires (can be overridden) - no need to set depends['age']
|
||||
if ($conf['cachetime'] == -1) {
|
||||
$this->_nocache = true;
|
||||
return;
|
||||
} elseif ($conf['cachetime'] > 0) {
|
||||
$this->depends['age'] = isset($this->depends['age']) ?
|
||||
min($this->depends['age'],$conf['cachetime']) : $conf['cachetime'];
|
||||
}
|
||||
|
||||
// renderer cache file dependencies ...
|
||||
$files = array(
|
||||
|
@ -253,18 +299,39 @@ class cache_renderer extends cache_parser {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Caching of parser instructions
|
||||
*/
|
||||
class cache_instructions extends cache_parser {
|
||||
|
||||
function cache_instructions($id, $file) {
|
||||
/**
|
||||
* @param string $id page id
|
||||
* @param string $file source file for cache
|
||||
*/
|
||||
public function cache_instructions($id, $file) {
|
||||
parent::cache_parser($id, $file, 'i');
|
||||
}
|
||||
|
||||
function retrieveCache($clean=true) {
|
||||
/**
|
||||
* retrieve the cached data
|
||||
*
|
||||
* @param bool $clean true to clean line endings, false to leave line endings alone
|
||||
* @return string cache contents
|
||||
*/
|
||||
public function retrieveCache($clean=true) {
|
||||
$contents = io_readFile($this->cache, false);
|
||||
return !empty($contents) ? unserialize($contents) : array();
|
||||
}
|
||||
|
||||
function storeCache($instructions) {
|
||||
/**
|
||||
* cache $instructions
|
||||
*
|
||||
* @param string $instructions the instruction to be cached
|
||||
* @return bool true on success, false otherwise
|
||||
*/
|
||||
public function storeCache($instructions) {
|
||||
if ($this->_nocache) return false;
|
||||
|
||||
return io_savefile($this->cache,serialize($instructions));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@ define('DOKU_CHANGE_TYPE_REVERT', 'R');
|
|||
* parses a changelog line into it's components
|
||||
*
|
||||
* @author Ben Coburn <btcoburn@silicodon.net>
|
||||
*
|
||||
* @param string $line changelog line
|
||||
* @return array|bool parsed line or false
|
||||
*/
|
||||
function parseChangelogLine($line) {
|
||||
$tmp = explode("\t", $line);
|
||||
|
@ -43,7 +46,7 @@ function parseChangelogLine($line) {
|
|||
* @param String $summary Summary of the change
|
||||
* @param mixed $extra In case of a revert the revision (timestmp) of the reverted page
|
||||
* @param array $flags Additional flags in a key value array.
|
||||
* Availible flags:
|
||||
* Available flags:
|
||||
* - ExternalEdit - mark as an external edit.
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
|
@ -52,6 +55,8 @@ function parseChangelogLine($line) {
|
|||
*/
|
||||
function addLogEntry($date, $id, $type=DOKU_CHANGE_TYPE_EDIT, $summary='', $extra='', $flags=null){
|
||||
global $conf, $INFO;
|
||||
/** @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
// check for special flags as keys
|
||||
if (!is_array($flags)) { $flags = array(); }
|
||||
|
@ -65,7 +70,7 @@ function addLogEntry($date, $id, $type=DOKU_CHANGE_TYPE_EDIT, $summary='', $extr
|
|||
|
||||
if(!$date) $date = time(); //use current time if none supplied
|
||||
$remote = (!$flagExternalEdit)?clientIP(true):'127.0.0.1';
|
||||
$user = (!$flagExternalEdit)?$_SERVER['REMOTE_USER']:'';
|
||||
$user = (!$flagExternalEdit)?$INPUT->server->str('REMOTE_USER'):'';
|
||||
|
||||
$strip = array("\t", "\n");
|
||||
$logline = array(
|
||||
|
@ -114,15 +119,26 @@ function addLogEntry($date, $id, $type=DOKU_CHANGE_TYPE_EDIT, $summary='', $extr
|
|||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
* @author Esther Brunner <wikidesign@gmail.com>
|
||||
* @author Ben Coburn <btcoburn@silicodon.net>
|
||||
*
|
||||
* @param int $date Timestamp of the change
|
||||
* @param String $id Name of the affected page
|
||||
* @param String $type Type of the change see DOKU_CHANGE_TYPE_*
|
||||
* @param String $summary Summary of the change
|
||||
* @param mixed $extra In case of a revert the revision (timestmp) of the reverted page
|
||||
* @param array $flags Additional flags in a key value array.
|
||||
* Available flags:
|
||||
* - (none, so far)
|
||||
*/
|
||||
function addMediaLogEntry($date, $id, $type=DOKU_CHANGE_TYPE_EDIT, $summary='', $extra='', $flags=null){
|
||||
global $conf;
|
||||
/** @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
$id = cleanid($id);
|
||||
|
||||
if(!$date) $date = time(); //use current time if none supplied
|
||||
$remote = clientIP(true);
|
||||
$user = $_SERVER['REMOTE_USER'];
|
||||
$user = $INPUT->server->str('REMOTE_USER');
|
||||
|
||||
$strip = array("\t", "\n");
|
||||
$logline = array(
|
||||
|
@ -290,6 +306,12 @@ function getRecentsSince($from,$to=null,$ns='',$flags=0){
|
|||
* @see getRecents()
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
* @author Ben Coburn <btcoburn@silicodon.net>
|
||||
*
|
||||
* @param string $line changelog line
|
||||
* @param string $ns restrict to given namespace
|
||||
* @param int $flags flags to control which changes are included
|
||||
* @param array $seen listing of seen pages
|
||||
* @return array|bool false or array with info about a change
|
||||
*/
|
||||
function _handleRecent($line,$ns,$flags,&$seen){
|
||||
if(empty($line)) return false; //skip empty lines
|
||||
|
@ -333,6 +355,665 @@ function _handleRecent($line,$ns,$flags,&$seen){
|
|||
return $recent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ChangeLog
|
||||
* methods for handling of changelog of pages or media files
|
||||
*/
|
||||
abstract class ChangeLog {
|
||||
|
||||
/** @var string */
|
||||
protected $id;
|
||||
/** @var int */
|
||||
protected $chunk_size;
|
||||
/** @var array */
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $id page id
|
||||
* @param int $chunk_size maximum block size read from file
|
||||
*/
|
||||
public function __construct($id, $chunk_size = 8192) {
|
||||
global $cache_revinfo;
|
||||
|
||||
$this->cache =& $cache_revinfo;
|
||||
if(!isset($this->cache[$id])) {
|
||||
$this->cache[$id] = array();
|
||||
}
|
||||
|
||||
$this->id = $id;
|
||||
$this->setChunkSize($chunk_size);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set chunk size for file reading
|
||||
* Chunk size zero let read whole file at once
|
||||
*
|
||||
* @param int $chunk_size maximum block size read from file
|
||||
*/
|
||||
public function setChunkSize($chunk_size) {
|
||||
if(!is_numeric($chunk_size)) $chunk_size = 0;
|
||||
|
||||
$this->chunk_size = (int) max($chunk_size, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns path to changelog
|
||||
*
|
||||
* @return string path to file
|
||||
*/
|
||||
abstract protected function getChangelogFilename();
|
||||
|
||||
/**
|
||||
* Returns path to current page/media
|
||||
*
|
||||
* @return string path to file
|
||||
*/
|
||||
abstract protected function getFilename();
|
||||
|
||||
/**
|
||||
* Get the changelog information for a specific page id and revision (timestamp)
|
||||
*
|
||||
* Adjacent changelog lines are optimistically parsed and cached to speed up
|
||||
* consecutive calls to getRevisionInfo. For large changelog files, only the chunk
|
||||
* containing the requested changelog line is read.
|
||||
*
|
||||
* @param int $rev revision timestamp
|
||||
* @return bool|array false or array with entries:
|
||||
* - date: unix timestamp
|
||||
* - ip: IPv4 address (127.0.0.1)
|
||||
* - type: log line type
|
||||
* - id: page id
|
||||
* - user: user name
|
||||
* - sum: edit summary (or action reason)
|
||||
* - extra: extra data (varies by line type)
|
||||
*
|
||||
* @author Ben Coburn <btcoburn@silicodon.net>
|
||||
* @author Kate Arzamastseva <pshns@ukr.net>
|
||||
*/
|
||||
public function getRevisionInfo($rev) {
|
||||
$rev = max($rev, 0);
|
||||
|
||||
// check if it's already in the memory cache
|
||||
if(isset($this->cache[$this->id]) && isset($this->cache[$this->id][$rev])) {
|
||||
return $this->cache[$this->id][$rev];
|
||||
}
|
||||
|
||||
//read lines from changelog
|
||||
list($fp, $lines) = $this->readloglines($rev);
|
||||
if($fp) {
|
||||
fclose($fp);
|
||||
}
|
||||
if(empty($lines)) return false;
|
||||
|
||||
// parse and cache changelog lines
|
||||
foreach($lines as $value) {
|
||||
$tmp = parseChangelogLine($value);
|
||||
if($tmp !== false) {
|
||||
$this->cache[$this->id][$tmp['date']] = $tmp;
|
||||
}
|
||||
}
|
||||
if(!isset($this->cache[$this->id][$rev])) {
|
||||
return false;
|
||||
}
|
||||
return $this->cache[$this->id][$rev];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of page revisions numbers
|
||||
*
|
||||
* Does not guarantee that the revision exists in the attic,
|
||||
* only that a line with the date exists in the changelog.
|
||||
* By default the current revision is skipped.
|
||||
*
|
||||
* The current revision is automatically skipped when the page exists.
|
||||
* See $INFO['meta']['last_change'] for the current revision.
|
||||
* A negative $first let read the current revision too.
|
||||
*
|
||||
* For efficiency, the log lines are parsed and cached for later
|
||||
* calls to getRevisionInfo. Large changelog files are read
|
||||
* backwards in chunks until the requested number of changelog
|
||||
* lines are recieved.
|
||||
*
|
||||
* @param int $first skip the first n changelog lines
|
||||
* @param int $num number of revisions to return
|
||||
* @return array with the revision timestamps
|
||||
*
|
||||
* @author Ben Coburn <btcoburn@silicodon.net>
|
||||
* @author Kate Arzamastseva <pshns@ukr.net>
|
||||
*/
|
||||
public function getRevisions($first, $num) {
|
||||
$revs = array();
|
||||
$lines = array();
|
||||
$count = 0;
|
||||
|
||||
$num = max($num, 0);
|
||||
if($num == 0) {
|
||||
return $revs;
|
||||
}
|
||||
|
||||
if($first < 0) {
|
||||
$first = 0;
|
||||
} else if(@file_exists($this->getFilename())) {
|
||||
// skip current revision if the page exists
|
||||
$first = max($first + 1, 0);
|
||||
}
|
||||
|
||||
$file = $this->getChangelogFilename();
|
||||
|
||||
if(!@file_exists($file)) {
|
||||
return $revs;
|
||||
}
|
||||
if(filesize($file) < $this->chunk_size || $this->chunk_size == 0) {
|
||||
// read whole file
|
||||
$lines = file($file);
|
||||
if($lines === false) {
|
||||
return $revs;
|
||||
}
|
||||
} else {
|
||||
// read chunks backwards
|
||||
$fp = fopen($file, 'rb'); // "file pointer"
|
||||
if($fp === false) {
|
||||
return $revs;
|
||||
}
|
||||
fseek($fp, 0, SEEK_END);
|
||||
$tail = ftell($fp);
|
||||
|
||||
// chunk backwards
|
||||
$finger = max($tail - $this->chunk_size, 0);
|
||||
while($count < $num + $first) {
|
||||
$nl = $this->getNewlinepointer($fp, $finger);
|
||||
|
||||
// was the chunk big enough? if not, take another bite
|
||||
if($nl > 0 && $tail <= $nl) {
|
||||
$finger = max($finger - $this->chunk_size, 0);
|
||||
continue;
|
||||
} else {
|
||||
$finger = $nl;
|
||||
}
|
||||
|
||||
// read chunk
|
||||
$chunk = '';
|
||||
$read_size = max($tail - $finger, 0); // found chunk size
|
||||
$got = 0;
|
||||
while($got < $read_size && !feof($fp)) {
|
||||
$tmp = @fread($fp, max(min($this->chunk_size, $read_size - $got), 0));
|
||||
if($tmp === false) {
|
||||
break;
|
||||
} //error state
|
||||
$got += strlen($tmp);
|
||||
$chunk .= $tmp;
|
||||
}
|
||||
$tmp = explode("\n", $chunk);
|
||||
array_pop($tmp); // remove trailing newline
|
||||
|
||||
// combine with previous chunk
|
||||
$count += count($tmp);
|
||||
$lines = array_merge($tmp, $lines);
|
||||
|
||||
// next chunk
|
||||
if($finger == 0) {
|
||||
break;
|
||||
} // already read all the lines
|
||||
else {
|
||||
$tail = $finger;
|
||||
$finger = max($tail - $this->chunk_size, 0);
|
||||
}
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
// skip parsing extra lines
|
||||
$num = max(min(count($lines) - $first, $num), 0);
|
||||
if ($first > 0 && $num > 0) { $lines = array_slice($lines, max(count($lines) - $first - $num, 0), $num); }
|
||||
else if($first > 0 && $num == 0) { $lines = array_slice($lines, 0, max(count($lines) - $first, 0)); }
|
||||
else if($first == 0 && $num > 0) { $lines = array_slice($lines, max(count($lines) - $num, 0)); }
|
||||
|
||||
// handle lines in reverse order
|
||||
for($i = count($lines) - 1; $i >= 0; $i--) {
|
||||
$tmp = parseChangelogLine($lines[$i]);
|
||||
if($tmp !== false) {
|
||||
$this->cache[$this->id][$tmp['date']] = $tmp;
|
||||
$revs[] = $tmp['date'];
|
||||
}
|
||||
}
|
||||
|
||||
return $revs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the nth revision left or right handside for a specific page id and revision (timestamp)
|
||||
*
|
||||
* For large changelog files, only the chunk containing the
|
||||
* reference revision $rev is read and sometimes a next chunck.
|
||||
*
|
||||
* Adjacent changelog lines are optimistically parsed and cached to speed up
|
||||
* consecutive calls to getRevisionInfo.
|
||||
*
|
||||
* @param int $rev revision timestamp used as startdate (doesn't need to be revisionnumber)
|
||||
* @param int $direction give position of returned revision with respect to $rev; positive=next, negative=prev
|
||||
* @return bool|int
|
||||
* timestamp of the requested revision
|
||||
* otherwise false
|
||||
*/
|
||||
public function getRelativeRevision($rev, $direction) {
|
||||
$rev = max($rev, 0);
|
||||
$direction = (int) $direction;
|
||||
|
||||
//no direction given or last rev, so no follow-up
|
||||
if(!$direction || ($direction > 0 && $this->isCurrentRevision($rev))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//get lines from changelog
|
||||
list($fp, $lines, $head, $tail, $eof) = $this->readloglines($rev);
|
||||
if(empty($lines)) return false;
|
||||
|
||||
// look for revisions later/earlier then $rev, when founded count till the wanted revision is reached
|
||||
// also parse and cache changelog lines for getRevisionInfo().
|
||||
$revcounter = 0;
|
||||
$relativerev = false;
|
||||
$checkotherchunck = true; //always runs once
|
||||
while(!$relativerev && $checkotherchunck) {
|
||||
$tmp = array();
|
||||
//parse in normal or reverse order
|
||||
$count = count($lines);
|
||||
if($direction > 0) {
|
||||
$start = 0;
|
||||
$step = 1;
|
||||
} else {
|
||||
$start = $count - 1;
|
||||
$step = -1;
|
||||
}
|
||||
for($i = $start; $i >= 0 && $i < $count; $i = $i + $step) {
|
||||
$tmp = parseChangelogLine($lines[$i]);
|
||||
if($tmp !== false) {
|
||||
$this->cache[$this->id][$tmp['date']] = $tmp;
|
||||
//look for revs older/earlier then reference $rev and select $direction-th one
|
||||
if(($direction > 0 && $tmp['date'] > $rev) || ($direction < 0 && $tmp['date'] < $rev)) {
|
||||
$revcounter++;
|
||||
if($revcounter == abs($direction)) {
|
||||
$relativerev = $tmp['date'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//true when $rev is found, but not the wanted follow-up.
|
||||
$checkotherchunck = $fp
|
||||
&& ($tmp['date'] == $rev || ($revcounter > 0 && !$relativerev))
|
||||
&& !(($tail == $eof && $direction > 0) || ($head == 0 && $direction < 0));
|
||||
|
||||
if($checkotherchunck) {
|
||||
list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, $direction);
|
||||
|
||||
if(empty($lines)) break;
|
||||
}
|
||||
}
|
||||
if($fp) {
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
return $relativerev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns revisions around rev1 and rev2
|
||||
* When available it returns $max entries for each revision
|
||||
*
|
||||
* @param int $rev1 oldest revision timestamp
|
||||
* @param int $rev2 newest revision timestamp (0 looks up last revision)
|
||||
* @param int $max maximum number of revisions returned
|
||||
* @return array with two arrays with revisions surrounding rev1 respectively rev2
|
||||
*/
|
||||
public function getRevisionsAround($rev1, $rev2, $max = 50) {
|
||||
$max = floor(abs($max) / 2)*2 + 1;
|
||||
$rev1 = max($rev1, 0);
|
||||
$rev2 = max($rev2, 0);
|
||||
|
||||
if($rev2) {
|
||||
if($rev2 < $rev1) {
|
||||
$rev = $rev2;
|
||||
$rev2 = $rev1;
|
||||
$rev1 = $rev;
|
||||
}
|
||||
} else {
|
||||
//empty right side means a removed page. Look up last revision.
|
||||
$revs = $this->getRevisions(-1, 1);
|
||||
$rev2 = $revs[0];
|
||||
}
|
||||
//collect revisions around rev2
|
||||
list($revs2, $allrevs, $fp, $lines, $head, $tail) = $this->retrieveRevisionsAround($rev2, $max);
|
||||
|
||||
if(empty($revs2)) return array(array(), array());
|
||||
|
||||
//collect revisions around rev1
|
||||
$index = array_search($rev1, $allrevs);
|
||||
if($index === false) {
|
||||
//no overlapping revisions
|
||||
list($revs1,,,,,) = $this->retrieveRevisionsAround($rev1, $max);
|
||||
if(empty($revs1)) $revs1 = array();
|
||||
} else {
|
||||
//revisions overlaps, reuse revisions around rev2
|
||||
$revs1 = $allrevs;
|
||||
while($head > 0) {
|
||||
for($i = count($lines) - 1; $i >= 0; $i--) {
|
||||
$tmp = parseChangelogLine($lines[$i]);
|
||||
if($tmp !== false) {
|
||||
$this->cache[$this->id][$tmp['date']] = $tmp;
|
||||
$revs1[] = $tmp['date'];
|
||||
$index++;
|
||||
|
||||
if($index > floor($max / 2)) break 2;
|
||||
}
|
||||
}
|
||||
|
||||
list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, -1);
|
||||
}
|
||||
sort($revs1);
|
||||
//return wanted selection
|
||||
$revs1 = array_slice($revs1, max($index - floor($max/2), 0), $max);
|
||||
}
|
||||
|
||||
return array(array_reverse($revs1), array_reverse($revs2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns lines from changelog.
|
||||
* If file larger than $chuncksize, only chunck is read that could contain $rev.
|
||||
*
|
||||
* @param int $rev revision timestamp
|
||||
* @return array(fp, array(changeloglines), $head, $tail, $eof)|bool
|
||||
* returns false when not succeed. fp only defined for chuck reading, needs closing.
|
||||
*/
|
||||
protected function readloglines($rev) {
|
||||
$file = $this->getChangelogFilename();
|
||||
|
||||
if(!@file_exists($file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$fp = null;
|
||||
$head = 0;
|
||||
$tail = 0;
|
||||
$eof = 0;
|
||||
|
||||
if(filesize($file) < $this->chunk_size || $this->chunk_size == 0) {
|
||||
// read whole file
|
||||
$lines = file($file);
|
||||
if($lines === false) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// read by chunk
|
||||
$fp = fopen($file, 'rb'); // "file pointer"
|
||||
if($fp === false) {
|
||||
return false;
|
||||
}
|
||||
$head = 0;
|
||||
fseek($fp, 0, SEEK_END);
|
||||
$eof = ftell($fp);
|
||||
$tail = $eof;
|
||||
|
||||
// find chunk
|
||||
while($tail - $head > $this->chunk_size) {
|
||||
$finger = $head + floor(($tail - $head) / 2.0);
|
||||
$finger = $this->getNewlinepointer($fp, $finger);
|
||||
$tmp = fgets($fp);
|
||||
if($finger == $head || $finger == $tail) {
|
||||
break;
|
||||
}
|
||||
$tmp = parseChangelogLine($tmp);
|
||||
$finger_rev = $tmp['date'];
|
||||
|
||||
if($finger_rev > $rev) {
|
||||
$tail = $finger;
|
||||
} else {
|
||||
$head = $finger;
|
||||
}
|
||||
}
|
||||
|
||||
if($tail - $head < 1) {
|
||||
// cound not find chunk, assume requested rev is missing
|
||||
fclose($fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
$lines = $this->readChunk($fp, $head, $tail);
|
||||
}
|
||||
return array(
|
||||
$fp,
|
||||
$lines,
|
||||
$head,
|
||||
$tail,
|
||||
$eof
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read chunk and return array with lines of given chunck.
|
||||
* Has no check if $head and $tail are really at a new line
|
||||
*
|
||||
* @param resource $fp resource filepointer
|
||||
* @param int $head start point chunck
|
||||
* @param int $tail end point chunck
|
||||
* @return array lines read from chunck
|
||||
*/
|
||||
protected function readChunk($fp, $head, $tail) {
|
||||
$chunk = '';
|
||||
$chunk_size = max($tail - $head, 0); // found chunk size
|
||||
$got = 0;
|
||||
fseek($fp, $head);
|
||||
while($got < $chunk_size && !feof($fp)) {
|
||||
$tmp = @fread($fp, max(min($this->chunk_size, $chunk_size - $got), 0));
|
||||
if($tmp === false) { //error state
|
||||
break;
|
||||
}
|
||||
$got += strlen($tmp);
|
||||
$chunk .= $tmp;
|
||||
}
|
||||
$lines = explode("\n", $chunk);
|
||||
array_pop($lines); // remove trailing newline
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set pointer to first new line after $finger and return its position
|
||||
*
|
||||
* @param resource $fp filepointer
|
||||
* @param int $finger a pointer
|
||||
* @return int pointer
|
||||
*/
|
||||
protected function getNewlinepointer($fp, $finger) {
|
||||
fseek($fp, $finger);
|
||||
$nl = $finger;
|
||||
if($finger > 0) {
|
||||
fgets($fp); // slip the finger forward to a new line
|
||||
$nl = ftell($fp);
|
||||
}
|
||||
return $nl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether given revision is the current page
|
||||
*
|
||||
* @param int $rev timestamp of current page
|
||||
* @return bool true if $rev is current revision, otherwise false
|
||||
*/
|
||||
public function isCurrentRevision($rev) {
|
||||
return $rev == @filemtime($this->getFilename());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next lines of the changelog of the chunck before head or after tail
|
||||
*
|
||||
* @param resource $fp filepointer
|
||||
* @param int $head position head of last chunk
|
||||
* @param int $tail position tail of last chunk
|
||||
* @param int $direction positive forward, negative backward
|
||||
* @return array with entries:
|
||||
* - $lines: changelog lines of readed chunk
|
||||
* - $head: head of chunk
|
||||
* - $tail: tail of chunk
|
||||
*/
|
||||
protected function readAdjacentChunk($fp, $head, $tail, $direction) {
|
||||
if(!$fp) return array(array(), $head, $tail);
|
||||
|
||||
if($direction > 0) {
|
||||
//read forward
|
||||
$head = $tail;
|
||||
$tail = $head + floor($this->chunk_size * (2 / 3));
|
||||
$tail = $this->getNewlinepointer($fp, $tail);
|
||||
} else {
|
||||
//read backward
|
||||
$tail = $head;
|
||||
$head = max($tail - $this->chunk_size, 0);
|
||||
while(true) {
|
||||
$nl = $this->getNewlinepointer($fp, $head);
|
||||
// was the chunk big enough? if not, take another bite
|
||||
if($nl > 0 && $tail <= $nl) {
|
||||
$head = max($head - $this->chunk_size, 0);
|
||||
} else {
|
||||
$head = $nl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//load next chunck
|
||||
$lines = $this->readChunk($fp, $head, $tail);
|
||||
return array($lines, $head, $tail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the $max revisions near to the timestamp $rev
|
||||
*
|
||||
* @param int $rev revision timestamp
|
||||
* @param int $max maximum number of revisions to be returned
|
||||
* @return bool|array
|
||||
* return array with entries:
|
||||
* - $requestedrevs: array of with $max revision timestamps
|
||||
* - $revs: all parsed revision timestamps
|
||||
* - $fp: filepointer only defined for chuck reading, needs closing.
|
||||
* - $lines: non-parsed changelog lines before the parsed revisions
|
||||
* - $head: position of first readed changelogline
|
||||
* - $lasttail: position of end of last readed changelogline
|
||||
* otherwise false
|
||||
*/
|
||||
protected function retrieveRevisionsAround($rev, $max) {
|
||||
//get lines from changelog
|
||||
list($fp, $lines, $starthead, $starttail, /* $eof */) = $this->readloglines($rev);
|
||||
if(empty($lines)) return false;
|
||||
|
||||
//parse chunk containing $rev, and read forward more chunks until $max/2 is reached
|
||||
$head = $starthead;
|
||||
$tail = $starttail;
|
||||
$revs = array();
|
||||
$aftercount = $beforecount = 0;
|
||||
while(count($lines) > 0) {
|
||||
foreach($lines as $line) {
|
||||
$tmp = parseChangelogLine($line);
|
||||
if($tmp !== false) {
|
||||
$this->cache[$this->id][$tmp['date']] = $tmp;
|
||||
$revs[] = $tmp['date'];
|
||||
if($tmp['date'] >= $rev) {
|
||||
//count revs after reference $rev
|
||||
$aftercount++;
|
||||
if($aftercount == 1) $beforecount = count($revs);
|
||||
}
|
||||
//enough revs after reference $rev?
|
||||
if($aftercount > floor($max / 2)) break 2;
|
||||
}
|
||||
}
|
||||
//retrieve next chunk
|
||||
list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, 1);
|
||||
}
|
||||
if($aftercount == 0) return false;
|
||||
|
||||
$lasttail = $tail;
|
||||
|
||||
//read additional chuncks backward until $max/2 is reached and total number of revs is equal to $max
|
||||
$lines = array();
|
||||
$i = 0;
|
||||
if($aftercount > 0) {
|
||||
$head = $starthead;
|
||||
$tail = $starttail;
|
||||
while($head > 0) {
|
||||
list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, -1);
|
||||
|
||||
for($i = count($lines) - 1; $i >= 0; $i--) {
|
||||
$tmp = parseChangelogLine($lines[$i]);
|
||||
if($tmp !== false) {
|
||||
$this->cache[$this->id][$tmp['date']] = $tmp;
|
||||
$revs[] = $tmp['date'];
|
||||
$beforecount++;
|
||||
//enough revs before reference $rev?
|
||||
if($beforecount > max(floor($max / 2), $max - $aftercount)) break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sort($revs);
|
||||
|
||||
//keep only non-parsed lines
|
||||
$lines = array_slice($lines, 0, $i);
|
||||
//trunk desired selection
|
||||
$requestedrevs = array_slice($revs, -$max, $max);
|
||||
|
||||
return array($requestedrevs, $revs, $fp, $lines, $head, $lasttail);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class PageChangelog handles changelog of a wiki page
|
||||
*/
|
||||
class PageChangelog extends ChangeLog {
|
||||
|
||||
/**
|
||||
* Returns path to changelog
|
||||
*
|
||||
* @return string path to file
|
||||
*/
|
||||
protected function getChangelogFilename() {
|
||||
return metaFN($this->id, '.changes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns path to current page/media
|
||||
*
|
||||
* @return string path to file
|
||||
*/
|
||||
protected function getFilename() {
|
||||
return wikiFN($this->id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class MediaChangelog handles changelog of a media file
|
||||
*/
|
||||
class MediaChangelog extends ChangeLog {
|
||||
|
||||
/**
|
||||
* Returns path to changelog
|
||||
*
|
||||
* @return string path to file
|
||||
*/
|
||||
protected function getChangelogFilename() {
|
||||
return mediaMetaFN($this->id, '.changes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns path to current page/media
|
||||
*
|
||||
* @return string path to file
|
||||
*/
|
||||
protected function getFilename() {
|
||||
return mediaFN($this->id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the changelog information for a specific page id
|
||||
* and revision (timestamp). Adjacent changelog lines
|
||||
|
@ -341,88 +1022,19 @@ function _handleRecent($line,$ns,$flags,&$seen){
|
|||
* changelog files, only the chunk containing the
|
||||
* requested changelog line is read.
|
||||
*
|
||||
* @deprecated 2013-11-20
|
||||
*
|
||||
* @author Ben Coburn <btcoburn@silicodon.net>
|
||||
* @author Kate Arzamastseva <pshns@ukr.net>
|
||||
*/
|
||||
function getRevisionInfo($id, $rev, $chunk_size=8192, $media=false) {
|
||||
global $cache_revinfo;
|
||||
$cache =& $cache_revinfo;
|
||||
if (!isset($cache[$id])) { $cache[$id] = array(); }
|
||||
$rev = max($rev, 0);
|
||||
|
||||
// check if it's already in the memory cache
|
||||
if (isset($cache[$id]) && isset($cache[$id][$rev])) {
|
||||
return $cache[$id][$rev];
|
||||
}
|
||||
|
||||
if ($media) {
|
||||
$file = mediaMetaFN($id, '.changes');
|
||||
function getRevisionInfo($id, $rev, $chunk_size = 8192, $media = false) {
|
||||
dbg_deprecated('class PageChangeLog or class MediaChangelog');
|
||||
if($media) {
|
||||
$changelog = new MediaChangeLog($id, $chunk_size);
|
||||
} else {
|
||||
$file = metaFN($id, '.changes');
|
||||
$changelog = new PageChangeLog($id, $chunk_size);
|
||||
}
|
||||
if (!@file_exists($file)) { return false; }
|
||||
if (filesize($file)<$chunk_size || $chunk_size==0) {
|
||||
// read whole file
|
||||
$lines = file($file);
|
||||
if ($lines===false) { return false; }
|
||||
} else {
|
||||
// read by chunk
|
||||
$fp = fopen($file, 'rb'); // "file pointer"
|
||||
if ($fp===false) { return false; }
|
||||
$head = 0;
|
||||
fseek($fp, 0, SEEK_END);
|
||||
$tail = ftell($fp);
|
||||
$finger = 0;
|
||||
$finger_rev = 0;
|
||||
|
||||
// find chunk
|
||||
while ($tail-$head>$chunk_size) {
|
||||
$finger = $head+floor(($tail-$head)/2.0);
|
||||
fseek($fp, $finger);
|
||||
fgets($fp); // slip the finger forward to a new line
|
||||
$finger = ftell($fp);
|
||||
$tmp = fgets($fp); // then read at that location
|
||||
$tmp = parseChangelogLine($tmp);
|
||||
$finger_rev = $tmp['date'];
|
||||
if ($finger==$head || $finger==$tail) { break; }
|
||||
if ($finger_rev>$rev) {
|
||||
$tail = $finger;
|
||||
} else {
|
||||
$head = $finger;
|
||||
}
|
||||
}
|
||||
|
||||
if ($tail-$head<1) {
|
||||
// cound not find chunk, assume requested rev is missing
|
||||
fclose($fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
// read chunk
|
||||
$chunk = '';
|
||||
$chunk_size = max($tail-$head, 0); // found chunk size
|
||||
$got = 0;
|
||||
fseek($fp, $head);
|
||||
while ($got<$chunk_size && !feof($fp)) {
|
||||
$tmp = @fread($fp, max($chunk_size-$got, 0));
|
||||
if ($tmp===false) { break; } //error state
|
||||
$got += strlen($tmp);
|
||||
$chunk .= $tmp;
|
||||
}
|
||||
$lines = explode("\n", $chunk);
|
||||
array_pop($lines); // remove trailing newline
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
// parse and cache changelog lines
|
||||
foreach ($lines as $value) {
|
||||
$tmp = parseChangelogLine($value);
|
||||
if ($tmp!==false) {
|
||||
$cache[$id][$tmp['date']] = $tmp;
|
||||
}
|
||||
}
|
||||
if (!isset($cache[$id][$rev])) { return false; }
|
||||
return $cache[$id][$rev];
|
||||
return $changelog->getRevisionInfo($rev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -431,10 +1043,6 @@ function getRevisionInfo($id, $rev, $chunk_size=8192, $media=false) {
|
|||
* only that a line with the date exists in the changelog.
|
||||
* By default the current revision is skipped.
|
||||
*
|
||||
* id: the page of interest
|
||||
* first: skip the first n changelog lines
|
||||
* num: number of revisions to return
|
||||
*
|
||||
* The current revision is automatically skipped when the page exists.
|
||||
* See $INFO['meta']['last_change'] for the current revision.
|
||||
*
|
||||
|
@ -443,106 +1051,24 @@ function getRevisionInfo($id, $rev, $chunk_size=8192, $media=false) {
|
|||
* backwards in chunks until the requested number of changelog
|
||||
* lines are recieved.
|
||||
*
|
||||
* @deprecated 2013-11-20
|
||||
*
|
||||
* @author Ben Coburn <btcoburn@silicodon.net>
|
||||
* @author Kate Arzamastseva <pshns@ukr.net>
|
||||
*
|
||||
* @param string $id the page of interest
|
||||
* @param int $first skip the first n changelog lines
|
||||
* @param int $num number of revisions to return
|
||||
* @param int $chunk_size
|
||||
* @param bool $media
|
||||
* @return array
|
||||
*/
|
||||
function getRevisions($id, $first, $num, $chunk_size=8192, $media=false) {
|
||||
global $cache_revinfo;
|
||||
$cache =& $cache_revinfo;
|
||||
if (!isset($cache[$id])) { $cache[$id] = array(); }
|
||||
|
||||
$revs = array();
|
||||
$lines = array();
|
||||
$count = 0;
|
||||
if ($media) {
|
||||
$file = mediaMetaFN($id, '.changes');
|
||||
function getRevisions($id, $first, $num, $chunk_size = 8192, $media = false) {
|
||||
dbg_deprecated('class PageChangeLog or class MediaChangelog');
|
||||
if($media) {
|
||||
$changelog = new MediaChangeLog($id, $chunk_size);
|
||||
} else {
|
||||
$file = metaFN($id, '.changes');
|
||||
$changelog = new PageChangeLog($id, $chunk_size);
|
||||
}
|
||||
$num = max($num, 0);
|
||||
if ($num == 0) { return $revs; }
|
||||
|
||||
$chunk_size = max($chunk_size, 0);
|
||||
if ($first<0) {
|
||||
$first = 0;
|
||||
} else if (!$media && @file_exists(wikiFN($id)) || $media && @file_exists(mediaFN($id))) {
|
||||
// skip current revision if the page exists
|
||||
$first = max($first+1, 0);
|
||||
}
|
||||
|
||||
if (!@file_exists($file)) { return $revs; }
|
||||
if (filesize($file)<$chunk_size || $chunk_size==0) {
|
||||
// read whole file
|
||||
$lines = file($file);
|
||||
if ($lines===false) { return $revs; }
|
||||
} else {
|
||||
// read chunks backwards
|
||||
$fp = fopen($file, 'rb'); // "file pointer"
|
||||
if ($fp===false) { return $revs; }
|
||||
fseek($fp, 0, SEEK_END);
|
||||
$tail = ftell($fp);
|
||||
|
||||
// chunk backwards
|
||||
$finger = max($tail-$chunk_size, 0);
|
||||
while ($count<$num+$first) {
|
||||
fseek($fp, $finger);
|
||||
$nl = $finger;
|
||||
if ($finger>0) {
|
||||
fgets($fp); // slip the finger forward to a new line
|
||||
$nl = ftell($fp);
|
||||
}
|
||||
|
||||
// was the chunk big enough? if not, take another bite
|
||||
if($nl > 0 && $tail <= $nl){
|
||||
$finger = max($finger-$chunk_size, 0);
|
||||
continue;
|
||||
}else{
|
||||
$finger = $nl;
|
||||
}
|
||||
|
||||
// read chunk
|
||||
$chunk = '';
|
||||
$read_size = max($tail-$finger, 0); // found chunk size
|
||||
$got = 0;
|
||||
while ($got<$read_size && !feof($fp)) {
|
||||
$tmp = @fread($fp, max($read_size-$got, 0));
|
||||
if ($tmp===false) { break; } //error state
|
||||
$got += strlen($tmp);
|
||||
$chunk .= $tmp;
|
||||
}
|
||||
$tmp = explode("\n", $chunk);
|
||||
array_pop($tmp); // remove trailing newline
|
||||
|
||||
// combine with previous chunk
|
||||
$count += count($tmp);
|
||||
$lines = array_merge($tmp, $lines);
|
||||
|
||||
// next chunk
|
||||
if ($finger==0) { break; } // already read all the lines
|
||||
else {
|
||||
$tail = $finger;
|
||||
$finger = max($tail-$chunk_size, 0);
|
||||
}
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
// skip parsing extra lines
|
||||
$num = max(min(count($lines)-$first, $num), 0);
|
||||
if ($first>0 && $num>0) { $lines = array_slice($lines, max(count($lines)-$first-$num, 0), $num); }
|
||||
else if ($first>0 && $num==0) { $lines = array_slice($lines, 0, max(count($lines)-$first, 0)); }
|
||||
else if ($first==0 && $num>0) { $lines = array_slice($lines, max(count($lines)-$num, 0)); }
|
||||
|
||||
// handle lines in reverse order
|
||||
for ($i = count($lines)-1; $i >= 0; $i--) {
|
||||
$tmp = parseChangelogLine($lines[$i]);
|
||||
if ($tmp!==false) {
|
||||
$cache[$id][$tmp['date']] = $tmp;
|
||||
$revs[] = $tmp['date'];
|
||||
}
|
||||
}
|
||||
|
||||
return $revs;
|
||||
return $changelog->getRevisions($first, $num);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,647 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class DokuCLI
|
||||
*
|
||||
* All DokuWiki commandline scripts should inherit from this class and implement the abstract methods.
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 immeadiately.',
|
||||
'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
|
||||
*/
|
||||
public function error($string) {
|
||||
$this->colors->ptln("E: $string", 'red', STDERR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a success message
|
||||
*
|
||||
* @param $string
|
||||
*/
|
||||
public function success($string) {
|
||||
$this->colors->ptln("S: $string", 'green', STDERR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an info message
|
||||
*
|
||||
* @param $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 $line
|
||||
* @param $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 mixed $default what to return if the option was not set
|
||||
* @return mixed
|
||||
*/
|
||||
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 array $widths list of column widths (in characters)
|
||||
* @param array $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
|
||||
|
||||
public function __construct($message = "", $code = 0, Exception $previous = null) {
|
||||
if(!$code) $code = DokuCLI_Exception::E_ANY;
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
|
@ -68,15 +68,16 @@ define('DOKU_CLI_OPTS_ARG_READ',5);//Could not read argv
|
|||
*
|
||||
* @author Andrei Zmievski <andrei@php.net>
|
||||
*
|
||||
* @deprecated 2014-05-16
|
||||
*/
|
||||
class Doku_Cli_Opts {
|
||||
|
||||
/**
|
||||
* <?php ?>
|
||||
* @see http://www.sitepoint.com/article/php-command-line-1/3
|
||||
* @param string executing file name - this MUST be passed the __FILE__ constant
|
||||
* @param string short options
|
||||
* @param array (optional) long options
|
||||
* @param string $bin_file executing file name - this MUST be passed the __FILE__ constant
|
||||
* @param string $short_options short options
|
||||
* @param array $long_options (optional) long options
|
||||
* @return Doku_Cli_Opts_Container or Doku_Cli_Opts_Error
|
||||
*/
|
||||
function & getOptions($bin_file, $short_options, $long_options = null) {
|
||||
|
@ -233,12 +234,12 @@ class Doku_Cli_Opts {
|
|||
* Parse short option
|
||||
*
|
||||
* @param string $arg Argument
|
||||
* @param string[] $short_options Available short options
|
||||
* @param string $short_options Available short options
|
||||
* @param string[][] &$opts
|
||||
* @param string[] &$args
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
* @return void|Doku_Cli_Opts_Error
|
||||
*/
|
||||
function _parseShortOption($arg, $short_options, &$opts, &$args) {
|
||||
$len = strlen($arg);
|
||||
|
@ -324,7 +325,7 @@ class Doku_Cli_Opts {
|
|||
* @param string[] &$args
|
||||
*
|
||||
* @access private
|
||||
* @return void|PEAR_Error
|
||||
* @return void|Doku_Cli_Opts_Error
|
||||
*/
|
||||
function _parseLongOption($arg, $long_options, &$opts, &$args) {
|
||||
@list($opt, $opt_arg) = explode('=', $arg, 2);
|
||||
|
@ -402,7 +403,7 @@ class Doku_Cli_Opts {
|
|||
* Will take care on register_globals and register_argc_argv ini directives
|
||||
*
|
||||
* @access public
|
||||
* @return mixed the $argv PHP array or PEAR error if not registered
|
||||
* @return array|Doku_Cli_Opts_Error the $argv PHP array or PEAR error if not registered
|
||||
*/
|
||||
function readPHPArgv() {
|
||||
global $argv;
|
||||
|
@ -421,10 +422,19 @@ class Doku_Cli_Opts {
|
|||
return $argv;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $code
|
||||
* @param $msg
|
||||
* @return Doku_Cli_Opts_Error
|
||||
*/
|
||||
function raiseError($code, $msg) {
|
||||
return new Doku_Cli_Opts_Error($code, $msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $obj
|
||||
* @return bool
|
||||
*/
|
||||
function isError($obj) {
|
||||
return is_a($obj, 'Doku_Cli_Opts_Error');
|
||||
}
|
||||
|
|
458
inc/common.php
458
inc/common.php
|
@ -22,6 +22,9 @@ define('RECENTS_MEDIA_PAGES_MIXED', 32);
|
|||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
* @see htmlspecialchars()
|
||||
*
|
||||
* @param string $string the string being converted
|
||||
* @return string converted string
|
||||
*/
|
||||
function hsc($string) {
|
||||
return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
|
||||
|
@ -33,6 +36,9 @@ function hsc($string) {
|
|||
* You can give an indention as optional parameter
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $string line of text
|
||||
* @param int $indent number of spaces indention
|
||||
*/
|
||||
function ptln($string, $indent = 0) {
|
||||
echo str_repeat(' ', $indent)."$string\n";
|
||||
|
@ -42,6 +48,9 @@ function ptln($string, $indent = 0) {
|
|||
* strips control characters (<32) from the given string
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param $string string being stripped
|
||||
* @return string
|
||||
*/
|
||||
function stripctl($string) {
|
||||
return preg_replace('/[\x00-\x1F]+/s', '', $string);
|
||||
|
@ -56,15 +65,21 @@ function stripctl($string) {
|
|||
* @return string
|
||||
*/
|
||||
function getSecurityToken() {
|
||||
return PassHash::hmac('md5', session_id().$_SERVER['REMOTE_USER'], auth_cookiesalt());
|
||||
/** @var Input $INPUT */
|
||||
global $INPUT;
|
||||
return PassHash::hmac('md5', session_id().$INPUT->server->str('REMOTE_USER'), auth_cookiesalt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the secret CSRF token
|
||||
*
|
||||
* @param null|string $token security token or null to read it from request variable
|
||||
* @return bool success if the token matched
|
||||
*/
|
||||
function checkSecurityToken($token = null) {
|
||||
/** @var Input $INPUT */
|
||||
global $INPUT;
|
||||
if(empty($_SERVER['REMOTE_USER'])) return true; // no logged in user, no need for a check
|
||||
if(!$INPUT->server->str('REMOTE_USER')) return true; // no logged in user, no need for a check
|
||||
|
||||
if(is_null($token)) $token = $INPUT->str('sectok');
|
||||
if(getSecurityToken() != $token) {
|
||||
|
@ -78,6 +93,9 @@ function checkSecurityToken($token = null) {
|
|||
* Print a hidden form field with a secret CSRF token
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param bool $print if true print the field, otherwise html of the field is returned
|
||||
* @return void|string html of hidden form field
|
||||
*/
|
||||
function formSecurityToken($print = true) {
|
||||
$ret = '<div class="no"><input type="hidden" name="sectok" value="'.getSecurityToken().'" /></div>'."\n";
|
||||
|
@ -90,17 +108,24 @@ function formSecurityToken($print = true) {
|
|||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
* @author Chris Smith <chris@jalakai.co.uk>
|
||||
*
|
||||
* @param string $id pageid
|
||||
* @param bool $htmlClient add info about whether is mobile browser
|
||||
* @return array with info for a request of $id
|
||||
*
|
||||
*/
|
||||
function basicinfo($id, $htmlClient=true){
|
||||
global $USERINFO;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
// set info about manager/admin status.
|
||||
$info['isadmin'] = false;
|
||||
$info['ismanager'] = false;
|
||||
if(isset($_SERVER['REMOTE_USER'])) {
|
||||
if($INPUT->server->has('REMOTE_USER')) {
|
||||
$info['userinfo'] = $USERINFO;
|
||||
$info['perm'] = auth_quickaclcheck($id);
|
||||
$info['client'] = $_SERVER['REMOTE_USER'];
|
||||
$info['client'] = $INPUT->server->str('REMOTE_USER');
|
||||
|
||||
if($info['perm'] == AUTH_ADMIN) {
|
||||
$info['isadmin'] = true;
|
||||
|
@ -111,7 +136,7 @@ function basicinfo($id, $htmlClient=true){
|
|||
|
||||
// if some outside auth were used only REMOTE_USER is set
|
||||
if(!$info['userinfo']['name']) {
|
||||
$info['userinfo']['name'] = $_SERVER['REMOTE_USER'];
|
||||
$info['userinfo']['name'] = $INPUT->server->str('REMOTE_USER');
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -134,12 +159,16 @@ function basicinfo($id, $htmlClient=true){
|
|||
* array.
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @return array with info about current document
|
||||
*/
|
||||
function pageinfo() {
|
||||
global $ID;
|
||||
global $REV;
|
||||
global $RANGE;
|
||||
global $lang;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
$info = basicinfo($ID);
|
||||
|
||||
|
@ -148,19 +177,20 @@ function pageinfo() {
|
|||
$info['id'] = $ID;
|
||||
$info['rev'] = $REV;
|
||||
|
||||
if(isset($_SERVER['REMOTE_USER'])) {
|
||||
if($INPUT->server->has('REMOTE_USER')) {
|
||||
$sub = new Subscription();
|
||||
$info['subscribed'] = $sub->user_subscription();
|
||||
} else {
|
||||
$info['subscribed'] = false;
|
||||
}
|
||||
|
||||
$info['locked'] = checklock($ID);
|
||||
$info['filepath'] = fullpath(wikiFN($ID));
|
||||
$info['exists'] = @file_exists($info['filepath']);
|
||||
$info['locked'] = checklock($ID);
|
||||
$info['filepath'] = fullpath(wikiFN($ID));
|
||||
$info['exists'] = @file_exists($info['filepath']);
|
||||
$info['currentrev'] = @filemtime($info['filepath']);
|
||||
if($REV) {
|
||||
//check if current revision was meant
|
||||
if($info['exists'] && (@filemtime($info['filepath']) == $REV)) {
|
||||
if($info['exists'] && ($info['currentrev'] == $REV)) {
|
||||
$REV = '';
|
||||
} elseif($RANGE) {
|
||||
//section editing does not work with old revisions!
|
||||
|
@ -187,13 +217,14 @@ function pageinfo() {
|
|||
$info['meta'] = p_get_metadata($ID);
|
||||
|
||||
//who's the editor
|
||||
$pagelog = new PageChangeLog($ID, 1024);
|
||||
if($REV) {
|
||||
$revinfo = getRevisionInfo($ID, $REV, 1024);
|
||||
$revinfo = $pagelog->getRevisionInfo($REV);
|
||||
} else {
|
||||
if(is_array($info['meta']['last_change'])) {
|
||||
if(!empty($info['meta']['last_change']) && is_array($info['meta']['last_change'])) {
|
||||
$revinfo = $info['meta']['last_change'];
|
||||
} else {
|
||||
$revinfo = getRevisionInfo($ID, $info['lastmod'], 1024);
|
||||
$revinfo = $pagelog->getRevisionInfo($info['lastmod']);
|
||||
// cache most recent changelog line in metadata if missing and still valid
|
||||
if($revinfo !== false) {
|
||||
$info['meta']['last_change'] = $revinfo;
|
||||
|
@ -237,6 +268,8 @@ function pageinfo() {
|
|||
|
||||
/**
|
||||
* Return information about the current media item as an associative array.
|
||||
*
|
||||
* @return array with info about current media item
|
||||
*/
|
||||
function mediainfo(){
|
||||
global $NS;
|
||||
|
@ -252,6 +285,10 @@ function mediainfo(){
|
|||
* Build an string of URL parameters
|
||||
*
|
||||
* @author Andreas Gohr
|
||||
*
|
||||
* @param array $params array with key-value pairs
|
||||
* @param string $sep series of pairs are separated by this character
|
||||
* @return string query string
|
||||
*/
|
||||
function buildURLparams($params, $sep = '&') {
|
||||
$url = '';
|
||||
|
@ -272,6 +309,10 @@ function buildURLparams($params, $sep = '&') {
|
|||
* Skips keys starting with '_', values get HTML encoded
|
||||
*
|
||||
* @author Andreas Gohr
|
||||
*
|
||||
* @param array $params array with (attribute name-attribute value) pairs
|
||||
* @param bool $skipempty skip empty string values?
|
||||
* @return string
|
||||
*/
|
||||
function buildAttributes($params, $skipempty = false) {
|
||||
$url = '';
|
||||
|
@ -293,6 +334,8 @@ function buildAttributes($params, $skipempty = false) {
|
|||
* This builds the breadcrumb trail and returns it as array
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @return array(pageid=>name, ... )
|
||||
*/
|
||||
function breadcrumbs() {
|
||||
// we prepare the breadcrumbs early for quick session closing
|
||||
|
@ -352,14 +395,21 @@ function breadcrumbs() {
|
|||
* Urlencoding is ommitted when the second parameter is false
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $id pageid being filtered
|
||||
* @param bool $ue apply urlencoding?
|
||||
* @return string
|
||||
*/
|
||||
function idfilter($id, $ue = true) {
|
||||
global $conf;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
if($conf['useslash'] && $conf['userewrite']) {
|
||||
$id = strtr($id, ':', '/');
|
||||
} elseif(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' &&
|
||||
$conf['userewrite'] &&
|
||||
strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') === false
|
||||
strpos($INPUT->server->str('SERVER_SOFTWARE'), 'Microsoft-IIS') === false
|
||||
) {
|
||||
$id = strtr($id, ':', ';');
|
||||
}
|
||||
|
@ -374,10 +424,15 @@ function idfilter($id, $ue = true) {
|
|||
/**
|
||||
* This builds a link to a wikipage
|
||||
*
|
||||
* It handles URL rewriting and adds additional parameter if
|
||||
* given in $more
|
||||
* It handles URL rewriting and adds additional parameters
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $id page id, defaults to start page
|
||||
* @param string|array $urlParameters URL parameters, associative array recommended
|
||||
* @param bool $absolute request an absolute URL instead of relative
|
||||
* @param string $separator parameter separator
|
||||
* @return string
|
||||
*/
|
||||
function wl($id = '', $urlParameters = '', $absolute = false, $separator = '&') {
|
||||
global $conf;
|
||||
|
@ -419,13 +474,19 @@ function wl($id = '', $urlParameters = '', $absolute = false, $separator = '&
|
|||
* Handles URL rewriting if enabled. Follows the style of wl().
|
||||
*
|
||||
* @author Ben Coburn <btcoburn@silicodon.net>
|
||||
* @param string $id page id, defaults to start page
|
||||
* @param string $format the export renderer to use
|
||||
* @param string|array $urlParameters URL parameters, associative array recommended
|
||||
* @param bool $abs request an absolute URL instead of relative
|
||||
* @param string $sep parameter separator
|
||||
* @return string
|
||||
*/
|
||||
function exportlink($id = '', $format = 'raw', $more = '', $abs = false, $sep = '&') {
|
||||
function exportlink($id = '', $format = 'raw', $urlParameters = '', $abs = false, $sep = '&') {
|
||||
global $conf;
|
||||
if(is_array($more)) {
|
||||
$more = buildURLparams($more, $sep);
|
||||
if(is_array($urlParameters)) {
|
||||
$urlParameters = buildURLparams($urlParameters, $sep);
|
||||
} else {
|
||||
$more = str_replace(',', $sep, $more);
|
||||
$urlParameters = str_replace(',', $sep, $urlParameters);
|
||||
}
|
||||
|
||||
$format = rawurlencode($format);
|
||||
|
@ -438,13 +499,13 @@ function exportlink($id = '', $format = 'raw', $more = '', $abs = false, $sep =
|
|||
|
||||
if($conf['userewrite'] == 2) {
|
||||
$xlink .= DOKU_SCRIPT.'/'.$id.'?do=export_'.$format;
|
||||
if($more) $xlink .= $sep.$more;
|
||||
if($urlParameters) $xlink .= $sep.$urlParameters;
|
||||
} elseif($conf['userewrite'] == 1) {
|
||||
$xlink .= '_export/'.$format.'/'.$id;
|
||||
if($more) $xlink .= '?'.$more;
|
||||
if($urlParameters) $xlink .= '?'.$urlParameters;
|
||||
} else {
|
||||
$xlink .= DOKU_SCRIPT.'?do=export_'.$format.$sep.'id='.$id;
|
||||
if($more) $xlink .= $sep.$more;
|
||||
if($urlParameters) $xlink .= $sep.$urlParameters;
|
||||
}
|
||||
|
||||
return $xlink;
|
||||
|
@ -551,6 +612,8 @@ function ml($id = '', $more = '', $direct = true, $sep = '&', $abs = false)
|
|||
* Consider using wl() instead, unless you absoutely need the doku.php endpoint
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function script() {
|
||||
return DOKU_BASE.DOKU_SCRIPT;
|
||||
|
@ -577,6 +640,7 @@ function script() {
|
|||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
* @author Michael Klier <chi@chimeric.de>
|
||||
*
|
||||
* @param string $text - optional text to check, if not given the globals are used
|
||||
* @return bool - true if a spam word was found
|
||||
*/
|
||||
|
@ -587,6 +651,8 @@ function checkwordblock($text = '') {
|
|||
global $SUM;
|
||||
global $conf;
|
||||
global $INFO;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
if(!$conf['usewordblock']) return false;
|
||||
|
||||
|
@ -619,9 +685,9 @@ function checkwordblock($text = '') {
|
|||
if(count($re) && preg_match('#('.join('|', $re).')#si', $text, $matches)) {
|
||||
// prepare event data
|
||||
$data['matches'] = $matches;
|
||||
$data['userinfo']['ip'] = $_SERVER['REMOTE_ADDR'];
|
||||
if($_SERVER['REMOTE_USER']) {
|
||||
$data['userinfo']['user'] = $_SERVER['REMOTE_USER'];
|
||||
$data['userinfo']['ip'] = $INPUT->server->str('REMOTE_ADDR');
|
||||
if($INPUT->server->str('REMOTE_USER')) {
|
||||
$data['userinfo']['user'] = $INPUT->server->str('REMOTE_USER');
|
||||
$data['userinfo']['name'] = $INFO['userinfo']['name'];
|
||||
$data['userinfo']['mail'] = $INFO['userinfo']['mail'];
|
||||
}
|
||||
|
@ -643,16 +709,22 @@ function checkwordblock($text = '') {
|
|||
* headers
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param boolean $single If set only a single IP is returned
|
||||
* @return string
|
||||
*/
|
||||
function clientIP($single = false) {
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
$ip = array();
|
||||
$ip[] = $_SERVER['REMOTE_ADDR'];
|
||||
if(!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
|
||||
$ip = array_merge($ip, explode(',', str_replace(' ', '', $_SERVER['HTTP_X_FORWARDED_FOR'])));
|
||||
if(!empty($_SERVER['HTTP_X_REAL_IP']))
|
||||
$ip = array_merge($ip, explode(',', str_replace(' ', '', $_SERVER['HTTP_X_REAL_IP'])));
|
||||
$ip[] = $INPUT->server->str('REMOTE_ADDR');
|
||||
if($INPUT->server->str('HTTP_X_FORWARDED_FOR')) {
|
||||
$ip = array_merge($ip, explode(',', str_replace(' ', '', $INPUT->server->str('HTTP_X_FORWARDED_FOR'))));
|
||||
}
|
||||
if($INPUT->server->str('HTTP_X_REAL_IP')) {
|
||||
$ip = array_merge($ip, explode(',', str_replace(' ', '', $INPUT->server->str('HTTP_X_REAL_IP'))));
|
||||
}
|
||||
|
||||
// some IPv4/v6 regexps borrowed from Feyd
|
||||
// see: http://forums.devnetwork.net/viewtopic.php?f=38&t=53479
|
||||
|
@ -709,18 +781,22 @@ function clientIP($single = false) {
|
|||
* Adapted from the example code at url below
|
||||
*
|
||||
* @link http://www.brainhandles.com/2007/10/15/detecting-mobile-browsers/#code
|
||||
*
|
||||
* @return bool if true, client is mobile browser; otherwise false
|
||||
*/
|
||||
function clientismobile() {
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
if(isset($_SERVER['HTTP_X_WAP_PROFILE'])) return true;
|
||||
if($INPUT->server->has('HTTP_X_WAP_PROFILE')) return true;
|
||||
|
||||
if(preg_match('/wap\.|\.wap/i', $_SERVER['HTTP_ACCEPT'])) return true;
|
||||
if(preg_match('/wap\.|\.wap/i', $INPUT->server->str('HTTP_ACCEPT'))) return true;
|
||||
|
||||
if(!isset($_SERVER['HTTP_USER_AGENT'])) return false;
|
||||
if(!$INPUT->server->has('HTTP_USER_AGENT')) return false;
|
||||
|
||||
$uamatches = 'midp|j2me|avantg|docomo|novarra|palmos|palmsource|240x320|opwv|chtml|pda|windows ce|mmp\/|blackberry|mib\/|symbian|wireless|nokia|hand|mobi|phone|cdm|up\.b|audio|SIE\-|SEC\-|samsung|HTC|mot\-|mitsu|sagem|sony|alcatel|lg|erics|vx|NEC|philips|mmm|xx|panasonic|sharp|wap|sch|rover|pocket|benq|java|pt|pg|vox|amoi|bird|compal|kg|voda|sany|kdd|dbt|sendo|sgh|gradi|jb|\d\d\di|moto';
|
||||
|
||||
if(preg_match("/$uamatches/i", $_SERVER['HTTP_USER_AGENT'])) return true;
|
||||
if(preg_match("/$uamatches/i", $INPUT->server->str('HTTP_USER_AGENT'))) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -731,6 +807,7 @@ function clientismobile() {
|
|||
* If $conf['dnslookups'] is disabled it simply returns the input string
|
||||
*
|
||||
* @author Glen Harris <astfgl@iamnota.org>
|
||||
*
|
||||
* @param string $ips comma separated list of IP addresses
|
||||
* @return string a comma separated list of hostnames
|
||||
*/
|
||||
|
@ -757,9 +834,15 @@ function gethostsbyaddrs($ips) {
|
|||
* removes stale lockfiles
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $id page id
|
||||
* @return bool page is locked?
|
||||
*/
|
||||
function checklock($id) {
|
||||
global $conf;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
$lock = wikiLockFN($id);
|
||||
|
||||
//no lockfile
|
||||
|
@ -772,8 +855,8 @@ function checklock($id) {
|
|||
}
|
||||
|
||||
//my own lock
|
||||
list($ip, $session) = explode("\n", io_readFile($lock));
|
||||
if($ip == $_SERVER['REMOTE_USER'] || $ip == clientIP() || $session == session_id()) {
|
||||
@list($ip, $session) = explode("\n", io_readFile($lock));
|
||||
if($ip == $INPUT->server->str('REMOTE_USER') || $ip == clientIP() || (session_id() && $session == session_id())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -784,17 +867,21 @@ function checklock($id) {
|
|||
* Lock a page for editing
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $id page id to lock
|
||||
*/
|
||||
function lock($id) {
|
||||
global $conf;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
if($conf['locktime'] == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$lock = wikiLockFN($id);
|
||||
if($_SERVER['REMOTE_USER']) {
|
||||
io_saveFile($lock, $_SERVER['REMOTE_USER']);
|
||||
if($INPUT->server->str('REMOTE_USER')) {
|
||||
io_saveFile($lock, $INPUT->server->str('REMOTE_USER'));
|
||||
} else {
|
||||
io_saveFile($lock, clientIP()."\n".session_id());
|
||||
}
|
||||
|
@ -804,14 +891,18 @@ function lock($id) {
|
|||
* Unlock a page if it was locked by the user
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $id page id to unlock
|
||||
* @return bool true if a lock was removed
|
||||
*/
|
||||
function unlock($id) {
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
$lock = wikiLockFN($id);
|
||||
if(@file_exists($lock)) {
|
||||
list($ip, $session) = explode("\n", io_readFile($lock));
|
||||
if($ip == $_SERVER['REMOTE_USER'] || $ip == clientIP() || $session == session_id()) {
|
||||
@list($ip, $session) = explode("\n", io_readFile($lock));
|
||||
if($ip == $INPUT->server->str('REMOTE_USER') || $ip == clientIP() || $session == session_id()) {
|
||||
@unlink($lock);
|
||||
return true;
|
||||
}
|
||||
|
@ -826,6 +917,9 @@ function unlock($id) {
|
|||
*
|
||||
* @see formText() for 2crlf conversion
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
function cleanText($text) {
|
||||
$text = preg_replace("/(\015\012)|(\015)/", "\012", $text);
|
||||
|
@ -845,6 +939,9 @@ function cleanText($text) {
|
|||
*
|
||||
* @see cleanText() for 2unix conversion
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
function formText($text) {
|
||||
$text = str_replace("\012", "\015\012", $text);
|
||||
|
@ -855,6 +952,10 @@ function formText($text) {
|
|||
* Returns the specified local text in raw format
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $id page id
|
||||
* @param string $ext extension of file being read, default 'txt'
|
||||
* @return string
|
||||
*/
|
||||
function rawLocale($id, $ext = 'txt') {
|
||||
return io_readFile(localeFN($id, $ext));
|
||||
|
@ -864,6 +965,10 @@ function rawLocale($id, $ext = 'txt') {
|
|||
* Returns the raw WikiText
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $id page id
|
||||
* @param string $rev timestamp when a revision of wikitext is desired
|
||||
* @return string
|
||||
*/
|
||||
function rawWiki($id, $rev = '') {
|
||||
return io_readWikiPage(wikiFN($id, $rev), $id, $rev);
|
||||
|
@ -874,6 +979,9 @@ function rawWiki($id, $rev = '') {
|
|||
*
|
||||
* @triggers COMMON_PAGETPL_LOAD
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $id the id of the page to be created
|
||||
* @return string parsed pagetemplate content
|
||||
*/
|
||||
function pageTemplate($id) {
|
||||
global $conf;
|
||||
|
@ -925,6 +1033,9 @@ function pageTemplate($id) {
|
|||
* This works on data from COMMON_PAGETPL_LOAD
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param array $data array with event data
|
||||
* @return string
|
||||
*/
|
||||
function parsePageTemplate(&$data) {
|
||||
/**
|
||||
|
@ -937,6 +1048,8 @@ function parsePageTemplate(&$data) {
|
|||
|
||||
global $USERINFO;
|
||||
global $conf;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
// replace placeholders
|
||||
$file = noNS($id);
|
||||
|
@ -968,7 +1081,7 @@ function parsePageTemplate(&$data) {
|
|||
utf8_ucfirst($page),
|
||||
utf8_ucwords($page),
|
||||
utf8_strtoupper($page),
|
||||
$_SERVER['REMOTE_USER'],
|
||||
$INPUT->server->str('REMOTE_USER'),
|
||||
$USERINFO['name'],
|
||||
$USERINFO['mail'],
|
||||
$conf['dformat'],
|
||||
|
@ -990,6 +1103,11 @@ function parsePageTemplate(&$data) {
|
|||
* The returned order is prefix, section and suffix.
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $range in form "from-to"
|
||||
* @param string $id page id
|
||||
* @param string $rev optional, the revision timestamp
|
||||
* @return array with three slices
|
||||
*/
|
||||
function rawWikiSlices($range, $id, $rev = '') {
|
||||
$text = io_readWikiPage(wikiFN($id, $rev), $id, $rev);
|
||||
|
@ -1014,6 +1132,12 @@ function rawWikiSlices($range, $id, $rev = '') {
|
|||
* lines between sections if needed (used on saving).
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $pre prefix
|
||||
* @param string $text text in the middle
|
||||
* @param string $suf suffix
|
||||
* @param bool $pretty add additional empty lines between sections
|
||||
* @return string
|
||||
*/
|
||||
function con($pre, $text, $suf, $pretty = false) {
|
||||
if($pretty) {
|
||||
|
@ -1038,6 +1162,11 @@ function con($pre, $text, $suf, $pretty = false) {
|
|||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
* @author Ben Coburn <btcoburn@silicodon.net>
|
||||
*
|
||||
* @param string $id page id
|
||||
* @param string $text wikitext being saved
|
||||
* @param string $summary summary of text update
|
||||
* @param bool $minor mark this saved version as minor update
|
||||
*/
|
||||
function saveWikiText($id, $text, $summary, $minor = false) {
|
||||
/* Note to developers:
|
||||
|
@ -1049,6 +1178,9 @@ function saveWikiText($id, $text, $summary, $minor = false) {
|
|||
global $conf;
|
||||
global $lang;
|
||||
global $REV;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
// ignore if no changes were made
|
||||
if($text == rawWiki($id, '')) {
|
||||
return;
|
||||
|
@ -1059,8 +1191,9 @@ function saveWikiText($id, $text, $summary, $minor = false) {
|
|||
$wasRemoved = (trim($text) == ''); // check for empty or whitespace only
|
||||
$wasCreated = !@file_exists($file);
|
||||
$wasReverted = ($REV == true);
|
||||
$pagelog = new PageChangeLog($id, 1024);
|
||||
$newRev = false;
|
||||
$oldRev = getRevisions($id, -1, 1, 1024); // from changelog
|
||||
$oldRev = $pagelog->getRevisions(-1, 1); // from changelog
|
||||
$oldRev = (int) (empty($oldRev) ? 0 : $oldRev[0]);
|
||||
if(!@file_exists(wikiFN($id, $old)) && @file_exists($file) && $old >= $oldRev) {
|
||||
// add old revision to the attic if missing
|
||||
|
@ -1111,7 +1244,7 @@ function saveWikiText($id, $text, $summary, $minor = false) {
|
|||
$type = DOKU_CHANGE_TYPE_CREATE;
|
||||
} else if($wasRemoved) {
|
||||
$type = DOKU_CHANGE_TYPE_DELETE;
|
||||
} else if($minor && $conf['useacl'] && $_SERVER['REMOTE_USER']) {
|
||||
} else if($minor && $conf['useacl'] && $INPUT->server->str('REMOTE_USER')) {
|
||||
$type = DOKU_CHANGE_TYPE_MINOR_EDIT;
|
||||
} //minor edits only for logged in users
|
||||
|
||||
|
@ -1138,9 +1271,11 @@ function saveWikiText($id, $text, $summary, $minor = false) {
|
|||
* revision date
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $id page id
|
||||
* @return int|string revision timestamp
|
||||
*/
|
||||
function saveOldRevision($id) {
|
||||
global $conf;
|
||||
$oldf = wikiFN($id);
|
||||
if(!@file_exists($oldf)) return '';
|
||||
$date = filemtime($oldf);
|
||||
|
@ -1158,12 +1293,14 @@ function saveOldRevision($id) {
|
|||
* @param string $summary What changed
|
||||
* @param boolean $minor Is this a minor edit?
|
||||
* @param array $replace Additional string substitutions, @KEY@ to be replaced by value
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*/
|
||||
function notify($id, $who, $rev = '', $summary = '', $minor = false, $replace = array()) {
|
||||
global $conf;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
// decide if there is something to do, eg. whom to mail
|
||||
if($who == 'admin') {
|
||||
|
@ -1172,8 +1309,8 @@ function notify($id, $who, $rev = '', $summary = '', $minor = false, $replace =
|
|||
$to = $conf['notify'];
|
||||
} elseif($who == 'subscribers') {
|
||||
if(!actionOK('subscribe')) return false; //subscribers enabled?
|
||||
if($conf['useacl'] && $_SERVER['REMOTE_USER'] && $minor) return false; //skip minors
|
||||
$data = array('id' => $id, 'addresslist' => '', 'self' => false);
|
||||
if($conf['useacl'] && $INPUT->server->str('REMOTE_USER') && $minor) return false; //skip minors
|
||||
$data = array('id' => $id, 'addresslist' => '', 'self' => false, 'replacements' => $replace);
|
||||
trigger_event(
|
||||
'COMMON_NOTIFY_ADDRESSLIST', $data,
|
||||
array(new Subscription(), 'notifyaddresses')
|
||||
|
@ -1195,12 +1332,17 @@ function notify($id, $who, $rev = '', $summary = '', $minor = false, $replace =
|
|||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
* @author Todd Augsburger <todd@rollerorgans.com>
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
function getGoogleQuery() {
|
||||
if(!isset($_SERVER['HTTP_REFERER'])) {
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
if(!$INPUT->server->has('HTTP_REFERER')) {
|
||||
return '';
|
||||
}
|
||||
$url = parse_url($_SERVER['HTTP_REFERER']);
|
||||
$url = parse_url($INPUT->server->str('HTTP_REFERER'));
|
||||
|
||||
// only handle common SEs
|
||||
if(!preg_match('/(google|bing|yahoo|ask|duckduckgo|babylon|aol|yandex)/',$url['host'])) return '';
|
||||
|
@ -1230,8 +1372,10 @@ function getGoogleQuery() {
|
|||
/**
|
||||
* Return the human readable size of a file
|
||||
*
|
||||
* @param int $size A file size
|
||||
* @param int $dec A number of decimal places
|
||||
* @param int $size A file size
|
||||
* @param int $dec A number of decimal places
|
||||
* @return string human readable size
|
||||
*
|
||||
* @author Martin Benjamin <b.martin@cybernet.ch>
|
||||
* @author Aidan Lister <aidan@php.net>
|
||||
* @version 1.0.0
|
||||
|
@ -1253,6 +1397,9 @@ function filesize_h($size, $dec = 1) {
|
|||
* Return the given timestamp as human readable, fuzzy age
|
||||
*
|
||||
* @author Andreas Gohr <gohr@cosmocode.de>
|
||||
*
|
||||
* @param int $dt timestamp
|
||||
* @return string
|
||||
*/
|
||||
function datetime_h($dt) {
|
||||
global $lang;
|
||||
|
@ -1287,6 +1434,10 @@ function datetime_h($dt) {
|
|||
*
|
||||
* @see datetime_h
|
||||
* @author Andreas Gohr <gohr@cosmocode.de>
|
||||
*
|
||||
* @param int|null $dt timestamp when given, null will take current timestamp
|
||||
* @param string $format empty default to $conf['dformat'], or provide format as recognized by strftime()
|
||||
* @return string
|
||||
*/
|
||||
function dformat($dt = null, $format = '') {
|
||||
global $conf;
|
||||
|
@ -1304,6 +1455,7 @@ function dformat($dt = null, $format = '') {
|
|||
*
|
||||
* @author <ungu at terong dot com>
|
||||
* @link http://www.php.net/manual/en/function.date.php#54072
|
||||
*
|
||||
* @param int $int_date: current date in UNIX timestamp
|
||||
* @return string
|
||||
*/
|
||||
|
@ -1320,6 +1472,9 @@ function date_iso8601($int_date) {
|
|||
*
|
||||
* @author Harry Fuecks <hfuecks@gmail.com>
|
||||
* @author Christopher Smith <chris@jalakai.co.uk>
|
||||
*
|
||||
* @param string $email email address
|
||||
* @return string
|
||||
*/
|
||||
function obfuscate($email) {
|
||||
global $conf;
|
||||
|
@ -1347,6 +1502,10 @@ function obfuscate($email) {
|
|||
* Removes quoting backslashes
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $char backslashed character
|
||||
* @return string
|
||||
*/
|
||||
function unslash($string, $char = "'") {
|
||||
return str_replace('\\'.$char, $char, $string);
|
||||
|
@ -1357,19 +1516,27 @@ function unslash($string, $char = "'") {
|
|||
*
|
||||
* @author <gilthans dot NO dot SPAM at gmail dot com>
|
||||
* @link http://de3.php.net/manual/en/ini.core.php#79564
|
||||
*
|
||||
* @param string $v shorthands
|
||||
* @return int|string
|
||||
*/
|
||||
function php_to_byte($v) {
|
||||
$l = substr($v, -1);
|
||||
$ret = substr($v, 0, -1);
|
||||
switch(strtoupper($l)) {
|
||||
/** @noinspection PhpMissingBreakStatementInspection */
|
||||
case 'P':
|
||||
$ret *= 1024;
|
||||
/** @noinspection PhpMissingBreakStatementInspection */
|
||||
case 'T':
|
||||
$ret *= 1024;
|
||||
/** @noinspection PhpMissingBreakStatementInspection */
|
||||
case 'G':
|
||||
$ret *= 1024;
|
||||
/** @noinspection PhpMissingBreakStatementInspection */
|
||||
case 'M':
|
||||
$ret *= 1024;
|
||||
/** @noinspection PhpMissingBreakStatementInspection */
|
||||
case 'K':
|
||||
$ret *= 1024;
|
||||
break;
|
||||
|
@ -1382,6 +1549,9 @@ function php_to_byte($v) {
|
|||
|
||||
/**
|
||||
* Wrapper around preg_quote adding the default delimiter
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
function preg_quote_cb($string) {
|
||||
return preg_quote($string, '/');
|
||||
|
@ -1415,37 +1585,135 @@ function shorten($keep, $short, $max, $min = 9, $char = '…') {
|
|||
* Return the users realname or e-mail address for use
|
||||
* in page footer and recent changes pages
|
||||
*
|
||||
* @param string|null $username or null when currently logged-in user should be used
|
||||
* @param bool $textonly true returns only plain text, true allows returning html
|
||||
* @return string html or plain text(not escaped) of formatted user name
|
||||
*
|
||||
* @author Andy Webber <dokuwiki AT andywebber DOT com>
|
||||
*/
|
||||
function editorinfo($username) {
|
||||
global $conf;
|
||||
function editorinfo($username, $textonly = false) {
|
||||
return userlink($username, $textonly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns users realname w/o link
|
||||
*
|
||||
* @param string|null $username or null when currently logged-in user should be used
|
||||
* @param bool $textonly true returns only plain text, true allows returning html
|
||||
* @return string html or plain text(not escaped) of formatted user name
|
||||
*
|
||||
* @triggers COMMON_USER_LINK
|
||||
*/
|
||||
function userlink($username = null, $textonly = false) {
|
||||
global $conf, $INFO;
|
||||
/** @var DokuWiki_Auth_Plugin $auth */
|
||||
global $auth;
|
||||
/** @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
switch($conf['showuseras']) {
|
||||
case 'username':
|
||||
case 'email':
|
||||
case 'email_link':
|
||||
if($auth) $info = $auth->getUserData($username);
|
||||
break;
|
||||
default:
|
||||
return hsc($username);
|
||||
}
|
||||
|
||||
if(isset($info) && $info) {
|
||||
switch($conf['showuseras']) {
|
||||
case 'username':
|
||||
return hsc($info['name']);
|
||||
case 'email':
|
||||
return obfuscate($info['mail']);
|
||||
case 'email_link':
|
||||
$mail = obfuscate($info['mail']);
|
||||
return '<a href="mailto:'.$mail.'">'.$mail.'</a>';
|
||||
default:
|
||||
return hsc($username);
|
||||
// prepare initial event data
|
||||
$data = array(
|
||||
'username' => $username, // the unique user name
|
||||
'name' => '',
|
||||
'link' => array( //setting 'link' to false disables linking
|
||||
'target' => '',
|
||||
'pre' => '',
|
||||
'suf' => '',
|
||||
'style' => '',
|
||||
'more' => '',
|
||||
'url' => '',
|
||||
'title' => '',
|
||||
'class' => ''
|
||||
),
|
||||
'userlink' => '', // formatted user name as will be returned
|
||||
'textonly' => $textonly
|
||||
);
|
||||
if($username === null) {
|
||||
$data['username'] = $username = $INPUT->server->str('REMOTE_USER');
|
||||
if($textonly){
|
||||
$data['name'] = $INFO['userinfo']['name']. ' (' . $INPUT->server->str('REMOTE_USER') . ')';
|
||||
}else {
|
||||
$data['name'] = '<bdi>' . hsc($INFO['userinfo']['name']) . '</bdi> (<bdi>' . hsc($INPUT->server->str('REMOTE_USER')) . '</bdi>)';
|
||||
}
|
||||
} else {
|
||||
return hsc($username);
|
||||
}
|
||||
|
||||
$evt = new Doku_Event('COMMON_USER_LINK', $data);
|
||||
if($evt->advise_before(true)) {
|
||||
if(empty($data['name'])) {
|
||||
if($conf['showuseras'] == 'loginname') {
|
||||
$data['name'] = $textonly ? $data['username'] : hsc($data['username']);
|
||||
} else {
|
||||
if($auth) $info = $auth->getUserData($username);
|
||||
if(isset($info) && $info) {
|
||||
switch($conf['showuseras']) {
|
||||
case 'username':
|
||||
case 'username_link':
|
||||
$data['name'] = $textonly ? $info['name'] : hsc($info['name']);
|
||||
break;
|
||||
case 'email':
|
||||
case 'email_link':
|
||||
$data['name'] = obfuscate($info['mail']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @var Doku_Renderer_xhtml $xhtml_renderer */
|
||||
static $xhtml_renderer = null;
|
||||
|
||||
if(!$data['textonly'] && empty($data['link']['url'])) {
|
||||
|
||||
if(in_array($conf['showuseras'], array('email_link', 'username_link'))) {
|
||||
if(!isset($info)) {
|
||||
if($auth) $info = $auth->getUserData($username);
|
||||
}
|
||||
if(isset($info) && $info) {
|
||||
if($conf['showuseras'] == 'email_link') {
|
||||
$data['link']['url'] = 'mailto:' . obfuscate($info['mail']);
|
||||
} else {
|
||||
if(is_null($xhtml_renderer)) {
|
||||
$xhtml_renderer = p_get_renderer('xhtml');
|
||||
}
|
||||
if(empty($xhtml_renderer->interwiki)) {
|
||||
$xhtml_renderer->interwiki = getInterwiki();
|
||||
}
|
||||
$shortcut = 'user';
|
||||
$exists = null;
|
||||
$data['link']['url'] = $xhtml_renderer->_resolveInterWiki($shortcut, $username, $exists);
|
||||
$data['link']['class'] .= ' interwiki iw_user';
|
||||
if($exists !== null) {
|
||||
if($exists) {
|
||||
$data['link']['class'] .= ' wikilink1';
|
||||
} else {
|
||||
$data['link']['class'] .= ' wikilink2';
|
||||
$data['link']['rel'] = 'nofollow';
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$data['textonly'] = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
$data['textonly'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if($data['textonly']) {
|
||||
$data['userlink'] = $data['name'];
|
||||
} else {
|
||||
$data['link']['name'] = $data['name'];
|
||||
if(is_null($xhtml_renderer)) {
|
||||
$xhtml_renderer = p_get_renderer('xhtml');
|
||||
}
|
||||
$data['userlink'] = $xhtml_renderer->_formatLink($data['link']);
|
||||
}
|
||||
}
|
||||
$evt->advise_after();
|
||||
unset($evt);
|
||||
|
||||
return $data['userlink'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1453,6 +1721,7 @@ function editorinfo($username) {
|
|||
* When no image exists, returns an empty string
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $type - type of image 'badge' or 'button'
|
||||
* @return string
|
||||
*/
|
||||
|
@ -1461,7 +1730,6 @@ function license_img($type) {
|
|||
global $conf;
|
||||
if(!$conf['license']) return '';
|
||||
if(!is_array($license[$conf['license']])) return '';
|
||||
$lic = $license[$conf['license']];
|
||||
$try = array();
|
||||
$try[] = 'lib/images/license/'.$type.'/'.$conf['license'].'.png';
|
||||
$try[] = 'lib/images/license/'.$type.'/'.$conf['license'].'.gif';
|
||||
|
@ -1483,9 +1751,8 @@ function license_img($type) {
|
|||
* @author Filip Oscadal <webmaster@illusionsoftworks.cz>
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param int $mem Size of memory you want to allocate in bytes
|
||||
* @param int $bytes
|
||||
* @internal param int $used already allocated memory (see above)
|
||||
* @param int $mem Size of memory you want to allocate in bytes
|
||||
* @param int $bytes already allocated memory (see above)
|
||||
* @return bool
|
||||
*/
|
||||
function is_mem_available($mem, $bytes = 1048576) {
|
||||
|
@ -1516,8 +1783,13 @@ function is_mem_available($mem, $bytes = 1048576) {
|
|||
*
|
||||
* @link http://support.microsoft.com/kb/q176113/
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string $url url being directed to
|
||||
*/
|
||||
function send_redirect($url) {
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
//are there any undisplayed messages? keep them in session for display
|
||||
global $MSG;
|
||||
if(isset($MSG) && count($MSG) && !defined('NOSESSION')) {
|
||||
|
@ -1531,7 +1803,7 @@ function send_redirect($url) {
|
|||
|
||||
// work around IE bug
|
||||
// http://www.ianhoar.com/2008/11/16/internet-explorer-6-and-redirected-anchor-links/
|
||||
list($url, $hash) = explode('#', $url);
|
||||
@list($url, $hash) = explode('#', $url);
|
||||
if($hash) {
|
||||
if(strpos($url, '?')) {
|
||||
$url = $url.'&#'.$hash;
|
||||
|
@ -1541,9 +1813,9 @@ function send_redirect($url) {
|
|||
}
|
||||
|
||||
// check if running on IIS < 6 with CGI-PHP
|
||||
if(isset($_SERVER['SERVER_SOFTWARE']) && isset($_SERVER['GATEWAY_INTERFACE']) &&
|
||||
(strpos($_SERVER['GATEWAY_INTERFACE'], 'CGI') !== false) &&
|
||||
(preg_match('|^Microsoft-IIS/(\d)\.\d$|', trim($_SERVER['SERVER_SOFTWARE']), $matches)) &&
|
||||
if($INPUT->server->has('SERVER_SOFTWARE') && $INPUT->server->has('GATEWAY_INTERFACE') &&
|
||||
(strpos($INPUT->server->str('GATEWAY_INTERFACE'), 'CGI') !== false) &&
|
||||
(preg_match('|^Microsoft-IIS/(\d)\.\d$|', trim($INPUT->server->str('SERVER_SOFTWARE')), $matches)) &&
|
||||
$matches[1] < 6
|
||||
) {
|
||||
header('Refresh: 0;url='.$url);
|
||||
|
@ -1584,6 +1856,10 @@ function valid_input_set($param, $valid_values, $array, $exc = '') {
|
|||
/**
|
||||
* Read a preference from the DokuWiki cookie
|
||||
* (remembering both keys & values are urlencoded)
|
||||
*
|
||||
* @param string $pref preference key
|
||||
* @param mixed $default value returned when preference not found
|
||||
* @return string preference value
|
||||
*/
|
||||
function get_doku_pref($pref, $default) {
|
||||
$enc_pref = urlencode($pref);
|
||||
|
@ -1602,6 +1878,9 @@ function get_doku_pref($pref, $default) {
|
|||
/**
|
||||
* Add a preference to the DokuWiki cookie
|
||||
* (remembering $_COOKIE['DOKU_PREFS'] is urlencoded)
|
||||
*
|
||||
* @param string $pref preference key
|
||||
* @param string $val preference value
|
||||
*/
|
||||
function set_doku_pref($pref, $val) {
|
||||
global $conf;
|
||||
|
@ -1630,4 +1909,13 @@ function set_doku_pref($pref, $val) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips source mapping declarations from given text #601
|
||||
*
|
||||
* @param &string $text reference to the CSS or JavaScript code to clean
|
||||
*/
|
||||
function stripsourcemaps(&$text){
|
||||
$text = preg_replace('/^(\/\/|\/\*)[@#]\s+sourceMappingURL=.*?(\*\/)?$/im', '\\1\\2', $text);
|
||||
}
|
||||
|
||||
//Setup VIM: ex: et ts=2 :
|
||||
|
|
|
@ -237,13 +237,14 @@ function getConfigFiles($type) {
|
|||
* check if the given action was disabled in config
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
* @param string $action
|
||||
* @returns boolean true if enabled, false if disabled
|
||||
*/
|
||||
function actionOK($action){
|
||||
static $disabled = null;
|
||||
if(is_null($disabled) || defined('SIMPLE_TEST')){
|
||||
global $conf;
|
||||
/** @var auth_basic $auth */
|
||||
/** @var DokuWiki_Auth_Plugin $auth */
|
||||
global $auth;
|
||||
|
||||
// prepare disabled actions array and handle legacy options
|
||||
|
|
|
@ -8,15 +8,18 @@
|
|||
|
||||
if(!defined('DOKU_INC')) die('meh.');
|
||||
|
||||
/**
|
||||
* The event
|
||||
*/
|
||||
class Doku_Event {
|
||||
|
||||
// public properties
|
||||
var $name = ''; // READONLY event name, objects must register against this name to see the event
|
||||
var $data = null; // READWRITE data relevant to the event, no standardised format (YET!)
|
||||
var $result = null; // READWRITE the results of the event action, only relevant in "_AFTER" advise
|
||||
public $name = ''; // READONLY event name, objects must register against this name to see the event
|
||||
public $data = null; // READWRITE data relevant to the event, no standardised format (YET!)
|
||||
public $result = null; // READWRITE the results of the event action, only relevant in "_AFTER" advise
|
||||
// event handlers may modify this if they are preventing the default action
|
||||
// to provide the after event handlers with event results
|
||||
var $canPreventDefault = true; // READONLY if true, event handlers can prevent the events default action
|
||||
public $canPreventDefault = true; // READONLY if true, event handlers can prevent the events default action
|
||||
|
||||
// private properties, event handlers can effect these through the provided methods
|
||||
var $_default = true; // whether or not to carry out the default action associated with the event
|
||||
|
@ -32,6 +35,13 @@ class Doku_Event {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function __toString() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* advise functions
|
||||
*
|
||||
|
@ -47,7 +57,8 @@ class Doku_Event {
|
|||
* $evt->advise_after();
|
||||
* unset($evt);
|
||||
*
|
||||
* @return results of processing the event, usually $this->_default
|
||||
* @param bool $enablePreventDefault
|
||||
* @return bool results of processing the event, usually $this->_default
|
||||
*/
|
||||
function advise_before($enablePreventDefault=true) {
|
||||
global $EVENT_HANDLER;
|
||||
|
@ -73,14 +84,21 @@ class Doku_Event {
|
|||
* $this->_default, all of which may have been modified by the event handlers.
|
||||
* - advise all registered (<event>_AFTER) handlers that the event has taken place
|
||||
*
|
||||
* @return $event->results
|
||||
* @param null|callable $action
|
||||
* @param bool $enablePrevent
|
||||
* @return mixed $event->results
|
||||
* the value set by any <event>_before or <event> handlers if the default action is prevented
|
||||
* or the results of the default action (as modified by <event>_after handlers)
|
||||
* or NULL no action took place and no handler modified the value
|
||||
*/
|
||||
function trigger($action=null, $enablePrevent=true) {
|
||||
|
||||
if (!is_callable($action)) $enablePrevent = false;
|
||||
if (!is_callable($action)) {
|
||||
$enablePrevent = false;
|
||||
if (!is_null($action)) {
|
||||
trigger_error('The default action of '.$this.' is not null but also not callable. Maybe the method is not public?', E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->advise_before($enablePrevent) && is_callable($action)) {
|
||||
if (is_array($action)) {
|
||||
|
@ -112,12 +130,15 @@ class Doku_Event {
|
|||
function preventDefault() { $this->_default = false; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls the registration and execution of all events,
|
||||
*/
|
||||
class Doku_Event_Handler {
|
||||
|
||||
// public properties: none
|
||||
|
||||
// private properties
|
||||
var $_hooks = array(); // array of events and their registered handlers
|
||||
protected $_hooks = array(); // array of events and their registered handlers
|
||||
|
||||
/**
|
||||
* event_handler
|
||||
|
@ -128,6 +149,7 @@ class Doku_Event_Handler {
|
|||
function Doku_Event_Handler() {
|
||||
|
||||
// load action plugins
|
||||
/** @var DokuWiki_Action_Plugin $plugin */
|
||||
$plugin = null;
|
||||
$pluginlist = plugin_list('action');
|
||||
|
||||
|
@ -143,34 +165,47 @@ class Doku_Event_Handler {
|
|||
*
|
||||
* register a hook for an event
|
||||
*
|
||||
* @param $event (string) name used by the event, (incl '_before' or '_after' for triggers)
|
||||
* @param $obj (obj) object in whose scope method is to be executed,
|
||||
* @param $event string name used by the event, (incl '_before' or '_after' for triggers)
|
||||
* @param $advise string
|
||||
* @param $obj object object in whose scope method is to be executed,
|
||||
* if NULL, method is assumed to be a globally available function
|
||||
* @param $method (function) event handler function
|
||||
* @param $param (mixed) data passed to the event handler
|
||||
* @param $method string event handler function
|
||||
* @param $param mixed data passed to the event handler
|
||||
* @param $seq int sequence number for ordering hook execution (ascending)
|
||||
*/
|
||||
function register_hook($event, $advise, $obj, $method, $param=null) {
|
||||
$this->_hooks[$event.'_'.$advise][] = array($obj, $method, $param);
|
||||
function register_hook($event, $advise, $obj, $method, $param=null, $seq=0) {
|
||||
$seq = (int)$seq;
|
||||
$doSort = !isset($this->_hooks[$event.'_'.$advise][$seq]);
|
||||
$this->_hooks[$event.'_'.$advise][$seq][] = array($obj, $method, $param);
|
||||
|
||||
if ($doSort) {
|
||||
ksort($this->_hooks[$event.'_'.$advise]);
|
||||
}
|
||||
}
|
||||
|
||||
function process_event(&$event,$advise='') {
|
||||
/**
|
||||
* process the before/after event
|
||||
*
|
||||
* @param Doku_Event $event
|
||||
* @param string $advise BEFORE or AFTER
|
||||
*/
|
||||
function process_event($event,$advise='') {
|
||||
|
||||
$evt_name = $event->name . ($advise ? '_'.$advise : '_BEFORE');
|
||||
|
||||
if (!empty($this->_hooks[$evt_name])) {
|
||||
foreach ($this->_hooks[$evt_name] as $hook) {
|
||||
// list($obj, $method, $param) = $hook;
|
||||
$obj =& $hook[0];
|
||||
$method = $hook[1];
|
||||
$param = $hook[2];
|
||||
foreach ($this->_hooks[$evt_name] as $sequenced_hooks) {
|
||||
foreach ($sequenced_hooks as $hook) {
|
||||
list($obj, $method, $param) = $hook;
|
||||
|
||||
if (is_null($obj)) {
|
||||
$method($event, $param);
|
||||
} else {
|
||||
$obj->$method($event, $param);
|
||||
if (is_null($obj)) {
|
||||
$method($event, $param);
|
||||
} else {
|
||||
$obj->$method($event, $param);
|
||||
}
|
||||
|
||||
if (!$event->_continue) return;
|
||||
}
|
||||
|
||||
if (!$event->_continue) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -181,12 +216,12 @@ class Doku_Event_Handler {
|
|||
*
|
||||
* function wrapper to process (create, trigger and destroy) an event
|
||||
*
|
||||
* @param $name (string) name for the event
|
||||
* @param $data (mixed) event data
|
||||
* @param $action (callback) (optional, default=NULL) default action, a php callback function
|
||||
* @param $canPreventDefault (bool) (optional, default=true) can hooks prevent the default action
|
||||
* @param $name string name for the event
|
||||
* @param $data mixed event data
|
||||
* @param $action callback (optional, default=NULL) default action, a php callback function
|
||||
* @param $canPreventDefault bool (optional, default=true) can hooks prevent the default action
|
||||
*
|
||||
* @return (mixed) the event results value after all event processing is complete
|
||||
* @return mixed the event results value after all event processing is complete
|
||||
* by default this is the return value of the default action however
|
||||
* it can be set or modified by event handler hooks
|
||||
*/
|
||||
|
|
|
@ -185,6 +185,8 @@ class HtmlDescribable {
|
|||
*/
|
||||
var $descriptionTruncSize;
|
||||
|
||||
var $description;
|
||||
|
||||
/**
|
||||
* Returns a formatted description field, depending on descriptionHtmlSyndicated and
|
||||
* $descriptionTruncSize properties
|
||||
|
@ -222,7 +224,7 @@ class FeedHtmlField {
|
|||
|
||||
/**
|
||||
* Creates a new instance of FeedHtmlField.
|
||||
* @param $string: if given, sets the rawFieldContent property
|
||||
* @param string $parFieldContent: if given, sets the rawFieldContent property
|
||||
*/
|
||||
function FeedHtmlField($parFieldContent) {
|
||||
if ($parFieldContent) {
|
||||
|
@ -267,8 +269,14 @@ class FeedHtmlField {
|
|||
* @author Kai Blankenhorn <kaib@bitfolge.de>
|
||||
*/
|
||||
class UniversalFeedCreator extends FeedCreator {
|
||||
/** @var FeedCreator */
|
||||
var $_feed;
|
||||
|
||||
/**
|
||||
* Sets format
|
||||
*
|
||||
* @param string $format
|
||||
*/
|
||||
function _setFormat($format) {
|
||||
switch (strtoupper($format)) {
|
||||
|
||||
|
@ -344,7 +352,7 @@ class UniversalFeedCreator extends FeedCreator {
|
|||
* Creates a syndication feed based on the items previously added.
|
||||
*
|
||||
* @see FeedCreator::addItem()
|
||||
* @param string format format the feed should comply to. Valid values are:
|
||||
* @param string $format format the feed should comply to. Valid values are:
|
||||
* "PIE0.1", "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3", "HTML", "JS"
|
||||
* @return string the contents of the feed.
|
||||
*/
|
||||
|
@ -358,10 +366,10 @@ class UniversalFeedCreator extends FeedCreator {
|
|||
* header may be sent to redirect the use to the newly created file.
|
||||
* @since 1.4
|
||||
*
|
||||
* @param string format format the feed should comply to. Valid values are:
|
||||
* @param string $format format the feed should comply to. Valid values are:
|
||||
* "PIE0.1" (deprecated), "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM", "ATOM0.3", "HTML", "JS"
|
||||
* @param string filename optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
|
||||
* @param boolean displayContents optional send the content of the file or not. If true, the file will be sent in the body of the response.
|
||||
* @param string $filename optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
|
||||
* @param boolean $displayContents optional send the content of the file or not. If true, the file will be sent in the body of the response.
|
||||
*/
|
||||
function saveFeed($format="RSS0.91", $filename="", $displayContents=true) {
|
||||
$this->_setFormat($format);
|
||||
|
@ -376,10 +384,10 @@ class UniversalFeedCreator extends FeedCreator {
|
|||
* before anything else, especially before you do the time consuming task to build the feed
|
||||
* (web fetching, for example).
|
||||
*
|
||||
* @param string format format the feed should comply to. Valid values are:
|
||||
* @param string $format format the feed should comply to. Valid values are:
|
||||
* "PIE0.1" (deprecated), "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3".
|
||||
* @param filename string optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
|
||||
* @param timeout int optional the timeout in seconds before a cached version is refreshed (defaults to 3600 = 1 hour)
|
||||
* @param string $filename optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
|
||||
* @param int $timeout optional the timeout in seconds before a cached version is refreshed (defaults to 3600 = 1 hour)
|
||||
*/
|
||||
function useCached($format="RSS0.91", $filename="", $timeout=3600) {
|
||||
$this->_setFormat($format);
|
||||
|
@ -390,7 +398,7 @@ class UniversalFeedCreator extends FeedCreator {
|
|||
/**
|
||||
* Outputs feed to the browser - needed for on-the-fly feed generation (like it is done in WordPress, etc.)
|
||||
*
|
||||
* @param format string format the feed should comply to. Valid values are:
|
||||
* @param $format string format the feed should comply to. Valid values are:
|
||||
* "PIE0.1" (deprecated), "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3".
|
||||
*/
|
||||
function outputFeed($format='RSS0.91') {
|
||||
|
@ -422,7 +430,13 @@ class FeedCreator extends HtmlDescribable {
|
|||
/**
|
||||
* Optional attributes of a feed.
|
||||
*/
|
||||
var $syndicationURL, $image, $language, $copyright, $pubDate, $lastBuildDate, $editor, $editorEmail, $webmaster, $category, $docs, $ttl, $rating, $skipHours, $skipDays;
|
||||
var $syndicationURL, $language, $copyright, $pubDate, $lastBuildDate, $editor, $editorEmail, $webmaster, $category, $docs, $ttl, $rating, $skipHours, $skipDays;
|
||||
/**
|
||||
* Optional attribute of a feed
|
||||
*
|
||||
* @var FeedImage
|
||||
*/
|
||||
var $image = null;
|
||||
|
||||
/**
|
||||
* The url of the external xsl stylesheet used to format the naked rss feed.
|
||||
|
@ -430,13 +444,18 @@ class FeedCreator extends HtmlDescribable {
|
|||
*/
|
||||
var $xslStyleSheet = "";
|
||||
|
||||
/**
|
||||
* Style sheet for rss feed
|
||||
*/
|
||||
var $cssStyleSheet = "";
|
||||
|
||||
|
||||
/**
|
||||
* @access private
|
||||
* @var FeedItem[]
|
||||
*/
|
||||
var $items = Array();
|
||||
|
||||
|
||||
/**
|
||||
* This feed's MIME content type.
|
||||
* @since 1.4
|
||||
|
@ -466,7 +485,7 @@ class FeedCreator extends HtmlDescribable {
|
|||
/**
|
||||
* Adds an FeedItem to the feed.
|
||||
*
|
||||
* @param object FeedItem $item The FeedItem to add to the feed.
|
||||
* @param FeedItem $item The FeedItem to add to the feed.
|
||||
* @access public
|
||||
*/
|
||||
function addItem($item) {
|
||||
|
@ -482,8 +501,8 @@ class FeedCreator extends HtmlDescribable {
|
|||
* If the string is already shorter than $length, it is returned unchanged.
|
||||
*
|
||||
* @static
|
||||
* @param string string A string to be truncated.
|
||||
* @param int length the maximum length the string should be truncated to
|
||||
* @param string $string A string to be truncated.
|
||||
* @param int $length the maximum length the string should be truncated to
|
||||
* @return string the truncated string
|
||||
*/
|
||||
function iTrunc($string, $length) {
|
||||
|
@ -527,8 +546,8 @@ class FeedCreator extends HtmlDescribable {
|
|||
/**
|
||||
* Creates a string containing all additional elements specified in
|
||||
* $additionalElements.
|
||||
* @param elements array an associative array containing key => value pairs
|
||||
* @param indentString string a string that will be inserted before every generated line
|
||||
* @param $elements array an associative array containing key => value pairs
|
||||
* @param $indentString string a string that will be inserted before every generated line
|
||||
* @return string the XML tags corresponding to $additionalElements
|
||||
*/
|
||||
function _createAdditionalElements($elements, $indentString="") {
|
||||
|
@ -541,6 +560,9 @@ class FeedCreator extends HtmlDescribable {
|
|||
return $ae;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create elements for stylesheets
|
||||
*/
|
||||
function _createStylesheetReferences() {
|
||||
$xml = "";
|
||||
if ($this->cssStyleSheet) $xml .= "<?xml-stylesheet href=\"".$this->cssStyleSheet."\" type=\"text/css\"?>\n";
|
||||
|
@ -610,8 +632,8 @@ class FeedCreator extends HtmlDescribable {
|
|||
* before anything else, especially before you do the time consuming task to build the feed
|
||||
* (web fetching, for example).
|
||||
* @since 1.4
|
||||
* @param filename string optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
|
||||
* @param timeout int optional the timeout in seconds before a cached version is refreshed (defaults to 3600 = 1 hour)
|
||||
* @param $filename string optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
|
||||
* @param $timeout int optional the timeout in seconds before a cached version is refreshed (defaults to 3600 = 1 hour)
|
||||
*/
|
||||
function useCached($filename="", $timeout=3600) {
|
||||
$this->_timeout = $timeout;
|
||||
|
@ -629,8 +651,8 @@ class FeedCreator extends HtmlDescribable {
|
|||
* header may be sent to redirect the user to the newly created file.
|
||||
* @since 1.4
|
||||
*
|
||||
* @param filename string optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
|
||||
* @param redirect boolean optional send an HTTP redirect header or not. If true, the user will be automatically redirected to the created file.
|
||||
* @param $filename string optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
|
||||
* @param $displayContents boolean optional send an HTTP redirect header or not. If true, the user will be automatically redirected to the created file.
|
||||
*/
|
||||
function saveFeed($filename="", $displayContents=true) {
|
||||
if ($filename=="") {
|
||||
|
@ -667,6 +689,7 @@ class FeedCreator extends HtmlDescribable {
|
|||
* Usually, you won't need to use this.
|
||||
*/
|
||||
class FeedDate {
|
||||
/** @var int */
|
||||
var $unix;
|
||||
|
||||
/**
|
||||
|
@ -726,7 +749,7 @@ class FeedDate {
|
|||
/**
|
||||
* Gets the date stored in this FeedDate as an RFC 822 date.
|
||||
*
|
||||
* @return a date in RFC 822 format
|
||||
* @return string a date in RFC 822 format
|
||||
*/
|
||||
function rfc822() {
|
||||
//return gmdate("r",$this->unix);
|
||||
|
@ -738,7 +761,7 @@ class FeedDate {
|
|||
/**
|
||||
* Gets the date stored in this FeedDate as an ISO 8601 date.
|
||||
*
|
||||
* @return a date in ISO 8601 (RFC 3339) format
|
||||
* @return string a date in ISO 8601 (RFC 3339) format
|
||||
*/
|
||||
function iso8601() {
|
||||
$date = gmdate("Y-m-d\TH:i:sO",$this->unix);
|
||||
|
@ -751,7 +774,7 @@ class FeedDate {
|
|||
/**
|
||||
* Gets the date stored in this FeedDate as unix time stamp.
|
||||
*
|
||||
* @return a date as a unix time stamp
|
||||
* @return int a date as a unix time stamp
|
||||
*/
|
||||
function unix() {
|
||||
return $this->unix;
|
||||
|
@ -777,7 +800,7 @@ class RSSCreator10 extends FeedCreator {
|
|||
$feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
|
||||
$feed.= $this->_createGeneratorComment();
|
||||
if ($this->cssStyleSheet=="") {
|
||||
$cssStyleSheet = "http://www.w3.org/2000/08/w3c-synd/style.css";
|
||||
$this->cssStyleSheet = "http://www.w3.org/2000/08/w3c-synd/style.css";
|
||||
}
|
||||
$feed.= $this->_createStylesheetReferences();
|
||||
$feed.= "<rdf:RDF\n";
|
||||
|
@ -1032,12 +1055,16 @@ class PIECreator01 extends FeedCreator {
|
|||
$this->encoding = "utf-8";
|
||||
}
|
||||
|
||||
/**
|
||||
* Build content
|
||||
* @return string
|
||||
*/
|
||||
function createFeed() {
|
||||
$feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
|
||||
$feed.= $this->_createStylesheetReferences();
|
||||
$feed.= "<feed version=\"0.1\" xmlns=\"http://example.com/newformat#\">\n";
|
||||
$feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars($this->title),100)."</title>\n";
|
||||
$this->truncSize = 500;
|
||||
$this->descriptionTruncSize = 500;
|
||||
$feed.= " <subtitle>".$this->getDescription()."</subtitle>\n";
|
||||
$feed.= " <link>".$this->link."</link>\n";
|
||||
$icnt = count($this->items);
|
||||
|
@ -1091,6 +1118,10 @@ class AtomCreator10 extends FeedCreator {
|
|||
$this->encoding = "utf-8";
|
||||
}
|
||||
|
||||
/**
|
||||
* Build content
|
||||
* @return string
|
||||
*/
|
||||
function createFeed() {
|
||||
$feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
|
||||
$feed.= $this->_createGeneratorComment();
|
||||
|
@ -1174,6 +1205,10 @@ class AtomCreator03 extends FeedCreator {
|
|||
$this->encoding = "utf-8";
|
||||
}
|
||||
|
||||
/**
|
||||
* Build content
|
||||
* @return string
|
||||
*/
|
||||
function createFeed() {
|
||||
$feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
|
||||
$feed.= $this->_createGeneratorComment();
|
||||
|
@ -1281,6 +1316,7 @@ class MBOXCreator extends FeedCreator {
|
|||
*/
|
||||
function createFeed() {
|
||||
$icnt = count($this->items);
|
||||
$feed = "";
|
||||
for ($i=0; $i<$icnt; $i++) {
|
||||
if ($this->items[$i]->author!="") {
|
||||
$from = $this->items[$i]->author;
|
||||
|
@ -1331,6 +1367,10 @@ class OPMLCreator extends FeedCreator {
|
|||
$this->encoding = "utf-8";
|
||||
}
|
||||
|
||||
/**
|
||||
* Build content
|
||||
* @return string
|
||||
*/
|
||||
function createFeed() {
|
||||
$feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
|
||||
$feed.= $this->_createGeneratorComment();
|
||||
|
@ -1441,6 +1481,7 @@ class HTMLCreator extends FeedCreator {
|
|||
}
|
||||
|
||||
//set an openInNewWindow_token_to be inserted or not
|
||||
$targetInsert = "";
|
||||
if ($this->openInNewWindow) {
|
||||
$targetInsert = " target='_blank'";
|
||||
}
|
||||
|
@ -1568,6 +1609,14 @@ class JSCreator extends HTMLCreator {
|
|||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*/
|
||||
class DokuWikiFeedCreator extends UniversalFeedCreator{
|
||||
|
||||
/**
|
||||
* Build content
|
||||
*
|
||||
* @param string $format
|
||||
* @param string $encoding
|
||||
* @return string
|
||||
*/
|
||||
function createFeed($format = "RSS0.91",$encoding='iso-8859-15') {
|
||||
$this->_setFormat($format);
|
||||
$this->_feed->encoding = $encoding;
|
||||
|
|
|
@ -77,7 +77,7 @@ function sendFile($file, $mime, $dl, $cache, $public = false, $orig = null) {
|
|||
}
|
||||
|
||||
//use x-sendfile header to pass the delivery to compatible webservers
|
||||
if(http_sendfile($file)) exit;
|
||||
http_sendfile($file);
|
||||
|
||||
// send file contents
|
||||
$fp = @fopen($file, "rb");
|
||||
|
|
50
inc/form.php
50
inc/form.php
|
@ -47,15 +47,11 @@ class Doku_Form {
|
|||
* with up to four parameters is deprecated, instead the first parameter
|
||||
* should be an array with parameters.
|
||||
*
|
||||
* @param mixed $params Parameters for the HTML form element; Using the
|
||||
* deprecated calling convention this is the ID
|
||||
* attribute of the form
|
||||
* @param string $action (optional, deprecated) submit URL, defaults to
|
||||
* current page
|
||||
* @param string $method (optional, deprecated) 'POST' or 'GET', default
|
||||
* is POST
|
||||
* @param string $enctype (optional, deprecated) Encoding type of the
|
||||
* data
|
||||
* @param mixed $params Parameters for the HTML form element; Using the deprecated
|
||||
* calling convention this is the ID attribute of the form
|
||||
* @param bool|string $action (optional, deprecated) submit URL, defaults to current page
|
||||
* @param bool|string $method (optional, deprecated) 'POST' or 'GET', default is POST
|
||||
* @param bool|string $enctype (optional, deprecated) Encoding type of the data
|
||||
* @author Tom N Harris <tnharris@whoopdedo.org>
|
||||
*/
|
||||
function Doku_Form($params, $action=false, $method=false, $enctype=false) {
|
||||
|
@ -135,7 +131,7 @@ class Doku_Form {
|
|||
* The element can be either a pseudo-tag or string.
|
||||
* If string, it is printed without escaping special chars. *
|
||||
*
|
||||
* @param string $elem Pseudo-tag or string to add to the form.
|
||||
* @param string|array $elem Pseudo-tag or string to add to the form.
|
||||
* @author Tom N Harris <tnharris@whoopdedo.org>
|
||||
*/
|
||||
function addElement($elem) {
|
||||
|
@ -147,8 +143,8 @@ class Doku_Form {
|
|||
*
|
||||
* Inserts a content element at a position.
|
||||
*
|
||||
* @param string $pos 0-based index where the element will be inserted.
|
||||
* @param string $elem Pseudo-tag or string to add to the form.
|
||||
* @param string $pos 0-based index where the element will be inserted.
|
||||
* @param string|array $elem Pseudo-tag or string to add to the form.
|
||||
* @author Tom N Harris <tnharris@whoopdedo.org>
|
||||
*/
|
||||
function insertElement($pos, $elem) {
|
||||
|
@ -160,8 +156,8 @@ class Doku_Form {
|
|||
*
|
||||
* Replace with NULL to remove an element.
|
||||
*
|
||||
* @param int $pos 0-based index the element will be placed at.
|
||||
* @param string $elem Pseudo-tag or string to add to the form.
|
||||
* @param int $pos 0-based index the element will be placed at.
|
||||
* @param string|array $elem Pseudo-tag or string to add to the form.
|
||||
* @author Tom N Harris <tnharris@whoopdedo.org>
|
||||
*/
|
||||
function replaceElement($pos, $elem) {
|
||||
|
@ -176,7 +172,7 @@ class Doku_Form {
|
|||
* Gets the position of the first of a type of element.
|
||||
*
|
||||
* @param string $type Element type to look for.
|
||||
* @return array pseudo-element if found, false otherwise
|
||||
* @return int position of element if found, otherwise false
|
||||
* @author Tom N Harris <tnharris@whoopdedo.org>
|
||||
*/
|
||||
function findElementByType($type) {
|
||||
|
@ -193,7 +189,7 @@ class Doku_Form {
|
|||
* Gets the position of the element with an ID attribute.
|
||||
*
|
||||
* @param string $id ID of the element to find.
|
||||
* @return array pseudo-element if found, false otherwise
|
||||
* @return int position of element if found, otherwise false
|
||||
* @author Tom N Harris <tnharris@whoopdedo.org>
|
||||
*/
|
||||
function findElementById($id) {
|
||||
|
@ -211,7 +207,7 @@ class Doku_Form {
|
|||
*
|
||||
* @param string $name Attribute name.
|
||||
* @param string $value Attribute value.
|
||||
* @return array pseudo-element if found, false otherwise
|
||||
* @return int position of element if found, otherwise false
|
||||
* @author Tom N Harris <tnharris@whoopdedo.org>
|
||||
*/
|
||||
function findElementByAttribute($name, $value) {
|
||||
|
@ -230,7 +226,7 @@ class Doku_Form {
|
|||
* first (underflow) or last (overflow) element.
|
||||
*
|
||||
* @param int $pos 0-based index
|
||||
* @return arrayreference pseudo-element
|
||||
* @return array reference pseudo-element
|
||||
* @author Tom N Harris <tnharris@whoopdedo.org>
|
||||
*/
|
||||
function &getElementAt($pos) {
|
||||
|
@ -565,10 +561,11 @@ function form_makeListboxField($name, $values, $selected='', $label=null, $id=''
|
|||
if (is_null($label)) $label = $name;
|
||||
$options = array();
|
||||
reset($values);
|
||||
if (is_null($selected) || $selected == '')
|
||||
if (is_null($selected) || $selected == '') {
|
||||
$selected = array();
|
||||
elseif (!is_array($selected))
|
||||
} elseif (!is_array($selected)) {
|
||||
$selected = array($selected);
|
||||
}
|
||||
// FIXME: php doesn't know the difference between a string and an integer
|
||||
if (is_string(key($values))) {
|
||||
foreach ($values as $val=>$text) {
|
||||
|
@ -576,11 +573,13 @@ function form_makeListboxField($name, $values, $selected='', $label=null, $id=''
|
|||
}
|
||||
} else {
|
||||
foreach ($values as $val) {
|
||||
if (is_array($val))
|
||||
@list($val,$text) = $val;
|
||||
else
|
||||
$disabled = false;
|
||||
if (is_array($val)) {
|
||||
@list($val,$text,$disabled) = $val;
|
||||
} else {
|
||||
$text = null;
|
||||
$options[] = array($val,$text,in_array($val,$selected));
|
||||
}
|
||||
$options[] = array($val,$text,in_array($val,$selected),$disabled);
|
||||
}
|
||||
}
|
||||
$elem = array('_elem'=>'listboxfield', '_options'=>$options, '_text'=>$label, '_class'=>$class,
|
||||
|
@ -934,11 +933,12 @@ function form_listboxfield($attrs) {
|
|||
$s .= '<select '.buildAttributes($attrs,true).'>'.DOKU_LF;
|
||||
if (!empty($attrs['_options'])) {
|
||||
foreach ($attrs['_options'] as $opt) {
|
||||
@list($value,$text,$select) = $opt;
|
||||
@list($value,$text,$select,$disabled) = $opt;
|
||||
$p = '';
|
||||
if(is_null($text)) $text = $value;
|
||||
$p .= ' value="'.formText($value).'"';
|
||||
if (!empty($select)) $p .= ' selected="selected"';
|
||||
if ($disabled) $p .= ' disabled="disabled"';
|
||||
$s .= '<option'.$p.'>'.formText($text).'</option>';
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -72,8 +72,20 @@ function _ft_pageSearch(&$data) {
|
|||
$pages = end($stack);
|
||||
$pages_matched = array();
|
||||
foreach(array_keys($pages) as $id){
|
||||
$text = utf8_strtolower(rawWiki($id));
|
||||
if (strpos($text, $phrase) !== false) {
|
||||
$evdata = array(
|
||||
'id' => $id,
|
||||
'phrase' => $phrase,
|
||||
'text' => rawWiki($id)
|
||||
);
|
||||
$evt = new Doku_Event('FULLTEXT_PHRASE_MATCH',$evdata);
|
||||
if ($evt->advise_before() && $evt->result !== true) {
|
||||
$text = utf8_strtolower($evdata['text']);
|
||||
if (strpos($text, $phrase) !== false) {
|
||||
$evt->result = true;
|
||||
}
|
||||
}
|
||||
$evt->advise_after();
|
||||
if ($evt->result === true) {
|
||||
$pages_matched[$id] = 0; // phrase: always 0 hit
|
||||
}
|
||||
}
|
||||
|
@ -333,7 +345,7 @@ function ft_snippet($id,$highlight){
|
|||
$pre = min($pre,100-$post);
|
||||
} else if ($post>50) {
|
||||
$post = min($post, 100-$pre);
|
||||
} else {
|
||||
} else if ($offset == 0) {
|
||||
// both are less than 50, means the context is the whole string
|
||||
// make it so and break out of this loop - there is no need for the
|
||||
// complex snippet calculations
|
||||
|
@ -354,12 +366,12 @@ function ft_snippet($id,$highlight){
|
|||
}
|
||||
|
||||
// set $offset for next match attempt
|
||||
// substract strlen to avoid splitting a potential search success,
|
||||
// this is an approximation as the search pattern may match strings
|
||||
// of varying length and it will fail if the context snippet
|
||||
// boundary breaks a matching string longer than the current match
|
||||
$utf8_offset = $utf8_idx + $post;
|
||||
$offset = $idx + strlen(utf8_substr($text,$utf8_idx,$post));
|
||||
// continue matching after the current match
|
||||
// if the current match is not the longest possible match starting at the current offset
|
||||
// this prevents further matching of this snippet but for possible matches of length
|
||||
// smaller than match length + context (at least 50 characters) this match is part of the context
|
||||
$utf8_offset = $utf8_idx + $utf8_len;
|
||||
$offset = $idx + strlen(utf8_substr($text,$utf8_idx,$utf8_len));
|
||||
$offset = utf8_correctIdx($text,$offset);
|
||||
}
|
||||
|
||||
|
|
503
inc/html.php
503
inc/html.php
|
@ -19,6 +19,7 @@ if(!defined('NL')) define('NL',"\n");
|
|||
* @return string the HTML code of the link
|
||||
*/
|
||||
function html_wikilink($id,$name=null,$search=''){
|
||||
/** @var Doku_Renderer_xhtml $xhtml_renderer */
|
||||
static $xhtml_renderer = null;
|
||||
if(is_null($xhtml_renderer)){
|
||||
$xhtml_renderer = p_get_renderer('xhtml');
|
||||
|
@ -64,6 +65,20 @@ function html_login(){
|
|||
print '</div>'.NL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Denied page content
|
||||
*
|
||||
* @return string html
|
||||
*/
|
||||
function html_denied() {
|
||||
print p_locale_xhtml('denied');
|
||||
|
||||
if(!$_SERVER['REMOTE_USER']){
|
||||
html_login();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* inserts section edit buttons if wanted or removes the markers
|
||||
*
|
||||
|
@ -396,8 +411,8 @@ function html_locked(){
|
|||
|
||||
print p_locale_xhtml('locked');
|
||||
print '<ul>';
|
||||
print '<li><div class="li"><strong>'.$lang['lockedby'].':</strong> '.editorinfo($INFO['locked']).'</div></li>';
|
||||
print '<li><div class="li"><strong>'.$lang['lockexpire'].':</strong> '.$expire.' ('.$min.' min)</div></li>';
|
||||
print '<li><div class="li"><strong>'.$lang['lockedby'].'</strong> '.editorinfo($INFO['locked']).'</div></li>';
|
||||
print '<li><div class="li"><strong>'.$lang['lockexpire'].'</strong> '.$expire.' ('.$min.' min)</div></li>';
|
||||
print '</ul>';
|
||||
}
|
||||
|
||||
|
@ -414,20 +429,23 @@ function html_revisions($first=0, $media_id = false){
|
|||
global $conf;
|
||||
global $lang;
|
||||
$id = $ID;
|
||||
if ($media_id) {
|
||||
$id = $media_id;
|
||||
$changelog = new MediaChangeLog($id);
|
||||
} else {
|
||||
$changelog = new PageChangeLog($id);
|
||||
}
|
||||
|
||||
/* we need to get one additional log entry to be able to
|
||||
* decide if this is the last page or is there another one.
|
||||
* see html_recent()
|
||||
*/
|
||||
if (!$media_id) $revisions = getRevisions($ID, $first, $conf['recent']+1);
|
||||
else {
|
||||
$revisions = getRevisions($media_id, $first, $conf['recent']+1, 8192, true);
|
||||
$id = $media_id;
|
||||
}
|
||||
|
||||
$revisions = $changelog->getRevisions($first, $conf['recent']+1);
|
||||
|
||||
if(count($revisions)==0 && $first!=0){
|
||||
$first=0;
|
||||
if (!$media_id) $revisions = getRevisions($ID, $first, $conf['recent']+1);
|
||||
else $revisions = getRevisions($media_id, $first, $conf['recent']+1, 8192, true);
|
||||
$revisions = $changelog->getRevisions($first, $conf['recent']+1);
|
||||
}
|
||||
$hasNext = false;
|
||||
if (count($revisions)>$conf['recent']) {
|
||||
|
@ -486,15 +504,18 @@ function html_revisions($first=0, $media_id = false){
|
|||
$form->addElement(form_makeCloseTag('span'));
|
||||
}
|
||||
|
||||
$changelog->setChunkSize(1024);
|
||||
|
||||
$form->addElement(form_makeOpenTag('span', array('class' => 'user')));
|
||||
if (!$media_id) $editor = $INFO['editor'];
|
||||
else {
|
||||
$revinfo = getRevisionInfo($id, @filemtime(fullpath(mediaFN($id))), 1024, true);
|
||||
if($revinfo['user']){
|
||||
if($media_id) {
|
||||
$revinfo = $changelog->getRevisionInfo(@filemtime(fullpath(mediaFN($id))));
|
||||
if($revinfo['user']) {
|
||||
$editor = $revinfo['user'];
|
||||
}else{
|
||||
} else {
|
||||
$editor = $revinfo['ip'];
|
||||
}
|
||||
} else {
|
||||
$editor = $INFO['editor'];
|
||||
}
|
||||
$form->addElement((empty($editor))?('('.$lang['external_edit'].')'):editorinfo($editor));
|
||||
$form->addElement(form_makeCloseTag('span'));
|
||||
|
@ -509,12 +530,11 @@ function html_revisions($first=0, $media_id = false){
|
|||
|
||||
foreach($revisions as $rev){
|
||||
$date = dformat($rev);
|
||||
if (!$media_id) {
|
||||
$info = getRevisionInfo($id,$rev,true);
|
||||
$exists = page_exists($id,$rev);
|
||||
} else {
|
||||
$info = getRevisionInfo($id,$rev,true,true);
|
||||
$exists = @file_exists(mediaFN($id,$rev));
|
||||
$info = $changelog->getRevisionInfo($rev);
|
||||
if($media_id) {
|
||||
$exists = @file_exists(mediaFN($id, $rev));
|
||||
} else {
|
||||
$exists = page_exists($id, $rev);
|
||||
}
|
||||
|
||||
if ($info['type']===DOKU_CHANGE_TYPE_MINOR_EDIT)
|
||||
|
@ -691,7 +711,7 @@ function html_recent($first=0, $show_changes='both'){
|
|||
|
||||
$form->addElement(form_makeOpenTag('div', array('class' => 'li')));
|
||||
|
||||
if ($recent['media']) {
|
||||
if (!empty($recent['media'])) {
|
||||
$form->addElement(media_printicon($recent['id']));
|
||||
} else {
|
||||
$icon = DOKU_BASE.'lib/images/fileicons/file.png';
|
||||
|
@ -705,7 +725,7 @@ function html_recent($first=0, $show_changes='both'){
|
|||
$diff = false;
|
||||
$href = '';
|
||||
|
||||
if ($recent['media']) {
|
||||
if (!empty($recent['media'])) {
|
||||
$diff = (count(getRevisions($recent['id'], 0, 1, 8192, true)) && @file_exists(mediaFN($recent['id'])));
|
||||
if ($diff) {
|
||||
$href = media_managerURL(array('tab_details' => 'history',
|
||||
|
@ -715,7 +735,7 @@ function html_recent($first=0, $show_changes='both'){
|
|||
$href = wl($recent['id'],"do=diff", false, '&');
|
||||
}
|
||||
|
||||
if ($recent['media'] && !$diff) {
|
||||
if (!empty($recent['media']) && !$diff) {
|
||||
$form->addElement('<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />');
|
||||
} else {
|
||||
$form->addElement(form_makeOpenTag('a', array('class' => 'diff_link', 'href' => $href)));
|
||||
|
@ -729,7 +749,7 @@ function html_recent($first=0, $show_changes='both'){
|
|||
$form->addElement(form_makeCloseTag('a'));
|
||||
}
|
||||
|
||||
if ($recent['media']) {
|
||||
if (!empty($recent['media'])) {
|
||||
$href = media_managerURL(array('tab_details' => 'history',
|
||||
'image' => $recent['id'], 'ns' => getNS($recent['id'])), '&');
|
||||
} else {
|
||||
|
@ -745,7 +765,7 @@ function html_recent($first=0, $show_changes='both'){
|
|||
)));
|
||||
$form->addElement(form_makeCloseTag('a'));
|
||||
|
||||
if ($recent['media']) {
|
||||
if (!empty($recent['media'])) {
|
||||
$href = media_managerURL(array('tab_details' => 'view', 'image' => $recent['id'], 'ns' => getNS($recent['id'])), '&');
|
||||
$class = (file_exists(mediaFN($recent['id']))) ? 'wikilink1' : $class = 'wikilink2';
|
||||
$form->addElement(form_makeOpenTag('a', array('class' => $class, 'href' => $href)));
|
||||
|
@ -902,6 +922,14 @@ function html_li_default($item){
|
|||
* a member of an object.
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param array $data array with item arrays
|
||||
* @param string $class class of ul wrapper
|
||||
* @param callable $func callback to print an list item
|
||||
* @param string $lifunc callback to the opening li tag
|
||||
* @param bool $forcewrapper Trigger building a wrapper ul if the first level is
|
||||
0 (we have a root object) or 1 (just the root content)
|
||||
* @return string html of an unordered list
|
||||
*/
|
||||
function html_buildlist($data,$class,$func,$lifunc='html_li_default',$forcewrapper=false){
|
||||
if (count($data) === 0) {
|
||||
|
@ -1008,10 +1036,15 @@ function html_diff_head($l_rev, $r_rev, $id = null, $media = false, $inline = fa
|
|||
$ml_or_wl = $media ? 'ml' : 'wl';
|
||||
$l_minor = $r_minor = '';
|
||||
|
||||
if($media) {
|
||||
$changelog = new MediaChangeLog($id);
|
||||
} else {
|
||||
$changelog = new PageChangeLog($id);
|
||||
}
|
||||
if(!$l_rev){
|
||||
$l_head = '—';
|
||||
}else{
|
||||
$l_info = getRevisionInfo($id,$l_rev,true, $media);
|
||||
$l_info = $changelog->getRevisionInfo($l_rev);
|
||||
if($l_info['user']){
|
||||
$l_user = '<bdi>'.editorinfo($l_info['user']).'</bdi>';
|
||||
if(auth_ismanager()) $l_user .= ' <bdo dir="ltr">('.$l_info['ip'].')</bdo>';
|
||||
|
@ -1029,7 +1062,7 @@ function html_diff_head($l_rev, $r_rev, $id = null, $media = false, $inline = fa
|
|||
}
|
||||
|
||||
if($r_rev){
|
||||
$r_info = getRevisionInfo($id,$r_rev,true, $media);
|
||||
$r_info = $changelog->getRevisionInfo($r_rev);
|
||||
if($r_info['user']){
|
||||
$r_user = '<bdi>'.editorinfo($r_info['user']).'</bdi>';
|
||||
if(auth_ismanager()) $r_user .= ' <bdo dir="ltr">('.$r_info['ip'].')</bdo>';
|
||||
|
@ -1045,7 +1078,7 @@ function html_diff_head($l_rev, $r_rev, $id = null, $media = false, $inline = fa
|
|||
$r_head_title.'</a></bdi>'.
|
||||
$head_separator.$r_user.' '.$r_sum;
|
||||
}elseif($_rev = @filemtime($media_or_wikiFN($id))){
|
||||
$_info = getRevisionInfo($id,$_rev,true, $media);
|
||||
$_info = $changelog->getRevisionInfo($_rev);
|
||||
if($_info['user']){
|
||||
$_user = '<bdi>'.editorinfo($_info['user']).'</bdi>';
|
||||
if(auth_ismanager()) $_user .= ' <bdo dir="ltr">('.$_info['ip'].')</bdo>';
|
||||
|
@ -1069,162 +1102,386 @@ function html_diff_head($l_rev, $r_rev, $id = null, $media = false, $inline = fa
|
|||
}
|
||||
|
||||
/**
|
||||
* show diff
|
||||
* Show diff
|
||||
* between current page version and provided $text
|
||||
* or between the revisions provided via GET or POST
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
* @param string $text - compare with this text with most current version
|
||||
* @param bool $intro - display the intro text
|
||||
* @param string $type type of the diff (inline or sidebyside)
|
||||
* @param string $text when non-empty: compare with this text with most current version
|
||||
* @param bool $intro display the intro text
|
||||
* @param string $type type of the diff (inline or sidebyside)
|
||||
*/
|
||||
function html_diff($text='',$intro=true,$type=null){
|
||||
function html_diff($text = '', $intro = true, $type = null) {
|
||||
global $ID;
|
||||
global $REV;
|
||||
global $lang;
|
||||
global $INPUT;
|
||||
global $INFO;
|
||||
$pagelog = new PageChangeLog($ID);
|
||||
|
||||
/*
|
||||
* Determine diff type
|
||||
*/
|
||||
if(!$type) {
|
||||
$type = $INPUT->str('difftype');
|
||||
if (empty($type)) {
|
||||
if(empty($type)) {
|
||||
$type = get_doku_pref('difftype', $type);
|
||||
if (empty($type) && $INFO['ismobile']) {
|
||||
if(empty($type) && $INFO['ismobile']) {
|
||||
$type = 'inline';
|
||||
}
|
||||
}
|
||||
}
|
||||
if($type != 'inline') $type = 'sidebyside';
|
||||
|
||||
/*
|
||||
* Determine requested revision(s)
|
||||
*/
|
||||
// we're trying to be clever here, revisions to compare can be either
|
||||
// given as rev and rev2 parameters, with rev2 being optional. Or in an
|
||||
// array in rev2.
|
||||
$rev1 = $REV;
|
||||
|
||||
$rev2 = $INPUT->ref('rev2');
|
||||
if(is_array($rev2)){
|
||||
if(is_array($rev2)) {
|
||||
$rev1 = (int) $rev2[0];
|
||||
$rev2 = (int) $rev2[1];
|
||||
|
||||
if(!$rev1){
|
||||
if(!$rev1) {
|
||||
$rev1 = $rev2;
|
||||
unset($rev2);
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
$rev2 = $INPUT->int('rev2');
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine left and right revision, its texts and the header
|
||||
*/
|
||||
$r_minor = '';
|
||||
$l_minor = '';
|
||||
|
||||
if($text){ // compare text to the most current revision
|
||||
$l_rev = '';
|
||||
$l_text = rawWiki($ID,'');
|
||||
$l_head = '<a class="wikilink1" href="'.wl($ID).'">'.
|
||||
$ID.' '.dformat((int) @filemtime(wikiFN($ID))).'</a> '.
|
||||
if($text) { // compare text to the most current revision
|
||||
$l_rev = '';
|
||||
$l_text = rawWiki($ID, '');
|
||||
$l_head = '<a class="wikilink1" href="' . wl($ID) . '">' .
|
||||
$ID . ' ' . dformat((int) @filemtime(wikiFN($ID))) . '</a> ' .
|
||||
$lang['current'];
|
||||
|
||||
$r_rev = '';
|
||||
$r_text = cleanText($text);
|
||||
$r_head = $lang['yours'];
|
||||
}else{
|
||||
if($rev1 && isset($rev2) && $rev2){ // two specific revisions wanted
|
||||
$r_rev = '';
|
||||
$r_text = cleanText($text);
|
||||
$r_head = $lang['yours'];
|
||||
} else {
|
||||
if($rev1 && isset($rev2) && $rev2) { // two specific revisions wanted
|
||||
// make sure order is correct (older on the left)
|
||||
if($rev1 < $rev2){
|
||||
if($rev1 < $rev2) {
|
||||
$l_rev = $rev1;
|
||||
$r_rev = $rev2;
|
||||
}else{
|
||||
} else {
|
||||
$l_rev = $rev2;
|
||||
$r_rev = $rev1;
|
||||
}
|
||||
}elseif($rev1){ // single revision given, compare to current
|
||||
} elseif($rev1) { // single revision given, compare to current
|
||||
$r_rev = '';
|
||||
$l_rev = $rev1;
|
||||
}else{ // no revision was given, compare previous to current
|
||||
} else { // no revision was given, compare previous to current
|
||||
$r_rev = '';
|
||||
$revs = getRevisions($ID, 0, 1);
|
||||
$revs = $pagelog->getRevisions(0, 1);
|
||||
$l_rev = $revs[0];
|
||||
$REV = $l_rev; // store revision back in $REV
|
||||
}
|
||||
|
||||
// when both revisions are empty then the page was created just now
|
||||
if(!$l_rev && !$r_rev){
|
||||
if(!$l_rev && !$r_rev) {
|
||||
$l_text = '';
|
||||
}else{
|
||||
$l_text = rawWiki($ID,$l_rev);
|
||||
} else {
|
||||
$l_text = rawWiki($ID, $l_rev);
|
||||
}
|
||||
$r_text = rawWiki($ID,$r_rev);
|
||||
$r_text = rawWiki($ID, $r_rev);
|
||||
|
||||
list($l_head, $r_head, $l_minor, $r_minor) = html_diff_head($l_rev, $r_rev, null, false, $type == 'inline');
|
||||
}
|
||||
|
||||
$df = new Diff(explode("\n",$l_text),explode("\n",$r_text));
|
||||
|
||||
if($type == 'inline'){
|
||||
$tdf = new InlineDiffFormatter();
|
||||
} else {
|
||||
$tdf = new TableDiffFormatter();
|
||||
/*
|
||||
* Build navigation
|
||||
*/
|
||||
$l_nav = '';
|
||||
$r_nav = '';
|
||||
if(!$text) {
|
||||
list($l_nav, $r_nav) = html_diff_navigation($pagelog, $type, $l_rev, $r_rev);
|
||||
}
|
||||
/*
|
||||
* Create diff object and the formatter
|
||||
*/
|
||||
$diff = new Diff(explode("\n", $l_text), explode("\n", $r_text));
|
||||
|
||||
if($type == 'inline') {
|
||||
$diffformatter = new InlineDiffFormatter();
|
||||
} else {
|
||||
$diffformatter = new TableDiffFormatter();
|
||||
}
|
||||
/*
|
||||
* Display intro
|
||||
*/
|
||||
if($intro) print p_locale_xhtml('diff');
|
||||
|
||||
if (!$text) {
|
||||
ptln('<div class="diffoptions">');
|
||||
/*
|
||||
* Display type and exact reference
|
||||
*/
|
||||
if(!$text) {
|
||||
ptln('<div class="diffoptions group">');
|
||||
|
||||
$form = new Doku_Form(array('action'=>wl()));
|
||||
$form->addHidden('id',$ID);
|
||||
$form->addHidden('rev2[0]',$l_rev);
|
||||
$form->addHidden('rev2[1]',$r_rev);
|
||||
$form->addHidden('do','diff');
|
||||
$form->addElement(form_makeListboxField(
|
||||
'difftype',
|
||||
array(
|
||||
'sidebyside' => $lang['diff_side'],
|
||||
'inline' => $lang['diff_inline']),
|
||||
$type,
|
||||
$lang['diff_type'],
|
||||
'','',
|
||||
array('class'=>'quickselect')));
|
||||
$form->addElement(form_makeButton('submit', 'diff','Go'));
|
||||
|
||||
$form = new Doku_Form(array('action' => wl()));
|
||||
$form->addHidden('id', $ID);
|
||||
$form->addHidden('rev2[0]', $l_rev);
|
||||
$form->addHidden('rev2[1]', $r_rev);
|
||||
$form->addHidden('do', 'diff');
|
||||
$form->addElement(
|
||||
form_makeListboxField(
|
||||
'difftype',
|
||||
array(
|
||||
'sidebyside' => $lang['diff_side'],
|
||||
'inline' => $lang['diff_inline']
|
||||
),
|
||||
$type,
|
||||
$lang['diff_type'],
|
||||
'', '',
|
||||
array('class' => 'quickselect')
|
||||
)
|
||||
);
|
||||
$form->addElement(form_makeButton('submit', 'diff', 'Go'));
|
||||
$form->printForm();
|
||||
|
||||
$diffurl = wl($ID, array(
|
||||
'do' => 'diff',
|
||||
'rev2[0]' => $l_rev,
|
||||
'rev2[1]' => $r_rev,
|
||||
'difftype' => $type,
|
||||
));
|
||||
ptln('<p><a class="wikilink1" href="'.$diffurl.'">'.$lang['difflink'].'</a></p>');
|
||||
ptln('</div>');
|
||||
ptln('<p>');
|
||||
// link to exactly this view FS#2835
|
||||
echo html_diff_navigationlink($type, 'difflink', $l_rev, $r_rev ? $r_rev : $INFO['currentrev']);
|
||||
ptln('</p>');
|
||||
|
||||
ptln('</div>'); // .diffoptions
|
||||
}
|
||||
|
||||
/*
|
||||
* Display diff view table
|
||||
*/
|
||||
?>
|
||||
<div class="table">
|
||||
<table class="diff diff_<?php echo $type?>">
|
||||
<?php if ($type == 'inline') { ?>
|
||||
<tr>
|
||||
<th class="diff-lineheader">-</th><th <?php echo $l_minor?>>
|
||||
<?php echo $l_head?>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="diff-lineheader">+</th><th <?php echo $r_minor?>>
|
||||
<?php echo $r_head?>
|
||||
</th>
|
||||
</tr>
|
||||
<?php } else { ?>
|
||||
<tr>
|
||||
<th colspan="2" <?php echo $l_minor?>>
|
||||
<?php echo $l_head?>
|
||||
</th>
|
||||
<th colspan="2" <?php echo $r_minor?>>
|
||||
<?php echo $r_head?>
|
||||
</th>
|
||||
</tr>
|
||||
<?php }
|
||||
echo html_insert_softbreaks($tdf->format($df)); ?>
|
||||
<table class="diff diff_<?php echo $type ?>">
|
||||
|
||||
<?php
|
||||
//navigation and header
|
||||
if($type == 'inline') {
|
||||
if(!$text) { ?>
|
||||
<tr>
|
||||
<td class="diff-lineheader">-</td>
|
||||
<td class="diffnav"><?php echo $l_nav ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="diff-lineheader">-</th>
|
||||
<th <?php echo $l_minor ?>>
|
||||
<?php echo $l_head ?>
|
||||
</th>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
<tr>
|
||||
<td class="diff-lineheader">+</td>
|
||||
<td class="diffnav"><?php echo $r_nav ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="diff-lineheader">+</th>
|
||||
<th <?php echo $r_minor ?>>
|
||||
<?php echo $r_head ?>
|
||||
</th>
|
||||
</tr>
|
||||
<?php } else {
|
||||
if(!$text) { ?>
|
||||
<tr>
|
||||
<td colspan="2" class="diffnav"><?php echo $l_nav ?></td>
|
||||
<td colspan="2" class="diffnav"><?php echo $r_nav ?></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
<tr>
|
||||
<th colspan="2" <?php echo $l_minor ?>>
|
||||
<?php echo $l_head ?>
|
||||
</th>
|
||||
<th colspan="2" <?php echo $r_minor ?>>
|
||||
<?php echo $r_head ?>
|
||||
</th>
|
||||
</tr>
|
||||
<?php }
|
||||
|
||||
//diff view
|
||||
echo html_insert_softbreaks($diffformatter->format($diff)); ?>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Create html for revision navigation
|
||||
*
|
||||
* @param PageChangeLog $pagelog changelog object of current page
|
||||
* @param string $type inline vs sidebyside
|
||||
* @param int $l_rev left revision timestamp
|
||||
* @param int $r_rev right revision timestamp
|
||||
* @return string[] html of left and right navigation elements
|
||||
*/
|
||||
function html_diff_navigation($pagelog, $type, $l_rev, $r_rev) {
|
||||
global $INFO, $ID;
|
||||
|
||||
// last timestamp is not in changelog, retrieve timestamp from metadata
|
||||
// note: when page is removed, the metadata timestamp is zero
|
||||
$r_rev = $r_rev ? $r_rev : $INFO['meta']['last_change']['date'];
|
||||
|
||||
//retrieve revisions with additional info
|
||||
list($l_revs, $r_revs) = $pagelog->getRevisionsAround($l_rev, $r_rev);
|
||||
$l_revisions = array();
|
||||
if(!$l_rev) {
|
||||
$l_revisions[0] = array(0, "", false); //no left revision given, add dummy
|
||||
}
|
||||
foreach($l_revs as $rev) {
|
||||
$info = $pagelog->getRevisionInfo($rev);
|
||||
$l_revisions[$rev] = array(
|
||||
$rev,
|
||||
dformat($info['date']) . ' ' . editorinfo($info['user'], true) . ' ' . $info['sum'],
|
||||
$r_rev ? $rev >= $r_rev : false //disable?
|
||||
);
|
||||
}
|
||||
$r_revisions = array();
|
||||
if(!$r_rev) {
|
||||
$r_revisions[0] = array(0, "", false); //no right revision given, add dummy
|
||||
}
|
||||
foreach($r_revs as $rev) {
|
||||
$info = $pagelog->getRevisionInfo($rev);
|
||||
$r_revisions[$rev] = array(
|
||||
$rev,
|
||||
dformat($info['date']) . ' ' . editorinfo($info['user'], true) . ' ' . $info['sum'],
|
||||
$rev <= $l_rev //disable?
|
||||
);
|
||||
}
|
||||
|
||||
//determine previous/next revisions
|
||||
$l_index = array_search($l_rev, $l_revs);
|
||||
$l_prev = $l_revs[$l_index + 1];
|
||||
$l_next = $l_revs[$l_index - 1];
|
||||
if($r_rev) {
|
||||
$r_index = array_search($r_rev, $r_revs);
|
||||
$r_prev = $r_revs[$r_index + 1];
|
||||
$r_next = $r_revs[$r_index - 1];
|
||||
} else {
|
||||
//removed page
|
||||
if($l_next) {
|
||||
$r_prev = $r_revs[0];
|
||||
} else {
|
||||
$r_prev = null;
|
||||
}
|
||||
$r_next = null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Left side:
|
||||
*/
|
||||
$l_nav = '';
|
||||
//move back
|
||||
if($l_prev) {
|
||||
$l_nav .= html_diff_navigationlink($type, 'diffbothprevrev', $l_prev, $r_prev);
|
||||
$l_nav .= html_diff_navigationlink($type, 'diffprevrev', $l_prev, $r_rev);
|
||||
}
|
||||
//dropdown
|
||||
$form = new Doku_Form(array('action' => wl()));
|
||||
$form->addHidden('id', $ID);
|
||||
$form->addHidden('difftype', $type);
|
||||
$form->addHidden('rev2[1]', $r_rev);
|
||||
$form->addHidden('do', 'diff');
|
||||
$form->addElement(
|
||||
form_makeListboxField(
|
||||
'rev2[0]',
|
||||
$l_revisions,
|
||||
$l_rev,
|
||||
'', '', '',
|
||||
array('class' => 'quickselect')
|
||||
)
|
||||
);
|
||||
$form->addElement(form_makeButton('submit', 'diff', 'Go'));
|
||||
$l_nav .= $form->getForm();
|
||||
//move forward
|
||||
if($l_next && ($l_next < $r_rev || !$r_rev)) {
|
||||
$l_nav .= html_diff_navigationlink($type, 'diffnextrev', $l_next, $r_rev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Right side:
|
||||
*/
|
||||
$r_nav = '';
|
||||
//move back
|
||||
if($l_rev < $r_prev) {
|
||||
$r_nav .= html_diff_navigationlink($type, 'diffprevrev', $l_rev, $r_prev);
|
||||
}
|
||||
//dropdown
|
||||
$form = new Doku_Form(array('action' => wl()));
|
||||
$form->addHidden('id', $ID);
|
||||
$form->addHidden('rev2[0]', $l_rev);
|
||||
$form->addHidden('difftype', $type);
|
||||
$form->addHidden('do', 'diff');
|
||||
$form->addElement(
|
||||
form_makeListboxField(
|
||||
'rev2[1]',
|
||||
$r_revisions,
|
||||
$r_rev,
|
||||
'', '', '',
|
||||
array('class' => 'quickselect')
|
||||
)
|
||||
);
|
||||
$form->addElement(form_makeButton('submit', 'diff', 'Go'));
|
||||
$r_nav .= $form->getForm();
|
||||
//move forward
|
||||
if($r_next) {
|
||||
if($pagelog->isCurrentRevision($r_next)) {
|
||||
$r_nav .= html_diff_navigationlink($type, 'difflastrev', $l_rev); //last revision is diff with current page
|
||||
} else {
|
||||
$r_nav .= html_diff_navigationlink($type, 'diffnextrev', $l_rev, $r_next);
|
||||
}
|
||||
$r_nav .= html_diff_navigationlink($type, 'diffbothnextrev', $l_next, $r_next);
|
||||
}
|
||||
return array($l_nav, $r_nav);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create html link to a diff defined by two revisions
|
||||
*
|
||||
* @param string $difftype display type
|
||||
* @param string $linktype
|
||||
* @param int $lrev oldest revision
|
||||
* @param int $rrev newest revision or null for diff with current revision
|
||||
* @return string html of link to a diff
|
||||
*/
|
||||
function html_diff_navigationlink($difftype, $linktype, $lrev, $rrev = null) {
|
||||
global $ID, $lang;
|
||||
if(!$rrev) {
|
||||
$urlparam = array(
|
||||
'do' => 'diff',
|
||||
'rev' => $lrev,
|
||||
'difftype' => $difftype,
|
||||
);
|
||||
} else {
|
||||
$urlparam = array(
|
||||
'do' => 'diff',
|
||||
'rev2[0]' => $lrev,
|
||||
'rev2[1]' => $rrev,
|
||||
'difftype' => $difftype,
|
||||
);
|
||||
}
|
||||
return '<a class="' . $linktype . '" href="' . wl($ID, $urlparam) . '" title="' . $lang[$linktype] . '">' .
|
||||
'<span>' . $lang[$linktype] . '</span>' .
|
||||
'</a>' . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert soft breaks in diff html
|
||||
*
|
||||
* @param $diffhtml
|
||||
* @return string
|
||||
*/
|
||||
function html_insert_softbreaks($diffhtml) {
|
||||
// search the diff html string for both:
|
||||
// - html tags, so these can be ignored
|
||||
|
@ -1232,6 +1489,12 @@ function html_insert_softbreaks($diffhtml) {
|
|||
return preg_replace_callback('/<[^>]*>|[^<> ]{12,}/','html_softbreak_callback',$diffhtml);
|
||||
}
|
||||
|
||||
/**
|
||||
* callback which adds softbreaks
|
||||
*
|
||||
* @param array $match array with first the complete match
|
||||
* @return string the replacement
|
||||
*/
|
||||
function html_softbreak_callback($match){
|
||||
// if match is an html tag, return it intact
|
||||
if ($match[0]{0} == '<') return $match[0];
|
||||
|
@ -1343,7 +1606,7 @@ function html_updateprofile(){
|
|||
global $conf;
|
||||
global $INPUT;
|
||||
global $INFO;
|
||||
/** @var auth_basic $auth */
|
||||
/** @var DokuWiki_Auth_Plugin $auth */
|
||||
global $auth;
|
||||
|
||||
print p_locale_xhtml('updateprofile');
|
||||
|
@ -1517,6 +1780,7 @@ function html_edit(){
|
|||
* Display the default edit form
|
||||
*
|
||||
* Is the default action for HTML_EDIT_FORMSELECTION.
|
||||
* @param mixed[] $param
|
||||
*/
|
||||
function html_edit_form($param) {
|
||||
global $TEXT;
|
||||
|
@ -1559,7 +1823,7 @@ function html_minoredit(){
|
|||
function html_debug(){
|
||||
global $conf;
|
||||
global $lang;
|
||||
/** @var auth_basic $auth */
|
||||
/** @var DokuWiki_Auth_Plugin $auth */
|
||||
global $auth;
|
||||
global $INFO;
|
||||
|
||||
|
@ -1634,6 +1898,17 @@ function html_debug(){
|
|||
print_r($inis);
|
||||
print '</pre>';
|
||||
|
||||
if (function_exists('apache_get_version')) {
|
||||
$apache['version'] = apache_get_version();
|
||||
|
||||
if (function_exists('apache_get_modules')) {
|
||||
$apache['modules'] = apache_get_modules();
|
||||
}
|
||||
print '<b>Apache</b><pre>';
|
||||
print_r($apache);
|
||||
print '</pre>';
|
||||
}
|
||||
|
||||
print '</body></html>';
|
||||
}
|
||||
|
||||
|
|
|
@ -64,12 +64,13 @@ function http_conditionalRequest($timestamp){
|
|||
* Let the webserver send the given file via x-sendfile method
|
||||
*
|
||||
* @author Chris Smith <chris@jalakai.co.uk>
|
||||
* @returns void or exits with previously header() commands executed
|
||||
* @param string $file absolute path of file to send
|
||||
* @returns void or exits with previous header() commands executed
|
||||
*/
|
||||
function http_sendfile($file) {
|
||||
global $conf;
|
||||
|
||||
//use x-sendfile header to pass the delivery to compatible webservers
|
||||
//use x-sendfile header to pass the delivery to compatible web servers
|
||||
if($conf['xsendfile'] == 1){
|
||||
header("X-LIGHTTPD-send-file: $file");
|
||||
ob_end_clean();
|
||||
|
@ -79,12 +80,12 @@ function http_sendfile($file) {
|
|||
ob_end_clean();
|
||||
exit;
|
||||
}elseif($conf['xsendfile'] == 3){
|
||||
// FS#2388 nginx just needs the relative path.
|
||||
$file = DOKU_REL.substr($file, strlen(fullpath(DOKU_INC)) + 1);
|
||||
header("X-Accel-Redirect: $file");
|
||||
ob_end_clean();
|
||||
exit;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,7 +93,7 @@ function http_sendfile($file) {
|
|||
*
|
||||
* This function exits the running script
|
||||
*
|
||||
* @param ressource $fh - file handle for an already open file
|
||||
* @param resource $fh - file handle for an already open file
|
||||
* @param int $size - size of the whole file
|
||||
* @param int $mime - MIME type of the file
|
||||
*
|
||||
|
@ -204,7 +205,7 @@ function http_gzip_valid($uncompressed_file) {
|
|||
*
|
||||
* This function handles output of cacheable resource files. It ses the needed
|
||||
* HTTP headers. If a useable cache is present, it is passed to the web server
|
||||
* and the scrpt is terminated.
|
||||
* and the script is terminated.
|
||||
*/
|
||||
function http_cached($cache, $cache_ok) {
|
||||
global $conf;
|
||||
|
@ -223,7 +224,8 @@ function http_cached($cache, $cache_ok) {
|
|||
header('Content-Encoding: gzip');
|
||||
readfile($cache.".gz");
|
||||
} else {
|
||||
if (!http_sendfile($cache)) readfile($cache);
|
||||
http_sendfile($cache);
|
||||
readfile($cache);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
|
|
@ -270,8 +270,9 @@ class Doku_Indexer {
|
|||
// Special handling for titles so the index file is simpler
|
||||
if (array_key_exists('title', $key)) {
|
||||
$value = $key['title'];
|
||||
if (is_array($value))
|
||||
if (is_array($value)) {
|
||||
$value = $value[0];
|
||||
}
|
||||
$this->saveIndexKey('title', '', $pid, $value);
|
||||
unset($key['title']);
|
||||
}
|
||||
|
@ -299,20 +300,24 @@ class Doku_Indexer {
|
|||
if ($val !== "") {
|
||||
$id = array_search($val, $metawords, true);
|
||||
if ($id === false) {
|
||||
// didn't find $val, so we'll add it to the end of metawords and create a placeholder in metaidx
|
||||
$id = count($metawords);
|
||||
$metawords[$id] = $val;
|
||||
$metaidx[$id] = '';
|
||||
$addwords = true;
|
||||
}
|
||||
// test if value is already in the index
|
||||
if (isset($val_idx[$id]) && $val_idx[$id] <= 0)
|
||||
if (isset($val_idx[$id]) && $val_idx[$id] <= 0){
|
||||
$val_idx[$id] = 0;
|
||||
else // else add it
|
||||
} else { // else add it
|
||||
$val_idx[$id] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($addwords)
|
||||
if ($addwords) {
|
||||
$this->saveIndex($metaname.'_w', '', $metawords);
|
||||
}
|
||||
$vals_changed = false;
|
||||
foreach ($val_idx as $id => $action) {
|
||||
if ($action == -1) {
|
||||
|
@ -1213,17 +1218,18 @@ class Doku_Indexer {
|
|||
* @author Tom N Harris <tnharris@whoopdedo.org>
|
||||
*/
|
||||
protected function updateTuple($line, $id, $count) {
|
||||
$newLine = $line;
|
||||
if ($newLine !== '')
|
||||
$newLine = preg_replace('/(^|:)'.preg_quote($id,'/').'\*\d*/', '', $newLine);
|
||||
$newLine = trim($newLine, ':');
|
||||
if ($count) {
|
||||
if (strlen($newLine) > 0)
|
||||
return "$id*$count:".$newLine;
|
||||
else
|
||||
return "$id*$count".$newLine;
|
||||
if ($line != ''){
|
||||
$line = preg_replace('/(^|:)'.preg_quote($id,'/').'\*\d*/', '', $line);
|
||||
}
|
||||
return $newLine;
|
||||
$line = trim($line, ':');
|
||||
if ($count) {
|
||||
if ($line) {
|
||||
return "$id*$count:".$line;
|
||||
} else {
|
||||
return "$id*$count";
|
||||
}
|
||||
}
|
||||
return $line;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -102,15 +102,21 @@ function getVersion(){
|
|||
function check(){
|
||||
global $conf;
|
||||
global $INFO;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
if ($INFO['isadmin'] || $INFO['ismanager']){
|
||||
msg('DokuWiki version: '.getVersion(),1);
|
||||
}
|
||||
|
||||
if(version_compare(phpversion(),'5.2.0','<')){
|
||||
msg('Your PHP version is too old ('.phpversion().' vs. 5.2.0+ needed)',-1);
|
||||
}else{
|
||||
msg('PHP version '.phpversion(),1);
|
||||
if(version_compare(phpversion(),'5.2.0','<')){
|
||||
msg('Your PHP version is too old ('.phpversion().' vs. 5.2.0+ needed)',-1);
|
||||
}else{
|
||||
msg('PHP version '.phpversion(),1);
|
||||
}
|
||||
} else {
|
||||
if(version_compare(phpversion(),'5.2.0','<')){
|
||||
msg('Your PHP version is too old',-1);
|
||||
}
|
||||
}
|
||||
|
||||
$mem = (int) php_to_byte(ini_get('memory_limit'));
|
||||
|
@ -200,7 +206,7 @@ function check(){
|
|||
}
|
||||
|
||||
if($INFO['userinfo']['name']){
|
||||
msg('You are currently logged in as '.$_SERVER['REMOTE_USER'].' ('.$INFO['userinfo']['name'].')',0);
|
||||
msg('You are currently logged in as '.$INPUT->server->str('REMOTE_USER').' ('.$INFO['userinfo']['name'].')',0);
|
||||
msg('You are part of the groups '.join($INFO['userinfo']['grps'],', '),0);
|
||||
}else{
|
||||
msg('You are currently not logged in',0);
|
||||
|
@ -274,6 +280,15 @@ define('MSG_USERS_ONLY', 1);
|
|||
define('MSG_MANAGERS_ONLY',2);
|
||||
define('MSG_ADMINS_ONLY',4);
|
||||
|
||||
/**
|
||||
* Display a message to the user
|
||||
*
|
||||
* @param string $message
|
||||
* @param int $lvl -1 = error, 0 = info, 1 = success, 2 = notify
|
||||
* @param string $line line number
|
||||
* @param string $file file number
|
||||
* @param int $allow who's allowed to see the message, see MSG_* constants
|
||||
*/
|
||||
function msg($message,$lvl=0,$line='',$file='',$allow=MSG_PUBLIC){
|
||||
global $MSG, $MSG_shown;
|
||||
$errors[-1] = 'error';
|
||||
|
@ -303,6 +318,7 @@ function msg($message,$lvl=0,$line='',$file='',$allow=MSG_PUBLIC){
|
|||
* lvl => int, level of the message (see msg() function)
|
||||
* allow => int, flag used to determine who is allowed to see the message
|
||||
* see MSG_* constants
|
||||
* @return bool
|
||||
*/
|
||||
function info_msg_allowed($msg){
|
||||
global $INFO, $auth;
|
||||
|
@ -357,6 +373,9 @@ function dbg($msg,$hidden=false){
|
|||
*/
|
||||
function dbglog($msg,$header=''){
|
||||
global $conf;
|
||||
/* @var Input $INPUT */
|
||||
global $INPUT;
|
||||
|
||||
// The debug log isn't automatically cleaned thus only write it when
|
||||
// debugging has been enabled by the user.
|
||||
if($conf['allowdebug'] !== 1) return;
|
||||
|
@ -369,11 +388,37 @@ function dbglog($msg,$header=''){
|
|||
$file = $conf['cachedir'].'/debug.log';
|
||||
$fh = fopen($file,'a');
|
||||
if($fh){
|
||||
fwrite($fh,date('H:i:s ').$_SERVER['REMOTE_ADDR'].': '.$msg."\n");
|
||||
fwrite($fh,date('H:i:s ').$INPUT->server->str('REMOTE_ADDR').': '.$msg."\n");
|
||||
fclose($fh);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log accesses to deprecated fucntions to the debug log
|
||||
*
|
||||
* @param string $alternative The function or method that should be used instead
|
||||
*/
|
||||
function dbg_deprecated($alternative = '') {
|
||||
global $conf;
|
||||
if(!$conf['allowdebug']) return;
|
||||
|
||||
$backtrace = debug_backtrace();
|
||||
array_shift($backtrace);
|
||||
$self = array_shift($backtrace);
|
||||
$call = array_shift($backtrace);
|
||||
|
||||
$called = trim($self['class'].'::'.$self['function'].'()', ':');
|
||||
$caller = trim($call['class'].'::'.$call['function'].'()', ':');
|
||||
|
||||
$msg = $called.' is deprecated. It was called from ';
|
||||
$msg .= $caller.' in '.$call['file'].':'.$call['line'];
|
||||
if($alternative) {
|
||||
$msg .= ' '.$alternative.' should be used instead!';
|
||||
}
|
||||
|
||||
dbglog($msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a reversed, prettyprinted backtrace
|
||||
*
|
||||
|
|
38
inc/init.php
38
inc/init.php
|
@ -140,18 +140,21 @@ if ($conf['gzip_output'] &&
|
|||
}
|
||||
|
||||
// init session
|
||||
if (!headers_sent() && !defined('NOSESSION')){
|
||||
session_name("DokuWiki");
|
||||
$cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
|
||||
if (version_compare(PHP_VERSION, '5.2.0', '>')) {
|
||||
session_set_cookie_params(0,$cookieDir,'',($conf['securecookie'] && is_ssl()),true);
|
||||
}else{
|
||||
session_set_cookie_params(0,$cookieDir,'',($conf['securecookie'] && is_ssl()));
|
||||
if(!headers_sent() && !defined('NOSESSION')) {
|
||||
if(!defined('DOKU_SESSION_NAME')) define ('DOKU_SESSION_NAME', "DokuWiki");
|
||||
if(!defined('DOKU_SESSION_LIFETIME')) define ('DOKU_SESSION_LIFETIME', 0);
|
||||
if(!defined('DOKU_SESSION_PATH')) {
|
||||
$cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
|
||||
define ('DOKU_SESSION_PATH', $cookieDir);
|
||||
}
|
||||
if(!defined('DOKU_SESSION_DOMAIN')) define ('DOKU_SESSION_DOMAIN', '');
|
||||
|
||||
session_name(DOKU_SESSION_NAME);
|
||||
session_set_cookie_params(DOKU_SESSION_LIFETIME, DOKU_SESSION_PATH, DOKU_SESSION_DOMAIN, ($conf['securecookie'] && is_ssl()), true);
|
||||
session_start();
|
||||
|
||||
// load left over messages
|
||||
if(isset($_SESSION[DOKU_COOKIE]['msg'])){
|
||||
if(isset($_SESSION[DOKU_COOKIE]['msg'])) {
|
||||
$MSG = $_SESSION[DOKU_COOKIE]['msg'];
|
||||
unset($_SESSION[DOKU_COOKIE]['msg']);
|
||||
}
|
||||
|
@ -173,7 +176,7 @@ if(function_exists('set_magic_quotes_runtime')) @set_magic_quotes_runtime(0);
|
|||
$_REQUEST = array_merge($_GET,$_POST);
|
||||
|
||||
// we don't want a purge URL to be digged
|
||||
if(isset($_REQUEST['purge']) && $_SERVER['HTTP_REFERER']) unset($_REQUEST['purge']);
|
||||
if(isset($_REQUEST['purge']) && !empty($_SERVER['HTTP_REFERER'])) unset($_REQUEST['purge']);
|
||||
|
||||
// disable gzip if not available
|
||||
if($conf['compression'] == 'bz2' && !function_exists('bzopen')){
|
||||
|
@ -183,11 +186,6 @@ if($conf['compression'] == 'gz' && !function_exists('gzopen')){
|
|||
$conf['compression'] = 0;
|
||||
}
|
||||
|
||||
// fix dateformat for upgraders
|
||||
if(strpos($conf['dformat'],'%') === false){
|
||||
$conf['dformat'] = '%Y/%m/%d %H:%M';
|
||||
}
|
||||
|
||||
// precalculate file creation modes
|
||||
init_creationmodes();
|
||||
|
||||
|
@ -404,6 +402,10 @@ function remove_magic_quotes(&$array) {
|
|||
* Returns the full absolute URL to the directory where
|
||||
* DokuWiki is installed in (includes a trailing slash)
|
||||
*
|
||||
* !! Can not access $_SERVER values through $INPUT
|
||||
* !! here as this function is called before $INPUT is
|
||||
* !! initialized.
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*/
|
||||
function getBaseURL($abs=null){
|
||||
|
@ -443,12 +445,12 @@ function getBaseURL($abs=null){
|
|||
//split hostheader into host and port
|
||||
if(isset($_SERVER['HTTP_HOST'])){
|
||||
$parsed_host = parse_url('http://'.$_SERVER['HTTP_HOST']);
|
||||
$host = $parsed_host['host'];
|
||||
$port = $parsed_host['port'];
|
||||
$host = isset($parsed_host['host']) ? $parsed_host['host'] : null;
|
||||
$port = isset($parsed_host['port']) ? $parsed_host['port'] : null;
|
||||
}elseif(isset($_SERVER['SERVER_NAME'])){
|
||||
$parsed_host = parse_url('http://'.$_SERVER['SERVER_NAME']);
|
||||
$host = $parsed_host['host'];
|
||||
$port = $parsed_host['port'];
|
||||
$host = isset($parsed_host['host']) ? $parsed_host['host'] : null;
|
||||
$port = isset($parsed_host['port']) ? $parsed_host['port'] : null;
|
||||
}else{
|
||||
$host = php_uname('n');
|
||||
$port = '';
|
||||
|
|
|
@ -367,8 +367,6 @@ function io_createNamespace($id, $ns_type='pages') {
|
|||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*/
|
||||
function io_makeFileDir($file){
|
||||
global $conf;
|
||||
|
||||
$dir = dirname($file);
|
||||
if(!@is_dir($dir)){
|
||||
io_mkdir_p($dir) || msg("Creating directory $dir failed",-1);
|
||||
|
|
|
@ -25,7 +25,7 @@ $lang['btn_back'] = 'Terug';
|
|||
$lang['btn_backlink'] = 'Wat skakel hierheen';
|
||||
$lang['btn_subscribe'] = 'Hou bladsy dop';
|
||||
$lang['btn_register'] = 'Skep gerus \'n rekening';
|
||||
$lang['loggedinas'] = 'Ingeteken as';
|
||||
$lang['loggedinas'] = 'Ingeteken as:';
|
||||
$lang['user'] = 'Gebruikernaam';
|
||||
$lang['pass'] = 'Wagwoord';
|
||||
$lang['newpass'] = 'Nuive wagwoord';
|
||||
|
@ -52,7 +52,7 @@ $lang['mediaroot'] = 'root';
|
|||
$lang['toc'] = 'Inhoud';
|
||||
$lang['current'] = 'huidige';
|
||||
$lang['line'] = 'Streak';
|
||||
$lang['youarehere'] = 'Jy is hier';
|
||||
$lang['youarehere'] = 'Jy is hier:';
|
||||
$lang['by'] = 'by';
|
||||
$lang['restored'] = 'Het terug gegaan na vroeëre weergawe (%s)';
|
||||
$lang['summary'] = 'Voorskou';
|
||||
|
@ -63,8 +63,8 @@ $lang['qb_extlink'] = 'Eksterne skakel';
|
|||
$lang['qb_hr'] = 'Horisontale streep';
|
||||
$lang['qb_sig'] = 'Handtekening met datum';
|
||||
$lang['admin_register'] = 'Skep gerus \'n rekening';
|
||||
$lang['img_backto'] = 'Terug na';
|
||||
$lang['img_date'] = 'Datem';
|
||||
$lang['img_camera'] = 'Camera';
|
||||
$lang['btn_img_backto'] = 'Terug na %s';
|
||||
$lang['img_date'] = 'Datem:';
|
||||
$lang['img_camera'] = 'Camera:';
|
||||
$lang['i_wikiname'] = 'Wiki Naam';
|
||||
$lang['i_funcna'] = 'PHP funksie <code>%s</code> is nie beskibaar nie. Miskien is dit af gehaal.';
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
====== لا صلاحيات ======
|
||||
|
||||
عذرا، ليس مصرح لك الاستمرار، لعلك نسيت تسجيل الدخول؟
|
||||
عذرا، ليس مصرح لك الاستمرار
|
|
@ -53,7 +53,7 @@ $lang['btn_register'] = 'سجّل';
|
|||
$lang['btn_apply'] = 'طبق';
|
||||
$lang['btn_media'] = 'مدير الوسائط';
|
||||
$lang['btn_deleteuser'] = 'احذف حسابي الخاص';
|
||||
$lang['loggedinas'] = 'داخل باسم';
|
||||
$lang['loggedinas'] = 'داخل باسم:';
|
||||
$lang['user'] = 'اسم المستخدم';
|
||||
$lang['pass'] = 'كلمة السر';
|
||||
$lang['newpass'] = 'كلمة سر جديدة';
|
||||
|
@ -98,12 +98,12 @@ $lang['license'] = 'مالم يشر لخلاف ذلك، فإن ا
|
|||
$lang['licenseok'] = 'لاحظ: بتحرير هذه الصفحة أنت توافق على ترخيص محتواها تحت الرخصة التالية:';
|
||||
$lang['searchmedia'] = 'ابحث في أسماء الملفات:';
|
||||
$lang['searchmedia_in'] = 'ابحث في %s';
|
||||
$lang['txt_upload'] = 'اختر ملفاً للرفع';
|
||||
$lang['txt_filename'] = 'رفع كـ (اختياري)';
|
||||
$lang['txt_upload'] = 'اختر ملفاً للرفع:';
|
||||
$lang['txt_filename'] = 'رفع كـ (اختياري):';
|
||||
$lang['txt_overwrt'] = 'اكتب على ملف موجود';
|
||||
$lang['maxuploadsize'] = 'الحجم الاقصى %s للملف';
|
||||
$lang['lockedby'] = 'مقفلة حاليا لـ';
|
||||
$lang['lockexpire'] = 'ينتهي القفل في';
|
||||
$lang['lockedby'] = 'مقفلة حاليا لـ:';
|
||||
$lang['lockexpire'] = 'ينتهي القفل في:';
|
||||
$lang['js']['willexpire'] = 'سينتهي قفل تحرير هذه الصفحه خلال دقيقة.\nلتجنب التعارض استخدم زر المعاينة لتصفير مؤقت القفل.';
|
||||
$lang['js']['notsavedyet'] = 'التعديلات غير المحفوظة ستفقد.';
|
||||
$lang['js']['searchmedia'] = 'ابحث عن ملفات';
|
||||
|
@ -184,9 +184,9 @@ $lang['diff_type'] = 'أظهر الفروق:';
|
|||
$lang['diff_inline'] = 'ضمنا';
|
||||
$lang['diff_side'] = 'جنبا إلى جنب';
|
||||
$lang['line'] = 'سطر';
|
||||
$lang['breadcrumb'] = 'أثر';
|
||||
$lang['youarehere'] = 'أنت هنا';
|
||||
$lang['lastmod'] = 'آخر تعديل';
|
||||
$lang['breadcrumb'] = 'أثر:';
|
||||
$lang['youarehere'] = 'أنت هنا:';
|
||||
$lang['lastmod'] = 'آخر تعديل:';
|
||||
$lang['by'] = 'بواسطة';
|
||||
$lang['deleted'] = 'حذفت';
|
||||
$lang['created'] = 'اُنشئت';
|
||||
|
@ -239,20 +239,20 @@ $lang['admin_register'] = 'أضف مستخدما جديدا';
|
|||
$lang['metaedit'] = 'تحرير البيانات الشمولية ';
|
||||
$lang['metasaveerr'] = 'فشلت كتابة البيانات الشمولية';
|
||||
$lang['metasaveok'] = 'حُفظت البيانات الشمولية';
|
||||
$lang['img_backto'] = 'عودة إلى';
|
||||
$lang['img_title'] = 'العنوان';
|
||||
$lang['img_caption'] = 'وصف';
|
||||
$lang['img_date'] = 'التاريخ';
|
||||
$lang['img_fname'] = 'اسم الملف';
|
||||
$lang['img_fsize'] = 'الحجم';
|
||||
$lang['img_artist'] = 'المصور';
|
||||
$lang['img_copyr'] = 'حقوق النسخ';
|
||||
$lang['img_format'] = 'الهيئة';
|
||||
$lang['img_camera'] = 'الكمرا';
|
||||
$lang['img_keywords'] = 'كلمات مفتاحية';
|
||||
$lang['img_width'] = 'العرض';
|
||||
$lang['img_height'] = 'الإرتفاع';
|
||||
$lang['img_manager'] = 'اعرض في مدير الوسائط';
|
||||
$lang['btn_img_backto'] = 'عودة إلى %s';
|
||||
$lang['img_title'] = 'العنوان:';
|
||||
$lang['img_caption'] = 'وصف:';
|
||||
$lang['img_date'] = 'التاريخ:';
|
||||
$lang['img_fname'] = 'اسم الملف:';
|
||||
$lang['img_fsize'] = 'الحجم:';
|
||||
$lang['img_artist'] = 'المصور:';
|
||||
$lang['img_copyr'] = 'حقوق النسخ:';
|
||||
$lang['img_format'] = 'الهيئة:';
|
||||
$lang['img_camera'] = 'الكمرا:';
|
||||
$lang['img_keywords'] = 'كلمات مفتاحية:';
|
||||
$lang['img_width'] = 'العرض:';
|
||||
$lang['img_height'] = 'الإرتفاع:';
|
||||
$lang['btn_mediaManager'] = 'اعرض في مدير الوسائط';
|
||||
$lang['subscr_subscribe_success'] = 'اضيف %s لقائمة اشتراك %s';
|
||||
$lang['subscr_subscribe_error'] = 'خطأ في إضافة %s لقائمة اشتراك %s';
|
||||
$lang['subscr_subscribe_noaddress'] = 'ليس هناك عنوان مرتبط بولوجك، لا يمكن اضافتك لقائمة الاشتراك';
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
====== Müraciət qadağan edilmişdir ======
|
||||
|
||||
Sizin bu əməliyyat üçün kifayət qədər haqqınız yoxdur. Bəlkə, Siz sistemə oz istifadəçi adınız ilə girməyi unutmusunuz?
|
||||
Sizin bu əməliyyat üçün kifayət qədər haqqınız yoxdur.
|
||||
|
|
|
@ -44,7 +44,7 @@ $lang['btn_recover'] = 'Qaralamanı qaytar';
|
|||
$lang['btn_draftdel'] = 'Qaralamanı sil';
|
||||
$lang['btn_revert'] = 'Qaytar';
|
||||
$lang['btn_register'] = 'Qeydiyyatdan keç';
|
||||
$lang['loggedinas'] = 'İstifadəcinin adı';
|
||||
$lang['loggedinas'] = 'İstifadəcinin adı:';
|
||||
$lang['user'] = 'istifadəci adı';
|
||||
$lang['pass'] = 'Şifrə';
|
||||
$lang['newpass'] = 'Yeni şifrə';
|
||||
|
@ -82,10 +82,10 @@ $lang['license'] = 'Fərqli şey göstərilmiş hallardan başqa,
|
|||
$lang['licenseok'] = 'Qeyd: bu səhifəni düzəliş edərək, Siz elədiyiniz düzəlişi aşağıda göstərilmiş lisenziyanın şərtlərinə uyğun istifadəsinə razılıq verirsiniz:';
|
||||
$lang['searchmedia'] = 'Faylın adına görə axtarış:';
|
||||
$lang['searchmedia_in'] = '%s-ın içində axtarış';
|
||||
$lang['txt_upload'] = 'Serverə yükləmək üçün fayl seçin';
|
||||
$lang['txt_filename'] = 'Faylın wiki-də olan adını daxil edin (mütləq deyil)';
|
||||
$lang['txt_upload'] = 'Serverə yükləmək üçün fayl seçin:';
|
||||
$lang['txt_filename'] = 'Faylın wiki-də olan adını daxil edin (mütləq deyil):';
|
||||
$lang['txt_overwrt'] = 'Mövcud olan faylın üstündən yaz';
|
||||
$lang['lockedby'] = 'В данный момент заблокирован Bu an blokdadır';
|
||||
$lang['lockedby'] = 'В данный момент заблокирован Bu an blokdadır:';
|
||||
$lang['lockexpire'] = 'Blok bitir:';
|
||||
$lang['js']['willexpire'] = 'Sizin bu səhifədə dəyişik etmək üçün blokunuz bir dəqiqə ərzində bitəcək.\nMünaqişələrdən yayınmaq və blokun taymerini sıfırlamaq üçün, baxış düyməsini sıxın.';
|
||||
$lang['rssfailed'] = 'Aşağıda göstərilmiş xəbər lentini əldə edən zaman xəta baş verdi: ';
|
||||
|
@ -128,9 +128,9 @@ $lang['yours'] = 'Sizin versiyanız';
|
|||
$lang['diff'] = 'hazırki versiyadan fərqləri göstər';
|
||||
$lang['diff2'] = 'Versiyaların arasındaki fərqləri göstər ';
|
||||
$lang['line'] = 'Sətr';
|
||||
$lang['breadcrumb'] = 'Siz ziyarət etdiniz';
|
||||
$lang['youarehere'] = 'Siz burdasınız';
|
||||
$lang['lastmod'] = 'Son dəyişiklər';
|
||||
$lang['breadcrumb'] = 'Siz ziyarət etdiniz:';
|
||||
$lang['youarehere'] = 'Siz burdasınız:';
|
||||
$lang['lastmod'] = 'Son dəyişiklər:';
|
||||
$lang['by'] = ' Kimdən';
|
||||
$lang['deleted'] = 'silinib';
|
||||
$lang['created'] = 'yaranıb';
|
||||
|
@ -172,17 +172,17 @@ $lang['admin_register'] = 'İstifadəçi əlavə et';
|
|||
$lang['metaedit'] = 'Meta-məlumatlarda düzəliş et';
|
||||
$lang['metasaveerr'] = 'Meta-məlumatları yazan zamanı xəta';
|
||||
$lang['metasaveok'] = 'Meta-məlumatlar yadda saxlandı';
|
||||
$lang['img_backto'] = 'Qayıd';
|
||||
$lang['img_title'] = 'Başlıq';
|
||||
$lang['img_caption'] = 'İmza';
|
||||
$lang['img_date'] = 'Tarix';
|
||||
$lang['img_fname'] = 'Faylın adı';
|
||||
$lang['img_fsize'] = 'Boy';
|
||||
$lang['img_artist'] = 'Şkilin müəllifi';
|
||||
$lang['img_copyr'] = 'Müəllif hüquqları';
|
||||
$lang['img_format'] = 'Format';
|
||||
$lang['img_camera'] = 'Model';
|
||||
$lang['img_keywords'] = 'Açar sözlər';
|
||||
$lang['btn_img_backto'] = 'Qayıd %s';
|
||||
$lang['img_title'] = 'Başlıq:';
|
||||
$lang['img_caption'] = 'İmza:';
|
||||
$lang['img_date'] = 'Tarix:';
|
||||
$lang['img_fname'] = 'Faylın adı:';
|
||||
$lang['img_fsize'] = 'Boy:';
|
||||
$lang['img_artist'] = 'Şkilin müəllifi:';
|
||||
$lang['img_copyr'] = 'Müəllif hüquqları:';
|
||||
$lang['img_format'] = 'Format:';
|
||||
$lang['img_camera'] = 'Model:';
|
||||
$lang['img_keywords'] = 'Açar sözlər:';
|
||||
$lang['authtempfail'] = 'İstifadəçilərin autentifikasiyası müvəqqəti dayandırılıb. Əgər bu problem uzun müddət davam edir sə, administrator ilə əlaqə saxlayın.';
|
||||
$lang['i_chooselang'] = 'Dili seçin/Language';
|
||||
$lang['i_installer'] = 'DokuWiki quraşdırılır';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
====== Отказан достъп ======
|
||||
|
||||
Нямате достатъчно права, за да продължите. Може би сте забравили да се впишете?
|
||||
Нямате достатъчно права, за да продължите.
|
||||
|
||||
|
|
|
@ -50,8 +50,8 @@ $lang['btn_revert'] = 'Възстановяване';
|
|||
$lang['btn_register'] = 'Регистриране';
|
||||
$lang['btn_apply'] = 'Прилагане';
|
||||
$lang['btn_media'] = 'Диспечер на файлове';
|
||||
$lang['btn_deleteuser'] = 'Изтрий профила ми';
|
||||
$lang['loggedinas'] = 'Вписани сте като';
|
||||
$lang['btn_deleteuser'] = 'Изтриване на профила';
|
||||
$lang['loggedinas'] = 'Вписани сте като:';
|
||||
$lang['user'] = 'Потребител';
|
||||
$lang['pass'] = 'Парола';
|
||||
$lang['newpass'] = 'Нова парола';
|
||||
|
@ -62,7 +62,7 @@ $lang['fullname'] = 'Истинско име';
|
|||
$lang['email'] = 'Електронна поща';
|
||||
$lang['profile'] = 'Потребителски профил';
|
||||
$lang['badlogin'] = 'Грешно потребителско име или парола.';
|
||||
$lang['badpassconfirm'] = 'Съжаляваме, паролата е грешна';
|
||||
$lang['badpassconfirm'] = 'За съжаление паролата е грешна';
|
||||
$lang['minoredit'] = 'Промените са незначителни';
|
||||
$lang['draftdate'] = 'Черновата е автоматично записана на';
|
||||
$lang['nosecedit'] = 'Страницата бе междувременно променена, презареждане на страницата поради неактуална информация.';
|
||||
|
@ -77,13 +77,13 @@ $lang['regpwmail'] = 'Паролата ви за DokuWiki';
|
|||
$lang['reghere'] = 'Все още нямате профил? Направете си';
|
||||
$lang['profna'] = 'Wiki-то не поддържа промяна на профила';
|
||||
$lang['profnochange'] = 'Няма промени.';
|
||||
$lang['profnoempty'] = 'Въвеждането на име и ел. поща е задължително';
|
||||
$lang['profnoempty'] = 'Въвеждането на име и имейл е задължително';
|
||||
$lang['profchanged'] = 'Потребителският профил е обновен успешно.';
|
||||
$lang['profnodelete'] = 'Не е възможно изтриване на потребители в това wiki ';
|
||||
$lang['profdeleteuser'] = 'Изтрий профила ми';
|
||||
$lang['profnodelete'] = 'Изтриването на потребители в това wiki не е възможно';
|
||||
$lang['profdeleteuser'] = 'Изтриване на профила';
|
||||
$lang['profdeleted'] = 'Вашият профил е премахнат от това wiki ';
|
||||
$lang['profconfdelete'] = 'Искам да изтрия профила си от това wiki. <br/> Веднъж изтрит, профила не може да бъде възстановен!';
|
||||
$lang['profconfdeletemissing'] = 'Не и маркирана опцията за потвърждение';
|
||||
$lang['profconfdelete'] = 'Искам да изтрия профила си от това wiki. <br/> Веднъж изтрит, профилът не може да бъде възстановен!';
|
||||
$lang['profconfdeletemissing'] = 'Не сте поставили отметка в кутията потвърждение';
|
||||
$lang['pwdforget'] = 'Забравили сте паролата си? Получете нова';
|
||||
$lang['resendna'] = 'Wiki-то не поддържа повторно пращане на паролата.';
|
||||
$lang['resendpwd'] = 'Задаване на нова парола за';
|
||||
|
@ -96,12 +96,12 @@ $lang['license'] = 'Ако не е посочено друго, с
|
|||
$lang['licenseok'] = 'Бележка: Редактирайки страницата, Вие се съгласявате да лицензирате промените (които сте направили) под следния лиценз:';
|
||||
$lang['searchmedia'] = 'Търсене на файл: ';
|
||||
$lang['searchmedia_in'] = 'Търсене в %s';
|
||||
$lang['txt_upload'] = 'Изберете файл за качване';
|
||||
$lang['txt_filename'] = 'Качи като (незадължително)';
|
||||
$lang['txt_upload'] = 'Изберете файл за качване:';
|
||||
$lang['txt_filename'] = 'Качи като (незадължително):';
|
||||
$lang['txt_overwrt'] = 'Презапиши съществуващите файлове';
|
||||
$lang['maxuploadsize'] = 'Макс. размер за отделните файлове е %s.';
|
||||
$lang['lockedby'] = 'В момента е заключена от';
|
||||
$lang['lockexpire'] = 'Ще бъде отключена на';
|
||||
$lang['lockedby'] = 'В момента е заключена от:';
|
||||
$lang['lockexpire'] = 'Ще бъде отключена на:';
|
||||
$lang['js']['willexpire'] = 'Страницата ще бъде отключена за редактиране след минута.\nЗа предотвратяване на конфликти, ползвайте бутона "Преглед", за рестартиране на брояча за заключване.';
|
||||
$lang['js']['notsavedyet'] = 'Незаписаните промени ще бъдат загубени. Желаете ли да продължите?';
|
||||
$lang['js']['searchmedia'] = 'Търсене на файлове';
|
||||
|
@ -140,7 +140,7 @@ $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_drop'] = 'Влачете и пуснете файлове тук, за да бъдат качени';
|
||||
$lang['js']['media_cancel'] = 'премахване';
|
||||
$lang['js']['media_overwrt'] = 'Презапиши съществуващите файлове';
|
||||
$lang['rssfailed'] = 'Възникна грешка при получаването на емисията: ';
|
||||
|
@ -164,7 +164,7 @@ $lang['accessdenied'] = 'Нямате необходимите прав
|
|||
$lang['mediausage'] = 'Ползвайте следния синтаксис, за да упоменете файла:';
|
||||
$lang['mediaview'] = 'Преглед на оригиналния файл';
|
||||
$lang['mediaroot'] = 'root';
|
||||
$lang['mediaupload'] = 'Качете файл в текущото именно пространство. За създаване на подимено пространство, добавете име преди това на файла като ги разделите с двоеточие в полето "Качи като"';
|
||||
$lang['mediaupload'] = 'Качете файл в текущото именно пространство. За създаване на подименно пространство, добавете име преди това на файла като ги разделите с двоеточие в полето "Качи като"';
|
||||
$lang['mediaextchange'] = 'Разширението на файла е сменено от .%s на .%s!';
|
||||
$lang['reference'] = 'Връзки за';
|
||||
$lang['ref_inuse'] = 'Файлът не може да бъде изтрит, защото все още се ползва от следните страници:';
|
||||
|
@ -181,9 +181,9 @@ $lang['diff_type'] = 'Преглед на разликите:';
|
|||
$lang['diff_inline'] = 'Вграден';
|
||||
$lang['diff_side'] = 'Един до друг';
|
||||
$lang['line'] = 'Ред';
|
||||
$lang['breadcrumb'] = 'Следа';
|
||||
$lang['youarehere'] = 'Намирате се в';
|
||||
$lang['lastmod'] = 'Последна промяна';
|
||||
$lang['breadcrumb'] = 'Следа:';
|
||||
$lang['youarehere'] = 'Намирате се в:';
|
||||
$lang['lastmod'] = 'Последна промяна:';
|
||||
$lang['by'] = 'от';
|
||||
$lang['deleted'] = 'изтрита';
|
||||
$lang['created'] = 'създадена';
|
||||
|
@ -236,23 +236,23 @@ $lang['admin_register'] = 'Добавяне на нов потребит
|
|||
$lang['metaedit'] = 'Редактиране на метаданни';
|
||||
$lang['metasaveerr'] = 'Записването на метаданните се провали';
|
||||
$lang['metasaveok'] = 'Метаданните са запазени успешно';
|
||||
$lang['img_backto'] = 'Назад към';
|
||||
$lang['img_title'] = 'Заглавие';
|
||||
$lang['img_caption'] = 'Надпис';
|
||||
$lang['img_date'] = 'Дата';
|
||||
$lang['img_fname'] = 'Име на файла';
|
||||
$lang['img_fsize'] = 'Размер';
|
||||
$lang['img_artist'] = 'Фотограф';
|
||||
$lang['img_copyr'] = 'Авторско право';
|
||||
$lang['img_format'] = 'Формат';
|
||||
$lang['img_camera'] = 'Фотоапарат';
|
||||
$lang['img_keywords'] = 'Ключови думи';
|
||||
$lang['img_width'] = 'Ширина';
|
||||
$lang['img_height'] = 'Височина';
|
||||
$lang['img_manager'] = 'Преглед в диспечера на файлове';
|
||||
$lang['btn_img_backto'] = 'Назад към %s';
|
||||
$lang['img_title'] = 'Заглавие:';
|
||||
$lang['img_caption'] = 'Надпис:';
|
||||
$lang['img_date'] = 'Дата:';
|
||||
$lang['img_fname'] = 'Име на файла:';
|
||||
$lang['img_fsize'] = 'Размер:';
|
||||
$lang['img_artist'] = 'Фотограф:';
|
||||
$lang['img_copyr'] = 'Авторско право:';
|
||||
$lang['img_format'] = 'Формат:';
|
||||
$lang['img_camera'] = 'Фотоапарат:';
|
||||
$lang['img_keywords'] = 'Ключови думи:';
|
||||
$lang['img_width'] = 'Ширина:';
|
||||
$lang['img_height'] = 'Височина:';
|
||||
$lang['btn_mediaManager'] = 'Преглед в диспечера на файлове';
|
||||
$lang['subscr_subscribe_success'] = '%s е добавен към списъка с абониралите се за %s';
|
||||
$lang['subscr_subscribe_error'] = 'Грешка при добавянето на %s към списъка с абониралите се за %s';
|
||||
$lang['subscr_subscribe_noaddress'] = 'Добавянето ви към списъка с абонати не е възможно поради липсата на свързан адрес (на ел. поща) с профила ви.';
|
||||
$lang['subscr_subscribe_noaddress'] = 'Добавянето ви към списъка с абонати не е възможно поради липсата на свързан адрес (имейл) с профила ви.';
|
||||
$lang['subscr_unsubscribe_success'] = '%s е премахнат от списъка с абониралите се за %s';
|
||||
$lang['subscr_unsubscribe_error'] = 'Грешка при премахването на %s от списъка с абониралите се за %s';
|
||||
$lang['subscr_already_subscribed'] = '%s е вече абониран за %s';
|
||||
|
@ -263,12 +263,12 @@ $lang['subscr_m_current_header'] = 'Текущи абонаменти';
|
|||
$lang['subscr_m_unsubscribe'] = 'Прекратяване на абонамента';
|
||||
$lang['subscr_m_subscribe'] = 'Абониране';
|
||||
$lang['subscr_m_receive'] = 'Получаване';
|
||||
$lang['subscr_style_every'] = 'на ел. писмо при всяка промяна';
|
||||
$lang['subscr_style_digest'] = 'на ел. писмо с обобщение на промените във всяка страница (всеки %.2f дни)';
|
||||
$lang['subscr_style_list'] = 'на списък с променените страници от последното ел. писмо (всеки %.2f дни)';
|
||||
$lang['subscr_style_every'] = 'на имейл при всяка промяна';
|
||||
$lang['subscr_style_digest'] = 'на имейл с обобщение на промените във всяка страница (всеки %.2f дни)';
|
||||
$lang['subscr_style_list'] = 'на списък с променените страници от последния имейл (всеки %.2f дни)';
|
||||
$lang['authtempfail'] = 'Удостоверяването на потребители не е възможно за момента. Ако продължи дълго, моля уведомете администратора на Wiki страницата.';
|
||||
$lang['authpwdexpire'] = 'Срока на паролата ви ще изтече след %d дни. Препорачително е да я смените по-скоро.';
|
||||
$lang['i_chooselang'] = 'Изберете вашия изик';
|
||||
$lang['authpwdexpire'] = 'Срока на паролата ви ще изтече след %d дни. Препоръчително е да я смените по-скоро.';
|
||||
$lang['i_chooselang'] = 'Изберете вашия език';
|
||||
$lang['i_installer'] = 'Инсталатор на DokuWiki';
|
||||
$lang['i_wikiname'] = 'Име на Wiki-то';
|
||||
$lang['i_enableacl'] = 'Ползване на списък за достъп (ACL) [препоръчително]';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
====== Регистриране като нов потребител ======
|
||||
|
||||
Моля, попълнете всичките полета отдолу, за да бъде създаден нов профил. Уверете се, че въведеният **адрес на ел. поща е правилен**. Ако няма поле за парола, ще ви бъде изпратена такава на въведения адрес. Потребителското име трябва да бъде валидно [[doku>pagename|име на страница]].
|
||||
Моля, попълнете всичките полета отдолу, за да бъде създаден нов профил. Уверете се, че въведеният **имейл адрес е правилен**. Ако няма поле за парола, ще ви бъде изпратена такава на въведения адрес. Потребителското име трябва да бъде валидно [[doku>pagename|име на страница]].
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
====== Пращане на нова парола ======
|
||||
|
||||
Моля, въведете потребителското си име във формата по-долу, ако желаете да получите нова парола. По ел. поща ще получите линк, с който да потвърдите.
|
||||
Моля, въведете потребителското си име във формата по-долу, ако желаете да получите нова парола. Чрез имейл ще получите линк, с който да потвърдите.
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
====== অনুমতি অস্বীকার =====
|
||||
|
||||
দুঃখিত, আপনি কি এগিয়ে যেতে যথেষ্ট অধিকার নেই. সম্ভবত আপনি লগইন ভুলে গেছেন?
|
||||
দুঃখিত, আপনি কি এগিয়ে যেতে যথেষ্ট অধিকার নেই.
|
|
@ -5,6 +5,7 @@
|
|||
*
|
||||
* @author Foysol <ragebot1125@gmail.com>
|
||||
* @author ninetailz <ninetailz1125@gmail.com>
|
||||
* @author Khan M. B. Asad <muhammad2017@gmail.com>
|
||||
*/
|
||||
$lang['encoding'] = 'utf-8';
|
||||
$lang['direction'] = 'itr';
|
||||
|
@ -49,7 +50,7 @@ $lang['btn_register'] = 'খাতা';
|
|||
$lang['btn_apply'] = 'প্রয়োগ করা';
|
||||
$lang['btn_media'] = 'মিডিয়া ম্যানেজার';
|
||||
$lang['btn_deleteuser'] = 'আমার অ্যাকাউন্ট অপসারণ করুন';
|
||||
$lang['loggedinas'] = 'লগ ইন';
|
||||
$lang['loggedinas'] = 'লগ ইন:';
|
||||
$lang['user'] = 'ইউজারনেম';
|
||||
$lang['pass'] = 'পাসওয়ার্ড';
|
||||
$lang['newpass'] = 'নতুন পাসওয়ার্ড';
|
||||
|
@ -95,12 +96,12 @@ $lang['license'] = 'অন্যথায় নোট যেখ
|
|||
$lang['licenseok'] = 'দ্রষ্টব্য: আপনি নিম্নলিখিত লাইসেন্সের অধীনে আপনার বিষয়বস্তু লাইসেন্স সম্মত হন এই পৃষ্ঠার সম্পাদনার দ্বারা:';
|
||||
$lang['searchmedia'] = 'অনুসন্ধান ফাইলের নাম:';
|
||||
$lang['searchmedia_in'] = 'অনুসন্ধান %s -এ';
|
||||
$lang['txt_upload'] = 'আপলোড করার জন্য নির্বাচন করুন ফাইল';
|
||||
$lang['txt_filename'] = 'হিসাবে আপলোড করুন (ঐচ্ছিক)';
|
||||
$lang['txt_upload'] = 'আপলোড করার জন্য নির্বাচন করুন ফাইল:';
|
||||
$lang['txt_filename'] = 'হিসাবে আপলোড করুন (ঐচ্ছিক):';
|
||||
$lang['txt_overwrt'] = 'বিদ্যমান ফাইল মুছে যাবে';
|
||||
$lang['maxuploadsize'] = 'সর্বোচ্চ আপলোড করুন. %s-ফাইলের প্রতি.';
|
||||
$lang['lockedby'] = 'বর্তমানে দ্বারা লক';
|
||||
$lang['lockexpire'] = 'তালা এ মেয়াদ শেষ';
|
||||
$lang['lockedby'] = 'বর্তমানে দ্বারা লক:';
|
||||
$lang['lockexpire'] = 'তালা এ মেয়াদ শেষ:';
|
||||
$lang['js']['willexpire'] = 'এই পৃষ্ঠার সম্পাদনার জন্য আপনার লক এক মিনিটের মধ্যে মেয়াদ শেষ সম্পর্কে. \ দ্বন্দ্ব লক টাইমার রিসেট প্রিভিউ বাটন ব্যবহার এড়াতে.';
|
||||
$lang['js']['notsavedyet'] = 'অসংরক্ষিত পরিবর্তন হারিয়ে যাবে.';
|
||||
$lang['js']['searchmedia'] = 'ফাইলের জন্য অনুসন্ধান';
|
||||
|
@ -117,3 +118,43 @@ $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']['nosmblinks'] = 'উইন্ডোস শেয়ার এর সাথে সংযোগ সাধন কেবল মাইক্রোসফ্ট ইন্টারনেট এক্সপ্লোরারেই সম্ভব।\nতবে আপনি লিংকটি কপি পেস্ট করতেই পারেন।';
|
||||
$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_opacity'] = 'শাইন-থ্রু';
|
||||
$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['rssfailed'] = 'ফিডটি জোগাড় করতে গিয়ে একটি ত্রুটি ঘটেছে:';
|
||||
$lang['nothingfound'] = 'কিছু পাওয়া যায়নি।';
|
||||
$lang['mediaselect'] = 'মিডিয়া ফাইল';
|
||||
$lang['fileupload'] = 'মিডিয়া ফাইল আপলোড';
|
||||
$lang['uploadsucc'] = 'আপলোড সফল';
|
||||
$lang['uploadfail'] = 'আপলোড ব্যর্থ। অনুমতি জনিত ত্রুটি কী?';
|
||||
$lang['uploadwrong'] = 'আপলোড প্রত্যাখ্যাত। এই ফাইল এক্সটেনশন অননুমোদিত।';
|
||||
$lang['uploadexist'] = 'ফাইল ইতিমধ্যেই বিরাজমান। কিছু করা হয়নি।';
|
||||
$lang['uploadbadcontent'] = 'আপলোডকৃত সামগ্রী %s ফাইল এক্সটেনশন এর সাথে মিলেনি।';
|
||||
$lang['uploadspam'] = 'স্প্যাম ব্ল্যাকলিস্ট আপলোড আটকে দিয়েছে।';
|
||||
$lang['uploadxss'] = 'সামগ্রীটি ক্ষতিকর ভেবে আপলোড আটকে দেয়া হয়েছে।';
|
||||
$lang['uploadsize'] = 'আপলোডকৃত ফাইলটি বেশি বড়ো। (সর্বোচ্চ %s)';
|
||||
$lang['deletesucc'] = '"%s" ফাইলটি মুছে ফেলা হয়েছে।';
|
||||
$lang['deletefail'] = '"%s" ডিলিট করা যায়নি - অনুমতি আছে কি না দেখুন।';
|
||||
$lang['mediainuse'] = '"%s" ফাইলটি মোছা হয়নি - এটি এখনো ব্যবহৃত হচ্ছে।';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
====== Permís denegat ======
|
||||
|
||||
Disculpe, pero no té permís per a continuar. ¿Haurà oblidat iniciar sessió?
|
||||
Disculpe, pero no té permís per a continuar.
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ $lang['btn_recover'] = 'Recuperar borrador';
|
|||
$lang['btn_draftdel'] = 'Borrar borrador';
|
||||
$lang['btn_revert'] = 'Recuperar';
|
||||
$lang['btn_register'] = 'Registrar-se';
|
||||
$lang['loggedinas'] = 'Sessió de';
|
||||
$lang['loggedinas'] = 'Sessió de:';
|
||||
$lang['user'] = 'Nom d\'usuari';
|
||||
$lang['pass'] = 'Contrasenya';
|
||||
$lang['newpass'] = 'Contrasenya nova';
|
||||
|
@ -83,11 +83,11 @@ $lang['license'] = 'Excepte quan s\'indique una atra cosa, el cont
|
|||
$lang['licenseok'] = 'Nota: a l\'editar esta pàgina accepta llicenciar el seu contingut baix la següent llicència:';
|
||||
$lang['searchmedia'] = 'Buscar nom d\'archiu:';
|
||||
$lang['searchmedia_in'] = 'Buscar en %s';
|
||||
$lang['txt_upload'] = 'Seleccione l\'archiu que vol pujar';
|
||||
$lang['txt_filename'] = 'Enviar com (opcional)';
|
||||
$lang['txt_upload'] = 'Seleccione l\'archiu que vol pujar:';
|
||||
$lang['txt_filename'] = 'Enviar com (opcional):';
|
||||
$lang['txt_overwrt'] = 'Sobreescriure archius existents';
|
||||
$lang['lockedby'] = 'Actualment bloquejat per';
|
||||
$lang['lockexpire'] = 'El bloqueig venç a les';
|
||||
$lang['lockedby'] = 'Actualment bloquejat per:';
|
||||
$lang['lockexpire'] = 'El bloqueig venç a les:';
|
||||
$lang['js']['willexpire'] = 'El seu bloqueig per a editar esta pàgina vencerà en un minut.\nPer a evitar conflictes utilise el botó de vista prèvia i reiniciarà el contador.';
|
||||
$lang['js']['notsavedyet'] = 'Els canvis no guardats es perdran.\n¿Segur que vol continuar?';
|
||||
$lang['rssfailed'] = 'Ha ocorregut un erro al solicitar este canal: ';
|
||||
|
@ -130,9 +130,9 @@ $lang['yours'] = 'La seua versió';
|
|||
$lang['diff'] = 'Mostrar diferències en la versió actual';
|
||||
$lang['diff2'] = 'Mostrar diferències entre versions';
|
||||
$lang['line'] = 'Llínea';
|
||||
$lang['breadcrumb'] = 'Traça';
|
||||
$lang['youarehere'] = 'Vosté està ací';
|
||||
$lang['lastmod'] = 'Última modificació el';
|
||||
$lang['breadcrumb'] = 'Traça:';
|
||||
$lang['youarehere'] = 'Vosté està ací:';
|
||||
$lang['lastmod'] = 'Última modificació el:';
|
||||
$lang['by'] = 'per';
|
||||
$lang['deleted'] = 'borrat';
|
||||
$lang['created'] = 'creat';
|
||||
|
@ -174,17 +174,17 @@ $lang['admin_register'] = 'Afegir nou usuari';
|
|||
$lang['metaedit'] = 'Editar meta-senyes';
|
||||
$lang['metasaveerr'] = 'Erro escrivint meta-senyes';
|
||||
$lang['metasaveok'] = 'Meta-senyes guardades';
|
||||
$lang['img_backto'] = 'Tornar a';
|
||||
$lang['img_title'] = 'Títul';
|
||||
$lang['img_caption'] = 'Subtítul';
|
||||
$lang['img_date'] = 'Data';
|
||||
$lang['img_fname'] = 'Nom de l\'archiu';
|
||||
$lang['img_fsize'] = 'Tamany';
|
||||
$lang['img_artist'] = 'Fotógraf';
|
||||
$lang['img_copyr'] = 'Copyright';
|
||||
$lang['img_format'] = 'Format';
|
||||
$lang['img_camera'] = 'Càmara';
|
||||
$lang['img_keywords'] = 'Paraules clau';
|
||||
$lang['btn_img_backto'] = 'Tornar a %s';
|
||||
$lang['img_title'] = 'Títul:';
|
||||
$lang['img_caption'] = 'Subtítul:';
|
||||
$lang['img_date'] = 'Data:';
|
||||
$lang['img_fname'] = 'Nom de l\'archiu:';
|
||||
$lang['img_fsize'] = 'Tamany:';
|
||||
$lang['img_artist'] = 'Fotógraf:';
|
||||
$lang['img_copyr'] = 'Copyright:';
|
||||
$lang['img_format'] = 'Format:';
|
||||
$lang['img_camera'] = 'Càmara:';
|
||||
$lang['img_keywords'] = 'Paraules clau:';
|
||||
$lang['authtempfail'] = 'L\'autenticació d\'usuaris està desactivada temporalment. Si la situació persistix, per favor, informe a l\'administrador del Wiki.';
|
||||
$lang['i_chooselang'] = 'Trie l\'idioma';
|
||||
$lang['i_installer'] = 'Instalador de DokuWiki';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
====== Permís denegat ======
|
||||
|
||||
No teniu prou drets per continuar. Potser us heu descuidat d'entrar?
|
||||
No teniu prou drets per continuar.
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ $lang['btn_draftdel'] = 'Suprimeix esborrany';
|
|||
$lang['btn_revert'] = 'Restaura';
|
||||
$lang['btn_register'] = 'Registra\'m';
|
||||
$lang['btn_apply'] = 'Aplica';
|
||||
$lang['loggedinas'] = 'Heu entrat com';
|
||||
$lang['loggedinas'] = 'Heu entrat com:';
|
||||
$lang['user'] = 'Nom d\'usuari';
|
||||
$lang['pass'] = 'Contrasenya';
|
||||
$lang['newpass'] = 'Nova contrasenya';
|
||||
|
@ -87,8 +87,8 @@ $lang['license'] = 'Excepte on es digui una altra cosa, el conting
|
|||
$lang['licenseok'] = 'Nota. En editar aquesta pàgina esteu acceptant que el vostre contingut estigui subjecte a la llicència següent:';
|
||||
$lang['searchmedia'] = 'Cerca pel nom de fitxer';
|
||||
$lang['searchmedia_in'] = 'Cerca en: %s';
|
||||
$lang['txt_upload'] = 'Trieu el fitxer que voleu penjar';
|
||||
$lang['txt_filename'] = 'Introduïu el nom wiki (opcional)';
|
||||
$lang['txt_upload'] = 'Trieu el fitxer que voleu penjar:';
|
||||
$lang['txt_filename'] = 'Introduïu el nom wiki (opcional):';
|
||||
$lang['txt_overwrt'] = 'Sobreescriu el fitxer actual';
|
||||
$lang['maxuploadsize'] = 'Puja com a màxim %s per arxiu.';
|
||||
$lang['lockedby'] = 'Actualment blocat per:';
|
||||
|
@ -174,9 +174,9 @@ $lang['diff_type'] = 'Veieu les diferències:';
|
|||
$lang['diff_inline'] = 'En línia';
|
||||
$lang['diff_side'] = 'Un al costat de l\'altre';
|
||||
$lang['line'] = 'Línia';
|
||||
$lang['breadcrumb'] = 'Camí';
|
||||
$lang['youarehere'] = 'Sou aquí';
|
||||
$lang['lastmod'] = 'Darrera modificació';
|
||||
$lang['breadcrumb'] = 'Camí:';
|
||||
$lang['youarehere'] = 'Sou aquí:';
|
||||
$lang['lastmod'] = 'Darrera modificació:';
|
||||
$lang['by'] = 'per';
|
||||
$lang['deleted'] = 'suprimit';
|
||||
$lang['created'] = 'creat';
|
||||
|
@ -228,19 +228,19 @@ $lang['admin_register'] = 'Afegeix nou usuari';
|
|||
$lang['metaedit'] = 'Edita metadades';
|
||||
$lang['metasaveerr'] = 'No s\'han pogut escriure les metadades';
|
||||
$lang['metasaveok'] = 'S\'han desat les metadades';
|
||||
$lang['img_backto'] = 'Torna a';
|
||||
$lang['img_title'] = 'Títol';
|
||||
$lang['img_caption'] = 'Peu d\'imatge';
|
||||
$lang['img_date'] = 'Data';
|
||||
$lang['img_fname'] = 'Nom de fitxer';
|
||||
$lang['img_fsize'] = 'Mida';
|
||||
$lang['img_artist'] = 'Fotògraf';
|
||||
$lang['img_copyr'] = 'Copyright';
|
||||
$lang['img_format'] = 'Format';
|
||||
$lang['img_camera'] = 'Càmera';
|
||||
$lang['img_keywords'] = 'Paraules clau';
|
||||
$lang['img_width'] = 'Ample';
|
||||
$lang['img_height'] = 'Alçada';
|
||||
$lang['btn_img_backto'] = 'Torna a %s';
|
||||
$lang['img_title'] = 'Títol:';
|
||||
$lang['img_caption'] = 'Peu d\'imatge:';
|
||||
$lang['img_date'] = 'Data:';
|
||||
$lang['img_fname'] = 'Nom de fitxer:';
|
||||
$lang['img_fsize'] = 'Mida:';
|
||||
$lang['img_artist'] = 'Fotògraf:';
|
||||
$lang['img_copyr'] = 'Copyright:';
|
||||
$lang['img_format'] = 'Format:';
|
||||
$lang['img_camera'] = 'Càmera:';
|
||||
$lang['img_keywords'] = 'Paraules clau:';
|
||||
$lang['img_width'] = 'Ample:';
|
||||
$lang['img_height'] = 'Alçada:';
|
||||
$lang['subscr_subscribe_success'] = 'S\'ha afegit %s a la llista de subscripcions per %s';
|
||||
$lang['subscr_subscribe_error'] = 'Hi ha hagut un error a l\'afegir %s a la llista per %s';
|
||||
$lang['subscr_subscribe_noaddress'] = 'No hi ha cap adreça associada pel vostre nom d\'usuari, no podeu ser afegit a la llista de subscripcions';
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
====== Nepovolená akce ======
|
||||
|
||||
Promiňte, ale nemáte dostatečná oprávnění k této činnosti. Možná jste se zapomněli přihlásit?
|
||||
Promiňte, ale nemáte dostatečná oprávnění k této činnosti.
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
* @author Jakub A. Těšínský (j@kub.cz)
|
||||
* @author mkucera66@seznam.cz
|
||||
* @author Zbyněk Křivka <krivka@fit.vutbr.cz>
|
||||
* @author Gerrit Uitslag <klapinklapin@gmail.com>
|
||||
* @author Petr Klíma <qaxi@seznam.cz>
|
||||
* @author Radovan Buroň <radovan@buron.cz>
|
||||
*/
|
||||
$lang['encoding'] = 'utf-8';
|
||||
$lang['direction'] = 'ltr';
|
||||
|
@ -61,7 +61,9 @@ $lang['btn_register'] = 'Registrovat';
|
|||
$lang['btn_apply'] = 'Použít';
|
||||
$lang['btn_media'] = 'Správa médií';
|
||||
$lang['btn_deleteuser'] = 'Odstranit můj účet';
|
||||
$lang['loggedinas'] = 'Přihlášen(a) jako';
|
||||
$lang['btn_img_backto'] = 'Zpět na %s';
|
||||
$lang['btn_mediaManager'] = 'Zobrazit ve správě médií';
|
||||
$lang['loggedinas'] = 'Přihlášen(a) jako:';
|
||||
$lang['user'] = 'Uživatelské jméno';
|
||||
$lang['pass'] = 'Heslo';
|
||||
$lang['newpass'] = 'Nové heslo';
|
||||
|
@ -106,8 +108,8 @@ $lang['license'] = 'Kromě míst, kde je explicitně uvedeno jinak
|
|||
$lang['licenseok'] = 'Poznámka: Tím, že editujete tuto stránku, souhlasíte, aby váš obsah byl licencován pod následující licencí:';
|
||||
$lang['searchmedia'] = 'Hledat jméno souboru:';
|
||||
$lang['searchmedia_in'] = 'Hledat v %s';
|
||||
$lang['txt_upload'] = 'Vyberte soubor jako přílohu';
|
||||
$lang['txt_filename'] = 'Wiki jméno (volitelné)';
|
||||
$lang['txt_upload'] = 'Vyberte soubor jako přílohu:';
|
||||
$lang['txt_filename'] = 'Wiki jméno (volitelné):';
|
||||
$lang['txt_overwrt'] = 'Přepsat existující soubor';
|
||||
$lang['maxuploadsize'] = 'Max. velikost souboru %s';
|
||||
$lang['lockedby'] = 'Právě zamknuto:';
|
||||
|
@ -193,9 +195,9 @@ $lang['diff_type'] = 'Zobrazit rozdíly:';
|
|||
$lang['diff_inline'] = 'Vložené';
|
||||
$lang['diff_side'] = 'Přidané';
|
||||
$lang['line'] = 'Řádek';
|
||||
$lang['breadcrumb'] = 'Historie';
|
||||
$lang['youarehere'] = 'Umístění';
|
||||
$lang['lastmod'] = 'Poslední úprava';
|
||||
$lang['breadcrumb'] = 'Historie:';
|
||||
$lang['youarehere'] = 'Umístění:';
|
||||
$lang['lastmod'] = 'Poslední úprava:';
|
||||
$lang['by'] = 'autor:';
|
||||
$lang['deleted'] = 'odstraněno';
|
||||
$lang['created'] = 'vytvořeno';
|
||||
|
@ -248,20 +250,18 @@ $lang['admin_register'] = 'Přidat nového uživatele';
|
|||
$lang['metaedit'] = 'Upravit Metadata';
|
||||
$lang['metasaveerr'] = 'Chyba při zápisu metadat';
|
||||
$lang['metasaveok'] = 'Metadata uložena';
|
||||
$lang['img_backto'] = 'Zpět na';
|
||||
$lang['img_title'] = 'Titulek';
|
||||
$lang['img_caption'] = 'Popis';
|
||||
$lang['img_date'] = 'Datum';
|
||||
$lang['img_fname'] = 'Jméno souboru';
|
||||
$lang['img_fsize'] = 'Velikost';
|
||||
$lang['img_artist'] = 'Autor fotografie';
|
||||
$lang['img_copyr'] = 'Copyright';
|
||||
$lang['img_format'] = 'Formát';
|
||||
$lang['img_camera'] = 'Typ fotoaparátu';
|
||||
$lang['img_keywords'] = 'Klíčová slova';
|
||||
$lang['img_width'] = 'Šířka';
|
||||
$lang['img_height'] = 'Výška';
|
||||
$lang['img_manager'] = 'Zobrazit ve správě médií';
|
||||
$lang['img_title'] = 'Titulek:';
|
||||
$lang['img_caption'] = 'Popis:';
|
||||
$lang['img_date'] = 'Datum:';
|
||||
$lang['img_fname'] = 'Jméno souboru:';
|
||||
$lang['img_fsize'] = 'Velikost:';
|
||||
$lang['img_artist'] = 'Autor fotografie:';
|
||||
$lang['img_copyr'] = 'Copyright:';
|
||||
$lang['img_format'] = 'Formát:';
|
||||
$lang['img_camera'] = 'Typ fotoaparátu:';
|
||||
$lang['img_keywords'] = 'Klíčová slova:';
|
||||
$lang['img_width'] = 'Šířka:';
|
||||
$lang['img_height'] = 'Výška:';
|
||||
$lang['subscr_subscribe_success'] = '%s byl přihlášen do seznamu odběratelů %s';
|
||||
$lang['subscr_subscribe_error'] = 'Došlo k chybě při přihlašování %s do seznamu odběratelů %s';
|
||||
$lang['subscr_subscribe_noaddress'] = 'K Vašemu loginu neexistuje žádná adresa, nemohl jste být přihlášen do seznamu odběratelů.';
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
====== Adgang nægtet! ======
|
||||
|
||||
Du har ikke rettigheder til at fortsætte. Måske er du ikke logget ind.
|
||||
Du har ikke rettigheder til at fortsætte.
|
||||
|
|
|
@ -61,7 +61,7 @@ $lang['btn_register'] = 'Registrér';
|
|||
$lang['btn_apply'] = 'Anvend';
|
||||
$lang['btn_media'] = 'Media Manager';
|
||||
$lang['btn_deleteuser'] = 'Fjern Min Konto';
|
||||
$lang['loggedinas'] = 'Logget ind som';
|
||||
$lang['loggedinas'] = 'Logget ind som:';
|
||||
$lang['user'] = 'Brugernavn';
|
||||
$lang['pass'] = 'Adgangskode';
|
||||
$lang['newpass'] = 'Ny adgangskode';
|
||||
|
@ -105,12 +105,12 @@ $lang['license'] = 'Med mindre andet angivet, vil indhold på denn
|
|||
$lang['licenseok'] = 'Note: ved at ændre denne side, acceptere du at dit indhold bliver frigivet under følgende licens:';
|
||||
$lang['searchmedia'] = 'Søg filnavn';
|
||||
$lang['searchmedia_in'] = 'Søg i %s';
|
||||
$lang['txt_upload'] = 'Vælg den fil der skal overføres';
|
||||
$lang['txt_filename'] = 'Indtast wikinavn (valgfrit)';
|
||||
$lang['txt_upload'] = 'Vælg den fil der skal overføres:';
|
||||
$lang['txt_filename'] = 'Indtast wikinavn (valgfrit):';
|
||||
$lang['txt_overwrt'] = 'Overskriv eksisterende fil';
|
||||
$lang['maxuploadsize'] = 'Upload max. %s pr. fil.';
|
||||
$lang['lockedby'] = 'Midlertidig låst af';
|
||||
$lang['lockexpire'] = 'Lås udløber kl.';
|
||||
$lang['lockedby'] = 'Midlertidig låst af:';
|
||||
$lang['lockexpire'] = 'Lås udløber kl:.';
|
||||
$lang['js']['willexpire'] = 'Din lås på dette dokument udløber om et minut.\nTryk på Forhåndsvisning-knappen for at undgå konflikter.';
|
||||
$lang['js']['notsavedyet'] = 'Ugemte ændringer vil blive mistet
|
||||
Fortsæt alligevel?';
|
||||
|
@ -191,9 +191,9 @@ $lang['diff_type'] = 'Vis forskelle:';
|
|||
$lang['diff_inline'] = 'Indeni';
|
||||
$lang['diff_side'] = 'Side ved Side';
|
||||
$lang['line'] = 'Linje';
|
||||
$lang['breadcrumb'] = 'Sti';
|
||||
$lang['youarehere'] = 'Du er her';
|
||||
$lang['lastmod'] = 'Sidst ændret';
|
||||
$lang['breadcrumb'] = 'Sti:';
|
||||
$lang['youarehere'] = 'Du er her:';
|
||||
$lang['lastmod'] = 'Sidst ændret:';
|
||||
$lang['by'] = 'af';
|
||||
$lang['deleted'] = 'slettet';
|
||||
$lang['created'] = 'oprettet';
|
||||
|
@ -246,20 +246,20 @@ $lang['admin_register'] = 'Tilføj ny bruger';
|
|||
$lang['metaedit'] = 'Rediger metadata';
|
||||
$lang['metasaveerr'] = 'Skrivning af metadata fejlede';
|
||||
$lang['metasaveok'] = 'Metadata gemt';
|
||||
$lang['img_backto'] = 'Tilbage til';
|
||||
$lang['img_title'] = 'Titel';
|
||||
$lang['img_caption'] = 'Billedtekst';
|
||||
$lang['img_date'] = 'Dato';
|
||||
$lang['img_fname'] = 'Filnavn';
|
||||
$lang['img_fsize'] = 'Størrelse';
|
||||
$lang['img_artist'] = 'Fotograf';
|
||||
$lang['img_copyr'] = 'Ophavsret';
|
||||
$lang['img_format'] = 'Format';
|
||||
$lang['img_camera'] = 'Kamera';
|
||||
$lang['img_keywords'] = 'Emneord';
|
||||
$lang['img_width'] = 'Bredde';
|
||||
$lang['img_height'] = 'Højde';
|
||||
$lang['img_manager'] = 'Vis i Media Manager';
|
||||
$lang['btn_img_backto'] = 'Tilbage til %s';
|
||||
$lang['img_title'] = 'Titel:';
|
||||
$lang['img_caption'] = 'Billedtekst:';
|
||||
$lang['img_date'] = 'Dato:';
|
||||
$lang['img_fname'] = 'Filnavn:';
|
||||
$lang['img_fsize'] = 'Størrelse:';
|
||||
$lang['img_artist'] = 'Fotograf:';
|
||||
$lang['img_copyr'] = 'Ophavsret:';
|
||||
$lang['img_format'] = 'Format:';
|
||||
$lang['img_camera'] = 'Kamera:';
|
||||
$lang['img_keywords'] = 'Emneord:';
|
||||
$lang['img_width'] = 'Bredde:';
|
||||
$lang['img_height'] = 'Højde:';
|
||||
$lang['btn_mediaManager'] = 'Vis i Media Manager';
|
||||
$lang['subscr_subscribe_success'] = 'Tilføjede %s til abonnement listen for %s';
|
||||
$lang['subscr_subscribe_error'] = 'Fejl ved tilføjelse af %s til abonnement listen for %s';
|
||||
$lang['subscr_subscribe_noaddress'] = 'Der er ikke nogen addresse forbundet til din bruger, så du kan ikke blive tilføjet til abonnement listen';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
====== Zugang verweigert ======
|
||||
|
||||
Du hast nicht die erforderliche Berechtigung, um diese Aktion durchzuführen. Eventuell bist du nicht am Wiki angemeldet?
|
||||
Du hast nicht die erforderliche Berechtigung, um diese Aktion durchzuführen.
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ $lang['btn_register'] = 'Registrieren';
|
|||
$lang['btn_apply'] = 'Übernehmen';
|
||||
$lang['btn_media'] = 'Medien-Manager';
|
||||
$lang['btn_deleteuser'] = 'Benutzerprofil löschen';
|
||||
$lang['loggedinas'] = 'Angemeldet als';
|
||||
$lang['loggedinas'] = 'Angemeldet als:';
|
||||
$lang['user'] = 'Benutzername';
|
||||
$lang['pass'] = 'Passwort';
|
||||
$lang['newpass'] = 'Neues Passwort';
|
||||
|
@ -111,12 +111,12 @@ $lang['license'] = 'Falls nicht anders bezeichnet, ist der Inhalt
|
|||
$lang['licenseok'] = 'Hinweis: Durch das Bearbeiten dieser Seite gibst du dein Einverständnis, dass dein Inhalt unter der folgenden Lizenz veröffentlicht wird:';
|
||||
$lang['searchmedia'] = 'Suche nach Datei:';
|
||||
$lang['searchmedia_in'] = 'Suche in %s';
|
||||
$lang['txt_upload'] = 'Datei zum Hochladen auswählen';
|
||||
$lang['txt_filename'] = 'Hochladen als (optional)';
|
||||
$lang['txt_upload'] = 'Datei zum Hochladen auswählen:';
|
||||
$lang['txt_filename'] = 'Hochladen als (optional):';
|
||||
$lang['txt_overwrt'] = 'Bestehende Datei überschreiben';
|
||||
$lang['maxuploadsize'] = 'Max. %s pro Datei-Upload.';
|
||||
$lang['lockedby'] = 'Momentan gesperrt von';
|
||||
$lang['lockexpire'] = 'Sperre läuft ab am';
|
||||
$lang['lockedby'] = 'Momentan gesperrt von:';
|
||||
$lang['lockexpire'] = 'Sperre läuft ab am:';
|
||||
$lang['js']['willexpire'] = 'Die Sperre zur Bearbeitung dieser Seite läuft in einer Minute ab.\nUm Bearbeitungskonflikte zu vermeiden, solltest du sie durch einen Klick auf den Vorschau-Knopf verlängern.';
|
||||
$lang['js']['notsavedyet'] = 'Nicht gespeicherte Änderungen gehen verloren!';
|
||||
$lang['js']['searchmedia'] = 'Suche nach Dateien';
|
||||
|
@ -196,9 +196,9 @@ $lang['diff_type'] = 'Unterschiede anzeigen:';
|
|||
$lang['diff_inline'] = 'Inline';
|
||||
$lang['diff_side'] = 'Side by Side';
|
||||
$lang['line'] = 'Zeile';
|
||||
$lang['breadcrumb'] = 'Zuletzt angesehen';
|
||||
$lang['youarehere'] = 'Du befindest dich hier';
|
||||
$lang['lastmod'] = 'Zuletzt geändert';
|
||||
$lang['breadcrumb'] = 'Zuletzt angesehen:';
|
||||
$lang['youarehere'] = 'Du befindest dich hier:';
|
||||
$lang['lastmod'] = 'Zuletzt geändert:';
|
||||
$lang['by'] = 'von';
|
||||
$lang['deleted'] = 'gelöscht';
|
||||
$lang['created'] = 'angelegt';
|
||||
|
@ -251,20 +251,20 @@ $lang['admin_register'] = 'Neuen Benutzer anmelden';
|
|||
$lang['metaedit'] = 'Metadaten bearbeiten';
|
||||
$lang['metasaveerr'] = 'Die Metadaten konnten nicht gesichert werden';
|
||||
$lang['metasaveok'] = 'Metadaten gesichert';
|
||||
$lang['img_backto'] = 'Zurück zu';
|
||||
$lang['img_title'] = 'Titel';
|
||||
$lang['img_caption'] = 'Bildunterschrift';
|
||||
$lang['img_date'] = 'Datum';
|
||||
$lang['img_fname'] = 'Dateiname';
|
||||
$lang['img_fsize'] = 'Größe';
|
||||
$lang['img_artist'] = 'Fotograf';
|
||||
$lang['img_copyr'] = 'Copyright';
|
||||
$lang['img_format'] = 'Format';
|
||||
$lang['img_camera'] = 'Kamera';
|
||||
$lang['img_keywords'] = 'Schlagwörter';
|
||||
$lang['img_width'] = 'Breite';
|
||||
$lang['img_height'] = 'Höhe';
|
||||
$lang['img_manager'] = 'Im Medien-Manager anzeigen';
|
||||
$lang['btn_img_backto'] = 'Zurück zu %s';
|
||||
$lang['img_title'] = 'Titel:';
|
||||
$lang['img_caption'] = 'Bildunterschrift:';
|
||||
$lang['img_date'] = 'Datum:';
|
||||
$lang['img_fname'] = 'Dateiname:';
|
||||
$lang['img_fsize'] = 'Größe:';
|
||||
$lang['img_artist'] = 'Fotograf:';
|
||||
$lang['img_copyr'] = 'Copyright:';
|
||||
$lang['img_format'] = 'Format:';
|
||||
$lang['img_camera'] = 'Kamera:';
|
||||
$lang['img_keywords'] = 'Schlagwörter:';
|
||||
$lang['img_width'] = 'Breite:';
|
||||
$lang['img_height'] = 'Höhe:';
|
||||
$lang['btn_mediaManager'] = 'Im Medien-Manager anzeigen';
|
||||
$lang['subscr_subscribe_success'] = 'Die Seite %s wurde zur Abonnementliste von %s hinzugefügt';
|
||||
$lang['subscr_subscribe_error'] = 'Fehler beim Hinzufügen von %s zur Abonnementliste von %s';
|
||||
$lang['subscr_subscribe_noaddress'] = 'In deinem Account ist keine E-Mail-Adresse hinterlegt. Dadurch kann die Seite nicht abonniert werden';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
====== Zugang verweigert ======
|
||||
|
||||
Sie haben nicht die erforderliche Berechtigung, um diese Aktion durchzuführen. Eventuell sind Sie nicht am Wiki angemeldet?
|
||||
Sie haben nicht die erforderliche Berechtigung, um diese Aktion durchzuführen.
|
||||
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
* @author Pierre Corell <info@joomla-praxis.de>
|
||||
* @author Mateng Schimmerlos <mateng@firemail.de>
|
||||
* @author Benedikt Fey <spam@lifeisgoooood.de>
|
||||
* @author Joerg <scooter22@gmx.de>
|
||||
* @author Simon <st103267@stud.uni-stuttgart.de>
|
||||
* @author Hoisl <hoisl@gmx.at>
|
||||
*/
|
||||
$lang['encoding'] = 'utf-8';
|
||||
$lang['direction'] = 'ltr';
|
||||
|
@ -67,7 +70,9 @@ $lang['btn_register'] = 'Registrieren';
|
|||
$lang['btn_apply'] = 'Übernehmen';
|
||||
$lang['btn_media'] = 'Medien-Manager';
|
||||
$lang['btn_deleteuser'] = 'Benutzerprofil löschen';
|
||||
$lang['loggedinas'] = 'Angemeldet als';
|
||||
$lang['btn_img_backto'] = 'Zurück zu %s';
|
||||
$lang['btn_mediaManager'] = 'Im Medien-Manager anzeigen';
|
||||
$lang['loggedinas'] = 'Angemeldet als:';
|
||||
$lang['user'] = 'Benutzername';
|
||||
$lang['pass'] = 'Passwort';
|
||||
$lang['newpass'] = 'Neues Passwort';
|
||||
|
@ -112,12 +117,12 @@ $lang['license'] = 'Falls nicht anders bezeichnet, ist der Inhalt
|
|||
$lang['licenseok'] = 'Hinweis: Durch das Bearbeiten dieser Seite geben Sie Ihr Einverständnis, dass Ihr Inhalt unter der folgenden Lizenz veröffentlicht wird:';
|
||||
$lang['searchmedia'] = 'Suche Dateinamen:';
|
||||
$lang['searchmedia_in'] = 'Suche in %s';
|
||||
$lang['txt_upload'] = 'Datei zum Hochladen auswählen';
|
||||
$lang['txt_filename'] = 'Hochladen als (optional)';
|
||||
$lang['txt_upload'] = 'Datei zum Hochladen auswählen:';
|
||||
$lang['txt_filename'] = 'Hochladen als (optional):';
|
||||
$lang['txt_overwrt'] = 'Bestehende Datei überschreiben';
|
||||
$lang['maxuploadsize'] = 'Max. %s pro Datei-Upload.';
|
||||
$lang['lockedby'] = 'Momentan gesperrt von';
|
||||
$lang['lockexpire'] = 'Sperre läuft ab am';
|
||||
$lang['lockedby'] = 'Momentan gesperrt von:';
|
||||
$lang['lockexpire'] = 'Sperre läuft ab am:';
|
||||
$lang['js']['willexpire'] = 'Die Sperre zur Bearbeitung dieser Seite läuft in einer Minute ab.\nUm Bearbeitungskonflikte zu vermeiden, sollten Sie sie durch einen Klick auf den Vorschau-Knopf verlängern.';
|
||||
$lang['js']['notsavedyet'] = 'Nicht gespeicherte Änderungen gehen verloren!';
|
||||
$lang['js']['searchmedia'] = 'Suche Dateien';
|
||||
|
@ -196,10 +201,13 @@ $lang['difflink'] = 'Link zu dieser Vergleichsansicht';
|
|||
$lang['diff_type'] = 'Unterschiede anzeigen:';
|
||||
$lang['diff_inline'] = 'Inline';
|
||||
$lang['diff_side'] = 'Side by Side';
|
||||
$lang['diffprevrev'] = 'Vorhergehende Überarbeitung';
|
||||
$lang['diffnextrev'] = 'Nächste Überarbeitung';
|
||||
$lang['difflastrev'] = 'Letzte Überarbeitung';
|
||||
$lang['line'] = 'Zeile';
|
||||
$lang['breadcrumb'] = 'Zuletzt angesehen';
|
||||
$lang['youarehere'] = 'Sie befinden sich hier';
|
||||
$lang['lastmod'] = 'Zuletzt geändert';
|
||||
$lang['breadcrumb'] = 'Zuletzt angesehen:';
|
||||
$lang['youarehere'] = 'Sie befinden sich hier:';
|
||||
$lang['lastmod'] = 'Zuletzt geändert:';
|
||||
$lang['by'] = 'von';
|
||||
$lang['deleted'] = 'gelöscht';
|
||||
$lang['created'] = 'angelegt';
|
||||
|
@ -252,20 +260,18 @@ $lang['admin_register'] = 'Neuen Benutzer anmelden';
|
|||
$lang['metaedit'] = 'Metadaten bearbeiten';
|
||||
$lang['metasaveerr'] = 'Die Metadaten konnten nicht gesichert werden';
|
||||
$lang['metasaveok'] = 'Metadaten gesichert';
|
||||
$lang['img_backto'] = 'Zurück zu';
|
||||
$lang['img_title'] = 'Titel';
|
||||
$lang['img_caption'] = 'Bildunterschrift';
|
||||
$lang['img_date'] = 'Datum';
|
||||
$lang['img_fname'] = 'Dateiname';
|
||||
$lang['img_fsize'] = 'Größe';
|
||||
$lang['img_artist'] = 'FotografIn';
|
||||
$lang['img_copyr'] = 'Copyright';
|
||||
$lang['img_format'] = 'Format';
|
||||
$lang['img_camera'] = 'Kamera';
|
||||
$lang['img_keywords'] = 'Schlagwörter';
|
||||
$lang['img_width'] = 'Breite';
|
||||
$lang['img_height'] = 'Höhe';
|
||||
$lang['img_manager'] = 'Im Medien-Manager anzeigen';
|
||||
$lang['img_title'] = 'Titel:';
|
||||
$lang['img_caption'] = 'Bildunterschrift:';
|
||||
$lang['img_date'] = 'Datum:';
|
||||
$lang['img_fname'] = 'Dateiname:';
|
||||
$lang['img_fsize'] = 'Größe:';
|
||||
$lang['img_artist'] = 'FotografIn:';
|
||||
$lang['img_copyr'] = 'Copyright:';
|
||||
$lang['img_format'] = 'Format:';
|
||||
$lang['img_camera'] = 'Kamera:';
|
||||
$lang['img_keywords'] = 'Schlagwörter:';
|
||||
$lang['img_width'] = 'Breite:';
|
||||
$lang['img_height'] = 'Höhe:';
|
||||
$lang['subscr_subscribe_success'] = '%s hat nun Änderungen der Seite %s abonniert';
|
||||
$lang['subscr_subscribe_error'] = '%s kann die Änderungen der Seite %s nicht abonnieren';
|
||||
$lang['subscr_subscribe_noaddress'] = 'Weil Ihre E-Mail-Adresse fehlt, können Sie das Thema nicht abonnieren';
|
||||
|
@ -345,3 +351,4 @@ $lang['media_restore'] = 'Diese Version wiederherstellen';
|
|||
$lang['currentns'] = 'Aktueller Namensraum';
|
||||
$lang['searchresult'] = 'Suchergebnisse';
|
||||
$lang['plainhtml'] = 'HTML Klartext';
|
||||
$lang['wikimarkup'] = 'Wiki Markup';
|
||||
|
|
|
@ -2,4 +2,3 @@
|
|||
|
||||
Συγγνώμη, αλλά δεν έχετε επαρκή δικαιώματα για την συγκεκριμένη ενέργεια.
|
||||
|
||||
Μήπως παραλείψατε να συνδεθείτε;
|
||||
|
|
|
@ -56,7 +56,7 @@ $lang['btn_register'] = 'Εγγραφή';
|
|||
$lang['btn_apply'] = 'Εφαρμογή';
|
||||
$lang['btn_media'] = 'Διαχειριστής πολυμέσων';
|
||||
$lang['btn_deleteuser'] = 'Αφαίρεσε τον λογαριασμό μου';
|
||||
$lang['loggedinas'] = 'Συνδεδεμένος ως';
|
||||
$lang['loggedinas'] = 'Συνδεδεμένος ως:';
|
||||
$lang['user'] = 'Όνομα χρήστη';
|
||||
$lang['pass'] = 'Κωδικός';
|
||||
$lang['newpass'] = 'Νέος κωδικός';
|
||||
|
@ -100,12 +100,12 @@ $lang['license'] = 'Εκτός εάν αναφέρεται δια
|
|||
$lang['licenseok'] = 'Σημείωση: Τροποποιώντας αυτή την σελίδα αποδέχεστε την διάθεση του υλικού σας σύμφωνα με την ακόλουθη άδεια:';
|
||||
$lang['searchmedia'] = 'Αναζήτηση αρχείου:';
|
||||
$lang['searchmedia_in'] = 'Αναζήτηση σε %s';
|
||||
$lang['txt_upload'] = 'Επιλέξτε αρχείο για φόρτωση';
|
||||
$lang['txt_filename'] = 'Επιλέξτε νέο όνομα αρχείου (προαιρετικό)';
|
||||
$lang['txt_upload'] = 'Επιλέξτε αρχείο για φόρτωση:';
|
||||
$lang['txt_filename'] = 'Επιλέξτε νέο όνομα αρχείου (προαιρετικό):';
|
||||
$lang['txt_overwrt'] = 'Αντικατάσταση υπάρχοντος αρχείου';
|
||||
$lang['maxuploadsize'] = 'Μέγιστο μέγεθος αρχείου: %s.';
|
||||
$lang['lockedby'] = 'Προσωρινά κλειδωμένο από';
|
||||
$lang['lockexpire'] = 'Το κλείδωμα λήγει στις';
|
||||
$lang['lockedby'] = 'Προσωρινά κλειδωμένο από:';
|
||||
$lang['lockexpire'] = 'Το κλείδωμα λήγει στις:';
|
||||
$lang['js']['willexpire'] = 'Το κλείδωμά σας για την επεξεργασία αυτής της σελίδας θα λήξει σε ένα λεπτό.\n Για να το ανανεώσετε χρησιμοποιήστε την Προεπισκόπηση.';
|
||||
$lang['js']['notsavedyet'] = 'Οι μη αποθηκευμένες αλλαγές θα χαθούν.
|
||||
Θέλετε να συνεχίσετε;';
|
||||
|
@ -186,9 +186,9 @@ $lang['diff_type'] = 'Προβολή διαφορών:';
|
|||
$lang['diff_inline'] = 'Σε σειρά';
|
||||
$lang['diff_side'] = 'Δίπλα-δίπλα';
|
||||
$lang['line'] = 'Γραμμή';
|
||||
$lang['breadcrumb'] = 'Ιστορικό';
|
||||
$lang['youarehere'] = 'Είστε εδώ';
|
||||
$lang['lastmod'] = 'Τελευταία τροποποίηση';
|
||||
$lang['breadcrumb'] = 'Ιστορικό:';
|
||||
$lang['youarehere'] = 'Είστε εδώ:';
|
||||
$lang['lastmod'] = 'Τελευταία τροποποίηση:';
|
||||
$lang['by'] = 'από';
|
||||
$lang['deleted'] = 'διαγράφηκε';
|
||||
$lang['created'] = 'δημιουργήθηκε';
|
||||
|
@ -241,20 +241,20 @@ $lang['admin_register'] = 'Προσθήκη νέου χρήστη';
|
|||
$lang['metaedit'] = 'Τροποποίηση metadata';
|
||||
$lang['metasaveerr'] = 'Η αποθήκευση των metadata απέτυχε';
|
||||
$lang['metasaveok'] = 'Επιτυχής αποθήκευση metadata';
|
||||
$lang['img_backto'] = 'Επιστροφή σε';
|
||||
$lang['img_title'] = 'Τίτλος';
|
||||
$lang['img_caption'] = 'Λεζάντα';
|
||||
$lang['img_date'] = 'Ημερομηνία';
|
||||
$lang['img_fname'] = 'Όνομα αρχείου';
|
||||
$lang['img_fsize'] = 'Μέγεθος';
|
||||
$lang['img_artist'] = 'Καλλιτέχνης';
|
||||
$lang['img_copyr'] = 'Copyright';
|
||||
$lang['img_format'] = 'Format';
|
||||
$lang['img_camera'] = 'Camera';
|
||||
$lang['img_keywords'] = 'Λέξεις-κλειδιά';
|
||||
$lang['img_width'] = 'Πλάτος';
|
||||
$lang['img_height'] = 'Ύψος';
|
||||
$lang['img_manager'] = 'Εμφάνιση στον διαχειριστή πολυμέσων';
|
||||
$lang['btn_img_backto'] = 'Επιστροφή σε %s';
|
||||
$lang['img_title'] = 'Τίτλος:';
|
||||
$lang['img_caption'] = 'Λεζάντα:';
|
||||
$lang['img_date'] = 'Ημερομηνία:';
|
||||
$lang['img_fname'] = 'Όνομα αρχείου:';
|
||||
$lang['img_fsize'] = 'Μέγεθος:';
|
||||
$lang['img_artist'] = 'Καλλιτέχνης:';
|
||||
$lang['img_copyr'] = 'Copyright:';
|
||||
$lang['img_format'] = 'Format:';
|
||||
$lang['img_camera'] = 'Camera:';
|
||||
$lang['img_keywords'] = 'Λέξεις-κλειδιά:';
|
||||
$lang['img_width'] = 'Πλάτος:';
|
||||
$lang['img_height'] = 'Ύψος:';
|
||||
$lang['btn_mediaManager'] = 'Εμφάνιση στον διαχειριστή πολυμέσων';
|
||||
$lang['subscr_subscribe_success'] = 'Ο/η %s προστέθηκε στην λίστα ειδοποιήσεων για το %s';
|
||||
$lang['subscr_subscribe_error'] = 'Σφάλμα κατά την προσθήκη του/της %s στην λίστα ειδοποιήσεων για το %s';
|
||||
$lang['subscr_subscribe_noaddress'] = 'Δεν υπάρχει διεύθυνση ταχυδρομείου συσχετισμένη με το όνομα χρήστη σας. Κατά συνέπεια δεν μπορείτε να προστεθείτε στην λίστα ειδοποιήσεων';
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue