"); // More includes include ZIPCMD; include TODO_IO; include "make_release.rc.php"; wb_set_handler($mainwin, "process_main"); wb_set_text($mainwin, APPNAME . " version " . VERSION); wb_set_image($mainwin, PATH_RES . "hyper.ico"); // Initialize controls wb_set_text(wb_get_control($mainwin, IDC_TYPE), COMBO_ITEMS); wb_set_text(wb_get_control($mainwin, IDC_NOTES), file_get_contents(RELNOTES)); // Accelerator table wb_create_control($mainwin, Accel, array( array(IDC_GO, "F9"), )); // Read data from INI file $lastresult = "";//"(Output)"; $settings = parse_ini(@file_get_contents(SYS_INIFILE)); $allctrls = $all_ctrls; if($settings) { foreach($all_ctrls as $flag) { $ctrl = wb_get_control($mainwin, constant("IDC_" . $flag)); $status = @$settings["Settings"][strtolower($flag)]; if(wb_get_class($ctrl) == ComboBox) wb_set_selected($ctrl, $status); else wb_set_value($ctrl, $status); } } else { // Using this app for the first time process_main($mainwin, IDC_TYPE); } process_main($mainwin, IDC_ZIP); // Disable commands if it is the case process_main($mainwin, IDC_RELNOTES); // Disable commands if it is the case // Get version from C header file $current_version = @file_get_contents(VERSION_FILE); $def = preg_match("/WINBINDER_VERSION\s+\"(.[^\"]*)\"/", $current_version, $ver); $ver = @$ver[1]; wb_set_text(wb_get_control($mainwin, IDC_VERSION), $ver); $textbox = wb_get_control($mainwin, IDC_RESULT); wb_set_text(wb_get_control($mainwin, IDC_STATE), PROJ_STATE); // Move and show main window $xpos = @$settings["Settings"]["xpos"]; $ypos = @$settings["Settings"]["ypos"]; wb_set_focus(wb_get_control($mainwin, IDC_GO)); wb_set_position($mainwin, $xpos, $ypos); wb_set_visible($mainwin, true); check_date_version($mainwin, LOGFILE, $ver); // Enter application loop wb_main_loop(); //--------------------------------------------------------------- MAIN FUNCTIONS /* Process main window commands */ function process_main($window, $id) { global $flistfiles, $all_flags, $zip_dependent, $lastresult, $textbox; switch($id) { case IDC_RELNOTES: $status = wb_get_value(wb_get_control($window, $id)); wb_set_enabled(wb_get_control($window, IDC_NOTES), $status); break; case IDC_SAVERELEASE: if(save_version($window)) out("Done.\n"); break; case IDC_ZIP: $status = wb_get_value(wb_get_control($window, $id)); foreach($zip_dependent as $flag) wb_set_enabled(wb_get_control($window, constant("IDC_" . $flag)), $status); if(wb_get_value(wb_get_control($window, $id))) { $fname = $flistfiles[wb_get_selected(wb_get_control($window, IDC_TYPE))]; wb_set_text(wb_get_control($window, IDC_FLIST), $fname ? ($fname . "_zipme.txt") : "(none)"); } else { wb_set_text(wb_get_control($window, IDC_FLIST), ""); } break; case IDC_RESULT: // Hack to make a white "read-only" text box wb_set_text(wb_get_control($window, $id), $lastresult); break; case IDC_CLEAR: out(null); break; case IDC_TYPE: $check = array( array(0,0,0,0,0,0,0,0,0,0), // Do nothing array(0,0,0,1,0,0,0,0,0,0), // Snapshot array(0,1,0,1,1,0,0,1,0,0), // PHP developer build array(0,0,0,1,0,0,0,0,0,0), // C developer array(1,1,1,1,1,1,1,0,1,1), // Release array(0,1,0,1,0,0,0,0,0,0), // Minimal PHP 4 array(0,1,0,1,0,0,0,0,0,0), // Minimal PHP 5 array(0,0,0,1,1,0,0,0,0,0), // DLL ); $status = wb_get_selected(wb_get_control($window, $id)); for($i = 0; $i < count($all_flags); $i++) { wb_set_value(wb_get_control($window, constant("IDC_" . $all_flags[$i])), $check[$status][$i]); } process_main($window, IDC_ZIP); process_main($window, IDC_RELNOTES); process_main($window, IDC_COPYFILES); //wb_set_enabled(wb_get_control($window, IDC_GO), $status); break; case IDC_ABOUT: wb_message_box($window, APPNAME . " version: " . VERSION . "\r\nWinBinder version: " . WBC_VERSION . "\r\nPHP version: " . PHP_VERSION, "About " . APPNAME); break; case IDC_GO: go($window); break; case IDC_SAVEINI: save_ini($window); break; case IDCLOSE: // IDCLOSE is predefined save_ini($window); wb_destroy_window($window); break; } } function save_version($mainwin) { global $current_version, $ver; // Get version number from edit control and save wb_version.h with new version number $current_version = @file_get_contents(VERSION_FILE); $ver = trim(wb_get_text(wb_get_control($mainwin, IDC_VERSION))); preg_match("/(\d+)\.(\d+)\.(\d+)/", $ver, $parts); $new_version = sprintf(VERSION_CONTENTS, $ver, $parts[1], $parts[2], $parts[3]); if(preg_split("/\r\n/", $current_version) != preg_split("/\r\n/", $new_version)) { out("Updating project version number to $ver...\r\n"); file_put_contents(VERSION_FILE, $new_version); return TRUE; } else return FALSE; } /* Do various actions according to options */ function go($mainwin) { global $copies, $verbose, $current_version, $ver, $flistfiles, $ftemplate; // Get some flags from the interface $verbose = wb_get_value(wb_get_control($mainwin, IDC_VERBOSE)); $type = wb_get_selected(wb_get_control($mainwin, IDC_TYPE)); // Get version number from edit control and save wb_version.h with new version number save_version($mainwin); // Verify changelog date / version if(!check_date_version($mainwin, LOGFILE, $ver)) { out("Aborted.\r\n"); return; } // Start out(null); out("Working...\r\n"); /* $ver = trim(wb_get_text(wb_get_control($mainwin, IDC_VERSION))); $new_version = sprintf(VERSION_CONTENTS, $ver); if(preg_split("/\r\n/", $current_version) != preg_split("/\r\n/", $new_version)) { out("Updating project version number...\r\n"); file_put_contents(VERSION_FILE, $new_version); }*/ // Save release notes if(wb_get_value(wb_get_control($mainwin, IDC_RELNOTES))) { if(file_get_contents(RELNOTES) != wb_get_text(wb_get_control($mainwin, IDC_NOTES))) { out("Saving release notes...\r\n"); file_put_contents(RELNOTES, wb_get_text(wb_get_control($mainwin, IDC_NOTES))); } } // Change directory $currdir = getcwd(); chdir(WB_ROOT); // Delete zip file if it exists if(wb_get_value(wb_get_control($mainwin, IDC_ZIP))) { if(strstr($ftemplate[$type], '%d')) { $fmt = str_replace('%d', '%s', $ftemplate[$type]); $filename = TARGET_PATH . sprintf($fmt, date('ymd')); } else $filename = TARGET_PATH . sprintf($ftemplate[$type], str_replace("-dev", "", $ver)); if(file_exists($filename)) { if(!wb_message_box($mainwin, "Overwrite " . basename($filename) . "?", APPNAME, WBC_YESNO)) { out("Aborted.\r\n"); chdir($currdir); return; } unlink($filename); } } // Compile project and update some files if(wb_get_value(wb_get_control($mainwin, IDC_ZIP))) { // Check and update DLLs if(wb_get_value(wb_get_control($mainwin, IDC_CHECKDLLS))) { if(needs_updating(DLL4, SOURCE_PATH)) { // Cannot overwrite php_winbinder.dll, It's being used right now! wb_message_box($mainwin, "Warning: The WinBinder DLL for PHP 4 is not up-to-date. Please recompile it and try again.", APPNAME, WBC_WARNING); out("Aborted.\r\n"); return; } if(needs_updating(DLL50, SOURCE_PATH)) { wb_message_box($mainwin, "Warning: The WinBinder DLL for PHP 5.0 is not up-to-date. Please recompile it and try again.", APPNAME, WBC_WARNING); out("Aborted.\r\n"); return; } if(needs_updating(DLL51, SOURCE_PATH)) { wb_message_box($mainwin, "Warning: The WinBinder DLL for PHP 5.1 is not up-to-date. Please recompile it and try again.", APPNAME, WBC_WARNING); out("Aborted.\r\n"); return; } } // Build package.xml (2 versions) if(wb_get_value(wb_get_control($mainwin, IDC_XML))) { out("Creating PEAR 1.0 information...\r\n"); update_xml_10($ver); out("Creating PEAR 1.4 information...\r\n"); update_xml_14($ver); } } // Convert HTML files to HTML help format if(wb_get_value(wb_get_control($mainwin, IDC_CHM))) { out("Converting HTML files to HTML Help..."); $helpfiles = get_folder_files(MANUAL_SRC, TRUE, TRUE, "/.*\.(html?|css|jpe?g|gif|[pm]ng)$/i"); if($verbose) out("\r\n"); empty_folder_files(MANUAL_TGT); // Avoid obsolete files from manual folder // Populate manual folder with fresh files foreach($helpfiles as $srcfile) { $tgtfile = str_replace(MANUAL_SRC, MANUAL_TGT, $srcfile); // Create directory if it does not exist $dir = dirname($tgtfile); if(!file_exists($dir)) mkdir($dir); if(strstr($srcfile, ".htm")) { $html = file_get_contents($srcfile); $hasklinks = preg_match("//is", $html, $klinks); if($hasklinks) { // Create "object" tag $lines = preg_split("/[\r\n]/", $klinks[1]); $klinks = ""; foreach($lines as $line) { $line = trim($line); if($line) $klinks .= "\t\r\n"; } $html = preg_replace("//is", "\r\n$klinks", $html); if(!file_put_contents($tgtfile, $html)) out("Warning: Failed to copy file $tgtfile.\r\n"); if($verbose) out("Converting " . basename($tgtfile) . "...\r\n"); } else { copy($srcfile, $tgtfile); @touch($tgtfile, filemtime($srcfile)); } } else { copy($srcfile, $tgtfile); @touch($tgtfile, filemtime($srcfile)); } } if(!$verbose) out("\r\n"); // Create HTML help manual out("Creating CHM manual...\r\n"); $res = shell_exec(HELPWORKSHOP . " " . HELP_PROJECT) . "\n"; if($verbose) out($res); } // Export To Do list as HTML if(wb_get_value(wb_get_control($mainwin, IDC_EXPORTTODO))) { out("Creating To Do list...\r\n"); todo_export(); } // Copy/update files if(wb_get_value(wb_get_control($mainwin, IDC_COPYFILES))) { if(!$verbose) out("Copying/updating files..."); for($i = 0; $i < count($copies); $i += 2) { if($verbose) out("Copying/updating " . basename($copies[$i + 1]) . "...\r\n"); else out("."); $tgtfile = $copies[$i + 1]; copy($copies[$i], $tgtfile); // Remove all references to any e-mail file_put_contents($tgtfile, preg_replace("/[\(\<]?\w+@\w+(\.\w{2,3})+[\)\>]?/i", "", file_get_contents($tgtfile))); @touch($copies[$i + 1], filemtime($copies[$i])); } if(!$verbose) out("\r\n"); } // Create zip file if(wb_get_value(wb_get_control($mainwin, IDC_ZIP))) { // if($type == 5 || $type == 6) { // $zipper = ZIPPER_FLAT; // out("You must remove the file paths manually from inside the ZIP file.\r\n"); // } else // $zipper = ZIPPER; // printf($zipper, $filename, $flistfiles[$type], $flistfiles[$type], ""); out("Creating zip archive...\r\n"); if($verbose) out("\r\n" . shell_exec(sprintf(ZIPPER, $filename, $flistfiles[$type], $flistfiles[$type], "")) . "\r\n"); else // out("\r\n" . exec(sprintf(ZIPPER, $filename, $flistfiles[$type], $flistfiles[$type], "")) . "\r\n"); exec(sprintf(ZIPPER, $filename, $flistfiles[$type], $flistfiles[$type], "")); if(file_exists($filename)) out("File " . basename($filename) . " created successfully.\r\n"); else { out("Error creating file $filename.\r\n"); out("Aborted.\r\n"); return; } // Convert zip file to tar.gz if(wb_get_value(wb_get_control($mainwin, IDC_TGZ))) { out("Converting to tar.gz (may require user intervention)...\r\n"); $targz = str_replace(".zip", ".tar.gz", $filename); $tgz = str_replace(".zip", ".tgz", $filename); if($verbose) out("\r\n" . shell_exec(sprintf(TARGZ, $filename)) . "\r\n"); else out("\r\n" . exec(sprintf(TARGZ, $filename)) . "\r\n"); @unlink($tgz); @rename($targz, $tgz); } // MIME-encode zip file if(wb_get_value(wb_get_control($mainwin, IDC_MIME))) { out("Encoding as MIME...\r\n"); $mime = str_replace(".zip", ".b64", $filename); file_put_contents($mime, b64encode($filename)); } } // Create setup if(wb_get_value(wb_get_control($mainwin, IDC_SETUP))) { out("Compiling setup application...\r\n"); // Change version number in setup script (.iss) file $contents = file_get_contents(SETUPSCRIPT); $previous = $contents; $contents = preg_replace("/^(AppVerName\s*=).*$/im", "\\1WinBinder version $ver", $contents); $contents = preg_replace("/^(VersionInfoVersion\s*=).*$/im", "\${1}" . preg_replace("/[^0-9\.]/", "", $ver), $contents); // Force compression settings $contents = preg_replace("/^(InternalCompressLevel\s*=).*/im", "\\1normal", $contents); $contents = preg_replace("/^(SolidCompression\s*=).*/im", "\\1true", $contents); $contents = preg_replace("/^(Compression\s*=).*/im", "\\1lzma/max", $contents); // Save .iss file and compile setup if($contents != $previous) file_put_contents(SETUPSCRIPT, $contents); // Force DEBUG = False in Pascal script $contents = file_get_contents(SETUPCODE); $contents = preg_replace("/WB_DEBUG = True/i", "WB_DEBUG = False", $contents); if($contents != $previous) file_put_contents(SETUPCODE, $contents); // Compile setup shell_exec(SETUPCOMP . SETUPSCRIPT); } // End chdir($currdir); out("Done.\r\n"); } //---------------------------------------------------------- AUXILIARY FUNCTIONS // Extracts last valid version number and date from changelog and compares them to // current date and version number function check_date_version($window, $logfile, $ver) { // Assumes that the Date line is always located after the Version line // Code adapted from version.php (web site) $log = file($logfile); $maxlines = 20; // Give up after 20 lines $currlin = 0; // Extract "version" line $version = ""; for($i = 0; $i < $maxlines; $i++) { $line = trim($log[$i]); if(preg_match("/Version/i", $line)) { $version = $line; $currlin = $i; break; } } // Check version $version = preg_replace("/\s*Version\s*/", "", $version); $version = preg_replace("/\s*\-\s*build\s*/", ".", $version); $version = preg_replace("/\s*\((pre\-)?alpha\)\s*/", "", $version); $ver = preg_replace("/\s*-\s*dev/", "", $ver); if(trim($version) != trim($ver)) { wb_message_box($window, "Warning: The version in the changelog is '$version'. Please edit\nthe changelog or the Version field and try again.", APPNAME, WBC_WARNING); return FALSE; } // Extract "date" line $date = ""; for($i = $currlin; $i < $maxlines; $i++) { $line = trim($log[$i]); if(preg_match("/Date/i", $line)) { $date = $line; break; } } // Check date if(trim($date) != "Date: " . date("M d, Y")) { wb_message_box($window, "Warning: The date in the changelog is incorrect or invalid. Please change it and try again.", APPNAME, WBC_WARNING); return FALSE; } return TRUE; } /* Generate file list in PEAR 1.0 XML format */ function update_xml_10($version) { global $mainwin; $text = file(FILELIST); $files = ""; foreach($text as $file) { $file = strtolower(trim($file)); $filename = WB_ROOT . $file; if(is_file($filename)) { // Ignore subdirectories $md5hash = md5_file($filename); $files .= " \r\n"; } } // Replace variables $version = str_replace("-dev", "", $version); $xml = file_get_contents(PEAR10_TEMPLATE); $xml = str_replace("%filelist%", $files, $xml); $xml = str_replace("%version%", $version, $xml); $xml = str_replace("%date%", date("Y-m-d"), $xml); $xml = str_replace("%state%", PROJ_STATE, $xml); $xml = str_replace("%notes%", wb_get_text(wb_get_control($mainwin, IDC_NOTES)), $xml); // Save XML file_put_contents(PEAR10_PACKAGE, $xml); } /* Generate file list in PEAR 1.4 XML format. There is some cheating here because the new directory structure feature ("")is not used properly, but if PEAR itself can do it (see PEAR package2.xml), so can we */ function update_xml_14($version) { global $mainwin; $text = file(FILELIST); $files = " \r\n"; foreach($text as $file) { $file = strtolower(trim($file)); $filename = WB_ROOT . $file; if(is_file($filename)) { // Ignore subdirectories $md5hash = md5_file($filename); $parts = pathinfo($filename); $role = get_role(@$parts['extension']); $files .= " \r\n"; } } $files .= " "; // Replace variables $version = str_replace("-dev", "", $version); $xml = file_get_contents(PEAR14_TEMPLATE); $xml = str_replace("%contents%", $files, $xml); $xml = str_replace("%version%", $version, $xml); $xml = str_replace("%date%", date("Y-m-d"), $xml); $xml = str_replace("%time%", date("H:i:s"), $xml); $xml = str_replace("%stability%", PROJ_STATE, $xml); $xml = str_replace("%notes%", wb_get_text(wb_get_control($mainwin, IDC_NOTES)), $xml); // Save XML file_put_contents(PEAR14_PACKAGE, $xml); } // Reference: http://www.appelsiini.net/~tuupola/doc/peardoc/developers.packagedef.html function get_role($extension) { switch($extension) { case 'txt': case 'ini': case 'prj': case 'wap': case 'wej': case 'xml': case 'html': case 'css': case 'chm': $role = 'doc'; break; case 'php': case 'phpw': $role = 'php'; break; case '': // "makefile" case 'c': case 'h': case 'rc': $role = 'src'; break; case 'bmp': case 'gif': case 'png': case 'jpg': $role = 'data'; break; default: $role = 'unkwnown'; break; } return $role; } // Reference: http://forums.devshed.com/archive/t-125668 function b64encode($filename) { $contents = file_get_contents($filename); $filename = basename($filename); $contents = chunk_split(base64_encode($contents)); return "Content-Type: application/octetstream;\n\tname=$filename\nContent-Transfer-Encoding: base64\n" . "Content-Disposition: attachment;\n\tfilename=$filename\n\n$contents\n\n--end\r\n"; } function out($str) { global $mainwin, $textbox, $lastresult; if($str === NULL) { $lastresult = ""; wb_set_text($textbox, ""); wb_refresh($textbox, 1); return; } if(!$str) { $lastresult = ""; return; } $lastresult .= $str; wb_set_text($textbox, $lastresult); wb_refresh($textbox, 1); } // Rough test to see if $targetfile needs to be rebuilt function needs_updating($targetfile, $path) { // Correct path name $comp = filemtime($targetfile); $path = str_replace('/', '\\', $path); if(substr($path, -1) != '\\') $path .= "\\"; if(!$path || !@is_dir($path)) return array(); // Browse the subdiretory list recursively $dir = array(); if($handle = opendir($path)) { while(($file = readdir($handle)) !== false) { if(!is_dir($path.$file)) { // No directories / subdirectories if($comp < filemtime($path.$file)) return TRUE; } else if($file[0] != ".") { // Exclude "." and ".." if(needs_updating($targetfile, $path.$file)) return TRUE; } } } closedir($handle); return FALSE; } // A recursive function for flattening nested arrays // From http://php.net/array function flatten_array($array) { $flat_array = array(); for($x = 0; $x < sizeof($array); $x++) { $element = $array[$x]; if(is_array($element)) { $results = flatten_array($element); for($y = 0; $y < sizeof($results); $y++) { $flat_array[] = $results[$y]; } } else { $flat_array[] = $element; } } return $flat_array; } // Empties folders recursively function empty_folder_files($path, $mask="") { $files = flatten_array(get_folder_files($path, true, true, "")); foreach($files as $file) unlink($file); } // Exports To Do list as HTML function todo_export() { db_open_database(TODO_DATABASE, TODO_PATH); $filename = WEB_TODO_HTML; $data = db_get_data("item", null, "", "priority != 4", FETCH_NUM, "id", "name"); // Exclude "solved" items $html = todo_export_html($data); file_put_contents($filename, $html); db_close_database(); } // Save the make_release configuration file function save_ini($window) { global $settings, $allctrls; out(null); out("Saving configurations...\r\n"); // Get values foreach($allctrls as $flag) { $ctrl = wb_get_control($window, constant("IDC_" . $flag)); if(wb_get_class($ctrl) == ComboBox) $settings["Settings"][strtolower($flag)] = wb_get_selected($ctrl); else $settings["Settings"][strtolower($flag)] = wb_get_value($ctrl); } $pos = wb_get_position($window); $settings["Settings"]["xpos"] = $pos[0]; $settings["Settings"]["ypos"] = $pos[1]; // Save options to INI file $contents = generate_ini($settings, "; Make Release INI file\r\n"); if($contents) { file_put_contents(SYS_INIFILE, $contents); } else wb_message_box($window, MSG_FILESAVEERR, APPNAME); out("Done.\r\n"); } //------------------------------------------------------------------ END OF FILE ?>