10b3fd2d3SAndreas Gohr<?php 2*dad993c5SAndreas Gohr 30b3fd2d3SAndreas Gohr/** 40b3fd2d3SAndreas Gohr * This file is part of the FreeDSx LDAP package. 50b3fd2d3SAndreas Gohr * 60b3fd2d3SAndreas Gohr * (c) Chad Sikorra <Chad.Sikorra@gmail.com> 70b3fd2d3SAndreas Gohr * 80b3fd2d3SAndreas Gohr * For the full copyright and license information, please view the LICENSE 90b3fd2d3SAndreas Gohr * file that was distributed with this source code. 100b3fd2d3SAndreas Gohr */ 110b3fd2d3SAndreas Gohr 120b3fd2d3SAndreas Gohrnamespace FreeDSx\Ldap\Entry; 130b3fd2d3SAndreas Gohr 14*dad993c5SAndreas Gohruse function preg_match; 15*dad993c5SAndreas Gohruse function strlen; 16*dad993c5SAndreas Gohruse function strtolower; 17*dad993c5SAndreas Gohruse function substr; 18*dad993c5SAndreas Gohr 190b3fd2d3SAndreas Gohr/** 200b3fd2d3SAndreas Gohr * Represents an attribute option. Described in RFC 4512, Section 2.5.2. 210b3fd2d3SAndreas Gohr * 220b3fd2d3SAndreas Gohr * @author Chad Sikorra <Chad.Sikorra@gmail.com> 230b3fd2d3SAndreas Gohr */ 240b3fd2d3SAndreas Gohrclass Option 250b3fd2d3SAndreas Gohr{ 260b3fd2d3SAndreas Gohr protected const MATCH_RANGE = '/range=(\d+)-(.*)/'; 270b3fd2d3SAndreas Gohr 280b3fd2d3SAndreas Gohr /** 290b3fd2d3SAndreas Gohr * @var string 300b3fd2d3SAndreas Gohr */ 310b3fd2d3SAndreas Gohr protected $option; 320b3fd2d3SAndreas Gohr 330b3fd2d3SAndreas Gohr /** 340b3fd2d3SAndreas Gohr * @var string 350b3fd2d3SAndreas Gohr */ 360b3fd2d3SAndreas Gohr protected $lcOption; 370b3fd2d3SAndreas Gohr 380b3fd2d3SAndreas Gohr /** 390b3fd2d3SAndreas Gohr * @param string $option 400b3fd2d3SAndreas Gohr */ 410b3fd2d3SAndreas Gohr public function __construct(string $option) 420b3fd2d3SAndreas Gohr { 430b3fd2d3SAndreas Gohr $this->option = $option; 440b3fd2d3SAndreas Gohr } 450b3fd2d3SAndreas Gohr 460b3fd2d3SAndreas Gohr /** 470b3fd2d3SAndreas Gohr * @return bool 480b3fd2d3SAndreas Gohr */ 490b3fd2d3SAndreas Gohr public function isLanguageTag(): bool 500b3fd2d3SAndreas Gohr { 510b3fd2d3SAndreas Gohr return $this->startsWith('lang-'); 520b3fd2d3SAndreas Gohr } 530b3fd2d3SAndreas Gohr 540b3fd2d3SAndreas Gohr /** 550b3fd2d3SAndreas Gohr * @return bool 560b3fd2d3SAndreas Gohr */ 570b3fd2d3SAndreas Gohr public function isRange(): bool 580b3fd2d3SAndreas Gohr { 590b3fd2d3SAndreas Gohr return $this->startsWith('range='); 600b3fd2d3SAndreas Gohr } 610b3fd2d3SAndreas Gohr 620b3fd2d3SAndreas Gohr /** 630b3fd2d3SAndreas Gohr * A convenience method to get the high value of a range option. 640b3fd2d3SAndreas Gohr * 650b3fd2d3SAndreas Gohr * @see https://msdn.microsoft.com/en-us/library/cc223242.aspx 66*dad993c5SAndreas Gohr * 67*dad993c5SAndreas Gohr * @return null|string 680b3fd2d3SAndreas Gohr */ 69*dad993c5SAndreas Gohr public function getHighRange(): ?string 700b3fd2d3SAndreas Gohr { 710b3fd2d3SAndreas Gohr if (!$this->isRange()) { 720b3fd2d3SAndreas Gohr return ''; 730b3fd2d3SAndreas Gohr } 74*dad993c5SAndreas Gohr preg_match(self::MATCH_RANGE, $this->option, $match); 750b3fd2d3SAndreas Gohr 760b3fd2d3SAndreas Gohr return $match[2] ?? null; 770b3fd2d3SAndreas Gohr } 780b3fd2d3SAndreas Gohr 790b3fd2d3SAndreas Gohr /** 800b3fd2d3SAndreas Gohr * A convenience method to get the low value of a range option. 810b3fd2d3SAndreas Gohr * 820b3fd2d3SAndreas Gohr * @see https://msdn.microsoft.com/en-us/library/cc223242.aspx 830b3fd2d3SAndreas Gohr * @return string|null 840b3fd2d3SAndreas Gohr */ 850b3fd2d3SAndreas Gohr public function getLowRange(): ?string 860b3fd2d3SAndreas Gohr { 870b3fd2d3SAndreas Gohr if (!$this->isRange()) { 880b3fd2d3SAndreas Gohr return null; 890b3fd2d3SAndreas Gohr } 90*dad993c5SAndreas Gohr preg_match(self::MATCH_RANGE, $this->option, $match); 910b3fd2d3SAndreas Gohr 920b3fd2d3SAndreas Gohr return $match[1] ?? null; 930b3fd2d3SAndreas Gohr } 940b3fd2d3SAndreas Gohr 950b3fd2d3SAndreas Gohr /** 960b3fd2d3SAndreas Gohr * @param string $option 970b3fd2d3SAndreas Gohr * @return bool 980b3fd2d3SAndreas Gohr */ 990b3fd2d3SAndreas Gohr public function startsWith(string $option): bool 1000b3fd2d3SAndreas Gohr { 1010b3fd2d3SAndreas Gohr if ($this->lcOption === null) { 102*dad993c5SAndreas Gohr $this->lcOption = strtolower($this->option); 1030b3fd2d3SAndreas Gohr } 104*dad993c5SAndreas Gohr $option = strtolower($option); 1050b3fd2d3SAndreas Gohr 106*dad993c5SAndreas Gohr return substr($this->lcOption, 0, strlen($option)) === $option; 1070b3fd2d3SAndreas Gohr } 1080b3fd2d3SAndreas Gohr 1090b3fd2d3SAndreas Gohr /** 1100b3fd2d3SAndreas Gohr * Options are case insensitive, so use this to optimize case-insensitive checks. 1110b3fd2d3SAndreas Gohr * 1120b3fd2d3SAndreas Gohr * @param Option $option 1130b3fd2d3SAndreas Gohr * @return bool 1140b3fd2d3SAndreas Gohr */ 1150b3fd2d3SAndreas Gohr public function equals(Option $option): bool 1160b3fd2d3SAndreas Gohr { 1170b3fd2d3SAndreas Gohr if ($this->lcOption === null) { 118*dad993c5SAndreas Gohr $this->lcOption = strtolower($this->option); 1190b3fd2d3SAndreas Gohr } 1200b3fd2d3SAndreas Gohr if ($option->lcOption === null) { 121*dad993c5SAndreas Gohr $option->lcOption = strtolower($option->option); 1220b3fd2d3SAndreas Gohr } 1230b3fd2d3SAndreas Gohr 1240b3fd2d3SAndreas Gohr return $this->lcOption === $option->lcOption; 1250b3fd2d3SAndreas Gohr } 1260b3fd2d3SAndreas Gohr 1270b3fd2d3SAndreas Gohr /** 1280b3fd2d3SAndreas Gohr * @param bool $lowercase forces the string representation to lowercase. 1290b3fd2d3SAndreas Gohr * @return string 1300b3fd2d3SAndreas Gohr */ 1310b3fd2d3SAndreas Gohr public function toString(bool $lowercase = false): string 1320b3fd2d3SAndreas Gohr { 1330b3fd2d3SAndreas Gohr if ($lowercase) { 1340b3fd2d3SAndreas Gohr if ($this->lcOption === null) { 135*dad993c5SAndreas Gohr $this->lcOption = strtolower($this->option); 1360b3fd2d3SAndreas Gohr } 1370b3fd2d3SAndreas Gohr 1380b3fd2d3SAndreas Gohr return $this->lcOption; 1390b3fd2d3SAndreas Gohr } 1400b3fd2d3SAndreas Gohr 1410b3fd2d3SAndreas Gohr return $this->option; 1420b3fd2d3SAndreas Gohr } 1430b3fd2d3SAndreas Gohr 1440b3fd2d3SAndreas Gohr /** 1450b3fd2d3SAndreas Gohr * @return string 1460b3fd2d3SAndreas Gohr */ 1470b3fd2d3SAndreas Gohr public function __toString() 1480b3fd2d3SAndreas Gohr { 1490b3fd2d3SAndreas Gohr return $this->option; 1500b3fd2d3SAndreas Gohr } 1510b3fd2d3SAndreas Gohr 1520b3fd2d3SAndreas Gohr /** 1530b3fd2d3SAndreas Gohr * Convenience factory method for creating a range option. 1540b3fd2d3SAndreas Gohr * 1550b3fd2d3SAndreas Gohr * @see https://msdn.microsoft.com/en-us/library/cc223242.aspx 1560b3fd2d3SAndreas Gohr * @param string $startAt 1570b3fd2d3SAndreas Gohr * @param string $endAt 1580b3fd2d3SAndreas Gohr * @return Option 1590b3fd2d3SAndreas Gohr */ 1600b3fd2d3SAndreas Gohr public static function fromRange(string $startAt, string $endAt = '*') 1610b3fd2d3SAndreas Gohr { 1620b3fd2d3SAndreas Gohr return new self('range=' . $startAt . '-' . $endAt); 1630b3fd2d3SAndreas Gohr } 1640b3fd2d3SAndreas Gohr} 165