use md5sum on ini files to determine if they need re-writing
[pear] / HTML / FlexyFramework.php
index 035c9d5..b9297b7 100755 (executable)
@@ -153,7 +153,7 @@ class HTML_FlexyFramework {
             $this->$k = $v;
         }
         $this->_parseConfig();
-        
+
         // echo '<PRE>'; print_r($this);exit;
         if ($this->cli) {
             $args = $_SERVER['argv'];
@@ -162,20 +162,34 @@ class HTML_FlexyFramework {
             $this->_run($this->run,false,$args);
             return;
         }
-    
+
         // handle apache mod_rewrite..
         // it looks like this might not work anymore..
         
-        
-        
-        if (!empty($_SERVER['REDIRECT_URL'])) {
-            
-            $this->_run($_SERVER['SCRIPT_NAME'] . $_SERVER['REQUEST_URI'],false);
+        /*
+         *
+<IfModule mod_rewrite.c>
+RewriteEngine On
+RewriteBase /
+RewriteRule ^/web.hpasite/index\.local.php$ - [L]
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteRule ^(.+)$ /web.hpasite/index.local.php [L,NC,E=URL:$1]
+</IfModule>
+*/ 
+        
+        if (!empty($_SERVER['REDIRECT_STATUS'])  && !empty($_SERVER['REDIRECT_URL'])) {
+          // phpinfo();exit;
+            $sn = $_SERVER['SCRIPT_NAME'];
+            $sublen = strlen(substr($sn , 0,  strlen($sn) - strlen(basename($sn)) -1));
+            //var_dump(array($sn,$subdir,basename($sn)));exit;
+          
+            //var_dump($_SERVER['SCRIPT_NAME'] . substr($_SERVER['REDIRECT_URL'],$sublen));
+            $this->_run($_SERVER['SCRIPT_NAME'] .  substr($_SERVER['REDIRECT_URL'], $sublen),false);
             return ;
         }
-        
-        
-        $this->_run($_SERVER['REQUEST_URI'],false);
+        // eg... /web.hpasite/index.local.php/Projects
+         $this->_run($_SERVER['REQUEST_URI'],false);
             
         
     }
@@ -194,12 +208,21 @@ class HTML_FlexyFramework {
      */
     function loadModuleConfig($cfg)
     {
+         
+        $proj = $cfg['project'];
+        $rootDir = realpath(dirname($_SERVER["SCRIPT_FILENAME"]));
+        
+        $cls = $proj.'_Config';
+         if (file_exists($rootDir . '/'.str_replace('_','/', $cls). '.php')) {
+            require_once str_replace('_','/', $cls). '.php';
+            $c = new $cls();
+            if (method_exists($c,'init')) {
+                $cfg = $c->init($this,$cfg);
+            }
+        }
         if (empty($cfg['enable'])) {
             return $cfg;
         }
-        $proj = $cfg['project'];
-        $rootDir = realpath(dirname($_SERVER["SCRIPT_FILENAME"]));
-
         foreach(explode(',',$cfg['enable']) as $m) {
             $cls = $proj.'_'. $m . '_Config';
 
@@ -232,7 +255,6 @@ class HTML_FlexyFramework {
             }
         }
         
-        $this->_handleLanguages();
         
         // enable modules.
         if (!empty($this->enable)) {
@@ -253,21 +275,30 @@ class HTML_FlexyFramework {
         if (!$this->cli) {
             $bits[0] = str_replace('%2F','/',urlencode($bits[0]));
             $this->baseURL = $bits[0] . basename($_SERVER["SCRIPT_FILENAME"]);
-            //phpinfo();exit;
-            if (empty($_SERVER['SCRIPT_NAME'])) {
+            // however this is not correct if we are using rewrite..
+            if (!empty($_SERVER['REDIRECT_STATUS'])  && !empty($_SERVER['REDIRECT_URL'])) {
+                $this->baseURL = substr($bits[0],0,-1); // without the trailing '/' ??
+                $this->rootURL = $bits[0] == '/' ? '' : $bits[0];
+                //$this->baseURL = $this->baseURL == '' ? '/' : $this->baseURL;
                 
-                $this->baseURL = ''; // ??? this is if we replace top level...
             }
+            //phpinfo();exit;
+            // is this bit used??
+            //if (empty($_SERVER['SCRIPT_NAME'])) {
+                
+            //    $this->baseURL = ''; // ??? this is if we replace top level...
+            //}
         }
         // if cli - you have to have set baseURL...
         
         
         $this->rootDir = realpath(dirname($_SERVER["SCRIPT_FILENAME"]));
         $this->baseDir = $this->rootDir .'/'. $this->project;
-        $this->rootURL = dirname($this->baseURL);
-        $this->rootURL = ($this->rootURL == '/') ? '' : $this->rootURL;
-        
-        
+        if (empty($this->rootURL)) {
+            $this->rootURL = dirname($this->baseURL); 
+            $this->rootURL = ($this->rootURL == '/') ? '' : $this->rootURL;
+        }
+         
       
         //var_dump($this->baseURL);
         
@@ -276,8 +307,7 @@ class HTML_FlexyFramework {
         }
         
          $this->classPrefix   = str_replace('/', '_', $this->project) . '_';
-        
-        // list the available options..
+         // list the available options..
         if ($this->cli && empty($_SERVER['argv'][1])) {
             require_once 'HTML/FlexyFramework/Cli.php';
             $fcli = new HTML_FlexyFramework_Cli($this);
@@ -294,7 +324,7 @@ class HTML_FlexyFramework {
             $res = $fcli->parseDefaultOpts();
             if ($res === true) {
                 $ishelp = true;
-            } 
+            }
              
         }
         
@@ -322,7 +352,7 @@ class HTML_FlexyFramework {
         }
 
         $this->_validateDatabase();
+
         $this->_validateTemplate();
         
     }
@@ -341,22 +371,53 @@ class HTML_FlexyFramework {
             )
         ),
     */
-    function _handleLanguages()
+    
+    function _handleLanguages($request)
     {
         if (
-                empty($this->languages) ||
-                (
-                        !isset($this->languages['cookie']) && !isset($this->languages['default'])
-                )
+            empty($this->languages) ||
+            (
+                    !isset($this->languages['cookie']) && !isset($this->languages['default'])
+            )
         ) {
             return;
         }
         
-        
         $cfg = $this->languages;
+        
+        $default = $cfg['default'];
+        
+        if(!empty($_SERVER["HTTP_ACCEPT_LANGUAGE"])){
+            
+            $brower_langs = explode(",", $_SERVER["HTTP_ACCEPT_LANGUAGE"]);
+            
+            foreach ($brower_langs as $bl) {
+                $l = preg_replace('/;(.*)/', '', $bl);
+                
+                $l = str_replace('-', '_', $l);
+                
+                if(!in_array($l, $cfg['avail'])){
+                    continue;
+                }
+                
+                $default = $l;
+                break;
+            }
+        }
            
-        $lang = isset($_COOKIE[$cfg['cookie']]) ?  $_COOKIE[$cfg['cookie']] : $cfg['default'];
+        $lang = isset($_COOKIE[$cfg['cookie']]) ?  $_COOKIE[$cfg['cookie']] : $default;
 
+        // handle languages in request..
+        $bits = explode('/', $request);
+        $redirect_to = false;
+        if (count($bits) && in_array($bits[0],$cfg['avail'])) {
+            // redirect..
+            $lang = array_shift($bits);
+            $redirect_to = implode('/', $bits);
+        }
+        
+         
+        
         if (isset($_REQUEST[$cfg['param']])) {
             $lang = $_REQUEST[$cfg['param']];
         }
@@ -374,14 +435,45 @@ class HTML_FlexyFramework {
         if (!empty($this->HTML_Template_Flexy)) {
             $this->HTML_Template_Flexy['locale'] = $lang;   //set a language for template engine
         }
+        if ($redirect_to !== false) {
+            header('Location: ' . $this->rootURL . '/'.$redirect_to );
+            exit;
          
+        }
     }
     
+    function parseDefaultLanguage($http_accept, $deflang = "en") 
+    {
+        if(isset($http_accept) && strlen($http_accept) > 1)  {
+           # Split possible languages into array
+           $x = explode(",",$http_accept);
+           
+           foreach ($x as $val) {
+              #check for q-value and create associative array. No q-value means 1 by rule
+              if(preg_match("/(.*);q=([0-1]{0,1}.\d{0,4})/i",$val,$matches))
+                 $lang[$matches[1]] = (float)$matches[2];
+              else
+                 $lang[$val] = 1.0;
+           }
+           
+           #return default language (highest q-value)
+           $qval = 0.0;
+           foreach ($lang as $key => $value) {
+              if ($value > $qval) {
+                 $qval = (float)$value;
+                 $deflang = $key;
+              }
+           }
+        }
+        return strtolower($deflang);
+     }
+    
     /**
      * overlay array properties..
      */
     
-    function applyIf($prop, $ar) {
+    function applyIf($prop, $ar)
+    {
         if (!isset($this->$prop)) {
             $this->$prop = $ar;
             return;
@@ -412,7 +504,13 @@ class HTML_FlexyFramework {
     function _configDataObjectsCache()
     {
         // cli works under different users... it may cause problems..
+        
         $this->debug(__METHOD__);
+        
+        if ($this->database === false) {
+            return;
+        }
+        
         if (function_exists('posix_getpwuid')) {
             $uinfo = posix_getpwuid( posix_getuid () ); 
             $user = $uinfo['name'];
@@ -423,7 +521,7 @@ class HTML_FlexyFramework {
         
 
         $iniCache = ini_get('session.save_path') .'/' . 
-               'dbcfg-' . $user . '/'. str_replace('/', '_', $this->project) ;
+               'dbcfg-' . $user . '/'. str_replace('/', '_', $this->project);
         
         
         if ($this->appNameShort) {
@@ -432,9 +530,7 @@ class HTML_FlexyFramework {
         if ($this->version) {
             $iniCache .= '.' . $this->version;
         }
-        if ($this->database === false) {
-            return;
-        }
+       
         
         $dburl = parse_url($this->database);
         if (!empty($dburl['path'])) {
@@ -452,15 +548,14 @@ class HTML_FlexyFramework {
             $this->dataObjectsOriginalIni = $this->DB_DataObject[$dbini];
             ///print_r($this->DB_DataObject);exit;
         }
-        // 
-        
-        
-        
+          
+         
         $this->DB_DataObject[$dbini] =   $iniCache;
         // we now have the configuration file name..
         
         
         if (!file_exists($iniCache) || empty( $this->dataObjectsCacheExpires)) {
+            $this->debug(__METHOD__ . ':calling generate do cache');
             $this->generateDataobjectsCache(true);
             return;
         }
@@ -481,7 +576,7 @@ class HTML_FlexyFramework {
     {
         //$this->debug('generateDataobjectsCache: force=' . ($force ? 'yes' : 'no'));
         if (!$this->dataObjectsCache) { // does not use dataObjects Caching..
-            $this->debug('generateDataobjectsCache', 'dataObjectsCache - empty');
+            $this->debug('generateDataobjectsCachedataObjectsCache - empty');
             return;
         }
         
@@ -490,10 +585,18 @@ class HTML_FlexyFramework {
         
         
         $iniCache = $this->DB_DataObject[$dbini];
-        if ($force && file_exists($iniCache)) {
-            unlink($iniCache);
-            clearstatcache();
+        $this->debug('generateDataobjectsCache:' .dirname($iniCache).'/*.ini');
+        
+        $replace = array();
+        
+        if (file_exists($iniCache)) {
+            $files = glob(dirname($iniCache).'/*.ini');
+            foreach($files as $f) {
+                $replace[$f] = md5(file_get_contents($f)); // hash it..
+               
+            }
         }
+        $this->debug('generateDataobjectsCache: DONE ini delete');
         
         $iniCacheTmp = $iniCache . '.tmp' .md5(rand());  // random to stop two processes using the same file.
         // has it expired..
@@ -516,23 +619,33 @@ class HTML_FlexyFramework {
             $this->DB_DataObject['quote_identifiers_tableinfo'] = true;
         }
         if (!file_exists(dirname($iniCache))) {
-            mkdir(dirname($iniCache),0700, true);
+            if (!mkdir(dirname($iniCache),0700, true)) {
+                die("Failed to make cache directory : $iniCache\n");
+            }
         }
         
         $this->DB_DataObject[$dbini] = $iniCacheTmp;
-        $this->_exposeToPear();
         
+        $dl = DB_DataObject::DebugLevel();
+        $this->_exposeToPear(); // this will reset the debug level...
+        DB_DataObject::DebugLevel($dl);
         
+        $this->debug('generateDataobjectsCache: running generator');
         // DB_DataObject::debugLevel(1);      
         require_once 'HTML/FlexyFramework/Generator.php';
         $generator = new HTML_FlexyFramework_Generator();
         $generator->start();
-        
-        HTML_FlexyFramework_Generator::writeCache($iniCacheTmp, $iniCache); 
+        $this->debug('generateDataobjectsCache: done generator');
+
+        HTML_FlexyFramework_Generator::writeCache($iniCacheTmp, $iniCache, $replace); 
         // reset the cache to the correct lcoation.
         $this->DB_DataObject[$dbini] = $iniCache;
-        $this->_exposeToPear();
         
+         
+
+        $this->_exposeToPear();
+        DB_DataObject::DebugLevel($dl);
+
         //$GLOBALS['_DB_DATAOBJECT']['INI'][$this->database] =   parse_ini_file($iniCache, true);
         //$GLOBALS['_DB_DATAOBJECT']['SEQUENCE']
         // clear any dataobject cache..
@@ -556,7 +669,7 @@ class HTML_FlexyFramework {
         }
         $dburl = parse_url($this->database);
         $dbini = 'ini_'. basename($dburl['path']);
-                print_r($dbini);exit;
+                
         $dbinis =  array(); //array(dirname(__FILE__) . '/Pman/DataObjects/pman.ini');
         $dbreq =  array(); //array( dirname(__FILE__) . '/Pman/DataObjects/');
         $dbcls =  array(); //array('Pman_DataObjects_');
@@ -753,7 +866,7 @@ class HTML_FlexyFramework {
         /* have I been initialized */
         
         
-        if (get_magic_quotes_gpc() && !$this->cli) {
+        if (version_compare(PHP_VERSION, '7.0.0') < 0  && get_magic_quotes_gpc() && !$this->cli) {
             $this->fatalError(
                 "magic quotes is enabled add the line<BR>
                    php_value magic_quotes_gpc 0<BR>
@@ -798,9 +911,15 @@ class HTML_FlexyFramework {
         if (PEAR::isError($err = $x->getDatabaseConnection())) {
                                 
 
-                $this->fatalError("Configuration or Database Error: could not connect to Database, <BR>
-                    Please check the value given to HTML_FlexyFramework, or run with debug on!<BR>
-                     <BR> ".$err->toString());
+            $this->fatalError("Configuration or Database Error: could not connect to Database, <BR>
+                Please check the value given to HTML_FlexyFramework, or run with debug on!<BR>
+                 <BR> ".$err->toString());
+        }
+        $res = $err->query("SELECT @@global.read_only as ro");
+        
+        $row = is_a($res, 'DB_Error') ? false : $res->fetchRow(DB_FETCHMODE_ASSOC);
+        if (!$row || (!empty($row['ro']) && empty($options['skip-read-only-check']))) {
+            $this->fatalError("Database is configured to be read-only - please check database<BR> ".$err->toString());
         }
         // reset dont die!
         $options['dont_die'] = $dd ;
@@ -904,6 +1023,7 @@ class HTML_FlexyFramework {
         
         $newRequest = $this->_getRequest($request,$isRedirect);
         
+         
         // find the class/file to load
         list($classname,$subRequest) = $this->requestToClassName($newRequest,FALSE);
         
@@ -928,6 +1048,7 @@ class HTML_FlexyFramework {
         $classobj->bootLoader  = $this;
         $classobj->request = $newRequest;
         $classobj->timer = &$this->timer;
+        $classobj->cli = $this->cli;
         
         $this->page = $classobj;
         if ($this->cli && !$isRedirect ) { // redirect always just takes redirect args..
@@ -940,6 +1061,7 @@ class HTML_FlexyFramework {
         
         // echo '<PRE>'; print_r($this);exit;
         // echo "CHECK GET AUTH?";
+
         if (!method_exists($classobj, 'getAuth')) {
         //    echo "NO GET AUTH?";
             $this->fatalError("class $classname does not have a getAuth Method");
@@ -967,6 +1089,7 @@ class HTML_FlexyFramework {
                 return $result;
             }
         }
+                    
         /* allow redirect from start */
         if (method_exists($classobj,"start")) {
             if (is_string($redirect = $classobj->start($subRequest,$isRedirect,$args)))  {
@@ -1030,27 +1153,43 @@ class HTML_FlexyFramework {
     function _getRequest($request, $isRedirect) 
     {
         
-        
-        
+         
         if ($this->cli) {
             return $request;
         }
         
         $startRequest = $request;
-        $request =@ array_shift(explode('?', $request));
+        $ra = explode('?', $request);
+        $request =  array_shift($ra);
         $this->debug("INPUT REQUEST $request<BR>");
         if (!$isRedirect) {
             // check that request forms contains baseurl????
+            if (!empty($_SERVER['REDIRECT_STATUS'])  && !empty($_SERVER['REDIRECT_URL'])) {
+               // phpinfo();exit;
+                $sn = $_SERVER['SCRIPT_NAME'];
+                $sublen = strlen(substr($sn , 0,  strlen($sn) - strlen(basename($sn)) -1 ));
+                 //var_dump(array($sn,$subdir,basename($sn)));exit;
+                $subreq =  $_SERVER['SCRIPT_NAME'];
+                $request = substr($_SERVER['REDIRECT_URL'],$sublen);
+                
+                 
+            } else {
+                  
              
-            $subreq = substr($request,0,strlen($this->baseURL));
-            if ($subreq != substr($this->baseURL,0,strlen($subreq))) {
-                $this->fatalError(
-                    "Configuration error: Got base of $subreq which does not 
-                        match configuration of: $this->baseURL} ");
+                $subreq = substr($request,0, strlen($this->baseURL));
+                if ($subreq != substr($this->baseURL,0,strlen($subreq))) {
+                    $this->fatalError(
+                        "Configuration error: Got base of $subreq which does not 
+                            match configuration of: $this->baseURL} ");
+                }
+                $request = substr($request,strlen($this->baseURL));
+                
             }
-            $request = substr($request,strlen($this->baseURL));
+            
              
         }
+       // var_Dump(array('req'=>$request,'subreq'=>$subreq));
+        
         // strip front
         // echo "REQUEST WAS: $request<BR>";
         // $request = preg_replace('/^'.preg_quote($base_url,'/').'/','',trim($request));
@@ -1089,7 +1228,13 @@ class HTML_FlexyFramework {
             }
             $request = "";
         }
+       // var_dump(array($startRequest,$request, $this->baseRequest));
+        
         $this->debug("OUTPUT REQUEST $request<BR>");
+        
+        $this->_handleLanguages($request);
+
+        
         return $request;
     }
     
@@ -1126,7 +1271,7 @@ class HTML_FlexyFramework {
         }
         
         
-        $request_array=explode("/",$request);
+        $request_array = explode("/",$request);
         $original_request_array = $request_array;
         $sub_request_array = array();
         $l = count($request_array)-1;
@@ -1290,7 +1435,8 @@ class HTML_FlexyFramework {
             return true;
         }
         // file exists, but process might not be the same..
-        $name = array_pop(explode('_', get_class($class)));
+        $ea = explode('_', get_class($class));
+        $name = array_pop($ea);
         $cmd = file_get_contents('/proc/' . $oldpid.'/cmdline');
         if (!preg_match('/php/i',$cmd) || !preg_match('/'.$name.'/i',$cmd)) {
             file_put_contents($lock, getmypid());
@@ -1364,7 +1510,9 @@ class HTML_FlexyFramework {
             HTML_FlexyFramework::run($this->fatalAction,$msg);
             exit;
         }
-        
+        header('HTTP/1.1 503 Service Temporarily Unavailable');
+        header('Status: 503 Service Temporarily Unavailable');
+        header('Retry-After: 300');
         echo $this->cli ? $msg ."\n" : "<H1>$msg</H1>configuration information<PRE>";
         if ($showConfig) {