| Viewing file:  Link.php (4.78 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
<?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;
 
 /**
 * Link represents an HTML link (an HTML a or area tag).
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @api
 */
 class Link
 {
 /**
 * @var \DOMNode A \DOMNode instance
 */
 protected $node;
 /**
 * @var string The method to use for the link
 */
 protected $method;
 /**
 * @var string The URI of the page where the link is embedded (or the base href)
 */
 protected $currentUri;
 
 /**
 * Constructor.
 *
 * @param \DOMNode $node       A \DOMNode instance
 * @param string   $currentUri The URI of the page where the link is embedded (or the base href)
 * @param string   $method     The method to use for the link (get by default)
 *
 * @throws \InvalidArgumentException if the node is not a link
 *
 * @api
 */
 public function __construct(\DOMNode $node, $currentUri, $method = 'GET')
 {
 if (!in_array(strtolower(substr($currentUri, 0, 4)), array('http', 'file'))) {
 throw new \InvalidArgumentException(sprintf('Current URI must be an absolute URL ("%s").', $currentUri));
 }
 
 $this->setNode($node);
 $this->method = $method ? strtoupper($method) : null;
 $this->currentUri = $currentUri;
 }
 
 /**
 * Gets the node associated with this link.
 *
 * @return \DOMNode A \DOMNode instance
 */
 public function getNode()
 {
 return $this->node;
 }
 
 /**
 * Gets the method associated with this link.
 *
 * @return string The method
 *
 * @api
 */
 public function getMethod()
 {
 return $this->method;
 }
 
 /**
 * Gets the URI associated with this link.
 *
 * @return string The URI
 *
 * @api
 */
 public function getUri()
 {
 $uri = trim($this->getRawUri());
 
 // absolute URL?
 if (null !== parse_url($uri, PHP_URL_SCHEME)) {
 return $uri;
 }
 
 // empty URI
 if (!$uri) {
 return $this->currentUri;
 }
 
 // only an anchor
 if ('#' === $uri[0]) {
 $baseUri = $this->currentUri;
 if (false !== $pos = strpos($baseUri, '#')) {
 $baseUri = substr($baseUri, 0, $pos);
 }
 
 return $baseUri.$uri;
 }
 
 // only a query string
 if ('?' === $uri[0]) {
 $baseUri = $this->currentUri;
 
 // remove the query string from the current URI
 if (false !== $pos = strpos($baseUri, '?')) {
 $baseUri = substr($baseUri, 0, $pos);
 }
 
 return $baseUri.$uri;
 }
 
 // absolute URL with relative schema
 if (0 === strpos($uri, '//')) {
 return preg_replace('#^([^/]*)//.*$#', '$1', $this->currentUri).$uri;
 }
 
 $baseUri = preg_replace('#^(.*?//[^/]*)(?:\/.*)?$#', '$1', $this->currentUri);
 
 // absolute path
 if ('/' === $uri[0]) {
 return $baseUri.$uri;
 }
 
 // relative path
 $path = parse_url(substr($this->currentUri, strlen($baseUri)), PHP_URL_PATH);
 $path = $this->canonicalizePath(substr($path, 0, strrpos($path, '/')).'/'.$uri);
 
 return $baseUri.('' === $path || '/' !== $path[0] ? '/' : '').$path;
 }
 
 /**
 * Returns raw URI data.
 *
 * @return string
 */
 protected function getRawUri()
 {
 return $this->node->getAttribute('href');
 }
 
 /**
 * Returns the canonicalized URI path (see RFC 3986, section 5.2.4)
 *
 * @param string $path URI path
 *
 * @return string
 */
 protected function canonicalizePath($path)
 {
 if ('' === $path || '/' === $path) {
 return $path;
 }
 
 if ('.' === substr($path, -1)) {
 $path = $path.'/';
 }
 
 $output = array();
 
 foreach (explode('/', $path) as $segment) {
 if ('..' === $segment) {
 array_pop($output);
 } elseif ('.' !== $segment) {
 array_push($output, $segment);
 }
 }
 
 return implode('/', $output);
 }
 
 /**
 * Sets current \DOMNode instance.
 *
 * @param \DOMNode $node A \DOMNode instance
 *
 * @throws \LogicException If given node is not an anchor
 */
 protected function setNode(\DOMNode $node)
 {
 if ('a' != $node->nodeName && 'area' != $node->nodeName) {
 throw new \LogicException(sprintf('Unable to click on a "%s" tag.', $node->nodeName));
 }
 
 $this->node = $node;
 }
 }
 
 |