| @@ -5,231 +5,232 @@ $path = ltrim($_SERVER['REQUEST_URI'], '/'); |
| 5 | $elements = explode('/', $path); |
5 | $elements = explode('/', $path); |
| 6 | |
6 | |
| 7 | if (empty($elements[0])) { |
7 | if (empty($elements[0])) { |
| 8 | $html_output = get_stories( |
8 | $html_output = get_stories( |
| 9 | 'https://hacker-news.firebaseio.com/v0/topstories.json?limitToFirst=10&orderBy="$key"', |
9 | 'https://hacker-news.firebaseio.com/v0/topstories.json?limitToFirst=10&orderBy="$key"', |
| 10 | 'Top' |
10 | 'Top' |
| 11 | ); |
11 | ); |
| 12 | echo_html( |
12 | echo_html( |
| 13 | $GLOBALS['full_domain'], |
13 | $GLOBALS['full_domain'], |
| 14 | 'The top stories from Hacker News, proxied by hn.', |
14 | 'The top stories from Hacker News, proxied by hn.', |
| 15 | 'hn', |
15 | 'hn', |
| 16 | $html_output |
16 | $html_output |
| 17 | ); |
17 | ); |
| 18 | } else { |
18 | } else { |
| 19 | switch (array_shift($elements)) { |
19 | switch (array_shift($elements)) { |
| 20 | case 'top': |
20 | case 'top': |
| 21 | $html_output = get_stories( |
21 | $html_output = get_stories( |
| 22 | 'https://hacker-news.firebaseio.com/v0/topstories.json?limitToFirst=10&orderBy="$key"', |
22 | 'https://hacker-news.firebaseio.com/v0/topstories.json?limitToFirst=10&orderBy="$key"', |
| 23 | 'Top' |
23 | 'Top' |
| 24 | ); |
24 | ); |
| 25 | echo_html( |
25 | echo_html( |
| 26 | $GLOBALS['full_domain'], |
26 | $GLOBALS['full_domain'], |
| 27 | 'The top stories from Hacker News, proxied by hn.', |
27 | 'The top stories from Hacker News, proxied by hn.', |
| 28 | 'hn', |
28 | 'hn', |
| 29 | $html_output |
29 | $html_output |
| 30 | ); |
30 | ); |
| 31 | break; |
31 | break; |
| 32 | |
32 | |
| 33 | case 'best': |
33 | case 'best': |
| 34 | $html_output = get_stories( |
34 | $html_output = get_stories( |
| 35 | 'https://hacker-news.firebaseio.com/v0/beststories.json?limitToFirst=10&orderBy="$key"', |
35 | 'https://hacker-news.firebaseio.com/v0/beststories.json?limitToFirst=10&orderBy="$key"', |
| 36 | 'Best' |
36 | 'Best' |
| 37 | ); |
37 | ); |
| 38 | echo_html( |
38 | echo_html( |
| 39 | $GLOBALS['full_domain'] . '/best/', |
39 | $GLOBALS['full_domain'] . '/best/', |
| 40 | 'The best 30 stories from Hacker News, proxied by hn.', |
40 | 'The best 30 stories from Hacker News, proxied by hn.', |
| 41 | 'hn ~ best', |
41 | 'hn ~ best', |
| 42 | $html_output |
42 | $html_output |
| 43 | ); |
43 | ); |
| 44 | break; |
44 | break; |
| 45 | |
45 | |
| 46 | case 'new': |
46 | case 'new': |
| 47 | $html_output = get_stories( |
47 | $html_output = get_stories( |
| 48 | 'https://hacker-news.firebaseio.com/v0/newstories.json?limitToFirst=10&orderBy="$key"', |
48 | 'https://hacker-news.firebaseio.com/v0/newstories.json?limitToFirst=10&orderBy="$key"', |
| 49 | 'New' |
49 | 'New' |
| 50 | ); |
50 | ); |
| 51 | echo_html( |
51 | echo_html( |
| 52 | $GLOBALS['full_domain'] . '/new/', |
52 | $GLOBALS['full_domain'] . '/new/', |
| 53 | 'The newest 30 stories from Hacker News, proxied by hn.', |
53 | 'The newest 30 stories from Hacker News, proxied by hn.', |
| 54 | 'hn ~ new', |
54 | 'hn ~ new', |
| 55 | $html_output |
55 | $html_output |
| 56 | ); |
56 | ); |
| 57 | break; |
57 | break; |
| 58 | |
58 | |
| 59 | case 'ask': |
59 | case 'ask': |
| 60 | $html_output = get_stories( |
60 | $html_output = get_stories( |
| 61 | 'https://hacker-news.firebaseio.com/v0/askstories.json?limitToFirst=10&orderBy="$key"', |
61 | 'https://hacker-news.firebaseio.com/v0/askstories.json?limitToFirst=10&orderBy="$key"', |
| 62 | 'Ask' |
62 | 'Ask' |
| 63 | ); |
63 | ); |
| 64 | echo_html( |
64 | echo_html( |
| 65 | $GLOBALS['full_domain'] . '/ask/', |
65 | $GLOBALS['full_domain'] . '/ask/', |
| 66 | 'The latest 30 asks from Hacker News, proxied by hn.', |
66 | 'The latest 30 asks from Hacker News, proxied by hn.', |
| 67 | 'hn ~ ask', |
67 | 'hn ~ ask', |
| 68 | $html_output |
68 | $html_output |
| 69 | ); |
69 | ); |
| 70 | break; |
70 | break; |
| 71 | |
71 | |
| 72 | case 'show': |
72 | case 'show': |
| 73 | $html_output = get_stories( |
73 | $html_output = get_stories( |
| 74 | 'https://hacker-news.firebaseio.com/v0/showstories.json?limitToFirst=10&orderBy="$key"', |
74 | 'https://hacker-news.firebaseio.com/v0/showstories.json?limitToFirst=10&orderBy="$key"', |
| 75 | 'Show' |
75 | 'Show' |
| 76 | ); |
76 | ); |
| 77 | echo_html( |
77 | echo_html( |
| 78 | $GLOBALS['full_domain'] . '/show/', |
78 | $GLOBALS['full_domain'] . '/show/', |
| 79 | 'The latest 30 show stories from Hacker News, proxied by hn.', |
79 | 'The latest 30 show stories from Hacker News, proxied by hn.', |
| 80 | 'hn ~ show', |
80 | 'hn ~ show', |
| 81 | $html_output |
81 | $html_output |
| 82 | ); |
82 | ); |
| 83 | break; |
83 | break; |
| 84 | |
84 | |
| 85 | case 'job': |
85 | case 'job': |
| 86 | $html_output = get_stories( |
86 | $html_output = get_stories( |
| 87 | 'https://hacker-news.firebaseio.com/v0/jobstories.json?limitToFirst=10&orderBy="$key"', |
87 | 'https://hacker-news.firebaseio.com/v0/jobstories.json?limitToFirst=10&orderBy="$key"', |
| 88 | 'Job' |
88 | 'Job' |
| 89 | ); |
89 | ); |
| 90 | echo_html( |
90 | echo_html( |
| 91 | $GLOBALS['full_domain'] . '/job/', |
91 | $GLOBALS['full_domain'] . '/job/', |
| 92 | 'The latest 30 job posts from Hacker News, proxied by hn.', |
92 | 'The latest 30 job posts from Hacker News, proxied by hn.', |
| 93 | 'hn ~ job', |
93 | 'hn ~ job', |
| 94 | $html_output |
94 | $html_output |
| 95 | ); |
95 | ); |
| 96 | break; |
96 | break; |
| 97 | |
97 | |
| 98 | case 'user': |
98 | case 'user': |
| 99 | $html_output = get_user( |
99 | $html_output = get_user( |
| 100 | 'https://hacker-news.firebaseio.com/v0/user/' . $elements[0] . '.json', |
100 | 'https://hacker-news.firebaseio.com/v0/user/' . $elements[0] . '.json', |
| 101 | 'User Profile: ' . $elements[0] |
101 | 'User Profile: ' . $elements[0] |
| 102 | ); |
102 | ); |
| 103 | echo_html( |
103 | echo_html( |
| 104 | $GLOBALS['full_domain'] . '/user/' . $elements[0], |
104 | $GLOBALS['full_domain'] . '/user/' . $elements[0], |
| 105 | 'The Hacker News profile for ' . $elements[0] . ', proxied by hn.', |
105 | 'The Hacker News profile for ' . $elements[0] . ', proxied by hn.', |
| 106 | 'hn', |
106 | 'hn', |
| 107 | $html_output |
107 | $html_output |
| 108 | ); |
108 | ); |
| 109 | break; |
109 | break; |
| 110 | |
110 | |
| 111 | default: |
111 | default: |
| 112 | header('HTTP/1.1 404 Not Found'); |
112 | header('HTTP/1.1 404 Not Found'); |
| 113 | } |
113 | } |
| 114 | } |
114 | } |
| 115 | |
115 | |
| 116 | /** |
116 | /** |
| 117 | * Extract a set of stories from Hacker News API and format in HTML |
117 | * Extract a set of stories from Hacker News API and format in HTML |
| 118 | * |
118 | * |
| 119 | * @access public |
119 | * @access public |
| 120 | * @author cmc <hello@cleberg.net> |
120 | * @param string $api_url The API endpoint to use for extraction |
| 121 | * @param string $api_url The API endpoint to use for extraction |
121 | * @param string $inline_title The <h1> title to use in the HTML |
| 122 | * @param string $inline_title The <h1> title to use in the HTML |
122 | * @return string $html_output The formatted HTML result of stories from the API |
| 123 | * @return string $html_output The formatted HTML result of stories from the API |
123 | * @author cmc <hello@cleberg.net> |
| 124 | */ |
124 | */ |
| 125 | function get_stories($api_url, $inline_title) { |
125 | function get_stories(string $api_url, string $inline_title): string |
| 126 | $response_raw = file_get_contents($api_url); |
126 | { |
| 127 | if (is_null($response_raw) || $response_raw == "null") { |
127 | $response_raw = file_get_contents($api_url); |
| 128 | $html_output .= '<p>ERROR: Stories not found. API returned `null`.</p>'; |
128 | if ($response_raw == "null") { |
| 129 | return $html_output; |
129 | return '<p>ERROR: Stories not found. API returned `null`.</p>'; |
| 130 | } else { |
130 | } else { |
| 131 | $response = json_decode($response_raw, true); |
131 | $response = json_decode($response_raw, true); |
| 132 | } |
132 | } |
| 133 | |
133 | |
| 134 | $html_output = '<h1>' . $inline_title . '</h1>'; |
134 | $html_output = '<h1>' . $inline_title . '</h1>'; |
| 135 | |
135 | |
| 136 | for ($i = 0; $i < count($response); $i++) { |
136 | for ($i = 0; $i < count($response); $i++) { |
| 137 | $sub_url = 'https://hacker-news.firebaseio.com/v0/item/' . $response[$i] . '.json'; |
137 | $sub_url = 'https://hacker-news.firebaseio.com/v0/item/' . $response[$i] . '.json'; |
| 138 | $sub_response_raw = file_get_contents($sub_url); |
138 | $sub_response_raw = file_get_contents($sub_url); |
| 139 | $sub_response = json_decode($sub_response_raw, true); |
139 | $sub_response = json_decode($sub_response_raw, true); |
| 140 | |
140 | |
| 141 | // TODO: Can this be converted to a heredoc string with variables? |
141 | // TODO: Can this be converted to a heredoc string with variables? |
| 142 | $html = '<div><a href="' . $sub_response['url'] . '">' . $sub_response['title'] . '</a>'; |
142 | $html = '<div><a href="' . $sub_response['url'] . '">' . $sub_response['title'] . '</a>'; |
| 143 | $html .= '<p><time datetime="' . date('Y-m-d h:m:s', $sub_response['time']) . '">'; |
143 | $html .= '<p><time datetime="' . date('Y-m-d h:m:s', $sub_response['time']) . '">'; |
| 144 | $html .= date('Y-m-d h:m:s', $sub_response['time']) . '</time> by <a'; |
144 | $html .= date('Y-m-d h:m:s', $sub_response['time']) . '</time> by <a'; |
| 145 | $html .= ' href="/user/'. $sub_response['by'] . '">'; |
145 | $html .= ' href="/user/' . $sub_response['by'] . '">'; |
| 146 | $html .= $sub_response['by'] . '</a> | ' . $sub_response['score']; |
146 | $html .= $sub_response['by'] . '</a> | ' . $sub_response['score']; |
| 147 | $html .= ' points</p></div>'; |
147 | $html .= ' points</p></div>'; |
| 148 | $html_output .= $html; |
148 | $html_output .= $html; |
| 149 | } |
149 | } |
| 150 | |
150 | |
| 151 | return $html_output; |
151 | return $html_output; |
| 152 | } |
152 | } |
| 153 | |
153 | |
| 154 | /** |
154 | /** |
| 155 | *Extract a user's profile from Hacker News API and format in HTML |
155 | *Extract a user's profile from Hacker News API and format in HTML |
| 156 | * |
156 | * |
| 157 | * @access public |
157 | * @access public |
| 158 | * @author cmc <hello@cleberg.net> |
158 | * @param string $api_url The API endpoint to use for extraction |
| 159 | * @param string $api_url The API endpoint to use for extraction |
159 | * @param string $inline_title The <h1> title to use in the HTML |
| 160 | * @param string $inline_title The <h1> title to use in the HTML |
160 | * @return string $html_output The formatted HTML result of stories from the API |
| 161 | * @return string $html_output The formatted HTML result of stories from the API |
161 | * @author cmc <hello@cleberg.net> |
| 162 | */ |
162 | */ |
| 163 | function get_user(string $api_url, string $inline_title) { |
163 | function get_user(string $api_url, string $inline_title): string |
| 164 | $response_raw = file_get_contents($api_url); |
164 | { |
| 165 | if (is_null($response_raw) || $response_raw == "null") { |
165 | $response_raw = file_get_contents($api_url); |
| 166 | $html_output .= '<p>ERROR: User not found.</p>'; |
166 | if ($response_raw == "null") { |
| 167 | return $html_output; |
167 | return '<p>ERROR: User not found.</p>'; |
| 168 | } else { |
168 | } else { |
| 169 | $response = json_decode($response_raw, true); |
169 | $response = json_decode($response_raw, true); |
| 170 | } |
170 | } |
| 171 | |
171 | |
| 172 | // TODO: Can this be converted to a heredoc string with variables? |
172 | // TODO: Can this be converted to a heredoc string with variables? |
| 173 | $html_output = '<h1>' . $inline_title . '</h1>'; |
173 | $html_output = '<h1>' . $inline_title . '</h1>'; |
| 174 | $html_output .= '<p>About: ' . $response['about'] . '</p>'; |
174 | $html_output .= '<p>About: ' . $response['about'] . '</p>'; |
| 175 | $html_output .= '<p>Karma: ' . $response['karma'] . '</p>'; |
175 | $html_output .= '<p>Karma: ' . $response['karma'] . '</p>'; |
| 176 | $html_output .= '<p>Created: <time datetime="' . date('Y-m-d h:m:s', $response['created']) . '>' . date('Y-m-d h:m:s', $response['created']) . '</time></p>'; |
176 | $html_output .= '<p>Created: <time datetime="' . date('Y-m-d h:m:s', $response['created']) . '>' . date('Y-m-d h:m:s', $response['created']) . '</time></p>'; |
| 177 | $html_output .= '<p>Recently Submitted Posts:</p>'; |
177 | $html_output .= '<p>Recently Submitted Posts:</p>'; |
| 178 | |
178 | |
| 179 | $limit = count($response['submitted']) > 10 ? 10 : count($response['submitted']); |
179 | $limit = count($response['submitted']) > 10 ? 10 : count($response['submitted']); |
| 180 | if (count($response['submitted']) > 0) { |
180 | if (count($response['submitted']) > 0) { |
| 181 | for ($i = 0; $i < $limit; $i++) { |
181 | for ($i = 0; $i < $limit; $i++) { |
| 182 | $sub_url = 'https://hacker-news.firebaseio.com/v0/item/' . $response['submitted'][$i] . '.json'; |
182 | $sub_url = 'https://hacker-news.firebaseio.com/v0/item/' . $response['submitted'][$i] . '.json'; |
| 183 | $sub_response_raw = file_get_contents($sub_url); |
183 | $sub_response_raw = file_get_contents($sub_url); |
| 184 | $sub_response = json_decode($sub_response_raw, true); |
184 | $sub_response = json_decode($sub_response_raw, true); |
| 185 | |
185 | |
| 186 | if ($sub_response['type'] == 'story' || $sub_response['type'] == 'job') { |
186 | if ($sub_response['type'] == 'story' || $sub_response['type'] == 'job') { |
| 187 | $html = '<div><a href="' . $sub_response['url'] . '">' . $sub_response['title'] . '</a>'; |
187 | $html = '<div><a href="' . $sub_response['url'] . '">' . $sub_response['title'] . '</a>'; |
| 188 | $html .= '<p><time datetime="' . date('Y-m-d h:m:s', $sub_response['time']) . '">'; |
188 | $html .= '<p><time datetime="' . date('Y-m-d h:m:s', $sub_response['time']) . '">'; |
| 189 | $html .= date('Y-m-d h:m:s', $sub_response['time']) . '</time> by <a'; |
189 | $html .= date('Y-m-d h:m:s', $sub_response['time']) . '</time> by <a'; |
| 190 | $html .= ' href="/user/'. $sub_response['by'] . '">'; |
190 | $html .= ' href="/user/' . $sub_response['by'] . '">'; |
| 191 | $html .= $sub_response['by'] . '</a> | ' . $sub_response['score']; |
191 | $html .= $sub_response['by'] . '</a> | ' . $sub_response['score']; |
| 192 | $html .= ' points</p></div>'; |
192 | $html .= ' points</p></div>'; |
| 193 | } elseif ($sub_response['type'] == 'poll') { |
193 | } elseif ($sub_response['type'] == 'poll') { |
| 194 | // TODO: Handle polls |
194 | // TODO: Handle polls |
| 195 | $html = 'TODO: Add logic to handle polls here.'; |
195 | $html = 'TODO: Add logic to handle polls here.'; |
| 196 | } else { |
196 | } else { |
| 197 | // TODO: Add link to parent with $sub_response['parent'] |
197 | // TODO: Add link to parent with $sub_response['parent'] |
| 198 | $html = '<div><time datetime="' . date('Y-m-d h:m:s', $sub_response['time']); |
198 | $html = '<div><time datetime="' . date('Y-m-d h:m:s', $sub_response['time']); |
| 199 | $html .= '">' . date('Y-m-d h:m:s', $sub_response['time']); |
199 | $html .= '">' . date('Y-m-d h:m:s', $sub_response['time']); |
| 200 | $html .= '</time><br><p>' . $sub_response['text'] . '</p></div>'; |
200 | $html .= '</time><br><p>' . $sub_response['text'] . '</p></div>'; |
| 201 | } |
201 | } |
| 202 | $html_output .= $html; |
202 | $html_output .= $html; |
| 203 | } |
203 | } |
| 204 | } else { |
204 | } else { |
| 205 | $html_output .= '<p>User has no subsmissions.</p>'; |
205 | $html_output .= '<p>User has no submissions.</p>'; |
| 206 | } |
206 | } |
| 207 | |
207 | |
| 208 | return $html_output; |
208 | return $html_output; |
| 209 | } |
209 | } |
| 210 | |
210 | |
| 211 | |
211 | |
| 212 | /** |
212 | /** |
| 213 | * Send formatted HTML results to the user via a template |
213 | * Send formatted HTML results to the user via a template |
| 214 | * |
214 | * |
| 215 | * @access public |
215 | * @access public |
| 216 | * @author cmc <hello@cleberg.net> |
216 | * @param string $page_url Canonical URL for HTML header |
| 217 | * @param string $page_url Canoncial URL for HTML header |
217 | * @param string $page_description Page description for HTML header |
| 218 | * @param string $page_description Page description for HTML header |
218 | * @param string $page_title Page title for HTML header |
| 219 | * @param string $page_title Page title for HTML header |
219 | * @param string $page_content Page content to display in <main> |
| 220 | * @param string $page_content Page content to display in <main> |
220 | * @author cmc <hello@cleberg.net> |
| 221 | */ |
221 | */ |
| 222 | function echo_html(string $page_url, string $page_description, string $page_title, string $page_content) { |
222 | function echo_html(string $page_url, string $page_description, string $page_title, string $page_content) |
| 223 | include_once 'src/View/class-template.php'; |
223 | { |
| 224 | |
224 | include_once 'src/View/class-template.php'; |
| 225 | $template = new HN\View\Template( |
225 | |
| 226 | $page_url, |
226 | $template = new HN\View\Template( |
| 227 | $page_description, |
227 | $page_url, |
| 228 | $page_title, |
228 | $page_description, |
| 229 | $page_content |
229 | $page_title, |
| 230 | ); |
230 | $page_content |
| 231 | |
231 | ); |
| 232 | $template->echo_template(); |
232 | |
| |
233 | $template->echo_template(); |
| 233 | } |
234 | } |
| 234 | |
235 | |
| 235 | // EOF |
236 | // EOF |