Fixes #149
[akelos.git] / lib / utils / generators / AkelosGenerator.php
blobdbbb8ca77ff211852d6f9a89af706e7b26fb6276
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4 // +----------------------------------------------------------------------+
5 // | Akelos Framework - http://www.akelos.org |
6 // +----------------------------------------------------------------------+
7 // | Copyright (c) 2002-2006, Akelos Media, S.L. & Bermi Ferrer Martinez |
8 // | Released under the GNU Lesser General Public License, see LICENSE.txt|
9 // +----------------------------------------------------------------------+
11 /**
12 * @package ActiveSupport
13 * @subpackage Generators
14 * @author Bermi Ferrer <bermi a.t akelos c.om>
15 * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
16 * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
19 defined('AK_GENERATORS_DIR') ? null : define('AK_GENERATORS_DIR', AK_LIB_DIR.DS.'utils'.DS.'generators');
21 class AkelosGenerator
23 var $log = array();
24 var $type = '';
25 var $_template_vars = array();
26 var $collisions = array();
27 var $generators_dir = AK_GENERATORS_DIR;
29 function runCommand($command)
31 $commands = $this->getOptionsFromCommand($command);
32 $generator_name = AkInflector::underscore(isset($commands['generator']) ? $commands['generator'] : array_shift($commands));
34 $available_generators = $this->_getAvailableGenerators();
35 $generator_file_name = array_shift(array_keys($available_generators, $generator_name));
37 if(empty($generator_file_name)){
38 echo "\n ".Ak::t("You must supply a valid generator as the first command.\n\n Available generator are:");
39 echo "\n\n ".join("\n ", $available_generators)."\n\n";
40 defined('AK_CONSOLE_MODE') && AK_CONSOLE_MODE ? null : exit;
41 return ;
44 if(include_once($generator_file_name)){
46 $generator_class_name = AkInflector::camelize($generator_name.'_generator');
47 $generator = new $generator_class_name();
48 $generator->_generator_base_path = dirname($generator_file_name);
50 if(count(array_diff($commands,array('help','-help','usage','-usage','h','-h','USAGE','-USAGE'))) != count($commands) || count($commands) == 0){
51 if(empty($generator->command_values) && empty($commands)){
52 // generator without commands
53 }else{
54 $generator->banner();
55 return;
59 $generator->type = $generator_name;
60 $generator->_identifyUnnamedCommands($commands);
61 $generator->_assignVars($commands);
62 $generator->cast();
63 $generator->_generate();
64 }else {
65 echo "\n".Ak::t('Could not find %generator_name generator',array('%generator_name'=>$generator_name))."\n";
69 function _assignVars($template_vars)
71 foreach ($template_vars as $key=>$value){
72 $this->$key = $value;
74 $this->_template_vars = (array)$this;
77 function assignVarToTemplate($var_name, $value)
79 $this->_template_vars[$var_name] = $value;
82 function cast()
87 function _identifyUnnamedCommands(&$commands)
89 $i = 0;
90 $extra_commands = array();
91 $unnamed_commands = array();
92 foreach ($commands as $param=>$value){
93 if($value[0] == '-'){
94 $next_is_value_for = trim($value,'- ');
95 $extra_commands[$next_is_value_for] = true;
96 continue;
99 if(isset($next_is_value_for)){
100 $extra_commands[$next_is_value_for] = trim($value,'- ');
101 unset($next_is_value_for);
102 continue;
105 if(is_numeric($param)){
106 if(!empty($this->command_values[$i])){
107 $index =$this->command_values[$i];
108 if(substr($this->command_values[$i],0,7) == '(array)'){
109 $index =substr($this->command_values[$i],7);
110 $unnamed_commands[$index][] = $value;
111 $i--;
112 }else{
113 $unnamed_commands[$index] = $value;
116 $i++;
119 $commands = array_merge($extra_commands, $unnamed_commands);
122 function render($template, $sintags_version = false)
124 $__file_path = $this->generators_dir.DS.$this->type.DS.($sintags_version?'sintags_':'').'templates'.DS.(strstr($template,'.') ? $template : $template.'.tpl');
125 if(!file_exists($__file_path)){
126 trigger_error(Ak::t('Template file %path not found.', array('%path'=>$__file_path)), E_USER_NOTICE);
128 extract($this->_template_vars);
129 ob_start();
130 include($__file_path);
131 $result = ob_get_contents();
132 ob_end_clean();
134 return $result;
137 function save($file_path, $content)
139 $this->log[] = $file_path;
140 Ak::file_put_contents($file_path, $content);
143 function printLog()
145 if(!empty($this->log)){
146 echo "\n".Ak::t('The following files have been created:')."\n";
147 echo join("\n",$this->log)."\n";
149 $this->log = array();
152 function _generate()
154 if(isset($this->_template_vars['force']) || !$this->hasCollisions()){
155 $this->generate();
156 $this->printLog();
157 }else{
158 echo "\n".Ak::t('There where collisions when attempting to generate the %type.',array('%type'=>$this->type))."\n";
159 echo Ak::t('Please add force=true to the argument list in order to overwrite existing files.')."\n\n";
161 echo join("\n",$this->collisions)."\n";
165 function hasCollisions()
167 return false;
170 function getOptionsFromCommand($command)
172 $command = $this->_maskAmpersands($command);
175 // Named params
176 if(preg_match_all('/( ([A-Za-z0-9_-])+=)/',' '.$command,$result)){
177 $command = str_replace($result[0],$this->_addAmpersands($result[0]),$command);
178 if(preg_match_all('/( [A-Z-a-z0-9_-]+&)+/',' '.$command,$result)){
179 $command = str_replace($result[0],$this->_addAmpersands($result[0]),$command);
182 $command = join('&',array_diff(explode(' ',$command.' '),array('')));
184 parse_str($command,$command_pieces);
186 $command_pieces = array_map('stripslashes',$command_pieces);
187 $command_pieces = array_map(array(&$this,'_unmaskAmpersands'),$command_pieces);
189 $params = array();
190 foreach ($command_pieces as $param=>$value){
191 if(empty($value)){
192 $params[] = $param;
193 }else{
194 $param = $param[0] == '-' ? substr($param,1) : $param;
195 $params[$param] = trim($value,"\"\n\r\t");
198 return $params;
201 function _addAmpersands($array)
203 $ret = array();
204 foreach ($array as $arr){
205 $ret[] = '&'.trim($arr);
207 return $ret;
210 function _maskAmpersands($str)
212 return str_replace('&','___AMP___',$str);
215 function _unmaskAmpersands($str)
217 return str_replace('___AMP___','&',$str);
220 function manifest($call_generate = true)
222 return $call_generate ? $this->generate() : null;
225 function generate()
227 return $this->manifest(false);
230 function banner()
232 $usage = @file_get_contents(@$this->_generator_base_path.DS.'USAGE');
233 echo empty($usage) ? "\n".Ak::t('Could not locate usage file for this generator') : "\n".$usage."\n";
236 function _getAvailableGenerators()
238 return array_merge($this->_getGeneratorsInsidePath($this->generators_dir), $this->_getPluginGenerators());
241 function _getPluginGenerators()
243 $generators = array();
244 defined('AK_PLUGINS_DIR') ? null : define('AK_PLUGINS_DIR', AK_APP_DIR.DS.'vendor'.DS.'plugins');
245 foreach (Ak::dir(AK_PLUGINS_DIR,array('files'=>false,'dirs'=>true)) as $folder){
246 $plugin_name = array_shift(array_keys($folder));
247 $generators = array_merge($generators, $this->_getGeneratorsInsidePath(AK_PLUGINS_DIR.DS.$plugin_name.DS.'generators'));
249 return $generators;
252 function _getGeneratorsInsidePath($path)
254 $generators = array();
255 if(is_dir($path)){
256 foreach (Ak::dir($path,array('files'=>false,'dirs'=>true)) as $folder){
257 $generator = array_shift(array_keys($folder));
258 if(strstr($generator,'.php')){
259 continue;
261 $generators[$path.DS.$generator.DS.$generator.'_generator.php'] = $generator;
264 return $generators;