This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Chay22\RecSelMeter; |
||
4 | |||
5 | use Chay22\RecSelMeter\Connection; |
||
6 | |||
7 | class Parser extends Connection |
||
8 | { |
||
9 | /** |
||
10 | * @var $xpath |
||
11 | */ |
||
12 | protected $xpath; |
||
13 | |||
14 | /** |
||
15 | * Retrieve amount product sold |
||
16 | * |
||
17 | * @var $sold |
||
18 | */ |
||
19 | public $sold; |
||
20 | |||
21 | /** |
||
22 | * @var $cod |
||
23 | */ |
||
24 | public $cod = false; |
||
25 | |||
26 | /** |
||
27 | * Latest bump attempt time |
||
28 | * |
||
29 | * @var $bump |
||
30 | */ |
||
31 | public $bump; |
||
32 | |||
33 | 1 | function __construct($url) |
|
34 | { |
||
35 | 1 | parent::__construct($url); |
|
36 | 1 | date_default_timezone_set('Asia/Jakarta'); |
|
37 | 1 | libxml_use_internal_errors(true); |
|
38 | |||
39 | 1 | if ($this->header['http_code'] != 200 ) { |
|
40 | throw new \Exception("URL not found!"); |
||
41 | } |
||
42 | |||
43 | 1 | $this->xpath = $this->document(new \DOMDocument); |
|
44 | 1 | } |
|
45 | |||
46 | /** |
||
47 | * Creates DOMXPath object from content |
||
48 | * |
||
49 | * @return object |
||
50 | */ |
||
51 | 1 | protected function document(\DOMDocument $doc) |
|
52 | { |
||
53 | 1 | $doc->loadHTML($this->content); |
|
54 | 1 | return new \DOMXPath($doc); |
|
55 | } |
||
56 | |||
57 | /** |
||
58 | * Find element from content with xpath expression |
||
59 | * |
||
60 | * @param string $query xpath query expression |
||
61 | * @return bool(false)|DOMNodeList |
||
62 | * @see http://php.net/manual/en/domxpath.query.php |
||
63 | */ |
||
64 | 6 | public function find($query) |
|
65 | { |
||
66 | 6 | return $this->xpath->query($query); |
|
67 | } |
||
68 | |||
69 | /** |
||
70 | * Fetch all result into array |
||
71 | * |
||
72 | * @return array |
||
73 | */ |
||
74 | 1 | public function fetch() |
|
75 | { |
||
76 | 1 | $product = $this->product(); |
|
77 | |||
78 | return [ |
||
79 | 1 | 'username' => $this->username(), |
|
80 | 1 | 'user_id' => $this->userID(), |
|
81 | 1 | 'rank' => $this->rank(), |
|
82 | 1 | 'feedback' => $this->feedback(), |
|
83 | 1 | 'feedback_percent' => $this->feedbackPercent(), |
|
84 | 1 | 'join_date' => $this->joinDate(), |
|
85 | 1 | 'verified' => $this->verifiedSeller(), |
|
86 | 1 | 'published_at' => $this->threadPublished(), |
|
87 | 1 | 'image_count' => $this->countImage(), |
|
88 | 1 | 'sold' => $product['sold'], |
|
89 | 1 | 'cod' => $product['cod'], |
|
90 | 1 | 'last_bump' => $product['bump'], |
|
91 | 1 | ]; |
|
92 | } |
||
93 | |||
94 | /** |
||
95 | * Get username |
||
96 | * |
||
97 | * @return string |
||
98 | */ |
||
99 | 2 | public function username() |
|
100 | { |
||
101 | 2 | return $this->find('//meta[@name="author"]') |
|
102 | 2 | ->item(0) |
|
103 | 2 | ->getAttribute('content'); |
|
104 | } |
||
105 | |||
106 | /** |
||
107 | * Get user id |
||
108 | * |
||
109 | * @return int |
||
110 | */ |
||
111 | 2 | public function userID() |
|
112 | { |
||
113 | 2 | $query = $this->find( |
|
114 | '//div[contains(@class,"seller-detail-info")]' . |
||
115 | '/span[contains(@class,"username")]/a' |
||
116 | 2 | )->item(0) |
|
117 | 2 | ->getAttribute('href'); |
|
118 | 2 | $query = explode('/', $query); |
|
119 | 2 | $query = end($query); |
|
120 | |||
121 | 2 | return $query + 0; |
|
122 | } |
||
123 | |||
124 | /** |
||
125 | * Amount of image of thread |
||
126 | * |
||
127 | * @return int |
||
128 | */ |
||
129 | 2 | public function countImage() |
|
130 | { |
||
131 | 2 | return $this->find( |
|
132 | '//div[contains(@id,"carousel-thumb")]' . |
||
133 | '/div[contains(@class,"thumbnail")]' |
||
134 | 2 | )->length; |
|
135 | } |
||
136 | |||
137 | /** |
||
138 | * Get user rank |
||
139 | * |
||
140 | * @return string |
||
141 | */ |
||
142 | 1 | public function rank() |
|
143 | { |
||
144 | 1 | return $this->find( |
|
145 | '//div[contains(@class,"seller-detail-info")]' . |
||
146 | '/span[contains(@class,"rank")]' |
||
147 | 1 | )->item(0) |
|
148 | 1 | ->nodeValue; |
|
149 | } |
||
150 | |||
151 | /** |
||
152 | * Get amount of feedback |
||
153 | * |
||
154 | * @return int |
||
155 | */ |
||
156 | 1 | public function feedback() |
|
157 | { |
||
158 | 1 | return $this->find( |
|
159 | '//div[contains(@class,"seller-detail-info")]' . |
||
160 | '/span[contains(@class,"feedback")]' |
||
161 | 1 | )->item(0) |
|
162 | 1 | ->getElementsByTagName('a') |
|
163 | 1 | ->item(0) |
|
164 | 1 | ->textContent + 0; |
|
165 | } |
||
166 | |||
167 | /** |
||
168 | * Get feedback precentage |
||
169 | * |
||
170 | * @return int |
||
171 | */ |
||
172 | 1 | public function feedbackPercent() |
|
173 | { |
||
174 | 1 | $query = $this->find( |
|
175 | '//div[contains(@class,"seller-detail-info")]' . |
||
176 | '/span[contains(@class,"feedback")]' |
||
177 | 1 | )->item(0) |
|
178 | 1 | ->getElementsByTagName('strong') |
|
179 | 1 | ->item(0) |
|
180 | 1 | ->nodeValue; |
|
181 | |||
182 | 1 | return str_replace('%', '', $query) + 0; |
|
183 | } |
||
184 | |||
185 | /** |
||
186 | * Retrieve user join date |
||
187 | * |
||
188 | * @return string date |
||
189 | */ |
||
190 | 1 | public function joinDate() |
|
191 | { |
||
192 | 1 | $query = $this->find( |
|
193 | '//div[contains(@class,"seller-detail-info")]' . |
||
194 | '/span[not(@class)]' |
||
195 | 1 | )->item(0) |
|
196 | 1 | ->nodeValue; |
|
197 | 1 | $query = str_replace('join: ', '', strtolower($query)); |
|
198 | 1 | $date = new \DateTime($query); |
|
199 | |||
200 | 1 | return $date->format('Y-m-d H:i:s'); |
|
201 | } |
||
202 | |||
203 | /** |
||
204 | * Check whether verified seller |
||
205 | * |
||
206 | * @return bool |
||
207 | */ |
||
208 | 2 | public function verifiedSeller() |
|
209 | { |
||
210 | 2 | if ($this->find('//div[contains(@class,"vsl-badge")]')->length > 0) { |
|
211 | return true; |
||
212 | } |
||
213 | |||
214 | 2 | return false; |
|
215 | } |
||
216 | |||
217 | /** |
||
218 | * Find date of thread started |
||
219 | * |
||
220 | * @return string date thread started |
||
221 | */ |
||
222 | 2 | public function threadPublished() |
|
223 | { |
||
224 | 2 | $query = $this->find( |
|
225 | '//div[contains(@class,"user-details")]/time' |
||
226 | 2 | )->item(0) |
|
227 | 2 | ->getAttribute('datetime'); |
|
228 | 2 | $date = new \DateTime($query); |
|
229 | |||
230 | 2 | return $date->format('Y-m-d H:i:s'); |
|
231 | } |
||
232 | |||
233 | /** |
||
234 | * Return product specified entities |
||
235 | * |
||
236 | * @return array sold, bump, cod |
||
237 | */ |
||
238 | 1 | public function product() |
|
239 | { |
||
240 | 1 | $query = $this->find( |
|
241 | '//div[contains(@class,"item-attributes")]/table/tr' |
||
242 | 1 | ); |
|
243 | 1 | foreach ($query as $value) { |
|
244 | $nodeValue = strtolower($value->nodeValue); |
||
245 | $titleEntity = trim(explode(':', $nodeValue)[0]); |
||
246 | $content = explode(':', $nodeValue)[1]; |
||
247 | |||
248 | if($titleEntity === 'terjual') { |
||
249 | $content = trim($content); |
||
250 | $this->sold = explode(' ', $content)[0] + 0; |
||
251 | } |
||
252 | |||
253 | if($titleEntity === 'lokasi') { |
||
254 | if(strpos($content, 'bisa cod') !== false) { |
||
255 | $this->cod = true; |
||
256 | } |
||
257 | } |
||
258 | |||
259 | if($titleEntity === 'last sundul') { |
||
260 | $product['bump'] = trim($content); |
||
0 ignored issues
–
show
|
|||
261 | if (strpos(trim($content), 'ago') !== false) { |
||
262 | $bumpTime = explode(' ', trim($content)); |
||
263 | $date = new \DateTime; |
||
264 | $date->modify('- '.$bumpTime[0] . ' '. $bumpTime[1]); |
||
265 | |||
266 | $this->bump = $date->format('Y-m-d H:i:s'); |
||
267 | } |
||
268 | } |
||
269 | |||
270 | 1 | } |
|
271 | |||
272 | return [ |
||
273 | 1 | 'sold' => $this->sold, |
|
274 | 1 | 'cod' => $this->cod, |
|
275 | 1 | 'bump' => $this->bump, |
|
276 | 1 | ]; |
|
277 | } |
||
278 | } |
||
279 |
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.
Let’s take a look at an example:
As you can see in this example, the array
$myArray
is initialized the first time when the foreach loop is entered. You can also see that the value of thebar
key is only written conditionally; thus, its value might result from a previous iteration.This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.