Issues (1519)

system/modules/Daemon/Daemon.php (20 issues)

1
<?php
2
3
class Daemon extends Module {
4
    private $tasksDirResource;
5
    private $serializer;
6
    private $workDir;
7
    public $checked = false;
8
9
    function check() {
10
        $workDir = $this->workDir();
11
        $lock = fopen($workDir . '/daemon.lock', 'w+');
12
        if (flock($lock, LOCK_EX | LOCK_NB)) {
0 ignored issues
show
It seems like $lock can also be of type false; however, parameter $handle of flock() does only seem to accept resource, 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

12
        if (flock(/** @scrutinizer ignore-type */ $lock, LOCK_EX | LOCK_NB)) {
Loading history...
13
            flock($lock, LOCK_UN);
14
            fclose($lock);
0 ignored issues
show
It seems like $lock can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, 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

14
            fclose(/** @scrutinizer ignore-type */ $lock);
Loading history...
15
            if (function_exists('pcntl_fork') && $pid = pcntl_fork() !== -1) {
16
                if ($pid) {
17
                    return $pid;
18
                } else {
19
                    $this->start(true);
20
                }
21
            } elseif (function_exists('fsockopen')) {
22
                $fp = fsockopen($_SERVER['SERVER_NAME'],
23
                    80,
24
                    $errno, $errstr, 30);
25
                $out = "GET /daemon/start HTTP/1.1\r\n";
26
                $out .= "Host: " . $_SERVER['SERVER_NAME'] . "\r\n";
27
                $out .= "Connection: Close\r\n\r\n";
28
                fwrite($fp, $out);
29
                fclose($fp);
30
            } elseif (function_exists('curl_init')) {
31
                $ch = curl_init('http://' . $_SERVER['SERVER_NAME'] . '/daemon/start');
32
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
33
                curl_setopt($ch, CURLOPT_TIMEOUT_MS, 100);
34
                curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
35
                $content = curl_exec($ch);
0 ignored issues
show
The assignment to $content is dead and can be removed.
Loading history...
36
                curl_close($ch);
37
            }
38
        }
39
    }
40
41
    function start($retry = false) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
42
        $workDir = $this->workDir();
43
        $lock = fopen($workDir . '/daemon.lock', 'w+');
44
        if (flock($lock, LOCK_EX | LOCK_NB)) {
0 ignored issues
show
It seems like $lock can also be of type false; however, parameter $handle of flock() does only seem to accept resource, 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

44
        if (flock(/** @scrutinizer ignore-type */ $lock, LOCK_EX | LOCK_NB)) {
Loading history...
45
            set_time_limit(0);
46
            ini_set('memory_limit', '-1');
47
            while (true) {
48
                $taskFile = $this->getNextTask();
49
                if (!$taskFile) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $taskFile of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
50
                    for ($i = 0; $i < 358; $i++) {
51
                        sleep(1);
52
                        $taskFile = $this->getNextTask();
53
                        if ($taskFile) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $taskFile of type false|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
54
                            break;
55
                        }
56
                    }
57
                    if (!$taskFile) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $taskFile of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
58
                        break;
59
                    }
60
                }
61
                $task = $this->unserialize(file_get_contents($taskFile));
0 ignored issues
show
It seems like $taskFile can also be of type false; however, parameter $filename of file_get_contents() does only seem to accept 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

61
                $task = $this->unserialize(file_get_contents(/** @scrutinizer ignore-type */ $taskFile));
Loading history...
62
                unlink($taskFile);
0 ignored issues
show
It seems like $taskFile can also be of type false; however, parameter $filename of unlink() does only seem to accept 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

62
                unlink(/** @scrutinizer ignore-type */ $taskFile);
Loading history...
63
                if ($task) {
64
                    $task();
65
                }
66
            }
67
        } else {
68
            if ($retry) {
69
                sleep(1);
70
                $this->start(false);
71
            }
72
        }
73
    }
74
75
    function getNextTask() {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
76
        $workDir = $this->workDir();
77
        if (!is_resource($this->tasksDirResource)) {
78
            $this->tasksDirResource = opendir($workDir . '/tasks/');
79
        }
80
        if ($this->tasksDirResource) {
81
            while (false !== ($entry = readdir($this->tasksDirResource))) {
82
                if ($entry != "." && $entry != "..") {
83
                    return $workDir . '/tasks/' . $entry;
84
                }
85
            }
86
        }
87
        return false;
88
    }
89
90
    function task($callback) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
91
        $keyLog = \App::$cur->log->start('add task');
92
        $workDir = $this->workDir();
93
        $taskFile = $workDir . '/tasks/' . microtime(true) . '.task';
94
        $keyLog2 = \App::$cur->log->start('serialize task');
95
        $serialize = $this->serialize($callback);
96
        \App::$cur->log->end($keyLog2);
97
        $keyLog3 = \App::$cur->log->start('put task to file');
98
        file_put_contents($taskFile, $serialize);
99
        \App::$cur->log->end($keyLog3);
100
        if (!$this->checked) {
101
            $this->checked = true;
102
            $this->check();
103
        }
104
        \App::$cur->log->end($keyLog);
105
        return $taskFile;
106
    }
107
108
    function workDir() {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
109
        if ($this->workDir) {
110
            return $this->workDir;
111
        }
112
        $path = App::$primary->path . '/daemon';
113
        Tools::createDir(App::$primary->path . '/daemon/tasks');
0 ignored issues
show
The type Tools 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...
114
        return $path;
115
    }
116
117
    function unserialize($item) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
118
        try {
119
            return $this->serializer()->unserialize($item);
120
        } catch (\SuperClosure\Exception\ClosureUnserializationException $e) {
0 ignored issues
show
The type SuperClosure\Exception\C...nserializationException 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...
121
            return false;
122
        }
123
    }
124
125
    function serialize($item) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
126
        return $this->serializer()->serialize($item);
127
    }
128
129
    function serializer() {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
130
        if ($this->serializer) {
131
            return $this->serializer;
132
        }
133
        \ComposerCmd::requirePackage('jeremeamia/superclosure');
134
        return $this->serializer = new \SuperClosure\Serializer(new SuperClosure\Analyzer\TokenAnalyzer());
0 ignored issues
show
The type SuperClosure\Analyzer\TokenAnalyzer 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...
The type SuperClosure\Serializer 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...
135
    }
136
137
}