Manipulator.php 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. <?php
  2. /*
  3. * This file is part of the Mink package.
  4. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. namespace Behat\Mink\Selector\Xpath;
  10. /**
  11. * XPath manipulation utility.
  12. *
  13. * @author Graham Bates
  14. * @author Christophe Coevoet <stof@notk.org>
  15. */
  16. class Manipulator
  17. {
  18. /**
  19. * Regex to find union operators not inside brackets.
  20. */
  21. const UNION_PATTERN = '/\|(?![^\[]*\])/';
  22. /**
  23. * Prepends the XPath prefix to the given XPath.
  24. *
  25. * The returned XPath will match elements matching the XPath inside an element
  26. * matching the prefix.
  27. *
  28. * @param string $xpath
  29. * @param string $prefix
  30. *
  31. * @return string
  32. */
  33. public function prepend($xpath, $prefix)
  34. {
  35. $expressions = array();
  36. // If the xpath prefix contains a union we need to wrap it in parentheses.
  37. if (preg_match(self::UNION_PATTERN, $prefix)) {
  38. $prefix = '('.$prefix.')';
  39. }
  40. // Split any unions into individual expressions.
  41. foreach (preg_split(self::UNION_PATTERN, $xpath) as $expression) {
  42. $expression = trim($expression);
  43. $parenthesis = '';
  44. // If the union is inside some braces, we need to preserve the opening braces and apply
  45. // the prefix only inside it.
  46. if (preg_match('/^[\(\s*]+/', $expression, $matches)) {
  47. $parenthesis = $matches[0];
  48. $expression = substr($expression, strlen($parenthesis));
  49. }
  50. // add prefix before element selector
  51. if (0 === strpos($expression, '/')) {
  52. $expression = $prefix.$expression;
  53. } else {
  54. $expression = $prefix.'/'.$expression;
  55. }
  56. $expressions[] = $parenthesis.$expression;
  57. }
  58. return implode(' | ', $expressions);
  59. }
  60. }