<?php

use EesyPHP\Log;
use EesyPHP\SentrySpan;
use EesyPHP\SentryTransaction;
use EesyPHP\Url;

if (php_sapi_name() == "cli")
  return true;

$smarty = new Smarty();

/*
 * Configure Smarty regarding the installed version
 */
if (method_exists($smarty,'register_function')) {
  $_smarty_version = 2;

  function smarty_enable_security_mode($functions=array(), $modifiers=array()) {
    global $smarty;
    // Enable security
    $smarty -> security = True;

    // Allow functions in IF clauses
    foreach($functions as $function)
      $smarty -> security_settings['IF_FUNCS'][] = $function;

    // Allow modifier functions
    foreach($modifiers as $modifier)
      $smarty -> security_settings['MODIFIER_FUNCS'][] = $modifier;
  }

  function smarty_register_function($func_name, $func) {
    global $smarty;
    $smarty -> register_function($func_name, $func);
  }
}
elseif (method_exists($smarty,'registerPlugin')) {
  $_smarty_version = 3;

  function smarty_enable_security_mode($functions=array(), $modifiers=array()) {
    global $smarty;

    // Define security policy
    $smarty_security_policy = new Smarty_Security($smarty);

    // Allow functions in IF clauses
    foreach($functions as $function)
      $smarty_security_policy->php_functions[] = $function;

    // Allow modifier functions
    foreach($modifiers as $modifier)
      $smarty_security_policy->php_modifiers[] = $modifier;

    // Enable security
    $smarty->enableSecurity($smarty_security_policy);
  }

  function smarty_register_function($func_name, $func) {
    global $smarty;
    $smarty -> registerPlugin("function", $func_name, $func);
  }
}
else {
  Log :: fatal(_('Smarty version not supported.'));
}

// Configure templates/templates_c directories
if (
    !isset($smarty_templates_dir)
    || !is_dir($smarty_templates_dir)
)
    Log :: fatal(
        "Template directory not found (%s)",
        isset($smarty_templates_dir)?$smarty_templates_dir:'not set');
else
    $smarty->setTemplateDir($smarty_templates_dir);

if (
    !isset($smarty_templates_c_dir)
    || !is_dir($smarty_templates_c_dir)
    || !is_writable($smarty_templates_c_dir)
)
    Log :: fatal(
        "Template cache directory not found or not writable (%s)",
        isset($smarty_templates_c_dir)?$smarty_templates_c_dir:'not set');
else
    $smarty->setCompileDir($smarty_templates_c_dir);

// Enable Smarty security
smarty_enable_security_mode(
  // Allow some functions in IF clauses
  array(
    'isset', 'empty', 'count', 'in_array', 'is_array', 'array_key_exists', 'is_null',
    'can_modify', 'can_archive', 'can_delete'
  ),
  // Allow some modifier functions
  array('range', 'implode', 'stripslashes')
);

// Defined some global template variables
$smarty->assign('public_root_url', isset($public_root_url)?$public_root_url:'/');
$smarty->assign('main_pagetitle', isset($main_pagetitle)?$main_pagetitle:null);
$smarty->assign('session_key', $_SESSION['session_key']);

// Handle in-page errors & messages
if (!isset($_SESSION['errors']))
  $_SESSION['errors'] = array();
function add_error($error) {
  // If more than one arguments passed, format error message using sprintf
  if (func_num_args() > 1) {
    $error = call_user_func_array(
      'sprintf',
      array_merge(array($error), array_slice(func_get_args(), 1))
    );
  }
  $_SESSION['errors'][] = $error;
}

if (!isset($_SESSION['messages']))
  $_SESSION['messages'] = array();
function add_message($message) {
  // If more than one arguments passed, format message using sprintf
  if (func_num_args() > 1) {
    $message = call_user_func_array(
      'sprintf',
      array_merge(array($message), array_slice(func_get_args(), 1))
    );
  }
  $_SESSION['messages'][] = $message;
}

// Handle CSS & JS files included
if (isset($included_css_files) && is_array($included_css_files)) {
  $_css = $included_css_files;
}
else {
  $_css = array();
}
function add_css_file() {
  global $_css;
  foreach (func_get_args() as $files) {
    if (!is_array($files)) $files=array($files);
    foreach ($files as $file) {
      if (!in_array($file, $_css))
        $_css[]=$file;
    }
  }
}

$_js = array();
function add_js_file() {
  global $_js;
  foreach (func_get_args() as $files) {
    if (!is_array($files)) $files = array($files);
    foreach ($files as $file) {
      if (!in_array($file, $_js))
        $_js[] = $file;
    }
  }
}

function _defineCommonTemplateVariables($template, $pagetitle) {
  global $smarty, $_css, $_js, $status_list, $auth_user, $admin, $webstats_js_code;
  $smarty->assign('pagetitle', $pagetitle);

  // Messages
  $smarty -> assign('errors', (isset($_SESSION['errors'])?$_SESSION['errors']:array()));
  $smarty -> assign('messages', (isset($_SESSION['messages'])?$_SESSION['messages']:array()));

  // Files inclusions
  $smarty -> assign('css', $_css);
  $smarty -> assign('js', $_js);

  // Authenticated user info
  if (isset($auth_user))
    $smarty->assign('auth_user', $auth_user);

  // Webstats JS code
  $smarty->assign(
    'webstats_js_code',
    isset($webstats_js_code)?$webstats_js_code:null);
}

function display_template($template, $pagetitle=false) {
  if (!$template)
    Log :: fatal(_("No template specified."));

  // If refresh parameter is present, remove it and redirect
  if (isset($_GET['refresh'])) {
    unset($_GET['refresh']);
    $url = Url :: get_current_url();
    if (!empty($_GET))
      $url .= '?'.http_build_query($_GET);
    Url :: redirect($url);
    return;
  }

  $sentry_span = new SentrySpan('smarty.display_template', "Display Smarty template");

  global $smarty;
  // If more than 2 arguments passed, format pagetitle using sprintf
  if ($pagetitle && func_num_args() > 2) {
    $pagetitle = call_user_func_array(
      'sprintf',
      array_merge(array($pagetitle), array_slice(func_get_args(), 2))
    );
  }
  try {
    _defineCommonTemplateVariables($template, $pagetitle);
    $smarty->display($template);
    unset($_SESSION['errors']);
    unset($_SESSION['messages']);
  }
  catch (Exception $e) {
    Log :: exception($e, "Smarty - An exception occured displaying template '$template'");
    if ($template != 'fatal_error.tpl')
      Log :: fatal(_("An error occurred while displaying this page."));
  }

  $sentry_span->finish();

}

function display_ajax_return($data=null, $pretty=false) {
  global $debug_ajax;
  if (is_null($data))
    $data = array();
  // Adjust HTTP error code on unsuccessfull request
  elseif (isset($data['success']) && !$data['success'] && http_response_code() == 200)
    http_response_code(400);

  if (isset($_SESSION['messages']) && !empty($_SESSION['messages'])) {
    $data['messages'] = $_SESSION['messages'];
    unset($_SESSION['messages']);
  }
  if (isset($_SESSION['errors']) && !empty($_SESSION['errors'])) {
    $data['errors'] = $_SESSION['errors'];
    unset($_SESSION['errors']);
  }
  if ($debug_ajax)
    Log :: debug("Ajax Response : ".vardump($data));
  header('Content-Type: application/json');
  echo json_encode($data, (($pretty||isset($_REQUEST['pretty']))?JSON_PRETTY_PRINT:0));
  exit();
}

$ajax=false;
function fatal_error($error) {
  global $smarty, $ajax;

  // If more than one arguments passed, format error message using sprintf
  if (func_num_args() > 1) {
    $error = call_user_func_array(
      'sprintf',
      array_merge(array($error), array_slice(func_get_args(), 1))
    );
  }

  if (php_sapi_name() == "cli")
    die("FATAL ERROR : $error\n");

  // Set HTTP reponse code to 500
  http_response_code(500);

  if ($ajax || Url :: api_mode())
    display_ajax_return(array('success' => false, 'error' => $error));

  $smarty->assign('fatal_error', $error);
  display_template('fatal_error.tpl');
  exit();
}

// Templates functions
function smarty_item_status($params) {
  global $status_list;
  $status2class = array (
    'pending' => 'info',
    'validated' => 'success',
    'refused' => 'danger',
    'archived' => 'secondary',
  );
  if (array_key_exists($params['item']['status'], $status2class)) {
    $class = $status2class[$params['item']['status']];
  }
  else
    $class='danger';
  echo "<span class='badge badge-$class'>";
  echo (
    array_key_exists($params['item']['status'], $status_list)?
    $status_list[$params['item']['status']]:
    "Inconnu (".$params['item']['status'].")"
  );
  echo "</span>";
}
smarty_register_function('item_status','smarty_item_status');

function smarty_format_time($params) {
  echo format_time($params['time'], (!isset($params['with_time']) || (bool)$params['with_time']));
}
smarty_register_function('format_time','smarty_format_time');

function smarty_format_size($params, $smarty) {
  if(!isset($params['digit'])) $params['digit'] = 2;
  echo format_size($params['size'],$params['digit']);
}
smarty_register_function('format_size','smarty_format_size');

function smarty_table_ordered_th($params, $smarty) {
  if ($params['order'] && $params['url'] && $params['text'] && is_array($params['search'])) {
    echo "<a href='".$params['url']."?order=".$params['order']."'>".$params['text']."</a>";
  }
  if ($params['order']==$params['search']['order']) {
    echo (
      ' <i class="fa fa-sort-'.
      (strtolower($params['search']['order_direction'])=='asc'?'up':'down').
      '" aria-hidden="true"></i>');
  }
}
smarty_register_function('table_ordered_th','smarty_table_ordered_th');

function smarty_encodeJsonBase64($params, $smarty) {
  if (isset($params['data']))
    echo base64_encode(json_encode($params['data']));
}
smarty_register_function('encodeJsonBase64','smarty_encodeJsonBase64');

# vim: tabstop=2 shiftwidth=2 softtabstop=2 expandtab