<?php
/*******************************************************************************
 * Copyright (C) 2007 Easter-eggs
 * https://ldapsaisie.org
 *
 * Author: See AUTHORS file in top-level directory.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

******************************************************************************/

/**
 * Gestion des erreurs pour LdapSaisie
 *
 * Cette classe gère les retours d'erreurs.
 *
 * @author Benjamin Renard <brenard@easter-eggs.com>
 */
class LSerror {

  /**
   * Registered error codes
   * @var array<string|int,array>
   */
  private static $_errorCodes = array(
    '0' => array('msg' => "%{msg}")
  );

  /**
   * Define an error
   *
   * @author Benjamin Renard <brenard@easter-eggs.com>
   *
   * @param string $code The error code
   * @param LSformat $msg  The LSformat of the error message
   * @param boolean $escape Set to false if you don't want the message
   *                            to be escaped on display (Default: true)
   *
   * @return void
   */
  public static function defineError($code='-1', $msg='', $escape=True) {
    self :: $_errorCodes[$code] = array(
      'msg' => $msg,
      'escape' => boolval($escape),
    );
  }

  /**
   * Add an error
   *
   * @author Benjamin Renard <brenard@easter-eggs.com>
   *
   * @param string $code The error code
   * @param mixed $msg If error code is not specified (or not defined), it could content the
   *                       the error message. If error code is provided (and defined), this parameter
   *                       will be used to format registred error message (as LSformat). In this case,
   *                       it could be any of data support by getFData function as $data parameter.
   *
   * @param boolean $escape Set to false if you don't want the message
   *                            to be escaped on display (Default: true)
   *
   * @return void
   */
  public static function addErrorCode($code=null, $msg=null, $escape=true) {
    $_SESSION['LSerror'][] = self :: formatError($code, $msg, $escape);
    if (class_exists('LSlog'))
      LSlog :: error(self :: formatError($code, $msg, $escape, 'addslashes'));
  }

  /**
   * Show errors
   *
   * @author Benjamin Renard <brenard@easter-eggs.com>
   *
   * @param boolean $return True if you want to retrieved errors message. If false,
   *                            (default), LSerrors template variable will be assigned
   *                            with errors message.
   *
   * @return array|null
   */
  public static function display($return=False) {
    $errors = self :: getErrors();
    if ($errors  && $return)
      return $errors;
    LStemplate :: assign('LSerrors', base64_encode(json_encode($errors)));
    return null;
  }

 /**
  * Format current errors message
  *
  * @param bool $reset Reset errors (optional, default: true)
  * 
  * @author Benjamin Renard <brenard@easter-eggs.com>
  *
  * @return array Array of formated error messages
  */
  public static function getErrors($reset=true) {
    $return = (
      self :: errorsDefined()?
      $_SESSION['LSerror']:
      array()
    );
    if ($reset)
      self :: resetError();
    return $return;
  }

 /**
  * Format error message
  *
  * @param string|null $code The error code
  * @param mixed $message Error message data for registred errors or the error message as string, or null
  * @param bool $escape Set to false to disable escaping error message
  * @param callable $escape_method The escape method (default: htmlentities)
  * @author Benjamin Renard <brenard@easter-eggs.com>
  *
  * @return string Le texte des erreurs
  */
  private static function formatError($code=null, $message=null, $escape=True, $escape_method=null) {
    if ($code && array_key_exists($code, self :: $_errorCodes)) {
      $message = getFData(__(self :: $_errorCodes[$code]['msg']), $message);
      if (!self :: $_errorCodes[$code]['escape'] === false)
        $escape = false;
    }
    else if (!$message) {
      if ($code)
        $message = $code;
      else
        $message = _("Unknown error");
    }

    if ($escape !== false) {
      if (is_null($escape_method) || !is_callable($escape_method))
        $escape_method = 'htmlentities';
      $code = call_user_func($escape_method, $code);
      $message = call_user_func($escape_method, $message);
    }

    return ($code?"(Code $code) ":"").$message;
  }

 /**
  * Check if some errors are defined
  *
  * @author Benjamin Renard <brenard@easter-eggs.com>
  *
  * @return boolean
  */
  public static function errorsDefined() {
    return (
      isset($_SESSION['LSerror']) &&
      is_array($_SESSION['LSerror']) &&
      !empty($_SESSION['LSerror'])
    );
  }

 /**
  * Clear current errors
  *
  * @author Benjamin Renard <brenard@easter-eggs.com>
  *
  * @return void
  */
  private static function resetError() {
    if (isset($_SESSION['LSerror']))
      unset ($_SESSION['LSerror']);
  }

  /**
   * Check if is Net_LDAP2 error and display possible error message
   *
   * @param mixed $data Data
   *
   * @return boolean True if it's an error or False
   **/
  public static function isLdapError($data) {
    if (Net_LDAP2::isError($data)) {
      LSerror :: addErrorCode(0, $data -> getMessage());
      return true;
    }
    return false;
  }

}

/*
 * Error Codes
 */
LSerror :: defineError(-1, ___("Unknown error : %{error}"));
