1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @package Blogs |
4
|
|
|
* @category modules |
5
|
|
|
* @author Nazar Mokrynskyi <[email protected]> |
6
|
|
|
* @copyright Copyright (c) 2011-2016, Nazar Mokrynskyi |
7
|
|
|
* @license MIT License, see license.txt |
8
|
|
|
*/ |
9
|
|
|
namespace cs\modules\Blogs\api; |
10
|
|
|
use |
11
|
|
|
h, |
12
|
|
|
cs\Config, |
13
|
|
|
cs\ExitException, |
14
|
|
|
cs\Language\Prefix, |
15
|
|
|
cs\Page, |
16
|
|
|
cs\User, |
17
|
|
|
cs\modules\Blogs\Posts, |
18
|
|
|
cs\modules\Blogs\Sections; |
19
|
|
|
|
20
|
|
|
class Controller { |
21
|
|
|
static function __get_settings () { |
22
|
|
|
$User = User::instance(); |
23
|
|
|
$module_data = Config::instance()->module('Blogs'); |
24
|
|
|
return [ |
25
|
|
|
'inline_editor' => functionality('inline_editor'), |
26
|
|
|
'max_sections' => $module_data->max_sections, |
27
|
|
|
'new_posts_only_from_admins' => $module_data->new_posts_only_from_admins, //TODO use this on frontend |
28
|
|
|
'can_delete_posts' => //TODO use this on frontend |
29
|
|
|
$User->admin() && |
30
|
|
|
$User->get_permission('admin/Blogs', 'index') && |
31
|
|
|
$User->get_permission('admin/Blogs', 'edit_post') |
32
|
|
|
]; |
33
|
|
|
} |
34
|
|
|
/** |
35
|
|
|
* @param \cs\Request $Request |
36
|
|
|
* |
37
|
|
|
* @return array |
|
|
|
|
38
|
|
|
* |
39
|
|
|
* @throws ExitException |
40
|
|
|
*/ |
41
|
|
|
static function posts_get ($Request) { |
42
|
|
|
$id = $Request->route_ids(0); |
43
|
|
|
if ($id) { |
44
|
|
|
$post = Posts::instance()->get($id); |
45
|
|
|
if (!$post) { |
46
|
|
|
throw new ExitException(404); |
47
|
|
|
} |
48
|
|
|
return $post; |
49
|
|
|
} else { |
|
|
|
|
50
|
|
|
// TODO: implement latest posts |
51
|
|
|
} |
52
|
|
|
} |
53
|
|
|
/** |
54
|
|
|
* @param \cs\Request $Request |
55
|
|
|
* @param \cs\Response $Response |
56
|
|
|
* |
57
|
|
|
* @return array |
|
|
|
|
58
|
|
|
* |
59
|
|
|
* @throws ExitException |
60
|
|
|
*/ |
61
|
|
|
static function posts_post ($Request, $Response) { |
62
|
|
|
$Config = Config::instance(); |
63
|
|
|
$module_data = $Config->module('Blogs'); |
64
|
|
|
$L = new Prefix('blogs_'); |
65
|
|
|
$User = User::instance(); |
66
|
|
|
if (!$User->admin() && $module_data->new_posts_only_from_admins) { |
67
|
|
|
throw new ExitException(403); |
68
|
|
|
} |
69
|
|
|
if (!$User->user()) { |
70
|
|
|
throw new ExitException($L->for_registered_users_only, 403); |
71
|
|
|
} |
72
|
|
|
$data = static::check_request_data($Request, $L); |
73
|
|
|
if (!$data) { |
74
|
|
|
throw new ExitException(400); |
75
|
|
|
} |
76
|
|
|
$Posts = Posts::instance(); |
77
|
|
|
$id = $Posts->add($data['title'], $data['path'], $data['content'], $data['sections'], $data['tags'], $data['mode'] == 'draft'); |
78
|
|
|
if (!$id) { |
79
|
|
|
throw new ExitException($L->post_adding_error, 500); |
80
|
|
|
} |
81
|
|
|
$Response->code = 201; |
82
|
|
|
return [ |
83
|
|
|
'id' => $id, |
84
|
|
|
'url' => $Config->base_url().'/'.path($L->Blogs).'/'.$Posts->get($id)['path'].":$id" |
85
|
|
|
]; |
86
|
|
|
} |
87
|
|
|
/** |
88
|
|
|
* @param \cs\Request $Request |
89
|
|
|
* |
90
|
|
|
* @return array |
|
|
|
|
91
|
|
|
* |
92
|
|
|
* @throws ExitException |
93
|
|
|
*/ |
94
|
|
|
static function posts_put ($Request) { |
95
|
|
|
$Config = Config::instance(); |
96
|
|
|
$L = new Prefix('blogs_'); |
97
|
|
|
$User = User::instance(); |
98
|
|
|
$id = $Request->route(1); |
99
|
|
|
$data = static::check_request_data($Request, $L); |
100
|
|
|
if (!$id || !$data) { |
101
|
|
|
throw new ExitException(400); |
102
|
|
|
} |
103
|
|
|
$Posts = Posts::instance(); |
104
|
|
|
$post = $Posts->get($id); |
105
|
|
|
if (!$post) { |
106
|
|
|
throw new ExitException(404); |
107
|
|
|
} |
108
|
|
|
if ( |
109
|
|
|
!$User->admin() || |
110
|
|
|
!$User->get_permission('admin/Blogs', 'index') || |
111
|
|
|
!$User->get_permission('admin/Blogs', 'edit_post') |
112
|
|
|
) { |
113
|
|
|
throw new ExitException(403); |
114
|
|
|
} |
115
|
|
|
if (!$Posts->set($id, $data['title'], $data['path'], $data['content'], $data['sections'], $data['tags'], $data['mode'] == 'draft')) { |
116
|
|
|
throw new ExitException($L->post_saving_error, 500); |
117
|
|
|
} |
118
|
|
|
return [ |
119
|
|
|
'id' => $id, |
120
|
|
|
'url' => $Config->base_url().'/'.path($L->Blogs).'/'.$Posts->get($id)['path'].":$id" |
121
|
|
|
]; |
122
|
|
|
} |
123
|
|
|
/** |
124
|
|
|
* @param \cs\Request $Request |
125
|
|
|
* |
126
|
|
|
* @throws ExitException |
127
|
|
|
*/ |
128
|
|
|
static function posts_delete ($Request) { |
129
|
|
|
$L = new Prefix('blogs_'); |
130
|
|
|
$User = User::instance(); |
131
|
|
|
$id = $Request->route(1); |
132
|
|
|
if (!$id) { |
133
|
|
|
throw new ExitException(400); |
134
|
|
|
} |
135
|
|
|
$Posts = Posts::instance(); |
136
|
|
|
$post = $Posts->get($id); |
137
|
|
|
if (!$post) { |
138
|
|
|
throw new ExitException(404); |
139
|
|
|
} |
140
|
|
|
if ( |
141
|
|
|
$post['user'] != $User->id && |
142
|
|
|
!( |
143
|
|
|
$User->admin() && |
144
|
|
|
$User->get_permission('admin/Blogs', 'index') && |
145
|
|
|
$User->get_permission('admin/Blogs', 'edit_post') |
146
|
|
|
) |
147
|
|
|
) { |
148
|
|
|
throw new ExitException(403); |
149
|
|
|
} |
150
|
|
|
if (!$Posts->del($id)) { |
151
|
|
|
throw new ExitException($L->post_deleting_error, 500); |
152
|
|
|
} |
153
|
|
|
} |
154
|
|
|
/** |
155
|
|
|
* @param \cs\Request $Request |
156
|
|
|
* @param Prefix $L |
157
|
|
|
* |
158
|
|
|
* @return array |
159
|
|
|
* |
160
|
|
|
* @throws ExitException |
161
|
|
|
*/ |
162
|
|
|
protected static function check_request_data ($Request, $L) { |
163
|
|
|
$data = $Request->data('title', 'sections', 'content', 'tags', 'mode'); |
164
|
|
|
if (!$data) { |
165
|
|
|
throw new ExitException(400); |
166
|
|
|
} |
167
|
|
|
$data['path'] = $Request->data('path'); |
168
|
|
|
if (empty($data['title'])) { |
169
|
|
|
throw new ExitException($L->post_title_empty, 400); |
170
|
|
|
} |
171
|
|
|
if (empty($data['sections']) || !is_array($data['sections'])) { |
172
|
|
|
throw new ExitException($L->no_post_sections_specified, 400); |
173
|
|
|
} |
174
|
|
|
if (empty($data['content'])) { |
175
|
|
|
throw new ExitException($L->post_content_empty, 400); |
176
|
|
|
} |
177
|
|
|
if (empty($data['tags']) || !is_array($data['tags'])) { |
178
|
|
|
throw new ExitException($L->no_post_tags_specified, 400); |
179
|
|
|
} |
180
|
|
|
return $data; |
181
|
|
|
} |
182
|
|
|
static function posts_preview () { |
183
|
|
|
$Config = Config::instance(); |
184
|
|
|
$User = User::instance(); |
185
|
|
|
if (!$User->user()) { |
186
|
|
|
throw new ExitException(403); |
187
|
|
|
} |
188
|
|
|
$L = new Prefix('blogs_'); |
189
|
|
|
$Page = Page::instance(); |
190
|
|
|
if (empty($_POST['title'])) { |
191
|
|
|
$Page->warning($L->post_title_empty); |
192
|
|
|
$Page->json($Page->Top); |
193
|
|
|
return; |
194
|
|
|
} |
195
|
|
|
if (empty($_POST['sections']) && $_POST['sections'] !== '0') { |
196
|
|
|
$Page->warning($L->no_post_sections_specified); |
197
|
|
|
$Page->json($Page->Top); |
198
|
|
|
return; |
199
|
|
|
} |
200
|
|
|
if (empty($_POST['content'])) { |
201
|
|
|
$Page->warning($L->post_content_empty); |
202
|
|
|
$Page->json($Page->Top); |
203
|
|
|
return; |
204
|
|
|
} |
205
|
|
|
if (empty($_POST['tags'])) { |
206
|
|
|
$Page->warning($L->no_post_tags_specified); |
207
|
|
|
$Page->json($Page->Top); |
208
|
|
|
return; |
209
|
|
|
} |
210
|
|
|
$Posts = Posts::instance(); |
211
|
|
|
$Sections = Sections::instance(); |
212
|
|
|
$post = isset($_POST['id']) ? $Posts->get($_POST['id']) : [ |
213
|
|
|
'date' => TIME, |
214
|
|
|
'user' => $User->id, |
215
|
|
|
'comments_count' => 0 |
216
|
|
|
]; |
217
|
|
|
$module = path($L->Blogs); |
218
|
|
|
$module_data = $Config->module('Blogs'); |
219
|
|
|
$Page->json( |
220
|
|
|
h::{'section.cs-blogs-post article'}( |
221
|
|
|
h::header( |
222
|
|
|
h::h1(xap($_POST['title'])). |
223
|
|
|
((array)$_POST['sections'] != [0] ? h::p( |
224
|
|
|
h::icon('bookmark'). |
225
|
|
|
implode( |
226
|
|
|
', ', |
227
|
|
|
array_map( |
228
|
|
|
function ($section) use ($Sections, $L, $module) { |
229
|
|
|
$section = $Sections->get($section); |
230
|
|
|
return h::a( |
231
|
|
|
$section['title'], |
232
|
|
|
[ |
233
|
|
|
'href' => "$module/".path($L->section)."/$section[full_path]" |
234
|
|
|
] |
235
|
|
|
); |
236
|
|
|
}, |
237
|
|
|
(array)$_POST['sections'] |
238
|
|
|
) |
239
|
|
|
) |
240
|
|
|
) : '') |
241
|
|
|
). |
242
|
|
|
xap($_POST['content'], true, $module_data->allow_iframes_without_content)."\n". |
243
|
|
|
h::footer( |
244
|
|
|
h::p( |
245
|
|
|
h::icon('tags'). |
246
|
|
|
implode( |
247
|
|
|
', ', |
248
|
|
|
array_map( |
249
|
|
|
function ($tag) use ($L, $module) { |
250
|
|
|
$tag = xap($tag); |
251
|
|
|
return h::a( |
252
|
|
|
$tag, |
253
|
|
|
[ |
254
|
|
|
'href' => "$module/".path($L->tag)."/$tag", |
255
|
|
|
'rel' => 'tag' |
256
|
|
|
] |
257
|
|
|
); |
258
|
|
|
}, |
259
|
|
|
_trim($_POST['tags']) |
260
|
|
|
) |
261
|
|
|
) |
262
|
|
|
). |
263
|
|
|
h::hr(). |
264
|
|
|
h::p( |
265
|
|
|
h::time( |
266
|
|
|
$L->to_locale(date($L->_datetime_long, $post['date'])), |
267
|
|
|
[ |
268
|
|
|
'datetime' => date('c', $post['date']) |
269
|
|
|
] |
270
|
|
|
). |
271
|
|
|
h::icon('user').$User->username($post['user']). |
272
|
|
|
( |
273
|
|
|
$module_data->enable_comments ? h::icon('comments').$post['comments_count'] : '' |
274
|
|
|
) |
275
|
|
|
) |
276
|
|
|
) |
277
|
|
|
). |
278
|
|
|
h::br(2) |
279
|
|
|
); |
280
|
|
|
} |
281
|
|
|
static function sections_get () { |
282
|
|
|
return Sections::instance()->get_all() ?: []; |
283
|
|
|
} |
284
|
|
|
} |
285
|
|
|
|
This check compares the return type specified in the
@return
annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.If the return type contains the type array, this check recommends the use of a more specific type like
String[]
orarray<String>
.