1: <?php
2: /**
3: *
4: * @package XCube
5: * @version $Id: XCube_Controller.class.php,v 1.9 2008/10/12 04:30:27 minahito Exp $
6: * @copyright Copyright 2005-2007 XOOPS Cube Project <https://github.com/xoopscube/legacy>
7: * @license https://github.com/xoopscube/legacy/blob/master/docs/bsd_licenses.txt Modified BSD license
8: *
9: */
10:
11: if (!defined('XCUBE_CORE_PATH')) define('XCUBE_CORE_PATH', dirname(__FILE__));
12:
13: require_once XCUBE_CORE_PATH . '/XCube_Root.class.php';
14:
15: require_once XCUBE_CORE_PATH . '/XCube_ActionFilter.class.php';
16: require_once XCUBE_CORE_PATH . '/XCube_RenderSystem.class.php';
17: require_once XCUBE_CORE_PATH . '/XCube_Delegate.class.php';
18:
19: require_once XCUBE_CORE_PATH . '/XCube_Object.class.php';
20: require_once XCUBE_CORE_PATH . '/XCube_Service.class.php';
21:
22: require_once XCUBE_CORE_PATH . '/XCube_Identity.class.php';
23: require_once XCUBE_CORE_PATH . '/XCube_RoleManager.class.php';
24: require_once XCUBE_CORE_PATH . '/XCube_Permission.class.php';
25:
26: require_once XCUBE_CORE_PATH . '/XCube_LanguageManager.class.php';
27:
28: require_once XCUBE_CORE_PATH . '/XCube_ActionForm.class.php';
29: require_once XCUBE_CORE_PATH . '/XCube_TextFilter.class.php';
30: require_once XCUBE_CORE_PATH . '/XCube_Session.class.php';
31:
32: /**
33: * Virtual or Actual front controller class.
34: *
35: * This is an abstract class. And, a sub-class of this class has many
36: * impositions which sets up root object finally and implements many actual
37: * logic.
38: *
39: * executeXXXXX() functions are a public member function called by an accessed
40: * file. These member functions call other protected member functions.
41: *
42: * _setupXXXXX() functions are a protected member function overridden by a
43: * sub-class controller. Most of these functions are empty. A sub-class
44: * controller overrides them to set up a controller object and others.
45: *
46: * _createXXXXX() functions are a protected member function overridden by a
47: * sub-class controller. These member functions are called in prepare() to set
48: * up the root object. And, they have been exported from prepare() for a
49: * sub-class controller to override easily. Most of sub-class controllers
50: * doesn't need to override them, because typical code is there.
51: */
52: class XCube_Controller
53: {
54: /**
55: * The reference for the root object.
56: *
57: * @var XCube_Root
58: */
59: var $mRoot;
60:
61: /**
62: * Array of a procedure class object.
63: *
64: * @var Array
65: */
66: var $_mBlockChain = array();
67:
68:
69: /**
70: * Vector Array of XCube_ActionFilter class object.
71: * @protected
72: * @var Array
73: * @remarks
74: * typedef std:vector<XCube_ActionFilter*> FilterList; \n
75: * FilterList _mFilterChain; \n
76: */
77: var $_mFilterChain = array();
78:
79: /**
80: * This is Map-Array to keep names of action filter classes which are
81: * applied as filters.
82: *
83: * @protected
84: */
85: var $_mLoadedFilterNames = array();
86:
87: /**
88: * The database object which is abstract layer for the database.
89: *
90: * @var object
91: */
92: var $mDB;
93:
94: /**
95: * A name of the current local.
96: *
97: * @access public
98: * @var string
99: */
100: var $mLocale = null;
101:
102: /**
103: * A name of the current language.
104: *
105: * @access public
106: * @var string
107: */
108: var $mLanguage = null;
109:
110: /**
111: * Rebuilds the principal object for the current HTTP-request.
112: * void setupUser(XCube_AbstractPrincipal &, XCube_Controller &, XCube_HttpContext &);
113: *
114: * @var XCube_Delegate
115: */
116: var $mSetupUser = null;
117:
118: /**
119: * Executes the main logic of the controller.
120: * void execute(XCube_Controller &);
121: *
122: * @var XCube_Delegate
123: */
124: var $mExecute = null;
125:
126: /**
127: * Make a instance of TextFilter.
128: * void senupTextFilter(XCube_TextFilter &);
129: *
130: * @var XCube_Delegate
131: */
132: var $mSetupTextFilter = null;
133:
134: function XCube_Controller()
135: {
136: $this->_mBlockChain = array();
137: $this->_mFilterChain = array();
138: $this->_mLoadedFilterNames = array();
139:
140: $this->mSetupUser = new XCube_Delegate();
141: $this->mExecute = new XCube_Delegate();
142: $this->mSetupTextFilter = new XCube_Delegate();
143: $this->mSetupTextFilter->add('XCube_TextFilter::getInstance',XCUBE_DELEGATE_PRIORITY_FINAL);
144: }
145:
146: /**
147: * This member function is overridden. The sub-class implements the
148: * initialization process which sets up the root object finally.
149: *
150: * @param XCube_Root $root
151: */
152: function prepare(&$root)
153: {
154: $this->mRoot =& $root;
155:
156: $this->mRoot->setDelegateManager($this->_createDelegateManager());
157: $this->mRoot->setServiceManager($this->_createServiceManager());
158: $this->mRoot->setPermissionManager($this->_createPermissionManager());
159: $this->mRoot->setRoleManager($this->_createRoleManager());
160: $this->mRoot->setContext($this->_createContext());
161: }
162:
163: /**
164: * This member function is actual initialize process of web application.
165: * Some Nuke-like bases call this function at any timing.
166: *
167: * @access public
168: */
169: function executeCommon()
170: {
171: //
172: // Setup Filter chain and execute the process of these filters.
173: //
174: $this->_setupFilterChain();
175: $this->_processFilter();
176:
177: $this->_setupEnvironment();
178:
179: $this->_setupDB();
180:
181: $this->_setupLanguage();
182:
183: $this->_setupTextFilter();
184:
185: $this->_setupConfig();
186:
187: //
188: // Block section
189: //
190: $this->_processPreBlockFilter(); // What's !?
191:
192: $this->_setupSession();
193:
194: $this->_setupUser();
195: }
196:
197: /**
198: * Usually this member function is called after executeCommon(). But, some
199: * cases don't call this. Therefore, the page controller type base should
200: * not write the indispensable code here. For example, this is good to call
201: * blocks.
202: */
203: function executeHeader()
204: {
205: $this->_setupBlock();
206: $this->_processBlock();
207: }
208:
209: /**
210: * Executes the main logic.
211: *
212: * @access public
213: */
214: function execute()
215: {
216: $this->mExecute->call(new XCube_Ref($this));
217: }
218:
219: /**
220: * Executes the view logic. This member function is overridden.
221: *
222: * @access public
223: */
224: function executeView()
225: {
226: }
227:
228: /**
229: * TODO We may change this name to forward()
230: *
231: * @param string $url Can't use html tags.
232: * @param int $time
233: * @param string $message
234: */
235: function executeForward($url, $time = 0, $message = null)
236: {
237: // check header output
238: header("location: " . $url);
239: exit();
240: }
241:
242: /**
243: * Redirect to the specified URL with displaying message.
244: *
245: * @param string $url Can't use html tags.
246: * @param int $time
247: * @param string $message
248: */
249: function executeRedirect($url, $time = 1, $message = null)
250: {
251: $this->executeForward($url, $time, $message);
252: }
253:
254: /**
255: * Adds the ActionFilter instance.
256: * @param $filter XCube_ActionFilter
257: */
258: function addActionFilter(&$filter)
259: {
260: $this->_mFilterChain[] =& $filter;
261: }
262:
263: /**
264: * Create filter chain.
265: * @access protected
266: */
267: function _setupFilterChain()
268: {
269: }
270:
271: /**
272: * This member function is overridden. Sets up the controller and the
273: * environment.
274: */
275: function _setupEnvironment()
276: {
277: }
278:
279: /**
280: * Creates the instance of DataBase class, and sets it to member property.
281: *
282: * @access protected
283: */
284: function _setupDB()
285: {
286: }
287:
288: /**
289: * Gets the DB instance.
290: *
291: * @access public
292: */
293: function &getDB()
294: {
295: return $this->mDB;
296: }
297:
298: /**
299: * Creates the instance of Language Manager class, and sets it to member
300: * property.
301: *
302: * @access protected
303: */
304: function _setupLanguage()
305: {
306: $this->mRoot->mLanguageManager = new XCube_LanguageManager();
307: }
308:
309:
310: /**
311: * Creates the instance of Text Filter class, and sets it to member
312: * property.
313: *
314: * @access protected
315: */
316: function _setupTextFilter()
317: {
318: $textFilter = null;
319: $this->mSetupTextFilter->call(new XCube_Ref($textFilter));
320: $this->mRoot->setTextFilter($textFilter);
321: }
322:
323:
324: /**
325: * This member function is overridden. Loads site configuration informations,
326: * and sets them to the member property.
327: */
328: function _setupConfig()
329: {
330: }
331:
332: /**
333: * This member function is overridden. Sets up handler for session, then
334: * starts session.
335: *
336: * @access protected
337: * @return void
338: */
339: function _setupSession()
340: {
341: $this->mRoot->setSession(new XCube_Session());
342: }
343:
344: /**
345: * Sets up a principal object to the root object. In other words, restores
346: * the principal object from session or other.
347: */
348: function _setupUser()
349: {
350: $this->mSetupUser->call(new XCube_Ref($this->mRoot->mContext->mUser), new XCube_Ref($this), new XCube_Ref($this->mRoot->mContext));
351: }
352:
353: /**
354: * Calls the preFilter() member function of action filters which have been
355: * loaded to the list of the controller.
356: *
357: * @access protected
358: */
359: function _processFilter()
360: {
361: foreach (array_keys($this->_mFilterChain) as $key) {
362: $this->_mFilterChain[$key]->preFilter();
363: }
364: }
365:
366: /**
367: * FIXME.
368: */
369: function _setupBlock()
370: {
371: }
372:
373: /**
374: * FIXME.
375: */
376: function _processBlock()
377: {
378: /* foreach(array_keys($this->mBlockChain) as $key) {
379: if ($this->mBlockChain[$key]->hasPermission($this, $this->getUser())) {
380: $renderTarget =new XCube_RenderTarget();
381: $renderTarget->setType(XCUBE_RENDER_TARGET_TYPE_MAIN);
382:
383: $this->mBlockChain[$key]->execute($this, $this->getUser(), $renderTarget);
384:
385: $this->mBlockChain[$key]->mRenderTarget =& $renderTarget;
386:
387: unset($renderTarget);
388: }
389: }*/
390: }
391:
392: /**
393: * Calls the preBlockFilter() member function of action filters which have been
394: * loaded to the list of the controller.
395: *
396: * @access protected
397: */
398: function _processPreBlockFilter()
399: {
400: foreach (array_keys($this->_mFilterChain) as $key) {
401: $this->_mFilterChain[$key]->preBlockFilter();
402: }
403: }
404:
405: /**
406: * Calls the postFilter() member function of action filters which have been
407: * loaded to the list of the controller.
408: *
409: * @access protected
410: */
411: function _processPostFilter()
412: {
413: foreach (array_reverse(array_keys($this->_mFilterChain)) as $key) {
414: $this->_mFilterChain[$key]->postFilter();
415: }
416: }
417:
418: /**
419: * This is utility member function for the sub-class controller. Load files
420: * with the rule from $path, and add the instance of the sub-class to the
421: * chain.
422: *
423: * @access protected
424: * @param $path string Absolute path.
425: */
426: function _processPreload($path)
427: {
428: $path = $path . "/";
429:
430: if (is_dir($path)) {
431: foreach (glob($path.'/*.class.php') as $file) {
432: require_once $file;
433: $className = basename($file, '.class.php');
434: if (XC_CLASS_EXISTS($className) && !isset($this->_mLoadedFilterNames[$className])) {
435: $this->_mLoadedFilterNames[$className] = true;
436: $instance = new $className($this);
437: $this->addActionFilter($instance);
438: unset($instance);
439: }
440: }
441: }
442: }
443:
444: /**
445: * Creates an instance of the delegate manager and returns it.
446: *
447: * @return XCube_DelegateManager
448: */
449: function &_createDelegateManager()
450: {
451: $delegateManager = new XCube_DelegateManager();
452: return $delegateManager;
453: }
454:
455: /**
456: * Creates an instance of the service manager and returns it.
457: *
458: * @return XCube_ServiceManager
459: */
460: function &_createServiceManager()
461: {
462: require_once XCUBE_CORE_PATH . '/XCube_ServiceManager.class.php';
463: $serviceManager = new XCube_ServiceManager();
464: return $serviceManager;
465: }
466:
467: /**
468: * Creates an instance of the permission manager and returns it.
469: *
470: * @return XCube_PermissionManager
471: */
472: function &_createPermissionManager()
473: {
474: $chunkName = $this->mRoot->getSiteConfig('Cube', 'PermissionManager');
475:
476: //
477: // FIXME: Access private method.
478: //
479: $manager =& $this->mRoot->_createInstance($this->mRoot->getSiteConfig($chunkName, 'class'), $this->mRoot->getSiteConfig($chunkName, 'path'));
480:
481: return $manager;
482: }
483:
484: /**
485: * Creates an instance of the role manager and returns it.
486: *
487: * @return XCube_RoleManager
488: */
489: function &_createRoleManager()
490: {
491: $chunkName = $this->mRoot->getSiteConfig('Cube', 'RoleManager');
492:
493: //
494: // FIXME: Access private method.
495: //
496: $manager =& $this->mRoot->_createInstance($this->mRoot->getSiteConfig($chunkName, 'class'), $this->mRoot->getSiteConfig($chunkName, 'path'));
497:
498: return $manager;
499: }
500:
501: /**
502: * Creates the context object to initial the root object, and returns it.
503: *
504: * @return XCube_HttpContext
505: */
506: function &_createContext()
507: {
508: $context = new XCube_HttpContext();
509: $request = new XCube_HttpRequest();
510: $context->setRequest($request);
511:
512: return $context;
513: }
514: }
515:
516: ?>
517: