PDA

View Full Version : JS Builder in PHP



moraes
29 Dec 2006, 5:54 AM
This is a very simple PHP class that reads a JS Builder's project file and writes a -debug.js file and a minified .js file to the target destination, using JSMin.

edit: the idea came from a discussion about a cross-platform builder, which started here: http://www.yui-ext.com/forum/viewtopic.php?p=7376#7376


<?php
/**
*
* PHP builder for JS Builder XML files.
*
* @author Rodrigo Moraes - http://tipos.org
*
*/
class Js_Builder
{
/**
*
* Configuration options.
*
* @var array
*
*/
protected $_config;

/**
*
* Constructor. Sets the configuration options, reads the XML file, set
* project properties and iteracts to build target files.
*
*/
public function __construct($config)
{
if(is_string($config)) {
$this->_config = include $config;
} elseif(is_array($config)) {
$this->_config = $config;
}

// Load the XML file
$xml = simplexml_load_file($this->_config['project_file']);

// Merge project properties with config. This can be used to
// override the project definitions, like the output path etc.
$properties = (array) $xml->attributes();
$this->_config = array_merge($properties['@attributes'], $this->_config);

foreach($xml as $key => $value) {
if($key == 'target') {
$this->_buildTarget($value);
}
}
}

/**
*
* Normalizes a path according to the current operating system.
*
* @param string $path Not-sure-if-normalized path.
*
* @return string Normalized path.
*
*/
protected function _normalizePath($path)
{
return str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path);
}

/**
*
* Parses the comments to include in the file header.
*
* @return string The parsed comments.
*
*/
protected function _getComments() {
// Replaces all variables.
$vars = array(
'$projectName' => $this->_config['name'],
'$version' => $this->_config['version'],
'$author' => $this->_config['author'],
);

$comments = str_replace(array_keys($vars), array_values($vars),
$this->_config['copyright']);
return $comments;
}

/**
*
* Builds a JS Builder target file.
*
* @param object SimpleXMLElement.
*
*/
protected function _buildTarget($target)
{
// Get the target attributes.
$attr = $target->attributes();

// It won't parse absolute paths yet. Sorry.
if(strstr($attr['file'], '$output') === false) {
return;
}

// Replace the output variable by the project output dir.
$out_file = str_replace('$output', $this->_config['output'],
$attr['file']);
$out_file = $this->_normalizePath($out_file);

// Create a debug file name.
$debug_file = str_replace('.js', '-debug.js', $out_file);

// Start reading target files.
$contents = '';
foreach($target as $key => $file) {
$source_path = $this->_config['source_dir'] . DIRECTORY_SEPARATOR
. $file['name'];
$source_path = $this->_normalizePath($source_path);
$contents .= file_get_contents($source_path) . "\n\n";
}

// Write to the debug file.
file_put_contents($debug_file, $contents);

// Minifies the debug file to the output file.
$comments = (array) $this->_getComments();
$jsmin = new JSMin($debug_file, $out_file, $comments);
$jsmin->minify();
}

}

Tthis is a index.php to run the builder from a browser:

<?php
// Edit configuration paths.
$config = array(
// YUI-ext's SVN - .jsb project file path
'project_file' => '/var/Libraries/SVN/YUI-ext/src/yui-ext.jsb',
// YUI-ext's SVN - /src directory path
'source_dir' => '/var/Libraries/SVN/YUI-ext/src',
// Output directory. If defined, will overwrite the definition
// in the project file. Comment it to use the definition in the .jsb file.
'output' => '/var/www/tipos/public_html/inc/js/yui-ext',
);

// Nothing below needs to be edited.

// Avoids JSMin to run automatically.
define('JSMIN_AS_LIB', true);

// Include libraries.
require 'JSMin.php';
require 'Js_Builder.php';

// Run from browser.
new Js_Builder($config);

The PHP version of JSMin is also needed: http://www.crockford.com/javascript/jsmin.html

update: the code above was simplified and improved on december 30, 2006.