1 | <?php |
||
2 | /** |
||
3 | * File containing the {@see \AppLocalize\Localization_Scanner} class. |
||
4 | * |
||
5 | * @package AppLocalize |
||
6 | * @subpackage Scanner |
||
7 | * @see \AppLocalize\Localization_Scanner |
||
8 | */ |
||
9 | |||
10 | declare(strict_types=1); |
||
11 | |||
12 | namespace AppLocalize; |
||
13 | |||
14 | use AppUtils\FileHelper; |
||
15 | |||
16 | /** |
||
17 | * The scanner is used to go through all PHP and JavaScript file |
||
18 | * sources that have been configured, and detects all translatable |
||
19 | * strings. |
||
20 | * |
||
21 | * @package AppLocalize |
||
22 | * @subpackage Scanner |
||
23 | * @author Sebastian Mordziol <[email protected]> |
||
24 | */ |
||
25 | class Localization_Scanner |
||
26 | { |
||
27 | /** |
||
28 | * @var float |
||
29 | */ |
||
30 | protected $timeStart; |
||
31 | |||
32 | /** |
||
33 | * @var float |
||
34 | */ |
||
35 | protected $timeEnd; |
||
36 | |||
37 | /** |
||
38 | * @var array |
||
39 | */ |
||
40 | protected $stringInfos = array(); |
||
41 | |||
42 | /** |
||
43 | * @var string |
||
44 | */ |
||
45 | protected $storageFile; |
||
46 | |||
47 | /** |
||
48 | * @var bool |
||
49 | */ |
||
50 | protected $loaded = false; |
||
51 | |||
52 | /** |
||
53 | * @var Localization_Scanner_StringsCollection|NULL |
||
54 | * @see Localization_Scanner::getCollection() |
||
55 | */ |
||
56 | protected $collection; |
||
57 | |||
58 | /** |
||
59 | * @var Localization_Parser |
||
60 | */ |
||
61 | protected $parser; |
||
62 | |||
63 | public function __construct(string $storageFile) |
||
64 | { |
||
65 | $this->storageFile = $storageFile; |
||
66 | } |
||
67 | |||
68 | public function isScanAvailable() : bool |
||
69 | { |
||
70 | return file_exists($this->storageFile); |
||
71 | } |
||
72 | |||
73 | public function scan() : void |
||
74 | { |
||
75 | if(isset($this->collection)) { |
||
76 | $this->collection = null; |
||
77 | } |
||
78 | |||
79 | $this->timeStart = microtime(true); |
||
0 ignored issues
–
show
|
|||
80 | |||
81 | $sources = Localization::getSources(); |
||
82 | foreach($sources as $source) |
||
83 | { |
||
84 | $source->scan($this); |
||
85 | } |
||
86 | |||
87 | $this->timeEnd = microtime(true); |
||
0 ignored issues
–
show
It seems like
microtime(true) can also be of type string . However, the property $timeEnd is declared as type double . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||
88 | |||
89 | $this->save(); |
||
90 | } |
||
91 | |||
92 | public function load() : void |
||
93 | { |
||
94 | if(!$this->isScanAvailable()) { |
||
95 | return; |
||
96 | } |
||
97 | |||
98 | if($this->loaded) { |
||
99 | return; |
||
100 | } |
||
101 | |||
102 | $this->loaded = true; |
||
103 | |||
104 | $data = FileHelper::parseJSONFile($this->storageFile); |
||
105 | |||
106 | if($this->getCollection()->fromArray($data) === true) { |
||
107 | return; |
||
108 | } |
||
109 | |||
110 | FileHelper::deleteFile($this->storageFile); |
||
111 | $this->loaded = false; |
||
112 | $this->collection = null; |
||
113 | } |
||
114 | |||
115 | protected function save() : void |
||
116 | { |
||
117 | $data = $this->getCollection()->toArray(); |
||
118 | |||
119 | FileHelper::saveAsJSON($data, $this->storageFile); |
||
120 | } |
||
121 | |||
122 | public function getParser() : Localization_Parser |
||
123 | { |
||
124 | if(!isset($this->parser)) { |
||
125 | $this->parser = new Localization_Parser($this); |
||
126 | } |
||
127 | |||
128 | return $this->parser; |
||
129 | } |
||
130 | |||
131 | public function getCollection() : Localization_Scanner_StringsCollection |
||
132 | { |
||
133 | if(!isset($this->collection)) { |
||
134 | $this->collection = new Localization_Scanner_StringsCollection($this); |
||
135 | } |
||
136 | |||
137 | return $this->collection; |
||
0 ignored issues
–
show
|
|||
138 | } |
||
139 | |||
140 | /** |
||
141 | * Returns the total execution time it took to parse |
||
142 | * all relevant files and folders. |
||
143 | * |
||
144 | * @return float |
||
145 | */ |
||
146 | public function getExecutionTime() : float |
||
147 | { |
||
148 | return $this->timeEnd - $this->timeStart; |
||
149 | } |
||
150 | |||
151 | public function countHashes() : int |
||
152 | { |
||
153 | $this->load(); |
||
154 | |||
155 | return $this->getCollection()->countHashes(); |
||
156 | } |
||
157 | |||
158 | public function countFiles() : int |
||
159 | { |
||
160 | $this->load(); |
||
161 | |||
162 | return $this->getCollection()->countFiles(); |
||
163 | } |
||
164 | |||
165 | public function hasWarnings() : bool |
||
166 | { |
||
167 | return $this->getCollection()->hasWarnings(); |
||
168 | } |
||
169 | |||
170 | public function countWarnings() : int |
||
171 | { |
||
172 | return $this->getCollection()->countWarnings(); |
||
173 | } |
||
174 | |||
175 | /** |
||
176 | * Retrieves all warnings that have been registered |
||
177 | * during the last search for translatable texts. |
||
178 | * |
||
179 | * @return Localization_Scanner_StringsCollection_Warning[] |
||
180 | */ |
||
181 | public function getWarnings() : array |
||
182 | { |
||
183 | return $this->getCollection()->getWarnings(); |
||
184 | } |
||
185 | } |
||
186 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.