83caa48f781a7db3d1a0dee2bd76b506c5c9b96b
[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) 2013 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     /**
18      * List of source and target files
19      * @var array
20      */
21     protected $_sourceAndTargets = array();
22
23     /**
24      * List of files to be created
25      * @var array
26     */
27     protected $_folders = array(
28             'Backend',
29             'Controller',
30             'css',
31             'Frontend',
32             'js',
33             'translations',
34             'Model',
35             'Setup'
36     );
37
38     protected $recursiveSources = array(
39             'translations'
40     );
41
42     protected $_applicationFolder = null;
43
44     protected $_applicationName = null;
45
46     protected $_rootFolder = null;
47
48     public function __construct()
49     {
50         $applicationName = self::APPLICATION_NAME;
51
52         $this->_sourceAndTargets =  array(
53             'Backend/ExampleRecord.php' => "Backend/{$applicationName}Record.php",
54             'Controller/ExampleRecord.php' => "/Controller/{$applicationName}Record.php",
55             'css/ExampleApplication.css' => "/css/{$applicationName}.css",
56             'Frontend/Cli.php' => 'Frontend/Cli.php',
57             'Frontend/Http.php' => 'Frontend/Http.php',
58             'Frontend/Json.php' => 'Frontend/Json.php',
59             'js/ExampleRecordDetailsPanel.js' => "js/{$applicationName}RecordDetailsPanel.js",
60             'js/ExampleRecordEditDialog.js' => "js/{$applicationName}RecordEditDialog.js",
61             'js/ExampleRecordGridPanel.js' => "js/{$applicationName}RecordGridPanel.js",
62             'Model/ExampleRecord.php' => "Model/{$applicationName}Record.php",
63             'Model/ExampleRecordFilter.php' => "Model/{$applicationName}RecordFilter.php",
64             'Model/Status.php' => "Model/Status.php",
65             'Setup/Initialize.php' => 'Setup/Initialize.php',
66             'Setup/setup.xml' => 'Setup/setup.xml',
67             'translations' => 'translations',
68             'Config.php' => 'Config.php',
69             'Controller.php' => 'Controller.php',
70             'ExampleApplication.jsb2' => $applicationName . '.jsb2',
71             'Exception.php' => 'Exception.php',
72             'Preference.php' => 'Preference.php'
73         );
74     }
75
76     public function build(array $args)
77     {
78         try {
79             $this->_applicationName = $args[0];
80
81             // creates application folder
82             $this->_applicationFolder = $args[count($args)-1] . self::DS . $args[0];
83                     
84             $this->_rootFolder = $args[count($args)-1];
85                     
86             $this->_createFolders();
87
88             $this->_copyFiles();
89                     
90         } catch (Exception $e) {
91             echo $e->getMessage();
92         }
93
94     }
95
96     /**
97      * Creates application folders
98      */
99     protected function _createFolders()
100     {
101         mkdir($this->fsOsSintax($this->_applicationFolder));
102
103         foreach ($this->_folders as $folder)
104         {
105             mkdir($this->fsOsSintax($this->_applicationFolder . self::DS . $folder));
106         }
107     }
108
109     /**
110      * Copy template files to target folders
111      */
112     protected function _copyFiles()
113     {
114         $templateFolder = $this->_rootFolder . self::DS . 'Tool/Application/templates';
115
116         foreach($this->_sourceAndTargets as $source => $target) {
117             $target = str_replace(self::APPLICATION_NAME, $this->_applicationName, $target);
118
119             if (in_array($target, $this->recursiveSources)) {                
120                 $directory = scandir($this->fsOsSintax($templateFolder . self::DS . $source));
121                 unset($directory[0]); // this directory
122                 unset($directory[1]); // parent directory
123                 
124                 foreach($directory as $file) {
125                     $sourcePath = $templateFolder . self::DS . $source . self::DS . $file;
126                     $targetPath = $this->_applicationFolder . self::DS . $target . self::DS . $file;
127                     $this->_copyFile($sourcePath, $targetPath);
128                 }
129                 
130             } else {
131                 $sourcePath = $templateFolder . self::DS . $source;
132                 $targetPath = $this->_applicationFolder . self::DS . $target;
133                 $this->_copyFile($templateFolder . self::DS . $source, $targetPath);
134             }
135         }
136     }
137
138     /**
139      * Copy file $sourcePath to $targetPath
140      * @param string $sourcePath
141      * @param string $targetPath
142      */
143     protected function _copyFile($sourcePath, $targetPath)
144     {
145         copy($this->fsOsSintax($sourcePath), $this->fsOsSintax($targetPath));
146         $this->_changeFile($targetPath);
147     }
148
149     /**
150      * Change content of copied files
151      * @param string $targetPath
152      */
153     protected function _changeFile($targetPath)
154     {
155         $content = file_get_contents($this->fsOsSintax($targetPath));
156
157         $content = str_replace('ExampleApplication', $this->_applicationName, $content);
158         $content = str_replace('ExampleRecord', $this->_applicationName . 'Record', $content);
159         $content = str_replace('EXAMPLERECORD', strtoupper($this->_applicationName) . 'RECORD', $content);
160         $chainFilter = new Zend_Filter();
161         $chainFilter->addFilter(new Zend_Filter_Word_CamelCaseToUnderscore())
162                     ->addFilter(new Zend_Filter_StringToLower());
163         $content = str_replace('example_application_record', $chainFilter->filter($this->_applicationName) . '_record', $content);        
164
165         file_put_contents($targetPath, $content);
166     }
167     
168     /**
169      * Ensures that path is according to sintax of filesystem
170      * Try to use only in PHP core functions
171      * @param string $path
172      * @return string
173      */
174     protected function fsOsSintax($path)
175     {
176         return str_replace('/', self::DS, $path);
177     }    
178 }