From: Stéphane Jacob Date: Sat, 2 May 2009 13:13:02 +0000 (+0200) Subject: Initiates reminders. X-Git-Tag: xorg/0.10.1~99 X-Git-Url: http://git.polytechnique.org/?a=commitdiff_plain;h=fb0ee2e864b3a5ffca27b5b6a1cd5c5308c60fe8;p=platal.git Initiates reminders. --- diff --git a/htdocs/xorg.php b/htdocs/xorg.php index ef51214..c177d1c 100644 --- a/htdocs/xorg.php +++ b/htdocs/xorg.php @@ -25,7 +25,7 @@ $platal = new Xorg('auth', 'carnet', 'email', 'events', 'forums', 'geoloc', 'lists', 'marketing', 'payment', 'platal', 'profile', 'register', 'search', 'stats', 'admin', 'newsletter', 'axletter', 'bandeau', 'survey', - 'gadgets', 'googleapps', 'poison', 'openid'); + 'gadgets', 'googleapps', 'poison', 'openid', 'reminder'); if (!($path = Env::v('n')) || ($path{0} < 'A' || $path{0} > 'Z')) { $platal->run(); diff --git a/include/reminder.inc.php b/include/reminder.inc.php new file mode 100644 index 0000000..b689656 --- /dev/null +++ b/include/reminder.inc.php @@ -0,0 +1,192 @@ +user = &$user; + + $this->type_id = $type['type_id']; + $this->name = $type['name']; + $this->weight = $type['weight']; + $this->remind_delay_yes = $type['remind_delay_yes']; + $this->remind_delay_no = $type['remind_delay_no']; + $this->remind_delay_dismiss = $type['remind_delay_dismiss']; + + if (isset($type['status'])) { + $this->current_status = $type['status']; + } + if (isset($type['remind_last'])) { + $this->last_ask = $type['remind_last']; + } + } + + // Updates (or creates) the reminder line for the pair (|user|, |reminder_id|) + // using the |status| as status, and the |next_ask| as the delay between now + // and the next ask (if any). + private function UpdateStatus($status, $next_ask) + { + XDB::execute('REPLACE INTO reminder + SET uid = {?}, type_id = {?}, status = {?}, + remind_last = NOW(), remind_next = FROM_UNIXTIME({?})', + $this->user->id(), $this->type_id, $status, + ($next_ask > 0 ? time() + $next_ask * 24 * 60 * 60 : null)); + } + + // Updates the status of the reminder for the current user. + protected function UpdateOnYes() + { + $this->UpdateStatus('yes', $this->remind_delay_yes); + } + protected function UpdateOnNo() + { + $this->UpdateStatus('no', $this->remind_delay_no); + } + protected function UpdateOnDismiss() + { + $this->UpdateStatus('dismiss', $this->remind_delay_dismiss); + } + + // Display and http handling helpers -------------------------------------- + + // Handles a hit on the reminder onebox (for links made using the GetBaseUrl + // method below). + abstract public function HandleAction($action); + + // Returns the content of the onebox reminder. Default implementation displays + // a text and three links (yes, no, dismiss); it uses the text from method + // GetDisplayText. + public function Display(&$page) + { + header('Content-Type: text/html; charset=utf-8'); + $page->changeTpl('reminder/default.tpl', NO_SKIN); + $page->assign('text', $this->GetDisplayText()); + $page->assign('baseurl', $this->GetBaseUrl()); + } + + // Helper for returning the content as a string, instead of using the existing + // globale XorgPage instance. + public function GetDisplayAsString() + { + $page = new XorgPage(); + $this->Display($page); + return $page->raw(); + } + + // Returns the text to display in the onebox. + abstract protected function GetDisplayText(); + + // Returns the base url for the reminder module. + protected function GetBaseUrl() + { + return 'ajax/reminder/' . $this->name; + } + + // Static factories ------------------------------------------------------- + + // Returns a chosen class using the user data from |user|, and from the database. + public static function GetCandidateReminder(User &$user) + { + $res = XDB::query('SELECT rt.*, r.status, r.remind_last + FROM reminder_type AS rt + LEFT JOIN reminder AS r ON (rt.type_id = r.type_id AND r.uid = {?}) + WHERE r.uid IS NULL OR r.remind_next < NOW() + ORDER BY RAND()', + $user->id()); + + $candidates = $res->fetchAllAssoc(); + $priority = rand(1, 100); + while (count($candidates) > 0 && $priority > 0) { + foreach ($candidates as $key => $candidate) { + if ($candidate['weight'] > $priority) { + $class = self::GetClassName($candidate['name']); + if ($class && call_user_func(array($class, 'IsCandidate'), $user)) { + return new $class($user, $candidate); + } + unset($candidates[$key]); + } + } + $priority = (int) ($priority / 2); + } + + return null; + } + + // Returns an instantiation of the reminder class which name is |name|, using + // user data from |user|, and from the database. + public static function GetByName(User &$user, $name) + { + if (!($class = self::GetClassName($name))) { + return null; + } + + $res = XDB::query('SELECT rt.*, r.status, r.remind_last + FROM reminder_type AS rt + LEFT JOIN reminder AS r ON (rt.type_id = r.type_id AND r.uid = {?}) + WHERE rt.name = {?}', + $user->id(), $name); + if ($res->numRows() > 0) { + return new $class($user, $res->fetchOneAssoc()); + } + + return null; + } + + // Computes the name of the class for reminder named |name|, and preloads + // the class. + private static function GetClassName($name) + { + @require_once "reminder/$name.inc.php"; + $class = 'Reminder' . str_replace(' ', '', ucwords(str_replace('_', ' ', $name))); + return (class_exists($class) ? $class : null); + } +} + + +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: +?> diff --git a/include/reminder/email_warning.inc.php b/include/reminder/email_warning.inc.php new file mode 100644 index 0000000..886ada8 --- /dev/null +++ b/include/reminder/email_warning.inc.php @@ -0,0 +1,23 @@ + diff --git a/modules/events.php b/modules/events.php index 81dddc4..c614dc6 100644 --- a/modules/events.php +++ b/modules/events.php @@ -106,6 +106,12 @@ class EventsModule extends PLModule $page->addJsLink('ajax.js'); $page->assign('tips', $this->get_tips()); + require_once 'reminder.inc.php'; + $user = S::user(); + if (($new_reminder = Reminder::GetCandidateReminder($user))) { + $page->assign('reminder', $new_reminder->GetDisplayAsString()); + } + // Profile update (appears when profile is > 400d old), and birthday // oneboxes. $res = XDB::query( diff --git a/modules/reminder.php b/modules/reminder.php new file mode 100644 index 0000000..d150f58 --- /dev/null +++ b/modules/reminder.php @@ -0,0 +1,56 @@ + $this->make_hook('reminder', AUTH_COOKIE), + ); + } + + function handler_reminder(&$page, $reminder_name = null, $action = null) + { + require_once 'reminder.inc.php'; + $user = S::user(); + + // If no reminder name was passed, or if we don't know that reminder name, + // just drop the request. + if (!$reminder_name || + !($reminder = Reminder::GetByName($user, $reminder_name))) { + return PL_NOT_FOUND; + } + + // Otherwise, the request is dispatched, and a new reminder, if any, is + // displayed. + $reminder->HandleAction($action); + + if ($new_reminder = Reminder::GetCandidateReminder($user)) { + $new_reminder->Display($page); + } else { + exit; + } + } +} + +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: +?> diff --git a/templates/events/index.tpl b/templates/events/index.tpl index 53d6640..03f96dd 100644 --- a/templates/events/index.tpl +++ b/templates/events/index.tpl @@ -41,6 +41,10 @@ Bienvenue {$smarty.session.prenom}{if $birthday} {/if} +{if $reminder} +{$reminder|smarty:nodefaults} +{/if} + {if $smarty.session.no_redirect}