<?php

/*******************************************************************************

 WINBINDER - A native Windows binding for PHP

 Copyright  2004-2005 Hypervisual - see LICENSE.TXT for details
 Author: Rubem Pechansky (http://www.hypervisual.com/winbinder/contact.php)

 Tool for building WinBinder snapshots and releases

********************************************************************************

Tasks performed:

- Update version number in Source\wb\wb_version.h
- Compile projects if not up-to-date
- Save version number to version.h
- Copy syntax definition file to WinBinder folder
- Copy text and code files to web site folder
- Convert HTML files to HTML Help
- Generate manual.chm
- Generate todo_items.html
- Include release notes
- Generate package.xml and package2.xml
- Save current files to zip file
- Convert zip to tar.gz for PECL
- Update version data in setup script
- Compile Setup application
- Upload files to server
- Upload web site changes to server

To do's:

- ZIPPER_FLAT does not work, must store files with no path
- Generate toc.hhc automatically from index.html

*/

//----------------------------------------------------------- CURRENT PARAMETERS

define("VERSION",           "0.56");            // Version of this utility
define("PROJ_STATE",        "alpha");           // For PECL: WinBinder status

//------------------------------------------------------------ SYSTEM PARAMETERS

define("PATH_SCRIPT",   dirname(__FILE__) . "/");
define("PATH_DATA",     PATH_SCRIPT);
define("PATH_INC",      PATH_SCRIPT "../include/");
define("PATH_RES",      PATH_SCRIPT "../resources/");

//----------------------------------------------------------------- DEPENDENCIES

include PATH_INC "winbinder.php";
include 
PATH_INC "db\\db_common.inc.php";

//-------------------------------------------------------------- USER PARAMETERS

// Set the constants below according to your system

define("WB_ROOT",           "C:\\@desenv\\WinBinder\\");    // The mother of all directories
define("PGMFILES",          wb_get_system_info("pgmpath"));
define("PHP_PHP4",          WB_ROOT "tools\\Lcc-win32\\php4");
define("PHP_PHP5",          WB_ROOT "tools\\Lcc-win32\\php5");
define("SETUPSCRIPT",       WB_ROOT "Tools\\inno_setup\\wb.iss");
define("ZIPPER",            "\"" PGMFILES "WinZip\\WZZIP.EXE\" %s -r -P @" WB_ROOT ."tools\\winzip\\%s_zipme.txt -x@" WB_ROOT "Tools\\winzip\\%s_zipmenot.txt%s");
define("ZIPPER_FLAT",       "\"" PGMFILES "WinZip\\WZZIP.EXE\" %s @" WB_ROOT ."tools\\winzip\\%s_zipme.txt -x@" WB_ROOT ."tools\\winzip\\%s_zipmenot.txt%s");
define("TARGZ",             "\"" PGMFILES "izarc\izarc.exe\" -cv %s");
define("HELPWORKSHOP",      "\"" PGMFILES "HTML Help Workshop\\hhc.exe\" ");
define("SETUPCOMP",         "\"" PGMFILES "Inno Setup\\compil32.exe\" /cc " SETUPSCRIPT);
define("COMPILER_MAKE",     "C:\\Util\\lcc\\bin\\make.exe");
define("WEBSITE",           "C:\\@Trab\\Hypervisual\\Website\\pages\\winbinder\\");

// You probably won't need to change these

$path pathinfo(__FILE__);
define("SCRIPTPATH",        $path["dirname"] . "\\");
define("HELP_DIR",          WB_ROOT "tools\\html_help\\");
define("TARGET_PATH",       WB_ROOT "@Privado\\Arquivo\\");
define("SOURCE_PATH",       WB_ROOT "csource\\");
define("VERSION_FILE",      WB_ROOT "csource\\core\\wb\\wb_version.h");
define("MANUAL_SRC",        WB_ROOT "docs\manual");
define("RELNOTES",          WB_ROOT "docs\\Release_notes.txt");
define("LOGFILE",           WB_ROOT "docs\\changelog.txt");
define("DLL4",              WB_ROOT "binaries\\php4\\ext\\php_winbinder.dll");
define("DLL5",              WB_ROOT "binaries\\php5\\ext\\php_winbinder.dll");
define("PEAR10_PACKAGE",    WB_ROOT "package.xml");
define("PEAR14_PACKAGE",    WB_ROOT "package2.xml");
define("TODO_PATH",         WB_ROOT "phpcode\\todo\\");
define("EXAMPLE_PATH",      WB_ROOT "phpcode\\examples\\");
define("WEB_TODO_HTML",     WEBSITE "doc\\todo_items.html");
define("MANUAL_TGT",        HELP_DIR "manual");
define("HELP_PROJECT",      HELP_DIR "manual.hhp");
define("FLIST",             "filelist.txt");
define("TODO_DATABASE",     "todo");
define("SYS_INIFILE",       "make_release.ini");
define("FILELIST",          SCRIPTPATH FLIST);
define("PEAR10_TEMPLATE",   SCRIPTPATH "pear10_template.xml");
define("PEAR14_TEMPLATE",   SCRIPTPATH "pear14_template.xml");

//-------------------------------------------------------------- OTHER CONSTANTS

define("APPNAME",           "WinBinder Release Maker"); // Application name
define("VERSION_CONTENTS",  "\r\n// Current WinBinder version\r\n// This file is generated automatically by " APPNAME ".\r\n\r\n#define WINBINDER_VERSION\t\t\"%s\"\r\n");
define("COMBO_ITEMS",       "No action\nSnapshot\nPHP developer\nC developer\nRelease\nMinimal PHP 4\nMinimal PHP 5\nDLLs only");


include 
WB_ROOT "phpcode/todo/todo_import_export.inc.php";

// Various arrays

$flistfiles = array("""snapshot""php_develop""c_develop""release""php4""php5""dlls");
$ftemplate = array("""wb_snap_%s.zip""wb_php_devel_%s.zip""wb_c_devel_%s.zip""winbinder_%s.zip""php4_minimal.zip""php5_minimal.zip""wb_dll_%s.zip");
$all_flags = array("CHM","COPYFILES","EXPORTTODO","ZIP","CHECKDLLS","XML","TGZ","MIME","RELNOTES""SETUP");
$all_ctrls $all_flags;
array_push($all_ctrls"TYPE""VERBOSE");
$zip_dependent = array("CHECKDLLS","XML","TGZ","MIME""FLIST");

// Additional files to copy

$copies = array(

    
PGMFILES "TextPad\\Samples\\php_winbinder.syn",       WB_ROOT "Tools\\textpad\\php_winbinder.syn",

    
WB_ROOT "readme.txt",                                 WEBSITE "doc\\readme.txt",
    
WB_ROOT "docs\\changelog.txt",                        WEBSITE "doc\\changelog.txt",
    
WB_ROOT "docs\\release_notes.txt",                    WEBSITE "doc\\release_notes.txt",
    
WB_ROOT "docs\\license.txt",                          WEBSITE "doc\\license.txt",
    
WB_ROOT "phpcode\\make_release\\make_release.phpw",   WEBSITE "code\\make_release.phpw",
    
WB_ROOT "phpcode\\make_release\\make_release.rc",     WEBSITE "code\\make_release.rc",

    
EXAMPLE_PATH "minimal.phpw",                          WEBSITE "code\\minimal.phpw",
    
EXAMPLE_PATH "digiclock.phpw",                        WEBSITE "code\\digiclock.phpw",
    
EXAMPLE_PATH "hello.phpw",                            WEBSITE "code\\hello.phpw",
    
EXAMPLE_PATH "hello_oo.phpw",                         WEBSITE "code\\hello_oo.phpw",
    
EXAMPLE_PATH "calc.phpw",                             WEBSITE "code\\calc.phpw",
    
EXAMPLE_PATH "ttfreader.phpw",                        WEBSITE "code\\ttfreader.phpw",
    
EXAMPLE_PATH "borderless.phpw",                       WEBSITE "code\\borderless.phpw",
    
EXAMPLE_PATH "calc.rc",                               WEBSITE "code\\calc.rc",
);

//-------------------------------------------------------------- EXECUTABLE CODE

// Create main window

// Remove the line below while not under development

file_put_contents("make_release.rc.php""<?php\n\n" parse_rc(file_get_contents("make_release.rc"),
  
'$mainwin'null'ModelessDialog'nullWBC_CENTERWBC_CENTERWBC_CENTERWBC_CENTER,
  
'WBC_INVISIBLE'0) . "\n?>");

include(
"make_release.rc.php");

wb_set_handler($mainwin"process_main");
wb_set_text($mainwinAPPNAME " version " VERSION);
wb_set_image($mainwinPATH_RES "hyper.ico");

// Initialize controls

wb_set_text(wb_get_control($mainwinIDC_TYPE), COMBO_ITEMS);
wb_set_text(wb_get_control($mainwinIDC_NOTES), file_get_contents(RELNOTES));

// Accelerator table

wb_create_control($mainwinAccel, 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($mainwinconstant("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($mainwinIDC_TYPE);
}
process_main($mainwinIDC_ZIP);        // Disable commands if it is the case
process_main($mainwinIDC_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($mainwinIDC_VERSION), $ver);
$textbox wb_get_control($mainwinIDC_RESULT);

wb_set_text(wb_get_control($mainwinIDC_STATE), PROJ_STATE);

// Move and show main window

$xpos = @$settings["Settings"]["xpos"];
$ypos = @$settings["Settings"]["ypos"];
wb_set_focus(wb_get_control($mainwinIDC_GO));
wb_set_position($mainwin$xpos$ypos);
wb_set_visible($mainwintrue);

check_date_version($mainwinLOGFILE$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($windowIDC_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($windowconstant("IDC_" $flag)), $status);
            if(
wb_get_value(wb_get_control($window$id))) {
                
$fname $flistfiles[wb_get_selected(wb_get_control($windowIDC_TYPE))];
                
wb_set_text(wb_get_control($windowIDC_FLIST), $fname ? ($fname "_zipme.txt") : "(none)");
            } else {
                
wb_set_text(wb_get_control($windowIDC_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($windowconstant("IDC_" $all_flags[$i])),
                
$check[$status][$i]);
            }
            
process_main($windowIDC_ZIP);
            
process_main($windowIDC_RELNOTES);
            
process_main($windowIDC_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($mainwinIDC_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 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($mainwinIDC_VERBOSE));
    
$type wb_get_selected(wb_get_control($mainwinIDC_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($mainwinLOGFILE$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($mainwinIDC_RELNOTES))) {

        if(
file_get_contents(RELNOTES) != wb_get_text(wb_get_control($mainwinIDC_NOTES))) {
            
out("Saving release notes...\r\n");
            
file_put_contents(RELNOTESwb_get_text(wb_get_control($mainwinIDC_NOTES)));
        }
    }

    
// Change directory

    
$currdir getcwd();
    
chdir(WB_ROOT);

    
// Delete zip file if it exists

    
if(wb_get_value(wb_get_control($mainwinIDC_ZIP))) {

        
$filename TARGET_PATH sprintf($ftemplate[$type], str_replace("-dev"""$ver));
        if(
file_exists($filename)) {
            if(!
wb_message_box($mainwin"Overwrite " basename($filename) . "?"APPNAMEWBC_YESNO)) {
                
out("Aborted.\r\n");
                
chdir($currdir);
                return;
            }
            
unlink($filename);
        }
    }

    
// Compile project and update some files

    
if(wb_get_value(wb_get_control($mainwinIDC_ZIP))) {

        
// Check and update DLLs

        
if(wb_get_value(wb_get_control($mainwinIDC_CHECKDLLS))) {

            if(
needs_updating(DLL4SOURCE_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."APPNAMEWBC_WARNING);
                
out("Aborted.\r\n");
                return;
            }

            if(
needs_updating(DLL5SOURCE_PATH)) {
                
wb_message_box($mainwin"Warning: The WinBinder DLL for PHP 5 is not up-to-date. Please recompile it and try again."APPNAMEWBC_WARNING);
                
out("Aborted.\r\n");
                return;
//              $dir = getcwd();
//              chdir(PHP_PHP5);
//              out("Building WinBinder for PHP 5...\r\n");
//              exec(COMPILER_MAKE);
//              chdir($dir);
            
}
        }

        
// Build package.xml (2 versions)

        
if(wb_get_value(wb_get_control($mainwinIDC_XML))) {
            
out("Creating PEAR 1.0 information...\r\n");
            
shell_exec(sprintf(ZIPPER$filename$flistfiles[$type], $flistfiles[$type], " -@" FILELIST));
            
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($mainwinIDC_CHM))) {

        
out("Converting HTML files...");
        
$helpfiles get_folder_files(MANUAL_SRCTRUETRUE"/.*\.(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_SRCMANUAL_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("/<!--KW:(.*)-->/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<param name=\"Keyword\" value=\"$line\">\r\n";
                    }
                    
$html preg_replace("/<!--KW:(.*)-->/is",
                        
"<object type=\"application/x-oleobject\" classid=\"clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e\">\r\n$klinks</object>"$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($tgtfilefilemtime($srcfile));
                }
            } else {
                
copy($srcfile$tgtfile);
                @
touch($tgtfilefilemtime($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($mainwinIDC_EXPORTTODO))) {
        
out("Creating To Do list...\r\n");
        
todo_export();
    }

    
// Copy/update files

    
if(wb_get_value(wb_get_control($mainwinIDC_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($tgtfilepreg_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($mainwinIDC_ZIP))) {
        if(
$type == || $type == 6) {
            
$zipper ZIPPER_FLAT;
            
out("You must remove the file paths manually from inside the ZIP file.\r\n");
        } else
            
$zipper ZIPPER;

        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");

        
// Convert zip file to tar.gz

        
if(wb_get_value(wb_get_control($mainwinIDC_TGZ))) {

            
out("Converting to tar.gz...\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($mainwinIDC_MIME))) {

            
out("Encoding as MIME...\r\n");
            
$mime str_replace(".zip"".b64"$filename);
            
file_put_contents($mimeb64encode($filename));
        }

    }

    
// Create setup

    
if(wb_get_value(wb_get_control($mainwinIDC_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);
        
shell_exec(SETUPCOMP);
    }

    
// 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."APPNAMEWBC_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 j, Y")) {
        
wb_message_box($window"Warning: The date in the changelog is incorrect or invalid. Please change it and try again."APPNAMEWBC_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 .= "         <file role=\"src\" md5sum=\"$md5hash\" name=\"$file\"/>\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($mainwinIDC_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 ("<dir name=...>")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 " <dir name=\"/\">\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 .= "  <file md5sum=\"$md5hash\" name=\"$file\" role=\"$role\" />\r\n";
        }
    }
    
$files .= " </dir> <!-- / -->";

    
// 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($mainwinIDC_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($textbox1);
        return;
    }

    if(!
$str) {
        
$lastresult "";
        return;
    }

    
$lastresult .= $str;
    
wb_set_text($textbox$lastresult);
    
wb_refresh($textbox1);
}

// 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($pathtruetrue""));

    foreach(
$files as $file)
        
unlink($file);
}

// Exports To Do list as HTML

function todo_export()
{
    
db_open_database(TODO_DATABASETODO_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($windowconstant("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($windowMSG_FILESAVEERRAPPNAME);
    
out("Done.\r\n");
}

//------------------------------------------------------------------ END OF FILE

?>