XoopsNotificationHandler::getCount()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 4
nop 1
dl 0
loc 13
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * XOOPS Kernel Class
4
 *
5
 * You may not change or alter any portion of this comment or credits
6
 * of supporting developers from this source code or any supporting source code
7
 * which is considered copyrighted (c) material of the original comment or credit authors.
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
13
 * @license             GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
14
 * @package             kernel
15
 * @since               2.0.0
16
 * @author              Michael van Dam <[email protected]>
17
 * @author              Kazumi Ono (AKA onokazu) http://www.myweb.ne.jp/, http://jp.xoops.org/
18
 */
19
defined('XOOPS_ROOT_PATH') || exit('Restricted access');
20
21
// RMV-NOTIFY
22
include_once $GLOBALS['xoops']->path('include/notification_constants.php');
23
include_once $GLOBALS['xoops']->path('include/notification_functions.php');
24
25
/**
26
 * A Notification
27
 *
28
 * @package             kernel
29
 * @subpackage          notification
30
 *
31
 * @author              Michael van Dam    <[email protected]>
32
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
33
 */
34
class XoopsNotification extends XoopsObject
35
{
36
    //PHP 8.2 Dynamic properties deprecated
37
    public $not_id;
38
    public $not_modid;
39
    public $not_category;
40
    public $not_itemid;
41
    public $not_event;
42
    public $not_uid;
43
    public $not_mode;
44
45
    /**
46
     * Constructor
47
     **/
48
    public function __construct()
49
    {
50
        parent::__construct();
51
        $this->initVar('not_id', XOBJ_DTYPE_INT, null, false);
52
        $this->initVar('not_modid', XOBJ_DTYPE_INT, null, false);
53
        $this->initVar('not_category', XOBJ_DTYPE_TXTBOX, null, false, 30);
54
        $this->initVar('not_itemid', XOBJ_DTYPE_INT, 0, false);
55
        $this->initVar('not_event', XOBJ_DTYPE_TXTBOX, null, false, 30);
56
        $this->initVar('not_uid', XOBJ_DTYPE_INT, 0, true);
57
        $this->initVar('not_mode', XOBJ_DTYPE_INT, 0, false);
58
    }
59
60
    // FIXME:???
61
    // To send email to multiple users simultaneously, we would need to move
62
    // the notify functionality to the handler class.  BUT, some of the tags
63
    // are user-dependent, so every email msg will be unique.  (Unless maybe use
64
    // smarty for email templates in the future.)  Also we would have to keep
65
    // track if each user wanted email or PM.
66
67
    /**
68
     * Returns Class Base Variable not_id
69
     * @param  string $format
70
     * @return mixed
71
     */
72
    public function id($format = 'N')
73
    {
74
        return $this->getVar('not_id', $format);
75
    }
76
77
    /**
78
     * Returns Class Base Variable not_id
79
     * @param  string $format
80
     * @return mixed
81
     */
82
    public function not_id($format = '')
83
    {
84
        return $this->getVar('not_id', $format);
85
    }
86
87
    /**
88
     * Returns Class Base Variable not_modid
89
     * @param  string $format
90
     * @return mixed
91
     */
92
    public function not_modid($format = '')
93
    {
94
        return $this->getVar('not_modid', $format);
95
    }
96
97
    /**
98
     * Returns Class Base Variable mid
99
     * @param  string $format
100
     * @return mixed
101
     */
102
    public function not_category($format = '')
103
    {
104
        return $this->getVar('not_category', $format);
105
    }
106
107
    /**
108
     * Returns Class Base Variable not_itemid
109
     * @param  string $format
110
     * @return mixed
111
     */
112
    public function not_itemid($format = '')
113
    {
114
        return $this->getVar('not_itemid', $format);
115
    }
116
117
    /**
118
     * Returns Class Base Variable not_event
119
     * @param  string $format
120
     * @return mixed
121
     */
122
    public function not_event($format = '')
123
    {
124
        return $this->getVar('not_event', $format);
125
    }
126
127
    /**
128
     * Returns Class Base Variable not_uid
129
     * @param  string $format
130
     * @return mixed
131
     */
132
    public function not_uid($format = '')
133
    {
134
        return $this->getVar('not_uid', $format);
135
    }
136
137
    /**
138
     * Returns Class Base Variable not_mode
139
     * @param  string $format
140
     * @return mixed
141
     */
142
    public function not_mode($format = '')
143
    {
144
        return $this->getVar('not_mode', $format);
145
    }
146
147
    /**
148
     * Send a notification message to the user
149
     *
150
     * @param string $template_dir Template directory
151
     * @param string $template     Template name
152
     * @param string $subject      Subject line for notification message
153
     * @param array  $tags         Array of substitutions for template variables
154
     *
155
     * @return bool true if success, false if error
156
     **/
157
    public function notifyUser($template_dir, $template, $subject, $tags)
158
    {
159
        // Check the user's notification preference.
160
        /** @var XoopsMemberHandler $member_handler */
161
        $member_handler = xoops_getHandler('member');
162
        $user           = $member_handler->getUser($this->getVar('not_uid'));
163
        if (!is_object($user) || !$user->isActive()) {
164
            return true;
165
        }
166
167
        $method = $user->getVar('notify_method');
168
169
        $xoopsMailer = xoops_getMailer();
170
        include_once $GLOBALS['xoops']->path('include/notification_constants.php');
171
        switch ($method) {
172
            case XOOPS_NOTIFICATION_METHOD_PM:
173
                $xoopsMailer->usePM();
174
                /** @var XoopsConfigHandler $config_handler */
175
                $config_handler    = xoops_getHandler('config');
176
                $xoopsMailerConfig = $config_handler->getConfigsByCat(XOOPS_CONF_MAILER);
177
                $xoopsMailer->setFromUser($member_handler->getUser($xoopsMailerConfig['fromuid']));
178
                foreach ($tags as $k => $v) {
179
                    $xoopsMailer->assign($k, $v);
180
                }
181
                break;
182
            case XOOPS_NOTIFICATION_METHOD_EMAIL:
183
                $xoopsMailer->useMail();
184
                foreach ($tags as $k => $v) {
185
                    $xoopsMailer->assign($k, preg_replace('/&amp;/i', '&', $v));
186
                }
187
                break;
188
            default:
189
                return true; // report error in user's profile??
190
//                break;
191
        }
192
193
        // Set up the mailer
194
        $xoopsMailer->setTemplateDir($template_dir);
195
        $xoopsMailer->setTemplate($template);
196
        $xoopsMailer->setToUsers($user);
197
        //global $xoopsConfig;
198
        //$xoopsMailer->setFromEmail($xoopsConfig['adminmail']);
199
        //$xoopsMailer->setFromName($xoopsConfig['sitename']);
200
        $xoopsMailer->setSubject($subject);
201
        $success = $xoopsMailer->send();
202
203
        // If send-once-then-delete, delete notification
204
        // If send-once-then-wait, disable notification
205
        include_once $GLOBALS['xoops']->path('include/notification_constants.php');
206
        $notification_handler = xoops_getHandler('notification');
207
208
        if ($this->getVar('not_mode') == XOOPS_NOTIFICATION_MODE_SENDONCETHENDELETE) {
209
            $notification_handler->delete($this);
210
211
            return $success;
212
        }
213
214
        if ($this->getVar('not_mode') == XOOPS_NOTIFICATION_MODE_SENDONCETHENWAIT) {
215
            $this->setVar('not_mode', XOOPS_NOTIFICATION_MODE_WAITFORLOGIN);
216
            $notification_handler->insert($this);
217
        }
218
219
        return $success;
220
    }
221
}
222
223
/**
224
 * XOOPS notification handler class.
225
 *
226
 * This class is responsible for providing data access mechanisms to the data source
227
 * of XOOPS notification class objects.
228
 *
229
 *
230
 * @package             kernel
231
 * @subpackage          notification
232
 *
233
 * @author              Michael van Dam <[email protected]>
234
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
235
 */
236
class XoopsNotificationHandler extends XoopsObjectHandler
237
{
238
    /**
239
     * Create a {@link XoopsNotification}
240
     *
241
     * @param bool $isNew Flag the object as "new"?
242
     *
243
     * @return XoopsNotification
244
     */
245
    public function create($isNew = true)
246
    {
247
        $notification = new XoopsNotification();
248
        if ($isNew) {
249
            $notification->setNew();
250
        }
251
252
        return $notification;
253
    }
254
255
    /**
256
     * Retrieve a {@link XoopsNotification}
257
     *
258
     * @param int $id ID
259
     *
260
     * @return XoopsNotification|false {@link XoopsNotification}, false on fail
261
     **/
262
    public function get($id)
263
    {
264
        $notification = false;
265
        $id           = (int)$id;
266
        if ($id > 0) {
267
            $sql = 'SELECT * FROM ' . $this->db->prefix('xoopsnotifications') . ' WHERE not_id=' . $id;
268
            $result = $this->db->query($sql);
0 ignored issues
show
Bug introduced by
The method query() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

268
            /** @scrutinizer ignore-call */ 
269
            $result = $this->db->query($sql);
Loading history...
269
            if (!$this->db->isResultSet($result)) {
270
                return $notification;
271
            }
272
            $numrows = $this->db->getRowsNum($result);
0 ignored issues
show
Bug introduced by
The method getRowsNum() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

272
            /** @scrutinizer ignore-call */ 
273
            $numrows = $this->db->getRowsNum($result);
Loading history...
273
            if ($numrows == 1) {
274
                $notification = new XoopsNotification();
275
                $notification->assignVars($this->db->fetchArray($result));
0 ignored issues
show
Bug introduced by
The method fetchArray() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

275
                $notification->assignVars($this->db->/** @scrutinizer ignore-call */ fetchArray($result));
Loading history...
276
            }
277
        }
278
279
        return $notification;
280
    }
281
282
    /**
283
     * Write a notification(subscription) to database
284
     *
285
     * @param  XoopsObject|XoopsNotification $notification a XoopsNotification object
286
     *
287
     * @return bool true on success, otherwise false
288
     **/
289
    public function insert(XoopsObject $notification)
290
    {
291
        $className = 'XoopsNotification';
292
        if (!($notification instanceof $className)) {
293
            return false;
294
        }
295
        if (!$notification->isDirty()) {
296
            return true;
297
        }
298
        if (!$notification->cleanVars()) {
299
            return false;
300
        }
301
        foreach ($notification->cleanVars as $k => $v) {
302
            ${$k} = $v;
303
        }
304
        if ($notification->isNew()) {
305
            $not_id = $this->db->genId('xoopsnotifications_not_id_seq');
0 ignored issues
show
Bug introduced by
The method genId() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

305
            /** @scrutinizer ignore-call */ 
306
            $not_id = $this->db->genId('xoopsnotifications_not_id_seq');
Loading history...
306
            $sql    = sprintf('INSERT INTO %s (not_id, not_modid, not_itemid, not_category, not_uid, not_event, not_mode) VALUES (%u, %u, %u, %s, %u, %s, %u)', $this->db->prefix('xoopsnotifications'), $not_id, $not_modid, $not_itemid, $this->db->quoteString($not_category), $not_uid, $this->db->quoteString($not_event), $not_mode);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $not_modid seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $not_mode seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $not_event seems to be never defined.
Loading history...
Bug introduced by
The method quoteString() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

306
            $sql    = sprintf('INSERT INTO %s (not_id, not_modid, not_itemid, not_category, not_uid, not_event, not_mode) VALUES (%u, %u, %u, %s, %u, %s, %u)', $this->db->prefix('xoopsnotifications'), $not_id, $not_modid, $not_itemid, $this->db->/** @scrutinizer ignore-call */ quoteString($not_category), $not_uid, $this->db->quoteString($not_event), $not_mode);
Loading history...
Comprehensibility Best Practice introduced by
The variable $not_itemid does not exist. Did you maybe mean $not_id?
Loading history...
Comprehensibility Best Practice introduced by
The variable $not_uid does not exist. Did you maybe mean $not_id?
Loading history...
Comprehensibility Best Practice introduced by
The variable $not_category seems to be never defined.
Loading history...
307
        } else {
308
            $sql = sprintf('UPDATE %s SET not_modid = %u, not_itemid = %u, not_category = %s, not_uid = %u, not_event = %s, not_mode = %u WHERE not_id = %u', $this->db->prefix('xoopsnotifications'), $not_modid, $not_itemid, $this->db->quoteString($not_category), $not_uid, $this->db->quoteString($not_event), $not_mode, $not_id);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $not_id seems to be never defined.
Loading history...
309
        }
310
        if (!$result = $this->db->query($sql)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
311
            return false;
312
        }
313
        if (empty($not_id)) {
314
            $not_id = $this->db->getInsertId();
0 ignored issues
show
Bug introduced by
The method getInsertId() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

314
            /** @scrutinizer ignore-call */ 
315
            $not_id = $this->db->getInsertId();
Loading history...
315
        }
316
        $notification->assignVar('not_id', $not_id);
317
318
        return true;
319
    }
320
321
    /**
322
     * Delete a {@link XoopsNotification} from the database
323
     *
324
     * @param  XoopsObject|XoopsNotification $notification a XoopsNotification object
325
     *
326
     * @return bool true on success, otherwise false
327
     **/
328
    public function delete(XoopsObject $notification)
329
    {
330
        $className = 'XoopsNotification';
331
        if (!($notification instanceof $className)) {
332
            return false;
333
        }
334
335
        $sql = sprintf('DELETE FROM %s WHERE not_id = %u', $this->db->prefix('xoopsnotifications'), $notification->getVar('not_id'));
0 ignored issues
show
Bug introduced by
It seems like $notification->getVar('not_id') can also be of type array and array; however, parameter $values of sprintf() does only seem to accept double|integer|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

335
        $sql = sprintf('DELETE FROM %s WHERE not_id = %u', $this->db->prefix('xoopsnotifications'), /** @scrutinizer ignore-type */ $notification->getVar('not_id'));
Loading history...
336
        if (!$result = $this->db->query($sql)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
337
            return false;
338
        }
339
340
        return true;
341
    }
342
343
    /**
344
     * Get some {@link XoopsNotification}s
345
     *
346
     * @param CriteriaElement|CriteriaCompo $criteria
347
     * @param bool            $id_as_key Use IDs as keys into the array?
348
     *
349
     * @return array Array of {@link XoopsNotification} objects
350
     **/
351
    public function getObjects(CriteriaElement $criteria = null, $id_as_key = false)
352
    {
353
        $ret   = array();
354
        $limit = $start = 0;
355
        $sql   = 'SELECT * FROM ' . $this->db->prefix('xoopsnotifications');
356
        if (isset($criteria) && \method_exists($criteria, 'renderWhere')) {
357
            $sql .= ' ' . $criteria->renderWhere();
358
            $sort = ($criteria->getSort() != '') ? $criteria->getSort() : 'not_id';
359
            $sql .= ' ORDER BY ' . $sort . ' ' . $criteria->getOrder();
360
            $limit = $criteria->getLimit();
361
            $start = $criteria->getStart();
362
        }
363
        $result = $this->db->query($sql, $limit, $start);
364
        if (!$this->db->isResultSet($result)) {
365
            return $ret;
366
        }
367
        /** @var array $myrow */
368
        while (false !== ($myrow = $this->db->fetchArray($result))) {
369
            $notification = new XoopsNotification();
370
            $notification->assignVars($myrow);
371
            if (!$id_as_key) {
372
                $ret[] = $notification;
373
            } else {
374
                $ret[$myrow['not_id']] = $notification;
375
            }
376
            unset($notification);
377
        }
378
379
        return $ret;
380
    }
381
382
    // TODO: Need this??
383
    /**
384
     * Count Notifications
385
     *
386
     * @param CriteriaElement|CriteriaCompo $criteria {@link CriteriaElement}
387
     *
388
     * @return int Count
389
     **/
390
    public function getCount(CriteriaElement $criteria = null)
391
    {
392
        $sql = 'SELECT COUNT(*) FROM ' . $this->db->prefix('xoopsnotifications');
393
        if (isset($criteria) && \method_exists($criteria, 'renderWhere')) {
394
            $sql .= ' ' . $criteria->renderWhere();
395
        }
396
        $result = $this->db->query($sql);
397
        if (!$this->db->isResultSet($result)) {
398
            return 0;
399
        }
400
        list($count) = $this->db->fetchRow($result);
0 ignored issues
show
Bug introduced by
The method fetchRow() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

400
        /** @scrutinizer ignore-call */ 
401
        list($count) = $this->db->fetchRow($result);
Loading history...
401
402
        return (int)$count;
403
    }
404
405
    /**
406
     * Delete multiple notifications
407
     *
408
     * @param CriteriaElement|CriteriaCompo $criteria {@link CriteriaElement}
409
     *
410
     * @return bool
411
     **/
412
    public function deleteAll(CriteriaElement $criteria = null)
413
    {
414
        $sql = 'DELETE FROM ' . $this->db->prefix('xoopsnotifications');
415
        if (isset($criteria) && \method_exists($criteria, 'renderWhere')) {
416
            $sql .= ' ' . $criteria->renderWhere();
417
        }
418
        if (!$result = $this->db->query($sql)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
419
            return false;
420
        }
421
422
        return true;
423
    }
424
425
    // TODO: rename this...
426
    // Also, should we have get by module, get by category, etc...??
427
    /**
428
     * @param $module_id
429
     * @param $category
430
     * @param $item_id
431
     * @param $event
432
     * @param $user_id
433
     *
434
     * @return bool
435
     */
436
    public function &getNotification($module_id, $category, $item_id, $event, $user_id)
437
    {
438
        $criteria = new CriteriaCompo();
439
        $criteria->add(new Criteria('not_modid', (int)$module_id));
440
        $criteria->add(new Criteria('not_category', $this->db->escape($category)));
0 ignored issues
show
Bug introduced by
The method escape() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

440
        $criteria->add(new Criteria('not_category', $this->db->/** @scrutinizer ignore-call */ escape($category)));
Loading history...
441
        $criteria->add(new Criteria('not_itemid', (int)$item_id));
442
        $criteria->add(new Criteria('not_event', $this->db->escape($event)));
443
        $criteria->add(new Criteria('not_uid', (int)$user_id));
444
        $objects = $this->getObjects($criteria);
445
        if (count($objects) == 1) {
446
            return $objects[0];
447
        }
448
        $inst = false;
449
450
        return $inst;
451
    }
452
453
    /**
454
     * Determine if a user is subscribed to a particular event in
455
     * a particular module.
456
     *
457
     * @param string $category  Category of notification event
458
     * @param int    $item_id   Item ID of notification event
459
     * @param string $event     Event
460
     * @param int    $module_id ID of module (default current module)
461
     * @param int    $user_id   ID of user (default current user)
462
     *                          return int  0 if not subscribe; non-zero if subscribed
463
     *
464
     * @return int
465
     */
466
    public function isSubscribed($category, $item_id, $event, $module_id, $user_id)
467
    {
468
        $criteria = new CriteriaCompo();
469
        $criteria->add(new Criteria('not_modid', (int)$module_id));
470
        $criteria->add(new Criteria('not_category', $this->db->escape($category)));
471
        $criteria->add(new Criteria('not_itemid', (int)$item_id));
472
        $criteria->add(new Criteria('not_event', $this->db->escape($event)));
473
        $criteria->add(new Criteria('not_uid', (int)$user_id));
474
475
        return $this->getCount($criteria);
476
    }
477
478
    // TODO: how about a function to subscribe a whole group of users???
479
    // e.g. if we want to add all moderators to be notified of subscription
480
    // of new threads...
481
    /**
482
     * Subscribe for notification for an event(s)
483
     *
484
     * @param string $category  category of notification
485
     * @param int    $item_id   ID of the item
486
     * @param mixed  $events    event string or array of events
487
     * @param int    $mode      force a particular notification mode
488
     *                          (e.g. once_only) (default to current user preference)
489
     * @param int    $module_id ID of the module (default to current module)
490
     * @param int    $user_id   ID of the user (default to current user)
491
     *                          *
492
     *
493
     * @return bool
494
     */
495
    public function subscribe($category, $item_id, $events, $mode = null, $module_id = null, $user_id = null)
496
    {
497
        if (!isset($user_id)) {
498
            global $xoopsUser;
499
            if (empty($xoopsUser)) {
500
                return false; // anonymous cannot subscribe
501
            } else {
502
                $user_id = $xoopsUser->getVar('uid');
503
            }
504
        }
505
506
        if (!isset($module_id)) {
507
            global $xoopsModule;
508
            $module_id = $xoopsModule->getVar('mid');
509
        }
510
511
        if (!isset($mode)) {
512
            $user = new XoopsUser($user_id);
513
            $mode = $user->getVar('notify_mode');
514
        }
515
516
        if (!is_array($events)) {
517
            $events = array($events);
518
        }
519
        foreach ($events as $event) {
520
            /** @var  XoopsNotification $notification */
521
            if ($notification = $this->getNotification($module_id, $category, $item_id, $event, $user_id)) {
522
                if ($notification->getVar('not_mode') != $mode) {
523
                    $this->updateByField($notification, 'not_mode', $mode);
524
                }
525
            } else {
526
                $notification = $this->create();
527
                $notification->setVar('not_modid', $module_id);
528
                $notification->setVar('not_category', $category);
529
                $notification->setVar('not_itemid', $item_id);
530
                $notification->setVar('not_uid', $user_id);
531
                $notification->setVar('not_event', $event);
532
                $notification->setVar('not_mode', $mode);
533
                $this->insert($notification);
534
            }
535
        }
536
        return true;
537
    }
538
539
    // TODO: this will be to provide a list of everything a particular
540
    // user has subscribed to... e.g. for on the 'Profile' page, similar
541
    // to how we see the various posts etc. that the user has made.
542
    // We may also want to have a function where we can specify module id
543
    /**
544
     * Get a list of notifications by user ID
545
     *
546
     * @param int $user_id ID of the user
547
     *
548
     * @return array Array of {@link XoopsNotification} objects
549
     **/
550
    public function getByUser($user_id)
551
    {
552
        $criteria = new Criteria('not_uid', $user_id);
553
554
        return $this->getObjects($criteria, true);
555
    }
556
557
    // TODO: rename this??
558
    /**
559
     * Get a list of notification events for the current item/mod/user
560
     *
561
     * @param $category
562
     * @param $item_id
563
     * @param $module_id
564
     * @param $user_id
565
     * @return array
566
     */
567
    public function getSubscribedEvents($category, $item_id, $module_id, $user_id)
568
    {
569
        $criteria = new CriteriaCompo();
570
        $criteria->add(new Criteria('not_modid', (int)$module_id));
571
        $criteria->add(new Criteria('not_category', $this->db->escape($category)));
572
        if ($item_id) {
573
            $criteria->add(new Criteria('not_itemid', (int)$item_id));
574
        }
575
        $criteria->add(new Criteria('not_uid', (int)$user_id));
576
        $results = $this->getObjects($criteria, true);
577
        $ret     = array();
578
        foreach (array_keys($results) as $i) {
579
            $ret[] = $results[$i]->getVar('not_event');
580
        }
581
582
        return $ret;
583
    }
584
585
    // TODO: is this a useful function?? (Copied from comment_handler)
586
    /**
587
     * Retrieve items by their ID
588
     *
589
     * @param int    $module_id Module ID
590
     * @param int    $item_id   Item ID
591
     * @param string $order     Sort order
592
     * @param int    $mode      not_mode    see include/notification_constants.php
593
     *
594
     * @param null   $status
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $status is correct as it would always require null to be passed?
Loading history...
595
     *
596
     * @return array Array of {@link XoopsNotification} objects
597
     */
598
    public function getByItemId($module_id, $item_id, $order = null, $mode = null)
599
    {
600
        $criteria = new CriteriaCompo(new Criteria('not_modid', (int)$module_id));
601
        $criteria->add(new Criteria('not_itemid', (int)$item_id));
602
        if (isset($mode)) {
603
            $criteria->add(new Criteria('not_mode', (int)$mode));
604
        }
605
        if (isset($order)) {
606
            $criteria->setOrder($order);
607
        }
608
609
        return $this->getObjects($criteria);
610
    }
611
612
    /**
613
     * Send notifications to users
614
     *
615
     * @param string $category     notification category
616
     * @param int    $item_id      ID of the item
617
     * @param array  $events       trigger events
618
     * @param array  $extra_tags   array of substitutions for template to be
619
     *                              merged with the one from function.
620
     * @param array  $user_list    only notify the selected users
621
     * @param int    $module_id    ID of the module
622
     * @param int    $omit_user_id ID of the user to omit from notifications. (default to current user).  set to 0 for all users to receive notification.
623
     * @internal param string $event notification event
624
     */
625
    // TODO:(?) - pass in an event LIST.  This will help to avoid
626
    // problem of sending people multiple emails for similar events.
627
    // BUT, then we need an array of mail templates, etc...  Unless
628
    // mail templates can include logic in the future, then we can
629
    // tailor the mail so it makes sense for any of the possible
630
    // (or combination of) events.
631
    public function triggerEvents($category, $item_id, $events, $extra_tags = array(), $user_list = array(), $module_id = null, $omit_user_id = null)
632
    {
633
        if (!is_array($events)) {
0 ignored issues
show
introduced by
The condition is_array($events) is always true.
Loading history...
634
            $events = array($events);
635
        }
636
        foreach ($events as $event) {
637
            $this->triggerEvent($category, $item_id, $event, $extra_tags, $user_list, $module_id, $omit_user_id);
638
        }
639
    }
640
641
    /**
642
     * Trigger a single notification event
643
     *
644
     * @param  string $category
645
     * @param  int    $item_id
646
     * @param  string $event
647
     * @param  array  $extra_tags
648
     * @param  array  $user_list
649
     * @param  int    $module_id
650
     * @param  int    $omit_user_id
651
     * @return mixed
652
     */
653
    public function triggerEvent($category, $item_id, $event, $extra_tags = array(), $user_list = array(), $module_id = null, $omit_user_id = null)
654
    {
655
        if (!isset($module_id)) {
656
            global $xoopsModule;
657
            $module    = $xoopsModule;
658
            $module_id = !empty($xoopsModule) ? $xoopsModule->getVar('mid') : 0;
659
        } else {
660
            /** @var XoopsModuleHandler $module_handler */
661
            $module_handler = xoops_getHandler('module');
662
            $module         = $module_handler->get($module_id);
663
        }
664
665
        // Check if event is enabled
666
        /** @var XoopsConfigHandler $config_handler */
667
        $config_handler = xoops_getHandler('config');
668
        $mod_config     = $config_handler->getConfigsByCat(0, $module->getVar('mid'));
669
        if (empty($mod_config['notification_enabled'])) {
670
            return false;
671
        }
672
        $category_info =& notificationCategoryInfo($category, $module_id);
673
        $event_info    =& notificationEventInfo($category, $event, $module_id);
674
        if (!in_array(notificationGenerateConfig($category_info, $event_info, 'option_name'), $mod_config['notification_events']) && empty($event_info['invisible'])) {
0 ignored issues
show
Bug introduced by
It seems like $category_info can also be of type false; however, parameter $category of notificationGenerateConfig() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

674
        if (!in_array(notificationGenerateConfig(/** @scrutinizer ignore-type */ $category_info, $event_info, 'option_name'), $mod_config['notification_events']) && empty($event_info['invisible'])) {
Loading history...
Bug introduced by
It seems like $event_info can also be of type false; however, parameter $event of notificationGenerateConfig() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

674
        if (!in_array(notificationGenerateConfig($category_info, /** @scrutinizer ignore-type */ $event_info, 'option_name'), $mod_config['notification_events']) && empty($event_info['invisible'])) {
Loading history...
675
            return false;
676
        }
677
678
        if (!isset($omit_user_id)) {
679
            global $xoopsUser;
680
            $omit_user_id = 0;
681
            if (!empty($xoopsUser)) {
682
                $omit_user_id = $xoopsUser->getVar('uid');
683
            }
684
        }
685
        $criteria = new CriteriaCompo();
686
        $criteria->add(new Criteria('not_modid', (int)$module_id));
687
        $criteria->add(new Criteria('not_category', $this->db->escape($category)));
688
        $criteria->add(new Criteria('not_itemid', (int)$item_id));
689
        $criteria->add(new Criteria('not_event', $this->db->escape($event)));
690
        $mode_criteria = new CriteriaCompo();
691
        $mode_criteria->add(new Criteria('not_mode', XOOPS_NOTIFICATION_MODE_SENDALWAYS), 'OR');
692
        $mode_criteria->add(new Criteria('not_mode', XOOPS_NOTIFICATION_MODE_SENDONCETHENDELETE), 'OR');
693
        $mode_criteria->add(new Criteria('not_mode', XOOPS_NOTIFICATION_MODE_SENDONCETHENWAIT), 'OR');
694
        $criteria->add($mode_criteria);
695
        if (!empty($user_list)) {
696
            $user_criteria = new CriteriaCompo();
697
            foreach ($user_list as $user) {
698
                $user_criteria->add(new Criteria('not_uid', (int)$user), 'OR');
699
            }
700
            $criteria->add($user_criteria);
701
        }
702
        $notifications = $this->getObjects($criteria);
703
        if (empty($notifications)) {
704
            return null;
705
        }
706
707
        // Add some tag substitutions here
708
709
        $not_config = $module->getInfo('notification');
710
        $tags       = array();
711
        if (!empty($not_config)) {
712
            if (!empty($not_config['tags_file'])) {
713
                $tags_file = $GLOBALS['xoops']->path('modules/' . $module->getVar('dirname') . '/' . $not_config['tags_file']);
714
                if (file_exists($tags_file)) {
715
                    include_once $tags_file;
716
                    if (!empty($not_config['tags_func'])) {
717
                        $tags_func = $not_config['tags_func'];
718
                        if (function_exists($tags_func)) {
719
                            $tags = $tags_func($category, (int)$item_id, $event);
720
                        }
721
                    }
722
                }
723
            }
724
            // RMV-NEW
725
            if (!empty($not_config['lookup_file'])) {
726
                $lookup_file = $GLOBALS['xoops']->path('modules/' . $module->getVar('dirname') . '/' . $not_config['lookup_file']);
727
                if (file_exists($lookup_file)) {
728
                    include_once $lookup_file;
729
                    if (!empty($not_config['lookup_func'])) {
730
                        $lookup_func = $not_config['lookup_func'];
731
                        if (function_exists($lookup_func)) {
732
                            $item_info = $lookup_func($category, (int)$item_id);
733
                        }
734
                    }
735
                }
736
            }
737
        }
738
739
        $tags['X_ITEM_NAME']       = !empty($item_info['name']) ? $item_info['name'] : '[' . _NOT_ITEMNAMENOTAVAILABLE . ']';
740
        $tags['X_ITEM_URL']        = !empty($item_info['url']) ? $item_info['url'] : '[' . _NOT_ITEMURLNOTAVAILABLE . ']';
741
        $tags['X_ITEM_TYPE']       = !empty($category_info['item_name']) ? $category_info['title'] : '[' . _NOT_ITEMTYPENOTAVAILABLE . ']';
742
        $tags['X_MODULE']          = $module->getVar('name');
743
        $tags['X_MODULE_URL']      = XOOPS_URL . '/modules/' . $module->getVar('dirname') . '/';
744
        $tags['X_NOTIFY_CATEGORY'] = $category;
745
        $tags['X_NOTIFY_EVENT']    = $event;
746
        $tags['X_UNSUBSCRIBE_URL'] = XOOPS_URL . '/notifications.php';
747
748
        $template_dir = $event_info['mail_template_dir'];
749
        $template     = $event_info['mail_template'] . '.tpl';
750
        $subject      = $event_info['mail_subject'];
751
752
        // Pre-merge any extra tags if they are common to all notifications
753
        if (!empty($extra_tags)) {
754
            $tags = array_merge($tags, $extra_tags);
755
        }
756
757
        foreach ($notifications as $notification) {
758
            if (empty($omit_user_id) || $notification->getVar('not_uid') != $omit_user_id) {
759
760
                // Add user-specific tags
761
                //$tags['X_UNSUBSCRIBE_URL'] = 'TODO';
762
                // TODO: don't show unsubscribe link if it is 'one-time' ??
763
764
                // Notify the user with the merged tags
765
                $notification->notifyUser($template_dir, $template, $subject, $tags);
766
            }
767
        }
768
769
        return null;
770
    }
771
772
    /**
773
     * Delete all notifications for one user
774
     *
775
     * @param  int $user_id ID of the user
776
     * @return bool
777
     **/
778
    public function unsubscribeByUser($user_id)
779
    {
780
        $criteria = new Criteria('not_uid', (int)$user_id);
781
782
        return $this->deleteAll($criteria);
783
    }
784
785
    // TODO: allow these to use current module, etc...
786
    /**
787
     * Unsubscribe notifications for an event(s).
788
     *
789
     * @param string $category  category of the events
790
     * @param int    $item_id   ID of the item
791
     * @param mixed  $events    event string or array of events
792
     * @param int    $module_id ID of the module (default current module)
793
     * @param int    $user_id   UID of the user (default current user)
794
     *
795
     * @return bool
796
     **/
797
    public function unsubscribe($category, $item_id, $events, $module_id = null, $user_id = null)
798
    {
799
        if (!isset($user_id)) {
800
            global $xoopsUser;
801
            if (empty($xoopsUser)) {
802
                return false; // anonymous cannot subscribe
803
            } else {
804
                $user_id = $xoopsUser->getVar('uid');
805
            }
806
        }
807
        if (!isset($module_id)) {
808
            global $xoopsModule;
809
            $module_id = $xoopsModule->getVar('mid');
810
        }
811
        $criteria = new CriteriaCompo();
812
        $criteria->add(new Criteria('not_modid', (int)$module_id));
813
        $criteria->add(new Criteria('not_category', $this->db->escape($category)));
814
        $criteria->add(new Criteria('not_itemid', (int)$item_id));
815
        $criteria->add(new Criteria('not_uid', (int)$user_id));
816
        if (!is_array($events)) {
817
            $events = array($events);
818
        }
819
        $event_criteria = new CriteriaCompo();
820
        foreach ($events as $event) {
821
            $event_criteria->add(new Criteria('not_event', $this->db->escape($event)), 'OR');
822
        }
823
        $criteria->add($event_criteria);
824
825
        return $this->deleteAll($criteria);
826
    }
827
828
    // TODO: When 'update' a module, may need to switch around some
829
    //  notification classes/IDs...  or delete the ones that no longer
830
    //  exist.
831
    /**
832
     * Delete all notifications for a particular module
833
     *
834
     * @param  int $module_id ID of the module
835
     * @return bool
836
     **/
837
    public function unsubscribeByModule($module_id)
838
    {
839
        $criteria = new Criteria('not_modid', (int)$module_id);
840
841
        return $this->deleteAll($criteria);
842
    }
843
844
    /**
845
     * Delete all subscriptions for a particular item.
846
     *
847
     * @param int    $module_id ID of the module to which item belongs
848
     * @param string $category  Notification category of the item
849
     * @param int    $item_id   ID of the item
850
     *
851
     * @return bool
852
     **/
853
    public function unsubscribeByItem($module_id, $category, $item_id)
854
    {
855
        $criteria = new CriteriaCompo();
856
        $criteria->add(new Criteria('not_modid', (int)$module_id));
857
        $criteria->add(new Criteria('not_category', $this->db->escape($category)));
858
        $criteria->add(new Criteria('not_itemid', (int)$item_id));
859
860
        return $this->deleteAll($criteria);
861
    }
862
863
    /**
864
     * Perform notification maintenance activites at login time.
865
     * In particular, any notifications for the newly logged-in
866
     * user with mode XOOPS_NOTIFICATION_MODE_WAITFORLOGIN are
867
     * switched to mode XOOPS_NOTIFICATION_MODE_SENDONCETHENWAIT.
868
     *
869
     * @param int $user_id ID of the user being logged in
870
     **/
871
    public function doLoginMaintenance($user_id)
872
    {
873
        $criteria = new CriteriaCompo();
874
        $criteria->add(new Criteria('not_uid', (int)$user_id));
875
        $criteria->add(new Criteria('not_mode', XOOPS_NOTIFICATION_MODE_WAITFORLOGIN));
876
877
        $notifications = $this->getObjects($criteria, true);
878
        foreach ($notifications as $n) {
879
            $n->setVar('not_mode', XOOPS_NOTIFICATION_MODE_SENDONCETHENWAIT);
880
            $this->insert($n);
881
        }
882
    }
883
884
    /**
885
     * Update
886
     *
887
     * @param XoopsNotification $notification {@link XoopsNotification} object
888
     * @param string            $field_name   Name of the field
889
     * @param mixed             $field_value  Value to write
890
     *
891
     * @return bool
892
     **/
893
    public function updateByField(XoopsNotification $notification, $field_name, $field_value)
894
    {
895
        $notification->unsetNew();
896
        $notification->setVar($field_name, $field_value);
897
898
        return $this->insert($notification);
899
    }
900
}
901