<?php

class TempTimer
{
  static $start;
  
  static function measure($position, $exit = false)
  {
    if (isSet($_GET["displaytimer"]))
    {
      //bench
      //echo $position.": ".(microtime(true)-self::$start)."ms<br />";
      
      $current = microtime(true);
      $time = ($current-self::$start)*1000;
      
      if ($time > 50)
      {
        $color = "#ffcfcf";
      }
      else if ($time > 40)
      {
        $color = "#fde0e0";
      }
      else if ($time > 20)
      {
        $color = "#ffe8d1";
      }
      else if ($time > 10)
      {
        $color = "#fff7e6";
      }
      else if ($time > 5)
      {
        $color = "#faffe6";
      }
      else if ($time > 1)
      {
        $color = "#e6ffe6";
      }
      else
      {
        $color = "white";
      }
      
      echo '<div style="position: relative; background-color: '.$color.'; padding:5px; font-size: 12px; font-family: Arial;">'.$position.": ".sprintf('%f',$time).' ms';
      
      $width = (round($time)*4);
      if ($width > 0)
      {
        echo '<div style="position: absolute; top: 8px; right: 0px; height: 15px; width: '.$width.'px; background-color: #16b3f9; max-width: 80%;"></div>';
      }
      echo '</div>';
      
      self::$start = $current;
      
      if ($exit)
      {
        exit();
      }
    }
  }
}
TempTimer::$start = microtime(true);


//error handling settings
ignore_user_abort(true);
error_reporting(E_ALL);
ini_set("display_errors", "0");
ini_set("log_errors", "1");
ini_set("error_log", "../errors.txt");
ini_set("zlib.output_compression", "On");

class FrameworkSettings
{
  static $linux_user;
  static $domain;
  static $public_folder;
  static $root_folder;
  static $framework_folder;
  static $framework_folder_dev;
  static $project_name;
  static $maintenance_mode;
  static $development_mode;
  static $developer_ips;
  static $log_global_events;
  static $allow_search_engine_index;
  static $translation_enabled;
  static $php_bin;
  static $php_lib;
  static $ssl;
  static $cache_enabled;
  static $cache_prefix;
  static $propel_version;
  static $class_file_locations;
  static $image_type_tables;
  static $seed;
  static $cli;

  static function packageInstalled($package, $version = null)
  {
    //TODO: verder implementeren
    if ($package == "webshop")
    {
      return class_exists("WebshopCartItems");
    }
    return false;
  }
}

//only single line supported..
FrameworkSettings::$linux_user = "(==|frameworksettings_linux_user|==)";
FrameworkSettings::$domain = "(==|frameworksettings_domain|==)";
if (FrameworkSettings::$domain == "" || FrameworkSettings::$domain == "localhost")
{
    FrameworkSettings::$domain = $_SERVER["HTTP_HOST"];
}
FrameworkSettings::$root_folder = "(==|frameworksettings_root_folder|==)";
FrameworkSettings::$public_folder = "(==|frameworksettings_public_folder|==)";
FrameworkSettings::$framework_folder = "(==|frameworksettings_framework_folder|==)";
FrameworkSettings::$framework_folder_dev = "(==|frameworksettings_framework_folder_dev|==)";
FrameworkSettings::$project_name = "(==|frameworksettings_project_name|==)";

FrameworkSettings::$php_bin = "(==|frameworksettings_php_bin|==)"; //  /usr/local/lib/php
FrameworkSettings::$php_lib = "(==|frameworksettings_php_lib|==)"; //  /usr/local/lib/php
FrameworkSettings::$ssl = (==|frameworksettings_ssl|==);

//Cache
FrameworkSettings::$cache_enabled = (==|frameworksettings_cache_enabled|==);
FrameworkSettings::$cache_prefix = "(==|frameworksettings_cache_prefix|==)";

//Development settings
FrameworkSettings::$propel_version = "(==|frameworksettings_propel_version|==)";
FrameworkSettings::$maintenance_mode = (==|frameworksettings_maintenance_mode|==);
FrameworkSettings::$development_mode = (==|frameworksettings_development_mode|==);
FrameworkSettings::$developer_ips = (==|frameworksettings_developer_ips|==);
FrameworkSettings::$log_global_events = (==|frameworksettings_log_global_events|==);
FrameworkSettings::$allow_search_engine_index = (==|frameworksettings_allow_search_engine_index|==);
FrameworkSettings::$translation_enabled = (==|frameworksettings_translation_enabled|==);

FrameworkSettings::$class_file_locations = (==|frameworksettings_class_file_locations|==);
FrameworkSettings::$image_type_tables = (==|frameworksettings_image_type_tables|==);
FrameworkSettings::$seed = "(==|frameworksettings_seed|==)";
FrameworkSettings::$cli = false;

TempTimer::measure("init");

if (php_sapi_name() === 'cli')
{
    FrameworkSettings::$cli = true;
    //FrameworkSettings::$ssl = false;
    
    
    $_SERVER["REMOTE_ADDR"] = "127.0.0.1";
    $_SERVER['REQUEST_METHOD'] = "GET";
    $_SERVER["HTTPS"] = FrameworkSettings::$ssl?"on":"off";
    
    if (isSet($argv[1]) && $argv[1][0] == "/")
    {
        $_SERVER["REQUEST_URI"] = $argv[1];
    }
    else
    {
        $_SERVER["REQUEST_URI"] = "/";
    }
    
    if (isSet($argv[2]))
    {
        $g = json_decode($argv[2], true);
        if ($g !== null && is_array($g))
        {
            $_GET = $g;
            foreach ($g as $key => $value)
            {
                $_REQUEST[$key] = $value;
            }
        }
    }
    
    if (isSet($argv[3]))
    {
        $p = json_decode($argv[3], true);
        if ($p !== null && is_array($p))
        {
            $_SERVER['REQUEST_METHOD'] = "POST";
            
            $_POST = $p;
            foreach ($p as $key => $value)
            {
                $_REQUEST[$key] = $value;
            }
        }
    }

    if (isset($_GET["cli_display_errors"]) && $_GET["cli_display_errors"] == "1")
    {
        error_reporting(E_ALL);
        ini_set("display_errors", 1);
    }
}

if (in_array($_SERVER["REMOTE_ADDR"], FrameworkSettings::$developer_ips))
{
  //alleen bij Cor thuis zien we errors :)
  ini_set("display_errors", "1");
}

//timezone is belangrijk! :)
setlocale(LC_ALL, 'nl_NL.UTF-8');
setlocale(LC_NUMERIC, "en_US.UTF-8");
date_default_timezone_set('Europe/Amsterdam');

set_include_path(FrameworkSettings::$php_lib . "/" . PATH_SEPARATOR . "../build/classes/" . PATH_SEPARATOR . FrameworkSettings::$public_folder . "/" . PATH_SEPARATOR . FrameworkSettings::$framework_folder . "/");

function frameworkClassLoader($class)
{
  if ($class == "HTMLText")
  {
      include_once("php/display/displayobject/htmlobject/htmltext/HTMLText.php");
  }
  if ($class == "VariablesText")
  {
      include_once("php/display/displayobject/htmlobject/text/VariablesText.php");
  }
  if ($class == "VariablesHTMLText")
  {
      include_once("php/display/displayobject/htmlobject/htmltext/VariablesHTMLText.php");
  }
}

spl_autoload_register('frameworkClassLoader');

TempTimer::measure("include_paths");

include_once("php/data/input/request/RequestData.php");
$requestData = new RequestData();

include_once("php/data/input/get/GetData.php");
$getData = new GetData();

if ($requestData->get("sid") !== null)
{
  session_id($requestData->get("sid"));
}
else if ($getData->get("sid") !== null)
{
  session_id($getData->get("sid"));
}

//ini_set('session.save_handler', 'redis');
//ini_set('session.save_path', "tcp://localhost:6379?prefix=".FrameworkSettings::$cache_prefix."session:");
include_once "php/data/model/BaseModel.php";
include_once "php/pattern/multiton/MultitonTrait.php";
/**
 * @property-read \CustomerAuth $customer Get CustomerAuth object
 * @property-read \AdminAuth $admin Get AdminAuth object
 * @property-read \LidAuth $lid Get LidAuth object
 * */
class Auth extends BaseModel
{
    use MultitonTrait;

    public function __construct()
    {
        parent::__construct();
    }

    protected function customer()
    {
        include_once "php/data/auth/CustomerAuth.php";
        return new CustomerAuth();
    }

    protected function admin()
    {
        include_once "php/data/auth/AdminAuth.php";
        return new AdminAuth();
    }

    protected function types()
    {
        $ret = [];

        include_once "php/data/filesystem/includesearch/IncludeSearch.php";
        $s = new IncludeSearch();
        $files = $s->getFilesInFolder("php/data/auth", "*", ".php");
        foreach ($files as $file)
        {
          if (strrpos($file->className, "Auth") === strlen($file->className)-4)
          {
              //only *Auth classes
              $type = lcfirst(substr($file->className, 0, -4));
              $ret[] = $type;
          }
        }
        
        return $ret;
    }

    public function __isset($name)
    {
        if (property_exists($this, $name))
        {
            return ($this->{$name} !== null);
        }

        //method exists weggehaald, omdat we hier autoloaden..
        return ($this->{$name} !== null);
    }

    public function __call($name, $arguments)
    {
        //Autoloading [.*]Auth classes
        $className = ucfirst($name)."Auth";
        $path = "php/data/auth/".$className.".php";

        if (stream_resolve_include_path($path) !== false)
        {
            include_once $path;
            if (class_exists($className, false))
            {
                return new $className($this);
            }
            else
            {
              error_log(__CLASS__.": ".$name."(): class '".$className."' not found in '".$path."'");
            }
        }
        else
        {
          error_log(__CLASS__.": ".$name."(): file not found: '".$path."'");
        }

        return parent::__call($name, $arguments);
    }
}

include_once "php/data/session/SH.php";
$sh = SH::getInstance();

if (!isset($_SERVER["REQUEST_URI"]) || (strpos($_SERVER["REQUEST_URI"], "/virtual/images/") !== 0 && (FrameworkSettings::$project_name != "cd01" || $_SERVER["REQUEST_URI"] != "/pages/Home")))
{
    $sh->enable();
}

//print_r($_SERVER);
//exit();


include_once "php/auth/sessionauth/SessionAuth.php";
$sa = SessionAuth::getInstance();
TempTimer::measure("session");

if ($sh->getVar("developer") === true)
{
  ini_set('memory_limit', '128M');
  set_include_path(FrameworkSettings::$php_lib . "/" . PATH_SEPARATOR . "../build/classes/" . PATH_SEPARATOR . FrameworkSettings::$public_folder . "/" . PATH_SEPARATOR . FrameworkSettings::$framework_folder_dev . "/" . PATH_SEPARATOR . FrameworkSettings::$framework_folder . "/");
}

include_once "php/applications/developer/DeveloperPanel.php";
$developerpanel = DeveloperPanel::getInstance();

TempTimer::measure("developerpanel init");

/**
 * @method RequestLog getInstance() Get current RequestLog object
 * */
class RequestLog extends FWObject
{
  private $data;
  private $triggers;

  public function __construct()
  {
    parent::__construct();

    include_once("php/data/input/get/GetData.php");
    $g = new GetData();

    $this->triggers = Array();
    $this->data = new \DB\RequestLog();
    $uriSplit = explode("?", $_SERVER['REQUEST_URI']);
    $this->data->setPath(reset($uriSplit));
    $this->data->setGetData(serialize($_GET));
    if (isSet($_SERVER['CONTENT_LENGTH']))
    {
      if ((INT)$_SERVER['CONTENT_LENGTH'] <= 1024)
      {
        $this->data->setPostData(serialize($_POST));
      }
      else
      {
        $this->data->setPostData(serialize("POSTDATA TOO BIG!"));
      }
    }
    $this->data->setMethod(strtolower($_SERVER['REQUEST_METHOD']));
    if (isSet($_SERVER['HTTP_REFERER']))
    {
      $this->data->setReferer(strtolower($_SERVER['HTTP_REFERER']));
    }
    $this->data->setFormId($g->get("form"));
    $this->data->setAjax($g->get("ajax"));
    $this->data->setInsertDateTime('NOW');

    //$user = SH::getUser();
    //$user->addRequestLog($this->data);
    //$user->save();
  }

  public function getDBRequestLog()
  {
      return $this->data;
  }
  
  public function addTrigger(\DB\TriggerLog $trigger)
  {
    $this->triggers[] = $trigger;
  }

}

class Trigger
{

  public function __construct($type, $identifier)
  {
    $trigger = new \DB\TriggerLog();
    RequestLog::getInstance()->addTrigger($trigger);
  }

}

include_once "php/pattern/multiton/Multiton.php";
/**
 * @method CLI getInstance() Get cli object
 * */
class CLI extends Multiton
{
    public function __construct()
    {
        parent::__construct();
    }
    
    public function startAdminProcess($class, $action, $params)
    {
        $adminProcessPath = "/beheer/system/processes";
        return $this->startInBackground($adminProcessPath, ["method" => "cliRun", "arguments" => [$class, $action, $params], "outputkey" => "framework_process"]);
    }
    
    public function startInBackground($path, $g = null, $p = null)
    {
        $cmd = FrameworkSettings::$php_bin.' index.php '.escapeshellarg((STRING)$path).' '.escapeshellarg(json_encode($g)).' '.escapeshellarg(json_encode($p));
        $cmd2 = "/usr/bin/nohup ".$cmd." >/dev/null 2>&1 & echo \$!";
        //error_log("CMD: ".$cmd2);
        return (INT)trim(shell_exec($cmd2));
    }

    public function renderPage($path, $g = null, $p = null, $hideCommandInException = true)
    {
        $cmd = FrameworkSettings::$php_bin.' index.php '.escapeshellarg((STRING)$path).' '.escapeshellarg(json_encode($g)).' '.escapeshellarg(json_encode($p));
        //$cmd2 = "".$cmd." 2>/dev/null";
        //error_log("CMD: ".$cmd2);

        $stdout = null;
        $stderr = null;
        $out = $this->execute($cmd, null, $stdout, $stderr, 10);
        
        if ($out !== 0)
        {
          throw new Exception("CLI command failed: ".($hideCommandInException?"--command hidden--":$cmd)." (code: ".$out.")\n".$stderr."\n".$stdout);
        }
        return $stdout;
        //return shell_exec($cmd2);
    }
    
    public function getOutputForPid($pid, $key = "system")
    {
        $ret = new stdClass();
        if (Cache::load("return_pid_".$key."_".(INT)$pid))
        {
            $ret->return = Cache::get();
        }
        $ret->pid = $pid;
        $ret->key = $key;
        $items = Cache::getListRange("generator_pid_".$key."_".(INT)$pid);
        $ret->output = [];
        foreach ($items as $item)
        {
            $ret->output[] = unserialize($item);
        }
        return $ret;
    }
    
    public function getVueOutputForPid($pid, $key = "system", $outputFunction = "onPidOutput", $returnFunction = "onPidReturn")
    {
        $d = $this->getOutputForPid($pid, $key);
        
        $ret = new stdClass();
        $ret->vue = new stdClass();
        $ret->vueCall = [];
        
        $r = new stdClass();
        $r->method = $outputFunction;
        $r->arguments = [$d->pid, $d->output, $d->key];
        $ret->vueCall[] = $r;
        
        if (isset($d->return))
        {
            $r = new stdClass();
            $r->method = $returnFunction;
            $r->arguments = [$d->return];
            $ret->vueCall[] = $r;
        }
        return $ret;
    }
    
    public function execute($cmd, $stdin=null, &$stdout=null, &$stderr=null, $timeout=false)
    {
        $pipes = array();
        $process = proc_open(
            $cmd,
            array(array('pipe','r'),array('pipe','w'),array('pipe','w')),
            $pipes
        );
        $start = time();
        $stdout = '';
        $stderr = '';

        if(is_resource($process))
        {
            stream_set_blocking($pipes[0], 0);
            stream_set_blocking($pipes[1], 0);
            stream_set_blocking($pipes[2], 0);
            if ($stdin !== null)
            {
                fwrite($pipes[0], $stdin);
            }
            fclose($pipes[0]);
        }

        while(is_resource($process))
        {
            //echo ".";
            $stdout .= stream_get_contents($pipes[1]);
            $stderr .= stream_get_contents($pipes[2]);

            if($timeout !== false && time() - $start > $timeout)
            {
                proc_terminate($process, 9);
                error_log("CLI execute timeout: ".$cmd);
            }

            $status = proc_get_status($process);
            if(!$status['running'])
            {
                //print_r(json_encode($status, JSON_PRETTY_PRINT));
                fclose($pipes[1]);
                fclose($pipes[2]);
                proc_close($process);
                
                //will return -1 on timeout
                return $status['exitcode'];
            }

            usleep(100000);
        }

        return 1;
    }
    
    public function executeGenerator($cmd, $stdin=null, $timeout=false)
    {
        $pipes = array();
        $process = proc_open(
            $cmd,
            array(array('pipe','r'),array('pipe','w'),array('pipe','w')),
            $pipes
        );
        $start = time();

        if(is_resource($process))
        {
            stream_set_blocking($pipes[0], 0);
            stream_set_blocking($pipes[1], 0);
            stream_set_blocking($pipes[2], 0);
            if ($stdin !== null)
            {
                fwrite($pipes[0], $stdin);
            }
            fclose($pipes[0]);
        }

        while(is_resource($process))
        {
            //echo ".";
            $stdout = stream_get_contents($pipes[1]);
            if ($stdout != "")
            {
                yield $stdout;
            }
            
            $stderr = stream_get_contents($pipes[2]);
            if ($stderr != "")
            {
                yield $stderr;
            }
            
            if($timeout !== false && time() - $start > $timeout)
            {
                proc_terminate($process, 9);
                yield "CLI execute timeout";
            }

            $status = proc_get_status($process);
            if(!$status['running'])
            {
                //print_r(json_encode($status, JSON_PRETTY_PRINT));
                fclose($pipes[1]);
                fclose($pipes[2]);
                proc_close($process);
                
                //will return -1 on timeout
                return $status['exitcode'];
            }

            usleep(100000);
        }

        return 1;
    }
}

class PageContext extends Multiton
{

  /** @var Page Contains the current Page object */
  static $CURRENT_PAGE = null;
  static $WEBP;
  /** @var Auth Contains the current Page object */
  static $AUTH;
  
  private $pages;

  public function __construct()
  {
    $this->pages = Array();
  }

  public function switchToPage($toPage)
  {
    PageContext::$CURRENT_PAGE = $toPage;
    return true;

    //we gebruiken voorlopig wel de snelle hack
    /* foreach ($this->pages as $page)
      {
      if ($page === $toPage)
      {
      PageContext::$CURRENT_PAGE = $toPage;
      return true;
      }
      }
      return false; */
  }

  public function getPageByKey($key)
  {
    if (isSet($this->pages[$key]))
    {
      return $this->pages[$key];
    }
    return null;
  }

  public function addPage($page, $key = null)
  {
    if ($key === null)
    {
      $this->pages[] = $page;
    }
    else
    {
      $this->pages[$key] = $page;
    }
  }

  static function setDefaultAppData($key, $value, $type = "default")
  {
    $d = self::getAppData($key, $type);
    
    //TempTimer::measure("setDefaultAppData start ".$key);
    if ($d->isNew())
    {
      $d->setValue($value);
      $d->setType($type);
      $d->save();
      
      $ck = "appdata2_".$type."_".$key;
      Cache::addRaw($ck, $d->getId()."_".$value, 60*60*48);
    }
    //TempTimer::measure("setDefaultAppData end ".$key);
    return $d;
  }

  static function getAppDataValue($key, $type = "default")
  {
    //extra snelle manier
    $ck = "appdata2_".$type."_".$key;
    $cacheData = Cache::getRaw($ck);
    if ($cacheData !== false)
    {
        if ($cacheData === "")
        {
            return null;
        }
        $adArray = explode("_",$cacheData, 2);
        return $adArray[1];
    }
    
    //standaard manier
    $d = self::getAppData($key, $type);
    if ($d->isNew())
    {
      return null;
    }
    return $d->getValue();
  }
  
  static function deleteAppDataCacheByObject($obj)
  {
      $ck = "appdata2_".$obj->getType()."_".$obj->getKey();
      Cache::delete($ck);
  }
  
  static function getAppData($key, $type = "default")
  {
    //TempTimer::measure("getAppData start ".$key);
    $ck = "appdata2_".$type."_".$key;
    $cacheData = Cache::getRaw($ck);
    if ($cacheData !== false)
    {
        if ($cacheData === "")
        {
            $d = new \DB\AppData();
            $d->setKey($key);
            $d->setType($type);
            //TempTimer::measure("getAppData end1 ".$key);
            
            return $d;
        }
        $adArray = explode("_",$cacheData, 2);
        $obj = new \DB\AppData();
        $obj->setId($adArray[0]);
        $obj->setKey($key);
        $obj->setValue($adArray[1]);
        $obj->setType($type);
        $obj->resetModified();
        $obj->setNew(false);

        if (FrameworkSettings::$propel_version == "1")
        {
            \DB\AppDataPeer::addInstanceToPool($obj, $adArray[0]);
        }
        //TempTimer::measure("getAppData end2 ".$key);
        return $obj;
    }
    $d = \DB\AppDataQuery::create()->filterByKey($key)->filterByType($type)->findOneOrCreate();
    if ($d->isNew())
    {
        $d = \DB\AppDataQuery::create()->filterByKey($key)->findOneOrCreate();
        $d->setType($type);//convert
    }
    
    if (!$d->isNew())
    {
        Cache::addRaw($ck, $d->getId()."_".$d->getValue(), 60*60*48);
    }
    else
    {
        //add to cache that it doesnt exist :)
        Cache::addRaw($ck, "", 60*60*48);
    }
    //TempTimer::measure("getAppData end3 ".$key);
    
    return $d;
  }

  static function setAppData($key, $value, $type = "default")
  {
    $d = self::getAppData($key, $type);
    
    if ($d->getValue() !== $value)
    {
        //TempTimer::measure("setAppData ".$key." start");
        $d->setValue($value);
        $d->save();
        
        $ck = "appdata2_".$type."_".$key;
        Cache::addRaw($ck, $d->getId()."_".$value, 60*60*48);
        //TempTimer::measure("setAppData ".$key." end");
    }
    
    return $d;
  }

  static function deleteAppDataById($id)
  {
    $appData = \DB\AppDataQuery::create()->filterById((INT)$id)->findOne();
    if ($appData !== null)
    {
      self::deleteAppDataCacheByObject($appData);
      return $appData->delete();
    }
  }
  
}

class QueryString extends FWObject
{
  private $data;
  private $parents;

  public function __construct($arrayData = null, $loadGetData = false, $include = null, $exclude = null)
  {
    parent::__construct();

    $this->data = Array();
    if ($loadGetData)
    {
      $this->loadGetData($include, $exclude);
    }

    if ($arrayData !== null)
    {
      $this->addArrayData($arrayData);
    }

    $this->parents = Array();
  }

  static function create($arrayData = null, $loadGetData = false)
  {
    return new QueryString($arrayData, $loadGetData);
  }

  public function loadGetData($include = null, $exclude = null, $add = null)
  {
    foreach ($_GET as $key => $val)
    {
      if ($exclude === null || !in_array($key, $exclude))
      {
        if ($include === null || in_array($key, $include))
        {
          if ((($key !== "form" && $key !== "ajax" && $key !== "dynamicpage_id") || ($add !== null && in_array($key, $add)) || ($include !== null && in_array($key, $include))) && $val !== null)//formId niet steeds doorgeven
          {
            $this->data[$key] = $val;
          }
        }
      }
    }
  }

  public function get($key)
  {
    if (isSet($this->data[$key]))
    {
      return $this->data[$key];
    }
    return null;
  }

  public function removeStringData($string)
  {
    //question mark er af
    if (strlen($string) > 0 && $string[0] == "?")
    {
      $string = substr($string, 1);
    }

    $array = Array();
    parse_str($string, $array);
    //print_r($array);

    $this->removeArrayData($array);
  }

  public function addStringData($string)
  {
    //question mark er af
    if (strlen($string) > 0 && $string[0] == "?")
    {
      $string = substr($string, 1);
    }

    $array = Array();
    parse_str($string, $array);
    //print_r($array);
    $this->addArrayData($array);
  }

  public function removeArrayData($value)
  {
    foreach ($value as $key => $val)
    {
      unset($this->data[$key]);
    }
  }

  public function addArrayData($value)
  {
    foreach ($value as $key => $val)
    {
      $this->set($key, $val);
    }
  }

  public function set($key, $value)
  {
    if ($value === null)
    {
      unset($this->data[$key]);
    }
    else
    {
      $this->data[$key] = $value;
    }
  }

  public function createChild()
  {
    $child = new QueryString();
    $child->setParent($this);
    return $child;
  }

  public function addParent($qs)
  {
    //todo: check op type
    $this->parents[] = $qs;
  }

  public function setParent($qs)
  {
    if ($qs instanceOf QueryString)
    {
      $this->parents = Array($qs);
      return $this;
    }
    else
    {
      //string
    }
  }

  public function getData()
  {
    if (count($this->parents) != 0)
    {
      $ret = Array();
      foreach ($this->parents as $par)
      {
        $ret = array_merge($par->getData(), $ret);
      }
      return array_merge($ret, $this->data);
    }
    return $this->data;
  }

  public function __toString()
  {
    $ret = "";

    if (count($this->parents) != 0)
    {
      $source = $this->getData();
    }
    else
    {
      $source = & $this->data;
    }

    ksort($source);

    /*foreach ($source as $key => $val)
    {
      $ret .= "&" . $key . "=" . urlencode($val);
    }
    if ($ret != "")
    {
      $ret[0] = '?';
    }*/
    if (count($source) > 0)
    {
      $ret .= "?".http_build_query($source);
    }
    return $ret;
  }

}

class Path
{
    static function remoteToLocal($pathname)
    {
        $pathname = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $pathname);
        
        while (strlen($pathname) > 0 && $pathname[0] == DIRECTORY_SEPARATOR && strpos($pathname, FrameworkSettings::$root_folder) !== 0)
        {
            $pathname = substr($pathname, 1);
        }
        return $pathname;
    }
}

class URL implements \JsonSerializable
{

  private $path;
  private $queryString;
  private $domain; //not sure to include http or not...
  private $language;
  private $protocol;

  public function __construct($path = null, $queryString = null, $domain = null, $language = null, $protocol = null)
  {
    if ($protocol === null)
    {
      $protocol = FrameworkSettings::$ssl ? "https://" : "http://";
    }
    if ($path === null)
    {
      $this->path = PageContext::$CURRENT_PAGE->getPath();
    }
    else
    {
      $this->path = $path;
    }

    if ($queryString === null)
    {
      $this->queryString = new QueryString();
      $this->queryString->addParent(QueryString::getInstance());
    }
    else
    {
      $this->queryString = $queryString;
    }

    if ($domain === null)
    {
//      Werkelijk geen idee waarom dit hier stond...      
//      if ($queryString === null)
//      {
//        $this->queryString = QueryString::getInstance();
//      }

      $this->domain = PageContext::$CURRENT_PAGE->getDomain();
    }
    else
    {
      $this->domain = $domain;
    }

    if ($language === null)
    {
      $this->language = Language::getInstance()->getPath();
    }
    else
    {
      $this->language = $language;
    }

    $this->protocol = $protocol;
  }

  public function setPath($path)
  {
    $this->path = $path;
  }
  
  public function getPath()
  {
    return $this->path;
  }

  public function getDomain()
  {
      return $this->domain;
  }
  
  public function fromString($string)
  {
    $pos = strpos($string, "//");
    if ($pos !== false)
    {
      $this->protocol = substr($string, 0, $pos + 2);
      $string = substr($string, $pos + 2);
    }
    else
    {
      $this->protocol = FrameworkSettings::$ssl ? "https://" : "http://";
    }

    if ($pos !== false)
    {
      $pos = strpos($string, "/");
      if ($pos !== false)
      {
        $this->domain = substr($string, 0, $pos);

        $string = substr($string, $pos); //path+qs
      }
      else
      {
        //er zit geen slash achter
        $qpos = strpos($string, "?");
        if ($qpos !== false)
        {
          //nog wel een querystring
          $this->domain = substr($string, 0, $qpos);
          $string = substr($string, $qpos);
        }
        else
        {
          //geen querystring
          $this->domain = $string;
          $string = "/";
        }
      }
    }

    $pos = strpos($string, "?");

    $this->queryString = new QueryString();
    if ($pos !== false)
    {
      $this->path = substr($string, 0, $pos);
      $this->queryString->addStringData(substr($string, $pos + 1));
    }
    else
    {
      $this->path = $string;
    }
    return true;
    //}

    return false;
  }

  public function setQueryString($queryString)
  {
    $this->queryString = $queryString;
  }

  public function getQueryString()
  {
    return $this->queryString;
  }

  public function __toString()
  {
    return $this->protocol . $this->domain . (STRING)$this->language . (STRING)$this->path . (STRING)$this->queryString;
  }

  public function __clone()
  {
    $this->queryString = clone $this->queryString;
  }

  #[\ReturnTypeWillChange]
  public function jsonSerialize()
  {
      return (string)$this;
  }
}

/**
 * @method CDN getInstance() Get CDN object
 * */
class CDN extends FWObject
{
    const PROJECT = "(==|frameworksettings_cdn_project_name|==)";
    
    private $url = "(==|frameworksettings_cdn_project_url|==)";
    private $key = "(==|frameworksettings_cdn_project_key|==)";
    
    public function __construct()
    {
        parent::__construct();
    }
    
    public function addModificationsToPath($path, $modifications)
    {
      return $path."?m=".urlencode(base64_encode(json_encode($modifications)));
    }
    
    public static function convertWEBPPath($value)//niet zomaar renamen, kan in gecompilede templates zitten...
    {
        $path = parse_url($value, PHP_URL_PATH);
        $info = pathinfo($path);

        $originalExtension = $info["extension"] ?? null;

        $queryString = parse_url($value, PHP_URL_QUERY);
        if ($originalExtension != "webp")
        {
            $vars = [];
            if ($queryString !== null)
            {
              parse_str($queryString, $vars);
            }
            if (isset($vars["m"]))
            {
                $modifications = json_decode(base64_decode($vars["m"]), true);
                if (!is_array($modifications))
                {
                    $modifications = [];
                }
            }
            else
            {
                $modifications = [];
            }

            //we convert the final file type, and pass the original filetype along the url
            if (empty($modifications))
            {
                $modifications[] = [
                  "type" => "resize"
                ];
            }
            $modifications[count($modifications)-1]["to-file-type"] = "webp";

            $vars["m"] = base64_encode(json_encode($modifications));
            $vars["fft"] = $originalExtension;

            $queryString = http_build_query($vars);

        }

        $webpSrc = ((!empty($info['dirname']) && $info['dirname'] != ".") ? $info['dirname'] . DIRECTORY_SEPARATOR : '') . $info['filename'] . '.webp'.($queryString?"?".$queryString:"");

        return $webpSrc;
    }
    
    public function resizeImagePath($path, $width, $height, $position = null, $trim = false)
    {
      $modifications = [
        [
          "type" => "resize",
          "width" => $width,
          "height" => $height
        ]
      ];
      
      if ($position !== null)
      {
        $modifications["position"] = $position;
      }
      
      if($trim)
          $modifications["trim"] = true;
      
      return $path."?m=".urlencode(base64_encode(json_encode($modifications)));
    }
    
    public function redownloadImagePath($path, $url = null)
    {
        include_once "php/data/external/urlrequest/URLRequest.php";
        $u = new URLRequest($this->url . "/pages/Home");

        //push the image
        $data = Array();
        $data["method"] = "redownloadimagepath";
        $data["path"] = $path;
        $data["downloadurl"] = $url;//URL is VERVANGENDE TARGET indien meegegeven
        $data["project"] = self::PROJECT;
        $data["key"] = $this->key;
        
        $req = $u->post($data);
        $remote = json_decode($req, true);

        if ($remote !== false && is_array($remote))
        {
          return $remote;
        }
        else
        {
          return ["success" => false, "error" => "CDN unexpected response: ".$req];
        }
    }
    
    public function getImagePathsByRemoteURL($url)
    {
        include_once "php/data/external/urlrequest/URLRequest.php";
        $u = new URLRequest($this->url . "/pages/Home");

        //push the image
        $data = Array();
        $data["method"] = "getcdnpathsbyurl";
        $data["url"] = $url;
        $data["project"] = self::PROJECT;
        $data["key"] = $key;
        
      $req = $u->post($data);
      $remote = json_decode($req, true);

      if ($remote !== false && is_array($remote))
      {
        return $remote;
      }
      else
      {
        return ["success" => false, "error" => "CDN unexpected response: ".$req];
      }
    }
    
    public function frameImagePath($path, $maxWidth, $maxHeight, $position = null)
    {
      $modifications = [
        [
          "type" => "resize",
          "max-width" => $maxWidth,
          "max-height" => $maxHeight,
          "to-file-type" => "png"
        ]
      ];
      
      if ($position !== null)
      {
        $modifications["position"] = $position;
      }
      
      return $path."?m=".urlencode(base64_encode(json_encode($modifications)));
    }
    
    public function remotePushData($stringData, $path = "", $overwrite = false, $createNewPathIfExists = false)
    {
        include_once "php/data/external/urlrequest/URLRequest.php";
        $u = new URLRequest($this->url . "/pages/Home");
        
        //push the image
        $data = Array();
        $data["method"] = "remotepush";
        $data["path"] = str_replace("%20"," ",$path);
        $data["data"] = $stringData;
        $data["project"] = self::PROJECT;
        $data["key"] = $this->key;
        if ($overwrite)
        {
          $data["overwrite"] = "1";
        }
        if ($createNewPathIfExists)
        {
          $data["createnewpathifexists"] = "1";
        }
      $req = $u->post($data);
      $remote = json_decode($req, true);

      if ($remote !== false && is_array($remote))
      {
        return $remote;
      }
      else
      {
        return ["success" => false, "error" => "CDN unexpected response: ".$req];
      }
    }
    
    public function remotePush($url, $path = "", $overwrite = false)
    {
        include_once "php/data/external/urlrequest/URLRequest.php";
        $u = new URLRequest($this->url . "/pages/Home");
        
        //push the image
        $data = Array();
        $data["method"] = "remotepush";
        $data["path"] = str_replace("%20"," ",$path);
        $data["url"] = $url;
        $data["project"] = self::PROJECT;
        $data["key"] = $this->key;
        if ($overwrite)
        {
          $data["overwrite"] = "1";
        }
        
      $req = $u->post($data);
      $remote = json_decode($req, true);

      if ($remote !== false && is_array($remote))
      {
        return $remote;
      }
      else
      {
        return ["success" => false, "error" => "CDN unexpected response: ".$req];
      }
    }
    
    public function getPathInfo($path)
    {
      include_once "php/data/external/urlrequest/URLRequest.php";
      $u = new URLRequest($this->url . "/pages/Home", 15);

      //get the image
      $data = Array();
      $data["method"] = "getpathinfo";
      $data["path"] = $path;
      $data["project"] = self::PROJECT;
      $data["key"] = $this->key;
      
      $req = $u->post($data);
      $remote = json_decode($req, true);

      if ($remote !== false && is_array($remote))
      {
        return $remote;
      }
      else
      {
        return ["success" => false, "error" => "CDN unexpected response: ".$req];
      }
    }
    
    public function getImage($path, $modifications = null)
    {
      include_once "php/data/external/urlrequest/URLRequest.php";
      $u = new URLRequest($this->url . "/pages/Home", 15);

      //get the image
      $data = Array();
      $data["method"] = "getimage";
      $data["path"] = $path;
      $data["project"] = self::PROJECT;
      $data["modifications"] = json_encode($modifications);
      $data["key"] = $this->key;

      if (isSet($_GET["nocache"]))
      {
        $data["nocache"] = 1;
      }
      
      $req = $u->post($data);
      $remote = json_decode($req, true);

      if ($remote !== false && is_array($remote))
      {
        return $remote;
      }
      else
      {
        return ["success" => false, "error" => "CDN unexpected response: ".$req];
      }
    }
    
    public function displayImageStream($path, $modifications = null)
    {
      include_once "php/data/external/urlrequest/URLRequest.php";
      $u = new URLRequest($this->url . "/pages/Home", 15);

      //get the image
      $data = Array();
      $data["method"] = "getimagestream";
      $data["path"] = str_replace("%20", " ", $path);
      $data["project"] = self::PROJECT;
      if ($modifications !== null)
      {
        $data["modifications"] = json_encode($modifications);
      }
      $data["key"] = $this->key;

      if (isSet($_GET["nocache"]))
      {
        $data["nocache"] = 1;
      }
      if (isset($_SESSION["developer"]) && $_SESSION["developer"])
      {
        //aanzetten om afbeelding cache te verversen
        $data["nocache"] = "save";
      }
      $fp = $u->postToStream($data);
      
      $cdnStatus = null;
      $http_response_header = $u->getResponseHeaders();
      if (is_array($http_response_header))
      {
        header_remove("Content-Transfer-Encoding");
        foreach ($http_response_header as $header)
        {
          if (stripos($header, "CDNStatus") === 0)
          {
            $split = explode(":", $header);
            $cdnStatus = trim(end($split));
            continue;
          }
          if (stripos($header, "Cookie") === false && stripos($header, "Referer") === false && $header !== "HTTP/1.1 200 OK")
          {
            header($header);
          }
        }
      }
      
      /*while (!feof($fp) && ( connection_status() == 0))
      {
        set_time_limit(0);
        print(fread($fp, 1024 * 8));
        flush();
        ob_flush();
        sleep(1);
      }*/
      
      if ($cdnStatus === "ok")
      {
        $cacheTime = (3600 * 24);
        if (!isSet($_GET["nocache"]))
        {
          header('Cache-Control: public');
          header('Pragma: cache');
          header("Expires: " . gmdate("D, d M Y H:i:s", time() + $cacheTime) . " GMT");
        }
        else
        {
          header('Cache-Control: no-cache');
          header('Pragma: no-cache');
          header("Expires: " . gmdate("D, d M Y H:i:s", time() - $cacheTime) . " GMT");
        }
        fpassthru($fp);
        fclose($fp);
      }
      else
      {
        //we get a json return...
        header("Content-type: text/html");
        http_response_code(404);
        echo "CDN status: ".$cdnStatus."!\n";
        
        if ($fp !== false)
        {
            fpassthru($fp);
            fclose($fp);
        }
        
        if ($cdnStatus == "modifications-failed")
        {
          //the file went missing..
          $images = \DB\ImageQuery::create()->filterByCDNPath([$data["path"], $path], Criteria::IN)->delete();
        }
      }
      TempTimer::measure("after image stream");
      exit();
    }
    
    public function displayImageData($remote)
    {
      if (!isSet($_GET["nocache"]))
      {
        //TEST, nog under construction...
        $cacheTime = (3600 * 24);
        header('Cache-Control: public');
        header('Pragma: cache');
        header("Expires: " . gmdate("D, d M Y H:i:s", time() + $cacheTime) . " GMT");
      }
      else
      {
        header('Pragma: no-cache');
      }
      
      if (isSet($remote["success"]) && $remote["success"])
      {
        if (isSet($remote["content-type"]))
        {
          header("Content-Type: ".$remote["content-type"]);
        }
        echo utf8_decode($remote["data"]);
        exit();
      }
      else
      {
        if (isSet($remote["header"]))
        {
          header($remote["header"]);
        }
        if (isSet($remote["error"]))
        {
          http_response_code(404);
          echo "CDN Error:".$remote["error"];
        }
        exit();
      }
    }
    
    public function getVideoData($path, $modifications = null)
    {
      include_once "php/data/external/urlrequest/URLRequest.php";
      $u = new URLRequest($this->url . "/pages/Home");

      //get the image
      $data = Array();
      $data["method"] = "getvideodata";
      $data["path"] = $path;
      $data["project"] = self::PROJECT;
      //$data["modifications"] = json_encode($modifications);
      $data["key"] = $this->key;

      $req = $u->post($data);
      $remote = json_decode($req, true);

      if ($remote !== false && is_array($remote))
      {
        return $remote;
      }
      else
      {
        return ["success" => false, "error" => "CDN unexpected response: ".$req];
      }
    }
    
    public function getVideo($path)
    {
      include_once "php/data/external/urlrequest/URLRequest.php";
      $u = new URLRequest($this->url . "/pages/Home", 30);

      //get the image
      $data = Array();
      $data["method"] = "getvideo";
      $data["path"] = $path;
      $data["project"] = self::PROJECT;
      //$data["modifications"] = json_encode($modifications);
      $data["key"] = $this->key;

      //control headers ook doorsturen
      $fp = $u->postToStream($data);
      
      $http_response_header = $u->getResponseHeaders();
      if (is_array($http_response_header))
      {
        header_remove("Content-Transfer-Encoding");
        foreach ($http_response_header as $header)
        {
          if (stripos($header, "Cookie") === false && stripos($header, "Referer") === false)
          {
            header($header);
          }
        }
      }
      
      /*while (!feof($fp) && ( connection_status() == 0))
      {
        set_time_limit(0);
        print(fread($fp, 1024 * 8));
        flush();
        ob_flush();
        sleep(1);
      }*/
      
      fpassthru($fp);
      fclose($fp);
      
      exit();
    }
    
    public function displayVideoData($remote)
    {
      //TEST, nog under construction...
      
      if (isSet($remote["success"]) && $remote["success"])
      {
        if (isSet($remote["content-type"]))
        {
          header("Content-Type: ".$remote["content-type"]);
        }
        if (isSet($remote["path"]))
        {
          $this->getVideo($remote["path"]);
          exit();
        }
        else
        {
          echo "VideoData is missing 'path'";
        }
      }
      else
      {
        if (isSet($remote["header"]))
        {
          header($remote["header"]);
        }
        if (isSet($remote["error"]))
        {
          echo $remote["error"];
        }
        exit();
      }
    }
}

//voorbeeld gewone code
//$s = new SDMEmail();
//$s->setFirstname("Cor");
//$con = Database::getPreviewConnectionIfRequired();

class FrameworkTools
{

  static function getFileIncludePath($file, $includePath = null)
  {
    if ($includePath === null)
    {
      $ps = explode(":", ini_get('include_path'));
    }
    else if (is_string($includePath))
    {
      $ps = explode(":", $includePath);
    }
    else if (is_array($includePath))
    {
      $ps = $includePath;
    }
    else
    {
      return null;
    }

    while (strlen($file) > 0 && ($file[0] == "/" || $file[0] == "."))
    {
      $file = substr($file, 1);
    }
    $file = str_replace("\\", "", $file);
    if (strlen($file) == 0)
    {
      return null;
    }

    //we hebben iets van een pad dat niet begint met een /
    foreach ($ps as $path)
    {
      if (file_exists($path . $file))
      {
        return ($path . $file);
      }
    }
    if (file_exists($file))
    {
      return $file;
    }
    return null;
  }

}

//include_once "php/FWObject.php";
/**
 * @method Language getInstance() Get language object
 * */
class Language extends FWObject
{

  const MAIN = "xx";
  const ENGLISH = "en";
  const NEDERLANDS = "nl";

  private $code;
  private $available;
  private $languagePaths;

  public function __construct($code = null, $available = Array())
  {
    include_once "php/display/displayobject/htmlobject/text/Text.php";
    if ($code === null)
    {
      $this->code = new Text(self::MAIN);
    }
    else if (!$code instanceOf Text)
    {
      $this->code = new Text((STRING)$code);
    }
    else
    {
      $this->code = $code;
    }

    $this->available = $available;
    $this->languagePaths = Array(self::MAIN => new Text());
  }

  public function getGeoCountryCode()
  {
      $currentLanguage = "XX";
      $ip = $_SERVER['REMOTE_ADDR'];
      
      if (!Cache::load("ip_geo_".$ip))
      {
        try {
          $geoString = @file_get_contents('http://www.geoplugin.net/php.gp?ip='.$ip);
          $geoData = @unserialize($geoString);
          
          if (isSet($geoData["geoplugin_countryCode"]) && strlen($geoData["geoplugin_countryCode"]) == 2)
          {
            $currentLanguage = $geoData["geoplugin_countryCode"];
            Cache::add("ip_geo_".$ip, $currentLanguage, 60*60*24*7);//weekje bewaren
          }
          else
          {
              //not found
              if (in_array(substr($ip, 0, 7), ["172.18."]))
              {
                  $currentLanguage = "NL";
                  Cache::add("ip_geo_".$ip, $currentLanguage, 60*60*24*7);//weekje bewaren
              }
              else
              {
                  error_log("index.php: ip ".$ip." could not be resolved by geoplugin");
                  Cache::add("ip_geo_".$ip, $currentLanguage, 60);//weekje bewaren
              }
          }

        } catch (Exception $e) {
            error_log("Language::getGeoCountryCode exception ".$e->getMessage());
        }
      }
      else
      {
        $currentLanguage = Cache::get();
      }
      
      return $currentLanguage;
  }
  
  public function getAvailableLanguages()
  {
    return $this->available;
  }

  public function getPaths()
  {
    return $this->languagePaths;
  }

  public function setPath($code, $path)
  {
    $this->languagePaths[$code] = $path;
  }

  public function getPath($code = null)
  {
    if ($code == "")
    {
      $code = $this->code;
    }
    //if no alternatives..
    //echo "jo".$code.";";

    if (isSet($this->languagePaths[(STRING)$code]))
    {
      return $this->languagePaths[(STRING)$code];
    }
    return "/" . $code;
  }

  public function getCode()
  {
    return $this->code;
  }

  public function changeTo($code)
  {
    $this->code->setText($code);
  }

  public function isAvailable($code)
  {
    return (in_array((STRING)$code, $this->available));
  }

}

class PropelTools
{
  static function escapeStringArray(Array $stringArray)
  {
      
        $c = Propel::getConnection();

        $escaped = [];
        foreach ($stringArray as $string)
        {
            $escaped[] = $c->quote($string);
        }
        return $escaped;
  }
  
  static function escapeIntArray(Array $intArray)
  {
      return array_map('intval', $intArray);
  }
  
  static function displayDate($date)
  {
      if ($date instanceof DateTime)
      {
          return $date->format("Y-m-d H:i:s");
      }
      return $date;
  }
  
  static function translateObjectColToPHP($object, $field)
  {
      if (FrameworkSettings::$propel_version == "2")
      {
          return Propel\Runtime\Map\TableMap::translateFieldnameForClass(
                  get_class($object), 
                  $field, 
                  Propel\Runtime\Map\TableMap::TYPE_COLNAME, 
                  Propel\Runtime\Map\TableMap::TYPE_PHPNAME
          );
      }
      else
      {
          $peer = $object->getPeer();
          return $peer->translateFieldName($field, BasePeer::TYPE_COLNAME, BasePeer::TYPE_PHPNAME);
      }
  }
    
  static function isActiveRecordObject($object)
  {
      if (FrameworkSettings::$propel_version == "2")
      {
          return ($object instanceof Propel\Runtime\ActiveRecord\ActiveRecordInterface);
      }
      else
      {
          return ($object instanceof BaseObject);
      }
  }
  
  static function getValueSet($tableName, $field)
  {
      //v1 $var = \DB\LeverancierPeer::getValueSets()[\DB\LeverancierPeer::VERZENDBON];
      //v2 $var = \DB\Map\LeverancierTableMap::getValueSet(\DB\Map\LeverancierTableMap::COL_VERZENDBON);
      
      if (FrameworkSettings::$propel_version == "2")
      {
            $map = "\\DB\Map\\".ucfirst($tableName)."TableMap";
            $col = 'COL_'.strtoupper($field);
            return $map::getValueSet(constant($map.'::'.$col));
      }
      else
      {
          $peer = "\\DB\\".ucfirst($tableName)."Peer";
          return $peer::getValueSet(constant($peer.'::'.strtoupper($field)));
      }
  }
  
  static function getTableMapFromObject($object)
  {
    if (FrameworkSettings::$propel_version == "2")
    {
        $mapClass = $object::TABLE_MAP;
        return $mapClass::getTableMap();
    }
    else
    {
        return $object->getPeer()->getTableMap();
    }
  }
  
  static function objectToStdClass($object)
  {
      if (FrameworkSettings::$propel_version == "2")
      {
          return (Object)$object->toArray(\Propel\Runtime\Map\TableMap::TYPE_FIELDNAME);
      }
      else
      {
          return (Object)$object->toArray(BasePeer::TYPE_FIELDNAME);
      }
  }
  
  static function rowCount($res)
  {
      if (FrameworkSettings::$propel_version == "2")
      {
          return $res->count();
      }
      else
      {
          return $res->rowCount();
      }
  }
  
  static function importStdClass($object, $obj)
  {
      if (FrameworkSettings::$propel_version == "2")
      {
          throw new ErrorException(__CLASS__." v2 ".__FUNCTION__." not implemented yet!");
      }
      else
      {
          $object->fromArray(get_object_vars($obj), BasePeer::TYPE_FIELDNAME);
          return $object;
      }
  }
  
  static function getFieldNamesFromObject($object)
  {
    if (FrameworkSettings::$propel_version == "2")
    {
        return Propel\Runtime\Map\TableMap::getFieldNamesForClass(get_class($object));
        
        $mapClass = $object::TABLE_MAP;
        $tableMap = new $mapClass();
        $columns = $tableMap->getColumns();
        
        //return $tableMap->getFieldNamesForClass(get_class($object));
    }
    else
    {
        return $object->getPeer()->getFieldNames();
    }
  }
  
  static function stringNull($input)
  {
      if ((string)$input == '')
      {
          return null;
      }
      return (string)$input;
  }
  
  static function makeDate($input)
  {
      if ($input instanceof DateTime)
      {
          return $input;
      }
      else if ($input === "" || $input === null)
      {
          return null;
      }
      return date("Y-m-d H:i:s", strtotime($input));
  }
  
  static function makeDecimal($input)
  {
    return str_replace(",", ".", (STRING)$input);
  }

  static function makeDecimalNull($input)
  {
    if ($input === "" || $input === null)
    {
      return null;
    }
    $ret = str_replace(",", ".", (STRING)$input);
    if ($ret === "" || !is_numeric($ret))
    {
      return null;
    }
    return $ret;
  }

  static function getNamespaceFreeClassName($class)
  {
    if (is_object($class))
    {
      $class = get_class($class);
    }
    $split = explode("\\", (STRING)$class);
    return end($split);
  }

  static function syncSubRelations($object, $relations)
  {
    $objectName = PropelTools::getNamespaceFreeClassName(get_class($object));
    $subItem = "\\DB\\Sub" . $objectName;
    /* $field = $objectName;
      $function1 = "set".$field."1";

      $newRelations = Array();

      foreach ($relations as $relation)
      {
      $item = new $subItem();
      $item->$function1($relation->getId());

      $newRelations[] = $item;
      } */

    self::syncRelations($object, $subItem, $relations);
  }

  static function syncRelations($object, $relationClass, $relations)
  { 
    $objectModel = PropelTools::getNamespaceFreeClassName(get_class($object));

    $cleanRT = PropelTools::getNamespaceFreeClassName($relationClass);
    $function = "set" . $cleanRT . "s";
    //$function2 = "get" . $cleanRT . "s";
    //$object->$function2(); //we call this because we need to know what exists and what not..
    //print_r($relations);

    //error_log("Sync relations: ".count($relations)." on ".$cleanRT);

    if (FrameworkSettings::$propel_version == "2")
    {
      $collection = new PropelCollection();
    }
    else
    {
      $collection = new PropelObjectCollection();
    }
    
    $collection->setModel("DB\\" . $cleanRT);
    $collection->setData($relations);

    $object->$function($collection);
  }

  //path: Array("User","Invoice");
  static function hasRelation($firstId, $secondId, $path = null)
  {
    
  }

  static function closeQuery($resource)
  {
      if (FrameworkSettings::$propel_version == "2")
      {
          $resource->close();
      }
      else
      {
          $resource->closeCursor();
      }
  }
  
}

class DateTimeWrapper extends DateTime implements JsonSerializable{
    private $string;
    
    public function __construct($string)
    {
        parent::__construct($string);
        $this->string = $string;
    }
    
    #[\ReturnTypeWillChange]
    public function jsonSerialize()
    {
        return parent::format("Y-m-d H:i:s");
    }
    
    public function __toString() {
        return parent::format("Y-m-d H:i:s");
    }
}

/**
 * @method Cache getInstance() Get the Cache object
 * */
class Cache
{
  static $prefix = "default_";
  static $enabled = false;
  static $lastKey = null;
  static $lastGetResult = null;
  static $connection;

  static function enable()
  {
    self::$connection = new Redis();
    if (self::$connection->connect("(==|frameworksettings_redis_host|==)"))
    {
      self::$enabled = true;
    }
  }

  static function rename($oldKey, $newKey)
  {
    if (self::$enabled)
    {
      return self::$connection->rename(self::$prefix . $oldKey, self::$prefix . $newKey);
    }
    return false;
  }
  
  static function load($key)
  {
    if (self::$enabled)
    {
      self::$lastKey = $key;
      //self::$lastGetResult = apc_fetch(self::$prefix . $key);
      self::$lastGetResult = @unserialize(self::$connection->get(self::$prefix . $key));

      return (self::$lastGetResult !== false);
    }
    return false;
  }

  static function addEncrypted($encryptionKey, $key, $data, $time = 60)
  {
    if (self::$enabled)
    {
      $plaintext = serialize($data);
      
      $cipher = "aes-128-gcm";
      if (in_array($cipher, openssl_get_cipher_methods()))
      {
          $ivlen = openssl_cipher_iv_length($cipher);
          $iv = openssl_random_pseudo_bytes($ivlen);
          $ciphertext = openssl_encrypt($plaintext, $cipher, $encryptionKey, $options=0, $iv, $tag);

          $fullObject = new stdClass();
          $fullObject->data = $ciphertext;
          $fullObject->iv = $iv;
          $fullObject->tag = $tag;
      }
      else
      {
        throw new ErrorException("Cipher not supported: ".$cipher);
      }
      return self::$connection->setex(self::$prefix . $key, $time, serialize($fullObject));
    }
    return false;
  }

  static function getDecrypted($encryptionKey, $key = null)
  {
    $value = self::get($key);
    if ($value !== false)
    {
      $cipher = "aes-128-gcm";
      if (in_array($cipher, openssl_get_cipher_methods()))
      {
        $originalSerialized = openssl_decrypt($value->data, $cipher, $encryptionKey, $options=0, $value->iv, $value->tag);
        return unserialize($originalSerialized);
      }
      else
      {
        throw new ErrorException("Cipher not supported: ".$cipher);
      }
    }
    return false;
  }

  static function get($key = null)
  {
    if ($key === null || $key === self::$lastKey)
    {
      return self::$lastGetResult;
    }

    if (self::load($key))
    {
      return self::$lastGetResult;
    }
    return false;
  }

  static function getRaw($key)
  {
    if (self::$enabled)
    {
      return self::$connection->get(self::$prefix . $key);
    }
    return false;
  }
  
  static function addRaw($key, $data, $time = 60)
  {
    if (self::$enabled)
    {
      //return apc_add(self::$prefix . $key, $data, $time);
      return self::$connection->setex(self::$prefix . $key, $time, $data);
    }
    return false;
  }
  
  static function stringGroupAdd($key, $stringValue)
  {
    if (self::$enabled)
    {
      //return apc_add(self::$prefix . $key, $data, $time);
      return self::$connection->sadd(self::$prefix . $key, $stringValue);
    }
    return false;
  }
  
  static function stringGroupRemove($key, $stringValue)
  {
    if (self::$enabled)
    {
      //return apc_add(self::$prefix . $key, $data, $time);
      return self::$connection->srem(self::$prefix . $key, $stringValue);
    }
    return false;
  }
  
  static function stringGroupHas($key, $stringValue)
  {
    if (self::$enabled)
    {
      //return apc_add(self::$prefix . $key, $data, $time);
      return (self::$connection->sismember(self::$prefix . $key, $stringValue) == 1);
    }
    return false;
  }
  
  static function stringGroupCount($key)
  {
    if (self::$enabled)
    {
      //return apc_add(self::$prefix . $key, $data, $time);
      return (INT)self::$connection->scard(self::$prefix . $key);
    }
    return false;
  }
  
  static function getStringGroup($key)
  {
    if (self::$enabled)
    {
      //return apc_add(self::$prefix . $key, $data, $time);
      return self::$connection->smembers(self::$prefix . $key);
    }
    return false;
  }
  
  static function setBit($key, $bit, $value)
  {
    if (self::$enabled)
    {
      //return apc_add(self::$prefix . $key, $data, $time);
      return self::$connection->setBit(self::$prefix . $key, $bit, $value);
    }
    return false;
  }
  
  static function bitCount($key)
  {
    if (self::$enabled)
    {
      //return apc_add(self::$prefix . $key, $data, $time);
      return self::$connection->bitCount(self::$prefix . $key);
    }
    return false;
  }
  
  static function setTTL($key, $time = 60)
  {
    if (self::$enabled)
    {
      //return apc_add(self::$prefix . $key, $data, $time);
      return self::$connection->expire(self::$prefix . $key, $time);
    }
    return false;
  }

  static function getTTL($key)
  {
    if (self::$enabled)
    {
      //return apc_add(self::$prefix . $key, $data, $time);
      return self::$connection->ttl(self::$prefix . $key);
    }
    return false;
  }
  
  static function add($key, $data, $time = 60)
  {
    if (self::$enabled)
    {
      //return apc_add(self::$prefix . $key, $data, $time);
      return self::$connection->setex(self::$prefix . $key, $time, serialize($data));
    }
    return false;
  }

  static function addIfNotExists($key, $data, $time = null)
  {
    if (self::$enabled)
    {
      //return apc_add(self::$prefix . $key, $data, $time);
      $ret = self::$connection->setNx(self::$prefix . $key, serialize($data));
      if ($ret === true && $time !== null)
      {
          self::$connection->expire(self::$prefix . $key, $time);
      }
      return $ret;
    }
    return false;
  }
  
  static function addRawIfNotExists($key, $data, $time = null)
  {
    if (self::$enabled)
    {
      //return apc_add(self::$prefix . $key, $data, $time);
      $ret = self::$connection->setNx(self::$prefix . $key, (STRING)$data);
      if ($time !== null)
      {
        self::$connection->expire(self::$prefix . $key, $time);
      }
      return $ret;
    }
    return false;
  }
  
  static function delete($key)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      return (self::$connection->del(self::$prefix . $key) == 1);
    }
    return false;
  }
  
  static function scoreListSetScore($key, $item, $score)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      return self::$connection->zAdd(self::$prefix . $key, $score, $item);
    }
    return false;
  }
  
  static function scoreListCount($key)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      return self::$connection->zCount(self::$prefix . $key, "-inf", "+inf");
    }
    return false;
  }
  
  static function scoreListIncrementScore($key, $item, $amount)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      return self::$connection->zIncrBy(self::$prefix . $key, $amount, $item);
    }
    return false;
  }
  
  static function scoreListCountBetweenScores($key, $start, $end)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      return self::$connection->zCount(self::$prefix . $key, $start, $end);
    }
    return false;
  }
  
  static function scoreListGetRange($key, $start, $end, $returnScores = true)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      return self::$connection->zRange(self::$prefix . $key, $start, $end, $returnScores);
    }
    return false;
  }
  
  static function scoreListGetRangeByScore($key, $fromMaxScore = "+inf", $toMinScore = 0, $returnScores = true, $limit = null, $offset = null)
  {
    if (self::$enabled)
    {
      $options = ["withscores" => $returnScores];
      if ($limit !== null)
      {
        $options["limit"]  = [(INT)$offset, $limit];
      }
      
      //return apc_delete(self::$prefix . $key);
      return self::$connection->zRevRangeByScore(self::$prefix . $key, $fromMaxScore, $toMinScore, $options);
    }
    return false;
  }
  
  static function scoreListGetRank($key, $item)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      return self::$connection->zRank(self::$prefix . $key, $item);
    }
    return false;
  }
  
  static function scoreListGetScore($key, $item)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      return self::$connection->zScore(self::$prefix . $key, $item);
    }
    return false;
  }
  
  static function scoreListIntersect($key, $keys, $weights = null, $method = "MAX")//MIN,MAX,SUM
  {
    if (self::$enabled)
    {
      $prefixedKeys = [];
      foreach ($keys as $k)
      {
        $prefixedKeys[] = self::$prefix . $k;
      }
      
      if ($weights === null)
      {
        return self::$connection->zInter(self::$prefix . $key, $prefixedKeys, null, $method);
      }
      else
      {
        return self::$connection->zInter(self::$prefix . $key, $prefixedKeys, $weights, $method);
      }
    }
    return false;
  }
  
  static function scoreListCombine($key, $keys, $weights = null, $method = "MAX")//MIN,MAX,SUM
  {
    if (self::$enabled)
    {
      $prefixedKeys = [];
      foreach ($keys as $k)
      {
        $prefixedKeys[] = self::$prefix . $k;
      }
      
      if ($weights === null)
      {
        return self::$connection->zUnion(self::$prefix . $key, $prefixedKeys, null, $method);
      }
      else
      {
        return self::$connection->zUnion(self::$prefix . $key, $prefixedKeys, $weights, $method);
      }
    }
    return false;
  }
  
  static function scoreListDeleteItem($key, $item)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      return self::$connection->zRem(self::$prefix . $key, $item);
    }
    return false;
  }
  
  static function hashSetField($key, $field, $value, $onlyIfNotExists = false)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      if (!$onlyIfNotExists)
      {
        return self::$connection->hSet(self::$prefix . $key, $field, $value);
      }
      else
      {
        return self::$connection->hSetNx(self::$prefix . $key, $field, $value);
      }
    }
    return false;
  }
  
  static function hashGetField($key, $field)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      return self::$connection->hGet(self::$prefix . $key, $field);
    }
    return false;
  }
  
  static function hashDeleteField($key, $field)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      return self::$connection->hDel(self::$prefix . $key, $field);
    }
    return false;
  }
  
  static function hashFieldExists($key, $field)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      return self::$connection->hExists(self::$prefix . $key, $field);
    }
    return false;
  }
  
  static function hashCount($key)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      return self::$connection->hLen(self::$prefix . $key);
    }
    return false;
  }
  
  static function hashSetFields($key, $fields)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      return self::$connection->hMset(self::$prefix . $key, $fields);
    }
    return false;
  }

  static function hashGetAll($key)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      return self::$connection->hGetAll(self::$prefix . $key);
    }
    return false;
  }
  
  static function listPush($key, $item, $left = true)//default is left because we use list limit a lot..
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      if ($left)
      {
        return self::$connection->lpush(self::$prefix . $key, $item);
      }
      else
      {
        return self::$connection->rpush(self::$prefix . $key, $item);
      }
    }
    return false;
  }
  
  static function listPop($key, $amount = 1)
  {
    if (self::$enabled)
    {
      //return apc_delete(self::$prefix . $key);
      if ($amount > 1)
      {
        return self::$connection->lpop(self::$prefix . $key, (INT)$amount);
      }
      else
      {
        return self::$connection->lpop(self::$prefix . $key);
      }
    }
    return false;
  }
  
  static function listRemove($key, $item, $amount = null, $removeFromLeftSide = true)
  {
    if (self::$enabled)
    {
      $amount = abs((INT)$amount);
      if (!$removeFromLeftSide)
      {
          $amount *= -1;
      }
      return self::$connection->lrem(self::$prefix . $key, $item, $amount);
    }
    return false;
  }

  static function listLimit($key, $num)//TODO: $keepNewest=true
  {
    if (self::$enabled)
    {
      if ($num > 0)
      {
        //return apc_delete(self::$prefix . $key);
        return (self::$connection->ltrim(self::$prefix . $key, 0, $num-1) == 1);
      }
    }
    return false;
  }
  
  static function getListRange($key, $from = 0, $to = -1)
  {
    if (self::$enabled)
    {
        //return apc_delete(self::$prefix . $key);
        return self::$connection->lrange(self::$prefix . $key, $from, $to);
    }
    return false;
  }
  
  static function exists($key)
  {
    if (self::$enabled)
    {
        //return apc_delete(self::$prefix . $key);
        return (self::$connection->exists(self::$prefix . $key) == 1);
    }
    return false;
  }
  
  static function linkObjectToKey($object, $identifier, $key, $time = 60)
  {
    if (self::$enabled)
    {
      if (!is_string($object))
      {
        $object = get_class($object);
      }

      return self::add("object_" . $object . "_" . $identifier, $key, $time);
    }
    return false;
  }

  static function clearByObject($object, $identifier)
  {
    exit("Cache::clearByObject = NOT YET IMPLEMENTED!");
  }

  static function clearByObjectType($object)
  {
    exit("Cache::clearByObjectType = NOT YET IMPLEMENTED!");
  }

}
 
class Solr extends Multiton
{
    private $solrOptions;
    //private $client;
    
    public function __construct()
    {
        $core = FrameworkSettings::$project_name."_products";
    
        $this->solrOptions = array
        (
            'hostname' => '(==|frameworksettings_solr_host|==)',
            'login'    => '(==|frameworksettings_solr_user|==)',
            'password' => '(==|frameworksettings_solr_password|==)',
            'port'     => 8983,
            'path'     => 'solr/' . $core,
        );
        
        //$this->client = new SolrClient($this->solrOptions);
    }
    
    public function getOptions()
    {
        return $this->solrOptions;
    }
}

TempTimer::measure("inline classes");

Cache::$prefix = FrameworkSettings::$cache_prefix;
if (FrameworkSettings::$cache_enabled)
{
  Cache::enable();
}

TempTimer::measure("cache");

class TemporaryRoutes
{

  private $routes;

  public function __construct()
  {
    $this->routes = Array();
  }

  public function addRoute(TemporaryRoute $route)
  {
    $this->routes[] = $route;
  }

  public function getMatchingRoute($route)
  {
    return null;
  }

}

class TemporaryRoute
{

  public function match($route)
  {
    return false;
  }

}

class URLRouter
{

  const SESSION_ROUTES_KEY = "urlrouter_session_routes";
  
  static function createSlug($input, $maxLength = null, $replacement = '-')
  {
    //use slug function from propel :)
    if (function_exists('iconv'))
    {
      $input = iconv('utf-8', 'us-ascii//TRANSLIT', $input);
    }

    // lowercase
    if (function_exists('mb_strtolower'))
    {
      $input = mb_strtolower($input);
    }
    else
    {
      $input = strtolower($input);
    }

    // remove accents resulting from OSX's iconv
    $input = str_replace(array('\'', '`', '^'), '', $input);

    // replace non letter or digits with separator
    $input = preg_replace('/[^\w%\/]+/u', $replacement, $input);

    // trim
    $input = trim($input, $replacement);

    if (empty($input))
    {
      return 'n-a';
    }

    if ($maxLength != null)
    {
      return substr($input, 0, $maxLength);
    }

    return $input;
  }

  static function deleteRouteByName($name)
  {
    $r = \DB\URLRouteQuery::create()->filterByName($name)->findOne();
    if ($r !== null)
    {
      Cache::delete("route:" . $r->getClassName() . ":" . $r->getFunctionName() . ":" . $r->getQueryString());
      $r->delete();
    }
    Cache::delete("route-name:" . $name);
  }
  
  static function makeRoute2($name, $rawRoute, $classFile, $className, $functionName = 'load', $queryString = null, $redirect = false, $canonical = false, $excludeQueryStringVariables = null)
  {
    $strQs = (STRING)$queryString;

    if (!Cache::load("route:" . $className . ":" . $functionName . ":" . $strQs) && !Cache::load("route-name:" . $name) || isSet($_GET["noroutecache"]))
    {
      //we kennen hem niet
      $route = \DB\URLRouteQuery::create()->filterByClassFile($classFile)->filterByClassName($className)->filterByFunctionName($functionName)->filterByRawRoute($rawRoute)->filterByQueryString($strQs)->orderById('desc')->findOneOrCreate();
      if ($route->isNew())
      {
        $route->setName($name);
        $route->save();
      }

      $dest = $route->getRoute();

      Cache::add("route:" . $className . ":" . $functionName . ":" . $strQs, $dest, 5 * 60); //5 minutes
      Cache::add("route-name:" . $name, $dest, 7 * 24 * 60 * 60);
    }
    else
    {
      $dest = Cache::get();
    }

    if ($redirect)
    {
      if ((STRING)PageContext::$CURRENT_PAGE->getPath() != (STRING)$dest)
      {
        //huidige get-vars ook toevoegen
        $qs = new QueryString();
        $qs->loadGetData(null, $excludeQueryStringVariables ?? ["ajax","form","gsearch","gclid"]);
        $qs->removeStringData($strQs);
        $url = new URL($dest, $qs);

        header('HTTP/1.1 301 Moved Permanently');
        header('Location: ' . $url);
        exit();
      }
    }
    else if ($canonical)
    {
      if ((STRING)PageContext::$CURRENT_PAGE->getPath() != (STRING)$dest)
      {
        //het is niet de echte pagina...
        $canonical = HTMLElement::getInstance("canonical", "link", Array("rel" => "canonical"));
        $qs = new QueryString();
        if ($className == get_class(PageContext::$CURRENT_PAGE->getPageHTMLElement()))
        {
          $qs->loadGetData(null, $excludeQueryStringVariables ?? ["ajax","form","gsearch","gclid"]);
          $qs->removeStringData($strQs);
        }
        $canonical->setAttribute("href", new URL($dest, $qs));

        //file_put_contents("canonical.txt", $_SERVER['REQUEST_URI'] . " > " . new URL($dest, $qs) . "\n", FILE_APPEND);

        HTMLElement::getInstance("head", "head")->addChild($canonical);
      }
    }

    //Cache::delete("route:".$className.":".$functionName.":".$strQs);
    return new URL($dest);
  }
  
  static function makeRoute($name, $rawRoute, $classFile, $className, $functionName = 'load', $queryString = null, $redirect = false, $canonical = false)
  {
    $strQs = (STRING)$queryString;
    
    if ((!Cache::load("route:" . $className . ":" . $functionName . ":" . $strQs) && !Cache::load("route-name:" . $name)) || isSet($_GET["noroutecache"]))
    {
      //we kennen hem niet
      $route = \DB\URLRouteQuery::create()->filterByClassFile($classFile)->filterByClassName($className)->filterByFunctionName($functionName)->filterByRawRoute($rawRoute)->filterByQueryString($strQs)->orderById('desc')->findOneOrCreate();
      if ($route->isNew())
      {
        $route->setName($name);
        $route->save();
      }

      $dest = $route->getRoute();

      Cache::add("route:" . $className . ":" . $functionName . ":" . $strQs, $dest, 5 * 60); //5 minutes
      Cache::add("route-name:" . $name, $dest, 5 * 60);
    }
    else
    {
      $dest = Cache::get();
    }

    if ($redirect)
    {
      if ((STRING)PageContext::$CURRENT_PAGE->getPath() != (STRING)$dest)
      {
        //huidige get-vars ook toevoegen
        $qs = new QueryString();
        $qs->loadGetData(["ajax","form","gsearch"]);
        $url = new URL($dest, $qs);

        header('HTTP/1.1 301 Moved Permanently');
        header('Location: ' . $url);
        exit();
      }
    }
    else if ($canonical)
    {
      if ((STRING)PageContext::$CURRENT_PAGE->getPath() != (STRING)$dest)
      {
        //het is niet de echte pagina...
        $canonical = HTMLElement::getInstance("canonical", "link", Array("rel" => "canonical"));
        $qs = new QueryString();
        if ($className == get_class(PageContext::$CURRENT_PAGE->getPageHTMLElement()))
        {
          $qs->loadGetData();
          $qs->removeStringData($strQs);
        }
        $canonical->setAttribute("href", new URL($dest, $qs));

        //file_put_contents("canonical.txt", $_SERVER['REQUEST_URI'] . " > " . new URL($dest, $qs) . "\n", FILE_APPEND);
        $current = PageContext::$CURRENT_PAGE->getURLRoute();
        if ($current !== null && ($current->getCanonicalid() === null))
        {
            $route = \DB\URLRouteQuery::create()->filterByClassFile($classFile)->filterByClassName($className)->filterByFunctionName($functionName)->filterByRawRoute($rawRoute)->filterByQueryString($strQs)->orderById('desc')->findOne();
            if ($route !== null)
            {
                $current->setCanonicalid($route->getId());
                $current->save();
            }
        }
        HTMLElement::getInstance("head", "head")->addChild($canonical);
      }
    }

    //Cache::delete("route:".$className.":".$functionName.":".$strQs);
    return new URL($dest);
  }

  static function getPageDataByURLRoute($route)
  {
    $lang = Language::getInstance();
    
    if (FrameworkSettings::$translation_enabled)
    {
      $languagePath = false;

      //Language part
      if (strlen($route) > 3 && $route[0] . $route[3] == "//")
      {
        $langCode = substr($route, 1, 2);
        if (Language::getInstance()->isAvailable($langCode))
        {
          $languagePath = true;
          Language::getInstance()->changeTo($langCode);
          $route = substr($route, 3);
        }
        else
        {
          //language not found
          exit("lnf 404 :)");
        }
      }
      else
      {
        //lets check custom paths :D
        $paths = $lang->getPaths();
        foreach ($paths as $code => $path)
        {
          if ($path == "")
          {
            //default path
            $languagePath = true;
            $lang->changeTo($code);
            //no break, we want to keep searching..
          }
          else if (strpos($route, $path) === 0)
          {
            //deze route is actief
            $languagePath = true;
            $lang->changeTo($code);
            $route = substr($route, strlen($path));
            break;
          }
        }
      }
    }

    TempTimer::measure("urlroute translation");

    $matchPath = null;
    $searchRoute = $route;

    if (strpos($route, "/virtual/images/remote") === 0)
    {
      include_once("php/pages/system/Image.php");
      $class = "ImagePage";
      $function = "load";
      $dbRoute = null;
    }
    else if (strpos($route, "/pages/") === 0)
    {
        //in case Nginx does not supply p and f values..
        //we have plans to keep nginx cleaner by using this code
        $routeSplit = explode("/", $route, 5);
                
        if (count($routeSplit) >= 4)
        {
            include_once("php/data/input/page/PageInput.php");
            $pageInput = new PageInput($routeSplit[3], (STRING)$routeSplit[2]);
        }
        else
        {
            include_once("php/data/input/page/PageInput.php");
            $pageInput = new PageInput($routeSplit[2], (STRING)"");
        }
        unset($_GET["p"]);
        unset($_GET["f"]);
        unset($_GET["urljunk"]);

        $route = $pageInput->getRoute();

        include_once($pageInput->getPath());
        $class = $pageInput->getClassName();
        $function = "load";
        $dbRoute = null;
    }
    else
    {
      //kleine snelheidsoptimalisatie
      if (strpos($route, "/virtual/images/") === 0)
      {
        $searchRoute = "/virtual/images/%";
      }
      else if (strpos($route, "/virtual/css/") === 0)
      {
        $searchRoute = "/virtual/css/%.css";
      }
      else if (strpos($route, "/virtual/js/") === 0)
      {
        $searchRoute = "/virtual/js/%.js";
      }

      TempTimer::measure("URLRoute before first query");
      //$routeData = \DB\URLRouteQuery::create()->filterByRoute($route, Criteria::EQUAL)->filterByLanguageCode($lang->getCode())->_or()->filterByLanguageCode('all')->findOne();
      $dbRoute = \DB\URLRouteQuery::create()->filterByRoute($searchRoute, Criteria::EQUAL)->filterByLanguageCode([$lang->getCode(), 'all'], Criteria::IN)->findOne();
      TempTimer::measure("URLRoute after first DB query");
      
      if ($dbRoute === null)
      {
        TempTimer::measure("DB\\URLRoute not found: ".$searchRoute);

        //kijken of we wildcard kunnen matchen
        $dbRoute = \DB\URLRouteQuery::create();
        //$routeData->addSelectColumn("urlroute.*");

        //onderstaande is een soort fix, omdat de columns in een andere volgorde in de live-db staan..
        $dbRoute->addSelectColumn("urlroute.id");
        $dbRoute->addSelectColumn("urlroute.name");
        $dbRoute->addSelectColumn("urlroute.rawroute");
        $dbRoute->addSelectColumn("urlroute.route");
        $dbRoute->addSelectColumn("urlroute.classfile");
        $dbRoute->addSelectColumn("urlroute.classname");
        $dbRoute->addSelectColumn("urlroute.functionname");
        $dbRoute->addSelectColumn("urlroute.querystring");
        $dbRoute->addSelectColumn("urlroute.languagecode");
        $dbRoute->addSelectColumn("urlroute.unique");
        $dbRoute->addSelectColumn("urlroute.notfound");
        $dbRoute->addSelectColumn("urlroute.canonicalid");
        $dbRoute->addSelectColumn("urlroute.sitemap");

        $dbRoute->addAsColumn('extra_column', 'LENGTH(urlroute.route)');
        $dbRoute->addDescendingOrderByColumn($dbRoute->getColumnForAs('extra_column'));
        $dbRoute->where("? LIKE urlroute.route", $route, PDO::PARAM_STR);

        $dbRoute = $dbRoute->findOne();
      }
      
      if ($dbRoute !== null)
      {
        TempTimer::measure("\\DB\\URLRoute found");

        $matchPath = $dbRoute->getRoute();
        //exit("route done".$routeData->getId());
        //set the getdata, a little hackish.. :)
        $qs = (STRING)$dbRoute->getQueryString();
        if ($qs != "" && $qs[0] == "?")
        {
          $old = Array();
          parse_str(substr($qs, 1), $old);

          $_GET = array_merge($old, $_GET); //huidige shit er wel overheen schrijven
          $_REQUEST = array_merge($old, $_REQUEST); //huidige shit er wel overheen schrijven
          unset($old);
        }

        include_once($dbRoute->getClassFile());
        $class = $dbRoute->getClassName();
        $function = $dbRoute->getFunctionName();
      }
      else
      {
        include_once("php/pages/FileNotFound.php");
        $class = "FileNotFoundPage";
        $function = "load";

        $matchPath = $route;
        $route = "/pages/FileNotFoundPage";
      }
    }

    TempTimer::measure("Controller loaded");
    
    return ["class" => $class, "function" => $function, "matchPath" => $matchPath, "route" => $route, "dbRoute" => $dbRoute];
  }
  
  static function link($urlRouteName, $alternative = null)
  {
    //return URL
    if (!Cache::load("route-name:" . $urlRouteName) || isSet($_GET["noroutecache"]))
    {
      $route = \DB\URLRouteQuery::create()->filterByName($urlRouteName)->orderById('desc')->findOne();
      if ($route !== null)
      {
        Cache::add("route-name:".$urlRouteName, $route->getRoute(), 14*24*60*60);
        return new URL($route->getRoute());
      }
      //kijken of we op een andere manier kunnen achterhalen wat we bedoelen :)
      $pos = strrpos($urlRouteName, "-");
      if ($pos !== false)
      {
        $name = ucfirst(substr($urlRouteName, 0, $pos)) . "Routes";
        $path = "php/data/routes/" . $name . ".php";

        $file = FrameworkTools::getFileIncludePath($path);
        if ($file !== null)
        {
          include_once($path);
          $router = new $name();
          return $router->link($urlRouteName);
        }
      }

      if (is_callable($alternative))
      {
        return $alternative();
      }

      return $alternative;
    }
    else
    {
      //hij zit in de cache
      return new URL(Cache::get());
    }
  }

  static function linkFunction($className, $functionName = 'load', $queryString = null)
  {
    //return URL
    $strQs = (STRING)$queryString;
    if (!Cache::load("route:" . $className . ":" . $functionName . ":" . $strQs))
    {
      $route = \DB\URLRouteQuery::create()->filterByClassName($className)->filterByFunctionName($functionName)->filterByQueryString($strQs)->findOne();
      if ($route !== null)
      {
        //Cache::add("route:".$className.":".$functionName.":".$strQs, $route->getRoute(), 5*60);
        return new URL($route->getRoute());
      }
      return null;
    }
    else
    {
      //hij zit in de cache
      return new URL(Cache::get());
    }
  }

}

class EventDispatcher extends FWObject
{
  private $globalListenersLoaded;

  public function __construct()
  {
    parent::__construct();

    $this->globalListenersLoaded = [];
  }

  private function addEventListenerByIncludeObject($type, $includeObject)
  {
    $this->addEventListener($type, function($event) use ($includeObject)
    {
      include_once $includeObject->includeFile;

      if (class_exists($includeObject->className, false))
      {
        if (method_exists($includeObject->className, 'getInstance'))
        {
          $obj = $includeObject->className::getInstance();
        }
        else
        {
          $className = $includeObject->className;
          $obj = new $className();
        }

        if (is_callable($obj))
        {
          return $obj($event);
        }
        else
        {
          error_log(__CLASS__ . ": class '" . $includeObject->className . "' is not callable in file '" . $includeObject->includeFile . "'");
        }
      }
      else
      {
        error_log(__CLASS__ . ": class '" . $includeObject->className . "' not found in file '" . $includeObject->includeFile . "'");
      }

    });
  }

  private function getEventSpace()
  {
    $arg = $this->getMultitonArg();
    if ($arg == 0)
    {
      return "global";
    }
    return $arg;
  }

  private function loadGlobalListeners($type)
  {
    $this->globalListenersLoaded[$type] = true;

    TempTimer::measure("Before loading global listeners '".$type."'");
    include_once "php/data/filesystem/includesearch/IncludeSearch.php";
    $is = new IncludeSearch();
    
    //error_log("Loading global listeners for type: " . $type);

    $includeObjects = $is->getFilesInFolder("php/events/listeners/".$this->getEventSpace()."/".$type."/", "*", ".php");
    foreach ($includeObjects as $includeObject)
    {
      //error_log("Found: " . print_r($includeObject, true));
      $this->addEventListenerByIncludeObject($type, $includeObject);
    }
    TempTimer::measure("Global Eventlisteners Listeners loaded '".$type."'");
  }

  public function dispatchEvent(Event $event)
  {
    $type = $event->getEventType();
    if (!isset($this->globalListenersLoaded[$type]))
    {
      $this->loadGlobalListeners($type);
    }
    
    //loggen voor documentatie
    if (FrameworkSettings::$log_global_events && $this->getMultitonKey() !== null)
    {
      /*$user = SH::getUser();
      
      $log = new \DB\GlobalEventLog();
      $log->setUser($user);
      if (RequestLog::hasInstance())
      {
        $log->setRequestLog(RequestLog::getInstance()->getData());
      }
      $log->setClass(get_class($event));
      $log->setType($event->getEventType());
      $log->setData($event->getLogData());
      $log->save();*/
    }

    return parent::dispatchEvent($event);
  }

}

class Storage extends FWObject
{
  public function __construct()
  {
    parent::__construct();
  }
  
  public function writeFile($fileName, $data, $flags = 0, $context = null)
  {
    if ($context === null)
    {
        return @file_put_contents($fileName, $data, $flags);
    }
    return @file_put_contents($fileName, $data, $flags, $context);
  }
  
  public function moveFile($from, $to)
  {
      return rename($from, $to);
  }
}

class HTML
{
	static $templates = [];
	static $classNames = [];
    static $templateNames = [];
	
    public static function addTemplateOnceByName($templateName, $aliasses = null)
    {
        if ($aliasses === null)
        {
            $aliasses = [];
        }
        $templatePath = $templateName;
        if (strpos($templateName, "/") !== false)
        {
            $templateName = "\\Template\\".str_replace("/","\\", $templateName);
            $split = explode("\\", $templateName);
            $aliasses[] = end($split);
        }
        else
        {
            $aliasses[] = $templateName;
            $templateName = "\\Template\\".$templateName;
        }
        
        if (!isSet(self::$classNames[$templateName]))
        {
            $file = "php/templates/".$templatePath.".php";
            $realFile = stream_resolve_include_path($file);
            if ($realFile !== false)
            {
                include_once($realFile);
                $template = new $templateName();
                self::addTemplateOnce($template, $aliasses);
                return $template;
            }
        }
        else if ($aliasses !== null)
        {
            $template = self::$templates[self::$classNames[$templateName]];
            self::addTemplateOnce($template, $aliasses);
            return $template;
        }
        return false;
    }
    
	public static function addTemplateOnce($template, $aliasses = null)
	{
        if (is_string($template))
        {
            throw new Exception("Can't use static methods as a HTML template in class HTML");
        }
		$index = array_search($template, self::$templates);
		if ($index === false)
		{
			$index = count(self::$templates);
            self::$classNames[get_class($template)] = $index;
            self::$templates[$index] = $template;
        }
		
		if ($aliasses !== null)
		{
			foreach ($aliasses as $alias)
			{
                if (!isSet(self::$classNames[$alias]))
                {
                    self::$classNames[$alias] = $index;
                }
			}
		}
	}
	
	public static function __callStatic($name, $arguments)
	{
		$class = ucfirst($name);
		$name = array_shift($arguments);
		$argument = array_values($arguments);
        
		if (isSet(self::$classNames[$name]))
		{
			$template = self::$templates[self::$classNames[$name]];
			if (method_exists($template, $name))
			{
				return call_user_func_array([$template, $name], $arguments);
			}
		}
		
		foreach (self::$templates as $template)
		{
			if (method_exists($template, $name))
			{
				//het kan
				return call_user_func_array([$template, $name], $arguments);
			}
		}
		throw new Exception("Method '".$name."' does not exist within templates: '.implode(", ", array_keys(self::$classNames)).'");
		return null;
	}
}

class Page
{

  /**
   * Contains the HTMLObject/HTML5Page of the Page
   * @var HTMLObject|HTML5Page
   */
  private $pageHTMLElement;
  private $dynamicPage;
  private $layout;
  private $view;
  private $path;
  private $pathSplit;
  private $matchPath;
  private $dbURLRoute;
  private $url;
  private $domain;
  private $languages;
  private $redirect;
  private $redirectCallback;
  private $finishCallbacks;

  public function __construct($pageHTMLElement = null, $path = "", $matchPath = null, $dbURLRoute = null, $languages = Array('all'))
  {
    $this->domain = FrameworkSettings::$domain;
    $this->pageHTMLElement = $pageHTMLElement;
    $this->dynamicPage = null;
    $this->layout = null;
    $this->view = null;

    $this->url = "http://" . $this->domain . $path;
    $this->path = $path;
    $this->pathSplit = null;
    $this->matchPath = $matchPath;
    $this->dbURLRoute = $dbURLRoute;
    $this->languages = $languages;
    $this->redirect = null;
    $this->redirectCallback = null;
    $this->finishCallbacks = [];
  }

  public function getPathVariable($index)
  {
    if ($this->pathSplit === null)
    {
      $this->pathSplit = explode("/", $this->path);
    }
    $index++;//skip de eerste
    if (isSet($this->pathSplit[$index]))
    {
      return strtolower($this->pathSplit[$index]);
    }
    return null;
  }
  
  public function getLanguageURLs($includeCurrentLanguage = false)
  {
    $ret = Array();
    if ($this->matchPath !== null)
    {
      $path = $this->matchPath;
    }
    else
    {
      $path = $this->route;
    }

    $langCode = Language::getInstance()->getCode();

    if ($includeCurrentLanguage)
    {
      $ret[$langCode] = new URL(null, null, null, $langCode);
    }

    $ts = \DB\TranslationQuery::create()->filterByFrom((STRING)Language::getInstance()->getCode())->filterByText((STRING)$path)->find();
    foreach ($ts as $t)
    {
      if (strpos((STRING)$path, "%") !== false)
      {
        $route = $this->path; //we nemen het originele pad en gaan daar in replacen
        $parts = explode("%", (STRING)$path); //het matchpath opsplitsen
        $parts2 = explode("%", $t->getTranslation());
        while (count($parts) > 0 && count($parts2) > 0)
        {
          $replaces = 1;
          $route = str_replace(array_shift($parts), array_shift($parts2), $route, $replaces);
        }
        //replacen gelukt..
      }
      else
      {
        $route = $t->getTranslation();
      }
      $ret[(STRING)$t->getTo()] = new URL($route, null, null, (STRING)$t->getTo());
    }

    foreach ($this->languages as $language)
    {
      if ($language == "all")
      {
        foreach (Language::getInstance()->getAvailableLanguages() as $language)
        {
          if (!isSet($ret[$language]))
          {
            //zelfde url voor deze taal..
            $ret[$language] = new URL(null, null, null, $language);
          }
        }
        break;
      }
      $ret[$language] = new URL(null, null, null, $language);
    }

    return $ret;
  }

  public function setPageHTMLElement($pageHTMLElement)
  {
    $this->pageHTMLElement = $pageHTMLElement;
  }

  public function getDomain()
  {
    return $this->domain;
  }

  public function getURL()//depricated
  {
    return $this->url;
  }

  public function getPath()
  {
    return $this->path;
  }

  public function getMatchPath()
  {
    return $this->matchPath;
  }

  public function getURLRoute()
  {
      return $this->dbURLRoute;
  }
  
  public function setLayout($layout)
  {
    $this->layout = $layout;
  }

  public function getLayout()
  {
    return $this->layout;
  }

  public function getDynamicPage()
  {
    return $this->dynamicPage;
  }
  
  public function setDynamicPage($page)
  {
    $this->dynamicPage = $page;
  }
  
  public function getPageHTMLElement()
  {
    return $this->pageHTMLElement;
  }

  public function setRedirect($url, $callback = null)
  {
    $this->redirect = $url;
    $this->redirectCallback = $callback;
  }
  
  public function getFinishCallbacks()
  {
    return $this->finishCallbacks;
  }

  public function addFinishCallback($callback)
  {
    if (is_callable($callback))
    {
      $this->finishCallbacks[] = $callback;
    }
    else
    {
      throw new ErrorException("Finish callback is not callable");
    }
  }

  public function display()
  {
    if ($this->redirect === null)
    {
      if ($this->pageHTMLElement !== null)
      {
        $this->pageHTMLElement->outputHTML();
        TempTimer::measure("Output HTML");
      }
    }
    else
    {
        if (isset($_GET["ajax"]) && $_GET["ajax"] == 1)
        {
            $r = Vue::getInstance()->response();
            $r->setRedirect($this->redirect);
            if ($this->redirectCallback !== null)
            {
                if (is_callable($this->redirectCallback))
                {
                    call_user_func($this->redirectCallback, $r);
                }
                else
                {
                    throw new ErrorException("Redirect callback is not callable");
                }
            }
            echo $r;
        }
        else
        {
            header("Location: ".$this->redirect);
            if ($this->redirectCallback !== null)
            {
                if (is_callable($this->redirectCallback))
                {
                    call_user_func($this->redirectCallback, null);
                }
                else
                {
                    throw new ErrorException("Redirect callback is not callable");
                }
            }
        }
      TempTimer::measure("Redirect");
    }
  }
}

TempTimer::measure("more inline classes");

try
{
  if (FrameworkSettings::$propel_version == "2")
  {
      require_once '../vendor/autoload.php';
      TempTimer::measure("composer autload");
      require_once '../generated-conf/config.php';
      include_once("php/tools/PropelTwo.php");
      
  }
  else
  {
    require_once '(==|frameworksettings_propel1_path|==)';
    @Propel::init("../build/conf/" . FrameworkSettings::$project_name . "-conf.php");
  }
}
catch (Exception $e)
{
  //configuratie checken..
  if (file_exists("php/pages/Install.php"))
  {
    //installatie geslaagd.. er is dus iets mis met propel!
    exit("Propel error!");
  }
  else
  {
    //we zitten in de installatie!
    unset($_GET["urlroute"]);
    unset($_GET["f"]);
    $_GET["p"] = "install";
  }
}

TempTimer::measure("propel init");

//set language default
$lang = Language::getInstance(null, "(==|frameworksettings_default_language|==)", (==|frameworksettings_languages|==));
$lang->setPath("(==|frameworksettings_default_language|==)", "");

TempTimer::measure("language init");

if ((FrameworkSettings::$ssl && !isSet($_SERVER["HTTPS"])) || (!FrameworkSettings::$ssl && isSet($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on"))
{
  //redirect to HTTPS
  $qs = new QueryString();
  $qs->loadGetData();
  $uriSplit = explode("?", $_SERVER["REQUEST_URI"]);
  $url = new URL(reset($uriSplit), $qs, FrameworkSettings::$domain);

  header('HTTP/1.1 301 Moved Permanently');
  header('Location: ' . $url);
  exit();
}

//als we alles in een transactie willen uitvoeren.. hieronder kan het :)
$preview = false;

if ($preview)
{
  //een kleine hack om onze transactions voor elkaar te krijgen
  $con = Propel::getConnection('moj', Propel::CONNECTION_READ); //geeft onze slave server terug..
  //de slave server werkt in een transaction, zodat zijn updates niet worden weggeschreven maar worden gerollbackt
  $con->beginTransaction();

  //in preview mode moeten we onze writes wegschrijven in de transaction
  $esmee = SDMEmailQuery::create()->filterById(690)->findOne();
  $esmee->setFirstName("Esmee gefaked");
  //print_r($esmee->getModifiedColumns());
  $esmee->save($con);
}

TempTimer::measure("some checks");

if ((==|frameworksettings_development_mode|==))
{
    include_once "php/applications/developer/modules/DeveloperPanelQueryCountModule.php";
    if (DeveloperPanelQueryCountModule::queryCountEnabled())
    {
      //enable debug mode
      Propel::setForceMasterConnection(true); //lets use a single connection for easy counting :D
      $con = Propel::getConnection();
      $con->useDebug(true);
    }
    
    TempTimer::measure("query counter");
}



if ($getData->get("observe") !== null)
{
  $sh->setVar("observe", $getData->get("observe"));
}


if ($sh->getVar("observe") == "1")
{

  class ObserverData
  {

    static $interrupted = true;

  }

  //register exit handler
  function shutdown()
  {
    chdir(__DIR__);

    include_once("php/data/input/get/GetData.php");
    $g = new GetData();

    if ($g->get("ajax") == "1")
    {
      //ajax calls gaan we niet loggen...
      return;
    }

    //contents
    $contents = ob_get_contents();
    ob_end_clean();

    $window = new DB\ObserveWindow();
    $window->setCreateDate('now');
    $window->setHTML($contents);
    $window->setURL(new URL(null, new QueryString(null, true)));
    $user = SH::getUser();
    $window->addUser($user);
    $window->save();

    //we gaan eerst kijken
    if (ObserverData::$interrupted)//als hij plotseling shutdownt, gaan we dit doen...
    {
      //het is een exit geweest..
      //de dingen inbouwen en outputten
    }
    else
    {
      //het blijkt een normale page te zijn, nu kan het laden makkelijker als het goed is :)
    }

    //outputten
    echo $contents;
  }

  register_shutdown_function('shutdown');

  //output gaan we vangen
  ob_start();
}

//Page inits here!!
TempTimer::measure("observe functionality");

if ($getData->get("p") === null && isSet($_SERVER["REQUEST_URI"]))
{
  //voor PHP-FPM :)
  $uriSplit = explode("?",$_SERVER["REQUEST_URI"]);
  $getData->set("urlroute", reset($uriSplit));
  //print_r($_SERVER);
  //exit();
}

$block = false;
if (FrameworkSettings::$maintenance_mode && !FrameworkSettings::$cli && !in_array($_SERVER["REMOTE_ADDR"], FrameworkSettings::$developer_ips) && ($sh->getVar("skip-maintenance") === null || !$sh->getVar("skip-maintenance")))
{
  if (isset($_GET["key"]) && $_GET["key"] == "1")
  {
      //skip
      $sh->setVar("skip-maintenance", true);
  }
  else
  {
    $block = true;
    if ($getData->get("urlroute") !== null)
    {
        if (strpos($getData->get("urlroute"), '/css') === 0)
        {
            $block = false;
        }
        else if (strpos($getData->get("urlroute"), '/virtual') === 0)
        {
            $block = false;
        }
        else if (strpos($getData->get("urlroute"), '/images') === 0)
        {
            $block = false;
        }
        
    }
    else
    {
        if ($getData->get("p") == "DownloadFramework")
        {
            $block = false;
        }
    }
  }
}

if ($block)
{
    $protocol = "HTTP/1.0";
    if ("HTTP/1.1" == $_SERVER["SERVER_PROTOCOL"])
    {
      $protocol = "HTTP/1.1";
    }
    header($protocol . " 503 Service Temporarily Unavailable", true, 503);
    header('Status: 503 Service Temporarily Unavailable');
    header('Retry-After: ' . (2 * (3600))); //uren 

    //echo "<!-- IP:" . $_SERVER["REMOTE_ADDR"] . " -->";
    include_once("php/pages/Maintenance.php");
    $class="MaintenancePage";
    $function="load";
    $dbRoute=null;
    $route=null;
    $matchPath=null;
}
else if ($getData->get("urlroute") !== null)
{
  $route = $getData->get("urlroute");
  unset($_GET["urlroute"]);

  $pageData = URLRouter::getPageDataByURLRoute($route);
  
  $class = $pageData["class"];
  $function = $pageData["function"];
  $dbRoute = $pageData["dbRoute"];
  $route = $pageData["route"];
  $matchPath = $pageData["matchPath"];
  
}
else
{ 
  include_once("php/data/input/page/PageInput.php");
  $pageInput = new PageInput($getData->get("p"), (STRING)$getData->get("f"));

  unset($_GET["p"]);
  unset($_GET["f"]);
  unset($_GET["urljunk"]);

  $route = $pageInput->getRoute();

  $matchPath = null;

  include_once($pageInput->getPath());
  $class = $pageInput->getClassName();
  $function = "load";
  $dbRoute = null;
  
  TempTimer::measure("Controller loaded");
}



//RequestLog::getInstance();

TempTimer::measure("Requestlog");

PageContext::$WEBP = (isset($_SERVER['HTTP_ACCEPT']) && strpos( $_SERVER['HTTP_ACCEPT'], 'image/webp' ) !== false);
PageContext::$AUTH = Auth::getInstance();
$app = PageContext::getInstance(); //global application context
$page = new Page(null, $route, $matchPath, $dbRoute);
$app->addPage($page);
$app->switchToPage($page);

TempTimer::measure("PageContext");

class PluginData
{
  
  public function __construct()
  {
    
  }

} 
$pluginData = new PluginData();

TempTimer::measure("PluginData");

//register shutdown function
$shutdownFunc = function() {

  chdir(FrameworkSettings::$public_folder);//we need this for everything to work properly
  //error_log("index.php: Shutdown function called, running finish callbacks...");
  $callbacks = PageContext::$CURRENT_PAGE->getFinishCallbacks();
  if (!empty($callbacks))
  {
    if (!function_exists('fastcgi_finish_request')) {
      error_log("index.php: fastcgi_finish_request() not available, callbacks will run anyway.");
    }
    else
    {
      // Only works with FastCGI (php-fpm + nginx)
      fastcgi_finish_request();
    }

    //error_log("index.php: Running finish callbacks after page display...");
    foreach ($callbacks as $callback)
    {
      call_user_func_array($callback, []);
    } 

  }
};

register_shutdown_function($shutdownFunc);

//always load JS and CSS support
include_once("php/js/JS.php");

TempTimer::measure("JS.php");

include_once("php/css/CSS.php");
TempTimer::measure("CSS.php");
$pageHTMLElement = new $class();
$page->setPageHTMLElement($pageHTMLElement);

TempTimer::measure("Page __construct()");



//call the init function
if ($getData->get("method") !== null)
{
  $methodName = (STRING)$getData->get("method");
  if (strpos($methodName, "ajax") === 0)
  {
    include_once("php/data/input/request/RequestData.php");
    $requestData = new RequestData();
    
    header("Content-Type: application/json");
    $function = $methodName;
    
    try {
      $args = $requestData->get("arguments");
      if (!is_array($args))
      {
        $args = (array)json_decode((STRING)$args);
      }
      if (is_callable([$pageHTMLElement, $function]))
      {
        $ret = call_user_func_array([$pageHTMLElement, $function], $args);
      }
      else
      {
        //invalid method, display error, and try to redirect
        $ret = [
          "status" => "error", 
          "message" => "Oops.. something went wrong...", 
          "alert" => "Oops.. something went wrong", 
          "redirect" => (STRING)new URL(null, new QueryString(null, true, null, ["method"]))
        ];
      }
    }
    catch (Exception $e)
    {
      error_log("Exception: ".$e->getFile()." (".$e->getLine().") -> ".$e->getMessage());
      
      if (SessionAuth::isAdmin())
      {
        $message = $e->getMessage();
      }
      else
      {
        $message = "Oops.. something went wrong...";
      }

      if (Vue::getInstance()->hasResponse())
      {
          $ret = Vue::getInstance()->response;
          $ret->setProp("status", "error");
          $ret->setProp("message", $message);
      }
      else
      {
        $ret = ["status" => "error", "message" => $message];
      }
    }
    catch (Error $e)
    {
      error_log("Error: ".$e->getFile()." (".$e->getLine().") -> ".$e->getMessage());
      
      if (SessionAuth::isAdmin())
      {
        $message = $e->getMessage();
      }
      else
      {
        $message = "Oops.. something went wrong...";
      }

      if (Vue::getInstance()->hasResponse())
      {
          $ret = Vue::getInstance()->response;
          $ret->setProp("status", "error");
          $ret->setProp("message", $message);
      }
      else
      {
        $ret = ["status" => "error", "message" => $message];
      }
    }
    
    if ($ret !== null)
    {
        if ($ret instanceof JSData)
        {
            header('Content-Type: text/javascript');
            echo (STRING)$ret;
        }
        else
        {
            echo json_encode($ret, JSON_PRETTY_PRINT);
        }
        TempTimer::measure("Controller '".$function."' called");
        exit();
    }
  }
  else if (FrameworkSettings::$cli && strpos($methodName, "cli") === 0 && strlen($methodName) > 3 && ctype_upper($methodName[3]))
  {
        $function = $methodName;
        
        include_once("php/data/input/request/RequestData.php");
        $requestData = new RequestData();
        $args = $requestData->get("arguments");
        if (!is_array($args))
        {
          $args = (array)json_decode((STRING)$args);
        }
        
        $outputKey = (STRING)$requestData->get("outputkey", "system");
        
        try {
            $pid = getmypid();
            Cache::delete("return_pid_".$outputKey."_".$pid);
            $ret = call_user_func_array([$pageHTMLElement, $function], $args);
            
            if ($ret instanceof Generator)
            {
                Cache::delete("generator_pid_".$outputKey."_".$pid);
                foreach ($ret as $out)
                {
                    Cache::listPush("generator_pid_".$outputKey."_".$pid, serialize($out));
                    Cache::setTTL("generator_pid_".$outputKey."_".$pid, 20);
                }
                
                $ret = $ret->getReturn();
            }
            
        } catch (Exception $e) {
            error_log($e->getFile()." (".$e->getLine().") -> ".$e->getMessage());
            $ret = null;
        }
        
        Cache::add("return_pid_".$outputKey."_".$pid, $ret, 10);
        exit();
  }
  else
  {
      /*var_dump(FrameworkSettings::$cli);
      var_dump(strpos($methodName, "cli"));
      var_dump(strlen($methodName));
      var_dump(ctype_upper($methodName{3}));*/
      error_log("index.php: Some bad formatted method called: ".$methodName);
      //$pageHTMLElement->$function();
  }
}
else
{
  $pageHTMLElement->$function();
}

TempTimer::measure("Controller '".$function."' called");

function loadPlugin($timing, $urlroute = null, $urlrouteId = null, $pageClass = null)
{
  global $pluginData;
  $plugins = \DB\PluginQuery::create()->filterByTiming($timing);

  $parts = Array();
  if ($urlroute !== null)
  {
    $parts[] = "urlroute";
    $plugins->condition("urlroute-select", "DB\\Plugin.Selection = ?", "urlroute");
    $plugins->condition("urlroute-value", "DB\\Plugin.SelectionValue = ?", $urlroute);
    $plugins->combine(Array("urlroute-select","urlroute-value"), "and", "urlroute");
  }
  if ($urlrouteId !== null)
  {
    $parts[] = "urlroute_id";
    $plugins->condition("urlroute_id-select", "DB\\Plugin.Selection = ?", "urlroute_id");
    $plugins->condition("urlroute_id-value", "DB\\Plugin.SelectionValue = ?", $urlrouteId);
    $plugins->combine(Array("urlroute_id-select","urlroute_id-value"), "and", "urlroute_id");
  }
  if ($pageClass !== null)
  {
    $parts[] = "pageclass";
    $plugins->condition("pageclass-select", "DB\\Plugin.Selection = ?", "pageclass");
    $plugins->condition("pageclass-value", "DB\\Plugin.SelectionValue = ?", $pageClass);
    $plugins->combine(Array("pageclass-select","pageclass-value"), "and", "pageclass");
  }

  if (count($parts) > 0)
  {
    $plugins = $plugins->where($parts, 'or')->orderByOrder("asc")->find();
  }
  else
  {
    $plugins = Array();
  }

  foreach ($plugins as $plugin)
  {
    if ($plugin->getFile() != "")
    {
      include_once($plugin->getFile());
    }
    $class = $plugin->getClassName();
    $obj = new $class();
    if (method_exists($obj, "setDBPlugin"))
    {
      $obj->setDBPlugin($plugin);
    }
    if (method_exists($obj, "setPluginData"))
    {
      $obj->setPluginData($pluginData);
    }
    if (method_exists($obj, "run"))
    {
      $obj->run();
    }
  }
}

function pageComplete()
{
  global $con, $sh, $lang, $sa, $developerpanel;

  TempTimer::measure("Page fully loaded");
  
  //deze halen we opnieuw op omdat dit veranderd kan zijn :)
  $pageHTMLElement = PageContext::$CURRENT_PAGE->getPageHTMLElement();

  if ($pageHTMLElement !== null)
  {
    //application finished.. lets do some magic hooking..
    //translation is last..
    //$lang = Language::getInstance();
    $langCode = (STRING)$lang->getCode();

    if (FrameworkSettings::$translation_enabled && $langCode !== Language::MAIN)
    {
      $translateAdminEnabled = ($sa->isAdmin() || $sa->isDeveloper());

      if ($translateAdminEnabled)
      {
        //translation module
        include_once("php/applications/developer/modules/DeveloperPanelTranslationModule.php");
        $dpmodule = DeveloperPanelTranslationModule::getInstance();
        $developerpanel->addModule($dpmodule);
      }

      //text vertalen
      $texts = $pageHTMLElement->getTextElements(true);
      foreach ($texts as $text)
      {
        $tl = $text->getLanguage();
        if ($tl === null)
        {
          $tl = Language::MAIN;
        }
        if ((STRING)$tl !== (STRING)$langCode)
        {
          //we need a translation
          $id = $text->translate((STRING)$langCode);

          if ($translateAdminEnabled)
          {
            //er is vertaald.. we willen dit doorgeven aan het developer panel :)
            $dpmodule->addTextTranslation((INT)$id, $text, $tl, $langCode);
          }
        }
      }

      //input values vertalen
      //meta stuff vertalen.
      //nog meer??
      //vertalingsmodule inschakelen
    }

    TempTimer::measure("TextElement translation");

    //developer panel :)
    if ($sa->isDeveloper())
    {
      $developerpanel->show();

      //include_once "php/applications/developer/modules/DeveloperPanelIncludesModule.php";
      //$developerpanel->addModule(DeveloperPanelIncludesModule::getInstance());

      if ((==|frameworksettings_development_mode|==))
      {
          $qcmodule = DeveloperPanelQueryCountModule::getInstance();
          $developerpanel->addModule($qcmodule); //module inschakelen

          if (DeveloperPanelQueryCountModule::queryCountEnabled())
          {
            $qcmodule->setNumQueries($con->getQueryCount());
          }
      }

      $mem = HTMLElement::getInstance("dp_memory", "p");
      $mem->setText("Memory usage: " . (INT)(memory_get_usage() / 1000000) . "Mb");
      $developerpanel->addModule($mem);

      include_once "php/applications/developer/modules/DeveloperPanelCSSEditorModule.php";
      $developerpanel->addModule(DeveloperPanelCSSEditorModule::getInstance());

      //include_once "php/applications/developer/modules/DeveloperPanelImageModule.php";
      //$developerpanel->addModule(DeveloperPanelImageModule::getInstance());

      //load error popups :)
      include_once "php/applications/developer/modules/DeveloperPanelPHPErrorsModule.php";
      $developerpanel->addModule(DeveloperPanelPHPErrorsModule::getInstance());
    }
    else if ($sa->isAdmin())
    {
      $developerpanel->show();

      include_once "php/applications/developer/modules/DeveloperPanelCSSEditorModule.php";
      $developerpanel->addModule(DeveloperPanelCSSEditorModule::getInstance());

      //include_once "php/applications/developer/modules/DeveloperPanelImageModule.php";
      //$developerpanel->addModule(DeveloperPanelImageModule::getInstance());
    }

    TempTimer::measure("DeveloperPanel finished");

    if ($sh->getVar("observe") == "1")
    {
      //het blijkt dat we gewoon kunnen returnen..
      ObserverData::$interrupted = false;
    }

    if (isSet($_GET["confetti"]))
    {
      include_once "php/js/JS.php";
      JS::getInstance()->addScript(new Confetti());
      $confettiDiv = new HTMLElement("div", Array("id" => "confetti", "class" => "noselect"));
      $confettiDiv->setText(" ");
      HTMLElement::getInstance("body")->addChildAt($confettiDiv, 0);
    }

    CSS::getInstance()->addToHead();

    TempTimer::measure("Custom CSS to head");

    if (isset($_REQUEST["ajax"]) && (!isset($_REQUEST["simple"]) || $_REQUEST["simple"] === "0"))
    {
      include_once "php/js/JS.php";
      $js = JS::getInstance();
      $ajaxHolder = new HTMLElement("div", Array("style" => "display: none; visibility: hidden;"));
      $ajaxHolder->addClass("ajaxcodeholder");

      $el = new HTMLElement("script");
      $el->setText((STRING)$js->getAjaxCode());
      $ajaxHolder->addChild($el);

      $js->disable();

      $added = false;
      $holder = HTMLElement::getInstance("body", "body");
      while ($holder->getParent() !== null)
      {
        $holder = $holder->getParent();
        if ($holder === $pageHTMLElement)
        {
          //de body hangt aan de page
          $body = HTMLElement::getInstance("body", "body");
          $body->setElementName("div");//transform into a div
          $body->setAttribute("id", null);
          $body->addChildAt($ajaxHolder, 0);

          //we returnen alleen de body inclusief javascript injection
          $pageHTMLElement->removeAllChildren();
          $pageHTMLElement->addChild($body);
          $added = true;
          break;
        }
      }

      header("X-Robots-Tag: noindex, nofollow", true);
      
      if (!$added)
      {
        $pageHTMLElement->addChild($ajaxHolder); //just add it
      }

      TempTimer::measure("Ajax-call body return");
    }
  }
  
  if(connection_status() != CONNECTION_NORMAL)
  {
    //user disconnected before seeing the page..
    //TODO: implement this!
  }
  
  PageContext::$CURRENT_PAGE->display();
  exit();
}

pageComplete(); //call if not already called
