first draft, only one (main) page
This commit is contained in:
231
inc/mask.php
Normal file
231
inc/mask.php
Normal file
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Mask Reader
|
||||
* @author franzz
|
||||
*
|
||||
*/
|
||||
class Mask extends PhpObject
|
||||
{
|
||||
public $sMaskName;
|
||||
public $sFilePath;
|
||||
private $sMask;
|
||||
private $asTags;
|
||||
private $asPartsSource;
|
||||
private $aoInstances;
|
||||
|
||||
const MASK_FOLDER = 'masks/';
|
||||
const MASK_EXT = '.html';
|
||||
const START_TAG = 'START';
|
||||
const END_TAG = 'END';
|
||||
const TAG_MARK = '[#]';
|
||||
|
||||
public function __construct($sFileName='')
|
||||
{
|
||||
//init
|
||||
parent::__construct(__CLASS__, Settings::DEBUG);
|
||||
$this->sMaskName = '';
|
||||
$this->sFilePath = '';
|
||||
$this->sMask = '';
|
||||
$this->asTags = array();
|
||||
$this->asPartsSource = array();
|
||||
$this->aoInstances = array();
|
||||
$this->sFilePath = '';
|
||||
|
||||
//load file
|
||||
if($sFileName!='')
|
||||
{
|
||||
$this->initFile($sFileName);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getMaskFile($sFileName)
|
||||
{
|
||||
return self::MASK_FOLDER.$sFileName.self::MASK_EXT;
|
||||
}
|
||||
|
||||
public function initFile($sFileName)
|
||||
{
|
||||
$sFilePath = self::getMaskFile(basename($sFileName));
|
||||
if(file_exists($sFilePath))
|
||||
{
|
||||
$this->sFilePath = $sFilePath;
|
||||
$sSource = file_get_contents($this->sFilePath);
|
||||
$this->initMask($sFileName, $sSource);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->addError('Fichier introuvable à l\'adresse : '.$sFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
public function initFileFromString($sSource, $sPartName='', $iInstanceNb=0)
|
||||
{
|
||||
$this->initMask($sPartName.' (from row) '.$iInstanceNb, $sSource);
|
||||
}
|
||||
|
||||
private function initMask($sMaskName, $sSource)
|
||||
{
|
||||
$this->sMaskName = $sMaskName;
|
||||
$this->sMask = $sSource;
|
||||
$this->setParts();
|
||||
}
|
||||
|
||||
private function setParts()
|
||||
{
|
||||
while(preg_match('/\<\!-- \[PART\] (?P<part>\S+) \[START\] --\>/u', $this->sMask, $asMatch))
|
||||
{
|
||||
$sPartName = $asMatch['part'];
|
||||
|
||||
$this->asPartsSource[$sPartName] = $this->getCleanPart($sPartName);
|
||||
$this->aoInstances[$sPartName] = array();
|
||||
}
|
||||
}
|
||||
|
||||
private function getCleanPart($sPartName)
|
||||
{
|
||||
$iStartPos = $this->getPartStartPos($sPartName);
|
||||
$iEndPos = $this->getPartEndPos($sPartName);
|
||||
$sPart = mb_substr($this->sMask, $iStartPos, $iEndPos-$iStartPos);
|
||||
$sExtendedPart = $this->getPartPattern($sPartName, self::START_TAG).$sPart. $this->getPartPattern($sPartName, self::END_TAG);
|
||||
$this->sMask = str_replace($sExtendedPart, $this->getPartTagPattern($sPartName), $this->sMask);
|
||||
return $sPart;
|
||||
}
|
||||
|
||||
private function getPartStartPos($sPartName)
|
||||
{
|
||||
$sPartStartPattern = $this->getPartPattern($sPartName, self::START_TAG);
|
||||
return mb_strpos($this->sMask, $sPartStartPattern) + strlen($sPartStartPattern);
|
||||
}
|
||||
|
||||
private function getPartEndPos($sPartName)
|
||||
{
|
||||
$sPartEndPattern = $this->getPartPattern($sPartName, self::END_TAG);
|
||||
return mb_strpos($this->sMask, $sPartEndPattern);
|
||||
}
|
||||
|
||||
private function getPartPattern($sPartName, $sAction)
|
||||
{
|
||||
return '<!-- [PART] '.$sPartName.' ['.$sAction.'] -->';
|
||||
}
|
||||
|
||||
private function getPartTagPattern($sPartName, $bMark=true)
|
||||
{
|
||||
$sPartTag = 'PART '.$sPartName;
|
||||
return $bMark?$this->addTagMark($sPartTag):$sPartTag;
|
||||
}
|
||||
|
||||
public function addInstance($sPartName, $asTags)
|
||||
{
|
||||
$this->newInstance($sPartName);
|
||||
foreach($asTags as $sTagName=>$sTagValue)
|
||||
{
|
||||
$this->setInstanceTag($sPartName, $sTagName, $sTagValue);
|
||||
}
|
||||
}
|
||||
|
||||
public function newInstance($sPartName)
|
||||
{
|
||||
//Finding the part ($oMask is a pointer)
|
||||
$oMask = $this->findPart($this, $sPartName);
|
||||
if(!$oMask) $this->addError('No part found : '.$sPartName);
|
||||
|
||||
//Retrieving source html
|
||||
$sPartSource = $oMask->asPartsSource[$sPartName];
|
||||
|
||||
//Creating new instance
|
||||
$oInstance = new Mask();
|
||||
$oInstance->initFileFromString($sPartSource, $sPartName);
|
||||
$oMask->aoInstances[$sPartName][] = $oInstance;
|
||||
}
|
||||
|
||||
public function setInstanceTag($sPartName, $sTagName, $sTagValue)
|
||||
{
|
||||
$oMask = $this->findPart($this, $sPartName);
|
||||
if(!$oMask) $this->addError('No part found : '.$sPartName);
|
||||
|
||||
$oMask->getCurrentInstance($sPartName)->setTag($sTagName, $sTagValue);
|
||||
}
|
||||
|
||||
private function findPart($oMask, $sPartName)
|
||||
{
|
||||
if(array_key_exists($sPartName, $oMask->aoInstances))
|
||||
{
|
||||
return $oMask;
|
||||
}
|
||||
else //going deeper to find the part
|
||||
{
|
||||
foreach($oMask->aoInstances as $sLevelPartName=>$aoInstances)
|
||||
{
|
||||
if(!empty($aoInstances))
|
||||
{
|
||||
//take last instances
|
||||
$oTmpMask = $this->findPart($oMask->getCurrentInstance($sLevelPartName), $sPartName);
|
||||
if($oTmpMask) return $oTmpMask;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getCurrentInstance($sPartName)
|
||||
{
|
||||
if(!empty($this->aoInstances[$sPartName]))
|
||||
{
|
||||
return end($this->aoInstances[$sPartName]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getTags()
|
||||
{
|
||||
$sSafeTagMark = preg_quote(self::TAG_MARK);
|
||||
$sPattern = '/'.$sSafeTagMark.'(?P<tag>\w+)'.$sSafeTagMark.'/u';
|
||||
preg_match_all($sPattern, $this->sMask, $asMatches);
|
||||
return array_unique(array_filter($asMatches['tag']));
|
||||
}
|
||||
|
||||
public function setTag($sTagName, $sTagValue)
|
||||
{
|
||||
$this->asTags[$sTagName] = $sTagValue;
|
||||
}
|
||||
|
||||
public function setTags($asTags)
|
||||
{
|
||||
foreach($asTags as $sTagName=>$sTagValue) $this->setTag($sTagName, $sTagValue);
|
||||
}
|
||||
|
||||
public function getMask()
|
||||
{
|
||||
$sCompletedMask = $this->sMask;
|
||||
|
||||
//build parts
|
||||
foreach($this->aoInstances as $sPart=>$aoParts)
|
||||
{
|
||||
$sTagValue = '';
|
||||
foreach($aoParts as $oInstance)
|
||||
{
|
||||
$sTagValue .= $oInstance->getMask();
|
||||
}
|
||||
$this->setTag($this->getPartTagPattern($sPart, false), $sTagValue);
|
||||
}
|
||||
|
||||
//replace tags
|
||||
if(!empty($this->asTags))
|
||||
{
|
||||
$asTags = $this->addTagMark(array_keys($this->asTags));
|
||||
$sCompletedMask = str_replace($asTags, $this->asTags, $sCompletedMask);
|
||||
}
|
||||
return $sCompletedMask;
|
||||
}
|
||||
|
||||
private function addTagMark($oData)
|
||||
{
|
||||
return ToolBox::array_map_encapsulate($oData, self::TAG_MARK);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
265
inc/resume.php
Normal file
265
inc/resume.php
Normal file
@@ -0,0 +1,265 @@
|
||||
<?php
|
||||
|
||||
class Resume extends PhpObject
|
||||
{
|
||||
//Resume constants
|
||||
const VERSION = '1.0.0';
|
||||
const DEFAULT_PAGE = 'home';
|
||||
const LOG_FILE = 'log';
|
||||
const PIC_PATH = 'images/pic.png';
|
||||
const PUBLIC_KEY_LENGTH = 13;
|
||||
const MAX_REQUEST_TIME = 10;
|
||||
|
||||
//Mask constants
|
||||
const RANDOM_TAG_PREFIX = 'uniqid_';
|
||||
const LOC_API_KEY = Settings::LOC_API_KEY;
|
||||
|
||||
//Variables
|
||||
private $oClassManagement;
|
||||
private $sLang;
|
||||
private $oTranslator;
|
||||
|
||||
private $asMasks;
|
||||
private $iLoadTime;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param ClassManagement $oClassManagement
|
||||
* @param string $sLang
|
||||
*/
|
||||
public function __construct($oClassManagement, $sLang='')
|
||||
{
|
||||
parent::__construct(__CLASS__, Settings::DEBUG);
|
||||
$this->oClassManagement = $oClassManagement;
|
||||
|
||||
//Browser <> PHP <> MySql synchronization
|
||||
date_default_timezone_set(Settings::TIMEZONE);
|
||||
ini_set('default_charset', Settings::TEXT_ENC);
|
||||
header('Content-Type: text/html; charset='.Settings::TEXT_ENC);
|
||||
mb_internal_encoding(Settings::TEXT_ENC);
|
||||
mb_http_output(Settings::TEXT_ENC);
|
||||
mb_http_input(Settings::TEXT_ENC);
|
||||
mb_language('uni');
|
||||
mb_regex_encoding(Settings::TEXT_ENC);
|
||||
|
||||
$this->oClassManagement->incClass('mask');
|
||||
$this->oClassManagement->incClass('translator');
|
||||
|
||||
$this->setLanguage($sLang);
|
||||
$this->setMasks();
|
||||
$this->setPageMasks(array('index'));
|
||||
$this->setLoadTime();
|
||||
$this->oTranslator = new Translator($this->getLanguage());
|
||||
}
|
||||
|
||||
private function getLanguage()
|
||||
{
|
||||
return $this->sLang;
|
||||
}
|
||||
|
||||
private function setLanguage($sLang='')
|
||||
{
|
||||
if($sLang!='') $this->sLang = $sLang;
|
||||
else
|
||||
{
|
||||
//$_SERVER['REMOTE_ADDR'] = '193.106.178.41'; //Test Spain
|
||||
//$_SERVER['REMOTE_ADDR'] = '160.92.167.193'; //Test France
|
||||
//$_SERVER['REMOTE_ADDR'] = '74.125.230.216'; //Test US
|
||||
$asIpInfo = json_decode(file_get_contents('http://api.ipinfodb.com/v3/ip-country/?key='.self::LOC_API_KEY.'&format=json&ip='.$_SERVER['REMOTE_ADDR']), true);
|
||||
if($asIpInfo['statusCode'] == 'OK') $this->sLang = $asIpInfo['countryCode'];
|
||||
}
|
||||
}
|
||||
|
||||
private function setLoadTime()
|
||||
{
|
||||
$this->iLoadTime = time();
|
||||
}
|
||||
|
||||
private function getLoadTime()
|
||||
{
|
||||
return $this->iLoadTime;
|
||||
}
|
||||
|
||||
private function setMasks()
|
||||
{
|
||||
//List all available masks
|
||||
$asMaskPaths = glob(Mask::getMaskFile('*'));
|
||||
$this->asMasks = array_map('basename', $asMaskPaths, array_fill(1, count($asMaskPaths), Mask::MASK_EXT));
|
||||
}
|
||||
|
||||
private function setPageMasks($asNonMasks)
|
||||
{
|
||||
//Exclude structure pages
|
||||
foreach($this->asMasks as $sMask)
|
||||
{
|
||||
$iIndex = array_search($sMask, $asNonMasks);
|
||||
if($iIndex === false) $this->asPageMasks[] = $sMask;
|
||||
}
|
||||
}
|
||||
|
||||
private function isAccessiblePage($sPageName)
|
||||
{
|
||||
return in_array($sPageName, $this->asPageMasks);
|
||||
}
|
||||
|
||||
public function getPage($sPageName, $bForceNoJson=false, $asForceTags=array())
|
||||
{
|
||||
$oResult = null;
|
||||
if(in_array($sPageName, $this->asMasks))
|
||||
{
|
||||
//Create Mask
|
||||
$oMask = new Mask($sPageName);
|
||||
|
||||
//Fill in with translated texts
|
||||
$asTags = $oMask->getTags();
|
||||
$iRandPrefixLen = mb_strlen(self::RANDOM_TAG_PREFIX);
|
||||
foreach($asTags as $sTag)
|
||||
{
|
||||
$sTagValue = '';
|
||||
if(array_key_exists($sTag, $asForceTags))
|
||||
{
|
||||
$sTagValue = $asForceTags[$sTag];
|
||||
}
|
||||
elseif(mb_substr($sTag, 0, $iRandPrefixLen) == self::RANDOM_TAG_PREFIX)
|
||||
{
|
||||
$sTagValue = uniqid();
|
||||
}
|
||||
else
|
||||
{
|
||||
$sTagValue = $this->oTranslator->getTranslation($sTag);
|
||||
}
|
||||
$oMask->setTag($sTag, $sTagValue);
|
||||
}
|
||||
|
||||
//Page specific postprocessing
|
||||
$asVars = array();
|
||||
switch($sPageName)
|
||||
{
|
||||
case 'index':
|
||||
$oMask->setTag('encoding', Settings::TEXT_ENC);
|
||||
break;
|
||||
}
|
||||
|
||||
//Get final mask
|
||||
$oResult = $oMask->getMask();
|
||||
|
||||
//Add title if this page is one of the site page
|
||||
if($this->isAccessiblePage($sPageName))
|
||||
{
|
||||
$oResult = array('title'=>$sPageName, 'page'=>$oResult, 'vars'=>$asVars);
|
||||
}
|
||||
}
|
||||
return (!$bForceNoJson && $this->isAccessiblePage($sPageName))?self::jsonExport($oResult):$oResult;
|
||||
}
|
||||
|
||||
public function getJavascript()
|
||||
{
|
||||
//Build picture key
|
||||
$sPublicKey = uniqid();
|
||||
$sSecretKey = $this->getLoadTime();
|
||||
list($iWidth, $iHeight) = getimagesize(self::PIC_PATH);
|
||||
file_put_contents(self::LOG_FILE, $sPublicKey.$sSecretKey."\n", FILE_APPEND);
|
||||
|
||||
//Display javascript functions
|
||||
$asResult = array();
|
||||
$asResult[] = "var cConfigPage = 'index.php'";
|
||||
$asResult[] = "var s = '$sPublicKey';";
|
||||
$asResult[] = "var iPicWidth = $iWidth;";
|
||||
$asResult[] = "var iPicHeight = $iHeight;";
|
||||
$asResult[] = file_get_contents('jquery/jquery.functions.js');
|
||||
return implode("\n", $asResult);
|
||||
}
|
||||
|
||||
public function getPic($sSerial)
|
||||
{
|
||||
if($this->checkSerial($sSerial))
|
||||
{
|
||||
header('Content-Type: image/jpeg');
|
||||
return file_get_contents(self::PIC_PATH);
|
||||
}
|
||||
else
|
||||
{
|
||||
header('HTTP/1.1 403 Forbidden');
|
||||
}
|
||||
}
|
||||
|
||||
public function sendEmail($sName, $sEmail, $sSubject, $sMsg)
|
||||
{
|
||||
$sResult = '';
|
||||
if($sName!='' && $sEmail!='' && $sSubject!='' && $sMsg!='')
|
||||
{
|
||||
//Message
|
||||
$sHtmlMessage = 'From: '.$sName."<br />".
|
||||
'Email: '.$sEmail."<br /><br />".
|
||||
'Subject: '.$sSubject."<br />".
|
||||
'Message: <br /><br />'.str_replace("\n", '<br />', $sMsg);
|
||||
$sPlainMessage = strip_tags(str_replace('<br />', "\n", $sHtmlMessage));
|
||||
|
||||
//Email
|
||||
$iBoundary = uniqid("HTMLEMAIL");
|
||||
$sHeaders = 'From: Contact CV <www-data@lutran.fr>'."\r\n".
|
||||
'Reply-To: Contact CV <www-data@lutran.fr>'."\r\n".
|
||||
'Cc: Julien Lutran <julien@lutran.fr>'."\r\n".
|
||||
'MIME-Version: 1.0'."\r\n".
|
||||
'Content-Type: multipart/alternative;'.
|
||||
'boundary = '.$iBoundary."\r\n\r\n".
|
||||
'MIME encoded Message'.
|
||||
'--'.$iBoundary."\r\n".
|
||||
'Content-Type: text/plain; charset=UTF-8'."\r\n".
|
||||
'Content-Transfer-Encoding: base64'."\r\n\r\n".
|
||||
chunk_split(base64_encode($sPlainMessage)).
|
||||
'--'.$iBoundary."\r\n".
|
||||
'Content-Type: text/html; charset=UTF-8'."\r\n".
|
||||
'Content-Transfer-Encoding: base64'."\r\n\r\n".
|
||||
chunk_split(base64_encode($sHtmlMessage));
|
||||
|
||||
//Store in case email fails
|
||||
@file_put_contents('log.html', '<br />----<br /><br />'.$sHtmlMessage, FILE_APPEND);
|
||||
|
||||
//Send
|
||||
if(mail('julien.lutran@gmail.com', 'julien.lutran.fr - Contact Me Message', '', $sHeaders))
|
||||
{
|
||||
$sResult = 'ok';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = 'An unknown error occured.';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = 'An error occured: Some fields were empty.';
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
private function checkSerial($sSerial)
|
||||
{
|
||||
$bResult = false;
|
||||
if(strlen($sSerial)==self::PUBLIC_KEY_LENGTH && strpos($this->getAppPath(), $_SERVER['HTTP_REFERER'])===0)
|
||||
{
|
||||
$sFileContent = file_get_contents(self::LOG_FILE);
|
||||
$asKeys = array_filter(explode("\n", $sFileContent));
|
||||
foreach($asKeys as $sKey)
|
||||
{
|
||||
$iOffset = $this->getLoadTime() - substr($sKey, self::PUBLIC_KEY_LENGTH);
|
||||
if($sSerial == substr($sKey, 0, self::PUBLIC_KEY_LENGTH) && $iOffset < self::MAX_REQUEST_TIME)
|
||||
{
|
||||
$bResult = true;
|
||||
file_put_contents(self::LOG_FILE, str_replace($sKey."\n", '', $sFileContent));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
private static function getAppPath()
|
||||
{
|
||||
$sAppPath = 'http://'.str_replace(array('http://', 'https://'), '', $_SERVER['SERVER_NAME'].dirname($_SERVER['SCRIPT_NAME']));
|
||||
$sAppPath = $sAppPath.(substr($sAppPath, -1)!='/'?'/':'');
|
||||
return $sAppPath;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
223
inc/toolbox.php
Normal file
223
inc/toolbox.php
Normal file
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ToolBox - Only static functions missing from php librairy
|
||||
* @author franzz
|
||||
*/
|
||||
class ToolBox
|
||||
{
|
||||
public static function cleanPost(&$asData)
|
||||
{
|
||||
//get rid of magic quotes
|
||||
if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc())
|
||||
{
|
||||
$asData = self::cleanData($asData, 'stripslashes');
|
||||
}
|
||||
}
|
||||
|
||||
public static function cleanData($oData, $sCleaningFunc)
|
||||
{
|
||||
if(!is_array($oData))
|
||||
{
|
||||
return call_user_func($sCleaningFunc, $oData);
|
||||
}
|
||||
elseif(count($oData)>0)
|
||||
{
|
||||
$asCleaningFunc = array_fill(1, count($oData), $sCleaningFunc);
|
||||
$asKeys = array_map(array('self', 'cleanData'), array_keys($oData), $asCleaningFunc);
|
||||
$asValues = array_map(array('self', 'cleanData'), $oData, $asCleaningFunc);
|
||||
return array_combine($asKeys, $asValues);
|
||||
}
|
||||
}
|
||||
|
||||
public static function fixGlobalVars($argv)
|
||||
{
|
||||
//Add CLI arguments
|
||||
if(defined('STDIN')) mb_parse_str(implode('&', array_slice($argv, 1)), $_GET);
|
||||
|
||||
//Add Server Name
|
||||
$sServerName = array_key_exists('SERVER_NAME', $_SERVER)?$_SERVER['SERVER_NAME']:$_SERVER['PWD'];
|
||||
$sAppPath = 'http://'.str_replace('http://', '', $sServerName.dirname($_SERVER['SCRIPT_NAME']));
|
||||
$_GET['serv_name'] = $sAppPath.(mb_substr($sAppPath, -1)!='/'?'/':'');
|
||||
}
|
||||
|
||||
public static function array_map_encapsulate($oData, $sChar)
|
||||
{
|
||||
if(is_array($oData))
|
||||
{
|
||||
$asChar = array_fill(1, count($oData), $sChar);
|
||||
return array_combine(array_keys($oData), array_map(array('self', 'array_map_encapsulate'), $oData, $asChar));
|
||||
}
|
||||
else
|
||||
{
|
||||
return $sChar.$oData.$sChar;
|
||||
}
|
||||
}
|
||||
|
||||
public static function capitalizeWords($acText, $sCharList = '')
|
||||
{
|
||||
// Use ucwords if no delimiters are given
|
||||
if($sCharList=='')
|
||||
{
|
||||
return Toolbox::mb_ucwords($acText);
|
||||
}
|
||||
|
||||
// Go through all characters
|
||||
$capitalizeNext = true;
|
||||
$max = mb_strlen($acText);
|
||||
for ($i = 0; $i < $max; $i++)
|
||||
{
|
||||
if(mb_strpos($sCharList, $acText[$i]) !== false)
|
||||
{
|
||||
$capitalizeNext = true;
|
||||
}
|
||||
elseif($capitalizeNext)
|
||||
{
|
||||
$capitalizeNext = false;
|
||||
$acText[$i] = mb_strtoupper($acText[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
return $acText;
|
||||
}
|
||||
|
||||
public static function createThumbnail($sInPath, $iMaxWidth, $iMaxHeight, $sOutPath='', $bDeleteIn=false, $asImageExts=array('jpg', 'jpeg', 'gif', 'png'))
|
||||
{
|
||||
$asResult = array('error'=>'');
|
||||
|
||||
//Look up the extension to choose the image creator
|
||||
//TODO use MIME types
|
||||
$sInInfo = pathinfo($sInPath);
|
||||
$sInName = mb_strtolower($sInInfo['basename']);
|
||||
$sImageExt = mb_strtolower($sInInfo['extension']);
|
||||
$sImageExt = ($sImageExt=='jpg')?'jpeg':$sImageExt;
|
||||
|
||||
//New Destination folder
|
||||
if($sOutPath=='') $sOutPath = $sInPath;
|
||||
elseif(mb_substr($sOutPath, -1)=='/') $sOutPath .= $sInName;
|
||||
|
||||
//New sizes
|
||||
if(in_array($sImageExt, $asImageExts))
|
||||
{
|
||||
list($iWidth, $iHeight) = getimagesize($sInPath);
|
||||
if($iWidth > $iMaxWidth || $iHeight > $iMaxHeight)
|
||||
{
|
||||
$dResizeDeltaWidth = $iWidth - $iMaxWidth;
|
||||
$dResizeDeltaHeight = $iHeight - $iMaxHeight;
|
||||
if($dResizeDeltaWidth > $dResizeDeltaHeight)
|
||||
{
|
||||
$iResizedWidth = $iMaxWidth;
|
||||
$iResizedHeight = ($iResizedWidth / $iWidth) * $iHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
$iResizedHeight = $iMaxHeight;
|
||||
$iResizedWidth = ($iResizedHeight / $iHeight) * $iWidth;
|
||||
}
|
||||
|
||||
//create image from source
|
||||
$oSource = call_user_func('imagecreatefrom'.$sImageExt, $sInPath);
|
||||
|
||||
//Resize
|
||||
$oThumb = imagecreatetruecolor($iResizedWidth, $iResizedHeight);
|
||||
imagecopyresized($oThumb, $oSource, 0, 0, 0, 0, $iResizedWidth, $iResizedHeight, $iWidth, $iHeight);
|
||||
|
||||
//Save
|
||||
if(file_exists($sOutPath)) unlink($sOutPath);
|
||||
if(!call_user_func_array('image'.$sImageExt, array($oThumb, $sOutPath)))
|
||||
{
|
||||
$asResult['error'] = 'Unable to create thumbnail : '.$sOutPath;
|
||||
}
|
||||
}
|
||||
elseif($sInPath != $sOutPath)
|
||||
{
|
||||
$iResizedWidth = $iWidth;
|
||||
$iResizedHeight = $iHeight;
|
||||
if(!copy($sInPath, $sOutPath)) $asResult['error'] = 'Copy failed from '.$sInPath.' to '.$sOutPath;
|
||||
}
|
||||
$asResult['width'] = $iResizedWidth;
|
||||
$asResult['height'] = $iResizedHeight;
|
||||
$asResult['out'] = $sOutPath;
|
||||
}
|
||||
else $asResult['error'] = 'Wrong file type';
|
||||
|
||||
if($bDeleteIn && $asResult['error']=='' && $sInPath != $sOutPath) unlink($sInPath);
|
||||
|
||||
return $asResult;
|
||||
}
|
||||
|
||||
public static function utf8_compliant($sText)
|
||||
{
|
||||
if(strlen($sText) == 0) return true;
|
||||
return (preg_match('/^.{1}/us', $sText, $ar) == 1);
|
||||
}
|
||||
|
||||
public static function mb_ucwords($sText)
|
||||
{
|
||||
return mb_convert_case($sText, MB_CASE_TITLE, "UTF-8");
|
||||
}
|
||||
|
||||
public static function file_get_contents_utf8($oFile)
|
||||
{
|
||||
$sContent = file_get_contents($oFile);
|
||||
return mb_convert_encoding($sContent, 'UTF-8', mb_detect_encoding($sContent, 'UTF-8, ISO-8859-1', true));
|
||||
}
|
||||
|
||||
public static function rgbToHex($R, $G, $B)
|
||||
{
|
||||
$R = dechex($R);
|
||||
if(strlen($R)<2) $R='0'.$R;
|
||||
|
||||
$G = dechex($G);
|
||||
if(strlen($G)<2) $G='0'.$G;
|
||||
|
||||
$B = dechex($B);
|
||||
if(strlen($B)<2) $B='0'.$B;
|
||||
|
||||
return $R.$G.$B;
|
||||
}
|
||||
|
||||
public static function setCookie($sCookieName, $sCookieValue, $iDays)
|
||||
{
|
||||
$iTimeLimit = time()+60*60*24*$iDays;
|
||||
setcookie($sCookieName, $sCookieValue, $iTimeLimit);
|
||||
}
|
||||
}
|
||||
|
||||
/* Debug */
|
||||
|
||||
function pre($sText, $sTitle='Test', $bDie=false, $sMode='log')
|
||||
{
|
||||
$sLog = '<fieldset class="rounded">
|
||||
<legend class="rounded">'.$sTitle.'</legend>
|
||||
<pre>'.print_r($sText, true).'</pre>
|
||||
</fieldset>';
|
||||
switch($sMode)
|
||||
{
|
||||
case 'echo':
|
||||
echo $sLog;
|
||||
break;
|
||||
case 'return':
|
||||
if($bDie) echo $sLog;
|
||||
break;
|
||||
case 'log':
|
||||
file_put_contents('log.html', ($sTitle!=''?$sTitle." :\n":'').print_r($sText, true)."\n\n", FILE_APPEND);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if($bDie)
|
||||
{
|
||||
die('die() called by the test function '.__FUNCTION__.'().'.($sMode=='log'?' Check log.html for details':''));
|
||||
}
|
||||
|
||||
return $sLog;
|
||||
}
|
||||
|
||||
function dlog($sText, $bDie=false, $sTitle='Test')
|
||||
{
|
||||
pre($sText, date('d/m/Y H:m:i').' - '.$sTitle, $bDie, 'log');
|
||||
}
|
||||
|
||||
?>
|
||||
112
inc/translator.php
Normal file
112
inc/translator.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
class Translator extends PhpObject
|
||||
{
|
||||
private $sLang;
|
||||
private $asLanguages;
|
||||
private $asTranslations; // [lang][key_word] = translation
|
||||
|
||||
const LANG_FOLDER = 'languages/';
|
||||
const LANG_EXT = '.lang';
|
||||
const LANG_SEP = '=';
|
||||
const DEFAULT_LANG = 'FR';
|
||||
|
||||
public function __construct($sLang='')
|
||||
{
|
||||
parent::__construct(__CLASS__, Settings::DEBUG);
|
||||
$this->asLanguages = array();
|
||||
$this->asTranslations = array();
|
||||
$this->loadLanguages();
|
||||
$this->setLanguage($sLang);
|
||||
}
|
||||
|
||||
public function setLanguage($sLang)
|
||||
{
|
||||
$this->sLang = in_array($sLang, $this->asLanguages)?$sLang:self::DEFAULT_LANG;
|
||||
}
|
||||
|
||||
public function getTranslation($sTransKey, $sLang='')
|
||||
{
|
||||
$sTransText = false;
|
||||
|
||||
//Select language
|
||||
if($sLang=='')
|
||||
{
|
||||
$sLang = $this->sLang;
|
||||
}
|
||||
|
||||
//Look up in the selected language dictionary
|
||||
if(in_array($sLang, $this->asLanguages) && array_key_exists($sTransKey, $this->asTranslations[$sLang]))
|
||||
{
|
||||
$sTransText = $this->asTranslations[$sLang][$sTransKey];
|
||||
}
|
||||
//Look up in the default language dictionary
|
||||
elseif(array_key_exists($sTransKey, $this->asTranslations[self::DEFAULT_LANG]))
|
||||
{
|
||||
$this->addWarning('Missing translation in "'.$sLang.'" for the key "'.$sTransKey.'", falling back to "'.self::DEFAULT_LANG.'"');
|
||||
$sTransText = $this->asTranslations[self::DEFAULT_LANG][$sTransKey];
|
||||
}
|
||||
else $this->addWarning('Missing translation in "'.$sLang.'" for the key "'.$sTransKey.'"');
|
||||
|
||||
return $sTransText;
|
||||
}
|
||||
|
||||
public function getHashToPage($asMenuPages)
|
||||
{
|
||||
$asHashToPage = array();
|
||||
foreach($asMenuPages as $sHash)
|
||||
{
|
||||
foreach($this->asLanguages as $sLang)
|
||||
{
|
||||
$asHashToPage[$this->getTranslation('menu_'.$sHash.'_key', $sLang)] = $sHash;
|
||||
}
|
||||
}
|
||||
return $asHashToPage;
|
||||
}
|
||||
|
||||
public function getPageToHash($asMenuPages)
|
||||
{
|
||||
$asPageToHash = array();
|
||||
foreach($asMenuPages as $sHash)
|
||||
{
|
||||
$asPageToHash[$sHash] = $this->getTranslation('menu_'.$sHash.'_key');
|
||||
}
|
||||
return $asPageToHash;
|
||||
}
|
||||
|
||||
private function loadLanguages()
|
||||
{
|
||||
//List all available languages
|
||||
$asLangPaths = glob(self::getLangPath('*'));
|
||||
$this->asLanguages = array_map('basename', $asLangPaths, array_fill(1, count($asLangPaths), self::LANG_EXT));
|
||||
|
||||
//Load languages
|
||||
array_walk($this->asLanguages, array($this, 'loadLanguageFile'));
|
||||
}
|
||||
|
||||
private function loadLanguageFile($sLang)
|
||||
{
|
||||
if(!in_array($sLang, $this->asTranslations))
|
||||
{
|
||||
$sData = file_get_contents(self::getLangPath($sLang));
|
||||
$asData = explode("\n", $sData);
|
||||
foreach($asData as $sTranslation)
|
||||
{
|
||||
$iSepPos = stripos($sTranslation, self::LANG_SEP);
|
||||
if($iSepPos!==false)
|
||||
{
|
||||
$sTransKey = trim(substr($sTranslation, 0, $iSepPos));
|
||||
$sTransText = /*htmlspecialchars(*/trim(substr($sTranslation, $iSepPos+1))/*, ENT_QUOTES)*/; //TODO when all entities have been removed
|
||||
$this->asTranslations[$sLang][$sTransKey] = $sTransText;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function getLangPath($sLang)
|
||||
{
|
||||
return self::LANG_FOLDER.$sLang.self::LANG_EXT;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user