#9544: Improvement of application generator
[tine20] / tine20 / Tool / CodeGenerator / Application.php
1 <?php
2 /**
3  * Application Generator
4  *
5  * @package     Tool
6  * @subpackage  CodeGenerator
7  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
8  * @author      Fl├ívio Gomes da Silva Lisboa <flavio.lisboa@serpro.gov.br>
9  * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
10  * @version     $Id$
11  */
12 class Tool_CodeGenerator_Application implements Tool_CodeGenerator_Interface
13 {
14     const APPLICATION_NAME = '[APPLICATION_NAME]';
15     const DS = DIRECTORY_SEPARATOR;
16     
17     public static $_resultMessage = null;
18
19     /**
20      * List of source and target files
21      * @var array
22      */
23     protected $_sourceAndTargets = array();
24
25     /**
26      * List of files to be created
27      * @var array
28     */
29     protected $_folders = array(
30             'Backend',
31             'Controller',
32             'css',
33             'Frontend',
34             'js',
35             'translations',
36             'Model',
37             'Setup'
38     );
39
40     protected $recursiveSources = array(
41             'translations'
42     );
43
44     /**
45      * 
46      * @var application root directory
47      */
48     protected $_applicationFolder = null;
49
50     /**
51      * 
52      * @var name of application applied to every class
53      */
54     protected $_applicationName = null;
55
56     /**
57      * 
58      * @var reference folder for finding templates 
59      */
60     protected $_rootFolder = null;
61     
62     /**
63      * 
64      * @var absolute path for templates
65      */
66     protected $_templateFolder = null;
67
68     public function __construct()
69     {
70         $applicationName = self::APPLICATION_NAME;
71
72         $this->_sourceAndTargets =  array(
73             'Backend/ExampleRecord.php' => "Backend/{$applicationName}Record.php",
74             'Controller/ExampleRecord.php' => "/Controller/{$applicationName}Record.php",
75             'css/ExampleApplication.css' => "/css/{$applicationName}.css",
76             'Frontend/Cli.php' => 'Frontend/Cli.php',
77             'Frontend/Http.php' => 'Frontend/Http.php',
78             'Frontend/Json.php' => 'Frontend/Json.php',
79             'js/ExampleRecordDetailsPanel.js' => "js/{$applicationName}RecordDetailsPanel.js",
80             'js/ExampleRecordEditDialog.js' => "js/{$applicationName}RecordEditDialog.js",
81             'js/ExampleRecordGridPanel.js' => "js/{$applicationName}RecordGridPanel.js",
82             'Model/ExampleRecord.php' => "Model/{$applicationName}Record.php",
83             'Model/ExampleRecordFilter.php' => "Model/{$applicationName}RecordFilter.php",
84             'Model/Status.php' => "Model/Status.php",
85             'Setup/Initialize.php' => 'Setup/Initialize.php',
86             'Setup/setup.xml' => 'Setup/setup.xml',
87             'translations' => 'translations',
88             'Config.php' => 'Config.php',
89             'Controller.php' => 'Controller.php',
90             'ExampleApplication.jsb2' => $applicationName . '.jsb2',
91             'Exception.php' => 'Exception.php',
92             'Preference.php' => 'Preference.php'
93         );
94     }
95
96     /**
97      * (non-PHPdoc)
98      * @see Tool_CodeGenerator_Interface::build()
99      */
100     public function build(array $args)
101     {
102         try {
103             $this->_applicationName = $args[0];
104
105             // creates application folder
106             $this->_applicationFolder = $args[count($args)-1] . self::DS . $args[0];
107                     
108             $this->_rootFolder = $args[count($args)-1];
109             
110             $this->_templateFolder = realpath($this->_rootFolder . self::DS . 'ExampleApplication');
111                     
112             $this->_createFolders();
113
114             $this->_copyFiles();
115             
116             return "Application {$this->_applicationName} was created successfully into tine20 folder! \n";
117                     
118         } catch (Exception $e) {
119             return self::$_resultMessage = $e->getMessage();
120         }
121
122     }
123
124     /**
125      * Creates application folders
126      */
127     protected function _createFolders()
128     {
129         mkdir($this->_fsOsSintax($this->_applicationFolder));
130
131         foreach ($this->_folders as $folder)
132         {
133             mkdir($this->_fsOsSintax($this->_applicationFolder . self::DS . $folder));
134         }
135     }
136
137     /**
138      * Copy template files to target folders
139      */
140     protected function _copyFiles()
141     {
142         foreach($this->_sourceAndTargets as $source => $target) {
143             $target = str_replace(self::APPLICATION_NAME, $this->_applicationName, $target);
144
145             if (in_array($target, $this->recursiveSources)) {                
146                 $directory = scandir($this->_fsOsSintax($this->_templateFolder . self::DS . $source));
147                 unset($directory[0]); // this directory
148                 unset($directory[1]); // parent directory
149                 
150                 foreach($directory as $file) {
151                     $sourcePath = $this->_templateFolder . self::DS . $source . self::DS . $file;
152                     $targetPath = $this->_applicationFolder . self::DS . $target . self::DS . $file;
153                     $this->_copyFile($sourcePath, $targetPath);
154                 }
155                 
156             } else {
157                 $sourcePath = $this->_templateFolder . self::DS . $source;
158                 $targetPath = $this->_applicationFolder . self::DS . $target;
159                 $this->_copyFile($this->_templateFolder . self::DS . $source, $targetPath);
160             }
161         }
162     }
163
164     /**
165      * Copy file $sourcePath to $targetPath
166      * @param string $sourcePath
167      * @param string $targetPath
168      */
169     protected function _copyFile($sourcePath, $targetPath)
170     {
171         copy($this->_fsOsSintax($sourcePath), $this->_fsOsSintax($targetPath));
172         $this->_changeFile($targetPath);
173     }
174
175     /**
176      * Change content of copied files
177      * @param string $targetPath
178      */
179     protected function _changeFile($targetPath)
180     {
181         $content = file_get_contents($this->_fsOsSintax($targetPath));
182
183         $content = str_replace('ExampleApplication', $this->_applicationName, $content);
184         $content = str_replace('ExampleRecord', $this->_applicationName . 'Record', $content);
185         $content = str_replace('EXAMPLERECORD', strtoupper($this->_applicationName) . 'RECORD', $content);
186         $chainFilter = new Zend_Filter();
187         $chainFilter->addFilter(new Zend_Filter_Word_CamelCaseToUnderscore())
188                     ->addFilter(new Zend_Filter_StringToLower());
189         $content = str_replace('example_application_record', $chainFilter->filter($this->_applicationName) . '_record', $content);        
190
191         file_put_contents($targetPath, $content);
192     }
193     
194     /**
195      * Ensures that path is according to sintax of filesystem
196      * Try to use only in PHP core functions
197      * @param string $path
198      * @return string
199      */
200     protected function _fsOsSintax($path)
201     {
202         return str_replace('/', self::DS, $path);
203     }  
204 }