diff --git a/MenuItem.php b/MenuItem.php
new file mode 100644
index 0000000..ae8bc70
--- /dev/null
+++ b/MenuItem.php
@@ -0,0 +1,32 @@
+getLang('menu_recommend');
+ }
+}
diff --git a/TPL_EXAMPLE.txt b/TPL_EXAMPLE.txt
deleted file mode 100644
index b0f8776..0000000
--- a/TPL_EXAMPLE.txt
+++ /dev/null
@@ -1,8 +0,0 @@
- 'recommend', 'id' => $ID));
-}
-?>
diff --git a/action.php b/action.php
index dd87823..6df69be 100644
--- a/action.php
+++ b/action.php
@@ -1,22 +1,24 @@
register_hook($event, 'BEFORE', $this, '_handle');
+ $controller->register_hook($event, 'BEFORE', $this, 'handle');
}
+ $controller->register_hook('MENU_ITEMS_ASSEMBLY', 'AFTER', $this, 'handleMenu');
+ $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'autocomplete');
}
- function _handle(&$event, $param) {
- if (!in_array($event->data, array('recommend', 'plugin_recommend'))) {
+ /**
+ * Main processing
+ *
+ * @param Doku_Event $event
+ * @return void
+ */
+ public function handle(Doku_Event $event) {
+ if ($event->data !=='recommend') {
return;
}
@@ -28,112 +30,203 @@ function _handle(&$event, $param) {
$event->stopPropagation();
- if ($_SERVER['REQUEST_METHOD'] == 'POST' &&
- isset($_POST['sectok']) &&
- !($err = $this->_handle_post())) {
- if ($event->name === 'AJAX_CALL_UNKNOWN') {
- /* To signal success to AJAX. */
- header('HTTP/1.1 204 No Content');
- return;
+ global $INPUT;
+
+ // early output to trigger display msgs even via AJAX.
+ echo ' ';
+ tpl_flush();
+ if ($INPUT->server->str('REQUEST_METHOD') === 'POST') {
+ try {
+ $this->handlePost();
+ if ($event->name === 'AJAX_CALL_UNKNOWN') {
+ $this->ajaxSuccess(); // To signal success to AJAX.
+ } else {
+ msg($this->getLang('thanks'), 1);
+ }
+ return; // we're done here
+ } catch (\Exception $e) {
+ msg($e->getMessage(), -1);
}
- echo 'Thanks for recommending our site.';
+ }
+
+ echo $this->getForm();
+ }
+
+ /**
+ * Page menu item
+ *
+ * @param Doku_Event $event
+ * @return void
+ */
+ public function handleMenu(Doku_Event $event)
+ {
+ if ($event->data['view'] !== 'page') return;
+ // menu item is only for logged in users
+ if (empty($_SERVER['REMOTE_USER'])) return;
+
+ array_splice($event->data['items'], -1, 0, [new \dokuwiki\plugin\recommend\MenuItem()]);
+ }
+
+ /**
+ * Autocomplete
+ * @param Doku_Event $event
+ * @throws Exception
+ * @author Andreas Gohr
+ *
+ */
+ public function autocomplete(Doku_Event $event)
+ {
+
+ if ($event->data !=='plugin_recommend_ac') {
return;
}
- /* To display msgs even via AJAX. */
- echo ' ';
- if (isset($err)) {
- msg($err, -1);
+
+ $event->preventDefault();
+ $event->stopPropagation();
+
+ /** @var \DokuWiki_Auth_Plugin $auth */
+ global $auth;
+ global $INPUT;
+
+ if (!$auth->canDo('getUsers')) {
+ throw new Exception('The user backend can not search for users');
}
- $this->_show_form();
- }
- function _show_form() {
- $r_name = isset($_REQUEST['r_name']) ? $_REQUEST['r_name'] : '';
- $r_email = isset($_REQUEST['r_email']) ? $_REQUEST['r_email'] : '';
- $s_name = isset($_REQUEST['s_name']) ? $_REQUEST['s_name'] : '';
- $s_email = isset($_REQUEST['s_email']) ? $_REQUEST['s_email'] : '';
- $comment = isset($_REQUEST['comment']) ? $_REQUEST['r_comment'] : '';
- if (isset($_REQUEST['id'])) {
- $id = $_REQUEST['id'];
- } else {
- global $ID;
- if (!isset($ID)) {
- msg('Unknown page', -1);
- return;
- }
- $id = $ID;
+ header('Content-Type: application/json');
+
+ // check minimum length
+ $lookup = trim($INPUT->str('search'));
+ if (utf8_strlen($lookup) < 3) {
+ echo json_encode([]);
+ return;
+ }
+
+ // find users by login and name
+ $logins = $auth->retrieveUsers(0, 10, ['user' => $lookup]);
+ if (count($logins) < 10) {
+ $logins = array_merge($logins, $auth->retrieveUsers(0, 10, ['name' => $lookup]));
}
- $form = new Doku_Form('recommend_plugin', '?do=recommend');
- $form->addHidden('id', $id);
- $form->startFieldset('Recommend page “' . hsc($id). '”');
- if (isset($_SERVER['REMOTE_USER'])) {
+
+ // reformat result for jQuery UI Autocomplete
+ $users = [];
+ foreach ($logins as $login => $info) {
+ $users[] = [
+ 'label' => $info['name'] . ' [' . $login . ']',
+ 'value' => $login
+ ];
+ }
+
+ echo json_encode($users);
+ }
+
+ /**
+ * Returns rendered form
+ *
+ * @return string
+ */
+ protected function getForm()
+ {
+ global $INPUT;
+
+ $id = getID(); // we may run in AJAX context
+ if ($id === '') throw new \RuntimeException('No ID given');
+
+ $form = new \dokuwiki\Form\Form([
+ 'action' => wl($id, ['do' => 'recommend'], false, '&'),
+ 'id' => 'plugin__recommend',
+ ]);
+ $form->setHiddenField('id', $id); // we need it for the ajax call
+
+ /** @var helper_plugin_recommend_assignment $helper */
+ $helper = plugin_load('helper', 'recommend_assignment');
+ $template = $helper->loadMatchingTemplate();
+
+ if ($INPUT->server->has('REMOTE_USER')) {
global $USERINFO;
- $form->addHidden('s_name', $USERINFO['name']);
- $form->addHidden('s_email', $USERINFO['mail']);
+ $form->setHiddenField('s_name', $USERINFO['name']);
+ $form->setHiddenField('s_email', $USERINFO['mail']);
} else {
- $form->addElement(form_makeTextField('s_name', $s_name, 'Your name'));
- $form->addElement(form_makeTextField('s_email', $s_email,
- 'Your email address'));
- }
- $form->addElement(form_makeTextField('r_name', $r_name, 'Recipient name'));
- $form->addElement(form_makeTextField('r_email', $r_email,
- 'Recipient email address'));
- $form->addElement('');
- $helper = null;
- if(@is_dir(DOKU_PLUGIN.'captcha')) $helper = plugin_load('helper','captcha');
- if(!is_null($helper) && $helper->isEnabled()){
- $form->addElement($helper->getHTML());
- }
-
- $form->addElement(form_makeButton('submit', '', 'Send recommendation'));
- $form->addElement(form_makeButton('submit', 'cancel', 'Cancel'));
- $form->printForm();
+ $form->addTextInput('s_name', $this->getLang('yourname'))->addClass('edit');
+ $form->addTextInput('s_email', $this->getLang('youremailaddress'))->addClass('edit');
+ }
+
+ $form->addTextInput('r_email', $this->getLang('recipients'))
+ ->addClass('edit')
+ ->val($template['user'] ?? '');
+ $form->addTextInput('subject', $this->getLang('subject'))
+ ->addClass('edit')
+ ->val($template['subject'] ?? '');
+ $form->addTextarea('comment', $this->getLang('message'))
+ ->attr('rows', '8')
+ ->attr('cols', '40')
+ ->addClass('edit')
+ ->val($template['message'] ?? '');
+
+ /** @var helper_plugin_captcha $captcha */
+ $captcha = plugin_load('helper', 'captcha');
+ if ($captcha) $form->addHTML($captcha->getHTML());
+
+ $form->addTagOpen('div')->addClass('buttons');
+ $form->addButton('submit', $this->getLang('send'))->attr('type', 'submit');
+ $form->addTagClose('div');
+
+ return $form->toHTML();
}
- function _handle_post() {
- $helper = null;
- if(@is_dir(DOKU_PLUGIN.'captcha')) $helper = plugin_load('helper','captcha');
- if(!is_null($helper) && $helper->isEnabled() && !$helper->check()) {
- return 'Wrong captcha';
+ /**
+ * Handles form submission
+ *
+ * @throws Exception
+ */
+ protected function handlePost()
+ {
+ global $INPUT;
+
+ if (!checkSecurityToken()) {
+ throw new \Exception('Security token did not match');
}
- /* Validate input. */
- if (!isset($_POST['r_email']) || !mail_isvalid($_POST['r_email'])) {
- return 'Invalid recipient email address submitted';
+ /** @var helper_plugin_recommend_mail $mailHelper */
+ $mailHelper = plugin_load('helper', 'recommend_mail');
+
+ // Captcha plugin
+ $captcha = null;
+ if (@is_dir(DOKU_PLUGIN . 'captcha')) $captcha = plugin_load('helper','captcha');
+ if (!is_null($captcha) && $captcha->isEnabled() && !$captcha->check()) {
+ throw new \Exception($this->getLang('err_captcha'));
}
- if (!isset($_POST['r_name']) || trim($_POST['r_name']) === '') {
- return 'Invalid recipient name submitted';
+
+ /* Validate input */
+ $recipients = $INPUT->str('r_email');
+
+ if (empty($recipients)) {
+ throw new \Exception($this->getLang('err_recipient'));
}
- $r_name = $_POST['r_name'];
- $recipient = $r_name . ' <' . $_POST['r_email'] . '>';
+
+ $recipients = $mailHelper->resolveRecipients($recipients);
+ $recipients = implode(',', $recipients);
if (!isset($_POST['s_email']) || !mail_isvalid($_POST['s_email'])) {
- return 'Invalid sender email address submitted';
+ throw new \Exception($this->getLang('err_sendermail'));
}
if (!isset($_POST['s_name']) || trim($_POST['s_name']) === '') {
- return 'Invalid sender name submitted';
+ throw new \Exception($this->getLang('err_sendername'));
}
$s_name = $_POST['s_name'];
$sender = $s_name . ' <' . $_POST['s_email'] . '>';
- if (!isset($_POST['id']) || !page_exists($_POST['id'])) {
- return 'Invalid page submitted';
- }
- $page = $_POST['id'];
+ $id = $INPUT->filter('cleanID')->str('id');
+ if ($id === '' || !page_exists($id)) throw new \Exception($this->getLang('err_page'));
- $comment = isset($_POST['comment']) ? $_POST['comment'] : null;
+ $comment = $INPUT->str('comment');
- /* Prepare mail text. */
- $mailtext = file_get_contents(dirname(__FILE__).'/template.txt');
+ /* Prepare mail text */
+ $mailtext = file_get_contents($this->localFN('template'));
global $conf;
- global $USERINFO;
- foreach (array('NAME' => $r_name,
- 'PAGE' => $page,
+ foreach (array('PAGE' => $id,
'SITE' => $conf['title'],
- 'URL' => wl($page, '', true),
+ 'URL' => wl($id, '', true),
'COMMENT' => $comment,
'AUTHOR' => $s_name) as $var => $val) {
$mailtext = str_replace('@' . $var . '@', $val, $mailtext);
@@ -141,10 +234,24 @@ function _handle_post() {
/* Limit to two empty lines. */
$mailtext = preg_replace('/\n{4,}/', "\n\n\n", $mailtext);
- /* Perform stuff. */
- mail_send($recipient, 'Page recommendation', $mailtext, $sender);
- $log = new Plugin_Recommend_Log(date('Y-m'));
- $log->writeEntry($page, $sender, $recipient, $comment);
- return false;
+ $mailHelper->sendMail($recipients, $mailtext, $sender);
+
+ /** @var helper_plugin_recommend_log $log */
+ $log = new helper_plugin_recommend_log(date('Y-m'));
+ $log->writeEntry($id, $sender, $recipients, $comment);
+ }
+
+ /**
+ * show success message in ajax mode
+ */
+ protected function ajaxSuccess()
+ {
+ echo '
';
}
}
diff --git a/admin.php b/admin.php
index 26e3128..a4ccd98 100644
--- a/admin.php
+++ b/admin.php
@@ -1,52 +1,154 @@
month = $_REQUEST['rec_month'];
} else {
$this->month = date('Y-m');
}
- $log = new Plugin_Recommend_Log($this->month);
+ $log = new helper_plugin_recommend_log($this->month);
$this->entries = $log->getEntries();
- $this->logs = Plugin_Recommend_Log::getLogs();
+ $this->logs = $log->getLogs();
+
+ global $INPUT;
+ global $ID;
+
+ /** @var helper_plugin_recommend_assignment $assignmentsHelper */
+ $assignmentsHelper = plugin_load('helper', 'recommend_assignment');
+
+ if ($INPUT->str('action') && $INPUT->arr('assignment') && checkSecurityToken()) {
+ $assignment = $INPUT->arr('assignment');
+ if ($INPUT->str('action') === 'delete') {
+ $ok = $assignmentsHelper->removeAssignment($assignment);
+ if (!$ok) {
+ msg('failed to remove pattern', -1);
+ }
+ } elseif ($INPUT->str('action') === 'add') {
+ if ($assignment['pattern'][0] == '/') {
+ if (@preg_match($assignment['pattern'], null) === false) {
+ msg('Invalid regular expression. Pattern not saved', -1);
+ } else {
+ $ok = $assignmentsHelper->addAssignment($assignment);
+ if (!$ok) {
+ msg('failed to add pattern', -1);
+ }
+ }
+ } else {
+ $ok = $assignmentsHelper->addAssignment($assignment);
+ if (!$ok) {
+ msg('failed to add pattern', -1);
+ }
+ }
+
+ }
+
+ send_redirect(wl($ID, array('do' => 'admin', 'page' => 'recommend'), true, '&'));
+ }
}
- function getTOC() {
- return array_map('recommend_make_toc', $this->logs);
+ public function getTOC() {
+ return array_map([$this, 'recommendMakeTOC'], $this->logs);
}
- function html() {
+ public function html() {
+ echo $this->locale_xhtml('intro');
+
if (!$this->logs) {
echo 'No recommendations.';
- return;
}
if (!$this->entries) {
echo 'No recommendations were made in ' . $this->month . '.';
- return;
}
+
+ echo '' . $this->getLang('headline_snippets') . '
';
+
+ echo $this->getForm();
+
+ echo '' . $this->getLang('headline_logs') . '
';
echo 'In ' . $this->month . ', your users made the following ' . count($this->entries) . ' recommendations:
';
echo '';
- foreach(array_reverse($this->entries) as $entry) {
+ foreach (array_reverse($this->entries) as $entry) {
echo "- " . hsc($entry) . "
";
}
echo '
';
}
-}
-function recommend_make_toc($month) {
- global $ID;
- return html_mktocitem('?do=admin&page=recommend&id=' . $ID . '&rec_month=' . $month, $month, 1, '');
+ protected function getForm()
+ {
+ global $ID;
+ $assignments = helper_plugin_recommend_assignment::getAssignments();
+
+ $form = '';
+
+ return $form;
+ }
+
+ protected function recommendMakeTOC($month) {
+ global $ID;
+ return html_mktocitem('?do=admin&page=recommend&id=' . $ID . '&rec_month=' . $month, $month, 2, '');
+ }
}
diff --git a/admin.svg b/admin.svg
new file mode 100644
index 0000000..2e6aa01
--- /dev/null
+++ b/admin.svg
@@ -0,0 +1,3 @@
+
diff --git a/conf/default.php b/conf/default.php
index c789b94..05acb11 100644
--- a/conf/default.php
+++ b/conf/default.php
@@ -1,2 +1,2 @@
path = DOKU_INC . 'data/cache/recommend';
+ if (!file_exists($this->path)) {
+ mkdir($this->path);
+ }
+ $this->path .= '/' . $month . '.log';
+ }
+
+ public function getLogs()
+ {
+ return array_map([$this, 'recommend_strip_extension'], glob(DOKU_INC . 'data/cache/recommend/*.log'));
+ }
+
+ public function getEntries()
+ {
+ return @file($this->path);
+ }
+
+ public function writeEntry($page, $sender, $receiver, $comment)
+ {
+ $comment = str_replace(["\n", '"'], ['', '\''], $comment);
+ $logfile = fopen($this->path, 'a');
+ fwrite($logfile, date('r') . ': ' .
+ "“${sender}” recommended “${page}” to " .
+ "“${receiver}” with comment “${comment}”.\n");
+ fclose($logfile);
+ }
+
+
+ protected function recommend_strip_extension($str) {
+ return substr(basename($str), 0, -4);
+ }
+}
diff --git a/helper/mail.php b/helper/mail.php
new file mode 100644
index 0000000..75ae0b6
--- /dev/null
+++ b/helper/mail.php
@@ -0,0 +1,115 @@
+bcc($recipient);
+ $mailer->from($sender);
+
+ $subject = $INPUT->str('subject');
+ $mailer->subject($subject);
+ $mailer->setBody($mailtext);
+ $mailer->send();
+ }
+
+ /**
+ * Processes recipients from input and returns an array of emails
+ * with user groups resolved to individual users
+ *
+ * @param string $recipients
+ * @return array
+ * @throws Exception
+ */
+ public function resolveRecipients($recipients)
+ {
+ $resolved = [];
+
+ $recipients = explode(',', $recipients);
+
+ foreach ($recipients as $recipient) {
+ $recipient = trim($recipient);
+
+ if ($recipient[0] === '@') {
+ $this->resolveGroup($resolved, $recipient);
+ } elseif (strpos($recipient, '@') === false) {
+ $this->resolveUser($resolved, $recipient);
+ } else {
+ if (!$this->emailIsValid($recipient)) {
+ throw new \Exception($this->getLang('err_recipient'));
+ }
+ $resolved[] = $recipient;
+ }
+ }
+ return $resolved;
+ }
+
+ /**
+ * @param array $resolved
+ * @param string $recipient
+ * @return void
+ * @throws Exception
+ */
+ protected function resolveGroup(&$resolved, $recipient)
+ {
+ /** @var AuthPlugin $auth */
+ global $auth;
+ if (!$auth->canDo('getUsers')) {
+ throw new \Exception('Auth cannot fetch users by group.');
+ }
+
+ $users = $auth->retrieveUsers(0, 0, ['grps' => substr($recipient, 1)]);
+ foreach ($users as $user) {
+ $resolved[] = $user['mail'];
+ }
+ }
+
+ /**
+ * @param array $resolved
+ * @param string $recipient
+ * @return void
+ */
+ protected function resolveUser(&$resolved, $recipient)
+ {
+ /** @var AuthPlugin $auth */
+ global $auth;
+ $user = $auth->getUserData($recipient);
+ if ($user) $resolved[] = $user['mail'];
+ }
+
+ /**
+ * Checks validity of given mail. With config 'wikionly' set to true
+ * also checks if user with this email is known.
+ *
+ * @param $mail
+ * @return bool
+ * @throws Exception
+ */
+ protected function emailIsValid($mail)
+ {
+ if(!$this->getConf('wikionly')) return mail_isvalid($mail);
+
+ /** @var AuthPlugin $auth */
+ global $auth;
+ if (!$auth->canDo('getUsers')) {
+ throw new \Exception('Auth cannot fetch users by email.');
+ }
+
+ $user = $auth->retrieveUsers(0, 1, ['mail' => $mail]);
+ return (bool)$user;
+ }
+}
diff --git a/lang/de/intro.txt b/lang/de/intro.txt
new file mode 100644
index 0000000..1cbfaca
--- /dev/null
+++ b/lang/de/intro.txt
@@ -0,0 +1,9 @@
+===== Recommend =====
+
+Hier kannst du Standardwerte für Nachrichten hinterlegen.
+
+Seite/Namensraum:
+ * Seiten-ID
+ * Namensräume, mit Ausnahme von untergeordneten Namensräumen, werden als ''namespace:*'' definiert.
+ * Namensräume, einschließlich untergeordneten Namensräumen, werden als ''namespace:**'' definiert.
+ * Reguläre Ausdrücke, welche mit ''/'' beginnen und enden, werden mit einem vorangestellten '':'' mit der kompletten Seiten-ID verglichen
diff --git a/lang/de/lang.php b/lang/de/lang.php
new file mode 100644
index 0000000..a65c44b
--- /dev/null
+++ b/lang/de/lang.php
@@ -0,0 +1,32 @@
+namespace:*''
+ * Namespace including subnamespaces are defined as ''namespace:**''
+ * Regular expressions starting and ending with ''/'' are matched against a '':'' prefixed full page id
diff --git a/lang/en/lang.php b/lang/en/lang.php
new file mode 100644
index 0000000..3096b2f
--- /dev/null
+++ b/lang/en/lang.php
@@ -0,0 +1,32 @@
+path = DOKU_INC . 'data/cache/recommend';
- if (!file_exists($this->path)) {
- mkdir($this->path);
- }
- $this->path .= '/' . $month . '.log';
- }
-
- function getLogs() {
- return array_map('recommend_strip_extension', glob(DOKU_INC . 'data/cache/recommend/*.log'));
- }
-
- function getEntries() {
- return @file($this->path);
- }
-
- function writeEntry($page, $sender, $receiver, $comment) {
- $logfile = fopen($this->path, 'a');
- fwrite($logfile, date('r') . ': ' .
- "“${sender}” recommended “${page}” to " .
- "“${receiver}” with comment “${comment}”.\n");
- fclose($logfile);
- }
-}
-
-function recommend_strip_extension($str) {
- return substr(basename($str), 0, -4);
-}
diff --git a/plugin.info.txt b/plugin.info.txt
index bd8537e..e20443c 100644
--- a/plugin.info.txt
+++ b/plugin.info.txt
@@ -1,7 +1,7 @@
base recommend
-author Adrian Lang
+author Adrian Lang, Andreas Gohr, Anna Dabrowska
email dokuwiki@cosmocode.de
-date 2016-07-06
-name recommend
+date 2022-11-23
+name recommend
desc Allows to recommend a page via email
url http://www.dokuwiki.org/plugin:recommend
diff --git a/script.js b/script.js
index b7e2601..1e44328 100644
--- a/script.js
+++ b/script.js
@@ -1,78 +1,148 @@
-(function () {
+/**
+ * jQuery rewrite is almost completely taken from infomail plugin
+ * @author Andreas Gohr
+ */
-/* Lib */
+const recommend = {
+ $dialog: null,
-var recommend_ajax_call = 'plugin_recommend';
+ /**
+ * Attach click handler to our link
+ */
+ init: function () {
+ jQuery('a.plugin_recommend').click(recommend.initform);
+ jQuery('li.recommend a').click(recommend.initform);
+ },
-function sack_form(form, fnc) {
- var ajax = new sack(DOKU_BASE + 'lib/exe/ajax.php');
- ajax.setVar('call', recommend_ajax_call);
- function serializeByTag(tag) {
- var inps = form.getElementsByTagName(tag);
- for (var inp in inps) {
- if (inps[inp].name) {
- ajax.setVar(inps[inp].name, inps[inp].value);
- }
+ /**
+ * Initializes the form dialog on click
+ *
+ * @param {Event} e
+ */
+ initform: function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+
+ let url = new URL(e.currentTarget.href);
+ // searchParams only works, when no URL rewriting takes place
+ // from Dokuwiki - else there is no parameter id and this
+ // returns null
+ let id = url.searchParams.get('id');
+ if ( id === null ) {
+ // Convert url to string an get the last part without
+ // any parameters from actions and the like
+ url = String(url);
+ id = url.split('/').pop().split('?')[0];
}
- }
- serializeByTag('input');
- serializeByTag('textarea');
- ajax.onCompletion = fnc;
- ajax.runAJAX();
- return false;
-}
-function bind(fnc, val) {
- return function () {
- return fnc(val);
- };
-}
+ recommend.$dialog = jQuery('');
+ recommend.$dialog.dialog(
+ {
+ modal: true,
+ title: LANG.plugins.recommend.formname + ' ' + id,
+ minWidth: 680,
+ height: "auto",
+ close: function () {
+ recommend.$dialog.dialog('destroy')
+ }
+ }
+ );
-function change_form_handler(forms, handler) {
- if (!forms) return;
- for (var formid in forms) {
- var form = forms[formid];
- form.onsubmit = bind(handler, form);
- }
-}
+ jQuery.get(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ 'call': 'recommend',
+ 'id': id
+ },
+ recommend.handleResult,
+ 'html'
+ );
+ },
-/* Recommend */
+ /**
+ * Display the result and attach handlers
+ *
+ * @param {string} data The HTML
+ */
+ handleResult: function (data) {
-function recommend_box(content) {
- var div = $('recommend_box');
- if (!div) {
- div = document.createElement('div');
- div.id = 'recommend_box';
- } else if (content === '') {
- div.parentNode.removeChild(div);
- return;
- }
- div.innerHTML = content;
- document.body.appendChild(div);
- return div;
-}
+ function commasplit( val ) {
+ return val.split( /,\s*/ );
+ }
-function recommend_handle() {
- if (this.response === "AJAX call '" + recommend_ajax_call + "' unknown!\n") {
- /* No user logged in. */
- return;
- }
- if (this.responseStatus[0] === 204) {
- var box = recommend_box('');
- } else {
+ recommend.$dialog.html(data);
+ recommend.$dialog.find('button[type=reset]').click(recommend.cancel);
+ recommend.$dialog.find('button[type=submit]').click(recommend.send);
+ recommend.$dialog.find('input[name=r_email]').autocomplete({
+ source: function (request, cb) {
+ let term = request.term;
+ term = commasplit(term).pop();
- var box = recommend_box(this.response);
- box.getElementsByTagName('label')[0].focus();
- change_form_handler(box.getElementsByTagName('form'),
- function (form) {return sack_form(form, recommend_handle); });
- }
- var inputs = box.getElementsByTagName('input');
- inputs[inputs.length - 1].onclick = function() {recommend_box(''); return false;};
-}
+ const payload = {};
+ payload['call'] = 'plugin_recommend_ac';
+ payload['search'] = term;
+
+ jQuery.post(DOKU_BASE + 'lib/exe/ajax.php', payload, cb, 'json')
+ .fail(function (result) {
+ if (result.responseJSON) {
+ if (result.responseJSON.stacktrace) {
+ console.error(result.responseJSON.error + "\n" + result.responseJSON.stacktrace);
+ }
+ alert(result.responseJSON.error);
+ } else {
+ // some fatal error occurred, get a text only version of the response
+ alert(jQuery(result.responseText).text());
+ }
+ });
+ },
+ focus: function() {
+ // prevent value inserted on focus
+ return false;
+ },
+ select: function( event, ui ) {
+ let terms = commasplit( this.value );
+ // remove the current input
+ terms.pop();
+ // add the selected item
+ terms.push( ui.item.value );
+ // add placeholder to get the comma-and-space at the end
+ terms.push( "" );
+ this.value = terms.join( ", " );
+ return false;
+ }
+ });
+ },
-addInitEvent(function () {
- change_form_handler(getElementsByClass('btn_recommend', document, 'form'),
- function (form) {return sack_form(form, recommend_handle); });
- });
+ /**
+ * Cancel the recommend form
+ *
+ * @param {Event} e
+ */
+ cancel: function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ recommend.$dialog.dialog('destroy');
+ },
-}());
+ /**
+ * Serialize the form and send it
+ *
+ * @param {Event} e
+ */
+ send: function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ let data = recommend.$dialog.find('form').serialize();
+ data = data + '&call=recommend';
+
+ recommend.$dialog.html('...');
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ data,
+ recommend.handleResult,
+ 'html'
+ );
+ }
+};
+jQuery(recommend.init);
diff --git a/style.css b/style.css
index 8305428..5d24abe 100644
--- a/style.css
+++ b/style.css
@@ -11,48 +11,48 @@
background: white;
}
-div.recommend_plugin {
+div.plugin__recommend {
width: 50%;
text-align: center;
font-size: 120%;
padding: 2em;
}
-form#recommend_plugin {
+form#plugin__recommend {
width: 100%;
text-align: center;
}
-form#recommend_plugin p {
+form#plugin__recommend p {
font-size: 90%;
text-align: left;
}
-form#recommend_plugin fieldset {
+form#plugin__recommend fieldset {
width: 90%;
}
-form#recommend_plugin label {
+form#plugin__recommend label {
display: block;
overflow: auto;
margin: 5px;
}
-form#recommend_plugin label span {
- width: 48%;
+form#plugin__recommend label span {
+ width: 28%;
text-align: right;
display: block;
float: left;
}
-form#recommend_plugin label input {
+form#plugin__recommend label input {
float: left;
margin-left: 5px;
}
-form#recommend_plugin label textarea.edit,
-form#recommend_plugin label input.edit {
- width: 48%;
+form#plugin__recommend label textarea.edit,
+form#plugin__recommend label input.edit {
+ width: 68%;
display: block;
float: left;
margin-left: 5px;
diff --git a/template.txt b/template.txt
deleted file mode 100644
index 3d8566d..0000000
--- a/template.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Hi @NAME@,
-
-I would like to recommend you the page “@PAGE@” on @SITE@ (@URL@).
-
-@COMMENT@
-
-Bye,
-
-@AUTHOR@