[ Index ]
 

Code source de PRADO 3.0.6

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/framework/ -> TApplication.php (source)

   1  <?php
   2  /**
   3   * TApplication class file
   4   *
   5   * @author Qiang Xue <qiang.xue@gmail.com>
   6   * @link http://www.pradosoft.com/
   7   * @copyright Copyright &copy; 2005 PradoSoft
   8   * @license http://www.pradosoft.com/license/
   9   * @version $Id: TApplication.php 1559 2006-12-04 03:03:21Z xue $
  10   * @package System
  11   */
  12  
  13  /**
  14   * Includes core interfaces essential for TApplication class
  15   */
  16  require_once (PRADO_DIR.'/interfaces.php');
  17  
  18  /**
  19   * Includes core classes essential for TApplication class
  20   */
  21  require_once (PRADO_DIR.'/TApplicationComponent.php');
  22  require_once (PRADO_DIR.'/TModule.php');
  23  require_once (PRADO_DIR.'/TService.php');
  24  require_once (PRADO_DIR.'/Exceptions/TErrorHandler.php');
  25  require_once (PRADO_DIR.'/Caching/TCache.php');
  26  require_once (PRADO_DIR.'/IO/TTextWriter.php');
  27  require_once (PRADO_DIR.'/Collections/TList.php');
  28  require_once (PRADO_DIR.'/Collections/TMap.php');
  29  require_once (PRADO_DIR.'/Xml/TXmlDocument.php');
  30  require_once (PRADO_DIR.'/Security/TAuthorizationRule.php');
  31  require_once (PRADO_DIR.'/Security/TSecurityManager.php');
  32  require_once (PRADO_DIR.'/Web/THttpUtility.php');
  33  require_once (PRADO_DIR.'/Web/Javascripts/TJavaScript.php');
  34  require_once (PRADO_DIR.'/Web/THttpRequest.php');
  35  require_once (PRADO_DIR.'/Web/THttpResponse.php');
  36  require_once (PRADO_DIR.'/Web/THttpSession.php');
  37  require_once (PRADO_DIR.'/Web/Services/TPageService.php');
  38  require_once (PRADO_DIR.'/Web/TAssetManager.php');
  39  require_once (PRADO_DIR.'/I18N/TGlobalization.php');
  40  
  41  
  42  /**
  43   * TApplication class.
  44   *
  45   * TApplication coordinates modules and services, and serves as a configuration
  46   * context for all Prado components.
  47   *
  48   * TApplication uses a configuration file to specify the settings of
  49   * the application, the modules, the services, the parameters, and so on.
  50   *
  51   * TApplication adopts a modular structure. A TApplication instance is a composition
  52   * of multiple modules. A module is an instance of class implementing
  53   * {@link IModule} interface. Each module accomplishes certain functionalities
  54   * that are shared by all Prado components in an application.
  55   * There are default modules and user-defined modules. The latter offers extreme
  56   * flexibility of extending TApplication in a plug-and-play fashion.
  57   * Modules cooperate with each other to serve a user request by following
  58   * a sequence of lifecycles predefined in TApplication.
  59   *
  60   * TApplication has four modes that can be changed by setting {@link setMode Mode}
  61   * property (in the application configuration file).
  62   * - <b>Off</b> mode will prevent the application from serving user requests.
  63   * - <b>Debug</b> mode is mainly used during application development. It ensures
  64   *   the cache is always up-to-date if caching is enabled. It also allows
  65   *   exceptions are displayed with rich context information if they occur.
  66   * - <b>Normal</b> mode is mainly used during production stage. Exception information
  67   *   will only be recorded in system error logs. The cache is ensured to be
  68   *   up-to-date if it is enabled.
  69   * - <b>Performance</b> mode is similar to <b>Normal</b> mode except that it
  70   *   does not ensure the cache is up-to-date.
  71   *
  72   * TApplication dispatches each user request to a particular service which
  73   * finishes the actual work for the request with the aid from the application
  74   * modules.
  75   *
  76   * TApplication maintains a lifecycle with the following stages:
  77   * - [construct] : construction of the application instance
  78   * - [initApplication] : load application configuration and instantiate modules and the requested service
  79   * - onBeginRequest : this event happens right after application initialization
  80   * - onAuthentication : this event happens when authentication is needed for the current request
  81   * - onAuthenticationComplete : this event happens right after the authentication is done for the current request
  82   * - onAuthorization : this event happens when authorization is needed for the current request
  83   * - onAuthorizationComplete : this event happens right after the authorization is done for the current request
  84   * - onLoadState : this event happens when application state needs to be loaded
  85   * - onLoadStateComplete : this event happens right after the application state is loaded
  86   * - onPreRunService : this event happens right before the requested service is to run
  87   * - runService : the requested service runs
  88   * - onSaveState : this event happens when application needs to save its state
  89   * - onSaveStateComplete : this event happens right after the application saves its state
  90   * - onPreFlushOutput : this event happens right before the application flushes output to client side.
  91   * - flushOutput : the application flushes output to client side.
  92   * - onEndRequest : this is the last stage a request is being completed
  93   * - [destruct] : destruction of the application instance
  94   * Modules and services can attach their methods to one or several of the above
  95   * events and do appropriate processing when the events are raised. By this way,
  96   * the application is able to coordinate the activities of modules and services
  97   * in the above order. To terminate an application before the whole lifecycle
  98   * completes, call {@link completeRequest}.
  99   *
 100   * Examples:
 101   * - Create and run a Prado application:
 102   * <code>
 103   * $application=new TApplication($configFile);
 104   * $application->run();
 105   * </code>
 106   *
 107   * @author Qiang Xue <qiang.xue@gmail.com>
 108   * @version $Id: TApplication.php 1559 2006-12-04 03:03:21Z xue $
 109   * @package System
 110   * @since 3.0
 111   */
 112  class TApplication extends TComponent
 113  {
 114      /**
 115       * possible application mode.
 116       * @deprecated deprecated since version 3.0.4 (use TApplicationMode constants instead)
 117       */
 118      const STATE_OFF='Off';
 119      const STATE_DEBUG='Debug';
 120      const STATE_NORMAL='Normal';
 121      const STATE_PERFORMANCE='Performance';
 122  
 123      /**
 124       * Page service ID
 125       */
 126      const PAGE_SERVICE_ID='page';
 127      /**
 128       * Application configuration file name
 129       */
 130      const CONFIG_FILE='application.xml';
 131      /**
 132       * Runtime directory name
 133       */
 134      const RUNTIME_PATH='runtime';
 135      /**
 136       * Config cache file
 137       */
 138      const CONFIGCACHE_FILE='config.cache';
 139      /**
 140       * Global data file
 141       */
 142      const GLOBAL_FILE='global.cache';
 143  
 144      /**
 145       * @var array list of events that define application lifecycles
 146       */
 147      private static $_steps=array(
 148          'onBeginRequest',
 149          'onAuthentication',
 150          'onAuthenticationComplete',
 151          'onAuthorization',
 152          'onAuthorizationComplete',
 153          'onLoadState',
 154          'onLoadStateComplete',
 155          'onPreRunService',
 156          'runService',
 157          'onSaveState',
 158          'onSaveStateComplete',
 159          'onPreFlushOutput',
 160          'flushOutput'
 161      );
 162  
 163      /**
 164       * @var string application ID
 165       */
 166      private $_id;
 167      /**
 168       * @var string unique application ID
 169       */
 170      private $_uniqueID;
 171      /**
 172       * @var boolean whether the request is completed
 173       */
 174      private $_requestCompleted=false;
 175      /**
 176       * @var integer application state
 177       */
 178      private $_step;
 179      /**
 180       * @var IService current service instance
 181       */
 182      private $_service=null;
 183      /**
 184       * @var TPageService page service
 185       */
 186      private $_pageService=null;
 187      /**
 188       * @var array list of application modules
 189       */
 190      private $_modules;
 191      /**
 192       * @var TMap list of application parameters
 193       */
 194      private $_parameters;
 195      /**
 196       * @var string configuration file
 197       */
 198      private $_configFile;
 199      /**
 200       * @var string application base path
 201       */
 202      private $_basePath;
 203      /**
 204       * @var string directory storing application state
 205       */
 206      private $_runtimePath;
 207      /**
 208       * @var boolean if any global state is changed during the current request
 209       */
 210      private $_stateChanged=false;
 211      /**
 212       * @var array global variables (persistent across sessions, requests)
 213       */
 214      private $_globals=array();
 215      /**
 216       * @var string cache file
 217       */
 218      private $_cacheFile;
 219      /**
 220       * @var TErrorHandler error handler module
 221       */
 222      private $_errorHandler=null;
 223      /**
 224       * @var THttpRequest request module
 225       */
 226      private $_request=null;
 227      /**
 228       * @var THttpResponse response module
 229       */
 230      private $_response=null;
 231      /**
 232       * @var THttpSession session module, could be null
 233       */
 234      private $_session=null;
 235      /**
 236       * @var ICache cache module, could be null
 237       */
 238      private $_cache=null;
 239      /**
 240       * @var IStatePersister application state persister
 241       */
 242      private $_statePersister=null;
 243      /**
 244       * @var IUser user instance, could be null
 245       */
 246      private $_user=null;
 247      /**
 248       * @var TGlobalization module, could be null
 249       */
 250      private $_globalization=null;
 251      /**
 252       * @var TSecurityManager security manager module
 253       */
 254      private $_security=null;
 255      /**
 256       * @var TAssetManager asset manager module
 257       */
 258      private $_assetManager=null;
 259      /**
 260       * @var TAuthorizationRuleCollection collection of authorization rules
 261       */
 262      private $_authRules=null;
 263      /**
 264       * @var TApplicationMode application mode
 265       */
 266      private $_mode=TApplicationMode::Debug;
 267  
 268      /**
 269       * Constructor.
 270       * Sets application base path and initializes the application singleton.
 271       * Application base path refers to the root directory storing application
 272       * data and code not directly accessible by Web users.
 273       * By default, the base path is assumed to be the <b>protected</b>
 274       * directory under the directory containing the current running script.
 275       * @param string application base path or configuration file path.
 276       *        If the parameter is a file, it is assumed to be the application
 277       *        configuration file, and the directory containing the file is treated
 278       *        as the application base path.
 279       *        If it is a directory, it is assumed to be the application base path,
 280       *        and within that directory, a file named <b>application.xml</b>
 281       *        will be looked for. If found, the file is considered as the application
 282       *        configuration file.
 283       * @param boolean whether to cache application configuration. Defaults to true.
 284       * @throws TConfigurationException if configuration file cannot be read or the runtime path is invalid.
 285       */
 286  	public function __construct($basePath='protected',$cacheConfig=true)
 287      {
 288          // register application as a singleton
 289          Prado::setApplication($this);
 290  
 291          // determine configuration path and file
 292          if(($this->_basePath=realpath($basePath))===false)
 293              throw new TConfigurationException('application_basepath_invalid',$basePath);
 294          if(is_file($this->_basePath))
 295          {
 296              $this->_configFile=$this->_basePath;
 297              $this->_basePath=dirname($this->_basePath);
 298          }
 299          else if(is_file($this->_basePath.'/'.self::CONFIG_FILE))
 300              $this->_configFile=$this->_basePath.'/'.self::CONFIG_FILE;
 301          else
 302              $this->_configFile=null;
 303  
 304          // determine runtime path
 305          $this->_runtimePath=$this->_basePath.'/'.self::RUNTIME_PATH;
 306          if(is_writable($this->_runtimePath))
 307          {
 308              if($this->_configFile!==null)
 309              {
 310                  $subdir=basename($this->_configFile);
 311                  $this->_runtimePath.='/'.$subdir;
 312                  if(!is_dir($this->_runtimePath))
 313                  {
 314                      if(@mkdir($this->_runtimePath)===false)
 315                          throw new TConfigurationException('application_runtimepath_failed',$this->_runtimePath);
 316                      chmod($this->_runtimePath, 0777); //make it deletable
 317                  }
 318              }
 319          }
 320          else
 321              throw new TConfigurationException('application_runtimepath_invalid',$this->_runtimePath);
 322  
 323          $this->_cacheFile=$cacheConfig ? $this->_runtimePath.'/'.self::CONFIGCACHE_FILE : null;
 324  
 325          // generates unique ID by hashing the runtime path
 326          $this->_uniqueID=md5($this->_runtimePath);
 327      }
 328  
 329      /**
 330       * Executes the lifecycles of the application.
 331       * This is the main entry function that leads to the running of the whole
 332       * Prado application.
 333       */
 334  	public function run()
 335      {
 336          try
 337          {
 338              $this->initApplication();
 339              $n=count(self::$_steps);
 340              $this->_step=0;
 341              $this->_requestCompleted=false;
 342              while($this->_step<$n)
 343              {
 344                  if($this->_mode===self::STATE_OFF)
 345                      throw new THttpException(503,'application_service_unavailable');
 346                  if($this->_requestCompleted)
 347                      break;
 348                  $method=self::$_steps[$this->_step];
 349                  Prado::trace("Executing $method()",'System.TApplication');
 350                  $this->$method();
 351                  $this->_step++;
 352              }
 353          }
 354          catch(Exception $e)
 355          {
 356              $this->onError($e);
 357          }
 358          $this->onEndRequest();
 359      }
 360  
 361      /**
 362       * Completes current request processing.
 363       * This method can be used to exit the application lifecycles after finishing
 364       * the current cycle.
 365       */
 366  	public function completeRequest()
 367      {
 368          $this->_requestCompleted=true;
 369      }
 370  
 371      /**
 372       * @return boolean whether the current request is processed.
 373       */
 374  	public function getRequestCompleted()
 375      {
 376          return $this->_requestCompleted;
 377      }
 378  
 379      /**
 380       * Returns a global value.
 381       *
 382       * A global value is one that is persistent across users sessions and requests.
 383       * @param string the name of the value to be returned
 384       * @param mixed the default value. If $key is not found, $defaultValue will be returned
 385       * @return mixed the global value corresponding to $key
 386       */
 387  	public function getGlobalState($key,$defaultValue=null)
 388      {
 389          return isset($this->_globals[$key])?$this->_globals[$key]:$defaultValue;
 390      }
 391  
 392      /**
 393       * Sets a global value.
 394       *
 395       * A global value is one that is persistent across users sessions and requests.
 396       * Make sure that the value is serializable and unserializable.
 397       * @param string the name of the value to be set
 398       * @param mixed the global value to be set
 399       * @param mixed the default value. If $key is not found, $defaultValue will be returned
 400       */
 401  	public function setGlobalState($key,$value,$defaultValue=null)
 402      {
 403          $this->_stateChanged=true;
 404          if($value===$defaultValue)
 405              unset($this->_globals[$key]);
 406          else
 407              $this->_globals[$key]=$value;
 408      }
 409  
 410      /**
 411       * Clears a global value.
 412       *
 413       * The value cleared will no longer be available in this request and the following requests.
 414       * @param string the name of the value to be cleared
 415       */
 416  	public function clearGlobalState($key)
 417      {
 418          $this->_stateChanged=true;
 419          unset($this->_globals[$key]);
 420      }
 421  
 422      /**
 423       * Loads global values from persistent storage.
 424       * This method is invoked when {@link onLoadState OnLoadState} event is raised.
 425       * After this method, values that are stored in previous requests become
 426       * available to the current request via {@link getGlobalState}.
 427       */
 428  	protected function loadGlobals()
 429      {
 430          $this->_globals=$this->getApplicationStatePersister()->load();
 431      }
 432  
 433      /**
 434       * Saves global values into persistent storage.
 435       * This method is invoked when {@link onSaveState OnSaveState} event is raised.
 436       */
 437  	protected function saveGlobals()
 438      {
 439          if($this->_stateChanged)
 440          {
 441              $this->_stateChanged=false;
 442              $this->getApplicationStatePersister()->save($this->_globals);
 443          }
 444      }
 445  
 446      /**
 447       * @return string application ID
 448       */
 449  	public function getID()
 450      {
 451          return $this->_id;
 452      }
 453  
 454      /**
 455       * @param string application ID
 456       */
 457  	public function setID($value)
 458      {
 459          $this->_id=$value;
 460      }
 461  
 462      /**
 463       * @return string an ID that uniquely identifies this Prado application from the others
 464       */
 465  	public function getUniqueID()
 466      {
 467          return $this->_uniqueID;
 468      }
 469  
 470      /**
 471       * @return TApplicationMode application mode. Defaults to TApplicationMode::Debug.
 472       */
 473  	public function getMode()
 474      {
 475          return $this->_mode;
 476      }
 477  
 478      /**
 479       * @param TApplicationMode application mode
 480       */
 481  	public function setMode($value)
 482      {
 483          $this->_mode=TPropertyValue::ensureEnum($value,'TApplicationMode');
 484      }
 485  
 486      /**
 487       * @return string configuration path
 488       */
 489  	public function getBasePath()
 490      {
 491          return $this->_basePath;
 492      }
 493  
 494      /**
 495       * @return string configuration file path
 496       */
 497  	public function getConfigurationFile()
 498      {
 499          return $this->_configFile;
 500      }
 501  
 502      /**
 503       * Gets the directory storing application-level persistent data.
 504       * @return string application state path
 505       */
 506  	public function getRuntimePath()
 507      {
 508          return $this->_runtimePath;
 509      }
 510  
 511      /**
 512       * @return IService the currently requested service
 513       */
 514  	public function getService()
 515      {
 516          return $this->_service;
 517      }
 518  
 519      /**
 520       * Adds a module to application.
 521       * Note, this method does not do module initialization.
 522       * @param string ID of the module
 523       * @param IModule module object
 524       */
 525  	public function setModule($id,IModule $module)
 526      {
 527          if(isset($this->_modules[$id]))
 528              throw new TConfigurationException('application_moduleid_duplicated',$id);
 529          else
 530              $this->_modules[$id]=$module;
 531      }
 532  
 533      /**
 534       * @return IModule the module with the specified ID, null if not found
 535       */
 536  	public function getModule($id)
 537      {
 538          return isset($this->_modules[$id])?$this->_modules[$id]:null;
 539      }
 540  
 541      /**
 542       * @return array list of loaded application modules, indexed by module IDs
 543       */
 544  	public function getModules()
 545      {
 546          return $this->_modules;
 547      }
 548  
 549      /**
 550       * Returns the list of application parameters.
 551       * Since the parameters are returned as a {@link TMap} object, you may use
 552       * the returned result to access, add or remove individual parameters.
 553       * @return TMap the list of application parameters
 554       */
 555  	public function getParameters()
 556      {
 557          return $this->_parameters;
 558      }
 559  
 560      /**
 561       * @return TPageService page service
 562       */
 563  	public function getPageService()
 564      {
 565          if(!$this->_pageService)
 566          {
 567              $this->_pageService=new TPageService;
 568              $this->_pageService->init(null);
 569          }
 570          return $this->_pageService;
 571      }
 572  
 573      /**
 574       * Registers the page service instance.
 575       * This method should only be used by framework developers.
 576       * @param TPageService page service
 577       */
 578  	public function setPageService(TPageService $service)
 579      {
 580          $this->_pageService=$service;
 581      }
 582  
 583      /**
 584       * @return THttpRequest the request module
 585       */
 586  	public function getRequest()
 587      {
 588          if(!$this->_request)
 589          {
 590              $this->_request=new THttpRequest;
 591              $this->_request->init(null);
 592          }
 593          return $this->_request;
 594      }
 595  
 596      /**
 597       * @param THttpRequest the request module
 598       */
 599  	public function setRequest(THttpRequest $request)
 600      {
 601          $this->_request=$request;
 602      }
 603  
 604      /**
 605       * @return THttpResponse the response module
 606       */
 607  	public function getResponse()
 608      {
 609          if(!$this->_response)
 610          {
 611              $this->_response=new THttpResponse;
 612              $this->_response->init(null);
 613          }
 614          return $this->_response;
 615      }
 616  
 617      /**
 618       * @param THttpRequest the request module
 619       */
 620  	public function setResponse(THttpResponse $response)
 621      {
 622          $this->_response=$response;
 623      }
 624  
 625      /**
 626       * @return THttpSession the session module, null if session module is not installed
 627       */
 628  	public function getSession()
 629      {
 630          if(!$this->_session)
 631          {
 632              $this->_session=new THttpSession;
 633              $this->_session->init(null);
 634          }
 635          return $this->_session;
 636      }
 637  
 638      /**
 639       * @param THttpSession the session module
 640       */
 641  	public function setSession(THttpSession $session)
 642      {
 643          $this->_session=$session;
 644      }
 645  
 646      /**
 647       * @return TErrorHandler the error hanlder module
 648       */
 649  	public function getErrorHandler()
 650      {
 651          if(!$this->_errorHandler)
 652          {
 653              $this->_errorHandler=new TErrorHandler;
 654              $this->_errorHandler->init(null);
 655          }
 656          return $this->_errorHandler;
 657      }
 658  
 659      /**
 660       * @param TErrorHandler the error hanlder module
 661       */
 662  	public function setErrorHandler(TErrorHandler $handler)
 663      {
 664          $this->_errorHandler=$handler;
 665      }
 666  
 667      /**
 668       * @return TSecurityManager the security manager module
 669       */
 670  	public function getSecurityManager()
 671      {
 672          if(!$this->_security)
 673          {
 674              $this->_security=new TSecurityManager;
 675              $this->_security->init(null);
 676          }
 677          return $this->_security;
 678      }
 679  
 680      /**
 681       * @param TSecurityManager the security manager module
 682       */
 683  	public function setSecurityManager(TSecurityManager $sm)
 684      {
 685          $this->_security=$sm;
 686      }
 687  
 688      /**
 689       * @return TAssetManager asset manager
 690       */
 691  	public function getAssetManager()
 692      {
 693          if(!$this->_assetManager)
 694          {
 695              $this->_assetManager=new TAssetManager;
 696              $this->_assetManager->init(null);
 697          }
 698          return $this->_assetManager;
 699      }
 700  
 701      /**
 702       * @param TAssetManager asset manager
 703       */
 704  	public function setAssetManager(TAssetManager $value)
 705      {
 706          $this->_assetManager=$value;
 707      }
 708  
 709      /**
 710       * @return IStatePersister application state persister
 711       */
 712  	public function getApplicationStatePersister()
 713      {
 714          if(!$this->_statePersister)
 715          {
 716              $this->_statePersister=new TApplicationStatePersister;
 717              $this->_statePersister->init(null);
 718          }
 719          return $this->_statePersister;
 720      }
 721  
 722      /**
 723       * @param IStatePersister  application state persister
 724       */
 725  	public function setApplicationStatePersister(IStatePersister $persister)
 726      {
 727          $this->_statePersister=$persister;
 728      }
 729  
 730      /**
 731       * @return ICache the cache module, null if cache module is not installed
 732       */
 733  	public function getCache()
 734      {
 735          return $this->_cache;
 736      }
 737  
 738      /**
 739       * @param ICache the cache module
 740       */
 741  	public function setCache(ICache $cache)
 742      {
 743          $this->_cache=$cache;
 744      }
 745  
 746      /**
 747       * @return IUser the application user
 748       */
 749  	public function getUser()
 750      {
 751          return $this->_user;
 752      }
 753  
 754      /**
 755       * @param IUser the application user
 756       */
 757  	public function setUser(IUser $user)
 758      {
 759          $this->_user=$user;
 760      }
 761  
 762      /**
 763       * @param boolean whether to create globalization if it does not exist
 764       * @return TGlobalization globalization module
 765       */
 766  	public function getGlobalization($createIfNotExists=true)
 767      {
 768          if($this->_globalization===null && $createIfNotExists)
 769              $this->_globalization=new TGlobalization;
 770          return $this->_globalization;
 771      }
 772  
 773      /**
 774       * @param TGlobalization globalization module
 775       */
 776  	public function setGlobalization(TGlobalization $glob)
 777      {
 778          $this->_globalization=$glob;
 779      }
 780  
 781      /**
 782       * @return TAuthorizationRuleCollection list of authorization rules for the current request
 783       */
 784  	public function getAuthorizationRules()
 785      {
 786          if($this->_authRules===null)
 787              $this->_authRules=new TAuthorizationRuleCollection;
 788          return $this->_authRules;
 789      }
 790  
 791      /**
 792       * Loads configuration and initializes application.
 793       * Configuration file will be read and parsed (if a valid cached version exists,
 794       * it will be used instead). Then, modules are created and initialized;
 795       * Afterwards, the requested service is created and initialized.
 796       * @param string configuration file path (absolute or relative to current executing script)
 797       * @param string cache file path, empty if no present or needed
 798       * @throws TConfigurationException if module is redefined of invalid type, or service not defined or of invalid type
 799       */
 800  	protected function initApplication()
 801      {
 802          Prado::trace('Initializing application','System.TApplication');
 803  
 804          Prado::setPathOfAlias('Application',$this->_basePath);
 805  
 806          if($this->_configFile===null)
 807          {
 808              $request=$this->getRequest();
 809              $request->setAvailableServices(array(self::PAGE_SERVICE_ID));
 810              $request->resolveRequest();
 811              $this->_service=$this->getPageService();
 812              return;
 813          }
 814  
 815          if($this->_cacheFile===null || @filemtime($this->_cacheFile)<filemtime($this->_configFile))
 816          {
 817              $config=new TApplicationConfiguration;
 818              $config->loadFromFile($this->_configFile);
 819              if($this->_cacheFile!==null)
 820              {
 821                  if(($fp=fopen($this->_cacheFile,'wb'))!==false)
 822                  {
 823                      fputs($fp,Prado::serialize($config));
 824                      fclose($fp);
 825                  }
 826                  else
 827                      syslog(LOG_WARNING, 'Prado application config cache file "'.$this->_cacheFile.'" cannot be created.');
 828              }
 829          }
 830          else
 831          {
 832              $config=Prado::unserialize(file_get_contents($this->_cacheFile));
 833          }
 834  
 835          // set path aliases and using namespaces
 836          foreach($config->getAliases() as $alias=>$path)
 837              Prado::setPathOfAlias($alias,$path);
 838          foreach($config->getUsings() as $using)
 839              Prado::using($using);
 840  
 841          // set application properties
 842          foreach($config->getProperties() as $name=>$value)
 843              $this->setSubProperty($name,$value);
 844  
 845          // load parameters
 846          $this->_parameters=new TMap;
 847          foreach($config->getParameters() as $id=>$parameter)
 848          {
 849              if(is_array($parameter))
 850              {
 851                  $component=Prado::createComponent($parameter[0]);
 852                  foreach($parameter[1] as $name=>$value)
 853                      $component->setSubProperty($name,$value);
 854                  $this->_parameters->add($id,$component);
 855              }
 856              else
 857                  $this->_parameters->add($id,$parameter);
 858          }
 859  
 860          // load and init modules specified in app config
 861          $this->_modules=array();
 862          $modules=array();
 863          foreach($config->getModules() as $id=>$moduleConfig)
 864          {
 865              Prado::trace("Loading module $id ({$moduleConfig[0]})",'System.TApplication');
 866  
 867              $module=Prado::createComponent($moduleConfig[0]);
 868              if(is_string($id))
 869                  $this->setModule($id,$module);
 870              foreach($moduleConfig[1] as $name=>$value)
 871                  $module->setSubProperty($name,$value);
 872              $modules[]=array($module,$moduleConfig[2]);
 873          }
 874          foreach($modules as $module)
 875              $module[0]->init($module[1]);
 876  
 877          // load service
 878          $services=$config->getServices();
 879          $serviceIDs=array_keys($services);
 880          array_unshift($serviceIDs,self::PAGE_SERVICE_ID);
 881          $request=$this->getRequest();
 882          $request->setAvailableServices($serviceIDs);
 883  
 884          $request->resolveRequest();
 885  
 886          if(($serviceID=$request->getServiceID())===null)
 887              $serviceID=self::PAGE_SERVICE_ID;
 888          if(isset($services[$serviceID]))
 889          {
 890              $serviceConfig=$services[$serviceID];
 891              $service=Prado::createComponent($serviceConfig[0]);
 892              if(!($service instanceof IService))
 893                  throw new THttpException(500,'application_service_unknown',$serviceID);
 894              $this->_service=$service;
 895              foreach($serviceConfig[1] as $name=>$value)
 896                  $service->setSubProperty($name,$value);
 897              $service->init($serviceConfig[2]);
 898          }
 899          else
 900              $this->_service=$this->getPageService();
 901      }
 902  
 903      /**
 904       * Raises OnError event.
 905       * This method is invoked when an exception is raised during the lifecycles
 906       * of the application.
 907       * @param mixed event parameter
 908       */
 909  	public function onError($param)
 910      {
 911          Prado::log($param->getMessage(),TLogger::ERROR,'System.TApplication');
 912          $this->raiseEvent('OnError',$this,$param);
 913          $this->getErrorHandler()->handleError($this,$param);
 914      }
 915  
 916      /**
 917       * Raises OnBeginRequest event.
 918       * At the time when this method is invoked, application modules are loaded
 919       * and initialized, user request is resolved and the corresponding service
 920       * is loaded and initialized. The application is about to start processing
 921       * the user request.
 922       */
 923  	public function onBeginRequest()
 924      {
 925          $this->raiseEvent('OnBeginRequest',$this,null);
 926      }
 927  
 928      /**
 929       * Raises OnAuthentication event.
 930       * This method is invoked when the user request needs to be authenticated.
 931       */
 932  	public function onAuthentication()
 933      {
 934          $this->raiseEvent('OnAuthentication',$this,null);
 935      }
 936  
 937      /**
 938       * Raises OnAuthenticationComplete event.
 939       * This method is invoked right after the user request is authenticated.
 940       */
 941  	public function onAuthenticationComplete()
 942      {
 943          $this->raiseEvent('OnAuthenticationComplete',$this,null);
 944      }
 945  
 946      /**
 947       * Raises OnAuthorization event.
 948       * This method is invoked when the user request needs to be authorized.
 949       */
 950  	public function onAuthorization()
 951      {
 952          $this->raiseEvent('OnAuthorization',$this,null);
 953      }
 954  
 955      /**
 956       * Raises OnAuthorizationComplete event.
 957       * This method is invoked right after the user request is authorized.
 958       */
 959  	public function onAuthorizationComplete()
 960      {
 961          $this->raiseEvent('OnAuthorizationComplete',$this,null);
 962      }
 963  
 964      /**
 965       * Raises OnLoadState event.
 966       * This method is invoked when the application needs to load state (probably stored in session).
 967       */
 968  	public function onLoadState()
 969      {
 970          $this->loadGlobals();
 971          $this->raiseEvent('OnLoadState',$this,null);
 972      }
 973  
 974      /**
 975       * Raises OnLoadStateComplete event.
 976       * This method is invoked right after the application state has been loaded.
 977       */
 978  	public function onLoadStateComplete()
 979      {
 980          $this->raiseEvent('OnLoadStateComplete',$this,null);
 981      }
 982  
 983      /**
 984       * Raises OnPreRunService event.
 985       * This method is invoked right before the service is to be run.
 986       */
 987  	public function onPreRunService()
 988      {
 989          $this->raiseEvent('OnPreRunService',$this,null);
 990      }
 991  
 992      /**
 993       * Runs the requested service.
 994       */
 995  	public function runService()
 996      {
 997          if($this->_service)
 998              $this->_service->run();
 999      }
1000  
1001      /**
1002       * Raises OnSaveState event.
1003       * This method is invoked when the application needs to save state (probably stored in session).
1004       */
1005  	public function onSaveState()
1006      {
1007          $this->raiseEvent('OnSaveState',$this,null);
1008          $this->saveGlobals();
1009      }
1010  
1011      /**
1012       * Raises OnSaveStateComplete event.
1013       * This method is invoked right after the application state has been saved.
1014       */
1015  	public function onSaveStateComplete()
1016      {
1017          $this->raiseEvent('OnSaveStateComplete',$this,null);
1018      }
1019  
1020      /**
1021       * Raises OnPreFlushOutput event.
1022       * This method is invoked right before the application flushes output to client.
1023       */
1024  	public function onPreFlushOutput()
1025      {
1026          $this->raiseEvent('OnPreFlushOutput',$this,null);
1027      }
1028  
1029      /**
1030       * Flushes output to client side.
1031       */
1032  	public function flushOutput()
1033      {
1034          $this->getResponse()->flush();
1035      }
1036  
1037      /**
1038       * Raises OnEndRequest event.
1039       * This method is invoked when the application completes the processing of the request.
1040       */
1041  	public function onEndRequest()
1042      {
1043          $this->saveGlobals();  // save global state
1044          $this->raiseEvent('OnEndRequest',$this,null);
1045      }
1046  }
1047  
1048  /**
1049   * TApplicationMode class.
1050   * TApplicationMode defines the possible mode that an application can be set at by
1051   * setting {@link TApplication::setMode Mode}.
1052   * In particular, the following modes are defined
1053   * - Off: the application is not running. Any request to the application will obtain an error.
1054   * - Debug: the application is running in debug mode.
1055   * - Debug: the application is running in normal production mode.
1056   * - Performance: the application is running in performance mode.
1057   * @author Qiang Xue <qiang.xue@gmail.com>
1058   * @version $Id: TApplication.php 1559 2006-12-04 03:03:21Z xue $
1059   * @package System
1060   * @since 3.0.4
1061   */
1062  class TApplicationMode extends TEnumerable
1063  {
1064      const Off='Off';
1065      const Debug='Debug';
1066      const Normal='Normal';
1067      const Performance='Performance';
1068  }
1069  
1070  
1071  /**
1072   * TApplicationConfiguration class.
1073   *
1074   * This class is used internally by TApplication to parse and represent application configuration.
1075   *
1076   * @author Qiang Xue <qiang.xue@gmail.com>
1077   * @version $Id: TApplication.php 1559 2006-12-04 03:03:21Z xue $
1078   * @package System
1079   * @since 3.0
1080   */
1081  class TApplicationConfiguration extends TComponent
1082  {
1083      /**
1084       * @var array list of application initial property values, indexed by property names
1085       */
1086      private $_properties=array();
1087      /**
1088       * @var array list of namespaces to be used
1089       */
1090      private $_usings=array();
1091      /**
1092       * @var array list of path aliases, indexed by alias names
1093       */
1094      private $_aliases=array();
1095      /**
1096       * @var array list of module configurations
1097       */
1098      private $_modules=array();
1099      /**
1100       * @var array list of service configurations
1101       */
1102      private $_services=array();
1103      /**
1104       * @var array list of parameters
1105       */
1106      private $_parameters=array();
1107  
1108      /**
1109       * Parses the application configuration file.
1110       * @param string configuration file name
1111       * @throws TConfigurationException if there is any parsing error
1112       */
1113  	public function loadFromFile($fname)
1114      {
1115          $configPath=dirname($fname);
1116          $dom=new TXmlDocument;
1117          $dom->loadFromFile($fname);
1118  
1119          // application properties
1120          foreach($dom->getAttributes() as $name=>$value)
1121              $this->_properties[$name]=$value;
1122  
1123          // paths
1124          if(($pathsNode=$dom->getElementByTagName('paths'))!==null)
1125          {
1126              foreach($pathsNode->getElementsByTagName('alias') as $aliasNode)
1127              {
1128                  if(($id=$aliasNode->getAttribute('id'))!==null && ($path=$aliasNode->getAttribute('path'))!==null)
1129                  {
1130                      $path=str_replace('\\','/',$path);
1131                      if(preg_match('/^\\/|.:\\/|.:\\\\/',$path))    // if absolute path
1132                          $p=realpath($path);
1133                      else
1134                          $p=realpath($configPath.'/'.$path);
1135                      if($p===false || !is_dir($p))
1136                          throw new TConfigurationException('appconfig_aliaspath_invalid',$id,$path);
1137                      if(isset($this->_aliases[$id]))
1138                          throw new TConfigurationException('appconfig_alias_redefined',$id);
1139                      $this->_aliases[$id]=$p;
1140                  }
1141                  else
1142                      throw new TConfigurationException('appconfig_alias_invalid');
1143              }
1144              foreach($pathsNode->getElementsByTagName('using') as $usingNode)
1145              {
1146                  if(($namespace=$usingNode->getAttribute('namespace'))!==null)
1147                      $this->_usings[]=$namespace;
1148                  else
1149                      throw new TConfigurationException('appconfig_using_invalid');
1150              }
1151          }
1152  
1153          // application modules
1154          if(($modulesNode=$dom->getElementByTagName('modules'))!==null)
1155          {
1156              foreach($modulesNode->getElementsByTagName('module') as $node)
1157              {
1158                  $properties=$node->getAttributes();
1159                  $id=$properties->itemAt('id');
1160                  $type=$properties->remove('class');
1161                  if($type===null)
1162                      throw new TConfigurationException('appconfig_moduletype_required',$id);
1163                  $node->setParent(null);
1164                  if($id===null)
1165                      $this->_modules[]=array($type,$properties->toArray(),$node);
1166                  else
1167                      $this->_modules[$id]=array($type,$properties->toArray(),$node);
1168              }
1169          }
1170  
1171          // services
1172          if(($servicesNode=$dom->getElementByTagName('services'))!==null)
1173          {
1174              foreach($servicesNode->getElementsByTagName('service') as $node)
1175              {
1176                  $properties=$node->getAttributes();
1177                  if(($id=$properties->itemAt('id'))===null)
1178                      throw new TConfigurationException('appconfig_serviceid_required');
1179                  if(($type=$properties->remove('class'))===null)
1180                      throw new TConfigurationException('appconfig_servicetype_required',$id);
1181                  $node->setParent(null);
1182                  $this->_services[$id]=array($type,$properties->toArray(),$node);
1183              }
1184          }
1185  
1186          // parameters
1187          if(($parametersNode=$dom->getElementByTagName('parameters'))!==null)
1188          {
1189              foreach($parametersNode->getElementsByTagName('parameter') as $node)
1190              {
1191                  $properties=$node->getAttributes();
1192                  if(($id=$properties->remove('id'))===null)
1193                      throw new TConfigurationException('appconfig_parameterid_required');
1194                  if(($type=$properties->remove('class'))===null)
1195                  {
1196                      if(($value=$properties->remove('value'))===null)
1197                          $this->_parameters[$id]=$node;
1198                      else
1199                          $this->_parameters[$id]=$value;
1200                  }
1201                  else
1202                      $this->_parameters[$id]=array($type,$properties->toArray());
1203              }
1204          }
1205      }
1206  
1207      /**
1208       * @return array list of application initial property values, indexed by property names
1209       */
1210  	public function getProperties()
1211      {
1212          return $this->_properties;
1213      }
1214  
1215      /**
1216       * @return array list of path aliases, indexed by alias names
1217       */
1218  	public function getAliases()
1219      {
1220          return $this->_aliases;
1221      }
1222  
1223      /**
1224       * @return array list of namespaces to be used
1225       */
1226  	public function getUsings()
1227      {
1228          return $this->_usings;
1229      }
1230  
1231      /**
1232       * @return array list of module configurations
1233       */
1234  	public function getModules()
1235      {
1236          return $this->_modules;
1237      }
1238  
1239      /**
1240       * @return array list of service configurations
1241       */
1242  	public function getServices()
1243      {
1244          return $this->_services;
1245      }
1246  
1247      /**
1248       * @return array list of parameters
1249       */
1250  	public function getParameters()
1251      {
1252          return $this->_parameters;
1253      }
1254  }
1255  
1256  /**
1257   * TApplicationStatePersister class.
1258   * TApplicationStatePersister provides a file-based persistent storage
1259   * for application state. Application state, when serialized, is stored
1260   * in a file named 'global.cache' under the 'runtime' directory of the application.
1261   * Cache will be exploited if it is enabled.
1262   *
1263   * @author Qiang Xue <qiang.xue@gmail.com>
1264   * @version $Id: TApplication.php 1559 2006-12-04 03:03:21Z xue $
1265   * @package System
1266   * @since 3.0
1267   */
1268  class TApplicationStatePersister extends TModule implements IStatePersister
1269  {
1270      /**
1271       * Name of the value stored in cache
1272       */
1273      const CACHE_NAME='prado:appstate';
1274  
1275      /**
1276       * Initializes module.
1277       * @param TXmlElement module configuration (may be null)
1278       */
1279  	public function init($config)
1280      {
1281          $this->getApplication()->setApplicationStatePersister($this);
1282      }
1283  
1284      /**
1285       * @return string the file path storing the application state
1286       */
1287  	protected function getStateFilePath()
1288      {
1289          return $this->getApplication()->getRuntimePath().'/global.cache';
1290      }
1291  
1292      /**
1293       * Loads application state from persistent storage.
1294       * @return mixed application state
1295       */
1296  	public function load()
1297      {
1298          if(($cache=$this->getApplication()->getCache())!==null && ($value=$cache->get(self::CACHE_NAME))!==false)
1299              return unserialize($value);
1300          else
1301          {
1302              if(($content=@file_get_contents($this->getStateFilePath()))!==false)
1303                  return unserialize($content);
1304              else
1305                  return null;
1306          }
1307      }
1308  
1309      /**
1310       * Saves application state in persistent storage.
1311       * @param mixed application state
1312       */
1313  	public function save($state)
1314      {
1315          $content=serialize($state);
1316          $saveFile=true;
1317          if(($cache=$this->getApplication()->getCache())!==null)
1318          {
1319              if($cache->get(self::CACHE_NAME)===$content)
1320                  $saveFile=false;
1321              else
1322                  $cache->set(self::CACHE_NAME,$content);
1323          }
1324          if($saveFile)
1325          {
1326              $fileName=$this->getStateFilePath();
1327              file_put_contents($fileName,$content,LOCK_EX);
1328          }
1329      }
1330  
1331  }
1332  ?>


Généré le : Sun Feb 25 21:07:04 2007 par Balluche grâce à PHPXref 0.7