/**
  * Method execute sql query by using prepared statements
  * 
  * @param string $sql
  * @return mysqli_stmt
  * @throws Exception\Service
  */
 public function execute($sql)
 {
     if (!$this->_isValidService()) {
         throw new Exception\Service('Not connected to a valid database service');
     }
     $profiler = Profiler::getInstance();
     $args = func_get_args();
     if (count($args) == 1) {
         $profiler->dbQueryStart($sql);
         $result = $this->_service->query($sql);
         $profiler->dbQueryStop($this->getAffectedRows());
         return $result;
     }
     //$profiler->dbQueryStart($sql);
     if (!($stmt = $this->_service->prepare($sql))) {
         $this->_logError($this->_service->error, $sql);
         if (ENV == 'dev') {
             throw new Exception\Sql(sprintf('There was an error in the query %s', $this->_service->error));
         } else {
             throw new Exception\Sql('There was an error in the query');
         }
     }
     array_shift($args);
     //remove sql from args
     $bindParamsReferences = array();
     foreach ($args as $key => $value) {
         $bindParamsReferences[$key] =& $args[$key];
     }
     $types = str_repeat('s', count($args));
     //all params are strings, works well on MySQL and SQLite
     array_unshift($bindParamsReferences, $types);
     $bindParamsMethod = new \ReflectionMethod('mysqli_stmt', 'bind_param');
     $bindParamsMethod->invokeArgs($stmt, $bindParamsReferences);
     $stmt->execute();
     //$profiler->dbQueryStop($stmt->affected_rows);
     $meta = $stmt->result_metadata();
     unset($bindParamsMethod);
     if ($meta) {
         $stmtRow = array();
         $rowReferences = array();
         while ($field = $meta->fetch_field()) {
             $rowReferences[] =& $stmtRow[$field->name];
         }
         $bindResultMethod = new \ReflectionMethod('mysqli_stmt', 'bind_result');
         $bindResultMethod->invokeArgs($stmt, $rowReferences);
         $result = array();
         while ($stmt->fetch()) {
             foreach ($stmtRow as $key => $value) {
                 $row[$key] = $value;
             }
             $result[] = $row;
         }
         $stmt->free_result();
         $stmt->close();
         unset($stmt);
         unset($bindResultMethod);
         return $result;
     } else {
         return null;
     }
 }
 /**
  * Main render method
  * 
  * @throws View\Exception\Renderer
  */
 public function render()
 {
     Event::fire('framework.controller.render.before', array($this->name));
     $defaultContentType = $this->defaultContentType;
     $results = null;
     $doAction = $this->willRenderActionView && $this->actionView;
     $doLayout = $this->willRenderLayoutView && $this->layoutView;
     $profiler = \THCFrame\Profiler\Profiler::getInstance();
     try {
         if ($doAction) {
             $view = $this->actionView;
             $results = $view->render();
             $this->actionView->template->implementation->set('action', $results);
         }
         if ($doLayout) {
             $view = $this->layoutView;
             $results = $view->render();
             $profiler->stop();
             //protection against clickjacking
             header('X-Frame-Options: deny');
             header("Content-type: {$defaultContentType}");
             echo $results;
         } elseif ($doAction) {
             $profiler->stop();
             //protection against clickjacking
             header('X-Frame-Options: deny');
             header("Content-type: {$defaultContentType}");
             echo $results;
         }
         $this->willRenderLayoutView = false;
         $this->willRenderActionView = false;
     } catch (\Exception $e) {
         throw new ViewException\Renderer('Invalid layout/template syntax');
     }
     Event::fire('framework.controller.render.after', array($this->name));
 }
} else {
    error_reporting(0);
}
//check PHP version
if (version_compare(phpversion(), '5.4', '<')) {
    header('Content-type: text/html');
    include APP_PATH . '/phpversion.phtml';
    exit;
}
//xdebug profiler
//setcookie('XDEBUG_PROFILE', 1, time()+1800);
//setcookie('XDEBUG_PROFILE', '', time()-1800);
//core
require APP_PATH . '/vendors/thcframe/core/core.php';
THCFrame\Core\Core::initialize();
//plugins
$path = APP_PATH . '/application/plugins';
$iterator = new \DirectoryIterator($path);
foreach ($iterator as $item) {
    if (!$item->isDot() && $item->isDir()) {
        include $path . '/' . $item->getFilename() . '/initialize.php';
    }
}
//register modules
$modules = array('App', 'Admin');
THCFrame\Core\Core::registerModules($modules);
//internal profiler
$profiler = \THCFrame\Profiler\Profiler::getInstance();
$profiler->start();
// load services and run dispatcher
THCFrame\Core\Core::run();
 /**
  * Method called by ajax shows profiler bar at the bottom of screen
  */
 public function showProfiler()
 {
     $this->willRenderActionView = false;
     $this->willRenderLayoutView = false;
     echo Profiler::display();
 }