Issues (6)

src/Driver/FilesystemQueue.php (4 issues)

Labels
1
<?php declare(strict_types=1);
2
3
namespace Initx\Querabilis\Driver;
4
5
use Initx\Querabilis\Envelope;
6
use Initx\Querabilis\Exception\IllegalStateException;
7
use Initx\Querabilis\Queue;
8
use JMS\Serializer\SerializerInterface;
9
10
final class FilesystemQueue implements Queue
11
{
12
    use HasFallbackSerializer;
13
    use HasDefaultRemoveAndElement;
14
15
    /**
16
     * @var string
17
     */
18
    private $path;
19
20
    /**
21
     * @var SerializerInterface
22
     */
23
    private $serializer;
24
25 11
    public function __construct(string $path, ?SerializerInterface $serializer = null)
26
    {
27 11
        $this->serializer = $this->fallbackSerializer($serializer);
28 11
        $this->path = $path;
29 11
    }
30
31 5
    public function add(Envelope $envelope): bool
32
    {
33 5
        if (!$this->offer($envelope)) {
34
            $this->throwItIsNotWriteable();
35
        }
36
37 4
        return true;
38
    }
39
40 7
    public function offer(Envelope $envelope): bool
41
    {
42 7
        $content = $this->serializer->serialize($envelope, 'json').PHP_EOL;
43
44 7
        $result = (bool)@file_put_contents(
45 7
            $this->path,
46 7
            $content,
47 7
            FILE_APPEND
48
        );
49
50 7
        if (!$result) {
51 2
            $this->throwItIsNotWriteable();
52
        }
53
54 5
        return true;
55
    }
56
57 3
    public function poll(): ?Envelope
58
    {
59 3
        $firstLine = $this->removeFirstLine();
0 ignored issues
show
Are you sure the assignment to $firstLine is correct as $this->removeFirstLine() targeting Initx\Querabilis\Driver\...ueue::removeFirstLine() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
60
61 2
        if (!$firstLine) {
0 ignored issues
show
$firstLine is of type null, thus it always evaluated to false.
Loading history...
62 1
            return null;
63
        }
64
65 1
        return $this->serializer->deserialize($firstLine, Envelope::class, 'json');
66
    }
67
68 4
    public function peek(): ?Envelope
69
    {
70 4
        $firstLine = $this->readFirstLine();
71
72 4
        if (!$firstLine) {
73 2
            return null;
74
        }
75
76 2
        return $this->serializer->deserialize($firstLine, Envelope::class, 'json');
77
    }
78
79 3
    private function removeFirstLine(): ?string
80
    {
81 3
        if (!file_exists($this->path)) {
82 1
            $this->throwItNotExists();
83
        }
84
85 2
        $firstLine = null;
86
87 2
        $handle = fopen($this->path, 'cb+');
88
89 2
        if ($handle) {
0 ignored issues
show
$handle is of type false|resource, thus it always evaluated to false.
Loading history...
90 2
            if (!flock($handle, LOCK_EX)) {
91
                fclose($handle);
92
            }
93
94 2
            $offset = 0;
95 2
            $len = filesize($this->path);
96
97 2
            while (($line = fgets($handle, 4096)) !== false) {
98 1
                if (!$firstLine) {
99 1
                    $firstLine = $line;
100 1
                    $offset = strlen($firstLine);
101
102 1
                    continue;
103
                }
104
105 1
                $pos = ftell($handle);
106 1
                fseek($handle, $pos - strlen($line) - $offset);
107 1
                fwrite($handle, $line);
108 1
                fseek($handle, $pos);
109
            }
110
111 2
            fflush($handle);
112 2
            ftruncate($handle, $len - $offset);
113 2
            flock($handle, LOCK_UN);
114 2
            fclose($handle);
115
        }
116
117 2
        return $firstLine;
118
    }
119
120 4
    private function readFirstLine(): ?string
121
    {
122 4
        if (!file_exists($this->path)) {
123
            $this->throwItNotExists();
124
        }
125
126 4
        $firstLine = fgets(fopen($this->path, 'rb'));
0 ignored issues
show
It seems like fopen($this->path, 'rb') can also be of type false; however, parameter $handle of fgets() 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

126
        $firstLine = fgets(/** @scrutinizer ignore-type */ fopen($this->path, 'rb'));
Loading history...
127
128 4
        return $firstLine ?: null;
129
    }
130
131 2
    private function throwItIsNotWriteable(): void
132
    {
133 2
        throw new IllegalStateException("Could not write to file: {$this->path}");
134
    }
135
136 1
    private function throwItNotExists(): void
137
    {
138 1
        throw new IllegalStateException("File $this->path not exists");
139
    }
140
}
141