]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/designadminpanel.php
0925880193a2b50f16712a213d20809aa9223ff0
[quix0rs-gnu-social.git] / actions / designadminpanel.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Design administration panel
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  * @author    Sarven Capadisli <csarven@status.net>
27  * @copyright 2008-2009 StatusNet, Inc.
28  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
29  * @link      http://status.net/
30  */
31
32 if (!defined('STATUSNET')) {
33     exit(1);
34 }
35
36 /**
37  * Administer design settings
38  *
39  * @category Admin
40  * @package  StatusNet
41  * @author   Evan Prodromou <evan@status.net>
42  * @author   Zach Copley <zach@status.net>
43  * @author   Sarven Capadisli <csarven@status.net>
44  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
45  * @link     http://status.net/
46  */
47
48 class DesignadminpanelAction extends AdminPanelAction
49 {
50
51     /* The default site design */
52     var $design = null;
53
54     /**
55      * Returns the page title
56      *
57      * @return string page title
58      */
59
60     function title()
61     {
62         return _('Design');
63     }
64
65     /**
66      * Instructions for using this form.
67      *
68      * @return string instructions
69      */
70
71     function getInstructions()
72     {
73         return _('Design settings for this StatusNet site.');
74     }
75
76     /**
77      * Get the default design and show the design admin panel form
78      *
79      * @return void
80      */
81
82     function showForm()
83     {
84         $this->design = Design::siteDesign();
85         $form = new DesignAdminPanelForm($this);
86         $form->show();
87         return;
88     }
89
90     /**
91      * Save settings from the form
92      *
93      * @return void
94      */
95
96     function saveSettings()
97     {
98         if ($this->arg('save')) {
99             $this->saveDesignSettings();
100         } else if ($this->arg('defaults')) {
101             $this->restoreDefaults();
102         } else {
103             $this->clientError(_('Unexpected form submission.'));
104         }
105     }
106
107     /**
108      * Save the new design settings
109      *
110      * @return void
111      */
112
113     function saveDesignSettings()
114     {
115         // Workaround for PHP returning empty $_POST and $_FILES when POST
116         // length > post_max_size in php.ini
117
118         if (empty($_FILES)
119             && empty($_POST)
120             && ($_SERVER['CONTENT_LENGTH'] > 0)
121         ) {
122             $msg = _('The server was unable to handle that much POST ' .
123                 'data (%s bytes) due to its current configuration.');
124             $this->clientException(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
125             return;
126         }
127
128         // check for an image upload
129
130         $bgimage = $this->saveBackgroundImage();
131
132         static $settings = array('theme', 'logo');
133
134         $values = array();
135
136         foreach ($settings as $setting) {
137             $values[$setting] = $this->trimmed($setting);
138         }
139
140         $this->validate($values);
141
142         $oldtheme = common_config('site', 'theme');
143
144         $config = new Config();
145
146         $config->query('BEGIN');
147
148         // Only update colors if the theme has not changed.
149
150         if ($oldtheme == $values['theme']) {
151
152             $bgcolor = new WebColor($this->trimmed('design_background'));
153             $ccolor  = new WebColor($this->trimmed('design_content'));
154             $sbcolor = new WebColor($this->trimmed('design_sidebar'));
155             $tcolor  = new WebColor($this->trimmed('design_text'));
156             $lcolor  = new WebColor($this->trimmed('design_links'));
157
158             Config::save('design', 'backgroundcolor', $bgcolor->intValue());
159             Config::save('design', 'contentcolor', $ccolor->intValue());
160             Config::save('design', 'sidebarcolor', $sbcolor->intValue());
161             Config::save('design', 'textcolor', $tcolor->intValue());
162             Config::save('design', 'linkcolor', $lcolor->intValue());
163         }
164
165         $onoff = $this->arg('design_background-image_onoff');
166
167         $on   = false;
168         $off  = false;
169
170         if ($onoff == 'on') {
171             $on = true;
172         } else {
173             $off = true;
174         }
175
176         $tile = $this->boolean('design_background-image_repeat');
177
178         // Hack to use Design's bit setter
179         $scratch = new Design();
180         $scratch->setDisposition($on, $off, $tile);
181
182         Config::save('design', 'disposition', $scratch->disposition);
183
184         foreach ($settings as $setting) {
185             Config::save('site', $setting, $values[$setting]);
186         }
187
188         if (isset($bgimage)) {
189             Config::save('design', 'backgroundimage', $bgimage);
190         }
191
192         $config->query('COMMIT');
193     }
194
195     /**
196       * Restore the default design
197       *
198       * @return void
199       */
200
201     function restoreDefaults()
202     {
203         $this->deleteSetting('site', 'logo');
204         $this->deleteSetting('site', 'theme');
205
206         $settings = array(
207             'theme', 'backgroundimage', 'backgroundcolor', 'contentcolor',
208             'sidebarcolor', 'textcolor', 'linkcolor', 'disposition'
209         );
210
211         foreach ($settings as $setting) {
212             $this->deleteSetting('design', $setting);
213         }
214
215         // XXX: Should we restore the default dir settings, etc.? --Z
216
217         // XXX: I can't get it to show the new settings without forcing
218         // this terrible reload -- FIX ME!
219         common_redirect(common_local_url('designadminpanel'), 303);
220     }
221
222     /**
223      * Save the background image if the user uploaded one
224      *
225      * @return string $filename the filename of the image
226      */
227
228     function saveBackgroundImage()
229     {
230         $filename = null;
231
232         if ($_FILES['design_background-image_file']['error'] ==
233             UPLOAD_ERR_OK) {
234
235             $filepath = null;
236
237             try {
238                 $imagefile =
239                     ImageFile::fromUpload('design_background-image_file');
240             } catch (Exception $e) {
241                 $this->clientError('Unable to save background image.');
242                 return;
243             }
244
245             // Note: site design background image has a special filename
246
247             $filename = Design::filename('site-design-background',
248                 image_type_to_extension($imagefile->type),
249                     common_timestamp());
250
251             $filepath = Design::path($filename);
252
253             move_uploaded_file($imagefile->filepath, $filepath);
254
255             // delete any old backround img laying around
256
257             if (isset($this->design->backgroundimage)) {
258                 @unlink(Design::path($design->backgroundimage));
259             }
260
261             return $filename;
262         }
263     }
264
265     /**
266      * Attempt to validate setting values
267      *
268      * @return void
269      */
270
271     function validate(&$values)
272     {
273         if (!empty($values['logo']) &&
274             !Validate::uri($values['logo'], array('allowed_schemes' => array('http', 'https')))) {
275             $this->clientError(_('Invalid logo URL.'));
276         }
277
278         if (!in_array($values['theme'], Theme::listAvailable())) {
279             $this->clientError(sprintf(_("Theme not available: %s."), $values['theme']));
280         }
281     }
282
283     /**
284      * Add the Farbtastic stylesheet
285      *
286      * @return void
287      */
288
289     function showStylesheets()
290     {
291         parent::showStylesheets();
292         $this->cssLink('js/farbtastic/farbtastic.css',null,'screen, projection, tv');
293     }
294
295     /**
296      * Add the Farbtastic scripts
297      *
298      * @return void
299      */
300
301     function showScripts()
302     {
303         parent::showScripts();
304
305         $this->script('farbtastic/farbtastic.js');
306         $this->script('userdesign.go.js');
307
308         $this->autofocus('design_background-image_file');
309     }
310
311 }
312
313 class DesignAdminPanelForm extends AdminForm
314 {
315
316     /**
317      * ID of the form
318      *
319      * @return int ID of the form
320      */
321
322     function id()
323     {
324         return 'form_design_admin_panel';
325     }
326
327     /**
328      * class of the form
329      *
330      * @return string class of the form
331      */
332
333     function formClass()
334     {
335         return 'form_settings';
336     }
337
338     /**
339      * HTTP method used to submit the form
340      *
341      * For image data we need to send multipart/form-data
342      * so we set that here too
343      *
344      * @return string the method to use for submitting
345      */
346
347     function method()
348     {
349         $this->enctype = 'multipart/form-data';
350
351         return 'post';
352     }
353
354     /**
355      * Action of the form
356      *
357      * @return string URL of the action
358      */
359
360     function action()
361     {
362         return common_local_url('designadminpanel');
363     }
364
365     /**
366      * Data elements of the form
367      *
368      * @return void
369      */
370
371     function formData()
372     {
373         $this->showLogo();
374         $this->showTheme();
375         $this->showBackground();
376         $this->showColors();
377     }
378
379     function showLogo()
380     {
381         $this->out->elementStart('fieldset', array('id' => 'settings_design_logo'));
382         $this->out->element('legend', null, _('Change logo'));
383
384         $this->out->elementStart('ul', 'form_data');
385
386         $this->li();
387         $this->input('logo', _('Site logo'), 'Logo for the site (full URL)');
388         $this->unli();
389
390         $this->out->elementEnd('ul');
391
392         $this->out->elementEnd('fieldset');
393
394     }
395
396     function showTheme()
397     {
398         $this->out->elementStart('fieldset', array('id' => 'settings_design_theme'));
399         $this->out->element('legend', null, _('Change theme'));
400
401         $this->out->elementStart('ul', 'form_data');
402
403         $themes = Theme::listAvailable();
404
405         // XXX: listAvailable() can return an empty list if you
406         // screw up your settings, so just in case:
407
408         if (empty($themes)) {
409             $themes = array('default', 'default');
410         }
411
412         asort($themes);
413         $themes = array_combine($themes, $themes);
414
415         $this->li();
416         $this->out->dropdown('theme', _('Site theme'),
417                              $themes, _('Theme for the site.'),
418                              false, $this->value('theme'));
419         $this->unli();
420
421         $this->out->elementEnd('ul');
422
423         $this->out->elementEnd('fieldset');
424     }
425
426     function showBackground()
427     {
428         $design = $this->out->design;
429
430         $this->out->elementStart('fieldset', array('id' =>
431             'settings_design_background-image'));
432         $this->out->element('legend', null, _('Change background image'));
433         $this->out->elementStart('ul', 'form_data');
434
435         $this->li();
436         $this->out->element('label', array('for' => 'design_background-image_file'),
437                                 _('Background'));
438         $this->out->element('input', array('name' => 'design_background-image_file',
439                                      'type' => 'file',
440                                      'id' => 'design_background-image_file'));
441         $this->out->element('p', 'form_guide',
442             sprintf(_('You can upload a background image for the site. ' .
443               'The maximum file size is %1$s.'), ImageFile::maxFileSize()));
444         $this->out->element('input', array('name' => 'MAX_FILE_SIZE',
445                                           'type' => 'hidden',
446                                           'id' => 'MAX_FILE_SIZE',
447                                           'value' => ImageFile::maxFileSizeInt()));
448         $this->unli();
449
450         if (!empty($design->backgroundimage)) {
451
452             $this->out->elementStart('li', array('id' =>
453                 'design_background-image_onoff'));
454
455             $this->out->element('img', array('src' =>
456                 Design::url($design->backgroundimage)));
457
458             $attrs = array('name' => 'design_background-image_onoff',
459                            'type' => 'radio',
460                            'id' => 'design_background-image_on',
461                            'class' => 'radio',
462                            'value' => 'on');
463
464             if ($design->disposition & BACKGROUND_ON) {
465                 $attrs['checked'] = 'checked';
466             }
467
468             $this->out->element('input', $attrs);
469
470             $this->out->element('label', array('for' => 'design_background-image_on',
471                                           'class' => 'radio'),
472                                           _('On'));
473
474             $attrs = array('name' => 'design_background-image_onoff',
475                            'type' => 'radio',
476                            'id' => 'design_background-image_off',
477                            'class' => 'radio',
478                            'value' => 'off');
479
480             if ($design->disposition & BACKGROUND_OFF) {
481                 $attrs['checked'] = 'checked';
482             }
483
484             $this->out->element('input', $attrs);
485
486             $this->out->element('label', array('for' => 'design_background-image_off',
487                                           'class' => 'radio'),
488                                           _('Off'));
489             $this->out->element('p', 'form_guide', _('Turn background image on or off.'));
490             $this->unli();
491
492             $this->li();
493             $this->out->checkbox('design_background-image_repeat',
494                             _('Tile background image'),
495                             ($design->disposition & BACKGROUND_TILE) ? true : false);
496             $this->unli();
497         }
498
499         $this->out->elementEnd('ul');
500         $this->out->elementEnd('fieldset');
501     }
502
503     function showColors()
504     {
505         $this->out->elementStart('fieldset', array('id' => 'settings_design_color'));
506         $this->out->element('legend', null, _('Change colours'));
507
508         $this->out->elementStart('ul', 'form_data');
509
510         try {
511             // @fixme avoid loop unrolling in non-performance-critical contexts like this
512
513             $bgcolor = new WebColor($design->backgroundcolor);
514
515             $this->li();
516             $this->out->element('label', array('for' => 'swatch-1'), _('Background'));
517             $this->out->element('input', array('name' => 'design_background',
518                                           'type' => 'text',
519                                           'id' => 'swatch-1',
520                                           'class' => 'swatch',
521                                           'maxlength' => '7',
522                                           'size' => '7',
523                                           'value' => ''));
524             $this->unli();
525
526             $ccolor = new WebColor($design->contentcolor);
527
528             $this->li();
529             $this->out->element('label', array('for' => 'swatch-2'), _('Content'));
530             $this->out->element('input', array('name' => 'design_content',
531                                           'type' => 'text',
532                                           'id' => 'swatch-2',
533                                           'class' => 'swatch',
534                                           'maxlength' => '7',
535                                           'size' => '7',
536                                           'value' => ''));
537             $this->unli();
538
539             $sbcolor = new WebColor($design->sidebarcolor);
540
541             $this->li();
542             $this->out->element('label', array('for' => 'swatch-3'), _('Sidebar'));
543             $this->out->element('input', array('name' => 'design_sidebar',
544                                         'type' => 'text',
545                                         'id' => 'swatch-3',
546                                         'class' => 'swatch',
547                                         'maxlength' => '7',
548                                         'size' => '7',
549                                         'value' => ''));
550             $this->unli();
551
552             $tcolor = new WebColor($design->textcolor);
553
554             $this->li();
555             $this->out->element('label', array('for' => 'swatch-4'), _('Text'));
556             $this->out->element('input', array('name' => 'design_text',
557                                         'type' => 'text',
558                                         'id' => 'swatch-4',
559                                         'class' => 'swatch',
560                                         'maxlength' => '7',
561                                         'size' => '7',
562                                         'value' => ''));
563             $this->unli();
564
565             $lcolor = new WebColor($design->linkcolor);
566
567             $this->li();
568             $this->out->element('label', array('for' => 'swatch-5'), _('Links'));
569             $this->out->element('input', array('name' => 'design_links',
570                                          'type' => 'text',
571                                          'id' => 'swatch-5',
572                                          'class' => 'swatch',
573                                          'maxlength' => '7',
574                                          'size' => '7',
575                                          'value' => ''));
576             $this->unli();
577
578         } catch (WebColorException $e) {
579             // @fixme normalize them individually!
580             common_log(LOG_ERR, 'Bad color values in site design: ' .
581                 $e->getMessage());
582         }
583
584         $this->out->elementEnd('fieldset');
585
586         $this->out->elementEnd('ul');
587     }
588
589     /**
590      * Action elements
591      *
592      * @return void
593      */
594
595     function formActions()
596     {
597         $this->out->submit('defaults', _('Use defaults'), 'submit form_action-default',
598                 'defaults', _('Restore default designs'));
599
600         $this->out->element('input', array('id' => 'settings_design_reset',
601                                          'type' => 'reset',
602                                          'value' => 'Reset',
603                                          'class' => 'submit form_action-primary',
604                                          'title' => _('Reset back to default')));
605
606         $this->out->submit('save', _('Save'), 'submit form_action-secondary',
607                 'save', _('Save design'));
608     }
609
610 }