]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - lib/designsettings.php
Merge branch 'runtime' into testing
[quix0rs-gnu-social.git] / lib / designsettings.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Change user password
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    Sarven Capadisli <csarven@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 require_once INSTALLDIR . '/lib/webcolor.php';
37
38 /**
39  * Base class for setting a user or group design
40  *
41  * Shows the design setting form and also handles some things like saving
42  * background images, and fetching a default design
43  *
44  * @category Settings
45  * @package  StatusNet
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 DesignSettingsAction extends AccountSettingsAction
52 {
53     var $submitaction = null;
54
55     /**
56      * Title of the page
57      *
58      * @return string Title of the page
59      */
60     function title()
61     {
62         // TRANS: Page title for profile design page.
63         return _('Profile design');
64     }
65
66     /**
67      * Instructions for use
68      *
69      * @return instructions for use
70      */
71     function getInstructions()
72     {
73         // TRANS: Instructions for profile design page.
74         return _('Customize the way your profile looks ' .
75         'with a background image and a colour palette of your choice.');
76     }
77
78     /**
79      * Shows the design settings form
80      *
81      * @param Design $design a working design to show
82      *
83      * @return nothing
84      */
85     function showDesignForm($design)
86     {
87         $this->elementStart('form', array('method' => 'post',
88                                           'enctype' => 'multipart/form-data',
89                                           'id' => 'form_settings_design',
90                                           'class' => 'form_settings',
91                                           'action' => $this->submitaction));
92         $this->elementStart('fieldset');
93         $this->hidden('token', common_session_token());
94
95         $this->elementStart('fieldset', array('id' =>
96             'settings_design_background-image'));
97         // TRANS: Fieldset legend on profile design page.
98         $this->element('legend', null, _('Change background image'));
99         $this->elementStart('ul', 'form_data');
100         $this->elementStart('li');
101         $this->element('input', array('name' => 'MAX_FILE_SIZE',
102                                       'type' => 'hidden',
103                                       'id' => 'MAX_FILE_SIZE',
104                                       'value' => ImageFile::maxFileSizeInt()));
105         $this->element('label', array('for' => 'design_background-image_file'),
106                                 // TRANS: Label in form on profile design page.
107                                 // TRANS: Field contains file name on user's computer that could be that user's custom profile background image.
108                                 _('Upload file'));
109         $this->element('input', array('name' => 'design_background-image_file',
110                                       'type' => 'file',
111                                       'id' => 'design_background-image_file'));
112         // TRANS: Instructions for form on profile design page.
113         $this->element('p', 'form_guide', _('You can upload your personal ' .
114             'background image. The maximum file size is 2MB.'));
115         $this->elementEnd('li');
116
117         if (!empty($design->backgroundimage)) {
118             $this->elementStart('li', array('id' =>
119                 'design_background-image_onoff'));
120
121             $this->element('img', array('src' =>
122                 Design::url($design->backgroundimage)));
123
124             $attrs = array('name' => 'design_background-image_onoff',
125                            'type' => 'radio',
126                            'id' => 'design_background-image_on',
127                            'class' => 'radio',
128                            'value' => 'on');
129
130             if ($design->disposition & BACKGROUND_ON) {
131                 $attrs['checked'] = 'checked';
132             }
133
134             $this->element('input', $attrs);
135
136             $this->element('label', array('for' => 'design_background-image_on',
137                                           'class' => 'radio'),
138                                           // TRANS: Radio button on profile design page that will enable use of the uploaded profile image.
139                                           _m('RADIO','On'));
140
141             $attrs = array('name' => 'design_background-image_onoff',
142                            'type' => 'radio',
143                            'id' => 'design_background-image_off',
144                            'class' => 'radio',
145                            'value' => 'off');
146
147             if ($design->disposition & BACKGROUND_OFF) {
148                 $attrs['checked'] = 'checked';
149             }
150
151             $this->element('input', $attrs);
152
153             $this->element('label', array('for' => 'design_background-image_off',
154                                           'class' => 'radio'),
155                                           // TRANS: Radio button on profile design page that will disable use of the uploaded profile image.
156                                           _m('RADIO','Off'));
157             // TRANS: Form guide for a set of radio buttons on the profile design page that will enable or disable
158             // TRANS: use of the uploaded profile image.
159             $this->element('p', 'form_guide', _('Turn background image on or off.'));
160             $this->elementEnd('li');
161
162             $this->elementStart('li');
163             $this->checkbox('design_background-image_repeat',
164                             // TRANS: Checkbox label on profile design page that will cause the profile image to be tiled.
165                             _('Tile background image'),
166                             ($design->disposition & BACKGROUND_TILE) ? true : false);
167             $this->elementEnd('li');
168         }
169
170         $this->elementEnd('ul');
171         $this->elementEnd('fieldset');
172
173         $this->elementStart('fieldset', array('id' => 'settings_design_color'));
174         // TRANS: Fieldset legend on profile design page to change profile page colours.
175         $this->element('legend', null, _('Change colours'));
176         $this->elementStart('ul', 'form_data');
177
178         try {
179             $bgcolor = new WebColor($design->backgroundcolor);
180
181             $this->elementStart('li');
182             // TRANS: Label on profile design page for setting a profile page background colour.
183             $this->element('label', array('for' => 'swatch-1'), _('Background'));
184             $this->element('input', array('name' => 'design_background',
185                                           'type' => 'text',
186                                           'id' => 'swatch-1',
187                                           'class' => 'swatch',
188                                           'maxlength' => '7',
189                                           'size' => '7',
190                                           'value' => ''));
191             $this->elementEnd('li');
192
193             $ccolor = new WebColor($design->contentcolor);
194
195             $this->elementStart('li');
196             // TRANS: Label on profile design page for setting a profile page content colour.
197             $this->element('label', array('for' => 'swatch-2'), _('Content'));
198             $this->element('input', array('name' => 'design_content',
199                                           'type' => 'text',
200                                           'id' => 'swatch-2',
201                                           'class' => 'swatch',
202                                           'maxlength' => '7',
203                                           'size' => '7',
204                                           'value' => ''));
205             $this->elementEnd('li');
206
207             $sbcolor = new WebColor($design->sidebarcolor);
208
209             $this->elementStart('li');
210             // TRANS: Label on profile design page for setting a profile page sidebar colour.
211             $this->element('label', array('for' => 'swatch-3'), _('Sidebar'));
212             $this->element('input', array('name' => 'design_sidebar',
213                                         'type' => 'text',
214                                         'id' => 'swatch-3',
215                                         'class' => 'swatch',
216                                         'maxlength' => '7',
217                                         'size' => '7',
218                                         'value' => ''));
219             $this->elementEnd('li');
220
221             $tcolor = new WebColor($design->textcolor);
222
223             $this->elementStart('li');
224             // TRANS: Label on profile design page for setting a profile page text colour.
225             $this->element('label', array('for' => 'swatch-4'), _('Text'));
226             $this->element('input', array('name' => 'design_text',
227                                         'type' => 'text',
228                                         'id' => 'swatch-4',
229                                         'class' => 'swatch',
230                                         'maxlength' => '7',
231                                         'size' => '7',
232                                         'value' => ''));
233             $this->elementEnd('li');
234
235             $lcolor = new WebColor($design->linkcolor);
236
237             $this->elementStart('li');
238             // TRANS: Label on profile design page for setting a profile page links colour.
239             $this->element('label', array('for' => 'swatch-5'), _('Links'));
240             $this->element('input', array('name' => 'design_links',
241                                          'type' => 'text',
242                                          'id' => 'swatch-5',
243                                          'class' => 'swatch',
244                                          'maxlength' => '7',
245                                          'size' => '7',
246                                          'value' => ''));
247             $this->elementEnd('li');
248
249         } catch (WebColorException $e) {
250             common_log(LOG_ERR, 'Bad color values in design ID: ' .$design->id);
251         }
252
253         $this->elementEnd('ul');
254         $this->elementEnd('fieldset');
255
256         // TRANS: Button text on profile design page to immediately reset all colour settings to default.
257         $this->submit('defaults', _('Use defaults'), 'submit form_action-default',
258             // TRANS: Title for button on profile design page to reset all colour settings to default.
259             'defaults', _('Restore default designs'));
260
261         $this->element('input', array('id' => 'settings_design_reset',
262                                      'type' => 'reset',
263                                      // TRANS: Button text on profile design page to reset all colour settings to default without saving.
264                                      'value' => _m('BUTTON','Reset'),
265                                      'class' => 'submit form_action-primary',
266                                      // TRANS: Title for button on profile design page to reset all colour settings to default without saving.
267                                      'title' => _('Reset back to default')));
268
269         // TRANS: Button text on profile design page to save settings.
270         $this->submit('save', _m('BUTTON','Save'), 'submit form_action-secondary',
271             // TRANS: Title for button on profile design page to save settings.
272             'save', _('Save design'));
273
274         $this->elementEnd('fieldset');
275         $this->elementEnd('form');
276     }
277
278     /**
279      * Handle a post
280      *
281      * Validate input and save changes. Reload the form with a success
282      * or error message.
283      *
284      * @return void
285      */
286     function handlePost()
287     {
288         if ($_SERVER['REQUEST_METHOD'] == 'POST') {
289
290             // Workaround for PHP returning empty $_POST and $_FILES when POST
291             // length > post_max_size in php.ini
292
293             if (empty($_FILES)
294                 && empty($_POST)
295                 && ($_SERVER['CONTENT_LENGTH'] > 0)
296             ) {
297                 // TRANS: Form validation error in design settings form. POST should remain untranslated.
298                 $msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.',
299                           'The server was unable to handle that much POST data (%s bytes) due to its current configuration.',
300                           intval($_SERVER['CONTENT_LENGTH']));
301
302                 $this->showForm(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
303                 return;
304             }
305         }
306
307         // CSRF protection
308         $token = $this->trimmed('token');
309         if (!$token || $token != common_session_token()) {
310             $this->showForm(_('There was a problem with your session token. '.
311                               'Try again, please.'));
312             return;
313         }
314
315         if ($this->arg('save')) {
316             $this->saveDesign();
317         } else if ($this->arg('defaults')) {
318             $this->restoreDefaults();
319         } else {
320             // TRANS: Unknown form validation error in design settings form.
321             $this->showForm(_('Unexpected form submission.'));
322         }
323     }
324
325     /**
326      * Add the Farbtastic stylesheet
327      *
328      * @return void
329      */
330     function showStylesheets()
331     {
332         parent::showStylesheets();
333         $this->cssLink('js/farbtastic/farbtastic.css',null,'screen, projection, tv');
334     }
335
336     /**
337      * Add the Farbtastic scripts
338      *
339      * @return void
340      */
341     function showScripts()
342     {
343         parent::showScripts();
344
345         $this->script('farbtastic/farbtastic.js');
346         $this->script('userdesign.go.js');
347
348         $this->autofocus('design_background-image_file');
349     }
350
351     /**
352      * Save the background image, if any, and set its disposition
353      *
354      * @param Design $design a working design to attach the img to
355      *
356      * @return nothing
357      */
358     function saveBackgroundImage($design)
359     {
360         // Now that we have a Design ID we can add a file to the design.
361         // XXX: This is an additional DB hit, but figured having the image
362         // associated with the Design rather than the User was worth
363         // it. -- Zach
364
365         if ($_FILES['design_background-image_file']['error'] ==
366             UPLOAD_ERR_OK) {
367
368             $filepath = null;
369
370             try {
371                 $imagefile =
372                     ImageFile::fromUpload('design_background-image_file');
373             } catch (Exception $e) {
374                 $this->showForm($e->getMessage());
375                 return;
376             }
377
378             $filename = Design::filename($design->id,
379                 image_type_to_extension($imagefile->type),
380                     common_timestamp());
381
382             $filepath = Design::path($filename);
383
384             move_uploaded_file($imagefile->filepath, $filepath);
385
386             // delete any old backround img laying around
387
388             if (isset($design->backgroundimage)) {
389                 @unlink(Design::path($design->backgroundimage));
390             }
391
392             $original = clone($design);
393
394             $design->backgroundimage = $filename;
395
396             // default to on, no tile
397
398             $design->setDisposition(true, false, false);
399
400             $result = $design->update($original);
401
402             if ($result === false) {
403                 common_log_db_error($design, 'UPDATE', __FILE__);
404                 // TRANS: Error message displayed if design settings could not be saved.
405                 $this->showForm(_('Couldn\'t update your design.'));
406                 return;
407             }
408         }
409     }
410
411     /**
412      * Restore the user or group design to system defaults
413      *
414      * @return nothing
415      */
416     function restoreDefaults()
417     {
418         $design = $this->getWorkingDesign();
419
420         if (!empty($design)) {
421
422             $result = $design->delete();
423
424             if ($result === false) {
425                 common_log_db_error($design, 'DELETE', __FILE__);
426                 // TRANS: Error message displayed if design settings could not be saved after clicking "Use defaults".
427                 $this->showForm(_('Couldn\'t update your design.'));
428                 return;
429             }
430         }
431
432         // TRANS: Success message displayed if design settings were saved after clicking "Use defaults".
433         $this->showForm(_('Design defaults restored.'), true);
434     }
435 }