3 * Laconica, the distributed open-source microblogging tool
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.
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.
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/>.
24 * @author Evan Prodromou <evan@controlyourself.ca>
25 * @author Zach Copley <zach@controlyourself.ca>
26 * @copyright 2008-2009 Control Yourself, Inc.
27 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
28 * @link http://laconi.ca/
31 if (!defined('LACONICA')) {
35 require_once INSTALLDIR.'/lib/accountsettingsaction.php';
37 define('MAX_ORIGINAL', 480);
42 * We use jCrop plugin for jQuery to crop the image after upload.
46 * @author Evan Prodromou <evan@controlyourself.ca>
47 * @author Zach Copley <zach@controlyourself.ca>
48 * @author Sarven Capadisli <csarven@controlyourself.ca>
49 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
50 * @link http://laconi.ca/
53 class GrouplogoAction extends GroupDesignAction
56 var $imagefile = null;
65 function prepare($args)
67 parent::prepare($args);
69 if (!common_config('inboxes','enabled')) {
70 $this->serverError(_('Inboxes must be enabled for groups to work'));
74 if (!common_logged_in()) {
75 $this->clientError(_('You must be logged in to create a group.'));
79 $nickname_arg = $this->trimmed('nickname');
80 $nickname = common_canonical_nickname($nickname_arg);
82 // Permanent redirect on non-canonical nickname
84 if ($nickname_arg != $nickname) {
85 $args = array('nickname' => $nickname);
86 common_redirect(common_local_url('grouplogo', $args), 301);
91 $this->clientError(_('No nickname'), 404);
95 $groupid = $this->trimmed('groupid');
98 $this->group = User_group::staticGet('id', $groupid);
100 $this->group = User_group::staticGet('nickname', $nickname);
104 $this->clientError(_('No such group'), 404);
108 $cur = common_current_user();
110 if (!$cur->isAdmin($this->group)) {
111 $this->clientError(_('You must be an admin to edit the group'), 403);
118 function handle($args)
120 parent::handle($args);
121 if ($_SERVER['REQUEST_METHOD'] == 'POST') {
128 function showForm($msg = null, $success = false)
131 $this->success = $success;
139 * @return string Title of the page
144 return _('Group logo');
148 * Instructions for use
150 * @return instructions for use
153 function getInstructions()
155 return sprintf(_('You can upload a logo image for your group. The maximum file size is %s.'), ImageFile::maxFileSize());
159 * Content area of the page
161 * Shows a form for uploading an avatar.
166 function showContent()
168 if ($this->mode == 'crop') {
169 $this->showCropForm();
171 $this->showUploadForm();
175 function showUploadForm()
177 $user = common_current_user();
179 $profile = $user->getProfile();
182 common_log_db_error($user, 'SELECT', __FILE__);
183 $this->serverError(_('User without matching profile'));
187 $original = $this->group->original_logo;
189 $this->elementStart('form', array('enctype' => 'multipart/form-data',
191 'id' => 'form_settings_avatar',
192 'class' => 'form_settings',
194 common_local_url('grouplogo',
195 array('nickname' => $this->group->nickname))));
196 $this->elementStart('fieldset');
197 $this->element('legend', null, _('Group logo'));
198 $this->hidden('token', common_session_token());
200 $this->elementStart('ul', 'form_data');
202 $this->elementStart('li', array('id' => 'avatar_original',
203 'class' => 'avatar_view'));
204 $this->element('h2', null, _("Original"));
205 $this->elementStart('div', array('id'=>'avatar_original_view'));
206 $this->element('img', array('src' => $this->group->original_logo,
207 'alt' => $this->group->nickname));
208 $this->elementEnd('div');
209 $this->elementEnd('li');
212 if ($this->group->homepage_logo) {
213 $this->elementStart('li', array('id' => 'avatar_preview',
214 'class' => 'avatar_view'));
215 $this->element('h2', null, _("Preview"));
216 $this->elementStart('div', array('id'=>'avatar_preview_view'));
217 $this->element('img', array('src' => $this->group->homepage_logo,
218 'width' => AVATAR_PROFILE_SIZE,
219 'height' => AVATAR_PROFILE_SIZE,
220 'alt' => $this->group->nickname));
221 $this->elementEnd('div');
222 $this->elementEnd('li');
225 $this->elementStart('li', array ('id' => 'settings_attach'));
226 $this->element('input', array('name' => 'avatarfile',
228 'id' => 'avatarfile'));
229 $this->element('input', array('name' => 'MAX_FILE_SIZE',
231 'id' => 'MAX_FILE_SIZE',
232 'value' => ImageFile::maxFileSizeInt()));
233 $this->elementEnd('li');
234 $this->elementEnd('ul');
236 $this->elementStart('ul', 'form_actions');
237 $this->elementStart('li');
238 $this->submit('upload', _('Upload'));
239 $this->elementEnd('li');
240 $this->elementEnd('ul');
242 $this->elementEnd('fieldset');
243 $this->elementEnd('form');
247 function showCropForm()
249 $this->elementStart('form', array('method' => 'post',
250 'id' => 'form_settings_avatar',
251 'class' => 'form_settings',
253 common_local_url('grouplogo',
254 array('nickname' => $this->group->nickname))));
255 $this->elementStart('fieldset');
256 $this->element('legend', null, _('Avatar settings'));
257 $this->hidden('token', common_session_token());
259 $this->elementStart('ul', 'form_data');
261 $this->elementStart('li',
262 array('id' => 'avatar_original',
263 'class' => 'avatar_view'));
264 $this->element('h2', null, _("Original"));
265 $this->elementStart('div', array('id'=>'avatar_original_view'));
266 $this->element('img', array('src' => Avatar::url($this->filedata['filename']),
267 'width' => $this->filedata['width'],
268 'height' => $this->filedata['height'],
269 'alt' => $this->group->nickname));
270 $this->elementEnd('div');
271 $this->elementEnd('li');
273 $this->elementStart('li',
274 array('id' => 'avatar_preview',
275 'class' => 'avatar_view'));
276 $this->element('h2', null, _("Preview"));
277 $this->elementStart('div', array('id'=>'avatar_preview_view'));
278 $this->element('img', array('src' => Avatar::url($this->filedata['filename']),
279 'width' => AVATAR_PROFILE_SIZE,
280 'height' => AVATAR_PROFILE_SIZE,
281 'alt' => $this->group->nickname));
282 $this->elementEnd('div');
284 foreach (array('avatar_crop_x', 'avatar_crop_y',
285 'avatar_crop_w', 'avatar_crop_h') as $crop_info) {
286 $this->element('input', array('name' => $crop_info,
288 'id' => $crop_info));
291 $this->submit('crop', _('Crop'));
293 $this->elementEnd('li');
294 $this->elementEnd('ul');
295 $this->elementEnd('fieldset');
296 $this->elementEnd('form');
303 * We mux on the button name to figure out what the user actually wanted.
308 function handlePost()
312 $token = $this->trimmed('token');
313 if (!$token || $token != common_session_token()) {
314 $this->show_form(_('There was a problem with your session token. '.
315 'Try again, please.'));
319 if ($this->arg('upload')) {
321 } else if ($this->arg('crop')) {
324 $this->showForm(_('Unexpected form submission.'));
329 * Handle an image upload
331 * Does all the magic for handling an image upload, and crops the
337 function uploadLogo()
340 $imagefile = ImageFile::fromUpload('avatarfile');
341 } catch (Exception $e) {
342 $this->showForm($e->getMessage());
346 $filename = Avatar::filename($this->group->id,
347 image_type_to_extension($imagefile->type),
349 'group-temp-'.common_timestamp());
351 $filepath = Avatar::path($filename);
353 move_uploaded_file($imagefile->filepath, $filepath);
355 $filedata = array('filename' => $filename,
356 'filepath' => $filepath,
357 'width' => $imagefile->width,
358 'height' => $imagefile->height,
359 'type' => $imagefile->type);
361 $_SESSION['FILEDATA'] = $filedata;
363 $this->filedata = $filedata;
365 $this->mode = 'crop';
367 $this->showForm(_('Pick a square area of the image to be the logo.'),
372 * Handle the results of jcrop.
379 $filedata = $_SESSION['FILEDATA'];
382 $this->serverError(_('Lost our file data.'));
386 // If image is not being cropped assume pos & dimentions of original
387 $dest_x = $this->arg('avatar_crop_x') ? $this->arg('avatar_crop_x'):0;
388 $dest_y = $this->arg('avatar_crop_y') ? $this->arg('avatar_crop_y'):0;
389 $dest_w = $this->arg('avatar_crop_w') ? $this->arg('avatar_crop_w'):$filedata['width'];
390 $dest_h = $this->arg('avatar_crop_h') ? $this->arg('avatar_crop_h'):$filedata['height'];
391 $size = min($dest_w, $dest_h);
392 $size = ($size > MAX_ORIGINAL) ? MAX_ORIGINAL:$size;
394 $imagefile = new ImageFile($this->group->id, $filedata['filepath']);
395 $filename = $imagefile->resize($size, $dest_x, $dest_y, $dest_w, $dest_h);
397 if ($this->group->setOriginal($filename)) {
398 @unlink($filedata['filepath']);
399 unset($_SESSION['FILEDATA']);
400 $this->mode = 'upload';
401 $this->showForm(_('Logo updated.'), true);
403 $this->showForm(_('Failed updating logo.'));
407 function showPageNotice()
410 $this->element('div', ($this->success) ? 'success' : 'error',
413 $inst = $this->getInstructions();
414 $output = common_markup_to_html($inst);
416 $this->elementStart('div', 'instructions');
418 $this->elementEnd('div');
423 * Add the jCrop stylesheet
428 function showStylesheets()
430 parent::showStylesheets();
431 $this->cssLink('css/jquery.Jcrop.css','base','screen, projection, tv');
435 * Add the jCrop scripts
440 function showScripts()
442 parent::showScripts();
444 if ($this->mode == 'crop') {
445 $this->script('js/jcrop/jquery.Jcrop.pack.js');
446 $this->script('js/jcrop/jquery.Jcrop.go.js');
450 function showLocalNav()
452 $nav = new GroupNav($this, $this->group);