Passed
Push — master ( 0f91e9...e0eb75 )
by Sebastian
03:48
created

TrackingIDTrait::validateSyntax_tracking_id()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 5
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 13
rs 10
1
<?php
2
/**
3
 * File containing the {@see \Mailcode\Traits\Commands\Validation\TrackingIDTrait} trait.
4
 *
5
 * @package Mailcode
6
 * @subpackage Validation
7
 * @see \Mailcode\Traits\Commands\Validation\TrackingIDTrait
8
 */
9
10
declare(strict_types=1);
11
12
namespace Mailcode\Traits\Commands\Validation;
13
14
use AppUtils\NamedClosure;
15
use Closure;
16
use Mailcode\Commands\Command\ShowURL\AutoTrackingID;
17
use Mailcode\Interfaces\Commands\Validation\TrackingIDInterface;
18
use Mailcode\Mailcode_Parser_Statement_Tokenizer;
19
use Mailcode\Mailcode_Parser_Statement_Tokenizer_Token_StringLiteral;
20
21
/**
22
 * Command validation drop-in: checks for the presence
23
 * of a tracking ID, which must be the first string
24
 * literal in the command's parameters list. If not
25
 * present or not a match for a tracking ID name, an
26
 * empty string is used as default.
27
 *
28
 * When the `no-tracking:` keyword is enabled, the
29
 * tracking ID will always be empty.
30
 *
31
 * @package Mailcode
32
 * @subpackage Validation
33
 * @author Sebastian Mordziol <[email protected]>
34
 *
35
 * @see TrackingIDInterface
36
 */
37
trait TrackingIDTrait
38
{
39
    private ?Mailcode_Parser_Statement_Tokenizer_Token_StringLiteral $trackingIDToken = null;
40
41
    /**
42
     * @return string
43
     */
44
    public function getTrackingID() : string
45
    {
46
        $token = $this->getTrackingIDToken();
47
48
        if($token === null)
49
        {
50
            return '';
51
        }
52
53
        // In case of an empty tracking ID
54
        $token->setText($this->filterTrackingID($token->getText()));
55
56
        return $token->getText();
57
    }
58
59
    private function filterTrackingID(string $trackingID) : string
60
    {
61
        if(empty($trackingID))
62
        {
63
            return AutoTrackingID::generate($this);
0 ignored issues
show
Bug introduced by
$this of type Mailcode\Traits\Commands...idation\TrackingIDTrait is incompatible with the type Mailcode\Interfaces\Comm...ion\TrackingIDInterface expected by parameter $command of Mailcode\Commands\Comman...oTrackingID::generate(). ( Ignorable by Annotation )

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

63
            return AutoTrackingID::generate(/** @scrutinizer ignore-type */ $this);
Loading history...
64
        }
65
66
        return $trackingID;
67
    }
68
69
    public function getTrackingIDToken() : ?Mailcode_Parser_Statement_Tokenizer_Token_StringLiteral
70
    {
71
        $this->initTrackingToken();
72
73
        return $this->trackingIDToken;
74
    }
75
76
    private function initTrackingToken() : void
77
    {
78
        if(!$this->isTrackingEnabled())
0 ignored issues
show
Bug introduced by
It seems like isTrackingEnabled() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

78
        if(!$this->/** @scrutinizer ignore-call */ isTrackingEnabled())
Loading history...
79
        {
80
            $this->clearTrackingIDToken();
81
            return;
82
        }
83
84
        if(isset($this->trackingIDToken))
85
        {
86
            return;
87
        }
88
89
        $token = $this->detectToken();
90
        if($token === null)
91
        {
92
            $token = $this->requireParams()
0 ignored issues
show
Bug introduced by
It seems like requireParams() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

92
            $token = $this->/** @scrutinizer ignore-call */ requireParams()
Loading history...
93
                ->getInfo()
94
                ->addStringLiteral(AutoTrackingID::generate($this));
0 ignored issues
show
Bug introduced by
$this of type Mailcode\Traits\Commands...idation\TrackingIDTrait is incompatible with the type Mailcode\Interfaces\Comm...ion\TrackingIDInterface expected by parameter $command of Mailcode\Commands\Comman...oTrackingID::generate(). ( Ignorable by Annotation )

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

94
                ->addStringLiteral(AutoTrackingID::generate(/** @scrutinizer ignore-type */ $this));
Loading history...
95
        }
96
97
        $this->trackingIDToken = $token;
98
    }
99
100
    private function clearTrackingIDToken() : void
101
    {
102
        $this->trackingIDToken = null;
103
104
        $token = $this->detectToken();
105
        if($token !== null)
106
        {
107
            $this->requireParams()
108
                ->getInfo()
109
                ->removeToken($token);
110
        }
111
    }
112
113
    public function setTrackingID(string $trackingID) : self
114
    {
115
        $token = $this->getTrackingIDToken();
116
117
        if($token !== null)
118
        {
119
            $token->setText($this->filterTrackingID($trackingID));
120
        }
121
122
        return $this;
123
    }
124
125
    private function detectToken() : ?Mailcode_Parser_Statement_Tokenizer_Token_StringLiteral
126
    {
127
        $literals = $this->requireParams()
128
            ->getInfo()
129
            ->getStringLiterals();
130
131
        if(empty($literals))
132
        {
133
            return null;
134
        }
135
136
        $trackingID = array_shift($literals);
137
138
        $id = $trackingID->getText();
139
140
        if(strpos($id, '=') === false)
141
        {
142
            return $trackingID;
143
        }
144
145
        return null;
146
    }
147
148
    /**
149
     * Checks if any of the parameters contain a trackingID.
150
     * This must be the first string literal in the parameters,
151
     * allowing any keywords to be placed before it, but not
152
     * after the optional query parameters.
153
     */
154
    protected function validateSyntax_tracking_id() : void
155
    {
156
        // Add a listener to automatically update the
157
        // tracking ID if the tracking is disabled
158
        // programmatically via `setTrackingEnabled()`.
159
        $this->requireParams()->getEventHandler()->onKeywordsChanged(
160
            NamedClosure::fromClosure(
161
                Closure::fromCallable(array($this, 'handleKeywordsChanged')),
162
                array($this, 'handleKeywordsChanged')
163
            )
164
        );
165
166
        $this->initTrackingToken();
167
    }
168
169
    private function handleKeywordsChanged(Mailcode_Parser_Statement_Tokenizer $tokenizer) : void
0 ignored issues
show
Unused Code introduced by
The parameter $tokenizer is not used and could be removed. ( Ignorable by Annotation )

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

169
    private function handleKeywordsChanged(/** @scrutinizer ignore-unused */ Mailcode_Parser_Statement_Tokenizer $tokenizer) : void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
170
    {
171
        $this->initTrackingToken();
172
    }
173
}
174