2 /************************************************************************/
4 /************************************************************************/
5 /* Copyright (c) 2002-2008 by Greg Gay, Joel Kronenberg & Heidi Hazelton*/
6 /* Adaptive Technology Resource Centre / University of Toronto */
9 /* This program is free software. You can redistribute it and/or */
10 /* modify it under the terms of the GNU General Public License */
11 /* as published by the Free Software Foundation. */
12 /************************************************************************/
13 // $Id: PatchCreator.class.php 7208 2008-02-08 16:07:24Z cindy $
17 * Class to create a zipped patch package
18 * zipped patch package contains patch.xml, the files to be added, overwritten
21 * @package PatchCreator
24 define('AT_INCLUDE_PATH', '../../../include/');
25 require_once (AT_INCLUDE_PATH.'vitals.inc.php');
27 require_once(AT_INCLUDE_PATH. "../mods/patcher/include/patch_xml_template.inc.php");
32 var $patch_info_array = array(); // the patch info data
33 var $patch_xml_file; // location of patch.xml
34 var $current_patch_id; // current myown_patches.myown_patch_id
35 var $version_folder; // version folder. underneath patcher content folder, to hold all patch folders and corresponding upload files
36 var $patch_folder; // patch folder. underneath version folder, to hold all upload files
39 * Constructor: Initialize object members
42 * @param $patch_info_array All information to create a patch. Example:
45 * [atutor_patch_id] => Patch001
46 * [atutor_version_to_apply] => 1.6
47 * [description] => this is a sample patch info array
49 * [dependent_patches] => Array
58 * [file_name] => script1.php
60 * [directory] => admin/
61 * [upload_tmp_name] => C:\xampp\tmp\php252.tmp
66 * [file_name] => script2.php
68 * [directory] => tools/
75 function PatchCreator($patch_info_array, $patch_id)
77 // add slashes if magic_quotes_gpc is off
78 if (!get_magic_quotes_gpc())
80 $patch_info_array["description"] = addslashes($patch_info_array["description"]);
81 $patch_info_array["sql_statement"] = addslashes($patch_info_array["sql_statement"]);
83 for ($i = 0; $i < count($patch_info_array["files"]); $i++)
85 $patch_info_array["files"][$i]["directory"] = addslashes($patch_info_array["files"][$i]["directory"]);
86 $patch_info_array["files"][$i]["upload_tmp_name"] = addslashes($patch_info_array["files"][$i]["upload_tmp_name"]);
87 $patch_info_array["files"][$i]["code_from"] = addslashes($patch_info_array["files"][$i]["code_from"]);
88 $patch_info_array["files"][$i]["code_to"] = addslashes($patch_info_array["files"][$i]["code_to"]);
92 $this->patch_info_array = $patch_info_array;
93 $this->current_patch_id = $patch_id;
95 $this->patch_xml_file = AT_CONTENT_DIR . "patcher/patch.xml";
97 $this->version_folder = AT_CONTENT_DIR . "patcher/" . str_replace('.', '_', $this->patch_info_array["atutor_version_to_apply"]) . "/";
98 $this->patch_folder = $this->version_folder . $this->patch_info_array["atutor_patch_id"] . "/";
104 * @return true if created successfully
105 * false if error happens
106 * @author Cindy Qi Li
108 function create_patch()
110 // save patch info into database & save uploaded files into content folder
113 // create patch.xml into $this->patch_xml_file
114 $fp = fopen($this->patch_xml_file,'w');
115 fwrite($fp,$this->createXML());
118 // create zip package and force download
122 unlink($this->patch_xml_file);
128 * Save patch info into database & save uploaded files into content folder
131 * @author Cindy Qi Li
137 if ($this->current_patch_id == 0)
139 $sql = "INSERT INTO ".TABLE_PREFIX."myown_patches
146 VALUES ('".$this->patch_info_array["atutor_patch_id"]."',
147 '".$this->patch_info_array["atutor_version_to_apply"]."',
148 '".$this->patch_info_array["description"]."',
149 '".$this->patch_info_array["sql_statement"]."',
155 $sql = "UPDATE ".TABLE_PREFIX."myown_patches
156 SET atutor_patch_id = '". $this->patch_info_array["atutor_patch_id"] ."',
157 applied_version = '". $this->patch_info_array["atutor_version_to_apply"] ."',
158 description = '". $this->patch_info_array["description"] ."',
159 sql_statement = '". $this->patch_info_array["sql_statement"] ."',
161 last_modified = now()
162 WHERE myown_patch_id = ". $this->current_patch_id;
165 $result = mysql_query($sql, $db) or die(mysql_error());
167 if ($this->current_patch_id == 0)
169 $this->current_patch_id = mysql_insert_id();
171 else // delete records for current_patch_id in tables myown_patches_dependent & myown_patches_files
173 $sql = "DELETE FROM ".TABLE_PREFIX."myown_patches_dependent WHERE myown_patch_id = " . $this->current_patch_id;
174 $result = mysql_query($sql, $db) or die(mysql_error());
176 $sql = "DELETE FROM ".TABLE_PREFIX."myown_patches_files WHERE myown_patch_id = " . $this->current_patch_id;
177 $result = mysql_query($sql, $db) or die(mysql_error());
180 // insert records into table myown_patches_dependent
181 if (is_array($this->patch_info_array["dependent_patches"]))
183 foreach ($this->patch_info_array["dependent_patches"] as $dependent_patch)
185 $sql = "INSERT INTO ".TABLE_PREFIX."myown_patches_dependent
188 VALUES ('".$this->current_patch_id."',
189 '".$dependent_patch."')";
191 $result = mysql_query($sql, $db) or die(mysql_error());
195 // insert records into table myown_patches_files
196 if (is_array($this->patch_info_array["files"]))
198 foreach ($this->patch_info_array["files"] as $file_info)
200 if ($file_info["upload_tmp_name"] <> "")
201 $upload_to = $this->saveFile($file_info);
205 $sql = "INSERT INTO ".TABLE_PREFIX."myown_patches_files
213 VALUES ('".$this->current_patch_id."',
214 '".$file_info["action"]."',
215 '".$file_info["file_name"]."',
216 '".$file_info["directory"]."',
217 '".$file_info["code_from"]."',
218 '".$file_info["code_to"]."',
219 '".addslashes($upload_to)."')";
221 $result = mysql_query($sql, $db) or die(mysql_error());
227 * Save upload file into content folder
230 * @author Cindy Qi Li
232 function saveFile($file_info)
234 // mkdir() function cannot create folder recursively, so have to acomplish the creation of patch folder by 2 steps.
235 if (!file_exists($this->version_folder)) mkdir($this->version_folder);
236 if (!file_exists($this->patch_folder)) mkdir($this->patch_folder);
238 $upload_to = $this->patch_folder . $file_info['file_name'];
240 // copy uploaded file into content folder
241 copy($file_info["upload_tmp_name"], $upload_to);
243 return realpath($upload_to);
250 * @author Cindy Qi Li
254 global $patch_xml, $dependent_patch_xml;
255 global $patch_action_detail_xml, $patch_file_xml;
257 // generate content of <dependent_patches> section
258 if (is_array($this->patch_info_array["dependent_patches"]))
260 foreach ($this->patch_info_array["dependent_patches"] as $dependent_patch)
261 $dependent_patches .= str_replace('{DEPENDENT_PATCH}', $dependent_patch, $dependent_patch_xml);
264 // generate content of <files> section
265 if (is_array($this->patch_info_array["files"]))
267 foreach ($this->patch_info_array["files"] as $file_info)
269 $action_details = "";
271 if ($file_info["action"] == "alter")
273 $action_details .= str_replace(array('{TYPE}', '{CODE_FROM}', '{CODE_TO}'),
275 htmlspecialchars(stripslashes($file_info["code_from"]), ENT_QUOTES),
276 htmlspecialchars(stripslashes($file_info["code_to"]), ENT_QUOTES)),
277 $patch_action_detail_xml);
280 $xml_files .= str_replace(array('{ACTION}', '{NAME}', '{LOCATION}', '{ACTION_DETAILS}'),
281 array($file_info["action"], $file_info["file_name"], $file_info["directory"], $action_details),
286 // generate patch.xml
287 return str_replace(array('{ATUTOR_PATCH_ID}',
291 '{DEPENDENT_PATCHES}',
293 array($this->patch_info_array["atutor_patch_id"],
294 $this->patch_info_array["atutor_version_to_apply"],
295 htmlspecialchars(stripslashes($this->htmlNewLine($this->patch_info_array["description"])), ENT_QUOTES),
296 htmlspecialchars(stripslashes($this->patch_info_array["sql_statement"]), ENT_QUOTES),
303 * Create xml for section <files> in patch.xml.
306 * @author Cindy Qi Li
308 function createXMLFiles($file_info)
311 $action_details = "";
313 if ($file_info["action"] == "alter")
315 $action_details .= str_replace(array('{TYPE}', '{CODE_FROM}', '{CODE_TO}'),
317 htmlspecialchars(stripslashes($file_info["code_from"]), ENT_QUOTES),
318 htmlspecialchars(stripslashes($file_info["code_to"]), ENT_QUOTES)),
319 $patch_action_detail_xml);
322 return str_replace(array('{ACTION}', '{NAME}', '{LOCATION}', '{ACTION_DETAILS}'),
323 array($file_info["action"], $file_info["file_name"], $file_info["directory"], $action_details),
328 * Create zip file which contains patch.xml and the files to be added, overwritten, altered; and force to download
330 * @return true if successful
332 * @author Cindy Qi Li
336 require_once(AT_INCLUDE_PATH . '/classes/zipfile.class.php');
338 $zipfile =& new zipfile();
340 $zipfile->add_file(file_get_contents($this->patch_xml_file), 'patch.xml');
342 if (is_array($this->patch_info_array["files"]))
344 foreach ($this->patch_info_array["files"] as $file_info)
346 if (isset($file_info["upload_tmp_name"]))
348 $file_name = preg_replace('/.php$/', '.new', $file_info['file_name']);
349 $zipfile->add_file(file_get_contents($file_info['upload_tmp_name']), $file_name);
354 $zipfile->send_file($this->patch_info_array["atutor_patch_id"]);
358 * replace new line string to html tag <br>
360 * @return converted string
361 * @author Cindy Qi Li
363 function htmlNewLine($str)
365 $new_line_array = array("\n", "\r", "\n\r", "\r\n");
367 $found_match = false;
369 if (strlen(trim($str))==0) return "";
371 foreach ($new_line_array as $new_line)
372 if (preg_match('/'.preg_quote($new_line).'/', $str) > 0)
374 $search_new_line = $new_line;
379 return preg_replace('/'. preg_quote($search_new_line) .'/', "<br>", $str);