PageRenderTime 45ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/htdocs/solar/1.1.1/source/solar/Solar/Cli/MakeApp.php

http://github.com/pmjones/php-framework-benchmarks
PHP | 407 lines | 177 code | 47 blank | 183 comment | 27 complexity | 8f62ca2c6f10963d282fa33579f57ba8 MD5 | raw file
Possible License(s): LGPL-3.0, Apache-2.0, BSD-3-Clause, ISC, AGPL-3.0, LGPL-2.1
  1. <?php
  2. /**
  3. *
  4. * Solar command to make a page-controller app structure.
  5. *
  6. * @category Solar
  7. *
  8. * @package Solar_Cli
  9. *
  10. * @author Paul M. Jones <pmjones@solarphp.com>
  11. *
  12. * @license http://opensource.org/licenses/bsd-license.php BSD
  13. *
  14. * @version $Id: MakeApp.php 4436 2010-02-25 21:38:34Z pmjones $
  15. *
  16. */
  17. class Solar_Cli_MakeApp extends Solar_Controller_Command
  18. {
  19. /**
  20. *
  21. * Default configuration values.
  22. *
  23. * @config string extends The default page-controller class to extend.
  24. *
  25. * @config string extends_model The page-controller class to extend when
  26. * a model name is the basis for the app.
  27. *
  28. * @var array
  29. *
  30. */
  31. protected $_Solar_Cli_MakeApp = array(
  32. 'extends' => null,
  33. 'extends_model' => null,
  34. );
  35. /**
  36. *
  37. * The base directory where we will write the class file to, typically
  38. * the local PEAR directory.
  39. *
  40. * @var string
  41. *
  42. */
  43. protected $_target = null;
  44. /**
  45. *
  46. * The name of the app class.
  47. *
  48. * @var string
  49. *
  50. */
  51. protected $_class;
  52. /**
  53. *
  54. * The directory for the app class.
  55. *
  56. * @var string
  57. *
  58. */
  59. protected $_class_dir;
  60. /**
  61. *
  62. * The filename for the app class.
  63. *
  64. * @var string
  65. *
  66. */
  67. protected $_class_file;
  68. /**
  69. *
  70. * What base app to extend?
  71. *
  72. * @var string
  73. *
  74. */
  75. protected $_extends = null;
  76. /**
  77. *
  78. * The model name for the model class.
  79. *
  80. * @var string
  81. *
  82. */
  83. protected $_model_name = null;
  84. /**
  85. *
  86. * Array of class templates (skeletons).
  87. *
  88. * @var array
  89. *
  90. */
  91. protected $_tpl = array();
  92. /**
  93. *
  94. * Write out a series of files and dirs for a page-controller.
  95. *
  96. * @param string $class The target class name for the app.
  97. *
  98. * @return void
  99. *
  100. */
  101. protected function _exec($class = null)
  102. {
  103. // we need a class name, at least
  104. if (! $class) {
  105. throw $this->_exception('ERR_NO_CLASS');
  106. } else {
  107. $this->_class = $class;
  108. }
  109. $this->_outln('Making app.');
  110. // we need a target directory
  111. $this->_setTarget();
  112. // using a model?
  113. $this->_setModelName();
  114. // extending which class?
  115. $this->_setExtends($class);
  116. // load the templates
  117. $this->_loadTemplates();
  118. // the class file locations
  119. $this->_class_file = $this->_target
  120. . str_replace('_', DIRECTORY_SEPARATOR, $this->_class)
  121. . '.php';
  122. // the class dir location
  123. $this->_class_dir = Solar_Dir::fix(
  124. $this->_target . str_replace('_', '/', $this->_class)
  125. );
  126. // create the View, Locale, Helper, Layout dirs
  127. $this->_createDirs();
  128. // write the app class itself
  129. $this->_writeAppClass();
  130. // write Locale/en_US.php
  131. $this->_writeLocale();
  132. // write files in the View dir
  133. $this->_writeViews();
  134. // link public dir for app
  135. $link_public = Solar::factory('Solar_Cli_LinkPublic');
  136. $link_public->exec($class);
  137. // done!
  138. $this->_outln("Done.");
  139. }
  140. /**
  141. *
  142. * Writes the application class file itself.
  143. *
  144. * @return void
  145. *
  146. */
  147. protected function _writeAppClass()
  148. {
  149. // emit feedback
  150. $this->_outln("App class '{$this->_class}' extends '{$this->_extends}'.");
  151. $this->_outln("Preparing to write to '{$this->_target}'.");
  152. // using app, or app-model?
  153. if ($this->_model_name) {
  154. $tpl_key = 'app-model';
  155. } else {
  156. $tpl_key = 'app';
  157. }
  158. // get the app class template
  159. $text = $this->_parseTemplate($tpl_key);
  160. // write the app class
  161. if (file_exists($this->_class_file)) {
  162. $this->_outln('App class already exists.');
  163. } else {
  164. $this->_outln('Writing app class.');
  165. file_put_contents($this->_class_file, $text);
  166. }
  167. }
  168. /**
  169. *
  170. * Creates the application directories..
  171. *
  172. * @return void
  173. *
  174. */
  175. protected function _createDirs()
  176. {
  177. $dir = $this->_class_dir;
  178. if (! file_exists($dir)) {
  179. $this->_outln('Creating app directory.');
  180. mkdir($dir, 0755, true);
  181. } else {
  182. $this->_outln('App directory exists.');
  183. }
  184. $list = array('Layout', 'Locale', 'Public', 'View');
  185. foreach ($list as $sub) {
  186. if (! file_exists("$dir/$sub")) {
  187. $this->_outln("Creating app $sub directory.");
  188. mkdir("$dir/$sub", 0755, true);
  189. } else {
  190. $this->_outln("App $sub directory exists.");
  191. }
  192. }
  193. }
  194. /**
  195. *
  196. * Writes the en_US application locale file.
  197. *
  198. * @return void
  199. *
  200. */
  201. protected function _writeLocale()
  202. {
  203. $text = $this->_tpl['locale'];
  204. $file = $this->_class_dir . DIRECTORY_SEPARATOR . "/Locale/en_US.php";
  205. if (file_exists($file)) {
  206. $this->_outln('Locale file exists.');
  207. } else {
  208. $this->_outln('Writing locale file.');
  209. file_put_contents($file, $text);
  210. }
  211. }
  212. /**
  213. *
  214. * Writes the application view files.
  215. *
  216. * @return void
  217. *
  218. */
  219. protected function _writeViews()
  220. {
  221. if (! $this->_model_name) {
  222. $list = array('index');
  223. } else {
  224. $list = array();
  225. }
  226. foreach ($list as $view) {
  227. $text = $this->_parseTemplate("view-$view");
  228. $file = $this->_class_dir . "/View/$view.php";
  229. if (file_exists($file)) {
  230. $this->_outln("View '$view' exists.");
  231. } else {
  232. $this->_outln("Writing '$view' view.");
  233. file_put_contents($file, $text);
  234. }
  235. }
  236. }
  237. /**
  238. *
  239. * Parses a template and sets placeholder values.
  240. *
  241. * @param string $key The template array key.
  242. *
  243. * @return string The template with placeholder values set.
  244. *
  245. */
  246. protected function _parseTemplate($key)
  247. {
  248. $data = array(
  249. '{:class}' => $this->_class,
  250. '{:extends}' => $this->_extends,
  251. '{:model_name}' => $this->_model_name,
  252. );
  253. return str_replace(
  254. array_keys($data),
  255. array_values($data),
  256. $this->_tpl[$key]
  257. );
  258. }
  259. /**
  260. *
  261. * Loads the template array from skeleton files.
  262. *
  263. * @return void
  264. *
  265. */
  266. protected function _loadTemplates()
  267. {
  268. $this->_tpl = array();
  269. $dir = Solar_Class::dir($this, 'Data');
  270. $list = glob($dir . '*.php');
  271. foreach ($list as $file) {
  272. // strip .php off the end of the file name to get the key
  273. $key = substr(basename($file), 0, -4);
  274. // load the file template
  275. $this->_tpl[$key] = file_get_contents($file);
  276. // we need to add the php-open tag ourselves, instead of
  277. // having it in the template file, becuase the PEAR packager
  278. // complains about parsing the skeleton code.
  279. //
  280. // however, only do this on non-view files.
  281. if (substr($key, 0, 4) != 'view') {
  282. $this->_tpl[$key] = "<?php\n" . $this->_tpl[$key];
  283. }
  284. }
  285. }
  286. /**
  287. *
  288. * Sets the base directory target.
  289. *
  290. * @return void
  291. *
  292. */
  293. protected function _setTarget()
  294. {
  295. // use the solar system "include" directory.
  296. // that should automatically point to the right vendor for us.
  297. $target = Solar::$system . "/include";
  298. $this->_target = Solar_Dir::fix($target);
  299. }
  300. /**
  301. *
  302. * Sets the class this app will extend from.
  303. *
  304. * @param string $class The app class name.
  305. *
  306. * @return void
  307. *
  308. */
  309. protected function _setExtends($class)
  310. {
  311. // explicit as cli option?
  312. $extends = $this->_options['extends'];
  313. if ($extends) {
  314. $this->_extends = $extends;
  315. return;
  316. }
  317. // explicit as config value?
  318. if ($this->_model_name) {
  319. $extends = $this->_config['extends_model'];
  320. } else {
  321. $extends = $this->_config['extends'];
  322. }
  323. if ($extends) {
  324. $this->_extends = $extends;
  325. return;
  326. }
  327. // look at the vendor name and find a controller class
  328. $vendor = Solar_Class::vendor($class);
  329. if ($this->_model_name) {
  330. $name = "{$vendor}_Controller_Bread";
  331. $file = $this->_target . "$vendor/Controller/Bread.php";
  332. } else {
  333. $name = "{$vendor}_Controller_Page";
  334. $file = $this->_target . "$vendor/Controller/Page.php";
  335. }
  336. if (file_exists($file)) {
  337. $this->_extends = $name;
  338. return;
  339. }
  340. // final fallback: Solar_Controller_Page
  341. $this->_extends = 'Solar_Controller_Page';
  342. return;
  343. }
  344. /**
  345. *
  346. * Sets the model class and var name the app class will use.
  347. *
  348. * @return void
  349. *
  350. */
  351. protected function _setModelName()
  352. {
  353. $model_name = $this->_options['model_name'];
  354. if ($model_name) {
  355. $this->_model_name = $model_name;
  356. } else {
  357. $this->_model_name = null;
  358. }
  359. }
  360. }