1: <?php
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: class Scaffold extends Object {
35:
36: 37: 38: 39: 40: 41:
42: var $controller = null;
43:
44: 45: 46: 47: 48: 49:
50: var $name = null;
51:
52: 53: 54: 55: 56: 57:
58: var $action = null;
59:
60: 61: 62: 63: 64: 65:
66: var $model = null;
67:
68: 69: 70: 71: 72: 73:
74: var $viewPath;
75:
76: 77: 78: 79: 80: 81:
82: var $base = null;
83:
84: 85: 86: 87: 88: 89:
90: var $layout = 'default';
91:
92: 93: 94: 95: 96: 97:
98: var $params;
99:
100: 101: 102: 103: 104: 105:
106: var $ext = '.ctp';
107:
108: 109: 110: 111: 112: 113:
114: var $subDir = null;
115:
116: 117: 118: 119: 120: 121:
122: var $plugin = null;
123:
124: 125: 126: 127: 128: 129:
130: var $_validSession = null;
131:
132: 133: 134: 135: 136: 137:
138: var $__passedVars = array(
139: 'action', 'base', 'webroot', 'layout', 'name',
140: 'viewPath', 'ext', 'params', 'data', 'plugin', 'cacheAction'
141: );
142:
143: 144: 145: 146: 147: 148:
149: var $scaffoldTitle = null;
150:
151: 152: 153: 154: 155: 156:
157: function __construct(&$controller, $params) {
158: $this->controller =& $controller;
159:
160: $count = count($this->__passedVars);
161: for ($j = 0; $j < $count; $j++) {
162: $var = $this->__passedVars[$j];
163: $this->{$var} = $controller->{$var};
164: }
165:
166: $this->redirect = array('action' => 'index');
167:
168: $this->modelClass = $controller->modelClass;
169: $this->modelKey = $controller->modelKey;
170:
171: if (!is_object($this->controller->{$this->modelClass})) {
172: return $this->cakeError('missingModel', array(array(
173: 'className' => $this->modelClass, 'webroot' => '', 'base' => $controller->base
174: )));
175: }
176:
177: $this->ScaffoldModel =& $this->controller->{$this->modelClass};
178: $this->scaffoldTitle = Inflector::humanize($this->viewPath);
179: $this->scaffoldActions = $controller->scaffold;
180: $title_for_layout = __('Scaffold :: ', true) . Inflector::humanize($this->action) . ' :: ' . $this->scaffoldTitle;
181: $modelClass = $this->controller->modelClass;
182: $primaryKey = $this->ScaffoldModel->primaryKey;
183: $displayField = $this->ScaffoldModel->displayField;
184: $singularVar = Inflector::variable($modelClass);
185: $pluralVar = Inflector::variable($this->controller->name);
186: $singularHumanName = Inflector::humanize(Inflector::underscore($modelClass));
187: $pluralHumanName = Inflector::humanize(Inflector::underscore($this->controller->name));
188: $scaffoldFields = array_keys($this->ScaffoldModel->schema());
189: $associations = $this->__associations();
190:
191: $this->controller->set(compact(
192: 'title_for_layout', 'modelClass', 'primaryKey', 'displayField', 'singularVar', 'pluralVar',
193: 'singularHumanName', 'pluralHumanName', 'scaffoldFields', 'associations'
194: ));
195:
196: if ($this->controller->view) {
197: $this->controller->view = 'Scaffold';
198: }
199: $this->_validSession = (
200: isset($this->controller->Session) && $this->controller->Session->valid() != false
201: );
202: $this->__scaffold($params);
203: }
204:
205: 206: 207: 208: 209: 210:
211: function _output() {
212: $this->controller->afterFilter();
213: echo($this->controller->output);
214: }
215:
216: 217: 218: 219: 220: 221: 222:
223: function __scaffoldView($params) {
224: if ($this->controller->_beforeScaffold('view')) {
225:
226: $message = sprintf(__("No id set for %s::view()", true), Inflector::humanize($this->modelKey));
227: if (isset($params['pass'][0])) {
228: $this->ScaffoldModel->id = $params['pass'][0];
229: } elseif ($this->_validSession) {
230: $this->controller->Session->setFlash($message);
231: $this->controller->redirect($this->redirect);
232: } else {
233: return $this->controller->flash($message, '/' . Inflector::underscore($this->controller->viewPath));
234: }
235: $this->ScaffoldModel->recursive = 1;
236: $this->controller->data = $this->ScaffoldModel->read();
237: $this->controller->set(
238: Inflector::variable($this->controller->modelClass), $this->controller->data
239: );
240: $this->controller->render($this->action, $this->layout);
241: $this->_output();
242: } elseif ($this->controller->_scaffoldError('view') === false) {
243: return $this->__scaffoldError();
244: }
245: }
246:
247: 248: 249: 250: 251: 252: 253:
254: function __scaffoldIndex($params) {
255: if ($this->controller->_beforeScaffold('index')) {
256: $this->ScaffoldModel->recursive = 0;
257: $this->controller->set(
258: Inflector::variable($this->controller->name), $this->controller->paginate()
259: );
260: $this->controller->render($this->action, $this->layout);
261: $this->_output();
262: } elseif ($this->controller->_scaffoldError('index') === false) {
263: return $this->__scaffoldError();
264: }
265: }
266:
267: 268: 269: 270: 271: 272: 273:
274: function __scaffoldForm($action = 'edit') {
275: $this->controller->viewVars['scaffoldFields'] = array_merge(
276: $this->controller->viewVars['scaffoldFields'],
277: array_keys($this->ScaffoldModel->hasAndBelongsToMany)
278: );
279: $this->controller->render($action, $this->layout);
280: $this->_output();
281: }
282:
283: 284: 285: 286: 287: 288: 289: 290:
291: function __scaffoldSave($params = array(), $action = 'edit') {
292: $formAction = 'edit';
293: $success = __('updated', true);
294: if ($action === 'add') {
295: $formAction = 'add';
296: $success = __('saved', true);
297: }
298:
299: if ($this->controller->_beforeScaffold($action)) {
300: if ($action == 'edit') {
301: if (isset($params['pass'][0])) {
302: $this->ScaffoldModel->id = $params['pass'][0];
303: }
304:
305: if (!$this->ScaffoldModel->exists()) {
306: $message = sprintf(__("Invalid id for %s::edit()", true), Inflector::humanize($this->modelKey));
307: if ($this->_validSession) {
308: $this->controller->Session->setFlash($message);
309: $this->controller->redirect($this->redirect);
310: } else {
311: $this->controller->flash($message, $this->redirect);
312: $this->_output();
313: }
314: }
315: }
316:
317: if (!empty($this->controller->data)) {
318: if ($action == 'create') {
319: $this->ScaffoldModel->create();
320: }
321:
322: if ($this->ScaffoldModel->save($this->controller->data)) {
323: if ($this->controller->_afterScaffoldSave($action)) {
324: $message = sprintf(
325: __('The %1$s has been %2$s', true),
326: Inflector::humanize($this->modelKey),
327: $success
328: );
329: if ($this->_validSession) {
330: $this->controller->Session->setFlash($message);
331: $this->controller->redirect($this->redirect);
332: } else {
333: $this->controller->flash($message, $this->redirect);
334: return $this->_output();
335: }
336: } else {
337: return $this->controller->_afterScaffoldSaveError($action);
338: }
339: } else {
340: if ($this->_validSession) {
341: $this->controller->Session->setFlash(__('Please correct errors below.', true));
342: }
343: }
344: }
345:
346: if (empty($this->controller->data)) {
347: if ($this->ScaffoldModel->id) {
348: $this->controller->data = $this->ScaffoldModel->read();
349: } else {
350: $this->controller->data = $this->ScaffoldModel->create();
351: }
352: }
353:
354: foreach ($this->ScaffoldModel->belongsTo as $assocName => $assocData) {
355: $varName = Inflector::variable(Inflector::pluralize(
356: preg_replace('/(?:_id)$/', '', $assocData['foreignKey'])
357: ));
358: $this->controller->set($varName, $this->ScaffoldModel->{$assocName}->find('list'));
359: }
360: foreach ($this->ScaffoldModel->hasAndBelongsToMany as $assocName => $assocData) {
361: $varName = Inflector::variable(Inflector::pluralize($assocName));
362: $this->controller->set($varName, $this->ScaffoldModel->{$assocName}->find('list'));
363: }
364:
365: return $this->__scaffoldForm($formAction);
366: } elseif ($this->controller->_scaffoldError($action) === false) {
367: return $this->__scaffoldError();
368: }
369: }
370:
371: 372: 373: 374: 375: 376: 377:
378: function __scaffoldDelete($params = array()) {
379: if ($this->controller->_beforeScaffold('delete')) {
380: $message = sprintf(
381: __("No id set for %s::delete()", true),
382: Inflector::humanize($this->modelKey)
383: );
384: if (isset($params['pass'][0])) {
385: $id = $params['pass'][0];
386: } elseif ($this->_validSession) {
387: $this->controller->Session->setFlash($message);
388: $this->controller->redirect($this->redirect);
389: } else {
390: $this->controller->flash($message, $this->redirect);
391: return $this->_output();
392: }
393:
394: if ($this->ScaffoldModel->delete($id)) {
395: $message = sprintf(
396: __('The %1$s with id: %2$d has been deleted.', true),
397: Inflector::humanize($this->modelClass), $id
398: );
399: if ($this->_validSession) {
400: $this->controller->Session->setFlash($message);
401: $this->controller->redirect($this->redirect);
402: } else {
403: $this->controller->flash($message, $this->redirect);
404: return $this->_output();
405: }
406: } else {
407: $message = sprintf(
408: __('There was an error deleting the %1$s with id: %2$d', true),
409: Inflector::humanize($this->modelClass), $id
410: );
411: if ($this->_validSession) {
412: $this->controller->Session->setFlash($message);
413: $this->controller->redirect($this->redirect);
414: } else {
415: $this->controller->flash($message, $this->redirect);
416: return $this->_output();
417: }
418: }
419: } elseif ($this->controller->_scaffoldError('delete') === false) {
420: return $this->__scaffoldError();
421: }
422: }
423:
424: 425: 426: 427: 428: 429:
430: function __scaffoldError() {
431: return $this->controller->render('error', $this->layout);
432: $this->_output();
433: }
434:
435: 436: 437: 438: 439: 440: 441: 442: 443:
444: function __scaffold($params) {
445: $db = &ConnectionManager::getDataSource($this->ScaffoldModel->useDbConfig);
446: $prefixes = Configure::read('Routing.prefixes');
447: $scaffoldPrefix = $this->scaffoldActions;
448:
449: if (isset($db)) {
450: if (empty($this->scaffoldActions)) {
451: $this->scaffoldActions = array(
452: 'index', 'list', 'view', 'add', 'create', 'edit', 'update', 'delete'
453: );
454: } elseif (!empty($prefixes) && in_array($scaffoldPrefix, $prefixes)) {
455: $this->scaffoldActions = array(
456: $scaffoldPrefix . '_index',
457: $scaffoldPrefix . '_list',
458: $scaffoldPrefix . '_view',
459: $scaffoldPrefix . '_add',
460: $scaffoldPrefix . '_create',
461: $scaffoldPrefix . '_edit',
462: $scaffoldPrefix . '_update',
463: $scaffoldPrefix . '_delete'
464: );
465: }
466:
467: if (in_array($params['action'], $this->scaffoldActions)) {
468: if (!empty($prefixes)) {
469: $params['action'] = str_replace($scaffoldPrefix . '_', '', $params['action']);
470: }
471: switch ($params['action']) {
472: case 'index':
473: case 'list':
474: $this->__scaffoldIndex($params);
475: break;
476: case 'view':
477: $this->__scaffoldView($params);
478: break;
479: case 'add':
480: case 'create':
481: $this->__scaffoldSave($params, 'add');
482: break;
483: case 'edit':
484: case 'update':
485: $this->__scaffoldSave($params, 'edit');
486: break;
487: case 'delete':
488: $this->__scaffoldDelete($params);
489: break;
490: }
491: } else {
492: return $this->cakeError('missingAction', array(array(
493: 'className' => $this->controller->name . "Controller",
494: 'base' => $this->controller->base,
495: 'action' => $this->action,
496: 'webroot' => $this->controller->webroot
497: )));
498: }
499: } else {
500: return $this->cakeError('missingDatabase', array(array(
501: 'webroot' => $this->controller->webroot
502: )));
503: }
504: }
505:
506: 507: 508: 509: 510: 511:
512: function __associations() {
513: $keys = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
514: $associations = array();
515:
516: foreach ($keys as $key => $type) {
517: foreach ($this->ScaffoldModel->{$type} as $assocKey => $assocData) {
518: $associations[$type][$assocKey]['primaryKey'] =
519: $this->ScaffoldModel->{$assocKey}->primaryKey;
520:
521: $associations[$type][$assocKey]['displayField'] =
522: $this->ScaffoldModel->{$assocKey}->displayField;
523:
524: $associations[$type][$assocKey]['foreignKey'] =
525: $assocData['foreignKey'];
526:
527: $associations[$type][$assocKey]['controller'] =
528: Inflector::pluralize(Inflector::underscore($assocData['className']));
529:
530: if ($type == 'hasAndBelongsToMany') {
531: $associations[$type][$assocKey]['with'] = $assocData['with'];
532: }
533: }
534: }
535: return $associations;
536: }
537: }
538:
539: 540: 541: 542: 543: 544:
545: if (!class_exists('ThemeView')) {
546: App::import('View', 'Theme');
547: }
548:
549: 550: 551: 552: 553: 554:
555: class ScaffoldView extends ThemeView {
556:
557: 558: 559: 560: 561: 562: 563:
564: function _getViewFileName($name = null) {
565: if ($name === null) {
566: $name = $this->action;
567: }
568: $name = Inflector::underscore($name);
569: $prefixes = Configure::read('Routing.prefixes');
570:
571: if (!empty($prefixes)) {
572: foreach ($prefixes as $prefix) {
573: if (strpos($name, $prefix . '_') !== false) {
574: $name = substr($name, strlen($prefix) + 1);
575: break;
576: }
577: }
578: }
579:
580: if ($name === 'add') {
581: $name = 'edit';
582: }
583:
584: $scaffoldAction = 'scaffold.' . $name;
585:
586: if (!is_null($this->subDir)) {
587: $subDir = strtolower($this->subDir) . DS;
588: } else {
589: $subDir = null;
590: }
591:
592: $names[] = $this->viewPath . DS . $subDir . $scaffoldAction;
593: $names[] = 'scaffolds' . DS . $subDir . $name;
594:
595: $paths = $this->_paths($this->plugin);
596: $exts = array($this->ext);
597: if ($this->ext !== '.ctp') {
598: array_push($exts, '.ctp');
599: }
600: foreach ($exts as $ext) {
601: foreach ($paths as $path) {
602: foreach ($names as $name) {
603: if (file_exists($path . $name . $ext)) {
604: return $path . $name . $ext;
605: }
606: }
607: }
608: }
609:
610: if ($name === 'scaffolds' . DS . $subDir . 'error') {
611: return LIBS . 'view' . DS . 'errors' . DS . 'scaffold_error.ctp';
612: }
613:
614: return $this->_missingView($paths[0] . $name . $this->ext, 'missingView');
615: }
616: }
617: