Passed
Push — main ( 46cb87...b800f4 )
by Marc
18:17 queued 13:49
created

normalize_uri()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 6
rs 10
1
<?php declare(strict_types=1);
2
3
use html_go\exceptions\InternalException;
4
use html_go\model\Config;
5
6
/**
7
 * The main entry point. Called from <code>index.php</code> in the application
8
 * root. The parameters are provided for testing thus they have default values.
9
 * @param string $uri
10
 * @param string $method
11
 * @return string The html to be rendered.
12
 */
13
function dispatch(string $uri = null, string $method = HTTP_GET): ?string {
14
    if ($uri === null) {
15
        $uri = $_SERVER['REQUEST_URI']; // @codeCoverageIgnore
16
        $method = \strtoupper($_SERVER['REQUEST_METHOD']); // @codeCoverageIgnore
17
    }
18
    $uri = strip_url_parameters($uri);
19
    $uri = normalize_uri($uri);
20
21
    return route($uri, $method);
22
}
23
24
/**
25
 * @param string $uri
26
 * @return string
27
 */
28
function normalize_uri(string $uri): string {
29
    $uri = \trim($uri, FWD_SLASH);
30
    if (empty($uri)) {
31
        $uri = HOME_INDEX_KEY;
32
    }
33
    return $uri;
34
}
35
36
/**
37
 * Route the given HTTP request.
38
 * @param string $uri The requested URI
39
 * @param string $method the HTTP method
40
 * @throws InternalException
41
 * @return string|NULL If the return value is an empty string (''), then an 'Location: ...' has been
42
 * done by t
43
 */
44
function route(string $uri, string $method): ?string {
45
    if (\str_starts_with($uri, get_config()->getString(Config::KEY_ADMIN_CONTEXT))) {
46
        $content = process_admin_request($method, $uri);
47
    } else {
48
        $content = process_request($uri, get_pagination_pagenumber(), get_config()->getInt(Config::KEY_POSTS_PERPAGE));
49
    }
50
51
    if ($content === null) {
52
        not_found();
53
        return null;
54
    }
55
56
    return render(get_template_context($content));
57
}
58
59
/**
60
 * Process a request for a public resource. This method assumes HTTP_GET only as request are for
61
 * the public site, not the admin.
62
 * @param string $uri
63
 * @param int $pageNum
64
 * @param int $perPage
65
 * @return \stdClass|NULL Returns <code>null</code> if the resource is not found
66
 */
67
function process_request(string $uri, int $pageNum, int $perPage): ?\stdClass {
68
    $template = LIST_TEMPLATE;
69
70
    if (HOME_INDEX_KEY === $uri) {
71
        return get_homepage($pageNum, $perPage);
72
    }
73
74
    $list = is_landing_page($uri, $pageNum, $perPage);
75
    if (empty($list)) {
76
        $list = is_list_page($uri, $pageNum, $perPage);
77
        if (empty($list)) {
78
            $template = SINGLE_TEMPLATE;
79
        }
80
    }
81
82
    return get_content_object($uri, $list, $template);
83
}
84
85
/**
86
 * Process an admin console request.
87
 * @param string $method
88
 * @param string $uri
89
 * @return \stdClass|NULL
90
 */
91
function process_admin_request(string $method, string $uri): ?\stdClass {
92
    require_once ADMIN_SYS_ROOT.DS.'bootstrap.php';
93
    return admin_route($method, $uri);
94
}
95
96
/**
97
 * Checks if the given URI is a landing page (excluding the home page). If so, returns a list of the
98
 * appropriate content objects for that page.
99
 * @param string $uri
100
 * @return array<\stdClass>
101
 */
102
function is_landing_page(string $uri, int $pageNum = 1, int $perPage = 0): array {
103
    $list = [];
104
    switch (true) {
105
        case $uri === CAT_INDEX_KEY:
106
            $list = get_categories($pageNum, $perPage);
107
            break;
108
        case $uri === POST_INDEX_KEY:
109
            $list = get_posts($pageNum, $perPage);
110
            break;
111
        case $uri === TAG_INDEX_KEY:
112
            $list = get_tags($pageNum, $perPage);
113
            break;
114
        default:
115
            // Do nothing
116
    }
117
    return $list;
118
}
119
120
/**
121
 * Checks if the given URI is a list page (excluding the home page), if so returns a list of the
122
 * approriate content object for that page.
123
 * @param string $uri
124
 * @param int $pageNum
125
 * @param int $perPage
126
 * @return array<\stdClass>
127
 */
128
function is_list_page(string $uri, int $pageNum = 1, int $perPage = 0): array {
129
    $list = [];
130
    switch (true) {
131
        case \str_starts_with($uri, POST_INDEX_KEY):
132
            $list = get_posts($pageNum, $perPage);
133
            break;
134
        case \str_starts_with($uri, CAT_INDEX_KEY.FWD_SLASH):
135
            $list = get_posts_for_section(CATEGORY_SECTION, $uri, $pageNum, $perPage);
136
            break;
137
        case \str_starts_with($uri, TAG_INDEX_KEY.FWD_SLASH):
138
            $list = get_posts_for_section(TAG_SECTION, $uri, $pageNum, $perPage);
139
            break;
140
        default:
141
            // Do nothing
142
    }
143
    return $list;
144
}
145
146
/**
147
 * Returns the home page.
148
 * @param int $pageNum
149
 * @param int $perPage
150
 * @throws InternalException
151
 * @return \stdClass
152
 */
153
function get_homepage(int $pageNum, int $perPage): \stdClass {
154
    if (get_config()->getBool(Config::KEY_STATIC_INDEX)) {
155
        $content = get_content_object(HOME_INDEX_KEY);
156
    } else {
157
        $content = get_content_object(HOME_INDEX_KEY, get_posts($pageNum, $perPage), LIST_TEMPLATE);
158
    }
159
160
    if ($content === null) {
161
        throw new InternalException("Unable to find the home index page!");
162
    }
163
164
    return $content;
165
}
166
167
/**
168
 * Strips parameters from the given URL.
169
 * @param string $url
170
 * @return string returns the URL without the parameters.
171
 */
172
function strip_url_parameters(string $url): string {
173
    if (($pos = \strpos($url, '?')) === false) {
174
        return $url;
175
    }
176
    parse_query(\substr($url, $pos + 1));
177
    return \substr($url, 0, $pos);
178
}
179
180
/**
181
 * @param string $query (Optional). Calling with this parameter set will populate the returned data array.
182
 * @return array<string, string>
183
 */
184
function parse_query(string $query = null): array {
185
    static $data = [];
186
    if (empty($data) && $query !== null) {
187
        \parse_str($query, $data);
188
    }
189
    return $data;
190
}
191
192
/**
193
 * Return the query string value for the given key.
194
 * @param string $key
195
 * @return string|NULL <code>null</code> if the key is not found
196
 */
197
function get_query_parameter(string $key): ?string {
198
    $params = parse_query();
199
    if (isset($params[$key])) {
200
        return $params[$key];
201
    }
202
    return null;
203
}
204