root/branches/multiuser/admin/themes.php

Revision 1604, 17.5 kB (checked in by mdodoo, 2 years ago)

Sync with trunk up to (but not including changeset [1585]). I should *definitely* do this more often, because this was really annoying.

  • Property svn:eol-style set to native
Line 
1<?php
2###############################################################################
3# Gregarius - A PHP based RSS aggregator.
4# Copyright (C) 2003 - 2006 Marco Bonetti
5#
6###############################################################################
7# This program is free software and open source software; you can redistribute
8# it and/or modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of the License,
10# or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful, but WITHOUT
13# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15# more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program; if not, write to the Free Software Foundation, Inc.,
19# 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  or visit
20# http://www.gnu.org/licenses/gpl.html
21#
22###############################################################################
23# E-mail:      mbonetti at gmail dot com
24# Web page:    http://gregarius.net/
25#
26###############################################################################
27
28
29function themes_admin() {
30    return CST_ADMIN_DOMAIN_THEMES;
31}
32
33function themes() {
34    $themes = getThemes();
35
36    if (isset($_GET['theme']) && array_key_exists($_GET['theme'],$themes)) {
37        $active_theme = sanitize($_GET['theme'], RSS_SANITIZER_SIMPLE_SQL |RSS_SANITIZER_NO_SPACES);
38       
39        $sql = "update " . getTable('config') . " set value_ = '$active_theme'"
40               ." where key_='rss.output.theme'";
41        rss_query($sql);
42       
43        rss_invalidate_cache();
44    }    else {
45        $active_theme= getConfig('rss.output.theme');
46    }
47
48                echo "<form style=\"float:right\" method=\"post\" action=\"" .$_SERVER['PHP_SELF'] ."\">\n"
49                  . "<p><input type=\"hidden\" name=\"".CST_ADMIN_DOMAIN."\" value=\"".CST_ADMIN_DOMAIN_THEMES."\" />\n"
50                ."<input type=\"submit\" name=\"admin_themes_check_for_updates\" value=\"".__('Check for Updates')."\" /></p>\n"
51                . "</form>\n";
52                if (isset($_POST['admin_themes_check_for_updates'])) {
53                        theme_getThemesUpdate($themes);
54                }
55   
56    echo "<h2 class=\"trigger\">".__('Themes')."</h2>\n"
57    ."<div id=\"admin_themes\" >\n";
58    echo __('<p style="font-size:small">Themes are made of a set of template files which specify how your Gregarius installation looks.<br />More themes can be downloaded from the <a style="text-decoration:underline"  href="http://themes.gregarius.net/">Themes Repository</a>.</p>');
59
60
61    foreach ($themes as $entry => $theme) {
62
63        extract($theme);
64        if (!$name) {
65            $name = $entry;
66        }
67        if ($url) {
68            $author = "<a href=\"$url\">$author</a>";
69        }
70        $active = ($entry ==  $active_theme);
71        $updateAvailable = isset($theme['updateVersion']);
72        if ($screenshot) {
73            $screenshotURL = "<img src=\"". getPath() . RSS_THEME_DIR . "/$fsname/$screenshot\"  />";
74        } else {
75            $screenshotURL = "<img src=\"". getPath() . RSS_THEME_DIR . "/default/media/noscreenshot.png\" />";
76        }
77        $h4="$name"; 
78        $h5="By&nbsp;$author | Version:&nbsp;$version";
79        if ($updateAvailable) {
80                $h5 .= ' | <a class="update" href="'.$theme['updateUrl'].'">Update to version ' .$theme['updateVersion'] .'</a>';
81        }
82       
83        if ($htmltheme) {
84            $seturl = "index.php?view=themes&amp;theme=$entry";
85        } else {
86            $seturl = "";
87        }
88        echo "<div class=\"themeframe".($active?" active":""). ($updateAvailable?" hilite":"")."\"><span>";
89        if (!$active && $htmltheme) {
90            echo "<a href=\"$seturl\" class=\"bookmarklet\">".__('Use this Theme')."</a>";
91        } elseif($active) {
92            echo "<p class=\"bookmarklet\">".__('Active Theme')."</p>";
93        }
94        echo "<h4>$h4</h4>\n";
95        if( file_exists( "../" . RSS_THEME_DIR . "/$fsname/config.php" ) )
96            echo "<a class=\"bookmarklet\" href=\"".$_SERVER['PHP_SELF']. "?".CST_ADMIN_DOMAIN."=".
97                    CST_ADMIN_DOMAIN_THEME_OPTIONS
98                    ."&amp;theme=".$entry
99                    ."&amp;" .CST_ADMIN_VIEW ."=" .CST_ADMIN_DOMAIN_THEME_OPTIONS
100                    ."\">" . __('Configure') . "</a>";
101        echo "<h5>$h5</h5>\n"
102            ."<p class=\"themescreenshot\">$screenshotURL</p>"
103            ."<p>$description</p>&nbsp;"           
104            ."</span></div>\n";
105    }
106
107    echo "</div>\n";
108}
109
110function getThemes() {
111
112    $d = dir('../'. RSS_THEME_DIR);
113    $files = array();
114    $ret = array();
115    $activeIdx = "0";
116    while (false !== ($theme = $d->read())) {
117        if ($theme != "CVS" && !is_file("../".RSS_THEME_DIR."/$theme") && substr($theme,0,1) != ".") {
118            $ret[$theme]=getThemeInfo($theme);
119        }
120    }
121    $d->close();
122    return $ret;
123}
124
125function theme_options_admin() {
126    return CST_ADMIN_DOMAIN_THEME_OPTIONS;
127}
128
129function theme_options() {
130    if (!array_key_exists('theme',$_REQUEST) ||
131            array_key_exists('admin_theme_options_cancel_changes', $_REQUEST)) {
132        themes();
133        return;
134    }
135
136    $theme = $_REQUEST['theme'];
137    $theme_output = "";
138    if (preg_match('/([a-zA-Z0-9_\/\-]+)/',$theme,$matches)) {
139        $theme = $matches[1]; // sanitize input
140        $theme_info = getThemeInfo($theme);
141        extract($theme_info);
142        if( file_exists( "../" . RSS_THEME_DIR . "/$fsname/config.php" ) ) {
143            ob_start();
144            rss_theme_options_rendered_buttons( false );
145            rss_require( RSS_THEME_DIR . "/$fsname/config.php" );
146            $theme_output = ob_get_contents();
147            ob_end_clean();
148            rss_invalidate_cache();
149        }
150        if ($theme_output) { // Let us set up a form
151            echo "<h2
152            class=\"trigger\">".__('Theme Options')." ".TITLE_SEP." ". $name. "</h2>\n"
153            ."<div id=\"admin_theme_options\">\n";
154            echo "<form method=\"post\" ";
155            if( rss_theme_options_form_class() !== null ) {
156                echo "class='" . rss_theme_options_form_class() . "' ";
157            }
158            echo "action=\"" .$_SERVER['PHP_SELF'] ."\">\n";
159            echo "<p><input type=\"hidden\" name=\"".CST_ADMIN_DOMAIN
160            ."\" value=\"".CST_ADMIN_DOMAIN_THEME_OPTIONS."\" /></p>\n";
161            echo $theme_output;
162            echo "<p><input type=\"hidden\" name=\"theme\" value=\"".$theme."\"/>\n";
163            echo "<input type=\"hidden\" name=\"". CST_ADMIN_METAACTION
164                   ."\" value=\"ACT_ADMIN_SUBMIT_CHANGES\"/>\n";
165            if( isset( $_REQUEST['mediaparam'] ) ) //pass it along
166            {
167                $mediaparam = sanitize($_REQUEST['mediaparam'], RSS_SANITIZER_CHARACTERS);
168                echo( "<input type=\"hidden\" name=\"mediaparam\" value=\"$mediaparam\">\n" );
169            }
170            if( !rss_theme_options_rendered_buttons() )
171            {
172                echo "<input type=\"submit\" name=\"admin_theme_options_submit_changes\" value=\""
173                .__('Submit Changes')."\" />\n";
174                echo "<input type=\"submit\" name=\"admin_theme_options_cancel_changes\"
175                value=\"".__('Cancel')."\" />\n";
176            }
177            echo "</p></form>\n";
178            echo "</div>";
179        } else {
180            themes();
181        }
182    }
183}
184
185// we take the array that's input, and return an array as if it had been selected
186// from the config table and dumped out using rss_fetch_assoc.  This means the
187// theme author does not have to pass anything more than key_ in his input array.
188// If $key is not null we query and return only that item, otherwise we fill
189// an array to match the entire input array
190function theme_options_fill_override_array($theme, $media, $array_input, $key=null) {
191    $ret = array();
192    if( !is_array( $array_input ) ) {
193        $array_input = split( ",", $array_input );
194    }
195   
196    foreach( $array_input as $inp ) {
197        if( !is_array( $inp ) && isset( $inp ) ) {
198            $inp = array( 'key_' => $inp );
199        }
200       
201        if( isset( $inp['key_'] ) ) {
202            $thisret = array();
203            if( $key === null || $key === $inp['key_'] ) {
204                $thisret = $inp;
205                if($inp['key_'] == 'rss.output.theme.scheme') {
206                    $schemes = loadSchemeList( true, $theme, $media );
207                    if( !isset( $inp['default_'] ) )
208                        $thisret['default_'] = implode(',', $schemes ) . ",0";
209                    $thisret['type_'] = 'enum';
210                    if( !isset( $inp['desc_'] ) )
211                        $thisret['desc_'] = 'The color scheme to use.';
212                    if( !isset( $inp['export_'] ) )
213                        $thisret['export_'] = '';
214                       
215                    $value = rss_theme_config_override_option($thisret['key_'], $thisret['default_'], $theme, $media);
216                    $value = array_pop( explode( ',', $value ) );
217                    $thisret['value_'] = implode(',', $schemes ) . "," . $value;
218                   
219                } else {
220                    $sql = "select * from " .getTable("config") ." where key_ like
221                           '" . $inp['key_'] . "'";
222                    $res = rss_query($sql);
223                    if ($row = rss_fetch_assoc($res)) {
224                        foreach( $row as $rowkey => $rowval ) {
225                            if( $rowkey !== 'value_' ) {
226                                if( !isset( $inp[$rowkey] ) ) {
227                                    $thisret[$rowkey] = $rowval;
228                                } else {
229                                    $thisret[$rowkey] = $inp[$rowkey];
230                                }
231                            }
232                        }
233                    }
234                   
235                    $thisret['value_'] = rss_theme_config_override_option($thisret['key_'], $thisret['default_'], $theme, $media);
236                }
237
238                if( $key === null )
239                    $ret[] = $thisret;
240                else
241                    $ret = $thisret;
242            }
243        } else {
244            rss_error('rss_theme_options_configure_overrides was passed an item with no key_', RSS_ERROR_ERROR,true);
245        }
246    }
247   
248    return $ret;
249}
250
251// Display a configuration form similar to the form in the admin->config section
252// except we will get the theme's overrides via rss_themes_get_option.  You will
253// need to pass in the theme, the media (optional - pass null for no media) and
254// an array.
255// The array is where it gets complex.  Each member of the array can be a string
256// representing the key of a configuration item, or it can be an array that specifies
257// the various properties of the configuration item.  These properties are the
258// same as the fields in the config table (key_, default_, descr_) and any that
259// are missing will be loaded from that table.  The keys of the configuration
260// items may match an entry in the config table, or you can create a custom one.
261// In the later case, you *must* use the second form of the $config_items array
262// and you must pass all the fields that this function uses (key_, default_, type_
263// and desc_)  Note that there is no point to passing value_ as this is loaded
264// via a call to rss_themes_get_option.
265function rss_theme_options_configure_overrides($theme, $media, $config_items) {
266    $action = null;
267
268        if (isset($_REQUEST[CST_ADMIN_METAACTION])) {
269                $action = $_REQUEST[CST_ADMIN_METAACTION];
270        } else if (isset($_REQUEST['action'])) {
271                $action = $_REQUEST['action'];
272        }
273       
274        if( isset( $_REQUEST['mediaparam'] ) && $media === sanitize($_REQUEST['mediaparam'], RSS_SANITIZER_CHARACTERS) ) {
275                if (array_key_exists(CST_ADMIN_CONFIRMED,$_POST) && $_POST[CST_ADMIN_CONFIRMED] == __('Yes')) {
276                        if (!array_key_exists('key',$_REQUEST)) {
277                                rss_error('Invalid config key specified.', RSS_ERROR_ERROR,true);
278                        } else {
279                                $key = sanitize($_REQUEST['key'],RSS_SANITIZER_NO_SPACES|RSS_SANITIZER_SIMPLE_SQL);
280                                rss_theme_delete_config_override_option($key,$theme,$media);
281                        }
282                        $action = null; //redirect to our theme's admin page
283                } else if( rss_theme_options_is_submit() ) {
284                        switch ($action) {
285                        case __('Submit Changes'):
286                        case 'ACT_ADMIN_SUBMIT_CHANGES':
287                                if (!array_key_exists('key',$_REQUEST)) {
288                                        rss_error('Invalid config key specified.', RSS_ERROR_ERROR,true);
289                                        break;
290                                }
291                                if (!array_key_exists('type',$_REQUEST)) {
292                                        rss_error('Invalid config type specified.', RSS_ERROR_ERROR,true);
293                                        break;
294                                }
295                                if (!array_key_exists('value',$_REQUEST)) {
296                                        rss_error('Invalid config value specified.', RSS_ERROR_ERROR,true);
297                                        break;
298                                }
299                               
300                                $key = sanitize($_REQUEST['key'],RSS_SANITIZER_NO_SPACES|RSS_SANITIZER_SIMPLE_SQL);
301                                $type = sanitize($_POST['type'],RSS_SANITIZER_CHARACTERS);
302                                $value = sanitize($_POST['value'], RSS_SANITIZER_SIMPLE_SQL);
303       
304                                if( $type == 'enum' ) {
305                                        $item = theme_options_fill_override_array($theme,$media,$config_items,$key);
306                                        if( count( $item ) ) {
307                                                $arr = explode(',',$item['default_']);
308                                                $idx = array_pop($arr);
309                                                $newkey = -1;
310                                                foreach ($arr as $i => $val) {
311                                                        if ($val == $value) {
312                                                                $newkey = $i;
313                                                        }
314                                                }
315                                                reset($arr);
316                                                if ($newkey > -1) {
317                                                        array_push($arr, $newkey);
318                                                        rss_theme_set_config_override_option($key, implode(',',$arr), $theme, $media);
319                                                } else {
320                                                        rss_error("Oops, invalid value '$value' for this config key", RSS_ERROR_ERROR,true);
321                                                }
322                                        }
323                                } else {
324                                        rss_theme_set_config_override_option($key, $value, $theme, $media);
325                                }
326       
327                                break;
328                               
329                        default:
330                                rss_error('Invalid config action specified.', RSS_ERROR_ERROR,true);
331                                break;
332                        }
333                        $action = null; //redirect to our theme's admin page
334                }
335    }
336   
337    switch ($action) {
338    case CST_ADMIN_DEFAULT_ACTION:
339    case 'CST_ADMIN_DEFAULT_ACTION':
340        if( isset( $_REQUEST['mediaparam'] ) && $media === sanitize($_REQUEST['mediaparam'], RSS_SANITIZER_CHARACTERS) ) {
341                        if (!array_key_exists('key',$_REQUEST)) {
342                                rss_error('Invalid config key specified.', RSS_ERROR_ERROR,true);
343                                break;
344                        }
345                        $key = sanitize($_REQUEST['key'],RSS_SANITIZER_NO_SPACES|RSS_SANITIZER_SIMPLE_SQL);
346                        $item = theme_options_fill_override_array($theme,$media,$config_items,$key);
347                        if( count( $item ) ) {
348                                extract( $item );
349                                config_default_form($key_, $type_, $default_, CST_ADMIN_DOMAIN_THEME_OPTIONS);
350                                rss_theme_options_form_class('box');
351                                rss_theme_options_rendered_buttons(true);
352                        }
353                }
354        break;
355       
356    case CST_ADMIN_EDIT_ACTION:
357    case 'CST_ADMIN_EDIT_ACTION':
358        if( isset( $_REQUEST['mediaparam'] ) && $media === sanitize($_REQUEST['mediaparam'], RSS_SANITIZER_CHARACTERS) ) {
359                        if (!array_key_exists('key',$_REQUEST)) {
360                                rss_error('Invalid config key specified.', RSS_ERROR_ERROR,true);
361                                break;
362                        }
363                        $key = sanitize($_REQUEST['key'],RSS_SANITIZER_NO_SPACES|RSS_SANITIZER_SIMPLE_SQL);
364                        $item = theme_options_fill_override_array($theme,$media,$config_items,$key);
365                        if( count( $item ) ) {
366                                extract( $item );
367                                $dummy = null;
368                                config_edit_form($key_,$value_,$default_,$type_,$desc_,$export_,$dummy);
369                        }
370                }
371                break;
372       
373    default:
374        $caption = "Configuration overrides";
375        if( isset( $media ) ) {
376            $caption .= " for $media media";
377        }
378        config_table_header($caption);
379
380        $cntr = 0;
381        $items = theme_options_fill_override_array($theme,$media,$config_items);
382        foreach( $items as $item ) {
383            config_table_row( $item, (($cntr++ % 2 == 0)?"even":"odd"), CST_ADMIN_DOMAIN_THEME_OPTIONS, "&theme=$theme&mediaparam=$media" );
384        }
385
386        config_table_footer();
387       
388        //no buttons here
389        rss_theme_options_rendered_buttons(true);
390
391        break;
392    }
393}
394
395function rss_theme_options_rendered_buttons($value=null) {
396    static $__rss_theme_options_rendered_buttons;
397    if( $value !== null )
398        $__rss_theme_options_rendered_buttons = $value;
399    return $__rss_theme_options_rendered_buttons;
400}
401
402function rss_theme_options_form_class($value=null) {
403    static $__rss_theme_options_form_class;
404    if( $value !== null )
405        $__rss_theme_options_form_class = $value;
406    return $__rss_theme_options_form_class;
407}
408
409
410function rss_theme_options_is_submit() {
411    return array_key_exists("admin_theme_options_submit_changes", $_REQUEST);
412}
413
414function theme_getThemesUpdate(&$themes) {
415          $themesxml = array();
416    global $themesxml;
417    $xml = getUrl('http://themes.gregarius.net/api.php');
418    $xml = str_replace("\r", '', $xml);
419    $xml = str_replace("\n", '', $xml);
420
421    $xp = xml_parser_create() or rss_error("couldn't create parser");
422
423    xml_set_element_handler($xp, 'themes_xml_startElement', 'themes_xml_endElement')
424    or rss_error("couldnt set XML handlers");
425
426    xml_parse($xp, $xml, true) or rss_error("failed parsing xml");
427    xml_parser_free($xp) or rss_error("failed freeing the parser");
428    if (is_array($themesxml)) {
429        foreach($themesxml as $theme => $data) {
430                list($tversion,$turl) = $data;
431                if (isset($themes[$theme]) && $themes[$theme]['version'] < $tversion) {
432                        $themes[$theme]['updateVersion'] = $tversion;
433                        $themes[$theme]['updateUrl'] = $turl;
434                }
435        }
436    }
437}
438
439function themes_xml_startElement($xp, $element, $attr) {
440    global $themesxml;
441
442    if ($element == 'THEME' &&
443            array_key_exists('PID',$attr) &&
444            array_key_exists('URL',$attr) &&
445            array_key_exists('VERSION',$attr)) {
446
447        $themesxml[$attr['PID']] = array($attr['VERSION'],$attr['URL']);
448    }
449}
450
451function themes_xml_endElement($xp, $element) {
452    ///global $pluginsxml;
453    return;
454}
455
456?>
Note: See TracBrowser for help on using the browser.