package and depencies
This commit is contained in:
@@ -55,49 +55,39 @@ abstract class AbstractUriElement
|
||||
|
||||
/**
|
||||
* Gets the node associated with this link.
|
||||
*
|
||||
* @return \DOMElement
|
||||
*/
|
||||
public function getNode()
|
||||
public function getNode(): \DOMElement
|
||||
{
|
||||
return $this->node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the method associated with this link.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod()
|
||||
public function getMethod(): string
|
||||
{
|
||||
return $this->method ?? 'GET';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URI associated with this link.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUri()
|
||||
public function getUri(): string
|
||||
{
|
||||
return UriResolver::resolve($this->getRawUri(), $this->currentUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns raw URI data.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getRawUri();
|
||||
abstract protected function getRawUri(): string;
|
||||
|
||||
/**
|
||||
* Returns the canonicalized URI path (see RFC 3986, section 5.2.4).
|
||||
*
|
||||
* @param string $path URI path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function canonicalizePath(string $path)
|
||||
protected function canonicalizePath(string $path): string
|
||||
{
|
||||
if ('' === $path || '/' === $path) {
|
||||
return $path;
|
||||
|
5
vendor/symfony/dom-crawler/CHANGELOG.md
vendored
5
vendor/symfony/dom-crawler/CHANGELOG.md
vendored
@@ -1,6 +1,11 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
6.0
|
||||
---
|
||||
|
||||
* Remove `Crawler::parents()` method, use `ancestors()` instead
|
||||
|
||||
5.4
|
||||
---
|
||||
|
||||
|
225
vendor/symfony/dom-crawler/Crawler.php
vendored
225
vendor/symfony/dom-crawler/Crawler.php
vendored
@@ -30,62 +30,44 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
|
||||
/**
|
||||
* The default namespace prefix to be used with XPath and CSS expressions.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $defaultNamespacePrefix = 'default';
|
||||
private string $defaultNamespacePrefix = 'default';
|
||||
|
||||
/**
|
||||
* A map of manually registered namespaces.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private $namespaces = [];
|
||||
private array $namespaces = [];
|
||||
|
||||
/**
|
||||
* A map of cached namespaces.
|
||||
*
|
||||
* @var \ArrayObject
|
||||
*/
|
||||
private $cachedNamespaces;
|
||||
private \ArrayObject $cachedNamespaces;
|
||||
|
||||
/**
|
||||
* The base href value.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $baseHref;
|
||||
|
||||
/**
|
||||
* @var \DOMDocument|null
|
||||
*/
|
||||
private $document;
|
||||
private ?string $baseHref;
|
||||
private ?\DOMDocument $document = null;
|
||||
|
||||
/**
|
||||
* @var list<\DOMNode>
|
||||
*/
|
||||
private $nodes = [];
|
||||
private array $nodes = [];
|
||||
|
||||
/**
|
||||
* Whether the Crawler contains HTML or XML content (used when converting CSS to XPath).
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $isHtml = true;
|
||||
private bool $isHtml = true;
|
||||
|
||||
/**
|
||||
* @var HTML5|null
|
||||
*/
|
||||
private $html5Parser;
|
||||
private HTML5 $html5Parser;
|
||||
|
||||
/**
|
||||
* @param \DOMNodeList|\DOMNode|\DOMNode[]|string|null $node A Node to use as the base for the crawling
|
||||
*/
|
||||
public function __construct($node = null, string $uri = null, string $baseHref = null)
|
||||
public function __construct(\DOMNodeList|\DOMNode|array|string $node = null, string $uri = null, string $baseHref = null)
|
||||
{
|
||||
$this->uri = $uri;
|
||||
$this->baseHref = $baseHref ?: $uri;
|
||||
$this->html5Parser = class_exists(HTML5::class) ? new HTML5(['disable_html_ns' => true]) : null;
|
||||
$this->html5Parser = new HTML5(['disable_html_ns' => true]);
|
||||
$this->cachedNamespaces = new \ArrayObject();
|
||||
|
||||
$this->add($node);
|
||||
@@ -93,20 +75,16 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the current URI.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getUri()
|
||||
public function getUri(): ?string
|
||||
{
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns base href.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getBaseHref()
|
||||
public function getBaseHref(): ?string
|
||||
{
|
||||
return $this->baseHref;
|
||||
}
|
||||
@@ -131,7 +109,7 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
*
|
||||
* @throws \InvalidArgumentException when node is not the expected type
|
||||
*/
|
||||
public function add($node)
|
||||
public function add(\DOMNodeList|\DOMNode|array|string|null $node)
|
||||
{
|
||||
if ($node instanceof \DOMNodeList) {
|
||||
$this->addNodeList($node);
|
||||
@@ -230,14 +208,11 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
public function addXmlContent(string $content, string $charset = 'UTF-8', int $options = \LIBXML_NONET)
|
||||
{
|
||||
// remove the default namespace if it's the only namespace to make XPath expressions simpler
|
||||
if (!preg_match('/xmlns:/', $content)) {
|
||||
if (!str_contains($content, 'xmlns:')) {
|
||||
$content = str_replace('xmlns', 'ns', $content);
|
||||
}
|
||||
|
||||
$internalErrors = libxml_use_internal_errors(true);
|
||||
if (\LIBXML_VERSION < 20900) {
|
||||
$disableEntities = libxml_disable_entity_loader(true);
|
||||
}
|
||||
|
||||
$dom = new \DOMDocument('1.0', $charset);
|
||||
$dom->validateOnParse = true;
|
||||
@@ -247,9 +222,6 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
}
|
||||
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
if (\LIBXML_VERSION < 20900) {
|
||||
libxml_disable_entity_loader($disableEntities);
|
||||
}
|
||||
|
||||
$this->addDocument($dom);
|
||||
|
||||
@@ -309,9 +281,7 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
throw new \InvalidArgumentException('Attaching DOM nodes from multiple documents in the same crawler is forbidden.');
|
||||
}
|
||||
|
||||
if (null === $this->document) {
|
||||
$this->document = $node->ownerDocument;
|
||||
}
|
||||
$this->document ??= $node->ownerDocument;
|
||||
|
||||
// Don't add duplicate nodes in the Crawler
|
||||
if (\in_array($node, $this->nodes, true)) {
|
||||
@@ -323,10 +293,8 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns a node given its position in the node list.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function eq(int $position)
|
||||
public function eq(int $position): static
|
||||
{
|
||||
if (isset($this->nodes[$position])) {
|
||||
return $this->createSubCrawler($this->nodes[$position]);
|
||||
@@ -351,7 +319,7 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
*
|
||||
* @return array An array of values returned by the anonymous function
|
||||
*/
|
||||
public function each(\Closure $closure)
|
||||
public function each(\Closure $closure): array
|
||||
{
|
||||
$data = [];
|
||||
foreach ($this->nodes as $i => $node) {
|
||||
@@ -363,10 +331,8 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Slices the list of nodes by $offset and $length.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function slice(int $offset = 0, int $length = null)
|
||||
public function slice(int $offset = 0, int $length = null): static
|
||||
{
|
||||
return $this->createSubCrawler(\array_slice($this->nodes, $offset, $length));
|
||||
}
|
||||
@@ -377,10 +343,8 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
* To remove a node from the list, the anonymous function must return false.
|
||||
*
|
||||
* @param \Closure $closure An anonymous function
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function reduce(\Closure $closure)
|
||||
public function reduce(\Closure $closure): static
|
||||
{
|
||||
$nodes = [];
|
||||
foreach ($this->nodes as $i => $node) {
|
||||
@@ -394,20 +358,16 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Returns the first node of the current selection.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function first()
|
||||
public function first(): static
|
||||
{
|
||||
return $this->eq(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last node of the current selection.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function last()
|
||||
public function last(): static
|
||||
{
|
||||
return $this->eq(\count($this->nodes) - 1);
|
||||
}
|
||||
@@ -415,11 +375,9 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
/**
|
||||
* Returns the siblings nodes of the current selection.
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @throws \InvalidArgumentException When current node is empty
|
||||
*/
|
||||
public function siblings()
|
||||
public function siblings(): static
|
||||
{
|
||||
if (!$this->nodes) {
|
||||
throw new \InvalidArgumentException('The current node list is empty.');
|
||||
@@ -470,11 +428,9 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
/**
|
||||
* Returns the next siblings nodes of the current selection.
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @throws \InvalidArgumentException When current node is empty
|
||||
*/
|
||||
public function nextAll()
|
||||
public function nextAll(): static
|
||||
{
|
||||
if (!$this->nodes) {
|
||||
throw new \InvalidArgumentException('The current node list is empty.');
|
||||
@@ -486,11 +442,9 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
/**
|
||||
* Returns the previous sibling nodes of the current selection.
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function previousAll()
|
||||
public function previousAll(): static
|
||||
{
|
||||
if (!$this->nodes) {
|
||||
throw new \InvalidArgumentException('The current node list is empty.');
|
||||
@@ -499,28 +453,12 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
return $this->createSubCrawler($this->sibling($this->getNode(0), 'previousSibling'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent nodes of the current selection.
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @throws \InvalidArgumentException When current node is empty
|
||||
*/
|
||||
public function parents()
|
||||
{
|
||||
trigger_deprecation('symfony/dom-crawler', '5.3', 'The %s() method is deprecated, use ancestors() instead.', __METHOD__);
|
||||
|
||||
return $this->ancestors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ancestors of the current selection.
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @throws \InvalidArgumentException When the current node is empty
|
||||
*/
|
||||
public function ancestors()
|
||||
public function ancestors(): static
|
||||
{
|
||||
if (!$this->nodes) {
|
||||
throw new \InvalidArgumentException('The current node list is empty.');
|
||||
@@ -541,12 +479,10 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
/**
|
||||
* Returns the children nodes of the current selection.
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @throws \InvalidArgumentException When current node is empty
|
||||
* @throws \RuntimeException If the CssSelector Component is not available and $selector is provided
|
||||
*/
|
||||
public function children(string $selector = null)
|
||||
public function children(string $selector = null): static
|
||||
{
|
||||
if (!$this->nodes) {
|
||||
throw new \InvalidArgumentException('The current node list is empty.');
|
||||
@@ -567,11 +503,9 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
/**
|
||||
* Returns the attribute value of the first node of the list.
|
||||
*
|
||||
* @return string|null
|
||||
*
|
||||
* @throws \InvalidArgumentException When current node is empty
|
||||
*/
|
||||
public function attr(string $attribute)
|
||||
public function attr(string $attribute): ?string
|
||||
{
|
||||
if (!$this->nodes) {
|
||||
throw new \InvalidArgumentException('The current node list is empty.');
|
||||
@@ -585,11 +519,9 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
/**
|
||||
* Returns the node name of the first node of the list.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException When current node is empty
|
||||
*/
|
||||
public function nodeName()
|
||||
public function nodeName(): string
|
||||
{
|
||||
if (!$this->nodes) {
|
||||
throw new \InvalidArgumentException('The current node list is empty.');
|
||||
@@ -606,11 +538,9 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
* @param string|null $default When not null: the value to return when the current node is empty
|
||||
* @param bool $normalizeWhitespace Whether whitespaces should be trimmed and normalized to single spaces
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException When current node is empty
|
||||
*/
|
||||
public function text(string $default = null, bool $normalizeWhitespace = true)
|
||||
public function text(string $default = null, bool $normalizeWhitespace = true): string
|
||||
{
|
||||
if (!$this->nodes) {
|
||||
if (null !== $default) {
|
||||
@@ -642,11 +572,9 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
*
|
||||
* @param string|null $default When not null: the value to return when the current node is empty
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException When current node is empty
|
||||
*/
|
||||
public function html(string $default = null)
|
||||
public function html(string $default = null): string
|
||||
{
|
||||
if (!$this->nodes) {
|
||||
if (null !== $default) {
|
||||
@@ -659,7 +587,7 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
$node = $this->getNode(0);
|
||||
$owner = $node->ownerDocument;
|
||||
|
||||
if (null !== $this->html5Parser && '<!DOCTYPE html>' === $owner->saveXML($owner->childNodes[0])) {
|
||||
if ('<!DOCTYPE html>' === $owner->saveXML($owner->childNodes[0])) {
|
||||
$owner = $this->html5Parser;
|
||||
}
|
||||
|
||||
@@ -680,7 +608,7 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
$node = $this->getNode(0);
|
||||
$owner = $node->ownerDocument;
|
||||
|
||||
if (null !== $this->html5Parser && '<!DOCTYPE html>' === $owner->saveXML($owner->childNodes[0])) {
|
||||
if ('<!DOCTYPE html>' === $owner->saveXML($owner->childNodes[0])) {
|
||||
$owner = $this->html5Parser;
|
||||
}
|
||||
|
||||
@@ -692,10 +620,8 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
*
|
||||
* Since an XPath expression might evaluate to either a simple type or a \DOMNodeList,
|
||||
* this method will return either an array of simple types or a new Crawler instance.
|
||||
*
|
||||
* @return array|Crawler
|
||||
*/
|
||||
public function evaluate(string $xpath)
|
||||
public function evaluate(string $xpath): array|Crawler
|
||||
{
|
||||
if (null === $this->document) {
|
||||
throw new \LogicException('Cannot evaluate the expression on an uninitialized crawler.');
|
||||
@@ -723,10 +649,8 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
* Example:
|
||||
*
|
||||
* $crawler->filter('h1 a')->extract(['_text', 'href']);
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function extract(array $attributes)
|
||||
public function extract(array $attributes): array
|
||||
{
|
||||
$count = \count($attributes);
|
||||
|
||||
@@ -756,10 +680,8 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
* is considered as a fake parent of the elements inside it.
|
||||
* This means that a child selector "div" or "./div" will match only
|
||||
* the div elements of the current crawler, not their children.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function filterXPath(string $xpath)
|
||||
public function filterXPath(string $xpath): static
|
||||
{
|
||||
$xpath = $this->relativize($xpath);
|
||||
|
||||
@@ -776,11 +698,9 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
*
|
||||
* This method only works if you have installed the CssSelector Symfony Component.
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @throws \RuntimeException if the CssSelector Component is not available
|
||||
*/
|
||||
public function filter(string $selector)
|
||||
public function filter(string $selector): static
|
||||
{
|
||||
$converter = $this->createCssSelectorConverter();
|
||||
|
||||
@@ -790,10 +710,8 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Selects links by name or alt value for clickable images.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function selectLink(string $value)
|
||||
public function selectLink(string $value): static
|
||||
{
|
||||
return $this->filterRelativeXPath(
|
||||
sprintf('descendant-or-self::a[contains(concat(\' \', normalize-space(string(.)), \' \'), %1$s) or ./img[contains(concat(\' \', normalize-space(string(@alt)), \' \'), %1$s)]]', static::xpathLiteral(' '.$value.' '))
|
||||
@@ -802,10 +720,8 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Selects images by alt value.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function selectImage(string $value)
|
||||
public function selectImage(string $value): static
|
||||
{
|
||||
$xpath = sprintf('descendant-or-self::img[contains(normalize-space(string(@alt)), %s)]', static::xpathLiteral($value));
|
||||
|
||||
@@ -814,10 +730,8 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
|
||||
/**
|
||||
* Selects a button by name or alt value for images.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function selectButton(string $value)
|
||||
public function selectButton(string $value): static
|
||||
{
|
||||
return $this->filterRelativeXPath(
|
||||
sprintf('descendant-or-self::input[((contains(%1$s, "submit") or contains(%1$s, "button")) and contains(concat(\' \', normalize-space(string(@value)), \' \'), %2$s)) or (contains(%1$s, "image") and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %2$s)) or @id=%3$s or @name=%3$s] | descendant-or-self::button[contains(concat(\' \', normalize-space(string(.)), \' \'), %2$s) or @id=%3$s or @name=%3$s]', 'translate(@type, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")', static::xpathLiteral(' '.$value.' '), static::xpathLiteral($value))
|
||||
@@ -827,11 +741,9 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
/**
|
||||
* Returns a Link object for the first node in the list.
|
||||
*
|
||||
* @return Link
|
||||
*
|
||||
* @throws \InvalidArgumentException If the current node list is empty or the selected node is not instance of DOMElement
|
||||
*/
|
||||
public function link(string $method = 'get')
|
||||
public function link(string $method = 'get'): Link
|
||||
{
|
||||
if (!$this->nodes) {
|
||||
throw new \InvalidArgumentException('The current node list is empty.');
|
||||
@@ -853,7 +765,7 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
*
|
||||
* @throws \InvalidArgumentException If the current node list contains non-DOMElement instances
|
||||
*/
|
||||
public function links()
|
||||
public function links(): array
|
||||
{
|
||||
$links = [];
|
||||
foreach ($this->nodes as $node) {
|
||||
@@ -870,11 +782,9 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
/**
|
||||
* Returns an Image object for the first node in the list.
|
||||
*
|
||||
* @return Image
|
||||
*
|
||||
* @throws \InvalidArgumentException If the current node list is empty
|
||||
*/
|
||||
public function image()
|
||||
public function image(): Image
|
||||
{
|
||||
if (!\count($this)) {
|
||||
throw new \InvalidArgumentException('The current node list is empty.');
|
||||
@@ -894,7 +804,7 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
*
|
||||
* @return Image[]
|
||||
*/
|
||||
public function images()
|
||||
public function images(): array
|
||||
{
|
||||
$images = [];
|
||||
foreach ($this as $node) {
|
||||
@@ -911,11 +821,9 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
/**
|
||||
* Returns a Form object for the first node in the list.
|
||||
*
|
||||
* @return Form
|
||||
*
|
||||
* @throws \InvalidArgumentException If the current node list is empty or the selected node is not instance of DOMElement
|
||||
*/
|
||||
public function form(array $values = null, string $method = null)
|
||||
public function form(array $values = null, string $method = null): Form
|
||||
{
|
||||
if (!$this->nodes) {
|
||||
throw new \InvalidArgumentException('The current node list is empty.');
|
||||
@@ -964,10 +872,8 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
*
|
||||
* echo Crawler::xpathLiteral('a\'b"c');
|
||||
* //prints concat('a', "'", 'b"c')
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function xpathLiteral(string $s)
|
||||
public static function xpathLiteral(string $s): string
|
||||
{
|
||||
if (!str_contains($s, "'")) {
|
||||
return sprintf("'%s'", $s);
|
||||
@@ -997,10 +903,8 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
* Filters the list of nodes with an XPath expression.
|
||||
*
|
||||
* The XPath expression should already be processed to apply it in the context of each node.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
private function filterRelativeXPath(string $xpath): object
|
||||
private function filterRelativeXPath(string $xpath): static
|
||||
{
|
||||
$crawler = $this->createSubCrawler(null);
|
||||
if (null === $this->document) {
|
||||
@@ -1106,19 +1010,12 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
return $xpath; // The XPath expression is invalid
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DOMNode|null
|
||||
*/
|
||||
public function getNode(int $position)
|
||||
public function getNode(int $position): ?\DOMNode
|
||||
{
|
||||
return $this->nodes[$position] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
return \count($this->nodes);
|
||||
}
|
||||
@@ -1126,16 +1023,12 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
/**
|
||||
* @return \ArrayIterator<int, \DOMNode>
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
public function getIterator(): \ArrayIterator
|
||||
{
|
||||
return new \ArrayIterator($this->nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function sibling(\DOMNode $node, string $siblingDir = 'nextSibling')
|
||||
protected function sibling(\DOMNode $node, string $siblingDir = 'nextSibling'): array
|
||||
{
|
||||
$nodes = [];
|
||||
|
||||
@@ -1159,9 +1052,6 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
$htmlContent = $this->convertToHtmlEntities($htmlContent, $charset);
|
||||
|
||||
$internalErrors = libxml_use_internal_errors(true);
|
||||
if (\LIBXML_VERSION < 20900) {
|
||||
$disableEntities = libxml_disable_entity_loader(true);
|
||||
}
|
||||
|
||||
$dom = new \DOMDocument('1.0', $charset);
|
||||
$dom->validateOnParse = true;
|
||||
@@ -1171,9 +1061,6 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
}
|
||||
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
if (\LIBXML_VERSION < 20900) {
|
||||
libxml_disable_entity_loader($disableEntities);
|
||||
}
|
||||
|
||||
return $dom;
|
||||
}
|
||||
@@ -1187,11 +1074,11 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
|
||||
try {
|
||||
return mb_encode_numericentity($htmlContent, [0x80, 0x10FFFF, 0, 0x1FFFFF], $charset);
|
||||
} catch (\Exception|\ValueError $e) {
|
||||
} catch (\Exception|\ValueError) {
|
||||
try {
|
||||
$htmlContent = iconv($charset, 'UTF-8', $htmlContent);
|
||||
$htmlContent = mb_encode_numericentity($htmlContent, [0x80, 0x10FFFF, 0, 0x1FFFFF], 'UTF-8');
|
||||
} catch (\Exception|\ValueError $e) {
|
||||
} catch (\Exception|\ValueError) {
|
||||
}
|
||||
|
||||
return $htmlContent;
|
||||
@@ -1249,10 +1136,8 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
* Creates a crawler for some subnodes.
|
||||
*
|
||||
* @param \DOMNodeList|\DOMNode|\DOMNode[]|string|null $nodes
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
private function createSubCrawler($nodes): object
|
||||
private function createSubCrawler(\DOMNodeList|\DOMNode|array|string|null $nodes): static
|
||||
{
|
||||
$crawler = new static($nodes, $this->uri, $this->baseHref);
|
||||
$crawler->isHtml = $this->isHtml;
|
||||
@@ -1291,12 +1176,10 @@ class Crawler implements \Countable, \IteratorAggregate
|
||||
|
||||
private function canParseHtml5String(string $content): bool
|
||||
{
|
||||
if (null === $this->html5Parser) {
|
||||
return false;
|
||||
}
|
||||
if (false === ($pos = stripos($content, '<!doctype html>'))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$header = substr($content, 0, $pos);
|
||||
|
||||
return '' === $header || $this->isValidHtml5Heading($header);
|
||||
|
@@ -20,29 +20,17 @@ namespace Symfony\Component\DomCrawler\Field;
|
||||
*/
|
||||
class ChoiceFormField extends FormField
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $type;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $multiple;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $options;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $validationDisabled = false;
|
||||
private string $type;
|
||||
private bool $multiple;
|
||||
private array $options;
|
||||
private bool $validationDisabled = false;
|
||||
|
||||
/**
|
||||
* Returns true if the field should be included in the submitted values.
|
||||
*
|
||||
* @return bool true if the field should be included in the submitted values, false otherwise
|
||||
*/
|
||||
public function hasValue()
|
||||
public function hasValue(): bool
|
||||
{
|
||||
// don't send a value for unchecked checkboxes
|
||||
if (\in_array($this->type, ['checkbox', 'radio']) && null === $this->value) {
|
||||
@@ -54,10 +42,8 @@ class ChoiceFormField extends FormField
|
||||
|
||||
/**
|
||||
* Check if the current selected option is disabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDisabled()
|
||||
public function isDisabled(): bool
|
||||
{
|
||||
if (parent::isDisabled() && 'select' === $this->type) {
|
||||
return true;
|
||||
@@ -74,10 +60,8 @@ class ChoiceFormField extends FormField
|
||||
|
||||
/**
|
||||
* Sets the value of the field.
|
||||
*
|
||||
* @param string|array $value The value of the field
|
||||
*/
|
||||
public function select($value)
|
||||
public function select(string|array|bool $value)
|
||||
{
|
||||
$this->setValue($value);
|
||||
}
|
||||
@@ -113,11 +97,9 @@ class ChoiceFormField extends FormField
|
||||
/**
|
||||
* Sets the value of the field.
|
||||
*
|
||||
* @param string|array|bool|null $value The value of the field
|
||||
*
|
||||
* @throws \InvalidArgumentException When value type provided is not correct
|
||||
*/
|
||||
public function setValue($value)
|
||||
public function setValue(string|array|bool|null $value)
|
||||
{
|
||||
if ('checkbox' === $this->type && false === $value) {
|
||||
// uncheck
|
||||
@@ -175,20 +157,16 @@ class ChoiceFormField extends FormField
|
||||
|
||||
/**
|
||||
* Returns the type of the choice field (radio, select, or checkbox).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the field accepts multiple values.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isMultiple()
|
||||
public function isMultiple(): bool
|
||||
{
|
||||
return $this->multiple;
|
||||
}
|
||||
@@ -244,7 +222,7 @@ class ChoiceFormField extends FormField
|
||||
}
|
||||
|
||||
// if no option is selected and if it is a simple select box, take the first option as the value
|
||||
if (!$found && !$this->multiple && !empty($this->options)) {
|
||||
if (!$found && !$this->multiple && $this->options) {
|
||||
$this->value = $this->options[0]['value'];
|
||||
}
|
||||
}
|
||||
@@ -268,11 +246,9 @@ class ChoiceFormField extends FormField
|
||||
/**
|
||||
* Checks whether given value is in the existing options.
|
||||
*
|
||||
* @internal since Symfony 5.3
|
||||
*
|
||||
* @return bool
|
||||
* @internal
|
||||
*/
|
||||
public function containsOption(string $optionValue, array $options)
|
||||
public function containsOption(string $optionValue, array $options): bool
|
||||
{
|
||||
if ($this->validationDisabled) {
|
||||
return true;
|
||||
@@ -290,11 +266,9 @@ class ChoiceFormField extends FormField
|
||||
/**
|
||||
* Returns list of available field options.
|
||||
*
|
||||
* @internal since Symfony 5.3
|
||||
*
|
||||
* @return array
|
||||
* @internal
|
||||
*/
|
||||
public function availableOptionValues()
|
||||
public function availableOptionValues(): array
|
||||
{
|
||||
$values = [];
|
||||
|
||||
@@ -308,11 +282,11 @@ class ChoiceFormField extends FormField
|
||||
/**
|
||||
* Disables the internal validation of the field.
|
||||
*
|
||||
* @internal since Symfony 5.3
|
||||
* @internal
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function disableValidation()
|
||||
public function disableValidation(): static
|
||||
{
|
||||
$this->validationDisabled = true;
|
||||
|
||||
|
20
vendor/symfony/dom-crawler/Field/FormField.php
vendored
20
vendor/symfony/dom-crawler/Field/FormField.php
vendored
@@ -57,10 +57,8 @@ abstract class FormField
|
||||
|
||||
/**
|
||||
* Returns the label tag associated to the field or null if none.
|
||||
*
|
||||
* @return \DOMElement|null
|
||||
*/
|
||||
public function getLabel()
|
||||
public function getLabel(): ?\DOMElement
|
||||
{
|
||||
$xpath = new \DOMXPath($this->node->ownerDocument);
|
||||
|
||||
@@ -78,20 +76,16 @@ abstract class FormField
|
||||
|
||||
/**
|
||||
* Returns the name of the field.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the field.
|
||||
*
|
||||
* @return string|array|null
|
||||
*/
|
||||
public function getValue()
|
||||
public function getValue(): string|array|null
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
@@ -106,20 +100,16 @@ abstract class FormField
|
||||
|
||||
/**
|
||||
* Returns true if the field should be included in the submitted values.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasValue()
|
||||
public function hasValue(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current field is disabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDisabled()
|
||||
public function isDisabled(): bool
|
||||
{
|
||||
return $this->node->hasAttribute('disabled');
|
||||
}
|
||||
|
77
vendor/symfony/dom-crawler/Form.php
vendored
77
vendor/symfony/dom-crawler/Form.php
vendored
@@ -21,20 +21,9 @@ use Symfony\Component\DomCrawler\Field\FormField;
|
||||
*/
|
||||
class Form extends Link implements \ArrayAccess
|
||||
{
|
||||
/**
|
||||
* @var \DOMElement
|
||||
*/
|
||||
private $button;
|
||||
|
||||
/**
|
||||
* @var FormFieldRegistry
|
||||
*/
|
||||
private $fields;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $baseHref;
|
||||
private \DOMElement $button;
|
||||
private FormFieldRegistry $fields;
|
||||
private ?string $baseHref;
|
||||
|
||||
/**
|
||||
* @param \DOMElement $node A \DOMElement instance
|
||||
@@ -54,10 +43,8 @@ class Form extends Link implements \ArrayAccess
|
||||
|
||||
/**
|
||||
* Gets the form node associated with this form.
|
||||
*
|
||||
* @return \DOMElement
|
||||
*/
|
||||
public function getFormNode()
|
||||
public function getFormNode(): \DOMElement
|
||||
{
|
||||
return $this->node;
|
||||
}
|
||||
@@ -69,7 +56,7 @@ class Form extends Link implements \ArrayAccess
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setValues(array $values)
|
||||
public function setValues(array $values): static
|
||||
{
|
||||
foreach ($values as $name => $value) {
|
||||
$this->fields->set($name, $value);
|
||||
@@ -82,10 +69,8 @@ class Form extends Link implements \ArrayAccess
|
||||
* Gets the field values.
|
||||
*
|
||||
* The returned array does not include file fields (@see getFiles).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getValues()
|
||||
public function getValues(): array
|
||||
{
|
||||
$values = [];
|
||||
foreach ($this->fields->all() as $name => $field) {
|
||||
@@ -103,10 +88,8 @@ class Form extends Link implements \ArrayAccess
|
||||
|
||||
/**
|
||||
* Gets the file field values.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFiles()
|
||||
public function getFiles(): array
|
||||
{
|
||||
if (!\in_array($this->getMethod(), ['POST', 'PUT', 'DELETE', 'PATCH'])) {
|
||||
return [];
|
||||
@@ -132,10 +115,8 @@ class Form extends Link implements \ArrayAccess
|
||||
*
|
||||
* This method converts fields with the array notation
|
||||
* (like foo[bar] to arrays) like PHP does.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPhpValues()
|
||||
public function getPhpValues(): array
|
||||
{
|
||||
$values = [];
|
||||
foreach ($this->getValues() as $name => $value) {
|
||||
@@ -159,10 +140,8 @@ class Form extends Link implements \ArrayAccess
|
||||
* (@see getPhpValues), rather than uploaded files found in $_FILES.
|
||||
* For a compound file field foo[bar] it will create foo[bar][name],
|
||||
* instead of foo[name][bar] which would be found in $_FILES.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPhpFiles()
|
||||
public function getPhpFiles(): array
|
||||
{
|
||||
$values = [];
|
||||
foreach ($this->getFiles() as $name => $value) {
|
||||
@@ -195,10 +174,8 @@ class Form extends Link implements \ArrayAccess
|
||||
* The returned URI is not the same as the form "action" attribute.
|
||||
* This method merges the value if the method is GET to mimics
|
||||
* browser behavior.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUri()
|
||||
public function getUri(): string
|
||||
{
|
||||
$uri = parent::getUri();
|
||||
|
||||
@@ -219,7 +196,7 @@ class Form extends Link implements \ArrayAccess
|
||||
return $uri;
|
||||
}
|
||||
|
||||
protected function getRawUri()
|
||||
protected function getRawUri(): string
|
||||
{
|
||||
// If the form was created from a button rather than the form node, check for HTML5 action overrides
|
||||
if ($this->button !== $this->node && $this->button->getAttribute('formaction')) {
|
||||
@@ -233,10 +210,8 @@ class Form extends Link implements \ArrayAccess
|
||||
* Gets the form method.
|
||||
*
|
||||
* If no method is defined in the form, GET is returned.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod()
|
||||
public function getMethod(): string
|
||||
{
|
||||
if (null !== $this->method) {
|
||||
return $this->method;
|
||||
@@ -262,10 +237,8 @@ class Form extends Link implements \ArrayAccess
|
||||
|
||||
/**
|
||||
* Returns true if the named field exists.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has(string $name)
|
||||
public function has(string $name): bool
|
||||
{
|
||||
return $this->fields->has($name);
|
||||
}
|
||||
@@ -285,7 +258,7 @@ class Form extends Link implements \ArrayAccess
|
||||
*
|
||||
* @throws \InvalidArgumentException When field is not present in this form
|
||||
*/
|
||||
public function get(string $name)
|
||||
public function get(string $name): FormField|array
|
||||
{
|
||||
return $this->fields->get($name);
|
||||
}
|
||||
@@ -303,7 +276,7 @@ class Form extends Link implements \ArrayAccess
|
||||
*
|
||||
* @return FormField[]
|
||||
*/
|
||||
public function all()
|
||||
public function all(): array
|
||||
{
|
||||
return $this->fields->all();
|
||||
}
|
||||
@@ -312,11 +285,8 @@ class Form extends Link implements \ArrayAccess
|
||||
* Returns true if the named field exists.
|
||||
*
|
||||
* @param string $name The field name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($name)
|
||||
public function offsetExists(mixed $name): bool
|
||||
{
|
||||
return $this->has($name);
|
||||
}
|
||||
@@ -330,8 +300,7 @@ class Form extends Link implements \ArrayAccess
|
||||
*
|
||||
* @throws \InvalidArgumentException if the field does not exist
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($name)
|
||||
public function offsetGet(mixed $name): FormField|array
|
||||
{
|
||||
return $this->fields->get($name);
|
||||
}
|
||||
@@ -342,12 +311,9 @@ class Form extends Link implements \ArrayAccess
|
||||
* @param string $name The field name
|
||||
* @param string|array $value The value of the field
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \InvalidArgumentException if the field does not exist
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($name, $value)
|
||||
public function offsetSet(mixed $name, mixed $value): void
|
||||
{
|
||||
$this->fields->set($name, $value);
|
||||
}
|
||||
@@ -356,11 +322,8 @@ class Form extends Link implements \ArrayAccess
|
||||
* Removes a field from the form.
|
||||
*
|
||||
* @param string $name The field name
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($name)
|
||||
public function offsetUnset(mixed $name): void
|
||||
{
|
||||
$this->fields->remove($name);
|
||||
}
|
||||
@@ -370,7 +333,7 @@ class Form extends Link implements \ArrayAccess
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function disableValidation()
|
||||
public function disableValidation(): static
|
||||
{
|
||||
foreach ($this->fields->all() as $field) {
|
||||
if ($field instanceof Field\ChoiceFormField) {
|
||||
|
13
vendor/symfony/dom-crawler/FormFieldRegistry.php
vendored
13
vendor/symfony/dom-crawler/FormFieldRegistry.php
vendored
@@ -20,9 +20,8 @@ use Symfony\Component\DomCrawler\Field\FormField;
|
||||
*/
|
||||
class FormFieldRegistry
|
||||
{
|
||||
private $fields = [];
|
||||
|
||||
private $base = '';
|
||||
private array $fields = [];
|
||||
private string $base = '';
|
||||
|
||||
/**
|
||||
* Adds a field to the registry.
|
||||
@@ -70,7 +69,7 @@ class FormFieldRegistry
|
||||
*
|
||||
* @throws \InvalidArgumentException if the field does not exist
|
||||
*/
|
||||
public function &get(string $name)
|
||||
public function &get(string $name): FormField|array
|
||||
{
|
||||
$segments = $this->getSegments($name);
|
||||
$target = &$this->fields;
|
||||
@@ -94,7 +93,7 @@ class FormFieldRegistry
|
||||
$this->get($name);
|
||||
|
||||
return true;
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
} catch (\InvalidArgumentException) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -102,11 +101,9 @@ class FormFieldRegistry
|
||||
/**
|
||||
* Set the value of a field based on the fully qualified name and its children.
|
||||
*
|
||||
* @param mixed $value The value
|
||||
*
|
||||
* @throws \InvalidArgumentException if the field does not exist
|
||||
*/
|
||||
public function set(string $name, $value)
|
||||
public function set(string $name, mixed $value)
|
||||
{
|
||||
$target = &$this->get($name);
|
||||
if ((!\is_array($value) && $target instanceof Field\FormField) || $target instanceof Field\ChoiceFormField) {
|
||||
|
2
vendor/symfony/dom-crawler/Image.php
vendored
2
vendor/symfony/dom-crawler/Image.php
vendored
@@ -21,7 +21,7 @@ class Image extends AbstractUriElement
|
||||
parent::__construct($node, $currentUri, 'GET');
|
||||
}
|
||||
|
||||
protected function getRawUri()
|
||||
protected function getRawUri(): string
|
||||
{
|
||||
return $this->node->getAttribute('src');
|
||||
}
|
||||
|
2
vendor/symfony/dom-crawler/Link.php
vendored
2
vendor/symfony/dom-crawler/Link.php
vendored
@@ -18,7 +18,7 @@ namespace Symfony\Component\DomCrawler;
|
||||
*/
|
||||
class Link extends AbstractUriElement
|
||||
{
|
||||
protected function getRawUri()
|
||||
protected function getRawUri(): string
|
||||
{
|
||||
return $this->node->getAttribute('href');
|
||||
}
|
||||
|
@@ -16,9 +16,9 @@ use Symfony\Component\DomCrawler\Crawler;
|
||||
|
||||
final class CrawlerSelectorAttributeValueSame extends Constraint
|
||||
{
|
||||
private $selector;
|
||||
private $attribute;
|
||||
private $expectedText;
|
||||
private string $selector;
|
||||
private string $attribute;
|
||||
private string $expectedText;
|
||||
|
||||
public function __construct(string $selector, string $attribute, string $expectedText)
|
||||
{
|
||||
@@ -27,9 +27,6 @@ final class CrawlerSelectorAttributeValueSame extends Constraint
|
||||
$this->expectedText = $expectedText;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return sprintf('has a node matching selector "%s" with attribute "%s" of value "%s"', $this->selector, $this->attribute, $this->expectedText);
|
||||
@@ -37,8 +34,6 @@ final class CrawlerSelectorAttributeValueSame extends Constraint
|
||||
|
||||
/**
|
||||
* @param Crawler $crawler
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function matches($crawler): bool
|
||||
{
|
||||
@@ -52,8 +47,6 @@ final class CrawlerSelectorAttributeValueSame extends Constraint
|
||||
|
||||
/**
|
||||
* @param Crawler $crawler
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function failureDescription($crawler): string
|
||||
{
|
||||
|
@@ -16,16 +16,13 @@ use Symfony\Component\DomCrawler\Crawler;
|
||||
|
||||
final class CrawlerSelectorExists extends Constraint
|
||||
{
|
||||
private $selector;
|
||||
private string $selector;
|
||||
|
||||
public function __construct(string $selector)
|
||||
{
|
||||
$this->selector = $selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return sprintf('matches selector "%s"', $this->selector);
|
||||
@@ -33,8 +30,6 @@ final class CrawlerSelectorExists extends Constraint
|
||||
|
||||
/**
|
||||
* @param Crawler $crawler
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function matches($crawler): bool
|
||||
{
|
||||
@@ -43,8 +38,6 @@ final class CrawlerSelectorExists extends Constraint
|
||||
|
||||
/**
|
||||
* @param Crawler $crawler
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function failureDescription($crawler): string
|
||||
{
|
||||
|
@@ -16,10 +16,10 @@ use Symfony\Component\DomCrawler\Crawler;
|
||||
|
||||
final class CrawlerSelectorTextContains extends Constraint
|
||||
{
|
||||
private $selector;
|
||||
private $expectedText;
|
||||
private $hasNode = false;
|
||||
private $nodeText;
|
||||
private string $selector;
|
||||
private string $expectedText;
|
||||
private bool $hasNode = false;
|
||||
private string $nodeText;
|
||||
|
||||
public function __construct(string $selector, string $expectedText)
|
||||
{
|
||||
@@ -27,9 +27,6 @@ final class CrawlerSelectorTextContains extends Constraint
|
||||
$this->expectedText = $expectedText;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
if ($this->hasNode) {
|
||||
@@ -41,8 +38,6 @@ final class CrawlerSelectorTextContains extends Constraint
|
||||
|
||||
/**
|
||||
* @param Crawler $crawler
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function matches($crawler): bool
|
||||
{
|
||||
@@ -56,13 +51,11 @@ final class CrawlerSelectorTextContains extends Constraint
|
||||
$this->hasNode = true;
|
||||
$this->nodeText = $crawler->text(null, true);
|
||||
|
||||
return false !== mb_strpos($this->nodeText, $this->expectedText);
|
||||
return str_contains($this->nodeText, $this->expectedText);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Crawler $crawler
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function failureDescription($crawler): string
|
||||
{
|
||||
|
@@ -16,8 +16,8 @@ use Symfony\Component\DomCrawler\Crawler;
|
||||
|
||||
final class CrawlerSelectorTextSame extends Constraint
|
||||
{
|
||||
private $selector;
|
||||
private $expectedText;
|
||||
private string $selector;
|
||||
private string $expectedText;
|
||||
|
||||
public function __construct(string $selector, string $expectedText)
|
||||
{
|
||||
@@ -25,9 +25,6 @@ final class CrawlerSelectorTextSame extends Constraint
|
||||
$this->expectedText = $expectedText;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return sprintf('has a node matching selector "%s" with content "%s"', $this->selector, $this->expectedText);
|
||||
@@ -35,8 +32,6 @@ final class CrawlerSelectorTextSame extends Constraint
|
||||
|
||||
/**
|
||||
* @param Crawler $crawler
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function matches($crawler): bool
|
||||
{
|
||||
@@ -50,8 +45,6 @@ final class CrawlerSelectorTextSame extends Constraint
|
||||
|
||||
/**
|
||||
* @param Crawler $crawler
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function failureDescription($crawler): string
|
||||
{
|
||||
|
4
vendor/symfony/dom-crawler/UriResolver.php
vendored
4
vendor/symfony/dom-crawler/UriResolver.php
vendored
@@ -58,7 +58,7 @@ class UriResolver
|
||||
}
|
||||
|
||||
// absolute URL with relative schema
|
||||
if (0 === strpos($uri, '//')) {
|
||||
if (str_starts_with($uri, '//')) {
|
||||
return preg_replace('#^([^/]*)//.*$#', '$1', $baseUriCleaned).$uri;
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ class UriResolver
|
||||
return $path;
|
||||
}
|
||||
|
||||
if ('.' === substr($path, -1)) {
|
||||
if (str_ends_with($path, '.')) {
|
||||
$path .= '/';
|
||||
}
|
||||
|
||||
|
11
vendor/symfony/dom-crawler/composer.json
vendored
11
vendor/symfony/dom-crawler/composer.json
vendored
@@ -16,18 +16,13 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/deprecation-contracts": "^2.1|^3",
|
||||
"php": ">=8.1",
|
||||
"symfony/polyfill-ctype": "~1.8",
|
||||
"symfony/polyfill-mbstring": "~1.0",
|
||||
"symfony/polyfill-php80": "^1.16"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/css-selector": "^4.4|^5.0|^6.0",
|
||||
"masterminds/html5": "^2.6"
|
||||
},
|
||||
"conflict": {
|
||||
"masterminds/html5": "<2.6"
|
||||
"require-dev": {
|
||||
"symfony/css-selector": "^5.4|^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/css-selector": ""
|
||||
|
Reference in New Issue
Block a user