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) |
|
0 ignored issues
–
show
|
|||
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 |
||
0 ignored issues
–
show
The doc-type
bool(false)|DOMNodeList could not be parsed: Expected "|" or "end of type", but got "(" at position 4. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
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
Coding Style
Comprehensibility
introduced
by
$product was never initialized. Although not strictly required by PHP, it is generally a good practice to add $product = array(); before regardless.
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: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array 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. ![]() |
|||
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 explicit visibility (
private
,protected
, orpublic
) is generally recommend to communicate to other developers how, and from where this method is intended to be used.