Merge xorg/maint into xorg/master
[platal.git] / include / notifs.inc.php
1 <?php
2 /***************************************************************************
3 * Copyright (C) 2003-2011 Polytechnique.org *
4 * http://opensource.polytechnique.org/ *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
21
22 abstract class WatchOperation
23 {
24 private static $false = null;
25
26 public function getTitle($count = 0)
27 {
28 if ($count == 1) {
29 return str_replace(array('$x', '$s'), '', $this->title);
30 } else {
31 return str_replace(array('$x', '$s'), array('x', 's'), $this->title);
32 }
33 }
34
35 public function getCondition(Watch $watch)
36 {
37 if (!$watch->user()->watchType($this->flag)) {
38 if (!self::$false) {
39 self::$false = new PFC_False();
40 }
41 return self::$false;
42 } else {
43 return $this->buildCondition($watch);
44 }
45 }
46
47 abstract protected function buildCondition(Watch $watch);
48 abstract public function getOrder();
49 abstract public function getDate(PlUser $user);
50
51 public function publicationDate(PlUser $user)
52 {
53 return $this->getDate($user);
54 }
55
56 public function seen(PlUser $user, $last)
57 {
58 return strtotime($this->getDate($user)) > $last;
59 }
60
61 public function getData(PlUser $user)
62 {
63 return null;
64 }
65 }
66
67 class WatchProfileUpdate extends WatchOperation
68 {
69 private static $order = null;
70
71 public $flag = 'profile';
72 public $title = 'Mise$s à jour de fiche';
73 private $date = null;
74
75 public static function register(Profile $profile, $field)
76 {
77 XDB::execute('INSERT INTO watch_profile (pid, ts, field)
78 VALUES ({?}, NOW(), {?})
79 ON DUPLICATE KEY UPDATE ts = NOW()',
80 $profile->id(), $field);
81 }
82
83 protected function buildCondition(Watch $watch)
84 {
85 $this->date = $watch->date();
86 return new PFC_And(new UFC_ProfileUpdated('>', $watch->date()),
87 $watch->contactCondition());
88 }
89
90 public function getOrder()
91 {
92 if (!self::$order) {
93 self::$order = new UFO_ProfileUpdate();
94 }
95 return self::$order;
96 }
97
98 public function getDate(PlUser $user)
99 {
100 return $user->profile()->last_change;
101 }
102
103 public function getData(PlUser $user)
104 {
105 $data = XDB::fetchColumn("SELECT field
106 FROM watch_profile
107 WHERE pid = {?} AND ts > FROM_UNIXTIME({?}) AND field != ''
108 ORDER BY ts",
109 $user->profile()->id(), $this->date);
110 if (count($data) == 0) {
111 return null;
112 } else {
113 $text = array();
114 foreach ($data as $f) {
115 $text[] = Profile::$descriptions[$f];
116 }
117 return $text;
118 }
119 }
120 }
121
122 class WatchRegistration extends WatchOperation
123 {
124 private static $order = null;
125
126 public $flag = 'registration';
127 public $title = 'Inscription$s';
128
129 protected function buildCondition(Watch $watch)
130 {
131 return new PFC_And(new UFC_Registered(false, '>', $watch->date()),
132 new PFC_Or($watch->contactCondition(),
133 $watch->promoCondition(),
134 $watch->groupCondition()));
135 }
136
137 public function getOrder()
138 {
139 if (!self::$order) {
140 self::$order = new UFO_Registration();
141 }
142 return self::$order;
143 }
144
145 public function getDate(PlUser $user)
146 {
147 return $user->registration_date;
148 }
149 }
150
151 class WatchDeath extends WatchOperation
152 {
153 private static $order = null;
154
155 public $flag = 'death';
156 public $title = 'Décès';
157
158 protected function buildCondition(Watch $watch)
159 {
160 return new PFC_And(new UFC_Dead('>', $watch->date(), true),
161 new PFC_Or($watch->contactCondition(),
162 $watch->promoCondition(),
163 $watch->groupCondition()));
164 }
165
166 public function getOrder()
167 {
168 if (!self::$order) {
169 self::$order = new UFO_Death();
170 }
171 return self::$order;
172 }
173
174 public function getDate(PlUser $user)
175 {
176 return $user->profile()->deathdate;
177 }
178
179 public function publicationDate(PlUser $user)
180 {
181 return $user->profile()->deathdate_rec;
182 }
183
184 public function seen(PlUser $user, $last)
185 {
186 return strtotime($user->profile()->deathdate_rec) > $last;
187 }
188 }
189
190 class WatchBirthday extends WatchOperation
191 {
192 const WATCH_LIMIT = 604800; // 1 week
193
194 private static $order = null;
195
196 public $flag = 'birthday';
197 public $title = 'Anniversaire$s';
198
199 protected function buildCondition(Watch $watch)
200 {
201 $select_date = new PFC_OR(new UFC_Birthday('=', time()),
202 new PFC_And(new UFC_Birthday('<=', time() + self::WATCH_LIMIT),
203 new UFC_Birthday('>', $watch->date() + self::WATCH_LIMIT)));
204 $profile = $watch->profile();
205 $cond = $watch->contactCondition();
206 if ($profile) {
207 $cond = new PFC_Or($cond,
208 new PFC_And($watch->promoCondition(),
209 new UFC_Promo('>=', $profile->mainGrade(), $profile->yearpromo() - 1),
210 new UFC_Promo('<=', $profile->mainGrade(), $profile->yearpromo() + 1)),
211 $watch->groupCondition());
212 }
213 return new PFC_And($select_date, $cond);
214 }
215
216 public function getOrder()
217 {
218 if (!self::$order) {
219 self::$order = new UFO_Birthday();
220 }
221 return self::$order;
222 }
223
224 public function getDate(PlUser $user)
225 {
226 return $user->profile()->next_birthday;
227 }
228
229 public function publicationDate(PlUser $user)
230 {
231 return date('Y-m-d', strtotime($user->profile()->next_birthday) - self::WATCH_LIMIT);
232 }
233
234 public function seen(PlUser $user, $last)
235 {
236 $birthday = strtotime($user->profile()->next_birthday);
237 return $birthday > $last + self::WATCH_LIMIT
238 || date('Ymd', $birthday) == date('Ymd');
239 }
240 }
241
242 class Watch
243 {
244 private static $classes = array('WatchRegistration',
245 'WatchProfileUpdate',
246 'WatchDeath',
247 'WatchBirthday');
248 private static $events = array();
249
250 private $user = null;
251 private $date = null;
252 private $contactCond = null;
253 private $promoCond = null;
254 private $groupCond = null;
255
256 private $filters = array();
257
258 public function __construct(PlUser $user, $date = null)
259 {
260 $this->user = $user;
261 $this->date = self::getDate($user, $date);
262 }
263
264 public function user()
265 {
266 return $this->user;
267 }
268
269 public function profile()
270 {
271 return $this->user->profile();
272 }
273
274 public function date()
275 {
276 return $this->date;
277 }
278
279 public function contactCondition()
280 {
281 if (!$this->contactCond) {
282 $this->contactCond = new UFC_WatchContact($this->user);
283 }
284 return $this->contactCond;
285 }
286
287 public function promoCondition()
288 {
289 if (!$this->promoCond) {
290 $this->promoCond = new UFC_WatchPromo($this->user);
291 }
292 return $this->promoCond;
293 }
294
295 public function groupCondition()
296 {
297 if (!$this->groupCond) {
298 $this->groupCond = new UFC_WatchGroup($this->user);
299 }
300 return $this->groupCond;
301 }
302
303 private function fetchEventWatch($class)
304 {
305 if (!isset(self::$events[$class])) {
306 self::$events[$class] = new $class();
307 }
308 return self::$events[$class];
309 }
310
311 private function fetchFilter($class)
312 {
313
314 if (!isset($this->filters[$class])) {
315 $event = $this->fetchEventWatch($class);
316 $this->filters[$class] = new UserFilter($event->getCondition($this),
317 array($event->getOrder(), new UFO_Name()));
318 }
319 return $this->filters[$class];
320 }
321
322 public function count()
323 {
324 $count = 0;
325 foreach (self::$classes as $class) {
326 $uf = $this->fetchFilter($class);
327 $count += $uf->getTotalCount();
328 }
329 return $count;
330 }
331
332
333 private function fetchEvents($class)
334 {
335 $obj = $this->fetchEventWatch($class);
336 $uf = $this->fetchFilter($class);
337 $users = $uf->getUsers();
338 if (count($users) == 0) {
339 return null;
340 } else {
341 return array('type' => $obj->flag,
342 'operation' => $obj,
343 'title' => $obj->getTitle(count($users)),
344 'users' => $users);
345 }
346 }
347
348 public function events()
349 {
350 $events = array();
351 foreach (self::$classes as $class) {
352 $e = $this->fetchEvents($class);
353 if (!is_null($e)) {
354 $events[] = $e;
355 }
356 }
357 return $events;
358 }
359
360
361 private static function getDate(PlUser $user, $date)
362 {
363 if (is_null($date)) {
364 $date = $user->watchLast();
365 $limit = time() - (7 * 86400);
366 if ($date < $limit) {
367 $date = $limit;
368 }
369 }
370 return $date;
371 }
372
373 public static function getCount(PlUser $user, $date = null)
374 {
375 $watch = new Watch($user, $date);
376 return $watch->count();
377 }
378
379 public static function getEvents(PlUser $user, $date = null)
380 {
381 $watch = new Watch($user, $date);
382 return $watch->events();
383 }
384 }
385
386 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
387 ?>