/**
  * Construct a Location object from action (either given as a string or an instance) 
  * and a set of parameters. You can omit the $action parameter (setting it to null)
  * if you want to create link to default action.
  * @param  mixed $action      either an instance of Action or action class name. If null, the location will point to the default action as specified in the <tt>action.default</tt> .config option.
  * @param  array $parameters  parameters that will be passed to the action
  */
 function __construct($action = null, $parameters = array(), $anchor = null) {
   if(is_null($this->action = ($action instanceof Action) ? get_class($action) : $action)) {
     $this->action = Package::getPackageByName('freeform')->getProperty('action.default');
   }
   $this->anchor = $anchor;
   $this->parameters = $parameters;
 }
 /**
  * As we have the same document preparation process in every demo action,
  * we difine this onInit method to take care of this
  */
 function onInit() {
   $this->document = new HTMLDocument($this->getResponce());
   $demos = FDRouterForm::getDemos();
   $this->document->setTemplate($this->getPackage()->getResourcePath('template.html'));
   $this->document->setVariable('main', get_class($this) . '.html');
   $this->document->setVariable('title', $this->getTitle());
   $this->document->setVariable('freddy', Package::getPackageByName('freddy'));
 }
 /**
  * This method is called by the launcher (index.php5)
  */
 static function processHTTP() {
   ob_start();
   
   $request = Request::parseHTTP();
   $responce = new Responce($request);
   
   $pkg = Package::getPackageByName('freeform');
     
   // Initialize session
   $sessionImpl = $pkg->getProperty('session.impl');
   $class = new ReflectionClass($sessionImpl);
   $method = $class->getMethod('load');
   Session::setHandler($method->invoke(null, $request));
   
   // See if we have the server cache hit here
   if(!$responce->getFromCache()) {
     // Initialize action
     $action = $request->getParameter('action', $da = $pkg->getProperty('action.default'));
     try {
       $class = new ReflectionClass($action);
       if(!$class->isSubclassOf('Action') || $class->isAbstract()) {
         throw new Exception('Can not execute action ' . $class->getName());
       }
     } catch(Exception $e) {
       $class = new ReflectionClass($pkg->getProperty('action.error', $da));
       if($class->isSubclassOf('Action') && !$class->isAbstract()) {
         $responce->relocate(new Location($class->getName()));
         $responce->setStatusCode(Response::STATUS_ERR_ACTION);
       } else {
         throw new ConfigurationException('freeform', 'action.error, action.default', 'do not denote a valid instantiable Action subclass');
       }
     }
     
     if(!$responce->isRelocation()) {
       // Initialize, secure and execute
       $action = $class->newInstance($request, $responce, true);
       Package::setEntryPackage(Package::getPackage($action));
       try {
         self::process($action);
       } catch(AccessDeniedException $ade) {
         $responce->setStatusCode(Responce::STATUS_ERR_ACCESS);
         $action->onAccessDenied();
       }
     }
   }
   
   // Send back the document
   foreach($responce->getHeaders() as $header) {
     header($header, false);
   }
   if($output = trim(ob_get_contents())) {
     error_log('Executed Action ' . $class->getName() . ' produced output: ' . $output);
   }
   ob_end_clean();
   echo $responce->getBody();
 }
 function process() {
   $d = new HTMLDocument($this->getResponce());
   $d->setTemplate($this->getPackage()->getResourcePath('WelcomeToFreeform.html'));
   if($p = Package::getPackageByName('freddy')) {
     $d->setVariable('freddy', new Location('Freddy'));
   }
   if($p = Package::getPackageByName('freeformdemo')) {
     $d->setVariable('demo', new Location('FDWelcome'));
   }
   $this->getResponce()->setDocument($d);
 }
 private static function getImpl() {
   if(is_null(self::$impl)) {
     $pkg = Package::getPackageByName('i18n');
     $implName = $pkg->getProperty('provider');
     try {
       $rc = new ReflectionClass($implName);
       self::$impl = $rc->newInstance();
     } catch(ReflectionException $re) {
       throw new ConfigurationException('i18n', 'provider', ($implName ? 'Cannot instantiate i18n provider ' . $$implName : 'i18n provider not set (provider option empty in i18n/.config)'));
     }
   }
   return self::$impl;
 }
 /**
  * Return an instance of the currently installed user management system
  * @return  UserManager  the currently installed user management system instance
  * @throws  ConfigurationException  if the 
  */
 static function getInstance() {
   if(!self::$instance) {
     $cn = Package::getPackageByName('freeform')->getProperty('userManager');
     try {
       $rc = new ReflectionClass($cn);
       if(!$rc->isSubclassOf('UserManager')) {
         throw new Exception();
       }
       self::$instance = $rc->newInstance();
     } catch(Exception $e) {  
       throw new ConfigurationException('freeform', 'userManager', 'not specified or denotes non-existing class');
     }
   }
   return self::$instance;
 }
 function process() {
   $this->success = false;
   if(($this->packageName = $this->getRequest()->getParameter('package')) && 
     ($this->fileName = $this->getRequest()->getParameter('name'))) {
     if($pkg = Package::getPackageByName($this->packageName)) {
       $filePath = $pkg->getResourcePath($this->fileName);
       if($this->body = file_get_contents($filePath)) {
         if($ii = getImageSize($filePath)) {
           $this->mimeType = $ii['mime'];
           if($etag = $this->getRequest()->getHeader('If-None-Match')) {
             $this->notModified = $etag == md5($this->body);
           }
           $this->success = true;
         }
       }
     }
   }
     
   $this->getResponce()->setDocument($this);
 }
  function onOpen() {
    $this->removeAll();
    $d = $this->getDocument();
    
    if(!($name = $this->getAttribute('name'))) {
      $name = $d->getVariable($this->getAttribute('key'));
    } else {
      if(!($pkg = $this->getAttribute('package'))) {
        // Try to find current package (where calling action defined)
        if(!($a = $d->getResponce()->getRequest()->getParameter('action'))) {
          $pkg = Package::getPackageByName('freeform');
          if($a = $pkg->getProperty('action.default')) {
            $pkg = Package::getPackageByName(Package::getPackageNameForClass($a));
          }
        } else {
          $pkg = Package::getPackageByName(Package::getPackageNameForClass($a));
	      }
      } else {
        echo $pkg;
        $pkg = Package::getPackageByName($pkg);
      }
      if($pkg) {
        $name = $pkg->getResourcePath($name);
      }
    }

    if($name) {
      $p = new HTMLParser($this->getDocument());
      $r = $p->parse($name);
      if($r) {
        $r->setExposed(false);
        $this->addNode($r);
        return self::PROCESS_BODY;
      } else {
        return self::SKIP_BODY;
      }
    }
    return self::SKIP_BODY;
  }
 /**
  * This method is overridden to possibly cache (serialize) the element tree if the caching
  * is enabled in the package configuration file.
  * @param  string $fileName  the absolute file name to parse
  * @return  SDElement  the root element of the tree, possibly retrieved from the cache
  * @throws  SDParserException  if something goes wrong
  */
 function parse($fileName) {
   $pkg = Package::getPackageByName('html');
   if($pkg->getProperty('cache.parserCache', false)) {
     $path = $pkg->getProperty('cache.parserCachePath', '/tmp');
     $cacheFile = $path . '/' . crc32($fileName) . '_' . baseName($fileName);
     if(file_exists($cacheFile) && filemtime($cacheFile) >= filemtime($fileName)) {
       $rv = unSerialize(file_get_contents($cacheFile));
       $rv->setDocument($this->doc);
       return $rv;
     } else {
       $rv = parent::parse($fileName);
       $rv->setDocument(null);
       flock($fp = fopen($fileName, 'r'), LOCK_EX);
       file_put_contents($cacheFile, serialize($rv));
       flock($fp, LOCK_UN);
       touch($cacheFile, filemtime($fileName));
       $rv->setDocument($this->doc);
       return $rv;
     }
   } else {
     return parent::parse($fileName);
   }
 }
 function onOpen() {
   if($this->key || $this->key = $this->removeAttribute('key')) {
     $this->setAttribute('src', htmlSpecialChars($this->getDocument()->getVariable($this->key)->toURL(), ENT_QUOTES, 'UTF-8'));
     return self::PROCESS_BODY;
   } elseif($this->name || $this->name = $this->removeAttribute('name')) {
     if($this->package || $this->package = $this->removeAttribute('package')) {
       $p = $this->package;
     } else {
       $p = Package::getPackageNameForClass(
         Package::getPackageByName('freeform')->getProperty('action.default'));
     }
     if($p) {
       $l = new Location('HTMLShowImage', array('package'=>$p, 'name'=>$this->name));
       $this->setAttribute('src', htmlSpecialChars($l->toURL(), ENT_QUOTES, 'UTF-8'));
       if($this->alt || $this->alt = !$this->getAttribute('alt')) {
         $this->setAttribute('alt', htmlSpecialChars($this->name, ENT_QUOTES, 'UTF-8'));
       }
       return self::PROCESS_BODY;
     } else {
       return self::SKIP_BODY;
     }
   }
   return self::SKIP_BODY;
 }
  /**
   * Create new request from HTTP parameters.
   * This method is used by ActionController to parse HTTP parameters to build initial Request
   * All instances of RequestAdaptor type will be queried and one that is
   * capable of processing content type of the request data will be instantiated.
   * Later the Request will query the Adaptor for parameters.
   *
   * <b>Note</b><br/>
   * This method is <i>always</i> called by the ActionController on every request.
   * @return  Request  request created from HTTP parameters (GET/POST/COOKIE and session referer)
   * @throws  ConfigurationException  if the config option <tt>locationRewriter</tt> specifies non-existent <class>LocationRewriter</class> 
   */
  static function parseHTTP() {
    // Create the URL
    $prot = split('/', $_SERVER['SERVER_PROTOCOL']);
    self::$URL = strtolower($prot[0]) . '://' . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['PHP_SELF'];
    
    // Fake HTTP headers from $_SERVER and $_ENV
    $headers = array();
    foreach($_SERVER as $k=>$v) {
      if(substr($k, 0, 5) == 'HTTP_') {
        $headers[str_replace('_', '-', substr($k, 5))] = $v;
      } else {
        if($k == 'CONTENT_TYPE' || $k == 'CONTENT_LENGTH') {
          $headers[str_replace('_', '-', $k)] = $v;
        }
      }
    }

    // Get request method 
    $method = strToUpper($_SERVER['REQUEST_METHOD']) == 'POST' ? self::METHOD_POST : self::METHOD_GET;
    
    // Find proper request adaptor for POST methods
    $parameters = array();
    if($method == Request::METHOD_POST) {
      $ctype = $headers['CONTENT-TYPE'];
      $rads = get_instances_of('RequestAdaptor');
      foreach($rads as $ra) {
        $rac = new ReflectionClass($ra);
        $m = $rac->getMethod('isSupportedContentType');
        if($m->invoke(null, $ctype)) {
          $requestAdaptor = $rac->newInstance();
          $parameters = $requestAdaptor->getParameters($headers);
          break;
        }
      }
    } else {     
      // Decode the possibly encoded query string with the LocationRewriter
      $pkg = Package::getPackageByName('freeform');
      if($lrc = $pkg->getProperty('locationRewriter')) {
        try {
          $lrrc = new ReflectionClass($lrc);
          $lrm = $lrrc->getMethod('decode');
          $parameters = $lrm->invoke(null, $_SERVER['QUERY_STRING']);
        } catch(ReflectionException $re) {
          throw new ConfigurationException('freeform', 'locationRewriter', 'denotes non-existent class ' . $lrc);
        }
      } else {
        $parameters = $_GET;
      }
      if(get_magic_quotes_gpc()) {
        array_walk_recursive($parameters, 'strip_slashes_gpc');
      }
    }
    
    if(get_magic_quotes_gpc()) {
      array_walk_recursive($_COOKIE, 'strip_slashes_gpc');
    }
    
    return new Request($parameters, $_COOKIE, $headers, $method);
  }