developer.jelix.org is not used any more and exists only for history. Post new tickets on the Github account.
developer.jelix.org n'est plus utilisée, et existe uniquement pour son historique. Postez les nouveaux tickets sur le compte github.

Ticket #732: module_mgr.patch

File module_mgr.patch, 213.6 KB (added by foxmask, 13 years ago)

one patch to deal with jelix installation process

  • clearbricks/common/_main.php

     
     1<?php
     2# ***** BEGIN LICENSE BLOCK *****
     3# This file is part of Clearbricks.
     4# Copyright (c) 2006 Olivier Meunier and contributors.
     5# All rights reserved.
     6#
     7# Clearbricks is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# Clearbricks is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with Clearbricks; if not, write to the Free Software
     19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     20#
     21# ***** END LICENSE BLOCK *****
     22/**
     23@defgroup CLEARBRICKS Clearbricks classes
     24*/
     25
     26define('CLEARBRICKS_VERSION','0.8');
     27
     28# Autoload
     29$__autoload = array(
     30        'crypt'                 => dirname(__FILE__).'/lib.crypt.php',
     31        'dt'                            => dirname(__FILE__).'/lib.date.php',
     32        'files'                 => dirname(__FILE__).'/lib.files.php',
     33        'path'                  => dirname(__FILE__).'/lib.files.php',
     34        'form'                  => dirname(__FILE__).'/lib.form.php',
     35        'formSelectOption'      => dirname(__FILE__).'/lib.form.php',
     36        'html'                  => dirname(__FILE__).'/lib.html.php',
     37        'http'                  => dirname(__FILE__).'/lib.http.php',
     38        'text'                  => dirname(__FILE__).'/lib.text.php'
     39);
     40
     41# autoload for clearbricks
     42function cb_autoload($name)
     43{
     44        global $__autoload;
     45       
     46        if (isset($__autoload[$name])) {
     47                require_once $__autoload[$name];
     48        }
     49}
     50
     51# if php version >= 5.1.2, we can benefit from spl_autoload_register,
     52# so other libraries can define their own independent autoload too
     53if (function_exists("spl_autoload_register")) {
     54        spl_autoload_register("cb_autoload");
     55} else {
     56        # otherwise we define a classic autoload function for older php...
     57        function __autoload($name) {
     58                cb_autoload($name);
     59        }
     60}
     61
     62# We only need l10n __() function
     63require_once dirname(__FILE__).'/lib.l10n.php';
     64
     65# We set default timezone to avoid warning
     66dt::setTZ('UTC');
     67?>
     68 No newline at end of file
  • clearbricks/common/lib.crypt.php

     
     1<?php
     2# ***** BEGIN LICENSE BLOCK *****
     3# This file is part of Clearbricks.
     4# Copyright (c) 2006 Olivier Meunier and contributors. All rights
     5# reserved.
     6#
     7# Clearbricks is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# Clearbricks is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with Clearbricks; if not, write to the Free Software
     19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     20#
     21# ***** END LICENSE BLOCK *****
     22
     23/**
     24@ingroup CLEARBRICKS
     25@brief Crypt and password helper functions.
     26*/
     27class crypt
     28{
     29        /**
     30        Returns an HMAC encoded value of <var>$data</var>, using the said <var>$key</var>
     31        and <var>$hashfunc</var> as hash method (sha1 or md5 are accepted.)
     32       
     33        @param  key             <b>string</b>           Hash key
     34        @param  data            <b>string</b>           Data
     35        @param  hashfunc        <b>string</b>           Hash function (md5 or sha1)
     36        @return <b>string</b>
     37        */
     38        public static function hmac($key,$data,$hashfunc='sha1')
     39        {
     40                $blocksize=64;
     41                if ($hashfunc != 'sha1') {
     42                        $hashfunc = 'md5';
     43                }
     44               
     45                if (strlen($key)>$blocksize) {
     46                        $key=pack('H*', $hashfunc($key));
     47                }
     48               
     49                $key=str_pad($key,$blocksize,chr(0x00));
     50                $ipad=str_repeat(chr(0x36),$blocksize);
     51                $opad=str_repeat(chr(0x5c),$blocksize);
     52                $hmac = pack('H*',$hashfunc(($key^$opad).pack('H*',$hashfunc(($key^$ipad).$data))));
     53                return bin2hex($hmac);
     54        }
     55       
     56        /**
     57        Returns an 8 characters random password.
     58       
     59        @return <b>string</b>
     60        */
     61        public static function createPassword()
     62        {
     63                $pwd = array();
     64                $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
     65                $chars2 = '$!@';
     66               
     67                foreach (range(0,8) as $i) {
     68                        $pwd[] = $chars[rand(0,strlen($chars)-1)];
     69                }
     70               
     71                $pos1 = array_rand(array(0,1,2,3));
     72                $pos2 = array_rand(array(4,5,6,7));
     73                $pwd[$pos1] = $chars2[rand(0,strlen($chars2)-1)];
     74                $pwd[$pos2] = $chars2[rand(0,strlen($chars2)-1)];
     75               
     76                return implode('',$pwd);
     77        }
     78}
     79?>
     80 No newline at end of file
  • clearbricks/common/lib.date.php

     
     1<?php
     2# ***** BEGIN LICENSE BLOCK *****
     3# This file is part of Clearbricks.
     4# Copyright (c) 2006 Olivier Meunier and contributors. All rights
     5# reserved.
     6#
     7# Clearbricks is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# Clearbricks is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with Clearbricks; if not, write to the Free Software
     19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     20#
     21# ***** END LICENSE BLOCK *****
     22
     23class dt
     24{
     25        public static function str($p,$ts=null,$tz=null)
     26        {
     27                if ($ts === null) { $ts = time(); }
     28               
     29                $hash = '799b4e471dc78154865706469d23d512';
     30                $p = preg_replace('/(?<!%)%(a|A)/','{{'.$hash.'__$1%w__}}',$p);
     31                $p = preg_replace('/(?<!%)%(b|B)/','{{'.$hash.'__$1%m__}}',$p);
     32               
     33                if ($tz) {
     34                        $T = self::getTZ();
     35                        self::setTZ($tz);
     36                }
     37               
     38                $res = strftime($p,$ts);
     39               
     40                if ($tz) {
     41                        self::setTZ($T);
     42                }
     43               
     44                $res = preg_replace_callback('/{{'.$hash.'__(a|A|b|B)([0-9]{1,2})__}}/',array('self','_callback'),$res);
     45               
     46                return $res;
     47        }
     48       
     49        public static function dt2str($p,$dt,$tz=null)
     50        {
     51                return dt::str($p,strtotime($dt),$tz);
     52        }
     53       
     54        public static function iso8601($ts,$tz='UTC')
     55        {
     56                $o = self::getTimeOffset($tz,$ts);
     57                $of = sprintf('%02u:%02u',abs($o)/3600,(abs($o)%3600)/60);
     58                return date('Y-m-d\\TH:i:s',$ts).($o < 0 ? '-' : '+').$of;
     59        }
     60       
     61        public static function rfc822($ts,$tz='UTC')
     62        {
     63                # Get offset
     64                $o = self::getTimeOffset($tz,$ts);
     65                $of = sprintf('%02u%02u',abs($o)/3600,(abs($o)%3600)/60);
     66                return strftime('%a, %d %b %Y %H:%M:%S '.($o < 0 ? '-' : '+').$of,$ts);
     67        }
     68       
     69        public static function setTZ($tz)
     70        {
     71                if (function_exists('date_default_timezone_set')) {
     72                        date_default_timezone_set($tz);
     73                        return;
     74                }
     75               
     76                if (!ini_get('safe_mode')) {
     77                        putenv('TZ='.$tz);
     78                }
     79        }
     80
     81        public static function getTZ()
     82        {
     83                if (function_exists('date_default_timezone_get')) {
     84                        return date_default_timezone_get();
     85                }
     86
     87                return date('T');
     88        }
     89       
     90        public static function getTimeOffset($utc_tz,$ts=false)
     91        {
     92                if (!$ts) {
     93                        $ts = time();
     94                }
     95               
     96                $server_tz = self::getTZ();
     97                $server_offset = date('Z',$ts);
     98               
     99                self::setTZ($utc_tz);
     100                $cur_offset = date('Z',$ts);
     101               
     102                self::setTZ($server_tz);
     103               
     104                return $cur_offset-$server_offset;
     105        }
     106       
     107        public static function toUTC($ts)
     108        {
     109                return $ts + self::getTimeOffset('UTC',$ts);
     110        }
     111       
     112        public static function addTimeZone($tz,$ts=false)
     113        {
     114                if (!$ts) {
     115                        $ts = time();
     116                }
     117               
     118                return $ts + self::getTimeOffset($tz,$ts);
     119        }
     120       
     121        public static function getZones($flip=false,$groups=false)
     122        {
     123                if (!is_readable($f = dirname(__FILE__).'/tz.dat')) {
     124                        return array();
     125                }
     126               
     127                $tz =  file(dirname(__FILE__).'/tz.dat');
     128               
     129                $res = array();
     130               
     131                foreach ($tz as $v)
     132                {
     133                        $v = trim($v);
     134                        if ($v) {
     135                                $res[$v] = str_replace('_',' ',$v);
     136                        }
     137                }
     138               
     139                if ($flip) {
     140                        $res = array_flip($res);
     141                        if ($groups) {
     142                                $tmp = array();
     143                                foreach ($res as $k => $v) {
     144                                        $g = explode('/',$k);
     145                                        $tmp[$g[0]][$k] = $v;
     146                                }
     147                                $res = $tmp;
     148                        }
     149                }
     150               
     151                return $res;
     152        }
     153       
     154        private static function _callback($args)
     155        {
     156                $b = array(1=>'_Jan',2=>'_Feb',3=>'_Mar',4=>'_Apr',5=>'_May',6=>'_Jun',
     157                7=>'_Jul',8=>'_Aug',9=>'_Sep',10=>'_Oct',11=>'_Nov',12=>'_Dec');
     158               
     159                $B = array(1=>'January',2=>'February',3=>'March',4=>'April',
     160                5=>'May',6=>'June',7=>'July',8=>'August',9=>'September',
     161                10=>'October',11=>'November',12=>'December');
     162               
     163                $a = array(1=>'_Mon',2=>'_Tue',3=>'_Wed',4=>'_Thu',5=>'_Fri',
     164                6=>'_Sat',0=>'_Sun');
     165               
     166                $A = array(1=>'Monday',2=>'Tuesday',3=>'Wednesday',4=>'Thursday',
     167                5=>'Friday',6=>'Saturday',0=>'Sunday');
     168               
     169                return __(${$args[1]}[(integer) $args[2]]);
     170        }
     171}
     172?>
     173 No newline at end of file
  • clearbricks/common/lib.files.php

     
     1<?php
     2# ***** BEGIN LICENSE BLOCK *****
     3# This file is part of Clearbricks.
     4# Copyright (c) 2006 Olivier Meunier and contributors. All rights
     5# reserved.
     6#
     7# Clearbricks is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# Clearbricks is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with Clearbricks; if not, write to the Free Software
     19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     20#
     21# ***** END LICENSE BLOCK *****
     22
     23class files
     24{
     25        # Default
     26        public static $dir_mode = null;
     27       
     28        # Supported MIME types
     29        public static $mimeType = array(
     30                        'odt'   => 'application/vnd.oasis.opendocument.text',
     31                        'odp'   => 'application/vnd.oasis.opendocument.presentation',
     32                        'ods'   => 'application/vnd.oasis.opendocument.spreadsheet',
     33                       
     34                        'sxw'   => 'application/vnd.sun.xml.writer',
     35                        'sxc'   => 'application/vnd.sun.xml.calc',
     36                        'sxi'   => 'application/vnd.sun.xml.impress',
     37                       
     38                        'ppt'   => 'application/mspowerpoint',
     39                        'doc'   => 'application/msword',
     40                        'xls'   => 'application/msexcel',                       
     41                        'rtf'   => 'application/rtf',
     42                       
     43                        'pdf'   => 'application/pdf',
     44                        'ps'            => 'application/postscript',
     45                        'ai'            => 'application/postscript',
     46                        'eps'   => 'application/postscript',
     47                       
     48                        'bin'   => 'application/octet-stream',
     49                        'exe'   => 'application/octet-stream',
     50                       
     51                        'deb'   => 'application/x-debian-package',
     52                        'gz'            => 'application/x-gzip',
     53                        'jar'   => 'application/x-java-archive',
     54                        'rar'   => 'application/rar',
     55                        'rpm'   => 'application/x-redhat-package-manager',
     56                        'tar'   => 'application/x-tar',
     57                        'tgz'   => 'application/x-gtar',
     58                        'zip'   => 'application/zip',
     59                       
     60                        'aiff'  => 'audio/x-aiff',
     61                        'ua'            => 'audio/basic',
     62                        'mp3'   => 'audio/mpeg3',
     63                        'mid'   => 'audio/x-midi',
     64                        'midi'  => 'audio/x-midi',
     65                        'ogg'   => 'application/ogg',
     66                        'wav'   => 'audio/x-wav',
     67                       
     68                        'swf'   => 'application/x-shockwave-flash',
     69                        'swfl'  => 'application/x-shockwave-flash',
     70                       
     71                        'bmp'   => 'image/bmp',
     72                        'gif'   => 'image/gif',
     73                        'jpeg'  => 'image/jpeg',
     74                        'jpg'   => 'image/jpeg',
     75                        'jpe'   => 'image/jpeg',
     76                        'png'   => 'image/png',
     77                        'tiff'  => 'image/tiff',
     78                        'tif'   => 'image/tiff',
     79                        'xbm'   => 'image/x-xbitmap',
     80                       
     81                        'css'   => 'text/css',
     82                        'js'            => 'text/javascript',
     83                        'html'  => 'text/html',
     84                        'htm'   => 'text/html',
     85                        'txt'   => 'text/plain',
     86                        'rtf'   => 'text/richtext',
     87                        'rtx'   => 'text/richtext',
     88                       
     89                        'mpg'   => 'video/mpeg',
     90                        'mpeg'  => 'video/mpeg',
     91                        'mpe'   => 'video/mpeg',
     92                        'viv'   => 'video/vnd.vivo',
     93                        'vivo'  => 'video/vnd.vivo',
     94                        'qt'            => 'video/quicktime',
     95                        'mov'   => 'video/quicktime',
     96                        'flv'   => 'video/x-flv',
     97                        'avi'   => 'video/x-msvideo'
     98                );
     99       
     100        public static function scandir($d,$order=0)
     101        {
     102                $res = array();
     103                $dh = @opendir($d);
     104               
     105                if ($dh === false) {
     106                        throw new Exception(__('Unable to open directory.'));
     107                }
     108               
     109                while (($f = readdir($dh)) !== false) {
     110                        $res[] = $f;
     111                }
     112                closedir($dh);
     113               
     114                sort($res);
     115                if ($order == 1) {
     116                        rsort($res);
     117                }
     118               
     119                return $res;
     120        }
     121       
     122        public static function getExtension($f)
     123        {
     124                $f = explode('.',basename($f));
     125               
     126                if (count($f) <= 1) { return ''; }
     127               
     128                return strtolower($f[count($f)-1]);
     129        }
     130       
     131        public static function getMimeType($f)
     132        {
     133                $ext = self::getExtension($f);
     134                $types = self::mimeTypes();
     135               
     136                if (isset($types[$ext])) {
     137                        return $types[$ext];
     138                } else {
     139                        return 'text/plain';
     140                }
     141        }
     142       
     143        public static function mimeTypes()
     144        {
     145                return self::$mimeType;
     146        }
     147       
     148        public static function registerMimeTypes($tab)
     149        {
     150                self::$mimeType = array_merge(self::$mimeType, $tab);
     151        }
     152       
     153        public static function isDeletable($f)
     154        {
     155                if (is_file($f)) {
     156                        return is_writable(dirname($f));
     157                } elseif (is_dir($f)) {
     158                        return (is_writable(dirname($f)) && count(files::scandir($f)) <= 2);
     159                }
     160        }
     161       
     162        # Recusive remove (rm -rf)
     163        public static function deltree($dir)
     164        {
     165                $current_dir = opendir($dir);
     166                while($entryname = readdir($current_dir))
     167                {
     168                        if (is_dir($dir.'/'.$entryname) and ($entryname != '.' and $entryname!='..'))
     169                        {
     170                                if (!files::deltree($dir.'/'.$entryname)) {
     171                                        return false;
     172                                }
     173                        }
     174                        elseif ($entryname != '.' and $entryname!='..')
     175                        {
     176                                if (!@unlink($dir.'/'.$entryname)) {
     177                                        return false;
     178                                }
     179                        }
     180                }
     181                closedir($current_dir);
     182                return @rmdir($dir);
     183        }
     184       
     185        public static function touch($f)
     186        {
     187                if (is_writable($f)) {
     188                        if (function_exists('touch')) {
     189                                @touch($f);
     190                        } else {
     191                                # Very bad hack
     192                                @file_put_contents($f,file_get_contents($f));
     193                        }
     194                }
     195        }
     196       
     197        public static function makeDir($f,$r=false)
     198        {
     199                if (empty($f)) {
     200                        return;
     201                }
     202               
     203                if (DIRECTORY_SEPARATOR == '\\') {
     204                        $f = str_replace('/','\\',$f);
     205                }
     206               
     207                if (is_dir($f)) {
     208                        return;
     209                }
     210               
     211                if ($r)
     212                {
     213                        $dir = path::real($f,false);
     214                        $dirs = array();
     215                       
     216                        while (!is_dir($dir)) {
     217                                array_unshift($dirs,basename($dir));
     218                                $dir = dirname($dir);
     219                        }
     220                       
     221                        foreach ($dirs as $d)
     222                        {
     223                                $dir .= DIRECTORY_SEPARATOR.$d;
     224                                if ($d != '' && !is_dir($dir)) {
     225                                        self::makeDir($dir);
     226                                }
     227                        }
     228                }
     229                else
     230                {
     231                        if (@mkdir($f) === false) {
     232                                throw new Exception(__('Unable to create directory.'));
     233                        }
     234                        self::inheritChmod($f);
     235                }
     236        }
     237       
     238        public static function inheritChmod($file)
     239        {
     240                if (!function_exists('fileperms') || !function_exists('chmod')) {
     241                        return false;
     242                }
     243               
     244                if (self::$dir_mode != null) {
     245                        return chmod($file,self::$dir_mode);
     246                } else {
     247                        return chmod($file,fileperms(dirname($file)));
     248                }
     249        }
     250       
     251        public static function putContent($f, $f_content)
     252        {
     253                if (file_exists($f) && !is_writable($f)) {     
     254                        throw new Exception(__('File is not writable.'));
     255                }
     256               
     257                $fp = @fopen($f, 'w');
     258               
     259                if ($fp === false) {
     260                        throw new Exception(__('Unable to open file.'));
     261                }
     262               
     263                fwrite($fp,$f_content,strlen($f_content));
     264                fclose($fp);
     265                return true;
     266        }
     267       
     268        public static function size($size)
     269        {
     270                $kb = 1024;
     271                $mb = 1024 * $kb;
     272                $gb = 1024 * $mb;
     273                $tb = 1024 * $gb;
     274               
     275                if($size < $kb) {
     276                        return $size." B";
     277                }
     278                else if($size < $mb) {
     279                        return round($size/$kb,2)." KB";
     280                }
     281                else if($size < $gb) {
     282                        return round($size/$mb,2)." MB";
     283                }
     284                else if($size < $tb) {
     285                        return round($size/$gb,2)." GB";
     286                }
     287                else {
     288                        return round($size/$tb,2)." TB";
     289                }
     290        }
     291       
     292        public static function str2bytes($v)
     293        {
     294                $v = trim($v);
     295                $last = strtolower(substr($v,-1,1));
     296               
     297                switch($last)
     298                {
     299                        case 'g':
     300                                $v *= 1024;
     301                        case 'm':
     302                                $v *= 1024;
     303                        case 'k':
     304                                $v *= 1024;
     305                }
     306               
     307                return $v;
     308        }
     309       
     310        public static function uploadStatus($file)
     311        {
     312                if (!isset($file['error'])) {
     313                        throw new Exception(__('Not an uploaded file.'));
     314                }
     315               
     316                switch ($file['error']) {
     317                        case UPLOAD_ERR_OK:
     318                                return true;
     319                        case UPLOAD_ERR_INI_SIZE:
     320                        case UPLOAD_ERR_FORM_SIZE:
     321                                throw new Exception(__('The uploaded file exceeds the maximum file size allowed.'));
     322                                return false;
     323                        case UPLOAD_ERR_PARTIAL:
     324                                throw new Exception(__('The uploaded file was only partially uploaded.'));
     325                                return false;
     326                        case UPLOAD_ERR_NO_FILE:
     327                                throw new Exception(__('No file was uploaded.'));
     328                                return false;
     329                        case UPLOAD_ERR_NO_TMP_DIR:
     330                                throw new Exception(__('Missing a temporary folder.'));
     331                                return false;
     332                        case UPLOAD_ERR_CANT_WRITE:
     333                                throw new Exception(__('Failed to write file to disk.'));
     334                                return false;
     335                        default:
     336                                return true;
     337                }
     338        }
     339       
     340        # Packages generation methods
     341        #
     342        public static function getDirList($dirName, &$contents = null)
     343        {
     344                if (!$contents) {
     345                        $contents = array('dirs'=> array(),'files' => array());
     346                }                       
     347               
     348                $exclude_list=array('.','..','.svn');
     349               
     350                if (empty($res)) {
     351                        $res = array();
     352                }
     353               
     354                $dirName = preg_replace('|/$|','',$dirName);
     355               
     356                if (!is_dir($dirName)) {
     357                        throw new Exception(sprintf(__('%s is not a directory.'),$dirName));
     358                }
     359               
     360                $contents['dirs'][] = $dirName;
     361               
     362                $d = @dir($dirName);
     363               
     364                if ($d === false) {
     365                        throw new Exception(__('Unable to open directory.'));
     366                }
     367               
     368                while($entry = $d->read())
     369                {
     370                        if (!in_array($entry,$exclude_list))
     371                        {
     372                                if (is_dir($dirName.'/'.$entry))
     373                                {
     374                                        files::getDirList($dirName.'/'.$entry, $contents);
     375                                }
     376                                else
     377                                {
     378                                        $contents['files'][] = $dirName.'/'.$entry;
     379                                }
     380                        }
     381                }
     382                $d->close();
     383               
     384                return $contents;
     385        }
     386       
     387        public static function tidyFileName($n)
     388        {
     389                $n = text::deaccent($n);
     390                $n = preg_replace('/^[.]/u','',$n);
     391                return preg_replace('/[^A-Za-z0-9._-]/u','_',$n);
     392        }
     393}
     394
     395
     396class path
     397{
     398        public static function real($p,$strict=true)
     399        {
     400                $os = (DIRECTORY_SEPARATOR == '\\') ? 'win' : 'nix';
     401               
     402                # Absolute path?
     403                if ($os == 'win') {
     404                        $_abs = preg_match('/^\w+:/',$p);
     405                } else {
     406                        $_abs = substr($p,0,1) == '/';
     407                }
     408               
     409                # Standard path form
     410                if ($os == 'win') {
     411                        $p = str_replace('\\','/',$p);
     412                }
     413               
     414                # Adding root if !$_abs
     415                if (!$_abs) {
     416                        $p = dirname($_SERVER['SCRIPT_FILENAME']).'/'.$p;
     417                }
     418               
     419                # Clean up
     420                $p = preg_replace('|/+|','/',$p);
     421               
     422                if (strlen($p) > 1) {
     423                        $p = preg_replace('|/$|','',$p);
     424                }
     425               
     426                $_start = '';
     427                if ($os == 'win') {
     428                        list($_start,$p) = explode(':',$p);
     429                        $_start .= ':/';
     430                } else {
     431                        $_start = '/';
     432                }
     433                $p = substr($p,1);
     434               
     435                # Go through
     436                $P = explode('/',$p);
     437                $res = array();
     438               
     439                for ($i=0;$i<count($P);$i++)
     440                {
     441                        if ($P[$i] == '.') {
     442                                continue;
     443                        }
     444                       
     445                        if ($P[$i] == '..') {
     446                                if (count($res) > 0) {
     447                                        array_pop($res);
     448                                }
     449                        } else {
     450                                array_push($res,$P[$i]);
     451                        }
     452                }
     453               
     454                $p = $_start.implode('/',$res);
     455               
     456                if ($strict && !@file_exists($p)) {
     457                        return false;
     458                }
     459               
     460                return $p;
     461        }
     462       
     463        public static function clean($p)
     464        {
     465                $p = str_replace('..','',$p);
     466                $p = preg_replace('|/{2,}|','/',$p);
     467                $p = preg_replace('|/$|','',$p);
     468               
     469                return $p;
     470        }
     471       
     472        public static function info($f)
     473        {
     474                $p = pathinfo($f);
     475                $res = array();
     476               
     477                $res['dirname'] = $p['dirname'];
     478                $res['basename'] = $p['basename'];
     479                $res['extension'] = isset($p['extension']) ? $p['extension'] : '';
     480                $res['base'] = preg_replace('/\.'.preg_quote($res['extension'],'/').'$/','',$res['basename']);
     481               
     482                return $res;
     483        }
     484       
     485        public static function fullFromRoot($p,$root)
     486        {
     487                if (substr($p,0,1) == '/') {
     488                        return $p;
     489                }
     490               
     491                return $root.'/'.$p;
     492        }
     493}
     494?>
     495 No newline at end of file
  • clearbricks/common/lib.form.php

     
     1<?php
     2# ***** BEGIN LICENSE BLOCK *****
     3# This file is part of Clearbricks.
     4# Copyright (c) 2006 Olivier Meunier and contributors. All rights
     5# reserved.
     6#
     7# Clearbricks is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# Clearbricks is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with Clearbricks; if not, write to the Free Software
     19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     20#
     21# ***** END LICENSE BLOCK *****
     22
     23class form
     24{
     25        private static function getNameAndId($nid,&$name,&$id)
     26        {
     27                if (is_array($nid)) {
     28                        $name = $nid[0];
     29                        $id = !empty($nid[1]) ? $nid[1] : null;
     30                } else {
     31                        $name = $id = $nid;
     32                }
     33        }
     34       
     35        public static function combo($nid, $data ,$default='', $class='', $tabindex='',
     36        $disabled=false, $extra_html='')
     37        {
     38                self::getNameAndId($nid,$name,$id);
     39               
     40                $res = '<select name="'.$name.'" ';
     41               
     42                $res .= $id ? 'id="'.$id.'" ' : '';
     43                $res .= $class ? 'class="'.$class.'" ' : '';
     44                $res .= $tabindex ? 'tabindex="'.$tabindex.'" ' : '';
     45                $res .= $disabled ? 'disabled="disabled" ' : '';
     46                $res .= $extra_html;
     47               
     48                $res .= '>'."\n";
     49               
     50                $res .= self::comboOptions($data,$default);
     51               
     52                $res .= '</select>'."\n";
     53               
     54                return $res;
     55        }
     56       
     57        private static function comboOptions($data,$default)
     58        {
     59                $res = '';
     60                $option = '<option value="%1$s"%3$s>%2$s</option>'."\n";
     61                $optgroup = '<optgroup label="%1$s">'."\n".'%2$s'."</optgroup>\n";
     62               
     63                foreach($data as $k => $v)
     64                {
     65                        if (is_array($v)) {
     66                                $res .= sprintf($optgroup,$k,self::comboOptions($v,$default));
     67                        } elseif ($v instanceof formSelectOption) {
     68                                $res .= $v->render($default);
     69                        } else {
     70                                $s = ($v == $default) ? ' selected="selected"' : '';
     71                                $res .= sprintf($option,$v,$k,$s);
     72                        }
     73                }
     74               
     75                return $res;
     76        }
     77       
     78        public static function radio($nid, $value, $checked='', $class='', $tabindex='',
     79        $disabled=false, $extra_html='')
     80        {
     81                self::getNameAndId($nid,$name,$id);
     82               
     83                $res = '<input type="radio" name="'.$name.'" value="'.$value.'" ';
     84               
     85                $res .= $id ? 'id="'.$id.'" ' : '';
     86                $res .= $checked ? 'checked="checked" ' : '';
     87                $res .= $class ? 'class="'.$class.'" ' : '';
     88                $res .= $tabindex ? 'tabindex="'.$tabindex.'" ' : '';
     89                $res .= $disabled ? 'disabled="disabled" ' : '';
     90                $res .= $extra_html;
     91               
     92                $res .= '/>'."\n";
     93               
     94                return $res;   
     95        }
     96
     97        public static function checkbox($nid, $value, $checked='', $class='', $tabindex='',
     98        $disabled=false, $extra_html='')
     99        {
     100                self::getNameAndId($nid,$name,$id);
     101               
     102                $res = '<input type="checkbox" name="'.$name.'" value="'.$value.'" ';
     103               
     104                $res .= $id ? 'id="'.$id.'" ' : '';
     105                $res .= $checked ? 'checked="checked" ' : '';
     106                $res .= $class ? 'class="'.$class.'" ' : '';
     107                $res .= $tabindex ? 'tabindex="'.$tabindex.'" ' : '';
     108                $res .= $disabled ? 'disabled="disabled" ' : '';
     109                $res .= $extra_html;
     110               
     111                $res .= ' />'."\n";
     112
     113                return $res;
     114        }
     115
     116        public static function field($nid, $size, $max, $default='', $class='', $tabindex='',
     117        $disabled=false, $extra_html='')
     118        {
     119                self::getNameAndId($nid,$name,$id);
     120               
     121                $res = '<input type="text" size="'.$size.'" name="'.$name.'" ';
     122               
     123                $res .= $id ? 'id="'.$id.'" ' : '';
     124                $res .= $max ? 'maxlength="'.$max.'" ' : '';
     125                $res .= $default || $default === '0' ? 'value="'.$default.'" ' : '';
     126                $res .= $class ? 'class="'.$class.'" ' : '';
     127                $res .= $tabindex ? 'tabindex="'.$tabindex.'" ' : '';
     128                $res .= $disabled ? 'disabled="disabled" ' : '';
     129                $res .= $extra_html;
     130               
     131                $res .= ' />';
     132               
     133                return $res;
     134        }
     135       
     136        public static function password($nid, $size, $max, $default='', $class='', $tabindex='',
     137        $disabled=false, $extra_html='')
     138        {
     139                self::getNameAndId($nid,$name,$id);
     140               
     141                $res = '<input type="password" size="'.$size.'" name="'.$name.'" ';
     142               
     143                $res .= $id ? 'id="'.$id.'" ' : '';
     144                $res .= $max ? 'maxlength="'.$max.'" ' : '';
     145                $res .= $default || $default === '0' ? 'value="'.$default.'" ' : '';
     146                $res .= $class ? 'class="'.$class.'" ' : '';
     147                $res .= $tabindex ? 'tabindex="'.$tabindex.'" ' : '';
     148                $res .= $disabled ? 'disabled="disabled" ' : '';
     149                $res .= $extra_html;
     150               
     151                $res .= ' />';
     152               
     153                return $res;
     154        }
     155       
     156        public static function textArea($nid, $cols, $rows, $default='', $class='',
     157        $tabindex='', $disabled=false, $extra_html='')
     158        {
     159                self::getNameAndId($nid,$name,$id);
     160               
     161                $res = '<textarea cols="'.$cols.'" rows="'.$rows.'" ';
     162                $res .= 'name="'.$name.'" ';
     163                $res .= $id ? 'id="'.$id.'" ' : '';
     164                $res .= ($tabindex != '') ? 'tabindex="'.$tabindex.'" ' : '';
     165                $res .= $class ? 'class="'.$class.'" ' : '';
     166                $res .= $disabled ? 'disabled="disabled" ' : '';
     167                $res .= $extra_html.'>';
     168                $res .= $default;
     169                $res .= '</textarea>';
     170               
     171                return $res;
     172        }
     173       
     174        public static function hidden($nid,$value)
     175        {
     176                self::getNameAndId($nid,$name,$id);
     177               
     178                $res = '<input type="hidden" name="'.$name.'" value="'.$value.'" ';
     179                $res .= $id ? 'id="'.$id.'" ' : '';
     180                $res .= ' />';
     181               
     182                return $res;
     183        }
     184}
     185
     186class formSelectOption
     187{
     188        public $name;
     189        public $value;
     190        public $class_name;
     191        public $html;
     192       
     193        private $option = '<option value="%1$s"%3$s>%2$s</option>';
     194       
     195        public function __construct($name,$value,$class_name='',$html='')
     196        {
     197                $this->name = $name;
     198                $this->value = $value;
     199                $this->class_name = $class_name;
     200                $this->html = $html;
     201        }
     202       
     203        public function render($default)
     204        {
     205                $attr = $this->html;
     206                $attr .= $this->class_name ? ' class="'.$this->class_name.'"' : '';
     207               
     208                if ($this->value == $default) {
     209                        $attr .= ' selected="selected"';
     210                }
     211               
     212                return sprintf($this->option,$this->value,$this->name,$attr)."\n";
     213        }
     214}
     215?>
     216 No newline at end of file
  • clearbricks/common/lib.html.php

     
     1<?php
     2# ***** BEGIN LICENSE BLOCK *****
     3# This file is part of Clearbricks.
     4# Copyright (c) 2006 Olivier Meunier and contributors. All rights
     5# reserved.
     6#
     7# Clearbricks is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# Clearbricks is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with Clearbricks; if not, write to the Free Software
     19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     20#
     21# ***** END LICENSE BLOCK *****
     22
     23class html
     24{
     25        public static $url_root;
     26        public static $absolute_regs = array();
     27       
     28        /**
     29        @function escapeHTML
     30       
     31        Replaces HTML special characters by entities.
     32       
     33        @param  str     string  String to escape
     34        @return string
     35        */
     36        public static function escapeHTML($str)
     37        {
     38                return htmlspecialchars($str,ENT_COMPAT,'UTF-8');
     39        }
     40       
     41        /**
     42        @function decodeEntities
     43       
     44        Returns a string with all entities decoded.
     45       
     46        @param  str     string  String to protect
     47        @param  keep_special string             Keep special characters: &gt; &lt; &amp;
     48        @return string
     49        */
     50        public static function decodeEntities($str,$keep_special=false)
     51        {
     52                if ($keep_special) {
     53                        $str = str_replace(
     54                                array('&amp;','&gt;','&lt;'),
     55                                array('&amp;amp;','&amp;gt;','&amp;lt;'),
     56                                $str);
     57                }
     58               
     59                # Some extra replacements
     60                $extra = array(
     61                        '&apos;' => "'"
     62                );
     63               
     64                $str = str_replace(array_keys($extra),array_values($extra),$str);
     65               
     66                return html_entity_decode($str,ENT_QUOTES,'UTF-8');
     67        }
     68       
     69        /**
     70        @function clean
     71       
     72        Removes every tags, comments, cdata from string
     73       
     74        @param  str     string  String to clean
     75        @return string
     76        */
     77        public static function clean($str)
     78        {
     79                $str = strip_tags($str);
     80                return $str;
     81        }
     82       
     83        /**
     84        @function escapeJS
     85       
     86        Returns a protected JavaScript string
     87       
     88        @param  string  str                     String to protect
     89        @return string
     90        */
     91        public static function escapeJS($str)
     92        {
     93                $str = htmlspecialchars($str,ENT_NOQUOTES,'UTF-8');
     94                $str = str_replace("'","\'",$str);
     95                $str = str_replace('"','\"',$str);
     96                return $str;
     97        }
     98       
     99        /**
     100        @function escapeURL
     101       
     102        Returns an escaped URL string for HTML content
     103       
     104        @param  str     string  String to escape
     105        @return string
     106        */
     107        public static function escapeURL($str)
     108        {
     109                return str_replace('&','&amp;',$str);
     110        }
     111       
     112        /**
     113        @function sanitizeURL
     114       
     115        Encode every parts between / in url
     116       
     117        @param  str     string  String to satinyze
     118        @return string
     119        */
     120        public static function sanitizeURL($str)
     121        {
     122                return str_replace('%2F','/',rawurlencode($str));
     123        }
     124       
     125        /**
     126        @function stripHostURL
     127       
     128        Removes host part in URL
     129       
     130        @param  url     string  URL to transform
     131        @return string
     132        */
     133        public static function stripHostURL($url)
     134        {
     135                return preg_replace('|^[a-z]{3,}://.*?(/.*$)|','$1',$url);
     136        }
     137       
     138        /**
     139        @function absoluteURLs
     140       
     141        Appends $root URL to URIs attributes in $str.
     142       
     143        @param  str             string  HTML to transform
     144        @param  root            string  Base URL
     145        @return string
     146        */
     147        public static function absoluteURLs($str,$root)
     148        {
     149                self::$url_root = $root;
     150                $attr = 'action|background|cite|classid|codebase|data|href|longdesc|profile|src|usemap';
     151               
     152                $str = preg_replace_callback('/((?:'.$attr.')=")(.*?)(")/msu',array('self','absoluteURLHandler'),$str);
     153               
     154                foreach (self::$absolute_regs as $r) {
     155                        $str = preg_replace_callback($r,array('self','absoluteURLHandler'),$str);
     156                }
     157               
     158                self::$url_root = null;
     159                return $str;
     160        }
     161       
     162        private static function absoluteURLHandler($m)
     163        {
     164                $url = $m[2];
     165               
     166                $link = $m[1].'%s'.$m[3];
     167                $host = preg_replace('|^([a-z]{3,}://)(.*?)/(.*)$|','$1$2',self::$url_root);
     168               
     169                $parse = parse_url($m[2]);
     170                if (empty($parse['scheme']))
     171                {
     172                        if (strpos($url,'/') === 0) {
     173                                $url = $host.$url;
     174                        } elseif (preg_match('|/$|',self::$url_root)) {
     175                                $url = self::$url_root.$url;
     176                        } else {
     177                                $url = dirname(self::$url_root).'/'.$url;
     178                        }
     179                }
     180               
     181                return sprintf($link,$url);
     182        }
     183}
     184?>
     185 No newline at end of file
  • clearbricks/common/lib.http.php

     
     1<?php
     2# ***** BEGIN LICENSE BLOCK *****
     3# This file is part of Clearbricks.
     4# Copyright (c) 2006 Olivier Meunier and contributors. All rights
     5# reserved.
     6#
     7# Clearbricks is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# Clearbricks is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with Clearbricks; if not, write to the Free Software
     19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     20#
     21# ***** END LICENSE BLOCK *****
     22
     23class http
     24{
     25        public static $https_scheme_on_443 = false;
     26       
     27        /**
     28        @function getHost
     29       
     30        Return current scheme, host and port.
     31        */
     32        public static function getHost()
     33        {
     34                $server_name = explode(':',$_SERVER['HTTP_HOST']);
     35                $server_name = $server_name[0];
     36                if (self::$https_scheme_on_443 && $_SERVER['SERVER_PORT'] == '443')
     37                {
     38                        $scheme = 'https';
     39                        $port = '';
     40                }
     41                elseif (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
     42                {
     43                        $scheme = 'https';
     44                        $port = ($_SERVER['SERVER_PORT'] != '443') ? ':'.$_SERVER['SERVER_PORT'] : '';
     45                }
     46                else
     47                {
     48                        $scheme = 'http';
     49                        $port = ($_SERVER['SERVER_PORT'] != '80') ? ':'.$_SERVER['SERVER_PORT'] : '';
     50                }
     51               
     52                return $scheme.'://'.$server_name.$port;
     53        }
     54       
     55        /**
     56        @function getSelfURI
     57       
     58        Returns current URI with full hostname
     59        */
     60        public static function getSelfURI()
     61        {
     62                return self::getHost().$_SERVER['REQUEST_URI'];
     63        }
     64       
     65        /**
     66        @function redirect
     67       
     68        Performs a conforming HTTP redirect for a relative URL.
     69       
     70        @param page     string          Relative URL
     71        */
     72        public static function redirect($page)
     73        {
     74                if (preg_match('%^http[s]?://%',$page))
     75                {
     76                        $redir = $page;
     77                }
     78                else
     79                {
     80                        $host = self::getHost();
     81                        $dir = dirname($_SERVER['PHP_SELF']);
     82                       
     83                        if (substr($page,0,1) == '/') {
     84                                $redir = $host.$page;
     85                        } else {
     86                                if (substr($dir,-1) == '/') {
     87                                        $dir =  substr($dir,0,-1);
     88                                }
     89                                $redir = $host.$dir.'/'.$page;
     90                        }
     91                }
     92               
     93                # Close session if exists
     94                if (session_id()) {
     95                        session_write_close();
     96                }
     97               
     98                header('Location: '.$redir);
     99                exit;
     100        }
     101       
     102        /**
     103        @function concatURL
     104       
     105        Appends a path to a given URL. If path begins with "/" it will replace the
     106        original URL path.
     107       
     108        @param url      string          URL
     109        @param path     string          Path to append
     110        @return string
     111        */
     112        public static function concatURL($url,$path)
     113        {
     114                if (substr($path,0,1) != '/') {
     115                        return $url.$path;
     116                }
     117               
     118                return preg_replace('#^(.+?//.+?)/(.*)$#','$1'.$path,$url);
     119        }
     120       
     121        /**
     122        @function realIP
     123       
     124        Returns the real client IP (or tries to do its best)
     125        Taken from http://uk.php.net/source.php?url=/include/ip-to-country.inc
     126       
     127        @return string
     128        */
     129        public static function realIP()
     130        {
     131                return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : null;
     132        }
     133       
     134        /**
     135        Returns a "almost" safe client unique ID
     136        */
     137        public static function browserUID($key)
     138        {
     139                $ip = self::realIP();
     140               
     141                $uid  = '';
     142                $uid .= isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
     143                $uid .= isset($_SERVER['HTTP_ACCEPT_ENCODING']) ? $_SERVER['HTTP_ACCEPT_ENCODING'] : '';
     144                $uid .= isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : '';
     145                $uid .= isset($_SERVER['HTTP_ACCEPT_CHARSET']) ? $_SERVER['HTTP_ACCEPT_CHARSET'] : '';
     146                $uid .= substr($ip,0,strpos($ip,'.'));
     147               
     148                return crypt::hmac($key,$uid);
     149        }
     150       
     151        /**
     152        Returns a two letters language code take from HTTP_ACCEPT_LANGUAGE.
     153       
     154        @return <b>string</b>
     155        */
     156        public static function getAcceptLanguage()
     157        {
     158                $dlang = '';
     159                if (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE']))
     160                {
     161                        $acclang = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
     162                        $L = explode(';', $acclang[0]);
     163                        $dlang = substr(trim($L[0]),0,2);
     164                }
     165               
     166                return $dlang;
     167        }
     168       
     169        /**
     170        @function cache
     171       
     172        Sends HTTP cache headers (304) according to a list of files and an optionnal
     173        list of timestamps.
     174       
     175        @param files            array           Files on which check mtime
     176        @param mod_ts           array           List of timestamps
     177        */
     178        public static function cache($files,$mod_ts=array())
     179        {
     180                if (empty($files) || !is_array($files)) {
     181                        return;
     182                }
     183               
     184                array_walk($files,create_function('&$v','$v = filemtime($v);'));
     185               
     186                $array_ts = array_merge($mod_ts,$files);
     187               
     188                rsort($array_ts);
     189                $ts = $array_ts[0];
     190               
     191                $since = null;
     192                if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
     193                        $since = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
     194                        $since = preg_replace ('/^(.*)(Mon|Tue|Wed|Thu|Fri|Sat|Sun)(.*)(GMT)(.*)/', '$2$3 GMT', $since);
     195                        $since = strtotime($since);
     196                }
     197               
     198                # Common headers list
     199                $headers[] = 'Last-Modified: '.gmdate('D, d M Y H:i:s',$ts).' GMT';
     200                $headers[] = 'Cache-Control: must-revalidate, max-age=0';
     201                $headers[] = 'Pragma:';
     202               
     203                if ($since >= $ts)
     204                {
     205                        self::head(304,'Not Modified');
     206                        foreach ($headers as $v) {
     207                                header($v);
     208                        }
     209                        exit;
     210                }
     211                else
     212                {
     213                        header('Date: '.gmdate('D, d M Y H:i:s').' GMT');
     214                        foreach ($headers as $v) {
     215                                header($v);
     216                        }
     217                }
     218        }
     219
     220        /**
     221        @function etag
     222       
     223        Sends HTTP cache headers (304) according to a list of etags in client request
     224       
     225        @param p_content        string          Response page content
     226        */
     227        public static function etag()
     228        {
     229                # We create an etag from all arguments
     230                $args = func_get_args();
     231                if (empty($args)) {
     232                        return;
     233                }
     234               
     235                $etag = md5(implode('',$args));
     236                unset($args);
     237               
     238                header('ETag: "'.$etag.'"');
     239               
     240                # Do we have a previously sent content?
     241                if (!empty($_SERVER['HTTP_IF_NONE_MATCH']))
     242                {
     243                        foreach (explode(',',$_SERVER['HTTP_IF_NONE_MATCH']) as $i)
     244                        {
     245                                if (stripslashes(trim($i)) == $etag) {
     246                                        self::head(304,'Not Modified');
     247                                        exit;
     248                                }
     249                        }
     250                }
     251        }
     252       
     253        /**
     254        @function head
     255       
     256        Sends an HTTP code and message to client
     257       
     258        @param code     string          HTTP code
     259        @param msg      string          Message
     260        */
     261        public static function head($code,$msg=null)
     262        {
     263                $status_mode = preg_match('/cgi/',PHP_SAPI);
     264               
     265                if (!$msg)
     266                {
     267                        $msg_codes = array(
     268                                100 => 'Continue',
     269                                101 => 'Switching Protocols',
     270                                200 => 'OK',
     271                                201 => 'Created',
     272                                202 => 'Accepted',
     273                                203 => 'Non-Authoritative Information',
     274                                204 => 'No Content',
     275                                205 => 'Reset Content',
     276                                206 => 'Partial Content',
     277                                300 => 'Multiple Choices',
     278                                301 => 'Moved Permanently',
     279                                302 => 'Found',
     280                                303 => 'See Other',
     281                                304 => 'Not Modified',
     282                                305 => 'Use Proxy',
     283                                307 => 'Temporary Redirect',
     284                                400 => 'Bad Request',
     285                                401 => 'Unauthorized',
     286                                402 => 'Payment Required',
     287                                403 => 'Forbidden',
     288                                404 => 'Not Found',
     289                                405 => 'Method Not Allowed',
     290                                406 => 'Not Acceptable',
     291                                407 => 'Proxy Authentication Required',
     292                                408 => 'Request Timeout',
     293                                409 => 'Conflict',
     294                                410 => 'Gone',
     295                                411 => 'Length Required',
     296                                412 => 'Precondition Failed',
     297                                413 => 'Request Entity Too Large',
     298                                414 => 'Request-URI Too Long',
     299                                415 => 'Unsupported Media Type',
     300                                416 => 'Requested Range Not Satisfiable',
     301                                417 => 'Expectation Failed',
     302                                500 => 'Internal Server Error',
     303                                501 => 'Not Implemented',
     304                                502 => 'Bad Gateway',
     305                                503 => 'Service Unavailable',
     306                                504 => 'Gateway Timeout',
     307                                505 => 'HTTP Version Not Supported'
     308                        );
     309                       
     310                        $msg = isset($msg_codes[$code]) ? $msg_codes[$code] : '-';
     311                }
     312               
     313                if ($status_mode) {
     314                        header('Status: '.$code.' '.$msg);
     315                } else {
     316                        if (version_compare(phpversion(),'4.3.0','>=')) {
     317                                header($msg, true, $code);
     318                        } else {
     319                                header('HTTP/1.x '.$code.' '.$msg);
     320                        }
     321                }
     322        }
     323       
     324        /**
     325        @function trimRequest
     326       
     327        Trims every value in GET, POST, REQUEST and COOKIE vars.
     328        Removes magic quotes if magic_quote_gpc is on.
     329        */
     330        public static function trimRequest()
     331        {
     332                if(!empty($_GET)) {
     333                        array_walk($_GET,array('self','trimRequestHandler'));
     334                }
     335                if(!empty($_POST)) {
     336                        array_walk($_POST,array('self','trimRequestHandler'));
     337                }
     338                if(!empty($_REQUEST)) {
     339                        array_walk($_REQUEST,array('self','trimRequestHandler'));
     340                }
     341                if(!empty($_COOKIE)) {
     342                        array_walk($_COOKIE,array('self','trimRequestHandler'));
     343                }
     344        }
     345       
     346        private static function trimRequestHandler(&$v,$key)
     347        {
     348                $v = self::trimRequestInVar($v);
     349        }
     350       
     351        private static function trimRequestInVar($value)
     352        {
     353                if (is_array($value))
     354                {
     355                        $result = array();
     356                        foreach ($value as $k => $v)
     357                        {
     358                                if (is_array($v)) {
     359                                        $result[$k] = self::trimRequestInVar($v);
     360                                } else {
     361                                        if (get_magic_quotes_gpc()) {
     362                                                $v = stripslashes($v);
     363                                        }
     364                                        $result[$k] = trim($v);
     365                                }
     366                        }
     367                        return $result;
     368                }
     369                else
     370                {
     371                        if (get_magic_quotes_gpc()) {
     372                                $value = stripslashes($value);
     373                        }
     374                        return trim($value);
     375                }
     376        }
     377       
     378        /**
     379        @function unsetGlobals
     380       
     381        If register_globals is on, removes every GET, POST, COOKIE, REQUEST, SERVER,
     382        ENV, FILES vars from GLOBALS.
     383        */
     384        public static function unsetGlobals()
     385        {
     386                if (!ini_get('register_globals')) {
     387                        return;
     388                }
     389               
     390                if (isset($_REQUEST['GLOBALS'])) {
     391                        throw new Exception('GLOBALS overwrite attempt detected');
     392                }
     393               
     394                # Variables that shouldn't be unset
     395                $no_unset = array('GLOBALS','_GET','_POST','_COOKIE','_REQUEST',
     396                '_SERVER','_ENV','_FILES');
     397               
     398                $input = array_merge($_GET,$_POST,$_COOKIE,$_SERVER,$_ENV,$_FILES,
     399                                (isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array()));
     400               
     401                foreach ($input as $k => $v) {
     402                        if (!in_array($k,$no_unset) && isset($GLOBALS[$k]) ) {
     403                                $GLOBALS[$k] = null;
     404                                unset($GLOBALS[$k]);
     405                        }
     406                }
     407        }
     408}
     409?>
     410 No newline at end of file
  • clearbricks/common/lib.l10n.php

     
     1<?php
     2# ***** BEGIN LICENSE BLOCK *****
     3# This file is part of Clearbricks.
     4# Copyright (c) 2006 Olivier Meunier and contributors. All rights
     5# reserved.
     6#
     7# Clearbricks is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# Clearbricks is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with Clearbricks; if not, write to the Free Software
     19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     20#
     21# ***** END LICENSE BLOCK *****
     22
     23
     24function __($str)
     25{
     26        return (!empty($GLOBALS['__l10n'][$str])) ? $GLOBALS['__l10n'][$str] : $str;
     27}
     28
     29class l10n
     30{
     31        public static $text_direction;
     32       
     33        protected static $langs = array();
     34       
     35        public static function init()
     36        {
     37                $GLOBALS['__l10n'] = array();
     38                $GLOBALS['__l10n_files'] = array();
     39        }
     40       
     41        public static function set($file)
     42        {
     43                $lang_file = $file.'.lang';
     44                $po_file = $file.'.po';
     45                $php_file = $file.'.lang.php';
     46               
     47                if (file_exists($php_file))
     48                {
     49                        require $php_file;
     50                }
     51                elseif (($tmp = self::getPoFile($po_file)) !== false)
     52                {
     53                        $GLOBALS['__l10n_files'][] = $po_file;
     54                        $GLOBALS['__l10n'] = array_merge($GLOBALS['__l10n'],$tmp);
     55                }
     56                elseif (($tmp = self::getLangFile($lang_file)) !== false)
     57                {
     58                        $GLOBALS['__l10n_files'][] = $lang_file;
     59                        $GLOBALS['__l10n'] = array_merge($GLOBALS['__l10n'],$tmp);
     60                }
     61                else
     62                {
     63                        return false;
     64                }
     65        }
     66       
     67        public static function getLangFile($file)
     68        {
     69                if (!file_exists($file)) {
     70                        return false;
     71                }
     72               
     73                $fp = @fopen($file,'r');
     74               
     75                if ($fp === false) {
     76                        return false;
     77                }
     78               
     79                $res = array();
     80                while ($l = fgets($fp))
     81                {
     82                        $l = trim($l);
     83                        # Comment
     84                        if (substr($l,0,1) == '#') {
     85                                continue;
     86                        }
     87                       
     88                        # Original text
     89                        if (substr($l,0,1) == ';' && ($t = fgets($fp)) !== false && trim($t) != '') {
     90                                $res[$l] = trim($t);
     91                        }
     92                       
     93                }
     94                fclose($fp);
     95               
     96                return $res;
     97        }
     98       
     99        public static function getPoFile($file)
     100        {
     101                if (!file_exists($file)) {
     102                        return false;
     103                }
     104               
     105                $fc = implode('',file($file));
     106               
     107                $res = array();
     108               
     109                $matched = preg_match_all('/(msgid\s+("([^"]|\\\\")*?"\s*)+)\s+'.
     110                '(msgstr\s+("([^"]|\\\\")*?(?<!\\\)"\s*)+)/',
     111                $fc, $matches);
     112               
     113                if (!$matched) {
     114                        return false;
     115                }
     116               
     117                for ($i=0; $i<$matched; $i++)
     118                {
     119                        $msgid = preg_replace('/\s*msgid\s*"(.*)"\s*/s','\\1',$matches[1][$i]);
     120                        $msgstr= preg_replace('/\s*msgstr\s*"(.*)"\s*/s','\\1',$matches[4][$i]);
     121                       
     122                        $msgstr = self::poString($msgstr);
     123                       
     124                        if ($msgstr) {
     125                                $res[self::poString($msgid)] = $msgstr;
     126                        }
     127                }
     128               
     129                if (!empty($res[''])) {
     130                        $meta = $res[''];
     131                        unset($res['']);
     132                }
     133               
     134                return $res;
     135        }
     136       
     137        private static function poString($string,$reverse=false)
     138        {
     139                if ($reverse) {
     140                        $smap = array('"', "\n", "\t", "\r");
     141                        $rmap = array('\\"', '\\n"' . "\n" . '"', '\\t', '\\r');
     142                        return trim((string) str_replace($smap, $rmap, $string));
     143                } else {
     144                        $smap = array('/"\s+"/', '/\\\\n/', '/\\\\r/', '/\\\\t/', '/\\\"/');
     145                        $rmap = array('', "\n", "\r", "\t", '"');
     146                        return trim((string) preg_replace($smap, $rmap, $string));
     147                }
     148        }
     149       
     150        public static function getFilePath($dir,$file,$lang)
     151        {
     152                $f = $dir.'/'.$lang.'/'.$file;
     153                if (!file_exists($f)) {
     154                        $f = $dir.'/en/'.$file;
     155                }
     156               
     157                return file_exists($f) ? $f : false;
     158        }
     159       
     160        public static function getISOcodes($flip=false,$name_with_code=false)
     161        {
     162                if (empty(self::$langs))
     163                {
     164                        self::$langs = array(
     165                        'aa' => 'Afaraf',
     166                        'ab' => 'Аҧсуа',
     167                        'ae' => 'avesta',
     168                        'af' => 'Afrikaans',
     169                        'ak' => 'Akan',
     170                        'am' => 'አማርኛ',
     171                        'an' => 'Aragonés',
     172                        'ar' => '‫العربية',
     173                        'as' => 'অসমীয়া',
     174                        'av' => 'авар мацӀ',
     175                        'ay' => 'aymar aru',
     176                        'az' => 'azərbaycan dili',
     177                        'ba' => 'башҡорт теле',
     178                        'be' => 'Беларуская',
     179                        'bg' => 'български език',
     180                        'bh' => 'भोजपुरी',
     181                        'bi' => 'Bislama',
     182                        'bm' => 'bamanankan',
     183                        'bn' => 'বাংলা',
     184                        'bo' => 'བོད་ཡིག',
     185                        'br' => 'brezhoneg',
     186                        'bs' => 'bosanski jezik',
     187                        'ca' => 'Català',
     188                        'ce' => 'нохчийн мотт',
     189                        'ch' => 'Chamoru',
     190                        'co' => 'corsu',
     191                        'cr' => 'ᓀᐦᐃᔭᐍᐏᐣ',
     192                        'cs' => 'česky',
     193                        'cu' => 'ѩзыкъ словѣньскъ',
     194                        'cv' => 'чӑваш чӗлхи',
     195                        'cy' => 'Cymraeg',
     196                        'da' => 'dansk',
     197                        'de' => 'Deutsch',
     198                        'dv' => '‫ދިވެހި',
     199                        'dz' => 'རྫོང་ཁ',
     200                        'ee' => 'Ɛʋɛgbɛ',
     201                        'el' => 'Ελληνικά',
     202                        'en' => 'English',
     203                        'eo' => 'Esperanto',
     204                        'es' => 'español',
     205                        'et' => 'Eesti keel',
     206                        'eu' => 'euskara',
     207                        'fa' => '‫فارسی',
     208                        'ff' => 'Fulfulde',
     209                        'fi' => 'suomen kieli',
     210                        'fj' => 'vosa Vakaviti',
     211                        'fo' => 'Føroyskt',
     212                        'fr' => 'français',
     213                        'fy' => 'Frysk',
     214                        'ga' => 'Gaeilge',
     215                        'gd' => 'Gàidhlig',
     216                        'gl' => 'Galego',
     217                        'gn' => "Avañe'ẽ",
     218                        'gu' => 'ગુજરાતી',
     219                        'gv' => 'Ghaelg',
     220                        'ha' => '‫هَوُسَ',
     221                        'he' => '‫עברית',
     222                        'hi' => 'हिन्दी',
     223                        'ho' => 'Hiri Motu',
     224                        'hr' => 'Hrvatski',
     225                        'ht' => 'Kreyòl ayisyen',
     226                        'hu' => 'Magyar',
     227                        'hy' => 'Հայերեն',
     228                        'hz' => 'Otjiherero',
     229                        'ia' => 'Interlingua',
     230                        'id' => 'Bahasa Indonesia',
     231                        'ie' => 'Interlingue',
     232                        'ig' => 'Igbo',
     233                        'ii' => 'ꆇꉙ',
     234                        'ik' => 'Iñupiaq',
     235                        'io' => 'Ido',
     236                        'is' => 'Íslenska',
     237                        'it' => 'Italiano',
     238                        'iu' => 'ᐃᓄᒃᑎᑐᑦ',
     239                        'ja' => '日本語',
     240                        'jv' => 'basa Jawa',
     241                        'ka' => 'ქართული',
     242                        'kg' => 'KiKongo',
     243                        'ki' => 'Gĩkũyũ',
     244                        'kj' => 'Kuanyama',
     245                        'kk' => 'Қазақ тілі',
     246                        'kl' => 'kalaallisut',
     247                        'km' => 'ភាសាខ្មែរ',
     248                        'kn' => 'ಕನ್ನಡ',
     249                        'ko' => '한국어',
     250                        'kr' => 'Kanuri',
     251                        'ks' => 'कश्मीरी',
     252                        'ku' => 'Kurdî',
     253                        'kv' => 'коми кыв',
     254                        'kw' => 'Kernewek',
     255                        'ky' => 'кыргыз тили',
     256                        'la' => 'latine',
     257                        'lb' => 'Lëtzebuergesch',
     258                        'lg' => 'Luganda',
     259                        'li' => 'Limburgs',
     260                        'ln' => 'Lingála',
     261                        'lo' => 'ພາສາລາວ',
     262                        'lt' => 'lietuvių kalba',
     263                        'lu' => 'Luba-Katanga   ',
     264                        'lv' => 'latviešu valoda',
     265                        'mg' => 'Malagasy fiteny',
     266                        'mh' => 'Kajin M̧ajeļ',
     267                        'mi' => 'te reo Māori',
     268                        'mk' => 'македонски јазик',
     269                        'ml' => 'മലയാളം',
     270                        'mn' => 'Монгол',
     271                        'mo' => 'Limba moldovenească',
     272                        'mr' => 'मराठी',
     273                        'ms' => 'bahasa Melayu',
     274                        'mt' => 'Malti',
     275                        'my' => 'ဗမာစာ',
     276                        'na' => 'Ekakairũ Naoero',
     277                        'nb' => 'Norsk bokmål',
     278                        'nd' => 'isiNdebele',
     279                        'ne' => 'नेपाली',
     280                        'ng' => 'Owambo',
     281                        'nl' => 'Nederlands',
     282                        'nl-be' => 'Nederlands (Belgium)',
     283                        'nn' => 'Norsk nynorsk',
     284                        'no' => 'Norsk',
     285                        'nr' => 'Ndébélé',
     286                        'nv' => 'Diné bizaad',
     287                        'ny' => 'chiCheŵa',
     288                        'oc' => 'Occitan',
     289                        'oj' => 'ᐊᓂᔑᓈᐯᒧᐎᓐ',
     290                        'om' => 'Afaan Oromoo',
     291                        'or' => 'ଓଡ଼ିଆ',
     292                        'os' => 'Ирон æвзаг',
     293                        'pa' => 'ਪੰਜਾਬੀ',
     294                        'pi' => 'पाऴि',
     295                        'pl' => 'polski',
     296                        'ps' => '‫پښتو',
     297                        'pt' => 'Português',
     298                        'pt-br' => 'Português (Brasil)',
     299                        'qu' => 'Runa Simi',
     300                        'rm' => 'rumantsch grischun',
     301                        'rn' => 'kiRundi',
     302                        'ro' => 'română',
     303                        'ru' => 'русский язык',
     304                        'rw' => 'Ikinyarwanda',
     305                        'sa' => 'संस्कृतम्',
     306                        'sc' => 'sardu',
     307                        'sd' => 'सिन्धी',
     308                        'se' => 'Davvisámegiella',
     309                        'sg' => 'yângâ tî sängö',
     310                        'sh' => 'Srpskohrvatski',
     311                        'si' => 'සිංහල',
     312                        'sk' => 'slovenčina',
     313                        'sl' => 'slovenščina',
     314                        'sm' => "gagana fa'a Samoa",
     315                        'sn' => 'chiShona',
     316                        'so' => 'Soomaaliga',
     317                        'sq' => 'Shqip',
     318                        'sr' => 'српски језик',
     319                        'ss' => 'SiSwati',
     320                        'st' => 'seSotho',
     321                        'su' => 'Basa Sunda',
     322                        'sv' => 'Svenska',
     323                        'sw' => 'Kiswahili',
     324                        'ta' => 'தமிழ்',
     325                        'te' => 'తెలుగు',
     326                        'tg' => 'тоҷикӣ',
     327                        'th' => 'ไทย',
     328                        'ti' => 'ትግርኛ',
     329                        'tk' => 'Türkmen',
     330                        'tl' => 'Tagalog',
     331                        'tn' => 'seTswana',
     332                        'to' => 'faka Tonga',
     333                        'tr' => 'Türkçe',
     334                        'ts' => 'xiTsonga',
     335                        'tt' => 'татарча',
     336                        'tw' => 'Twi',
     337                        'ty' => 'Reo Mā`ohi',
     338                        'ug' => 'Uyƣurqə',
     339                        'uk' => 'Українська',
     340                        'ur' => '‫اردو',
     341                        'uz' => "O'zbek",
     342                        've' => 'tshiVenḓa',
     343                        'vi' => 'Tiếng Việt',
     344                        'vo' => 'Volapük',
     345                        'wa' => 'Walon',
     346                        'wo' => 'Wollof',
     347                        'xh' => 'isiXhosa',
     348                        'yi' => '‫ייִדיש',
     349                        'yo' => 'Yorùbá',
     350                        'za' => 'Saɯ cueŋƅ',
     351                        'zh' => '中文',
     352                        'zh-hk' => '中文 (香港)',
     353                        'zh-tw' => '中文 (臺灣)',
     354                        'zu' => 'isiZulu'
     355                        );
     356                }
     357               
     358                $langs = self::$langs;
     359                if ($name_with_code) {
     360                        foreach ($langs as $k => &$v) {
     361                                $v = '('.$k.') '.$v;
     362                        }
     363                }
     364               
     365                if ($flip) {
     366                        return array_flip($langs);
     367                }
     368               
     369                return $langs;
     370        }
     371       
     372        public static function getTextDirection($lang)
     373        {
     374                if (self::$text_direction) {
     375                        return self::$text_direction;
     376                }
     377               
     378                if (preg_match('/^(ar|dv|fa|ha|he|ps|ur|yi)$/i',$lang)) {
     379                        return 'rtl';
     380                }
     381                return 'ltr';
     382        }
     383}
     384?>
     385 No newline at end of file
  • clearbricks/common/lib.text.php

     
     1<?php
     2# ***** BEGIN LICENSE BLOCK *****
     3# This file is part of Clearbricks.
     4# Copyright (c) 2006 Olivier Meunier and contributors. All rights
     5# reserved.
     6#
     7# Clearbricks is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# Clearbricks is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with Clearbricks; if not, write to the Free Software
     19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     20#
     21# ***** END LICENSE BLOCK *****
     22
     23class text
     24{
     25        /**
     26        @function isEmail
     27       
     28        Checks if "email" var is a valid email address.
     29       
     30        Changed code, from http://www.iamcal.com/publish/articles/php/parsing_email/
     31       
     32        @param email    string          Email string
     33        @return boolean
     34        */
     35        public static function isEmail($email)
     36        {
     37                $qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
     38                $dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
     39                $atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
     40                $quoted_pair = '\\x5c[\\x00-\\x7f]';
     41                $domain_literal = "\\x5b($dtext|$quoted_pair)*\\x5d";
     42                $quoted_string = "\\x22($qtext|$quoted_pair)*\\x22";
     43                $domain_ref = $atom;
     44                $sub_domain = "($domain_ref|$domain_literal)";
     45                $word = "($atom|$quoted_string)";
     46                $domain = "$sub_domain(\\x2e$sub_domain)*";
     47                $local_part = "$word(\\x2e$word)*";
     48                $addr_spec = "$local_part\\x40$domain";
     49               
     50                return (boolean) preg_match("!^$addr_spec$!", $email);
     51        }
     52       
     53        /**
     54        Converts accented (and some other) characters from a string.
     55       
     56        @param  str             <b>string</b>           String to deaccent
     57        @return string
     58        */
     59        public static function deaccent($str)
     60        {
     61                $pattern['A'] = '\x{00C0}-\x{00C5}';
     62                $pattern['AE'] = '\x{00C6}';
     63                $pattern['C'] = '\x{00C7}';
     64                $pattern['D'] = '\x{00D0}';
     65                $pattern['E'] = '\x{00C8}-\x{00CB}';
     66                $pattern['I'] = '\x{00CC}-\x{00CF}';
     67                $pattern['N'] = '\x{00D1}';
     68                $pattern['O'] = '\x{00D2}-\x{00D6}\x{00D8}';
     69                $pattern['OE'] = '\x{0152}';
     70                $pattern['S'] = '\x{0160}';
     71                $pattern['U'] = '\x{00D9}-\x{00DC}';
     72                $pattern['Y'] = '\x{00DD}';
     73                $pattern['Z'] = '\x{017D}';
     74               
     75                $pattern['a'] = '\x{00E0}-\x{00E5}';
     76                $pattern['ae'] = '\x{00E6}';
     77                $pattern['c'] = '\x{00E7}';
     78                $pattern['d'] = '\x{00F0}';
     79                $pattern['e'] = '\x{00E8}-\x{00EB}';
     80                $pattern['i'] = '\x{00EC}-\x{00EF}';
     81                $pattern['n'] = '\x{00F1}';
     82                $pattern['o'] = '\x{00F2}-\x{00F6}\x{00F8}';
     83                $pattern['oe'] = '\x{0153}';
     84                $pattern['s'] = '\x{0161}';
     85                $pattern['u'] = '\x{00F9}-\x{00FC}';
     86                $pattern['y'] = '\x{00FD}\x{00FF}';
     87                $pattern['z'] = '\x{017E}';
     88               
     89                $pattern['ss'] = '\x{00DF}';
     90               
     91                foreach ($pattern as $r => $p) {
     92                        $str = preg_replace('/['.$p.']/u',$r,$str);
     93                }
     94               
     95                return $str;
     96        }
     97       
     98        /**
     99        @function str2URL
     100       
     101        Transforms a string to a proper URL.
     102       
     103        @param str                      string          String to transform
     104        @param with_slashes             boolean         Keep slashes in URL
     105        @return string
     106        */
     107        public static function str2URL($str,$with_slashes=true)
     108        {
     109                $str = self::deaccent($str);
     110                $str = preg_replace('/[^A-Za-z0-9_\s\'\:\/[\]-]/','',$str);
     111               
     112                return self::tidyURL($str,$with_slashes);
     113        }
     114       
     115        /**
     116        @function tidyURL
     117       
     118        Cleans an URL.
     119       
     120        @param str                      string          URL to tidy
     121        @param keep_slashes             boolean         Keep slashes in URL
     122        @param keep_spaces              boolean         Keep spaces in URL
     123        @return string
     124        */
     125        public static function tidyURL($str,$keep_slashes=true,$keep_spaces=false)
     126        {
     127                $str = strip_tags($str);
     128                $str = str_replace(array('?','&','#','=','+','<','>'),'',$str);
     129                $str = str_replace("'",' ',$str);
     130                $str = preg_replace('/[\s]+/',' ',trim($str));
     131               
     132                if (!$keep_slashes) {
     133                        $str = str_replace('/','-',$str);
     134                }
     135               
     136                if (!$keep_spaces) {
     137                        $str = str_replace(' ','-',$str);
     138                }
     139               
     140                $str = preg_replace('/[-]+/','-',$str);
     141               
     142                # Remove path changes in URL
     143                $str = preg_replace('%^/%','',$str);
     144                $str = preg_replace('%\.+/%','',$str);
     145               
     146                return $str;
     147        }
     148       
     149        /**
     150        @function cutString
     151       
     152        Cuts a string on spaces.
     153       
     154        @param  string  str             String to cut
     155        @param  integer l               Length to keep
     156        @return string
     157        */
     158        public static function cutString($str,$l)
     159        {
     160                $s = preg_split('/([\s]+)/u',$str,-1,PREG_SPLIT_DELIM_CAPTURE);
     161               
     162                $res = '';
     163                $L = 0;
     164               
     165                if (mb_strlen($s[0]) >= $l) {
     166                        return mb_substr($s[0],0,$l);
     167                }
     168               
     169                foreach ($s as $v)
     170                {
     171                        $L = $L+mb_strlen($v);
     172                       
     173                        if ($L > $l) {
     174                                break;
     175                        } else {
     176                                $res .= $v;
     177                        }
     178                }
     179               
     180                return trim($res);
     181        }
     182       
     183        /**
     184        @function splitWords
     185       
     186        Returns an array of words from a given string.
     187       
     188        @param str      string  Words to split
     189        @return array
     190        */
     191        public static function splitWords($str)
     192        {
     193                $non_word = '\x{0000}-\x{002F}\x{003A}-\x{0040}\x{005b}-\x{0060}\x{007B}-\x{007E}\x{00A0}-\x{00BF}\s';
     194                if (preg_match_all('/([^'.$non_word.']{3,})/msu',html::clean($str),$match)) {
     195                        foreach ($match[1] as $i => $v) {
     196                                $match[1][$i] = mb_strtolower($v);
     197                        }
     198                        return $match[1];
     199                }
     200                return array();
     201        }
     202       
     203        /**
     204        @function detectEncoding
     205       
     206        Returns the encoding (in lowercase) of given $str.
     207       
     208        @param str      string  String
     209        @return string
     210        */
     211        public static function detectEncoding($str)
     212        {
     213                return strtolower(mb_detect_encoding($str.' ',
     214                        'UTF-8,ISO-8859-1,ISO-8859-2,ISO-8859-3,'.
     215                        'ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO-8859-7,ISO-8859-8,'.
     216                        'ISO-8859-9,ISO-8859-10,ISO-8859-13,ISO-8859-14,ISO-8859-15'));
     217        }
     218       
     219        /**
     220        @function toUTF8
     221       
     222        Return an UTF-8 converted string.
     223       
     224        @param str              string  String to convert
     225        @param encoding string  Optionnal "from" encoding
     226        @return string
     227        */
     228        public static function toUTF8($str,$encoding=null)
     229        {
     230                if (!$encoding) {
     231                        $encoding = self::detectEncoding($str);
     232                }
     233               
     234                if ($encoding != 'utf-8') {
     235                        $str = iconv($encoding,'UTF-8',$str);
     236                }
     237               
     238                return $str;
     239        }
     240       
     241        /**
     242        @function utf8badFind
     243       
     244        Taken from http://phputf8.sourceforge.net
     245       
     246        Locates the first bad byte in a UTF-8 string returning it's
     247        byte index in the string
     248        PCRE Pattern to locate bad bytes in a UTF-8 string
     249        Comes from W3 FAQ: Multilingual Forms
     250        Note: modified to include full ASCII range including control chars
     251       
     252        @param str      string  String to search
     253        @return mixed
     254        */
     255        public static function utf8badFind($str)
     256        {
     257                $UTF8_BAD =
     258                '([\x00-\x7F]'.                          # ASCII (including control chars)
     259                '|[\xC2-\xDF][\x80-\xBF]'.               # non-overlong 2-byte
     260                '|\xE0[\xA0-\xBF][\x80-\xBF]'.           # excluding overlongs
     261                '|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}'.    # straight 3-byte
     262                '|\xED[\x80-\x9F][\x80-\xBF]'.           # excluding surrogates
     263                '|\xF0[\x90-\xBF][\x80-\xBF]{2}'.        # planes 1-3
     264                '|[\xF1-\xF3][\x80-\xBF]{3}'.            # planes 4-15
     265                '|\xF4[\x80-\x8F][\x80-\xBF]{2}'.        # plane 16
     266                '|(.{1}))';                              # invalid byte
     267                $pos = 0;
     268                $badList = array();
     269               
     270                while (preg_match('/'.$UTF8_BAD.'/S', $str, $matches)) {
     271                        $bytes = strlen($matches[0]);
     272                        if ( isset($matches[2])) {
     273                                return $pos;
     274                        }
     275                        $pos += $bytes;
     276                        $str = substr($str,$bytes);
     277                }
     278                return false;
     279        }
     280       
     281        /**
     282        @function cleanUTF8
     283       
     284        Taken from http://phputf8.sourceforge.net/
     285       
     286        Replace non utf8 bytes in $str by $repl.
     287       
     288        @param str      string  String to clean
     289        @param repl     string  Replacement string
     290        @return string
     291        */
     292        public static function cleanUTF8($str,$repl='?')
     293        {
     294                while (($bad_index = self::utf8badFind($str)) !== false) {
     295                        $str = substr_replace($str,$repl,$bad_index,1);
     296                }
     297               
     298                return $str;
     299        }
     300       
     301        /**
     302        @function removeBOM
     303       
     304        Removes BOM from the begining of a string if present.
     305       
     306        @param str      string  String to clean
     307        @return string
     308        */
     309        public static function removeBOM($str)
     310        {
     311                if (substr_count($str,'')) {
     312                        return str_replace('','',$str);
     313                }
     314               
     315                return $str;
     316        }
     317       
     318        /**
     319        @function QPEncode
     320       
     321        Encodes given str to quoted printable
     322       
     323        @param str      string  String to encode
     324        @return string
     325        */
     326        public static function QPEncode($str)
     327        {
     328                $res = '';
     329               
     330                foreach (preg_split("/\r?\n/msu", $str) as $line)
     331                {
     332                        $l = '';
     333                        preg_match_all('/./',$line,$m);
     334                       
     335                        foreach ($m[0] as $c)
     336                        {
     337                                $a = ord($c);
     338                               
     339                                if ($a < 32 || $a == 61 || $a > 126) {
     340                                        $c = sprintf('=%02X',$a);
     341                                }
     342                               
     343                                $l .= $c;
     344                        }
     345                       
     346                        $res .= $l."\r\n";
     347                }
     348                return $res;
     349        }
     350}
     351?>
     352 No newline at end of file
  • clearbricks/common/tz.dat

     
     1Africa/Abidjan
     2Africa/Accra
     3Africa/Addis_Ababa
     4Africa/Algiers
     5Africa/Asmera
     6Africa/Bamako
     7Africa/Bangui
     8Africa/Banjul
     9Africa/Bissau
     10Africa/Blantyre
     11Africa/Brazzaville
     12Africa/Bujumbura
     13Africa/Cairo
     14Africa/Casablanca
     15Africa/Ceuta
     16Africa/Conakry
     17Africa/Dakar
     18Africa/Dar_es_Salaam
     19Africa/Djibouti
     20Africa/Douala
     21Africa/El_Aaiun
     22Africa/Freetown
     23Africa/Gaborone
     24Africa/Harare
     25Africa/Johannesburg
     26Africa/Kampala
     27Africa/Khartoum
     28Africa/Kigali
     29Africa/Kinshasa
     30Africa/Lagos
     31Africa/Libreville
     32Africa/Lome
     33Africa/Luanda
     34Africa/Lubumbashi
     35Africa/Lusaka
     36Africa/Malabo
     37Africa/Maputo
     38Africa/Maseru
     39Africa/Mbabane
     40Africa/Mogadishu
     41Africa/Monrovia
     42Africa/Nairobi
     43Africa/Ndjamena
     44Africa/Niamey
     45Africa/Nouakchott
     46Africa/Ouagadougou
     47Africa/Porto-Novo
     48Africa/Sao_Tome
     49Africa/Timbuktu
     50Africa/Tripoli
     51Africa/Tunis
     52Africa/Windhoek
     53
     54
     55America/Adak
     56America/Anchorage
     57America/Anguilla
     58America/Antigua
     59America/Araguaina
     60America/Argentina/Buenos_Aires
     61America/Argentina/Catamarca
     62America/Argentina/ComodRivadavia
     63America/Argentina/Cordoba
     64America/Argentina/Jujuy
     65America/Argentina/La_Rioja
     66America/Argentina/Mendoza
     67America/Argentina/Rio_Gallegos
     68America/Argentina/San_Juan
     69America/Argentina/Tucuman
     70America/Argentina/Ushuaia
     71America/Aruba
     72America/Asuncion
     73America/Bahia
     74America/Barbados
     75America/Belem
     76America/Belize
     77America/Boa_Vista
     78America/Bogota
     79America/Boise
     80America/Cambridge_Bay
     81America/Campo_Grande
     82America/Cancun
     83America/Caracas
     84America/Cayenne
     85America/Cayman
     86America/Chicago
     87America/Chihuahua
     88America/Costa_Rica
     89America/Cuiaba
     90America/Curacao
     91America/Danmarkshavn
     92America/Dawson
     93America/Dawson_Creek
     94America/Denver
     95America/Detroit
     96America/Dominica
     97America/Edmonton
     98America/Eirunepe
     99America/El_Salvador
     100America/Fortaleza
     101America/Glace_Bay
     102America/Godthab
     103America/Goose_Bay
     104America/Grand_Turk
     105America/Grenada
     106America/Guadeloupe
     107America/Guatemala
     108America/Guayaquil
     109America/Guyana
     110America/Halifax
     111America/Havana
     112America/Hermosillo
     113America/Indiana/Indianapolis
     114America/Indiana/Knox
     115America/Indiana/Marengo
     116America/Indiana/Vevay
     117America/Indianapolis
     118America/Inuvik
     119America/Iqaluit
     120America/Jamaica
     121America/Juneau
     122America/Kentucky/Louisville
     123America/Kentucky/Monticello
     124America/La_Paz
     125America/Lima
     126America/Los_Angeles
     127America/Louisville
     128America/Maceio
     129America/Managua
     130America/Manaus
     131America/Martinique
     132America/Mazatlan
     133America/Menominee
     134America/Merida
     135America/Mexico_City
     136America/Miquelon
     137America/Monterrey
     138America/Montevideo
     139America/Montreal
     140America/Montserrat
     141America/Nassau
     142America/New_York
     143America/Nipigon
     144America/Nome
     145America/Noronha
     146America/North_Dakota/Center
     147America/Panama
     148America/Pangnirtung
     149America/Paramaribo
     150America/Phoenix
     151America/Port-au-Prince
     152America/Port_of_Spain
     153America/Porto_Velho
     154America/Puerto_Rico
     155America/Rainy_River
     156America/Rankin_Inlet
     157America/Recife
     158America/Regina
     159America/Rio_Branco
     160America/Santiago
     161America/Santo_Domingo
     162America/Sao_Paulo
     163America/Scoresbysund
     164America/Shiprock
     165America/St_Johns
     166America/St_Kitts
     167America/St_Lucia
     168America/St_Thomas
     169America/St_Vincent
     170America/Swift_Current
     171America/Tegucigalpa
     172America/Thule
     173America/Thunder_Bay
     174America/Tijuana
     175America/Toronto
     176America/Tortola
     177America/Vancouver
     178America/Whitehorse
     179America/Winnipeg
     180America/Yakutat
     181America/Yellowknife
     182
     183
     184Antarctica/Casey
     185Antarctica/Davis
     186Antarctica/DumontDUrville
     187Antarctica/Mawson
     188Antarctica/McMurdo
     189Antarctica/Palmer
     190Antarctica/Rothera
     191Antarctica/South_Pole
     192Antarctica/Syowa
     193Antarctica/Vostok
     194
     195
     196Arctic/Longyearbyen
     197
     198
     199Asia/Aden
     200Asia/Almaty
     201Asia/Amman
     202Asia/Anadyr
     203Asia/Aqtau
     204Asia/Aqtobe
     205Asia/Ashgabat
     206Asia/Baghdad
     207Asia/Bahrain
     208Asia/Baku
     209Asia/Bangkok
     210Asia/Beirut
     211Asia/Bishkek
     212Asia/Brunei
     213Asia/Calcutta
     214Asia/Choibalsan
     215Asia/Chongqing
     216Asia/Colombo
     217Asia/Damascus
     218Asia/Dhaka
     219Asia/Dili
     220Asia/Dubai
     221Asia/Dushanbe
     222Asia/Gaza
     223Asia/Harbin
     224Asia/Hong_Kong
     225Asia/Hovd
     226Asia/Irkutsk
     227Asia/Istanbul
     228Asia/Jakarta
     229Asia/Jayapura
     230Asia/Jerusalem
     231Asia/Kabul
     232Asia/Kamchatka
     233Asia/Karachi
     234Asia/Kashgar
     235Asia/Katmandu
     236Asia/Krasnoyarsk
     237Asia/Kuala_Lumpur
     238Asia/Kuching
     239Asia/Kuwait
     240Asia/Macau
     241Asia/Magadan
     242Asia/Makassar
     243Asia/Manila
     244Asia/Muscat
     245Asia/Nicosia
     246Asia/Novosibirsk
     247Asia/Omsk
     248Asia/Oral
     249Asia/Phnom_Penh
     250Asia/Pontianak
     251Asia/Pyongyang
     252Asia/Qatar
     253Asia/Qyzylorda
     254Asia/Rangoon
     255Asia/Riyadh
     256Asia/Saigon
     257Asia/Sakhalin
     258Asia/Samarkand
     259Asia/Seoul
     260Asia/Shanghai
     261Asia/Singapore
     262Asia/Taipei
     263Asia/Tashkent
     264Asia/Tbilisi
     265Asia/Tehran
     266Asia/Thimphu
     267Asia/Tokyo
     268Asia/Ulaanbaatar
     269Asia/Urumqi
     270Asia/Vientiane
     271Asia/Vladivostok
     272Asia/Yakutsk
     273Asia/Yekaterinburg
     274Asia/Yerevan
     275
     276
     277Atlantic/Azores
     278Atlantic/Bermuda
     279Atlantic/Canary
     280Atlantic/Cape_Verde
     281Atlantic/Faeroe
     282Atlantic/Jan_Mayen
     283Atlantic/Madeira
     284Atlantic/Reykjavik
     285Atlantic/South_Georgia
     286Atlantic/St_Helena
     287Atlantic/Stanley
     288
     289
     290Australia/Adelaide
     291Australia/Brisbane
     292Australia/Broken_Hill
     293Australia/Darwin
     294Australia/Hobart
     295Australia/Lindeman
     296Australia/Lord_Howe
     297Australia/Melbourne
     298Australia/Perth
     299Australia/Sydney
     300
     301
     302Europe/Amsterdam
     303Europe/Andorra
     304Europe/Athens
     305Europe/Belfast
     306Europe/Belgrade
     307Europe/Berlin
     308Europe/Bratislava
     309Europe/Brussels
     310Europe/Bucharest
     311Europe/Budapest
     312Europe/Chisinau
     313Europe/Copenhagen
     314Europe/Dublin
     315Europe/Gibraltar
     316Europe/Helsinki
     317Europe/Istanbul
     318Europe/Kaliningrad
     319Europe/Kiev
     320Europe/Lisbon
     321Europe/Ljubljana
     322Europe/London
     323Europe/Luxembourg
     324Europe/Madrid
     325Europe/Malta
     326Europe/Mariehamn
     327Europe/Minsk
     328Europe/Monaco
     329Europe/Moscow
     330Europe/Nicosia
     331Europe/Oslo
     332Europe/Paris
     333Europe/Prague
     334Europe/Riga
     335Europe/Rome
     336Europe/Samara
     337Europe/San_Marino
     338Europe/Sarajevo
     339Europe/Simferopol
     340Europe/Skopje
     341Europe/Sofia
     342Europe/Stockholm
     343Europe/Tallinn
     344Europe/Tirane
     345Europe/Uzhgorod
     346Europe/Vaduz
     347Europe/Vatican
     348Europe/Vienna
     349Europe/Vilnius
     350Europe/Warsaw
     351Europe/Zagreb
     352Europe/Zaporozhye
     353Europe/Zurich
     354
     355
     356Indian/Antananarivo
     357Indian/Chagos
     358Indian/Christmas
     359Indian/Cocos
     360Indian/Comoro
     361Indian/Kerguelen
     362Indian/Mahe
     363Indian/Maldives
     364Indian/Mauritius
     365Indian/Mayotte
     366Indian/Reunion
     367
     368
     369Pacific/Apia
     370Pacific/Auckland
     371Pacific/Chatham
     372Pacific/Easter
     373Pacific/Efate
     374Pacific/Enderbury
     375Pacific/Fakaofo
     376Pacific/Fiji
     377Pacific/Funafuti
     378Pacific/Galapagos
     379Pacific/Gambier
     380Pacific/Guadalcanal
     381Pacific/Guam
     382Pacific/Honolulu
     383Pacific/Johnston
     384Pacific/Kiritimati
     385Pacific/Kosrae
     386Pacific/Kwajalein
     387Pacific/Majuro
     388Pacific/Marquesas
     389Pacific/Midway
     390Pacific/Nauru
     391Pacific/Niue
     392Pacific/Norfolk
     393Pacific/Noumea
     394Pacific/Pago_Pago
     395Pacific/Palau
     396Pacific/Pitcairn
     397Pacific/Ponape
     398Pacific/Port_Moresby
     399Pacific/Rarotonga
     400Pacific/Saipan
     401Pacific/Tahiti
     402Pacific/Tarawa
     403Pacific/Tongatapu
     404Pacific/Truk
     405Pacific/Wake
     406Pacific/Wallis
     407Pacific/Yap
     408 No newline at end of file
  • clearbricks/dbschema/class.dbschema.php

     
     1<?php
     2# ***** BEGIN LICENSE BLOCK *****
     3# This file is part of Clearbricks.
     4# Copyright (c) 2007 Olivier Meunier and contributors. All rights
     5# reserved.
     6#
     7# Clearbricks is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# Clearbricks is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with Clearbricks; if not, write to the Free Software
     19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     20#
     21# ***** END LICENSE BLOCK *****
     22
     23interface i_dbSchema
     24{
     25        /**
     26        This method should return an array of all tables in database for the current
     27        connection.
     28       
     29        @return <b>array</b>
     30        */
     31        function db_get_tables();
     32       
     33        /**
     34        This method should return an associative array of columns in given table
     35        <var>$table</var> with column names in keys. Each line value is an array
     36        with following values:
     37       
     38        - [type] data type (string)
     39        - [len] data length (integer or null)
     40        - [null] is null? (boolean)
     41        - [default] default value (string)
     42       
     43        @param  table   <b>string</b>           Table name
     44        @return <b>array</b>
     45        */
     46        function db_get_columns($table);
     47       
     48        /**
     49        This method should return an array of keys in given table
     50        <var>$table</var>. Each line value is an array with following values:
     51       
     52        - [name] index name (string)
     53        - [primary] primary key (boolean)
     54        - [unique] unique key (boolean)
     55        - [cols] columns (array)
     56       
     57        @param  table   <b>string</b>           Table name
     58        @return <b>array</b>
     59        */
     60        function db_get_keys($table);
     61       
     62        /**
     63        This method should return an array of indexes in given table
     64        <var>$table</var>. Each line value is an array with following values:
     65       
     66        - [name] index name (string)
     67        - [type] index type (string)
     68        - [cols] columns (array)
     69       
     70        @param  table   <b>string</b>           Table name
     71        @return <b>array</b>
     72        */
     73        function db_get_indexes($table);
     74       
     75        /**
     76        This method should return an array of foreign keys in given table
     77        <var>$table</var>. Each line value is an array with following values:
     78       
     79        - [name] key name (string)
     80        - [c_cols] child columns (array)
     81        - [p_table] parent table (string)
     82        - [p_cols] parent columns (array)
     83        - [update] on update statement (string)
     84        - [delete] on delete statement (string)
     85       
     86        @param  table   <b>string</b>           Table name
     87        @return <b>array</b>
     88        */
     89        function db_get_references($table);
     90       
     91        function db_create_table($name,$fields);
     92       
     93        function db_create_field($table,$name,$type,$len,$null,$default);
     94       
     95        function db_create_primary($table,$name,$cols);
     96       
     97        function db_create_unique($table,$name,$cols);
     98       
     99        function db_create_index($table,$name,$type,$cols);
     100       
     101        function db_create_reference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete);
     102       
     103        function db_alter_field($table,$name,$type,$len,$null,$default);
     104       
     105        function db_alter_primary($table,$name,$newname,$cols);
     106       
     107        function db_alter_unique($table,$name,$newname,$cols);
     108       
     109        function db_alter_index($table,$name,$newname,$type,$cols);
     110       
     111        function db_alter_reference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete);
     112}
     113
     114class dbSchema
     115{
     116        protected $con;
     117       
     118        public function __construct(&$con)
     119        {
     120                $this->con =& $con;
     121        }
     122       
     123        public static function init(&$con)
     124        {
     125                $driver = $con->driver();
     126                $driver_class = $driver.'Schema';
     127               
     128                if (!class_exists($driver_class))
     129                {
     130                        if (file_exists(dirname(__FILE__).'/class.'.$driver.'.dbschema.php')) {
     131                                require dirname(__FILE__).'/class.'.$driver.'.dbschema.php';
     132                        } else {
     133                                trigger_error('Unable to load DB schema layer for '.$driver,E_USER_ERROR);
     134                                exit(1);
     135                        }
     136                }
     137               
     138                return new $driver_class($con);
     139        }
     140       
     141        /**
     142        Database data type to universal data type conversion.
     143       
     144        @param  type            <b>string</b>           Type name
     145        @param  leng            <b>integer</b>          Field length (in/out)
     146        @param  default <b>string</b>           Default field value (in/out)
     147        @return <b>string</b>
     148        */
     149        public function dbt2udt($type,&$len,&$default)
     150        {
     151                $c = array(
     152                        'bool' => 'boolean',
     153                        'int2' => 'smallint',
     154                        'int' => 'integer',
     155                        'int4' => 'integer',
     156                        'int8' => 'bigint',
     157                        'float4' => 'real',
     158                        'double precision' => 'float',
     159                        'float8' => 'float',
     160                        'decimal' => 'numeric',
     161                        'character varying' => 'varchar',
     162                        'character' => 'char'
     163                );
     164               
     165                if (isset($c[$type])) {
     166                        return $c[$type];
     167                }
     168               
     169                return $type;
     170        }
     171       
     172        /**
     173        Universal data type to database data tye conversion.
     174       
     175        @param  type            <b>string</b>           Type name
     176        @param  leng            <b>integer</b>          Field length (in/out)
     177        @param  default <b>string</b>           Default field value (in/out)
     178        @return <b>string</b>
     179        */
     180        public function udt2dbt($type,&$len,&$default)
     181        {
     182                return $type;
     183        }
     184       
     185        /**
     186        Returns an array of all table names.
     187       
     188        @see            i_dbSchema::db_get_tables
     189        @return <b>array</b>
     190        */
     191        public function getTables()
     192        {
     193                return $this->db_get_tables();
     194        }
     195       
     196        /**
     197        Returns an array of columns (name and type) of a given table.
     198       
     199        @see            i_dbSchema::db_get_columns
     200        @param  table   <b>string</b>           Table name
     201        @return <b>array</b>
     202        */
     203        public function getColumns($table)
     204        {
     205                return $this->db_get_columns($table);
     206        }
     207       
     208        /**
     209        Returns an array of index of a given table.
     210       
     211        @see            i_dbSchema::db_get_keys
     212        @param  table   <b>string</b>           Table name
     213        @return <b>array</b>
     214        */
     215        public function getKeys($table)
     216        {
     217                return $this->db_get_keys($table);
     218        }
     219       
     220        /**
     221        Returns an array of indexes of a given table.
     222       
     223        @see            i_dbSchema::db_get_index
     224        @param  table   <b>string</b>           Table name
     225        @return <b>array</b>
     226        */
     227        public function getIndexes($table)
     228        {
     229                return $this->db_get_indexes($table);
     230        }
     231       
     232        /**
     233        Returns an array of foreign keys of a given table.
     234       
     235        @see            i_dbSchema::db_get_references
     236        @param  table   <b>string</b>           Table name
     237        @return <b>array</b>
     238        */
     239        public function getReferences($table)
     240        {
     241                return $this->db_get_references($table);
     242        }
     243       
     244        public function createTable($name,$fields)
     245        {
     246                return $this->db_create_table($name,$fields);
     247        }
     248       
     249        public function createField($table,$name,$type,$len,$null,$default)
     250        {
     251                return $this->db_create_field($table,$name,$type,$len,$null,$default);
     252        }
     253       
     254        public function createPrimary($table,$name,$cols)
     255        {
     256                return $this->db_create_primary($table,$name,$cols);
     257        }
     258       
     259        public function createUnique($table,$name,$cols)
     260        {
     261                return $this->db_create_unique($table,$name,$cols);
     262        }
     263       
     264        public function createIndex($table,$name,$type,$cols)
     265        {
     266                return $this->db_create_index($table,$name,$type,$cols);
     267        }
     268       
     269        public function createReference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete)
     270        {
     271                return $this->db_create_reference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete);
     272        }
     273       
     274        public function alterField($table,$name,$type,$len,$null,$default)
     275        {
     276                return $this->db_alter_field($table,$name,$type,$len,$null,$default);
     277        }
     278       
     279        public function alterPrimary($table,$name,$newname,$cols)
     280        {
     281                return $this->db_alter_primary($table,$name,$newname,$cols);
     282        }
     283       
     284        public function alterUnique($table,$name,$newname,$cols)
     285        {
     286                return $this->db_alter_unique($table,$name,$newname,$cols);
     287        }
     288       
     289        public function alterIndex($table,$name,$newname,$type,$cols)
     290        {
     291                return $this->db_alter_index($table,$name,$newname,$type,$cols);
     292        }
     293       
     294        public function alterReference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete)
     295        {
     296                return $this->db_alter_reference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete);
     297        }
     298       
     299        public function flushStack()
     300        {
     301        }
     302}
     303?>
     304 No newline at end of file
  • clearbricks/dbschema/class.dbstruct.php

     
     1<?php
     2# ***** BEGIN LICENSE BLOCK *****
     3# This file is part of Clearbricks.
     4# Copyright (c) 2006 Olivier Meunier and contributors. All rights
     5# reserved.
     6#
     7# Clearbricks is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# Clearbricks is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with Clearbricks; if not, write to the Free Software
     19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     20#
     21# ***** END LICENSE BLOCK *****
     22
     23class dbStruct
     24{
     25        protected $con;
     26        protected $prefix;
     27        protected $tables = array();
     28        protected $references = array();
     29       
     30        public function __construct(&$con,$prefix='')
     31        {
     32                $this->con =& $con;
     33                $this->prefix = $prefix;
     34        }
     35       
     36        public function driver()
     37        {
     38                return $this->con->driver();
     39        }
     40       
     41        public function table($name)
     42        {
     43                $this->tables[$name] = new dbStructTable($name);
     44                return $this->tables[$name];
     45        }
     46       
     47        public function __get($name)
     48        {
     49                if (!isset($this->tables[$name])) {
     50                        return $this->table($name);
     51                }
     52               
     53                return $this->tables[$name];
     54        }
     55       
     56        public function reverse()
     57        {
     58                $schema = dbSchema::init($this->con);
     59               
     60                # Get tables
     61                $tables = $schema->getTables();
     62               
     63                foreach ($tables as $t_name)
     64                {
     65                        if ($this->prefix && strpos($t_name,$this->prefix) !== 0) {
     66                                continue;
     67                        }
     68                       
     69                        $t = $this->table($t_name);
     70                       
     71                        # Get columns
     72                        $cols = $schema->getColumns($t_name);
     73                       
     74                        foreach ($cols as $c_name => $col) {
     75                                $type = $schema->dbt2udt($col['type'],$col['len'],$col['default']);
     76                                $t->field($c_name,$type,$col['len'],$col['null'],$col['default'],true);
     77                        }
     78                       
     79                        # Get keys
     80                        $keys = $schema->getKeys($t_name);
     81                       
     82                        foreach ($keys as $k)
     83                        {
     84                                $args = $k['cols'];
     85                                array_unshift($args,$k['name']);
     86                               
     87                                if ($k['primary']) {
     88                                        call_user_func_array(array($t,'primary'),$args);
     89                                } elseif ($k['unique']) {
     90                                        call_user_func_array(array($t,'unique'),$args);
     91                                }
     92                        }
     93                       
     94                        # Get indexes
     95                        $idx = $schema->getIndexes($t_name);
     96                        foreach ($idx as $i)
     97                        {
     98                                $args = array($i['name'],$i['type']);
     99                                $args = array_merge($args,$i['cols']);
     100                                       
     101                                call_user_func_array(array($t,'index'),$args);
     102                        }
     103                       
     104                        # Get foreign keys
     105                        $ref = $schema->getReferences($t_name);
     106                        foreach ($ref as $r) {
     107                                $t->reference($r['name'],$r['c_cols'],$r['p_table'],$r['p_cols'],$r['update'],$r['delete']);
     108                        }
     109                }
     110        }
     111       
     112        /**
     113        Synchronize this schema taken from database with $schema.
     114       
     115        @param  s               <b>dbStruct</b>         Structure to synchronize with
     116        */
     117        public function synchronize($s)
     118        {
     119                $this->tables = array();
     120                $this->reverse();
     121               
     122                if (!($s instanceof self)) {
     123                        throw new Exception('Invalid database schema');
     124                }
     125               
     126                $tables = $s->getTables();
     127               
     128                $table_create = array();
     129                $key_create = array();
     130                $index_create = array();
     131                $reference_create = array();
     132               
     133                $field_create = array();
     134                $field_update = array();
     135                $key_update = array();
     136                $index_update = array();
     137                $reference_update = array();
     138               
     139                $got_work = false;
     140               
     141                $schema = dbSchema::init($this->con);
     142               
     143                foreach ($tables as $tname => $t)
     144                {
     145                        if (!$this->tableExists($tname))
     146                        {
     147                                # Table does not exist, create table
     148                                $table_create[$tname] = $t->getFields();
     149                               
     150                                # Add keys, indexes and references
     151                                $keys = $t->getKeys();
     152                                $indexes = $t->getIndexes();
     153                                $references = $t->getReferences();
     154                               
     155                                foreach ($keys as $k => $v) {
     156                                        $key_create[$tname][$this->prefix.$k] = $v;
     157                                }
     158                                foreach ($indexes as $k => $v) {
     159                                        $index_create[$tname][$this->prefix.$k] = $v;
     160                                }
     161                                foreach ($references as $k => $v) {
     162                                        $v['p_table'] = $this->prefix.$v['p_table'];
     163                                        $reference_create[$tname][$this->prefix.$k] = $v;
     164                                }
     165                               
     166                                $got_work = true;
     167                        }
     168                        else # Table exists
     169                        {
     170                                # Check new fields to create
     171                                $fields = $t->getFields();
     172                                $db_fields = $this->tables[$tname]->getFields();
     173                                foreach ($fields as $fname => $f)
     174                                {
     175                                        if (!$this->tables[$tname]->fieldExists($fname))
     176                                        {
     177                                                # Field doest not exist, create it
     178                                                $field_create[$tname][$fname] = $f;
     179                                                $got_work = true;
     180                                        }
     181                                        elseif ($this->fieldsDiffer($db_fields[$fname],$f))
     182                                        {
     183                                                # Field exists and differs from db version
     184                                                $field_update[$tname][$fname] = $f;
     185                                                $got_work = true;
     186                                        }
     187                                }
     188                               
     189                                # Check keys to add or upgrade
     190                                $keys = $t->getKeys();
     191                                $db_keys = $this->tables[$tname]->getKeys();
     192                               
     193                                foreach ($keys as $kname => $k)
     194                                {
     195                                        if ($k['type'] == 'primary' && $this->con->driver() == 'mysql') {
     196                                                $kname = 'PRIMARY';
     197                                        } else {
     198                                                $kname = $this->prefix.$kname;
     199                                        }
     200                                       
     201                                        $db_kname = $this->tables[$tname]->keyExists($kname,$k['type'],$k['cols']);
     202                                        if (!$db_kname)
     203                                        {
     204                                                # Key does not exist, create it
     205                                                $key_create[$tname][$kname] = $k;
     206                                                $got_work = true;
     207                                        }
     208                                        elseif ($this->keysDiffer($db_kname,$db_keys[$db_kname]['cols'],$kname,$k['cols']))
     209                                        {
     210                                                # Key exists and differs from db version
     211                                                $key_update[$tname][$db_kname] = array_merge(array('name'=>$kname),$k);
     212                                                $got_work = true;
     213                                        }
     214                                }
     215                               
     216                                # Check index to add or upgrade
     217                                $idx = $t->getIndexes();
     218                                $db_idx = $this->tables[$tname]->getIndexes();
     219                               
     220                                foreach ($idx as $iname => $i)
     221                                {
     222                                        $iname = $this->prefix.$iname;
     223                                        $db_iname = $this->tables[$tname]->indexExists($iname,$i['type'],$i['cols']);
     224                                       
     225                                        if (!$db_iname)
     226                                        {
     227                                                # Index does not exist, create it
     228                                                $index_create[$tname][$iname] = $i;
     229                                                $got_work = true;
     230                                        }
     231                                        elseif ($this->indexesDiffer($db_iname,$db_idx[$db_iname],$iname,$i))
     232                                        {
     233                                                # Index exists and differs from db version
     234                                                $index_update[$tname][$db_iname] = array_merge(array('name'=>$iname),$i);
     235                                                $got_work = true;
     236                                        }
     237                                }
     238                               
     239                                # Check references to add or upgrade
     240                                $ref = $t->getReferences();
     241                                $db_ref = $this->tables[$tname]->getReferences();
     242                               
     243                                foreach ($ref as $rname => $r)
     244                                {
     245                                        $rname = $this->prefix.$rname;
     246                                        $r['p_table'] = $this->prefix.$r['p_table'];
     247                                        $db_rname = $this->tables[$tname]->referenceExists($rname,$r['c_cols'],$r['p_table'],$r['p_cols']);
     248                                       
     249                                        if (!$db_rname)
     250                                        {
     251                                                # Reference does not exist, create it
     252                                                $reference_create[$tname][$rname] = $r;
     253                                                $got_work = true;
     254                                        }
     255                                        elseif ($this->referencesDiffer($db_rname,$db_ref[$db_rname],$rname,$r))
     256                                        {
     257                                                $reference_update[$tname][$db_rname] = array_merge(array('name'=>$rname),$r);
     258                                                $got_work = true;
     259                                        }
     260                                }
     261                        }
     262                }
     263               
     264                if (!$got_work) {
     265                        return;
     266                }
     267               
     268                # Create tables
     269                foreach ($table_create as $table => $fields)
     270                {
     271                        $schema->createTable($table,$fields);
     272                }
     273               
     274                # Create new fields
     275                foreach ($field_create as $tname => $fields)
     276                {
     277                        foreach ($fields as $fname => $f) {
     278                                $schema->createField($tname,$fname,$f['type'],$f['len'],$f['null'],$f['default']);
     279                        }
     280                }
     281               
     282                # Update fields
     283                foreach ($field_update as $tname => $fields)
     284                {
     285                        foreach ($fields as $fname => $f) {
     286                                $schema->alterField($tname,$fname,$f['type'],$f['len'],$f['null'],$f['default']);
     287                        }
     288                }
     289               
     290                # Create new keys
     291                foreach ($key_create as $tname => $keys)
     292                {
     293                        foreach ($keys as $kname => $k)
     294                        {
     295                                if ($k['type'] == 'primary') {
     296                                        $schema->createPrimary($tname,$kname,$k['cols']);
     297                                } elseif ($k['type'] == 'unique') {
     298                                        $schema->createUnique($tname,$kname,$k['cols']);
     299                                }
     300                        }
     301                }
     302               
     303                # Update keys
     304                foreach ($key_update as $tname => $keys)
     305                {
     306                        foreach ($keys as $kname => $k)
     307                        {
     308                                if ($k['type'] == 'primary') {
     309                                        $schema->alterPrimary($tname,$kname,$k['name'],$k['cols']);
     310                                } elseif ($k['type'] == 'unique') {
     311                                        $schema->alterUnique($tname,$kname,$k['name'],$k['cols']);
     312                                }
     313                        }
     314                }
     315               
     316                # Create indexes
     317                foreach ($index_create as $tname => $index)
     318                {
     319                        foreach ($index as $iname => $i) {
     320                                $schema->createIndex($tname,$iname,$i['type'],$i['cols']);
     321                        }
     322                }
     323               
     324                # Update indexes
     325                foreach ($index_update as $tname => $index)
     326                {
     327                        foreach ($index as $iname => $i) {
     328                                $schema->alterIndex($tname,$iname,$i['name'],$i['type'],$i['cols']);
     329                        }
     330                }
     331               
     332                # Create references
     333                foreach ($reference_create as $tname => $ref)
     334                {
     335                        foreach ($ref as $rname => $r)
     336                        {
     337                                $schema->createReference($rname,$tname,$r['c_cols'],$r['p_table'],$r['p_cols'],$r['update'],$r['delete']);
     338                        }
     339                }
     340               
     341                # Update references
     342                foreach ($reference_update as $tname => $ref)
     343                {
     344                        foreach ($ref as $rname => $r) {
     345                                $schema->alterReference($rname,$r['name'],$tname,$r['c_cols'],$r['p_table'],$r['p_cols'],$r['update'],$r['delete']);
     346                        }
     347                }
     348               
     349                # Flush execution stack
     350                $schema->flushStack();
     351               
     352                return
     353                count($table_create) + count($key_create) + count($index_create) +
     354                count($reference_create) + count($field_create) + count($field_update) +
     355                count($key_update) + count($index_update) + count($reference_update);
     356        }
     357       
     358        public function getTables()
     359        {
     360                $res = array();
     361                foreach ($this->tables as $t => $v)
     362                {
     363                        $res[$this->prefix.$t] = $v;
     364                }
     365               
     366                return $res;
     367        }
     368       
     369        public function tableExists($name)
     370        {
     371                return isset($this->tables[$name]);
     372        }
     373       
     374        private function fieldsDiffer($db_field,$schema_field)
     375        {
     376                $d_type = $db_field['type'];
     377                $d_len = (integer) $db_field['len'];
     378                $d_default = $db_field['default'];
     379                $d_null = $db_field['null'];
     380               
     381                $s_type = $schema_field['type'];
     382                $s_len = (integer) $schema_field['len'];
     383                $s_default = $schema_field['default'];
     384                $s_null = $schema_field['null'];
     385               
     386                return $d_type != $s_type || $d_len != $s_len || $d_default != $s_default || $d_null != $s_null;
     387        }
     388       
     389        private function keysDiffer($d_name,$d_cols,$s_name,$s_cols)
     390        {
     391                return $d_name != $s_name || $d_cols != $s_cols;
     392        }
     393       
     394        private function indexesDiffer($d_name,$d_i,$s_name,$s_i)
     395        {
     396                return $d_name != $s_name || $d_i['cols'] != $s_i['cols'] || $d_i['type'] != $s_i['type'];
     397        }
     398       
     399        private function referencesDiffer($d_name,$d_r,$s_name,$s_r)
     400        {
     401                return
     402                $d_name != $s_name || $d_r['c_cols'] != $s_r['c_cols']
     403                || $d_r['p_table'] != $s_r['p_table'] || $d_r['p_cols'] != $s_r['p_cols']
     404                || $d_r['update'] != $s_r['update'] || $d_r['delete'] != $s_r['delete'];
     405        }
     406}
     407
     408class dbStructTable
     409{
     410        protected $name;
     411        protected $has_primary = false;
     412       
     413        protected $fields = array();
     414        protected $keys = array();
     415        protected $indexes = array();
     416        protected $references = array();
     417       
     418        /**
     419        Universal data types supported by dbSchema
     420       
     421        SMALLINT        : signed 2 bytes integer
     422        INTEGER : signed 4 bytes integer
     423        BIGINT  : signed 8 bytes integer
     424        REAL            : signed 4 bytes floating point number
     425        FLOAT   : signed 8 bytes floating point number
     426        NUMERIC : exact numeric type
     427       
     428        DATE            : Calendar date (day, month and year)
     429        TIME            : Time of day
     430        TIMESTAMP       : Date and time
     431       
     432        CHAR            : A fixed n-length character string
     433        VARCHAR : A variable length character string
     434        TEXT            : A variable length of text
     435        */
     436        protected $allowed_types = array(
     437                'smallint','integer','bigint','real','float','numeric',
     438                'date','time','timestamp',
     439                'char','varchar','text'
     440        );
     441       
     442        public function __construct($name)
     443        {
     444                $this->name = $name;
     445                return $this;
     446        }
     447       
     448        public function getFields()
     449        {
     450                return $this->fields;
     451        }
     452       
     453        public function getKeys($primary=null)
     454        {
     455                return $this->keys;
     456        }
     457       
     458        public function getIndexes()
     459        {
     460                return $this->indexes;
     461        }
     462       
     463        public function getReferences()
     464        {
     465                return $this->references;
     466        }
     467       
     468        public function fieldExists($name)
     469        {
     470                return isset($this->fields[$name]);
     471        }
     472       
     473        public function keyExists($name,$type,$cols)
     474        {
     475                # Look for key with the same name
     476                if (isset($this->keys[$name])) {
     477                        return $name;
     478                }
     479               
     480                # Look for key with the same columns list and type
     481                foreach ($this->keys as $n => $k)
     482                {
     483                        if ($k['cols'] == $cols && $k['type'] == $type) {
     484                                # Same columns and type, return new name
     485                                return $n;
     486                        }
     487                }
     488               
     489                return false;
     490        }
     491       
     492        public function indexExists($name,$type,$cols)
     493        {
     494                # Look for key with the same name
     495                if (isset($this->indexes[$name])) {
     496                        return $name;
     497                }
     498               
     499                # Look for index with the same columns list and type
     500                foreach ($this->indexes as $n => $i)
     501                {
     502                        if ($i['cols'] == $cols && $i['type'] == $type) {
     503                                # Same columns and type, return new name
     504                                return $n;
     505                        }
     506                }
     507               
     508                return false;
     509        }
     510       
     511        public function referenceExists($name,$c_cols,$p_table,$p_cols)
     512        {
     513                if (isset($this->references[$name])) {
     514                        return $name;
     515                }
     516               
     517                # Look for reference with same chil columns, parent table and columns
     518                foreach ($this->references as $n => $r)
     519                {
     520                        if ($c_cols == $r['c_cols'] && $p_table == $r['p_table'] && $p_cols == $r['p_cols']) {
     521                                # Only name differs, return new name
     522                                return $n;
     523                        }
     524                }
     525               
     526                return false;
     527        }
     528       
     529        public function field($name,$type,$len,$null=true,$default=false,$to_null=false)
     530        {
     531                $type = strtolower($type);
     532               
     533                if (!in_array($type,$this->allowed_types))
     534                {
     535                        if ($to_null) {
     536                                $type = null;
     537                        } else {
     538                                throw new Exception('Invalid data type '.$type.' in schema');
     539                        }
     540                }
     541               
     542                $this->fields[$name] = array(
     543                        'type' => $type,
     544                        'len' => (integer) $len,
     545                        'default' => $default,
     546                        'null' => (boolean) $null
     547                );
     548               
     549                return $this;
     550        }
     551       
     552        public function __call($name,$args)
     553        {
     554                array_unshift($args,$name);
     555                return call_user_func_array(array($this,'field'),$args);
     556        }
     557       
     558        public function primary($name,$col)
     559        {
     560                if ($this->has_primary) {
     561                        throw new Exception(sprintf('Table %s already has a primary key',$this->name));
     562                }
     563               
     564                $cols = func_get_args();
     565                array_shift($cols);
     566               
     567                return $this->newKey('primary',$name,$cols);
     568        }
     569       
     570        public function unique($name,$col)
     571        {
     572                $cols = func_get_args();
     573                array_shift($cols);
     574               
     575                return $this->newKey('unique',$name,$cols);
     576        }
     577       
     578        public function index($name,$type,$col)
     579        {
     580                $cols = func_get_args();
     581                array_shift($cols);
     582                array_shift($cols);
     583               
     584                $this->checkCols($cols);
     585               
     586                $this->indexes[$name] = array(
     587                        'type' => strtolower($type),
     588                        'cols' => $cols
     589                );
     590               
     591                return $this;
     592        }
     593       
     594        public function reference($name,$c_cols,$p_table,$p_cols,$update=false,$delete=false)
     595        {
     596                if (!is_array($p_cols)) {
     597                        $p_cols = array($p_cols);
     598                }
     599                if (!is_array($c_cols)) {
     600                        $c_cols = array($c_cols);
     601                }
     602               
     603                $this->checkCols($c_cols);
     604               
     605                $this->references[$name] = array(
     606                        'c_cols' => $c_cols,
     607                        'p_table' => $p_table,
     608                        'p_cols' => $p_cols,
     609                        'update' => $update,
     610                        'delete' => $delete
     611                );
     612        }
     613       
     614        protected function newKey($type,$name,$cols)
     615        {
     616                $this->checkCols($cols);
     617               
     618                $this->keys[$name] = array(
     619                        'type' => $type,
     620                        'cols' => $cols
     621                );
     622               
     623                if ($type == 'primary') {
     624                        $this->has_primary = true;
     625                }
     626               
     627                return $this;
     628        }
     629       
     630        protected function checkCols($cols)
     631        {
     632                foreach ($cols as $v) {
     633                        if (!preg_match('/^\(.*?\)$/',$v) && !isset($this->fields[$v])) {
     634                                throw new Exception(sprintf('Field %s does not exist in table %s',$v,$this->name));
     635                        }
     636                }
     637        }
     638}
     639?>
     640 No newline at end of file
  • clearbricks/dbschema/class.mysql.dbschema.php

     
     1<?php
     2# ***** BEGIN LICENSE BLOCK *****
     3# This file is part of Clearbricks.
     4# Copyright (c) 2007 Olivier Meunier and contributors. All rights
     5# reserved.
     6#
     7# Clearbricks is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# Clearbricks is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with Clearbricks; if not, write to the Free Software
     19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     20#
     21# ***** END LICENSE BLOCK *****
     22
     23class mysqlSchema extends dbSchema implements i_dbSchema
     24{
     25        public function dbt2udt($type,&$len,&$default)
     26        {
     27                $type = parent::dbt2udt($type,$len,$default);
     28               
     29                switch ($type)
     30                {
     31                        case 'float':
     32                                return 'real';
     33                        case 'double':
     34                                return 'float';
     35                        case 'datetime':
     36                                # DATETIME real type is TIMESTAMP
     37                                if ($default == "'1970-01-01 00:00:00'") {
     38                                        # Bad hack
     39                                        $default = 'now()';
     40                                }
     41                                return 'timestamp';
     42                        case 'integer':
     43                        case 'mediumint':
     44                                if ($len == 11) { $len = 0; }
     45                                return 'integer';
     46                        case 'bigint':
     47                                if ($len == 20) { $len = 0; }
     48                                break;
     49                        case 'tinyint':
     50                        case 'smallint':
     51                                if ($len == 6) { $len = 0; }
     52                                return 'smallint';
     53                        case 'numeric':
     54                                $len = 0;
     55                                break;
     56                        case 'tinytext':
     57                        case 'longtext':
     58                                return 'text';
     59                }
     60               
     61                return $type;
     62        }
     63       
     64        public function udt2dbt($type,&$len,&$default)
     65        {
     66                $type = parent::udt2dbt($type,$len,$default);
     67               
     68                switch ($type)
     69                {
     70                        case 'real':
     71                                return 'float';
     72                        case 'float':
     73                                return 'double';
     74                        case 'timestamp':
     75                                if ($default == 'now()') {
     76                                        # MySQL does not support now() default value...
     77                                        $default = "'1970-01-01 00:00:00'";
     78                                }
     79                                return 'datetime';
     80                        case 'text':
     81                                $len = 0;
     82                                return 'longtext';
     83                }
     84               
     85                return $type;
     86        }
     87       
     88        public function db_get_tables()
     89        {
     90                $sql = 'SHOW TABLES';
     91                $rs = $this->con->select($sql);
     92               
     93                $res = array();
     94                while ($rs->fetch()) {
     95                        $res[] = $rs->f(0);
     96                }
     97                return $res;
     98        }
     99       
     100        public function db_get_columns($table)
     101        {
     102                $sql = 'SHOW COLUMNS FROM '.$this->con->escapeSystem($table);
     103                $rs = $this->con->select($sql);
     104               
     105                $res = array();
     106                while ($rs->fetch())
     107                {
     108                        $field = trim($rs->f('Field'));
     109                        $type = trim($rs->f('Type'));
     110                        $null = strtolower($rs->f('Null')) == 'yes';
     111                        $default = $rs->f('Default');
     112                       
     113                        $len = null;
     114                        if (preg_match('/^(.+?)\(([\d,]+)\)$/si',$type,$m)) {
     115                                $type = $m[1];
     116                                $len = (integer) $m[2];
     117                        }
     118                       
     119                        if ($default != '' && !is_numeric($default)) {
     120                                $default = "'".$default."'";
     121                        }
     122                       
     123                        $res[$field] = array(
     124                                'type' => $type,
     125                                'len' => $len,
     126                                'null' => $null,
     127                                'default' => $default
     128                        );
     129                }
     130                return $res;
     131        }
     132       
     133        public function db_get_keys($table)
     134        {
     135                $sql = 'SHOW INDEX FROM '.$this->con->escapeSystem($table);
     136                $rs = $this->con->select($sql);
     137               
     138                $t = array();
     139                $res = array();
     140                while ($rs->fetch())
     141                {
     142                        $key_name = $rs->f('Key_name');
     143                        $unique = $rs->f('Non_unique') == 0;
     144                        $seq = $rs->f('Seq_in_index');
     145                        $col_name = $rs->f('Column_name');
     146                       
     147                        if ($key_name == 'PRIMARY' || $unique) {
     148                                $t[$key_name]['cols'][$seq] = $col_name;
     149                                $t[$key_name]['unique'] = $unique;
     150                        }
     151                }
     152               
     153                foreach ($t as $name => $idx)
     154                {
     155                        ksort($idx['cols']);
     156                       
     157                        $res[] = array(
     158                                'name' => $name,
     159                                'primary' => $name == 'PRIMARY',
     160                                'unique' => $idx['unique'],
     161                                'cols' => array_values($idx['cols'])
     162                        );
     163                }
     164               
     165                return $res;
     166        }
     167       
     168        public function db_get_indexes($table)
     169        {
     170                $sql = 'SHOW INDEX FROM '.$this->con->escapeSystem($table);
     171                $rs = $this->con->select($sql);
     172               
     173                $t = array();
     174                $res = array();
     175                while ($rs->fetch())
     176                {
     177                        $key_name = $rs->f('Key_name');
     178                        $unique = $rs->f('Non_unique') == 0;
     179                        $seq = $rs->f('Seq_in_index');
     180                        $col_name = $rs->f('Column_name');
     181                        $type = $rs->f('Index_type');
     182                       
     183                        if ($key_name != 'PRIMARY' && !$unique) {
     184                                $t[$key_name]['cols'][$seq] = $col_name;
     185                                $t[$key_name]['type'] = $type;
     186                        }
     187                }
     188               
     189                foreach ($t as $name => $idx)
     190                {
     191                        ksort($idx['cols']);
     192                       
     193                        $res[] = array(
     194                                'name' => $name,
     195                                'type' => $idx['type'],
     196                                'cols' => $idx['cols']
     197                        );
     198                }
     199               
     200                return $res;
     201        }
     202       
     203        public function db_get_references($table)
     204        {
     205                $sql = 'SHOW CREATE TABLE '.$this->con->escapeSystem($table);
     206                $rs = $this->con->select($sql);
     207               
     208                $s = $rs->f(1);
     209               
     210                $res = array();
     211               
     212                $n = preg_match_all('/^\s*CONSTRAINT\s+`(.+?)`\s+FOREIGN\s+KEY\s+\((.+?)\)\s+REFERENCES\s+`(.+?)`\s+\((.+?)\)(.*?)$/msi',$s,$match);
     213                if ($n > 0)
     214                {
     215                        foreach ($match[1] as $i => $name)
     216                        {
     217                                # Columns transformation
     218                                $t_cols = str_replace('`','',$match[2][$i]);
     219                                $t_cols = explode(',',$t_cols);
     220                                $r_cols = str_replace('`','',$match[4][$i]);
     221                                $r_cols = explode(',',$r_cols);
     222                               
     223                                # ON UPDATE|DELETE
     224                                $on = trim($match[5][$i],', ');
     225                                $on_delete = null;
     226                                $on_update = null;
     227                                if ($on != '') {
     228                                        if (preg_match('/ON DELETE (.+?)(?:\s+ON|$)/msi',$on,$m)) {
     229                                                $on_delete = strtolower(trim($m[1]));
     230                                        }
     231                                        if (preg_match('/ON UPDATE (.+?)(?:\s+ON|$)/msi',$on,$m)) {
     232                                                $on_update = strtolower(trim($m[1]));
     233                                        }
     234                                }
     235                               
     236                                $res[] = array (
     237                                        'name' => $name,
     238                                        'c_cols' => $t_cols,
     239                                        'p_table' => $match[3][$i],
     240                                        'p_cols' => $r_cols,
     241                                        'update' => $on_update,
     242                                        'delete' => $on_delete
     243                                );
     244                        }
     245                }
     246                return $res;
     247        }
     248       
     249        public function db_create_table($name,$fields)
     250        {
     251                $a = array();
     252               
     253                foreach ($fields as $n => $f)
     254                {
     255                        $type = $f['type'];
     256                        $len = (integer) $f['len'];
     257                        $default = $f['default'];
     258                        $null = $f['null'];
     259                       
     260                        $type = $this->udt2dbt($type,$len,$default);
     261                        $len = $len > 0 ? '('.$len.')' : '';
     262                        $null = $null ? 'NULL' : 'NOT NULL';
     263                       
     264                        if ($default === null) {
     265                                $default = 'DEFAULT NULL';
     266                        } elseif ($default !== false) {
     267                                $default = 'DEFAULT '.$default.' ';
     268                        } else {
     269                                $default = '';
     270                        }
     271                       
     272                        $a[] =
     273                        $this->con->escapeSystem($n).' '.
     274                        $type.$len.' '.$null.' '.$default;
     275                }
     276               
     277                $sql =
     278                'CREATE TABLE '.$this->con->escapeSystem($name)." (\n".
     279                        implode(",\n",$a).
     280                "\n) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin ";
     281               
     282                $this->con->execute($sql);
     283        }
     284       
     285        public function db_create_field($table,$name,$type,$len,$null,$default)
     286        {
     287                $type = $this->udt2dbt($type,$len,$default);
     288                $len = (integer) $len > 0 ? '('.(integer) $len.')' : '';
     289                $null = $null ? 'NULL' : 'NOT NULL';
     290               
     291                if ($default === null) {
     292                        $default = 'DEFAULT NULL';
     293                } elseif ($default !== false) {
     294                        $default = 'DEFAULT '.$default;
     295                } else {
     296                        $default = '';
     297                }
     298               
     299                $sql =
     300                'ALTER TABLE '.$this->con->escapeSystem($table).' '.
     301                'ADD COLUMN '.$this->con->escapeSystem($name).' '.
     302                $type.$len.' '.$null.' '.$default;
     303               
     304                $this->con->execute($sql);
     305        }
     306       
     307        public function db_create_primary($table,$name,$cols)
     308        {
     309                $c = array();
     310                foreach ($cols as $v) {
     311                        $c[] = $this->con->escapeSystem($v);
     312                }
     313               
     314                $sql =
     315                'ALTER TABLE '.$this->con->escapeSystem($table).' '.
     316                'ADD CONSTRAINT PRIMARY KEY ('.implode(',',$c).') ';
     317               
     318                $this->con->execute($sql);
     319        }
     320       
     321        public function db_create_unique($table,$name,$cols)
     322        {
     323                $c = array();
     324                foreach ($cols as $v) {
     325                        $c[] = $this->con->escapeSystem($v);
     326                }
     327               
     328                $sql =
     329                'ALTER TABLE '.$this->con->escapeSystem($table).' '.
     330                'ADD CONSTRAINT UNIQUE KEY '.$this->con->escapeSystem($name).' '.
     331                '('.implode(',',$c).') ';
     332               
     333                $this->con->execute($sql);
     334        }
     335       
     336        public function db_create_index($table,$name,$type,$cols)
     337        {
     338                $c = array();
     339                foreach ($cols as $v) {
     340                        $c[] = $this->con->escapeSystem($v);
     341                }
     342               
     343                $sql =
     344                'ALTER TABLE '.$this->con->escapeSystem($table).' '.
     345                'ADD INDEX '.$this->con->escapeSystem($name).' USING '.$type.' '.
     346                '('.implode(',',$c).') ';
     347               
     348                $this->con->execute($sql);
     349        }
     350       
     351        public function db_create_reference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete)
     352        {
     353                $c = array();
     354                $p = array();
     355                foreach ($c_cols as $v) {
     356                        $c[] = $this->con->escapeSystem($v);
     357                }
     358                foreach ($p_cols as $v) {
     359                        $p[] = $this->con->escapeSystem($v);
     360                }
     361               
     362                $sql =
     363                'ALTER TABLE '.$this->con->escapeSystem($c_table).' '.
     364                'ADD CONSTRAINT '.$name.' FOREIGN KEY '.
     365                '('.implode(',',$c).') '.
     366                'REFERENCES '.$this->con->escapeSystem($p_table).' '.
     367                '('.implode(',',$p).') ';
     368               
     369                if ($update) {
     370                        $sql .= 'ON UPDATE '.$update.' ';
     371                }
     372                if ($delete) {
     373                        $sql .= 'ON DELETE '.$delete.' ';
     374                }
     375               
     376                $this->con->execute($sql);
     377        }
     378       
     379        public function db_alter_field($table,$name,$type,$len,$null,$default)
     380        {
     381                $type = $this->udt2dbt($type,$len,$default);
     382                $len = (integer) $len > 0 ? '('.(integer) $len.')' : '';
     383                $null = $null ? 'NULL' : 'NOT NULL';
     384               
     385                if ($default === null) {
     386                        $default = 'DEFAULT NULL';
     387                } elseif ($default !== false) {
     388                        $default = 'DEFAULT '.$default;
     389                } else {
     390                        $default = '';
     391                }
     392               
     393                $sql =
     394                'ALTER TABLE '.$this->con->escapeSystem($table).' '.
     395                'CHANGE COLUMN '.$this->con->escapeSystem($name).' '.$this->con->escapeSystem($name).' '.
     396                $type.$len.' '.$null.' '.$default;
     397               
     398                $this->con->execute($sql);
     399        }
     400       
     401        public function db_alter_primary($table,$name,$newname,$cols)
     402        {
     403                $c = array();
     404                foreach ($cols as $v) {
     405                        $c[] = $this->con->escapeSystem($v);
     406                }
     407               
     408                $sql =
     409                'ALTER TABLE '.$this->con->escapeSystem($table).' '.
     410                'DROP PRIMARY KEY, ADD PRIMARY KEY '.
     411                '('.implode(',',$c).') ';
     412               
     413                $this->con->execute($sql);
     414        }
     415       
     416        public function db_alter_unique($table,$name,$newname,$cols)
     417        {
     418                $c = array();
     419                foreach ($cols as $v) {
     420                        $c[] = $this->con->escapeSystem($v);
     421                }
     422               
     423                $sql =
     424                'ALTER TABLE '.$this->con->escapeSystem($table).' '.
     425                'DROP INDEX '.$this->con->escapeSystem($name).', '.
     426                'ADD UNIQUE '.$this->con->escapeSystem($newname).' '.
     427                '('.implode(',',$c).') ';
     428               
     429                $this->con->execute($sql);
     430        }
     431       
     432        public function db_alter_index($table,$name,$newname,$type,$cols)
     433        {
     434                $c = array();
     435                foreach ($cols as $v) {
     436                        $c[] = $this->con->escapeSystem($v);
     437                }
     438               
     439                $sql =
     440                'ALTER TABLE '.$this->con->escapeSystem($table).' '.
     441                'DROP INDEX '.$this->con->escapeSystem($name).', '.
     442                'ADD INDEX '.$this->con->escapeSystem($newname).' '.
     443                'USING '.$type.' '.
     444                '('.implode(',',$c).') ';
     445               
     446                $this->con->execute($sql);
     447        }
     448       
     449        public function db_alter_reference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete)
     450        {
     451                $sql =
     452                'ALTER TABLE '.$this->con->escapeSystem($c_table).' '.
     453                'DROP FOREIGN KEY '.$this->con->escapeSystem($name);
     454               
     455                $this->con->execute($sql);
     456                $this->createReference($newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete);
     457        }
     458}
     459?>
     460 No newline at end of file
  • clearbricks/dbschema/class.pgsql.dbschema.php

     
     1<?php
     2# ***** BEGIN LICENSE BLOCK *****
     3# This file is part of Clearbricks.
     4# Copyright (c) 2007 Olivier Meunier and contributors. All rights
     5# reserved.
     6#
     7# Clearbricks is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# Clearbricks is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with Clearbricks; if not, write to the Free Software
     19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     20#
     21# ***** END LICENSE BLOCK *****
     22
     23class pgsqlSchema extends dbSchema implements i_dbSchema
     24{
     25        protected $ref_actions_map = array(
     26                'a' => 'no action',
     27                'r' => 'restrict',
     28                'c' => 'cascade',
     29                'n' => 'set null',
     30                'd' => 'set default'
     31        );
     32       
     33        public function dbt2udt($type,&$len,&$default)
     34        {
     35                $type = parent::dbt2udt($type,$len,$default);
     36               
     37                return $type;
     38        }
     39       
     40        public function udt2dbt($type,&$len,&$default)
     41        {
     42                $type = parent::udt2dbt($type,$len,$default);
     43               
     44                return $type;
     45        }
     46       
     47        public function db_get_tables()
     48        {
     49                $sql =
     50                'SELECT table_name '.
     51                'FROM information_schema.tables '.
     52                "WHERE table_schema = 'public' ";
     53               
     54                $rs = $this->con->select($sql);
     55               
     56                $res = array();
     57                while ($rs->fetch()) {
     58                        $res[] = $rs->f(0);
     59                }
     60                return $res;
     61        }
     62       
     63        public function db_get_columns($table)
     64        {
     65                $sql =
     66                'SELECT column_name, udt_name, character_maximum_length, '.
     67                'is_nullable, column_default '.
     68                'FROM information_schema.columns '.
     69                "WHERE table_name = '".$this->con->escape($table)."' ";
     70               
     71                $rs = $this->con->select($sql);
     72               
     73                $res = array();
     74                while ($rs->fetch())
     75                {
     76                        $field = trim($rs->column_name);
     77                        $type = trim($rs->udt_name);
     78                        $null = strtolower($rs->is_nullable) == 'yes';
     79                        $default = $rs->column_default;
     80                        $len = $rs->character_maximum_length;
     81                       
     82                        if ($len == '') {
     83                                $len = null;
     84                        }
     85                       
     86                        $default = preg_replace('/::([\w\d\s]*)$/','',$default);
     87                       
     88                        $res[$field] = array(
     89                                'type' => $type,
     90                                'len' => $len,
     91                                'null' => $null,
     92                                'default' => $default
     93                        );
     94                }
     95               
     96                return $res;
     97        }
     98       
     99        public function db_get_keys($table)
     100        {
     101                $sql =
     102                'SELECT DISTINCT ON(cls.relname) cls.oid, cls.relname as idxname, indisunique::integer, indisprimary::integer, '.
     103                'indnatts, tab.relname as tabname, contype, amname '.
     104                'FROM pg_index idx '.
     105                'JOIN pg_class cls ON cls.oid=indexrelid '.
     106                'JOIN pg_class tab ON tab.oid=indrelid '.
     107                'LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace '.
     108                'JOIN pg_namespace n ON n.oid=tab.relnamespace '.
     109                'JOIN pg_am am ON am.oid=cls.relam '.
     110                "LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0') ".
     111                'LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) '.
     112                'LEFT OUTER JOIN pg_description des ON des.objoid=con.oid '.
     113                'LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) '.
     114                "WHERE tab.relname = '".$this->con->escape($table)."' ".
     115                "AND contype IN ('p','u') ".
     116                'ORDER BY cls.relname ';
     117               
     118                $rs = $this->con->select($sql);
     119               
     120                $res = array();
     121                while ($rs->fetch())
     122                {
     123                        $k = array(
     124                                'name' => $rs->idxname,
     125                                'primary' => (boolean) $rs->indisprimary,
     126                                'unique' => (boolean) $rs->indisunique,
     127                                'cols' => array()
     128                        );
     129                       
     130                        for ($i=1; $i<=$rs->indnatts; $i++) {
     131                                $cols = $this->con->select('SELECT pg_get_indexdef('.$rs->oid.'::oid, '.$i.', true);');
     132                                $k['cols'][] = $cols->f(0);
     133                        }
     134                       
     135                        $res[] = $k;
     136                }
     137               
     138                return $res;
     139        }
     140       
     141        public function db_get_indexes($table)
     142        {
     143                $sql =
     144                'SELECT DISTINCT ON(cls.relname) cls.oid, cls.relname as idxname, n.nspname, '.
     145                'indnatts, tab.relname as tabname, contype, amname '.
     146                'FROM pg_index idx '.
     147                'JOIN pg_class cls ON cls.oid=indexrelid '.
     148                'JOIN pg_class tab ON tab.oid=indrelid '.
     149                'LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace '.
     150                'JOIN pg_namespace n ON n.oid=tab.relnamespace '.
     151                'JOIN pg_am am ON am.oid=cls.relam '.
     152                "LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0') ".
     153                'LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) '.
     154                'LEFT OUTER JOIN pg_description des ON des.objoid=con.oid '.
     155                'LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) '.
     156                "WHERE tab.relname = '".$this->con->escape($table)."' ".
     157                'AND conname IS NULL '.
     158                'ORDER BY cls.relname ';
     159               
     160                $rs = $this->con->select($sql);
     161               
     162                $res = array();
     163                while ($rs->fetch())
     164                {
     165                        $k = array(
     166                                'name' => $rs->idxname,
     167                                'type' => $rs->amname,
     168                                'cols' => array()
     169                        );
     170                       
     171                        for ($i=1; $i<=$rs->indnatts; $i++) {
     172                                $cols = $this->con->select('SELECT pg_get_indexdef('.$rs->oid.'::oid, '.$i.', true);');
     173                                $k['cols'][] = $cols->f(0);
     174                        }
     175                       
     176                        $res[] = $k;
     177                }
     178               
     179                return $res;
     180        }
     181       
     182        public function db_get_references($table)
     183        {
     184                $sql =
     185                'SELECT ct.oid, conname, condeferrable, condeferred, confupdtype, '.
     186                'confdeltype, confmatchtype, conkey, confkey, conrelid, confrelid, cl.relname as fktab, '.
     187                'cr.relname as reftab '.
     188                'FROM pg_constraint ct '.
     189                'JOIN pg_class cl ON cl.oid=conrelid '.
     190                'JOIN pg_namespace nl ON nl.oid=cl.relnamespace '.
     191                'JOIN pg_class cr ON cr.oid=confrelid '.
     192                'JOIN pg_namespace nr ON nr.oid=cr.relnamespace '.
     193                "WHERE contype='f' ".
     194                "AND cl.relname = '".$this->con->escape($table)."' ".
     195                'ORDER BY conname ';
     196               
     197                $rs = $this->con->select($sql);
     198               
     199                $cols_sql =
     200                'SELECT a1.attname as conattname, a2.attname as confattname '.
     201                'FROM pg_attribute a1, pg_attribute a2 '.
     202                'WHERE a1.attrelid=%1$s::oid AND a1.attnum=%2$s '.
     203                'AND a2.attrelid=%3$s::oid AND a2.attnum=%4$s ';
     204               
     205                $res = array();
     206                while ($rs->fetch())
     207                {
     208                        $conkey = preg_replace('/[^\d]/','',$rs->conkey);
     209                        $confkey = preg_replace('/[^\d]/','',$rs->confkey);
     210                       
     211                        $k = array(
     212                                'name' => $rs->conname,
     213                                'c_cols' => array(),
     214                                'p_table' => $rs->reftab,
     215                                'p_cols' => array(),
     216                                'update' => $this->ref_actions_map[$rs->confupdtype],
     217                                'delete' => $this->ref_actions_map[$rs->confdeltype]
     218                        );
     219                       
     220                        $cols = $this->con->select(sprintf($cols_sql,$rs->conrelid,$conkey,$rs->confrelid,$confkey));
     221                        while ($cols->fetch()) {
     222                                $k['c_cols'][] = $cols->conattname;
     223                                $k['p_cols'][] = $cols->confattname;
     224                        }
     225                       
     226                        $res[] = $k;
     227                }
     228               
     229                return $res;
     230        }
     231       
     232        public function db_create_table($name,$fields)
     233        {
     234                $a = array();
     235               
     236                foreach ($fields as $n => $f)
     237                {
     238                        $type = $f['type'];
     239                        $len = (integer) $f['len'];
     240                        $default = $f['default'];
     241                        $null = $f['null'];
     242                       
     243                        $type = $this->udt2dbt($type,$len,$default);
     244                        $len = $len > 0 ? '('.$len.')' : '';
     245                        $null = $null ? 'NULL' : 'NOT NULL';
     246                       
     247                        if ($default === null) {
     248                                $default = 'DEFAULT NULL';
     249                        } elseif ($default !== false) {
     250                                $default = 'DEFAULT '.$default.' ';
     251                        } else {
     252                                $default = '';
     253                        }
     254                       
     255                        $a[] =
     256                        $n.' '.
     257                        $type.$len.' '.$null.' '.$default;
     258                }
     259               
     260                $sql =
     261                'CREATE TABLE '.$name." (\n".
     262                        implode(",\n",$a).
     263                "\n)";
     264               
     265                $this->con->execute($sql);
     266        }
     267       
     268        public function db_create_field($table,$name,$type,$len,$null,$default)
     269        {
     270                $type = $this->udt2dbt($type,$len,$default);
     271                $len = $len > 0 ? '('.$len.')' : '';
     272                $null = $null ? 'NULL' : 'NOT NULL';
     273               
     274                if ($default === null) {
     275                        $default = 'DEFAULT NULL';
     276                } elseif ($default !== false) {
     277                        $default = 'DEFAULT '.$default.' ';
     278                } else {
     279                        $default = '';
     280                }
     281               
     282                $sql =
     283                'ALTER TABLE '.$table.' ADD COLUMN '.$name.' '.
     284                $type.$len.' '.$null.' '.$default;
     285               
     286                $this->con->execute($sql);
     287        }
     288       
     289        public function db_create_primary($table,$name,$cols)
     290        {
     291                $sql =
     292                'ALTER TABLE '.$table.' '.
     293                'ADD CONSTRAINT '.$name.' PRIMARY KEY ('.implode(",",$cols).') ';
     294               
     295                $this->con->execute($sql);
     296        }
     297       
     298        public function db_create_unique($table,$name,$cols)
     299        {
     300                $sql =
     301                'ALTER TABLE '.$table.' '.
     302                'ADD CONSTRAINT '.$name.' UNIQUE ('.implode(',',$cols).') ';
     303               
     304                $this->con->execute($sql);
     305        }
     306       
     307        public function db_create_index($table,$name,$type,$cols)
     308        {
     309                $sql =
     310                'CREATE INDEX '.$name.' ON '.$table.' USING '.$type.
     311                '('.implode(',',$cols).') ';
     312               
     313                $this->con->execute($sql);
     314        }
     315       
     316        public function db_create_reference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete)
     317        {
     318                $sql =
     319                'ALTER TABLE '.$c_table.' '.
     320                'ADD CONSTRAINT '.$name.' FOREIGN KEY '.
     321                '('.implode(',',$c_cols).') '.
     322                'REFERENCES '.$p_table.' '.
     323                '('.implode(',',$p_cols).') ';
     324               
     325                if ($update) {
     326                        $sql .= 'ON UPDATE '.$update.' ';
     327                }
     328                if ($delete) {
     329                        $sql .= 'ON DELETE '.$delete.' ';
     330                }
     331               
     332                $this->con->execute($sql);
     333        }
     334       
     335        public function db_alter_field($table,$name,$type,$len,$null,$default)
     336        {
     337                $type = $this->udt2dbt($type,$len,$default);
     338                $len = (integer) $len > 0 ? '('.(integer) $len.')' : '';
     339               
     340                $sql = 'ALTER TABLE '.$table.' ALTER COLUMN '.$name.' TYPE '.$type.$len;
     341                $this->con->execute($sql);
     342               
     343                if ($default === null) {
     344                        $default = 'SET DEFAULT NULL';
     345                } elseif ($default !== false) {
     346                        $default = 'SET DEFAULT '.$default;
     347                } else {
     348                        $default = 'DROP DEFAULT';
     349                }
     350               
     351                $sql = 'ALTER TABLE '.$table.' ALTER COLUMN '.$name.' '.$default;
     352                $this->con->execute($sql);
     353               
     354                $null = $null ? 'DROP NOT NULL' : 'SET NOT NULL';
     355                $sql = 'ALTER TABLE '.$table.' ALTER COLUMN '.$name.' '.$null;
     356                $this->con->execute($sql);
     357        }
     358       
     359        public function db_alter_primary($table,$name,$newname,$cols)
     360        {
     361                $sql = 'ALTER TABLE '.$table.' DROP CONSTRAINT '.$name;
     362                $this->con->execute($sql);
     363               
     364                $this->createPrimary($table,$newname,$cols);
     365        }
     366       
     367        public function db_alter_unique($table,$name,$newname,$cols)
     368        {
     369                $sql = 'ALTER TABLE '.$table.' DROP CONSTRAINT '.$name;
     370                $this->con->execute($sql);
     371               
     372                $this->createUnique($table,$newname,$cols);
     373        }
     374       
     375        public function db_alter_index($table,$name,$newname,$type,$cols)
     376        {
     377                $sql = 'DROP INDEX '.$name;
     378                $this->con->execute($sql);
     379               
     380                $this->createIndex($table,$newname,$type,$cols);
     381        }
     382       
     383        public function db_alter_reference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete)
     384        {
     385                $sql = 'ALTER TABLE '.$c_table.' DROP CONSTRAINT '.$name;
     386                $this->con->execute($sql);
     387               
     388                $this->createReference($newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete);
     389        }
     390}
     391?>
     392 No newline at end of file
  • clearbricks/dbschema/class.sqlite.dbschema.php

     
     1<?php
     2# ***** BEGIN LICENSE BLOCK *****
     3# This file is part of Clearbricks.
     4# Copyright (c) 2007 Olivier Meunier and contributors. All rights
     5# reserved.
     6#
     7# Clearbricks is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# Clearbricks is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with Clearbricks; if not, write to the Free Software
     19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     20#
     21# ***** END LICENSE BLOCK *****
     22
     23class sqliteSchema extends dbSchema implements i_dbSchema
     24{
     25        private $table_hist = array();
     26       
     27        private $table_stack = array(); // Stack for tables creation
     28        private $x_stack = array();             // Execution stack
     29       
     30        public function dbt2udt($type,&$len,&$default)
     31        {
     32                $type = parent::dbt2udt($type,$len,$default);
     33               
     34                switch ($type)
     35                {
     36                        case 'float':
     37                                return 'real';
     38                        case 'double':
     39                                return 'float';
     40                        case 'timestamp':
     41                                # DATETIME real type is TIMESTAMP
     42                                if ($default == "'1970-01-01 00:00:00'") {
     43                                        # Bad hack
     44                                        $default = 'now()';
     45                                }
     46                                return 'timestamp';
     47                        case 'integer':
     48                        case 'mediumint':
     49                        case 'bigint':
     50                        case 'tinyint':
     51                        case 'smallint':
     52                        case 'numeric':
     53                                return 'integer';
     54                        case 'tinytext':
     55                        case 'longtext':
     56                                return 'text';
     57                }
     58               
     59                return $type;
     60        }
     61       
     62        public function udt2dbt($type,&$len,&$default)
     63        {
     64                $type = parent::udt2dbt($type,$len,$default);
     65               
     66                switch ($type)
     67                {
     68                        case 'integer':
     69                        case 'smallint':
     70                        case 'bigint':
     71                                return 'integer';
     72                        case 'real':
     73                        case 'float:':
     74                                return 'real';
     75                        case 'date':
     76                        case 'time':
     77                                return 'timestamp';
     78                        case 'timestamp':
     79                                if ($default == 'now()') {
     80                                        # SQLite does not support now() default value...
     81                                        $default = "'1970-01-01 00:00:00'";
     82                                }
     83                                return $type;
     84                }
     85               
     86                return $type;
     87        }
     88       
     89        public function flushStack()
     90        {
     91                foreach ($this->table_stack as $table => $def)
     92                {
     93                        $sql = 'CREATE TABLE '.$table." (\n".implode(",\n",$def)."\n)\n ";
     94                        $this->con->execute($sql);
     95                }
     96               
     97                foreach ($this->x_stack as $x)
     98                {
     99                        $this->con->execute($x);
     100                }
     101               
     102        }
     103       
     104        public function db_get_tables()
     105        {
     106                $res = array();
     107                $sql = "SELECT * FROM sqlite_master WHERE type = 'table'";
     108                $rs = $this->con->select($sql);
     109               
     110                $res = array();
     111                while ($rs->fetch()) {
     112                        $res[] = $rs->tbl_name;
     113                }
     114               
     115                return $res;
     116        }
     117       
     118        public function db_get_columns($table)
     119        {
     120                $sql = 'PRAGMA table_info('.$this->con->escapeSystem($table).')';
     121                $rs = $this->con->select($sql);
     122               
     123                $res = array();
     124                while ($rs->fetch())
     125                {
     126                        $field = trim($rs->name);
     127                        $type = trim($rs->type);
     128                        $null = trim($rs->notnull) == 0;
     129                        $default = trim($rs->dflt_value);
     130                       
     131                        $len = null;
     132                        if (preg_match('/^(.+?)\(([\d,]+)\)$/si',$type,$m)) {
     133                                $type = $m[1];
     134                                $len = (integer) $m[2];
     135                        }
     136                       
     137                        $res[$field] = array(
     138                                'type' => $type,
     139                                'len' => $len,
     140                                'null' => $null,
     141                                'default' => $default
     142                        );
     143                }
     144                return $res;
     145        }
     146       
     147        public function db_get_keys($table)
     148        {
     149                $t = array();
     150                $res = array();
     151               
     152                # Get primary keys first
     153                $sql = "SELECT sql FROM sqlite_master WHERE type='table' AND name='".$this->con->escape($table)."'";
     154                $rs = $this->con->select($sql);
     155               
     156                if ($rs->isEmpty()) {
     157                        return array();
     158                }
     159               
     160                # Get primary keys
     161                $n = preg_match_all('/^\s*CONSTRAINT\s+([^,]+?)\s+PRIMARY\s+KEY\s+\((.+?)\)/msi',$rs->sql,$match);
     162                if ($n > 0)
     163                {
     164                        foreach ($match[1] as $i => $name)
     165                        {
     166                                $cols = preg_split('/\s*,\s*/',$match[2][$i]);
     167                                $res[] = array(
     168                                        'name' => $name,
     169                                        'primary' => true,
     170                                        'unique' => false,
     171                                        'cols' => $cols
     172                                );
     173                        }
     174                }
     175               
     176                # Get unique keys
     177                $n = preg_match_all('/^\s*CONSTRAINT\s+([^,]+?)\s+UNIQUE\s+\((.+?)\)/msi',$rs->sql,$match);
     178                if ($n > 0)
     179                {
     180                        foreach ($match[1] as $i => $name)
     181                        {
     182                                $cols = preg_split('/\s*,\s*/',$match[2][$i]);
     183                                $res[] = array(
     184                                        'name' => $name,
     185                                        'primary' => false,
     186                                        'unique' => true,
     187                                        'cols' => $cols
     188                                );
     189                        }
     190                }
     191               
     192                return $res;
     193        }
     194       
     195        public function db_get_indexes($table)
     196        {
     197                $sql = 'PRAGMA index_list('.$this->con->escapeSystem($table).')';
     198                $rs = $this->con->select($sql);
     199               
     200                $res = array();
     201                while ($rs->fetch())
     202                {
     203                        if (preg_match('/^sqlite_/',$rs->name)) {
     204                                continue;
     205                        }
     206                       
     207                        $idx = $this->con->select('PRAGMA index_info('.$this->con->escapeSystem($rs->name).')');
     208                        $cols = array();
     209                        while ($idx->fetch()) {
     210                                $cols[] = $idx->name;
     211                        }
     212                       
     213                        $res[] = array(
     214                                'name' => $rs->name,
     215                                'type' => 'btree',
     216                                'cols' => $cols
     217                        );
     218                }
     219               
     220                return $res;
     221        }
     222       
     223        public function db_get_references($table)
     224        {
     225                $sql = 'SELECT * FROM sqlite_master WHERE type=\'trigger\' AND tbl_name = \'%1$s\' AND name LIKE \'%2$s_%%\' ';
     226                $res = array();
     227               
     228                # Find constraints on table
     229                $bir = $this->con->select(sprintf($sql,$this->con->escape($table),'bir'));
     230                $bur = $this->con->select(sprintf($sql,$this->con->escape($table),'bur'));
     231               
     232                if ($bir->isEmpty() || $bur->isempty()) {
     233                        return $res;
     234                }
     235               
     236                while ($bir->fetch())
     237                {
     238                        # Find child column and parent table and column
     239                        if (!preg_match('/FROM\s+(.+?)\s+WHERE\s+(.+?)\s+=\s+NEW\.(.+?)\s*?\) IS\s+NULL/msi',$bir->sql,$m)) {
     240                                continue;
     241                        }
     242                       
     243                        $c_col = $m[3];
     244                        $p_table = $m[1];
     245                        $p_col = $m[2];
     246                       
     247                        # Find on update
     248                        $on_update = 'restrict';
     249                        $aur = $this->con->select(sprintf($sql,$this->con->escape($p_table),'aur'));
     250                        while ($aur->fetch())
     251                        {
     252                                if (!preg_match('/AFTER\s+UPDATE/msi',$aur->sql)) {
     253                                        continue;
     254                                }
     255                               
     256                                if (preg_match('/UPDATE\s+'.$table.'\s+SET\s+'.$c_col.'\s*=\s*NEW.'.$p_col.
     257                                        '\s+WHERE\s+'.$c_col.'\s*=\s*OLD\.'.$p_col.'/msi',$aur->sql)) {
     258                                        $on_update = 'cascade';
     259                                        break;
     260                                }
     261                               
     262                                if (preg_match('/UPDATE\s+'.$table.'\s+SET\s+'.$c_col.'\s*=\s*NULL'.
     263                                        '\s+WHERE\s+'.$c_col.'\s*=\s*OLD\.'.$p_col.'/msi',$aur->sql)) {
     264                                        $on_update = 'set null';
     265                                        break;
     266                                }
     267                        }
     268                       
     269                        # Find on delete
     270                        $on_delete = 'restrict';
     271                        $bdr = $this->con->select(sprintf($sql,$this->con->escape($p_table),'bdr'));
     272                        while ($bdr->fetch())
     273                        {
     274                                if (!preg_match('/BEFORE\s+DELETE/msi',$bdr->sql)) {
     275                                        continue;
     276                                }
     277                               
     278                                if (preg_match('/DELETE\s+FROM\s+'.$table.'\s+WHERE\s+'.$c_col.'\s*=\s*OLD\.'.$p_col.'/msi',$bdr->sql)) {
     279                                        $on_delete = 'cascade';
     280                                        break;
     281                                }
     282                               
     283                                if (preg_match('/UPDATE\s+'.$table.'\s+SET\s+'.$c_col.'\s*=\s*NULL'.
     284                                        '\s+WHERE\s+'.$c_col.'\s*=\s*OLD\.'.$p_col.'/msi',$bdr->sql)) {
     285                                        $on_update = 'set null';
     286                                        break;
     287                                }
     288                        }
     289                       
     290                        $res[] = array(
     291                                'name' => substr($bir->name,4),
     292                                'c_cols' => array($c_col),
     293                                'p_table' => $p_table,
     294                                'p_cols' => array($p_col),
     295                                'update' => $on_update,
     296                                'delete' => $on_delete
     297                        );
     298                }
     299               
     300                return $res;
     301        }
     302       
     303        public function db_create_table($name,$fields)
     304        {
     305                $a = array();
     306               
     307                foreach ($fields as $n => $f)
     308                {
     309                        $type = $f['type'];
     310                        $len = (integer) $f['len'];
     311                        $default = $f['default'];
     312                        $null = $f['null'];
     313                       
     314                        $type = $this->udt2dbt($type,$len,$default);
     315                        $len = $len > 0 ? '('.$len.')' : '';
     316                        $null = $null ? 'NULL' : 'NOT NULL';
     317                       
     318                        if ($default === null) {
     319                                $default = 'DEFAULT NULL';
     320                        } elseif ($default !== false) {
     321                                $default = 'DEFAULT '.$default.' ';
     322                        } else {
     323                                $default = '';
     324                        }
     325                       
     326                        $a[] = $n.' '.$type.$len.' '.$null.' '.$default;
     327                }
     328               
     329                $this->table_stack[$name][] = implode(",\n",$a);
     330                $this->table_hist[$name] = $fields;
     331        }
     332       
     333        public function db_create_field($table,$name,$type,$len,$null,$default)
     334        {
     335                $type = $this->udt2dbt($type,$len,$default);
     336                $len = $len > 0 ? '('.$len.')' : '';
     337                $null = $null ? 'NULL' : 'NOT NULL';
     338               
     339                if ($default === null) {
     340                        $default = 'DEFAULT NULL';
     341                } elseif ($default !== false) {
     342                        $default = 'DEFAULT '.$default.' ';
     343                } else {
     344                        $default = '';
     345                }
     346               
     347                $sql =
     348                'ALTER TABLE '.$this->con->escapeSystem($table).' '.
     349                'ADD COLUMN '.$this->con->escapeSystem($name).' '.
     350                $type.$len.' '.$null.' '.$default;
     351               
     352                $this->con->execute($sql);
     353        }
     354       
     355        public function db_create_primary($table,$name,$cols)
     356        {
     357                $this->table_stack[$table][] = 'CONSTRAINT '.$name.' PRIMARY KEY ('.implode(',',$cols).') ';
     358        }
     359       
     360        public function db_create_unique($table,$name,$cols)
     361        {
     362                $this->table_stack[$table][] = 'CONSTRAINT '.$name.' UNIQUE ('.implode(',',$cols).') ';
     363        }
     364       
     365        public function db_create_index($table,$name,$type,$cols)
     366        {
     367                $this->x_stack[] = 'CREATE INDEX '.$name.' ON '.$table.' ('.implode(',',$cols).') ';
     368        }
     369       
     370        public function db_create_reference($name,$c_table,$c_cols,$p_table,$p_cols,$update,$delete)
     371        {
     372                if (!isset($this->table_hist[$c_table])) {
     373                        return;
     374                }
     375               
     376                if (count($c_cols) > 1 || count($p_cols) > 1) {
     377                        throw new Exception('SQLite UDBS does not support multiple columns foreign keys');
     378                }
     379               
     380                $c_col = $c_cols[0];
     381                $p_col = $p_cols[0];
     382               
     383                $update = strtolower($update);
     384                $delete = strtolower($delete);
     385               
     386                $cnull = $this->table_hist[$c_table][$c_col]['null'];
     387               
     388                # Create constraint
     389                $this->x_stack[] =
     390                'CREATE TRIGGER bir_'.$name."\n".
     391                'BEFORE INSERT ON '.$c_table."\n".
     392                "FOR EACH ROW BEGIN\n".
     393                '  SELECT RAISE(ROLLBACK,\'insert on table "'.$c_table.'" violates foreign key constraint "'.$name.'"\')'."\n".
     394                '  WHERE '.
     395                ($cnull ? 'NEW.'.$c_col." IS NOT NULL\n  AND " : '').
     396                '(SELECT '.$p_col.' FROM '.$p_table.' WHERE '.$p_col.' = NEW.'.$c_col.") IS NULL;\n".
     397                "END;\n";
     398               
     399                # Update constraint
     400                $this->x_stack[] =
     401                'CREATE TRIGGER bur_'.$name."\n".
     402                'BEFORE UPDATE ON '.$c_table."\n".
     403                "FOR EACH ROW BEGIN\n".
     404                '  SELECT RAISE(ROLLBACK,\'update on table "'.$c_table.'" violates foreign key constraint "'.$name.'"\')'."\n".
     405                '  WHERE '.
     406                ($cnull ? 'NEW.'.$c_col." IS NOT NULL\n  AND " : '').
     407                '(SELECT '.$p_col.' FROM '.$p_table.' WHERE '.$p_col.' = NEW.'.$c_col.") IS NULL;\n".
     408                "END;\n";
     409               
     410                # ON UPDATE
     411                if ($update == 'cascade')
     412                {
     413                        $this->x_stack[] =
     414                        'CREATE TRIGGER aur_'.$name."\n".
     415                        'AFTER UPDATE ON '.$p_table."\n".
     416                        "FOR EACH ROW BEGIN\n".
     417                        '  UPDATE '.$c_table.' SET '.$c_col.' = NEW.'.$p_col.' WHERE '.$c_col.' = OLD.'.$p_col.";\n".
     418                        "END;\n";
     419                }
     420                elseif ($update == 'set null')
     421                {
     422                        $this->x_stack[] =
     423                        'CREATE TRIGGER aur_'.$name."\n".
     424                        'AFTER UPDATE ON '.$p_table."\n".
     425                        "FOR EACH ROW BEGIN\n".
     426                        '  UPDATE '.$c_table.' SET '.$c_col.' = NULL WHERE '.$c_col.' = OLD.'.$p_col.";\n".
     427                        "END;\n";
     428                }
     429                else # default on restrict
     430                {
     431                        $this->x_stack[] =
     432                        'CREATE TRIGGER burp_'.$name."\n".
     433                        'BEFORE UPDATE ON '.$p_table."\n".
     434                        "FOR EACH ROW BEGIN\n".
     435                        '  SELECT RAISE (ROLLBACK,\'update on table "'.$p_table.'" violates foreign key constraint "'.$name.'"\')'."\n".
     436                        '  WHERE (SELECT '.$c_col.' FROM '.$c_table.' WHERE '.$c_col.' = OLD.'.$p_col.") IS NOT NULL;\n".
     437                        "END;\n";
     438                }
     439               
     440                # ON DELETE
     441                if ($delete == 'cascade')
     442                {
     443                        $this->x_stack[] =
     444                        'CREATE TRIGGER bdr_'.$name."\n".
     445                        'BEFORE DELETE ON '.$p_table."\n".
     446                        "FOR EACH ROW BEGIN\n".
     447                        '  DELETE FROM '.$c_table.' WHERE '.$c_col.' = OLD.'.$p_col.";\n".
     448                        "END;\n";
     449                }
     450                elseif ($delete == 'set null')
     451                {
     452                        $this->x_stack[] =
     453                        'CREATE TRIGGER bdr_'.$name."\n".
     454                        'BEFORE DELETE ON '.$p_table."\n".
     455                        "FOR EACH ROW BEGIN\n".
     456                        '  UPDATE '.$c_table.' SET '.$c_col.' = NULL WHERE '.$c_col.' = OLD.'.$p_col.";\n".
     457                        "END;\n";
     458                }
     459                else
     460                {
     461                        $this->x_stack[] =
     462                        'CREATE TRIGGER bdr_'.$name."\n".
     463                        'BEFORE DELETE ON '.$p_table."\n".
     464                        "FOR EACH ROW BEGIN\n".
     465                        '  SELECT RAISE (ROLLBACK,\'delete on table "'.$p_table.'" violates foreign key constraint "'.$name.'"\')'."\n".
     466                        '  WHERE (SELECT '.$c_col.' FROM '.$c_table.' WHERE '.$c_col.' = OLD.'.$p_col.") IS NOT NULL;\n".
     467                        "END;\n";
     468                }
     469        }
     470       
     471        public function db_alter_field($table,$name,$type,$len,$null,$default)
     472        {
     473                $type = $this->udt2dbt($type,$len,$default);
     474                if ($type != 'integer' && $type != 'text' && $type != 'timestamp') {
     475                        throw new Exception('SQLite fields cannot be changed.');
     476                }
     477        }
     478       
     479        public function db_alter_primary($table,$name,$newname,$cols)
     480        {
     481                throw new Exception('SQLite primary key cannot be changed.');
     482        }
     483       
     484        public function db_alter_unique($table,$name,$newname,$cols)
     485        {
     486                throw new Exception('SQLite unique index cannot be changed.');
     487        }
     488       
     489        public function db_alter_index($table,$name,$newname,$type,$cols)
     490        {
     491                $this->con->execute('DROP INDEX IF EXISTS '.$name);
     492                $this->con->execute('CREATE INDEX '.$newname.' ON '.$table.' ('.implode(',',$cols).') ');
     493        }
     494       
     495        public function db_alter_reference($name,$newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete)
     496        {
     497                $this->con->execute('DROP TRIGGER IF EXISTS bur_'.$name);
     498                $this->con->execute('DROP TRIGGER IF EXISTS burp_'.$name);
     499                $this->con->execute('DROP TRIGGER IF EXISTS bir_'.$name);
     500                $this->con->execute('DROP TRIGGER IF EXISTS aur_'.$name);
     501                $this->con->execute('DROP TRIGGER IF EXISTS bdr_'.$name);
     502               
     503                $this->table_hist[$c_table] = $this->db_get_columns($c_table);
     504                $this->db_create_reference($newname,$c_table,$c_cols,$p_table,$p_cols,$update,$delete);
     505        }
     506}
     507?>
     508 No newline at end of file
  • clearbricks/zip/class.unzip.php

     
     1<?php
     2# ***** BEGIN LICENSE BLOCK *****
     3# This file is part of Clearbricks.
     4# Copyright (c) 2008 Olivier Meunier and contributors.
     5# All rights reserved.
     6#
     7# Clearbricks is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# Clearbricks is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with Clearbricks; if not, write to the Free Software
     19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     20#
     21# ***** END LICENSE BLOCK *****
     22
     23class fileUnzip
     24{
     25        protected $file_name;
     26        protected $compressed_list = array();
     27        protected $eo_central = array();
     28       
     29        protected $zip_sig   = "\x50\x4b\x03\x04"; # local file header signature
     30        protected $dir_sig   = "\x50\x4b\x01\x02"; # central dir header signature
     31        protected $dir_sig_e = "\x50\x4b\x05\x06"; # end of central dir signature
     32        protected $fp = null;
     33       
     34        protected $memory_limit = null;
     35       
     36        public function __construct($file_name)
     37        {
     38                $this->file_name = $file_name;
     39        }
     40       
     41        public function __destroy()
     42        {
     43                $this->close();
     44        }
     45       
     46        public function close()
     47        {
     48                if ($this->fp) {
     49                        fclose($this->fp);
     50                }
     51               
     52                if ($this->memory_limit) {
     53                        ini_set('memory_limit',$this->memory_limit);
     54                }
     55        }
     56       
     57        public function getList($stop_on_file=false,$exclude=false)
     58        {
     59                if (!empty($this->compressed_list)) {
     60                        return $this->compressed_list;
     61                }
     62               
     63                if (!$this->loadFileListByEOF($stop_on_file,$exclude)) {
     64                        if(!$this->loadFileListBySignatures($stop_on_file,$exclude)) {
     65                                return false;
     66                        }
     67                }
     68               
     69                return $this->compressed_list;
     70        }
     71       
     72        public function unzipAll($target)
     73        {
     74                if (empty($this->compressed_list)) {
     75                        $this->getList();
     76                }
     77               
     78                foreach ($this->compressed_list as $k => $v)
     79                {
     80                        if ($v['is_dir']) {
     81                                continue;
     82                        }
     83                       
     84                        $this->unzip($k,$target.'/'.$k);
     85                }
     86        }
     87       
     88        public function unzip($file_name,$target=false)
     89        {
     90                if (empty($this->compressed_list)) {
     91                        $this->getList($file_name);
     92                }
     93               
     94                if (!isset($this->compressed_list[$file_name])) {
     95                        throw new Exception(sprintf(__('File %s is not compressed in the zip.'),$file_name));
     96                }
     97                $details =& $this->compressed_list[$file_name];
     98               
     99                if ($details['is_dir']) {
     100                        throw new Exception(sprintf(__('Trying to unzip a folder name %s'),$file_name));
     101                }
     102               
     103                if (!$details['uncompressed_size']) {
     104                        return $this->putContent('',$target);
     105                }
     106               
     107                if ($target) {
     108                        $this->testTargetDir(dirname($target));
     109                }
     110               
     111                fseek($this->fp(),$details['contents_start_offset']);
     112               
     113                $this->memoryAllocate($details['compressed_size']);
     114                return $this->uncompress(
     115                        fread($this->fp(), $details['compressed_size']),
     116                        $details['compression_method'],
     117                        $details['uncompressed_size'],
     118                        $target
     119                );
     120        }
     121       
     122        public function getFilesList()
     123        {
     124                if (empty($this->compressed_list)) {
     125                        $this->getList();
     126                }
     127               
     128                $res = array();
     129                foreach ($this->compressed_list as $k => $v) {
     130                        if (!$v['is_dir']) {
     131                                $res[] = $k;
     132                        }
     133                }
     134                return $res;
     135        }
     136       
     137        public function getDirsList()
     138        {
     139                if (empty($this->compressed_list)) {
     140                        $this->getList();
     141                }
     142               
     143                $res = array();
     144                foreach ($this->compressed_list as $k => $v) {
     145                        if ($v['is_dir']) {
     146                                $res[] = substr($k,0,-1);
     147                        }
     148                }
     149                return $res;
     150        }
     151       
     152        public function getRootDir()
     153        {
     154                if (empty($this->compressed_list)) {
     155                        $this->getList();
     156                }
     157               
     158                $files = $this->getFilesList();
     159                $dirs = $this->getDirsList();
     160               
     161                $root_files = 0;
     162                $root_dirs = 0;
     163                foreach ($files as $v) { if (strpos($v,'/') === false) { $root_files++; }}
     164                foreach ($dirs as $v)  { if (strpos($v,'/') === false) { $root_dirs++;  }}
     165               
     166                if ($root_files == 0 && $root_dirs == 1) {
     167                        return $dirs[0];
     168                } else {
     169                        return false;
     170                }
     171        }
     172       
     173        public function isEmpty()
     174        {
     175                if (empty($this->compressed_list)) {
     176                        $this->getList();
     177                }
     178               
     179                return count($this->compressed_list) == 0;
     180        }
     181       
     182        public function hasFile($f)
     183        {
     184                if (empty($this->compressed_list)) {
     185                        $this->getList();
     186                }
     187               
     188                return isset($this->compressed_list[$f]);
     189        }
     190       
     191        protected function fp()
     192        {
     193                if ($this->fp === null) {
     194                        $this->fp = @fopen($this->file_name,'rb');
     195                }
     196               
     197                if ($this->fp === false) {
     198                        throw new Exception('Unable to open file.');
     199                }
     200               
     201                return $this->fp;
     202        }
     203       
     204        protected function putContent($content,$target=false)
     205        {
     206                if ($target) {
     207                        $r = @file_put_contents($target,$content);
     208                        if (!$r) {
     209                                throw new Exception(__('Unable to write destination file.'));
     210                        }
     211                        files::inheritChmod($target);
     212                        return true;
     213                }
     214                return $content;
     215        }
     216       
     217        protected function testTargetDir($dir)
     218        {
     219                if (is_dir($dir) && !is_writable($dir)) {
     220                        throw new Exception(__('Unable to write in target directory, permission denied.'));
     221                }
     222               
     223                if (!is_dir($dir)) {
     224                        files::makeDir($dir,true);
     225                }
     226        }
     227       
     228        protected function uncompress($content,$mode,$size,$target=false)
     229        {
     230                switch ($mode)
     231                {
     232                        case 0:
     233                                # Not compressed
     234                                $this->memoryAllocate($size*2);
     235                                return $this->putContent($content,$target);
     236                        case 1:
     237                                throw new Exception('Shrunk mode is not supported.');
     238                        case 2:
     239                        case 3:
     240                        case 4:
     241                        case 5:
     242                                throw new Exception('Compression factor '.($mode-1).' is not supported.');
     243                        case 6:
     244                                throw new Exception('Implode is not supported.');
     245                        case 7:
     246                                throw new Exception('Tokenizing compression algorithm is not supported.');
     247                        case 8:
     248                                # Deflate
     249                                if (!function_exists('gzinflate')) {
     250                                        throw new Exception('Gzip functions are not available.');
     251                                }
     252                                $this->memoryAllocate($size*2);
     253                                return $this->putContent(gzinflate($content,$size),$target);
     254                        case 9:
     255                                throw new Exception('Enhanced Deflating is not supported.');
     256                        case 10:
     257                                throw new Exception('PKWARE Date Compression Library Impoloding is not supported.');
     258                        case 12:
     259                                # Bzip2
     260                                if (!function_exists('bzdecompress')) {
     261                                        throw new Exception('Bzip2 functions are not available.');
     262                                }
     263                                $this->memoryAllocate($size*2);
     264                                return $this->putContent(bzdecompress($content),$target);
     265                        case 18:
     266                                throw new Exception('IBM TERSE is not supported.');
     267                        default:
     268                                throw new Exception('Unknown uncompress method');
     269                }
     270        }
     271       
     272        protected function loadFileListByEOF($stop_on_file=false,$exclude=false)
     273        {
     274                $fp = $this->fp();
     275               
     276                for ($x=0; $x<1024; $x++)
     277                {
     278                        fseek($fp,-22-$x,SEEK_END);
     279                        $signature = fread($fp,4);
     280                       
     281                        if ($signature == $this->dir_sig_e)
     282                        {
     283                                $dir_list = array();
     284                               
     285                                $eodir = array(
     286                                        'disk_number_this'   => unpack('v', fread($fp,2)),
     287                                        'disk_number'        => unpack('v', fread($fp,2)),
     288                                        'total_entries_this' => unpack('v', fread($fp,2)),
     289                                        'total_entries'      => unpack('v', fread($fp,2)),
     290                                        'size_of_cd'         => unpack('V', fread($fp,4)),
     291                                        'offset_start_cd'    => unpack('V', fread($fp,4))
     292                                );
     293                               
     294                                $zip_comment_len = unpack('v', fread($fp,2));
     295                                $eodir['zipfile_comment'] = $zip_comment_len[1] ? fread($fp,$zip_comment_len) : '';
     296                               
     297                                $this->eo_central = array(
     298                                        'disk_number_this'   => $eodir['disk_number_this'][1],
     299                                        'disk_number'        => $eodir['disk_number'][1],
     300                                        'total_entries_this' => $eodir['total_entries_this'][1],
     301                                        'total_entries'      => $eodir['total_entries'][1],
     302                                        'size_of_cd'         => $eodir['size_of_cd'][1],
     303                                        'offset_start_cd'    => $eodir['offset_start_cd'][1],
     304                                        'zipfile_comment'    => $eodir['zipfile_comment']
     305                                );
     306                               
     307                                fseek($fp, $this->eo_central['offset_start_cd']);
     308                                $signature = fread($fp,4);
     309                               
     310                                while ($signature == $this->dir_sig)
     311                                {
     312                                        $dir = array();
     313                                        $dir['version_madeby']       = unpack("v",fread($fp, 2)); # version made by
     314                                        $dir['version_needed']       = unpack("v",fread($fp, 2)); # version needed to extract
     315                                        $dir['general_bit_flag']     = unpack("v",fread($fp, 2)); # general purpose bit flag
     316                                        $dir['compression_method']   = unpack("v",fread($fp, 2)); # compression method
     317                                        $dir['lastmod_time']         = unpack("v",fread($fp, 2)); # last mod file time
     318                                        $dir['lastmod_date']         = unpack("v",fread($fp, 2)); # last mod file date
     319                                        $dir['crc-32']               = fread($fp,4);              # crc-32
     320                                        $dir['compressed_size']      = unpack("V",fread($fp, 4)); # compressed size
     321                                        $dir['uncompressed_size']    = unpack("V",fread($fp, 4)); # uncompressed size
     322                                       
     323                                        $file_name_len               = unpack("v",fread($fp, 2)); # filename length
     324                                        $extra_field_len             = unpack("v",fread($fp, 2)); # extra field length
     325                                        $file_comment_len            = unpack("v",fread($fp, 2)); # file comment length
     326                                       
     327                                        $dir['disk_number_start']    = unpack("v",fread($fp, 2)); # disk number start
     328                                        $dir['internal_attributes']  = unpack("v",fread($fp, 2)); # internal file attributes-byte1
     329                                        $dir['external_attributes1'] = unpack("v",fread($fp, 2)); # external file attributes-byte2
     330                                        $dir['external_attributes2'] = unpack("v",fread($fp, 2)); # external file attributes
     331                                        $dir['relative_offset']      = unpack("V",fread($fp, 4)); # relative offset of local header
     332                                        $dir['file_name']            = $this->cleanFileName(fread($fp, $file_name_len[1]));          # filename
     333                                        $dir['extra_field']          = $extra_field_len[1] ? fread($fp, $extra_field_len[1]) : '';   # extra field
     334                                        $dir['file_comment']         = $file_comment_len[1] ? fread($fp, $file_comment_len[1]) : ''; # file comment                     
     335                                       
     336                                        $dir_list[$dir['file_name']] = array(
     337                                                'version_madeby'       => $dir['version_madeby'][1],
     338                                                'version_needed'       => $dir['version_needed'][1],
     339                                                'general_bit_flag'     => str_pad(decbin($dir['general_bit_flag'][1]), 8, '0', STR_PAD_LEFT),
     340                                                'compression_method'   => $dir['compression_method'][1],
     341                                                'lastmod_datetime'     => $this->getTimeStamp($dir['lastmod_date'][1],$dir['lastmod_time'][1]),
     342                                                'crc-32'               => str_pad(dechex(ord($dir['crc-32'][3])), 2, '0', STR_PAD_LEFT).
     343                                                                                         str_pad(dechex(ord($dir['crc-32'][2])), 2, '0', STR_PAD_LEFT).
     344                                                                                         str_pad(dechex(ord($dir['crc-32'][1])), 2, '0', STR_PAD_LEFT).
     345                                                                                         str_pad(dechex(ord($dir['crc-32'][0])), 2, '0', STR_PAD_LEFT),
     346                                                'compressed_size'      => $dir['compressed_size'][1],
     347                                                'uncompressed_size'    => $dir['uncompressed_size'][1],
     348                                                'disk_number_start'    => $dir['disk_number_start'][1],
     349                                                'internal_attributes'  => $dir['internal_attributes'][1],
     350                                                'external_attributes1' => $dir['external_attributes1'][1],
     351                                                'external_attributes2' => $dir['external_attributes2'][1],
     352                                                'relative_offset'      => $dir['relative_offset'][1],
     353                                                'file_name'            => $dir['file_name'],
     354                                                'extra_field'          => $dir['extra_field'],
     355                                                'file_comment'         => $dir['file_comment']
     356                                        );
     357                                        $signature = fread($fp, 4);
     358                                }
     359                               
     360                                foreach ($dir_list as $k => $v)
     361                                {
     362                                        if ($exclude && preg_match($exclude,$k)) {
     363                                                continue;
     364                                        }
     365                                       
     366                                        $i = $this->getFileHeaderInformation($v['relative_offset']);
     367                                       
     368                                        $this->compressed_list[$k]['file_name']            = $k;
     369                                        $this->compressed_list[$k]['is_dir']               = $v['external_attributes1'] == 16 || substr($k,-1,1) == '/';
     370                                        $this->compressed_list[$k]['compression_method']   = $v['compression_method'];
     371                                        $this->compressed_list[$k]['version_needed']       = $v['version_needed'];
     372                                        $this->compressed_list[$k]['lastmod_datetime']     = $v['lastmod_datetime'];
     373                                        $this->compressed_list[$k]['crc-32']               = $v['crc-32'];
     374                                        $this->compressed_list[$k]['compressed_size']      = $v['compressed_size'];
     375                                        $this->compressed_list[$k]['uncompressed_size']    = $v['uncompressed_size'];
     376                                        $this->compressed_list[$k]['lastmod_datetime']     = $v['lastmod_datetime'];
     377                                        $this->compressed_list[$k]['extra_field']          = $i['extra_field'];
     378                                        $this->compressed_list[$k]['contents_start_offset'] = $i['contents_start_offset'];
     379                                       
     380                                        if(strtolower($stop_on_file) == strtolower($k)) {
     381                                                break;
     382                                        }
     383                                }
     384                                return true;
     385                        }
     386                }
     387                return false;
     388        }
     389       
     390        protected function loadFileListBySignatures($stop_on_file=false,$exclude=false)
     391        {
     392                $fp = $this->fp();
     393                fseek($fp,0);
     394               
     395                $return = false;
     396                while(true)
     397                {
     398                        $details = $this->getFileHeaderInformation();
     399                        if (!$details) {
     400                                fseek($fp,12-4,SEEK_CUR); # 12: Data descriptor - 4: Signature (that will be read again)
     401                                $details = $this->getFileHeaderInformation();
     402                        }
     403                        if (!$details) {
     404                                break;
     405                        }
     406                        $filename = $details['file_name'];
     407                       
     408                        if ($exclude && preg_match($exclude,$filename)) {
     409                                continue;
     410                        }
     411                       
     412                        $this->compressed_list[$filename] = $details;
     413                        $return = true;
     414                       
     415                        if (strtolower($stop_on_file) == strtolower($filename)) {
     416                                break;
     417                        }
     418                }
     419               
     420                return $return;
     421        }
     422       
     423        protected function getFileHeaderInformation($start_offset=false)
     424        {
     425                $fp = $this->fp();
     426               
     427                if ($start_offset !== false) {
     428                        fseek($fp,$start_offset);
     429                }
     430               
     431                $signature = fread($fp, 4);
     432                if ($signature == $this->zip_sig)
     433                {
     434                        # Get information about the zipped file
     435                        $file = array();
     436                        $file['version_needed']        = unpack("v",fread($fp, 2)); # version needed to extract
     437                        $file['general_bit_flag']      = unpack("v",fread($fp, 2)); # general purpose bit flag
     438                        $file['compression_method']    = unpack("v",fread($fp, 2)); # compression method
     439                        $file['lastmod_time']          = unpack("v",fread($fp, 2)); # last mod file time
     440                        $file['lastmod_date']          = unpack("v",fread($fp, 2)); # last mod file date
     441                        $file['crc-32']                = fread($fp,4);              # crc-32
     442                        $file['compressed_size']       = unpack("V",fread($fp, 4)); # compressed size
     443                        $file['uncompressed_size']     = unpack("V",fread($fp, 4)); # uncompressed size
     444                       
     445                        $file_name_len                 = unpack("v",fread($fp, 2)); # filename length
     446                        $extra_field_len               = unpack("v",fread($fp, 2)); # extra field length
     447                       
     448                        $file['file_name']             = $this->cleanFileName(fread($fp,$file_name_len[1])); # filename
     449                        $file['extra_field']           = $extra_field_len[1] ? fread($fp, $extra_field_len[1]) : ''; # extra field
     450                        $file['contents_start_offset'] = ftell($fp);
     451                       
     452                        # Look for the next file
     453                        fseek($fp, $file['compressed_size'][1], SEEK_CUR);
     454                       
     455                        # Mount file table
     456                        $i = array(
     457                                'file_name'            => $file['file_name'],
     458                                'is_dir'               => substr($file['file_name'],-1,1) == '/',
     459                                'compression_method'   => $file['compression_method'][1],
     460                                'version_needed'       => $file['version_needed'][1],
     461                                'lastmod_datetime'     => $this->getTimeStamp($file['lastmod_date'][1],$file['lastmod_time'][1]),
     462                                'crc-32'               => str_pad(dechex(ord($file['crc-32'][3])), 2, '0', STR_PAD_LEFT).
     463                                                                         str_pad(dechex(ord($file['crc-32'][2])), 2, '0', STR_PAD_LEFT).
     464                                                                         str_pad(dechex(ord($file['crc-32'][1])), 2, '0', STR_PAD_LEFT).
     465                                                                         str_pad(dechex(ord($file['crc-32'][0])), 2, '0', STR_PAD_LEFT),
     466                                'compressed_size'      => $file['compressed_size'][1],
     467                                'uncompressed_size'    => $file['uncompressed_size'][1],
     468                                'extra_field'          => $file['extra_field'],
     469                                'general_bit_flag'     => str_pad(decbin($file['general_bit_flag'][1]), 8, '0', STR_PAD_LEFT),
     470                                'contents_start_offset'=>$file['contents_start_offset']
     471                        );
     472                        return $i;
     473                }
     474                return false;
     475        }
     476       
     477        protected function getTimeStamp($date,$time)
     478        {
     479                $BINlastmod_date = str_pad(decbin($date), 16, '0', STR_PAD_LEFT);
     480                $BINlastmod_time = str_pad(decbin($time), 16, '0', STR_PAD_LEFT);
     481                $lastmod_dateY   = bindec(substr($BINlastmod_date,  0, 7))+1980;
     482                $lastmod_dateM   = bindec(substr($BINlastmod_date,  7, 4));
     483                $lastmod_dateD   = bindec(substr($BINlastmod_date, 11, 5));
     484                $lastmod_timeH   = bindec(substr($BINlastmod_time,   0, 5));
     485                $lastmod_timeM   = bindec(substr($BINlastmod_time,   5, 6));
     486                $lastmod_timeS   = bindec(substr($BINlastmod_time,  11, 5)) * 2;
     487               
     488                return mktime($lastmod_timeH, $lastmod_timeM, $lastmod_timeS, $lastmod_dateM, $lastmod_dateD, $lastmod_dateY);
     489        }
     490       
     491        protected function cleanFileName($n)
     492        {
     493                $n = str_replace('../','',$n);
     494                $n = preg_replace('#^/+#','',$n);
     495                return $n;
     496        }
     497       
     498        protected function memoryAllocate($size)
     499        {
     500                $mem_used = function_exists('memory_get_usage') ? @memory_get_usage() : 4000000;
     501                $mem_limit = @ini_get('memory_limit');
     502                if ($mem_used && $mem_limit)
     503                {