summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/exe/indexer.php79
-rw-r--r--lib/exe/js.php1
-rw-r--r--lib/plugins/config/lang/en/lang.php1
-rw-r--r--lib/plugins/config/settings/config.metadata.php1
-rw-r--r--lib/scripts/drag.js55
-rw-r--r--lib/scripts/edit.js5
-rw-r--r--lib/scripts/script.js41
-rw-r--r--lib/scripts/subscriptions.js46
-rw-r--r--lib/scripts/toolbar.js4
-rw-r--r--lib/tpl/default/_subscription.css21
-rw-r--r--lib/tpl/default/design.css5
-rw-r--r--lib/tpl/default/main.php1
-rw-r--r--lib/tpl/default/style.ini7
13 files changed, 221 insertions, 46 deletions
diff --git a/lib/exe/indexer.php b/lib/exe/indexer.php
index 1c4128eb7..84eb9d482 100644
--- a/lib/exe/indexer.php
+++ b/lib/exe/indexer.php
@@ -37,6 +37,7 @@ if ($evt->advise_before()) {
runIndexer() or
metaUpdate() or
runSitemapper() or
+ sendDigest() or
runTrimRecentChanges() or
runTrimRecentChanges(true) or
$evt->advise_after();
@@ -335,6 +336,84 @@ function runSitemapper(){
}
/**
+ * Send digest and list mails for all subscriptions which are in effect for the
+ * current page
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+function sendDigest() {
+ echo 'sendDigest(): start'.NL;
+ global $ID;
+ global $conf;
+ if (!$conf['subscribers']) {
+ return;
+ }
+ require_once DOKU_INC . 'inc/subscription.php';
+ $subscriptions = subscription_find($ID, array('style' => '(digest|list)',
+ 'escaped' => true));
+ global $auth;
+ global $lang;
+ global $conf;
+ global $USERINFO;
+
+ // remember current user info
+ $olduinfo = $USERINFO;
+ $olduser = $_SERVER['REMOTE_USER'];
+
+ foreach($subscriptions as $id => $users) {
+ foreach($users as $data) {
+ list($user, $style, $lastupdate) = $data;
+ $lastupdate = (int) $lastupdate;
+ if ($lastupdate + $conf['subscribe_interval'] > time()) {
+ // Less than a day 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));
+ if (count($changes) === 0) {
+ continue;
+ }
+ if ($style === 'digest') {
+ foreach($changes as $change) {
+ subscription_send_digest($USERINFO['mail'], $change,
+ $lastupdate);
+ }
+ } elseif ($style === 'list') {
+ subscription_send_list($USERINFO['mail'], $changes, $id);
+ }
+ // TODO: Handle duplicate subscriptions.
+ } else {
+ if(auth_quickaclcheck($id) < AUTH_READ) continue;
+
+ $meta = p_get_metadata($id);
+ $rev = $meta['last_change']['date'];
+ if ($rev < $lastupdate) {
+ // There is no new revision.
+ continue;
+ }
+ subscription_send_digest($USERINFO['mail'], $meta['last_change'],
+ $lastupdate);
+ }
+ // Update notification time.
+ subscription_set($user, $id, $style, time(), true);
+ }
+ }
+
+ // restore current user info
+ $USERINFO = $olduinfo;
+ $_SERVER['REMOTE_USER'] = $olduser;
+}
+
+/**
* Formats a timestamp as ISO 8601 date
*
* @author <ungu at terong dot com>
diff --git a/lib/exe/js.php b/lib/exe/js.php
index 38fda1789..8648bf18f 100644
--- a/lib/exe/js.php
+++ b/lib/exe/js.php
@@ -53,6 +53,7 @@ function js_out(){
DOKU_INC.'lib/scripts/edit.js',
DOKU_INC.'lib/scripts/linkwiz.js',
DOKU_INC.'lib/scripts/media.js',
+ DOKU_INC.'lib/scripts/subscriptions.js',
DOKU_TPLINC.'script.js',
);
diff --git a/lib/plugins/config/lang/en/lang.php b/lib/plugins/config/lang/en/lang.php
index 25103278c..45b653680 100644
--- a/lib/plugins/config/lang/en/lang.php
+++ b/lib/plugins/config/lang/en/lang.php
@@ -130,6 +130,7 @@ $lang['gdlib'] = 'GD Lib version';
$lang['im_convert'] = 'Path to ImageMagick\'s convert tool';
$lang['jpg_quality'] = 'JPG compression quality (0-100)';
$lang['subscribers'] = 'Enable page subscription support';
+$lang['subscribe_time'] = 'Time after which subscription lists and digests are sent (sec); This should be larger than the time specified in recent_days.';
$lang['compress'] = 'Compact CSS and javascript output';
$lang['hidepages'] = 'Hide matching pages (regular expressions)';
$lang['send404'] = 'Send "HTTP 404/Page Not Found" for non existing pages';
diff --git a/lib/plugins/config/settings/config.metadata.php b/lib/plugins/config/settings/config.metadata.php
index 742faf387..da2ba4aef 100644
--- a/lib/plugins/config/settings/config.metadata.php
+++ b/lib/plugins/config/settings/config.metadata.php
@@ -148,6 +148,7 @@ $meta['htmlok'] = array('onoff');
$meta['phpok'] = array('onoff');
$meta['notify'] = array('email', '_multiple' => true);
$meta['subscribers'] = array('onoff');
+$meta['subscribe_time'] = array('numeric');
$meta['locktime'] = array('numeric');
$meta['cachetime'] = array('numeric');
diff --git a/lib/scripts/drag.js b/lib/scripts/drag.js
index 4726b77de..fa249a996 100644
--- a/lib/scripts/drag.js
+++ b/lib/scripts/drag.js
@@ -1,8 +1,9 @@
/**
* Makes a DOM object draggable
*
- * This is currently for movable DOM dialogs only. If needed it could be
- * extended to execute callbacks on special events...
+ * If you just want to move objects around, use drag.attach. For full
+ * customization, drag can be used as a javascript prototype, it is
+ * inheritance-aware.
*
* @link http://nofunc.org/Drag_Drop/
*/
@@ -26,33 +27,36 @@ var drag = {
attach: function (obj,handle) {
if(handle){
handle.dragobject = obj;
- addEvent($(handle),'mousedown',drag.start);
}else{
- addEvent($(obj),'mousedown',drag.start);
+ handle = obj;
}
+ var _this = this;
+ addEvent($(handle),'mousedown',function (e) {return _this.start(e); });
},
/**
* Starts the dragging operation
*/
start: function (e){
- drag.handle = e.target;
- if(drag.handle.dragobject){
- drag.obj = drag.handle.dragobject;
+ this.handle = e.target;
+ if(this.handle.dragobject){
+ this.obj = this.handle.dragobject;
}else{
- drag.obj = drag.handle;
+ this.obj = this.handle;
}
- drag.handle.className += ' ondrag';
- drag.obj.className += ' ondrag';
+ this.handle.className += ' ondrag';
+ this.obj.className += ' ondrag';
- drag.oX = parseInt(drag.obj.style.left);
- drag.oY = parseInt(drag.obj.style.top);
- drag.eX = drag.evX(e);
- drag.eY = drag.evY(e);
+ this.oX = parseInt(this.obj.style.left);
+ this.oY = parseInt(this.obj.style.top);
+ this.eX = drag.evX(e);
+ this.eY = drag.evY(e);
- addEvent(document,'mousemove',drag.drag);
- addEvent(document,'mouseup',drag.stop);
+ var _this = this;
+ this.mousehandlers = [function (e) {return _this.drag(e);}, function (e) {return _this.stop(e);}];
+ addEvent(document,'mousemove', this.mousehandlers[0]);
+ addEvent(document,'mouseup', this.mousehandlers[1]);
e.preventDefault();
e.stopPropagation();
@@ -63,21 +67,21 @@ var drag = {
* Ends the dragging operation
*/
stop: function(){
- drag.handle.className = drag.handle.className.replace(/ ?ondrag/,'');
- drag.obj.className = drag.obj.className.replace(/ ?ondrag/,'');
- removeEvent(document,'mousemove',drag.drag);
- removeEvent(document,'mouseup',drag.stop);
- drag.obj = null;
- drag.handle = null;
+ this.handle.className = this.handle.className.replace(/ ?ondrag/,'');
+ this.obj.className = this.obj.className.replace(/ ?ondrag/,'');
+ removeEvent(document,'mousemove', this.mousehandlers[0]);
+ removeEvent(document,'mouseup', this.mousehandlers[1]);
+ this.obj = null;
+ this.handle = null;
},
/**
* Moves the object during the dragging operation
*/
drag: function(e) {
- if(drag.obj) {
- drag.obj.style.top = (drag.evY(e)+drag.oY-drag.eY+'px');
- drag.obj.style.left = (drag.evX(e)+drag.oX-drag.eX+'px');
+ if(this.obj) {
+ this.obj.style.top = (this.evY(e)+this.oY-this.eY+'px');
+ this.obj.style.left = (this.evX(e)+this.oX-this.eX+'px');
}
},
@@ -96,4 +100,3 @@ var drag = {
}
};
-
diff --git a/lib/scripts/edit.js b/lib/scripts/edit.js
index d7391b7e7..4d8ead858 100644
--- a/lib/scripts/edit.js
+++ b/lib/scripts/edit.js
@@ -12,12 +12,15 @@
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function createToolButton(icon,label,key,id){
+function createToolButton(icon,label,key,id,classname){
var btn = document.createElement('button');
var ico = document.createElement('img');
// preapare the basic button stuff
btn.className = 'toolbutton';
+ if(classname){
+ btn.className += ' '+classname;
+ }
btn.title = label;
if(key){
btn.title += ' ['+key.toUpperCase()+']';
diff --git a/lib/scripts/script.js b/lib/scripts/script.js
index ccba82144..b611f980a 100644
--- a/lib/scripts/script.js
+++ b/lib/scripts/script.js
@@ -538,24 +538,41 @@ addInitEvent(function(){
var break_classes = new RegExp('secedit|toc|page');
var btns = getElementsByClass('btn_secedit',document,'form');
for(var i=0; i<btns.length; i++){
- addEvent(btns[i],'mouseover',function(e){
- var tgt = e.target;
- if(tgt.form) tgt = tgt.form;
- tgt = tgt.parentNode.previousSibling;
- if(tgt.nodeName != "DIV") tgt = tgt.previousSibling;
- while(!break_classes.test(tgt.className)) {
- tgt.className += ' section_highlight';
- if (tgt.tagName == 'H1') break;
- tgt = (tgt.previousSibling != null) ? tgt.previousSibling : tgt.parentNode;
- }
- });
+ switch(btns[i].parentNode.className.match(/editbutton_(\w+)/)[1]) {
+ case 'plain':
+ addEvent(btns[i],'mouseover',function(e){
+ var tgt = e.target.form.parentNode;
+ do {
+ tgt = tgt.previousSibling;
+ } while (tgt && !tgt.tagName);
+ if (!tgt) return;
+ if(tgt.nodeName != "DIV") tgt = tgt.previousSibling;
+ while(!break_classes.test(tgt.className)) {
+ tgt.className += ' section_highlight';
+ if (tgt.tagName == 'H1') break;
+ tgt = (tgt.previousSibling != null) ? tgt.previousSibling : tgt.parentNode;
+ }
+ });
+ break;
+
+ case 'table':
+ addEvent(btns[i],'mouseover',function(e){
+ var tgt = e.target.form.parentNode;
+ do {
+ tgt = tgt.previousSibling;
+ } while (tgt && !tgt.tagName);
+ if (tgt && tgt.tagName === 'TABLE') {
+ tgt.className += ' section_highlight';
+ }
+ });
+ break;
+ }
addEvent(btns[i],'mouseout',function(e){
var secs = getElementsByClass('section_highlight');
for(var j=0; j<secs.length; j++){
secs[j].className = secs[j].className.replace(/section_highlight/,'');
}
- var secs = getElementsByClass('section_highlight');
});
}
});
diff --git a/lib/scripts/subscriptions.js b/lib/scripts/subscriptions.js
new file mode 100644
index 000000000..d701f258f
--- /dev/null
+++ b/lib/scripts/subscriptions.js
@@ -0,0 +1,46 @@
+/**
+ * Hide list subscription style if target is a page
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+
+addInitEvent(function () {
+ var form = $('subscribe__form');
+ if (!form) {
+ return;
+ }
+
+ var styleradios = {};
+
+ function update_state() {
+ if (!this.checked) {
+ return;
+ }
+ if (this.value.match(/:$/)) {
+ styleradios.list.parentNode.style.display = '';
+ } else {
+ styleradios.list.parentNode.style.display = 'none';
+ if (styleradios.list.checked) {
+ styleradios.digest.checked = 'checked';
+ }
+ }
+ }
+
+ var cur_sel = null;
+
+ var inputs = form.getElementsByTagName('input');
+ for (var i = 0; i < inputs.length ; ++i) {
+ switch (inputs[i].name) {
+ case 'sub_target':
+ addEvent(inputs[i], 'click', update_state);
+ if (inputs[i].checked) {
+ cur_sel = inputs[i];
+ }
+ break;
+ case 'sub_style':
+ styleradios[inputs[i].value] = inputs[i];
+ break;
+ }
+ }
+ update_state.call(cur_sel);
+});
diff --git a/lib/scripts/toolbar.js b/lib/scripts/toolbar.js
index 1e4a91864..99ad1bb9c 100644
--- a/lib/scripts/toolbar.js
+++ b/lib/scripts/toolbar.js
@@ -27,7 +27,9 @@ function initToolbar(tbid,edid,tb){
// create new button
var btn = createToolButton(tb[i]['icon'],
tb[i]['title'],
- tb[i]['key']);
+ tb[i]['key'],
+ tb[i]['id'],
+ tb[i]['class']);
// type is a tb function -> assign it as onclick
diff --git a/lib/tpl/default/_subscription.css b/lib/tpl/default/_subscription.css
new file mode 100644
index 000000000..0792c8c21
--- /dev/null
+++ b/lib/tpl/default/_subscription.css
@@ -0,0 +1,21 @@
+/**
+ * Styles for the subscription page
+ */
+
+form#subscribe__form {
+ display: block;
+ width: 300px;
+ text-align: center;
+}
+
+form#subscribe__form fieldset {
+ text-align: left;
+ margin: 0.5em 0;
+}
+
+form#subscribe__form label {
+ display:block;
+ margin: 0 0.5em 0.5em;
+}
+
+
diff --git a/lib/tpl/default/design.css b/lib/tpl/default/design.css
index 4830a9e2c..cd4d03e43 100644
--- a/lib/tpl/default/design.css
+++ b/lib/tpl/default/design.css
@@ -741,8 +741,8 @@ div.dokuwiki ul.search_quickhits li {
width: 30%;
}
-div.dokuwiki div.section_highlight {
- background-color: __background_alt__;
+div.dokuwiki .section_highlight {
+ background-color: __background_alt__ !important;
}
/* ------------------ Additional ---------------------- */
@@ -833,3 +833,4 @@ div.dokuwiki div.imagemeta img.thumb {
float: left;
margin-right: 0.1em;
}
+
diff --git a/lib/tpl/default/main.php b/lib/tpl/default/main.php
index 67c3a00ba..b5717c009 100644
--- a/lib/tpl/default/main.php
+++ b/lib/tpl/default/main.php
@@ -117,7 +117,6 @@ if (!defined('DOKU_INC')) die();
</div>
<div class="bar-right" id="bar__bottomright">
<?php tpl_button('subscribe')?>
- <?php tpl_button('subscribens')?>
<?php tpl_button('admin')?>
<?php tpl_button('profile')?>
<?php tpl_button('login')?>
diff --git a/lib/tpl/default/style.ini b/lib/tpl/default/style.ini
index dfd5500fa..84d04e743 100644
--- a/lib/tpl/default/style.ini
+++ b/lib/tpl/default/style.ini
@@ -10,9 +10,10 @@ layout.css = screen
design.css = screen
style.css = screen
-media.css = screen
-_admin.css = screen
-_linkwiz.css = screen
+media.css = screen
+_admin.css = screen
+_linkwiz.css = screen
+_subscription.css = screen
rtl.css = rtl
print.css = print