1<?php 2 3/** 4 * This file is part of the FreeDSx LDAP package. 5 * 6 * (c) Chad Sikorra <Chad.Sikorra@gmail.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 FreeDSx\Ldap\Entry; 13 14use function preg_match; 15use function strlen; 16use function strtolower; 17use function substr; 18 19/** 20 * Represents an attribute option. Described in RFC 4512, Section 2.5.2. 21 * 22 * @author Chad Sikorra <Chad.Sikorra@gmail.com> 23 */ 24class Option 25{ 26 protected const MATCH_RANGE = '/range=(\d+)-(.*)/'; 27 28 /** 29 * @var string 30 */ 31 protected $option; 32 33 /** 34 * @var string 35 */ 36 protected $lcOption; 37 38 /** 39 * @param string $option 40 */ 41 public function __construct(string $option) 42 { 43 $this->option = $option; 44 } 45 46 /** 47 * @return bool 48 */ 49 public function isLanguageTag(): bool 50 { 51 return $this->startsWith('lang-'); 52 } 53 54 /** 55 * @return bool 56 */ 57 public function isRange(): bool 58 { 59 return $this->startsWith('range='); 60 } 61 62 /** 63 * A convenience method to get the high value of a range option. 64 * 65 * @see https://msdn.microsoft.com/en-us/library/cc223242.aspx 66 * 67 * @return null|string 68 */ 69 public function getHighRange(): ?string 70 { 71 if (!$this->isRange()) { 72 return ''; 73 } 74 preg_match(self::MATCH_RANGE, $this->option, $match); 75 76 return $match[2] ?? null; 77 } 78 79 /** 80 * A convenience method to get the low value of a range option. 81 * 82 * @see https://msdn.microsoft.com/en-us/library/cc223242.aspx 83 * @return string|null 84 */ 85 public function getLowRange(): ?string 86 { 87 if (!$this->isRange()) { 88 return null; 89 } 90 preg_match(self::MATCH_RANGE, $this->option, $match); 91 92 return $match[1] ?? null; 93 } 94 95 /** 96 * @param string $option 97 * @return bool 98 */ 99 public function startsWith(string $option): bool 100 { 101 if ($this->lcOption === null) { 102 $this->lcOption = strtolower($this->option); 103 } 104 $option = strtolower($option); 105 106 return substr($this->lcOption, 0, strlen($option)) === $option; 107 } 108 109 /** 110 * Options are case insensitive, so use this to optimize case-insensitive checks. 111 * 112 * @param Option $option 113 * @return bool 114 */ 115 public function equals(Option $option): bool 116 { 117 if ($this->lcOption === null) { 118 $this->lcOption = strtolower($this->option); 119 } 120 if ($option->lcOption === null) { 121 $option->lcOption = strtolower($option->option); 122 } 123 124 return $this->lcOption === $option->lcOption; 125 } 126 127 /** 128 * @param bool $lowercase forces the string representation to lowercase. 129 * @return string 130 */ 131 public function toString(bool $lowercase = false): string 132 { 133 if ($lowercase) { 134 if ($this->lcOption === null) { 135 $this->lcOption = strtolower($this->option); 136 } 137 138 return $this->lcOption; 139 } 140 141 return $this->option; 142 } 143 144 /** 145 * @return string 146 */ 147 public function __toString() 148 { 149 return $this->option; 150 } 151 152 /** 153 * Convenience factory method for creating a range option. 154 * 155 * @see https://msdn.microsoft.com/en-us/library/cc223242.aspx 156 * @param string $startAt 157 * @param string $endAt 158 * @return Option 159 */ 160 public static function fromRange(string $startAt, string $endAt = '*') 161 { 162 return new self('range=' . $startAt . '-' . $endAt); 163 } 164} 165