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