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';
40 * We use jCrop plugin for jQuery to crop the image after upload.
44 * @author Evan Prodromou <evan@controlyourself.ca>
45 * @author Zach Copley <zach@controlyourself.ca>
46 * @author Sarven Capadisli <csarven@controlyourself.ca>
47 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
48 * @link http://laconi.ca/
51 class AvatarsettingsAction extends AccountSettingsAction
54 var $imagefile = null;
60 * @return string Title of the page
69 * Instructions for use
71 * @return instructions for use
74 function getInstructions()
76 return _('You can upload your personal avatar.');
80 * Content area of the page
82 * Shows a form for uploading an avatar.
87 function showContent()
89 if ($this->mode == 'crop') {
90 $this->showCropForm();
92 $this->showUploadForm();
96 function showUploadForm()
98 $user = common_current_user();
100 $profile = $user->getProfile();
103 common_log_db_error($user, 'SELECT', __FILE__);
104 $this->serverError(_('User without matching profile'));
108 $original = $profile->getOriginalAvatar();
110 $this->elementStart('form', array('enctype' => 'multipart/form-data',
112 'id' => 'form_settings_avatar',
113 'class' => 'form_settings',
115 common_local_url('avatarsettings')));
116 $this->elementStart('fieldset');
117 $this->element('legend', null, _('Avatar settings'));
118 $this->hidden('token', common_session_token());
120 $this->elementStart('ul', 'form_data');
122 $this->elementStart('li',
123 array('id' => 'avatar_original',
124 'class' => 'avatar_view'));
125 $this->element('h2', null, _("Original"));
126 $this->elementStart('div', array('id'=>'avatar_original_view'));
127 $this->element('img', array('src' => $original->url,
128 'width' => $original->width,
129 'height' => $original->height,
130 'alt' => $user->nickname));
131 $this->elementEnd('div');
132 $this->elementEnd('li');
135 $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE);
138 $this->elementStart('li',
139 array('id' => 'avatar_preview',
140 'class' => 'avatar_view'));
141 $this->element('h2', null, _("Preview"));
142 $this->elementStart('div', array('id'=>'avatar_preview_view'));
143 $this->element('img', array('src' => $original->url,//$avatar->url,
144 'width' => AVATAR_PROFILE_SIZE,
145 'height' => AVATAR_PROFILE_SIZE,
146 'alt' => $user->nickname));
147 $this->elementEnd('div');
150 $this->elementStart('li', array ('id' => 'settings_attach'));
151 $this->element('input', array('name' => 'avatarfile',
153 'id' => 'avatarfile'));
154 $this->element('input', array('name' => 'MAX_FILE_SIZE',
156 'id' => 'MAX_FILE_SIZE',
157 'value' => MAX_AVATAR_SIZE));
158 $this->elementEnd('li');
159 $this->elementEnd('ul');
161 $this->elementStart('ul', 'form_actions');
162 $this->elementStart('li');
163 $this->submit('upload', _('Upload'));
164 $this->elementEnd('li');
165 $this->elementEnd('ul');
167 $this->elementEnd('fieldset');
168 $this->elementEnd('form');
172 function showCropForm()
174 $user = common_current_user();
176 $profile = $user->getProfile();
179 common_log_db_error($user, 'SELECT', __FILE__);
180 $this->serverError(_('User without matching profile'));
184 $original = $profile->getOriginalAvatar();
186 $this->elementStart('form', array('method' => 'post',
187 'id' => 'form_settings_avatar',
188 'class' => 'form_settings',
190 common_local_url('avatarsettings')));
191 $this->elementStart('fieldset');
192 $this->element('legend', null, _('Avatar settings'));
193 $this->hidden('token', common_session_token());
195 $this->elementStart('ul', 'form_data');
197 $this->elementStart('li',
198 array('id' => 'avatar_original',
199 'class' => 'avatar_view'));
200 $this->element('h2', null, _("Original"));
201 $this->elementStart('div', array('id'=>'avatar_original_view'));
202 $this->element('img', array('src' => common_avatar_url($this->filedata['filename']),
203 'width' => $this->filedata['width'],
204 'height' => $this->filedata['height'],
205 'alt' => $user->nickname));
206 $this->elementEnd('div');
207 $this->elementEnd('li');
209 $this->elementStart('li',
210 array('id' => 'avatar_preview',
211 'class' => 'avatar_view'));
212 $this->element('h2', null, _("Preview"));
213 $this->elementStart('div', array('id'=>'avatar_preview_view'));
214 $this->element('img', array('src' => common_avatar_url($this->filedata['filename']),
215 'width' => AVATAR_PROFILE_SIZE,
216 'height' => AVATAR_PROFILE_SIZE,
217 'alt' => $user->nickname));
218 $this->elementEnd('div');
220 foreach (array('avatar_crop_x', 'avatar_crop_y',
221 'avatar_crop_w', 'avatar_crop_h') as $crop_info) {
222 $this->element('input', array('name' => $crop_info,
224 'id' => $crop_info));
226 $this->submit('crop', _('Crop'));
228 $this->elementEnd('li');
229 $this->elementEnd('ul');
230 $this->elementEnd('fieldset');
231 $this->elementEnd('form');
238 * We mux on the button name to figure out what the user actually wanted.
243 function handlePost()
247 $token = $this->trimmed('token');
248 if (!$token || $token != common_session_token()) {
249 $this->show_form(_('There was a problem with your session token. '.
250 'Try again, please.'));
254 if ($this->arg('upload')) {
255 $this->uploadAvatar();
256 } else if ($this->arg('crop')) {
259 $this->showForm(_('Unexpected form submission.'));
264 * Handle an image upload
266 * Does all the magic for handling an image upload, and crops the
272 function uploadAvatar()
275 $imagefile = ImageFile::fromUpload('avatarfile');
276 } catch (Exception $e) {
277 $this->showForm($e->getMessage());
281 $cur = common_current_user();
283 $filename = common_avatar_filename($cur->id,
284 image_type_to_extension($imagefile->type),
286 'tmp'.common_timestamp());
288 $filepath = common_avatar_path($filename);
290 move_uploaded_file($imagefile->filename, $filepath);
292 $filedata = array('filename' => $filename,
293 'filepath' => $filepath,
294 'width' => $imagefile->width,
295 'height' => $imagefile->height,
296 'type' => $imagefile->type);
298 $_SESSION['FILEDATA'] = $filedata;
300 $this->filedata = $filedata;
302 $this->mode = 'crop';
304 $this->showForm(_('Pick a square area of the image to be your avatar'),
309 * Handle the results of jcrop.
314 function cropAvatar()
316 $user = common_current_user();
318 $profile = $user->getProfile();
320 $x = $this->arg('avatar_crop_x');
321 $y = $this->arg('avatar_crop_y');
322 $w = $this->arg('avatar_crop_w');
323 $h = $this->arg('avatar_crop_h');
325 $filedata = $_SESSION['FILEDATA'];
328 $this->serverError(_('Lost our file data.'));
332 $filepath = common_avatar_path($filedata['filename']);
334 if (!file_exists($filepath)) {
335 $this->serverError(_('Lost our file.'));
339 switch ($filedata['type']) {
341 $image_src = imagecreatefromgif($filepath);
344 $image_src = imagecreatefromjpeg($filepath);
347 $image_src = imagecreatefrompng($filepath);
350 $this->serverError(_('Unknown file type'));
354 common_debug("W = $w, H = $h, X = $x, Y = $y");
356 $image_dest = imagecreatetruecolor($w, $h);
358 $background = imagecolorallocate($image_dest, 0, 0, 0);
359 ImageColorTransparent($image_dest, $background);
360 imagealphablending($image_dest, false);
362 imagecopyresized($image_dest, $image_src, 0, 0, $x, $y, $w, $h, $w, $h);
364 $cur = common_current_user();
366 $filename = common_avatar_filename($cur->id,
367 image_type_to_extension($filedata['type']),
371 $filepath = common_avatar_path($filename);
373 switch ($filedata['type']) {
375 imagegif($image_dest, $filepath);
378 imagejpeg($image_dest, $filepath);
381 imagepng($image_dest, $filepath);
384 $this->serverError(_('Unknown file type'));
388 $user = common_current_user();
390 $profile = $cur->getProfile();
392 if ($profile->setOriginal($filepath)) {
393 @unlink(common_avatar_path($filedata['filename']));
394 unset($_SESSION['FILEDATA']);
395 $this->mode = 'upload';
396 $this->showForm(_('Avatar updated.'), true);
398 $this->showForm(_('Failed updating avatar.'));
403 * Add the jCrop stylesheet
408 function showStylesheets()
410 parent::showStylesheets();
412 common_path('theme/base/css/jquery.Jcrop.css?version='.LACONICA_VERSION);
414 $this->element('link', array('rel' => 'stylesheet',
415 'type' => 'text/css',
416 'href' => $jcropStyle,
417 'media' => 'screen, projection, tv'));
421 * Add the jCrop scripts
426 function showScripts()
428 parent::showScripts();
430 $jcropPack = common_path('js/jcrop/jquery.Jcrop.pack.js');
431 $jcropGo = common_path('js/jcrop/jquery.Jcrop.go.js');
433 $this->element('script', array('type' => 'text/javascript',
434 'src' => $jcropPack));
435 $this->element('script', array('type' => 'text/javascript',