Commit d0138b92ae

d0138b92ae002002d520b9871764039e678930b7

parent: 7f0d14fe6f

Unsigned

cmc <hello@cleberg.net> · 2023-06-14 19:37 UTC

fix: code quality and formatting

Layout: unified · split

.idea/.gitignore added +8
@@ -0,0 +1,8 @@
1# Default ignored files
2/shelf/
3/workspace.xml
4# Editor-based HTTP Client requests
5/httpRequests/
6# Datasource local storage ignored files
7/dataSources/
8/dataSources.local.xml
.idea/hn.iml added +8
@@ -0,0 +1,8 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<module type="WEB_MODULE" version="4">
3 <component name="NewModuleRootManager">
4 <content url="file://$MODULE_DIR$" />
5 <orderEntry type="inheritedJdk" />
6 <orderEntry type="sourceFolder" forTests="false" />
7 </component>
8</module>\ No newline at end of file
.idea/modules.xml added +8
@@ -0,0 +1,8 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<project version="4">
3 <component name="ProjectModuleManager">
4 <modules>
5 <module fileurl="file://$PROJECT_DIR$/.idea/hn.iml" filepath="$PROJECT_DIR$/.idea/hn.iml" />
6 </modules>
7 </component>
8</project>\ No newline at end of file
.idea/php.xml added +22
@@ -0,0 +1,22 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<project version="4">
3 <component name="MessDetectorOptionsConfiguration">
4 <option name="transferred" value="true" />
5 </component>
6 <component name="PHPCSFixerOptionsConfiguration">
7 <option name="transferred" value="true" />
8 </component>
9 <component name="PHPCodeSnifferOptionsConfiguration">
10 <option name="highlightLevel" value="WARNING" />
11 <option name="transferred" value="true" />
12 </component>
13 <component name="PhpProjectSharedConfiguration" php_language_level="7.0">
14 <option name="suggestChangeDefaultLanguageLevel" value="false" />
15 </component>
16 <component name="PhpStanOptionsConfiguration">
17 <option name="transferred" value="true" />
18 </component>
19 <component name="PsalmOptionsConfiguration">
20 <option name="transferred" value="true" />
21 </component>
22</project>\ No newline at end of file
.idea/vcs.xml added +6
@@ -0,0 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<project version="4">
3 <component name="VcsDirectoryMappings">
4 <mapping directory="" vcs="Git" />
5 </component>
6</project>\ No newline at end of file
index.php +215 −214
@@ -5,231 +5,232 @@ $path = ltrim($_SERVER['REQUEST_URI'], '/');
5$elements = explode('/', $path); 5$elements = explode('/', $path);
6 6
7if (empty($elements[0])) { 7if (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 */
125function get_stories($api_url, $inline_title) { 125function 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 */
163function get_user(string $api_url, string $inline_title) { 163function 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 */
222function echo_html(string $page_url, string $page_description, string $page_title, string $page_content) { 222function 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