/
www
/
wwwroot
/
alo88.autos
/
wp-content
/
plugins
/
wp-content-crawler
/
app
/
Objects
/
Transformation
/
Objects
/
Upload File
HOME
<?php /** * Created by PhpStorm. * User: turgutsaricam * Date: 12/04/2020 * Time: 14:21 * * @since 1.11.0 */ namespace WPCCrawler\Objects\Transformation\Objects; use DOMNode; use Symfony\Component\DomCrawler\Crawler; use WPCCrawler\Objects\Crawling\Bot\AbstractBot; use WPCCrawler\Objects\Filtering\Enums\InputName; use WPCCrawler\Objects\Filtering\Interfaces\NeedsBot; use WPCCrawler\Objects\Settings\Enums\SettingInnerKey; use WPCCrawler\Objects\Transformation\Interfaces\Transformable; use WPCCrawler\Utils; class ElementTransformableField extends TransformableField implements NeedsBot { /** @var AbstractBot|null */ private $bot; public function getSubjectItem($key, $value) { // We work with DOM elements in this field. That is because the elements do not have a unique key that we can // use. Objects are persisted. So, to be able to identify the same elements later in the action commands, we use // objects. But, we cannot use Crawler instances because the same DOM element might exist in different Crawler // instances. Instead, we directly use DOM elements, since they are persisted and unique. // * Persisted: Not like "saved to the db" but like "the same object is maintained" /** @var Crawler $value */ if (is_a($value, Crawler::class)) { return $value->getNode(0); } $cmd = $this->getCommand(); if (!$cmd) return null; // This value is not a Crawler. It is probably a property of the Crawler, such as an attribute value or HTML. // Try to get this item from the original extracted values, if it is possible. $lastSubjectValues = $cmd->getLastExtractedSubjectValues(); if (!$lastSubjectValues) return null; $subject = $lastSubjectValues[$key] ?? null; if ($subject === null || !is_a($subject, Crawler::class)) return null; /** @var Crawler $subject */ return $subject->getNode(0); } public function getSubjectItemForHumans($key, $value, $subjectItem): ?string { return $subjectItem instanceof DOMNode ? Utils::getDomNodeHtml($subjectItem) : null; } protected function onExtractSubjectValues(?Transformable $dataSource): ?array { $cmd = $this->getCommand(); if (!$cmd) return null; $bot = $this->getBot(); if (!$bot) return null; $crawler = $bot->getCrawler(); if (!$crawler) return null; // Get the assigned selectors. If the option does not exist, return null. $selectorOption = $this->getSelectorOption(); if ($selectorOption === null) return null; // Find the elements matching the selectors and collect them in an array $results = []; foreach($selectorOption as $selectorData) { $nodes = $bot->getElementsFromCrawler($crawler, $selectorData); if ($nodes === null) continue; $results = array_merge($results, $nodes); } return $results; } /** * @return array|null Selector option's value. If there is no command, no selector option or no selector option * with a non-empty CSS selector, returns null. Otherwise, the selector option, which is an * array of selector data (associative array). The result is filtered such that each selector * data contains a non-empty CSS selector. * @since 1.11.0 */ public function getSelectorOption(): ?array { $cmd = $this->getCommand(); if (!$cmd) return null; $selectorOption = $cmd->getOption(InputName::CSS_SELECTOR); $value = !is_array($selectorOption) || !$selectorOption ? null : $selectorOption; if ($value === null) return null; // Remove items with empty CSS selectors $value = array_filter($value, function($item) { // Include the item only if it is an array with a non-empty CSS selector return is_array($item) && isset($item[SettingInnerKey::SELECTOR]) && trim($item[SettingInnerKey::SELECTOR]) !== ''; }); // If, after removal, there is no item in the array, return null. Otherwise, return the value. return $value ?: null; } /* * */ public function setBot(?AbstractBot $bot): void { $this->bot = $bot; } public function getBot(): ?AbstractBot { return $this->bot; } }