PageRenderTime 24ms CodeModel.GetById 47ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/controller/scaffold.php

https://github.com/balkin/kohana-scaffold
PHP | 374 lines | 312 code | 52 blank | 10 comment | 50 complexity | e25e94dcf15b56838424715f0e917286 MD5 | raw file
  1. <?php defined('SYSPATH') OR die('No direct access allowed.');
  2. class Controller_Scaffold extends Controller {
  3. protected $column = '';
  4. protected $auto_modeller = TRUE;
  5. protected $items_per_page = 15;
  6. protected $db_first = "";
  7. protected $header = Array();
  8. protected function _get_schema($force = FALSE) {
  9. $column = ImplodeUppercase::decode($this->column);
  10. if (empty($this->header) || $force) {
  11. $db = Database::instance()->list_columns($column);
  12. $this->header = Array();
  13. foreach ($db as $collum) {
  14. array_push($this->header, $collum["column_name"]);
  15. if (isset($collum["key"]) && $collum["key"] === "PRI") {
  16. $this->db_first = $collum["column_name"];
  17. }
  18. }
  19. }
  20. }
  21. public function before() {
  22. }
  23. public function flash($msg, $type = "success") {
  24. $last = Session::instance()->get("flash.message");
  25. $new = array(
  26. "msg" => $msg,
  27. "type" => $type
  28. );
  29. if ($last !== NULL) {
  30. $new = array_merge(array($new), $last);
  31. } else {
  32. $new = array($new);
  33. }
  34. Session::instance()->set("flash.message", $new);
  35. }
  36. protected function _auto_model($model = NULL) {
  37. $success = FALSE;
  38. if ($this->auto_modeller) {
  39. if ($model !== NULL) {
  40. $model_tmp = $this->column = $model;
  41. }
  42. $class_name = $this->generateClassName($this->column);
  43. if (strpos($class_name, '_')) {
  44. // We can't handle subdirectories yet
  45. $class_name = str_replace('_', '', $class_name);
  46. }
  47. $directory_name = "model" . DIRECTORY_SEPARATOR . "scaffold" . DIRECTORY_SEPARATOR;
  48. $path = APPPATH . 'classes' . DIRECTORY_SEPARATOR . $directory_name;
  49. $file = $path . $class_name . EXT;
  50. if (!file_exists($file)) {
  51. $db = Database::instance()->list_columns($this->column);
  52. $_primary_key = "";
  53. $_primary_val = "";
  54. $properties_phpdoc = array();
  55. $belongs_to = array();
  56. foreach ($db as $column) {
  57. if (($_primary_key !== "") && ($_primary_val === "") && $column["type"] === "string") {
  58. $_primary_val = $column["column_name"];
  59. }
  60. if ($column["key"] === "PRI") {
  61. $_primary_key = $column["column_name"];
  62. }
  63. if ($column['key'] === 'MUL') {
  64. if (substr($column['column_name'], -3) == '_id') {
  65. $referenced_class = substr($column['column_name'], 0, -3);
  66. $referenced_model = 'Model_Scaffold_' . ucfirst($referenced_class);
  67. $belongs_to[] = '\'' . $referenced_class . '\' => array(\'model\' => \'scaffold_'.$referenced_class.'\')';
  68. $properties_phpdoc[] = '@property ' . $referenced_model . ' $' . $referenced_class;
  69. }
  70. }
  71. $properties_phpdoc[] = '@property ' . $column['type'] . ' $' . $column["column_name"];
  72. }
  73. $properties_phpdoc_implode = implode("\n * ", $properties_phpdoc);
  74. $factory = "\tpublic static function factory(\$model=NULL,\$id=NULL) { return new Model_Scaffold_$class_name(\$id); }";
  75. $model_container = "<?php defined('SYSPATH') or die('No direct access allowed.');
  76. /**
  77. * $properties_phpdoc_implode
  78. */
  79. class Model_Scaffold_" . $class_name . " extends ORM
  80. {
  81. protected \$_db = 'default';
  82. protected \$_table_name = '" . str_replace('scaffold_', "", $this->column) . "';
  83. protected \$_primary_key = '$_primary_key';
  84. protected \$_primary_val = '$_primary_val';
  85. ";
  86. if (count($belongs_to)) {
  87. $model_container .= "\tprotected \$_belongs_to = array(" . implode($belongs_to, ', ') . ');' . PHP_EOL;
  88. }
  89. $model_container .= "
  90. protected \$_table_columns = array(\n";
  91. foreach ($db as $column) {
  92. $model_container .= "\t\t'" . $column["column_name"] . "' => array('data_type' => '" . $column["type"] . "', 'is_nullable' => " . (($column["is_nullable"])
  93. ? "TRUE" : "FALSE") . "),\n";
  94. }
  95. // TODO: BaRoN!: Add a few static factory methods :)
  96. $model_container .= "\t);\n\n$factory\n}";
  97. if (!is_dir($path)) {
  98. mkdir($path, 0777, TRUE);
  99. }
  100. file_put_contents($file, $model_container);
  101. $success = TRUE;
  102. }
  103. if (isset($model_tmp)) {
  104. $this->column = $model_tmp;
  105. }
  106. }
  107. return $success;
  108. }
  109. protected function generateClassName($column) {
  110. // TODO: BaRoN: make this configurable
  111. $class_name = Inflector::singular($column);
  112. $class_name = str_replace(" ", "", ucwords($class_name));
  113. return $class_name;
  114. }
  115. protected function auto_modeller() {
  116. $i = 0;
  117. $items = array();
  118. foreach (Database::instance()->list_tables() as $item) {
  119. $className = $this->generateClassName($item);
  120. $simpleName = 'Model_' . $className;
  121. if (class_exists($simpleName)) continue;
  122. // We can't deal with subdirectories yet, so…
  123. if ($this->_auto_model($item)) {
  124. $i++;
  125. }
  126. $items[] = $className;
  127. }
  128. $path = APPPATH . 'classes' . DIRECTORY_SEPARATOR . "model" . DIRECTORY_SEPARATOR . "scaffold" . DIRECTORY_SEPARATOR;
  129. $files = glob($path . "*.php");
  130. foreach ($files as $fname) {
  131. $what = str_replace(array($path, ".php"), "", $fname);
  132. if (!in_array($what, $items)) {
  133. unlink($fname);
  134. }
  135. }
  136. if ($i == 1) {
  137. $this->flash(__("One new model"));
  138. }
  139. elseif ($i > 0) {
  140. $this->flash(__(":num new models", array(':num' => $i)));
  141. }
  142. else {
  143. $this->flash(__("No new models found"), "notice");
  144. }
  145. $this->request->redirect("scaffold");
  146. }
  147. protected function remove_models() {
  148. $path = APPPATH . 'classes' . DIRECTORY_SEPARATOR . "model" . DIRECTORY_SEPARATOR . "scaffold" . DIRECTORY_SEPARATOR;
  149. $count = 0;
  150. foreach (glob($path . "*") as $fname) {
  151. unlink($fname);
  152. $count++;
  153. }
  154. if ($count === 0) {
  155. $this->flash(__("No models removed"), "notice");
  156. } else {
  157. $this->flash(__(":count models removed", array(':count'=>$count)), "notice");
  158. }
  159. $this->request->redirect("scaffold");
  160. }
  161. public function action_index() {
  162. $content = array();
  163. if (isset($_GET["auto_modeller"])) {
  164. if (empty($_GET["auto_modeller"])) {
  165. $this->auto_modeller();
  166. } else {
  167. $this->auto_modeller($_GET["auto_modeller"]);
  168. }
  169. }
  170. if (isset($_GET["remove_models"])) {
  171. if (empty($_GET["remove_models"])) {
  172. $this->remove_models();
  173. } else {
  174. $this->remove_models($_GET["remove_models"]);
  175. }
  176. }
  177. $subPath = (isset($_GET["dir"])) ? $_GET["dir"] : "";
  178. $path = APPPATH . 'classes' . DIRECTORY_SEPARATOR . "model" . DIRECTORY_SEPARATOR . "scaffold" . DIRECTORY_SEPARATOR . $subPath;
  179. if (!is_dir($path)) {
  180. mkdir($path, 0777, TRUE);
  181. }
  182. if ($handle = opendir($path)) {
  183. $files = Array();
  184. $directores = Array();
  185. while (FALSE !== ($file = readdir($handle))) {
  186. if (preg_match("/" . EXT . "/i", $file)) {
  187. array_push($files, str_replace(EXT, "", $file));
  188. } else if (!preg_match("/\./i", $file)) {
  189. array_push($directores, str_replace(EXT, "", $file));
  190. }
  191. }
  192. closedir($handle);
  193. foreach ($directores as $item) {
  194. $item_name = str_replace(Array($path, EXT), "", $item);
  195. // array_push( $content, HTML::anchor('scaffold?dir='.$item_name, "[+] " . ucfirst($item_name)) );
  196. // array_push( $content, "[+] " . ucfirst($item_name) );
  197. }
  198. foreach ($files as $item) {
  199. $item_name = str_replace(Array($path, EXT), "", $item);
  200. array_push($content, HTML::anchor('scaffold/list/' . $subPath . $item_name, ImplodeUppercase::ucwords_text($item_name)));
  201. }
  202. }
  203. if (empty($content)) {
  204. $content = __("No models to list");
  205. }
  206. $data = Array(
  207. "content" => $content,
  208. "msg" => (isset($_GET["msg"]) ? $_GET["msg"] : ""),
  209. "msgtype" => (isset($_GET["msgtype"]) ? $_GET["msgtype"] : "success")
  210. );
  211. echo View::factory("scaffold/index", $data)->render();
  212. }
  213. public function action_list($column = NULL) {
  214. $column = $this->request->param('column');
  215. if (empty($column)) {
  216. $this->request->redirect('scaffold');
  217. }
  218. $orm = ORM::factory(class_exists('Model_' . $column) ? $column : 'scaffold_' . $column);
  219. $this->column = $orm->table_name();
  220. $this->_get_schema();
  221. if ($this->column === "") {
  222. echo "<p>" . __("Please, select a column") . "</p>";
  223. exit;
  224. }
  225. $controller = url::site($this->request->controller());
  226. $this->items_per_page = (isset($_GET["items_per_page"])) ? $_GET["items_per_page"] : $this->items_per_page;
  227. $pagination = Pagination::factory(array(
  228. 'total_items' => $orm->count_all(),
  229. 'items_per_page' => $this->items_per_page
  230. ));
  231. $query = $orm
  232. ->limit($this->items_per_page)
  233. ->offset($pagination->offset)
  234. ->find_all();
  235. $result = Array();
  236. foreach ($query as $key) {
  237. $key = $key->as_array();
  238. $item = Array();
  239. foreach ($key as $value) {
  240. array_push($item, $value);
  241. }
  242. $id = $key[$this->db_first];
  243. array_push($item, "<a href=\"$controller/edit/" . $column . "/$id\">" . __("Edit") . "</a> | <a href=\"$controller/delete/" . $column . "/$id\" class=\"delete\">" . __("Delete") . "</a>");
  244. array_push($result, $item);
  245. }
  246. $data = Array(
  247. "column" => $column,
  248. "db_first" => $this->db_first,
  249. "header" => $this->header,
  250. "pagination" => $pagination->render(),
  251. "content" => $result,
  252. "msg" => (isset($_GET["msg"]) ? $_GET["msg"] : NULL),
  253. "msgtype" => (isset($_GET["msgtype"]) ? $_GET["msgtype"] : "success")
  254. );
  255. echo View::factory("scaffold/list", $data)->render();
  256. }
  257. public function action_insert($request = NULL) {
  258. if (is_null($request)) {
  259. $request = $this->request->param('column');
  260. }
  261. if ($request === "save") {
  262. $column = $_POST["column"];
  263. unset($_POST["column"]);
  264. $orm = ORM::factory(class_exists('Model_' . $column) ? $column : 'scaffold_' . $column)->values($_POST);
  265. if ($orm->check()) {
  266. $orm->save();
  267. $this->flash(__('Record added successfully!'));
  268. } else {
  269. $errors = $orm->validate()->errors();
  270. $this->flash($errors, "error");
  271. }
  272. $this->request->redirect("scaffold/list/" . $this->column . "/");
  273. } else {
  274. $column = $this->generateClassName($request);
  275. $orm = ORM::factory((class_exists('Model_' . $column) ? $column : 'scaffold_' . $column));
  276. $this->column = $orm->table_name();
  277. $this->_get_schema();
  278. $data = Array(
  279. "column" => $column,
  280. "header" => $this->header,
  281. "first" => $this->db_first
  282. );
  283. echo View::factory("scaffold/insert", $data)->render();
  284. }
  285. }
  286. public function action_edit() {
  287. $id = $this->request->param('id');
  288. $column = $this->request->param('column');
  289. $orm = ORM::factory((class_exists('Model_' . $column) ? $column : 'scaffold_' . $column), $id);
  290. $this->column = $orm->table_name();
  291. $this->_get_schema(TRUE);
  292. $data = Array(
  293. "column" => ucfirst($column),
  294. "request" => $id,
  295. "first" => $this->db_first,
  296. "content" => $orm->as_array()
  297. );
  298. echo View::factory("scaffold/edit", $data)->render();
  299. }
  300. public function action_save() {
  301. $column = $_POST["column"];
  302. unset($_POST["column"]);
  303. $id = array_shift($_POST);
  304. $orm = ORM::factory((class_exists('Model_' . $column) ? $column : 'scaffold_' . $column), $id)->values($_POST);
  305. if ($orm->check()) {
  306. $orm->save();
  307. $this->request->redirect('scaffold/list/' . $column . '/?msg=' . __('Record updated successfully') . '!');
  308. } else {
  309. $errors = $orm->validate()->errors();
  310. $this->request->redirect("scaffold/list/" . $column . "/?msg=$errors&msgtype=error");
  311. }
  312. }
  313. public function action_delete() {
  314. $column = $this->request->param('column');
  315. $id = $this->request->param('id');
  316. $orm = ORM::factory((class_exists('Model_' . $column) ? $column : 'scaffold_' . $column), $id)->delete();
  317. $this->column = $orm->table_name();
  318. $this->flash(__("Model :model with id :id successfully deleted", array(':model' => $column, ':id' => $id)), "error");
  319. $this->request->redirect("scaffold/list/" . $column);
  320. }
  321. }
  322. // end controller