From 580b126a356ca633c1c54d512dd8c6aa7967e146 Mon Sep 17 00:00:00 2001 From: Amrouche Hamza Date: Wed, 3 Jul 2019 08:01:17 +0200 Subject: [PATCH] [DomCrawler] [5.0] add type-hint whenever possible --- .../DomCrawler/AbstractUriElement.php | 2 +- src/Symfony/Component/DomCrawler/Crawler.php | 102 +++++------------- .../DomCrawler/Field/ChoiceFormField.php | 5 +- .../DomCrawler/Field/FileFormField.php | 14 +-- .../Component/DomCrawler/Field/FormField.php | 4 +- src/Symfony/Component/DomCrawler/Form.php | 12 +-- .../DomCrawler/FormFieldRegistry.php | 42 +++----- .../DomCrawler/Tests/AbstractCrawlerTest.php | 4 +- .../Tests/Field/FileFormFieldTest.php | 2 +- 9 files changed, 52 insertions(+), 135 deletions(-) diff --git a/src/Symfony/Component/DomCrawler/AbstractUriElement.php b/src/Symfony/Component/DomCrawler/AbstractUriElement.php index ead9dca25b..3dc67c7cab 100644 --- a/src/Symfony/Component/DomCrawler/AbstractUriElement.php +++ b/src/Symfony/Component/DomCrawler/AbstractUriElement.php @@ -136,7 +136,7 @@ abstract class AbstractUriElement * * @return string */ - protected function canonicalizePath($path) + protected function canonicalizePath(string $path) { if ('' === $path || '/' === $path) { return $path; diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php index 4aa778bfa9..b4479450e8 100644 --- a/src/Symfony/Component/DomCrawler/Crawler.php +++ b/src/Symfony/Component/DomCrawler/Crawler.php @@ -61,9 +61,7 @@ class Crawler implements \Countable, \IteratorAggregate private $html5Parser; /** - * @param mixed $node A Node to use as the base for the crawling - * @param string $uri The current URI - * @param string $baseHref The base href value + * @param mixed $node A Node to use as the base for the crawling */ public function __construct($node = null, string $uri = null, string $baseHref = null) { @@ -134,11 +132,8 @@ class Crawler implements \Countable, \IteratorAggregate * If the charset is not set via the content type, it is assumed to be UTF-8, * or ISO-8859-1 as a fallback, which is the default charset defined by the * HTTP 1.1 specification. - * - * @param string $content A string to parse as HTML/XML - * @param string|null $type The content type of the string */ - public function addContent($content, $type = null) + public function addContent(string $content, string $type = null) { if (empty($type)) { $type = 0 === strpos($content, 'html5Parser && strspn($content, " \t\r\n") === stripos($content, '') ? $this->parseHtml5($content, $charset) : $this->parseXhtml($content, $charset); @@ -219,13 +211,11 @@ class Crawler implements \Countable, \IteratorAggregate * and then, get the errors via libxml_get_errors(). Be * sure to clear errors with libxml_clear_errors() afterward. * - * @param string $content The XML content - * @param string $charset The charset - * @param int $options Bitwise OR of the libxml option constants - * LIBXML_PARSEHUGE is dangerous, see - * http://symfony.com/blog/security-release-symfony-2-0-17-released + * @param int $options Bitwise OR of the libxml option constants + * LIBXML_PARSEHUGE is dangerous, see + * http://symfony.com/blog/security-release-symfony-2-0-17-released */ - public function addXmlContent($content, $charset = 'UTF-8', $options = LIBXML_NONET) + 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)) { @@ -318,11 +308,9 @@ class Crawler implements \Countable, \IteratorAggregate /** * Returns a node given its position in the node list. * - * @param int $position The position - * * @return self */ - public function eq($position) + public function eq(int $position) { if (isset($this->nodes[$position])) { return $this->createSubCrawler($this->nodes[$position]); @@ -360,12 +348,9 @@ class Crawler implements \Countable, \IteratorAggregate /** * Slices the list of nodes by $offset and $length. * - * @param int $offset - * @param int $length - * * @return self */ - public function slice($offset = 0, $length = null) + public function slice(int $offset = 0, int $length = null) { return $this->createSubCrawler(\array_slice($this->nodes, $offset, $length)); } @@ -487,8 +472,6 @@ class Crawler implements \Countable, \IteratorAggregate /** * Returns the children nodes of the current selection. * - * @param string|null $selector An optional CSS selector to filter children - * * @return self * * @throws \InvalidArgumentException When current node is empty @@ -515,13 +498,11 @@ class Crawler implements \Countable, \IteratorAggregate /** * Returns the attribute value of the first node of the list. * - * @param string $attribute The attribute name - * * @return string|null The attribute value or null if the attribute does not exist * * @throws \InvalidArgumentException When current node is empty */ - public function attr($attribute) + public function attr(string $attribute) { if (!$this->nodes) { throw new \InvalidArgumentException('The current node list is empty.'); @@ -610,11 +591,9 @@ 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. * - * @param string $xpath An XPath expression - * * @return array|Crawler An array of evaluation results or a new Crawler instance */ - public function evaluate($xpath) + public function evaluate(string $xpath) { if (null === $this->document) { throw new \LogicException('Cannot evaluate the expression on an uninitialized crawler.'); @@ -643,13 +622,10 @@ class Crawler implements \Countable, \IteratorAggregate * * $crawler->filter('h1 a')->extract(['_text', 'href']); * - * @param array $attributes An array of attributes - * * @return array An array of extracted values */ - public function extract($attributes) + public function extract(array $attributes) { - $attributes = (array) $attributes; $count = \count($attributes); $data = []; @@ -679,11 +655,9 @@ class Crawler implements \Countable, \IteratorAggregate * This means that a child selector "div" or "./div" will match only * the div elements of the current crawler, not their children. * - * @param string $xpath An XPath expression - * * @return self */ - public function filterXPath($xpath) + public function filterXPath(string $xpath) { $xpath = $this->relativize($xpath); @@ -700,13 +674,11 @@ class Crawler implements \Countable, \IteratorAggregate * * This method only works if you have installed the CssSelector Symfony Component. * - * @param string $selector A CSS selector - * * @return self * * @throws \RuntimeException if the CssSelector Component is not available */ - public function filter($selector) + public function filter(string $selector) { $converter = $this->createCssSelectorConverter(); @@ -717,11 +689,9 @@ class Crawler implements \Countable, \IteratorAggregate /** * Selects links by name or alt value for clickable images. * - * @param string $value The link text - * * @return self */ - public function selectLink($value) + public function selectLink(string $value) { 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.' ')) @@ -731,11 +701,9 @@ class Crawler implements \Countable, \IteratorAggregate /** * Selects images by alt value. * - * @param string $value The image alt - * * @return self A new instance of Crawler with the filtered list of nodes */ - public function selectImage($value) + public function selectImage(string $value) { $xpath = sprintf('descendant-or-self::img[contains(normalize-space(string(@alt)), %s)]', static::xpathLiteral($value)); @@ -745,11 +713,9 @@ class Crawler implements \Countable, \IteratorAggregate /** * Selects a button by name or alt value for images. * - * @param string $value The button text - * * @return self */ - public function selectButton($value) + public function selectButton(string $value) { 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)) @@ -759,13 +725,11 @@ class Crawler implements \Countable, \IteratorAggregate /** * Returns a Link object for the first node in the list. * - * @param string $method The method for the link (get by default) - * * @return Link A Link instance * * @throws \InvalidArgumentException If the current node list is empty or the selected node is not instance of DOMElement */ - public function link($method = 'get') + public function link(string $method = 'get') { if (!$this->nodes) { throw new \InvalidArgumentException('The current node list is empty.'); @@ -845,14 +809,11 @@ class Crawler implements \Countable, \IteratorAggregate /** * Returns a Form object for the first node in the list. * - * @param array $values An array of values for the form fields - * @param string $method The method for the form - * * @return Form A Form instance * * @throws \InvalidArgumentException If the current node list is empty or the selected node is not instance of DOMElement */ - public function form(array $values = null, $method = null) + public function form(array $values = null, string $method = null) { if (!$this->nodes) { throw new \InvalidArgumentException('The current node list is empty.'); @@ -875,19 +836,13 @@ class Crawler implements \Countable, \IteratorAggregate /** * Overloads a default namespace prefix to be used with XPath and CSS expressions. - * - * @param string $prefix */ - public function setDefaultNamespacePrefix($prefix) + public function setDefaultNamespacePrefix(string $prefix) { $this->defaultNamespacePrefix = $prefix; } - /** - * @param string $prefix - * @param string $namespace - */ - public function registerNamespace($prefix, $namespace) + public function registerNamespace(string $prefix, string $namespace) { $this->namespaces[$prefix] = $namespace; } @@ -909,11 +864,9 @@ class Crawler implements \Countable, \IteratorAggregate * //prints concat('a', "'", 'b"c') * * - * @param string $s String to be escaped - * * @return string Converted string */ - public static function xpathLiteral($s) + public static function xpathLiteral(string $s) { if (false === strpos($s, "'")) { return sprintf("'%s'", $s); @@ -944,11 +897,9 @@ class Crawler implements \Countable, \IteratorAggregate * * The XPath expression should already be processed to apply it in the context of each node. * - * @param string $xpath - * * @return self */ - private function filterRelativeXPath($xpath) + private function filterRelativeXPath(string $xpath) { $prefixes = $this->findNamespacePrefixes($xpath); @@ -1053,11 +1004,9 @@ class Crawler implements \Countable, \IteratorAggregate } /** - * @param int $position - * * @return \DOMElement|null */ - public function getNode($position) + public function getNode(int $position) { if (isset($this->nodes[$position])) { return $this->nodes[$position]; @@ -1082,11 +1031,10 @@ class Crawler implements \Countable, \IteratorAggregate /** * @param \DOMElement $node - * @param string $siblingDir * * @return array */ - protected function sibling($node, $siblingDir = 'nextSibling') + protected function sibling($node, string $siblingDir = 'nextSibling') { $nodes = []; diff --git a/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php b/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php index 8fa1903755..9a8ba553bb 100644 --- a/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php +++ b/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php @@ -270,12 +270,9 @@ class ChoiceFormField extends FormField /** * Checks whether given value is in the existing options. * - * @param string $optionValue - * @param array $options - * * @return bool */ - public function containsOption($optionValue, $options) + public function containsOption(string $optionValue, array $options) { if ($this->validationDisabled) { return true; diff --git a/src/Symfony/Component/DomCrawler/Field/FileFormField.php b/src/Symfony/Component/DomCrawler/Field/FileFormField.php index 9e21c9c4b9..f38aca3f4e 100644 --- a/src/Symfony/Component/DomCrawler/Field/FileFormField.php +++ b/src/Symfony/Component/DomCrawler/Field/FileFormField.php @@ -25,7 +25,7 @@ class FileFormField extends FormField * * @throws \InvalidArgumentException When error code doesn't exist */ - public function setErrorCode($error) + public function setErrorCode(int $error) { $codes = [UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE, UPLOAD_ERR_PARTIAL, UPLOAD_ERR_NO_FILE, UPLOAD_ERR_NO_TMP_DIR, UPLOAD_ERR_CANT_WRITE, UPLOAD_ERR_EXTENSION]; if (!\in_array($error, $codes)) { @@ -37,20 +37,16 @@ class FileFormField extends FormField /** * Sets the value of the field. - * - * @param string $value The value of the field */ - public function upload($value) + public function upload(?string $value) { $this->setValue($value); } /** * Sets the value of the field. - * - * @param string $value The value of the field */ - public function setValue($value) + public function setValue(?string $value) { if (null !== $value && is_readable($value)) { $error = UPLOAD_ERR_OK; @@ -80,10 +76,8 @@ class FileFormField extends FormField /** * Sets path to the file as string for simulating HTTP request. - * - * @param string $path The path to the file */ - public function setFilePath($path) + public function setFilePath(string $path) { parent::setValue($path); } diff --git a/src/Symfony/Component/DomCrawler/Field/FormField.php b/src/Symfony/Component/DomCrawler/Field/FormField.php index 33c0bbeac0..60bfe6b816 100644 --- a/src/Symfony/Component/DomCrawler/Field/FormField.php +++ b/src/Symfony/Component/DomCrawler/Field/FormField.php @@ -99,10 +99,8 @@ abstract class FormField /** * Sets the value of the field. - * - * @param string $value The value of the field */ - public function setValue($value) + public function setValue(?string $value) { $this->value = (string) $value; } diff --git a/src/Symfony/Component/DomCrawler/Form.php b/src/Symfony/Component/DomCrawler/Form.php index 13d3bc70a8..8205923b76 100644 --- a/src/Symfony/Component/DomCrawler/Form.php +++ b/src/Symfony/Component/DomCrawler/Form.php @@ -263,21 +263,17 @@ class Form extends Link implements \ArrayAccess /** * Returns true if the named field exists. * - * @param string $name The field name - * * @return bool true if the field exists, false otherwise */ - public function has($name) + public function has(string $name) { return $this->fields->has($name); } /** * Removes a field from the form. - * - * @param string $name The field name */ - public function remove($name) + public function remove(string $name) { $this->fields->remove($name); } @@ -285,13 +281,11 @@ class Form extends Link implements \ArrayAccess /** * Gets a named field. * - * @param string $name The field name - * * @return FormField The field instance * * @throws \InvalidArgumentException When field is not present in this form */ - public function get($name) + public function get(string $name) { return $this->fields->get($name); } diff --git a/src/Symfony/Component/DomCrawler/FormFieldRegistry.php b/src/Symfony/Component/DomCrawler/FormFieldRegistry.php index 8f432cfbbb..9f8574562d 100644 --- a/src/Symfony/Component/DomCrawler/FormFieldRegistry.php +++ b/src/Symfony/Component/DomCrawler/FormFieldRegistry.php @@ -22,7 +22,7 @@ class FormFieldRegistry { private $fields = []; - private $base; + private $base = ''; /** * Adds a field to the registry. @@ -47,11 +47,9 @@ class FormFieldRegistry } /** - * Removes a field and its children from the registry. - * - * @param string $name The fully qualified name of the base field + * Removes a field based on the fully qualifed name and its children from the registry. */ - public function remove($name) + public function remove(string $name) { $segments = $this->getSegments($name); $target = &$this->fields; @@ -66,15 +64,13 @@ class FormFieldRegistry } /** - * Returns the value of the field and its children. - * - * @param string $name The fully qualified name of the field + * Returns the value of the field based on the fully qualifed name and its children. * * @return mixed The value of the field * * @throws \InvalidArgumentException if the field does not exist */ - public function &get($name) + public function &get(string $name) { $segments = $this->getSegments($name); $target = &$this->fields; @@ -90,13 +86,11 @@ class FormFieldRegistry } /** - * Tests whether the form has the given field. - * - * @param string $name The fully qualified name of the field + * Tests whether the form has the given field based on the fully qualified name. * * @return bool Whether the form has the given field */ - public function has($name) + public function has(string $name) { try { $this->get($name); @@ -108,14 +102,13 @@ class FormFieldRegistry } /** - * Set the value of a field and its children. + * Set the value of a field based on the fully qualified name and its children. * - * @param string $name The fully qualified name of the field - * @param mixed $value The value + * @param mixed $value The value * * @throws \InvalidArgumentException if the field does not exist */ - public function set($name, $value) + public function set(string $name, $value) { $target = &$this->get($name); if ((!\is_array($value) && $target instanceof Field\FormField) || $target instanceof Field\ChoiceFormField) { @@ -146,12 +139,11 @@ class FormFieldRegistry * This function is made private because it allows overriding the $base and * the $values properties without any type checking. * - * @param string $base The fully qualified name of the base field - * @param array $values The values of the fields + * @param array $values The values of the fields * * @return static */ - private static function create($base, array $values) + private static function create(string $base, array $values) { $registry = new static(); $registry->base = $base; @@ -163,13 +155,9 @@ class FormFieldRegistry /** * Transforms a PHP array in a list of fully qualified name / value. * - * @param array $array The PHP array - * @param string $base The name of the base field - * @param array $output The initial values - * * @return array The list of fields as [string] Fully qualified name => (mixed) value) */ - private function walk(array $array, $base = '', array &$output = []) + private function walk(array $array, string $base = '', array &$output = []) { foreach ($array as $k => $v) { $path = empty($base) ? $k : sprintf('%s[%s]', $base, $k); @@ -188,11 +176,9 @@ class FormFieldRegistry * * getSegments('base[foo][3][]') = ['base', 'foo, '3', '']; * - * @param string $name The name of the field - * * @return string[] The list of segments */ - private function getSegments($name) + private function getSegments(string $name) { if (preg_match('/^(?P[^[]+)(?P(\[.*)|$)/', $name, $m)) { $segments = [$m['base']]; diff --git a/src/Symfony/Component/DomCrawler/Tests/AbstractCrawlerTest.php b/src/Symfony/Component/DomCrawler/Tests/AbstractCrawlerTest.php index d4b6d8886d..2cda8031c5 100644 --- a/src/Symfony/Component/DomCrawler/Tests/AbstractCrawlerTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/AbstractCrawlerTest.php @@ -364,11 +364,11 @@ abstract class AbstractCrawlerTest extends TestCase { $crawler = $this->createTestCrawler()->filterXPath('//ul[1]/li'); - $this->assertEquals(['One', 'Two', 'Three'], $crawler->extract('_text'), '->extract() returns an array of extracted data from the node list'); + $this->assertEquals(['One', 'Two', 'Three'], $crawler->extract(['_text']), '->extract() returns an array of extracted data from the node list'); $this->assertEquals([['One', 'first'], ['Two', ''], ['Three', '']], $crawler->extract(['_text', 'class']), '->extract() returns an array of extracted data from the node list'); $this->assertEquals([[], [], []], $crawler->extract([]), '->extract() returns empty arrays if the attribute list is empty'); - $this->assertEquals([], $this->createTestCrawler()->filterXPath('//ol')->extract('_text'), '->extract() returns an empty array if the node list is empty'); + $this->assertEquals([], $this->createTestCrawler()->filterXPath('//ol')->extract(['_text']), '->extract() returns an empty array if the node list is empty'); $this->assertEquals([['One', 'li'], ['Two', 'li'], ['Three', 'li']], $crawler->extract(['_text', '_name']), '->extract() returns an array of extracted data from the node list'); } diff --git a/src/Symfony/Component/DomCrawler/Tests/Field/FileFormFieldTest.php b/src/Symfony/Component/DomCrawler/Tests/Field/FileFormFieldTest.php index 03ab383cbb..32756c48ad 100644 --- a/src/Symfony/Component/DomCrawler/Tests/Field/FileFormFieldTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/Field/FileFormFieldTest.php @@ -96,7 +96,7 @@ class FileFormFieldTest extends FormFieldTestCase $this->assertEquals(UPLOAD_ERR_FORM_SIZE, $value['error'], '->setErrorCode() sets the file input field error code'); try { - $field->setErrorCode('foobar'); + $field->setErrorCode(12345); $this->fail('->setErrorCode() throws a \InvalidArgumentException if the error code is not valid'); } catch (\InvalidArgumentException $e) { $this->assertTrue(true, '->setErrorCode() throws a \InvalidArgumentException if the error code is not valid');