first draft, only one (main) page
This commit is contained in:
234
classmanagement.php
Normal file
234
classmanagement.php
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage includes
|
||||||
|
* @author franzz
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
class ClassManagement extends PhpObject
|
||||||
|
{
|
||||||
|
const INC_FOLDER = 'inc/';
|
||||||
|
const INC_EXT = '.php';
|
||||||
|
const SETTINGS_FILE = 'settings.php';
|
||||||
|
const TOOLBOX_CLASS = 'toolbox';
|
||||||
|
|
||||||
|
private $asIncFiles;
|
||||||
|
|
||||||
|
function __construct($sMainClass)
|
||||||
|
{
|
||||||
|
parent::__construct(__CLASS__, true);
|
||||||
|
$this->asIncFiles = array();
|
||||||
|
|
||||||
|
//try to include default files
|
||||||
|
$this->incFile(self::SETTINGS_FILE);
|
||||||
|
$this->incClass(self::TOOLBOX_CLASS);
|
||||||
|
|
||||||
|
//Include main class
|
||||||
|
$this->incClass($sMainClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
function __destruct()
|
||||||
|
{
|
||||||
|
parent::__destruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function incClass($sClassName)
|
||||||
|
{
|
||||||
|
return $this->incFile(self::INC_FOLDER.$sClassName.self::INC_EXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function incFile($sFilePath, $bMandatory=true)
|
||||||
|
{
|
||||||
|
$bIncluded = false;
|
||||||
|
if(!in_array($sFilePath, $this->asIncFiles))
|
||||||
|
{
|
||||||
|
$sMissingFile = 'File "'.$sFilePath.'" missing.';
|
||||||
|
if(file_exists($sFilePath))
|
||||||
|
{
|
||||||
|
$bIncluded = require_once($sFilePath);
|
||||||
|
$this->asIncFiles[] = $sFilePath;
|
||||||
|
}
|
||||||
|
elseif($bMandatory)
|
||||||
|
{
|
||||||
|
die($sMissingFile.' Stopping process.');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->addError($sMissingFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $bIncluded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author franzz
|
||||||
|
* @version 1.0a
|
||||||
|
*/
|
||||||
|
class PhpObject
|
||||||
|
{
|
||||||
|
//Log file name
|
||||||
|
const LOG_FILENAME = 'log.html';
|
||||||
|
|
||||||
|
//Message types
|
||||||
|
const NOTICE_TAB = 'Notice';
|
||||||
|
const WARNING_TAB = 'Warning';
|
||||||
|
const ERROR_TAB = 'Error';
|
||||||
|
const ALL_TAB = 'All';
|
||||||
|
|
||||||
|
//Extraction mode
|
||||||
|
const MODE_ARRAY = 0;
|
||||||
|
const MODE_TEXT = 1;
|
||||||
|
const MODE_HTML = 2;
|
||||||
|
const MODE_FILE = 3;
|
||||||
|
|
||||||
|
//Class variables
|
||||||
|
private $asMessageStack;
|
||||||
|
private $iExtractMode;
|
||||||
|
private $sChildClass;
|
||||||
|
protected $bDebug;
|
||||||
|
|
||||||
|
function __construct($sClass='', $bDebug=false, $iExtractMode=self::MODE_FILE)
|
||||||
|
{
|
||||||
|
$this->resetMessageStack();
|
||||||
|
$this->iExtractMode = $iExtractMode;
|
||||||
|
$this->sChildClass = $sClass;
|
||||||
|
$this->bDebug = $bDebug;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function getLogPath()
|
||||||
|
{
|
||||||
|
return dirname(__FILE__).'/'.self::LOG_FILENAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resetMessageStack($sType=self::ALL_TAB)
|
||||||
|
{
|
||||||
|
if($sType==self::ALL_TAB)
|
||||||
|
{
|
||||||
|
$this->resetMessageStack(self::NOTICE_TAB);
|
||||||
|
$this->resetMessageStack(self::WARNING_TAB);
|
||||||
|
$this->resetMessageStack(self::ERROR_TAB);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->asMessageStack[$sType] = array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function addNotice($sNotice)
|
||||||
|
{
|
||||||
|
$this->addMessage(self::NOTICE_TAB, $sNotice);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function addWarning($sWarning)
|
||||||
|
{
|
||||||
|
$this->addMessage(self::WARNING_TAB, $sWarning);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function addError($sError)
|
||||||
|
{
|
||||||
|
$this->addMessage(self::ERROR_TAB, $sError);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addMessage($sType, $sMessage)
|
||||||
|
{
|
||||||
|
$this->asMessageStack[$sType][] = $sMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCleanMessageStack($sType=self::ALL_TAB)
|
||||||
|
{
|
||||||
|
$asMessages = ($sType==self::ALL_TAB)?$this->asMessageStack:$this->asMessageStack[$sType];
|
||||||
|
$this->resetMessageStack($sType);
|
||||||
|
|
||||||
|
return $this->glueMessages($asMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function cleanMessageStack()
|
||||||
|
{
|
||||||
|
$sErrorStack = $this->getCleanMessageStack($this->bDebug?self::ALL_TAB:self::ERROR_TAB);
|
||||||
|
if($sErrorStack!='')
|
||||||
|
{
|
||||||
|
switch($this->iExtractMode)
|
||||||
|
{
|
||||||
|
case self::MODE_TEXT:
|
||||||
|
echo $sErrorStack;
|
||||||
|
break;
|
||||||
|
case self::MODE_HTML:
|
||||||
|
echo $sErrorStack;
|
||||||
|
break;
|
||||||
|
case self::MODE_ARRAY:
|
||||||
|
break;
|
||||||
|
case self::MODE_FILE:
|
||||||
|
@file_put_contents(self::getLogPath(), "\n\n".$this->sChildClass.' - '.date('r')."\n".$sErrorStack, FILE_APPEND);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCleanMessageStacks($aoExtsources, $sType=self::ALL_TAB)
|
||||||
|
{
|
||||||
|
$aoExtsources[] = $this;
|
||||||
|
$aoMessages = array();
|
||||||
|
foreach($aoExtsources as $oExtSource)
|
||||||
|
{
|
||||||
|
$oMessages = $oExtSource->getCleanMessageStack($sType);
|
||||||
|
if($oMessages!='')
|
||||||
|
{
|
||||||
|
$aoMessages[get_class($oExtSource)] = $oMessages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->glueMessages($aoMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function glueMessages($asMessages)
|
||||||
|
{
|
||||||
|
switch($this->iExtractMode)
|
||||||
|
{
|
||||||
|
case self::MODE_TEXT:
|
||||||
|
$oMessageStack = self::recursiveImplode("\n", $asMessages);
|
||||||
|
break;
|
||||||
|
case self::MODE_HTML:
|
||||||
|
$oMessageStack = self::recursiveImplode('<br />', $asMessages);
|
||||||
|
break;
|
||||||
|
case self::MODE_ARRAY:
|
||||||
|
$oMessageStack = $asMessages;
|
||||||
|
break;
|
||||||
|
case self::MODE_FILE:
|
||||||
|
$oMessageStack = self::recursiveImplode("\n", $asMessages);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $oMessageStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function flattenMessageStack($asTab, $sGlobalKey='')
|
||||||
|
{
|
||||||
|
$asFlatTab = array();
|
||||||
|
foreach($asTab as $oKey=>$oRow)
|
||||||
|
{
|
||||||
|
$sKey = is_numeric($oKey)?$sGlobalKey:$oKey.' - ';
|
||||||
|
if(is_array($oRow))
|
||||||
|
{
|
||||||
|
$asFlatTab = array_merge($asFlatTab, self::flattenMessageStack($oRow, $sKey));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$asFlatTab[] = $sKey.$oRow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $asFlatTab;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function recursiveImplode($sGlue, $asTab)
|
||||||
|
{
|
||||||
|
$asTab = self::flattenMessageStack($asTab);
|
||||||
|
return implode($sGlue, $asTab);
|
||||||
|
}
|
||||||
|
|
||||||
|
function __destruct()
|
||||||
|
{
|
||||||
|
$this->cleanMessageStack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
ob_start();
|
ob_start();
|
||||||
|
|
||||||
$sType = isset($_REQUEST['t'])?$_REQUEST['t']:'';
|
$sType = isset($_REQUEST['t'])?$_REQUEST['t']:'';
|
||||||
$sSerial = isset($_GET['a'])?$_GET['a']:'';
|
$sSerial = isset($_GET['s'])?$_GET['s']:'';
|
||||||
$sName = isset($_POST['name'])?$_POST['name']:'';
|
$sName = isset($_POST['name'])?$_POST['name']:'';
|
||||||
$sEmail = isset($_POST['email'])?$_POST['email']:'';
|
$sEmail = isset($_POST['email'])?$_POST['email']:'';
|
||||||
$sSubject = isset($_POST['subject'])?$_POST['subject']:'';
|
$sSubject = isset($_POST['subject'])?$_POST['subject']:'';
|
||||||
|
|||||||
70
index.php
Normal file
70
index.php
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
Wedding Project
|
||||||
|
http://git.lutran.fr/wedding.git
|
||||||
|
Copyright (C) 2014 François Lutran
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
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, see http://www.gnu.org/licenses
|
||||||
|
*/
|
||||||
|
|
||||||
|
//Start buffering
|
||||||
|
ob_start();
|
||||||
|
require_once 'classmanagement.php';
|
||||||
|
$oClassManagement = new ClassManagement('resume');
|
||||||
|
ToolBox::cleanPost($_POST);
|
||||||
|
ToolBox::cleanPost($_GET);
|
||||||
|
ToolBox::cleanPost($_REQUEST);
|
||||||
|
|
||||||
|
//Add server name
|
||||||
|
$sAppPath = 'http://'.str_replace('http://', '', $_SERVER['SERVER_NAME'].dirname($_SERVER['SCRIPT_NAME']));
|
||||||
|
$_GET['serv_name'] = $sAppPath.(substr($sAppPath, -1)!='/'?'/':'');
|
||||||
|
|
||||||
|
//Available variables
|
||||||
|
$sAction = isset($_GET['a'])?$_GET['a']:'';
|
||||||
|
$sPage = isset($_GET['p'])?$_GET['p']:'index';
|
||||||
|
$sLang = isset($_GET['l'])?$_GET['l']:(isset($_COOKIE['l'])?$_COOKIE['l']:'');
|
||||||
|
$sSerial = isset($_GET['s'])?$_GET['s']:'';
|
||||||
|
$sName = isset($_POST['name'])?$_POST['name']:'';
|
||||||
|
$sEmail = isset($_POST['email'])?$_POST['email']:'';
|
||||||
|
$sSubject = isset($_POST['subject'])?$_POST['subject']:'';
|
||||||
|
$sMsg = isset($_POST['message'])?$_POST['message']:'';
|
||||||
|
|
||||||
|
//Initiate main class
|
||||||
|
$oResume = new Resume($oClassManagement, $sLang);
|
||||||
|
|
||||||
|
//Check requested action
|
||||||
|
switch($sAction)
|
||||||
|
{
|
||||||
|
case 'javascript':
|
||||||
|
$sResult = $oResume->getJavascript();
|
||||||
|
break;
|
||||||
|
case 'pic':
|
||||||
|
$sResult = $oResume->getPic($sSerial);
|
||||||
|
break;
|
||||||
|
case 'mail':
|
||||||
|
$sResult = $oResume->sendEmail($sName, $sEmail, $sSubject, $sMsg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$sResult = $oResume->getPage($sPage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Log and clean buffer
|
||||||
|
$sDebug = ob_get_clean();
|
||||||
|
if(Settings::DEBUG && $sDebug!='') dlog($sDebug, true);
|
||||||
|
|
||||||
|
echo $sResult;
|
||||||
|
|
||||||
|
?>
|
||||||
File diff suppressed because one or more lines are too long
@@ -8,7 +8,7 @@ $(document).ready
|
|||||||
var $Pic = $('#pic');
|
var $Pic = $('#pic');
|
||||||
$Pic.css('height', iPicHeight+'px');
|
$Pic.css('height', iPicHeight+'px');
|
||||||
$('.person').css('marginTop', Math.round(($('#header').height() - $Pic.outerHeight())/2));
|
$('.person').css('marginTop', Math.round(($('#header').height() - $Pic.outerHeight())/2));
|
||||||
$Pic.attr('src', cConfigPage+'?t=pic&a='+a);
|
$Pic.attr('src', cConfigPage+'?a=pic&s='+s);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Fix IE
|
//Fix IE
|
||||||
@@ -29,7 +29,7 @@ $(document).ready
|
|||||||
Cufon.replace('h1', {fontFamily:'Candara'});
|
Cufon.replace('h1', {fontFamily:'Candara'});
|
||||||
Cufon.replace('.item h2', {fontFamily:'Puritan 2.0'});
|
Cufon.replace('.item h2', {fontFamily:'Puritan 2.0'});
|
||||||
Cufon.replace('.item h3', {fontFamily:'Puritan 2.0'});
|
Cufon.replace('.item h3', {fontFamily:'Puritan 2.0'});
|
||||||
Cufon.replace('h2.section_name', {fontFamily:'Hattori Hanzo Light'});
|
Cufon.replace('h2.section_name', {fontFamily:'Andika Basic'});
|
||||||
|
|
||||||
//Contact panel events
|
//Contact panel events
|
||||||
$('#contact_me_btn, #contact_me_link').click
|
$('#contact_me_btn, #contact_me_link').click
|
||||||
@@ -146,7 +146,7 @@ $(document).ready
|
|||||||
$('a[href^=#]').click(function(e){$(this).jump(e);});
|
$('a[href^=#]').click(function(e){$(this).jump(e);});
|
||||||
|
|
||||||
//To-the-top Button
|
//To-the-top Button
|
||||||
iProfileHeight = $('#profile').offset().top;
|
iProfileHeight = $('#presentation').offset().top;
|
||||||
$(window).scroll
|
$(window).scroll
|
||||||
(
|
(
|
||||||
function()
|
function()
|
||||||
@@ -203,7 +203,9 @@ $.prototype.jump = function(e)
|
|||||||
var sElem = this.attr('href');
|
var sElem = this.attr('href');
|
||||||
if(sElem != '#')
|
if(sElem != '#')
|
||||||
{
|
{
|
||||||
e.preventDefault();
|
if($(this).parent().parent().attr('id')!='menu') e.preventDefault();
|
||||||
|
else sElem += '_ln';
|
||||||
|
|
||||||
this.blur();
|
this.blur();
|
||||||
var $Elem = $(sElem);
|
var $Elem = $(sElem);
|
||||||
var iOffSet = ($Elem.length>0)?($Elem.offset().top - 15):0;
|
var iOffSet = ($Elem.length>0)?($Elem.offset().top - 15):0;
|
||||||
|
|||||||
0
jquery/jquery.functions.min.js
vendored
0
jquery/jquery.functions.min.js
vendored
1
languages/.htaccess
Normal file
1
languages/.htaccess
Normal file
@@ -0,0 +1 @@
|
|||||||
|
deny from all
|
||||||
2
languages/EN.lang
Normal file
2
languages/EN.lang
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
language=EN
|
||||||
|
name=TOTO
|
||||||
22
languages/FR.lang
Normal file
22
languages/FR.lang
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
language=FR
|
||||||
|
header_name=Julien Lutran
|
||||||
|
header_title=Ingenieur Stockage SAN
|
||||||
|
menu_prez=Présentation
|
||||||
|
menu_prez_key=presentation
|
||||||
|
menu_xp=Expérience
|
||||||
|
menu_xp_key=experience
|
||||||
|
menu_lang=Langues
|
||||||
|
menu_lang_key=langues
|
||||||
|
menu_skills=Compétences
|
||||||
|
menu_skills_key=competences
|
||||||
|
menu_edu=Formation
|
||||||
|
menu_edu_key=formation
|
||||||
|
menu_switch_lang=English
|
||||||
|
menu_switch_lang_key=EN
|
||||||
|
card_xp=8 années d'experience
|
||||||
|
card_certif=Certification NetApp NCDA
|
||||||
|
card_edu=License Professionnelle
|
||||||
|
card_contact_me=Contactez-moi
|
||||||
|
profile_par1=Après 6 ans d'administration système sur les environnements de production de plusieurs grands comptes, j'ai eu l'opportunité d'intégrer une équipe d'ingénierie en infrastructure. Ce poste m'a permis de me spécialiser dans le domaine du stockage SAN et de concevoir des solutions pour des clients implantés à l'international
|
||||||
|
profile_par2=Toujours curieux et passionné par les nouvelles technologies, mon expérience me permet de m'adapter rapidement afin de relever avec succès chaque nouveau challenge professionnel que l'on peut me confier
|
||||||
|
profile_more_info=pour plus d'informations
|
||||||
43
log
Normal file
43
log
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
538a4c65e8f1e1401572453
|
||||||
|
538a4c8daea991401572493
|
||||||
|
538a4c91cd3cd1401572497
|
||||||
|
538a4c9cd4b741401572508
|
||||||
|
538a4df5a548d1401572853
|
||||||
|
538a4e1332b4e1401572883
|
||||||
|
538a4e18a4cbf1401572888
|
||||||
|
538a4e3a08c4b1401572922
|
||||||
|
538a4e40869781401572928
|
||||||
|
538a4e56e79591401572950
|
||||||
|
538a4e586a9ae1401572952
|
||||||
|
538a4e59244d71401572953
|
||||||
|
538a4ee9806811401573097
|
||||||
|
538a4f6c6107e1401573228
|
||||||
|
538a4f81e0c5d1401573249
|
||||||
|
538a4f89c124f1401573257
|
||||||
|
538a504d24efd1401573453
|
||||||
|
538a512251e7f1401573666
|
||||||
|
538a5180a63b31401573760
|
||||||
|
538a51ae726161401573806
|
||||||
|
538a51e8a53df1401573864
|
||||||
|
538a521b5fe1c1401573915
|
||||||
|
538a52b42e41f1401574068
|
||||||
|
538a52dbb9f871401574107
|
||||||
|
538a52dd785221401574109
|
||||||
|
538a52de1ef961401574110
|
||||||
|
538a52de923711401574110
|
||||||
|
538a52ded943a1401574110
|
||||||
|
538a52df278891401574111
|
||||||
|
538a540ca032e1401574412
|
||||||
|
538a5432014be1401574450
|
||||||
|
538a543951f711401574457
|
||||||
|
538a545a3426a1401574490
|
||||||
|
538a549e48e081401574558
|
||||||
|
538a54a9ee9141401574569
|
||||||
|
538a54d8d1ae61401574616
|
||||||
|
538c3979b77ca1401698681
|
||||||
|
538c3a10ced641401698832
|
||||||
|
538c3a1277b3a1401698834
|
||||||
|
538c47e69c3271401702374
|
||||||
|
538c4845a805c1401702469
|
||||||
|
538c4890535f21401702544
|
||||||
|
538c494a8de161401702730
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Julien Lutran </title>
|
<title>Julien Lutran </title>
|
||||||
<meta name="robots" content="noimageindex" />
|
<meta name="robots" content="noimageindex" />
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
<meta http-equiv="Content-Type" content="text/html; charset=[#]encoding[#]" />
|
||||||
<meta name="description" content="cv Julien Lutran" />
|
<meta name="description" content="cv Julien Lutran" />
|
||||||
<meta name="keywords" content="cv ingenieur stockage SAN" />
|
<meta name="keywords" content="cv ingenieur stockage SAN" />
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="images/favicon.ico" />
|
<link rel="shortcut icon" type="image/x-icon" href="images/favicon.ico" />
|
||||||
@@ -19,16 +19,24 @@
|
|||||||
<script src="jquery/cufon.fonts.js" type="text/javascript"></script>
|
<script src="jquery/cufon.fonts.js" type="text/javascript"></script>
|
||||||
<script src="jquery/jquery.min.js" type="text/javascript"></script>
|
<script src="jquery/jquery.min.js" type="text/javascript"></script>
|
||||||
<script src="jquery/jquery.tipsy.min.js" type="text/javascript"></script>
|
<script src="jquery/jquery.tipsy.min.js" type="text/javascript"></script>
|
||||||
<script src="includes/config.php?t=javascript" type="text/javascript"></script>
|
<script src="index.php?a=javascript" type="text/javascript"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="cv">
|
<div id="cv">
|
||||||
|
<div id="menu">
|
||||||
|
<div><a href="#[#]menu_prez_key[#]">[#]menu_prez[#]</a></div>
|
||||||
|
<div><a href="#[#]menu_xp_key[#]">[#]menu_xp[#]</a></div>
|
||||||
|
<div><a href="#[#]menu_lang_key[#]">[#]menu_lang[#]</a></div>
|
||||||
|
<div><a href="#[#]menu_skills_key[#]">[#]menu_skills[#]</a></div>
|
||||||
|
<div><a href="#[#]menu_edu_key[#]">[#]menu_edu[#]</a></div>
|
||||||
|
<div><a href="#[#]menu_switch_lang_key[#]">[#]menu_switch_lang[#]</a></div>
|
||||||
|
</div>
|
||||||
<div id="header" class="section header fixed">
|
<div id="header" class="section header fixed">
|
||||||
<div class="paperclip"></div>
|
<div class="paperclip"></div>
|
||||||
<div class="person">
|
<div class="person">
|
||||||
<img oncontextmenu="return false;" id="pic" src="images/pic.gif" alt="Julien Lutran" />
|
<img oncontextmenu="return false;" id="pic" src="images/pic.gif" alt="Julien Lutran" />
|
||||||
<h1>Julien Lutran</h1>
|
<h1>[#]header_name[#]</h1>
|
||||||
<h2><span>Ingenieur Stockage SAN</span></h2>
|
<h2><span>[#]header_title[#]</span></h2>
|
||||||
</div>
|
</div>
|
||||||
<div id="card">
|
<div id="card">
|
||||||
<ul class="card_buttons">
|
<ul class="card_buttons">
|
||||||
@@ -38,11 +46,11 @@
|
|||||||
<li><a href="#" id="print" title="Print this page" class="tip_link"><img src="images/print.png" alt="Print"/></a></li>
|
<li><a href="#" id="print" title="Print this page" class="tip_link"><img src="images/print.png" alt="Print"/></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="card_items">
|
<ul class="card_items">
|
||||||
<li class="xp"><a href="#work">8 années d'experience</a></li>
|
<li class="xp"><a href="#work">[#]card_xp[#]</a></li>
|
||||||
<li class="globe"><a href="#certif">Certification NetApp NCDA</a></li>
|
<li class="globe"><a href="#certif">[#]card_certif[#]</a></li>
|
||||||
<li class="university"><a href="#licence">License Professionnelle</a></li>
|
<li class="university"><a href="#licence">[#]card_edu[#]</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<a id="contact_me_btn" class="contact_me_btn clickable" href="#">Contactez-moi</a>
|
<a id="contact_me_btn" class="contact_me_btn clickable" href="#">[#]card_contact_me[#]</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="contact_me_box" class="section contact fixed hide">
|
<div id="contact_me_box" class="section contact fixed hide">
|
||||||
@@ -59,17 +67,17 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="profile" class="section profile fixed">
|
<div id="[#]menu_prez_key[#]_ln" class="section profile fixed">
|
||||||
<h2 class="section_name">Presentation</h2>
|
<h2 class="section_name">[#]menu_prez[#]</h2>
|
||||||
<div class="section_items">
|
<div class="section_items">
|
||||||
<div class="item last_item">
|
<div class="item last_item">
|
||||||
<p>Après 6 ans d'administration système sur les environnements de production de plusieurs grands comptes, j'ai eu l'opportunité d'intégrer une équipe d'ingénierie en infrastructure. Ce poste m'a permis de me spécialiser dans le domaine du stockage SAN et de concevoir des solutions pour des clients implantés à l'international.</p>
|
<p>[#]profile_par1[#].</p>
|
||||||
<p>Toujours curieux et passionné par les nouvelles technologies, mon expérience me permet de m'adapter rapidement afin de relever avec succès chaque nouveau challenge professionnel que l'on peut me confier.</p>
|
<p>[#]profile_par2[#].</p>
|
||||||
<p class="last"><a id="contact_me_link" class="no_print_link" href="#contact_me">Contactez-moi <span id="mail"></span>pour plus d'informations</a>.</p>
|
<p class="last"><a id="contact_me_link" class="no_print_link" href="#contact_me">[#]card_contact_me[#] <span id="mail"></span>[#]profile_more_info[#]</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="work" class="section work fixed">
|
<div id="[#]menu_xp_key[#]_ln" class="section work fixed">
|
||||||
<h2 class="section_name">Experience professionnelle</h2>
|
<h2 class="section_name">Experience professionnelle</h2>
|
||||||
<div class="section_items">
|
<div class="section_items">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
@@ -92,8 +100,8 @@
|
|||||||
<li class="action">Analyse et conception de solutions de stockage EMC et NetApp</li>
|
<li class="action">Analyse et conception de solutions de stockage EMC et NetApp</li>
|
||||||
<li class="action">Test et validation des nouveaux produits, rédaction de documentations techniques</li>
|
<li class="action">Test et validation des nouveaux produits, rédaction de documentations techniques</li>
|
||||||
<li class="action">Support aux équipes d'avant-vente et d'implémentation</li>
|
<li class="action">Support aux équipes d'avant-vente et d'implémentation</li>
|
||||||
<li class="action">Support aux équipes BackOffice pour la résolution d'incidents complexes</li>
|
<li class="action">Support aux équipes BackOffice pour la résolution d'incidents complexes</li>
|
||||||
<li class="action">Analyse et résolution de problèmes performances sur les infrastructures de stockage client</li>
|
<li class="action">Analyse et résolution de problèmes performances sur les infrastructures de stockage client</li>
|
||||||
<li class="action">Développement de scripts d'industrialisation</li>
|
<li class="action">Développement de scripts d'industrialisation</li>
|
||||||
<li class="action">Veille technologique</li>
|
<li class="action">Veille technologique</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -138,7 +146,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div></div>
|
</div></div>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="subtitle">Expertise UNIX et réalisation de projets techniques</li>
|
<li class="subtitle">Expertise UNIX et réalisation de projets techniques</li>
|
||||||
<li class="action">Administration des environnements de production (SI des bureaux de Poste, automates d'affranchissement, etc...)</li>
|
<li class="action">Administration des environnements de production (SI des bureaux de Poste, automates d'affranchissement, etc...)</li>
|
||||||
<li class="action">Expertise technique sur l'infrastructure virtuelle existante : IBM pSeries (LPAR), Zones Solaris et hyperviseurs ESX</li>
|
<li class="action">Expertise technique sur l'infrastructure virtuelle existante : IBM pSeries (LPAR), Zones Solaris et hyperviseurs ESX</li>
|
||||||
<li class="action">Implémentation système AIX, Solaris et Linux RedHat</li>
|
<li class="action">Implémentation système AIX, Solaris et Linux RedHat</li>
|
||||||
@@ -166,11 +174,11 @@
|
|||||||
</div></div>
|
</div></div>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="subtitle">Administration UNIX / Linux pour EDF R&D</li>
|
<li class="subtitle">Administration UNIX / Linux pour EDF R&D</li>
|
||||||
<li class="action">Migration des bases métier vers Oracle 10g</li>
|
<li class="action">Migration des bases métier vers Oracle 10g</li>
|
||||||
<li class="action">Installation d'une plateforme de stockage HP EVA 8100 et rédaction de procédures d'exploitation</li>
|
<li class="action">Installation d'une plateforme de stockage HP EVA 8100 et rédaction de procédures d'exploitation</li>
|
||||||
<li class="action">Etude et migration de l'authentification centralisée de NIS vers OpenLDAP
|
<li class="action">Etude et migration de l'authentification centralisée de NIS vers OpenLDAP
|
||||||
<li class="action">Exploitation de cluster HPC IBM Blue Gene/L et Blue Gene/P</li>
|
<li class="action">Exploitation de cluster HPC IBM Blue Gene/L et Blue Gene/P</li>
|
||||||
<li class="action">Gestion des sauvegardes serveurs: politique, rétention, externalisation</li>
|
<li class="action">Gestion des sauvegardes serveurs: politique, rétention, externalisation</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@@ -184,7 +192,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div></div>
|
</div></div>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="subtitle">Installation et dépannage sur site EDF R&D</li>
|
<li class="subtitle">Installation et dépannage sur site EDF R&D</li>
|
||||||
<li class="action">Gestion des changements et incidents de niveau 2 sur stations de travail (Linux Debian et Windows 2000/XP)</li>
|
<li class="action">Gestion des changements et incidents de niveau 2 sur stations de travail (Linux Debian et Windows 2000/XP)</li>
|
||||||
<li class="action">Câblage et configuration des équipements réseau</li>
|
<li class="action">Câblage et configuration des équipements réseau</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -193,7 +201,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section language fixed">
|
<div id="[#]menu_lang_key[#]_ln" class="section language fixed">
|
||||||
<h2 class="section_name">Langues</h2>
|
<h2 class="section_name">Langues</h2>
|
||||||
<div class="section_items">
|
<div class="section_items">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
@@ -206,7 +214,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section technical fixed">
|
<div id="[#]menu_skills_key[#]_ln" class="section technical fixed">
|
||||||
<h2 class="section_name">Competences techniques</h2>
|
<h2 class="section_name">Competences techniques</h2>
|
||||||
<div class="section_items">
|
<div class="section_items">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
@@ -254,7 +262,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section education fixed">
|
<div id="[#]menu_edu_key[#]_ln" class="section education fixed">
|
||||||
<h2 class="section_name">Formation</h2>
|
<h2 class="section_name">Formation</h2>
|
||||||
<div class="section_items">
|
<div class="section_items">
|
||||||
<div class="item" id="certif">
|
<div class="item" id="certif">
|
||||||
23
settings.php
Normal file
23
settings.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Settings
|
||||||
|
{
|
||||||
|
const LOC_API_KEY = 'get a API key from http://ipinfodb.com/';
|
||||||
|
const MAIL_SCRIPT = 'your mail script (optional)';
|
||||||
|
const MAIL_API_KEY = 'your mail API key (optional)';
|
||||||
|
const MAIL_ADDRESS = 'admin email address';
|
||||||
|
const CONSUMER_KEY = 'Your Twitter API KEY (consumer)';
|
||||||
|
const CONSUMER_SECRET = 'Your Twitter API KEY (consumer secret)';
|
||||||
|
const OAUTH_TOKEN = 'Your Twitter API KEY (OAuth token)';
|
||||||
|
const OAUTH_TOKEN_SECRET = 'Your Twitter API KEY (OAuth token secret)';
|
||||||
|
const DB_SERVER = 'localhost';
|
||||||
|
const DB_LOGIN = 'root';
|
||||||
|
const DB_PASS = '';
|
||||||
|
const DB_NAME = 'wedding';
|
||||||
|
const DB_ENC = 'utf8mb4';
|
||||||
|
const TEXT_ENC = 'UTF-8';
|
||||||
|
const TIMEZONE = 'Europe/Paris';
|
||||||
|
const DEBUG = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -278,6 +278,47 @@ h2.section_name {
|
|||||||
padding:0 0 40px;
|
padding:0 0 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Menu */
|
||||||
|
|
||||||
|
#menu {
|
||||||
|
padding:0;
|
||||||
|
margin:0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu div {
|
||||||
|
display:inline-block;
|
||||||
|
width:16%;
|
||||||
|
padding:5px;
|
||||||
|
text-align:center;
|
||||||
|
/*border-left:1px solid #DEDEDE;*/
|
||||||
|
border-right:1px solid #DEDEDE;
|
||||||
|
box-sizing:border-box;
|
||||||
|
-moz-box-sizing:border-box;
|
||||||
|
-webkit-box-sizing:border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu div:hover {
|
||||||
|
background:rgb(99, 123, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu div:hover a {
|
||||||
|
color:white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu a {
|
||||||
|
font-size:14px;
|
||||||
|
color:#4B5564;
|
||||||
|
}
|
||||||
|
|
||||||
|
#card {
|
||||||
|
float:right;
|
||||||
|
border-style:solid;
|
||||||
|
border-width: 1px 2px 2px 1px;
|
||||||
|
border-color: #DEDEDE #808080 #808080 #DEDEDE;
|
||||||
|
padding:10px;
|
||||||
|
background:#FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
/* Header */
|
/* Header */
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
|
|||||||
Reference in New Issue
Block a user