setScheme( (string) $scheme ); } if ($user = parse_url($address, PHP_URL_USER)) { $this->setUser( (string) $user ); } if ($pass = parse_url($address, PHP_URL_PASS)) { $this->setPass( (string) $pass ); } if ($host = parse_url($address, PHP_URL_HOST)) { $this->setHost( (string) $host ); } if ($port = parse_url($address, PHP_URL_PORT)) { $this->setPort( (int) $port ); } if ($path = parse_url($address, PHP_URL_PATH)) { $this->setPath( (string) $path ); } if ($query = parse_url($address, PHP_URL_QUERY)) { $this->setQuery( (string) $query ); } if ($fragment = parse_url($address, PHP_URL_FRAGMENT)) { $this->setFragment( (string) $fragment ); } } } public function isAbsolute(): bool { return ($this->_scheme && $this->_host); } public function isRelative(): bool { return !$this->isAbsolute(); } public function getScheme(): ?string { return $this->_scheme; } public function setScheme(?string $value): void { $this->_scheme = $value; } public function getHost(): ?string { return $this->_host; } public function setHost(?string $value): void { $this->_host = $value; } public function getUser(): ?string { return $this->_user; } public function setUser(?string $value): void { $this->_user = $value; } public function getPass(): ?string { return $this->_pass; } public function setPass(?string $value): void { $this->_pass = $value; } public function getPort(): ?int { return $this->_port; } public function setPort(?int $value): void { $this->_port = $value; } public function getPath(): ?string { return $this->_path; } public function setPath(?string $value): void { if (false !== strpos($value, '\\')) { $this->setSeparator( '\\' ); } $this->_segments = explode( $this->_separator, $value ); $this->_path = $value; } public function getSegments(): array { return $this->_segments; } public function getQuery(): ?string { return $this->_query; } public function setQuery(?string $value): void { $this->_query = $value; } public function getFragment(): ?string { return $this->_fragment; } public function setFragment(?string $value): void { $this->_fragment = $value; } public function getSeparator(): string { return $this->_separator; } public function setSeparator(?string $value): void { $this->_separator = $value; } public function get( bool $scheme = true, bool $user = true, bool $pass = true, bool $host = true, bool $port = true, bool $path = true, bool $query = true, bool $fragment = true, ): string { $address = ''; if ($scheme && $this->getScheme()) { $address .= sprintf( '%s:%s%s', $this->getScheme(), $this->getSeparator(), $this->getSeparator() ); } if ($user && $this->getUser()) { if ($pass && $this->getPass()) { $address .= sprintf( '%s:%s@', $this->getUser(), $this->getPass() ); } else { $address .= sprintf( '%s@', $this->getUser() ); } } if ($host && $this->getHost()) { $address .= $this->getHost(); } if ($port && $this->getPort()) { $address .= sprintf( ':%d', $this->getPort() ); } if ($path && $this->getPath()) { if (!str_starts_with($this->getPath(), $this->getSeparator())) { $address .= $this->getSeparator(); } $address .= $this->getPath(); } if ($query && $this->getQuery()) { $address .= sprintf( '?%s', $this->getQuery() ); } if ($fragment && $this->getFragment()) { $address .= sprintf( '#%s', $this->getFragment() ); } return $address; } public function getAbsolute( \Yggverse\Net\Address $base ): ?string { if ($this->isAbsolute()) { return $this->get(); } if ($base->isRelative()) { return null; } $this->setScheme( $base->getScheme() ); $this->setUser( $base->getUser() ); $this->setPass( $base->getPass() ); $this->setHost( $base->getHost() ); $this->setPort( $base->getPort() ); $this->setSeparator( $base->getSeparator() ); if (str_starts_with((string) $this->getPath(), $this->getSeparator())) { return $this->get(); } if ($path = $this->getPath()) { $prefix = array_reverse( $base->getSegments() ); array_shift( $prefix ); $navigate = true; $postfix = []; foreach ($this->getSegments() as $index => $segment) { if ($segment == '.') { continue; } if ($navigate && $segment == '..') { if (empty($prefix[$index])) { return null; } unset( $prefix[$index] ); continue; } $navigate = false; $postfix[] = $segment; } $this->setPath( implode( $this->getSeparator(), array_merge( array_reverse( $prefix ), $postfix ) ) ); } return $this->get(); } }