/
template.php
212 lines (197 loc) · 6.09 KB
/
template.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
<?php
/**
* Template Task can generate templated output Used in other Tasks
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.console.libs.tasks
* @since CakePHP(tm) v 1.3
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::import('Core', 'Folder');
class TemplateTask extends Shell {
/**
* variables to add to template scope
*
* @var array
*/
public $templateVars = array();
/**
* Paths to look for templates on.
* Contains a list of $theme => $path
*
* @var array
*/
public $templatePaths = array();
/**
* Initialize callback. Setup paths for the template task.
*
* @access public
* @return void
*/
public function initialize() {
$this->templatePaths = $this->_findThemes();
}
/**
* Find the paths to all the installed shell themes in the app.
*
* Bake themes are directories not named `skel` inside a `vendors/shells/templates` path.
*
* @return array Array of bake themes that are installed.
*/
protected function _findThemes() {
$paths = App::path('shells');
$core = array_pop($paths);
$separator = DS === '/' ? '/' : '\\\\';
$core = preg_replace('#shells' . $separator . '$#', '', $core);
$paths[] = $core;
$Folder =& new Folder($core . 'templates' . DS . 'default');
$contents = $Folder->read();
$themeFolders = $contents[0];
$plugins = App::objects('plugin');
foreach ($plugins as $plugin) {
$paths[] = $this->_pluginPath($plugin) . 'console' . DS . 'shells' . DS;
$paths[] = $this->_pluginPath($plugin) . 'vendors' . DS . 'shells' . DS;
}
// TEMPORARY TODO remove when all paths are DS terminated
foreach ($paths as $i => $path) {
$paths[$i] = rtrim($path, DS) . DS;
}
$themes = array();
foreach ($paths as $path) {
$Folder =& new Folder($path . 'templates', false);
$contents = $Folder->read();
$subDirs = $contents[0];
foreach ($subDirs as $dir) {
if (empty($dir) || preg_match('@^skel$|_skel$@', $dir)) {
continue;
}
$Folder =& new Folder($path . 'templates' . DS . $dir);
$contents = $Folder->read();
$subDirs = $contents[0];
if (array_intersect($contents[0], $themeFolders)) {
$templateDir = $path . 'templates' . DS . $dir . DS;
$themes[$dir] = $templateDir;
}
}
}
return $themes;
}
/**
* Set variable values to the template scope
*
* @param mixed $one A string or an array of data.
* @param mixed $two Value in case $one is a string (which then works as the key).
* Unused if $one is an associative array, otherwise serves as the values to $one's keys.
* @return void
*/
public function set($one, $two = null) {
$data = null;
if (is_array($one)) {
if (is_array($two)) {
$data = array_combine($one, $two);
} else {
$data = $one;
}
} else {
$data = array($one => $two);
}
if ($data == null) {
return false;
}
$this->templateVars = $data + $this->templateVars;
}
/**
* Runs the template
*
* @param string $directory directory / type of thing you want
* @param string $filename template name
* @param string $vars Additional vars to set to template scope.
* @access public
* @return contents of generated code template
*/
public function generate($directory, $filename, $vars = null) {
if ($vars !== null) {
$this->set($vars);
}
if (empty($this->templatePaths)) {
$this->initialize();
}
$themePath = $this->getThemePath();
$templateFile = $this->_findTemplate($themePath, $directory, $filename);
if ($templateFile) {
extract($this->templateVars);
ob_start();
ob_implicit_flush(0);
include($templateFile);
$content = ob_get_clean();
return $content;
}
return '';
}
/**
* Find the theme name for the current operation.
* If there is only one theme in $templatePaths it will be used.
* If there is a -theme param in the cli args, it will be used.
* If there is more than one installed theme user interaction will happen
*
* @return string returns the path to the selected theme.
*/
public function getThemePath() {
if (count($this->templatePaths) == 1) {
$paths = array_values($this->templatePaths);
return $paths[0];
}
if (!empty($this->params['theme']) && isset($this->templatePaths[$this->params['theme']])) {
return $this->templatePaths[$this->params['theme']];
}
$this->hr();
$this->out(__('You have more than one set of templates installed.'));
$this->out(__('Please choose the template set you wish to use:'));
$this->hr();
$i = 1;
$indexedPaths = array();
foreach ($this->templatePaths as $key => $path) {
$this->out($i . '. ' . $key);
$indexedPaths[$i] = $path;
$i++;
}
$index = $this->in(__('Which bake theme would you like to use?'), range(1, $i - 1), 1);
$themeNames = array_keys($this->templatePaths);
$this->params['theme'] = $themeNames[$index - 1];
return $indexedPaths[$index];
}
/**
* Find a template inside a directory inside a path.
* Will scan all other theme dirs if the template is not found in the first directory.
*
* @param string $path The initial path to look for the file on. If it is not found fallbacks will be used.
* @param string $directory Subdirectory to look for ie. 'views', 'objects'
* @param string $filename lower_case_underscored filename you want.
* @access public
* @return string filename will exit program if template is not found.
*/
public function _findTemplate($path, $directory, $filename) {
$themeFile = $path . $directory . DS . $filename . '.ctp';
if (file_exists($themeFile)) {
return $themeFile;
}
foreach ($this->templatePaths as $path) {
$templatePath = $path . $directory . DS . $filename . '.ctp';
if (file_exists($templatePath)) {
return $templatePath;
}
}
$this->err(sprintf(__('Could not find template for %s'), $filename));
return false;
}
}