2026-02-25 06:59:34 +00:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\DomCrawler ;
/**
* Any HTML element that can link to an URI .
*
* @ author Fabien Potencier < fabien @ symfony . com >
*/
abstract class AbstractUriElement
{
2026-02-27 00:03:00 +00:00
protected \DOMElement $node ;
protected ? string $method ;
2026-02-25 06:59:34 +00:00
/**
* @ param \DOMElement $node A \DOMElement instance
* @ param string | null $currentUri The URI of the page where the link is embedded ( or the base href )
* @ param string | null $method The method to use for the link ( GET by default )
*
* @ throws \InvalidArgumentException if the node is not a link
*/
2026-02-27 00:03:00 +00:00
public function __construct (
\DOMElement $node ,
protected ? string $currentUri = null ,
? string $method = 'GET' ,
) {
2026-02-25 06:59:34 +00:00
$this -> setNode ( $node );
$this -> method = $method ? strtoupper ( $method ) : null ;
2026-02-27 00:03:00 +00:00
$elementUriIsRelative = ! parse_url ( trim ( $this -> getRawUri ()), \PHP_URL_SCHEME );
$baseUriIsAbsolute = null !== $this -> currentUri && \in_array ( strtolower ( substr ( $this -> currentUri , 0 , 4 )), [ 'http' , 'file' ], true );
2026-02-25 06:59:34 +00:00
if ( $elementUriIsRelative && ! $baseUriIsAbsolute ) {
2026-02-27 00:03:00 +00:00
throw new \InvalidArgumentException ( \sprintf ( 'The URL of the element is relative, so you must define its base URI passing an absolute URL to the constructor of the "%s" class ("%s" was passed).' , __CLASS__ , $this -> currentUri ));
2026-02-25 06:59:34 +00:00
}
}
/**
* Gets the node associated with this link .
*/
2026-02-27 00:03:00 +00:00
public function getNode () : \DOMElement
2026-02-25 06:59:34 +00:00
{
return $this -> node ;
}
/**
* Gets the method associated with this link .
*/
2026-02-27 00:03:00 +00:00
public function getMethod () : string
2026-02-25 06:59:34 +00:00
{
return $this -> method ? ? 'GET' ;
}
/**
* Gets the URI associated with this link .
*/
2026-02-27 00:03:00 +00:00
public function getUri () : string
2026-02-25 06:59:34 +00:00
{
2026-02-27 00:03:00 +00:00
return UriResolver :: resolve ( $this -> getRawUri (), $this -> currentUri );
2026-02-25 06:59:34 +00:00
}
/**
* Returns raw URI data .
*/
2026-02-27 00:03:00 +00:00
abstract protected function getRawUri () : string ;
2026-02-25 06:59:34 +00:00
/**
* Returns the canonicalized URI path ( see RFC 3986 , section 5.2 . 4 ) .
*
* @ param string $path URI path
*/
2026-02-27 00:03:00 +00:00
protected function canonicalizePath ( string $path ) : string
2026-02-25 06:59:34 +00:00
{
if ( '' === $path || '/' === $path ) {
return $path ;
}
if ( str_ends_with ( $path , '.' )) {
$path .= '/' ;
}
$output = [];
foreach ( explode ( '/' , $path ) as $segment ) {
if ( '..' === $segment ) {
array_pop ( $output );
} elseif ( '.' !== $segment ) {
$output [] = $segment ;
}
}
return implode ( '/' , $output );
}
/**
* Sets current \DOMElement instance .
*
* @ param \DOMElement $node A \DOMElement instance
*
* @ throws \LogicException If given node is not an anchor
*/
2026-02-27 00:03:00 +00:00
abstract protected function setNode ( \DOMElement $node ) : void ;
2026-02-25 06:59:34 +00:00
}