統計
| ブランチ: | リビジョン:

pictcode / lib / Cake / Console / Command / Task / TemplateTask.php @ 0b1b8047

履歴 | 表示 | アノテート | ダウンロード (6.194 KB)

1
<?php
2
/**
3
 * Template Task can generate templated output Used in other Tasks
4
 *
5
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
6
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
 *
8
 * Licensed under The MIT License
9
 * For full copyright and license information, please see the LICENSE.txt
10
 * Redistributions of files must retain the above copyright notice.
11
 *
12
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13
 * @link          http://cakephp.org CakePHP(tm) Project
14
 * @since         CakePHP(tm) v 1.3
15
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
16
 */
17

    
18
App::uses('AppShell', 'Console/Command');
19
App::uses('Folder', 'Utility');
20

    
21
/**
22
 * Template Task can generate templated output Used in other Tasks.
23
 * Acts like a simplified View class.
24
 *
25
 * @package       Cake.Console.Command.Task
26
 */
27
class TemplateTask extends AppShell {
28

    
29
/**
30
 * variables to add to template scope
31
 *
32
 * @var array
33
 */
34
        public $templateVars = array();
35

    
36
/**
37
 * Paths to look for templates on.
38
 * Contains a list of $theme => $path
39
 *
40
 * @var array
41
 */
42
        public $templatePaths = array();
43

    
44
/**
45
 * Initialize callback. Setup paths for the template task.
46
 *
47
 * @return void
48
 */
49
        public function initialize() {
50
                $this->templatePaths = $this->_findThemes();
51
        }
52

    
53
/**
54
 * Find the paths to all the installed shell themes in the app.
55
 *
56
 * Bake themes are directories not named `skel` inside a `Console/Templates` path.
57
 * They are listed in this order: app -> plugin -> default
58
 *
59
 * @return array Array of bake themes that are installed.
60
 */
61
        protected function _findThemes() {
62
                $paths = App::path('Console');
63

    
64
                $plugins = App::objects('plugin');
65
                foreach ($plugins as $plugin) {
66
                        $paths[] = $this->_pluginPath($plugin) . 'Console' . DS;
67
                }
68

    
69
                $core = current(App::core('Console'));
70
                $separator = DS === '/' ? '/' : '\\\\';
71
                $core = preg_replace('#shells' . $separator . '$#', '', $core);
72

    
73
                $Folder = new Folder($core . 'Templates' . DS . 'default');
74

    
75
                $contents = $Folder->read();
76
                $themeFolders = $contents[0];
77

    
78
                $paths[] = $core;
79

    
80
                foreach ($paths as $i => $path) {
81
                        $paths[$i] = rtrim($path, DS) . DS;
82
                }
83

    
84
                $themes = array();
85
                foreach ($paths as $path) {
86
                        $Folder = new Folder($path . 'Templates', false);
87
                        $contents = $Folder->read();
88
                        $subDirs = $contents[0];
89
                        foreach ($subDirs as $dir) {
90
                                if (empty($dir) || preg_match('@^skel$|_skel$@', $dir)) {
91
                                        continue;
92
                                }
93
                                $Folder = new Folder($path . 'Templates' . DS . $dir);
94
                                $contents = $Folder->read();
95
                                $subDirs = $contents[0];
96
                                if (array_intersect($contents[0], $themeFolders)) {
97
                                        $templateDir = $path . 'Templates' . DS . $dir . DS;
98
                                        $themes[$dir] = $templateDir;
99
                                }
100
                        }
101
                }
102
                return $themes;
103
        }
104

    
105
/**
106
 * Set variable values to the template scope
107
 *
108
 * @param string|array $one A string or an array of data.
109
 * @param string|array $two Value in case $one is a string (which then works as the key).
110
 *   Unused if $one is an associative array, otherwise serves as the values to $one's keys.
111
 * @return void
112
 */
113
        public function set($one, $two = null) {
114
                if (is_array($one)) {
115
                        if (is_array($two)) {
116
                                $data = array_combine($one, $two);
117
                        } else {
118
                                $data = $one;
119
                        }
120
                } else {
121
                        $data = array($one => $two);
122
                }
123

    
124
                if (!$data) {
125
                        return false;
126
                }
127
                $this->templateVars = $data + $this->templateVars;
128
        }
129

    
130
/**
131
 * Runs the template
132
 *
133
 * @param string $directory directory / type of thing you want
134
 * @param string $filename template name
135
 * @param array $vars Additional vars to set to template scope.
136
 * @return string contents of generated code template
137
 */
138
        public function generate($directory, $filename, $vars = null) {
139
                if ($vars !== null) {
140
                        $this->set($vars);
141
                }
142
                if (empty($this->templatePaths)) {
143
                        $this->initialize();
144
                }
145
                $themePath = $this->getThemePath();
146
                $templateFile = $this->_findTemplate($themePath, $directory, $filename);
147
                if ($templateFile) {
148
                        extract($this->templateVars);
149
                        ob_start();
150
                        ob_implicit_flush(0);
151
                        include $templateFile;
152
                        $content = ob_get_clean();
153
                        return $content;
154
                }
155
                return '';
156
        }
157

    
158
/**
159
 * Find the theme name for the current operation.
160
 * If there is only one theme in $templatePaths it will be used.
161
 * If there is a -theme param in the cli args, it will be used.
162
 * If there is more than one installed theme user interaction will happen
163
 *
164
 * @return string returns the path to the selected theme.
165
 */
166
        public function getThemePath() {
167
                if (count($this->templatePaths) === 1) {
168
                        $paths = array_values($this->templatePaths);
169
                        return $paths[0];
170
                }
171
                if (!empty($this->params['theme']) && isset($this->templatePaths[$this->params['theme']])) {
172
                        return $this->templatePaths[$this->params['theme']];
173
                }
174

    
175
                $this->hr();
176
                $this->out(__d('cake_console', 'You have more than one set of templates installed.'));
177
                $this->out(__d('cake_console', 'Please choose the template set you wish to use:'));
178
                $this->hr();
179

    
180
                $i = 1;
181
                $indexedPaths = array();
182
                foreach ($this->templatePaths as $key => $path) {
183
                        $this->out($i . '. ' . $key);
184
                        $indexedPaths[$i] = $path;
185
                        $i++;
186
                }
187
                $index = $this->in(__d('cake_console', 'Which bake theme would you like to use?'), range(1, $i - 1), 1);
188
                $themeNames = array_keys($this->templatePaths);
189
                $this->params['theme'] = $themeNames[$index - 1];
190
                return $indexedPaths[$index];
191
        }
192

    
193
/**
194
 * Find a template inside a directory inside a path.
195
 * Will scan all other theme dirs if the template is not found in the first directory.
196
 *
197
 * @param string $path The initial path to look for the file on. If it is not found fallbacks will be used.
198
 * @param string $directory Subdirectory to look for ie. 'views', 'objects'
199
 * @param string $filename lower_case_underscored filename you want.
200
 * @return string filename will exit program if template is not found.
201
 */
202
        protected function _findTemplate($path, $directory, $filename) {
203
                $themeFile = $path . $directory . DS . $filename . '.ctp';
204
                if (file_exists($themeFile)) {
205
                        return $themeFile;
206
                }
207
                foreach ($this->templatePaths as $path) {
208
                        $templatePath = $path . $directory . DS . $filename . '.ctp';
209
                        if (file_exists($templatePath)) {
210
                                return $templatePath;
211
                        }
212
                }
213
                $this->err(__d('cake_console', 'Could not find template for %s', $filename));
214
                return false;
215
        }
216

    
217
}