home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / DB / Sqlite / Tools.php
Encoding:
PHP Script  |  2008-07-02  |  44.6 KB  |  1,389 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
  3.  
  4. // {{{ Header
  5.  
  6. /**
  7.  * Class to manage sqlite database. On object-oriented interface to sqlite
  8.  * integrity check, optimizations and backup.
  9.  *
  10.  * PHP version 5
  11.  *
  12.  * LICENSE:
  13.  *
  14.  * BSD License
  15.  *
  16.  * Copyright (c) 2004-2006 David Costa
  17.  * All rights reserved.
  18.  *
  19.  * Redistribution and use in source and binary forms, with or without
  20.  * modification, are permitted provided that the following conditions
  21.  * are met:
  22.  *
  23.  * 1. Redistributions of source code must retain the above copyright
  24.  *    notice, this list of conditions and the following disclaimer.
  25.  * 2. Redistributions in binary form must reproduce the above
  26.  *    copyright notice, this list of conditions and the following
  27.  *    disclaimer in the documentation and/or other materials provided
  28.  *    with the distribution.
  29.  * 3. Neither the name of David Costa nor the names of
  30.  *    contributors may be used to endorse or promote products derived
  31.  *    from this software without specific prior written permission.
  32.  *
  33.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  34.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  35.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  36.  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  37.  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  38.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  39.  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  40.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  41.  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  42.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  43.  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  44.  * POSSIBILITY OF SUCH DAMAGE.
  45.  *
  46.  * @category Database
  47.  * @package DB_Sqlite_Tools
  48.  * @license http://www.php.net/license/3_0.txt PHP License 3.0
  49.  * @author David Costa <gurugeek@php.net>
  50.  * @author Ashley Hewson <morbidness@gmail.com>
  51.  * @author Firman Wandayandi <firman@php.net>
  52.  * @copyright Copyright (c) 2004-2006 David Costa
  53.  * @license http://www.opensource.org/licenses/bsd-license.php
  54.  *          BSD License
  55.  * @version CVS: $Id: Tools.php,v 1.2 2006/05/26 17:23:43 firman Exp $
  56.  */
  57.  
  58. // }}}
  59. // {{{ Dependencies
  60.  
  61. /**
  62.  * Load PEAR_Exception to throws.
  63.  */
  64. require_once 'PEAR/Exception.php';
  65.  
  66. // }}}
  67. // {{{ Inline codes
  68.  
  69. // Avoid the fatal error, caused by redeclare
  70. // the magic __autoload() function.
  71. if (!function_exists('__autoload')) {
  72.     function __autoload($class)
  73.     {
  74.         switch ($class) {
  75.             case 'DB_Sqlite_Tools_DBC':
  76.             case 'DB_Sqlite_Tools_XMLParser':
  77.             case 'DB_Sqlite_Tools_ArcFour':
  78.                 include str_replace('_', '/', $class) . '.php';
  79.                 break;
  80.         }
  81.     }
  82. } else {
  83. // __autoload() already declared in the other line.
  84. // There is no way just load all files.
  85.  
  86.     require_once 'DB/Sqlite/Tools/DBC.php';
  87.     require_once 'DB/Sqlite/Tools/XMLParser.php';
  88.     require_once 'DB/Sqlite/Tools/ArcFour.php';
  89. }
  90.  
  91. // }}}
  92. // {{{ Class: DB_Sqlite_Tools
  93.  
  94. /**
  95.  * Class to manage sqlite database. An object-oriented interface to sqlite
  96.  * integrity check, optimizations and backup and export. It curently supports
  97.  * pragma integrity checks, cache values to optimize performance,
  98.  * synchronisation values for an higher integrity protection.
  99.  *
  100.  * For backups it supports ftp, rsync (both local and remote) and local backups.
  101.  *
  102.  * It offer an extra in build export method to XML for a whole database schema
  103.  * and data which can be particularly useful for backup and export purposes.
  104.  *
  105.  * Via the XML parser it allows to import and XML dump back to an Sqlite
  106.  * database.
  107.  *
  108.  * @category Database
  109.  * @package DB_Sqlite_Tools
  110.  * @author David Costa <gurugeek@php.net>
  111.  * @author Ashley Hewson <morbidness@gmail.com>
  112.  * @author Firman Wandayandi <firman@php.net>
  113.  * @copyright Copyright (c) 2004-2006 David Costa
  114.  * @license http://www.opensource.org/licenses/bsd-license.php
  115.  *          BSD License
  116.  * @version Release: 0.1.5
  117.  */
  118. class DB_Sqlite_Tools
  119. {
  120.     // {{{ Properties
  121.  
  122.     /**
  123.      * Error handling related Constants
  124.      *
  125.      * Verbose error output in each of the cases
  126.      */
  127.     const DB_SQLITE_TOOLS_COD =
  128.             'DB_DB_Sqlite_Tools Cannot Open Database File Possible Problem:';
  129.     const DB_SQLITE_TOOLS_QRS =
  130.             'Query Result.. ';
  131.     const DB_SQLITE_TOOLS_QNR =
  132.             'Query executed with no object returned as result';
  133.     const DB_SQLITE_TOOLS_NAV =
  134.             'Invalid parameter';
  135.     const DB_SQLITE_TOOLS_COFL =
  136.             'Cannot Open file for Lock';
  137.     const DB_SQLITE_TOOLS_CCFL =
  138.             'Cannot release lock on file';
  139.     const DB_SQLITE_TOOLS_CLF =
  140.             'Unable to activate the lock in the database file';
  141.     const DB_SQLITE_TOOLS_CSF =
  142.             'Cannot Save File';
  143.     const DB_SQLITE_TOOLS_CCFS =
  144.             'Cannot Connect to FTP Server';
  145.     const DB_SQLITE_TOOLS_CLFS =
  146.             'Cannot login to FTP Server';
  147.     const DB_SQLITE_TOOLS_CUFS =
  148.             'Cannot upload file on FTP Server';
  149.     const DB_SQLITE_TOOLS_NAR =
  150.             'The database array is empty';
  151.     const DB_SQLITE_TOOLS_NNU =
  152.             'parameter must be an integer';
  153.     const DB_SQLITE_TOOLS_RSE =
  154.             'Rsync Error see logfile for details';
  155.     const DB_SQLITE_TOOLS_INSC =
  156.             'Cannot backup the database remotely without safecopy';
  157.     const DB_SQLITE_TOOLS_CSD =
  158.             'Cannot scan directory';
  159.     const DB_SQLITE_TOOLS_CCXML =
  160.             'Cannot create XML';
  161.     const DB_SQLITE_TOOLS_CCLXML =
  162.             'Cannot close XML File';
  163.  
  164.     /**
  165.      * Debug mode.
  166.      *
  167.      * @var string
  168.      */
  169.     public $debug = false;
  170.  
  171.     /**
  172.      * List of databases.
  173.      *
  174.      * @var string
  175.      */
  176.     public $database = array();
  177.  
  178.     public $email;
  179.  
  180.     /**
  181.      * Error storage.
  182.      *
  183.      * @var string
  184.      */
  185.     private $error;
  186.  
  187.     /**
  188.      * Database opening process.
  189.      *
  190.      * @var string
  191.      */
  192.     private $opendb;
  193.  
  194.     /**
  195.      * Query results.
  196.      *
  197.      * @var string
  198.      */
  199.     private $result;
  200.  
  201.     /**
  202.      * FTP connection object.
  203.      *
  204.      * @var string
  205.      */
  206.     private $ftpconnection;
  207.  
  208.     /**
  209.      * Info stores all the file related information for the given databases.
  210.      *
  211.      * @var string
  212.      */
  213.     private $info;
  214.  
  215.     /**
  216.      * Used to verify if safecopy takes place before remote backup this is
  217.      * necessary to ensure the live db integrity.
  218.      *
  219.      * @var string
  220.      */
  221.     private $safecopy;
  222.  
  223.     /**
  224.      * Stores an array of log objects used for verbose output or logging
  225.      * purposes.
  226.      *
  227.      * @array objects
  228.      */
  229.     private $logs = array();
  230.  
  231.     /**
  232.      * Backup path.
  233.      *
  234.      * @var string
  235.      */
  236.     private $backupp;
  237.  
  238.     /**
  239.      * An array of the databases available in the backup directory generated
  240.      * after scanning the backup directory for all the .bkp files generated by
  241.      * the copySafe function.
  242.      *
  243.      * @array
  244.      */
  245.     private $backupar;
  246.  
  247.     /**
  248.      * Database object.
  249.      *
  250.      * @var string
  251.      */
  252.     private $dbobj;
  253.  
  254.     /**
  255.      * If true, shows logs as they are added to DB.
  256.      *
  257.      * @var bool
  258.      */
  259.     public $showLogs ;
  260.  
  261.     // }}}
  262.     // {{{ Constructor
  263.  
  264.     /**
  265.      * Instantiate a new SQLite_Tools Object
  266.      * Expects a db location or an array of db locations for
  267.      * multiple checks
  268.      *
  269.      * @param string $database the Sqlite database.
  270.      *
  271.      * @return return $this->database array
  272.      */
  273.     public function __construct($database)
  274.     {
  275.         if (!is_array($database)) {
  276.             $this->database[] = $database;
  277.         } else{
  278.             $this->database = $database;
  279.         }
  280.  
  281.     }
  282.  
  283.     // }}}
  284.     // {{{ displayLogs()
  285.  
  286.     /**
  287.      * Display The logs on the screen in an XML-like format.
  288.      */
  289.     private function displayLogs()
  290.     {
  291.         foreach($this->logs as $logs) {
  292.             if ($this->showLogs == true) {
  293.                   print $logs;
  294.                   /*echo "<pre>\n";
  295.                   echo strtr($lstr, get_html_translation_table(HTML_SPECIALCHARS));
  296.                   echo "<pre>\n";*/
  297.             }
  298.         }
  299.     }
  300.  
  301.     // }}}
  302.     // {{{ checkIntegrity()
  303.  
  304.     /**
  305.      * Checks the database integrity does an integrity check of the entire
  306.      * database including malformed records, corrupted pages out of order
  307.      * records, invalid indeces returns okay on success or the error details,
  308.      * if multiple is true the the value for $database in  the constructor is
  309.      * expected to be an array with a list of databases.
  310.      *
  311.      * @return true
  312.      * @throws PEAR_Exception
  313.      */
  314.     public function checkIntegrity()
  315.     {
  316.         if (!count($this->database)){
  317.             throw new PEAR_Exception(self::DB_SQLITE_TOOLS_NAR . $this->database, -1);
  318.         } else {
  319.             foreach($this->database as $databases) {
  320.                 $this->sqliteConnect($databases);
  321.                 $this->sqliteQuery('PRAGMA integrity_check');
  322.             }
  323.         }
  324.  
  325.         $this->logs[] = new DB_Sqlite_Tools_LogObject(
  326.                             __CLASS__, __FUNCTION__,
  327.                             'Integrity check returned ' .
  328.                             $this->result->integrity_check);
  329.         $this->displayLogs();
  330.  
  331.         return true;
  332.     }
  333.  
  334.     // }}}
  335.     // {{{ cacheSize()
  336.  
  337.     /**
  338.      * Check or set the cacheSize of the database.
  339.      *
  340.      * As a default value an sqlite database will hold 2000 disk pages in the
  341.      * memory each page requires approximately 1.5 K of memory. For intensive
  342.      * UPDATE or DELETE queries an higher memory might result in a speed
  343.      * increase. If pages parameter is not defined it will return the current
  344.      * cache size of the database or the multiple databases if $this->database
  345.      * is an array with more then one element
  346.      *
  347.      * If a valid integer is passed as $pages parameter it will set the cache
  348.      * size for the database or for multiple database if $this->database is an
  349.      * array with more then one element
  350.      *
  351.      * If defined it will set the new cache size (in pages) as per the specified
  352.      * integer.
  353.      *
  354.      * Note:
  355.      * When setting a new cache size. It might get a query error if on
  356.      * the database or one of the databases doesn't have the relevant write
  357.      * permissions. Please set the necessary permissions on
  358.      * the database/databases before attemping to change their cache value.
  359.      *
  360.      * @param int $pages (optional) number of pages to hold in the updated
  361.      *                              memory allocation
  362.      *
  363.      * @return true
  364.      * @throws PEAR_Exception
  365.      */
  366.     public function cacheSize($pages = false)
  367.     {
  368.         if (empty($pages)) {
  369.             foreach($this->database as $databases) {
  370.                 $this->sqliteConnect($databases);
  371.                 $this->sqliteQuery('PRAGMA default_cache_size');
  372.             }
  373.         } else {
  374.             if (!eregi('[[:digit:]]', $pages)) {
  375.                 throw new PEAR_Exception(self::DB_SQLITE_TOOLS_NNU . $pages, -1);
  376.             } else {
  377.                 foreach($this->database as $databases) {
  378.                     $this->sqliteConnect($databases);
  379.                     $this->sqliteQuery('PRAGMA default_cache_size = ' . $pages);
  380.                 }
  381.             }
  382.         }
  383.  
  384.         $this->logs[] = new DB_Sqlite_Tools_LogObject(
  385.                             __CLASS__, __FUNCTION__,
  386.                             'cache correctly reset to ' . $pages);
  387.         $this->displayLogs();
  388.  
  389.         return true;
  390.     }
  391.  
  392.     // }}}
  393.     // {{{ sync()
  394.  
  395.     /**
  396.      * Check or set the synchronous value for the database.
  397.      *
  398.      * Sqlite provides with different synchronous modes. The synchronous level
  399.      * determines the integrity protection. At NORMAL (default mode) the sqlite
  400.      * engine will stop at most critical moment providing with a limited
  401.      * integrity protection of the database. In FULL mode the engine will stop
  402.      * more often thus ensuring and higher integrity level. When OFF the engine
  403.      * will continue as soon as the new data is provided without stopping.
  404.      * Values are represented by an integer, 1 for NORMAL, 2 for FULL and 0 for
  405.      * off.
  406.      *
  407.      * If the parameter value is not set it will return the current default
  408.      * syncronous for the databases. If value is set with either FULL, NORMAL
  409.      * or OFF it will change the default syncronous value for each of
  410.      * the databases.
  411.      *
  412.      * @param sting $value (optional) A synchronous value.
  413.      *
  414.      * @return true
  415.      * @throws PEAR_Exception
  416.      */
  417.     public function sync($value = false)
  418.     {
  419.         if (empty ($value)) {
  420.             foreach($this->database as $databases) {
  421.                 $this->sqliteConnect($databases);
  422.                 $this->sqliteQuery('PRAGMA default_synchronous');
  423.             }
  424.         } else {
  425.             foreach($this->database as $databases) {
  426.                 $this->sqliteConnect($databases);
  427.                 if (eregi('FULL|NORMAL|OFF', $value)) {
  428.                     $this->sqliteQuery('PRAGMA default_synchronous = ' . $value);
  429.                 } else {
  430.                     throw new PEAR_Exception(self::DB_SQLITE_TOOLS_NAV . $value, -1);
  431.                 }
  432.             }
  433.         }
  434.  
  435.         $this->logs[] = new DB_Sqlite_Tools_LogObject(
  436.                             __CLASS__, __FUNCTION__,
  437.                             'Synchronous value correctly reset to ' . $value);
  438.         $this->displayLogs();
  439.  
  440.         return true;
  441.     }
  442.  
  443.     // }}}
  444.     // {{{ dbFileInfo()
  445.  
  446.     /**
  447.      * Retrieve general information on the database files like filename,
  448.      * owner id, group, name, permissions, library encoding and version,
  449.      * the size of the database, last time it was modified, blocks and
  450.      * generally every possible information on the database files.
  451.      *
  452.      * @return array An array of databases info.
  453.      * @throws PEAR_Exception
  454.      */
  455.     public function dbFileInfo()
  456.     {
  457.         foreach($this->database as $databases) {
  458.             $this->info[$databases] = array();
  459.             $stat = lstat($databases);
  460.             $this->info[$databases]['file_name'] = $databases;
  461.             $this->info[$databases]['file_owner_id'] = fileowner($databases);
  462.             if (function_exists('posix_getpwuid')) {
  463.                 $userinfo = posix_getpwuid($this->info[$databases]['file_owner_id']);
  464.             }
  465.  
  466.             //on windows $userinfo=null
  467.             $this->info[$databases]['file_owner_name'] =
  468.                 empty($userinfo['name']) ? '' : $userinfo['name'];
  469.             //on windows $userinfo=null
  470.             $this->info[$databases]['file_owner_group'] =
  471.                 empty($userinfo['gid']) ? '' : $userinfo['gid'];
  472.             $this->info[$databases]['libenconding'] = sqlite_libencoding();
  473.             $this->info[$databases]['libversion'] = sqlite_libversion();
  474.             $this->info[$databases]['permissions'] = fileperms($databases);
  475.             $this->info[$databases]['file_dev'] = $stat['dev'];
  476.             $this->info[$databases]['file_ino'] = $stat['ino'];
  477.             $this->info[$databases]['file_mode'] = $stat['mode'];
  478.             $this->info[$databases]['file_nlink'] = $stat['nlink'];
  479.             $this->info[$databases]['file_uid'] = $stat['uid'];
  480.             $this->info[$databases]['file_rdev'] = $stat['rdev'];
  481.             $this->info[$databases]['file_size'] = ($stat['size'] / 1024) .'KB';
  482.             $this->info[$databases]['file_atime'] = date('r', $stat['atime']);
  483.             $this->info[$databases]['file_mtime'] = date('r', $stat['mtime']);
  484.             $this->info[$databases]['file_ctime'] = date('r', $stat['ctime']);
  485.             $this->info[$databases]['file_blksize'] = $stat['blksize'];
  486.             $this->info[$databases]['file_blocks'] = $stat['blocks'];
  487.             $this->logs [] = new DB_Sqlite_Tools_LogObject(
  488.                                 __CLASS__, __FUNCTION__,
  489.                                 $this->info[$databases]);
  490.         }
  491.  
  492.         $this->displayLogs();
  493.  
  494.         return $this->info;
  495.     }
  496.  
  497.     // }}}
  498.     // {{{ copySafe()
  499.  
  500.     /**
  501.      * Safely duplicates a database file. copySafe should be performed before
  502.      * a backup as transfering via ftp or rsync.
  503.      *
  504.      * With this function we obtain an exclusive lock on the database before the
  505.      * copy, we then check the integrity of the copied databases.
  506.      * if the integrity check on the copied database returns OK this means that
  507.      * we have a cloned database ready for backup purposes.
  508.      *
  509.      * Individual or multiple databases are duplicated with the same name of the
  510.      * original database and the suffix .bkp
  511.      *
  512.      * @param string $path (optional) Destination path, default is current
  513.      *                                working path.
  514.      *
  515.      * @throws PEAR_Exception
  516.      */
  517.     public function copySafe($path = '')
  518.     {
  519.         // Set the output path to current working dir.
  520.         if (trim($path) == '') {
  521.             $path = './';
  522.         }
  523.  
  524.         $this->backupp = $path;
  525.  
  526.         if (!count($this->database)) {
  527.             throw new PEAR_Exception(self::DB_SQLITE_TOOLS_NAR . $this->database, -1);
  528.         } else {
  529.             foreach($this->database as $databases) {
  530.                 $fopenlock = @fopen($databases, 'r');
  531.                 if (!@$fopenlock) {
  532.                     throw new PEAR_Exception(self::DB_SQLITE_TOOLS_COFL,-1);
  533.                 }
  534.  
  535.                 $lock = @flock($fopenlock, LOCK_EX);
  536.                 if (!@$lock) {
  537.                     throw new PEAR_Exception(self::DB_SQLITE_TOOLS_CLF,-1);
  538.                 }
  539.  
  540.                 $clone = @copy($databases, $path . DIRECTORY_SEPARATOR . basename($databases) .'.bkp');
  541.                 if (!@$clone) {
  542.                     throw new PEAR_Exception(self::DB_SQLITE_TOOLS_CSF,-1);
  543.                 } else {
  544.                     $this->sqliteConnect($databases.'.bkp');
  545.                     $this->sqliteQuery('PRAGMA integrity_check');
  546.                 }
  547.  
  548.                 $release = @flock($fopenlock, LOCK_UN);
  549.                 if (!@$release) {
  550.                     throw new PEAR_Exception(self::DB_SQLITE_TOOLS_CCFL,-1);
  551.                 }
  552.             }
  553.         }
  554.  
  555.         $this->safecopy = true;
  556.         $this->logs[] = new DB_Sqlite_Tools_LogObject(__CLASS__, __FUNCTION__, 'done');
  557.         $this->displayLogs();
  558.         return true;
  559.     }
  560.  
  561.     // }}}
  562.     // {{{ scanBackupDir()
  563.  
  564.     /**
  565.      * Scans the backup directory as defined on copysafe for sqlite database
  566.      * preparing for the ftp backup
  567.      *
  568.      * It looks for previously backed up files with extension .bkp
  569.      *
  570.      * @return true
  571.      * @throws PEAR_Exception
  572.      */
  573.     private function scanBackupDir()
  574.     {
  575.         //scanning the directory
  576.         $scanned = @scandir($this->backupp, 0);
  577.  
  578.         if (!$scanned) {
  579.             throw new PEAR_Exception(self::DB_SQLITE_TOOLS_CSD, -1);
  580.         }
  581.  
  582.         foreach ($scanned as $this->parsed) {
  583.             // check if is an backup db file obtained in the previous copySafe
  584.             if(substr($this->parsed, -4) == '.bkp'){
  585.                       $this->backupar[] = $this->parsed;
  586.             }
  587.         }
  588.  
  589.         $this->logs[] = new DB_Sqlite_Tools_LogObject(
  590.                             __CLASS__, __FUNCTION__, $this->backupar);
  591.         return true ;
  592.     }
  593.  
  594.     // }}}
  595.     // {{{ ftpBackup()
  596.  
  597.     /**
  598.      * Safely copy the backup db to a remote ftp server. this function can be
  599.      * called only after a copySafe operation is performed.
  600.      *
  601.      * It will backup every database in the backup dir which is set with
  602.      * copySafe. If the intended use is to backup different group of databases
  603.      * the user can simply set a different path for copySafe.
  604.      *
  605.      * @param string $server   remote ftp server
  606.      * @param string $username ftp username
  607.      * @param string $password ftp password
  608.      * @param string $path     remote ftp path
  609.      *
  610.      * @return true
  611.      * @throws PEAR_Exception
  612.      */
  613.     public function ftpBackup($server, $username, $password, $path = '')
  614.     {
  615.         if ($this->safecopy == false) {
  616.             throw new PEAR_Exception(self::DB_SQLITE_TOOLS_INSC, -1);
  617.         }
  618.  
  619.         $this->scanBackupDir();
  620.         $this->ftpConnect($server, $username, $password);
  621.  
  622.         foreach($this->backupar as $database) {
  623.             $localdb = $this->backupp . DIRECTORY_SEPARATOR . $database;
  624.             $put = @ftp_put($this->ftpconnection, $path . '/' . $database,
  625.                            $localdb, FTP_BINARY);
  626.  
  627.             if (!$put) {
  628.                 throw new PEAR_Exception(self::DB_SQLITE_TOOLS_CUFS);
  629.             } else {
  630.                 $this->logs[] = new DB_Sqlite_Tools_LogObject(
  631.                                     __CLASS__, __FUNCTION__,
  632.                                     $localdb . ' uploaded');
  633.             }
  634.         }
  635.  
  636.         $this->displayLogs();
  637.         return true;
  638.     }
  639.  
  640.     // }}}
  641.     // {{{ ftpConnect()
  642.  
  643.     /**
  644.      * Connects to the remote ftp server
  645.      *
  646.      * @param string $server   remote ftp server
  647.      * @param string $username ftp username
  648.      * @param string $password ftp password
  649.      *
  650.      * @throws PEAR_Exception
  651.      */
  652.     private function ftpConnect ($server,$username,$password)
  653.     {
  654.         $this->ftpconnection = @ftp_connect($server);
  655.         if (!@$this->ftpconnection) {
  656.             throw new PEAR_Exception (self::DB_SQLITE_TOOLS_CCFS,-1);
  657.         }
  658.  
  659.         $logged = ftp_login($this->ftpconnection, $username, $password);
  660.         if (!@$logged) {
  661.             throw new PEAR_Exception(self::DB_SQLITE_TOOLS_CLFS,-1);
  662.         }
  663.     }
  664.  
  665.     // }}}
  666.     // {{{ localBackup()
  667.  
  668.     /**
  669.      * Creates a local backup of the database file and checks for its integrity.
  670.      *
  671.      * @param string $destination Local backup path.
  672.      *
  673.      * @throws PEAR_Exception
  674.      */
  675.     public function localBackup($destination)
  676.     {
  677.         foreach($this->database as $databases) {
  678.             $backupfile = $destination.'/'.$databases.'.bkp';
  679.  
  680.             $fopenlock = @fopen($databases, 'r');
  681.             if (!@$fopenlock) {
  682.                 throw new PEAR_Exception(self::DB_SQLITE_TOOLS_COFL, -1);
  683.             }
  684.  
  685.             $lock = @flock($fopenlock, LOCK_EX);
  686.             if (!@$lock) {
  687.                 throw new PEAR_Exception(self::DB_SQLITE_TOOLS_CLF, -1);
  688.             }
  689.  
  690.             $clone = @copy($databases, $backupfile);
  691.             if (!@$clone) {
  692.                 throw new PEAR_Exception(self::DB_SQLITE_TOOLS_CSF, -1);
  693.             } else {
  694.                 $this->logs[] = new DB_Sqlite_Tools_LogObject(
  695.                                     __CLASS__, __FUNCTION__,
  696.                                     $backupfile .' successfully copied');
  697.  
  698.                 $this->sqliteConnect($backupfile);
  699.                 $this->sqliteQuery('PRAGMA integrity_check');
  700.             }
  701.  
  702.             $release = @flock($fopenlock, LOCK_UN);
  703.             if (!@$release) {
  704.                 throw new PEAR_Exception(self::DB_SQLITE_TOOLS_CCFL, -1);
  705.             }
  706.         }
  707.  
  708.         $this->displayLogs();
  709.         return true;
  710.     }
  711.  
  712.     // }}}
  713.     // {{{ localRsync()
  714.  
  715.     /**
  716.      * Initiaties a local rsync of a given database path requires rsync
  717.      * installed locally.
  718.      *
  719.      * @param string $databasesPath  Path to the databases folder to sync locally
  720.      * @param string $backupsPath    Sync Destionation path
  721.      * @param string $options        Rsync options
  722.      *
  723.      * @throws PEAR_Exception
  724.      */
  725.     public function localRsync ($databasesPath,$backupsPath,
  726.                                 $options='--verbose --stats --recursive --progress --delete')
  727.     {
  728.         $command = 'rsync ' . $options . ' ' . $databasesPath . ' ' . $backupsPath;
  729.         $this->logs[] = new DB_Sqlite_Tools_LogObject(__CLASS__, __FUNCTION__, $command);
  730.         $command = escapeshellcmd($command);
  731.         $exec = shell_exec($command);
  732.         $this->logs[] = new DB_Sqlite_Tools_LogObject(__CLASS__, __FUNCTION__, $exec);
  733.         $this->displayLogs();
  734.     }
  735.  
  736.     // }}}
  737.     // {{{ remoteRsync()
  738.  
  739.     /**
  740.      * remoteRsync prepared the server where this package is running to receive
  741.      * read connections over rsync for the purpose of remote synchronisation.
  742.      * it created a valid rsync configuration file and starts the deamon
  743.      * allowing connection from the allowed host.
  744.      *
  745.      * This function is experimental.
  746.      *
  747.      * @param sting $databasesPath    Path for the databases folder
  748.      * @param string $configfile      name of the rsync config file
  749.      * @param string $configfilepath  path where the rsync config file will be saved
  750.      *                                the users that runs apache must have permissions
  751.      *                                on this path for the config, the pid and the lock file
  752.      * @param string $uid             user id under which rsync will run
  753.      * @param string $gid             group id under which rsync will run
  754.      * @param string $allowedhost     ip or domain of the allowed host
  755.      * @param string $logs            logs file name and path
  756.      * @param string $secretfile      rsync secret file location (which should contain the password)
  757.      *
  758.      * @throws PEAR_Exception
  759.      */
  760.     public function remoteRsync ($databasesPath, $configfile, $configfilepath,
  761.                                 $uid ,$gid , $allowedhost,$logs,$secretfile)
  762.     {
  763.         $rsynconfig= <<<RSYNC
  764. uid = $uid
  765. gid = $gid
  766. use chroot = no
  767. max connections = 4
  768. syslog facility = local5
  769. pid file = $configfilepath/rsyncd.pid
  770. lock file =  $configfilepath/rsyncd.lock
  771. strict modes = no
  772. [sqlite_tools]
  773. read only= yes
  774. path = $databasesPath
  775. auth users = rsync
  776. hosts allow = $allowedhost
  777. secrets file = $secretfile
  778. RSYNC;
  779.  
  780.         $cffile = $configfilepath . '/' . $configfile;
  781.         $sfile=@fopen($cffile,'w+');
  782.         if (!@$sfile){
  783.             throw new PEAR_Exception (self::DB_SQLITE_TOOLS_RSE,-1);
  784.         }
  785.  
  786.         $sfilew=@fwrite($sfile,$rsynconfig);
  787.         if (!@$sfilew){
  788.             throw new PEAR_Exception (self::DB_SQLITE_TOOLS_RSE,-1);
  789.         }
  790.  
  791.         $sfileclose=fclose($sfile);
  792.         if (!@$sfileclose){
  793.             throw new PEAR_Exception (self::DB_SQLITE_TOOLS_RSE,-1);
  794.         }
  795.  
  796.         print_r($cffile);
  797.  
  798.         $spec = array(
  799.             0 => array('pipe', 'r'),  // read pipe
  800.             1 => array('pipe', 'w'),  // write pipe
  801.             2 => array('file', $logs, 'a') // logs file
  802.         );
  803.         $pipes = '';
  804.  
  805.         // added port 2000 because the apache user doesn't have permissions in
  806.         // the default rsync port
  807.         $proc = proc_open("rsync --no-detach --daemon --port=2000 --config=$cffile",
  808.                           $spec, $pipes);
  809.  
  810.         fclose($pipes[1]);
  811.         $output = proc_close($proc);
  812.         $this->logs[] = new DB_Sqlite_Log_Object(__CLASS__, __FUNCTION__, $output);
  813.         $this->displayLogs();
  814.     }
  815.  
  816.     // }}}
  817.     // {{{ sqliteLogs()
  818.  
  819.     /**
  820.      * Logs all the perfomed action in a database log
  821.      * this includes backups, integrity checks
  822.      * each of the integrity queries. Verbose XML style output for each of the
  823.      * actions.
  824.      *
  825.      * Sample log output -
  826.      * <logevent>  <class>DB_Sqlite_Tools</class>  <function>cacheSize</function>
  827.      * <data> 'cache correctly reset to 10000'  </data> </logevent>
  828.      *
  829.      * All the logs are saved with the time of execution. The user can easily
  830.      * generate customized logs from the raw data provided in this package.
  831.      *
  832.      * @param string $db             Logs database
  833.      * @param string $maketable      create a default log table
  834.      * @param string $table          table name
  835.      *
  836.      * @throws PEAR_Exception on failure
  837.      */
  838.     public function sqliteLogs($db = '', $maketable = true, $table = '')
  839.     {
  840.         $this->sqliteConnect($db);
  841.         if ($maketable == true) {
  842.              $sql = "CREATE table $table (
  843.                         id  INTEGER PRIMARY KEY,
  844.                         log VARCHAR (200),
  845.                         date VARCHAR (200))";
  846.             $this->sqliteQuery($sql);
  847.         }
  848.  
  849.         foreach($this->logs as $logs) {
  850.                 $time = time();
  851.                 $lstr = $logs->toString() ;
  852.                 $sstr = sqlite_escape_string($lstr);
  853.                 $sql = "INSERT into $table(log, date)
  854.                         VALUES ('$sstr',$time)";
  855.                 $this->sqliteQuery($sql);
  856.         }
  857.  
  858.         unset($this->logs);
  859.     }
  860.  
  861.     // }}}
  862.     // {{{ sqliteConnect()
  863.  
  864.     /**
  865.      * Connects to the SQLite database.
  866.      *
  867.      * @param string $db Path to the database
  868.      *
  869.      * @return true
  870.      * @throws PEAR_Exception on failure
  871.      */
  872.     private function sqliteConnect($db)
  873.     {
  874.         $this->debug('Connecting to ' . $db . "\n");
  875.  
  876.         try {
  877.             $obj = $this->dbobj = new SQLiteDatabase($db);
  878.         } catch (PEAR_Exception $obj) {
  879.             print $obj;
  880.             return false ;
  881.         }
  882.  
  883.         return true;
  884.     }
  885.  
  886.     // }}}
  887.     // {{{ sqliteConnectProc()
  888.  
  889.     /**
  890.      * Procedural version of sqliteConnect.
  891.      *
  892.      * @param string $db Path to the database
  893.      *
  894.      * @return TRUE
  895.      * @throws PEAR_Exception
  896.      */
  897.     private function sqliteConnectProc ($db)
  898.     {
  899.         $this->debug(print 'Connecting to ' . $db . "\n");
  900.  
  901.         $this->opendb = @sqlite_open($db, 0666, $this->error);
  902.  
  903.         if (!@$this->opendb){
  904.             throw new PEAR_Exception (self::DB_SQLITE_TOOLS_COD . $this->error, -1);
  905.         }
  906.  
  907.         return true ;
  908.     }
  909.  
  910.     // }}}
  911.     // {{{ sqliteQuery()
  912.  
  913.     /**
  914.      * Queries the sqlite database.
  915.      *
  916.      * @param string $sql query
  917.      *
  918.      * @return $this->results
  919.      */
  920.     private function sqliteQuery($sql)
  921.     {
  922.         $results = $this->dbobj->query($sql);
  923.         if ($results != false) {
  924.             $this->result = $results->fetchObject();
  925.             if (!is_object($this->result)) {
  926.                 $this->debug(self::DB_SQLITE_TOOLS_QNR);
  927.             } else {
  928.                 $this->debug(
  929.                     self::DB_SQLITE_TOOLS_QRS . "\n" .
  930.                     print_r($this->result, true)
  931.                 );
  932.             }
  933.         }
  934.         return $this->result;
  935.     }
  936.  
  937.     // }}}
  938.     // {{{ XMLDecode()
  939.  
  940.     /**
  941.      * Decodes the XML content.
  942.      *
  943.      * @param string $str A content.
  944.      *
  945.      * @return string
  946.      */
  947.     public function XMLDecode($str)
  948.     {
  949.         return strtr($str, array_flip(get_html_translation_table(HTML_SPECIALCHARS)));
  950.     }
  951.  
  952.     // }}}
  953.     // {{{ XMLEncode()
  954.  
  955.     /**
  956.      * Encodes the XML content.
  957.      *
  958.      * @param string $str A content.
  959.      *
  960.      * @return string
  961.      */
  962.     public function XMLEncode($str)
  963.     {
  964.        return strtr($str, get_html_translation_table(HTML_SPECIALCHARS));
  965.     }
  966.  
  967.     // }}}
  968.     // {{{ performXMLDump()
  969.  
  970.     /**
  971.      * Creates an XML dump for a full sqlite database the dump can be
  972.      * manipulated or used to export the data in several other formats or
  973.      * converted back to an sqlite database with the method createDBFromXML
  974.      *
  975.      * @param string $db the sqlite database file to convert
  976.      * @param string $fh the XML file used for the dump
  977.      *
  978.      */
  979.     private function performXMLDump($db, $fh)
  980.     {
  981.         $this->sqliteConnectProc($db);
  982.  
  983.         // Obtain a list of all tables
  984.         $tableList = array();
  985.         $result = sqlite_query($this->opendb, "SELECT name FROM sqlite_master WHERE type='table'");
  986.  
  987.         if ($result) {
  988.             while (sqlite_has_more($result)) {
  989.                 $table = array();
  990.                 // Fetch name
  991.                 $table["name"] = sqlite_fetch_single($result);
  992.                 // Perform a query on the table to get it's columns
  993.                 $table["columns"] = array();
  994.                 $columnQuery = sqlite_query($this->opendb, "SELECT ALL * FROM ".$table["name"]." LIMIT 1");
  995.                 $numColumns = sqlite_num_fields($columnQuery);
  996.                 for ($i = 0;$i<$numColumns;$i++) {
  997.                     $table["columns"][$i] = array();
  998.                     $table["columns"][$i]["name"] = sqlite_field_name($columnQuery, $i);
  999.                     $table["columns"][$i]["type"] = "";
  1000.                 }
  1001.                 array_push($tableList, $table);
  1002.             }
  1003.         }
  1004.  
  1005.         // XML declaration
  1006.         fputs($fh, '<?xml version="1.0" encoding="ISO-8859-1" ?>'."\n");
  1007.         fputs($fh, "<db name=\"$db\">\n");
  1008.         foreach($tableList as $table) {
  1009.             fputs($fh, "   <table name=\"".$table["name"]."\">\n");
  1010.             fputs($fh, "      <columns count=\"".count($table["columns"]) ."\">\n");
  1011.             foreach($table["columns"] as $column) {
  1012.                 fputs($fh, "          <column name=\"".$column["name"]."\" />\n");
  1013.             }
  1014.             fputs($fh, "      </columns>\n");
  1015.             $rowQuery = sqlite_query($this->opendb, "SELECT ALL * FROM ".$table["name"]);
  1016.             fputs($fh, "      <rows count=\"".sqlite_num_rows($rowQuery) ."\">\n");
  1017.             while (sqlite_has_more($rowQuery)) {
  1018.                 $rowArray = sqlite_fetch_array($rowQuery);
  1019.                 fputs($fh, "          <row>\n");
  1020.                 foreach($table["columns"] as $column) {
  1021.                     fputs($fh, "             <column name=\"".$column["name"]."\">");
  1022.                     fputs($fh, $this->XMLEncode($rowArray[$column["name"]]));
  1023.                     fputs($fh, "</column>\n");
  1024.                 }
  1025.                 fputs($fh, "          </row>\n");
  1026.             }
  1027.             fputs($fh, "      </rows>\n");
  1028.             fputs($fh, "   </table>\n");
  1029.         }
  1030.         fputs($fh, "</db>");
  1031.     }
  1032.  
  1033.     // }}}
  1034.     // {{{ createXMLDumps()
  1035.  
  1036.     /**
  1037.      * For each of the databases in our contructor array creates an XML dump
  1038.      * including all the tables of that database.
  1039.      * The XML file is generated via the function performXMLDump
  1040.      * The backup file is by default the database name .xml
  1041.      *
  1042.      * @return true
  1043.      * @throws  PEAR exception on failure
  1044.      */
  1045.     public function createXMLDumps($path ='')
  1046.     {
  1047.         if ($this->safecopy == false) {
  1048.             throw new PEAR_Exception(self::DB_SQLITE_TOOLS_INSC, -1);
  1049.         }
  1050.  
  1051.         $this->scanBackupDir();
  1052.         foreach($this->backupar as $database) {
  1053.             $XMLFile = @fopen($path . $database . '.xml', 'w');
  1054.             if (!$XMLFile) {
  1055.                 throw new PEAR_Exception(self::DB_SQLITE_TOOLS_CCXML . $database . '.xml', -1);
  1056.             }
  1057.  
  1058.             $this->performXMLDump($this->backupp.DIRECTORY_SEPARATOR . $database, $XMLFile);
  1059.             $XMLclose = @fclose($XMLFile);
  1060.             if (!$XMLclose) {
  1061.                 throw new PEAR_Exception(self::DB_SQLITE_TOOLS_CCLXML . $database . '.xml', -1);
  1062.             }
  1063.  
  1064.             $this->debug("{$database}.xml successfully created\n");
  1065.             $this->logs[] = new DB_Sqlite_Tools_LogObject(
  1066.                 __CLASS__, __FUNCTION__, "{$database}.xml successfully created"
  1067.             );
  1068.         }
  1069.  
  1070.         $this->displayLogs();
  1071.         return true;
  1072.     }
  1073.  
  1074.     // }}}
  1075.     // {{{ createDBFromXML()
  1076.  
  1077.     /**
  1078.      * Converts an XML exported database back to an Sqlite database
  1079.      *
  1080.      * @param string $xmlFile  the XML database dump to convert
  1081.      * @param string $db       the sqlite db to be generated from the XML data
  1082.      *
  1083.      */
  1084.     public function createDBFromXML($xmlFile, $db)
  1085.     {
  1086.         $this->debug("Now importing XML from $xmlFile to $db\n");
  1087.  
  1088.         $fh = fopen($xmlFile, "r");
  1089.  
  1090.         $this->debug("opened $xmlFile as $fh\n");
  1091.  
  1092.         $parser = new DB_Sqlite_Tools_XMLParser( $fh ) ;
  1093.         $parser->ignore('^\?.*$') ;
  1094.         $parser->ignore('^!--.*$') ;
  1095.  
  1096.         $parser->getNextElement() ;
  1097.  
  1098.         if ($parser->getElementName() != 'db') {
  1099.             return false;
  1100.         }
  1101.  
  1102.         $tables = array() ;
  1103.  
  1104.         while ($parser->getNextElement()) {
  1105.             if ($parser->getElementName() == '/db') {
  1106.                 break ;
  1107.             } else if ($parser->getElementName() == 'table') {
  1108.                 $tableName = $parser->getElementAttribute('name');
  1109.                 $columns = array() ;
  1110.                 $rows = array() ;
  1111.  
  1112.                 while($parser->getNextElement()) {
  1113.                     if($parser->getElementName() == 'rows') {
  1114.                         $this->debug("Begin rows\n");
  1115.                         $i = 0 ;
  1116.                         while ($parser->getNextElement()) {
  1117.                             if ($parser->getElementName() == 'row') {
  1118.                                 $rows[$i] = array() ;
  1119.                                 while ($parser->getNextElement()) {
  1120.                                     if ($parser->getElementName() == 'column') {
  1121.                                         $curColumn = $parser->getElementAttribute('name');
  1122.                                         $this->debug("Column $curColumn in row $i\n");
  1123.                                     } else if ($parser->getElementName() == '/column') {
  1124.                                         $rows[$i][$curColumn] = $this->XMLDecode($parser->getEnclosed());
  1125.                                         $this->debug("Close column $curColumn in row $i\n");
  1126.                                     } else if ($parser->getElementName() == '/row') {
  1127.                                         break ;
  1128.                                     }
  1129.                                 // end while
  1130.                                 }
  1131.                                 $i++ ;
  1132.                             // end "row"
  1133.                             } else if ($parser->getElementName() == '/rows') {
  1134.                                 break ;
  1135.                             }
  1136.                         // end while
  1137.                         }
  1138.                     // end "rows"
  1139.                     } else if ($parser->getElementName() == 'columns') {
  1140.                         $this->debug("Begin columns\n");
  1141.                         $i = 0 ;
  1142.                         while ($parser->getNextElement()) {
  1143.                             if ($parser->getElementName() == 'column') {
  1144.                                 $columns[$i] = array() ;
  1145.                                 $columns[$i]['name'] = $parser->getElementAttribute('name');
  1146.                                 $i++ ;
  1147.                             // end "row"
  1148.                             } else if ($parser->getElementName() == '/columns') {
  1149.                                 $this->debug("End columns\n");
  1150.                                 break ;
  1151.                             }
  1152.                         // end while
  1153.                         }
  1154.                     // end columns
  1155.                     }
  1156.  
  1157.                     if ($parser->getElementName() == '/table') {
  1158.                         break ;
  1159.                     }
  1160.  
  1161.                 // end while
  1162.                 }
  1163.  
  1164.                 array_push( $tables, array( "name" => $tableName, "columns" => $columns, "rows" => $rows ) ) ;
  1165.  
  1166.             // end table
  1167.             }
  1168.  
  1169.         // end while
  1170.         }
  1171.  
  1172.         $this->debug("Now performing SQL queries...\n");
  1173.  
  1174.         $this->sqliteConnect($db);
  1175.         $this->sqliteQuery('BEGIN TRANSACTION;');
  1176.  
  1177.         foreach ($tables as $table) {
  1178.             $columnList ='';
  1179.             foreach ($table['columns'] as $column) {
  1180.                 $columnList=$columnList.$column["name"]."," ;
  1181.             }
  1182.  
  1183.             // Remove trailing comma
  1184.             $columnList = substr($columnList, 0, strlen($columnList) - 1);
  1185.  
  1186.             $this->sqliteQuery("CREATE TABLE {$table['name']} ($columnList);");
  1187.             foreach ($table['rows'] as $row ) {
  1188.                 $fieldNameList = '';
  1189.                 $fieldDataList = '';
  1190.                 foreach( $row as $fieldName => $fieldData ) {
  1191.                     $fieldNameList = $fieldNameList . $fieldName . ',';
  1192.                     $fieldDataList = $fieldDataList . '\'' . sqlite_escape_string($fieldData) . '\',';
  1193.                 }
  1194.  
  1195.                 // Remove trailing commas
  1196.                 $fieldNameList=substr($fieldNameList,0,strlen($fieldNameList)-1) ;
  1197.                 $fieldDataList=substr($fieldDataList,0,strlen($fieldDataList)-1) ;
  1198.                 $this->sqliteQuery(
  1199.                     "INSERT OR ROLLBACK INTO
  1200.                         {$table['name']} ($fieldNameList)
  1201.                      VALUES
  1202.                         ($fieldDataList);"
  1203.                 );
  1204.             }
  1205.         }
  1206.  
  1207.         $this->sqliteQuery('COMMIT;') ;
  1208.         fclose($fh) ;
  1209.     }
  1210.  
  1211.     // }}}
  1212.     // {{{ debug()
  1213.  
  1214.     /**
  1215.      * Set and display debug message if debug is On.
  1216.      *
  1217.      * @param string $msg Debug message.
  1218.      */
  1219.     private function debug($msg)
  1220.     {
  1221.         if ($this->debug) {
  1222.             // Web context.
  1223.             if (isset($_SERVER['REQUEST_URI'])) {
  1224.                 $msg = nl2br($msg);
  1225.             }
  1226.  
  1227.             echo 'DB_Sqlite_Tools debug: ' . $msg;
  1228.         }
  1229.     }
  1230.  
  1231.     // }}}
  1232. }
  1233.  
  1234. // }}}
  1235. // {{{ Class: DB_Sqlite_Tools_LogObject
  1236.  
  1237. /**
  1238.  * A class provides few function for working with the event log.
  1239.  *
  1240.  * @category Database
  1241.  * @package DB_Sqlite_Tools
  1242.  * @author David Costa <gurugeek@php.net>
  1243.  * @author Ashley Hewson <morbidness@gmail.com>
  1244.  * @author Firman Wandayandi <firman@php.net>
  1245.  * @copyright Copyright (c) 2004-2006 David Costa
  1246.  * @license http://www.opensource.org/licenses/bsd-license.php
  1247.  *          BSD License
  1248.  * @version Release: 0.1.5
  1249.  */
  1250. class DB_Sqlite_Tools_LogObject
  1251. {
  1252.     // {{{ Properties
  1253.  
  1254.     /**
  1255.      * Class name.
  1256.      *
  1257.      * @var string
  1258.      */
  1259.     private $class;
  1260.  
  1261.     /**
  1262.      * Function name.
  1263.      *
  1264.      * @var string
  1265.      */
  1266.     private $function;
  1267.  
  1268.     /**
  1269.      * Log data or message.
  1270.      *
  1271.      * @var string
  1272.      */
  1273.     public $data;
  1274.  
  1275.     // }}}
  1276.     // {{{ Constructor()
  1277.  
  1278.     /**
  1279.      * Constructor.
  1280.      *
  1281.      * @param string $class A class name.
  1282.      * @param string $function A function name.
  1283.      * @param string $data Log data or message.
  1284.      */
  1285.     public function __construct($class, $function, $data)
  1286.     {       $this->class = $class;
  1287.             $this->function = $function;
  1288.             $this->data = $data;
  1289.     }
  1290.  
  1291.     // }}}
  1292.     // {{{ __toString()
  1293.  
  1294.     /**
  1295.      * Magic function, to print this object.
  1296.      *
  1297.      * This function determine the context of which representation
  1298.      * to return.
  1299.      *
  1300.      * @return string The event log.
  1301.      */
  1302.     public function __toString()
  1303.     {
  1304.         if (isset($_SERVER['REQUEST_URI'])) {
  1305.             return $this->toHtml();
  1306.         }
  1307.         return $this->toText();
  1308.     }
  1309.  
  1310.     // }}}
  1311.     // {{{ toXML()
  1312.  
  1313.     /**
  1314.      * Creates an XML representation of event log.
  1315.      *
  1316.      * @return string The XML representation of the event log.
  1317.      */
  1318.     public function toXML()
  1319.     {
  1320.       $data = var_export($this->data, true);
  1321.  
  1322. return <<<XML
  1323. <logevent>
  1324.   <class>$this->class</class>
  1325.   <function>$this->function</function>
  1326.   <data>$data</data>
  1327. </logevent>
  1328. XML;
  1329.     }
  1330.  
  1331.     // }}}
  1332.     // {{{ toText()
  1333.  
  1334.     /**
  1335.      * Creates a plain-text representation of event log.
  1336.      *
  1337.      * @return string The plain-text representation of event log.
  1338.      */
  1339.     public function toText()
  1340.     {
  1341.         return 'DB_Sqlite_Tools log: ' .
  1342.                'logged on ' . $this->class . '::' . $this->function . '(), ' .
  1343.                'data=' . print_r($this->data, true) . "\n";
  1344.     }
  1345.  
  1346.     // }}}
  1347.     // {{{ toHTML()
  1348.  
  1349.     /**
  1350.      * Creates a HTML representation of event log.
  1351.      *
  1352.      * @return string The HTML representation of event log.
  1353.      */
  1354.     public function toHTML()
  1355.     {
  1356.         $data = $this->data;
  1357.         if (is_array($data) || is_object($this->data)) {
  1358.             $data = '<pre>' . "\n"
  1359.                   . print_r($data, true)
  1360.                   . '</pre>' . "\n";
  1361.         }
  1362.  
  1363.         return '<table border="1" cellspacing="0">' . "\n"
  1364.              . '<tr><td colspan="3" bgcolor="#aaaaaa" align="center"><b>DB_Sqlite_Tools log</b></td></tr>' . "\n"
  1365.              . '<tr>'
  1366.              . '<td align="center" bgcolor="#cccccc"><b>Event</b></td>'
  1367.              . '<td align="center" bgcolor="#cccccc"><b>Data</b></td>'
  1368.              . '</tr>' . "\n"
  1369.              . '<tr>'
  1370.              . '<td valign="top">' . $this->class . '::' . $this->function . '()' . '</td>'
  1371.              . '<td>' . $data . '</td>'
  1372.              . '</tr>' . "\n"
  1373.              . '</table>';
  1374.     }
  1375.  
  1376.     // }}}
  1377. }
  1378.  
  1379. // }}}
  1380.  
  1381. /*
  1382.  * Local variables:
  1383.  * mode: php
  1384.  * tab-width: 4
  1385.  * c-basic-offset: 4
  1386.  * c-hanging-comment-ender-p: nil
  1387.  * End:
  1388.  */
  1389. ?>