1<?php
2
3
4namespace ComboStrap;
5
6/**
7 * Class Url
8 * @package ComboStrap
9 * There is no URL in php
10 * Only function
11 * https://www.php.net/manual/en/ref.url.php
12 */
13class Url
14{
15    /**
16     * @var array|false|int|string|null
17     */
18    private $urlComponents;
19    /**
20     * @var void
21     */
22    private $query;
23
24
25    /**
26     * UrlUtility constructor.
27     * @throws ExceptionCombo
28     */
29    public function __construct($url)
30    {
31        $this->urlComponents = parse_url($url);
32        if ($this->urlComponents === false) {
33            throw new ExceptionCombo("The url ($url) is not valid");
34        }
35        parse_str($this->urlComponents['query'], $queryKeys);
36        $this->query = $queryKeys;
37    }
38
39
40    const RESERVED_WORDS = [':', '!', '#', '$', '&', '\'', '(', ')', '*', '+', ',', '/', ';', '=', '?', '@', '[', ']'];
41
42    /**
43     * A text to an encoded url
44     * @param $string -  a string
45     * @param string $separator - the path separator in the string
46     */
47    public static function encodeToUrlPath($string, string $separator = DokuPath::PATH_SEPARATOR): string
48    {
49        $parts = explode($separator, $string);
50        $encodedParts = array_map(function ($e) {
51            return urlencode($e);
52        }, $parts);
53        $urlPath = implode("/", $encodedParts);
54        return $urlPath;
55    }
56
57    function getQuery()
58    {
59
60        return $this->query;
61    }
62
63    function getQueryPropertyValue($prop)
64    {
65        return $this->query[$prop];
66    }
67
68    /**
69     * Extract the value of a property
70     * @param $propertyName
71     * @return string - the value of the property
72     */
73    public function getPropertyValue($propertyName): string
74    {
75        $parsedQuery = $this->urlComponents["query"];
76        $parsedQueryArray = [];
77        parse_str($parsedQuery, $parsedQueryArray);
78        return $parsedQueryArray[$propertyName];
79    }
80
81    /**
82     * Validate URL
83     * @return   boolean     Returns TRUE/FALSE
84     */
85    public static function isValid($url): bool
86    {
87        /**
88         *
89         * @var false
90         *
91         * Note: Url validation is hard with regexp
92         * for instance:
93         *  - http://example.lan/utility/a-combostrap-component-to-render-web-code-in-a-web-page-javascript-html-...-u8fe6ahw
94         *  - does not pass return preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $url);
95         * of preg_match('/^https?:\/\//',$url) ? from redirect plugin
96         *
97         * We try to create the object, the object use the {@link parse_url()}
98         * method to validate or send an exception if it can be parsed
99         */
100        $urlObject = null;
101        try {
102            $urlObject = Url::create($url);
103        } catch (ExceptionCombo $e) {
104            return false;
105        }
106
107        $scheme = $urlObject->getScheme();
108        if (!in_array($scheme, ["http", "https"])) {
109            return false;
110        }
111        return true;
112
113    }
114
115    /**
116     * @throws ExceptionCombo
117     */
118    public static function create(string $url): Url
119    {
120        return new Url($url);
121    }
122
123    private function getScheme()
124    {
125        return $this->urlComponents["scheme"];
126    }
127
128
129}
130