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

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

Bug #51 gefixt (http://labs.technikum29.de/ticket/51).
Jetzt sollten neue Pagestyles gleich beim Erstellen erkannt werden.

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                // We address the css property directly with the [1] index. Bad!
97                return $this->ressources_array()['page_dir'][1] . '/' . $seiten_id . '.css';
98        }
99
100        /// Singleton fun for detect()
101        private static $instance;
102        private static function new_singleton($classname) {
103                if(!isset(self::$instance))
104                        self::$instance = new $classname;
105                return self::$instance;
106        }
107
108        /**
109         * Factory for creating a t29Host instance automatically
110         * from the current host. This method will decide which
111         * subclass has to be taken.
112         * This function als implements the Singleton pattern, so
113         * you can call it frequently.
114         **/
115        static function detect() {
116                $instance = null;
117
118                // check if local host file exists
119                $hostfile = dirname(__FILE__) . '/../' . self::webroot_host_file;
120                if(file_exists($hostfile)) {
121                        include $hostfile;
122                        if(class_exists(self::webroot_local_host_classname)) {
123                                $x = self::webroot_local_host_classname;
124                                $host = self::new_singleton($x);
125                                $host->setup();
126                                return $host;
127                        } else {
128                                print "Warning: Hostfile $hostfile does not contain class ".self::webroot_local_host_classname."\n";
129                        }
130                }
131               
132                // Quick and Dirty: Load hostname specific instances
133                switch($_SERVER['SERVER_NAME']) {
134                        case 'heribert':
135                        case 'localhost':
136                                $localhost = self::new_singleton('t29HeribertHost');
137                                $localhost->setup();
138                                return $localhost;
139                }
140               
141                $publichost = self::new_singleton('t29PublicHost');
142                $publichost->setup();
143                return $publichost;
144        }
145       
146        /**
147         * A constructing method which is always called by the t29Host::detect() factory.
148         * It does some general stuff.
149         * Of course you can always write your own setup() class - it's just your __constructor.
150         * The constructor will of course be called before the setup() method.
151         *
152         * This method detects two things:
153         *   1. if this host does Clean URLs (Suffix rewriting)
154         *   2. if this host is *not* installed in its own virtualhost (i.e. on docroot).
155         **/
156        private function setup() {
157                $this->is_rewriting_host = isset($_SERVER[self::env_hidesuffix_name]);
158               
159                $this->lib = dirname(__FILE__);
160                $this->webroot = realpath($this->lib . '/../');  # file path to root of t29 web installation
161               
162                /*
163                   calculate the web_prefix. This is kind of a detection.
164                   
165                   Examples for an installation in Document root:
166                      $lib = /var/www/technikum29.de/lib
167                      $webroot = /var/www/technikum29.de
168                      $_SERVER["DOCUMENT_ROOT"] = /var/www/technikum29.de
169                      $this->document_root = /var/www/technikum29.de
170                      $_SERVER["SCRIPT_FILENAME"] = /var/www/technikum29-www/de/index.php
171                      $this->script_filename = /de/index.php
172                      $_SERVER["REQUEST_URI"] = /de
173                      $_SERVER["SCRIPT_NAME"] = /de/index.php
174                      $web_prefix = ""
175                     
176                   Example for an installation in an arbitrary directory below Document Root:
177                     $lib = /var/www/arbitrary/lib
178                     $webroot = /var/www/arbitrary
179                     $_SERVER['DOCUMENT_ROOT'] = /var/www
180                     $this->document_root = /var/www/arbitrary
181                     $_SERVER['SCRIPT_FILENAME'] = /var/www/arbitrary/de/index.php
182                     $this->script_filename = /arbitrary/de/index.php
183                     $_SERVER['REQUEST_URI'] = /arbitrary/de
184                     $_SERVER['SCRIPT_NAME'] = /arbitrary/de/index.php
185                     $web_prefix = "/arbitrary"
186                     
187                   Example for an installation in mod_userdirs homedir out of Docroot:
188                     $lib = /home/sven/public_html/foo/lib
189                     $webroot = /home/sven/public_html/foo
190                     $_SERVER['DOCUMENT_ROOT'] = /var/www   (mind that!)
191                     $this->document_root = /home/sven/public_html/foo
192                     $_SERVER['SCRIPT_FILENAME'] = /~sven/foo/en/index.php
193                     $this->script_filename = /~sven/foo/en/index.php
194                     $_SERVER['REQUEST_URI'] = /~sven/foo/en/
195                     $_SERVER['SCRIPT_NAME'] = /~sven/foo/en/index.php
196                     $web_prefix = "/~sven/foo"
197                */
198
199                // this algorithm is good for detecting paths below the document root.
200                // it is not suitable for paths out of the document root
201                $this->document_root = realpath($_SERVER['DOCUMENT_ROOT']);
202                if($this->webroot == $this->document_root) {
203                        // we are installed in document root
204                        $this->web_prefix = "";
205                } else {
206                        // we are installed in some arbitary directory
207                        $this->web_prefix = substr($this->webroot, strlen($this->document_root));
208                }
209               
210                // TODO: Somehow autodetect paths out of the document root
211               
212                $this->has_web_prefix = !empty($this->web_prefix);
213               
214                //print "Web prefix:<pre>";
215                //var_dump($this); exit;
216                   
217                $this->script_filename = substr(realpath($_SERVER['SCRIPT_FILENAME']), strlen($this->document_root)); # e.g.: "/de/page.php"
218               
219                // Windows realpath() converts Unix Paths ($_SERVER) to Windows Paths (like \en\index.php).
220                // We want to use unix paths ($_SERVER like) internally, so do this dummy conversion back, if neccessary
221                $this->script_filename = str_replace('\\', '/', $this->script_filename);
222               
223                //phpinfo(); exit;
224        }
225       
226        function check_url_rewrite() {
227                if($this->is_rewriting_host) {
228                        $path = $_SERVER['REQUEST_URI'];
229                        $newpath = $this->rewrite_link($path);
230                        if($path != $newpath) {
231                                header('HTTP/1.1 301 Moved Permanently');
232                                header('Location: '.$newpath);
233                                return $newpath;
234                        }
235                }
236                return null;
237        }
238
239        public function __toString() {
240                return 't29v6/'.$this->hostname;
241        }
242       
243        /**
244         * Rewrite Links so they match for this host.
245         * This method acts like a pipeline:
246         *  $new_link = rewrite_link($old_link);
247         * It can perform two conversions:
248         *
249         *   1. Rewriting/Clean URL system: Will strip file suffixes, if appropriate.
250         *      This will be done whenever this is a rewriting host and this is the
251         *      main purpose for this function.
252         *
253         *   2. Prefixing the correct web prefix. This is *only* be done when
254         *      $also_rewrite_prefix = true. The reaseon is that prefix rewriting is
255         *      generally done by a global page rewrite after generation of the whole
256         *      page on a whole-page-level. This is less error prone.
257         *      Anyway you can use this function if you think you need. blubblubb
258         *
259         *
260         **/
261        function rewrite_link($link_target, $also_rewrite_prefix=false) {
262                // rewrite link if neccessary. This function will be called hundreds of times
263                // while rendering a page, rewriting all links found.
264               
265                // pending: prefix setzen.
266                if($this->has_web_prefix && $also_rewrite_prefix) {
267                        $link_target = $this->web_prefix . $link_target;
268                }
269               
270                if($this->is_rewriting_host) {
271                        $new_target = preg_replace('/\.(?:php|shtml?)([#?].+)?$/i', '\\1', $link_target);
272                        return $new_target;
273                } else {
274                        // just the identity function
275                        return $link_target;
276                }
277               
278        }
279       
280        function get_shorthand_link_returner() {
281                $t = $this;
282                return function($link_target)use($t) { return $t->rewrite_link($link_target); };
283        }
284
285        abstract function fillup_template_conf(&$template_conf);
286}
287
288class t29PublicHost extends t29Host {
289        /**
290         * This is actually the default public host which should be loaded
291         * at www.technikum29.de.
292         **/
293        public $hostname = "public";
294        function fillup_template_conf(&$template_conf) {}
295}
296
297/**
298 * Host auf heriberts Rechner; dort wird ein weiterer Metatag mit id eingefuehrt,
299 * mit dem seine Firefox Editthispage-Extension die Seite bearbeiten kann.
300 **/
301class t29HeribertHost extends t29Host {
302        public $hostname = "heribert";
303
304        function fillup_template_conf(&$template_conf) {
305                $template_conf['header_prepend'][] = 
306                        '<meta name="t29.localfile" content="'.$_SERVER['SCRIPT_FILENAME'].'" id="localFileSource">';
307        }
308}
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