summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README2
-rw-r--r--_test/tests/inc/auth_password.test.php6
-rw-r--r--_test/tests/inc/indexer_rename.test.php83
-rw-r--r--_test/tests/inc/subscription.test.php246
-rw-r--r--_test/tests/inc/subscription_set.test.php20
-rw-r--r--inc/PassHash.class.php68
-rw-r--r--inc/actions.php22
-rw-r--r--inc/auth.php14
-rw-r--r--inc/changelog.php1
-rw-r--r--inc/common.php85
-rw-r--r--inc/html.php2
-rw-r--r--inc/indexer.php123
-rw-r--r--inc/lang/ar/subscr_single.txt2
-rw-r--r--inc/lang/bg/subscr_single.txt2
-rw-r--r--inc/lang/da/subscr_single.txt2
-rw-r--r--inc/lang/de-informal/subscr_single.txt2
-rw-r--r--inc/lang/de/subscr_single.txt2
-rw-r--r--inc/lang/el/lang.php25
-rw-r--r--inc/lang/el/mailwrap.html13
-rw-r--r--inc/lang/el/resetpwd.txt3
-rw-r--r--inc/lang/en/subscr_single.txt2
-rw-r--r--inc/lang/eo/subscr_single.txt2
-rw-r--r--inc/lang/gl/lang.php12
-rw-r--r--inc/lang/gl/mailwrap.html2
-rw-r--r--inc/lang/gl/resetpwd.txt4
-rw-r--r--inc/lang/he/subscr_single.txt2
-rw-r--r--inc/lang/ia/subscr_single.txt2
-rw-r--r--inc/lang/it/subscr_single.txt2
-rw-r--r--inc/lang/ko/subscr_single.txt2
-rw-r--r--inc/lang/la/subscr_digest.txt2
-rw-r--r--inc/lang/la/subscr_single.txt2
-rw-r--r--inc/lang/no/subscr_digest.txt2
-rw-r--r--inc/lang/no/subscr_list.txt2
-rw-r--r--inc/lang/no/subscr_single.txt2
-rw-r--r--inc/lang/pt/subscr_single.txt2
-rw-r--r--inc/lang/sq/subscr_single.txt2
-rw-r--r--inc/load.php1
-rw-r--r--inc/media.php23
-rw-r--r--inc/plugin.php2
-rw-r--r--inc/subscription.php993
-rw-r--r--inc/template.php3
-rw-r--r--lib/exe/indexer.php93
-rw-r--r--lib/plugins/acl/lang/el/lang.php1
-rw-r--r--lib/plugins/acl/lang/en/help.txt9
-rw-r--r--lib/plugins/acl/lang/gl/lang.php2
-rw-r--r--lib/plugins/acl/lang/nl/help.txt9
-rw-r--r--lib/plugins/config/lang/el/lang.php105
-rw-r--r--lib/plugins/config/lang/gl/lang.php22
-rw-r--r--lib/plugins/config/settings/config.metadata.php2
-rw-r--r--lib/plugins/plugin/lang/el/lang.php1
-rw-r--r--lib/plugins/plugin/lang/gl/lang.php2
-rw-r--r--lib/plugins/popularity/lang/el/lang.php1
-rw-r--r--lib/plugins/popularity/lang/gl/lang.php2
-rw-r--r--lib/plugins/revert/lang/el/lang.php1
-rw-r--r--lib/plugins/revert/lang/gl/lang.php2
-rw-r--r--lib/plugins/syntax.php106
-rw-r--r--lib/plugins/usermanager/lang/el/lang.php1
-rw-r--r--lib/plugins/usermanager/lang/gl/lang.php2
-rw-r--r--lib/scripts/fileuploaderextended.js2
-rw-r--r--lib/tpl/dokuwiki/css/basic.css92
-rw-r--r--lib/tpl/dokuwiki/css/content.css2
-rw-r--r--lib/tpl/dokuwiki/css/pagetools.css1
-rw-r--r--lib/tpl/dokuwiki/css/print.css95
-rw-r--r--lib/tpl/dokuwiki/style.ini2
64 files changed, 1541 insertions, 803 deletions
diff --git a/README b/README
index 0490040f2..3b7cb8a9c 100644
--- a/README
+++ b/README
@@ -4,7 +4,7 @@ at http://www.dokuwiki.org/
For Installation Instructions see
http://www.dokuwiki.org/install
-DokuWiki - 2004-2012 (c) Andreas Gohr <andi@splitbrain.org>
+DokuWiki - 2004-2013 (c) Andreas Gohr <andi@splitbrain.org>
and the DokuWiki Community
See COPYING and file headers for license info
diff --git a/_test/tests/inc/auth_password.test.php b/_test/tests/inc/auth_password.test.php
index 426353291..27e03be60 100644
--- a/_test/tests/inc/auth_password.test.php
+++ b/_test/tests/inc/auth_password.test.php
@@ -16,6 +16,7 @@ class auth_password_test extends PHPUnit_Framework_TestCase {
'kmd5' => 'a579299436d7969791189acadd86fcb716',
'djangomd5' => 'md5$abcde$d0fdddeda8cd92725d2b54148ac09158',
'djangosha1' => 'sha1$abcde$c8e65a7f0acc9158843048a53dcc5a6bc4d17678',
+ 'sha512' => '$6$abcdefgh12345678$J9.zOcgx0lotwZdcz0uulA3IVQMinZvFZVjA5vapRLVAAqtay23XD4xeeUxQ3B4JvDWYFBIxVWW1tOYlHX13k1'
);
@@ -61,6 +62,11 @@ class auth_password_test extends PHPUnit_Framework_TestCase {
$this->assertTrue(auth_verifyPassword('test12345','$H$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0'));
}
+ function test_veryPassword_mediawiki(){
+ $this->assertTrue(auth_verifyPassword('password', ':B:838c83e1:e4ab7024509eef084cdabd03d8b2972c'));
+ }
+
+
/**
* pmd5 checking should throw an exception when a hash with a too high
* iteration count is passed
diff --git a/_test/tests/inc/indexer_rename.test.php b/_test/tests/inc/indexer_rename.test.php
new file mode 100644
index 000000000..d8c456f8e
--- /dev/null
+++ b/_test/tests/inc/indexer_rename.test.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Test cases for the Doku_Indexer::renamePage and Doku_Indexer::renameMetaValue methods
+ */
+class indexer_rename_test extends DokuWikiTest {
+ /** @var Doku_Indexer $indexer */
+ private $indexer;
+
+ private $old_id = 'old_testid';
+
+ function setUp() {
+ parent::setUp();
+ $this->indexer = idx_get_indexer();
+ $this->indexer->clear();
+
+ saveWikiText($this->old_id, 'Old test content', 'Created old test page for indexer rename test');
+ idx_addPage($this->old_id);
+ }
+
+ function test_rename_to_new_page() {
+ $newid = 'new_id_1';
+
+ $oldpid = $this->indexer->getPID($this->old_id);
+
+ $this->assertTrue($this->indexer->renamePage($this->old_id, $newid), 'Renaming the page to a new id failed');
+ io_rename(wikiFN($this->old_id), wikiFN($newid));
+
+ $this->assertNotEquals($this->indexer->getPID($this->old_id), $oldpid, 'PID for the old page unchanged after rename.');
+ $this->assertEquals($this->indexer->getPID($newid), $oldpid, 'New page has not the old pid.');
+ $query = array('old');
+ $this->assertEquals(array('old' => array($newid => 1)), $this->indexer->lookup($query), '"Old" doesn\'t find the new page');
+ }
+
+ function test_rename_to_existing_page() {
+ $newid = 'existing_page';
+ saveWikiText($newid, 'Existing content', 'Created page for move_to_existing_page');
+ idx_addPage($newid);
+
+ $oldpid = $this->indexer->getPID($this->old_id);
+ $existingpid = $this->indexer->getPID($newid);
+
+ $this->assertTrue($this->indexer->renamePage($this->old_id, $newid), 'Renaming the page to an existing id failed');
+
+ $this->assertNotEquals($this->indexer->getPID($this->old_id), $oldpid, 'PID for old page unchanged after rename.');
+ $this->assertNotEquals($this->indexer->getPID($this->old_id), $existingpid, 'PID for old page is now PID of the existing page.');
+ $this->assertEquals($this->indexer->getPID($newid), $oldpid, 'New page has not the old pid.');
+ $query = array('existing');
+ $this->assertEquals(array('existing' => array()), $this->indexer->lookup($query), 'Existing page hasn\'t been deleted from the index.');
+ $query = array('old');
+ $this->assertEquals(array('old' => array($newid => 1)), $this->indexer->lookup($query), '"Old" doesn\'t find the new page');
+ }
+
+ function test_meta_rename_to_new_value() {
+ $this->indexer->addMetaKeys($this->old_id, array('mkey' => 'old_value'));
+
+ $this->assertTrue($this->indexer->renameMetaValue('mkey', 'old_value', 'new_value'), 'Meta value rename to new value failed.');
+ $query = 'old_value';
+ $this->assertEquals(array(), $this->indexer->lookupKey('mkey', $query), 'Page can still be found under old value.');
+ $query = 'new_value';
+ $this->assertEquals(array($this->old_id), $this->indexer->lookupKey('mkey', $query), 'Page can\'t be found under new value.');
+ }
+
+ function test_meta_rename_to_existing_value() {
+ $this->indexer->addMetaKeys($this->old_id, array('mkey' => array('old_value', 'new_value')));
+
+ saveWikiText('newvalue', 'Test page', '');
+ idx_addPage('newvalue');
+ $this->indexer->addMetaKeys('newvalue', array('mkey' => array('new_value')));
+
+ saveWikiText('oldvalue', 'Test page', '');
+ idx_addPage('oldvalue');
+ $this->indexer->addMetaKeys('oldvalue', array('mkey' => array('old_value')));
+
+ $this->assertTrue($this->indexer->renameMetaValue('mkey', 'old_value', 'new_value'), 'Meta value rename to existing value failed');
+ $query = 'old_value';
+ $this->assertEquals(array(), $this->indexer->lookupKey('mkey', $query), 'Page can still be found under old value.');
+ $query = 'new_value';
+ $result = $this->indexer->lookupKey('mkey', $query);
+ $this->assertContains($this->old_id, $result, 'Page with both values can\'t be found anymore');
+ $this->assertContains('newvalue', $result, 'Page with new value can\'t be found anymore');
+ $this->assertContains('oldvalue', $result, 'Page with only the old value can\'t be found anymore');
+ }
+}
diff --git a/_test/tests/inc/subscription.test.php b/_test/tests/inc/subscription.test.php
new file mode 100644
index 000000000..333400576
--- /dev/null
+++ b/_test/tests/inc/subscription.test.php
@@ -0,0 +1,246 @@
+<?php
+
+class subscription_test extends DokuWikiTest {
+
+ function test_regexp() {
+ // data to test against
+ $data = array(
+ "casper every\n",
+ "Andreas digest 1344689733",
+ "Cold%20Fusion every",
+ "zioth list 1344691369\n",
+ "nlights digest",
+ "rikblok\tdigest \t 1344716803",
+ );
+
+ // user, style, data, expected number of results
+ $tests = array(
+ array('Cold Fusion', null, null, 1),
+ array('casper', null, null, 1),
+ array('nope', null, null, 0),
+ array('lights', null, null, 0),
+ array(array('Cold Fusion', 'casper', 'nope'), null, null, 2),
+ array(null, 'list', null, 1),
+ array(null, 'every', null, 2),
+ array(null, 'digest', null, 3),
+ array(null, array('list', 'every'), null, 3),
+ array('casper', 'digest', null, 0),
+ array('casper', array('digest', 'every'), null, 1),
+ array('zioth', 'list', '1344691369', 1),
+ array('zioth', null, '1344691369', 1),
+ array('zioth', 'digest', '1344691369', 0),
+ );
+
+ $sub = new MockupSubscription();
+
+ $row = 0;
+ foreach($tests as $test) {
+ $re = $sub->buildregex($test[0], $test[1], $test[2]);
+ $this->assertFalse(empty($re), "test line $row");
+ $result = preg_grep($re, $data);
+ $this->assertEquals($test[3], count($result), "test line $row. $re got\n".print_r($result, true));
+
+ $row++;
+ }
+ }
+
+ function test_addremove() {
+ $sub = new MockupSubscription();
+
+ // no subscriptions
+ $this->assertArrayNotHasKey(
+ 'wiki:dokuwiki',
+ $sub->subscribers('wiki:dokuwiki', null, array('every', 'list', 'digest'))
+ );
+
+ // add page subscription
+ $sub->add('wiki:dokuwiki', 'testuser', 'every');
+
+ // one subscription
+ $this->assertArrayHasKey(
+ 'wiki:dokuwiki',
+ $sub->subscribers('wiki:dokuwiki', null, array('every', 'list', 'digest'))
+ );
+
+ // remove page subscription
+ $sub->remove('wiki:dokuwiki', 'testuser');
+
+ // no subscription
+ $this->assertArrayNotHasKey(
+ 'wiki:dokuwiki',
+ $sub->subscribers('wiki:dokuwiki', null, array('every', 'list', 'digest'))
+ );
+
+ // add namespace subscription
+ $sub->add('wiki:', 'testuser', 'every');
+
+ // one subscription
+ $this->assertArrayHasKey(
+ 'wiki:',
+ $sub->subscribers('wiki:dokuwiki', null, array('every', 'list', 'digest'))
+ );
+
+ // remove (non existing) page subscription
+ $sub->remove('wiki:dokuwiki', 'testuser');
+
+ // still one subscription
+ $this->assertArrayHasKey(
+ 'wiki:',
+ $sub->subscribers('wiki:dokuwiki', null, array('every', 'list', 'digest'))
+ );
+
+ // change namespace subscription
+ $sub->add('wiki:', 'testuser', 'digest', '1234567');
+
+ // still one subscription
+ $this->assertArrayHasKey(
+ 'wiki:',
+ $sub->subscribers('wiki:dokuwiki', null, array('every', 'list', 'digest'))
+ );
+
+ // check contents
+ $this->assertEquals(
+ array('wiki:' => array('testuser' => array('digest', '1234567'))),
+ $sub->subscribers('wiki:dokuwiki', null, array('every', 'list', 'digest'))
+ );
+
+ // change subscription data
+ $sub->add('wiki:', 'testuser', 'digest', '7654321');
+
+ // still one subscription
+ $this->assertArrayHasKey(
+ 'wiki:',
+ $sub->subscribers('wiki:dokuwiki', null, array('every', 'list', 'digest'))
+ );
+
+ // check contents
+ $this->assertEquals(
+ array('wiki:' => array('testuser' => array('digest', '7654321'))),
+ $sub->subscribers('wiki:dokuwiki', null, array('every', 'list', 'digest'))
+ );
+ }
+
+ function test_bulkdigest() {
+ $sub = new MockupSubscription();
+
+ // let's start with nothing
+ $this->assertEquals(0, $sub->send_bulk('sub1:test'));
+
+ // create a subscription
+ $sub->add('sub1:', 'testuser', 'digest', '978328800'); // last mod 2001-01-01
+
+ // now create change
+ $_SERVER['REMOTE_USER'] = 'someguy';
+ saveWikiText('sub1:test', 'foo bar', 'a subscription change', false);
+
+ // should trigger a mail
+ $this->assertEquals(1, $sub->send_bulk('sub1:test'));
+ $this->assertEquals(array('arthur@example.com'), $sub->mails);
+
+ $sub->reset();
+
+ // now create more changes
+ $_SERVER['REMOTE_USER'] = 'someguy';
+ saveWikiText('sub1:sub2:test', 'foo bar', 'a subscription change', false);
+ saveWikiText('sub1:another_test', 'foo bar', 'a subscription change', false);
+
+ // should not trigger a mail, because the subscription time has not been reached, yet
+ $this->assertEquals(0, $sub->send_bulk('sub1:test'));
+ $this->assertEquals(array(), $sub->mails);
+
+ // reset the subscription time
+ $sub->add('sub1:', 'testuser', 'digest', '978328800'); // last mod 2001-01-01
+
+ // we now should get mails for three changes
+ $this->assertEquals(3, $sub->send_bulk('sub1:test'));
+ $this->assertEquals(array('arthur@example.com', 'arthur@example.com', 'arthur@example.com'), $sub->mails);
+ }
+
+ function test_bulklist() {
+ $sub = new MockupSubscription();
+
+ // let's start with nothing
+ $this->assertEquals(0, $sub->send_bulk('sub1:test'));
+
+ // create a subscription
+ $sub->add('sub1:', 'testuser', 'list', '978328800'); // last mod 2001-01-01
+
+ // now create change
+ $_SERVER['REMOTE_USER'] = 'someguy';
+ saveWikiText('sub1:test', 'foo bar', 'a subscription change', false);
+
+ // should trigger a mail
+ $this->assertEquals(1, $sub->send_bulk('sub1:test'));
+ $this->assertEquals(array('arthur@example.com'), $sub->mails);
+
+ $sub->reset();
+
+ // now create more changes
+ $_SERVER['REMOTE_USER'] = 'someguy';
+ saveWikiText('sub1:sub2:test', 'foo bar', 'a subscription change', false);
+ saveWikiText('sub1:another_test', 'foo bar', 'a subscription change', false);
+
+ // should not trigger a mail, because the subscription time has not been reached, yet
+ $this->assertEquals(0, $sub->send_bulk('sub1:test'));
+ $this->assertEquals(array(), $sub->mails);
+
+ // reset the subscription time
+ $sub->add('sub1:', 'testuser', 'list', '978328800'); // last mod 2001-01-01
+
+ // we now should get a single mail for all three changes
+ $this->assertEquals(1, $sub->send_bulk('sub1:test'));
+ $this->assertEquals(array('arthur@example.com'), $sub->mails);
+ }
+
+ /**
+ * Tests, if overwriting subscriptions works even when subscriptions for the same
+ * user exist for two nested namespaces, this is a test for the bug described in FS#2580
+ */
+ function test_overwrite() {
+ $sub = new MockupSubscription();
+
+ $sub->add(':', 'admin', 'digest', '123456789');
+ $sub->add(':wiki:', 'admin', 'digest', '123456789');
+ $sub->add(':', 'admin', 'digest', '1234');
+ $sub->add(':wiki:', 'admin', 'digest', '1234');
+
+ $subscriptions = $sub->subscribers(':wiki:', 'admin');
+
+ $this->assertCount(1, $subscriptions[':'], 'More than one subscription saved for the root namespace even though the old one should have been overwritten.');
+ $this->assertCount(1, $subscriptions[':wiki:'], 'More than one subscription saved for the wiki namespace even though the old one should have been overwritten.');
+ $this->assertCount(2, $subscriptions, 'Didn\'t find the expected two subscriptions');
+ }
+}
+
+/**
+ * makes protected methods visible for testing
+ */
+class MockupSubscription extends Subscription {
+ public $mails; // we keep sent mails here
+
+ public function __construct() {
+ $this->reset();
+ }
+
+ /**
+ * resets the mail array
+ */
+ public function reset() {
+ $this->mails = array();
+ }
+
+ public function isenabled() {
+ return true;
+ }
+
+ public function buildregex($user = null, $style = null, $data = null) {
+ return parent::buildregex($user, $style, $data);
+ }
+
+ protected function send($subscriber_mail, $subject, $id, $template, $trep, $hrep = null) {
+ $this->mails[] = $subscriber_mail;
+ return true;
+ }
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/tests/inc/subscription_set.test.php b/_test/tests/inc/subscription_set.test.php
deleted file mode 100644
index 5c0a6c816..000000000
--- a/_test/tests/inc/subscription_set.test.php
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
-/**
- * Tests the subscription set function
- */
-class subscription_set_test extends DokuWikiTest {
- /**
- * Tests, if overwriting subscriptions works even when subscriptions for the same
- * user exist for two nested namespaces, this is a test for the bug described in FS#2580
- */
- function test_overwrite() {
- subscription_set('admin', ':', 'digest', '123456789');
- subscription_set('admin', ':wiki:', 'digest', '123456789');
- subscription_set('admin', ':', 'digest', '1234', true);
- subscription_set('admin', ':wiki:', 'digest', '1234', true);
- $subscriptions = subscription_find(':wiki:', array('user' => 'admin'));
- $this->assertCount(1, $subscriptions[':'], 'More than one subscription saved for the root namespace even though the old one should have been overwritten.');
- $this->assertCount(1, $subscriptions[':wiki:'], 'More than one subscription saved for the wiki namespace even though the old one should have been overwritten.');
- $this->assertCount(2, $subscriptions, 'Didn\'t find the expected two subscriptions');
- }
-}
diff --git a/inc/PassHash.class.php b/inc/PassHash.class.php
index 13be479cc..080fb4778 100644
--- a/inc/PassHash.class.php
+++ b/inc/PassHash.class.php
@@ -4,7 +4,7 @@
*
* This class implements various mechanisms used to hash passwords
*
- * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Andreas Gohr <andi@splitbrain.org>
* @license LGPL2
*/
class PassHash {
@@ -58,6 +58,12 @@ class PassHash {
} elseif(substr($hash, 0, 6) == '{SMD5}') {
$method = 'lsmd5';
$salt = substr(base64_decode(substr($hash, 6)), 16);
+ } elseif(preg_match('/^:B:(.+?):.{32}$/', $hash, $m)) {
+ $method = 'mediawiki';
+ $salt = $m[1];
+ } elseif(preg_match('/^\$6\$(.+?)\$/', $hash, $m)) {
+ $method = 'sha512';
+ $salt = $m[1];
} elseif($len == 32) {
$method = 'md5';
} elseif($len == 40) {
@@ -101,14 +107,18 @@ class PassHash {
* Initialize the passed variable with a salt if needed.
*
* If $salt is not null, the value is kept, but the lenght restriction is
- * applied.
+ * applied (unless, $cut is false).
*
* @param string &$salt The salt, pass null if you want one generated
- * @param int $len The length of the salt
+ * @param int $len The length of the salt
+ * @param bool $cut Apply length restriction to existing salt?
*/
- public function init_salt(&$salt, $len = 32) {
- if(is_null($salt)) $salt = $this->gen_salt($len);
- if(strlen($salt) > $len) $salt = substr($salt, 0, $len);
+ public function init_salt(&$salt, $len = 32, $cut = true) {
+ if(is_null($salt)) {
+ $salt = $this->gen_salt($len);
+ $cut = true; // for new hashes we alway apply length restriction
+ }
+ if(strlen($salt) > $len && $cut) $salt = substr($salt, 0, $len);
}
// Password hashing methods follow below
@@ -263,7 +273,7 @@ class PassHash {
*
* This method was used by old MySQL systems
*
- * @link http://www.php.net/mysql
+ * @link http://www.php.net/mysql
* @author <soren at byu dot edu>
* @param string $clear The clear text to hash
* @return string Hashed password
@@ -327,9 +337,9 @@ class PassHash {
* an exception.
*
* @link http://www.openwall.com/phpass/
- * @param string $clear The clear text to hash
- * @param string $salt The salt to use, null for random
- * @param string $magic The hash identifier (P or H)
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @param string $magic The hash identifier (P or H)
* @param int $compute The iteration count for new passwords
* @throws Exception
* @return string Hashed password
@@ -430,8 +440,8 @@ class PassHash {
* will break. When no salt is given, the iteration count can be set
* through the $compute variable.
*
- * @param string $clear The clear text to hash
- * @param string $salt The salt to use, null for random
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
* @param int $compute The iteration count (between 4 and 31)
* @throws Exception
* @return string Hashed password
@@ -450,4 +460,38 @@ class PassHash {
return crypt($clear, $salt);
}
+ /**
+ * Password hashing method SHA512
+ *
+ * This is only supported on PHP 5.3.2 or higher and will throw an exception if
+ * the needed crypt support is not available
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @return string Hashed password
+ * @throws Exception
+ */
+ public function hash_sha512($clear, $salt = null) {
+ if(!defined('CRYPT_SHA512') || CRYPT_SHA512 != 1) {
+ throw new Exception('This PHP installation has no SHA512 support');
+ }
+ $this->init_salt($salt, 8, false);
+ return crypt($clear, '$6$'.$salt.'$');
+ }
+
+ /**
+ * Password hashing method 'mediawiki'
+ *
+ * Uses salted MD5, this is referred to as Method B in MediaWiki docs. Unsalted md5
+ * method 'A' is not supported.
+ *
+ * @link http://www.mediawiki.org/wiki/Manual_talk:User_table#user_password_column
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @return string Hashed password
+ */
+ public function hash_mediawiki($clear, $salt = null) {
+ $this->init_salt($salt, 8, false);
+ return ':B:'.$salt.':'.md5($salt.'-'.md5($clear));
+ }
}
diff --git a/inc/actions.php b/inc/actions.php
index f65b47451..4083b0454 100644
--- a/inc/actions.php
+++ b/inc/actions.php
@@ -711,21 +711,28 @@ function act_subscription($act){
$target = $params['target'];
$style = $params['style'];
- $data = $params['data'];
$action = $params['action'];
// Perform action.
- if (!subscription_set($_SERVER['REMOTE_USER'], $target, $style, $data)) {
+ $sub = new Subscription();
+ if($action == 'unsubscribe'){
+ $ok = $sub->remove($target, $_SERVER['REMOTE_USER'], $style);
+ }else{
+ $ok = $sub->add($target, $_SERVER['REMOTE_USER'], $style);
+ }
+
+ if($ok) {
+ msg(sprintf($lang["subscr_{$action}_success"], hsc($INFO['userinfo']['name']),
+ prettyprint_id($target)), 1);
+ act_redirect($ID, $act);
+ } else {
throw new Exception(sprintf($lang["subscr_{$action}_error"],
hsc($INFO['userinfo']['name']),
prettyprint_id($target)));
}
- msg(sprintf($lang["subscr_{$action}_success"], hsc($INFO['userinfo']['name']),
- prettyprint_id($target)), 1);
- act_redirect($ID, $act);
// Assure that we have valid data if act_redirect somehow fails.
- $INFO['subscribed'] = get_info_subscribed();
+ $INFO['subscribed'] = $sub->user_subscription();
return 'show';
}
@@ -777,8 +784,7 @@ function subscription_handle_post(&$params) {
$style = null;
}
- $data = in_array($style, array('list', 'digest')) ? time() : null;
- $params = compact('target', 'style', 'data', 'action');
+ $params = compact('target', 'style', 'action');
}
//Setup VIM: ex: et ts=2 :
diff --git a/inc/auth.php b/inc/auth.php
index c68a699fe..c4f1dcf2b 100644
--- a/inc/auth.php
+++ b/inc/auth.php
@@ -780,23 +780,19 @@ function register() {
return false;
}
- // create substitutions for use in notification email
- $substitutions = array(
- 'NEWUSER' => $login,
- 'NEWNAME' => $fullname,
- 'NEWEMAIL' => $email,
- );
+ // send notification about the new user
+ $subscription = new Subscription();
+ $subscription->send_register($login, $fullname, $email);
+ // are we done?
if(!$conf['autopasswd']) {
msg($lang['regsuccess2'], 1);
- notify('', 'register', '', $login, false, $substitutions);
return true;
}
- // autogenerated password? then send him the password
+ // autogenerated password? then send password to user
if(auth_sendPassword($login, $pass)) {
msg($lang['regsuccess'], 1);
- notify('', 'register', '', $login, false, $substitutions);
return true;
} else {
msg($lang['regmailfail'], -1);
diff --git a/inc/changelog.php b/inc/changelog.php
index 688aebfd6..9768fea51 100644
--- a/inc/changelog.php
+++ b/inc/changelog.php
@@ -258,6 +258,7 @@ function getRecentsSince($from,$to=null,$ns='',$flags=0){
} else {
$lines = @file($conf['changelog']);
}
+ if(!$lines) return $recent;
// we start searching at the end of the list
$lines = array_reverse($lines);
diff --git a/inc/common.php b/inc/common.php
index 3c40a47dc..bc49e76b2 100644
--- a/inc/common.php
+++ b/inc/common.php
@@ -107,9 +107,11 @@ function pageinfo() {
$info['isadmin'] = false;
$info['ismanager'] = false;
if(isset($_SERVER['REMOTE_USER'])) {
+ $sub = new Subscription();
+
$info['userinfo'] = $USERINFO;
$info['perm'] = auth_quickaclcheck($ID);
- $info['subscribed'] = get_info_subscribed();
+ $info['subscribed'] = $sub->user_subscription();
$info['client'] = $_SERVER['REMOTE_USER'];
if($info['perm'] == AUTH_ADMIN) {
@@ -320,15 +322,13 @@ function idfilter($id, $ue = true) {
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
+ $conf['userewrite']
) {
$id = strtr($id, ':', ';');
}
if($ue) {
$id = rawurlencode($id);
$id = str_replace('%3A', ':', $id); //keep as colon
- $id = str_replace('%3B', ';', $id); //keep as semicolon
$id = str_replace('%2F', '/', $id); //keep as slash
}
return $id;
@@ -1105,90 +1105,31 @@ function saveOldRevision($id) {
* @author Andreas Gohr <andi@splitbrain.org>
*/
function notify($id, $who, $rev = '', $summary = '', $minor = false, $replace = array()) {
- global $lang;
global $conf;
- global $INFO;
- global $DIFF_INLINESTYLES;
// decide if there is something to do, eg. whom to mail
if($who == 'admin') {
if(empty($conf['notify'])) return false; //notify enabled?
- $text = rawLocale('mailtext');
- $to = $conf['notify'];
- $bcc = '';
+ $tpl = 'mailtext';
+ $to = $conf['notify'];
} elseif($who == 'subscribers') {
- if(!$conf['subscribers']) return false; //subscribers enabled?
+ 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);
trigger_event(
'COMMON_NOTIFY_ADDRESSLIST', $data,
- 'subscription_addresslist'
+ array(new Subscription(), 'notifyaddresses')
);
- $bcc = $data['addresslist'];
- if(empty($bcc)) return false;
- $to = '';
- $text = rawLocale('subscr_single');
- } elseif($who == 'register') {
- if(empty($conf['registernotify'])) return false;
- $text = rawLocale('registermail');
- $to = $conf['registernotify'];
- $bcc = '';
+ $to = $data['addresslist'];
+ if(empty($to)) return false;
+ $tpl = 'subscr_single';
} else {
return false; //just to be safe
}
- // prepare replacements (keys not set in hrep will be taken from trep)
- $trep = array(
- 'NEWPAGE' => wl($id, '', true, '&'),
- 'PAGE' => $id,
- 'SUMMARY' => $summary
- );
- $trep = array_merge($trep, $replace);
- $hrep = array();
-
// prepare content
- if($who == 'register') {
- $subject = $lang['mail_new_user'].' '.$summary;
- } elseif($rev) {
- $subject = $lang['mail_changed'].' '.$id;
- $trep['OLDPAGE'] = wl($id, "rev=$rev", true, '&');
- $old_content = rawWiki($id, $rev);
- $new_content = rawWiki($id);
- $df = new Diff(explode("\n", $old_content),
- explode("\n", $new_content));
- $dformat = new UnifiedDiffFormatter();
- $tdiff = $dformat->format($df);
-
- $DIFF_INLINESTYLES = true;
- $hdf = new Diff(explode("\n", hsc($old_content)),
- explode("\n", hsc($new_content)));
- $dformat = new InlineDiffFormatter();
- $hdiff = $dformat->format($hdf);
- $hdiff = '<table>'.$hdiff.'</table>';
- $DIFF_INLINESTYLES = false;
- } else {
- $subject = $lang['mail_newpage'].' '.$id;
- $trep['OLDPAGE'] = '---';
- $tdiff = rawWiki($id);
- $hdiff = nl2br(hsc($tdiff));
- }
- $trep['DIFF'] = $tdiff;
- $hrep['DIFF'] = $hdiff;
-
- // send mail
- $mail = new Mailer();
- $mail->to($to);
- $mail->bcc($bcc);
- $mail->subject($subject);
- $mail->setBody($text, $trep, $hrep);
- if($who == 'subscribers') {
- $mail->setHeader(
- 'List-Unsubscribe',
- '<'.wl($id, array('do'=> 'subscribe'), true, '&').'>',
- false
- );
- }
- return $mail->send();
+ $subscription = new Subscription();
+ return $subscription->send_diff($to, $tpl, $id, $rev, $summary);
}
/**
diff --git a/inc/html.php b/inc/html.php
index 5c1c75cf6..3124f4b1d 100644
--- a/inc/html.php
+++ b/inc/html.php
@@ -859,7 +859,7 @@ function html_list_index($item){
$base = ':'.$item['id'];
$base = substr($base,strrpos($base,':')+1);
if($item['type']=='d'){
- $ret .= '<a href="'.wl($ID,'idx='.rawurlencode($item['id'])).'" class="idx_dir"><strong>';
+ $ret .= '<a href="'.wl($ID,'idx='.rawurlencode($item['id'])).'" title="' . $item['id'] . '" class="idx_dir"><strong>';
$ret .= $base;
$ret .= '</strong></a>';
}else{
diff --git a/inc/indexer.php b/inc/indexer.php
index 7a62345bf..e518907d7 100644
--- a/inc/indexer.php
+++ b/inc/indexer.php
@@ -339,6 +339,109 @@ class Doku_Indexer {
}
/**
+ * Rename a page in the search index without changing the indexed content. This function doesn't check if the
+ * old or new name exists in the filesystem. It returns an error if the old page isn't in the page list of the
+ * indexer and it deletes all previously indexed content of the new page.
+ *
+ * @param string $oldpage The old page name
+ * @param string $newpage The new page name
+ * @return string|bool If the page was successfully renamed, can be a message in the case of an error
+ */
+ public function renamePage($oldpage, $newpage) {
+ if (!$this->lock()) return 'locked';
+
+ $pages = $this->getPages();
+
+ $id = array_search($oldpage, $pages);
+ if ($id === false) {
+ $this->unlock();
+ return 'page is not in index';
+ }
+
+ $new_id = array_search($newpage, $pages);
+ if ($new_id !== false) {
+ // make sure the page is not in the index anymore
+ if ($this->deletePageNoLock($newpage) !== true) {
+ return false;
+ }
+
+ $pages[$new_id] = 'deleted:'.time().rand(0, 9999);
+ }
+
+ $pages[$id] = $newpage;
+
+ // update index
+ if (!$this->saveIndex('page', '', $pages)) {
+ $this->unlock();
+ return false;
+ }
+
+ // reset the pid cache
+ $this->pidCache = array();
+
+ $this->unlock();
+ return true;
+ }
+
+ /**
+ * Renames a meta value in the index. This doesn't change the meta value in the pages, it assumes that all pages
+ * will be updated.
+ *
+ * @param string $key The metadata key of which a value shall be changed
+ * @param string $oldvalue The old value that shall be renamed
+ * @param string $newvalue The new value to which the old value shall be renamed, can exist (then values will be merged)
+ * @return bool|string If renaming the value has been successful, false or error message on error.
+ */
+ public function renameMetaValue($key, $oldvalue, $newvalue) {
+ if (!$this->lock()) return 'locked';
+
+ // change the relation references index
+ $metavalues = $this->getIndex($key, '_w');
+ $oldid = array_search($oldvalue, $metavalues);
+ if ($oldid !== false) {
+ $newid = array_search($newvalue, $metavalues);
+ if ($newid !== false) {
+ // free memory
+ unset ($metavalues);
+
+ // okay, now we have two entries for the same value. we need to merge them.
+ $indexline = $this->getIndexKey($key, '_i', $oldid);
+ if ($indexline != '') {
+ $newindexline = $this->getIndexKey($key, '_i', $newid);
+ $pagekeys = $this->getIndex($key, '_p');
+ $parts = explode(':', $indexline);
+ foreach ($parts as $part) {
+ list($id, $count) = explode('*', $part);
+ $newindexline = $this->updateTuple($newindexline, $id, $count);
+
+ $keyline = explode(':', $pagekeys[$id]);
+ // remove old meta value
+ $keyline = array_diff($keyline, array($oldid));
+ // add new meta value when not already present
+ if (!in_array($newid, $keyline)) {
+ array_push($keyline, $newid);
+ }
+ $pagekeys[$id] = implode(':', $keyline);
+ }
+ $this->saveIndex($key, '_p', $pagekeys);
+ unset($pagekeys);
+ $this->saveIndexKey($key, '_i', $oldid, '');
+ $this->saveIndexKey($key, '_i', $newid, $newindexline);
+ }
+ } else {
+ $metavalues[$oldid] = $newvalue;
+ if (!$this->saveIndex($key, '_w', $metavalues)) {
+ $this->unlock();
+ return false;
+ }
+ }
+ }
+
+ $this->unlock();
+ return true;
+ }
+
+ /**
* Remove a page from the index
*
* Erases entries in all known indexes.
@@ -351,10 +454,26 @@ class Doku_Indexer {
if (!$this->lock())
return "locked";
+ $result = $this->deletePageNoLock($page);
+
+ $this->unlock();
+
+ return $result;
+ }
+
+ /**
+ * Remove a page from the index without locking the index, only use this function if the index is already locked
+ *
+ * Erases entries in all known indexes.
+ *
+ * @param string $page a page name
+ * @return boolean the function completed successfully
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ protected function deletePageNoLock($page) {
// load known documents
$pid = $this->getPIDNoLock($page);
if ($pid === false) {
- $this->unlock();
return false;
}
@@ -380,7 +499,6 @@ class Doku_Indexer {
}
// Save the reverse index
if (!$this->saveIndexKey('pageword', '', $pid, "")) {
- $this->unlock();
return false;
}
@@ -397,7 +515,6 @@ class Doku_Indexer {
$this->saveIndexKey($metaname.'_p', '', $pid, '');
}
- $this->unlock();
return true;
}
diff --git a/inc/lang/ar/subscr_single.txt b/inc/lang/ar/subscr_single.txt
index 5c62aeaeb..611688415 100644
--- a/inc/lang/ar/subscr_single.txt
+++ b/inc/lang/ar/subscr_single.txt
@@ -15,7 +15,7 @@
لإلغاء إشعارات الصفحة,لُج الويكي في
@DOKUWIKIURL@ ثم زُر
-@NEWPAGE@
+@SUBSCRIBE@
وألغ الاشتراك من تغييرات الصفحة و/أو النطاق.
--
diff --git a/inc/lang/bg/subscr_single.txt b/inc/lang/bg/subscr_single.txt
index 7b26f8e96..a74a21fb8 100644
--- a/inc/lang/bg/subscr_single.txt
+++ b/inc/lang/bg/subscr_single.txt
@@ -14,7 +14,7 @@
Нова версия: @NEWPAGE@
Ако желаете да прекратите уведомяването за страницата трябва да се впишете на адрес @DOKUWIKIURL@, да посетите
-@NEWPAGE@
+@SUBSCRIBE@
и да прекратите абонамента за промени по страницата или именното пространство.
--
diff --git a/inc/lang/da/subscr_single.txt b/inc/lang/da/subscr_single.txt
index 64b14588c..cdc554513 100644
--- a/inc/lang/da/subscr_single.txt
+++ b/inc/lang/da/subscr_single.txt
@@ -15,7 +15,7 @@ Ny Revision: @NEWPAGE@
For at slå side notifikationer fra, skal du logge ind på
@DOKUWIKIURL@ og besøge
-@NEWPAGE@
+@SUBSCRIBE@
og slå abonnoment for side / navnerum ændringer fra.
--
diff --git a/inc/lang/de-informal/subscr_single.txt b/inc/lang/de-informal/subscr_single.txt
index 3c557bc17..6e3f58b9f 100644
--- a/inc/lang/de-informal/subscr_single.txt
+++ b/inc/lang/de-informal/subscr_single.txt
@@ -15,7 +15,7 @@ Neue Revision: @NEWPAGE@
Um das Abonnement für diese Seite aufzulösen, melde dich im Wiki an
@DOKUWIKIURL@, besuche dann
-@NEWPAGE@
+@SUBSCRIBE@
und klicke auf den Link 'Aboverwaltung'.
--
diff --git a/inc/lang/de/subscr_single.txt b/inc/lang/de/subscr_single.txt
index f3e1cd393..da9914e50 100644
--- a/inc/lang/de/subscr_single.txt
+++ b/inc/lang/de/subscr_single.txt
@@ -15,7 +15,7 @@ Neue Revision: @NEWPAGE@
Um das Abonnement für diese Seite aufzulösen, melden Sie sich im Wiki an
@DOKUWIKIURL@, besuchen dann
-@NEWPAGE@
+@SUBSCRIBE@
und klicken auf die Taste 'Aboverwaltung'.
--
diff --git a/inc/lang/el/lang.php b/inc/lang/el/lang.php
index b6cdc38c1..55b70074f 100644
--- a/inc/lang/el/lang.php
+++ b/inc/lang/el/lang.php
@@ -8,6 +8,7 @@
* @author Konstantinos Koryllos <koryllos@gmail.com>
* @author George Petsagourakis <petsagouris@gmail.com>
* @author Petros Vidalis <pvidalis@gmail.com>
+ * @author Vasileios Karavasilis vasileioskaravasilis@gmail.com
*/
$lang['encoding'] = 'utf-8';
$lang['direction'] = 'ltr';
@@ -43,6 +44,7 @@ $lang['btn_backtomedia'] = 'Επιστροφή στην επιλογή α
$lang['btn_subscribe'] = 'Εγγραφή σε λήψη ενημερώσεων σελίδας';
$lang['btn_profile'] = 'Επεξεργασία προφίλ';
$lang['btn_reset'] = 'Ακύρωση';
+$lang['btn_resendpwd'] = 'Εισαγωγή νέου κωδικού';
$lang['btn_draft'] = 'Επεξεργασία αυτόματα αποθηκευμένης σελίδας';
$lang['btn_recover'] = 'Επαναφορά αυτόματα αποθηκευμένης σελίδας';
$lang['btn_draftdel'] = 'Διαγραφή αυτόματα αποθηκευμένης σελίδας';
@@ -79,6 +81,7 @@ $lang['profnoempty'] = 'Δεν επιτρέπεται κενό όνο
$lang['profchanged'] = 'Το προφίλ χρήστη τροποποιήθηκε επιτυχώς.';
$lang['pwdforget'] = 'Ξεχάσατε το κωδικό σας; Αποκτήστε νέο.';
$lang['resendna'] = 'Αυτό το wiki δεν υποστηρίζει την εκ\' νέου αποστολή κωδικών.';
+$lang['resendpwd'] = 'Εισαγωγή νέου ωδικού για';
$lang['resendpwdmissing'] = 'Πρέπει να συμπληρώσετε όλα τα πεδία.';
$lang['resendpwdnouser'] = 'Αυτός ο χρήστης δεν υπάρχει στα αρχεία μας.';
$lang['resendpwdbadauth'] = 'Αυτός ο κωδικός ενεργοποίησης δεν είναι έγκυρος.';
@@ -91,6 +94,7 @@ $lang['searchmedia_in'] = 'Αναζήτηση σε %s';
$lang['txt_upload'] = 'Επιλέξτε αρχείο για φόρτωση';
$lang['txt_filename'] = 'Επιλέξτε νέο όνομα αρχείου (προαιρετικό)';
$lang['txt_overwrt'] = 'Αντικατάσταση υπάρχοντος αρχείου';
+$lang['maxuploadsize'] = 'Μέγιστο μέγεθος αρχείου: %s.';
$lang['lockedby'] = 'Προσωρινά κλειδωμένο από';
$lang['lockexpire'] = 'Το κλείδωμα λήγει στις';
$lang['js']['willexpire'] = 'Το κλείδωμά σας για την επεξεργασία αυτής της σελίδας θα λήξει σε ένα λεπτό.\n Για να το ανανεώσετε χρησιμοποιήστε την Προεπισκόπηση.';
@@ -185,6 +189,12 @@ $lang['external_edit'] = 'εξωτερική τροποποίηση';
$lang['summary'] = 'Επεξεργασία σύνοψης';
$lang['noflash'] = 'Το <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> απαιτείται για την προβολή αυτού του στοιχείου.';
$lang['download'] = 'Λήψη Κώδικα';
+$lang['tools'] = 'Εργαλεία';
+$lang['user_tools'] = 'Εργαλεία Χρήστη';
+$lang['site_tools'] = 'Εργαλεία ιστότοπου';
+$lang['page_tools'] = 'Εργαλεία ιστοσελίδας';
+$lang['skip_to_content'] = 'παράληψη περιεχομένων';
+$lang['sidebar'] = 'Sidebar';
$lang['mail_newpage'] = 'σελίδα προστέθηκε:';
$lang['mail_changed'] = 'σελίδα τροποποιήθηκε:';
$lang['mail_subscribe_list'] = 'σελίδες που άλλαξαν στον φάκελο:';
@@ -255,6 +265,7 @@ $lang['subscr_style_digest'] = 'συνοπτικό email αλλαγών της
$lang['subscr_style_list'] = 'λίστα σελίδων με αλλαγές μετά από το τελευταίο email (κάθε %.2f μέρες)';
$lang['authmodfailed'] = 'Κακή ρύθμιση λίστας χρηστών. Παρακαλούμε ενημερώστε τον διαχειριστή του wiki.';
$lang['authtempfail'] = 'Η συνδεση χρηστών είναι απενεργοποιημένη αυτή την στιγμή. Αν αυτό διαρκέσει για πολύ, παρακαλούμε ενημερώστε τον διαχειριστή του wiki.';
+$lang['authpwdexpire'] = 'Ο κωδικός πρόσβασης θα λήξει σε %s ημέρες. Προτείνουμε να τον αλλάξετε σύντομα.';
$lang['i_chooselang'] = 'Επιλογή γλώσσας';
$lang['i_installer'] = 'Οδηγός εγκατάστασης DokuWiki';
$lang['i_wikiname'] = 'Ονομασία wiki';
@@ -270,8 +281,8 @@ $lang['i_confexists'] = '<code>%s</code> υπάρχει ήδη';
$lang['i_writeerr'] = 'Δεν είναι δυνατή η δημιουργία του <code>%s</code>. Πρέπει να διορθώσετε τα δικαιώματα πρόσβασης αυτού του φακέλου/αρχείου και να δημιουργήσετε το αρχείο χειροκίνητα!';
$lang['i_badhash'] = 'Μη αναγνωρίσιμο ή τροποποιημένο αρχείο dokuwiki.php (hash=<code>%s</code>)';
$lang['i_badval'] = '<code>%s</code> - λάθος ή ανύπαρκτη τιμή';
-$lang['i_success'] = 'Η εγκατάσταση ολοκληρώθηκε επιτυχώς. Μπορείτε πλέον να διαγράψετε το αρχείο install.php. Συνεχίστε στο <a href="doku.php?id=wiki:welcome">νέο σας DokuWiki</a>.';
-$lang['i_failure'] = 'Εμφανίστηκαν κάποια προβλήματα στη διαδικασία ανανέωσης των αρχείων ρυθμίσεων. Πιθανόν να χρειάζεται να τα τροποποιήσετε χειροκίνητα ώστε να μπορείτε να χρησιμοποιήσετε το <a href="doku.php?id=wiki:welcome">νέο σας DokuWiki</a>.';
+$lang['i_success'] = 'Η εγκατάσταση ολοκληρώθηκε επιτυχώς. Μπορείτε πλέον να διαγράψετε το αρχείο install.php. Συνεχίστε στο <a href="doku.php">νέο σας DokuWiki</a>.';
+$lang['i_failure'] = 'Εμφανίστηκαν κάποια προβλήματα στη διαδικασία ανανέωσης των αρχείων ρυθμίσεων. Πιθανόν να χρειάζεται να τα τροποποιήσετε χειροκίνητα ώστε να μπορείτε να χρησιμοποιήσετε το <a href="doku.php">νέο σας DokuWiki</a>.';
$lang['i_policy'] = 'Αρχική πολιτική Λίστας Δικαιωμάτων Πρόσβασης - ACL';
$lang['i_pol0'] = 'Ανοιχτό Wiki (όλοι μπορούν να διαβάσουν ή να δημιουργήσουν/τροποποιήσουν σελίδες και να μεταφορτώσουν αρχεία)';
$lang['i_pol1'] = 'Δημόσιο Wiki (όλοι μπορούν να διαβάσουν σελίδες αλλά μόνο οι εγγεγραμμένοι χρήστες μπορούν να δημιουργήσουν/τροποποιήσουν σελίδες και να μεταφορτώσουν αρχεία)';
@@ -289,16 +300,20 @@ $lang['seconds'] = 'πριν %d δευτερόλεπτα';
$lang['wordblock'] = 'Η αλλαγή σας δεν αποθηκεύτηκε γιατί περιείχε spam.';
$lang['media_uploadtab'] = 'Φόρτωση';
$lang['media_searchtab'] = 'Αναζήτηση';
+$lang['media_file'] = 'Αρχείο';
$lang['media_viewtab'] = 'Εμφάνιση';
$lang['media_edittab'] = 'Επεξεργασία';
$lang['media_historytab'] = 'Ιστορικό';
-$lang['media_thumbsview'] = 'Προεπισκόπιση';
-$lang['media_listview'] = 'Λίστα';
-$lang['media_sort'] = 'Ταξινόμιση';
+$lang['media_list_thumbs'] = 'Μικρογραφίες';
+$lang['media_list_rows'] = 'Γραμμές';
$lang['media_sort_name'] = 'ανά όνομα';
$lang['media_sort_date'] = 'ανά ημερομηνία';
+$lang['media_namespaces'] = 'Επιλογή namespace';
+$lang['media_files'] = 'Αρχεία στο %s φάκελο';
$lang['media_upload'] = 'Φόρτωση στο <strong>%s</strong> φάκελο.';
$lang['media_search'] = 'Αναζήτηση στο <strong>%s</strong> φάκελο.';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s στα %s';
$lang['media_edit'] = 'Επεξεργασία';
$lang['media_history'] = 'Αυτές είναι οι παλαιότερες αναθεωρήσεις του αρχείου.';
$lang['media_meta_edited'] = 'τα μεταδεδομένα επεξεργάστηκαν';
diff --git a/inc/lang/el/mailwrap.html b/inc/lang/el/mailwrap.html
new file mode 100644
index 000000000..b2e655789
--- /dev/null
+++ b/inc/lang/el/mailwrap.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+<title>@TITLE@</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+</head>
+<body>
+
+@HTMLBODY@
+
+<br /><hr />
+<small>Το email έχει δημιουργηθεί από το DokuWiki στις @DOKUWIKIURL@.</small>
+</body>
+</html> \ No newline at end of file
diff --git a/inc/lang/el/resetpwd.txt b/inc/lang/el/resetpwd.txt
new file mode 100644
index 000000000..0d26d05fa
--- /dev/null
+++ b/inc/lang/el/resetpwd.txt
@@ -0,0 +1,3 @@
+====== Εισάγετε νέο κωδικό πρόσβασης ======
+
+Παρακαλούμε, εισάγετε έναν νέο κωδικό πρόσβασης για τον λογαριασμό σας. \ No newline at end of file
diff --git a/inc/lang/en/subscr_single.txt b/inc/lang/en/subscr_single.txt
index 673c4c32a..0bc310e04 100644
--- a/inc/lang/en/subscr_single.txt
+++ b/inc/lang/en/subscr_single.txt
@@ -15,7 +15,7 @@ New Revision: @NEWPAGE@
To cancel the page notifications, log into the wiki at
@DOKUWIKIURL@ then visit
-@NEWPAGE@
+@SUBSCRIBE@
and unsubscribe page and/or namespace changes.
--
diff --git a/inc/lang/eo/subscr_single.txt b/inc/lang/eo/subscr_single.txt
index 431fd0251..e4847e8ab 100644
--- a/inc/lang/eo/subscr_single.txt
+++ b/inc/lang/eo/subscr_single.txt
@@ -15,7 +15,7 @@ Nova versio: @NEWPAGE@
Por nuligi la paĝinformojn, ensalutu la vikion ĉe
@DOKUWIKIURL@, poste iru al
-@NEWPAGE@
+@SUBSCRIBE@
kaj malabonu la paĝajn kaj/aŭ nomspacajn ŝanĝojn.
--
diff --git a/inc/lang/gl/lang.php b/inc/lang/gl/lang.php
index a33aba72e..7cc06a833 100644
--- a/inc/lang/gl/lang.php
+++ b/inc/lang/gl/lang.php
@@ -5,7 +5,7 @@
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author Medúlio <medulio@ciberirmandade.org>
* @author Oscar M. Lage <r0sk10@gmail.com>
- * @author Leandro Regueiro <leandro.regueiro@gmail.com>
+ * @author Rodrigo Rega <rodrigorega@gmail.com>
*/
$lang['encoding'] = 'utf-8';
$lang['direction'] = 'ltr';
@@ -41,7 +41,7 @@ $lang['btn_backtomedia'] = 'Volver á Selección de Arquivos-Media';
$lang['btn_subscribe'] = 'Avísame dos trocos na páxina';
$lang['btn_profile'] = 'Actualizar Perfil';
$lang['btn_reset'] = 'Reiniciar';
-$lang['btn_resendpwd'] = 'Definir novo contrasinal';
+$lang['btn_resendpwd'] = 'Establecer novo contrasinal';
$lang['btn_draft'] = 'Editar borrador';
$lang['btn_recover'] = 'Recuperar borrador';
$lang['btn_draftdel'] = 'Eliminar borrador';
@@ -78,7 +78,7 @@ $lang['profnoempty'] = 'Non se permite un nome ou un enderezo de corre
$lang['profchanged'] = 'Perfil de usuario actualizado correctamente.';
$lang['pwdforget'] = 'Esqueceches o teu contrasinal? Consegue un novo';
$lang['resendna'] = 'Este wiki non permite o reenvío de contrasinais.';
-$lang['resendpwd'] = 'Definir novo contrasinal para';
+$lang['resendpwd'] = 'Establecer novo contrasinal para';
$lang['resendpwdmissing'] = 'Sentímolo, tes que cubrir todos os campos.';
$lang['resendpwdnouser'] = 'Sentímolo, non atopamos este usuario no noso banco de datos.';
$lang['resendpwdbadauth'] = 'Sentímolo, mais este código de autorización non é válido. Asegúrate de que usaches a ligazón completa de confirmación.';
@@ -91,7 +91,7 @@ $lang['searchmedia_in'] = 'Procurar en %s';
$lang['txt_upload'] = 'Escolle o arquivo para subir';
$lang['txt_filename'] = 'Subir como (opcional)';
$lang['txt_overwrt'] = 'Sobrescribir arquivo existente';
-$lang['maxuploadsize'] = 'Envío máx. de %s por ficheiro.';
+$lang['maxuploadsize'] = 'Subida máxima %s por arquivo.';
$lang['lockedby'] = 'Bloqueado actualmente por';
$lang['lockexpire'] = 'O bloqueo remata o';
$lang['js']['willexpire'] = 'O teu bloqueo para editares esta páxina vai caducar nun minuto.\nPara de evitar conflitos, emprega o botón de previsualización para reiniciares o contador do tempo de bloqueo.';
@@ -190,7 +190,7 @@ $lang['tools'] = 'Ferramentas';
$lang['user_tools'] = 'Ferramentas de usuario';
$lang['site_tools'] = 'Ferramentas do sitio';
$lang['page_tools'] = 'Ferramentas de páxina';
-$lang['skip_to_content'] = 'saltar ao contido';
+$lang['skip_to_content'] = 'Pasar ao contido';
$lang['sidebar'] = 'Barra lateral';
$lang['mail_newpage'] = 'páxina engadida:';
$lang['mail_changed'] = 'páxina mudada:';
@@ -262,7 +262,7 @@ $lang['subscr_style_digest'] = 'correo-e con resumo de trocos para cada páxin
$lang['subscr_style_list'] = 'lista de páxinas mudadas dende o último correo-e';
$lang['authmodfailed'] = 'Configuración de autenticación de usuario incorrecta. Por favor, informa ao Administrador do teu Wiki.';
$lang['authtempfail'] = 'A autenticación de usuario non está dispoñible de xeito temporal. De persistir esta situación, por favor, informa ao Administrador do teu Wiki.';
-$lang['authpwdexpire'] = 'O seu contrasinal vai caducar en %d días, razón pola cal debería cambialo axiña.';
+$lang['authpwdexpire'] = 'A túa contrasinal expirará en %d días, deberías cambiala pronto.';
$lang['i_chooselang'] = 'Escolle o teu idioma';
$lang['i_installer'] = 'Instalador do DokuWiki';
$lang['i_wikiname'] = 'Nome do Wiki';
diff --git a/inc/lang/gl/mailwrap.html b/inc/lang/gl/mailwrap.html
index 05ef4175a..19927c117 100644
--- a/inc/lang/gl/mailwrap.html
+++ b/inc/lang/gl/mailwrap.html
@@ -8,6 +8,6 @@
@HTMLBODY@
<br /><hr />
-<small>Esta mensaxe foi xerada por DokuWiki en @DOKUWIKIURL@.</small>
+<small>Este correo era xerado por DokuWiki en @DOKUWIKIURL@.</small>
</body>
</html> \ No newline at end of file
diff --git a/inc/lang/gl/resetpwd.txt b/inc/lang/gl/resetpwd.txt
index 7b662d8f5..d3d64e90d 100644
--- a/inc/lang/gl/resetpwd.txt
+++ b/inc/lang/gl/resetpwd.txt
@@ -1,3 +1,3 @@
-====== Definir novo contrasinal ======
+====== Establecer novo contrasinal ======
-Introduza un novo contrasinal para a súa conta neste wiki. \ No newline at end of file
+Por favor introduzca un novo contrasinal para a súa conta neste wiki. \ No newline at end of file
diff --git a/inc/lang/he/subscr_single.txt b/inc/lang/he/subscr_single.txt
index 123b186c8..78b551e2f 100644
--- a/inc/lang/he/subscr_single.txt
+++ b/inc/lang/he/subscr_single.txt
@@ -14,7 +14,7 @@
לביטול התרעות בנוגע לעמוד, יש להיכנס לאתר הוויקי בכתובת
@DOKUWIKIURL@ ואז לבקר בדף
-@NEWPAGE@
+@SUBSCRIBE@
ולבטל את המינוי לקבלת שינויים בדף ו/או במרחב השם.
--
diff --git a/inc/lang/ia/subscr_single.txt b/inc/lang/ia/subscr_single.txt
index 3d6ef7103..445df197c 100644
--- a/inc/lang/ia/subscr_single.txt
+++ b/inc/lang/ia/subscr_single.txt
@@ -15,7 +15,7 @@ Version nove: @NEWPAGE@
Pro cancellar le notificationes de paginas, aperi un session al wiki a
@DOKUWIKIURL@ postea visita
-@NEWPAGE@
+@SUBSCRIBE@
e cancella tu subscription al modificationes in paginas e/o spatios de nomines.
--
diff --git a/inc/lang/it/subscr_single.txt b/inc/lang/it/subscr_single.txt
index 8cde8ea0f..a8649a4ef 100644
--- a/inc/lang/it/subscr_single.txt
+++ b/inc/lang/it/subscr_single.txt
@@ -15,7 +15,7 @@ Nuova revisione: @NEWPAGE@
Per non ricevere più queste notifiche, collegati al
wiki all'indirizzo @DOKUWIKIURL@ e poi visita
-@NEWPAGE@
+@SUBSCRIBE@
e rimuovi la sottoscrizione alle modifiche della
pagina o categoria.
diff --git a/inc/lang/ko/subscr_single.txt b/inc/lang/ko/subscr_single.txt
index 6bd1885e6..2679db393 100644
--- a/inc/lang/ko/subscr_single.txt
+++ b/inc/lang/ko/subscr_single.txt
@@ -14,7 +14,7 @@
새 버전 : @NEWPAGE@
이 문서의 알림을 취소하려면, @DOKUWIKIURL@에 로그인한 뒤
-@NEWPAGE@ 문서를 방문하여 문서나 이름공간의 구독을 취소하세요.
+@SUBSCRIBE@ 문서를 방문하여 문서나 이름공간의 구독을 취소하세요.
--
@DOKUWIKIURL@의 DokuWiki가 자동으로 만들어낸 메일입니다. \ No newline at end of file
diff --git a/inc/lang/la/subscr_digest.txt b/inc/lang/la/subscr_digest.txt
index 629213359..32d378a7e 100644
--- a/inc/lang/la/subscr_digest.txt
+++ b/inc/lang/la/subscr_digest.txt
@@ -12,7 +12,7 @@ Noua recensio: @NEWPAGE@
Ut paginae adnotationes deleas, in uicem ineas in
@DOKUWIKIURL@, deinde uideas
-@NEWPAGE@
+@SUBSCRIBE@
et paginarum generum optiones mutes.
--
diff --git a/inc/lang/la/subscr_single.txt b/inc/lang/la/subscr_single.txt
index 7839791ea..14285014c 100644
--- a/inc/lang/la/subscr_single.txt
+++ b/inc/lang/la/subscr_single.txt
@@ -15,7 +15,7 @@ Noua recensio: @NEWPAGE@
Ut paginae adnotationes deleas, in uicem ineas in
@DOKUWIKIURL@, deinde uideas
-@NEWPAGE@
+@SUBSCRIBE@
et paginarum et\aut generum optiones mutasa.
--
diff --git a/inc/lang/no/subscr_digest.txt b/inc/lang/no/subscr_digest.txt
index 6afd0cc5c..670d39d32 100644
--- a/inc/lang/no/subscr_digest.txt
+++ b/inc/lang/no/subscr_digest.txt
@@ -12,7 +12,7 @@ Ny versjon: @NEWPAGE@
For å avslutte varslingen, logg inn på
@DOKUWIKIURL@ og gå til
-@NEWPAGE@
+@SUBSCRIBE@
og avslutt abonnementet på endringer av siden eller i navnerommet.
--
diff --git a/inc/lang/no/subscr_list.txt b/inc/lang/no/subscr_list.txt
index 72cd307cb..860d88d2a 100644
--- a/inc/lang/no/subscr_list.txt
+++ b/inc/lang/no/subscr_list.txt
@@ -9,7 +9,7 @@ Her er endringene:
For å avslutte varslinga, logg inn på
@DOKUWIKIURL@ og gå til
-@NEWPAGE@
+@SUBSCRIBE@
og avslutt abonnementet på endringer av sida eller i navnerommet.
--
diff --git a/inc/lang/no/subscr_single.txt b/inc/lang/no/subscr_single.txt
index 25296da58..b26b3a879 100644
--- a/inc/lang/no/subscr_single.txt
+++ b/inc/lang/no/subscr_single.txt
@@ -15,7 +15,7 @@ Ny versjon: @NEWPAGE@
For å avslutte varslingen, logg inn på
@DOKUWIKIURL@, gå til
-@NEWPAGE@
+@SUBSCRIBE@
og avslutt abonnementet på endringer av siden eller i navnerommet.
--
diff --git a/inc/lang/pt/subscr_single.txt b/inc/lang/pt/subscr_single.txt
index 1187b5911..469c6bfb1 100644
--- a/inc/lang/pt/subscr_single.txt
+++ b/inc/lang/pt/subscr_single.txt
@@ -15,7 +15,7 @@ Revisão Nova: @NEWPAGE@
Para cancelar as notificações de página, inicie sessão no wiki em
@DOKUWIKIURL@, visite
-@NEWPAGE@
+@SUBSCRIBE@
e des-subscreva às alterações de página e/ou espaço de nome.
--
diff --git a/inc/lang/sq/subscr_single.txt b/inc/lang/sq/subscr_single.txt
index 90520be4f..df28ee176 100644
--- a/inc/lang/sq/subscr_single.txt
+++ b/inc/lang/sq/subscr_single.txt
@@ -15,7 +15,7 @@ Rishikimi i ri: @NEWPAGE@
Për të fshirë lajmërimet e faqes, hyni në wiki tek
@DOKUWIKIURL@ dhe pastaj vizitoni
-@NEWPAGE@
+@SUBSCRIBE@
dhe fshini ndryshimet e faqes dhe/ose hapësirës së emrit.
--
diff --git a/inc/load.php b/inc/load.php
index 49c307054..7fd9fc9d0 100644
--- a/inc/load.php
+++ b/inc/load.php
@@ -82,6 +82,7 @@ function load_autoload($name){
'Mailer' => DOKU_INC.'inc/Mailer.class.php',
'RemoteAPI' => DOKU_INC.'inc/remote.php',
'RemoteAPICore' => DOKU_INC.'inc/RemoteAPICore.php',
+ 'Subscription' => DOKU_INC.'inc/subscription.php',
'DokuWiki_Action_Plugin' => DOKU_PLUGIN.'action.php',
'DokuWiki_Admin_Plugin' => DOKU_PLUGIN.'admin.php',
diff --git a/inc/media.php b/inc/media.php
index 6335bf210..572b1177c 100644
--- a/inc/media.php
+++ b/inc/media.php
@@ -535,32 +535,13 @@ function media_contentcheck($file,$mime){
* Send a notify mail on uploads
*
* @author Andreas Gohr <andi@splitbrain.org>
- * @fixme this should embed thumbnails of images in HTML version
*/
function media_notify($id,$file,$mime,$old_rev=false){
- global $lang;
global $conf;
- global $INFO;
if(empty($conf['notify'])) return; //notify enabled?
- $text = rawLocale('uploadmail');
- $trep = array(
- 'MIME' => $mime,
- 'MEDIA' => ml($id,'',true,'&',true),
- 'SIZE' => filesize_h(filesize($file)),
- );
-
- if ($old_rev && $conf['mediarevisions']) {
- $trep['OLD'] = ml($id, "rev=$old_rev", true, '&', true);
- } else {
- $trep['OLD'] = '---';
- }
-
- $mail = new Mailer();
- $mail->to($conf['notify']);
- $mail->subject($lang['mail_upload'].' '.$id);
- $mail->setBody($text,$trep);
- return $mail->send();
+ $subscription = new Subscription();
+ return $subscription->send_media_diff($conf['notify'], 'uploadmail', $id, $old_rev, '');
}
/**
diff --git a/inc/plugin.php b/inc/plugin.php
index 153e89407..649fc1f26 100644
--- a/inc/plugin.php
+++ b/inc/plugin.php
@@ -189,7 +189,7 @@ class DokuWiki_Plugin {
*
* @return object helper plugin object
*/
- function loadHelper($name, $msg){
+ function loadHelper($name, $msg = true){
if (!plugin_isdisabled($name)){
$obj = plugin_load('helper',$name);
}else{
diff --git a/inc/subscription.php b/inc/subscription.php
index 6b201c266..2989de032 100644
--- a/inc/subscription.php
+++ b/inc/subscription.php
@@ -1,414 +1,697 @@
<?php
/**
- * Utilities for handling (email) subscriptions
- *
- * The public interface of this file consists of the functions
- * - subscription_find
- * - subscription_send_digest
- * - subscription_send_list
- * - subscription_set
- * - get_info_subscribed
- * - subscription_addresslist
- * - subscription_lock
- * - subscription_unlock
+ * Class for handling (email) subscriptions
*
* @author Adrian Lang <lang@cosmocode.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*/
+class Subscription {
-/**
- * Get the name of the metafile tracking subscriptions to target page or
- * namespace
- *
- * @author Adrian Lang <lang@cosmocode.de>
- *
- * @param string $id The target page or namespace, specified by id; Namespaces
- * are identified by appending a colon.
- * @return string
- */
-function subscription_filename($id) {
- $meta_fname = '.mlist';
- if ((substr($id, -1, 1) === ':')) {
- $meta_froot = getNS($id);
- $meta_fname = '/' . $meta_fname;
- } else {
- $meta_froot = $id;
+ /**
+ * Check if subscription system is enabled
+ *
+ * @return bool
+ */
+ public function isenabled() {
+ return actionOK('subscribe');
}
- return metaFN((string) $meta_froot, $meta_fname);
-}
-/**
- * Lock subscription info for an ID
- *
- * @author Adrian Lang <lang@cosmocode.de>
- * @param string $id The target page or namespace, specified by id; Namespaces
- * are identified by appending a colon.
- * @return string
- */
-function subscription_lock_filename ($id){
- global $conf;
- return $conf['lockdir'].'/_subscr_' . md5($id) . '.lock';
-}
+ /**
+ * Return the subscription meta file for the given ID
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ * @return string
+ */
+ protected function file($id) {
+ $meta_fname = '.mlist';
+ if((substr($id, -1, 1) === ':')) {
+ $meta_froot = getNS($id);
+ $meta_fname = '/'.$meta_fname;
+ } else {
+ $meta_froot = $id;
+ }
+ return metaFN((string) $meta_froot, $meta_fname);
+ }
-/**
- * Creates a lock file for writing subscription data
- *
- * @todo add lock time parameter to io_lock() and use this instead
- * @param $id
- * @return bool
- */
-function subscription_lock($id) {
- global $conf;
- $lock = subscription_lock_filename($id);
+ /**
+ * Lock subscription info
+ *
+ * We don't use io_lock() her because we do not wait for the lock and use a larger stale time
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ * @return bool true, if you got a succesful lock
+ */
+ protected function lock($id) {
+ global $conf;
+
+ $lock = $conf['lockdir'].'/_subscr_'.md5($id).'.lock';
+
+ if(is_dir($lock) && time() - @filemtime($lock) > 60 * 5) {
+ // looks like a stale lock - remove it
+ @rmdir($lock);
+ }
+
+ // try creating the lock directory
+ if(!@mkdir($lock, $conf['dmode'])) {
+ return false;
+ }
- if (is_dir($lock) && time()-@filemtime($lock) > 60*5) {
- // looks like a stale lock - remove it
- @rmdir($lock);
+ if($conf['dperm']) chmod($lock, $conf['dperm']);
+ return true;
}
- // try creating the lock directory
- if (!@mkdir($lock,$conf['dmode'])) {
- return false;
+ /**
+ * Unlock subscription info
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ * @return bool
+ */
+ protected function unlock($id) {
+ global $conf;
+ $lock = $conf['lockdir'].'/_subscr_'.md5($id).'.lock';
+ return @rmdir($lock);
}
- if($conf['dperm']) chmod($lock, $conf['dperm']);
- return true;
-}
+ /**
+ * Construct a regular expression for parsing a subscription definition line
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string|array $user
+ * @param string|array $style
+ * @param string|array $data
+ * @return string complete regexp including delimiters
+ * @throws Exception when no data is passed
+ */
+ protected function buildregex($user = null, $style = null, $data = null) {
+ // always work with arrays
+ $user = (array) $user;
+ $style = (array) $style;
+ $data = (array) $data;
-/**
- * Unlock subscription info for an ID
- *
- * @author Adrian Lang <lang@cosmocode.de>
- * @param string $id The target page or namespace, specified by id; Namespaces
- * are identified by appending a colon.
- * @return bool
- */
-function subscription_unlock($id) {
- $lockf = subscription_lock_filename($id);
- return @rmdir($lockf);
-}
+ // clean
+ $user = array_filter(array_map('trim', $user));
+ $style = array_filter(array_map('trim', $style));
+ $data = array_filter(array_map('trim', $data));
-/**
- * Set subscription information
- *
- * Allows to set subscription information for permanent storage in meta files.
- * Subscriptions consist of a target object, a subscribing user, a subscribe
- * style and optional data.
- * A subscription may be deleted by specifying an empty subscribe style.
- * Only one subscription per target and user is allowed.
- * The function returns false on error, otherwise true. Note that no error is
- * returned if a subscription should be deleted but the user is not subscribed
- * and the subscription meta file exists.
- *
- * @author Adrian Lang <lang@cosmocode.de>
- *
- * @param string $user The subscriber or unsubscriber
- * @param string $page The target object (page or namespace), specified by
- * id; Namespaces are identified by a trailing colon.
- * @param string $style The subscribe style; DokuWiki currently implements
- * “every”, “digest”, and “list”.
- * @param string $data An optional data blob
- * @param bool $overwrite Whether an existing subscription may be overwritten
- * @return bool
- */
-function subscription_set($user, $page, $style, $data = null,
- $overwrite = false) {
- global $lang;
- if (is_null($style)) {
- // Delete subscription.
- $file = subscription_filename($page);
- if (!@file_exists($file)) {
- msg(sprintf($lang['subscr_not_subscribed'], $user,
- prettyprint_id($page)), -1);
- return false;
+ // user names are encoded
+ $user = array_map('auth_nameencode', $user);
+
+ // quote
+ $user = array_map('preg_quote_cb', $user);
+ $style = array_map('preg_quote_cb', $style);
+ $data = array_map('preg_quote_cb', $data);
+
+ // join
+ $user = join('|', $user);
+ $style = join('|', $style);
+ $data = join('|', $data);
+
+ // any data at all?
+ if($user.$style.$data === '') throw new Exception('no data passed');
+
+ // replace empty values, set which ones are optional
+ $sopt = '';
+ $dopt = '';
+ if($user === '') {
+ $user = '\S+';
+ }
+ if($style === '') {
+ $style = '\S+';
+ $sopt = '?';
+ }
+ if($data === '') {
+ $data = '\S+';
+ $dopt = '?';
}
- // io_deleteFromFile does not return false if no line matched.
- return io_deleteFromFile($file,
- subscription_regex(array('user' => auth_nameencode($user))),
- true);
+ // assemble
+ return "/^($user)(?:\\s+($style))$sopt(?:\\s+($data))$dopt$/";
}
- // Delete subscription if one exists and $overwrite is true. If $overwrite
- // is false, fail.
- $subs = subscription_find($page, array('user' => $user));
- if (count($subs) > 0 && isset($subs[$page])) {
- if (!$overwrite) {
- msg(sprintf($lang['subscr_already_subscribed'], $user,
- prettyprint_id($page)), -1);
- return false;
- }
- // Fail if deletion failed, else continue.
- if (!subscription_set($user, $page, null)) {
- return false;
+ /**
+ * Recursively search for matching subscriptions
+ *
+ * This function searches all relevant subscription files for a page or
+ * namespace.
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $page The target object’s (namespace or page) id
+ * @param string|array $user
+ * @param string|array $style
+ * @param string|array $data
+ * @return array
+ */
+ public function subscribers($page, $user = null, $style = null, $data = null) {
+ if(!$this->isenabled()) return array();
+
+ // Construct list of files which may contain relevant subscriptions.
+ $files = array(':' => $this->file(':'));
+ do {
+ $files[$page] = $this->file($page);
+ $page = getNS(rtrim($page, ':')).':';
+ } while($page !== ':');
+
+ $re = $this->buildregex($user, $style, $data);
+
+ // Handle files.
+ $result = array();
+ foreach($files as $target => $file) {
+ if(!@file_exists($file)) continue;
+
+ $lines = file($file);
+ foreach($lines as $line) {
+ // fix old style subscription files
+ if(strpos($line, ' ') === false) $line = trim($line)." every\n";
+
+ // check for matching entries
+ if(!preg_match($re, $line, $m)) continue;
+
+ $u = rawurldecode($m[1]); // decode the user name
+ if(!isset($result[$target])) $result[$target] = array();
+ $result[$target][$u] = array($m[2], $m[3]); // add to result
+ }
}
+ return array_reverse($result);
}
- $file = subscription_filename($page);
- $content = auth_nameencode($user) . ' ' . $style;
- if (!is_null($data)) {
- $content .= ' ' . $data;
+ /**
+ * Adds a new subscription for the given page or namespace
+ *
+ * This will automatically overwrite any existent subscription for the given user on this
+ * *exact* page or namespace. It will *not* modify any subscription that may exist in higher namespaces.
+ *
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ * @param string $user
+ * @param string $style
+ * @param string $data
+ * @throws Exception when user or style is empty
+ * @return bool
+ */
+ public function add($id, $user, $style, $data = '') {
+ if(!$this->isenabled()) return false;
+
+ // delete any existing subscription
+ $this->remove($id, $user);
+
+ $user = auth_nameencode(trim($user));
+ $style = trim($style);
+ $data = trim($data);
+
+ if(!$user) throw new Exception('no subscription user given');
+ if(!$style) throw new Exception('no subscription style given');
+ if(!$data) $data = time(); //always add current time for new subscriptions
+
+ $line = "$user $style $data\n";
+ $file = $this->file($id);
+ return io_saveFile($file, $line, true);
}
- return io_saveFile($file, $content . "\n", true);
-}
-/**
- * Recursively search for matching subscriptions
- *
- * This function searches all relevant subscription files for a page or
- * namespace.
- *
- * @author Adrian Lang <lang@cosmocode.de>
- * @see function subscription_regex for $pre documentation
- *
- * @param string $page The target object’s (namespace or page) id
- * @param array $pre A hash of predefined values
- * @return array
- */
-function subscription_find($page, $pre) {
- // Construct list of files which may contain relevant subscriptions.
- $filenames = array(':' => subscription_filename(':'));
- do {
- $filenames[$page] = subscription_filename($page);
- $page = getNS(rtrim($page, ':')) . ':';
- } while ($page !== ':');
-
- // Handle files.
- $matches = array();
- foreach ($filenames as $cur_page => $filename) {
- if (!@file_exists($filename)) {
- continue;
+ /**
+ * Removes a subscription for the given page or namespace
+ *
+ * This removes all subscriptions matching the given criteria on the given page or
+ * namespace. It will *not* modify any subscriptions that may exist in higher
+ * namespaces.
+ *
+ * @param string $id The target object’s (namespace or page) id
+ * @param string|array $user
+ * @param string|array $style
+ * @param string|array $data
+ * @return bool
+ */
+ public function remove($id, $user = null, $style = null, $data = null) {
+ if(!$this->isenabled()) return false;
+
+ $file = $this->file($id);
+ if(!file_exists($file)) return true;
+
+ $re = $this->buildregex($user, $style, $data);
+ return io_deleteFromFile($file, $re, true);
+ }
+
+ /**
+ * Get data for $INFO['subscribed']
+ *
+ * $INFO['subscribed'] is either false if no subscription for the current page
+ * and user is in effect. Else it contains an array of arrays with the fields
+ * “target”, “style”, and optionally “data”.
+ *
+ * @param string $id Page ID, defaults to global $ID
+ * @param string $user User, defaults to $_SERVER['REMOTE_USER']
+ * @return array
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+ function user_subscription($id = '', $user = '') {
+ if(!$this->isenabled()) return false;
+
+ global $ID;
+ if(!$id) $id = $ID;
+ if(!$user) $user = $_SERVER['REMOTE_USER'];
+
+ $subs = $this->subscribers($id, $user);
+ if(!count($subs)) return false;
+
+ $result = array();
+ foreach($subs as $target => $info) {
+ $result[] = array(
+ 'target' => $target,
+ 'style' => $info[$user][0],
+ 'data' => $info[$user][1]
+ );
}
- $subscriptions = file($filename);
- foreach ($subscriptions as $subscription) {
- if (strpos($subscription, ' ') === false) {
- // This is an old subscription file.
- $subscription = trim($subscription) . " every\n";
- }
- list($user, $rest) = explode(' ', $subscription, 2);
- $subscription = rawurldecode($user) . " " . $rest;
+ return $result;
+ }
- if (preg_match(subscription_regex($pre), $subscription,
- $line_matches) === 0) {
- continue;
- }
- $match = array_slice($line_matches, 1);
- if (!isset($matches[$cur_page])) {
- $matches[$cur_page] = array();
+ /**
+ * Send digest and list subscriptions
+ *
+ * This sends mails to all subscribers that have a subscription for namespaces above
+ * the given page if the needed $conf['subscribe_time'] has passed already.
+ *
+ * This function is called form lib/exe/indexer.php
+ *
+ * @param string $page
+ * @return int number of sent mails
+ */
+ public function send_bulk($page) {
+ if(!$this->isenabled()) return 0;
+
+ /** @var auth_basic $auth */
+ global $auth;
+ global $conf;
+ global $USERINFO;
+ $count = 0;
+
+ $subscriptions = $this->subscribers($page, null, array('digest', 'list'));
+
+ // remember current user info
+ $olduinfo = $USERINFO;
+ $olduser = $_SERVER['REMOTE_USER'];
+
+ foreach($subscriptions as $target => $users) {
+ if(!$this->lock($target)) continue;
+
+ foreach($users as $user => $info) {
+ list($style, $lastupdate) = $info;
+
+ $lastupdate = (int) $lastupdate;
+ if($lastupdate + $conf['subscribe_time'] > time()) {
+ // Less than the configured time period passed since last
+ // update.
+ continue;
+ }
+
+ // Work as the user to make sure ACLs apply correctly
+ $USERINFO = $auth->getUserData($user);
+ $_SERVER['REMOTE_USER'] = $user;
+ if($USERINFO === false) continue;
+ if(!$USERINFO['mail']) continue;
+
+ if(substr($target, -1, 1) === ':') {
+ // subscription target is a namespace, get all changes within
+ $changes = getRecentsSince($lastupdate, null, getNS($target));
+ } else {
+ // single page subscription, check ACL ourselves
+ if(auth_quickaclcheck($target) < AUTH_READ) continue;
+ $meta = p_get_metadata($target);
+ $changes = array($meta['last_change']);
+ }
+
+ // Filter out pages only changed in small and own edits
+ $change_ids = array();
+ foreach($changes as $rev) {
+ $n = 0;
+ while(!is_null($rev) && $rev['date'] >= $lastupdate &&
+ ($_SERVER['REMOTE_USER'] === $rev['user'] ||
+ $rev['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT)) {
+ $rev = getRevisions($rev['id'], $n++, 1);
+ $rev = (count($rev) > 0) ? $rev[0] : null;
+ }
+
+ if(!is_null($rev) && $rev['date'] >= $lastupdate) {
+ // Some change was not a minor one and not by myself
+ $change_ids[] = $rev['id'];
+ }
+ }
+
+ // send it
+ if($style === 'digest') {
+ foreach($change_ids as $change_id) {
+ $this->send_digest(
+ $USERINFO['mail'], $change_id,
+ $lastupdate
+ );
+ $count++;
+ }
+ } elseif($style === 'list') {
+ $this->send_list($USERINFO['mail'], $change_ids, $target);
+ $count++;
+ }
+ // TODO: Handle duplicate subscriptions.
+
+ // Update notification time.
+ $this->add($target, $user, $style, time());
}
- $matches[$cur_page][] = $match;
+ $this->unlock($target);
}
- }
- return array_reverse($matches);
-}
-/**
- * Get data for $INFO['subscribed']
- *
- * $INFO['subscribed'] is either false if no subscription for the current page
- * and user is in effect. Else it contains an array of arrays with the fields
- * “target”, “style”, and optionally “data”.
- *
- * @author Adrian Lang <lang@cosmocode.de>
- */
-function get_info_subscribed() {
- global $ID;
- global $conf;
- if (!$conf['subscribers']) {
- return false;
+ // restore current user info
+ $USERINFO = $olduinfo;
+ $_SERVER['REMOTE_USER'] = $olduser;
+ return $count;
}
- $subs = subscription_find($ID, array('user' => $_SERVER['REMOTE_USER']));
- if (count($subs) === 0) {
- return false;
+ /**
+ * Send the diff for some page change
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param string $template Mail template ('subscr_digest', 'subscr_single', 'mailtext', ...)
+ * @param string $id Page for which the notification is
+ * @param int|null $rev Old revision if any
+ * @param string $summary Change summary if any
+ * @return bool true if successfully sent
+ */
+ public function send_diff($subscriber_mail, $template, $id, $rev = null, $summary = '') {
+ global $DIFF_INLINESTYLES;
+
+ // prepare replacements (keys not set in hrep will be taken from trep)
+ $trep = array(
+ 'PAGE' => $id,
+ 'NEWPAGE' => wl($id, '', true, '&'),
+ 'SUMMARY' => $summary,
+ 'SUBSCRIBE' => wl($id, array('do' => 'subscribe'), true, '&')
+ );
+ $hrep = array();
+
+ if($rev) {
+ $subject = 'changed';
+ $trep['OLDPAGE'] = wl($id, "rev=$rev", true, '&');
+
+ $old_content = rawWiki($id, $rev);
+ $new_content = rawWiki($id);
+
+ $df = new Diff(explode("\n", $old_content),
+ explode("\n", $new_content));
+ $dformat = new UnifiedDiffFormatter();
+ $tdiff = $dformat->format($df);
+
+ $DIFF_INLINESTYLES = true;
+ $df = new Diff(explode("\n", hsc($old_content)),
+ explode("\n", hsc($new_content)));
+ $dformat = new InlineDiffFormatter();
+ $hdiff = $dformat->format($df);
+ $hdiff = '<table>'.$hdiff.'</table>';
+ $DIFF_INLINESTYLES = false;
+ } else {
+ $subject = 'newpage';
+ $trep['OLDPAGE'] = '---';
+ $tdiff = rawWiki($id);
+ $hdiff = nl2br(hsc($tdiff));
+ }
+
+ $trep['DIFF'] = $tdiff;
+ $hrep['DIFF'] = $hdiff;
+
+ $headers = array('Message-Id' => $this->getMessageID($id));
+ if ($rev) {
+ $headers['In-Reply-To'] = $this->getMessageID($id, $rev);
+ }
+
+ return $this->send(
+ $subscriber_mail, $subject, $id,
+ $template, $trep, $hrep, $headers
+ );
}
- $_ret = array();
- foreach ($subs as $target => $subs_data) {
- $new = array('target' => $target,
- 'style' => $subs_data[0][0]);
- if (count($subs_data[0]) > 1) {
- $new['data'] = $subs_data[0][1];
+ /**
+ * Send the diff for some media change
+ *
+ * @fixme this should embed thumbnails of images in HTML version
+ * @param string $subscriber_mail The target mail address
+ * @param string $template Mail template ('uploadmail', ...)
+ * @param string $id Media file for which the notification is
+ * @param int|bool $rev Old revision if any
+ * @return bool true if successfully sent
+ */
+ public function send_media_diff($subscriber_mail, $template, $id, $rev = false) {
+ global $conf;
+
+ $file = mediaFN($id);
+ list($mime, $ext) = mimetype($id);
+
+ $trep = array(
+ 'MIME' => $mime,
+ 'MEDIA' => ml($id,'',true,'&',true),
+ 'SIZE' => filesize_h(filesize($file)),
+ );
+
+ if ($rev && $conf['mediarevisions']) {
+ $trep['OLD'] = ml($id, "rev=$rev", true, '&', true);
+ } else {
+ $trep['OLD'] = '---';
+ }
+
+ $headers = array('Message-Id' => $this->getMessageID($id, @filemtime($file)));
+ if ($rev) {
+ $headers['In-Reply-To'] = $this->getMessageID($id, $rev);
}
- $_ret[] = $new;
+
+ $this->send($subscriber_mail, 'upload', $id, $template, $trep, null, $headers);
+
}
- return $_ret;
-}
+ /**
+ * Send a notify mail on new registration
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $login login name of the new user
+ * @param string $fullname full name of the new user
+ * @param string $email email address of the new user
+ * @return bool true if a mail was sent
+ */
+ public function send_register($login, $fullname, $email) {
+ global $conf;
+ if(empty($conf['registernotify'])) return false;
-/**
- * Construct a regular expression parsing a subscription definition line
- *
- * @author Adrian Lang <lang@cosmocode.de>
- *
- * @param array $pre A hash of predefined values; “user”, “style”, and
- * “data” may be set to limit the results to
- * subscriptions matching these parameters. If
- * “escaped” is true, these fields are inserted into the
- * regular expression without escaping.
- *
- * @return string complete regexp including delimiters
- */
-function subscription_regex($pre = array()) {
- if (!isset($pre['escaped']) || $pre['escaped'] === false) {
- $pre = array_map('preg_quote_cb', $pre);
+ $trep = array(
+ 'NEWUSER' => $login,
+ 'NEWNAME' => $fullname,
+ 'NEWEMAIL' => $email,
+ );
+
+ return $this->send(
+ $conf['registernotify'],
+ 'new_user',
+ $login,
+ 'registermail',
+ $trep
+ );
}
- foreach (array('user', 'style', 'data') as $key) {
- if (!isset($pre[$key])) {
- $pre[$key] = '(\S+)';
+
+ /**
+ * Send a digest mail
+ *
+ * Sends a digest mail showing a bunch of changes of a single page. Basically the same as send_diff()
+ * but determines the last known revision first
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param array $id The ID
+ * @param int $lastupdate Time of the last notification
+ * @return bool
+ */
+ protected function send_digest($subscriber_mail, $id, $lastupdate) {
+ $n = 0;
+ do {
+ $rev = getRevisions($id, $n++, 1);
+ $rev = (count($rev) > 0) ? $rev[0] : null;
+ } while(!is_null($rev) && $rev > $lastupdate);
+
+ return $this->send_diff(
+ $subscriber_mail,
+ 'subscr_digest',
+ $id, $rev
+ );
+ }
+
+ /**
+ * Send a list mail
+ *
+ * Sends a list mail showing a list of changed pages.
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param array $ids Array of ids
+ * @param string $ns_id The id of the namespace
+ * @return bool true if a mail was sent
+ */
+ protected function send_list($subscriber_mail, $ids, $ns_id) {
+ if(count($ids) === 0) return false;
+
+ $tlist = '';
+ $hlist = '<ul>';
+ foreach($ids as $id) {
+ $link = wl($id, array(), true);
+ $tlist .= '* '.$link.NL;
+ $hlist .= '<li><a href="'.$link.'">'.hsc($id).'</a></li>'.NL;
}
+ $hlist .= '</ul>';
+
+ $id = prettyprint_id($ns_id);
+ $trep = array(
+ 'DIFF' => rtrim($tlist),
+ 'PAGE' => $id,
+ 'SUBSCRIBE' => wl($id, array('do' => 'subscribe'), true, '&')
+ );
+ $hrep = array(
+ 'DIFF' => $hlist
+ );
+
+ return $this->send(
+ $subscriber_mail,
+ 'subscribe_list',
+ $ns_id,
+ 'subscr_list', $trep, $hrep
+ );
}
- return '/^' . $pre['user'] . '(?: ' . $pre['style'] .
- '(?: ' . $pre['data'] . ')?)?$/';
-}
-/**
- * Return a string with the email addresses of all the
- * users subscribed to a page
- *
- * This is the default action for COMMON_NOTIFY_ADDRESSLIST.
- *
- * @author Steven Danz <steven-danz@kc.rr.com>
- * @author Adrian Lang <lang@cosmocode.de>
- *
- * @todo this does NOT return a string but uses a reference to write back, either fix function or docs
- * @param array $data Containing $id (the page id), $self (whether the author
- * should be notified, $addresslist (current email address
- * list)
- * @return string
- */
-function subscription_addresslist(&$data){
- global $conf;
- /** @var auth_basic $auth */
- global $auth;
+ /**
+ * Helper function for sending a mail
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param string $subject The lang id of the mail subject (without the
+ * prefix “mail_”)
+ * @param string $context The context of this mail, eg. page or namespace id
+ * @param string $template The name of the mail template
+ * @param array $trep Predefined parameters used to parse the
+ * template (in text format)
+ * @param array $hrep Predefined parameters used to parse the
+ * template (in HTML format), null to default to $trep
+ * @param array $headers Additional mail headers in the form 'name' => 'value'
+ * @return bool
+ */
+ protected function send($subscriber_mail, $subject, $context, $template, $trep, $hrep = null, $headers = array()) {
+ global $lang;
+ global $conf;
+
+ $text = rawLocale($template);
+ $subject = $lang['mail_'.$subject].' '.$context;
+ $mail = new Mailer();
+ $mail->bcc($subscriber_mail);
+ $mail->subject($subject);
+ $mail->setBody($text, $trep, $hrep);
+ if(in_array($template, array('subscr_list', 'subscr_digest'))){
+ $mail->from($conf['mailfromnobody']);
+ }
+ if(isset($trep['SUBSCRIBE'])) {
+ $mail->setHeader('List-Unsubscribe', '<'.$trep['SUBSCRIBE'].'>', false);
+ }
- $id = $data['id'];
- $self = $data['self'];
- $addresslist = $data['addresslist'];
+ foreach ($headers as $header => $value) {
+ $mail->setHeader($header, $value);
+ }
- if (!$conf['subscribers'] || $auth === null) {
- return '';
+ return $mail->send();
}
- $pres = array('style' => 'every', 'escaped' => true);
- if (!$self && isset($_SERVER['REMOTE_USER'])) {
- $pres['user'] = '((?!' . preg_quote_cb($_SERVER['REMOTE_USER']) .
- '(?: |$))\S+)';
+
+ /**
+ * Get a valid message id for a certain $id and revision (or the current revision)
+ * @param string $id The id of the page (or media file) the message id should be for
+ * @param string $rev The revision of the page, set to the current revision of the page $id if not set
+ * @return string
+ */
+ protected function getMessageID($id, $rev = NULL) {
+ static $listid = null;
+ if (is_null($listid)) {
+ $server = parse_url(DOKU_URL, PHP_URL_HOST);
+ $listid = join('.', array_reverse(explode('/', DOKU_BASE))).$server;
+ $listid = urlencode($listid);
+ $listid = strtolower(trim($listid, '.'));
+ }
+
+ if (is_null($rev)) {
+ $rev = @filemtime(wikiFN($id));
+ }
+
+ return "<$id?rev=$rev@$listid>";
}
- $subs = subscription_find($id, $pres);
- $emails = array();
- foreach ($subs as $by_targets) {
- foreach ($by_targets as $sub) {
- $info = $auth->getUserData($sub[0]);
- if ($info === false) continue;
- $level = auth_aclcheck($id, $sub[0], $info['grps']);
- if ($level >= AUTH_READ) {
- if (strcasecmp($info['mail'], $conf['notify']) != 0) {
- $emails[$sub[0]] = $info['mail'];
+
+ /**
+ * Default callback for COMMON_NOTIFY_ADDRESSLIST
+ *
+ * Aggregates all email addresses of user who have subscribed the given page with 'every' style
+ *
+ * @author Steven Danz <steven-danz@kc.rr.com>
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @todo move the whole functionality into this class, trigger SUBSCRIPTION_NOTIFY_ADDRESSLIST instead,
+ * use an array for the addresses within it
+ *
+ * @param array &$data Containing $id (the page id), $self (whether the author
+ * should be notified, $addresslist (current email address
+ * list)
+ */
+ public function notifyaddresses(&$data) {
+ if(!$this->isenabled()) return;
+
+ /** @var auth_basic $auth */
+ global $auth;
+ global $conf;
+
+ $id = $data['id'];
+ $self = $data['self'];
+ $addresslist = $data['addresslist'];
+
+ $subscriptions = $this->subscribers($id, null, 'every');
+
+ $result = array();
+ foreach($subscriptions as $target => $users) {
+ foreach($users as $user => $info) {
+ $userinfo = $auth->getUserData($user);
+ if($userinfo === false) continue;
+ if(!$userinfo['mail']) continue;
+ if(!$self && $user == $_SERVER['REMOTE_USER']) continue; //skip our own changes
+
+ $level = auth_aclcheck($id, $user, $userinfo['grps']);
+ if($level >= AUTH_READ) {
+ if(strcasecmp($userinfo['mail'], $conf['notify']) != 0) { //skip user who get notified elsewhere
+ $result[$user] = $userinfo['mail'];
+ }
}
}
}
+ $data['addresslist'] = trim($addresslist.','.implode(',', $result), ',');
}
- $data['addresslist'] = trim($addresslist . ',' . implode(',', $emails), ',');
}
/**
- * Send a digest mail
+ * Compatibility wrapper around Subscription:notifyaddresses
*
- * Sends a digest mail showing a bunch of changes.
+ * for plugins emitting COMMON_NOTIFY_ADDRESSLIST themselves and relying on on this to
+ * be the default handler
*
- * @author Adrian Lang <lang@cosmocode.de>
+ * @param array $data event data for
*
- * @param string $subscriber_mail The target mail address
- * @param array $id The ID
- * @param int $lastupdate Time of the last notification
+ * @deprecated 2012-12-07
*/
-function subscription_send_digest($subscriber_mail, $id, $lastupdate) {
- $n = 0;
- do {
- $rev = getRevisions($id, $n++, 1);
- $rev = (count($rev) > 0) ? $rev[0] : null;
- } while (!is_null($rev) && $rev > $lastupdate);
-
- $replaces = array('NEWPAGE' => wl($id, '', true, '&'),
- 'SUBSCRIBE' => wl($id, array('do' => 'subscribe'), true, '&'));
- if (!is_null($rev)) {
- $subject = 'changed';
- $replaces['OLDPAGE'] = wl($id, "rev=$rev", true, '&');
- $df = new Diff(explode("\n", rawWiki($id, $rev)),
- explode("\n", rawWiki($id)));
- $dformat = new UnifiedDiffFormatter();
- $replaces['DIFF'] = $dformat->format($df);
- } else {
- $subject = 'newpage';
- $replaces['OLDPAGE'] = 'none';
- $replaces['DIFF'] = rawWiki($id);
- }
- subscription_send($subscriber_mail, $replaces, $subject, $id,
- 'subscr_digest');
-}
-
-/**
- * Send a list mail
- *
- * Sends a list mail showing a list of changed pages.
- *
- * @author Adrian Lang <lang@cosmocode.de>
- *
- * @param string $subscriber_mail The target mail address
- * @param array $ids Array of ids
- * @param string $ns_id The id of the namespace
- */
-function subscription_send_list($subscriber_mail, $ids, $ns_id) {
- if (count($ids) === 0) return;
- global $conf;
- $list = '';
- foreach ($ids as $id) {
- $list .= '* ' . wl($id, array(), true) . NL;
- }
- subscription_send($subscriber_mail,
- array('DIFF' => rtrim($list),
- 'SUBSCRIBE' => wl($ns_id . $conf['start'],
- array('do' => 'subscribe'),
- true, '&')),
- 'subscribe_list',
- prettyprint_id($ns_id),
- 'subscr_list');
-}
-
-/**
- * Helper function for sending a mail
- *
- * @author Adrian Lang <lang@cosmocode.de>
- *
- * @param string $subscriber_mail The target mail address
- * @param array $replaces Predefined parameters used to parse the
- * template
- * @param string $subject The lang id of the mail subject (without the
- * prefix “mail_”)
- * @param string $id The page or namespace id
- * @param string $template The name of the mail template
- * @return bool
- */
-function subscription_send($subscriber_mail, $replaces, $subject, $id, $template) {
- global $lang;
- global $conf;
-
- $text = rawLocale($template);
- $trep = array_merge($replaces, array('PAGE' => $id));
- $hrep = $trep;
- $hrep['DIFF'] = nl2br(htmlspecialchars($hrep['DIFF']));
-
- $subject = $lang['mail_' . $subject] . ' ' . $id;
- $mail = new Mailer();
- $mail->bcc($subscriber_mail);
- $mail->subject($subject);
- $mail->setBody($text,$trep,$hrep);
- $mail->from($conf['mailfromnobody']);
- $mail->setHeader(
- 'List-Unsubscribe',
- '<'.wl($id,array('do'=>'subscribe'),true,'&').'>',
- false
- );
- return $mail->send();
-}
+function subscription_addresslist(&$data) {
+ $sub = new Subscription();
+ $sub->notifyaddresses($data);
+} \ No newline at end of file
diff --git a/inc/template.php b/inc/template.php
index 4af35cc2b..2c083c964 100644
--- a/inc/template.php
+++ b/inc/template.php
@@ -703,6 +703,7 @@ function tpl_get_action($type) {
}
break;
case 'media':
+ $params['ns'] = getNS($ID);
break;
default:
return '[unknown %s type]';
@@ -839,7 +840,9 @@ function tpl_youarehere($sep = ' » ') {
echo '<span class="bchead">'.$lang['youarehere'].': </span>';
// always print the startpage
+ echo '<span class="home">';
tpl_pagelink(':'.$conf['start']);
+ echo '</span>';
// print intermediate namespace links
$part = '';
diff --git a/lib/exe/indexer.php b/lib/exe/indexer.php
index 28ee5331f..27576f76d 100644
--- a/lib/exe/indexer.php
+++ b/lib/exe/indexer.php
@@ -169,97 +169,20 @@ function runSitemapper(){
* @author Adrian Lang <lang@cosmocode.de>
*/
function sendDigest() {
- echo 'sendDigest(): started'.NL;
- global $ID;
global $conf;
- if (!$conf['subscribers']) {
+ global $ID;
+
+ echo 'sendDigest(): started'.NL;
+ if(!actionOK('subscribe')) {
echo 'sendDigest(): disabled'.NL;
return false;
}
- $subscriptions = subscription_find($ID, array('style' => '(digest|list)',
- 'escaped' => true));
- /** @var auth_basic $auth */
- global $auth;
- global $lang;
- global $conf;
- global $USERINFO;
-
- $sent = false;
-
- // remember current user info
- $olduinfo = $USERINFO;
- $olduser = $_SERVER['REMOTE_USER'];
-
- foreach($subscriptions as $id => $users) {
- if (!subscription_lock($id)) {
- continue;
- }
- foreach($users as $data) {
- list($user, $style, $lastupdate) = $data;
- $lastupdate = (int) $lastupdate;
- if ($lastupdate + $conf['subscribe_time'] > time()) {
- // Less than the configured time period passed since last
- // update.
- continue;
- }
-
- // Work as the user to make sure ACLs apply correctly
- $USERINFO = $auth->getUserData($user);
- $_SERVER['REMOTE_USER'] = $user;
- if ($USERINFO === false) {
- continue;
- }
-
- if (substr($id, -1, 1) === ':') {
- // The subscription target is a namespace
- $changes = getRecentsSince($lastupdate, null, getNS($id));
- } else {
- if(auth_quickaclcheck($id) < AUTH_READ) continue;
-
- $meta = p_get_metadata($id);
- $changes = array($meta['last_change']);
- }
-
- // Filter out pages only changed in small and own edits
- $change_ids = array();
- foreach($changes as $rev) {
- $n = 0;
- while (!is_null($rev) && $rev['date'] >= $lastupdate &&
- ($_SERVER['REMOTE_USER'] === $rev['user'] ||
- $rev['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT)) {
- $rev = getRevisions($rev['id'], $n++, 1);
- $rev = (count($rev) > 0) ? $rev[0] : null;
- }
-
- if (!is_null($rev) && $rev['date'] >= $lastupdate) {
- // Some change was not a minor one and not by myself
- $change_ids[] = $rev['id'];
- }
- }
-
- if ($style === 'digest') {
- foreach($change_ids as $change_id) {
- subscription_send_digest($USERINFO['mail'], $change_id,
- $lastupdate);
- $sent = true;
- }
- } elseif ($style === 'list') {
- subscription_send_list($USERINFO['mail'], $change_ids, $id);
- $sent = true;
- }
- // TODO: Handle duplicate subscriptions.
-
- // Update notification time.
- subscription_set($user, $id, $style, time(), true);
- }
- subscription_unlock($id);
- }
+ $sub = new Subscription();
+ $sent = $sub->send_bulk($ID);
- // restore current user info
- $USERINFO = $olduinfo;
- $_SERVER['REMOTE_USER'] = $olduser;
+ echo "sendDigest(): sent $sent mails".NL;
echo 'sendDigest(): finished'.NL;
- return $sent;
+ return (bool) $sent;
}
/**
diff --git a/lib/plugins/acl/lang/el/lang.php b/lib/plugins/acl/lang/el/lang.php
index e1cd26755..516d7bdf5 100644
--- a/lib/plugins/acl/lang/el/lang.php
+++ b/lib/plugins/acl/lang/el/lang.php
@@ -14,6 +14,7 @@
* @author Konstantinos Koryllos <koryllos@gmail.com>
* @author George Petsagourakis <petsagouris@gmail.com>
* @author Petros Vidalis <pvidalis@gmail.com>
+ * @author Vasileios Karavasilis vasileioskaravasilis@gmail.com
*/
$lang['admin_acl'] = 'Διαχείριση Δικαιωμάτων Πρόσβασης';
$lang['acl_group'] = 'Ομάδα';
diff --git a/lib/plugins/acl/lang/en/help.txt b/lib/plugins/acl/lang/en/help.txt
index 2b80cc4c7..e865bbb23 100644
--- a/lib/plugins/acl/lang/en/help.txt
+++ b/lib/plugins/acl/lang/en/help.txt
@@ -1,12 +1,9 @@
=== Quick Help: ===
On this page you can add and remove permissions for namespaces and pages in your wiki.
-
-The left pane displays all available namespaces and pages.
-
-The form above allows you to see and modify the permissions of a selected user or group.
-
-In the table below all currently set access control rules are shown. You can use it to quickly delete or change multiple rules.
+ * The left pane displays all available namespaces and pages.
+ * The form above allows you to see and modify the permissions of a selected user or group.
+ * In the table below all currently set access control rules are shown. You can use it to quickly delete or change multiple rules.
Reading the [[doku>acl|official documentation on ACL]] might help you to fully understand how access control works in DokuWiki.
diff --git a/lib/plugins/acl/lang/gl/lang.php b/lib/plugins/acl/lang/gl/lang.php
index 537e03eef..3325bfd07 100644
--- a/lib/plugins/acl/lang/gl/lang.php
+++ b/lib/plugins/acl/lang/gl/lang.php
@@ -4,7 +4,7 @@
*
* @author Medúlio <medulio@ciberirmandade.org>
* @author Oscar M. Lage <r0sk10@gmail.com>
- * @author Leandro Regueiro <leandro.regueiro@gmail.com>
+ * @author Rodrigo Rega <rodrigorega@gmail.com>
*/
$lang['admin_acl'] = 'Xestión da Lista de Control de Acceso (ACL)';
$lang['acl_group'] = 'Grupo';
diff --git a/lib/plugins/acl/lang/nl/help.txt b/lib/plugins/acl/lang/nl/help.txt
index 255f21ba0..14c78e20a 100644
--- a/lib/plugins/acl/lang/nl/help.txt
+++ b/lib/plugins/acl/lang/nl/help.txt
@@ -1,11 +1,8 @@
=== Snelle hulp: ===
Op deze pagina kun je bevoegdheden toevoegen en verwijderen voor namespaces en pagina's in je wiki.
-
-Het linkerpaneel geeft alle beschikbare namespaces en pagina's weer.
-
-In het formulier hierboven kun je bevoegdheden zien en aanpassen voor een selecteerde gebruiker of groep.
-
-In de tabel hieronder worden alle momenteel ingestelde toegangsregels weergegeven. Je kunt hier snel regels wijzigen of verwijderen.
+ * Het linkerpaneel geeft alle beschikbare namespaces en pagina's weer.
+ * In het formulier hierboven kun je bevoegdheden zien en aanpassen voor een selecteerde gebruiker of groep.
+ * In de tabel hieronder worden alle momenteel ingestelde toegangsregels weergegeven. Je kunt hier snel regels wijzigen of verwijderen.
Lees de [[doku>acl|documentatie over ACLs]] om de mogelijkheden volledig te begrijpen.
diff --git a/lib/plugins/config/lang/el/lang.php b/lib/plugins/config/lang/el/lang.php
index 093212664..d2801e507 100644
--- a/lib/plugins/config/lang/el/lang.php
+++ b/lib/plugins/config/lang/el/lang.php
@@ -12,6 +12,7 @@
* @author Konstantinos Koryllos <koryllos@gmail.com>
* @author George Petsagourakis <petsagouris@gmail.com>
* @author Petros Vidalis <pvidalis@gmail.com>
+ * @author Vasileios Karavasilis vasileioskaravasilis@gmail.com
*/
$lang['menu'] = 'Ρυθμίσεις';
$lang['error'] = 'Οι ρυθμίσεις σας δεν έγιναν δεκτές λόγω λανθασμένης τιμής κάποιας ρύθμισης. Διορθώστε την λάθος τιμή και προσπαθήστε ξανά.
@@ -34,6 +35,8 @@ $lang['_anti_spam'] = 'Ρυθμίσεις Anti-Spam';
$lang['_editing'] = 'Ρυθμίσεις Σύνταξης σελίδων';
$lang['_links'] = 'Ρυθμίσεις Συνδέσμων';
$lang['_media'] = 'Ρυθμίσεις Αρχείων';
+$lang['_notifications'] = 'Ρυθμίσεις ενημερώσεων';
+$lang['_syndication'] = 'Ρυθμίσεις σύνδεσης';
$lang['_advanced'] = 'Ρυθμίσεις για Προχωρημένους';
$lang['_network'] = 'Ρυθμίσεις Δικτύου';
$lang['_plugin_sufix'] = 'Ρυθμίσεις Επεκτάσεων';
@@ -41,26 +44,29 @@ $lang['_template_sufix'] = 'Ρυθμίσεις Προτύπων παρου
$lang['_msg_setting_undefined'] = 'Δεν έχουν οριστεί metadata.';
$lang['_msg_setting_no_class'] = 'Δεν έχει οριστεί κλάση.';
$lang['_msg_setting_no_default'] = 'Δεν υπάρχει τιμή εξ ορισμού.';
-$lang['fmode'] = 'Δικαιώματα πρόσβασης δημιουργούμενων αρχείων';
-$lang['dmode'] = 'Δικαιώματα πρόσβασης δημιουργούμενων φακέλων';
+$lang['title'] = 'Τίτλος Wiki';
+$lang['start'] = 'Ονομασία αρχικής σελίδας';
$lang['lang'] = 'Γλώσσα';
+$lang['template'] = 'Πρότυπο προβολής';
+$lang['tagline'] = 'Tagline';
+$lang['sidebar'] = 'Sidebar page name';
+$lang['license'] = 'Κάτω από ποια άδεια θέλετε να δημοσιευτεί το υλικό σας?';
+$lang['savedir'] = 'Φάκελος για την αποθήκευση δεδομένων';
$lang['basedir'] = 'Αρχικός Φάκελος';
$lang['baseurl'] = 'Αρχικό URL';
-$lang['savedir'] = 'Φάκελος για την αποθήκευση δεδομένων';
$lang['cookiedir'] = 'Διαδρομή cookie. Αφήστε την κενή για την χρησιμοποίηση της αρχικής URL.';
-$lang['start'] = 'Ονομασία αρχικής σελίδας';
-$lang['title'] = 'Τίτλος Wiki';
-$lang['template'] = 'Πρότυπο προβολής';
-$lang['license'] = 'Κάτω από ποια άδεια θέλετε να δημοσιευτεί το υλικό σας?';
-$lang['fullpath'] = 'Εμφάνιση πλήρους διαδρομής σελίδας στην υποκεφαλίδα';
+$lang['dmode'] = 'Δικαιώματα πρόσβασης δημιουργούμενων φακέλων';
+$lang['fmode'] = 'Δικαιώματα πρόσβασης δημιουργούμενων αρχείων';
+$lang['allowdebug'] = 'Δεδομένα εκσφαλμάτωσης (debug) <b>απενεργοποιήστε τα εάν δεν τα έχετε ανάγκη!</b>';
$lang['recent'] = 'Αριθμός πρόσφατων αλλαγών ανά σελίδα';
+$lang['recent_days'] = 'Πόσο παλιές αλλαγές να εμφανίζονται (ημέρες)';
$lang['breadcrumbs'] = 'Αριθμός συνδέσμων ιστορικού';
$lang['youarehere'] = 'Εμφάνιση ιεραρχικής προβολής τρέχουσας σελίδας';
+$lang['fullpath'] = 'Εμφάνιση πλήρους διαδρομής σελίδας στην υποκεφαλίδα';
$lang['typography'] = 'Μετατροπή ειδικών χαρακτήρων στο τυπογραφικό ισοδύναμό τους';
-$lang['htmlok'] = 'Να επιτρέπεται η ενσωμάτωση HTML';
-$lang['phpok'] = 'Να επιτρέπεται η ενσωμάτωση PHP';
$lang['dformat'] = 'Μορφή ημερομηνίας (βλέπε την <a href="http://www.php.net/strftime">strftime</a> function της PHP)';
$lang['signature'] = 'Υπογραφή';
+$lang['showuseras'] = 'Τι να εμφανίζεται όταν φαίνεται ο χρήστης που τροποποίησε τελευταίος μία σελίδα';
$lang['toptoclevel'] = 'Ανώτατο επίπεδο πίνακα περιεχομένων σελίδας';
$lang['tocminheads'] = 'Ελάχιστος αριθμός κεφαλίδων για την δημιουργία πίνακα περιεχομένων - TOC';
$lang['maxtoclevel'] = 'Μέγιστο επίπεδο για πίνακα περιεχομένων σελίδας';
@@ -68,15 +74,8 @@ $lang['maxseclevel'] = 'Μέγιστο επίπεδο για εμφά
$lang['camelcase'] = 'Χρήση CamelCase στους συνδέσμους';
$lang['deaccent'] = 'Αφαίρεση σημείων στίξης από ονόματα σελίδων';
$lang['useheading'] = 'Χρήση κεφαλίδας πρώτου επιπέδου σαν τίτλο συνδέσμων';
-$lang['refcheck'] = 'Πριν τη διαγραφή ενός αρχείου να ελέγχεται η ύπαρξη σελίδων που το χρησιμοποιούν';
-$lang['refshow'] = 'Εμφανιζόμενος αριθμός σελίδων που χρησιμοποιούν ένα αρχείο';
-$lang['allowdebug'] = 'Δεδομένα εκσφαλμάτωσης (debug) <b>απενεργοποιήστε τα εάν δεν τα έχετε ανάγκη!</b>';
-$lang['usewordblock'] = 'Χρήστη λίστα απαγορευμένων λέξεων για καταπολέμηση του spam';
-$lang['indexdelay'] = 'Χρόνος αναμονής προτού επιτραπεί σε μηχανές αναζήτησης να ευρετηριάσουν μια τροποποιημένη σελίδα (sec)';
-$lang['relnofollow'] = 'Χρήση rel="nofollow"';
-$lang['mailguard'] = 'Κωδικοποίηση e-mail διευθύνσεων';
-$lang['iexssprotect'] = 'Έλεγχος μεταφορτώσεων για πιθανώς επικίνδυνο κώδικα JavaScript ή HTML';
-$lang['showuseras'] = 'Τι να εμφανίζεται όταν φαίνεται ο χρήστης που τροποποίησε τελευταίος μία σελίδα';
+$lang['sneaky_index'] = 'Εξ ορισμού, η εφαρμογή DokuWiki δείχνει όλους τους φακέλους στην προβολή Καταλόγου. Ενεργοποιώντας αυτή την επιλογή, δεν θα εμφανίζονται οι φάκελοι για τους οποίους ο χρήστης δεν έχει δικαιώματα ανάγνωσης αλλά και οι υπο-φάκελοί τους ανεξαρτήτως δικαιωμάτων πρόσβασης.';
+$lang['hidepages'] = 'Φίλτρο απόκρυψης σελίδων (regular expressions)';
$lang['useacl'] = 'Χρήση Λίστας Δικαιωμάτων Πρόσβασης (ACL)';
$lang['autopasswd'] = 'Αυτόματη δημιουργία κωδικού χρήστη';
$lang['authtype'] = 'Τύπος πιστοποίησης στοιχείων χρήστη';
@@ -85,58 +84,70 @@ $lang['defaultgroup'] = 'Προεπιλεγμένη ομάδα χρησ
$lang['superuser'] = 'Υπερ-χρήστης - μία ομάδα ή ένας χρήστης με πλήρη δικαιώματα πρόσβασης σε όλες τις σελίδες και όλες τις λειτουργίες ανεξάρτητα από τις ρυθμίσεις των Λιστών Δικαιωμάτων Πρόσβασης (ACL)';
$lang['manager'] = 'Διαχειριστής - μία ομάδα ή ένας χρήστης με δικαιώματα πρόσβασης σε ορισμένες από τις λειτουργίες της εφαρμογής';
$lang['profileconfirm'] = 'Να απαιτείται ο κωδικός χρήστη για την επιβεβαίωση αλλαγών στο προφίλ χρήστη';
+$lang['rememberme'] = 'Να επιτρέπονται τα cookies λογαρισμού χρήστη αορίστου χρόνου (Απομνημόνευση στοιχείων λογαριασμού)';
$lang['disableactions'] = 'Απενεργοποίηση λειτουργιών DokuWiki';
$lang['disableactions_check'] = 'Έλεγχος';
$lang['disableactions_subscription'] = 'Εγγραφή/Διαγραφή χρήστη';
$lang['disableactions_wikicode'] = 'Προβολή κώδικα σελίδας';
$lang['disableactions_other'] = 'Άλλες λειτουργίες (διαχωρίστε τις με κόμμα)';
-$lang['sneaky_index'] = 'Εξ ορισμού, η εφαρμογή DokuWiki δείχνει όλους τους φακέλους στην προβολή Καταλόγου. Ενεργοποιώντας αυτή την επιλογή, δεν θα εμφανίζονται οι φάκελοι για τους οποίους ο χρήστης δεν έχει δικαιώματα ανάγνωσης αλλά και οι υπο-φάκελοί τους ανεξαρτήτως δικαιωμάτων πρόσβασης.';
$lang['auth_security_timeout'] = 'Διάρκεια χρόνου για ασφάλεια πιστοποίησης (δευτερόλεπτα)';
$lang['securecookie'] = 'Τα cookies που έχουν οριστεί μέσω HTTPS πρέπει επίσης να αποστέλλονται μόνο μέσω HTTPS από τον φυλλομετρητή? Απενεργοποιήστε αυτή την επιλογή όταν μόνο η είσοδος στο wiki σας διασφαλίζεται μέσω SSL αλλά η περιήγηση γίνεται και χωρίς αυτό.';
+$lang['remote'] = 'Ενεργοποίησης απομακρυσμένης προγραμματιστικής διεπαφής εφαρμογών (API). Με αυτό τον τρόπο επιτρέπεται η πρόσβαση στο wiki με το XML-RPC ή με άλλα πρωτόκολλα επικοινωνίας.';
+$lang['remoteuser'] = 'Απενεργοποίησης απομακρυσμένης προγραμματιστικής διεπαφής εφαρμογών (API). Αφήστε το κενό για να είναι δυνατή η πρόσβαση στον οποιοδήποτε.';
+$lang['usewordblock'] = 'Χρήστη λίστα απαγορευμένων λέξεων για καταπολέμηση του spam';
+$lang['relnofollow'] = 'Χρήση rel="nofollow"';
+$lang['indexdelay'] = 'Χρόνος αναμονής προτού επιτραπεί σε μηχανές αναζήτησης να ευρετηριάσουν μια τροποποιημένη σελίδα (sec)';
+$lang['mailguard'] = 'Κωδικοποίηση e-mail διευθύνσεων';
+$lang['iexssprotect'] = 'Έλεγχος μεταφορτώσεων για πιθανώς επικίνδυνο κώδικα JavaScript ή HTML';
+$lang['usedraft'] = 'Αυτόματη αποθήκευση αντιγράφων κατά την τροποποίηση σελίδων';
+$lang['htmlok'] = 'Να επιτρέπεται η ενσωμάτωση HTML';
+$lang['phpok'] = 'Να επιτρέπεται η ενσωμάτωση PHP';
+$lang['locktime'] = 'Μέγιστος χρόνος κλειδώματος αρχείου υπό τροποποίηση (sec)';
+$lang['cachetime'] = 'Μέγιστη ηλικία cache (sec)';
+$lang['target____wiki'] = 'Παράθυρο-στόχος για εσωτερικούς συνδέσμους';
+$lang['target____interwiki'] = 'Παράθυρο-στόχος για συνδέσμους interwiki';
+$lang['target____extern'] = 'Παράθυρο-στόχος για εξωτερικούς σθνδέσμους';
+$lang['target____media'] = 'Παράθυρο-στόχος για συνδέσμους αρχείων';
+$lang['target____windows'] = 'Παράθυρο-στόχος για συνδέσμους σε Windows shares';
+$lang['mediarevisions'] = 'Ενεργοποίηση Mediarevisions;';
+$lang['refcheck'] = 'Πριν τη διαγραφή ενός αρχείου να ελέγχεται η ύπαρξη σελίδων που το χρησιμοποιούν';
+$lang['refshow'] = 'Εμφανιζόμενος αριθμός σελίδων που χρησιμοποιούν ένα αρχείο';
+$lang['gdlib'] = 'Έκδοση βιβλιοθήκης GD';
+$lang['im_convert'] = 'Διαδρομή προς το εργαλείο μετατροπής εικόνων του ImageMagick';
+$lang['jpg_quality'] = 'Ποιότητα συμπίεσης JPG (0-100)';
+$lang['fetchsize'] = 'Μέγιστο μέγεθος (σε bytes) εξωτερικού αρχείου που επιτρέπεται να μεταφέρει η fetch.php';
+$lang['subscribers'] = 'Να επιτρέπεται η εγγραφή στην ενημέρωση αλλαγών σελίδας';
+$lang['subscribe_time'] = 'Χρόνος μετά τον οποίο οι λίστες ειδοποιήσεων και τα συνοπτικά θα αποστέλλονται (δευτερόλεπτα). Αυτό θα πρέπει να είναι μικρότερο από τον χρόνο που έχει η ρύθμιση recent_days.';
+$lang['notify'] = 'Αποστολή ενημέρωσης για αλλαγές σε αυτή την e-mail διεύθυνση';
+$lang['registernotify'] = 'Αποστολή ενημερωτικών μηνυμάτων σε αυτή την e-mail διεύθυνση κατά την εγγραφή νέων χρηστών';
+$lang['mailfrom'] = 'e-mail διεύθυνση αποστολέα για μηνύματα από την εφαρμογή';
+$lang['mailprefix'] = 'Πρόθεμα θέματος που να χρησιμοποιείται για τα αυτόματα μηνύματα ηλεκτρονικού ταχυδρομείου.';
+$lang['htmlmail'] = 'Αποστολή οπτικά καλύτερου, αλλά μεγαλύτερου σε μέγεθος email με χρήση HTML. Απενεργοποιήστε το για αποστέλλονται μόνο email απλού κειμένου.';
+$lang['sitemap'] = 'Δημιουργία Google sitemap (ημέρες)';
+$lang['rss_type'] = 'Τύπος XML feed';
+$lang['rss_linkto'] = 'Τύπος συνδέσμων στο XML feed';
+$lang['rss_content'] = 'Τι να εμφανίζεται στα XML feed items?';
+$lang['rss_update'] = 'Χρόνος ανανέωσης XML feed (sec)';
+$lang['rss_show_summary'] = 'Να εμφανίζεται σύνοψη του XML feed στον τίτλο';
+$lang['rss_media'] = 'Τι είδους αλλαγές πρέπει να εμφανίζονται στο XLM feed;';
$lang['updatecheck'] = 'Έλεγχος για ύπαρξη νέων εκδόσεων και ενημερώσεων ασφαλείας της εφαρμογής? Απαιτείται η σύνδεση με το update.dokuwiki.org για να λειτουργήσει σωστά αυτή η επιλογή.';
$lang['userewrite'] = 'Χρήση ωραίων URLs';
$lang['useslash'] = 'Χρήση slash σαν διαχωριστικό φακέλων στα URLs';
-$lang['usedraft'] = 'Αυτόματη αποθήκευση αντιγράφων κατά την τροποποίηση σελίδων';
$lang['sepchar'] = 'Διαχωριστικός χαρακτήρας για κανονικοποίηση ονόματος σελίδας';
$lang['canonical'] = 'Πλήρη και κανονικοποιημένα URLs';
$lang['fnencode'] = 'Μέθοδος κωδικοποίησης για ονόματα αρχείων μη-ASCII';
$lang['autoplural'] = 'Ταίριασμα πληθυντικού στους συνδέσμους';
$lang['compression'] = 'Μέθοδος συμπίεσης για αρχεία attic';
-$lang['cachetime'] = 'Μέγιστη ηλικία cache (sec)';
-$lang['locktime'] = 'Μέγιστος χρόνος κλειδώματος αρχείου υπό τροποποίηση (sec)';
-$lang['fetchsize'] = 'Μέγιστο μέγεθος (σε bytes) εξωτερικού αρχείου που επιτρέπεται να μεταφέρει η fetch.php';
-$lang['notify'] = 'Αποστολή ενημέρωσης για αλλαγές σε αυτή την e-mail διεύθυνση';
-$lang['registernotify'] = 'Αποστολή ενημερωτικών μηνυμάτων σε αυτή την e-mail διεύθυνση κατά την εγγραφή νέων χρηστών';
-$lang['mailfrom'] = 'e-mail διεύθυνση αποστολέα για μηνύματα από την εφαρμογή';
-$lang['mailprefix'] = 'Πρόθεμα θέματος που να χρησιμοποιείται για τα αυτόματα μηνύματα ηλεκτρονικού ταχυδρομείου.';
$lang['gzip_output'] = 'Χρήση gzip Content-Encoding για την xhtml';
-$lang['gdlib'] = 'Έκδοση βιβλιοθήκης GD';
-$lang['im_convert'] = 'Διαδρομή προς το εργαλείο μετατροπής εικόνων του ImageMagick';
-$lang['jpg_quality'] = 'Ποιότητα συμπίεσης JPG (0-100)';
-$lang['subscribers'] = 'Να επιτρέπεται η εγγραφή στην ενημέρωση αλλαγών σελίδας';
-$lang['subscribe_time'] = 'Χρόνος μετά τον οποίο οι λίστες ειδοποιήσεων και τα συνοπτικά θα αποστέλλονται (δευτερόλεπτα). Αυτό θα πρέπει να είναι μικρότερο από τον χρόνο που έχει η ρύθμιση recent_days.';
$lang['compress'] = 'Συμπίεση αρχείων CSS και javascript';
$lang['cssdatauri'] = 'Το μέγεθος σε bytes στο οποίο οι εικόνες που αναφέρονται σε CSS αρχεία θα πρέπει να είναι ενσωματωμένες για τη μείωση των απαιτήσεων μιας κεφαλίδας αίτησης HTTP . Αυτή η τεχνική δεν θα λειτουργήσει σε IE <8! <code> 400 </code> με <code> 600 </code> bytes είναι μια καλή τιμή. Ορίστε την τιμή <code> 0 </code> για να το απενεργοποιήσετε.';
-$lang['hidepages'] = 'Φίλτρο απόκρυψης σελίδων (regular expressions)';
$lang['send404'] = 'Αποστολή "HTTP 404/Page Not Found" για σελίδες που δεν υπάρχουν';
-$lang['sitemap'] = 'Δημιουργία Google sitemap (ημέρες)';
$lang['broken_iua'] = 'Η συνάρτηση ignore_user_abort δεν λειτουργεί σωστά στο σύστημά σας? Σε αυτή την περίπτωση μπορεί να μην δουλεύει σωστά η λειτουργία Καταλόγου. Ο συνδυασμός IIS+PHP/CGI είναι γνωστό ότι έχει τέτοιο πρόβλημα. Δείτε και <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> για λεπτομέρειες.';
$lang['xsendfile'] = 'Χρήση της κεφαλίδας X-Sendfile από τον εξυπηρετητή κατά την φόρτωση στατικών αρχείων? Ο εξυπηρετητής σας πρέπει να υποστηρίζει αυτή την δυνατότητα.';
$lang['renderer_xhtml'] = 'Πρόγραμμα δημιουργίας βασικής (xhtml) εξόδου wiki.';
$lang['renderer__core'] = '%s (βασικός κώδικας dokuwiki)';
$lang['renderer__plugin'] = '%s (επέκταση)';
-$lang['rememberme'] = 'Να επιτρέπονται τα cookies λογαρισμού χρήστη αορίστου χρόνου (Απομνημόνευση στοιχείων λογαριασμού)';
-$lang['rss_type'] = 'Τύπος XML feed';
-$lang['rss_linkto'] = 'Τύπος συνδέσμων στο XML feed';
-$lang['rss_content'] = 'Τι να εμφανίζεται στα XML feed items?';
-$lang['rss_update'] = 'Χρόνος ανανέωσης XML feed (sec)';
-$lang['recent_days'] = 'Πόσο παλιές αλλαγές να εμφανίζονται (ημέρες)';
-$lang['rss_show_summary'] = 'Να εμφανίζεται σύνοψη του XML feed στον τίτλο';
-$lang['target____wiki'] = 'Παράθυρο-στόχος για εσωτερικούς συνδέσμους';
-$lang['target____interwiki'] = 'Παράθυρο-στόχος για συνδέσμους interwiki';
-$lang['target____extern'] = 'Παράθυρο-στόχος για εξωτερικούς σθνδέσμους';
-$lang['target____media'] = 'Παράθυρο-στόχος για συνδέσμους αρχείων';
-$lang['target____windows'] = 'Παράθυρο-στόχος για συνδέσμους σε Windows shares';
+$lang['dnslookups'] = 'Το DokuWiki θα ψάξει τα ονόματα υπολογιστών που αντιστοιχούν σε διευθύνσεις IP των χρηστών που γράφουν στις σελίδες. Αν ο DNS είναι αργός, δεν δουλεύει ή δεν χρειάζεστε αυτή την λειτουργία, απενεργοποιήστε την.';
$lang['proxy____host'] = 'Διακομιστής Proxy';
$lang['proxy____port'] = 'Θύρα Proxy';
$lang['proxy____user'] = 'Όνομα χρήστη Proxy';
diff --git a/lib/plugins/config/lang/gl/lang.php b/lib/plugins/config/lang/gl/lang.php
index 5ba3be2ec..21fe17452 100644
--- a/lib/plugins/config/lang/gl/lang.php
+++ b/lib/plugins/config/lang/gl/lang.php
@@ -4,7 +4,7 @@
*
* @author Medúlio <medulio@ciberirmandade.org>
* @author Oscar M. Lage <r0sk10@gmail.com>
- * @author Leandro Regueiro <leandro.regueiro@gmail.com>
+ * @author Rodrigo Rega <rodrigorega@gmail.com>
*/
$lang['menu'] = 'Opcións de Configuración';
$lang['error'] = 'Configuración non actualizada debido a un valor inválido, por favor revisa os teus trocos e volta envialos de novo.
@@ -28,8 +28,8 @@ $lang['_anti_spam'] = 'Configuración de Anti-Correo-lixo';
$lang['_editing'] = 'Configuración de Edición';
$lang['_links'] = 'Configuración de Ligazóns';
$lang['_media'] = 'Configuración de Media';
-$lang['_notifications'] = 'Configuración de notificación';
-$lang['_syndication'] = 'Configuración de afiliación';
+$lang['_notifications'] = 'Opcións de Notificación';
+$lang['_syndication'] = 'Opcións de Sindicación';
$lang['_advanced'] = 'Configuración Avanzada';
$lang['_network'] = 'Configuración de Rede';
$lang['_plugin_sufix'] = 'Configuración de Extensións';
@@ -41,8 +41,8 @@ $lang['title'] = 'Título do Wiki';
$lang['start'] = 'Nome da páxina inicial';
$lang['lang'] = 'Idioma';
$lang['template'] = 'Sobreplanta';
-$lang['tagline'] = 'Slogan (se o modelo o admite)';
-$lang['sidebar'] = 'Nome da páxina de barra lateral (se o modelo o admite), se o campo está baleiro desactívase a barra lateral';
+$lang['tagline'] = 'Tagline (si a plantilla o soporta)';
+$lang['sidebar'] = 'Nome de páxina da barra lateral (si a platilla o soporta), o campo en baleiro deshabilita a barra lateral';
$lang['license'] = 'Baixo de que licenza será ceibado o teu contido?';
$lang['savedir'] = 'Directorio no que se gardarán os datos';
$lang['basedir'] = 'Directorio base';
@@ -85,8 +85,8 @@ $lang['disableactions_wikicode'] = 'Ver fonte/Exportar Datos Raw';
$lang['disableactions_other'] = 'Outras accións (separadas por comas)';
$lang['auth_security_timeout'] = 'Tempo Límite de Seguridade de Autenticación (segundos)';
$lang['securecookie'] = 'Deben enviarse só vía HTTPS polo navegador as cookies configuradas vía HTTPS? Desactiva esta opción cando só o inicio de sesión do teu wiki estea asegurado con SSL pero a navegación do mesmo se faga de xeito inseguro.';
-$lang['remote'] = 'Activar o sistema de API remota. Isto permítelle a outras aplicacións acceder ao wiki a través de XML-RPC ou outros mecanismos.';
-$lang['remoteuser'] = 'Restrinxir o acceso remoto á API aos grupos ou usuarios separados por comas especificados aquí. Déixeo baleiro para concederlle acceso a todos.';
+$lang['remote'] = 'Permite o uso do sistema API remoto. Isto permite a outras aplicacións acceder ao wiki mediante XML-RPC ou outros mecanismos.';
+$lang['remoteuser'] = 'Restrinxe o uso remoto da API aos grupos ou usuarios indicados, separados por comas. Deixar baleiro para dar acceso a todo o mundo.';
$lang['usewordblock'] = 'Bloquear correo-lixo segundo unha lista de verbas';
$lang['relnofollow'] = 'Utilizar rel="nofollow" nas ligazóns externas';
$lang['indexdelay'] = 'Retardo denantes de indexar (seg)';
@@ -115,14 +115,14 @@ $lang['notify'] = 'Enviar notificacións de trocos a este enderez
$lang['registernotify'] = 'Enviar información de novos usuarios rexistrados a este enderezo de correo-e';
$lang['mailfrom'] = 'Enderezo de correo-e a usar para as mensaxes automáticas';
$lang['mailprefix'] = 'Prefixo de asunto de correo-e para as mensaxes automáticas';
-$lang['htmlmail'] = 'Enviar mensaxes de e-mail HTML multiparte con mellor aspecto, pero de tamaño maior. Desactivar para as mensaxes de só texto plano.';
+$lang['htmlmail'] = 'Enviar correos electrónicos HTML multiparte máis estéticos, pero máis grande en tamaño. Deshabilitar para mandar correos electrónicos en texto claro.';
$lang['sitemap'] = 'Xerar mapa do sitio co Google (días)';
$lang['rss_type'] = 'Tipo de corrente RSS XML';
$lang['rss_linkto'] = 'A corrente XML liga para';
$lang['rss_content'] = 'Que queres amosar nos elementos da corrente XML?';
$lang['rss_update'] = 'Intervalo de actualización da corrente XML (seg.)';
$lang['rss_show_summary'] = 'Amosar sumario no título da corrente XML';
-$lang['rss_media'] = 'Que tipo de cambios se deben mostrar na fonte XML?';
+$lang['rss_media'] = 'Qué tipo de cambios deben ser listados no feed XML?';
$lang['updatecheck'] = 'Comprobar se hai actualizacións e avisos de seguridade? O DokuWiki precisa contactar con update.dokuwiki.org para executar esta característica.';
$lang['userewrite'] = 'Utilizar URLs amigábeis';
$lang['useslash'] = 'Utilizar a barra inclinada (/) como separador de nome de espazo nos URLs';
@@ -133,14 +133,14 @@ $lang['autoplural'] = 'Comprobar formas plurais nas ligazóns';
$lang['compression'] = 'Método de compresión para arquivos attic';
$lang['gzip_output'] = 'Utilizar Contido-Codificación gzip para o xhtml';
$lang['compress'] = 'Saída compacta de CSS e Javascript';
-$lang['cssdatauri'] = 'Tamaño en bytes ata o cal as imaxes referenciadas nos ficheiros CSS se deben incorporar directamente na folla de estilos para reducir o exceso de cabeceiras de solicitudes HTTP. Esta técnica non funciona con IE 7 ou inferior! Valores entre <code>400</code> e <code>600</code> son axeitados. Defina <code>0</code> para desactivar.';
+$lang['cssdatauri'] = 'Tamaño en bytes ata o cal as imaxes referenciadas nos CSS serán incrustadas na folla de estilos para disminuir o tamaño das cabeceiras das solicitudes HTTP. Esta técnica non funcionará en IE 7 ou anteriores! entre <code>400</code> e <code>600</code> bytes é un valor axeitado. Establecer a <code>0</code> para deshabilitar.';
$lang['send404'] = 'Enviar "HTTP 404/Páxina non atopada" para as páxinas inexistentes';
$lang['broken_iua'] = 'Rachou a función ignore_user_abort no teu sistema? Isto podería causar que o índice de procura non funcione. Coñécese que o IIS+PHP/CGI ráchaa. Bótalle un ollo ao <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> para obter máis información.';
$lang['xsendfile'] = 'Empregar a cabeceira X-Sendfile para que o servidor web envie arquivos estáticos? O teu servidor web precisa soportar isto.';
$lang['renderer_xhtml'] = 'Intérprete a empregar para a saída principal (XHTML) do Wiki';
$lang['renderer__core'] = '%s (núcleo do Dokuwiki)';
$lang['renderer__plugin'] = '%s (extensión)';
-$lang['dnslookups'] = 'DokuWiki buscará os nomes de máquina ou enderezos IP remotos dos usuarios que editen páxinas. Se ten un servidor DNS lento ou que non funciona ou en caso de non querer esta característica, desactive esta opción.';
+$lang['dnslookups'] = 'DokuWiki resolverá os nomes de host das direccións IP dos usuarios que editan as páxinas. Si contas un servidor DNS lento, que non funciona ou non che interesa esta característica, deshabilita esta opción';
$lang['proxy____host'] = 'Nome do servidor Proxy';
$lang['proxy____port'] = 'Porto do Proxy';
$lang['proxy____user'] = 'Nome de usuario do Proxy';
diff --git a/lib/plugins/config/settings/config.metadata.php b/lib/plugins/config/settings/config.metadata.php
index 3607f56c6..89824381b 100644
--- a/lib/plugins/config/settings/config.metadata.php
+++ b/lib/plugins/config/settings/config.metadata.php
@@ -126,7 +126,7 @@ $meta['_authentication'] = array('fieldset');
$meta['useacl'] = array('onoff');
$meta['autopasswd'] = array('onoff');
$meta['authtype'] = array('authtype');
-$meta['passcrypt'] = array('multichoice','_choices' => array('smd5','md5','apr1','sha1','ssha','lsmd5','crypt','mysql','my411','kmd5','pmd5','hmd5','bcrypt'));
+$meta['passcrypt'] = array('multichoice','_choices' => array('smd5','md5','apr1','sha1','ssha','lsmd5','crypt','mysql','my411','kmd5','pmd5','hmd5','mediawiki','bcrypt','sha512'));
$meta['defaultgroup']= array('string');
$meta['superuser'] = array('string');
$meta['manager'] = array('string');
diff --git a/lib/plugins/plugin/lang/el/lang.php b/lib/plugins/plugin/lang/el/lang.php
index bd6dc2013..4a6f1dbfd 100644
--- a/lib/plugins/plugin/lang/el/lang.php
+++ b/lib/plugins/plugin/lang/el/lang.php
@@ -12,6 +12,7 @@
* @author Konstantinos Koryllos <koryllos@gmail.com>
* @author George Petsagourakis <petsagouris@gmail.com>
* @author Petros Vidalis <pvidalis@gmail.com>
+ * @author Vasileios Karavasilis vasileioskaravasilis@gmail.com
*/
$lang['menu'] = 'Διαχείριση Επεκτάσεων';
$lang['download'] = 'Κατεβάστε και εγκαταστήστε μια νέα επέκταση (plugin)';
diff --git a/lib/plugins/plugin/lang/gl/lang.php b/lib/plugins/plugin/lang/gl/lang.php
index fecdf9425..b3da44096 100644
--- a/lib/plugins/plugin/lang/gl/lang.php
+++ b/lib/plugins/plugin/lang/gl/lang.php
@@ -4,7 +4,7 @@
*
* @author Medúlio <medulio@ciberirmandade.org>
* @author Oscar M. Lage <r0sk10@gmail.com>
- * @author Leandro Regueiro <leandro.regueiro@gmail.com>
+ * @author Rodrigo Rega <rodrigorega@gmail.com>
*/
$lang['menu'] = 'Xestionar Extensións';
$lang['download'] = 'Descargar e instalar unha nova extensión';
diff --git a/lib/plugins/popularity/lang/el/lang.php b/lib/plugins/popularity/lang/el/lang.php
index 32558b060..10268a4c3 100644
--- a/lib/plugins/popularity/lang/el/lang.php
+++ b/lib/plugins/popularity/lang/el/lang.php
@@ -5,6 +5,7 @@
* @author Konstantinos Koryllos <koryllos@gmail.com>
* @author George Petsagourakis <petsagouris@gmail.com>
* @author Petros Vidalis <pvidalis@gmail.com>
+ * @author Vasileios Karavasilis vasileioskaravasilis@gmail.com
*/
$lang['name'] = 'Αναφορά Δημοτικότητας (ίσως αργήσει λίγο να εμφανιστεί)';
$lang['submit'] = 'Αποστολή Δεδομένων';
diff --git a/lib/plugins/popularity/lang/gl/lang.php b/lib/plugins/popularity/lang/gl/lang.php
index 8032fccb0..86cd34db6 100644
--- a/lib/plugins/popularity/lang/gl/lang.php
+++ b/lib/plugins/popularity/lang/gl/lang.php
@@ -4,7 +4,7 @@
*
* @author Medúlio <medulio@ciberirmandade.org>
* @author Oscar M. Lage <r0sk10@gmail.com>
- * @author Leandro Regueiro <leandro.regueiro@gmail.com>
+ * @author Rodrigo Rega <rodrigorega@gmail.com>
*/
$lang['name'] = 'Resposta de Popularidade (pode demorar un tempo a cargar)';
$lang['submit'] = 'Enviar Datos';
diff --git a/lib/plugins/revert/lang/el/lang.php b/lib/plugins/revert/lang/el/lang.php
index 63454e4e9..c6e8bd56c 100644
--- a/lib/plugins/revert/lang/el/lang.php
+++ b/lib/plugins/revert/lang/el/lang.php
@@ -10,6 +10,7 @@
* @author Konstantinos Koryllos <koryllos@gmail.com>
* @author George Petsagourakis <petsagouris@gmail.com>
* @author Petros Vidalis <pvidalis@gmail.com>
+ * @author Vasileios Karavasilis vasileioskaravasilis@gmail.com
*/
$lang['menu'] = 'Αποκατάσταση κακόβουλων αλλαγών σελίδων';
$lang['filter'] = 'Αναζήτηση σελίδων που περιέχουν spam';
diff --git a/lib/plugins/revert/lang/gl/lang.php b/lib/plugins/revert/lang/gl/lang.php
index ad4fe4045..0e376d9a7 100644
--- a/lib/plugins/revert/lang/gl/lang.php
+++ b/lib/plugins/revert/lang/gl/lang.php
@@ -4,7 +4,7 @@
*
* @author Medúlio <medulio@ciberirmandade.org>
* @author Oscar M. Lage <r0sk10@gmail.com>
- * @author Leandro Regueiro <leandro.regueiro@gmail.com>
+ * @author Rodrigo Rega <rodrigorega@gmail.com>
*/
$lang['menu'] = 'Xestor de Reversión';
$lang['filter'] = 'Procurar páxinas con correo-lixo';
diff --git a/lib/plugins/syntax.php b/lib/plugins/syntax.php
index 552cc747a..b7839b2b2 100644
--- a/lib/plugins/syntax.php
+++ b/lib/plugins/syntax.php
@@ -226,56 +226,76 @@ class DokuWiki_Syntax_Plugin extends Doku_Parser_Mode {
$this->localised = true;
}
- // configuration methods
- /**
- * getConf($setting)
- *
- * use this function to access plugin configuration variables
- */
- function getConf($setting){
-
- if (!$this->configloaded){ $this->loadConfig(); }
-
- return $this->conf[$setting];
- }
-
- /**
- * loadConfig()
- * merges the plugin's default settings with any local settings
- * this function is automatically called through getConf()
- */
- function loadConfig(){
- global $conf;
-
- $defaults = $this->readDefaultSettings();
- $plugin = $this->getPluginName();
-
- foreach ($defaults as $key => $value) {
- if (isset($conf['plugin'][$plugin][$key])) continue;
- $conf['plugin'][$plugin][$key] = $value;
+ // configuration methods
+ /**
+ * getConf($setting)
+ *
+ * use this function to access plugin configuration variables
+ */
+ function getConf($setting) {
+
+ if(!$this->configloaded) { $this->loadConfig(); }
+
+ return $this->conf[$setting];
+ }
+
+ /**
+ * loadConfig()
+ * merges the plugin's default settings with any local settings
+ * this function is automatically called through getConf()
+ */
+ function loadConfig() {
+ global $conf;
+
+ $defaults = $this->readDefaultSettings();
+ $plugin = $this->getPluginName();
+
+ foreach($defaults as $key => $value) {
+ if(isset($conf['plugin'][$plugin][$key])) continue;
+ $conf['plugin'][$plugin][$key] = $value;
+ }
+
+ $this->configloaded = true;
+ $this->conf =& $conf['plugin'][$plugin];
}
- $this->configloaded = true;
- $this->conf =& $conf['plugin'][$plugin];
- }
+ /**
+ * read the plugin's default configuration settings from conf/default.php
+ * this function is automatically called through getConf()
+ *
+ * @return array setting => value
+ */
+ function readDefaultSettings() {
- /**
- * read the plugin's default configuration settings from conf/default.php
- * this function is automatically called through getConf()
- *
- * @return array setting => value
- */
- function readDefaultSettings() {
+ $path = DOKU_PLUGIN.$this->getPluginName().'/conf/';
+ $conf = array();
- $path = DOKU_PLUGIN.$this->getPluginName().'/conf/';
- $conf = array();
+ if(@file_exists($path.'default.php')) {
+ include($path.'default.php');
+ }
- if (@file_exists($path.'default.php')) {
- include($path.'default.php');
+ return $conf;
}
- return $conf;
- }
+ /**
+ * Loads a given helper plugin (if enabled)
+ *
+ * @author Esther Brunner <wikidesign@gmail.com>
+ *
+ * @param string $name name of plugin to load
+ * @param bool $msg if a message should be displayed in case the plugin is not available
+ *
+ * @return object helper plugin object
+ */
+ function loadHelper($name, $msg = true) {
+ if(!plugin_isdisabled($name)) {
+ $obj = plugin_load('helper', $name);
+ } else {
+ $obj = null;
+ }
+ if(is_null($obj) && $msg) msg("Helper plugin $name is not available or invalid.", -1);
+ return $obj;
+ }
/**
* Allow the plugin to prevent DokuWiki from reusing an instance
diff --git a/lib/plugins/usermanager/lang/el/lang.php b/lib/plugins/usermanager/lang/el/lang.php
index 4b4d95379..da7c8fb0f 100644
--- a/lib/plugins/usermanager/lang/el/lang.php
+++ b/lib/plugins/usermanager/lang/el/lang.php
@@ -11,6 +11,7 @@
* @author Konstantinos Koryllos <koryllos@gmail.com>
* @author George Petsagourakis <petsagouris@gmail.com>
* @author Petros Vidalis <pvidalis@gmail.com>
+ * @author Vasileios Karavasilis vasileioskaravasilis@gmail.com
*/
$lang['menu'] = 'Διαχείριση Χρηστών';
$lang['noauth'] = '(η είσοδος χρηστών δεν είναι δυνατή)';
diff --git a/lib/plugins/usermanager/lang/gl/lang.php b/lib/plugins/usermanager/lang/gl/lang.php
index fb965985f..f3a7ef281 100644
--- a/lib/plugins/usermanager/lang/gl/lang.php
+++ b/lib/plugins/usermanager/lang/gl/lang.php
@@ -4,7 +4,7 @@
*
* @author Medúlio <medulio@ciberirmandade.org>
* @author Oscar M. Lage <r0sk10@gmail.com>
- * @author Leandro Regueiro <leandro.regueiro@gmail.com>
+ * @author Rodrigo Rega <rodrigorega@gmail.com>
*/
$lang['menu'] = 'Xestor de Usuarios';
$lang['noauth'] = '(autenticación de usuarios non dispoñible)';
diff --git a/lib/scripts/fileuploaderextended.js b/lib/scripts/fileuploaderextended.js
index 4abd63bef..0ba7a0525 100644
--- a/lib/scripts/fileuploaderextended.js
+++ b/lib/scripts/fileuploaderextended.js
@@ -173,7 +173,7 @@ qq.extend(qq.FileUploaderExtended.prototype, {
if (result.success){
qq.addClass(item, this._classes.success);
- $link = '<a href="' + result.link + '" name="h_:' + result.id + '" class="select">' + nameInput.value + '</a>';
+ $link = '<a href="' + result.link + '" id="h_:' + result.id + '" class="select">' + nameInput.value + '</a>';
jQuery(fileElement).html($link);
} else {
diff --git a/lib/tpl/dokuwiki/css/basic.css b/lib/tpl/dokuwiki/css/basic.css
index 8b7447239..a0a60d295 100644
--- a/lib/tpl/dokuwiki/css/basic.css
+++ b/lib/tpl/dokuwiki/css/basic.css
@@ -28,15 +28,20 @@ body {
/*____________ headers ____________*/
+caption,
+figcaption,
+summary,
+legend {
+ padding: 0;
+ margin: 0 0 .35em;
+ line-height: 1.2;
+}
h1,
h2,
h3,
h4,
h5,
-h6,
-caption,
-legend {
- font-family: Arial, sans-serif;
+h6 {
font-weight: bold;
padding: 0;
line-height: 1.2;
@@ -47,9 +52,7 @@ legend {
[dir=rtl] h3,
[dir=rtl] h4,
[dir=rtl] h5,
-[dir=rtl] h6,
-[dir=rtl] caption,
-[dir=rtl] legend {
+[dir=rtl] h6 {
clear: right;
}
@@ -90,6 +93,8 @@ pre,
table,
hr,
blockquote,
+figure,
+details,
fieldset,
address {
margin: 0 0 1.4em 0; /* bottom margin = line-height */
@@ -161,7 +166,6 @@ table {
caption {
caption-side: top;
text-align: left;
- margin: 0 0 .3em;
}
[dir=rtl] caption {
text-align: right;
@@ -173,13 +177,12 @@ td {
margin: 0;
vertical-align: top;
border: 1px solid __border__;
- text-align: left;
}
th {
font-weight: bold;
background-color: __background_alt__;
+ text-align: left;
}
-[dir=rtl] td,
[dir=rtl] th {
text-align: right;
}
@@ -216,11 +219,15 @@ img {
height: auto;
}
img,
-object {
+object,
+embed,
+iframe,
+video,
+audio {
max-width: 100%;
}
-/* IE8 and below won't display the images otherwise */
-button img {
+#IE7 img,
+#IE8 img {
max-width: none;
}
@@ -229,7 +236,6 @@ hr {
border-bottom: solid __background__;
border-width: 1px 0;
height: 0;
- width: 100%;
text-align: center;
clear: both;
}
@@ -240,6 +246,15 @@ abbr {
border-bottom: 1px dotted;
font-style: normal;
}
+em acronym,
+em abbr {
+ font-style: italic;
+}
+
+mark {
+ background-color: __highlight__;
+ color: inherit;
+}
pre,
code,
@@ -289,6 +304,10 @@ sup {
vertical-align: super;
}
+small {
+ font-size: .8em;
+}
+
/*____________ forms ____________*/
/* for all of the form styles, style.ini colours are not used on purpose (except for fieldset border) */
@@ -299,9 +318,13 @@ form {
padding: 0;
}
fieldset {
- padding: 1em 1em 0;
+ padding: .7em 1em 0;
+ padding: .7rem 1rem; /* for those browsers understanding :last-child */
border: 1px solid __text_alt__;
}
+fieldset > :last-child {
+ margin-bottom: 0;
+}
legend {
margin: 0;
padding: 0 .1em;
@@ -316,12 +339,16 @@ textarea,
button,
select,
optgroup,
-option {
+option,
+keygen,
+output,
+meter,
+progress {
font: inherit;
font-weight: normal;
color: #333;
background-color: #fff;
- line-height: 1;
+ line-height: normal;
margin: 0;
vertical-align: middle;
-moz-box-sizing: border-box;
@@ -340,7 +367,8 @@ option {
input,
textarea,
-select {
+select,
+keygen {
border: 1px solid #ccc;
box-shadow: inset 0 0 1px #eee;
border-radius: 2px;
@@ -350,11 +378,14 @@ input:focus,
textarea:active,
textarea:focus,
select:active,
-select:focus {
+select:focus,
+keygen:active,
+keygen:focus {
border-color: #999;
}
input[type=radio],
-input[type=checkbox] {
+input[type=checkbox],
+input[type=image] {
padding: 0;
border-style: none;
box-shadow: none;
@@ -362,6 +393,8 @@ input[type=checkbox] {
/* all types of buttons */
input[type=submit],
+input[type=button],
+input[type=reset],
input.button,
a.button,
button,
@@ -369,7 +402,7 @@ button,
color: #333;
background-color: #eee;
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPgo8bGluZWFyR3JhZGllbnQgaWQ9Imc4MjQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkZGRkYiIG9mZnNldD0iMCIvPjxzdG9wIHN0b3AtY29sb3I9IiNGNEY0RjQiIG9mZnNldD0iMC4zIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0VFRUVFRSIgb2Zmc2V0PSIwLjk5Ii8+PHN0b3Agc3RvcC1jb2xvcj0iI0NDQ0NDQyIgb2Zmc2V0PSIuOTkiLz4KPC9saW5lYXJHcmFkaWVudD4KPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNnODI0KSIgLz4KPC9zdmc+);
- /*background: -moz-linear-gradient( top, #ffffff 0%, #f4f4f4 30%, #eeeeee 99%, #cccccc 99%); see FS#2447*/
+ background: -moz-linear-gradient( top, #ffffff 0%, #f4f4f4 30%, #eeeeee 99%, #cccccc 99%);
background: -webkit-linear-gradient(top, #ffffff 0%, #f4f4f4 30%, #eeeeee 99%, #cccccc 99%);
background: -o-linear-gradient( top, #ffffff 0%, #f4f4f4 30%, #eeeeee 99%, #cccccc 99%);
background: -ms-linear-gradient( top, #ffffff 0%, #f4f4f4 30%, #eeeeee 99%, #cccccc 99%);
@@ -382,11 +415,18 @@ button,
#IE7 input.button,
#IE7 button {
line-height: 1.4;
+ overflow: visible;
}
input[type=submit]:hover,
input[type=submit]:active,
input[type=submit]:focus,
+input[type=button]:hover,
+input[type=button]:active,
+input[type=button]:hover,
+input[type=reset]:hover,
+input[type=reset]:active,
+input[type=reset]:hover,
input.button:hover,
input.button:active,
input.button:focus,
@@ -400,7 +440,7 @@ button:focus,
border-color: #999;
background-color: #ddd;
background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPgo8bGluZWFyR3JhZGllbnQgaWQ9Imc2NzAiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkZGRkYiIG9mZnNldD0iMCIvPjxzdG9wIHN0b3AtY29sb3I9IiNGNEY0RjQiIG9mZnNldD0iMC4zIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0RERERERCIgb2Zmc2V0PSIwLjk5Ii8+PHN0b3Agc3RvcC1jb2xvcj0iI0JCQkJCQiIgb2Zmc2V0PSIuOTkiLz4KPC9saW5lYXJHcmFkaWVudD4KPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNnNjcwKSIgLz4KPC9zdmc+);
- /*background: -moz-linear-gradient( top, #ffffff 0%, #f4f4f4 30%, #dddddd 99%, #cccccc 99%); see FS#2447*/
+ background: -moz-linear-gradient( top, #ffffff 0%, #f4f4f4 30%, #dddddd 99%, #bbbbbb 99%);
background: -webkit-linear-gradient(top, #ffffff 0%, #f4f4f4 30%, #dddddd 99%, #bbbbbb 99%);
background: -o-linear-gradient( top, #ffffff 0%, #f4f4f4 30%, #dddddd 99%, #bbbbbb 99%);
background: -ms-linear-gradient( top, #ffffff 0%, #f4f4f4 30%, #dddddd 99%, #bbbbbb 99%);
@@ -415,7 +455,13 @@ button::-moz-focus-inner {
input[disabled],
button[disabled],
+select[disabled],
+textarea[disabled],
input[readonly],
-button[readonly] {
+button[readonly],
+select[readonly],
+textarea[readonly] {
cursor: auto;
+ opacity: .5;
+ background-color: #eee;
}
diff --git a/lib/tpl/dokuwiki/css/content.css b/lib/tpl/dokuwiki/css/content.css
index c23612643..119859e38 100644
--- a/lib/tpl/dokuwiki/css/content.css
+++ b/lib/tpl/dokuwiki/css/content.css
@@ -121,7 +121,7 @@
.dokuwiki dl.code dt,
.dokuwiki dl.file dt {
background-color: __background_site__;
- /* background: -moz-linear-gradient( top, __background_alt__ 0%, __background_site__ 100%); see FS#2447 */
+ background: -moz-linear-gradient( top, __background_alt__ 0%, __background_site__ 100%);
background: -webkit-linear-gradient(top, __background_alt__ 0%, __background_site__ 100%);
background: -o-linear-gradient( top, __background_alt__ 0%, __background_site__ 100%);
background: -ms-linear-gradient( top, __background_alt__ 0%, __background_site__ 100%);
diff --git a/lib/tpl/dokuwiki/css/pagetools.css b/lib/tpl/dokuwiki/css/pagetools.css
index a40d525b3..60dc43fb1 100644
--- a/lib/tpl/dokuwiki/css/pagetools.css
+++ b/lib/tpl/dokuwiki/css/pagetools.css
@@ -53,6 +53,7 @@
padding: 0;
/* add transparent border to prevent jumping when proper border is added on hover */
border: 1px solid transparent;
+ z-index: 10;
}
[dir=rtl] #dokuwiki__pagetools ul {
right: auto;
diff --git a/lib/tpl/dokuwiki/css/print.css b/lib/tpl/dokuwiki/css/print.css
index d30bc6c91..e0eaab848 100644
--- a/lib/tpl/dokuwiki/css/print.css
+++ b/lib/tpl/dokuwiki/css/print.css
@@ -5,18 +5,19 @@
*/
body {
- /*
- font: normal 12pt/1.2 serif;
- color: #000;
+ font: normal 87.5%/1.3 Garamond, Baskerville, "Hoefler Text", "Nimbus Roman No9 L", serif;
background-color: #fff;
- */
+ color: #000;
}
/* hide certain sections */
.a11y,
+audio,
+video,
#dokuwiki__header .tools,
#dokuwiki__aside,
.dokuwiki .breadcrumbs,
+.dokuwiki .pageId,
#dw__toc,
h3.toggle,
#dokuwiki__pagetools,
@@ -24,37 +25,38 @@ h3.toggle,
display: none;
}
-.dokuwiki h1,
-.dokuwiki h2,
-.dokuwiki h3,
-.dokuwiki h4,
-.dokuwiki h5,
-.dokuwiki caption,
-.dokuwiki legend {
+h1,
+h2,
+h3,
+h4,
+h5,
+caption,
+legend {
clear: both;
}
-.dokuwiki ul {
+ul {
list-style: disc outside;
}
-.dokuwiki ol {
+ol {
list-style: decimal outside;
}
-.dokuwiki ol ol {
+ol ol {
list-style-type: lower-alpha;
}
-.dokuwiki ol ol ol {
+ol ol ol {
list-style-type: upper-roman;
}
-.dokuwiki ol ol ol ol {
+ol ol ol ol {
list-style-type: upper-alpha;
}
-.dokuwiki ol ol ol ol ol {
+ol ol ol ol ol {
list-style-type: lower-roman;
}
-.dokuwiki a:link,
-.dokuwiki a:visited {
- text-decoration: underline;
+a:link,
+a:visited {
+ text-decoration: none;
+ border-bottom: 1pt dotted;
color: #333;
background-color: inherit;
}
@@ -68,33 +70,37 @@ a.mail:after {
}
/* code blocks */
-.dokuwiki pre {
+pre {
font-family: monospace;
}
-.dokuwiki dl.code dt,
-.dokuwiki dl.file dt {
+dl.code dt,
+dl.file dt {
+ font-weight: bold;
+}
+
+mark {
font-weight: bold;
}
/* images */
-.dokuwiki img {
+img {
border-width: 0;
vertical-align: middle;
}
-.dokuwiki img.media {
+img.media {
margin: .2em 0;
}
-.dokuwiki img.medialeft {
+img.medialeft {
margin: .2em 1em .2em 0;
}
-.dokuwiki img.mediaright {
+img.mediaright {
margin: .2em 0 .2em 1em;
}
-.dokuwiki img.mediacenter {
+img.mediacenter {
margin: .2em auto;
}
-.dokuwiki blockquote {
+blockquote {
padding: 0 10pt;
margin: 0;
border: solid #ccc;
@@ -105,27 +111,26 @@ a.mail:after {
}
/* tables */
-.dokuwiki table {
+table {
border-collapse: collapse;
empty-cells: show;
border-spacing: 0;
border: 1pt solid #ccc;
}
-.dokuwiki th,
-.dokuwiki td {
+th,
+td {
padding: 3pt 5pt;
margin: 0;
vertical-align: top;
border: 1pt solid #666;
+}
+th {
+ font-weight: bold;
text-align: left;
}
-[dir=rtl] .dokuwiki th,
-[dir=rtl] .dokuwiki td {
+[dir=rtl] th {
text-align: right;
}
-.dokuwiki th {
- font-weight: bold;
-}
/*____________ a bit of layout ____________*/
@@ -138,6 +143,7 @@ a.mail:after {
}
#dokuwiki__header h1 a {
text-decoration: none;
+ border-width: 0;
}
#dokuwiki__header h1 img {
float: left;
@@ -148,8 +154,21 @@ a.mail:after {
margin-right: 0;
margin-left: .5em;
}
+
.dokuwiki div.footnotes {
clear: both;
- border-top: 1pt solid #000;
+ border-top: 1pt dotted #999;
margin-top: 10pt;
}
+
+.dokuwiki div.docInfo {
+ font-size: 90%;
+ text-align: right;
+ clear: both;
+ padding-top: 2pt;
+ border-top: 1pt solid #999;
+ margin-top: 10pt;
+}
+[dir=rtl] .dokuwiki div.docInfo {
+ text-align: left;
+}
diff --git a/lib/tpl/dokuwiki/style.ini b/lib/tpl/dokuwiki/style.ini
index 67fbb3065..77bb98236 100644
--- a/lib/tpl/dokuwiki/style.ini
+++ b/lib/tpl/dokuwiki/style.ini
@@ -75,5 +75,5 @@ __missing__ = "#d30"
__site_width__ = "75em"
__sidebar_width__ = "16em"
; cut off points for mobile devices
-__tablet_width__ = "979px"
+__tablet_width__ = "800px"
__phone_width__ = "480px"