]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/newnotice.php
IMPORTANT: parent::handlePost() in NewnoticeAction
[quix0rs-gnu-social.git] / actions / newnotice.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Handler for posting new notices
6  *
7  * PHP version 5
8  *
9  * LICENCE: This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU Affero General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Affero General Public License for more details.
18  *
19  * You should have received a copy of the GNU Affero General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  * @category  Personal
23  * @package   StatusNet
24  * @author    Evan Prodromou <evan@status.net>
25  * @author    Zach Copley <zach@status.net>
26  * @author    Sarven Capadisli <csarven@status.net>
27  * @copyright 2008-2009 StatusNet, Inc.
28  * @copyright 2013 Free Software Foundation, Inc.
29  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
30  * @link      http://status.net/
31  */
32
33 if (!defined('STATUSNET')) {
34     exit(1);
35 }
36
37 require_once INSTALLDIR . '/lib/noticelist.php';
38 require_once INSTALLDIR . '/lib/mediafile.php';
39
40 /**
41  * Action for posting new notices
42  *
43  * @category Personal
44  * @package  StatusNet
45  * @author   Evan Prodromou <evan@status.net>
46  * @author   Zach Copley <zach@status.net>
47  * @author   Sarven Capadisli <csarven@status.net>
48  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
49  * @link     http://status.net/
50  */
51 class NewnoticeAction extends FormAction
52 {
53     /**
54      * Title of the page
55      *
56      * Note that this usually doesn't get called unless something went wrong
57      *
58      * @return string page title
59      */
60     function title()
61     {
62         // TRANS: Page title for sending a new notice.
63         return _m('TITLE','New notice');
64     }
65
66     /**
67      * Handle input, produce output
68      *
69      * Switches based on GET or POST method. On GET, shows a form
70      * for posting a notice. On POST, saves the results of that form.
71      *
72      * Results may be a full page, or just a single notice list item,
73      * depending on whether AJAX was requested.
74      *
75      * @param array $args $_REQUEST contents
76      *
77      * @return void
78      */
79     protected function prepare(array $args=array())
80     {
81         parent::prepare($args);
82
83         if (!common_logged_in()) {
84             // TRANS: Error message displayed when trying to perform an action that requires a logged in user.
85             $this->clientError(_('Not logged in.'), 403);
86         }
87
88         return true;
89     }
90
91     /**
92      * This handlePost saves a new notice, based on arguments
93      *
94      * If successful, will show the notice, or return an Ajax-y result.
95      * If not, it will show an error message -- possibly Ajax-y.
96      *
97      * Also, if the notice input looks like a command, it will run the
98      * command and show the results -- again, possibly ajaxy.
99      *
100      * @return void
101      */
102     protected function handlePost()
103     {
104         parent::handlePost();
105
106         assert($this->scoped); // XXX: maybe an error instead...
107         $user = $this->scoped->getUser();
108         $content = $this->trimmed('status_textarea');
109         $options = array();
110         Event::handle('StartSaveNewNoticeWeb', array($this, $user, &$content, &$options));
111
112         if (!$content) {
113             // TRANS: Client error displayed trying to send a notice without content.
114             $this->clientError(_('No content!'));
115         }
116
117         $inter = new CommandInterpreter();
118
119         $cmd = $inter->handle_command($user, $content);
120
121         if ($cmd) {
122             if (StatusNet::isAjax()) {
123                 $cmd->execute(new AjaxWebChannel($this));
124             } else {
125                 $cmd->execute(new WebChannel($this));
126             }
127             return;
128         }
129
130         $content_shortened = $user->shortenLinks($content);
131         if (Notice::contentTooLong($content_shortened)) {
132             // TRANS: Client error displayed when the parameter "status" is missing.
133             // TRANS: %d is the maximum number of character for a notice.
134             $this->clientError(sprintf(_m('That\'s too long. Maximum notice size is %d character.',
135                                           'That\'s too long. Maximum notice size is %d characters.',
136                                           Notice::maxContent()),
137                                        Notice::maxContent()));
138         }
139
140         $replyto = intval($this->trimmed('inreplyto'));
141         if ($replyto) {
142             $options['reply_to'] = $replyto;
143         }
144
145         $upload = null;
146         $upload = MediaFile::fromUpload('attach');
147
148         if (isset($upload)) {
149
150             if (Event::handle('StartSaveNewNoticeAppendAttachment', array($this, $upload, &$content_shortened, &$options))) {
151                 $content_shortened .= ' ' . $upload->shortUrl();
152             }
153             Event::handle('EndSaveNewNoticeAppendAttachment', array($this, $upload, &$content_shortened, &$options));
154
155             if (Notice::contentTooLong($content_shortened)) {
156                 $upload->delete();
157                 // TRANS: Client error displayed exceeding the maximum notice length.
158                 // TRANS: %d is the maximum length for a notice.
159                 $this->clientError(sprintf(_m('Maximum notice size is %d character, including attachment URL.',
160                                               'Maximum notice size is %d characters, including attachment URL.',
161                                               Notice::maxContent()),
162                                            Notice::maxContent()));
163             }
164         }
165
166         if ($user->shareLocation()) {
167             // use browser data if checked; otherwise profile data
168             if ($this->arg('notice_data-geo')) {
169                 $locOptions = Notice::locationOptions($this->trimmed('lat'),
170                                                       $this->trimmed('lon'),
171                                                       $this->trimmed('location_id'),
172                                                       $this->trimmed('location_ns'),
173                                                       $user->getProfile());
174             } else {
175                 $locOptions = Notice::locationOptions(null,
176                                                       null,
177                                                       null,
178                                                       null,
179                                                       $user->getProfile());
180             }
181
182             $options = array_merge($options, $locOptions);
183         }
184
185         $author_id = $user->id;
186         $text      = $content_shortened;
187
188         // Does the heavy-lifting for getting "To:" information
189
190         ToSelector::fillOptions($this, $options);
191
192         if (Event::handle('StartNoticeSaveWeb', array($this, &$author_id, &$text, &$options))) {
193
194             $notice = Notice::saveNew($user->id, $content_shortened, 'web', $options);
195
196             if (isset($upload)) {
197                 $upload->attachToNotice($notice);
198             }
199
200             Event::handle('EndNoticeSaveWeb', array($this, $notice));
201         }
202         Event::handle('EndSaveNewNoticeWeb', array($this, $user, &$content_shortened, &$options));
203
204         if (StatusNet::isAjax()) {
205             header('Content-Type: text/xml;charset=utf-8');
206             $this->xw->startDocument('1.0', 'UTF-8');
207             $this->elementStart('html');
208             $this->elementStart('head');
209             // TRANS: Page title after sending a notice.
210             $this->element('title', null, _('Notice posted'));
211             $this->elementEnd('head');
212             $this->elementStart('body');
213             $this->showNotice($notice);
214             $this->elementEnd('body');
215             $this->elementEnd('html');
216             exit;
217         } else {
218             $returnto = $this->trimmed('returnto');
219
220             if ($returnto) {
221                 $url = common_local_url($returnto,
222                                         array('nickname' => $user->nickname));
223             } else {
224                 $url = common_local_url('shownotice',
225                                         array('notice' => $notice->id));
226             }
227             common_redirect($url, 303);
228         }
229     }
230
231     /**
232      * Show an Ajax-y error message
233      *
234      * Goes back to the browser, where it's shown in a popup.
235      *
236      * @param string $msg Message to show
237      *
238      * @return void
239      */
240     function ajaxErrorMsg($msg)
241     {
242         $this->startHTML('text/xml;charset=utf-8', true);
243         $this->elementStart('head');
244         // TRANS: Page title after an AJAX error occurs on the send notice page.
245         $this->element('title', null, _('Ajax Error'));
246         $this->elementEnd('head');
247         $this->elementStart('body');
248         $this->element('p', array('id' => 'error'), $msg);
249         $this->elementEnd('body');
250         $this->elementEnd('html');
251     }
252
253     /**
254      * Show an Ajax-y notice form
255      *
256      * Goes back to the browser, where it's shown in a popup.
257      *
258      * @param string $msg Message to show
259      *
260      * @return void
261      */
262     function ajaxShowForm()
263     {
264         $this->startHTML('text/xml;charset=utf-8', true);
265         $this->elementStart('head');
266         // TRANS: Title for form to send a new notice.
267         $this->element('title', null, _m('TITLE','New notice'));
268         $this->elementEnd('head');
269         $this->elementStart('body');
270
271         $form = new NoticeForm($this);
272         $form->show();
273
274         $this->elementEnd('body');
275         $this->elementEnd('html');
276     }
277
278     /**
279      * Formerly page output
280      *
281      * This used to be the whole page output; now that's been largely
282      * subsumed by showPage. So this just stores an error message, if
283      * it was passed, and calls showPage.
284      *
285      * Note that since we started doing Ajax output, this page is rarely
286      * seen.
287      *
288      * @param string  $msg     An error/info message, if any
289      * @param boolean $success false for error indication, true for info
290      *
291      * @return void
292      */
293     function showForm($msg=null, $success=false)
294     {
295         if (StatusNet::isAjax()) {
296             if ($msg) {
297                 $this->ajaxErrorMsg($msg);
298             } else {
299                 $this->ajaxShowForm();
300             }
301             return;
302         }
303
304         parent::showForm($msg, $success);
305     }
306
307     /**
308      * // XXX: Should we be showing the notice form with microapps here?
309      *
310      * Overload for replies or bad results
311      *
312      * We show content in the notice form if there were replies or results.
313      *
314      * @return void
315      */
316     function showNoticeForm()
317     {
318         $content = $this->trimmed('status_textarea');
319         if (!$content) {
320             $replyto = $this->trimmed('replyto');
321             $inreplyto = $this->trimmed('inreplyto');
322             $profile = Profile::getKV('nickname', $replyto);
323             if ($profile) {
324                 $content = '@' . $profile->nickname . ' ';
325             }
326         } else {
327             // @fixme most of these bits above aren't being passed on above
328             $inreplyto = null;
329         }
330
331         $this->elementStart('div', 'input_forms');
332         $this->elementStart(
333             'div',
334             array(
335                 'id'    => 'input_form_status',
336                 'class' => 'input_form current nonav'
337             )
338         );
339
340         $notice_form = new NoticeForm(
341             $this,
342             array(
343                 'content' => $content,
344                 'inreplyto' => $inreplyto
345             )
346         );
347
348         $notice_form->show();
349
350         $this->elementEnd('div');
351         $this->elementEnd('div');
352     }
353
354     /**
355      * Show an error message
356      *
357      * Shows an error message if there is one.
358      *
359      * @return void
360      *
361      * @todo maybe show some instructions?
362      */
363     function showPageNotice()
364     {
365         if ($this->msg) {
366             $this->element('p', array('id' => 'error'), $this->msg);
367         }
368     }
369
370     /**
371      * Output a notice
372      *
373      * Used to generate the notice code for Ajax results.
374      *
375      * @param Notice $notice Notice that was saved
376      *
377      * @return void
378      */
379     function showNotice($notice)
380     {
381         $nli = new NoticeListItem($notice, $this);
382         $nli->show();
383     }
384 }