Passed
Push — master ( 1afc11...f876cf )
by Goffy
03:38
created

TaskHandler::processTasks()   D

Complexity

Conditions 18
Paths 18

Size

Total Lines 97
Code Lines 66

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 18
eloc 66
c 1
b 0
f 1
nc 18
nop 1
dl 0
loc 97
rs 4.8666

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
declare(strict_types=1);
4
5
6
namespace XoopsModules\Wgevents;
7
8
/*
9
 You may not change or alter any portion of this comment or credits
10
 of supporting developers from this source code or any supporting source code
11
 which is considered copyrighted (c) material of the original comment or credit authors.
12
13
 This program is distributed in the hope that it will be useful,
14
 but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
*/
17
18
/**
19
 * wgEvents module for xoops
20
 *
21
 * @copyright    2021 XOOPS Project (https://xoops.org)
22
 * @license      GPL 2.0 or later
23
 * @package      wgevents
24
 * @since        1.0.0
25
 * @min_xoops    2.5.11 Beta1
26
 * @author       Goffy - Wedega - Email:[email protected] - Website:https://xoops.wedega.com
27
 */
28
29
use XoopsModules\Wgevents;
30
use XoopsModules\Wgevents\{
31
    Constants,
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, XoopsModules\Wgevents\Constants. 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...
32
    MailHandler
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, XoopsModules\Wgevents\MailHandler. 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...
33
};
34
35
/**
36
 * Class Object Handler Task
37
 */
38
class TaskHandler extends \XoopsPersistableObjectHandler
39
{
40
    /**
41
     * Constructor
42
     *
43
     * @param \XoopsDatabase $db
44
     */
45
    public function __construct(\XoopsDatabase $db)
46
    {
47
        parent::__construct($db, 'wgevents_task', Task::class, 'id', 'id');
48
    }
49
50
    /**
51
     * @param bool $isNew
52
     *
53
     * @return object
54
     */
55
    public function create($isNew = true)
56
    {
57
        return parent::create($isNew);
58
    }
59
60
    /**
61
     * retrieve a field
62
     *
63
     * @param int $id field id
64
     * @param null fields
0 ignored issues
show
Bug introduced by
The type XoopsModules\Wgevents\fields was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
65
     * @return \XoopsObject|null reference to the {@link Get} object
66
     */
67
    public function get($id = null, $fields = null)
68
    {
69
        return parent::get($id, $fields);
70
    }
71
72
    /**
73
     * get inserted id
74
     *
75
     * @param null
76
     * @return int reference to the {@link Get} object
77
     */
78
    public function getInsertId()
79
    {
80
        return $this->db->getInsertId();
81
    }
82
83
    /**
84
     * Get Count Task in the database
85
     * @param int    $start
86
     * @param int    $limit
87
     * @param string $sort
88
     * @param string $order
89
     * @return int
90
     */
91
    public function getCountTasks($start = 0, $limit = 0, $sort = 'id', $order = 'ASC')
92
    {
93
        $crCountTasks = new \CriteriaCompo();
94
        $crCountTasks = $this->getTasksCriteria($crCountTasks, $start, $limit, $sort, $order);
95
        return $this->getCount($crCountTasks);
0 ignored issues
show
Bug introduced by
$crCountTasks of type integer is incompatible with the type CriteriaElement|null expected by parameter $criteria of XoopsPersistableObjectHandler::getCount(). ( Ignorable by Annotation )

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

95
        return $this->getCount(/** @scrutinizer ignore-type */ $crCountTasks);
Loading history...
96
    }
97
98
    /**
99
     * Get All Task in the database
100
     * @param int    $start
101
     * @param int    $limit
102
     * @param string $sort
103
     * @param string $order
104
     * @return array
105
     */
106
    public function getAllTasks($start = 0, $limit = 0, $sort = 'id', $order = 'ASC')
107
    {
108
        $crAllTasks = new \CriteriaCompo();
109
        $crAllTasks = $this->getTasksCriteria($crAllTasks, $start, $limit, $sort, $order);
110
        return $this->getAll($crAllTasks);
0 ignored issues
show
Bug introduced by
$crAllTasks of type integer is incompatible with the type CriteriaElement|null expected by parameter $criteria of XoopsPersistableObjectHandler::getAll(). ( Ignorable by Annotation )

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

110
        return $this->getAll(/** @scrutinizer ignore-type */ $crAllTasks);
Loading history...
111
    }
112
113
    /**
114
     * Get Criteria Task
115
     * @param        $crTasks
116
     * @param int    $start
117
     * @param int    $limit
118
     * @param string $sort
119
     * @param string $order
120
     * @return int
121
     */
122
    private function getTasksCriteria($crTasks, $start, $limit, $sort, $order)
123
    {
124
        $crTasks->setStart($start);
125
        $crTasks->setLimit($limit);
126
        $crTasks->setSort($sort);
127
        $crTasks->setOrder($order);
128
        return $crTasks;
129
    }
130
131
    /**
132
     * Get count open tasks for cron.php
133
     * @return int
134
     */
135
    public function getCountTasksOpen()
136
    {
137
        $crTask = new \CriteriaCompo();
138
        $crTask->add(new \Criteria('status', Constants::STATUS_DONE, '<'));
139
140
        return $this->getCount($crTask);
141
    }
142
143
    /**
144
     * Create a task
145
     * @param $type
146
     * @param $recipient
147
     * @param $params
148
     * @return bool
149
     */
150
    public function createTask($type, $recipient, $params)
151
    {
152
        $uidCurrent = \is_object($GLOBALS['xoopsUser']) ? (int)$GLOBALS['xoopsUser']->uid() : 0;
153
154
        $taskObj = $this->create();
155
        // Set Vars
156
        $taskObj->setVar('type', $type);
157
        $taskObj->setVar('params', $params);
158
        $taskObj->setVar('recipient', $recipient);
159
        $taskObj->setVar('datecreated', time());
160
        $taskObj->setVar('submitter', $uidCurrent);
161
        $taskObj->setVar('status', Constants::STATUS_PENDING);
162
163
        // Insert Data
164
        return (bool)$this->insert($taskObj);
165
    }
166
167
    /**
168
     * process all task if limit is not exceeded
169
     * @param $log_level
170
     * @return array
171
     */
172
    public function processTasks($log_level = 0)
173
    {
174
        $helper = \XoopsModules\Wgevents\Helper::getInstance();
175
176
        // get limit_hour from primary account
177
        $accountHandler = $helper->getHandler('Account');
178
        $limitHour = $accountHandler->getLimitHour();
179
180
        $resProcess = '';
181
182
        $crTaskPending = new \CriteriaCompo();
183
        $crTaskPending->add(new \Criteria('status', Constants::STATUS_PENDING));
184
        $tasksCountPending = $this->getCount($crTaskPending);
185
186
        // if all works properly there shouldn't be a task type 'processing' left
187
        $crTaskProcessing = new \CriteriaCompo();
188
        $crTaskProcessing->add(new \Criteria('status', Constants::STATUS_PROCESSING));
189
        $tasksCountProcessing = $this->getCount($crTaskProcessing);
190
191
        $crTaskDone = new \CriteriaCompo();
192
        $crTaskDone->add(new \Criteria('status', Constants::STATUS_DONE));
193
        $crTaskDone->add(new \Criteria('datedone', time() - 3600, '>'));
194
        $tasksCountDone = $this->getCount($crTaskDone);
195
196
        $counterDone = 0;
197
        if ($log_level > 0) {
198
            $resProcess .=  '<br>Start processTasks';
199
            $resProcess .=  '<br>time - 3600: ' . \formatTimestamp(time() - 3600, 'm');
200
            if ($tasksCountProcessing > 0) {
201
                $resProcess .= '<br><span style="color:#ff0000;font-weight:700">Count status PROCESSING at start: ' . $tasksCountProcessing . '</span>';
202
            }
203
            $resProcess .=  '<br>Count status PENDING at start: ' . $tasksCountPending;
204
            $resProcess .=  '<br>Count status DONE at start: ' . $tasksCountDone;
205
        }
206
        if (($tasksCountPending > 0) && ($tasksCountDone < $limitHour || 0 == $limitHour)) {
207
            if ($limitHour > 0) {
208
                $crTaskPending->setLimit($limitHour);
209
            }
210
            $tasksAll = $this->getAll($crTaskPending);
211
            $resultMH = 0;
212
            foreach (\array_keys($tasksAll) as $i) {
213
                // check whether task is still pending
214
                // ignore it if meanwhile another one started to process the task
215
                if ($log_level > 1) {
216
                    $resProcess .=  '<br>Task key: ' . $i;
217
                }
218
                if (554 === $resultMH) {
219
                    $resProcess .=  '<br>Skipped Error 554: SMTP limit exceeded';
220
                } else {
221
                    if ((Constants::STATUS_PENDING == (int)$tasksAll[$i]->getVar('status'))
222
                        && ($tasksCountDone < $limitHour || 0 == $limitHour)) {
223
                        $taskProcessObj = $this->get($i);
224
                        $taskProcessObj->setVar('status', Constants::STATUS_PROCESSING);
225
                        if ($this->insert($taskProcessObj)) {
226
                            $mailsHandler = new MailHandler();
227
                            $mailParams = json_decode($tasksAll[$i]->getVar('params', 'n'), true);
228
                            $mailParams['recipients'] = $tasksAll[$i]->getVar('recipient');
229
                            $mailParams['taskId'] = $i;
230
                            $mailsHandler->setParams($mailParams);
231
                            $mailsHandler->setType($tasksAll[$i]->getVar('type'));
232
                            // send mails
233
                            $resultMH = (int)$mailsHandler->execute();
234
                            unset($mailsHandler);
235
                            //update task list corresponding the result
236
                            if (0 === $resultMH) {
237
                                $taskProcessObj->setVar('status', Constants::STATUS_DONE);
238
                                $taskProcessObj->setVar('datedone', time());
239
                                $counterDone++;
240
                                if ($log_level > 1) {
241
                                    $resProcess .=  ' - done';
242
                                }
243
                            } else {
244
                                $taskProcessObj->setVar('status', Constants::STATUS_PENDING);
245
                                if ($log_level > 1) {
246
                                    $resProcess .=  ' - failed';
247
                                }
248
                            }
249
                            $this->insert($taskProcessObj);
250
                        } else {
251
                            $resProcess .=  ' - error insert taskProcessObj';
252
                        }
253
                    }
254
                }
255
                // check once more number of done
256
                $tasksCountDone = $this->getCount($crTaskDone);
257
            }
258
        }
259
        // check once more number of open tasks
260
        $crTaskOpen = new \CriteriaCompo();
261
        $crTaskOpen->add(new \Criteria('status', Constants::STATUS_DONE, '<'));
262
        $tasksCountOpen = $this->getCount($crTaskOpen);
263
264
        if ($log_level > 0) {
265
            $resProcess .=  '<br>End processTasks';
266
        }
267
268
        return ['pending' => $tasksCountPending, 'done' => $counterDone, 'resprocess' => $resProcess, 'still_open' => $tasksCountOpen];
269
    }
270
}
271