root/trunk/patPortal.php

Revision 266 (checked in by schst, 3 years ago)

Added the concept of Access_Control objects,
check whether the page is accessible before serving it

  • Property 0 set to
  • Property 1 set to
Line 
1 <?PHP
2 /**
3  * patPortal
4  *
5  * $Id$
6  *
7  * An extendible framework to solve the
8  * web problem (and others as well)
9  *
10  * @author        Stephan Schmidt <schst@php-tools.net>
11  * @license        PHP License
12  * @package        patPortal
13  */
14
15 if (!defined( 'PATPORTAL_BASE_PATH' )) {
16     define( 'PATPORTAL_BASE_PATH', dirname( __FILE__ ) );
17 }
18
19 /**
20  * uses the factory
21  */
22 require_once PATPORTAL_BASE_PATH.'/patPortal/Factory.php';
23     
24 /**
25  * autoload function that loads classes on demand
26  *
27  * @param    string        name of the class
28  */
29 function __autoload($class)
30 {
31     patPortal_Factory::loadClass($class);
32 }
33
34 /**
35  * patPortal main class
36  *
37  * This is the controller
38  *
39  * @author        Stephan Schmidt <schst@php-tools.net>
40  * @license        PHP License
41  * @package        patPortal
42  */
43 class patPortal
44 {
45    /**
46     * store the instance
47     *
48     * @var object patPortal
49     */
50     private static $instance = null;
51
52    /**
53     * configuration object
54     *
55     * @var object patPortal_Configuration
56     */
57     private $config;
58     
59    /**
60     * error handler
61     *
62     * @var    object patPortal_ErrorHandler
63     */
64     private $errorHandler;
65
66    /**
67     * accesspoint of the portal
68     *
69     * @var  object patPortal_AccessPoint
70     */
71     private $accessPoint;
72
73    /**
74     * request
75     *
76     * @var  patPortal_Request
77     */
78     private $request;
79
80    /**
81     * response
82     *
83     * @var  patPortal_Response
84     */
85     private $response;
86
87    /**
88     * session
89     *
90     * @var  patPortal_Session
91     */
92     private $session;
93     
94    /**
95     * authentication
96     *
97     * @var  patPortal_Auth
98     */
99     private $auth = null;
100
101    /**
102     * event manager
103     *
104     * @var  patPortal_EventManager
105     */
106     private $eventManager;
107
108    /**
109     * The requested page
110     *
111     * @var  patPortal_Page
112     */
113     private $page;
114
115    /**
116     * create a new patPortal instance
117     *
118     * @param    string    path to configuration file
119     */
120     public static function create($configFile = null)
121     {
122         if (self::$instance === null) {
123             self::$instance = new patPortal( $configFile );
124         }
125         return self::$instance;
126     }
127
128    /**
129     * constructor
130     *
131     * @param    string    path to the main configuration file
132     */
133     private function __construct($configFile)
134     {
135         $this->config = patPortal_Configuration::singleton();
136         $this->config->setConfigFile( $configFile );
137         $this->errorHandler = new patPortal_ErrorHandler();
138         
139         // we'll convert patError objects to Exceptions
140         patErrorManager::setErrorHandling(E_ALL, 'callback', array( $this->errorHandler, 'handlePatError' ) );
141     }
142
143    /**
144     * provide the service
145     *
146     * This method accepts three parameters. You may specify
147     * a portal, an accesspoint and a debugging enviroment
148     *
149     * @param    string        portal id
150     * @param    string        access point
151     * @param    string        debugging environment
152     */
153     public function service( $portalId, $accessPoint, $environment )
154     {
155         try {
156             /**
157              * load config
158              */
159             $this->config->load( $portalId, $accessPoint, $environment );
160     
161             $this->buildEnvironment();
162     
163             $this->loadPlugins();
164             
165             /**
166              * insert cache here!
167              */
168             $this->render();
169
170             // insert HTML snippets created by the plugins
171             patPortal_PluginManager::insertOutput($this->request, $this->response);
172             
173             $this->response->send($this->request);
174             
175             $this->closeEnvironment();
176         } catch (Exception $e) {
177             
178             // This is used while patPortal is still in development
179             // more flexible error handling will be implemented later
180             echo '<b>Exception has been thrown, we need an error page.</b>';
181             echo '<pre>';
182             echo $e;
183             echo '</pre>';
184             exit();
185         }
186     }
187
188    /**
189     * build the environment
190     *
191     * @todo        check for errors
192     */
193     private function buildEnvironment()
194     {
195         $this->registerErrorHandling();
196
197         /**
198          * configure directories
199          */
200         patPortal_Factory::configureDirectories( $this->config->getDirectories() );
201
202         $this->registerEventListeners();
203
204         $this->config->getPersistence();
205         
206         $this->accessPoint = $this->config->getAccessPoint();
207         
208         $sitemap = $this->accessPoint->getSitemap();
209         $this->sitemap = patPortal_Sitemap::singleton( $sitemap['type'], $sitemap );
210
211         $this->request  = $this->accessPoint->getRequest($this->eventManager);
212
213         $this->response = $this->accessPoint->getResponse($this->eventManager);
214         
215         // access point uses session
216         if ($this->accessPoint->hasSession()) {
217             // name of the session
218             $sessionName = $this->accessPoint->getSessionName();
219             
220             // check, whether the request contained the ID
221             $id = $this->request->getSessionIdentifier($sessionName);
222             
223             // fetch the session object
224             $this->session = $this->accessPoint->getSession($this->eventManager, $id);
225             
226             // pass it to the request
227             $this->request->setSession($this->session);
228         }
229         
230         // accesspoint uses authentication
231         if ($this->accessPoint->hasAuth()) {
232             $this->auth = $this->accessPoint->getAuth($this->eventManager);
233             $this->request->setAuth($this->auth);
234         }
235
236         // fetch the properties of the request
237         $this->request->fetchProperties();
238         $this->request->applyUrlScheme();
239     }
240
241    /**
242     * register event listeners
243     *
244     * @return   boolean
245     */   
246     function registerEventListeners()
247     {
248         $this->eventManager = patPortal_EventManager::getInstance('Root', null, 'Portal');
249         patPortal_EventManager::registerEventListeners($this->config->getEvents(), $this);
250         return true;
251     }
252
253    /**
254     * register the error handling
255     *
256     * @return    boolean
257     */
258     private function registerErrorHandling()
259     {
260         foreach ($this->config->getErrorHandling() as $level => $handlers) {
261             foreach ($handlers as $handler => $options) {
262                 $this->errorHandler->registerHandler($level, $handler, $options);
263             }
264         }
265         return true;
266     }
267
268    /**
269     * load all registered plugins
270     *
271     * Plugins are defined in the XML file.
272     *
273     * @return boolean
274     */
275     private function loadPlugins()
276     {
277         $pluginSpecs = $this->config->getPlugins();
278         patPortal_PluginManager::registerPlugins($pluginSpecs);
279         
280         patPortal_PluginManager::processRequest($this->request, $this->response);
281         return true;
282     }
283     
284    /**
285     * close the environment
286     *
287     * Stores session data, etc.
288     */
289     private function closeEnvironment()
290     {
291         if (is_object($this->session)) {
292             $this->session->closeSession();
293         }
294     }
295
296    /**
297     * render the current page
298     *
299     * This will:
300     * - load and render all components
301     *
302     * @return    boolean
303     */
304     private function render()
305     {
306         $requestedPage = $this->request->getPath();
307         $this->callPage($requestedPage);
308
309         $this->page->prepare();
310
311         if ($this->request->hasFrame()) {
312             $this->config->selectFrame($this->request->getFrame());
313         } else {
314             $this->config->selectFrame($this->page->frame);
315         }
316
317         $this->page->buildAreas($this->config->getAreas());
318         
319         if ($this->request->cancelled()) {
320             return true;
321         }
322         $this->page->buildComponents();
323         
324         patPortal_Lifecycle::execute();
325         
326         $this->request->start();
327
328         patPortal_Lifecycle::render($this->page);
329
330         return true;
331     }
332     
333    /**
334     * open a page
335     *
336     * @param    string    path of the page
337     * @todo        find a clean way to set the path inside the request, maybe a distinction between requestedPath and served path
338     */
339     private function callPage( $path )
340     {
341         if (!$this->sitemap->pageExists($path)) {
342             $event = $this->eventManager->raiseEvent('PageNotFound', $path);
343             $path  = $event->getContext();
344             
345             if (!$event->isCancelled()) {
346                 patErrorManager::raiseNotice('NOCODE', 'The requested page '.$path.' does not exist');
347                 $path = $this->accessPoint->getIndex();
348             }
349         }
350         $this->request->setPath($path);
351         $this->page = $this->sitemap->loadPage($path);
352         if (!$this->page->isAccessible($this->request)) {
353             $event = $this->eventManager->raiseEvent('PageNotAccessible', $path);
354             $newPath = $event->getContext();
355             
356             if (!$event->isCancelled()) {
357                 patErrorManager::raiseNotice('NOCODE', 'The requested page '.$path.' may not be accessed');
358                 $path = $this->accessPoint->getIndex();
359                 $this->page = $this->sitemap->loadPage($path);
360             } else {
361                 if ($newPath !== $path) {
362                     $this->page = $this->sitemap->loadPage($newPath);
363                 }
364             }
365         }
366         $this->page->createEventManager($this->eventManager);
367     }
368     
369    /**
370     * return the event manager
371     *
372     * @return patPortal_EventManager
373     */
374     public function getEventManager()
375     {
376         return $this->eventManager;
377     }   
378 }
379 /**
380  * Exception class
381  *
382  * @author        Stephan Schmidt
383  * @package        patPortal
384  */
385 class patPortalException extends Exception {}
386 ?>
Note: See TracBrowser for help on using the browser.