]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/designadminpanel.php
Updated path to farbtastic stylesheet
[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('js/farbtastic/farbtastic.js');
306         $this->script('js/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
374         $this->out->elementStart('fieldset', array('id' => 'settings_design_logo'));
375         $this->out->element('legend', null, _('Change logo'));
376
377         $this->out->elementStart('ul', 'form_data');
378
379         $this->li();
380         $this->input('logo', _('Site logo'), 'Logo for the site (full URL)');
381         $this->unli();
382
383         $this->out->elementEnd('ul');
384
385         $this->out->elementEnd('fieldset');
386         $this->out->elementStart('fieldset', array('id' => 'settings_design_theme'));
387         $this->out->element('legend', null, _('Change theme'));
388
389         $this->out->elementStart('ul', 'form_data');
390
391         $themes = Theme::listAvailable();
392
393         // XXX: listAvailable() can return an empty list if you
394         // screw up your settings, so just in case:
395
396         if (empty($themes)) {
397             $themes = array('default', 'default');
398         }
399
400         asort($themes);
401         $themes = array_combine($themes, $themes);
402
403         $this->li();
404         $this->out->dropdown('theme', _('Site theme'),
405                              $themes, _('Theme for the site.'),
406                              false, $this->value('theme'));
407         $this->unli();
408
409         $this->out->elementEnd('ul');
410
411         $this->out->elementEnd('fieldset');
412
413         $design = $this->out->design;
414
415         $this->out->elementStart('fieldset', array('id' =>
416             'settings_design_background-image'));
417         $this->out->element('legend', null, _('Change background image'));
418         $this->out->elementStart('ul', 'form_data');
419
420         $this->li();
421         $this->out->element('label', array('for' => 'design_background-image_file'),
422                                 _('Background'));
423         $this->out->element('input', array('name' => 'design_background-image_file',
424                                      'type' => 'file',
425                                      'id' => 'design_background-image_file'));
426         $this->out->element('p', 'form_guide',
427             sprintf(_('You can upload a background image for the site. ' .
428               'The maximum file size is %1$s.'), ImageFile::maxFileSize()));
429         $this->out->element('input', array('name' => 'MAX_FILE_SIZE',
430                                           'type' => 'hidden',
431                                           'id' => 'MAX_FILE_SIZE',
432                                           'value' => ImageFile::maxFileSizeInt()));
433         $this->unli();
434
435         if (!empty($design->backgroundimage)) {
436
437             $this->out->elementStart('li', array('id' =>
438                 'design_background-image_onoff'));
439
440             $this->out->element('img', array('src' =>
441                 Design::url($design->backgroundimage)));
442
443             $attrs = array('name' => 'design_background-image_onoff',
444                            'type' => 'radio',
445                            'id' => 'design_background-image_on',
446                            'class' => 'radio',
447                            'value' => 'on');
448
449             if ($design->disposition & BACKGROUND_ON) {
450                 $attrs['checked'] = 'checked';
451             }
452
453             $this->out->element('input', $attrs);
454
455             $this->out->element('label', array('for' => 'design_background-image_on',
456                                           'class' => 'radio'),
457                                           _('On'));
458
459             $attrs = array('name' => 'design_background-image_onoff',
460                            'type' => 'radio',
461                            'id' => 'design_background-image_off',
462                            'class' => 'radio',
463                            'value' => 'off');
464
465             if ($design->disposition & BACKGROUND_OFF) {
466                 $attrs['checked'] = 'checked';
467             }
468
469             $this->out->element('input', $attrs);
470
471             $this->out->element('label', array('for' => 'design_background-image_off',
472                                           'class' => 'radio'),
473                                           _('Off'));
474             $this->out->element('p', 'form_guide', _('Turn background image on or off.'));
475             $this->unli();
476
477             $this->li();
478             $this->out->checkbox('design_background-image_repeat',
479                             _('Tile background image'),
480                             ($design->disposition & BACKGROUND_TILE) ? true : false);
481             $this->unli();
482         }
483
484         $this->out->elementEnd('ul');
485         $this->out->elementEnd('fieldset');
486
487         $this->out->elementStart('fieldset', array('id' => 'settings_design_color'));
488         $this->out->element('legend', null, _('Change colours'));
489
490         $this->out->elementStart('ul', 'form_data');
491
492         try {
493
494             $bgcolor = new WebColor($design->backgroundcolor);
495
496             $this->li();
497             $this->out->element('label', array('for' => 'swatch-1'), _('Background'));
498             $this->out->element('input', array('name' => 'design_background',
499                                           'type' => 'text',
500                                           'id' => 'swatch-1',
501                                           'class' => 'swatch',
502                                           'maxlength' => '7',
503                                           'size' => '7',
504                                           'value' => ''));
505             $this->unli();
506
507             $ccolor = new WebColor($design->contentcolor);
508
509             $this->li();
510             $this->out->element('label', array('for' => 'swatch-2'), _('Content'));
511             $this->out->element('input', array('name' => 'design_content',
512                                           'type' => 'text',
513                                           'id' => 'swatch-2',
514                                           'class' => 'swatch',
515                                           'maxlength' => '7',
516                                           'size' => '7',
517                                           'value' => ''));
518             $this->unli();
519
520             $sbcolor = new WebColor($design->sidebarcolor);
521
522             $this->li();
523             $this->out->element('label', array('for' => 'swatch-3'), _('Sidebar'));
524             $this->out->element('input', array('name' => 'design_sidebar',
525                                         'type' => 'text',
526                                         'id' => 'swatch-3',
527                                         'class' => 'swatch',
528                                         'maxlength' => '7',
529                                         'size' => '7',
530                                         'value' => ''));
531             $this->unli();
532
533             $tcolor = new WebColor($design->textcolor);
534
535             $this->li();
536             $this->out->element('label', array('for' => 'swatch-4'), _('Text'));
537             $this->out->element('input', array('name' => 'design_text',
538                                         'type' => 'text',
539                                         'id' => 'swatch-4',
540                                         'class' => 'swatch',
541                                         'maxlength' => '7',
542                                         'size' => '7',
543                                         'value' => ''));
544             $this->unli();
545
546             $lcolor = new WebColor($design->linkcolor);
547
548             $this->li();
549             $this->out->element('label', array('for' => 'swatch-5'), _('Links'));
550             $this->out->element('input', array('name' => 'design_links',
551                                          'type' => 'text',
552                                          'id' => 'swatch-5',
553                                          'class' => 'swatch',
554                                          'maxlength' => '7',
555                                          'size' => '7',
556                                          'value' => ''));
557             $this->unli();
558
559         } catch (WebColorException $e) {
560             common_log(LOG_ERR, 'Bad color values in site design: ' .
561                 $e->getMessage());
562         }
563
564         $this->out->elementEnd('fieldset');
565
566         $this->out->elementEnd('ul');
567     }
568
569     /**
570      * Action elements
571      *
572      * @return void
573      */
574
575     function formActions()
576     {
577         $this->out->submit('defaults', _('Use defaults'), 'submit form_action-default',
578                 'defaults', _('Restore default designs'));
579
580         $this->out->element('input', array('id' => 'settings_design_reset',
581                                          'type' => 'reset',
582                                          'value' => 'Reset',
583                                          'class' => 'submit form_action-primary',
584                                          'title' => _('Reset back to default')));
585
586         $this->out->submit('save', _('Save'), 'submit form_action-secondary',
587                 'save', _('Save design'));
588     }
589
590 }