Source for file install.php

Documentation is available at install.php

  1. <?php
  2. /**
  3.  * PLUGIN INSTALLER
  4.  *
  5.  * Version 0.4
  6.  * Für Contenido 4.4.4 and up 4.5.x
  7.  *
  8.  * @author      Martin Horwath (horwath@dayside.net)
  9.  * @date        26.09.2004
  10.  * @date        10.10.2005
  11.  * @date        15.02.2006 - Paul Sauer <contenido@saueronline.de>
  12.  * @date        12.09.2006 - Murat Purc <murat@purc.de>
  13.  * @package     Contenido
  14.  * @subpackage  Plugin installer
  15.  */
  16.  
  17. /* PLUGIN INSTALLER
  18.  * Version 0.4
  19.  * Für Contenido 4.4.4 and up 4.5.x
  20.  * Autor: Martin Horwath (horwath@dayside.net)
  21.  * Datum: 26.09.2004
  22.  * Modifiziert: 10.10.2005
  23.  *              15.02.2006 - Paul Sauer <contenido@saueronline.de>
  24.  *              12.09.2006 - Murat Purc <murat@purc.de>
  25.  */
  26.  
  27.  
  28. $cfg['debug']['installer'false;
  29. $checktablestatus true;
  30.  
  31.  
  32. $contenido_path '../../';
  33. if (file_exists($contenido_path 'includes/startup.php')) {
  34.     include_once($contenido_path 'includes/startup.php');
  35. else {
  36.     include_once($contenido_path 'includes/config.php');
  37. }
  38.  
  39. cInclude('includes''functions.general.php');
  40.  
  41. $cfg['debug']['backend_exectime']['fullstart'getmicrotime();
  42.  
  43. cInclude('includes''functions.i18n.php');
  44. cInclude('includes''functions.api.php');
  45. cInclude('includes''functions.general.php');
  46. cInclude('includes''functions.database.php');
  47. cInclude('includes''functions.str.php');
  48.  
  49. cInclude('classes''class.xml.php');
  50. cInclude('classes''class.navigation.php');
  51. cInclude('classes''class.template.php');
  52. cInclude('classes''class.backend.php');
  53. cInclude('classes''class.notification.php');
  54. cInclude('classes''class.area.php');
  55. cInclude('classes''class.action.php');
  56. cInclude('classes''class.layout.php');
  57. cInclude('classes''class.treeitem.php');
  58. cInclude('classes''class.user.php');
  59. cInclude('classes''class.group.php');
  60. cInclude('classes''class.cat.php');
  61. cInclude('classes''class.client.php');
  62. cInclude('classes''class.inuse.php');
  63. cInclude('classes''class.table.php');
  64.  
  65. plugin_include('mod_rewrite''includes/functions.mod_rewrite_setup.php');
  66.  
  67. page_open(array('sess' => 'Contenido_Session''auth' => 'Contenido_Challenge_Crypt_Auth''perm' => 'Contenido_Perm'));
  68.  
  69. i18nInit($cfg['path']['contenido'$cfg['path']['locale']$belang);
  70. cInclude('includes''cfg_language_de.inc.php');
  71.  
  72. class DB_Upgrade extends DB_Contenido {/*donut*/}
  73.  
  74. // instanzen der db_contenido
  75. $db  new DB_Contenido;
  76. $db2 new DB_Contenido;
  77.  
  78. $data['top']         '';
  79. $data['content']     '';
  80. $data['bottom']      '';
  81. $data['body_bottom''';
  82.  
  83. #$currentuser = new User();
  84. #$currentuser->loadUserByUserID($auth->auth["uid"]);
  85.  
  86. $cfg["debug"]["backend_exectime"]["start"getmicrotime();
  87.  
  88. if ($checktablestatus{
  89.     $required_fields array(
  90.         "idplugin""name""version""author""idinternal""url",
  91.         "status""description""install""uninstall""date"
  92.     );
  93.     
  94. //    $required_table = "DROP TABLE " . $cfg['tab']['plugins'] . ";
  95.     $required_table "RENAME TABLE " $cfg['tab']['plugins'" TO " $cfg['tab']['plugins'"_" date('Ymd'";
  96.                       CREATE TABLE " $cfg['tab']['plugins'" (
  97.                           idplugin INT(10) NOT NULL default '0',
  98.                           name VARCHAR(60) default NULL,
  99.                           version VARCHAR(10) NOT NULL default '0',
  100.                           author VARCHAR(60) default NULL,
  101.                           idinternal VARCHAR(32) NOT NULL default '0',
  102.                           url TEXT,
  103.                           status INT(10) NOT NULL default '0',
  104.                           description TEXT,
  105.                           install TEXT,
  106.                           uninstall TEXT,
  107.                           date DATETIME NOT NULL default '0000-00-00 00:00:00',
  108.                           PRIMARY KEY (idplugin)
  109.                       ) TYPE=MyISAM;";
  110.     // now we check if the plugin table has the right format...
  111.     msg("Checking status " $cfg['tab']['plugins']);
  112.     $ptable $db->metadata($cfg['tab']['plugins']);
  113.  
  114.     foreach ($ptable as $key{
  115.         if (!in_array($key['name']$required_fields)) {
  116.             msg($key['name'" (this key can be deleted)""unused key");
  117.         else {
  118.             $availableKeys[$key['name'];
  119.         }
  120.         $foundkeys[$key['name'];
  121.     }
  122.     foreach ($required_fields as $key{
  123.         if (!in_array($key$foundkeys)) {
  124.             msg($key " (this key must be added)""missing key");
  125.             $missingKeys[$key;
  126.         }
  127.     }
  128.     unset ($foundkeys$key);
  129.     // available elements in table are stored in array -> $availableKeys;
  130.     // missing elements in table are stored in array -> $missingKeys;
  131.     // this is a possible way to handle new versions of plugin installer
  132.     // since this is initial release the table will be dropped and recreated
  133.     // when a missing element is found.
  134.     if (count($missingKeys0{
  135.         $sql_data remove_remarks($required_table);
  136.         $sql_pieces split_sql_file($sql_data';');
  137.         msg(count($sql_pieces" queries""Executing:");
  138.         foreach ($sql_pieces as $sqlinit{
  139.             $db->query($sqlinit);
  140.             msg($sqlinit);
  141.         }
  142.     else {
  143.         msg("ok");
  144.     }
  145. }
  146.  
  147. // con_sequence update
  148.  
  149. #print '<html><body style="font-family: Verdana; font-size:11px;">';
  150. // installer starts here
  151. #print "<b>PLUGIN INSTALLER</b><br><br>\n";
  152. $data['top'.= "<b>PLUGIN INSTALLER</b><br><br>\n";
  153.  
  154. $clink "<br><a href=\"../../index.php?contenido=$contenido\">Switch to backend</a>\r\n";
  155.  
  156. if ($installsql file_get_contents('install.sql')) {
  157.     // get info from sql file
  158.     if (preg_match ("/####(.*)####/i"$installsql$pinfo)) {
  159.         $pinfo explode (";"$pinfo[1]);
  160.         // take some nice names easier to work with...
  161.         $pname       $pinfo[0];
  162.         $pversion    $pinfo[1];
  163.         $pauthor     $pinfo[2];
  164.         $pinternalid $pinfo[3];
  165.  
  166.         unset($pinfo);
  167.         // first show info
  168.         $data['content'.= "Plugin Name: " $pname "<br>\n";
  169.         $data['content'.= "Plugin Version: " $pversion "<br>\n";
  170.         $data['content'.= "Author: " $pauthor "<br>\n";
  171.         $data['content'.= "Internal ID: " $pinternalid "<br>\n";
  172.         // the user don't need this info...
  173.         $installsql preg_replace ("/####(.*)####/i"""$installsql);
  174.  
  175.         $pstatus true;
  176.     else {
  177.         $data['content'.= "Info missing. First line of install.sql should include following line:<br>";
  178.         $data['content'.= "<b>####NAME;VERSION;AUTHOR;INTERNAL_ID####</b><br>";
  179.         $data['content'.= "No further action takes place<br>";
  180.  
  181.         $pstatus false;
  182.     }
  183.  
  184.     // check if idinternal is allready available in table
  185.     $sql "SELECT * FROM " $cfg["tab"]["plugins"" WHERE idinternal='" $pinternalid "';";
  186.     $db->query($sql);
  187.     if ($db->next_record()) {
  188.         $mode     "update";
  189.         $message .= "Plugin with this internal id allready exists in table.<br>\n";
  190.         if ($pversion == $db->f('version')) {
  191.             $message .= "This version is allready installed.<br>\n";
  192.             $mode     "uninstall";
  193.         else {
  194.             $message .= "Switching to upgrade mode.<br>\n";
  195.         }
  196.         $pluginid $db->f('idplugin');
  197.     else {
  198.         $mode     "install";
  199.         $message .= "No plugin with this internal id exists in table.<br>\n";
  200.         $pluginid false;
  201.     }
  202.  
  203.     if (!$install && !$uninstall{
  204.         $data['content'.= "<br>" $message;
  205.     }
  206.  
  207.     if (!$install && $mode == "update"{
  208.         $data['content'.= "<br><a href=$PHP_SELF?install=1&contenido=$contenido>Update $pname $pversion</a></br>";
  209.     }
  210.  
  211.     if (!$install && $mode == "install"{
  212.         $data['content'.= "<br><a href=$PHP_SELF?install=1&contenido=$contenido>Install $pname $pversion</a></br>";
  213.     }
  214.  
  215.     if (!$uninstall && $mode == "uninstall"{
  216.         $data['content'.= "<br><a href=$PHP_SELF?uninstall=1&contenido=$contenido>UnInstall $pname $pversion</a></br>";
  217.     }
  218.  
  219.     if ($uninstall && $pluginid{
  220.         $sql "SELECT uninstall FROM " $cfg["tab"]["plugins"" WHERE idplugin='" $pluginid "'";
  221.         msg($sql);
  222.         $db->query($sql);
  223.         $db->next_record();
  224.  
  225.         $uninstallsql $db->f('uninstall');
  226.         $sql_data     remove_remarks($uninstallsql);
  227.         $sql_pieces   split_sql_file($sql_data';');
  228.  
  229.         msg(count($sql_pieces)." queries""Executing:");
  230.         foreach ($sql_pieces as $sqlinit{
  231.             $db->query($sqlinit);
  232.             msg($sqlinit);
  233.         }
  234.  
  235.         uninstallModRewrite();
  236.         
  237.         $data['content'.= "<br><b>Uninstall complete.</b><br>\r\n";
  238.     }
  239.  
  240.     if ($pstatus && $install{
  241.         if ($mode == "install"// insert all data from install.sql
  242.             $pluginid $db->nextid($cfg["tab"]["plugins"])// get next free id using phplib method
  243.  
  244.             $PID 100 $pluginid// generate !PID! replacement
  245.             $replace array('!PREFIX!' => $cfg['sql']['sqlprefix']'!PID!' => $PID);
  246.  
  247.             $installsql strtr($installsql$replace);
  248.  
  249.             $sql "INSERT INTO " $cfg["tab"]["plugins"" (idplugin,name,`version`,author,idinternal,`status`,`date`) VALUES ('" $pluginid "','" $pname "','" $pversion "','" $pauthor "','" $pinternalid "','0','" date("Y-m-d H:i:s""');";
  250.             $uninstallsql "DELETE FROM " $cfg["tab"]["plugins"" WHERE idplugin='" $pluginid "';\r\n";
  251.             msg($sql"Insert statement for plugin: ");
  252.             $db->query($sql);
  253.  
  254.             msg ($installsql"Install query:");
  255.  
  256.             $sql_data remove_remarks($installsql);
  257.             $sql_pieces split_sql_file($sql_data';');
  258.             msg(count($sql_pieces" queries""Executing:");
  259.             foreach ($sql_pieces as $sqlinit{
  260.                 // $sqlinit = strtr($sqlinit, $replace);
  261.                 // create uninstall.sql for each insert entry
  262.                 if (preg_match("/INSERT\s+INTO\s+(.*)\s+VALUES\s*\([´\"'\s]*(\d+)/i"$sqlinit$tmpsql)) {
  263.                     $tmpidname $db->metadata(trim(str_replace("`"""$tmpsql[1])));
  264.                     $tmpidname $tmpidname[0]['name'];
  265.                     $uninstallsql "DELETE FROM " trim($tmpsql[1]" WHERE " $tmpidname "='" trim($tmpsql[2]"';\r\n" $uninstallsql;
  266.                 }
  267.  
  268.                 $db->query($sqlinit);
  269.                 msg($sqlinit);
  270.             }
  271.  
  272.             if ($uninstallsqlfile file_get_contents('uninstall.sql')) {
  273.                 $uninstallsqlfile remove_remarks($uninstallsqlfile)// remove all comments
  274.  
  275.                 $uninstallsql .= strtr($uninstallsqlfile$replace)// add to generated sql
  276.                 $data['content'.= "I found uninstall.sql in " dirname(__FILE__"<br>Statements added to uninstall query.<br>\n";
  277.             }
  278.  
  279.             msg ($uninstallsql"Uninstall query:");
  280.  
  281.             $sql "UPDATE " $cfg["tab"]["plugins"" SET install=0x" bin2hex($installsql", uninstall=0x" bin2hex($uninstallsql" WHERE (idplugin='" $pluginid "');";
  282.             msg($sql"un/install statements stored");
  283.             $db->query($sql);
  284.  
  285.             upgradeModRewrite();
  286.             
  287.             $data['content'.= "<br><b>Install complete.</b><br>\r\n";
  288.         }
  289.  
  290.         if ($mode == "update"{
  291.             $sql  "UPDATE " $cfg["tab"]["plugins"" SET\n";
  292.             $sql .= " version = '" $pversion "'\n";
  293.             $sql .= "WHERE (idplugin='" $pluginid "');";
  294.             msg($sql"Store new plugin version: ");
  295.             $db->query($sql);
  296.             if ($updatesqlfile @file_get_contents('update.sql')) {
  297.                 $sql "SELECT uninstall FROM " $cfg["tab"]["plugins"" WHERE idplugin='" $pluginid "'";
  298.                 msg($sql"Getting stored uninstall statements: ");
  299.                 $db->query($sql);
  300.                 $db->next_record();
  301.  
  302.                 $uninstallsql $db->f('uninstall');
  303.                 $updatesqlfile remove_remarks($updatesqlfile)// remove all comments
  304.  
  305.                 $data['content'.= "I found update.sql in " dirname(__FILE__"<br>\n";
  306.  
  307.                 $PID 100 $pluginid// generate !PID! replacement
  308.                 $replace array('!PREFIX!' => $cfg['sql']['sqlprefix']'!PID!' => $PID);
  309.                 $updatesql .= strtr($updatesqlfile$replace)// add to generated sql
  310.  
  311.                 $sql_pieces split_sql_file($updatesql';');
  312.                 msg(count($sql_pieces" queries""Executing:");
  313.                 foreach ($sql_pieces as $sqlinit{
  314.                     // $sqlinit = strtr($sqlinit, $replace);
  315.                     // create uninstall.sql for each insert entry
  316.                     if (preg_match("/INSERT\s+INTO\s+(.*)\s+VALUES\s*\([´\"'\s]*(\d+)/i"$sqlinit$tmpsql)) {
  317.                         $tmpidname    $db->metadata(trim(str_replace("`"""$tmpsql[1])));
  318.                         $tmpidname    $tmpidname[0]['name'];
  319.                         $uninstallsql "DELETE FROM " trim($tmpsql[1]" WHERE " $tmpidname "='" trim($tmpsql[2]"';\r\n" $uninstallsql;
  320.                     else if (preg_match("/REPLACE \s+INTO\s+(.*)\s+VALUES\s*\([´\"'\s]*(\d+)/i"$sqlinit$tmpsql)) {
  321.                         $tmpidname    $db->metadata(trim(str_replace("`"""$tmpsql[1])));
  322.                         $tmpidname    $tmpidname[0]['name'];
  323.                         $uninstallsql "DELETE FROM " trim($tmpsql[1]" WHERE " $tmpidname "='" trim($tmpsql[2]"';\r\n" $uninstallsql;
  324.                     }
  325.  
  326.                     $db->query($sqlinit);
  327.                     msg($sqlinit);
  328.                 }
  329.                 $sql "UPDATE " $cfg["tab"]["plugins"" SET uninstall = 0x" bin2hex($uninstallsql" WHERE (idplugin='" $pluginid "');";
  330.                 msg($sql"New uninstall statements stored: ");
  331.                 $db->query($sql);
  332.             }
  333.  
  334.             upgradeModRewrite();
  335.             
  336.             $data['content'.= "<br><b>Update complete.</b><br>\r\n";
  337.         }
  338.  
  339.         // con_sequence update
  340.         updateSequence();
  341.     }
  342. else {
  343.     $data['content'.= "Sorry i found no install.sql in " dirname(__FILE__"<br>\n";
  344. }
  345.  
  346.  
  347. // print $clink;
  348.  
  349. #print '</body></html>';
  350.  
  351. $cfg["debug"]["backend_exectime"]["end"getmicrotime();
  352.  
  353. if ($cfg["debug"]["rendering"== true{
  354.     $data['body_bottom'.= "Rendering this page took: " ($cfg["debug"]["backend_exectime"]["end"$cfg["debug"]["backend_exectime"]["start"]" seconds<br>";
  355.     $data['body_bottom'.= "Building the complete page took: " ($cfg["debug"]["backend_exectime"]["end"$cfg["debug"]["backend_exectime"]["fullstart"]" seconds<br>";
  356.  
  357.     if (function_exists("memory_get_usage")) {
  358.         $data['body_bottom'.= "Include memory usage: " human_readable_size(memory_get_usage($cfg["debug"]["oldmemusage"]"<br>";
  359.         $data['body_bottom'.= "Complete memory usage: " human_readable_size(memory_get_usage()) "<br>";
  360.     }
  361. }
  362.  
  363.  
  364. page_close();
  365.  
  366.  
  367. ####################################################################################################
  368. ##### Output
  369.  
  370. echo <<<HTML
  371. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  372. <head>
  373.     <title>Plugin installer</title>
  374. </head>
  375. <body style="font-family:verdana;font-size:11px;">
  376. <form name="client_properties" method="post" action="$PHP_SELF">
  377.     <input type="hidden" name="contenido" value="$contenido">
  378. {$data['top']}<br>
  379. {$data['content']}
  380. {$data['bottom']}
  381. </form>
  382. {$data['body_bottom']}
  383. </body>
  384. </html>
  385. HTML;
  386.  
  387.  
  388. ####################################################################################################
  389. ##### Functions
  390.  
  391. // some functions to work with...
  392. /**
  393.  * removes '# blabla...' from the mysql_dump.
  394.  * This function was originally developed for phpbb 2.01
  395.  * (C) 2001 The phpBB Group http://www.phpbb.com
  396.  *
  397.  * @return string input_without_#
  398.  */
  399. function remove_remarks($sql{
  400.     $lines explode("\n"$sql);
  401.     // try to keep mem. use down
  402.     $sql "";
  403.  
  404.     $linecount count($lines);
  405.     $output "";
  406.  
  407.     for ($i 0$i $linecount$i++{
  408.         if (($i != ($linecount 1)) || (strlen($lines[$i]0)) {
  409.             $output .= ($lines[$i][0!= "#")  $lines[$i]."\n" "\n";
  410.  
  411.             // Trading a bit of speed for lower mem. use here.
  412.             $lines[$i"";
  413.         }
  414.     }
  415.     return $output;
  416. }
  417.  
  418. /**
  419.  * Splits sql- statements into handy pieces.
  420.  * This function was original developed for the phpbb 2.01
  421.  * (C) 2001 The phpBB Group http://www.phpbb.com
  422.  *
  423.  * @return array sql_pieces
  424.  */
  425. function split_sql_file($sql$delimiter{
  426.   // Split up our string into "possible" SQL statements.
  427.   $tokens explode($delimiter$sql);
  428.   // try to save mem.
  429.   $sql "";
  430.   $output array();
  431.   // we don't actually care about the matches preg gives us.
  432.   $matches array();
  433.   // this is faster than calling count($oktens) every time thru the loop.
  434.   $token_count count($tokens);
  435.   for ($i 0$i $token_count$i++{
  436.     // Dont wanna add an empty string as the last thing in the array.
  437.     if (($i != ($token_count 1)) || (strlen($tokens[$i0))) {
  438.       // This is the total number of single quotes in the token.
  439.       $total_quotes preg_match_all("/'/"$tokens[$i]$matches);
  440.       // Counts single quotes that are preceded by an odd number of backslashes,
  441.       // which means they're escaped quotes.
  442.       $escaped_quotes preg_match_all("/(?<!\\\\)(\\\\\\\\)*\\\\'/"$tokens[$i]$matches);
  443.  
  444.       $unescaped_quotes $total_quotes $escaped_quotes;
  445.       // If the number of unescaped quotes is even, then the delimiter did NOT occur inside a string literal.
  446.       if (($unescaped_quotes 2== 0{
  447.         // It's a complete sql statement.
  448.         $output[$tokens[$i];
  449.         // save memory.
  450.         $tokens[$i"";
  451.       else {
  452.         // incomplete sql statement. keep adding tokens until we have a complete one.
  453.         // $temp will hold what we have so far.
  454.         $temp $tokens[$i$delimiter;
  455.         // save memory..
  456.         $tokens[$i"";
  457.         // Do we have a complete statement yet?
  458.         $complete_stmt false;
  459.  
  460.         for ($j $i 1(!$complete_stmt && ($j $token_count))$j++{
  461.           // This is the total number of single quotes in the token.
  462.           $total_quotes preg_match_all("/'/"$tokens[$j]$matches);
  463.           // Counts single quotes that are preceded by an odd number of backslashes,
  464.           // which means theyre escaped quotes.
  465.           $escaped_quotes preg_match_all("/(?<!\\\\)(\\\\\\\\)*\\\\'/"$tokens[$j]$matches);
  466.  
  467.           $unescaped_quotes $total_quotes $escaped_quotes;
  468.  
  469.           if (($unescaped_quotes 2== 1{
  470.             // odd number of unescaped quotes. In combination with the previous incomplete
  471.             // statement(s), we now have a complete statement. (2 odds always make an even)
  472.             $output[$temp $tokens[$j];
  473.             // save memory.
  474.             $tokens[$j"";
  475.             $temp "";
  476.             // exit the loop.
  477.             $complete_stmt true;
  478.             // make sure the outer loop continues at the right point.
  479.             $i $j;
  480.           else {
  481.             // even number of unescaped quotes. We still dont have a complete statement.
  482.             // (1 odd and 1 even always make an odd)
  483.             $temp .= $tokens[$j$delimiter;
  484.             // save memory.
  485.             $tokens[$j"";
  486.           }
  487.         // for..
  488.       // else
  489.     }
  490.   }
  491.   return $output;
  492. }
  493. // simple function to update con_sequence
  494. function updateSequence($table false{
  495.     global $db$cfg;
  496.     if (!$table{
  497.         $sql "SHOW TABLES";
  498.         $db->query($sql);
  499.         while ($db->next_record()) {
  500.             dbUpdateSequence($cfg['sql']['sqlprefix'"_sequence"$db->f(0));
  501.         }
  502.     else {
  503.         dbUpdateSequence($cfg['sql']['sqlprefix'"_sequence"$table);
  504.     }
  505. }
  506. // read out next free id * deprecated
  507. function getSequenceId($table{
  508.     global $db2$cfg;
  509.     $sql "SELECT nextid FROM " $cfg['sql']['sqlprefix'"_sequence" " where seq_name = '$table'";
  510.     $db2->query($sql);
  511.     if ($db2->next_record()) {
  512.         return ($db2->f("nextid"1);
  513.     else {
  514.         msg($table"missing in " $cfg['sql']['sqlprefix'"_sequence");
  515.         return 0;
  516.     }
  517. }
  518. // debug functions
  519. function msg($value$info false{
  520.     global $cfg;
  521.     if (trim($cfg["debug"]["messages"]== ""$cfg["debug"]["messages""<br><b>DEBUG:</b>";
  522.     if (!$cfg["debug"]["installer"]{
  523.         return;
  524.     }
  525.     if ($info{
  526.         $cfg["debug"]["messages".= "<b>$info</b> -> ";
  527.     }
  528.     if (is_array($value)) {
  529.         ob_start();
  530.         print_r($value);
  531.         $output ob_get_contents();
  532.         ob_end_clean();
  533.         $cfg["debug"]["messages".= "<pre>" htmlspecialchars($output"</pre>";
  534.     else {
  535.         $cfg["debug"]["messages".= htmlspecialchars($value"<br>";
  536.     }
  537. }
  538.  
  539. function showmsg({
  540.     global $cfg;
  541.     if ($cfg["debug"]["installer"]{
  542.         print "<div style=\"font-family: Verdana, Arial, Helvetica, Sans-Serif; font-size: 11px; color: #000000\">";
  543.         print $cfg["debug"]["messages"];
  544.         print "</div>";
  545.     }
  546. }
  547.  
  548.  
  549. /**
  550.  * isWriteable:
  551.  * Checks if a specific file is writeable. Includes a PHP 4.0.4
  552.  * workaround where is_writable doesn't return a value of type
  553.  * boolean. Also clears the stat cache and checks if the file
  554.  * exists.
  555.  * 
  556.  * Copied from /setup/lib/functions.filesystem.php
  557.  * 
  558.  * @param $file string    Path to the file, accepts absolute and relative files
  559.  * @return boolean true if the file exists and is writeable, false otherwise
  560.  */
  561. function isWriteable($file{
  562.     clearstatcache();
  563.     if (!file_exists($file)) {
  564.         return false;
  565.     }
  566.     
  567.     $bStatus is_writable($file);
  568.     /* PHP 4.0.4 workaround */
  569.     settype($bStatus"boolean");
  570.     
  571.     return $bStatus;
  572. }
  573.  
  574.  
  575. function copyFile($source$destination$backupName=null{
  576.     global $cfg;
  577.     
  578.     // check source and destination, allow filesystem processes only inside htdocs
  579.     if (strpos($source$cfg['path']['frontend']=== false{
  580.         return false;
  581.     elseif (strpos($destination$cfg['path']['frontend']=== false{
  582.         return false;
  583.     elseif (isset($backupName&& strpos($backupName$cfg['path']['frontend']=== false{
  584.         return false;
  585.     }
  586.     
  587.     if ($backupName !== null{
  588.         if (!rename($destination$backupName)) {
  589.             return false;
  590.         }
  591.     }
  592.     
  593.     if (!copy($source$destination '.bak')) {
  594.         return false;
  595.     }
  596.     
  597.     return true;
  598. }

Documentation generated on Sun, 20 Jul 2008 16:27:01 +0200 by phpDocumentor 1.4.0