]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/grouplogo.php
Translator comments added
[quix0rs-gnu-social.git] / actions / grouplogo.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Upload an avatar
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  Settings
23  * @package   StatusNet
24  * @author    Evan Prodromou <evan@status.net>
25  * @author    Zach Copley <zach@status.net>
26  * @copyright 2008-2009 StatusNet, Inc.
27  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
28  * @link      http://status.net/
29  */
30
31 if (!defined('STATUSNET') && !defined('LACONICA')) {
32     exit(1);
33 }
34
35 require_once INSTALLDIR.'/lib/accountsettingsaction.php';
36
37 define('MAX_ORIGINAL', 480);
38
39 /**
40  * Upload an avatar
41  *
42  * We use jCrop plugin for jQuery to crop the image after upload.
43  *
44  * @category Settings
45  * @package  StatusNet
46  * @author   Evan Prodromou <evan@status.net>
47  * @author   Zach Copley <zach@status.net>
48  * @author   Sarven Capadisli <csarven@status.net>
49  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
50  * @link     http://status.net/
51  */
52 class GrouplogoAction extends GroupDesignAction
53 {
54     var $mode = null;
55     var $imagefile = null;
56     var $filename = null;
57     var $msg = null;
58     var $success = null;
59
60     /**
61      * Prepare to run
62      */
63
64     function prepare($args)
65     {
66         parent::prepare($args);
67
68         if (!common_logged_in()) {
69             // TRANS: Client error displayed when trying to create a group while not logged in.
70             $this->clientError(_('You must be logged in to create a group.'));
71             return false;
72         }
73
74         $nickname_arg = $this->trimmed('nickname');
75         $nickname = common_canonical_nickname($nickname_arg);
76
77         // Permanent redirect on non-canonical nickname
78
79         if ($nickname_arg != $nickname) {
80             $args = array('nickname' => $nickname);
81             common_redirect(common_local_url('grouplogo', $args), 301);
82             return false;
83         }
84
85         if (!$nickname) {
86             // TRANS: Client error displayed when trying to change group logo settings without having a nickname.
87             $this->clientError(_('No nickname.'), 404);
88             return false;
89         }
90
91         $groupid = $this->trimmed('groupid');
92
93         if ($groupid) {
94             $this->group = User_group::staticGet('id', $groupid);
95         } else {
96             $local = Local_group::staticGet('nickname', $nickname);
97             if ($local) {
98                 $this->group = User_group::staticGet('id', $local->group_id);
99             }
100         }
101
102         if (!$this->group) {
103             // TRANS: Client error displayed when trying to update logo settings for a non-existing group.
104             $this->clientError(_('No such group.'), 404);
105             return false;
106         }
107
108         $cur = common_current_user();
109
110         if (!$cur->isAdmin($this->group)) {
111             // TRANS: Client error displayed when trying to change group logo settings while not being a group admin.
112             $this->clientError(_('You must be an admin to edit the group.'), 403);
113             return false;
114         }
115
116         return true;
117     }
118
119     function handle($args)
120     {
121         parent::handle($args);
122         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
123             $this->handlePost();
124         } else {
125             $this->showForm();
126         }
127     }
128
129     function showForm($msg = null, $success = false)
130     {
131         $this->msg     = $msg;
132         $this->success = $success;
133
134         $this->showPage();
135     }
136
137     /**
138      * Title of the page
139      *
140      * @return string Title of the page
141      */
142     function title()
143     {
144         // TRANS: Title for group logo settings page.
145         return _('Group logo');
146     }
147
148     /**
149      * Instructions for use
150      *
151      * @return instructions for use
152      */
153     function getInstructions()
154     {
155         // TRANS: Instructions for group logo page.
156         // TRANS: %s is the maximum file size for that site.
157         return sprintf(_('You can upload a logo image for your group. The maximum file size is %s.'), ImageFile::maxFileSize());
158     }
159
160     /**
161      * Content area of the page
162      *
163      * Shows a form for uploading an avatar.
164      *
165      * @return void
166      */
167     function showContent()
168     {
169         if ($this->mode == 'crop') {
170             $this->showCropForm();
171         } else {
172             $this->showUploadForm();
173         }
174     }
175
176     function showUploadForm()
177     {
178         $user = common_current_user();
179
180         $profile = $user->getProfile();
181
182         if (!$profile) {
183             common_log_db_error($user, 'SELECT', __FILE__);
184             // TRANS: Server error displayed coming across a request from a user without a profile.
185             $this->serverError(_('User without matching profile.'));
186             return;
187         }
188
189         $original = $this->group->original_logo;
190
191         $this->elementStart('form', array('enctype' => 'multipart/form-data',
192                                           'method' => 'post',
193                                           'id' => 'form_settings_avatar',
194                                           'class' => 'form_settings',
195                                           'action' =>
196                                           common_local_url('grouplogo',
197                                                            array('nickname' => $this->group->nickname))));
198         $this->elementStart('fieldset');
199         // TRANS: Group logo form legend.
200         $this->element('legend', null, _('Group logo'));
201         $this->hidden('token', common_session_token());
202
203         $this->elementStart('ul', 'form_data');
204         if ($original) {
205             $this->elementStart('li', array('id' => 'avatar_original',
206                                             'class' => 'avatar_view'));
207             // TRANS: Uploaded original file in group logo form.
208             $this->element('h2', null, _("Original"));
209             $this->elementStart('div', array('id'=>'avatar_original_view'));
210             $this->element('img', array('src' => $this->group->original_logo,
211                                         'alt' => $this->group->nickname));
212             $this->elementEnd('div');
213             $this->elementEnd('li');
214         }
215
216         if ($this->group->homepage_logo) {
217             $this->elementStart('li', array('id' => 'avatar_preview',
218                                             'class' => 'avatar_view'));
219             // TRANS: Header for preview of to be displayed group logo.
220             $this->element('h2', null, _("Preview"));
221             $this->elementStart('div', array('id'=>'avatar_preview_view'));
222             $this->element('img', array('src' => $this->group->homepage_logo,
223                                         'width' => AVATAR_PROFILE_SIZE,
224                                         'height' => AVATAR_PROFILE_SIZE,
225                                         'alt' => $this->group->nickname));
226             $this->elementEnd('div');
227             $this->elementEnd('li');
228         }
229
230         $this->elementStart('li', array ('id' => 'settings_attach'));
231         $this->element('input', array('name' => 'avatarfile',
232                                       'type' => 'file',
233                                       'id' => 'avatarfile'));
234         $this->element('input', array('name' => 'MAX_FILE_SIZE',
235                                       'type' => 'hidden',
236                                       'id' => 'MAX_FILE_SIZE',
237                                       'value' => ImageFile::maxFileSizeInt()));
238         $this->elementEnd('li');
239         $this->elementEnd('ul');
240
241         $this->elementStart('ul', 'form_actions');
242         $this->elementStart('li');
243         // TRANS: Submit button for uploading a group logo.
244         $this->submit('upload', _('Upload'));
245         $this->elementEnd('li');
246         $this->elementEnd('ul');
247
248         $this->elementEnd('fieldset');
249         $this->elementEnd('form');
250
251     }
252
253     function showCropForm()
254     {
255         $this->elementStart('form', array('method' => 'post',
256                                           'id' => 'form_settings_avatar',
257                                           'class' => 'form_settings',
258                                           'action' =>
259                                           common_local_url('grouplogo',
260                                                            array('nickname' => $this->group->nickname))));
261         $this->elementStart('fieldset');
262         // TRANS: Legend for group logo settings fieldset.
263         $this->element('legend', null, _('Avatar settings'));
264         $this->hidden('token', common_session_token());
265
266         $this->elementStart('ul', 'form_data');
267
268         $this->elementStart('li',
269                             array('id' => 'avatar_original',
270                                   'class' => 'avatar_view'));
271         // TRANS: Header for originally uploaded file before a crop on the group logo page.
272         $this->element('h2', null, _("Original"));
273         $this->elementStart('div', array('id'=>'avatar_original_view'));
274         $this->element('img', array('src' => Avatar::url($this->filedata['filename']),
275                                     'width' => $this->filedata['width'],
276                                     'height' => $this->filedata['height'],
277                                     'alt' => $this->group->nickname));
278         $this->elementEnd('div');
279         $this->elementEnd('li');
280
281         $this->elementStart('li',
282                             array('id' => 'avatar_preview',
283                                   'class' => 'avatar_view'));
284         // TRANS: Header for the cropped group logo on the group logo page.
285         $this->element('h2', null, _("Preview"));
286         $this->elementStart('div', array('id'=>'avatar_preview_view'));
287         $this->element('img', array('src' => Avatar::url($this->filedata['filename']),
288                                     'width' => AVATAR_PROFILE_SIZE,
289                                     'height' => AVATAR_PROFILE_SIZE,
290                                     'alt' => $this->group->nickname));
291         $this->elementEnd('div');
292
293         foreach (array('avatar_crop_x', 'avatar_crop_y',
294                        'avatar_crop_w', 'avatar_crop_h') as $crop_info) {
295             $this->element('input', array('name' => $crop_info,
296                                           'type' => 'hidden',
297                                           'id' => $crop_info));
298         }
299
300         // TRANS: Button text for cropping an uploaded group logo.
301         $this->submit('crop', _('Crop'));
302
303         $this->elementEnd('li');
304         $this->elementEnd('ul');
305         $this->elementEnd('fieldset');
306         $this->elementEnd('form');
307
308     }
309
310     /**
311      * Handle a post
312      *
313      * We mux on the button name to figure out what the user actually wanted.
314      *
315      * @return void
316      */
317     function handlePost()
318     {
319         // CSRF protection
320
321         $token = $this->trimmed('token');
322         if (!$token || $token != common_session_token()) {
323             // TRANS: Form validation error message.
324             $this->show_form(_('There was a problem with your session token. '.
325                                'Try again, please.'));
326             return;
327         }
328
329         if ($this->arg('upload')) {
330             $this->uploadLogo();
331         } else if ($this->arg('crop')) {
332             $this->cropLogo();
333         } else {
334             // TRANS: Form validation error message when an unsupported argument is used.
335             $this->showForm(_('Unexpected form submission.'));
336         }
337     }
338
339     /**
340      * Handle an image upload
341      *
342      * Does all the magic for handling an image upload, and crops the
343      * image by default.
344      *
345      * @return void
346      */
347     function uploadLogo()
348     {
349         try {
350             $imagefile = ImageFile::fromUpload('avatarfile');
351         } catch (Exception $e) {
352             $this->showForm($e->getMessage());
353             return;
354         }
355
356         $filename = Avatar::filename($this->group->id,
357                                      image_type_to_extension($imagefile->type),
358                                      null,
359                                      'group-temp-'.common_timestamp());
360
361         $filepath = Avatar::path($filename);
362
363         move_uploaded_file($imagefile->filepath, $filepath);
364
365         $filedata = array('filename' => $filename,
366                           'filepath' => $filepath,
367                           'width' => $imagefile->width,
368                           'height' => $imagefile->height,
369                           'type' => $imagefile->type);
370
371         $_SESSION['FILEDATA'] = $filedata;
372
373         $this->filedata = $filedata;
374
375         $this->mode = 'crop';
376
377         // TRANS: Form instructions on the group logo page.
378         $this->showForm(_('Pick a square area of the image to be the logo.'),
379                         true);
380     }
381
382     /**
383      * Handle the results of jcrop.
384      *
385      * @return void
386      */
387     function cropLogo()
388     {
389         $filedata = $_SESSION['FILEDATA'];
390
391         if (!$filedata) {
392             // TRANS: Server error displayed trying to crop an uploaded group logo that is no longer present.
393             $this->serverError(_('Lost our file data.'));
394             return;
395         }
396
397         // If image is not being cropped assume pos & dimentions of original
398         $dest_x = $this->arg('avatar_crop_x') ? $this->arg('avatar_crop_x'):0;
399         $dest_y = $this->arg('avatar_crop_y') ? $this->arg('avatar_crop_y'):0;
400         $dest_w = $this->arg('avatar_crop_w') ? $this->arg('avatar_crop_w'):$filedata['width'];
401         $dest_h = $this->arg('avatar_crop_h') ? $this->arg('avatar_crop_h'):$filedata['height'];
402         $size = min($dest_w, $dest_h);
403         $size = ($size > MAX_ORIGINAL) ? MAX_ORIGINAL:$size;
404
405         $imagefile = new ImageFile($this->group->id, $filedata['filepath']);
406         $filename = $imagefile->resize($size, $dest_x, $dest_y, $dest_w, $dest_h);
407
408         if ($this->group->setOriginal($filename)) {
409             @unlink($filedata['filepath']);
410             unset($_SESSION['FILEDATA']);
411             $this->mode = 'upload';
412             // TRANS: Form success message after updating a group logo.
413             $this->showForm(_('Logo updated.'), true);
414         } else {
415             // TRANS: Form failure message after failing to update a group logo.
416             $this->showForm(_('Failed updating logo.'));
417         }
418     }
419
420     function showPageNotice()
421     {
422         if ($this->msg) {
423             $this->element('div', ($this->success) ? 'success' : 'error',
424                            $this->msg);
425         } else {
426             $inst   = $this->getInstructions();
427             $output = common_markup_to_html($inst);
428
429             $this->elementStart('div', 'instructions');
430             $this->raw($output);
431             $this->elementEnd('div');
432         }
433     }
434
435     /**
436      * Add the jCrop stylesheet
437      *
438      * @return void
439      */
440
441     function showStylesheets()
442     {
443         parent::showStylesheets();
444         $this->cssLink('css/jquery.Jcrop.css','base','screen, projection, tv');
445     }
446
447     /**
448      * Add the jCrop scripts
449      *
450      * @return void
451      */
452
453     function showScripts()
454     {
455         parent::showScripts();
456
457         if ($this->mode == 'crop') {
458             $this->script('jcrop/jquery.Jcrop.min.js');
459             $this->script('jcrop/jquery.Jcrop.go.js');
460         }
461
462         $this->autofocus('avatarfile');
463     }
464
465     function showLocalNav()
466     {
467         $nav = new GroupNav($this, $this->group);
468         $nav->show();
469     }
470 }