Issues (13)

src/Controllers/PostsController.php (1 issue)

1
<?php
2
3
/**
4
 *  * Post controller
5
 *  *
6
 * The file contains all the functions used for posts.
7
 * Display / Save / update / ...
8
 *
9
 *  * @category   Controllers
10
 *  * @package    SuperHive
11
 *  * @author     Florent Kosmala <[email protected]>
12
 *  * @license    https://www.gnu.org/licenses/gpl-3.0.txt GPL-3.0
13
 *  */
14
15
declare(strict_types=1);
16
17
namespace App\Controllers;
18
19
use App\Controllers\CommonController as Common;
20
use Embed\Embed;
21
use Hive\PhpLib\Hive\Condenser as HiveCondenser;
22
use League\CommonMark\Environment\Environment;
23
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
24
use League\CommonMark\Extension\Embed\EmbedExtension;
25
use League\CommonMark\Extension\Embed\Bridge\OscaroteroEmbedAdapter;
26
use League\CommonMark\Extension\GithubFlavoredMarkdownExtension;
27
use League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkExtension;
28
use League\CommonMark\Extension\TableOfContents\TableOfContentsExtension;
29
use League\CommonMark\MarkdownConverter;
30
use Psr\Container\ContainerInterface;
31
use Psr\Http\Message\ResponseInterface as Response;
32
33
final class PostsController
34
{
35
    private ContainerInterface $app;
36
37
    public function __construct(ContainerInterface $app)
38
    {
39
        $this->app = $app;
40
        $genPosts = new Common($this->app);
41
        $genPosts->genPostsFile();
42
43
        $session = $this->app->get('session');
44
45
        $this->app->get('view')->getEnvironment()->addGlobal("user", [
46
            'author' => $session['sh_author'],
47
            'signature' => $session['sh_sign'],
48
        ]);
49
    }
50
51
    /**
52
     *  * Post function
53
     *  *
54
     * This function display the selected post in the blog.json (from Blockchain).
55
     * It also take all comments to display them in the end of post
56
     *
57
     * @param string $permlink
58
     * @param Response $response
59
     */
60
    public function post(string $permlink, Response $response): Response
61
    {
62
        $settings = $this->app->get('settings');
63
64
        $apiConfig = [
65
            'hiveNode' => $settings['api'],
66
            'debug' => false,
67
        ];
68
69
        if (!empty($permlink)) {
70
            $embedLibrary = new Embed();
71
            $embedLibrary->setSettings([
72
                'oembed:query_parameters' => [
73
                    'maxwidth' => 800,
74
                    'maxheight' => 600,
75
                ]
76
            ]);
77
78
            $markdownConfig = [
79
                'embed' => [
80
                    'adapter' => new OscaroteroEmbedAdapter($embedLibrary),
81
                    'fallback' => 'link',
82
                ],
83
                'heading_permalink' => [
84
                    'html_class' => 'heading-permalink',
85
                    'insert' => 'before',
86
                    'symbol' => '# ',
87
                    'title' => "Permalink",
88
                    'id_prefix' => ''
89
                ]
90
            ];
91
92
            $environment = new Environment($markdownConfig);
93
            $environment->addExtension(new CommonMarkCoreExtension());
94
            $environment->addExtension(new GithubFlavoredMarkdownExtension());
95
            $environment->addExtension(new HeadingPermalinkExtension());
96
            $environment->addExtension(new EmbedExtension());
97
            $converter = new MarkdownConverter($environment);
98
99
            $parsedReplies = [];
100
            $file = $this->app->get('blogfile');
101
            $articles = json_decode(file_get_contents($file), true);
102
            foreach ($articles as $index => $article) {
103
                if ($article['permlink'] === $permlink) {
104
                    $metadata = json_decode($article['json_metadata'], true);
105
                    $article['body'] = $converter->convert($article['body']);
106
107
                    // Check if comments exists for this post
108
                    $cmts = $this->app->get('commentsdir') . $permlink . '.comments';
109
                    $delay = $settings['delay'];
110
                    if ((!file_exists($cmts)) || (file_exists($cmts)) && (time() - filemtime($cmts) > $delay)) {
111
                        $api = new HiveCondenser($apiConfig);
112
                        $replies = $api->getContentReplies($article['author'], $permlink);
113
                        $result = json_encode($replies, JSON_PRETTY_PRINT);
114
                        file_put_contents($cmts, $result);
115
                    }
116
                    $replies = json_decode(file_get_contents($cmts), true);
117
118
                    foreach ($replies as $reply) {
119
                        $reply['body'] = $converter->convert($reply['body']);
120
                        $parsedReplies[] = $reply;
121
                    }
122
123
                    return $this->app->get('view')->render($response, $settings['theme'] . '/post.html', [
124
                        'settings' => $settings,
125
                        'article' => $article,
126
                        'metadata' => $metadata,
127
                        'replies' => $parsedReplies,
128
                    ]);
129
                }
130
            }
131
        }
132
        return $response;
133
    }
134
135
    /**
136
     *  * Post function
137
     *  *
138
     * This function display the selected post in the blog.json (from Blockchain).
139
     * It also take all comments to display them in the end of post
140
     *
141
     * @param string $tag
142
     * @param object $request
143
     * @param Response $response
144
     *
145
     * @return Response $response
146
     */
147
    public function tag(string $tag, Response $response): Response
148
    {
149
        $settings = $this->app->get('settings');
150
        $posts = [];
151
        $result = [];
0 ignored issues
show
The assignment to $result is dead and can be removed.
Loading history...
152
153
        if (!empty($tag)) {
154
            $matches = [];
155
            $file = $this->app->get('blogfile');
156
            $articles = json_decode(file_get_contents($file), true);
157
158
            foreach ($articles as $article) {
159
                //Check in Tags
160
                $metadata = json_decode($article['json_metadata'], true);
161
                $tags = implode(',', $metadata['tags']);
162
                if (preg_match("/\b{$tag}\b/i", $tags)) {
163
                    $matches[] = $article['title'];
164
                }
165
            }
166
167
            $result = array_unique($matches);
168
169
            foreach ($articles as $article) {
170
                if (in_array($article['title'], $result)) {
171
                    //Get featured image
172
                    $meta = json_decode($article['json_metadata'], true);
173
174
                    if (
175
                        array_key_exists('image', $meta)
176
                        && is_array($meta['image'])
177
                        && array_key_exists(0, $meta['image'])
178
                    ) {
179
                        $featured = $meta['image'][0];
180
                    } else {
181
                        $featured = '/themes/' . $settings['theme'] . '/no-img.png';
182
                    }
183
184
                    $article['featured'] = $featured;
185
                    $posts[] = $article;
186
                }
187
            }
188
        }
189
190
        return $this->app->get('view')->render($response, $settings['theme'] . '/tag.html', [
191
            'tag' => $tag,
192
            'posts' => $posts,
193
            'settings' => $settings,
194
        ]);
195
    }
196
197
    /**
198
     *  * Administration posts function
199
     *  *
200
     * This function display the post page in admin panel.
201
     * Contains every posts in blog.json file (from blockchain)
202
     *
203
     * @param Response $response
204
     */
205
    public function adminPosts(Response $response): Response
206
    {
207
        $settings = $this->app->get('settings');
208
209
        $file = $this->app->get('blogfile');
210
        $blog = json_decode(file_get_contents($file), true);
211
212
        return $this->app->get('view')->render($response, '/admin/admin-posts.html', [
213
            'settings' => $settings,
214
            'posts' => $blog,
215
        ]);
216
    }
217
218
    /**
219
     *  * Administration new post function
220
     *  *
221
     * This function just display the new post page to write and send post.
222
     *
223
     * @param Response $response
224
     */
225
    public function adminNewPost(Response $response): Response
226
    {
227
        $settings = $this->app->get('settings');
228
229
        return $this->app->get('view')->render($response, '/admin/admin-newpost.html', [
230
            'settings' => $settings,
231
        ]);
232
    }
233
234
    /**
235
     *  * Administration edit post function
236
     *  *
237
     * Same as adminNewPost but with already written content from an old post.
238
     *
239
     * @param string $posted
240
     * @param Response $response
241
     */
242
    public function adminEditPost(string $posted, Response $response): Response
243
    {
244
        $file = $this->app->get('blogfile');
245
        $settings = $this->app->get('settings');
246
247
        $posts = json_decode(file_get_contents($file), true);
248
249
        $permlinks = [];
250
251
        foreach ($posts as $post) {
252
            $permlinks[] = $post['permlink'];
253
        }
254
255
        $column = array_column($posts, 'permlink');
256
        $postIndex = array_search($posted, $column);
257
258
        if (is_numeric($postIndex)) {
259
            $post = $posts[$postIndex];
260
            $postTitle = $post['title'];
261
            $permlink = $post['permlink'];
262
            $content = $post['body'];
263
            $metadata = json_decode($post['json_metadata']);
264
265
            return $this->app->get('view')->render($response, '/admin/admin-newpost.html', [
266
                'settings' => $settings,
267
                'postTitle' => $postTitle,
268
                'postContent' => $content,
269
                'postPermlink' => $permlink,
270
                'postTags' => $metadata->tags,
271
            ]);
272
        }
273
        $response->getBody()->write('No Post Found');
274
        return $response;
275
    }
276
}
277