source: t29-www/lib/host.php @ 649

Last change on this file since 649 was 649, checked in by sven, 5 years ago

RSS-Feed-Probebetrieb ausgeweitet: Internationalisiert, fuer englische Version gibts jetzt auch einen RSS-Feed.

Insbesondere ist in auf englischen Newsseite jetzt testweise ein alternatives Format zum Deutschen geschaltet, auf welches das Deutsche dann auch umgeschaltet werden soll. Es bedarf weniger Pflege und generiert gleichzeitig die Newsseite, das Newsmenü und den abonnierbaren News-Feed. Wenn sich das Format bewährt, kann die deutsche Newsseite darauf auch umgestellt werden.

Ferner wurden die RSS-Feeds auf den News-Seiten textuell erwähnt. Testweise werden auch im englischen Menü wieder Vorschaubilder (Thumbnails) bei den Neuigkeiten eingeblendet, die allerdings derzeit nur auf max 64x64px verkleinerte Einblendungen der entsprechenden News-Bilder sind. Hierfür fehlt noch eine sinnvollere Methode.

File size: 13.6 KB
Line 
1<?php
2/**
3 * t29v6 new Hostinfo and Hosthook system.
4 *
5 * Local host.php files in the webroot can hook into t29* php
6 * and js classes without interfering the code. This can be usually
7 * be used for extra svn information.
8 * Hostinfos can also be appended in this file and therefore be
9 * managed centrally.
10 *
11 * webroot/host.php muss have a t29LocalHost extends t29Host class.
12 *
13 **/
14
15abstract class t29Host {
16        const webroot_host_file = '/host.php'; # relative to webroot
17        const webroot_local_host_classname = 't29LocalHost';
18        const env_hidesuffix_name = "T29URLHIDESUFFIX";
19
20        /// $hostname: An identifier like a FQDN. Is only used to identify the t29Host instance and not
21        ///            for constructing any URL.
22        /// This value must be overwritten in child classes!
23        public $hostname = "undefined";
24       
25        /// $document_root := realpath($_SERVER['DOCUMENT_ROOT']), performed by setup().
26        ///                   Can be used to identify the unix file path to the webserver docroot of the
27        ///                   webhost. Independent of the t29 system.
28        public $document_root;
29       
30        /// $webroot: The unix file path to the t29 web installation, actually the parent directory
31        ///           of the lib/ directory. Is widely used by many files and also computed by themselves.
32        public $webroot;
33        /// $lib  := realpath(__FILE__), just for convenience. $lib = "$webroot/lib" always holds.
34        public $lib;
35       
36        /// $web_prefix: The URL path to the webroot. Example:
37        ///              http://example.com/path/to/t29/de/page.php
38        ///                                ^^^^^^^^^^^^
39        ///                            This part is the web prefix, if /de/page.php is the script_filename.
40        /// This value is computed by setup().
41        public $web_prefix = "";
42       
43        /// $has_web_prefix := !empty($web_prefix). If this host is installed in root or not
44        public $has_web_prefix = false;
45       
46        /// $script_filename: The t29-internal identifying url path, like "/de/page.php" or "/en".
47        ///                   While $_SERVER['SCRIPT_FILENAME'] still contains the $web_prefix, this
48        ///                   string is sanitized.
49        /// This value is computed by setup().
50        public $script_filename;
51
52        /// $slash_filename: Cross-platform $script_filename, always starting with a "/".
53        public $slash_filename;
54
55        /// $ressources: CSS and JavaScript file paths ("Assets"), as used by the RessourceLoader,
56        ///              the loader.php and technikum29.php entry points and the Template.
57        private function ressources_array($webroot='') {
58                // this is implemented as method, because of
59                // 1. "$webbroot/..." like strings. This isn't a good idea anyway (e.g. in ressourceloader: $module_dir_rel2webroot
60                // 2. Closures: function($conf){...} doesn't work as class attribute.
61                // This is rather dirty, but anyway the supposed way to access these data is the public get_ressources().
62                $ressources = array(
63                        'cache_file' => array('compressed.js', 'style.css'),
64                        'module_dir' => array("$webroot/shared/js-v6/modules", "$webroot/shared/css-v6/modules"),
65                        'page_dir' => array("$webroot/shared/js-v6/pagescripts", "$webroot/shared/css-v6/pagestyles"),
66                        'glob_pattern' => array('*.js', '*.css'),
67                        'content_types' => array('application/javascript', 'text/css'),
68                        'class' => array('t29JavaScriptRessourceLoader', 't29StyleSheetRessourceLoader'),
69                        'modules' => function($conf){ return glob($conf['module_dir'] . '/' . $conf['glob_pattern']); },
70                );
71                return $ressources;
72        }
73
74        /// $ressources_types: The Ressources array above consists of numeric arrays. This array
75        ///                    maps those positions (numeric keys) to $conf array positions.
76        ///                    Use get_ressources() to resolve this mapping.
77        private $ressources_types = array('js', 'css');
78
79        public function get_ressources($type, $webroot, $debug_flag=false) {
80                $typepos = array_search($type, $this->ressources_types);
81                if($typepos === FALSE) return null;
82                $conf = array_map(function($val) use($typepos) 
83                        { return is_array($val) ? $val[$typepos] : $val; },
84                        $this->ressources_array($webroot));
85                $conf['type'] = $type;
86                // callback functions need the $conf we built.
87                $conf['modules'] = call_user_func($conf['modules'], $conf);
88                $conf['debug'] = $debug_flag; // skip cache and just concat everything
89                return $conf;
90        }
91
92        /**
93         * A special helper class, used by t29Template and technikum29.php entry point.
94         * The general (clean) way would be querying get_ressources().
95         * There is also t29RessourceLoader::get_page_specific_urls() which basically does
96         * the same, just using the global conf array.
97         **/ 
98        public function ressources_get_pagestyle($seiten_id) {
99                $ressources =  $this->ressources_array();
100                // We address the css property directly with the [1] index. Bad!
101                return $ressources['page_dir'][1] . '/' . $seiten_id . '.css';
102        }
103
104        /// Singleton fun for detect()
105        private static $instance;
106        private static function new_singleton($classname) {
107                if(!isset(self::$instance))
108                        self::$instance = new $classname;
109                return self::$instance;
110        }
111
112        /**
113         * Factory for creating a t29Host instance automatically
114         * from the current host. This method will decide which
115         * subclass has to be taken.
116         * This function als implements the Singleton pattern, so
117         * you can call it frequently.
118         **/
119        static function detect() {
120                $instance = null;
121
122                // check if local host file exists
123                $hostfile = dirname(__FILE__) . '/../' . self::webroot_host_file;
124                if(file_exists($hostfile)) {
125                        include $hostfile;
126                        if(class_exists(self::webroot_local_host_classname)) {
127                                $x = self::webroot_local_host_classname;
128                                $host = self::new_singleton($x);
129                                $host->setup();
130                                return $host;
131                        } else {
132                                print "Warning: Hostfile $hostfile does not contain class ".self::webroot_local_host_classname."\n";
133                        }
134                }
135               
136                // Quick and Dirty: Load hostname specific instances
137                switch($_SERVER['SERVER_NAME']) {
138                        case 'heribert':
139                        case 'localhost':
140                                $localhost = self::new_singleton('t29HeribertHost');
141                                $localhost->setup();
142                                return $localhost;
143                }
144               
145                $publichost = self::new_singleton('t29PublicHost');
146                $publichost->setup();
147                return $publichost;
148        }
149
150        /**
151         * "Factory" for creating an instance of $className as a singleton.
152         * You should really use detect() for auto-detection instead of
153         * forcing a host.
154         * Only useful for explicitely calling t29ExternalHost by $external call.
155         **/
156        static function create($className) {
157                return self::new_singleton($className)->setup();
158        }
159       
160        /**
161         * A constructing method which is always called by the t29Host::detect() factory.
162         * It does some general stuff.
163         * Of course you can always write your own setup() class - it's just your __constructor.
164         * The constructor will of course be called before the setup() method.
165         *
166         * This method detects two things:
167         *   1. if this host does Clean URLs (Suffix rewriting)
168         *   2. if this host is *not* installed in its own virtualhost (i.e. on docroot).
169         *
170         * @returns $this for chaining
171         **/
172        private function setup() {
173                $this->is_rewriting_host = isset($_SERVER[self::env_hidesuffix_name]);
174               
175                $this->lib = dirname(__FILE__);
176                $this->webroot = realpath($this->lib . '/../');  # file path to root of t29 web installation
177               
178                /*
179                   calculate the web_prefix. This is kind of a detection.
180                   
181                   Examples for an installation in Document root:
182                      $lib = /var/www/technikum29.de/lib
183                      $webroot = /var/www/technikum29.de
184                      $_SERVER["DOCUMENT_ROOT"] = /var/www/technikum29.de
185                      $this->document_root = /var/www/technikum29.de
186                      $_SERVER["SCRIPT_FILENAME"] = /var/www/technikum29-www/de/index.php
187                      $this->script_filename = /de/index.php
188                      $_SERVER["REQUEST_URI"] = /de
189                      $_SERVER["SCRIPT_NAME"] = /de/index.php
190                      $web_prefix = ""
191                     
192                   Example for an installation in an arbitrary directory below Document Root:
193                     $lib = /var/www/arbitrary/lib
194                     $webroot = /var/www/arbitrary
195                     $_SERVER['DOCUMENT_ROOT'] = /var/www
196                     $this->document_root = /var/www/arbitrary
197                     $_SERVER['SCRIPT_FILENAME'] = /var/www/arbitrary/de/index.php
198                     $this->script_filename = /arbitrary/de/index.php
199                     $_SERVER['REQUEST_URI'] = /arbitrary/de
200                     $_SERVER['SCRIPT_NAME'] = /arbitrary/de/index.php
201                     $web_prefix = "/arbitrary"
202                     
203                   Example for an installation in mod_userdirs homedir out of Docroot:
204                     $lib = /home/sven/public_html/foo/lib
205                     $webroot = /home/sven/public_html/foo
206                     $_SERVER['DOCUMENT_ROOT'] = /var/www   (mind that!)
207                     $this->document_root = /home/sven/public_html/foo
208                     $_SERVER['SCRIPT_FILENAME'] = /~sven/foo/en/index.php
209                     $this->script_filename = /~sven/foo/en/index.php
210                     $_SERVER['REQUEST_URI'] = /~sven/foo/en/
211                     $_SERVER['SCRIPT_NAME'] = /~sven/foo/en/index.php
212                     $web_prefix = "/~sven/foo"
213                */
214
215                // this algorithm is good for detecting paths below the document root.
216                // it is not suitable for paths out of the document root
217                $this->document_root = realpath($_SERVER['DOCUMENT_ROOT']);
218                if($this->webroot == $this->document_root) {
219                        // we are installed in document root
220                        $this->web_prefix = "";
221                } else {
222                        // we are installed in some arbitary directory
223                        $this->web_prefix = substr($this->webroot, strlen($this->document_root));
224                }
225               
226                // TODO: Somehow autodetect paths out of the document root
227               
228                $this->has_web_prefix = !empty($this->web_prefix);
229               
230                //print "Web prefix:<pre>";
231                //var_dump($this); exit;
232                   
233                $this->script_filename = substr(realpath($_SERVER['SCRIPT_FILENAME']), strlen($this->document_root)); # e.g.: "/de/page.php"
234
235                # Bug when DOCUMENT_ROOT ends with trailing slash: make sure $file begins with /:
236                $this->slash_filename = $this->script_filename;
237                if($this->slash_filename{0} != '/') $this->slash_filename = '/'.$this->slash_filename;
238               
239                // Windows realpath() converts Unix Paths ($_SERVER) to Windows Paths (like \en\index.php).
240                // We want to use unix paths ($_SERVER like) internally, so do this dummy conversion back, if neccessary
241                $this->script_filename = str_replace('\\', '/', $this->script_filename);
242               
243                //phpinfo(); exit;
244                return $this; // Chaining
245        }
246       
247        function check_url_rewrite() {
248                if($this->is_rewriting_host) {
249                        $path = $_SERVER['REQUEST_URI'];
250                        $newpath = $this->rewrite_link($path);
251                        if($path != $newpath) {
252                                header('HTTP/1.1 301 Moved Permanently');
253                                header('Location: '.$newpath);
254                                return $newpath;
255                        }
256                }
257                return null;
258        }
259
260        public function __toString() {
261                return 't29v6/'.$this->hostname;
262        }
263       
264        /**
265         * Rewrite Links so they match for this host.
266         * This method acts like a pipeline:
267         *  $new_link = rewrite_link($old_link);
268         * It can perform two conversions:
269         *
270         *   1. Rewriting/Clean URL system: Will strip file suffixes, if appropriate.
271         *      This will be done whenever this is a rewriting host and this is the
272         *      main purpose for this function.
273         *
274         *   2. Prefixing the correct web prefix. This is *only* be done when
275         *      $also_rewrite_prefix = true. The reaseon is that prefix rewriting is
276         *      generally done by a global page rewrite after generation of the whole
277         *      page on a whole-page-level. This is less error prone.
278         *      Anyway you can use this function if you think you need. blubblubb
279         *
280         *
281         **/
282        function rewrite_link($link_target, $also_rewrite_prefix=false) {
283                // rewrite link if neccessary. This function will be called hundreds of times
284                // while rendering a page, rewriting all links found.
285               
286                // pending: prefix setzen.
287                if($this->has_web_prefix && $also_rewrite_prefix) {
288                        $link_target = $this->web_prefix . $link_target;
289                }
290               
291                if($this->is_rewriting_host) {
292                        $new_target = preg_replace('/\.(?:php|shtml?)([#?].+)?$/i', '\\1', $link_target);
293                        return $new_target;
294                } else {
295                        // just the identity function
296                        return $link_target;
297                }
298               
299        }
300       
301        function get_shorthand_link_returner() {
302                $t = $this;
303                return function($link_target)use($t) { return $t->rewrite_link($link_target); };
304        }
305
306        abstract function fillup_template_conf(&$template_conf);
307}
308
309class t29PublicHost extends t29Host {
310        /**
311         * This is actually the default public host which should be loaded
312         * at www.technikum29.de.
313         **/
314        public $hostname = "public";
315        function fillup_template_conf(&$template_conf) {}
316}
317
318/**
319 * Host auf heriberts Rechner; dort wird ein weiterer Metatag mit id eingefuehrt,
320 * mit dem seine Firefox Editthispage-Extension die Seite bearbeiten kann.
321 **/
322class t29HeribertHost extends t29Host {
323        public $hostname = "heribert";
324
325        function fillup_template_conf(&$template_conf) {
326                $template_conf['header_prepend'][] = 
327                        '<meta name="t29.localfile" content="'.$_SERVER['SCRIPT_FILENAME'].'" id="localFileSource">';
328        }
329}
330
331/**
332 * Ein "external" Host, der Links mit voller URL angeben muss, etwa bei der
333 * Einbindung von CSS/JS, aber auch von Links.
334 * Genutzt fuer $external-Einbindung von technikum29.php
335 **/
336class t29ExternalHost extends t29Host {
337        public $hostname = "external";
338        public $target_host = 'http://www.technikum29.de';
339
340        function rewrite_link($link_target, $also_rewrite_prefix=false) {
341                $link_target = parent::rewrite_link($link_target, $also_rewrite_prefix);
342       
343                if($also_rewrite_prefix) {
344                        // check if link has host part
345                        if(!preg_match('#^http:#i', $link_target)) {
346                                $sep = ($link_target{0} == '/') ? '' : '/';
347                                $link_target = $this->target_host . $sep . $link_target;
348                        }
349                }
350
351                return $link_target;
352        }
353
354        function fillup_template_conf(&$template_conf) {
355                $template_conf['header_prepend'][] = 
356                        '<meta name="t29.host.from" content="'.$_SERVER['SERVER_NAME'].'">';
357        }
358}
Note: See TracBrowser for help on using the repository browser.
© 2008 - 2013 technikum29 • Sven Köppel • Some rights reserved
Powered by Trac
Expect where otherwise noted, content on this site is licensed under a Creative Commons 3.0 License