* @since PHP 4.0 * @copyright Copyright (c) 2000-2003 David Giffin : LGPL - See LICENCE * */ /** * * Define Pear Console Options */ require_once('Console/Getopt.php'); require_once("Combine/Combine.php"); /** XML Parsers / Class Generators / XML Generators */ require_once(dirname(__FILE__) . "/SchemaParser.php"); require_once(dirname(__FILE__) . "/ConfigWriter.php"); require_once(dirname(__FILE__) . "/TemplateHandler.php"); /** * Process the schema file and generate source code * * This object will handle reading the schema, command line options and more * * @version V2.0 Copyright (c) 2000-2001 David Giffin * @package Generator * @author David Giffin * @since PHP 4.0 * @copyright Copyright (c) 2000-2003 David Giffin : LGPL - See LICENCE * */ class Generator { /** Path Seperator */ var $pathSeperator = "/"; /** Smarty Template Handler */ var $templateHandler; /** Schema Files */ var $schemaFiles = array(); /** Project Directory */ var $projectDir = ""; /** Pear Console Object */ var $console; /** Pear Console Aguments */ var $args; var $fileTypePaths = array( "properties" => "/combine", "stub" => "/combine", "object" => "/combine/om", "action" => "/actions", "template" => "/templates" ); /** List of files which require generation */ var $generateFiles = array(); /** Types wich require generation */ var $generateTypes = array(); /** Types wich require generation */ var $generateAllTypes = array(); /** force over write */ var $forceOverWrite = false; var $queue = array(); /** * Constructor * */ function Generator() { $this->combine =& Combine::getInstance(); $this->projectDir = $this->combine->request->getEnv("PWD"); $this->extraDir = $this->combine->getCombineDir() . "/extra"; $this->iconsDir = $this->combine->getCombineDir() . "/icons"; $this->schemaDir = $this->projectDir . "/schema"; } /** * Process the schema files */ function doGenerator() { $this->getSchemaFiles(); $this->templateHandler = new TemplateHandler(); $this->templateHandler->projectDir = $this->projectDir; foreach ($this->schemaFiles as $schemaFile) { print "Processing Schema File: $schemaFile\n"; // Read the schema and pass it to the template handler $schemaParser = new SchemaParser($schemaFile); $schema =& $schemaParser->getSchema(); $this->templateHandler->setSchema($schema); foreach ($schema->tables as $tableName => $tableData) { // reset the queue for this table $this->queue = array(); // add new files into the queue $this->doFileQueue($tableName); // process the files from the queue foreach ($this->queue as $file => $template) { // print "Parsing Template: $template\n"; $this->templateHandler->parseAndWrite($tableName, $template, $file); print "Wrote File: $file\n"; } } $this->doConfigWriter($schema); } $this->doCopyExtra(); $this->doMakeDirs(); } /** * Write a Combine MVC Config file * */ function doConfigWriter(&$schema) { $configFileName = $schema->name . "-config.xml"; $configFilePath = $this->projectDir . "/combine/$configFileName"; if (!file_exists($configFilePath)) { require_once(dirname(__FILE__) . "/ConfigWriter.php"); $configWriter = new ConfigWriter(); $configWriter->setSchema($schema); $configWriter->doProcess(); $configWriter->writeFile($configFilePath); } } /** * Copy additional files required for runtime * */ function doCopyExtra() { $this->copyNoOverWrite($this->extraDir . "/doAction.php",$this->projectDir . "/doAction.php"); $this->copyNoOverWrite($this->extraDir . "/dot.htaccess",$this->projectDir . "/combine/.htaccess"); $this->copyNoOverWrite($this->extraDir . "/dot.htaccess",$this->projectDir . "/actions/.htaccess"); $this->copyNoOverWrite($this->extraDir . "/dot.htaccess",$this->projectDir . "/templates/.htaccess"); $this->copyNoOverWrite($this->extraDir . "/header.tpl",$this->projectDir . "/templates/header.tpl"); $this->copyNoOverWrite($this->extraDir . "/footer.tpl",$this->projectDir . "/templates/footer.tpl"); $mediaDir = $this->projectDir . "/media"; $projectIcons = $this->projectDir . "/media/icons"; if (!file_exists($mediaDir)) { mkdir($mediaDir); } if (!file_exists($projectIcons)) { mkdir($projectIcons); } $this->copyRecursive($this->iconsDir, $projectIcons); } /** * Copy a file but don't overwrite it if it already exists * * @param string $src The source file * @param string $dest The destination file * * @return int the result of the copy command */ function copyNoOverWrite($src, $dest) { if (!file_exists($dest)) { return copy($src,$dest); } } /** * Make Additional Directories * */ function doMakeDirs() { $cacheDir = $this->projectDir . "/cache"; if (!file_exists($cacheDir)) { mkdir($cacheDir); } } /** * Get the file name for a generated component * * @param string $table The name of the table for which the component references * @param string $type The type of component we are generating * */ function doFileQueue($table) { $phpName = $this->db2phpName($table); foreach ($this->fileTypePaths as $type => $path) { $absolutePath = $this->projectDir . $path; switch($type) { case "properties": $this->addToQueue($type,"{$absolutePath}/combine.properties","CombineProperties.tpl"); break; case "stub": $this->addToQueue($type,"{$absolutePath}/{$phpName}.php","StubObject.tpl"); $this->addToQueue($type,"{$absolutePath}/{$phpName}Peer.php","StubPeer.tpl"); break; case "object": $this->addToQueue($type,"{$absolutePath}/Base{$phpName}.php","BaseObject.tpl"); $this->addToQueue($type,"{$absolutePath}/Base{$phpName}Peer.php","BasePeer.tpl"); break; case "action": $this->addToQueue($type,"{$absolutePath}/save{$phpName}.php","ActionSave.tpl"); $this->addToQueue($type,"{$absolutePath}/edit{$phpName}.php","ActionEdit.tpl"); $this->addToQueue($type,"{$absolutePath}/list{$phpName}.php","ActionList.tpl"); $this->addToQueue($type,"{$absolutePath}/delete{$phpName}.php","ActionDelete.tpl"); $this->addToQueue($type,"{$absolutePath}/detail{$phpName}.php","ActionDetail.tpl"); break; case "template": $this->addToQueue($type,"{$absolutePath}/edit{$phpName}.tpl","SmartyEdit.tpl"); $this->addToQueue($type,"{$absolutePath}/list{$phpName}.tpl","SmartyList.tpl"); $this->addToQueue($type,"{$absolutePath}/detail{$phpName}.tpl","SmartyDetail.tpl"); break; default: break; } } } /** * Check if a file needs to be generated and add the file to the queue * * We will handle all of the logic to check if the file really needs * to be generated here... * * @param string $type The type of component we are generating * @param string $path The type of component we are generating * @param string $template The type of component we are generating */ function addToQueue($type,$path,$template) { $addToQueue = false; if ($type == "stub" || $type == "properties") { if (!file_exists($path)) { $addToQueue = true; } } else { $addToQueue = $this->requiresGeneration($path,$type); } if ($addToQueue == true) { $this->queue[$path] = $template; } } /** * Set the schema directory * * @param string $directory */ function setSchemaDirectory($directory) { if ($directory{0} == "/") { $this->schemaDir = $directory; } $this->schemaDir = $this->projectDir . "/" . $directory; } /** * Set Force Over Writing * * @param bool $value */ function setForceOverWrite($value) { $this->forceOverWrite = $value; } /** * Add a generation type * * @param string $type */ function addGenerateType($type) { $this->generateTypes[$type] = true; } /** * Add an generation all type * * @param string $type */ function addGenerateAllType($type) { $this->generateAllTypes[$type] = true; } /** * Check if a files requires generation * * @param string $filepath path to the file * @param string $type Type of file to be generated * * @return bool True if the file needs to be generated */ function requiresGeneration($filepath,$type) { $filename = basename($filepath); if (!file_exists($filepath)) { return true; } else if ($this->generateTypes[$type] === true && is_array($this->generateFiles) && in_array($filename, $this->generateFiles) ) { return true; } else if ($this->generateAllTypes[$type] === true) { return true; } return false; } /** * Find all of the Schema files in the schema dir * */ function getSchemaFiles() { if (!file_exists($this->schemaDir)) { die("schema directory is missing: {$this->schemaDir}\n"); } print "Looking for schema files in: {$this->schemaDir}\n"; $dh = dir($this->schemaDir); while ($entry = $dh->read()) { // Find Files with schema.xml extesion if (preg_match("/schema.xml$/",$entry)) { $this->schemaFiles[] = $this->schemaDir . "/" . $entry; } } $dh->close(); } /** * Convert a Database Name to a PHP Name * * @access private * * @param string $name The database column name * @return string The php name for the database column */ function db2phpName($name) { $words = split("_",strtolower($name)); $ret = ""; foreach ($words as $word) { $ret .= ucfirst($word); } return $ret; } /** * Copy Files Recursively * * This function copies all files in a directory structure * * @param string $from The The path to copy from * @param string $to The path to copy to */ function copyRecursive($from,$to) { /* if (is_dir($to)) { if (!file_exists($to)) { mkdir($to); } } */ $d = dir($from); while (false !== ($entry = $d->read())) { if ($entry == "." || $entry == ".." || $entry == "CVS") { continue; } $fromPath = "$from" . $this->pathSeperator . "$entry"; $toPath = "$to" . $this->pathSeperator . "$entry"; if (is_dir($fromPath)) { if (!file_exists($toPath)) { mkdir($toPath); } $this->copyRecursive($fromPath, $toPath); } else { print "Installing: $toPath\n"; copy($fromPath, $toPath); } } $d->close(); } } if (!function_exists("lcfirst")) { function lcfirst($str) { return substr_replace($str,strtolower(substr($str, 0, 1)), 0, 1); } } ?>