");
// 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",
"", $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
?>