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

Last change on this file since 541 was 517, checked in by sven, 10 years ago

Ein Fix vom Fix, scheinbar kommt die PHP-Version auf t29.de nicht mit
dem Syntax zurecht.

File size: 12.0 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        /// $ressources: CSS and JavaScript file paths ("Assets"), as used by the RessourceLoader,
53        ///              the loader.php and technikum29.php entry points and the Template.
54        private function ressources_array($webroot='') {
55                // this is implemented as method, because of
56                // 1. "$webbroot/..." like strings. This isn't a good idea anyway (e.g. in ressourceloader: $module_dir_rel2webroot
57                // 2. Closures: function($conf){...} doesn't work as class attribute.
58                // This is rather dirty, but anyway the supposed way to access these data is the public get_ressources().
59                $ressources = array(
60                        'cache_file' => array('compressed.js', 'style.css'),
61                        'module_dir' => array("$webroot/shared/js-v6/modules", "$webroot/shared/css-v6/modules"),
62                        'page_dir' => array("$webroot/shared/js-v6/pagescripts", "$webroot/shared/css-v6/pagestyles"),
63                        'glob_pattern' => array('*.js', '*.css'),
64                        'content_types' => array('application/javascript', 'text/css'),
65                        'class' => array('t29JavaScriptRessourceLoader', 't29StyleSheetRessourceLoader'),
66                        'modules' => function($conf){ return glob($conf['module_dir'] . '/' . $conf['glob_pattern']); },
67                );
68                return $ressources;
69        }
70
71        /// $ressources_types: The Ressources array above consists of numeric arrays. This array
72        ///                    maps those positions (numeric keys) to $conf array positions.
73        ///                    Use get_ressources() to resolve this mapping.
74        private $ressources_types = array('js', 'css');
75
76        public function get_ressources($type, $webroot, $debug_flag=false) {
77                $typepos = array_search($type, $this->ressources_types);
78                if($typepos === FALSE) return null;
79                $conf = array_map(function($val) use($typepos) 
80                        { return is_array($val) ? $val[$typepos] : $val; },
81                        $this->ressources_array($webroot));
82                $conf['type'] = $type;
83                // callback functions need the $conf we built.
84                $conf['modules'] = call_user_func($conf['modules'], $conf);
85                $conf['debug'] = $debug_flag; // skip cache and just concat everything
86                return $conf;
87        }
88
89        /**
90         * A special helper class, used by t29Template and technikum29.php entry point.
91         * The general (clean) way would be querying get_ressources().
92         * There is also t29RessourceLoader::get_page_specific_urls() which basically does
93         * the same, just using the global conf array.
94         **/ 
95        public function ressources_get_pagestyle($seiten_id) {
96                $ressources =  $this->ressources_array();
97                // We address the css property directly with the [1] index. Bad!
98                return $ressources['page_dir'][1] . '/' . $seiten_id . '.css';
99        }
100
101        /// Singleton fun for detect()
102        private static $instance;
103        private static function new_singleton($classname) {
104                if(!isset(self::$instance))
105                        self::$instance = new $classname;
106                return self::$instance;
107        }
108
109        /**
110         * Factory for creating a t29Host instance automatically
111         * from the current host. This method will decide which
112         * subclass has to be taken.
113         * This function als implements the Singleton pattern, so
114         * you can call it frequently.
115         **/
116        static function detect() {
117                $instance = null;
118
119                // check if local host file exists
120                $hostfile = dirname(__FILE__) . '/../' . self::webroot_host_file;
121                if(file_exists($hostfile)) {
122                        include $hostfile;
123                        if(class_exists(self::webroot_local_host_classname)) {
124                                $x = self::webroot_local_host_classname;
125                                $host = self::new_singleton($x);
126                                $host->setup();
127                                return $host;
128                        } else {
129                                print "Warning: Hostfile $hostfile does not contain class ".self::webroot_local_host_classname."\n";
130                        }
131                }
132               
133                // Quick and Dirty: Load hostname specific instances
134                switch($_SERVER['SERVER_NAME']) {
135                        case 'heribert':
136                        case 'localhost':
137                                $localhost = self::new_singleton('t29HeribertHost');
138                                $localhost->setup();
139                                return $localhost;
140                }
141               
142                $publichost = self::new_singleton('t29PublicHost');
143                $publichost->setup();
144                return $publichost;
145        }
146       
147        /**
148         * A constructing method which is always called by the t29Host::detect() factory.
149         * It does some general stuff.
150         * Of course you can always write your own setup() class - it's just your __constructor.
151         * The constructor will of course be called before the setup() method.
152         *
153         * This method detects two things:
154         *   1. if this host does Clean URLs (Suffix rewriting)
155         *   2. if this host is *not* installed in its own virtualhost (i.e. on docroot).
156         **/
157        private function setup() {
158                $this->is_rewriting_host = isset($_SERVER[self::env_hidesuffix_name]);
159               
160                $this->lib = dirname(__FILE__);
161                $this->webroot = realpath($this->lib . '/../');  # file path to root of t29 web installation
162               
163                /*
164                   calculate the web_prefix. This is kind of a detection.
165                   
166                   Examples for an installation in Document root:
167                      $lib = /var/www/technikum29.de/lib
168                      $webroot = /var/www/technikum29.de
169                      $_SERVER["DOCUMENT_ROOT"] = /var/www/technikum29.de
170                      $this->document_root = /var/www/technikum29.de
171                      $_SERVER["SCRIPT_FILENAME"] = /var/www/technikum29-www/de/index.php
172                      $this->script_filename = /de/index.php
173                      $_SERVER["REQUEST_URI"] = /de
174                      $_SERVER["SCRIPT_NAME"] = /de/index.php
175                      $web_prefix = ""
176                     
177                   Example for an installation in an arbitrary directory below Document Root:
178                     $lib = /var/www/arbitrary/lib
179                     $webroot = /var/www/arbitrary
180                     $_SERVER['DOCUMENT_ROOT'] = /var/www
181                     $this->document_root = /var/www/arbitrary
182                     $_SERVER['SCRIPT_FILENAME'] = /var/www/arbitrary/de/index.php
183                     $this->script_filename = /arbitrary/de/index.php
184                     $_SERVER['REQUEST_URI'] = /arbitrary/de
185                     $_SERVER['SCRIPT_NAME'] = /arbitrary/de/index.php
186                     $web_prefix = "/arbitrary"
187                     
188                   Example for an installation in mod_userdirs homedir out of Docroot:
189                     $lib = /home/sven/public_html/foo/lib
190                     $webroot = /home/sven/public_html/foo
191                     $_SERVER['DOCUMENT_ROOT'] = /var/www   (mind that!)
192                     $this->document_root = /home/sven/public_html/foo
193                     $_SERVER['SCRIPT_FILENAME'] = /~sven/foo/en/index.php
194                     $this->script_filename = /~sven/foo/en/index.php
195                     $_SERVER['REQUEST_URI'] = /~sven/foo/en/
196                     $_SERVER['SCRIPT_NAME'] = /~sven/foo/en/index.php
197                     $web_prefix = "/~sven/foo"
198                */
199
200                // this algorithm is good for detecting paths below the document root.
201                // it is not suitable for paths out of the document root
202                $this->document_root = realpath($_SERVER['DOCUMENT_ROOT']);
203                if($this->webroot == $this->document_root) {
204                        // we are installed in document root
205                        $this->web_prefix = "";
206                } else {
207                        // we are installed in some arbitary directory
208                        $this->web_prefix = substr($this->webroot, strlen($this->document_root));
209                }
210               
211                // TODO: Somehow autodetect paths out of the document root
212               
213                $this->has_web_prefix = !empty($this->web_prefix);
214               
215                //print "Web prefix:<pre>";
216                //var_dump($this); exit;
217                   
218                $this->script_filename = substr(realpath($_SERVER['SCRIPT_FILENAME']), strlen($this->document_root)); # e.g.: "/de/page.php"
219               
220                // Windows realpath() converts Unix Paths ($_SERVER) to Windows Paths (like \en\index.php).
221                // We want to use unix paths ($_SERVER like) internally, so do this dummy conversion back, if neccessary
222                $this->script_filename = str_replace('\\', '/', $this->script_filename);
223               
224                //phpinfo(); exit;
225        }
226       
227        function check_url_rewrite() {
228                if($this->is_rewriting_host) {
229                        $path = $_SERVER['REQUEST_URI'];
230                        $newpath = $this->rewrite_link($path);
231                        if($path != $newpath) {
232                                header('HTTP/1.1 301 Moved Permanently');
233                                header('Location: '.$newpath);
234                                return $newpath;
235                        }
236                }
237                return null;
238        }
239
240        public function __toString() {
241                return 't29v6/'.$this->hostname;
242        }
243       
244        /**
245         * Rewrite Links so they match for this host.
246         * This method acts like a pipeline:
247         *  $new_link = rewrite_link($old_link);
248         * It can perform two conversions:
249         *
250         *   1. Rewriting/Clean URL system: Will strip file suffixes, if appropriate.
251         *      This will be done whenever this is a rewriting host and this is the
252         *      main purpose for this function.
253         *
254         *   2. Prefixing the correct web prefix. This is *only* be done when
255         *      $also_rewrite_prefix = true. The reaseon is that prefix rewriting is
256         *      generally done by a global page rewrite after generation of the whole
257         *      page on a whole-page-level. This is less error prone.
258         *      Anyway you can use this function if you think you need. blubblubb
259         *
260         *
261         **/
262        function rewrite_link($link_target, $also_rewrite_prefix=false) {
263                // rewrite link if neccessary. This function will be called hundreds of times
264                // while rendering a page, rewriting all links found.
265               
266                // pending: prefix setzen.
267                if($this->has_web_prefix && $also_rewrite_prefix) {
268                        $link_target = $this->web_prefix . $link_target;
269                }
270               
271                if($this->is_rewriting_host) {
272                        $new_target = preg_replace('/\.(?:php|shtml?)([#?].+)?$/i', '\\1', $link_target);
273                        return $new_target;
274                } else {
275                        // just the identity function
276                        return $link_target;
277                }
278               
279        }
280       
281        function get_shorthand_link_returner() {
282                $t = $this;
283                return function($link_target)use($t) { return $t->rewrite_link($link_target); };
284        }
285
286        abstract function fillup_template_conf(&$template_conf);
287}
288
289class t29PublicHost extends t29Host {
290        /**
291         * This is actually the default public host which should be loaded
292         * at www.technikum29.de.
293         **/
294        public $hostname = "public";
295        function fillup_template_conf(&$template_conf) {}
296}
297
298/**
299 * Host auf heriberts Rechner; dort wird ein weiterer Metatag mit id eingefuehrt,
300 * mit dem seine Firefox Editthispage-Extension die Seite bearbeiten kann.
301 **/
302class t29HeribertHost extends t29Host {
303        public $hostname = "heribert";
304
305        function fillup_template_conf(&$template_conf) {
306                $template_conf['header_prepend'][] = 
307                        '<meta name="t29.localfile" content="'.$_SERVER['SCRIPT_FILENAME'].'" id="localFileSource">';
308        }
309}
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