PageRenderTime 784ms CodeModel.GetById 37ms RepoModel.GetById 7ms app.codeStats 0ms

/vendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Link.php

https://bitbucket.org/davide_grobberio/laravel-angular
PHP | 232 lines | 99 code | 33 blank | 100 comment | 16 complexity | 0c7f4f4cabced5463068e1d33dd3f7fe MD5 | raw file
Possible License(s): MIT, BSD-3-Clause
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\DomCrawler;
  11. /**
  12. * Link represents an HTML link (an HTML a or area tag).
  13. *
  14. * @author Fabien Potencier <fabien@symfony.com>
  15. *
  16. * @api
  17. */
  18. class Link
  19. {
  20. /**
  21. * @var \DOMNode A \DOMNode instance
  22. */
  23. protected $node;
  24. /**
  25. * @var string The method to use for the link
  26. */
  27. protected $method;
  28. /**
  29. * @var string The URI of the page where the link is embedded (or the base href)
  30. */
  31. protected $currentUri;
  32. /**
  33. * Constructor.
  34. *
  35. * @param \DOMNode $node A \DOMNode instance
  36. * @param string $currentUri The URI of the page where the link is embedded (or the base href)
  37. * @param string $method The method to use for the link (get by default)
  38. *
  39. * @throws \InvalidArgumentException if the node is not a link
  40. *
  41. * @api
  42. */
  43. public function __construct(\DOMNode $node, $currentUri, $method = 'GET')
  44. {
  45. if (!in_array(strtolower(substr($currentUri, 0, 4)), array('http', 'file'))) {
  46. throw new \InvalidArgumentException(sprintf('Current URI must be an absolute URL ("%s").', $currentUri));
  47. }
  48. $this->setNode($node);
  49. $this->method = $method ? strtoupper($method) : null;
  50. $this->currentUri = $currentUri;
  51. }
  52. /**
  53. * Gets the node associated with this link.
  54. *
  55. * @return \DOMNode A \DOMNode instance
  56. */
  57. public function getNode()
  58. {
  59. return $this->node;
  60. }
  61. /**
  62. * Gets the method associated with this link.
  63. *
  64. * @return string The method
  65. *
  66. * @api
  67. */
  68. public function getMethod()
  69. {
  70. return $this->method;
  71. }
  72. /**
  73. * Gets the URI associated with this link.
  74. *
  75. * @return string The URI
  76. *
  77. * @api
  78. */
  79. public function getUri()
  80. {
  81. $uri = trim($this->getRawUri());
  82. // absolute URL?
  83. if (null !== parse_url($uri, PHP_URL_SCHEME)) {
  84. return $uri;
  85. }
  86. // empty URI
  87. if (!$uri) {
  88. return $this->currentUri;
  89. }
  90. // an anchor
  91. if ('#' === $uri[0]) {
  92. return $this->cleanupAnchor($this->currentUri).$uri;
  93. }
  94. $baseUri = $this->cleanupUri($this->currentUri);
  95. if ('?' === $uri[0]) {
  96. return $baseUri.$uri;
  97. }
  98. // absolute URL with relative schema
  99. if (0 === strpos($uri, '//')) {
  100. return preg_replace('#^([^/]*)//.*$#', '$1', $baseUri).$uri;
  101. }
  102. $baseUri = preg_replace('#^(.*?//[^/]*)(?:\/.*)?$#', '$1', $baseUri);
  103. // absolute path
  104. if ('/' === $uri[0]) {
  105. return $baseUri.$uri;
  106. }
  107. // relative path
  108. $path = parse_url(substr($this->currentUri, strlen($baseUri)), PHP_URL_PATH);
  109. $path = $this->canonicalizePath(substr($path, 0, strrpos($path, '/')).'/'.$uri);
  110. return $baseUri.('' === $path || '/' !== $path[0] ? '/' : '').$path;
  111. }
  112. /**
  113. * Returns raw URI data.
  114. *
  115. * @return string
  116. */
  117. protected function getRawUri()
  118. {
  119. return $this->node->getAttribute('href');
  120. }
  121. /**
  122. * Returns the canonicalized URI path (see RFC 3986, section 5.2.4)
  123. *
  124. * @param string $path URI path
  125. *
  126. * @return string
  127. */
  128. protected function canonicalizePath($path)
  129. {
  130. if ('' === $path || '/' === $path) {
  131. return $path;
  132. }
  133. if ('.' === substr($path, -1)) {
  134. $path = $path.'/';
  135. }
  136. $output = array();
  137. foreach (explode('/', $path) as $segment) {
  138. if ('..' === $segment) {
  139. array_pop($output);
  140. } elseif ('.' !== $segment) {
  141. array_push($output, $segment);
  142. }
  143. }
  144. return implode('/', $output);
  145. }
  146. /**
  147. * Sets current \DOMNode instance.
  148. *
  149. * @param \DOMNode $node A \DOMNode instance
  150. *
  151. * @throws \LogicException If given node is not an anchor
  152. */
  153. protected function setNode(\DOMNode $node)
  154. {
  155. if ('a' !== $node->nodeName && 'area' !== $node->nodeName) {
  156. throw new \LogicException(sprintf('Unable to click on a "%s" tag.', $node->nodeName));
  157. }
  158. $this->node = $node;
  159. }
  160. /**
  161. * Removes the query string and the anchor from the given uri.
  162. *
  163. * @param string $uri The uri to clean
  164. *
  165. * @return string
  166. */
  167. private function cleanupUri($uri)
  168. {
  169. return $this->cleanupQuery($this->cleanupAnchor($uri));
  170. }
  171. /**
  172. * Remove the query string from the uri.
  173. *
  174. * @param string $uri
  175. *
  176. * @return string
  177. */
  178. private function cleanupQuery($uri)
  179. {
  180. if (false !== $pos = strpos($uri, '?')) {
  181. return substr($uri, 0, $pos);
  182. }
  183. return $uri;
  184. }
  185. /**
  186. * Remove the anchor from the uri.
  187. *
  188. * @param string $uri
  189. *
  190. * @return string
  191. */
  192. private function cleanupAnchor($uri)
  193. {
  194. if (false !== $pos = strpos($uri, '#')) {
  195. return substr($uri, 0, $pos);
  196. }
  197. return $uri;
  198. }
  199. }