Passed
Push — master ( fa88b1...55d379 )
by
unknown
05:52
created

notificationCategoryInfo()   B

Complexity

Conditions 7
Paths 24

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 17
nc 24
nop 2
dl 0
loc 26
rs 8.8333
c 0
b 0
f 0
1
<?php
2
/**
3
 * XOOPS Notifications
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
 * @subpackage          Xoop Notifications Functions
16
 * @since               2.0.0
17
 * @author              Kazumi Ono (AKA onokazu) http://www.myweb.ne.jp/, http://jp.xoops.org/
18
 */
19
20
use Xmf\Request;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Request. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
21
22
defined('XOOPS_ROOT_PATH') || exit('Restricted access');
23
24
// RMV-NOTIFY
25
26
// FIXME: Do some caching, so we don't retrieve the same category / event
27
// info many times.
28
29
/**
30
 * Determine if notification is enabled for the selected module.
31
 *
32
 * @param  string $style     Subscription style: 'block' or 'inline'
33
 * @param  int    $module_id ID of the module  (default current module)
34
 * @return bool
35
 */
36
function notificationEnabled($style, $module_id = null)
37
{
38
    if (isset($GLOBALS['xoopsModuleConfig']['notification_enabled'])) {
39
        $status = $GLOBALS['xoopsModuleConfig']['notification_enabled'];
40
    } else {
41
        if (!isset($module_id)) {
42
            return false;
43
        }
44
        /** @var XoopsModuleHandler $module_handler */
45
        $module_handler = xoops_getHandler('module');
46
        $module         = $module_handler->get($module_id);
47
        if (!empty($module) && $module->getVar('hasnotification') == 1) {
48
            /** @var XoopsConfigHandler $config_handler */
49
            $config_handler = xoops_getHandler('config');
50
            $config         = $config_handler->getConfigsByCat(0, $module_id);
51
            $status         = $config['notification_enabled'];
52
        } else {
53
            return false;
54
        }
55
    }
56
    include_once $GLOBALS['xoops']->path('include/notification_constants.php');
57
    if (($style === 'block') && ($status === XOOPS_NOTIFICATION_ENABLEBLOCK || $status === XOOPS_NOTIFICATION_ENABLEBOTH)) {
58
        return true;
59
    }
60
61
    return ($style === 'inline') && ($status === XOOPS_NOTIFICATION_ENABLEINLINE || $status === XOOPS_NOTIFICATION_ENABLEBOTH);
62
}
63
64
/**
65
 * Get an associative array of info for a particular notification
66
 * category in the selected module.  If no category is selected,
67
 * return an array of info for all categories.
68
 *
69
 * @param string $category_name
70
 * @param  int|null   $module_id ID of the module (default current module)
71
 *
72
 * @internal param string $name Category name (default all categories)
73
 * @return mixed
74
 */
75
function &notificationCategoryInfo($category_name = '', ?int $module_id = null)
76
{
77
    if (!isset($module_id)) {
78
        global $xoopsModule;
79
        $module_id = !empty($xoopsModule) ? $xoopsModule->getVar('mid') : 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $module_id is dead and can be removed.
Loading history...
80
        $module    = & $xoopsModule;
81
    } else {
82
        /** @var XoopsModuleHandler $module_handler */
83
        $module_handler = xoops_getHandler('module');
84
        $module         = $module_handler->get($module_id);
85
    }
86
87
    if (null !== $module) {
88
    $not_config = &$module->getInfo('notification');
89
    }
90
    if (empty($category_name)) {
91
        return $not_config['category'];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $not_config does not seem to be defined for all execution paths leading up to this point.
Loading history...
92
    }
93
    foreach ($not_config['category'] as $category) {
94
        if ($category['name'] == $category_name) {
95
            return $category;
96
        }
97
    }
98
    $ret = false;
99
100
    return $ret;
101
}
102
103
/**
104
 * Get associative array of info for the category to which comment events
105
 * belong.
106
 *
107
 * @todo This could be more efficient... maybe specify in
108
 *        $modversion['comments'] the notification category.
109
 *       This would also serve as a way to enable notification
110
 *        of comments, and also remove the restriction that
111
 *        all notification categories must have unique item_name. (TODO)
112
 *
113
 * @param  int $module_id ID of the module (default current module)
114
 * @return mixed            Associative array of category info
115
 */
116
function &notificationCommentCategoryInfo($module_id = null)
117
{
118
    $ret            = false;
119
    $all_categories = & notificationCategoryInfo('', $module_id);
120
    if (empty($all_categories)) {
121
        return $ret;
122
    }
123
    foreach ($all_categories as $category) {
124
        $all_events = & notificationEvents($category['name'], false, $module_id);
125
        if (empty($all_events)) {
126
            continue;
127
        }
128
        foreach ($all_events as $event) {
129
            if ($event['name'] === 'comment') {
130
                return $category;
131
            }
132
        }
133
    }
134
135
    return $ret;
136
}
137
138
// TODO: some way to include or exclude admin-only events...
139
140
/**
141
 * Get an array of info for all events (each event has associative array)
142
 * in the selected category of the selected module.
143
 *
144
 * @param  string $category_name Category name
145
 * @param  bool   $enabled_only  If true, return only enabled events
146
 * @param  int    $module_id     ID of the module (default current module)
147
 * @return mixed
148
 */
149
function &notificationEvents($category_name, $enabled_only, $module_id = null)
150
{
151
    if (!isset($module_id)) {
152
        global $xoopsModule;
153
        $module_id = !empty($xoopsModule) ? $xoopsModule->getVar('mid') : 0;
154
        $module    = & $xoopsModule;
155
    } else {
156
        /** @var XoopsModuleHandler $module_handler */
157
        $module_handler = xoops_getHandler('module');
158
        $module         = $module_handler->get($module_id);
159
    }
160
    $not_config     = $module->getInfo('notification');
161
    /** @var XoopsConfigHandler $config_handler */
162
    $config_handler = xoops_getHandler('config');
163
    $mod_config     = $config_handler->getConfigsByCat(0, $module_id);
0 ignored issues
show
Unused Code introduced by
The assignment to $mod_config is dead and can be removed.
Loading history...
164
165
    $category = & notificationCategoryInfo($category_name, $module_id);
166
167
    global $xoopsConfig;
168
    $event_array = [];
169
170
    $override_comment       = false;
171
    $override_commentsubmit = false;
172
    $override_bookmark      = false;
173
174
    foreach ($not_config['event'] as $event) {
175
        if ($event['category'] == $category_name) {
176
            if (!is_dir($dir = XOOPS_ROOT_PATH . '/modules/' . $module->getVar('dirname') . '/language/' . $xoopsConfig['language'] . '/mail_template/')) {
177
                $dir = XOOPS_ROOT_PATH . '/modules/' . $module->getVar('dirname') . '/language/english/mail_template/';
178
            }
179
            $event['mail_template_dir'] = $dir;
180
            if (!$enabled_only || notificationEventEnabled($category, $event, $module)) {
0 ignored issues
show
Bug introduced by
It seems like $category can also be of type false; however, parameter $category of notificationEventEnabled() 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

180
            if (!$enabled_only || notificationEventEnabled(/** @scrutinizer ignore-type */ $category, $event, $module)) {
Loading history...
181
                $event_array[] = $event;
182
            }
183
            if ($event['name'] === 'comment') {
184
                $override_comment = true;
185
            }
186
            if ($event['name'] === 'comment_submit') {
187
                $override_commentsubmit = true;
188
            }
189
            if ($event['name'] === 'bookmark') {
190
                $override_bookmark = true;
191
            }
192
        }
193
    }
194
195
    xoops_loadLanguage('notification');
196
    // Insert comment info if applicable
197
198
    if ($module->getVar('hascomments')) {
199
        $com_config = $module->getInfo('comments');
200
        if (!empty($category['item_name']) && $category['item_name'] == $com_config['itemName']) {
201
            if (!is_dir($dir = XOOPS_ROOT_PATH . '/language/' . $xoopsConfig['language'] . '/mail_template/')) {
202
                $dir = XOOPS_ROOT_PATH . '/language/english/mail_template/';
203
            }
204
            $mail_template_dir = $dir;
205
206
            include_once $GLOBALS['xoops']->path('include/comment_constants.php');
207
            /** @var \XoopsConfigHandler $config_handler */
208
            $config_handler = xoops_getHandler('config');
209
            $com_config     = $config_handler->getConfigsByCat(0, $module_id);
210
            if (!$enabled_only) {
211
                $insert_comment = true;
212
                $insert_submit  = true;
213
            } else {
214
                $insert_comment = false;
215
                $insert_submit  = false;
216
                switch ($com_config['com_rule']) {
217
                    case XOOPS_COMMENT_APPROVENONE:
218
                        // comments disabled, no comment events
219
                        break;
220
                    case XOOPS_COMMENT_APPROVEALL:
221
                        // all comments are automatically approved, no 'submit'
222
                        if (!$override_comment) {
223
                            $insert_comment = true;
224
                        }
225
                        break;
226
                    case XOOPS_COMMENT_APPROVEUSER:
227
                    case XOOPS_COMMENT_APPROVEADMIN:
228
                        // comments first submitted, require later approval
229
                        if (!$override_comment) {
230
                            $insert_comment = true;
231
                        }
232
                        if (!$override_commentsubmit) {
233
                            $insert_submit = true;
234
                        }
235
                        break;
236
                }
237
            }
238
            if ($insert_comment) {
239
                $event = [
240
                    'name'              => 'comment',
241
                    'category'          => $category['name'],
242
                    'title'             => _NOT_COMMENT_NOTIFY,
243
                    'caption'           => _NOT_COMMENT_NOTIFYCAP,
244
                    'description'       => _NOT_COMMENT_NOTIFYDSC,
245
                    'mail_template_dir' => $mail_template_dir,
246
                    'mail_template'     => 'comment_notify',
247
                    'mail_subject'      => _NOT_COMMENT_NOTIFYSBJ,
248
                ];
249
                if (!$enabled_only || notificationEventEnabled($category, $event, $module)) {
250
                    $event_array[] = $event;
251
                }
252
            }
253
            if ($insert_submit) {
254
                $event = [
255
                    'name'              => 'comment_submit',
256
                    'category'          => $category['name'],
257
                    'title'             => _NOT_COMMENTSUBMIT_NOTIFY,
258
                    'caption'           => _NOT_COMMENTSUBMIT_NOTIFYCAP,
259
                    'description'       => _NOT_COMMENTSUBMIT_NOTIFYDSC,
260
                    'mail_template_dir' => $mail_template_dir,
261
                    'mail_template'     => 'commentsubmit_notify',
262
                    'mail_subject'      => _NOT_COMMENTSUBMIT_NOTIFYSBJ,
263
                    'admin_only'        => 1,
264
                ];
265
                if (!$enabled_only || notificationEventEnabled($category, $event, $module)) {
266
                    $event_array[] = $event;
267
                }
268
            }
269
        }
270
    }
271
272
    // Insert bookmark info if appropriate
273
274
    if (!empty($category['allow_bookmark'])) {
275
        if (!$override_bookmark) {
276
            $event = [
277
                'name'        => 'bookmark',
278
                'category'    => $category['name'],
279
                'title'       => _NOT_BOOKMARK_NOTIFY,
280
                'caption'     => _NOT_BOOKMARK_NOTIFYCAP,
281
                'description' => _NOT_BOOKMARK_NOTIFYDSC,
282
            ];
283
            if (!$enabled_only || notificationEventEnabled($category, $event, $module)) {
284
                $event_array[] = $event;
285
            }
286
        }
287
    }
288
289
    return $event_array;
290
}
291
292
/**
293
 * Determine whether a particular notification event is enabled.
294
 * Depends on module config options.
295
 *
296
 * @todo  Check that this works correctly for comment and other
297
 *   events which depend on additional config options...
298
 *
299
 * @param  array  $category Category info array
300
 * @param  array  $event    Event info array
301
 * @param  object $module   Module
302
 * @return bool
303
 **/
304
function notificationEventEnabled($category, $event, $module)
305
{
306
    /** @var XoopsConfigHandler $config_handler */
307
    $config_handler = xoops_getHandler('config');
308
    $mod_config     = $config_handler->getConfigsByCat(0, $module->getVar('mid'));
309
310
    if (is_array($mod_config['notification_events']) && $mod_config['notification_events'] != []) {
311
        $option_name = notificationGenerateConfig($category, $event, 'option_name');
312
        if (in_array($option_name, $mod_config['notification_events'])) {
313
            return true;
314
        }
315
        $notification_handler = xoops_getHandler('notification');
0 ignored issues
show
Unused Code introduced by
The assignment to $notification_handler is dead and can be removed.
Loading history...
316
    }
317
318
    return false;
319
}
320
321
/**
322
 * Get associative array of info for the selected event in the selected
323
 * category (for the selected module).
324
 *
325
 * @param  string $category_name Notification category
326
 * @param  string $event_name    Notification event
327
 * @param  int    $module_id     ID of the module (default current module)
328
 * @return mixed
329
 */
330
function &notificationEventInfo($category_name, $event_name, $module_id = null)
331
{
332
    $all_events = & notificationEvents($category_name, false, $module_id);
333
    foreach ($all_events as $event) {
334
        if ($event['name'] == $event_name) {
335
            return $event;
336
        }
337
    }
338
    $ret = false;
339
340
    return $ret;
341
}
342
343
/**
344
 * Get an array of associative info arrays for subscribable categories
345
 * for the selected module.
346
 *
347
 * @param  int|null $module_id ID of the module
348
 * @return mixed
349
 */
350
351
function &notificationSubscribableCategoryInfo(?int $module_id = null)
352
{
353
    $all_categories = & notificationCategoryInfo('', $module_id);
354
355
    // FIXME: better or more standardized way to do this?
356
    $script_url  = explode('/', $_SERVER['PHP_SELF']);
357
    $script_name = $script_url[count($script_url) - 1];
358
359
    $sub_categories = [];
360
    if (null != $all_categories) {
361
        foreach ($all_categories as $category) {
362
            // Check the script name
363
            $subscribe_from = $category['subscribe_from'];
364
            if (!is_array($subscribe_from)) {
365
                if ($subscribe_from === '*') {
366
                    $subscribe_from = [
367
                        $script_name,
368
                    ];
369
                    // FIXME: this is just a hack: force a match
370
                } else {
371
                    $subscribe_from = [
372
                        $subscribe_from,
373
                    ];
374
                }
375
            }
376
            if (!in_array($script_name, $subscribe_from)) {
377
                continue;
378
            }
379
            // If 'item_name' is missing, automatic match.  Otherwise,
380
            // check if that argument exists...
381
            if (empty($category['item_name'])) {
382
                $category['item_name'] = '';
383
                $category['item_id']   = 0;
384
                $sub_categories[]      = $category;
385
            } else {
386
                $item_name = $category['item_name'];
387
                $id        = ($item_name != '' && isset($_GET[$item_name])) ? Request::getInt($item_name, 0, 'GET') : 0;
388
                if ($id > 0) {
389
                    $category['item_id'] = $id;
390
                    $sub_categories[]    = $category;
391
                }
392
            }
393
        }
394
    }
395
    return $sub_categories;
396
}
397
398
/**
399
 * Generate module config info for a particular category, event pair.
400
 * The selectable config options are given names depending on the
401
 * category and event names, and the text depends on the category
402
 * and event titles.  These are pieced together in this function in
403
 * case we wish to alter the syntax.
404
 *
405
 * @param  array  $category Array of category info
406
 * @param  array  $event    Array of event info
407
 * @param  string $type     The particular name to generate
408
 *                          return string
409
 *                          *
410
 *
411
 * @return bool|string
412
 */
413
function notificationGenerateConfig($category, $event, $type)
414
{
415
    switch ($type) {
416
        case 'option_value':
417
        case 'name':
418
            return 'notify:' . $category['name'] . '-' . $event['name'];
419
            break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
420
        case 'option_name':
421
            return $category['name'] . '-' . $event['name'];
422
            break;
423
        default:
424
            return false;
425
            break;
426
    }
427
}
428