| Total Complexity | 69 |
| Total Lines | 378 |
| Duplicated Lines | 0 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 0 |
Complex classes like AdePipe often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use AdePipe, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 13 | class AdePipe extends AbstractAdultProviderPipe |
||
| 14 | { |
||
| 15 | protected int $priority = 40; |
||
| 16 | |||
| 17 | private const BASE_URL = 'https://www.adultdvdempire.com'; |
||
| 18 | private const SEARCH_URL = '/dvd/search?q='; |
||
| 19 | |||
| 20 | protected string $directUrl = ''; |
||
| 21 | protected string $title = ''; |
||
| 22 | protected string $response = ''; |
||
| 23 | |||
| 24 | public function getName(): string |
||
| 25 | { |
||
| 26 | return 'ade'; |
||
| 27 | } |
||
| 28 | |||
| 29 | public function getDisplayName(): string |
||
| 32 | } |
||
| 33 | |||
| 34 | protected function getBaseUrl(): string |
||
| 35 | { |
||
| 36 | return self::BASE_URL; |
||
| 37 | } |
||
| 38 | |||
| 39 | protected function process(AdultProcessingPassable $passable): AdultProcessingResult |
||
| 74 | ); |
||
| 75 | } |
||
| 76 | |||
| 77 | protected function search(string $movie): array|false |
||
| 139 | } |
||
| 140 | |||
| 141 | protected function getMovieInfo(): array|false |
||
| 142 | { |
||
| 143 | $results = []; |
||
| 144 | |||
| 145 | if (!empty($this->directUrl)) { |
||
| 146 | if (!empty($this->title)) { |
||
| 147 | $results['title'] = $this->title; |
||
| 148 | } |
||
| 149 | $results['directurl'] = $this->directUrl; |
||
| 150 | } |
||
| 151 | |||
| 152 | // Get all the movie data |
||
| 153 | $synopsis = $this->extractSynopsis(); |
||
| 154 | if (is_array($synopsis)) { |
||
| 155 | $results = array_merge($results, $synopsis); |
||
| 156 | } |
||
| 157 | |||
| 158 | $productInfo = $this->extractProductInfo(true); |
||
| 159 | if (is_array($productInfo)) { |
||
| 160 | $results = array_merge($results, $productInfo); |
||
| 161 | } |
||
| 162 | |||
| 163 | $cast = $this->extractCast(); |
||
| 164 | if (is_array($cast)) { |
||
| 165 | $results = array_merge($results, $cast); |
||
| 166 | } |
||
| 167 | |||
| 168 | $genres = $this->extractGenres(); |
||
| 169 | if (is_array($genres)) { |
||
| 170 | $results = array_merge($results, $genres); |
||
| 171 | } |
||
| 172 | |||
| 173 | $covers = $this->extractCovers(); |
||
| 174 | if (is_array($covers)) { |
||
| 175 | $results = array_merge($results, $covers); |
||
| 176 | } |
||
| 177 | |||
| 178 | $trailers = $this->extractTrailers(); |
||
| 179 | if (is_array($trailers)) { |
||
| 180 | $results = array_merge($results, $trailers); |
||
| 181 | } |
||
| 182 | |||
| 183 | if (empty($results)) { |
||
| 184 | return false; |
||
| 185 | } |
||
| 186 | |||
| 187 | return $results; |
||
| 188 | } |
||
| 189 | |||
| 190 | protected function extractTrailers(): array |
||
| 191 | { |
||
| 192 | $res = []; |
||
| 193 | |||
| 194 | $trailersUrl = str_replace('/item/', '/item/trailers/', $this->directUrl); |
||
| 195 | $trailersResponse = $this->fetchHtml($trailersUrl, $this->cookie); |
||
| 196 | |||
| 197 | if ($trailersResponse !== false) { |
||
| 198 | if (preg_match("/([\"|'])(?P<swf>[^\"']+.swf)([\"|'])/i", $trailersResponse, $hits)) { |
||
| 199 | $res['trailers']['url'] = self::BASE_URL . trim(trim($hits['swf']), '"'); |
||
| 200 | |||
| 201 | if (preg_match('#(?:streamID:\s\")(?P<streamid>[0-9A-Z]+)(?:\")#', $trailersResponse, $hits)) { |
||
| 202 | $res['trailers']['streamid'] = trim($hits['streamid']); |
||
| 203 | } |
||
| 204 | |||
| 205 | if (preg_match('#(?:BaseStreamingUrl:\s\")(?P<baseurl>[\d]+\.[\d]+\.[\d]+\.[\d]+)(?:\")#', $trailersResponse, $hits)) { |
||
| 206 | $res['trailers']['baseurl'] = $hits['baseurl']; |
||
| 207 | } |
||
| 208 | } |
||
| 209 | } |
||
| 210 | |||
| 211 | return $res; |
||
| 212 | } |
||
| 213 | |||
| 214 | protected function extractCovers(): array |
||
| 215 | { |
||
| 216 | $res = []; |
||
| 217 | |||
| 218 | // Try multiple selectors for better reliability |
||
| 219 | $selectors = [ |
||
| 220 | 'div#Boxcover img[itemprop=image]', |
||
| 221 | 'img[itemprop=image]', |
||
| 222 | 'div#Boxcover img', |
||
| 223 | 'div.boxcover img', |
||
| 224 | ]; |
||
| 225 | |||
| 226 | foreach ($selectors as $selector) { |
||
| 227 | $ret = $this->getHtmlParser()->findOne($selector); |
||
| 228 | if ($ret && isset($ret->src)) { |
||
| 229 | // Get high-resolution covers |
||
| 230 | $res['boxcover'] = preg_replace('/[ms]\.jpg$/', 'h.jpg', $ret->src); |
||
| 231 | $res['backcover'] = preg_replace('/[ms]\.jpg$/', 'bh.jpg', $ret->src); |
||
| 232 | |||
| 233 | return $res; |
||
| 234 | } |
||
| 235 | } |
||
| 236 | |||
| 237 | return $res; |
||
| 238 | } |
||
| 239 | |||
| 240 | protected function extractSynopsis(): array |
||
| 241 | { |
||
| 242 | $res = []; |
||
| 243 | |||
| 244 | // Try multiple selectors in priority order |
||
| 245 | $selectors = [ |
||
| 246 | 'meta[property="og:description"]' => 'content', |
||
| 247 | 'meta[name="description"]' => 'content', |
||
| 248 | 'div[itemprop="description"]' => 'plaintext', |
||
| 249 | 'p.synopsis' => 'plaintext', |
||
| 250 | ]; |
||
| 251 | |||
| 252 | foreach ($selectors as $selector => $property) { |
||
| 253 | $meta = $this->getHtmlParser()->findOne($selector); |
||
| 254 | if ($meta && isset($meta->$property) && $meta->$property !== false && !empty(trim($meta->$property))) { |
||
| 255 | $res['synopsis'] = trim($meta->$property); |
||
| 256 | |||
| 257 | return $res; |
||
| 258 | } |
||
| 259 | } |
||
| 260 | |||
| 261 | return $res; |
||
| 262 | } |
||
| 263 | |||
| 264 | protected function extractCast(): array |
||
| 265 | { |
||
| 266 | $res = []; |
||
| 267 | $cast = []; |
||
| 268 | |||
| 269 | // Try multiple selector strategies |
||
| 270 | $selectors = [ |
||
| 271 | 'div[itemprop="actor"] span[itemprop="name"]', |
||
| 272 | 'div.performer-list a', |
||
| 273 | 'a[href*="/performer/"]', |
||
| 274 | ]; |
||
| 275 | |||
| 276 | foreach ($selectors as $selector) { |
||
| 277 | $elements = $this->getHtmlParser()->find($selector); |
||
| 278 | if (!empty($elements)) { |
||
| 279 | foreach ($elements as $a) { |
||
| 280 | if ($a->plaintext !== false && !empty(trim($a->plaintext))) { |
||
| 281 | $cast[] = trim($a->plaintext); |
||
| 282 | } |
||
| 283 | } |
||
| 284 | |||
| 285 | if (!empty($cast)) { |
||
| 286 | break; |
||
| 287 | } |
||
| 288 | } |
||
| 289 | } |
||
| 290 | |||
| 291 | $res['cast'] = array_values(array_unique($cast)); |
||
| 292 | |||
| 293 | return $res; |
||
| 294 | } |
||
| 295 | |||
| 296 | protected function extractGenres(): array |
||
| 297 | { |
||
| 298 | $res = []; |
||
| 299 | $genres = []; |
||
| 300 | |||
| 301 | // Try multiple selector strategies |
||
| 302 | $selectors = [ |
||
| 303 | 'a[Label="Category"]', |
||
| 304 | 'div.categories a', |
||
| 305 | 'a[href*="/category/"]', |
||
| 306 | 'span[itemprop="genre"]', |
||
| 307 | ]; |
||
| 308 | |||
| 309 | foreach ($selectors as $selector) { |
||
| 310 | $elements = $this->getHtmlParser()->find($selector); |
||
| 311 | if (!empty($elements)) { |
||
| 312 | foreach ($elements as $a) { |
||
| 313 | if ($a->plaintext !== false && !empty(trim($a->plaintext))) { |
||
| 314 | $genres[] = trim($a->plaintext); |
||
| 315 | } |
||
| 316 | } |
||
| 317 | |||
| 318 | if (!empty($genres)) { |
||
| 319 | break; |
||
| 320 | } |
||
| 321 | } |
||
| 322 | } |
||
| 323 | |||
| 324 | $res['genres'] = array_values(array_unique($genres)); |
||
| 325 | |||
| 326 | return $res; |
||
| 327 | } |
||
| 328 | |||
| 329 | protected function extractProductInfo(bool $extras = false): array |
||
| 330 | { |
||
| 331 | $res = []; |
||
| 332 | $dofeature = null; |
||
| 333 | |||
| 334 | $tmpResponse = str_ireplace('Section ProductInfo', 'spdinfo', $this->response); |
||
| 335 | $tmpHtml = new \voku\helper\HtmlDomParser(); |
||
| 336 | $tmpHtml->loadHtml($tmpResponse); |
||
| 337 | |||
| 338 | if ($ret = $tmpHtml->findOne('div[class=spdinfo]')) { |
||
| 339 | $productinfo = []; |
||
| 340 | $extrasData = []; |
||
| 341 | |||
| 342 | $tmpResponse = trim($ret->outertext); |
||
| 343 | $ret = $tmpHtml->loadHtml($tmpResponse); |
||
| 344 | |||
| 345 | foreach ($ret->find('text') as $strong) { |
||
| 346 | if (trim($strong->innertext) === 'Features') { |
||
| 347 | $dofeature = true; |
||
| 348 | } |
||
| 349 | if ($dofeature !== true) { |
||
| 350 | if (trim($strong->innertext) !== ' ') { |
||
| 351 | $productinfo[] = trim($strong->innertext); |
||
| 352 | } |
||
| 353 | } else { |
||
| 354 | if ($extras === true) { |
||
| 355 | $extrasData[] = trim($strong->innertext); |
||
| 356 | } |
||
| 357 | } |
||
| 358 | } |
||
| 359 | |||
| 360 | array_shift($productinfo); |
||
| 361 | array_shift($productinfo); |
||
| 362 | $res['productinfo'] = array_chunk($productinfo, 2, false); |
||
| 363 | |||
| 364 | if (!empty($extrasData)) { |
||
| 365 | $res['extras'] = $extrasData; |
||
| 366 | } |
||
| 367 | } |
||
| 368 | |||
| 369 | return $res; |
||
| 370 | } |
||
| 371 | |||
| 372 | /** |
||
| 373 | * Initialize session by visiting the site to establish cookies. |
||
| 374 | * ADE uses JavaScript-based age verification with cookies. |
||
| 375 | */ |
||
| 376 | protected function initializeSession(): void |
||
| 391 | } |
||
| 392 | } |
||
| 393 | } |
||
| 394 | |||
| 395 |