friendship ended with social-app. php is my new best friend
1<?php 2 3/* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Symfony\Component\CssSelector\XPath\Extension; 13 14use Symfony\Component\CssSelector\XPath\Translator; 15use Symfony\Component\CssSelector\XPath\XPathExpr; 16 17/** 18 * XPath expression translator attribute extension. 19 * 20 * This component is a port of the Python cssselect library, 21 * which is copyright Ian Bicking, @see https://github.com/SimonSapin/cssselect. 22 * 23 * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com> 24 * 25 * @internal 26 */ 27class AttributeMatchingExtension extends AbstractExtension 28{ 29 public function getAttributeMatchingTranslators(): array 30 { 31 return [ 32 'exists' => $this->translateExists(...), 33 '=' => $this->translateEquals(...), 34 '~=' => $this->translateIncludes(...), 35 '|=' => $this->translateDashMatch(...), 36 '^=' => $this->translatePrefixMatch(...), 37 '$=' => $this->translateSuffixMatch(...), 38 '*=' => $this->translateSubstringMatch(...), 39 '!=' => $this->translateDifferent(...), 40 ]; 41 } 42 43 public function translateExists(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr 44 { 45 return $xpath->addCondition($attribute); 46 } 47 48 public function translateEquals(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr 49 { 50 return $xpath->addCondition(\sprintf('%s = %s', $attribute, Translator::getXpathLiteral($value))); 51 } 52 53 public function translateIncludes(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr 54 { 55 return $xpath->addCondition($value ? \sprintf( 56 '%1$s and contains(concat(\' \', normalize-space(%1$s), \' \'), %2$s)', 57 $attribute, 58 Translator::getXpathLiteral(' '.$value.' ') 59 ) : '0'); 60 } 61 62 public function translateDashMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr 63 { 64 return $xpath->addCondition(\sprintf( 65 '%1$s and (%1$s = %2$s or starts-with(%1$s, %3$s))', 66 $attribute, 67 Translator::getXpathLiteral($value), 68 Translator::getXpathLiteral($value.'-') 69 )); 70 } 71 72 public function translatePrefixMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr 73 { 74 return $xpath->addCondition($value ? \sprintf( 75 '%1$s and starts-with(%1$s, %2$s)', 76 $attribute, 77 Translator::getXpathLiteral($value) 78 ) : '0'); 79 } 80 81 public function translateSuffixMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr 82 { 83 return $xpath->addCondition($value ? \sprintf( 84 '%1$s and substring(%1$s, string-length(%1$s)-%2$s) = %3$s', 85 $attribute, 86 \strlen($value) - 1, 87 Translator::getXpathLiteral($value) 88 ) : '0'); 89 } 90 91 public function translateSubstringMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr 92 { 93 return $xpath->addCondition($value ? \sprintf( 94 '%1$s and contains(%1$s, %2$s)', 95 $attribute, 96 Translator::getXpathLiteral($value) 97 ) : '0'); 98 } 99 100 public function translateDifferent(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr 101 { 102 return $xpath->addCondition(\sprintf( 103 $value ? 'not(%1$s) or %1$s != %2$s' : '%s != %s', 104 $attribute, 105 Translator::getXpathLiteral($value) 106 )); 107 } 108 109 public function getName(): string 110 { 111 return 'attribute-matching'; 112 } 113}