notificationEvents()   F
last analyzed

Complexity

Conditions 33
Paths > 20000

Size

Total Lines 141
Code Lines 96

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 33
eloc 96
nc 96288
nop 3
dl 0
loc 141
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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

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