<?php
//
// +---------------------------------------------------------------------------+
// | Nitro :: Text |
// +---------------------------------------------------------------------------+
// | Copyright (c) 2003 June Systems BV |
// +---------------------------------------------------------------------------+
// | This library is free software; you can redistribute it and/or modify it |
// | under the terms of the GNU Lesser General Public License as published by |
// | the Free Software Foundation; either version 2.1 of the License, or (at |
// | your option) any later version. |
// | |
// | This library 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 Lesser |
// | General Public License for more details. |
// | |
// | You should have received a copy of the GNU Lesser General Public License |
// | along with this library; if not, write to the Free Software Foundation, |
// | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
// +---------------------------------------------------------------------------+
// | Authors: Siggi Oskarsson <hide@address.com> |
// +---------------------------------------------------------------------------+
//
// $Id: Text.inc.php 247 2008-09-24 08:00:07Z andries $
//
// This file contains the Text functions for Nitro
//
/**
* This file contains the Internationalization functions and class of Nitro
*
* @package Nitro
* @subpackage Base
* @author Siggi Oskarsson
* @version $Revision: 1.28 $
* @copyright 2004 June Systems BV
*/
/**
* Request language string
*
* This functions uses the language object to retreive the translation
* of the language string given by $IDString.
*
* <CODE>
* Language('Test String');
* Language('Test /{%Parameter%}/ String', Array('Parameter' => 'Value'));
* Language('Test /{%Parameter%}/ String', Array('Parameter' => 'Value'), 'eng', 'rawurlencode');
* </CODE>
*
* @param string $IDString ID string to lookup
* @param array $Parameter Parameters to replace in the translated string
* @param string $Language Language to use in lookup (default = session language)
* @param string $EncodecharsFunction Function to use to encode string after translation
* @return string Translated string
* @access public
*/
function Language($IDString, $Parameter = NULL, $Language = NULL, $EncodecharsFunction = "htmlentities") {
global $LanguageObject, $__NSess;
if (!is_object($LanguageObject)) {
$LanguageObject = new LanguageClass();
}
if (!$Language) $Language = $__NSess->Language;
return $LanguageObject->Query($IDString, $Language, $Parameter, $EncodecharsFunction);
}
/**
* Get object linked to ID string
*
* This function looks up the object linked to the ID string, draws it
* and returns the output.
*
* <CODE>
* GetObjectLink('Object link ID');
* GetObjectLink('Object link ID', Array('Parameter' => 'Value'), 'eng');
* </CODE>
*
* @param string $IDString ID string of object link
* @param array $Parameter Parameters to replace in the looked up string
* @param string $Language Language to use in lookup (default = session language)
* @return string Object drawn
*/
function GetObjectLink($IDString, $Parameter = NULL, $Language = NULL) {
global $DB, $__NSess;
if (!$Language) $Language = $__NSess->Language;
DebugGroup("Text", "GetObjectLink", "Getting object link for $IDString in $Language", __FILE__, __LINE__, DEBUG_APPL_OK);
$ObjectRow = Array();
$Query = "SELECT OL.ObjectLinkID, OL.Settings AS RuntimeSettings,
O.ObjectID, O.DefaultSettings,
OD.Settings, M.File, M.Class
FROM ObjectLink AS OL
LEFT JOIN Object AS O
ON O.ObjectID = OL.ObjectID
LEFT JOIN Module AS M
ON M.ModuleID = O.ModuleID
LEFT JOIN ObjectData AS OD
ON OD.ObjectID = O.ObjectID
AND (OD.Language = ".NitroPrepareDB($__NSess->Language)." OR OD.Language = '')
AND OD.Published = 1
WHERE OL.IDString = ".NitroPrepareDB($IDString)."
ORDER BY OD.Language DESC, OD.Version DESC
";
//echo $DB["Nitro"]->PrepareQuery($Query);exit;
$ObjectRow = $DB["Nitro"]->getRow($Query);
if (is_array($ObjectRow)) {
Debug("Text", "GetObjectLink", "Object Link found", __FILE__, __LINE__, DEBUG_APPL_OK);
if ($ObjectRow["File"]) {
Debug("Text", "GetObjectLink", "Object found, creating and drawing", __FILE__, __LINE__, DEBUG_APPL_OK);
include_once $ObjectRow["File"];
if(class_exists($ObjectRow["Class"])){
//check if DefaultSettings/Settings/RuntimeSettings is a string otherwise unserialize gives an error
$DefaultSettings = (strlen($ObjectRow["DefaultSettings"]) ? unserialize($ObjectRow["DefaultSettings"]) : '');
if (!is_array($DefaultSettings)) $DefaultSettings = Array();
$Settings = (strlen($ObjectRow["Settings"]) ? unserialize($ObjectRow["Settings"]) : '');
if (!is_array($Settings)) $Settings = Array();
$RuntimeSettings = (strlen($ObjectRow["RuntimeSettings"]) ? unserialize($ObjectRow["RuntimeSettings"]) : '');
if (!is_array($RuntimeSettings)) $RuntimeSettings = Array();
$RuntimeSettings = array_merge($RuntimeSettings, $Parameter);
$Settings = array_merge($DefaultSettings, $Settings);
eval('$Object = new '.$ObjectRow["Class"].'($ObjectRow["ObjectRowID"], $Settings);');
if(method_exists($Object, "Draw")) {
$RV = $Object->DrawObject($RuntimeSettings);
//replace params?
} else {
Debug("Text", "GetObjectLink", "ERROR: DrawResult function does not exist in class ".$ObjectRow[ClassName], __FILE__, __LINE__, DEBUG_APPL_ERR);
$RV = FALSE;
}
} else {
Debug("Text", "GetObjectLink", "ERROR: Class '".$ObjectRow["Class"]."' does not exist", __FILE__, __LINE__, DEBUG_APPL_ERR);
$RV = FALSE;
}
} else {
Debug("Text", "GetObjectLink", "Object link is not linked to a valid object, returning NULL", __FILE__, __LINE__, DEBUG_APPL_ERR);
$RV = NULL;
}
} else {
// Insert object link into DB for future use
Debug("Text", "GetObjectLink", "Object Link not found, creating in DB", __FILE__, __LINE__, DEBUG_APPL_OK|DEBUG_APPL_ERR);
$Query = "INSERT INTO ObjectLink
(IDString, ObjectID, Settings, CreatedByUserID, CreatedOn)
VALUES
(".NitroPrepareDB($IDString).", 0, NULL, 0, CURRENT_TIMESTAMP)
";
$DB["Nitro"]->query($Query);
$RV = FALSE;
}
DebugCloseGroup(DEBUG_APPL_OK);
return $RV;
}
/**
* Retrieves list of used objectlinks with specific pattern (and optional language)
*
* This function retrieves a list of all the objects links that match a specified searchpattern
*
* @param string $SearchPattern Search pattern you want to use
* @param string $Language optional Language parameter so you can search for specific language ('All' is also searched when language is specified)
* @return array List of matching ObjectLink's IDStrings
*/
function GetObjectLinks($SearchPattern = '', $Language = FALSE)
{
DebugGroup(__CLASS__, __FUNCTION__, "Getting object links for pattern: ".$SearchPattern, __FILE__, __LINE__, DEBUG_APPL_OK);
global $DB, $__NSess;
if ($Language !== FALSE && !strlen($Language)) $Language = $__NSess->Language;
$ObjectLinks = Array();
$Query = "SELECT OL.IDString
FROM ObjectLink AS OL
LEFT JOIN Object AS O
ON O.ObjectID = OL.ObjectID
LEFT JOIN ObjectData AS OD
ON OD.ObjectID = O.ObjectID
".($Language === FALSE ? '' : "AND (OD.Language = ".NitroPrepareDB($__NSess->Language)." OR OD.Language = '')")."
AND OD.Published = 1
WHERE OL.IDString LIKE ".NitroPrepareDB($SearchPattern)."
GROUP BY OL.IDString
ORDER BY OL.IDString, OD.Language DESC, OD.Version DESC
";
$Result = $DB["Nitro"]->query($Query);
while ($Data = $Result->fetchRow()) {
$ObjectLinks[] = $Data['IDString'];
}
return $ObjectLinks;
}
/**
* Language class
*
* This is the class that is used by the Language function to lookup
* translations of the language strings. This class loads the language
* file as needed and creates the cache that is used.
*
* @package Nitro
* @subpackage Base
*/
class LanguageClass {
/**
* Language array with all translated strings
* @var array $Language Language array
*/
var $Languages = Array();
/**
* Class constructor
*
* The class constructor globalizes the DB array and sets
* $this->DB to $DB["Nitro"].
*/
function LanguageClass() {
global $DB;
$this->DB =& $DB["Nitro"];
}
/**
* Load language array
*
* This function loads the language array from the database or from
* the cache if it exists. It also checks whether an existing cache
* is completely up to date and deletes it if not.
*
* @param string $LanguageCode Language code to load into class
* @param boolean $ByPassCache By pass the cached file if set to true (=load from database)
* @return boolean TRUE|FALSE for loading language
*/
function LoadLanguage($LanguageCode, $ByPassCache = FALSE) {
DebugGroup("LanguageClass", "LoadLanguage", "Loading language: $LanguageCode", __FILE__, __LINE__, DEBUG_APPL_OK);
if ($CacheDir = NitroGetCacheDir("Language")) {
// Check max last edited language string for this language
if ($ByPassCache) {
$MaxEdit = NULL;
} else {
$Query = "SELECT MAX(EditedOn) FROM LanguageStringData WHERE LanguageCode = ".NitroPrepareDB($LanguageCode);
$MaxEdit = strtotime($this->DB->getOne($Query));
}
$CacheFile = $CacheDir."/".$LanguageCode;
if (!$ByPassCache && file_exists($CacheFile) && filemtime($CacheFile) > $MaxEdit) {
Debug("LanguageClass", "LoadLanguage", "Language cache exists and is up2date, loading", __FILE__, __LINE__, DEBUG_APPL_OK);
//load cache
$this->Languages[$LanguageCode] = unserialize(current(file($CacheFile)));
$RV = TRUE;
} else {
Debug("LanguageClass", "LoadLanguage", "Language cache does not exists, creating", __FILE__, __LINE__, DEBUG_APPL_OK);
//get data and create cache
$Query = "SELECT LS.IDString, LSD.Text
FROM LanguageString AS LS, LanguageStringData AS LSD
WHERE LS.LanguageStringID = LSD.LanguageStringID
AND LSD.LanguageCode = ".NitroPrepareDB($LanguageCode)."
";
$Result = $this->DB->query($Query);
if ($Result->numRows()) {
while($Row = $Result->fetchArray()) {
$Language["".strtoupper($Row["IDString"]).""] = $Row["Text"];
}
$Result->free();
$fp = fopen($CacheFile, "w");
fputs($fp, serialize($Language));
fclose($fp);
$this->Languages[$LanguageCode] = $Language;
$RV = TRUE;
} else {
$this->Languages[$LanguageCode] = FALSE;
$RV = FALSE;
}
}
} else {
$this->Languages[$LanguageCode] = FALSE;
$RV = FALSE;
}
DebugCloseGroup(DEBUG_APPL_OK);
return $RV;
}
/**
* Query the language array
*
* This function queries the language array and replaces all codes in
* the string with the parameters given.
*
* @param string $IDString ID string of string to query
* @param string $LanguageCode Code of language to use to query
* @param array $Parameter Array of parameters to replace in string
* @param string $EncodecharsFunction Function to use to encode to found and replace string
* @return string Translated string
*/
function Query($IDString, $LanguageCode, $Parameter = NULL, $EncodecharsFunction = "htmlentities")
{
$OriginalString = $IDString;
$IDString = strtoupper($IDString);
if (!$this->isLoaded($LanguageCode)) $this->LoadLanguage($LanguageCode);
if (is_array($this->Languages)
&& array_key_exists($LanguageCode, $this->Languages)
&& is_array($this->Languages[$LanguageCode])
&& array_key_exists($IDString, $this->Languages[$LanguageCode])
&& strlen($this->Languages[$LanguageCode][$IDString])
) {
$Text = $this->ReplaceParameters($this->Languages[$LanguageCode][$IDString], $Parameter);
$Text = $this->PostProcess($Text, $OriginalString, $LanguageCode);
} else {
Debug("LanguageClass", "Query", "Language ($LanguageCode) IDString not found: ".$IDString, __FILE__, __LINE__, DEBUG_APPL_OK|DEBUG_APPL_ERR);
// String not found (in cache), add to DB??
// First check if it has been added and the cache is not up2date
$Query = "
SELECT LS.LanguageStringID
FROM LanguageString AS LS
WHERE LS.IDString = ".NitroPrepareDB(strtoupper($IDString))."
";
$LSID = $this->DB->getOne($Query);
if (!(int)$LSID) {
$Query = "
INSERT INTO LanguageString
(IDString, CreatedOn, EditedOn)
VALUES
(".NitroPrepareDB(strtoupper($IDString)).", CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
";
$this->DB->query($Query);
$this->LoadLanguage($LanguageCode);
} else {
// Set language string to temp value to avoid further queries on this string
$this->Languages[$LanguageCode][$IDString] = $OriginalString;
}
if (NITRO_DEBUG) {
$Text = "{{{".$IDString."}}}";
} else {
$Text = $this->ReplaceParameters($OriginalString, $Parameter);
$Text = $this->PostProcess($Text, $OriginalString, $LanguageCode);
}
}
if (function_exists($EncodecharsFunction)) eval("\$Text = $EncodecharsFunction(\$Text);");
return $Text;
}
function ReplaceParameters($Text, $Parameter = array())
{
if (is_array($Parameter) && count($Parameter)) {
foreach ($Parameter AS $ID => $ParameterValue) {
$ParameterID = strtolower($ID);
$Text = preg_replace("/{%".$ParameterID."%}/i", $ParameterValue, $Text);
}
}
//opschonen, verwijderen
$Text = preg_replace("/{%[^}]%} ?/", "", $Text);
return $Text;
}
function PostProcess($Text, $OriginalString, $LanguageCode)
{
$RegularPostProcess = TRUE;
if (strlen($LanguageCode) && file_exists(NITRO_PATH.'Language/'.$LanguageCode.'.inc.php') && include_once('Nitro/Language/'.$LanguageCode.'.inc.php')) {
if (class_exists('Language_'.$LanguageCode) && is_callable(array('Language_'.$LanguageCode, 'PostProcess'))) {
eval('$Text = Language_'.$LanguageCode.'::PostProcess($Text, $OriginalString);');
$RegularPostProcess = FALSE;
}
}
if ($RegularPostProcess) {
$Text = trim($Text);
$Text = strtolower($Text);
if (ereg("^([A-Z][^ ]* ?)+$", $OriginalString." ")) {
// All First Upper
$Text = ucwords($Text);
} elseif (ereg("^[A-Z]+$", $OriginalString)) {
// All Caps
$Text = strtoupper($Text);
} elseif (ereg("^[A-Z].*$", $OriginalString)) {
// First Upper
$Text = ucfirst($Text);
}
}
return $Text;
}
/**
* Check whether language is loaded
*
* This function checks whether the language given is loaded into
* the internal array.
*
* @param string $LanguageCode Code of language to check
* @return boolean TRUE|FALSE for language loaded
*/
function isLoaded($LanguageCode) {
if (count($this->Languages[$LanguageCode]) > 1) return TRUE;
else return FALSE;
}
}
?>