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