<?php
/**
 * fromvega XML Generator
 *
 * Generates a simple config XML file from files in a directory
 * based on user customization.
 *
 * You can also run this script from the command line.
 * That way you can interact with the script as it generates the XML files.
 *
 *         Usage: php xmlgen.php dir1 dir2 dir3
 *
 * Visit us to talk about this script and read other interesting articles!
 *
 * @author fromvega
 * @version 1.0
 * @link http://fromvega.com
 */

/**
 * Customize the behavior of the script
 */

// if the script should invert Windows slashes ('\' to '/')
$invertSlash true;

// list of directories to be read (relative to the xmlgen.php file) with no trailing slash
$directoryList = array('cars''people''landscape');

// name of the XML file
$xmlFileName 'images.xml';

// name of the root tag
$rootTagName 'images';

// name of the file tag
$childTagName  'image';

/**
 * Definition of individual tags for each file entry.
 * Add a pair 'tagname' => 'tagvalue' for each tag.
 *
 * You can use these placeholders in the tag value:
 *
 *         {filename} - the file name
 *         {dirname} - the directory name
 *         {pathname} - the whole path
 *         {id} - a numeric file id
 *         {input} - to ask for data when in CLI mode
 *
 * You can also call a custom function for the tag. The pathname of
 * the file will be passed as arguments and a string containing the
 * value of the tag should be returned.
 *
 *         {callback:user_function}
 */
$childTagList = array('name'         => 'images/{pathname}',
                      
'caption'     => '{input}',
                      
'orientation'    => '{callback:discoverOrientation}',
                      
'filesize'     => '{callback:filesize}');


/**
 * Code - Do not modify below this point (unless you know what you're doing)
 *
 */

// detect if it's being run through cli
$cliMode = (php_sapi_name() == 'cli');

// if cliMode catch the directories from the cmd line
if($cliMode && $argc 1){

    
array_shift($argv);

    foreach (
$argv as $dir){
        
array_push($directoryList$dir);
    }
}

// for HTML display purposes
if(!$cliMode) echo "<pre>\n";

// informative display
echo "---------------------------------------------\n\n";
echo 
"    fromvega XML Generator - fromvega.com\n\n";

// loop through the directories list
foreach ($directoryList as $directory) {

    
// informative display
    
echo "---------------------------------------------\n";
    echo 
"Creating XML file for '$directory'...\n";

    
// start XML formation
    
$xml  '<?xml version="1.0" ?>'."\n";
    
$xml .= "<$rootTagName>\n";

    try {
        
// create a new DirectoryIterator for the current directory
        
$dir = new DirectoryIterator($directory);
    } catch (
Exception $e){
        echo 
"Couldn't open the directory '$directory'.\n";
        continue;
    }

    
// flag to be used as the file id
    
$fileId 1;

    
// loop through the entries of the directory
    
foreach($dir as $file){

        
// if it's a file
        
if($file->isFile()){

            
// open child tag
            
$xml .= "  <$childTagName>\n";

            
// loop through each tag in the list
            
foreach ($childTagList as $tagName => $tagValue) {

                
// format the info variables according to $invertSlash boolean
                
$filename  $invertSlash str_replace('\\''/'$file->getFilename()) : $file->getFilename();
                
$directory $invertSlash str_replace('\\''/'$directory) : $directory;
                
$pathname  $invertSlash str_replace('\\''/'$file->getPathname()): $file->getPathname();

                
// check for {input} placeholder
                
if(strpos($tagValue'{input}') !== false){

                    
// if cliMode ask for input otherwise leave blank
                    
if($cliMode){
                        echo 
"Enter the '$tagName' of '$filename': ";
                        
$line trim(fgets(STDIN));
                        
$tagValue str_replace('{input}'$line$tagValue);
                    } else {
                        
$tagValue '';
                    }

                }
                
// check for {callback} placeholder
                
else if (strpos($tagValue'{callback') !== false){

                    
// get the function name
                    
if(preg_match('/{callback:(\w+)}/'$tagValue$match)){
                        
$callback $match[1];

                        try{
                            
// call the function
                            
$tagValue $callback($pathname);
                        } catch (
Exception $e){
                            echo 
"Couldn't call '$callback' function!\n";
                        }
                    }

                }
                
// try other placeholders
                
else {
                    
$tagValue str_replace('{filename}'$filename$tagValue);
                    
$tagValue str_replace('{dirname}'$directory$tagValue);
                    
$tagValue str_replace('{pathname}'$pathname$tagValue);
                    
$tagValue str_replace('{id}'$fileId$tagValue);
                }

                
// create the tag pair
                
$xml .= "    <$tagName>$tagValue</$tagName>\n";
            }

            
// closes child tag
            
$xml .= "  </$childTagName>\n";

            
// increments the file id number
            
$fileId++;
        }
    }

    
// closes the root tag
    
$xml .= "</$rootTagName>\n";

    try {
        
// creates the XML file
        
$fp fopen($directory.'/'.$xmlFileName,'w');
        
fwrite($fp$xml);
        
fclose($fp);

        echo 
"XML file created!\n";
    } catch (
Exception $e){
        echo 
"Error creating the XML file.\n";
    }
}

// informative display
echo "Done!\n";
if(!
$cliMode) echo '</pre>';

/**
 * Discover the orientation of an image
 *
 * @param string $path
 * @param int $id
 * @return string
 */
function discoverOrientation($path){

    try {
        
// get image information
        
$info getimagesize($path);
    } catch (
Exception $e){
        return 
'unknown';
    }

    
// compare height and width values
    
if($info[1] > $info[0]){
        return 
'vertical';
    } else{
        return 
'horizontal';
    }
}