Passed
Push — master ( 5b160d...6a638e )
by Florent
14:38
created

HomeController   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 283
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 125
c 3
b 0
f 0
dl 0
loc 283
rs 10
wmc 28

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A login() 0 6 1
B search() 0 49 8
A index() 0 39 4
A loginPost() 0 24 3
A sitemap() 0 23 2
A about() 0 12 1
B feed() 0 37 8
1
<?php
2
3
/**
4
 *  * Home controller
5
 *  *
6
 * The file contains every necessary functions for Home display.
7
 *
8
 *  * @category   Controllers
9
 *  * @package    SuperHive
10
 *  * @author     Florent Kosmala <[email protected]>
11
 *  * @license    https://www.gnu.org/licenses/gpl-3.0.txt GPL-3.0
12
 *  */
13
14
declare(strict_types=1);
15
16
namespace App\Controllers;
17
18
use App\Controllers\CommonController as Common;
19
use League\CommonMark\CommonMarkConverter;
20
use Psr\Container\ContainerInterface;
21
use Psr\Http\Message\ResponseInterface as Response;
22
use Psr\Http\Message\ServerRequestInterface as Request;
23
24
final class HomeController
25
{
26
    /** @var array<int|string, int|string> $settings */
27
    private array $settings;
28
29
    private ContainerInterface $app;
30
31
    public function __construct(ContainerInterface $app)
32
    {
33
        $this->app = $app;
34
        $this->settings = $app->get('settings');
35
36
        $common = new Common($this->app);
37
        $common->genPostsFile();
38
    }
39
40
    /**
41
     *  * Index function
42
     *  *
43
     * This function display the index page with the list of posts.
44
     * It ocntians also the function to generate the blog.json file with all posts informations.
45
     * All the posts must be converted from MarkDown to HTML before display.
46
     *
47
     * @param Response $response
48
     */
49
    public function index(Response $response): Response
50
    {
51
        $settings = $this->settings;
52
53
        // The file with the latest posts.
54
        $file = $this->app->get('blogfile');
55
56
        // Get the JSON
57
        $articles = json_decode(file_get_contents($file), true);
58
59
        //Get ready to parse the mardown
60
        $converter = new CommonMarkConverter();
61
        $parsedPosts = [];
62
63
        foreach ($articles as &$article) {
64
            // Create HTML from Markdown
65
            $article['body'] = $converter->convert($article['body']);
66
67
            //Get featured image
68
            $meta = json_decode($article['json_metadata'], true);
69
70
            if (isset($meta['image']) && (array_key_exists(0, $meta['image']))) {
71
                $featured = $meta['image'][0];
72
            } else {
73
                $featured = '/themes/' . $settings['theme'] . '/no-img.png';
74
            }
75
            $article['featured'] = $featured;
76
77
            $parsedPosts[] = $article;
78
        }
79
80
        $common = new Common($this->app);
81
        $mostUsedTags = $common->getMostUsedTags();
82
83
        // Return view with articles
84
        return $this->app->get('view')->render($response, $settings['theme'] . '/index.html', [
85
            'articles' => $parsedPosts,
86
            'tags' => $mostUsedTags,
87
            'settings' => $settings,
88
        ]);
89
    }
90
91
    /**
92
     *  * Search function
93
     *  *
94
     * This function was called when search form is not empty and the form was send.
95
     * It displays the posts which contains the selected string.
96
     *
97
     * @param Request $request
98
     * @param Response $response
99
     */
100
    public function search(Request $request, Response $response): Response
101
    {
102
        $data = $request->getParsedBody();
103
        $term = $data['term'];
104
        $posts = [];
105
        $result = [];
106
107
        $settings = $this->settings;
108
109
        if ($term === '') {
110
            $result = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
111
        } else {
112
            $file = $this->app->get('blogfile');
113
            $articles = json_decode(file_get_contents($file), true);
114
115
            $matches = [];
116
            $tags = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $tags is dead and can be removed.
Loading history...
117
118
            foreach ($articles as $article) {
119
                // Check in Title
120
                if (preg_match("/\b{$term}\b/i", $article['title'])) {
121
                    $matches[] = $article['title'];
122
                }
123
124
                // Check in Body
125
                if (preg_match("/\b{$term}\b/i", $article['body'])) {
126
                    $matches[] = $article['title'];
127
                }
128
129
                //Check in Tags
130
                $metadata = json_decode($article['json_metadata'], true);
131
                $tags = implode(',', $metadata['tags']);
132
                if (preg_match("/\b{$term}\b/i", $tags)) {
133
                    $matches[] = $article['title'];
134
                }
135
            }
136
            $result = array_unique($matches);
137
138
            foreach ($articles as $article) {
139
                if (in_array($article['title'], $result)) {
140
                    $posts[] = $article;
141
                }
142
            }
143
        }
144
145
        return $this->app->get('view')->render($response, $settings['theme'] . '/search.html', [
146
            'term' => $term,
147
            'posts' => $posts,
148
            'settings' => $settings,
149
        ]);
150
    }
151
152
    /**
153
     *  * Login function
154
     *  *
155
     * This function displays the login form.
156
     * It was called everytime an admin page is called without good session.
157
     *
158
     * @param object $request
159
     * @param Response $response
160
     */
161
    public function login(Response $response): Response
162
    {
163
        $settings = $this->settings;
164
165
        return $this->app->get('view')->render($response, 'login.html', [
166
            'settings' => $settings,
167
        ]);
168
    }
169
170
    /**
171
     *  * Login post function
172
     *  *
173
     * Called when the login form is send.
174
     * just compare the entered login and the encrypted key (generated by HiveKeychain)
175
     * with the credentials in passwod file.
176
     *
177
     * @param Request $request
178
     * @param Response $response
179
     */
180
    public function loginPost(Request $request, Response $response): Response
181
    {
182
        $settings = $this->settings;
183
        $session = $this->app->get('session');
184
        $data = $request->getParsedBody();
185
        $author = $settings['author'];
186
187
        if ($author !== $data['username']) {
188
            $session::destroy();
189
            $msg = 'Not Ok';
190
        } else {
191
            $cred = unserialize(file_get_contents($this->app->get('password')));
192
            $passwd = $cred[$author];
193
            if ($data['passwd'] === $passwd) {
194
                $session['sh_author'] = $author;
195
                $session['sh_sign'] = $passwd;
196
                $msg = 'OK';
197
            } else {
198
                $session::destroy();
199
                $msg = 'Not Ok';
200
            }
201
        }
202
        $response->getBody()->write($msg);
203
        return $response;
204
    }
205
206
    /*The value "always" should be used to describe documents that change each time they are accessed. T
207
     * Feed function
208
     *
209
     * Generate the RSS feed of account's posts
210
     *
211
     * @param object $response
212
     *
213
     * @return object $response
214
     */
215
    public function feed(Request $request, Response $response): Response
216
    {
217
        $settings = $this->settings;
218
        $data = $request->getQueryParams();
219
        $tag = $data['tag'] ?? null;
220
        $matches = [];
221
222
        $file = $this->app->get('blogfile');
223
        $articles = json_decode(file_get_contents($file), true);
224
225
        if($tag !== null) {
226
            foreach ($articles as $article) {
227
                $metadata = json_decode($article['json_metadata'], true);
228
                $tags = implode(',', $metadata['tags']);
229
                if (preg_match("/\b{$tag}\b/i", $tags)) {
230
                    $matches[] = $article['title'];
231
                }
232
            }
233
        }
234
235
        $result = array_unique($matches);
236
237
        if ($result !== null) {
238
            foreach ($articles as $article) {
239
                if (in_array($article['title'], $result)) {
240
                    $posts[] = $article;
241
                }
242
            }
243
        }
244
        if (!empty($posts)) {
245
            $articles = $posts;
246
        }
247
248
        header('Content-Type: text/xml');
249
        return $this->app->get('view')->render($response, '/feed.xml', [
250
            'articles' => $articles,
251
            'settings' => $settings,
252
        ]);
253
    }
254
255
    /**
256
     *  * Sitemap function
257
     *  *
258
     * Generate the Sitemap with all posts links.
259
     *
260
     * @param Response $response
261
     */
262
    public function sitemap(Response $response): Response
263
    {
264
        $settings = $this->settings;
265
266
        $pages = [];
267
268
        $file = $this->app->get('blogfile');
269
        $articles = json_decode(file_get_contents($file), true);
270
271
        $pagesDir = $this->app->get('pagesdir');
272
        $files = preg_grep('~\.(html)$~', scandir($pagesDir));
273
        foreach ($files as $file) {
274
            $page = [];
275
            $page['created'] = filemtime($pagesDir . $file);
276
            $page['name'] = mb_substr($file, 0, -5);
277
            $pages[] = $page;
278
        }
279
280
        header('Content-Type: text/xml');
281
        return $this->app->get('view')->render($response, '/sitemap.xml', [
282
            'articles' => $articles,
283
            'pages' => $pages,
284
            'settings' => $settings,
285
        ]);
286
    }
287
288
    /**
289
     *  * About function
290
     *  *
291
     * Generate the about page with account information.
292
     *
293
     * @param Response $response
294
     */
295
    public function about(Response $response): Response
296
    {
297
        $settings = $this->settings;
298
        $accountFile = $this->app->get('accountfile');
299
        $account = json_decode(file_get_contents($accountFile), true);
300
301
        $accountBio = json_decode($account[0]['posting_json_metadata'], true);
302
303
        return $this->app->get('view')->render($response, $settings['theme'] . '/about.html', [
304
            'settings' => $settings,
305
            'data' => $account[0],
306
            'account' => $accountBio['profile'],
307
        ]);
308
    }
309
}
310