init
This commit is contained in:
226
config.php
Executable file
226
config.php
Executable file
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Manage includes
|
||||
* @author franzz
|
||||
*/
|
||||
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();
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PhpObject
|
||||
* @author franzz
|
||||
* @version 1.0
|
||||
*/
|
||||
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;
|
||||
protected $bDebug;
|
||||
|
||||
function __construct($iExtractMode=self::MODE_FILE)
|
||||
{
|
||||
$this->resetMessageStack();
|
||||
$this->iExtractMode = $iExtractMode;
|
||||
$this->bDebug = false;
|
||||
}
|
||||
|
||||
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 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()
|
||||
{
|
||||
$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".date('r')."\n".$sErrorStack, FILE_APPEND);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
131
inc/main.php
Executable file
131
inc/main.php
Executable file
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Main Class
|
||||
* @author franzz
|
||||
* @version 1.0
|
||||
*/
|
||||
class Main extends PhpObject
|
||||
{
|
||||
//Constants
|
||||
//...
|
||||
|
||||
//Objects
|
||||
private $oClassManagement;
|
||||
private $oMySql;
|
||||
private $oTranslator;
|
||||
//...
|
||||
|
||||
//Variables
|
||||
private $sLang;
|
||||
private $asMasks;
|
||||
//...
|
||||
|
||||
/**
|
||||
* Main constructor [to be called from index.php]
|
||||
* @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);
|
||||
|
||||
//Load classes
|
||||
$this->oClassManagement->incClass('mask');
|
||||
$this->oClassManagement->incClass('translator');
|
||||
$this->oClassManagement->incClass('mysqlmanager');
|
||||
//...
|
||||
|
||||
//Init objects
|
||||
$this->setLanguage($sLang);
|
||||
$this->setMasks();
|
||||
$this->oTranslator = new Translator($this->getLanguage());
|
||||
$this->oMySql = new MySqlManager(Settings::DB_SERVER, Settings::DB_LOGIN, Settings::DB_PASS, Settings::DB_NAME, self::getSqlOptions() , Settings::DB_ENC);
|
||||
if($this->oMySql->sDbState == MySqlManager::DB_NO_DATA) $this->install();
|
||||
//...
|
||||
}
|
||||
|
||||
/**
|
||||
* DB structure. See MySqlManager::__construct
|
||||
*/
|
||||
private static function getSqlOptions()
|
||||
{
|
||||
return array
|
||||
(
|
||||
'tables' => array
|
||||
(
|
||||
self::USER_TABLE=>array( 'first_name', 'last_name', 'nickname', 'email', 'pass')
|
||||
//...
|
||||
),
|
||||
'types' => array
|
||||
(
|
||||
'first_name'=>"varchar(20) NOT NULL",
|
||||
'last_name'=>"varchar(20) NOT NULL",
|
||||
'nickname'=>"varchar(50) NOT NULL",
|
||||
'email'=>"varchar(100) NOT NULL",
|
||||
'pass'=>"varchar(128) NOT NULL"
|
||||
//...
|
||||
),
|
||||
'constraints' => array
|
||||
(
|
||||
self::USER_TABLE=>"UNIQUE KEY `firstname_lastname_nickname` (`first_name`, `last_name`, `nickname`)"
|
||||
//...
|
||||
),
|
||||
'cascading_delete' => array
|
||||
(
|
||||
self::USER_TABLE=>array(self::DON_TABLE)
|
||||
//...
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function getLanguage()
|
||||
{
|
||||
return $this->sLang;
|
||||
}
|
||||
|
||||
private function setLanguage($sLang='')
|
||||
{
|
||||
if($sLang!='') $this->sLang = $sLang;
|
||||
else
|
||||
{
|
||||
//$_SERVER['REMOTE_ADDR'] = '193.106.178.41'; //Spain
|
||||
//$_SERVER['REMOTE_ADDR'] = '160.92.167.193'; //France
|
||||
//$_SERVER['REMOTE_ADDR'] = '74.125.230.216'; //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 setMasks()
|
||||
{
|
||||
//List all available masks
|
||||
$asMaskPaths = glob(Mask::getMaskFile('*'));
|
||||
$this->asMasks = array_map('basename', $asMaskPaths, array_fill(1, count($asMaskPaths), Mask::MASK_EXT));
|
||||
}
|
||||
|
||||
private static function jsonExport($asData)
|
||||
{
|
||||
header('Content-type: application/json');
|
||||
//return htmlspecialchars(json_encode($asData), ENT_NOQUOTES);
|
||||
return self::jsonConvert($asData);
|
||||
}
|
||||
|
||||
private static function jsonConvert($asData)
|
||||
{
|
||||
return json_encode($asData);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
231
inc/mask.php
Executable file
231
inc/mask.php
Executable file
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Mask Reader
|
||||
* @author franzz
|
||||
* @version 1.0
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
600
inc/mysqlmanager.php
Executable file
600
inc/mysqlmanager.php
Executable file
@@ -0,0 +1,600 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* MySql query manager and generator
|
||||
* @author franzz
|
||||
* @version 1.0
|
||||
*/
|
||||
class MySqlManager extends PhpObject
|
||||
{
|
||||
const DB_NO_CONN = 'ERR_1';
|
||||
const DB_NO_DATA = 'ERR_2';
|
||||
const ID_TAG = 'id_';
|
||||
|
||||
public $sDbState;
|
||||
private $bTrace;
|
||||
private $asOptions;
|
||||
|
||||
/**
|
||||
* SQL connection Handle
|
||||
* @var mysqli
|
||||
*/
|
||||
private $oConnection;
|
||||
private $sDatabase;
|
||||
|
||||
/**
|
||||
* Constructor MySqlManager
|
||||
* @param String $sDbServer
|
||||
* @param String $sLogin
|
||||
* @param String $sPass
|
||||
* @param String $sDatabase
|
||||
* @param Array $asOptions
|
||||
* array( 'tables'=>array('table_name1'=>array('table_field1', 'table_field2', ...), 'table_name2'=>array(...)),
|
||||
* 'types'=>array('field1'=>'field_type1', 'field2'=>'field_type2', ...)
|
||||
* 'constraints'=>array('table_name1'=>'table_contraint1', 'table_name2'=>'table_contraint2', ...),
|
||||
* 'cascading_delete'=>array('table_name1'=>array('linked_table1', 'linked_table2', ...), 'table_name2'=>...))
|
||||
* @param string $sEncoding
|
||||
*/
|
||||
public function __construct($sDbServer, $sLogin, $sPass, $sDatabase, $asOptions, $sEncoding='utf8mb4')
|
||||
{
|
||||
parent::__construct(__CLASS__, Settings::DEBUG);
|
||||
$this->sDatabase = $sDatabase;
|
||||
$this->asOptions = $asOptions;
|
||||
//$this->oConnection = mysql_connect(self::DB_SERVER, self::DB_LOGIN, self::DB_PASS);
|
||||
$this->oConnection = new mysqli($sDbServer, $sLogin, $sPass);
|
||||
$this->syncPhpParams($sEncoding);
|
||||
|
||||
/*
|
||||
$dsn = 'mysql:dbname='.$this->sDatabase.';host='.self::DB_SERVER;
|
||||
try {$dbh = new PDO($dsn, self::DB_LOGIN, self::DB_PASS);}
|
||||
catch (PDOException $e) {$this->addError('Connexion échouée : ' . $e->getMessage());}
|
||||
*/
|
||||
|
||||
$this->setTrace(false);
|
||||
//if(!$this->oConnection)
|
||||
if($this->oConnection->connect_error)
|
||||
{
|
||||
//$this->addError('bug connection');
|
||||
$this->addError('bug connection : '.$this->oConnection->connect_error);
|
||||
$this->sDbState = self::DB_NO_CONN;
|
||||
}
|
||||
else
|
||||
{
|
||||
//if(!mysql_select_db($this->sDatabase, $this->oConnection))
|
||||
if(!$this->oConnection->select_db($this->sDatabase))
|
||||
{
|
||||
$this->addError('bug selecting database. Installing...');
|
||||
$this->sDbState = self::DB_NO_DATA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function syncPhpParams($sEncoding)
|
||||
{
|
||||
//Characters encoding
|
||||
$this->oConnection->set_charset($sEncoding); //SET NAMES
|
||||
|
||||
//Time zone
|
||||
$oNow = new DateTime();
|
||||
$iMins = $oNow->getOffset() / 60;
|
||||
$iSign = ($iMins < 0)?-1:1;
|
||||
$iMins = abs($iMins);
|
||||
$iHours = floor($iMins / 60);
|
||||
$iMins -= $iHours * 60;
|
||||
$sOffset = sprintf('%+d:%02d', $iHours*$iSign, $iMins);
|
||||
$this->setQuery("SET time_zone='{$sOffset}';");
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
parent::__destruct();
|
||||
//mysql_close($this->oConnection);
|
||||
$this->oConnection->close();
|
||||
}
|
||||
|
||||
public function setTrace($bAction)
|
||||
{
|
||||
$this->bTrace = $bAction;
|
||||
}
|
||||
|
||||
public function getTables()
|
||||
{
|
||||
/*
|
||||
$oReflect = new ReflectionClass(__CLASS__);
|
||||
$asConstants = $oReflect->getConstants();
|
||||
$sTableTag = '_TABLE';
|
||||
$asTables = array();
|
||||
foreach($asConstants as $sConstant=>$sConstantValue)
|
||||
{
|
||||
if(mb_strpos($sConstant, $sTableTag)!==false && mb_strpos($sConstant, $sTableTag)==(mb_strlen($sConstant) - mb_strlen($sTableTag)))
|
||||
{
|
||||
$asTables[] = $sConstantValue;
|
||||
}
|
||||
}
|
||||
return $asTables;
|
||||
*/
|
||||
return array_keys($this->asOptions['tables']);
|
||||
}
|
||||
|
||||
public function install()
|
||||
{
|
||||
//Create Database
|
||||
$this->setQuery("DROP DATABASE IF EXISTS ".$this->sDatabase);
|
||||
$this->setQuery("CREATE DATABASE ".$this->sDatabase." DEFAULT CHARACTER SET ".Settings::DB_ENC." DEFAULT COLLATE ".Settings::DB_ENC."_general_ci");
|
||||
//mysql_select_db($this->sDatabase, $this->oConnection);
|
||||
$this->oConnection->select_db($this->sDatabase);
|
||||
|
||||
//Create tables
|
||||
@array_walk($this->getInstallQueries(), array($this, 'setQuery'));
|
||||
}
|
||||
|
||||
//For debug purposes
|
||||
public function getFullInstallQuery()
|
||||
{
|
||||
$asInstallQueries = $this->getInstallQueries();
|
||||
return str_replace("\n", "<br />", implode(";\n\n", $asInstallQueries))."\n\n<!-- \n".implode(";\n\n", $asInstallQueries)."\n -->";
|
||||
}
|
||||
|
||||
private function getInstallQueries()
|
||||
{
|
||||
$asTables = $this->getTables();
|
||||
$asInstallQueries = array_map(array($this, 'getInstallQuery'), $asTables);
|
||||
$asAlterQueries = $this->getForeignKeyQueries($asTables);
|
||||
return array_merge($asInstallQueries, $asAlterQueries);
|
||||
}
|
||||
|
||||
private function getInstallQuery($sTableName)
|
||||
{
|
||||
$asTableColumns = $this->getTableColumns($sTableName);
|
||||
$sQuery = "\n".$this->implodeAll($asTableColumns, "` ", "\n", "`", ",")."\n".implode(", \n", $this->getTableConstraints($sTableName));
|
||||
return "CREATE TABLE `{$sTableName}` ({$sQuery})";
|
||||
}
|
||||
|
||||
private function getForeignKeyQueries($asTableNames)
|
||||
{
|
||||
$asForeignKeyQueries = array();
|
||||
foreach($asTableNames as $sTableName)
|
||||
{
|
||||
$asTableColumns = array_keys($this->getTablecolumns($sTableName));
|
||||
foreach($asTableColumns as $sColumnName)
|
||||
{
|
||||
if($this->isId($sColumnName) && $sColumnName!=self::getId($sTableName))
|
||||
{
|
||||
$asForeignKeyQueries[] = "ALTER TABLE ".$sTableName." ADD INDEX(`".$sColumnName."`)";
|
||||
$asForeignKeyQueries[] = "ALTER TABLE ".$sTableName." ADD FOREIGN KEY (`".$sColumnName."`) REFERENCES ".self::getTable($sColumnName)."(`".$sColumnName."`)";
|
||||
}
|
||||
}
|
||||
}
|
||||
return $asForeignKeyQueries;
|
||||
}
|
||||
|
||||
private function setQuery($sQuery, $sTypeQuery=__FUNCTION__)
|
||||
{
|
||||
$this->getQuery($sQuery, $sTypeQuery);
|
||||
//return (mysql_affected_rows()!=0);
|
||||
return ($this->oConnection->affected_rows!=0);
|
||||
}
|
||||
|
||||
private function getQuery($sQuery, $sTypeQuery=__FUNCTION__)
|
||||
{
|
||||
$sQuery = str_replace(array("\n", "\t"), array(" ", ""), $sQuery);
|
||||
//$oResult = mysql_query($sQuery, $this->oConnection);
|
||||
|
||||
if($this->bTrace)
|
||||
{
|
||||
$this->setDebug(true);
|
||||
$this->addNotice($sQuery);
|
||||
}
|
||||
|
||||
if(!($oResult = $this->oConnection->query($sQuery)))
|
||||
{
|
||||
$this->addError("\nErreur SQL : \n".str_replace("\t", "", $sQuery)."\n\n".str_replace(array("\t", "\n"), "", $this->oConnection->error));
|
||||
}
|
||||
return $oResult;
|
||||
}
|
||||
|
||||
public function getLastError()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function getArrayQuery($sQuery, $bStringOnly=false, $sGroupBy='', $sTypeQuery=__FUNCTION__)
|
||||
{
|
||||
$iIndex = 0;
|
||||
$iColumnCount = 0;
|
||||
$asResult = array();
|
||||
$oResult = $this->getQuery($sQuery, true, $sTypeQuery);
|
||||
if($oResult!==false)
|
||||
{
|
||||
//while($asCurrentRow = mysql_fetch_array($oResult))
|
||||
while($asCurrentRow = $oResult->fetch_array())
|
||||
{
|
||||
if($bStringOnly) $asCurrentRow = $this->arrayKeyFilter($asCurrentRow, 'is_string');
|
||||
|
||||
//Add table reel keys
|
||||
if($sGroupBy!='' && array_key_exists($sGroupBy, $asCurrentRow))
|
||||
{
|
||||
$iRowKey = $asCurrentRow[$sGroupBy];
|
||||
unset($asCurrentRow[$sGroupBy]);
|
||||
}
|
||||
else $iRowKey = $iIndex;
|
||||
|
||||
//For first loop, check table width
|
||||
if($iIndex==0) $iColumnCount = count($asCurrentRow);
|
||||
|
||||
//One column case : collapse a level
|
||||
if($iColumnCount==1) $asCurrentRow = array_shift($asCurrentRow);
|
||||
|
||||
$asResult[$iRowKey] = $asCurrentRow;
|
||||
$iIndex++;
|
||||
}
|
||||
}
|
||||
return $asResult;
|
||||
}
|
||||
|
||||
private function getMaxIncrementedValue($sTable)
|
||||
{
|
||||
return $this->selectValue($sTable, "MAX(".$this->getId($sTable).")");
|
||||
}
|
||||
|
||||
public static function getId($sTableName, $bFull=false)
|
||||
{
|
||||
$sColumnName = self::ID_TAG.self::getText($sTableName);
|
||||
return $bFull?self::getFullColumnName($sTableName, $sColumnName):$sColumnName;
|
||||
}
|
||||
|
||||
public static function getText($sTableName, $bFull=false)
|
||||
{
|
||||
$sColumnName = mb_substr(str_replace('`', '', $sTableName), 0, -1);
|
||||
$sColumnName = mb_substr($sColumnName, -2)=='ie'?mb_substr($sColumnName, 0, -2).'y':$sColumnName;
|
||||
return $bFull?self::getFullColumnName($sTableName, $sColumnName):$sColumnName;
|
||||
}
|
||||
|
||||
public static function getFullColumnName($sTableName, $sColumnName)
|
||||
{
|
||||
return $sTableName.".".$sColumnName;
|
||||
}
|
||||
|
||||
private function isId($sColumnName, $sTableName='')
|
||||
{
|
||||
$asTables = ($sTableName=='')?$this->getTables():array($sTableName);
|
||||
$asTableIds = array_map(array('self', 'getId'), $asTables);
|
||||
return in_array($sColumnName, $asTableIds);
|
||||
}
|
||||
|
||||
private function getTable($sTableId)
|
||||
{
|
||||
$asTables = $this->getTables();
|
||||
$asTableIds = array_map(array('self', 'getId'), $asTables);
|
||||
if(in_array($sTableId, $asTableIds)) return $asTables[array_search($sTableId, $asTableIds)];
|
||||
else
|
||||
{
|
||||
$this->addError('Id '.$sTableId.' présent dans aucune table');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getTablecolumns($sTableName)
|
||||
{
|
||||
if(!array_key_exists($sTableName, $this->asOptions['tables'])) return false;
|
||||
|
||||
$asTableColumns = array(self::getId($sTableName));
|
||||
foreach($this->asOptions['tables'][$sTableName] as $sFieldName) $asTableColumns[] = $sFieldName;
|
||||
$asTableColumns[] = 'led';
|
||||
|
||||
$asTableName = array_fill(0, count($asTableColumns), $sTableName);
|
||||
return array_combine($asTableColumns, array_map(array('self', 'getColumnType'), $asTableColumns, $asTableName));
|
||||
}
|
||||
|
||||
private function getColumnType($sColumnName, $sTableName)
|
||||
{
|
||||
$sColumnType = '';
|
||||
switch($sColumnName)
|
||||
{
|
||||
case array_key_exists($sColumnName, $this->asOptions['types']):
|
||||
$sColumnType = $this->asOptions['types'][$sColumnName];
|
||||
break;
|
||||
case 'led':
|
||||
$sColumnType = "TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP";
|
||||
break;
|
||||
case $this->isId($sColumnName, $sTableName):
|
||||
$sColumnType = "int(10) UNSIGNED auto_increment";
|
||||
break;
|
||||
case $this->isId($sColumnName):
|
||||
$sColumnType = "int(10) UNSIGNED";
|
||||
break;
|
||||
}
|
||||
return $sColumnType;
|
||||
}
|
||||
|
||||
private function getTableConstraints($sTableName)
|
||||
{
|
||||
//Primary key
|
||||
$asTableConstraints = array('PRIMARY' => "PRIMARY KEY (`".self::getId($sTableName)."`)");
|
||||
|
||||
//Foreign keys: applied using ALTER TABLE syntax at the end to prevent scheduling CREATE TABLE queries
|
||||
|
||||
//Other constraints
|
||||
if(array_key_exists($sTableName, $this->asOptions['constraints'])) $asTableConstraints[] = $this->asOptions['constraints'][$sTableName];
|
||||
return $asTableConstraints;
|
||||
}
|
||||
|
||||
private function addQuotes($oData)
|
||||
{
|
||||
//TODO remake
|
||||
$asTrustedFunc = array('CURDATE()', 'NOW()');
|
||||
$sChar = "'";
|
||||
if(is_array($oData))
|
||||
{
|
||||
$asChar = array_fill(1, count($oData), $sChar);
|
||||
return array_combine(array_keys($oData), array_map(array($this, 'addQuotes'), $oData, $asChar));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(in_array($oData, $asTrustedFunc)) return $oData;
|
||||
else return $sChar.$oData.$sChar;
|
||||
}
|
||||
}
|
||||
|
||||
private function getLastId()
|
||||
{
|
||||
return $this->oConnection->insert_id;
|
||||
}
|
||||
|
||||
public function insertRow($sTableName, $asData)
|
||||
{
|
||||
$this->cleanSql($sTableName);
|
||||
$this->cleanSql($asData);
|
||||
|
||||
$asQueryValues = $this->addQuotes($asData);
|
||||
$sQuery = "INSERT INTO ".$sTableName." (`".implode("`, `", array_keys($asQueryValues))."`) VALUES (".implode(", ", $asQueryValues).")";
|
||||
return $this->setQuery($sQuery)?$this->getLastId():0;
|
||||
}
|
||||
|
||||
public function updateRow($sTableName, $asConstraints, $asData)
|
||||
{
|
||||
return $this->updateRows($sTableName, $asConstraints, $asData, 1);
|
||||
}
|
||||
|
||||
public function updateRows($sTableName, $asConstraints, $asData, $iLimit=0)
|
||||
{
|
||||
if(!is_array($asConstraints))
|
||||
{
|
||||
$asConstraints = array($this->getId($sTableName)=>$asConstraints);
|
||||
}
|
||||
|
||||
$this->cleanSql($sTableName);
|
||||
$this->cleanSql($iTableId);
|
||||
$this->cleanSql($asData);
|
||||
$this->cleanSql($asConstraints);
|
||||
$asQueryValues = $this->addQuotes($asData);
|
||||
$asConstraintsValues = $this->addQuotes($asConstraints);
|
||||
$this->addColumnSelectors($asQueryValues);
|
||||
$this->addColumnSelectors($asConstraintsValues);
|
||||
|
||||
$sLimit = $iLimit>0?" LIMIT $iLimit":"";
|
||||
$sQuery = "UPDATE {$sTableName} ".
|
||||
"SET ".$this->implodeAll($asQueryValues, " = ", ", ")." ".
|
||||
"WHERE ".$this->implodeAll($asConstraintsValues, " = ", " AND ").$sLimit;
|
||||
|
||||
$iResult = false;
|
||||
if($this->setQuery($sQuery))
|
||||
{
|
||||
$iResult = ($iLimit==1)?$this->selectValue($sTableName, $this->getId($sTableName), $asConstraints):true;
|
||||
}
|
||||
return $iResult;
|
||||
}
|
||||
|
||||
public function insertUpdateRow($sTableName, $asData, $asKeys=array(), $bUpdate=true)
|
||||
{
|
||||
$sTableIdName = self::getId($sTableName);
|
||||
|
||||
//check for data in the db
|
||||
if($asKeys==array())
|
||||
{
|
||||
$asKeys[] = $sTableIdName;
|
||||
}
|
||||
$asValues = array_intersect_key($asData, array_flip($asKeys));
|
||||
$iTableId = $this->selectValue($sTableName, $sTableIdName, $asValues);
|
||||
|
||||
//insert
|
||||
if(!$iTableId)
|
||||
{
|
||||
$iTableId = $this->insertRow($sTableName, $asData);
|
||||
}
|
||||
//Update
|
||||
elseif($bUpdate)
|
||||
{
|
||||
if(array_key_exists($sTableIdName, $asData))
|
||||
{
|
||||
unset($asData[$sTableIdName]);
|
||||
}
|
||||
$iTableId = $this->updateRow($sTableName, $iTableId, $asData);
|
||||
}
|
||||
return $iTableId;
|
||||
}
|
||||
|
||||
public function selectInsert($sTableName, $asData, $asKeys=array())
|
||||
{
|
||||
return $this->insertUpdateRow($sTableName, $asData, $asKeys, false);
|
||||
}
|
||||
|
||||
public function deleteRow($sTableName, $iTableId)
|
||||
{
|
||||
$this->cleanSql($sTableName);
|
||||
$this->cleanSql($iTableId);
|
||||
|
||||
//linked tables
|
||||
switch($sTableName)
|
||||
{
|
||||
case array_key_exists($sTableName, $this->asOptions['cascading_delete']) :
|
||||
$asTables = array_filter(is_array($sTableName)?$sTableName:array($sTableName) + $this->asOptions['cascading_delete'][$sTableName]);
|
||||
break;
|
||||
case is_string($sTableName) :
|
||||
$asTables = array($sTableName);
|
||||
break;
|
||||
case is_array($sTableName):
|
||||
$asTables = $sTableName;
|
||||
break;
|
||||
default:
|
||||
$asTables = array();
|
||||
}
|
||||
foreach($asTables as $sTable)
|
||||
{
|
||||
$this->setQuery("DELETE FROM ".$sTable." WHERE ".$this->getId($sTableName)." = ".$iTableId);
|
||||
}
|
||||
}
|
||||
|
||||
public function selectRows($asInfo, $bStringOnly=true, $sGroupBy='')
|
||||
{
|
||||
$asAttributes = array('select'=>"SELECT", 'from'=>"FROM", 'join'=>"LEFT JOIN", 'joinOn'=>"LEFT JOIN", 'constraint'=>"WHERE", 'groupBy'=>"GROUP BY", 'orderBy'=>"ORDER BY", 'limit'=>'LIMIT');
|
||||
$asRowSeparators = array('select'=>", ", 'from'=>"", 'join'=>" LEFT JOIN ", 'joinOn'=>" LEFT JOIN ", 'constraint'=>" AND ", 'groupBy'=>", ", 'orderBy'=>", ", 'limit'=>"");
|
||||
$asOperators = array('constraint'=>" = ", 'orderBy'=>" ", 'join'=>" USING(", 'joinOn'=>" ON ");
|
||||
$asEndOfStatement = array('constraint'=>"", 'orderBy'=>"", 'join'=>")", 'joinOn'=>"");
|
||||
|
||||
//$sQuery = "/* ".str_replace(array("\n", "\t"), '', print_r($asInfo, true))." */";
|
||||
$sQuery = "";
|
||||
foreach($asAttributes as $sStatement => $sKeyWord)
|
||||
{
|
||||
$asSelection = array_key_exists($sStatement, $asInfo)?$asInfo[$sStatement]:array();
|
||||
if(!is_array($asSelection))
|
||||
{
|
||||
$asSelection = array($asSelection);
|
||||
}
|
||||
|
||||
//if provided values
|
||||
if(!empty($asSelection))
|
||||
{
|
||||
$this->cleanSql($asSelection);
|
||||
|
||||
if($sStatement=='constraint' && !array_key_exists('constVar', $asInfo))
|
||||
{
|
||||
$asSelection = $this->addQuotes($asSelection);
|
||||
}
|
||||
$this->addColumnSelectors($asSelection);
|
||||
|
||||
$sQuery .= " ".$sKeyWord." ";
|
||||
|
||||
//in case of double value input
|
||||
if(array_key_exists($sStatement, $asOperators))
|
||||
{
|
||||
if($sStatement=='constraint' && array_key_exists('constOpe', $asInfo))
|
||||
{
|
||||
$asOperators[$sStatement] = $asInfo['constOpe'];
|
||||
}
|
||||
$sQuery .= $this->implodeAll($asSelection, $asOperators[$sStatement], $asRowSeparators[$sStatement], "", $asEndOfStatement[$sStatement]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sQuery .= implode($asRowSeparators[$sStatement], $asSelection);
|
||||
}
|
||||
}
|
||||
//default value for select
|
||||
elseif($sStatement=='select')
|
||||
{
|
||||
$sQuery .= " ".$sKeyWord." * ";
|
||||
}
|
||||
}
|
||||
return $this->getArrayQuery($sQuery, $bStringOnly, $sGroupBy);
|
||||
}
|
||||
|
||||
private function addColumnSelectors(&$asSelection)
|
||||
{
|
||||
//TODO get rid of this
|
||||
$sSqlWord = 'option';
|
||||
$sKey = array_search($sSqlWord, $asSelection);
|
||||
if($sKey!==false)
|
||||
{
|
||||
$asSelection[$sKey] = "`".$asSelection[$sKey]."`";
|
||||
}
|
||||
elseif(array_key_exists($sSqlWord, $asSelection))
|
||||
{
|
||||
$asSelection["`".$sSqlWord."`"] = $asSelection[$sSqlWord];
|
||||
unset($asSelection[$sSqlWord]);
|
||||
}
|
||||
}
|
||||
|
||||
public function selectRow($sTableName, $asConstraints=array(), $sColumnName='*')
|
||||
{
|
||||
if(!is_array($asConstraints))
|
||||
{
|
||||
$asConstraints = array($this->getId($sTableName)=>$asConstraints);
|
||||
}
|
||||
$asResult = $this->selectRows(array('select'=>$sColumnName, 'from'=>$sTableName, 'constraint'=>$asConstraints));
|
||||
$iCountNb = count($asResult);
|
||||
switch($iCountNb)
|
||||
{
|
||||
case 0 :
|
||||
return false;
|
||||
case $iCountNb > 1 :
|
||||
$this->addError('Trop de résultats pour un selectRow() : '.$iCountNb.' lignes. Table: '.$sTableName.', contrainte: '.self::implodeAll($asConstraints, '=', ' ').', colonne: '.$sColumnName);
|
||||
break;
|
||||
}
|
||||
return array_shift($asResult);
|
||||
}
|
||||
|
||||
public function selectValue($sTableName, $sColumnName, $oConstraints=array())
|
||||
{
|
||||
if(!is_array($oConstraints))
|
||||
{
|
||||
$oConstraints = array($this->getId($sTableName)=>$oConstraints);
|
||||
}
|
||||
return $this->selectRow($sTableName, $oConstraints, $sColumnName);
|
||||
}
|
||||
|
||||
public function pingValue($sTableName, $oConstraints)
|
||||
{
|
||||
return $this->selectValue($sTableName, 'COUNT(1)', $oConstraints);
|
||||
}
|
||||
|
||||
public function cleanSql(&$oData)
|
||||
{
|
||||
//self::cleanData($oData, 'mysql_real_escape_string');
|
||||
//$oData = self::cleanData($oData, 'mysql_real_escape_string');
|
||||
$this->cleanData($oData);
|
||||
$oData = $this->cleanData($oData);
|
||||
}
|
||||
|
||||
public static function implodeAll($asText, $asKeyValueSeparator='', $sRowSeparator='', $sKeyPre='', $sValuePost=false)
|
||||
{
|
||||
if($sValuePost===false)
|
||||
{
|
||||
$sValuePost = $sKeyPre;
|
||||
}
|
||||
$asCombinedText = array();
|
||||
|
||||
//if unique value for key value separator
|
||||
if(!is_array($asKeyValueSeparator) && !empty($asText))
|
||||
{
|
||||
$asKeyValueSeparator = array_combine(array_keys($asText), array_fill(0, count($asText), $asKeyValueSeparator));
|
||||
}
|
||||
|
||||
foreach($asText as $sKey=>$sValue)
|
||||
{
|
||||
$asCombinedText[] = $sKeyPre.$sKey.$asKeyValueSeparator[$sKey].(is_array($sValue)?implode($sValue):$sValue).$sValuePost;
|
||||
}
|
||||
return implode($sRowSeparator, $asCombinedText);
|
||||
}
|
||||
|
||||
public static function arrayKeyFilter($asArray, $sCallBack)
|
||||
{
|
||||
$asValidKeys = array_flip(array_filter(array_keys($asArray), $sCallBack));
|
||||
return array_intersect_key($asArray, $asValidKeys);
|
||||
}
|
||||
|
||||
public function cleanData($oData)
|
||||
{
|
||||
if(!is_array($oData))
|
||||
{
|
||||
return $this->oConnection->real_escape_string($oData);
|
||||
}
|
||||
elseif(count($oData)>0)
|
||||
{
|
||||
$asKeys = array_map(array($this, 'cleanData'), array_keys($oData));
|
||||
$asValues = array_map(array($this, 'cleanData'), $oData);
|
||||
return array_combine($asKeys, $asValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
169
inc/rss.php
Executable file
169
inc/rss.php
Executable file
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RSS Feed Class
|
||||
* @author franzz
|
||||
* @version 1.1
|
||||
*
|
||||
* Input:
|
||||
* - $asDesc: Array. Description of the feed: fields 'title', 'link' (optional), 'copyright', 'description', 'language', 'webmaster_mail'
|
||||
* - $asItems: Array. Feed item data: fields 'title', 'description', 'author', 'link', 'pub_date', 'guid'
|
||||
*/
|
||||
class Feed extends PhpObject {
|
||||
|
||||
private $asDesc;
|
||||
private $asItems;
|
||||
|
||||
public function __construct($asDesc, $asItems=array())
|
||||
{
|
||||
parent::__construct(__CLASS__, Settings::DEBUG);
|
||||
if(!array_key_exists('link', $asDesc))
|
||||
{
|
||||
$asDesc['link'] = 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME'].'/rss';
|
||||
}
|
||||
$this->asDesc = $asDesc;
|
||||
array_walk($asItems, array($this, 'addItem'));
|
||||
}
|
||||
|
||||
public function addItem($asItem)
|
||||
{
|
||||
$this->asItems[] = $asItem;
|
||||
return count($this->asItems) - 1;
|
||||
}
|
||||
|
||||
public function removeItem($iItemId)
|
||||
{
|
||||
$bExist = array_key_exists($iItemId, $this->asItems);
|
||||
if($bExist) unset($this->asItems[$iItemId]);
|
||||
return $bExist;
|
||||
}
|
||||
|
||||
private function getGlobalPubDate()
|
||||
{
|
||||
$iGlobalPubDate = 0;
|
||||
foreach($this->asItems as $asItem)
|
||||
{
|
||||
$iItemPubDate = strtotime($asItem['pub_date']);
|
||||
if($iItemPubDate>$iGlobalPubDate)
|
||||
{
|
||||
$iGlobalPubDate = $iItemPubDate;
|
||||
}
|
||||
}
|
||||
return self::cleanRss(self::getDate($iGlobalPubDate));
|
||||
}
|
||||
|
||||
public function getFeed()
|
||||
{
|
||||
|
||||
//feed header
|
||||
$sRssFeedHeader = self::getHtml($this->asDesc['title'], 'title');
|
||||
$sRssFeedHeader .= self::getHtml($this->asDesc['link'], 'link');
|
||||
$sRssFeedHeader .= self::getHtml($this->asDesc['copyright'], 'copyright');
|
||||
$sRssFeedHeader .= self::getHtml($this->asDesc['description'], 'description');
|
||||
$sRssFeedHeader .= self::getHtml('', 'atom:link', '', '', array('href'=>$this->asDesc['link'], 'rel'=>'self', 'type'=>'application/atom+xml'), true);
|
||||
$sRssFeedHeader .= self::getHtml($this->asDesc['language'], 'language');
|
||||
$sRssFeedHeader .= self::getHtml($this->getGlobalPubDate(), 'pubDate');
|
||||
$sRssFeedHeader .= self::getHtml('Lutran.fr RSS Feed Generator', 'generator');
|
||||
$sRssFeedHeader .= self::getHtml($this->asDesc['webmaster_mail'].' (Webmaster)', 'webMaster');
|
||||
|
||||
//feed items
|
||||
$asSortedItems = $this->rSortTimeMatrix($this->asItems, 'pub_date');
|
||||
$sItems = implode("\n", array_map(array($this, 'buildItem'), $asSortedItems));
|
||||
|
||||
//Global Feed
|
||||
$sFeed = '<?xml version="1.0" encoding="'.Settings::TEXT_ENC.'" ?>';
|
||||
$sFeed .= self::getHtml(self::getHtml($sRssFeedHeader.$sItems, 'channel'), 'rss', '', '', array('version'=>'2.0', 'xmlns:atom'=>'http://www.w3.org/2005/Atom'));
|
||||
|
||||
return $sFeed;
|
||||
}
|
||||
|
||||
private static function getDate($sDate)
|
||||
{
|
||||
if(!is_numeric($sDate))
|
||||
{
|
||||
$sDate = strtotime($sDate);
|
||||
}
|
||||
return date('r', $sDate);
|
||||
}
|
||||
|
||||
private function buildItem($asItem)
|
||||
{
|
||||
$sRssItem = self::getHtml(self::cleanRss($asItem['title']), 'title');
|
||||
$sRssItem .= self::getHtml(self::cleanRss($asItem['author']), 'author');
|
||||
$sRssItem .= self::getHtml($asItem['link'], 'link');
|
||||
$sRssItem .= self::getHtml($asItem['category'], 'category');
|
||||
$sRssItem .= self::getHtml(self::cleanRss($asItem['description'].'.'), 'description');
|
||||
$sRssItem .= self::getHtml(self::getDate($asItem['pub_date']), 'pubDate');
|
||||
$sRssItem .= self::getHtml($asItem['guid'], 'guid', '', '', array('isPermaLink'=>'true'));
|
||||
return self::getHtml($sRssItem, 'item');
|
||||
}
|
||||
|
||||
private static function getHtml($oText, $sTag, $sClass='', $sStyle='', $asExtraAttr=array(), $bAutoClose=false, $sInter='')
|
||||
{
|
||||
$sHtmlAttr = '';
|
||||
if($sClass!='')
|
||||
{
|
||||
$asExtraAttr['class'] = $sClass;
|
||||
}
|
||||
if($sStyle!='')
|
||||
{
|
||||
$asExtraAttr['style'] = $sStyle;
|
||||
}
|
||||
foreach($asExtraAttr as $sAttrName=>$sAttrValue)
|
||||
{
|
||||
$sHtmlAttr .= ' '.$sAttrName.'="'.$sAttrValue.'"';
|
||||
}
|
||||
if($bAutoClose)
|
||||
{
|
||||
$sHtml = self::encapsulate('', "\n".'<'.$sTag.$sHtmlAttr, ' />');
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml = self::encapsulate($oText, "\n".'<'.$sTag.$sHtmlAttr.'>', '</'.$sTag.'>', $sInter);
|
||||
}
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
private static function cleanRss($oText)
|
||||
{
|
||||
$asForbiddenChars = array('&', '<', '>', '"', "'");
|
||||
$asReplacementCode = array('&', '<', '>', '"', ''');
|
||||
if(!is_array($oText))
|
||||
{
|
||||
return str_replace($asForbiddenChars, $asReplacementCode, $oText);
|
||||
}
|
||||
elseif(count($oText)>0)
|
||||
{
|
||||
$oTextKeys = array_map(array($this, 'cleanRss'), array_keys($oText));
|
||||
$oTextValues = array_map(array($this, 'cleanRss'), array_values($oText));
|
||||
return array_combine($oTextKeys, $oTextValues);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $oText;
|
||||
}
|
||||
}
|
||||
|
||||
private static function encapsulate($oText, $sPre='', $sPost=false, $sInter='')
|
||||
{
|
||||
if($sPost===false)
|
||||
{
|
||||
$sPost = $sPre;
|
||||
}
|
||||
if(is_array($oText))
|
||||
{
|
||||
$oText = implode($sPost.$sInter.$sPre, $oText);
|
||||
}
|
||||
return $sPre.$oText.$sPost;
|
||||
}
|
||||
|
||||
private static function rSortTimeMatrix($asMatrix, $sTimeCol)
|
||||
{
|
||||
$asResult = array();
|
||||
foreach($asMatrix as $iRowId=>$asLine) $asKeys[$iRowId] = strtotime($asLine[$sTimeCol]);
|
||||
arsort($asKeys);
|
||||
foreach($asKeys as $iRowId=>$iTimeStamp) $asResult[$iRowId] = $asMatrix[$iRowId];
|
||||
return $asResult;
|
||||
}
|
||||
}
|
||||
?>
|
||||
235
inc/toolbox.php
Executable file
235
inc/toolbox.php
Executable file
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ToolBox - Only static functions missing from php librairy
|
||||
* @author franzz
|
||||
* @version 1.1
|
||||
*/
|
||||
class ToolBox
|
||||
{
|
||||
const MAIL_SUCCESS = 2;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param String $sFromName
|
||||
* @param String $sSubject
|
||||
* @param String $sMessage
|
||||
* @param String $sTo
|
||||
* @param Array $asCc array(name => email)
|
||||
* @param Boolean $bSelfMail
|
||||
* @return mixed
|
||||
*/
|
||||
public function sendMail($sFromName, $sSubject, $sMessage, $sTo, $asCc=array(), $bSelfMail=true)
|
||||
{
|
||||
$asForm = array('api_key'=>Settings::MAIL_API_KEY,
|
||||
'app'=>'Wedding',
|
||||
'from_name'=>$sFromName,
|
||||
'subject'=>$sSubject,
|
||||
'msg'=>$sMessage,
|
||||
'to_email'=>$sTo,
|
||||
'cc_email'=>self::jsonConvert($asCc),
|
||||
'self'=>$bSelfMail);
|
||||
|
||||
$oCurl = curl_init();
|
||||
curl_setopt($oCurl, CURLOPT_URL, Settings::MAIL_SCRIPT);
|
||||
curl_setopt($oCurl, CURLOPT_POST, true);
|
||||
curl_setopt($oCurl, CURLOPT_HEADER, false);
|
||||
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($oCurl, CURLOPT_POSTFIELDS, $asForm);
|
||||
$iResult = curl_exec($oCurl);
|
||||
curl_close($oCurl);
|
||||
|
||||
return $iResult;
|
||||
}
|
||||
|
||||
public static function jsonExport($asData)
|
||||
{
|
||||
header('Content-type: application/json');
|
||||
//return htmlspecialchars(json_encode($asData), ENT_NOQUOTES);
|
||||
return self::jsonConvert($asData);
|
||||
}
|
||||
|
||||
public static function jsonConvert($asData)
|
||||
{
|
||||
return json_encode($asData);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
117
inc/translator.php
Executable file
117
inc/translator.php
Executable file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Translator Class
|
||||
* @author franzz
|
||||
* @version 1.0
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
39
index.php
Executable file
39
index.php
Executable file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/* Requests Handler */
|
||||
|
||||
//Start buffering
|
||||
ob_start();
|
||||
require_once 'config.php';
|
||||
$oClassManagement = new ClassManagement('main');
|
||||
ToolBox::cleanPost($_POST);
|
||||
ToolBox::cleanPost($_GET);
|
||||
ToolBox::cleanPost($_REQUEST);
|
||||
ToolBox::fixGlobalVars(isset($argv)?$argv:array());
|
||||
|
||||
//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']:'');
|
||||
//...
|
||||
|
||||
//Initiate class
|
||||
$oWedding = new Main($oClassManagement, $sLang);
|
||||
switch($sAction)
|
||||
{
|
||||
case 'action':
|
||||
break;
|
||||
//...
|
||||
|
||||
default:
|
||||
$sResult = $oWedding->getPage($sPage);
|
||||
break;
|
||||
}
|
||||
|
||||
//Log and clean buffer
|
||||
$sDebug = ob_get_clean();
|
||||
if(Settings::DEBUG && $sDebug!='') dlog($sDebug, true);
|
||||
|
||||
echo $sResult;
|
||||
|
||||
?>
|
||||
4
script/jquery.js
vendored
Normal file
4
script/jquery.js
vendored
Normal file
File diff suppressed because one or more lines are too long
22
settings.php
Executable file
22
settings.php
Executable file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
class Settings
|
||||
{
|
||||
const LOC_API_KEY = '1cfb97eb3c88913653f3d5bc0096e92c2e7edc523712d2bf1bcf49946571951a';
|
||||
const MAIL_SCRIPT = 'http://francois.lutran.fr/send_mail.php';
|
||||
const CONSUMER_KEY = 'JEZlzGK7x6Evg5ShlVHiA';
|
||||
const CONSUMER_SECRET = 'khD9ljSQtJlluiemyAgbVISnb0Kl8d22Ir34ftfQX0';
|
||||
const OAUTH_TOKEN = '1531614350-XnXaDmmj0qCiHh2ffDGtiwZR4RxOZ9SqXplaE8S';
|
||||
const OAUTH_TOKEN_SECRET = 'otz0XQsWoSTywfHCI49QuVEOcZjvNGrgVwM7uDM';
|
||||
const MAIL_API_KEY = '8D98B36BB558BC6771324AEFB9E37';
|
||||
const DB_SERVER = 'localhost';
|
||||
const DB_LOGIN = 'root';
|
||||
const DB_PASS = '0nadmin';
|
||||
const DB_NAME = '';
|
||||
const DB_ENC = 'utf8mb4';
|
||||
const TEXT_ENC = 'UTF-8';
|
||||
const TIMEZONE = 'Europe/Paris';
|
||||
const DEBUG = true;
|
||||
}
|
||||
|
||||
?>
|
||||
436
standalone/cerberus.php
Executable file
436
standalone/cerberus.php
Executable file
@@ -0,0 +1,436 @@
|
||||
<?php
|
||||
|
||||
/* Main (Exemple) */
|
||||
|
||||
session_start();
|
||||
//session_destroy();
|
||||
|
||||
pre($_COOKIE, 'Cookie');
|
||||
pre($_SESSION, 'Session');
|
||||
pre($_REQUEST, 'Request');
|
||||
|
||||
//default values of reserved POST keys
|
||||
$sLogin = array_key_exists('login', $_POST)?$_POST['login']:'';
|
||||
$sPass = array_key_exists('pass', $_POST)?$_POST['pass']:'';
|
||||
$sPage = array_key_exists('p', $_REQUEST)?$_REQUEST['p']:'';
|
||||
$sAction = array_key_exists('a', $_POST)?$_POST['a']:'';
|
||||
$sPostToken = array_key_exists('post_token', $_POST)?$_POST['post_token']:'';
|
||||
|
||||
$oMySql = new MySqlManager();
|
||||
$oCerberus = new Cerberus($oMySql, array(Cerberus::OPTION_AUTO_LOGON=>true, Cerberus::OPTION_RENEW_TOKEN=>true));
|
||||
|
||||
//logging In / Out
|
||||
if($sAction=='logout')
|
||||
{
|
||||
$oCerberus->logMeOut();
|
||||
}
|
||||
else/*if(($sLogin=='' && $sPass=='') || $oCerberus->checkPostToken($sPostToken))*/
|
||||
{
|
||||
$oCerberus->logMeIn($sLogin, $sPass);
|
||||
}
|
||||
/*else
|
||||
{
|
||||
echo 'pouet';
|
||||
}*/
|
||||
|
||||
$sLayout = $sMenu = '';
|
||||
if($oCerberus->isLogguedIn())
|
||||
{
|
||||
$sMenu = '<form method="post"><input type="submit" name="a" value="logout">Log out</a><hr /></form>';
|
||||
$sLayout = 'Loggued In. '.$oCerberus->getNewPostToken();
|
||||
}
|
||||
else
|
||||
{
|
||||
$sLayout = '<form name="login" method="post">
|
||||
Login <input type="text" name="login" />
|
||||
pass <input type="text" name="pass" />
|
||||
<input type="hidden" name="post_token" value="'.$oCerberus->getNewPostToken().'" />
|
||||
<input type="submit" value="ok" />
|
||||
</form>';
|
||||
}
|
||||
|
||||
$sErrors = $oCerberus->getCleanMessages();
|
||||
|
||||
echo '<html><head><title>Cerberus</title></head><body>'.$sMenu."\n".$sLayout.'<br />'.$sErrors.'</body></html>';
|
||||
pre('new session post token : '.$_SESSION[Cerberus::SESSION_POST_TOKEN]);
|
||||
|
||||
/* Class */
|
||||
|
||||
/* Requirements */
|
||||
require_once 'functions.php';
|
||||
require_once 'php_object.php';
|
||||
require_once 'mysql_manager.php';
|
||||
|
||||
/**
|
||||
* Cerberus
|
||||
* Access control class
|
||||
* @author FranzZ
|
||||
*
|
||||
* Requirements:
|
||||
* Database with DB_TABLE_USER table and fields:
|
||||
* - DB_FIELD_ID_USER
|
||||
* - DB_FIELD_LOGIN
|
||||
* - DB_FIELD_PASS
|
||||
* - DB_FIELD_TOKEN
|
||||
*
|
||||
* Setup:
|
||||
* - Replace required tables and fields names with the mysql manager constants
|
||||
* - Set options :
|
||||
* - Cerberus::OPTION_AUTO_LOGON
|
||||
* - Cerberus::OPTION_RENEW_TOKEN
|
||||
*/
|
||||
class Cerberus extends PhpObject
|
||||
{
|
||||
// Database
|
||||
private $oMySql;
|
||||
const DB_TABLE_USER = MySqlManager::USER_TABLE;
|
||||
const DB_FIELD_ID_USER = 'id_user';
|
||||
const DB_FIELD_LOGIN = 'user';
|
||||
const DB_FIELD_PASS = 'pass';
|
||||
const DB_FIELD_TOKEN = 'token';
|
||||
|
||||
//Session
|
||||
const SESSION_ID_USER = self::DB_FIELD_ID_USER;
|
||||
const SESSION_LOGIN = self::DB_FIELD_LOGIN;
|
||||
const SESSION_TOKEN = self::DB_FIELD_TOKEN;
|
||||
const SESSION_POST_TOKEN = 'post_token';
|
||||
|
||||
//Cookie
|
||||
const COOKIE_ID_USER = self::DB_FIELD_ID_USER;
|
||||
const COOKIE_TOKEN = self::DB_FIELD_TOKEN;
|
||||
const COOKIE_POST_TOKEN = self::SESSION_POST_TOKEN;
|
||||
|
||||
//Options
|
||||
const OPTION_AUTO_LOGON = 'auto_logon';
|
||||
const OPTION_RENEW_TOKEN = 'renew_token';
|
||||
public $abOptions;
|
||||
|
||||
//Session Variables
|
||||
private $iUserId;
|
||||
private $sLogin;
|
||||
private $sToken;
|
||||
private $sPostToken;
|
||||
|
||||
public function __construct(&$oMySql, $abOptions)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->iUserId = $this->sLogin = $this->sToken = $this->sPostToken = false;
|
||||
$this->oMySql = $oMySql;
|
||||
$this->setOptions($abOptions);
|
||||
$this->syncSession();
|
||||
}
|
||||
|
||||
private function setOptions($abOptions)
|
||||
{
|
||||
//default values
|
||||
$this->abOptions = array(self::OPTION_AUTO_LOGON=>false, self::OPTION_RENEW_TOKEN=>true);
|
||||
$this->abOptions = array_merge($this->abOptions, $abOptions);
|
||||
}
|
||||
|
||||
private function getOption($sOptionName)
|
||||
{
|
||||
return $this->abOptions[$sOptionName];
|
||||
}
|
||||
|
||||
public function getUserId()
|
||||
{
|
||||
return $this->iUserId;
|
||||
}
|
||||
|
||||
private function syncSession()
|
||||
{
|
||||
if(isset($_SESSION[self::SESSION_ID_USER]))
|
||||
{
|
||||
$this->iUserId = $_SESSION[self::SESSION_ID_USER];
|
||||
}
|
||||
if(isset($_SESSION[self::SESSION_LOGIN]))
|
||||
{
|
||||
$this->sLogin = $_SESSION[self::SESSION_LOGIN];
|
||||
}
|
||||
if(isset($_SESSION[self::SESSION_TOKEN]))
|
||||
{
|
||||
$this->sToken = $_SESSION[self::SESSION_TOKEN];
|
||||
}
|
||||
if(isset($_SESSION[self::SESSION_POST_TOKEN]))
|
||||
{
|
||||
$this->sPostToken = $_SESSION[self::SESSION_POST_TOKEN];
|
||||
}
|
||||
}
|
||||
|
||||
public function register($asData)
|
||||
{
|
||||
//data to register
|
||||
//TODO To be customized
|
||||
$sLogin = strtolower(trim($asData[self::DB_FIELD_LOGIN]));
|
||||
$sPass = $asData[self::DB_FIELD_PASS];
|
||||
|
||||
if($sLogin=='' || $sPass=='')
|
||||
{
|
||||
$this->addError('Empty mandatory fields (Nickname or password)');
|
||||
}
|
||||
elseif(htmlspecialchars($sLogin, ENT_QUOTES)!=$sLogin)
|
||||
{
|
||||
$this->addError('Nickname: HTML characters are forbidden');
|
||||
}
|
||||
elseif($this->checkAccount($sLogin))
|
||||
{
|
||||
$this->addError('Nickname: There is already a user called by that name, choose a different one');
|
||||
}
|
||||
else
|
||||
{
|
||||
$asData[self::DB_FIELD_LOGIN] = $sLogin;
|
||||
$asData[self::DB_FIELD_PASS] = self::encryptPassword($sPass);
|
||||
$this->oMySql->insertRow(self::DB_TABLE_USER, $asData);
|
||||
return $this->logMeIn($sLogin, $sPass);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function logMeIn($sLogin='', $sPass='')
|
||||
{
|
||||
$bResult = false;
|
||||
$bFirstLogin = true;
|
||||
if($sLogin=='' || $sPass=='')
|
||||
{
|
||||
$bFirstLogin = false;
|
||||
if($this->iUserId && $this->sLogin && $this->sToken && $this->checkToken())
|
||||
{
|
||||
//log in with session variables
|
||||
$iUserId = $this->iUserId;
|
||||
$sLogin = $this->sLogin;
|
||||
$sToken = $this->sToken;
|
||||
$bResult = true;
|
||||
}
|
||||
elseif($this->getOption(self::OPTION_AUTO_LOGON) && $this->checkToken(true))
|
||||
{
|
||||
//log in with cookies
|
||||
$iUserId = $_COOKIE[self::COOKIE_ID_USER];
|
||||
$sLogin = $this->oMySql->selectValue(self::DB_TABLE_USER, self::DB_FIELD_LOGIN, $iUserId);
|
||||
$sToken = $_COOKIE[self::COOKIE_TOKEN];
|
||||
$bResult = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->addWarning('No login info (cookie / session)');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$asUser = $this->getUser($sLogin);
|
||||
if(!$asUser)
|
||||
{
|
||||
$this->addError('Unknown user');
|
||||
}
|
||||
elseif(!$this->checkPassword($sPass, $asUser[self::DB_FIELD_PASS]))
|
||||
{
|
||||
$this->addError('Incorrect password');
|
||||
}
|
||||
else
|
||||
{
|
||||
$iUserId = $asUser[self::DB_FIELD_ID_USER];
|
||||
$sToken = $asUser[self::DB_FIELD_TOKEN];
|
||||
$bResult = true;
|
||||
}
|
||||
}
|
||||
|
||||
if($bResult)
|
||||
{
|
||||
//Class
|
||||
$this->iUserId = $iUserId;
|
||||
$this->sLogin = $sLogin;
|
||||
$this->sToken = $sToken;
|
||||
|
||||
//Session
|
||||
$_SESSION[self::SESSION_ID_USER] = $iUserId;
|
||||
$_SESSION[self::SESSION_LOGIN] = $sLogin;
|
||||
$_SESSION[self::SESSION_TOKEN] = $sToken;
|
||||
|
||||
//Cookie (doesn't leave any password nor login on user's computer)
|
||||
self::setCookie(self::COOKIE_ID_USER, $iUserId);
|
||||
self::setCookie(self::COOKIE_TOKEN, $sToken);
|
||||
|
||||
//reset pass
|
||||
if($bFirstLogin || $this->getOption(self::OPTION_RENEW_TOKEN))
|
||||
{
|
||||
$this->resetToken();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->logMeOut();
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
public function isLogguedIn()
|
||||
{
|
||||
$bLogguedIn = false;
|
||||
if($this->iUserId && $this->sLogin && $this->sToken)
|
||||
{
|
||||
//check if token is set and valid
|
||||
if($this->checkToken())
|
||||
{
|
||||
//Check if user got a actual account in the database
|
||||
$bLogguedIn = $this->checkAccount($this->sLogin, $this->iUserId);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->addError('Authentication problem, please sign in again');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
echo "[TEST]<br />check token :
|
||||
<br />db token ", $this->iUserId." - ".$this->getDbToken($this->iUserId),"
|
||||
<br />session token ", $_SESSION[self::SESSION_TOKEN], "
|
||||
<br />class token ", $this->sToken, "
|
||||
<br />cookie token ", $_COOKIE[self::COOKIE_TOKEN], '<br />[/TEST]';
|
||||
*/
|
||||
|
||||
return $bLogguedIn;
|
||||
}
|
||||
|
||||
public function logMeOut()
|
||||
{
|
||||
//Database
|
||||
if($this->iUserId)
|
||||
{
|
||||
$this->oMySql->updateRow(self::DB_TABLE_USER, $this->iUserId, array(self::DB_FIELD_TOKEN=>''));
|
||||
}
|
||||
|
||||
//Class variables
|
||||
$this->iUserId = $this->sLogin = $this->sToken = $this->sPostToken = false;
|
||||
|
||||
//Cookie
|
||||
self::setCookie(self::COOKIE_TOKEN, '', -1);
|
||||
self::setCookie(self::COOKIE_ID_USER, '', -1);
|
||||
|
||||
//Server session
|
||||
$_SESSION = array();
|
||||
return session_destroy();
|
||||
}
|
||||
|
||||
private function checkAccount($sUserName, $iUserId=0)
|
||||
{
|
||||
$asConstraints = array(self::DB_FIELD_LOGIN=>$sUserName);
|
||||
if($iUserId>0)
|
||||
{
|
||||
$asConstraints[self::DB_FIELD_ID_USER] = $iUserId;
|
||||
}
|
||||
return $this->oMySql->selectValue(self::DB_TABLE_USER, 'COUNT(1)', $asConstraints);
|
||||
}
|
||||
|
||||
private function getUser($oUser)
|
||||
{
|
||||
$sField = is_numeric($oUser)?self::DB_FIELD_ID_USER:self::DB_FIELD_LOGIN;
|
||||
return $this->oMySql->selectRow(self::DB_TABLE_USER, array($sField=>$oUser));
|
||||
}
|
||||
|
||||
public static function encryptPassword($sPass)
|
||||
{
|
||||
$sRandomText = 'F_RA-1H"2{bvj)5f?0sd3r#fP,K]U|w}hGiN@(sZ.sDe!7*x/:Mq+&';
|
||||
for($iIndex=0; $iIndex < strlen($sPass); $iIndex++)
|
||||
{
|
||||
$sPass[$iIndex] = $sRandomText[$iIndex%strlen($sRandomText)] ^ $sPass[$iIndex];
|
||||
}
|
||||
return md5($sPass);
|
||||
}
|
||||
|
||||
private static function createToken()
|
||||
{
|
||||
return self::encryptPassword( $_SERVER['HTTP_USER_AGENT'].
|
||||
$_SERVER['REMOTE_ADDR'].
|
||||
$_SERVER['REQUEST_TIME'].
|
||||
strstr(microtime(), ' ', true).
|
||||
$_SERVER['SERVER_SIGNATURE'].
|
||||
$_SERVER['SERVER_ADMIN']);
|
||||
}
|
||||
|
||||
private function resetToken()
|
||||
{
|
||||
//new token
|
||||
$sToken = $this->createToken();
|
||||
|
||||
//set database token
|
||||
$this->oMySql->updateRow(self::DB_TABLE_USER, $this->iUserId, array(self::DB_FIELD_TOKEN=>$sToken));
|
||||
|
||||
//set session token
|
||||
$_SESSION[self::SESSION_TOKEN] = $sToken;
|
||||
$this->sToken = $sToken;
|
||||
|
||||
//set cookie token
|
||||
self::setCookie(self::COOKIE_TOKEN, $sToken);
|
||||
}
|
||||
|
||||
public static function setCookie($sCookieName, $oCookieValue, $iTime=1)
|
||||
{
|
||||
setcookie($sCookieName, $oCookieValue, time()+60*60*24*$iTime);
|
||||
$_COOKIE[$sCookieName] = $oCookieValue;
|
||||
}
|
||||
|
||||
private function checkToken($bCookieCheck=false)
|
||||
{
|
||||
$bTokenOk = $iUserId = $sToken = false;
|
||||
|
||||
//Cookie check
|
||||
if($bCookieCheck && array_key_exists(self::COOKIE_ID_USER, $_COOKIE) && array_key_exists(self::COOKIE_TOKEN, $_COOKIE))
|
||||
{
|
||||
$iUserId = $_COOKIE[self::COOKIE_ID_USER];
|
||||
$sToken = $_COOKIE[self::COOKIE_TOKEN];
|
||||
}
|
||||
//Session check
|
||||
elseif(!$bCookieCheck && $this->iUserId && $this->sToken !== false)
|
||||
{
|
||||
$iUserId = $this->iUserId;
|
||||
$sToken = $this->sToken;
|
||||
}
|
||||
|
||||
if($iUserId && $sToken)
|
||||
{
|
||||
$sDbPass = $this->getDbToken($bCookieCheck?$_COOKIE[self::COOKIE_ID_USER]:$this->iUserId);
|
||||
$bTokenOk = ($sDbPass == $_COOKIE[self::COOKIE_TOKEN] && ($sDbPass == $this->sToken || $bCookieCheck));
|
||||
}
|
||||
|
||||
return $bTokenOk;
|
||||
}
|
||||
|
||||
private function getDbToken($iUserId)
|
||||
{
|
||||
$sPass = false;
|
||||
if($iUserId !== false)
|
||||
{
|
||||
$sPass = $this->oMySql->selectValue(self::DB_TABLE_USER, self::DB_FIELD_TOKEN, $iUserId);
|
||||
}
|
||||
return $sPass;
|
||||
}
|
||||
|
||||
public function getNewPostToken()
|
||||
{
|
||||
$sToken = self::createToken();
|
||||
$this->sPostToken = $sToken;
|
||||
$_SESSION[self::SESSION_POST_TOKEN] = $sToken;
|
||||
return $sToken;
|
||||
}
|
||||
|
||||
public function checkPostToken($sPostToken)
|
||||
{
|
||||
pre(array('Posted'=>$sPostToken, 'Class'=>$this->sPostToken, 'Session'=>$_SESSION[self::SESSION_POST_TOKEN]), 'check posted token');
|
||||
$bPostTokenOk = ($this->sPostToken && $sPostToken!='' && $sPostToken == $this->sPostToken);
|
||||
$this->sPostToken = '';
|
||||
$_SESSION[self::SESSION_POST_TOKEN] = '';
|
||||
return $bPostTokenOk;
|
||||
}
|
||||
|
||||
private static function checkPassword($sClearPass, $sEncodedPass)
|
||||
{
|
||||
return self::encryptPassword($sClearPass) == $sEncodedPass;
|
||||
}
|
||||
|
||||
public function getCleanMessages($sType=parent::ALL_TAB)
|
||||
{
|
||||
return $this->getCleanMessageStacks(array($this->oMySql), $sType);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
21
standalone/colors.php
Executable file
21
standalone/colors.php
Executable file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
$iMin = 0;
|
||||
$iMax = 256;
|
||||
$iStep = 20;
|
||||
$iBoxWidth = 10;
|
||||
|
||||
echo '<html><head><title>Colors</title></head><body><table style="border:0;">';
|
||||
for($i=$iMin;$i<$iMax;$i+=$iStep)
|
||||
{
|
||||
for($j=$iMin;$j<$iMax;$j+=$iStep)
|
||||
{
|
||||
echo '<tr>';
|
||||
for($k=$iMin;$k<$iMax;$k+=$iStep)
|
||||
{
|
||||
echo '<td style="width:'.$iBoxWidth.'px;height:'.$iBoxWidth.'px;background:rgb('.$i.','.$j.','.$k.')"></td>';
|
||||
}
|
||||
echo '</tr>';
|
||||
}
|
||||
}
|
||||
echo '</table><body></html>';
|
||||
14
standalone/image.php
Executable file
14
standalone/image.php
Executable file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
header("Content-type: image/png");
|
||||
|
||||
$iHeight = 150;
|
||||
$iWidth = 200;
|
||||
|
||||
$im = @imagecreate($iWidth, $iHeight) or die("Cannot Initialize new GD image stream");
|
||||
$background_color = imagecolorallocate($im, 145, 145, 145);
|
||||
$text_color = imagecolorallocate($im, 255, 255, 255);
|
||||
imagestring($im, 4, 5, $iHeight-20, "Picture 12", $text_color);
|
||||
imagepng($im);
|
||||
imagedestroy($im);
|
||||
?>
|
||||
0
standalone/rssbinsearch/bl_desc
Normal file
0
standalone/rssbinsearch/bl_desc
Normal file
3
standalone/rssbinsearch/bl_title
Normal file
3
standalone/rssbinsearch/bl_title
Normal file
@@ -0,0 +1,3 @@
|
||||
german
|
||||
xxx
|
||||
pr0n
|
||||
119
standalone/rssbinsearch/rssbinsearch.php
Executable file
119
standalone/rssbinsearch/rssbinsearch.php
Executable file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
//Anti Spam List
|
||||
$sMovieList = '';
|
||||
if(file_exist('movie_list')) $sMovieList = file_get_contents('movie_list');
|
||||
if(substr($sMovieList, 0, 8) != date('Ymd')) file_put_contents('movie_list', '');
|
||||
$asMovieList = array_shift(explode("\n", $sMovieList));
|
||||
|
||||
//Black List
|
||||
$sBlTitleContent = file_get_contents('bl_title');
|
||||
$sBlDescContent = file_get_contents('bl_desc');
|
||||
$asBlTitle = explode("\n", $sBlTitleContent);
|
||||
$asBlDesc = explode("\n", $sBlTitleContent);
|
||||
|
||||
$asChannels = array('alt.binaries.hdtv.x264', 'alt.binaries.movies', 'alt.binaries.sleazemovies');
|
||||
foreach($asChannels as $iChanKey=>$sChannel)
|
||||
{
|
||||
//Extract file
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, 'http://rss.binsearch.net/rss.php?max=300&g='.$sChannel);
|
||||
curl_setopt($ch, CURLOPT_HEADER, false);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_ENCODING , "gzip");
|
||||
$sRssIn = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
//Rss Feed Input
|
||||
$sRssIn = str_replace("\n", '', $sRssIn);
|
||||
|
||||
//Rss Feed Output
|
||||
$sRssOut = '';
|
||||
|
||||
//Slice Rss feed into items
|
||||
preg_match_all("/\<item\>(.+)\<\/item\>/U", $sRssIn, $asItems);
|
||||
//print_r($asItems);die();
|
||||
foreach($asItems[1] as $iItemKey=>$sItem)
|
||||
{
|
||||
//Slice item into tags
|
||||
preg_match_all("/\<(?P<tag>\w+)\>(?P<text>.+)\<\/(?P<tag_fin>\w+)\>/U", $sItem, $asTags);
|
||||
//print_r($asTags);die();
|
||||
/*
|
||||
[0] => Array
|
||||
(
|
||||
[0] => <title>dc96773fb88f2f75d581194a4320fedc[76/79] - "15321568f277a26d326baddfb33d62621fe93693187c474f8cac0fb13a0d5b8f.0" yEnc (1/1)</title>
|
||||
[1] => <description><table border width="75%" style="border: solid 1px"><tr><td width="25%">Group:<td>alt.binaries.hdtv.x264<tr><td>Subject:<td>dc96773fb88f2f75d581194a4320fedc[76/79] - "15321568f277a26d326baddfb33d62621fe93693187c474f8cac0fb13a0d5b8f.0" yEnc (1/1)<tr><td>Poster:<td>Yenc@power-post.org (Yenc-PP-A&amp;A)<tr><td>Details:<td><span class="d"><br><a href="http://www.binsearch.info/?b=15321568f277a26d326baddfb33d62621fe93693187c474f8cac0fb13a0d5b8f&amp;g=alt.binaries.hdtv.x264&amp;p=Yenc%40power-post.org+%28Yenc-PP-A%26A%29&amp;max=250">collection</a> size: 2.35&nbsp;MB, parts available: 7 / 7<br>- 2 par2 files<br>- 1 split file<br>- 1 other file<br></span></table></description>
|
||||
[2] => <pubDate>Thu, 03 Jan 2013 15:31:53 GMT</pubDate>
|
||||
[3] => <link>http://www.binsearch.info/?action=nzb&97515747=1</link>
|
||||
)
|
||||
|
||||
[tag] => Array
|
||||
(
|
||||
[0] => title
|
||||
[1] => description
|
||||
[2] => pubDate
|
||||
[3] => link
|
||||
)
|
||||
|
||||
[text] => Array
|
||||
(
|
||||
[0] => dc96773fb88f2f75d581194a4320fedc[76/79] - "15321568f277a26d326baddfb33d62621fe93693187c474f8cac0fb13a0d5b8f.0" yEnc (1/1)
|
||||
[1] => <table border width="75%" style="border: solid 1px"><tr><td width="25%">Group:<td>alt.binaries.hdtv.x264<tr><td>Subject:<td>dc96773fb88f2f75d581194a4320fedc[76/79] - "15321568f277a26d326baddfb33d62621fe93693187c474f8cac0fb13a0d5b8f.0" yEnc (1/1)<tr><td>Poster:<td>Yenc@power-post.org (Yenc-PP-A&amp;A)<tr><td>Details:<td><span class="d"><br><a href="http://www.binsearch.info/?b=15321568f277a26d326baddfb33d62621fe93693187c474f8cac0fb13a0d5b8f&amp;g=alt.binaries.hdtv.x264&amp;p=Yenc%40power-post.org+%28Yenc-PP-A%26A%29&amp;max=250">collection</a> size: 2.35&nbsp;MB, parts available: 7 / 7<br>- 2 par2 files<br>- 1 split file<br>- 1 other file<br></span></table>
|
||||
[2] => Thu, 03 Jan 2013 15:31:53 GMT
|
||||
[3] => http://www.binsearch.info/?action=nzb&97515747=1
|
||||
*/
|
||||
|
||||
//Extract item's tag names
|
||||
foreach($asTags['tag'] as $iTagKey=>$sTageName)
|
||||
{
|
||||
$asTagIndex[$sTageName] = $iTagKey;
|
||||
}
|
||||
$sTitle = $asTags['text'][$asTagIndex['title']];
|
||||
$sDesc = $asTags['text'][$asTagIndex['description']];
|
||||
|
||||
//Validator
|
||||
$bValid = true;
|
||||
|
||||
//Check Poster
|
||||
//preg_match('/Poster\:\<\;td\>\;(?P<address>\S*)\ \((?P<user>\S*)\)/i', $sTitle, $as);
|
||||
foreach($asBlTitle as $sBlWord)
|
||||
{
|
||||
preg_match('/'.preg_quote($sBlWord).'/i', $sTitle, $asFoundBlWord);
|
||||
if(count($asFoundBlWord) != 0) $bValid = false;
|
||||
}
|
||||
|
||||
foreach($asBlDesc as $sBlWord)
|
||||
{
|
||||
preg_match('/'.preg_quote($sBlWord).'/i', $sDesc, $asFoundBlWord);
|
||||
if(count($asFoundBlWord) != 0) $bValid = false;
|
||||
}
|
||||
|
||||
//Check movie quality
|
||||
preg_match('/1080p/i', $sTitle, $asQuality);
|
||||
if(count($asQuality) == 0) $bValid = false;
|
||||
|
||||
//Jul - Remove German movies
|
||||
//preg_match('/german/i', $sTitle, $asLang);
|
||||
//if(count($asLang) != 0) $bValid = false;
|
||||
|
||||
//Check Series
|
||||
preg_match('/s([0-9]{1,2})e([0-9]{2})/i', $sTitle, $asSeries);
|
||||
if(count($asSeries) != 0) $bValid = false;
|
||||
|
||||
if($bValid) $asValidItems[] = $asItems[0][$iItemKey];
|
||||
}
|
||||
}
|
||||
|
||||
//rebuild RSS feed
|
||||
date_default_timezone_set('Europe/Paris');
|
||||
echo '<?xml version="1.0" encoding="utf-8"?><rss version="2.0">'.
|
||||
'<channel>'.
|
||||
'<title>'.implode(', ', $asChannels).'</title>'.
|
||||
'<link>http://www.binsearch.info/</link>'.
|
||||
'<description>Latest newsgroup posts as indexed by BinSearch.info</description>'.
|
||||
'<copyright>This RSS collection is copyright (c) BinSearch team. Commercial use prohibited. This collection is generated by an automated process based on the posts found in global Usenet newsgroups. The posters retain copyright over their individual posts.</copyright>'.
|
||||
'<lastBuildDate>'.date('r').'</lastBuildDate>'.
|
||||
implode("\n\t\t", $asValidItems).
|
||||
'</channel>'.
|
||||
'</rss>';
|
||||
?>
|
||||
110
standalone/send_mail.php
Executable file
110
standalone/send_mail.php
Executable file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
ini_set('default_charset', 'UTF-8');
|
||||
header('Content-Type: text/html; charset='.'UTF-8');
|
||||
mb_internal_encoding('UTF-8');
|
||||
mb_http_output('UTF-8');
|
||||
mb_http_input('UTF-8');
|
||||
mb_language('uni');
|
||||
mb_regex_encoding('UTF-8');
|
||||
|
||||
//Main
|
||||
$sApiKey = isset($_POST['api_key'])?$_POST['api_key']:'';
|
||||
$sApp = isset($_POST['app'])?$_POST['app']:'lutran.fr';
|
||||
$sFromName = isset($_POST['from_name'])?$_POST['from_name']:'';
|
||||
$sFromEmail = isset($_POST['from_email'])?$_POST['from_email']:'www-data@lutran.fr';
|
||||
$sSubject = isset($_POST['subject'])?$_POST['subject']:'';
|
||||
$sMsg = isset($_POST['msg'])?$_POST['msg']:'';
|
||||
$sToEmail = isset($_POST['to_email'])?$_POST['to_email']:'';
|
||||
$asCc = isset($_POST['cc_email'])?json_decode($_POST['cc_email'], true):'';
|
||||
$bSelfMail = isset($_POST['self'])?$_POST['self']:true;
|
||||
|
||||
$asAuthorizedApi = array('Wedding'=>'8D98B36BB558BC6771324AEFB9E37');
|
||||
if(array_key_exists($sApp, $asAuthorizedApi) && $sApiKey = $asAuthorizedApi[$sApp])
|
||||
{
|
||||
$sResult = sendEmail($sApp, $sFromName, $sFromEmail, $sSubject, $sMsg, $sToEmail, $asCc, $bSelfMail);
|
||||
}
|
||||
else $sResult = 1;
|
||||
|
||||
echo $sResult;
|
||||
|
||||
//Functions
|
||||
function sendEmail($sApp, $sFromName, $sFromEmail, $sSubject, $sMsg, $sToEmail, $asCc, $bSelfMail)
|
||||
{
|
||||
$sResult = 0;
|
||||
if($sFromName!='' && $sFromEmail!='' && $sSubject!='' && $sMsg!='' && $sToEmail!='')
|
||||
{
|
||||
//Message
|
||||
$sHtmlMessage = '';
|
||||
if($bSelfMail)
|
||||
{
|
||||
$sHtmlMessage = 'From: '.$sFromName."<br />".
|
||||
'Email: '.$sFromEmail."<br /><br />".
|
||||
'Subject: '.$sSubject."<br />".
|
||||
'Message: <br /><br />';
|
||||
$sFromName = $sApp;
|
||||
$sSubject = $sApp.' - Contact';
|
||||
}
|
||||
$sHtmlMessage .= str_replace("\n", '<br />', $sMsg);
|
||||
$sPlainMessage = strip_tags(str_replace('<br />', "\n", $sHtmlMessage));
|
||||
|
||||
//Email
|
||||
$iBoundary = uniqid("HTMLEMAIL");
|
||||
$sCc = empty($asCc)?'':('Cc: '.implodeAll($asCc, ' <', "\r\n, ", '', '>')."\r\n");
|
||||
$sHeaders = 'From: '.$sFromName.' <www-data@lutran.fr>'."\r\n".
|
||||
'Reply-To: '.$sFromName.' <www-data@lutran.fr>'."\r\n".
|
||||
$sCc.
|
||||
'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($sToEmail, $sSubject, '', $sHeaders))
|
||||
{
|
||||
$sResult = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sResult = 4;
|
||||
}
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
function implodeAll($asText, $asKeyValueSeparator='', $sRowSeparator='', $sKeyPre='', $sValuePost=false)
|
||||
{
|
||||
if($sValuePost===false)
|
||||
{
|
||||
$sValuePost = $sKeyPre;
|
||||
}
|
||||
$asCombinedText = array();
|
||||
|
||||
//if unique value for key value separator
|
||||
if(!is_array($asKeyValueSeparator) && !empty($asText))
|
||||
{
|
||||
$asKeyValueSeparator = array_combine(array_keys($asText), array_fill(0, count($asText), $asKeyValueSeparator));
|
||||
}
|
||||
|
||||
foreach($asText as $sKey=>$sValue)
|
||||
{
|
||||
$asCombinedText[] = $sKeyPre.$sKey.$asKeyValueSeparator[$sKey].(is_array($sValue)?implode($sValue):$sValue).$sValuePost;
|
||||
}
|
||||
return implode($sRowSeparator, $asCombinedText);
|
||||
}
|
||||
?>
|
||||
78
standalone/test.php
Executable file
78
standalone/test.php
Executable file
File diff suppressed because one or more lines are too long
83
standalone/upload.php
Normal file
83
standalone/upload.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
function combinedImplode($asPieces, $sKeyValGlue='', $sRowGlue='')
|
||||
{
|
||||
$asResult = array();
|
||||
foreach($asPieces as $sKey=>$sValue)
|
||||
{
|
||||
$asResult[] = is_array($sValue)?combinedImplode($sValue, $sKeyValGlue, $sRowGlue):$sKey.$sKeyValGlue.$sValue;
|
||||
}
|
||||
return implode($sRowGlue, $asResult);
|
||||
}
|
||||
|
||||
function getSabContent($sSabServer, $asParams)
|
||||
{
|
||||
$sQueueUrl = $sSabServer.'?'.combinedImplode($asParams, '=', '&');
|
||||
return json_decode(file_get_contents($sQueueUrl), true);
|
||||
}
|
||||
|
||||
$sUploadResult = $sQueueResult = $sHistoryResult = '';
|
||||
if(isset($_GET['api']) && $_GET['api']=='123456')
|
||||
{
|
||||
|
||||
$sSabServer = 'http://192.168.0.2:8085/sabnzbd/api';
|
||||
$asCommonParams = array('output'=>'json', 'apikey'=>'d93d02d23510871b0252fe282a0f591c');
|
||||
$asQueueParams = $asCommonParams + array('mode'=>'queue', 'start'=>0, 'limit'=>1);
|
||||
$asHistoryParams = $asCommonParams + array('mode'=>'history', 'start'=>0, 'limit'=>3);
|
||||
|
||||
//Displaying current download
|
||||
$asQueueResult = getSabContent($sSabServer, $asQueueParams);
|
||||
if(count($asQueueResult['queue']['slots'])==0) $sQueueResult = 'Empty queue';
|
||||
else
|
||||
{
|
||||
$asFile = $asQueueResult['queue']['slots'][0];
|
||||
$sQueueResult = 'Downloading '.$asFile['filename'].' ('.$asFile['size'].') ';
|
||||
$sQueueResult.= 'at '.$asQueueResult['queue']['speed'].'. File expected at ';
|
||||
$sQueueResult.= $asFile['eta'].' ('.$asFile['sizeleft'].' / '.$asFile['timeleft'].' left)';
|
||||
}
|
||||
|
||||
//Displaying history
|
||||
$asHistoryResult = getSabContent($sSabServer, $asHistoryParams);
|
||||
if(count($asHistoryResult['history']['slots'])==0) $asHistoryResult = 'Empty history';
|
||||
else
|
||||
{
|
||||
foreach($asHistoryResult['history']['slots'] as $asFile)
|
||||
{
|
||||
$sHistoryResult .= '<li>'.$asFile['name'].' ('.$asFile['size'].') ';
|
||||
if($asFile['status']=='Failed') $sHistoryResult.= 'failed to be downloaded ("'.$asFile['fail_message'].'")';
|
||||
else $sHistoryResult.= 'has been downloaded with success';
|
||||
$sHistoryResult .= '</li>';
|
||||
}
|
||||
}
|
||||
|
||||
//Uploading file
|
||||
$sUploadResult = '';
|
||||
if(array_key_exists('upload', $_FILES) && strtolower(substr($_FILES['upload']['name'], -4))=='.nzb')
|
||||
{
|
||||
$sWatchDir = "/tmp/downloads/watchdir/";
|
||||
$sPath = $sWatchDir.basename($_FILES['upload']['name']);
|
||||
$ok=1;
|
||||
if(move_uploaded_file($_FILES['upload']['tmp_name'], $sPath))
|
||||
{
|
||||
$sUploadResult = "The file ". basename( $_FILES['upload']['name']). " has been uploaded";
|
||||
}
|
||||
else $sUploadResult = "Sorry, there was a problem copying your file.";
|
||||
}
|
||||
}
|
||||
else $sUploadResult = 'Missing API key';
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Add to NZB</title>
|
||||
</head>
|
||||
<body>
|
||||
<form enctype="multipart/form-data" action="upload.php" method="POST">
|
||||
Add to NZB: <input name="upload" type="file" /> <input type="submit" value="Upload" />
|
||||
</form>
|
||||
<p class="result"><?php echo $sUploadResult; ?></p>
|
||||
<p class="queue"><?php echo $sQueueResult; ?></p>
|
||||
<p class="history"><ul><?php echo $sHistoryResult; ?></ul></p>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user