4574 lines
154 KiB
PHP
Executable File
4574 lines
154 KiB
PHP
Executable File
<?php
|
|
|
|
/**
|
|
* Ideas
|
|
* code page : hover -> wait 1sec -> if(focus) -> expand {-5 lines, + 5 lines}
|
|
* Translations in EN / ES
|
|
*/
|
|
|
|
/**
|
|
* Manage includes
|
|
* @author franzz
|
|
*/
|
|
class ClassManagement extends PhpObject
|
|
{
|
|
const INC_FOLDER = 'inc/';
|
|
const INC_EXT = '.php';
|
|
const SETTINGS_FILE = 'settings.php';
|
|
|
|
private $asIncFiles;
|
|
|
|
function __construct()
|
|
{
|
|
parent::__construct();
|
|
$this->asIncFiles = array();
|
|
$this->incFile(self::SETTINGS_FILE);
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Common class for all classes.
|
|
* Handles the error log process
|
|
* @author franzz
|
|
*/
|
|
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 $bDebug;
|
|
|
|
function __construct($iExtractMode=self::MODE_FILE)
|
|
{
|
|
$this->resetMessageStack();
|
|
$this->iExtractMode = $iExtractMode;
|
|
$this->setDebug(false);
|
|
}
|
|
|
|
protected function setDebug($bSwitch)
|
|
{
|
|
$this->bDebug = $bSwitch;
|
|
}
|
|
|
|
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->addTrace(self::NOTICE_TAB, $sNotice);
|
|
}
|
|
|
|
protected function addWarning($sWarning)
|
|
{
|
|
$this->addTrace(self::WARNING_TAB, $sWarning);
|
|
}
|
|
|
|
protected function addError($sError)
|
|
{
|
|
$this->addTrace(self::ERROR_TAB, $sError);
|
|
}
|
|
|
|
private function addTrace($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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Application Core
|
|
* @author franzz
|
|
*/
|
|
class Databap extends PhpObject
|
|
{
|
|
//Common Constants
|
|
const EXPECTED_PAGE_COOKIE = 'exp_page';
|
|
const MAIN_SEPARATOR = ' ';
|
|
const DATE_FORMAT = 'd/m/Y';
|
|
const TIME_FORMAT = 'H:i:s';
|
|
const DATE_TIME_FORMAT = 'd/m/Y H:i:s';
|
|
const DATE_COMPACT_FORMAT = 'YmdHis';
|
|
const DATE_TIME_SQL_FORMAT = 'Y-m-d H:i:s';
|
|
const DATE_SQL_FORMAT = 'Y-m-d';
|
|
const HISTORY_LENGTH = 10;
|
|
const STYLE_PATH = 'style.css';
|
|
public static $UPLOAD_IMG_EXTS = array('jpg', 'jpeg', 'gif', 'png');
|
|
public static $UPLOAD_DOC_EXTS = array('jpg', 'jpeg', 'gif', 'png', 'doc', 'ppt', 'pdf', 'xls', 'docx', 'pptx', 'xlsx');
|
|
const ID_SEPARATOR = '_';
|
|
|
|
//Code
|
|
const MAX_LIST_LENGTH = 5;
|
|
|
|
//Authorizations
|
|
const CLEARANCE_MEMBER = 0;
|
|
const CLEARANCE_ADMIN = 9;
|
|
const EXT_ACCESS = 'external_access';
|
|
const USER_COOKIE_ID = 'id_user';
|
|
const USER_COOKIE_PASS = 'checksum';
|
|
const COOKIE_LIFETIME = 7;
|
|
const TOKEN_LENGTH = 32;
|
|
|
|
//HTTP Requests response
|
|
const DISCONNECTED = '__DISCONNECTED__';
|
|
const ERROR = '__ERROR__';
|
|
const SUCCESS = '__SUCCESS__';
|
|
|
|
//Chat Constants
|
|
//TODO Transfer these constants to chat page
|
|
const MESSAGE_USER = 'U';
|
|
const MESSAGE_ADD_CODE = 'A';
|
|
const MESSAGE_EDIT_CODE = 'E';
|
|
const MESSAGE_ADD_PROC = 'PA';
|
|
const MESSAGE_EDIT_PROC = 'PE';
|
|
const MESSAGE_ADD_DOC = 'DA';
|
|
const MESSAGE_EDIT_DOC = 'DE';
|
|
const MESSAGE_ACTION = 'M';
|
|
const MESSAGE_PRIVATE = 'P';
|
|
const MESSAGE_IMG = 'I';
|
|
const MESSAGE_9GAG = '9';
|
|
const MESSAGE_NICK = 'N';
|
|
const MESSAGE_STATUS = 'S';
|
|
const MESSAGE_CONN = 'C';
|
|
const MESSAGE_INVITE = 'V';
|
|
const MESSAGE_REBOOT = 'R';
|
|
const MESSAGE_ARTICLE = 'B';
|
|
const DEFAULT_COMPANY_LOGO = 'tux_24.png';
|
|
const DEFAULT_CHAN = 'Principal';
|
|
const ALL_CHAN_ID = 1;
|
|
const ALL_CHAN_TEXT = 'A.l.l_C.h.a.n_I.n.c.l.u.d.e.d';
|
|
const KEEP_ALIVE = 600; //seconds
|
|
const REBOOT_DELAY = 15; //seconds
|
|
const PM_SEP = '___';
|
|
const CHAT_IMG_MAX_WIDTH = 700;
|
|
const CHAT_IMG_MAX_HEIGHT = 2000;
|
|
const JSON_PREFIX = '[\-JSON-/]';
|
|
|
|
//Options Constants
|
|
const LANG_FR = 'FR';
|
|
const OPT_TEXT = 'T';
|
|
const OPT_SELECT = 'S';
|
|
const OPT_NICKNAME = 1;
|
|
const OPT_BG = 2;
|
|
const OPT_BRIGHT_BG = 3;
|
|
const OPT_HOVER = 4;
|
|
const OPT_TOKEN = 5;
|
|
const OPT_IMAGE_CHAT = 6;
|
|
const OPT_STATUS = 7;
|
|
|
|
//Search Constants
|
|
const PROC_TYPE = 'p';
|
|
const CODE_TYPE = 'c';
|
|
const DOC_TYPE = 'd';
|
|
const ART_TYPE = 'a';
|
|
|
|
//Doc constants
|
|
const DOC_FOLDER = 'docs/';
|
|
const DOC_TMP_FOLDER = 'docs/tmp/';
|
|
|
|
//Objects
|
|
private $oMySql;
|
|
private $oProcedure;
|
|
private $oSearchEngine;
|
|
private $oClassManagement;
|
|
|
|
//Variables
|
|
private $iUserId;
|
|
private $asUserInfo;
|
|
private $sLanguage;
|
|
|
|
function __construct($oClassManagement)
|
|
{
|
|
parent::__construct();
|
|
$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);
|
|
|
|
//Passing settings down to mySQL
|
|
$this->oMySql = new MySqlManager(Settings::DB_SERVER, Settings::DB_LOGIN, Settings::DB_PASS, Settings::DB_NAME, Settings::SQL_ENC);
|
|
if($this->oMySql->sDbState == MySqlManager::DB_NO_DATA) $this->install();
|
|
|
|
//Init other variables
|
|
$this->oProcedure = new Procedure($this->oMySql);
|
|
$this->setUserId(0);
|
|
$this->sLanguage = self::LANG_FR;
|
|
$this->oSearchEngine = new SearchEngine($this->oMySql);
|
|
}
|
|
|
|
private function install()
|
|
{
|
|
//Install DB
|
|
$this->oMySql->install();
|
|
|
|
//Options
|
|
$sOptionNameCol = MySqlManager::getText(MySqlManager::OPTNAME_TABLE);
|
|
$sOptionNameIdCol = MySqlManager::getId(MySqlManager::OPTNAME_TABLE);
|
|
$iNicknameOptId = $this->oMySql->insertRow(MySqlManager::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_NICKNAME, $sOptionNameCol=>'pseudo du chat', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
|
|
$iBgColorOptId = $this->oMySql->insertRow(MySqlManager::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_BG, $sOptionNameCol=>'couleur de fond', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
|
|
$iBgColorOpt2Id = $this->oMySql->insertRow(MySqlManager::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_BRIGHT_BG, $sOptionNameCol=>'couleur de fond 2 (claire)', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
|
|
$iHoverColorOptId = $this->oMySql->insertRow(MySqlManager::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_HOVER, $sOptionNameCol=>'couleur de survol', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
|
|
$iHoverColorOptId = $this->oMySql->insertRow(MySqlManager::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_TOKEN, $sOptionNameCol=>'token', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
|
|
$iChatImageOptId = $this->oMySql->insertRow(MySqlManager::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_IMAGE_CHAT, $sOptionNameCol=>'image du chat', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
|
|
$iChatImageOptId = $this->oMySql->insertRow(MySqlManager::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_STATUS, $sOptionNameCol=>'Mission en cours', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
|
|
|
|
//Insert default and all channels
|
|
$this->oMySql->insertRow(MySqlManager::CHAN_TABLE, array('safe_name'=>self::getChanSafeName(self::ALL_CHAN_TEXT), MySqlManager::getText(MySqlManager::CHAN_TABLE)=>self::ALL_CHAN_TEXT));
|
|
$this->oMySql->insertRow(MySqlManager::CHAN_TABLE, array('safe_name'=>self::getChanSafeName(self::DEFAULT_CHAN), MySqlManager::getText(MySqlManager::CHAN_TABLE)=>self::DEFAULT_CHAN));
|
|
|
|
//Install default users : admin and test
|
|
$iAdminId = $this->addUser('francois', 'lutran', 'cgi', 'francois@lutran.fr', self::CLEARANCE_ADMIN);
|
|
$this->addUser('test', 'test', 'test', 'test@test.com');
|
|
|
|
//Write the SAP blog parser bash script to main folder
|
|
@file_put_contents('sap_website_parser.sh', "#!/bin/bash\n\n/usr/bin/php -f index.php a=external_access p=sap_blog auth_token=".$iAdminId.'_'.$this->generateToken($iAdminId));
|
|
}
|
|
|
|
private function setUserId($iUserId)
|
|
{
|
|
$this->iUserId = $iUserId;
|
|
$this->asUserInfo = ($iUserId>0)?$this->getUserInfo($iUserId):array();
|
|
}
|
|
|
|
public function getUserId()
|
|
{
|
|
return $this->iUserId;
|
|
}
|
|
|
|
public function getPage($sPage, $asVars)
|
|
{
|
|
$oPage = new Mask('index');
|
|
$oPage->setTag('text_enc', Settings::TEXT_ENC);
|
|
$oPage->setTag('first_page', $sPage);
|
|
$oPage->setTag('index_link', $asVars['serv_name']);
|
|
$oPage->setTag('line_break', "Global databap constants\n");
|
|
|
|
//Rss Link
|
|
$oPage->setTag('rss_link', $this->getUserOptionValue(self::OPT_TOKEN));
|
|
|
|
//Pass GET variables down to jQuery
|
|
$asVars['user_id'] = $this->getUserId();
|
|
$sLastKey = end(array_keys($asVars));
|
|
foreach($asVars as $sName => $sValue)
|
|
{
|
|
$oPage->addInstance('VARS', array('var_name'=>$sName, 'var_value'=>$sValue, 'coma'=>$sName==$sLastKey?'':', '));
|
|
}
|
|
|
|
//Pages
|
|
$asMaskPaths = glob(Mask::MASK_FOLDER.'*.html');
|
|
$asMaskNames = array_map('basename', $asMaskPaths, array_fill(1, count($asMaskPaths), '.html'));
|
|
$sLastKey = end(array_keys($asMaskNames));
|
|
foreach($asMaskNames as $sKey=>$sMaskName)
|
|
{
|
|
$oPage->addInstance('PAGES', array('page_name'=>$sMaskName, 'page_value'=>$sMaskName, 'coma'=>$sKey==$sLastKey?'':', '));
|
|
}
|
|
|
|
//Constants
|
|
$asConstants = array( 'disconnected'=>self::DISCONNECTED,
|
|
'error'=>self::ERROR,
|
|
'keep_alive'=>self::KEEP_ALIVE,
|
|
'opt_type_text'=>self::OPT_TEXT,
|
|
'opt_type_select'=>self::OPT_SELECT,
|
|
'max_size'=>self::getMaxSize(),
|
|
'authorized_img_exts'=>self::$UPLOAD_IMG_EXTS,
|
|
'authorized_file_exts'=>self::$UPLOAD_DOC_EXTS,
|
|
'id_sep'=>self::ID_SEPARATOR,
|
|
'mask_folder'=>Mask::MASK_FOLDER,
|
|
'image_folder'=>Procedure::IMAGE_FOLDER,
|
|
'image_folder_tmp'=>Procedure::IMAGE_FOLDER_TMP,
|
|
'image_folder_thumb'=>Procedure::IMAGE_FOLDER_THUMB,
|
|
'default_chan'=>self::DEFAULT_CHAN,
|
|
'all_chan_id'=>self::ALL_CHAN_ID,
|
|
'all_chan_text'=>self::ALL_CHAN_TEXT,
|
|
'pm_separator'=>self::PM_SEP,
|
|
'reboot_delay'=>self::REBOOT_DELAY);
|
|
$oPage->setTag('constants', $this->jsonConvert($asConstants));
|
|
|
|
return $oPage->getMask();
|
|
}
|
|
|
|
public function getRss($sCat='')
|
|
{
|
|
//Class Feed
|
|
$this->oClassManagement->incClass('rss');
|
|
|
|
//Building header
|
|
$asDesc = array
|
|
(
|
|
'title'=>'Flux RSS Databap'.($sCat==''?'':' - '.$sCat),
|
|
'link'=>$_GET['serv_name'].'rss'.($sCat==''?'':'-'.$sCat),
|
|
'copyright'=>'Powered by Francois Lutran. RSS Feed Generator under GPLv3 License',
|
|
'description'=>'Flux RSS du chat'.($sCat==''?'':', section '.$sCat),
|
|
'language'=>'fr',
|
|
'webmaster_mail'=>'francois@lutran.fr'
|
|
);
|
|
$oFeed = new Feed($asDesc);
|
|
|
|
//Building items
|
|
switch(mb_strtolower($sCat))
|
|
{
|
|
case '9gag':
|
|
$sRegEx = '^(https?://|www\\.)(.*)9gag\\.com';
|
|
break;
|
|
case 'youtube':
|
|
$sRegEx = '^(https?://|www\\.)(.*)youtube\\.com';
|
|
break;
|
|
case '':
|
|
$sRegEx = '^(https?://|www\\.)[\.A-Za-z0-9\-]+\\.[a-zA-Z]{2,4}';
|
|
break;
|
|
default:
|
|
$sRegEx = '^(https?://|www\\.)(.*)'.$sCat.'(.*)\\.[a-zA-Z]{2,4}';
|
|
break;
|
|
}
|
|
$asResult = $this->oMySql->selectRows(array('select'=>array('id_message', 'nickname', 'message', 'led'), 'from'=>'messages', 'constraint'=>array('message'=>$sRegEx), 'constOpe'=>array('message'=>' REGEXP ')));
|
|
$sPattern = '/(https?\:\/\/|www\.)[\S]+\.[a-zA-Z]{2,4}([\S]*)/i';
|
|
|
|
foreach($asResult as $iLinkId=>$asRow)
|
|
{
|
|
//get link out of message
|
|
preg_match($sPattern, $asRow['message'], $asMatches);
|
|
$asRow['link'] = $asMatches[0];
|
|
|
|
//add item
|
|
$asItem = array
|
|
(
|
|
'title'=>'Lien'.($sCat==''?'':' - '.$sCat).' #'.($iLinkId+1),
|
|
'category'=>$sCat,
|
|
'description'=>'Lien posté par '.self::getNickNameFormat($asRow['nickname']).' à '.self::getDateFormat($asRow['led']).' : <a href="'.$asRow['link'].'" target="_blank">'.$asRow['message'].'</a>',
|
|
'author'=>$asRow['nickname'],
|
|
'link'=>$_GET['serv_name'].'chat-'.$asRow['id_message'],
|
|
'pub_date'=>$asRow['led'],
|
|
'guid'=>$_GET['serv_name'].'chat-'.$asRow['id_message']
|
|
);
|
|
$oFeed->addItem($asItem);
|
|
}
|
|
|
|
return $oFeed->getFeed();
|
|
}
|
|
|
|
public function syncSapBlog()
|
|
{
|
|
//Get articles list
|
|
$asArticles = $this->getSAPBlogRss();
|
|
|
|
//Update and spread the news
|
|
$asResult = array();
|
|
if(date('N')>5) $asResult[] = "Pas de mise-à-jour pendant le week end !";
|
|
else
|
|
{
|
|
foreach($asArticles as $asArticle)
|
|
{
|
|
$iArticleId = $this->oMySql->selectValue(MySqlManager::ART_TABLE, MySqlManager::getId(MySqlManager::ART_TABLE), array('title'=>$asArticle['title']));
|
|
|
|
if($iArticleId==0)
|
|
{
|
|
$iArticleId = $this->oMySql->insertRow(MySqlManager::ART_TABLE, $asArticle);
|
|
$this->addMessage($iArticleId, self::MESSAGE_ARTICLE, self::ALL_CHAN_ID);
|
|
$this->oSearchEngine->buildIndex($iArticleId, self::ART_TYPE);
|
|
$sResult = 'ADDED';
|
|
}
|
|
else $sResult = 'OK';
|
|
$asResult[$iArticleId] = $sResult.' | '.implode(' | ', $asArticle);
|
|
}
|
|
}
|
|
return MySqlManager::implodeAll($asResult, '->', "\n");
|
|
}
|
|
|
|
private function getSAPBlogRss()
|
|
{
|
|
$sSAPDomain = 'http://scn.sap.com';
|
|
$sSAPBlogUrl = $sSAPDomain.'/community/data-warehousing/netweaver-bw/blog';
|
|
|
|
//TODO add http://www.biportal.org/sap_bi_blog
|
|
|
|
$oDom = $this->getRemotePageDom($sSAPBlogUrl);
|
|
$aoArticles = $oDom->getElementsByTagName('header');
|
|
|
|
$asArticles = array();
|
|
foreach($aoArticles as $oArticle)
|
|
{
|
|
if($oArticle->getAttribute('class')=='jive-blog-post-subject')
|
|
{
|
|
$asArticleInfo = array();
|
|
$aoLinks = $oArticle->getElementsByTagName('a');
|
|
foreach($aoLinks as $oLink)
|
|
{
|
|
switch($oLink->getAttribute('class'))
|
|
{
|
|
//Title & link
|
|
case 'font-color-normal':
|
|
$asArticleInfo['title'] = ucfirst(trim($oLink->nodeValue));
|
|
$asArticleInfo['title'] = mb_substr($asArticleInfo['title'], -1)=='.'?mb_substr($asArticleInfo['title'], 0, -1):$asArticleInfo['title'];
|
|
$asArticleInfo['link'] = $oLink->getAttribute('href');
|
|
$asArticleInfo['date'] = mb_substr(str_replace(array($sSAPBlogUrl.'/', '/'), array('', '-'), $asArticleInfo['link']), 0, 10);
|
|
break;
|
|
//Author
|
|
case 'jiveTT-hover-user jive-username-link':
|
|
$asNames = array_filter(explode(' ', ToolBox::mb_ucwords(trim($oLink->nodeValue))));
|
|
$asArticleInfo['first_name'] = array_shift($asNames);
|
|
$asArticleInfo['last_name'] = implode('-', $asNames);
|
|
$asArticleInfo['email'] = $sSAPDomain.$oLink->getAttribute('href');
|
|
break;
|
|
}
|
|
}
|
|
$asArticles[] = $asArticleInfo;
|
|
}
|
|
}
|
|
|
|
return $asArticles;
|
|
}
|
|
|
|
private function get9gagPost($sUrl)
|
|
{
|
|
$asPost = array('url'=>$sUrl);
|
|
$oDom = $this->getRemotePageDom($sUrl);
|
|
|
|
$oDivs = $oDom->getElementsByTagName('section');
|
|
foreach($oDivs as $oPost) {if($oPost->getAttribute('id')=='individual-post') break;}
|
|
|
|
//Title
|
|
$asPost['title'] = $oPost->getElementsByTagName('h2')->item(0)->nodeValue;
|
|
|
|
//Image
|
|
$oImages = $oPost->getElementsByTagName('img');
|
|
foreach($oImages as $oImage)
|
|
{
|
|
switch($oImage->getAttribute('class'))
|
|
{
|
|
case 'badge-item-animated-img':
|
|
$o9gagImage = $oImage;
|
|
break 2;
|
|
case 'badge-item-img':
|
|
$o9gagImage = $oImage;
|
|
break;
|
|
}
|
|
}
|
|
$asResult = $this->downloadToTmp($o9gagImage->getAttribute('src'));
|
|
|
|
if($asResult['error']=='')
|
|
{
|
|
$asPost['url_img'] = $asResult['out'];
|
|
$asPost['width'] = $asResult['width'];
|
|
$asPost['height'] = $asResult['height'];
|
|
}
|
|
|
|
return $asPost;
|
|
}
|
|
|
|
private function getRemotePageDom($sUrl)
|
|
{
|
|
$oDom = new DOMDocument();
|
|
@$oDom->loadHTML(file_get_contents($sUrl));
|
|
return $oDom->getElementsByTagName('body')->item(0);
|
|
}
|
|
|
|
public function addUser($sFirstName, $sLastName, $sCompany, $sEmail='', $iClearance=self::CLEARANCE_MEMBER)
|
|
{
|
|
$sFirstName = mb_strtolower($sFirstName);
|
|
$sLastName = mb_strtolower($sLastName);
|
|
$sCompany = mb_strtolower($sCompany);
|
|
$sEmail = mb_strtolower($sEmail);
|
|
|
|
//Checking company existency in company table
|
|
$sCompanyTextCol = MySqlManager::getText(MySqlManager::COMP_TABLE);
|
|
$iCompanyId = $this->oMySql->selectInsert(MySqlManager::COMP_TABLE, array($sCompanyTextCol=>mb_strtolower($sCompany), 'logo'=>self::DEFAULT_COMPANY_LOGO), array($sCompanyTextCol));
|
|
|
|
$asInfo = array('first_name'=>$sFirstName,
|
|
'last_name'=>$sLastName,
|
|
'email'=>$sEmail,
|
|
MySqlManager::getId(MySqlManager::COMP_TABLE)=>$iCompanyId,
|
|
'clearance'=>$iClearance,
|
|
'led'=>'0000-00-00 00:00:00');
|
|
$iUserId = $this->oMySql->insertRow(MySqlManager::USER_TABLE, $asInfo);
|
|
|
|
//Admin Options
|
|
$sOptionTable = MySqlManager::OPT_TABLE;
|
|
$sUserIdCol = MySqlManager::getId(MySqlManager::USER_TABLE);
|
|
$sOptNameIdCol = MySqlManager::getId(MySqlManager::OPTNAME_TABLE);
|
|
$sOptionTextCol = MySqlManager::getText(MySqlManager::OPT_TABLE);
|
|
$this->oMySql->insertRow($sOptionTable, array($sUserIdCol=>$iUserId, $sOptNameIdCol=>self::OPT_NICKNAME, $sOptionTextCol=>$sFirstName));
|
|
//$this->oMySql->insertRow($sOptionTable, array($sUserIdCol=>$iUserId, $sOptNameIdCol=>self::OPT_BG, $sOptionTextCol=>'#04357B'));
|
|
//$this->oMySql->insertRow($sOptionTable, array($sUserIdCol=>$iUserId, $sOptNameIdCol=>self::OPT_BRIGHT_BG, $sOptionTextCol=>'#D9E5F2'));
|
|
//$this->oMySql->insertRow($sOptionTable, array($sUserIdCol=>$iUserId, $sOptNameIdCol=>self::OPT_HOVER, $sOptionTextCol=>'#EFAB00'));
|
|
$this->oMySql->insertRow($sOptionTable, array($sUserIdCol=>$iUserId, $sOptNameIdCol=>self::OPT_TOKEN, $sOptionTextCol=>$this->generateRssLink($iUserId)));
|
|
//$this->oMySql->insertRow($sOptionTable, array($sUserIdCol=>$iUserId, $sOptNameIdCol=>self::OPT_IMAGE_CHAT, $sOptionTextCol=>'images/sap_gold_332.jpg'));
|
|
|
|
return $iUserId;
|
|
}
|
|
|
|
public function resetToken()
|
|
{
|
|
$asRs = $this->oMySql->selectRows(array('from'=>'`options`', 'constraint'=>array('id_option_name'=>self::OPT_TOKEN)));
|
|
foreach($asRs as $asR)
|
|
{
|
|
$sTokenLink = $this->generateRssLink($asR['id_user']);
|
|
$this->oMySql->updateRow('`options`', array('id_option'=>$asR['id_option']), array('`option`'=>$sTokenLink));
|
|
}
|
|
return $asRs;
|
|
}
|
|
|
|
private function generateRssLink($iUserId=0)
|
|
{
|
|
if($iUserId==0) $iUserId = $this->getUserId();
|
|
return $_GET['serv_name'].'?a='.self::EXT_ACCESS.'&p=rss&auth_token='.$iUserId.'_'.$this->generateToken($iUserId);
|
|
}
|
|
|
|
private function generateToken($iUserId)
|
|
{
|
|
$sEncryptedToken = '';
|
|
if($iUserId>0)
|
|
{
|
|
$asUser = $this->oMySql->selectRow(MySqlManager::USER_TABLE, $iUserId, array('first_name', 'last_name', 'email', MySqlManager::getId(MySqlManager::COMP_TABLE)));
|
|
$sEncryptedToken = self::encryptPassword($asUser['first_name'].$asUser['last_name'].$asUser['email'].$asUser[MySqlManager::getId(MySqlManager::COMP_TABLE)]);
|
|
}
|
|
else
|
|
{
|
|
$this->addError('generating token : invalid user id "'.$iUserId.'"');
|
|
}
|
|
return $sEncryptedToken;
|
|
}
|
|
|
|
public function buildCompleteIndex()
|
|
{
|
|
$asSearchTypes = array( self::CODE_TYPE=>MySqlManager::CODE_TABLE,
|
|
self::PROC_TYPE=>MySqlManager::PROC_TABLE,
|
|
self::ART_TYPE=>MySqlManager::ART_TABLE,
|
|
self::DOC_TYPE=>MySqlManager::DOC_TABLE);
|
|
|
|
$this->oMySql->getArrayQuery("TRUNCATE ".MySqlManager::SEARCH_TABLE);
|
|
foreach($asSearchTypes as $sSearchType=>$sSearchTable)
|
|
{
|
|
$asItemIds = $this->oMySql->selectRows(array('select'=>MySqlManager::getId($sSearchTable), 'from'=>$sSearchTable));
|
|
foreach($asItemIds as $iItemId) $this->oSearchEngine->buildIndex($iItemId, $sSearchType);
|
|
}
|
|
}
|
|
|
|
//insert new code / version
|
|
public function addCode($asData)
|
|
{
|
|
$sContent = $asData['content'];
|
|
$sDescription = $asData['description'];
|
|
$sLink = str_replace(' ', '_', $asData['link']);
|
|
|
|
//insert value in db
|
|
$asInsert = array( MySqlManager::getText(MySqlManager::CODE_TABLE)=>$sContent,
|
|
'description'=>$sDescription,
|
|
'id_user'=>$this->getUserId());
|
|
$iCodeId = $this->oMySql->insertRow(MySqlManager::CODE_TABLE, $asInsert);
|
|
|
|
//insert link if exists
|
|
if($sLink!='')
|
|
{
|
|
$asInsert = array(MySqlManager::getId(MySqlManager::CODE_TABLE)=>$iCodeId, 'phrase'=>$sLink);
|
|
$this->oMySql->insertRow(MySqlManager::URL_TABLE, $asInsert);
|
|
}
|
|
|
|
//refer id update
|
|
$this->oMySql->updateRow(MySqlManager::CODE_TABLE, $iCodeId, array('refer_id'=>$iCodeId));
|
|
|
|
//Add message
|
|
$this->addMessage($iCodeId, self::MESSAGE_ADD_CODE, self::ALL_CHAN_ID);
|
|
|
|
//Add record in Search Table
|
|
$this->oSearchEngine->buildIndex($iCodeId, self::CODE_TYPE);
|
|
|
|
return $iCodeId;
|
|
}
|
|
|
|
public function editCode($oCode, $sContent)
|
|
{
|
|
$asRef = $this->getCodeInfo($oCode, 'first');
|
|
$iVersion = $this->oMySql->selectValue(MySqlManager::CODE_TABLE, 'COUNT(id_code)', array('refer_id'=>$asRef['id_code']))+1;
|
|
$asEdit = array('code'=>$sContent,
|
|
'description'=>$asRef['description'].' (v'.$iVersion.')',
|
|
'id_user'=>$this->iUserId,
|
|
'refer_id'=>$asRef['id_code']);
|
|
|
|
$iCodeId = $this->oMySql->insertRow(MySqlManager::CODE_TABLE, $asEdit);
|
|
|
|
//Add message
|
|
$this->addMessage($iCodeId, self::MESSAGE_EDIT_CODE, self::ALL_CHAN_ID);
|
|
|
|
//Add record in Search Table
|
|
$this->oSearchEngine->buildIndex($iCodeId, self::CODE_TYPE);
|
|
|
|
return $iCodeId;
|
|
}
|
|
|
|
public function addProcedure($asPost)
|
|
{
|
|
$asPost['id_user'] = $this->getUserId();
|
|
$this->oProcedure->inputForm($asPost);
|
|
$asErrors = $this->oProcedure->checkIntegrity();
|
|
if(count($asErrors)==0)
|
|
{
|
|
//Previous procedure Id
|
|
$iPrevProcId = isset($asPost['procedure_id'])?$asPost['procedure_id']:0;
|
|
|
|
//Load procedure into database
|
|
$bCreation = $this->oProcedure->saveProcedure($iPrevProcId);
|
|
|
|
//Extract extra data
|
|
$asProc = $this->oProcedure->getProcedure();
|
|
$iNewProcId = $asProc['proc_id'];
|
|
$asUser = $this->getUserInfo($this->getUserId());
|
|
|
|
$oResult = array('result'=>'success',
|
|
'proc_id'=>$iNewProcId,
|
|
'led'=>$asProc['led'],
|
|
'name'=>$asUser['name'],
|
|
'company'=>$asUser['company']);
|
|
|
|
//Add Message in chat
|
|
if($bCreation)
|
|
{
|
|
$this->addMessage($iNewProcId, self::MESSAGE_ADD_PROC, self::ALL_CHAN_ID);
|
|
}
|
|
else
|
|
{
|
|
$this->addMessage($iNewProcId, self::MESSAGE_EDIT_PROC, self::ALL_CHAN_ID);
|
|
}
|
|
|
|
//Add record in Search Table
|
|
$this->oSearchEngine->buildIndex($iNewProcId, self::PROC_TYPE);
|
|
}
|
|
else
|
|
{
|
|
$oResult = array('result'=>'fail', 'errors'=>$asErrors);
|
|
}
|
|
|
|
return self::jsonExport($oResult);
|
|
}
|
|
|
|
public function getProcedure($iProcId)
|
|
{
|
|
$this->oProcedure->loadProcedure($iProcId);
|
|
$asProc = $this->oProcedure->getProcedure();
|
|
|
|
//Adding user info
|
|
$asUser = $this->getUserInfo($asProc['id_user']);
|
|
$asProc['name'] = $asUser['name'];
|
|
$asProc['company'] = $asUser['company'];
|
|
|
|
return self::jsonExport($asProc);
|
|
}
|
|
|
|
public function addDoc($asPost)
|
|
{
|
|
//Previous Doc Id
|
|
$iPrevDocId = $asPost['doc_id'];
|
|
$bCreation = ($iPrevDocId==0);
|
|
|
|
//User
|
|
$iUserId = $this->getUserId();
|
|
|
|
//Titles
|
|
$sTitle = isset($asPost['title'])?$asPost['title']:'';
|
|
$sDescription = isset($asPost['description'])?$asPost['description']:'';
|
|
|
|
//Get docs
|
|
$sImagePattern = '/c1_(?P<doc_id>\d+)_image_(?P<doc_info>\w+)/';
|
|
foreach($asPost as $sFormId=>$sValue)
|
|
{
|
|
preg_match($sImagePattern, $sFormId, $asMatches);
|
|
if($asMatches['doc_info'] == 'name' || $asMatches['doc_info'] == 'desc')
|
|
{
|
|
$asDocs[$asMatches['doc_id']][$asMatches['doc_info']] = $sValue;
|
|
}
|
|
}
|
|
|
|
//Load doc into database
|
|
$asData = array('title'=>$sTitle, 'description'=>$sDescription, MySqlManager::getId(MySqlManager::USER_TABLE)=>$iUserId);
|
|
$iDbDocId = $this->oMySql->insertRow(MySqlManager::DOC_TABLE, $asData);
|
|
|
|
//Load doc files into database
|
|
$asDocData[MySqlManager::getId(MySqlManager::DOC_TABLE)] = $iDbDocId;
|
|
foreach($asDocs as $asDocInfo)
|
|
{
|
|
//insert into database
|
|
$sFileName = $asDocInfo['name'];
|
|
$asDocData['description'] = $asDocInfo['desc'];
|
|
$asDocData['file_name'] = $sFileName;
|
|
$iDbImageId = $this->oMySql->insertRow(MySqlManager::FILE_TABLE, $asDocData);
|
|
|
|
//Move file
|
|
$sTempFilePath = self::DOC_TMP_FOLDER.$sFileName;
|
|
$sFilePath = self::DOC_FOLDER.$sFileName;
|
|
if(!rename($sTempFilePath, $sFilePath))
|
|
{
|
|
$this->addError('Unmoveable file : '.$sTempFilePath);
|
|
}
|
|
}
|
|
|
|
//Add this doc to the group
|
|
$iReferId = $bCreation?$iDbDocId:$this->oMySql->selectValue(MySqlManager::DOC_TABLE, 'refer_id', $iPrevDocId);
|
|
$this->oMySql->updateRow(MySqlManager::DOC_TABLE, $iDbDocId, array('refer_id'=>$iReferId));
|
|
|
|
//Add Message in chat
|
|
$this->addMessage($iDbDocId, $bCreation?self::MESSAGE_ADD_DOC:self::MESSAGE_EDIT_DOC, self::ALL_CHAN_ID);
|
|
|
|
//Add record in Search Table
|
|
$this->oSearchEngine->buildIndex($iDbDocId, self::DOC_TYPE);
|
|
|
|
return self::jsonExport(array('result'=>'success','doc_id'=>$iDbDocId));
|
|
}
|
|
|
|
public function getDoc($iDocId)
|
|
{
|
|
//Extract doc data
|
|
$asDoc = $this->oMySql->selectRow(MySqlManager::DOC_TABLE, $iDocId);
|
|
|
|
//Extract extra data
|
|
$asUser = $this->getUserInfo($asDoc['id_user']);
|
|
$asDoc['name'] = $asUser['name'];
|
|
$asDoc['company'] = $asUser['company'];
|
|
|
|
//Extract doc files
|
|
$asFiles = $this->oMySql->selectRows(array('from'=>MySqlManager::FILE_TABLE, 'constraint'=>array('id_doc'=>$iDocId)));
|
|
foreach($asFiles as $asFile)
|
|
{
|
|
$asDoc['files'][$asFile[MySqlManager::getId(MySqlManager::FILE_TABLE)]] = array('description'=>$asFile['description'], 'ext'=>pathinfo($asFile['file_name'], PATHINFO_EXTENSION));
|
|
}
|
|
|
|
return self::jsonExport($asDoc);
|
|
}
|
|
|
|
public function getFile($iFileId)
|
|
{
|
|
$sFileName = $this->oMySql->selectValue(MySqlManager::FILE_TABLE, 'file_name', $iFileId);
|
|
$sFilePath = self::DOC_FOLDER.$sFileName;
|
|
$sFileFullPath = dirname($_SERVER['SCRIPT_FILENAME'])."/".$sFilePath;
|
|
|
|
if(!file_exists($sFilePath))
|
|
{
|
|
die();
|
|
}
|
|
else
|
|
{
|
|
//get mime type
|
|
if(class_exists('finfo'))
|
|
{
|
|
$oFileInfo = new finfo(FILEINFO_MIME);
|
|
$sMimetype = $oFileInfo->file($sFileFullPath);
|
|
}
|
|
else
|
|
{
|
|
$sMimetype = 'application/force-download';
|
|
}
|
|
|
|
//set headers
|
|
header('Pragma: public');
|
|
header('Expires: 0');
|
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
|
header('Cache-Control: public');
|
|
header('Content-Description: File Transfer');
|
|
header('Content-Type: '.$sMimetype);
|
|
header('Content-Disposition: attachment; filename='.$sFileName);
|
|
header('Content-Transfer-Encoding: binary');
|
|
header('Content-Length: '.@filesize($sFilePath));
|
|
|
|
// download
|
|
if ($oFile = @fopen($sFilePath, 'rb'))
|
|
{
|
|
while(!feof($oFile))
|
|
{
|
|
print(fread($oFile, 1024*8));
|
|
flush();
|
|
if(connection_status() != 0)
|
|
{
|
|
@fclose($oFile);
|
|
}
|
|
}
|
|
@fclose($oFile);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function uploadImage()
|
|
{
|
|
$oFileUploader = new fileUploader(Procedure::IMAGE_FOLDER_TMP, self::$UPLOAD_IMG_EXTS);
|
|
$asResult = $oFileUploader->handleUpload();
|
|
|
|
return $this->jsonConvert($asResult);
|
|
}
|
|
|
|
public function uploadDoc()
|
|
{
|
|
$oFileUploader = new fileUploader(self::DOC_TMP_FOLDER, self::$UPLOAD_DOC_EXTS);
|
|
$asResult = $oFileUploader->handleUpload();
|
|
|
|
return $this->jsonConvert($asResult);
|
|
}
|
|
|
|
private function getCodeInfo($oCode, $sMode='', $bCode=false)
|
|
{
|
|
$iCodeId = is_numeric($oCode)?$oCode:$this->getIdCodeFromPhrase($oCode);
|
|
|
|
//Mode (get last or first id_code)
|
|
if($sMode!='')
|
|
{
|
|
$this->switchCodeId($iCodeId, $sMode);
|
|
}
|
|
|
|
//Efficient request : don't request for the entire code
|
|
if(!$bCode)
|
|
{
|
|
$asSelect = MySqlManager::getTablecolumns(MySqlManager::CODE_TABLE);
|
|
unset($asSelect[MySqlManager::getText(MySqlManager::CODE_TABLE)]);
|
|
$asSelect = array_keys($asSelect);
|
|
}
|
|
else
|
|
{
|
|
$asSelect = "*";
|
|
}
|
|
|
|
$asCode = $this->oMySql->selectRow(MySqlManager::CODE_TABLE, $iCodeId, $asSelect);$this->addError($asCode);
|
|
$asCode['description'] = self::getDescriptionFormat($asCode['description']);
|
|
$asCode['timestamp'] = strtotime($asCode['led']);
|
|
$asCode['led'] = self::getDateFormat($asCode['led']);
|
|
return $asCode;
|
|
}
|
|
|
|
private function getProcInfo($iProcId)
|
|
{
|
|
$asProc = $this->oMySql->selectRow(MySqlManager::PROC_TABLE, $iProcId);
|
|
$asProc['title'] = self::getDescriptionFormat($asProc['title']);
|
|
$asProc['description'] = self::getDescriptionFormat($asProc['description']);
|
|
$asProc['timestamp'] = strtotime($asProc['led']);
|
|
$asProc['led'] = self::getDateFormat($asProc['led']);
|
|
return $asProc;
|
|
}
|
|
|
|
private function getDocInfo($iDocId)
|
|
{
|
|
$asDoc = $this->oMySql->selectRow(MySqlManager::DOC_TABLE, $iDocId);
|
|
$asDoc['title'] = self::getDescriptionFormat($asDoc['title']);
|
|
$asDoc['description'] = self::getDescriptionFormat($asDoc['description']);
|
|
$asDoc['timestamp'] = strtotime($asDoc['led']);
|
|
$asDoc['led'] = self::getDateFormat($asDoc['led']);
|
|
return $asDoc;
|
|
}
|
|
|
|
private function getArticleInfo($iArtId)
|
|
{
|
|
$asArt = $this->oMySql->selectRow(MySqlManager::ART_TABLE, $iArtId);
|
|
$asTransferredInfo = array('link_art'=>$asArt['link'], 'art_title'=>$asArt['title'], 'link_auth'=>$asArt['email']);
|
|
$asTransferredInfo['art_date'] = self::getDateFormat($asArt['date'], self::DATE_FORMAT);
|
|
$asTransferredInfo['name'] = self::getNameFormat($asArt['first_name'], $asArt['last_name']);
|
|
$asTransferredInfo['description'] = self::getDescriptionFormat($asArt['title']);
|
|
$asTransferredInfo['timestamp'] = strtotime($asArt['led']);
|
|
$asTransferredInfo['led'] = self::getDateFormat($asArt['led']);
|
|
$asTransferredInfo['company'] = 'SAP';
|
|
return $asTransferredInfo;
|
|
}
|
|
|
|
public function getUserInfo($iUserId, $bJson=false)
|
|
{
|
|
if($iUserId==$this->getUserId() && !empty($this->asUserInfo))
|
|
{
|
|
$asUserInfo = $this->asUserInfo;
|
|
}
|
|
else
|
|
{
|
|
$asRow = $this->oMySql->selectRow(MySqlManager::USER_TABLE, $iUserId);
|
|
$asCompany = $this->oMySql->selectRow(MySqlManager::COMP_TABLE, $asRow[MySqlManager::getId(MySqlManager::COMP_TABLE)]);
|
|
$asUserInfo = array( 'name'=>self::getNameFormat($asRow['first_name'], $asRow['last_name']),
|
|
'nickname'=>self::getNickNameFormat($this->getChatNickNames($iUserId)),
|
|
'email'=>$asRow['email'],
|
|
'company'=>self::getCompanyFormat($asCompany[MySqlManager::getText(MySqlManager::COMP_TABLE)]),
|
|
'status'=>$this->getDescriptionFormat($this->getUserOptionValue(self::OPT_STATUS, $iUserId)),
|
|
'logo'=>$asCompany['logo'],
|
|
'clearance'=>$asRow['clearance'],
|
|
'user_led'=>self::getDateFormat($asRow['led'], self::DATE_FORMAT));
|
|
}
|
|
return $bJson?$this->jsonExport($asUserInfo):$asUserInfo;
|
|
}
|
|
|
|
public function getUserClearance()
|
|
{
|
|
$asUserInfo = $this->getUserInfo($this->getUserId());
|
|
return $asUserInfo['clearance'];
|
|
}
|
|
|
|
public function getOptions()
|
|
{
|
|
$sOptValueIdCol = MySqlManager::getId(MySqlManager::OPTVAL_TABLE);
|
|
$sOptionTextCol = MySqlManager::getText(MySqlManager::OPT_TABLE);
|
|
$sOptNameTextCol = MySqlManager::getText(MySqlManager::OPTNAME_TABLE);
|
|
$sOptValueTextCol = MySqlManager::getText(MySqlManager::OPTVAL_TABLE);
|
|
|
|
//Available Options
|
|
$asAvailableOptions = $this->getAvailableOptions();
|
|
|
|
//User options
|
|
$asUserOptions = $this->getUserOptions();
|
|
|
|
//Build Options panel
|
|
$asSelectedOptions = array();
|
|
foreach($asAvailableOptions as $sOptNameId=>$asOption)
|
|
{
|
|
$asSelectedOptions[$sOptNameId]['option_name'] = self::getDescriptionFormat($asOption[$sOptNameTextCol]);
|
|
$asSelectedOptions[$sOptNameId]['user_value_id'] = array_key_exists($sOptNameId, $asUserOptions)?$asUserOptions[$sOptNameId][$sOptValueIdCol]:0;
|
|
$asSelectedOptions[$sOptNameId]['user_value'] = array_key_exists($sOptNameId, $asUserOptions)?$asUserOptions[$sOptNameId][$sOptionTextCol]:'';
|
|
$asSelectedOptions[$sOptNameId]['type'] = $asOption['type'];
|
|
if($asOption['type']==self::OPT_SELECT)
|
|
{
|
|
$asOptionValuesInfo = array('select'=>array($sOptValueIdCol, $sOptValueTextCol),
|
|
'from'=>MySqlManager::OPTVAL_TABLE,
|
|
'constraint'=>array('language'=>$this->sLanguage,
|
|
MySqlManager::getId(MySqlManager::OPTNAME_TABLE)=>$sOptNameId),
|
|
'orderBy'=>array('led'=>'ASC'));
|
|
$asSelectedOptions[$sOptNameId]['select'] = $this->oMySql->selectRows($asOptionValuesInfo, true, $sOptValueIdCol);
|
|
}
|
|
}
|
|
return $this->jsonExport($asSelectedOptions);
|
|
}
|
|
|
|
public function setOptions($asUserOptions, $bSilentUpdate=true)
|
|
{
|
|
foreach($this->getAvailableOptions() as $sOptNameId=>$asOption)
|
|
{
|
|
if(array_key_exists($sOptNameId, $asUserOptions))
|
|
{
|
|
switch($asOption['type'])
|
|
{
|
|
case self::OPT_SELECT: //insert id of option value table
|
|
$sUpdateCol = MySqlManager::getId(MySqlManager::OPTVAL_TABLE);
|
|
break;
|
|
case self::OPT_TEXT: //insert value
|
|
$sUpdateCol = MySqlManager::getText(MySqlManager::OPT_TABLE);
|
|
break;
|
|
default:
|
|
continue 2;
|
|
}
|
|
$sNewValue = $asUserOptions[$sOptNameId];
|
|
|
|
//Check identical data
|
|
$asKeys = array(MySqlManager::getId(MySqlManager::USER_TABLE)=>$this->getUserId(), MySqlManager::getId(MySqlManager::OPTNAME_TABLE)=>$sOptNameId);
|
|
$asData = array($sUpdateCol=>$sNewValue) + $asKeys;
|
|
$sOldValue = $this->oMySql->selectValue(MySqlManager::OPT_TABLE, $sUpdateCol, $asKeys);
|
|
|
|
//Update value
|
|
if($sOldValue!=$sNewValue)
|
|
{
|
|
//Update value
|
|
$this->oMySql->insertUpdateRow(MySqlManager::OPT_TABLE, $asData, array_keys($asKeys));
|
|
|
|
//Spread the word
|
|
if(!$bSilentUpdate)
|
|
{
|
|
//TODO rassembler les messages similaires dans une fonction de template
|
|
switch($sOptNameId)
|
|
{
|
|
case self::OPT_NICKNAME:
|
|
$sType = self::MESSAGE_NICK;
|
|
$sChanName = self::ALL_CHAN_TEXT;
|
|
$sMessage = $sOldValue.' a changé son pseudo en '.$sNewValue;
|
|
break;
|
|
case self::OPT_STATUS:
|
|
$sType = self::MESSAGE_STATUS;
|
|
$sChanName = self::ALL_CHAN_TEXT;
|
|
$sMessage = 'est sur une nouvelle mission : '.$this->getDescriptionFormat($sNewValue);
|
|
break;
|
|
default:
|
|
continue 2;
|
|
}
|
|
$sChanId = $this->getChanId($sChanName);
|
|
$this->addMessage($sMessage, $sType, $sChanId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private function getAvailableOptions()
|
|
{
|
|
$sOptNameIdCol = MySqlManager::getId(MySqlManager::OPTNAME_TABLE);
|
|
$sOptNameTextCol = MySqlManager::getText(MySqlManager::OPTNAME_TABLE);
|
|
$asInfo = array('select'=>array($sOptNameIdCol, $sOptNameTextCol, 'type'),
|
|
'from'=>MySqlManager::OPTNAME_TABLE,
|
|
'constraint'=>array('language'=>$this->sLanguage));
|
|
return $this->oMySql->selectRows($asInfo, true, $sOptNameIdCol);
|
|
}
|
|
|
|
private function getUserOptionValue($sOptionNameId, $iUserId=0)
|
|
{
|
|
$asUserOptions = $this->getUserOptions($sOptionNameId, $iUserId);
|
|
$asOptionInfo = array_shift($asUserOptions);
|
|
return $asOptionInfo['option'];
|
|
}
|
|
|
|
private function getUserOptions($oOptionNameIds=array(), $iUserId=0)
|
|
{
|
|
$iUserId = $iUserId>0?$iUserId:$this->getUserId();
|
|
$sUserIdCol = MySqlManager::getId(MySqlManager::USER_TABLE);
|
|
$sOptNameIdCol = MySqlManager::getId(MySqlManager::OPTNAME_TABLE);
|
|
$sOptValueIdCol = MySqlManager::getId(MySqlManager::OPTVAL_TABLE);
|
|
$sOptionTextCol = MySqlManager::getText(MySqlManager::OPT_TABLE);
|
|
|
|
if(!is_array($oOptionNameIds))
|
|
{
|
|
$oOptionNameIds = array($oOptionNameIds);
|
|
}
|
|
|
|
$asUserinfo = array('select'=>array($sOptNameIdCol, $sOptValueIdCol, $sOptionTextCol),
|
|
'from'=>MySqlManager::OPT_TABLE,
|
|
'constraint'=>array($sUserIdCol=>$iUserId));
|
|
if(count($oOptionNameIds)>0)
|
|
{
|
|
$asUserinfo['constraint'][$sOptNameIdCol] = "(".implode(", ", $oOptionNameIds).")";
|
|
$asUserinfo['constOpe'] = array($sUserIdCol=>"=", $sOptNameIdCol=>" IN ");
|
|
$asUserinfo['constVar'] = true;
|
|
}
|
|
return $this->oMySql->selectRows($asUserinfo, true, $sOptNameIdCol);
|
|
}
|
|
|
|
public function getProfile($oUser)
|
|
{
|
|
switch($oUser)
|
|
{
|
|
case '':
|
|
$iUserId = $this->getUserId();
|
|
break;
|
|
case is_numeric($oUser):
|
|
$iUserId = $oUser;
|
|
break;
|
|
case is_string($oUser):
|
|
$oRes = $this->oMySql->selectValue(MySqlManager::USER_TABLE, MySqlManager::getId(MySqlManager::USER_TABLE), array('user'=>$oUser));
|
|
$iUserId = !$oRes?$this->getUserId():$oRes;
|
|
break;
|
|
default:
|
|
$iUserId = $this->getUserId();
|
|
break;
|
|
}
|
|
|
|
//User Info
|
|
$asProfile = $this->getUserInfo($iUserId);
|
|
|
|
//History Info
|
|
$iFullCodeId = MySqlManager::getId(MySqlManager::CODE_TABLE, true);
|
|
$iFullLedName = MySqlManager::getFullColumnName(MySqlManager::CODE_TABLE, 'led');
|
|
$asInfo = array('select'=>array($iFullCodeId, 'description', 'refer_id', $iFullLedName, 'phrase'),
|
|
'from'=>MySqlManager::CODE_TABLE,
|
|
'join'=>array(MySqlManager::URL_TABLE=>MySqlManager::getId(MySqlManager::CODE_TABLE)),
|
|
'constraint'=>array('id_user'=>$iUserId),
|
|
'orderBy'=>array('led'=>'DESC'));
|
|
|
|
$asHistory = $this->oMySql->selectRows($asInfo);
|
|
foreach($asHistory as $asCode)
|
|
{
|
|
$asProfile['history'][$asCode['id_code']]['action'] = (($asCode['refer_id']==$asCode['id_code'])?'Création':'Modification').' de code';
|
|
$asProfile['history'][$asCode['id_code']]['date'] = self::getDateFormat($asCode['led']);
|
|
$asProfile['history'][$asCode['id_code']]['description'] = $asCode['description'];
|
|
$asProfile['history'][$asCode['id_code']]['phrase'] = ($asCode['phrase']=='')?$asCode['id_code']:$asCode['phrase'];
|
|
}
|
|
return $this->jsonExport($asProfile);
|
|
}
|
|
|
|
private static function isPmChan($sChanSafeName)
|
|
{
|
|
$asResult = array('is_pm'=>false, 'chan_name'=>$sChanSafeName);
|
|
|
|
preg_match('/(?P<from>\d+)'.self::PM_SEP.'(?P<to>\d+)/', $sChanSafeName, $asMatch);
|
|
if(!empty($asMatch))
|
|
{
|
|
$asResult['is_pm'] = true;
|
|
$asResult['from'] = $asMatch['from'];
|
|
$asResult['to'] = $asMatch['to'];
|
|
if($asMatch['from'] > $asMatch['to']) $asResult['chan_name'] = $asMatch['to'].self::PM_SEP.$asMatch['from'];
|
|
else $asResult['chan_name'] = $asMatch['from'].self::PM_SEP.$asMatch['to'];
|
|
}
|
|
|
|
return $asResult;
|
|
}
|
|
|
|
private function checkChanAuth($sChanSafeName, $iUserId=0)
|
|
{
|
|
$asUserInfo = ($iUserId > 0)?$this->getUserInfo($iUserId):array('company'=>'');
|
|
$asCompanies = $this->oMySql->selectRows(array('select'=>MySqlManager::getText(MySqlManager::COMP_TABLE), 'from'=>MySqlManager::COMP_TABLE));
|
|
$iCompChan = array_search($sChanSafeName, array_map(array('self', 'getChanSafeName'), $asCompanies));
|
|
$asPm = $this->isPmChan($sChanSafeName);
|
|
|
|
return $sChanSafeName!='' && //Empty channel name
|
|
($iCompChan===false || $asUserInfo['company']==self::getCompanyFormat($asCompanies[$iCompChan])) && //Test Company Channel
|
|
(!$asPm['is_pm'] || $iUserId==$asPm['from'] || $iUserId==$asPm['to']); //Test PM
|
|
}
|
|
|
|
public function joinChan($sChanName, $bFirstConn=false, $asAttendees=array())
|
|
{
|
|
$asResult = array('success'=>self::ERROR);
|
|
$sSafeChanName = self::getChanSafeName($sChanName);
|
|
|
|
//Authorization to join channel
|
|
$asMessages = array();
|
|
if($this->checkChanAuth($sSafeChanName, $this->getUserId()))
|
|
{
|
|
//On first connection, display on-join message for all channels
|
|
if($bFirstConn)
|
|
{
|
|
$asConnChans = $this->getChannels($this->getUserId());
|
|
$bFirstChan = true;
|
|
foreach($asConnChans as $iConnChanId=>$sConnChanName)
|
|
{
|
|
//Checking once for all channels
|
|
if(!$bFirstChan || !$this->isUserConnected($iConnChanId))
|
|
{
|
|
$asMessages[$iConnChanId] = $sConnChanName;
|
|
}
|
|
else break;
|
|
$bFirstChan = false;
|
|
}
|
|
}
|
|
|
|
//Add connection link in DB
|
|
$sUserIdCol = MySqlManager::getId(MySqlManager::USER_TABLE);
|
|
$sChanIdCol = MySqlManager::getId(MySqlManager::CHAN_TABLE);
|
|
|
|
$asData = array('safe_name'=>$sSafeChanName, MySqlManager::getText(MySqlManager::CHAN_TABLE)=>$sChanName);
|
|
$iChanId = $this->oMySql->insertUpdateRow(MySqlManager::CHAN_TABLE, $asData, array('safe_name'), false);
|
|
|
|
//Is user already connected to this chan
|
|
$bConnectedUser = $this->isUserConnected($iChanId);
|
|
$iConnId = $this->oMySql->insertUpdateRow(MySqlManager::CONN_TABLE, array($sUserIdCol=>$this->getUserId(), $sChanIdCol=>$iChanId), array($sUserIdCol, $sChanIdCol), false);
|
|
if($iConnId>0) $asResult['success'] = self::SUCCESS;
|
|
|
|
if($asResult['success']==self::SUCCESS)
|
|
{
|
|
//Return connected channels
|
|
$asResult['channels'] = $this->getChannels($this->getUserId());
|
|
|
|
//Add tab title (customized)
|
|
//TODO delete this shit and insert the channel type into channels DB table
|
|
foreach($asResult['channels'] as $iConnectedChanId=>$sConnectedChanName)
|
|
{
|
|
$asPm = $this->isPmChan($sConnectedChanName);
|
|
$asResult['channel_tab_names'][$iConnectedChanId] = $asPm['is_pm']?$this->getChatNickNames($asPm['from']==$this->getUserId()?$asPm['to']:$asPm['from']):$sConnectedChanName;
|
|
}
|
|
$asResult['current_chan_id'] = $iChanId;
|
|
|
|
//Communicate on user's connection
|
|
if(!$bConnectedUser)
|
|
{
|
|
$asMessages[$iChanId] = $this->oMySql->selectValue(MySqlManager::CHAN_TABLE, MySqlManager::getText(MySqlManager::CHAN_TABLE), $iChanId);
|
|
}
|
|
$sStatus = $this->getUserOptionValue(self::OPT_STATUS);
|
|
$asUserInfo = $this->getUserInfo($this->getUserId());
|
|
foreach($asMessages as $iChanId=>$sMsgChanName)
|
|
{
|
|
$asPm = $this->isPmChan($sMsgChanName);
|
|
$this->addMessage(' de '.$asUserInfo['company'].' ('.($sStatus==''?'aucune mission en cours':$this->getDescriptionFormat($sStatus)).') rejoint '.($asPm['is_pm']?'le chan privé':'#'.$sMsgChanName), self::MESSAGE_CONN, $iChanId);
|
|
}
|
|
|
|
//Send invites to attendees
|
|
if(!empty($asAttendees))
|
|
{
|
|
$asUserInfo = $this->getUserInfo($this->getUserId());
|
|
foreach($asAttendees as $sAttendee)
|
|
{
|
|
if($this->checkChanAuth($sSafeChanName, $sAttendee))
|
|
{
|
|
$this->addMessage($sAttendee, self::MESSAGE_INVITE, $iChanId);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Update chan leds
|
|
$this->pingChans();
|
|
}
|
|
}
|
|
|
|
return self::jsonExport($asResult);
|
|
}
|
|
|
|
private function isUserConnected($iChanId=0, $iUserId=0)
|
|
{
|
|
$iUserId = $iUserId>0?$iUserId:$this->getUserId();
|
|
|
|
$sUserIdCol = MySqlManager::getId(MySqlManager::USER_TABLE);
|
|
$asInfo = array('select' => MySqlManager::getId(MySqlManager::CONN_TABLE),
|
|
'from' => MySqlManager::CONN_TABLE,
|
|
'constraint'=> array($sUserIdCol=>$iUserId, 'led'=>"DATE_SUB(NOW(), INTERVAL ".self::KEEP_ALIVE." SECOND)"),
|
|
'constOpe' => array($sUserIdCol=>'=', 'led'=>'>'),
|
|
'constVar' => true,
|
|
'groupBy' => $sUserIdCol);
|
|
|
|
//Add chan constraint
|
|
if($iChanId>0)
|
|
{
|
|
$asInfo['constraint'][MySqlManager::getId(MySqlManager::CHAN_TABLE)] = $iChanId;
|
|
$asInfo['constOpe'][MySqlManager::getId(MySqlManager::CHAN_TABLE)] = '=';
|
|
}
|
|
return (count($this->oMySql->selectRows($asInfo))>0);
|
|
}
|
|
|
|
public function pingChans()
|
|
{
|
|
$aiConstraints = array(MySqlManager::getId(MySqlManager::USER_TABLE)=>$this->getUserId());
|
|
$asUpdates = array('led'=>date(self::DATE_TIME_SQL_FORMAT));
|
|
$this->oMySql->updateRows(MySqlManager::CONN_TABLE, $aiConstraints, $asUpdates);
|
|
}
|
|
|
|
public function quitChan($sChanName)
|
|
{
|
|
$iChanId = $this->getChanId($sChanName);
|
|
$iConnId = $this->getConnId($iChanId);
|
|
if($iConnId>0)
|
|
{
|
|
$this->oMySql->deleteRow(MySqlManager::CONN_TABLE, $iConnId);
|
|
$asPm = $this->isPmChan($sChanName);
|
|
$this->addMessage('quitte '.($asPm['is_pm']?'le chan privé':'#'.$sChanName), self::MESSAGE_CONN, $iChanId);
|
|
}
|
|
}
|
|
|
|
private function getActiveChannels()
|
|
{
|
|
//Get connected users
|
|
$asActiveChanUsers = $this->getConnectedUsers(false, false);
|
|
$asActiveChans = array_keys($asActiveChanUsers);
|
|
|
|
//Get Channel names
|
|
$sChanIdCol = MySqlManager::getId(MySqlManager::CHAN_TABLE);
|
|
$asChanNames = $this->oMySql->selectRows(array('select'=>array($sChanIdCol, MySqlManager::getText(MySqlManager::CHAN_TABLE)), 'from'=>MySqlManager::CHAN_TABLE), true, $sChanIdCol);
|
|
|
|
foreach($asActiveChans as $iChanId)
|
|
{
|
|
$asChannels[$asChanNames[$iChanId]] = count($asActiveChanUsers[$iChanId]);
|
|
}
|
|
|
|
//remove restricted channels
|
|
$asPublicChannels = array();
|
|
foreach($asChannels as $sChanName=>$iChanCount)
|
|
{
|
|
if($this->checkChanAuth($this->getChanSafeName($sChanName))) $asPublicChannels[$sChanName] = $iChanCount;
|
|
}
|
|
|
|
return $asPublicChannels;
|
|
}
|
|
|
|
private function getChannels($iUserId=0)
|
|
{
|
|
$sChanIdCol = MySqlManager::getId(MySqlManager::CHAN_TABLE, true);
|
|
$sChanNameCol = MySqlManager::getText(MySqlManager::CHAN_TABLE);
|
|
|
|
$asInfo = array('select'=>array($sChanIdCol, $sChanNameCol),
|
|
'from'=> MySqlManager::CONN_TABLE,
|
|
'join'=> array(MySqlManager::CHAN_TABLE=>MySqlManager::getId(MySqlManager::CHAN_TABLE)),
|
|
'orderBy'=> array(MySqlManager::getId(MySqlManager::CONN_TABLE)=>'ASC'));
|
|
if($iUserId > 0) $asInfo['constraint'] = array(MySqlManager::getId(MySqlManager::USER_TABLE)=>$iUserId);
|
|
|
|
$asChannels = $this->oMySql->selectRows($asInfo, true, MySqlManager::getId(MySqlManager::CHAN_TABLE));
|
|
|
|
//remove restricted channels
|
|
$asPublicChannels = array();
|
|
foreach($asChannels as $iChanId=>$sChanName)
|
|
{
|
|
if($this->checkChanAuth($this->getChanSafeName($sChanName), $iUserId)) $asPublicChannels[$iChanId] = $sChanName;
|
|
}
|
|
return $asPublicChannels;
|
|
}
|
|
|
|
private function getChanId($sChanName)
|
|
{
|
|
$sChanIdCol = MySqlManager::getId(MySqlManager::CHAN_TABLE);
|
|
$sSafeChanName = self::getChanSafeName($sChanName);
|
|
$iChanId = $this->oMySql->selectValue(MySqlManager::CHAN_TABLE, $sChanIdCol, array('safe_name'=>$sSafeChanName));
|
|
if($iChanId==0)
|
|
{
|
|
|
|
$this->addError('No channel id found with channel name (safe): '.$sSafeChanName.', unsafe: '.$sChanName);
|
|
}
|
|
return $iChanId;
|
|
}
|
|
|
|
private function getConnId($iChanId, $iUserId=0)
|
|
{
|
|
$sUserIdCol = MySqlManager::getId(MySqlManager::USER_TABLE);
|
|
$sConnIdCol = MySqlManager::getId(MySqlManager::CONN_TABLE);
|
|
$sChanIdCol = MySqlManager::getId(MySqlManager::CHAN_TABLE);
|
|
|
|
if($iUserId==0) $iUserId = $this->getUserId();
|
|
$iConnId = $this->oMySql->selectValue(MySqlManager::CONN_TABLE, $sConnIdCol, array($sUserIdCol=>$iUserId, $sChanIdCol=>$iChanId));
|
|
if($iConnId==0)
|
|
{
|
|
$this->addError('No connection found for user: '.$iUserId.' and channel id: '.$iChanId);
|
|
}
|
|
return $iConnId;
|
|
}
|
|
|
|
public function addChatMessage($sMessage, $sChanName)
|
|
{
|
|
$sMessage = htmlspecialchars($sMessage);
|
|
$sType = self::MESSAGE_USER;
|
|
if(mb_substr($sMessage, 0, 1) == '/')
|
|
{
|
|
if(mb_substr($sMessage, 0, 4) == '/me ')
|
|
{
|
|
$sType = self::MESSAGE_ACTION;
|
|
$sMessage = mb_substr($sMessage, 3);
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 6) == '/slap ')
|
|
{
|
|
$sType = self::MESSAGE_ACTION;
|
|
$sMessage = ' fout une grosse tarte à '.mb_substr($sMessage, 5);
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 4) == '/bs ')
|
|
{
|
|
$sType = self::MESSAGE_ACTION;
|
|
$sMessage = ' bitch-slaps '.mb_substr($sMessage, 3);
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 6) == '/kick ')
|
|
{
|
|
$sType = self::MESSAGE_ACTION;
|
|
$sMessage = ' met un coup de pied au cul de '.mb_substr($sMessage, 5);
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 6) == '/nick ' && mb_strlen($sMessage)>6)
|
|
{
|
|
$sNewNick = $this->getNickNameFormat(mb_substr($sMessage, 5));
|
|
$sOldNick = $this->getNickNameFormat($this->getChatNickNames($this->getUserId()));
|
|
|
|
//changing Nickname
|
|
$this->setOptions(array(self::OPT_NICKNAME=>$sNewNick));
|
|
|
|
//Message
|
|
$sType = self::MESSAGE_NICK;
|
|
$sChanName = self::ALL_CHAN_TEXT;
|
|
$sMessage = $sOldNick.' a changé son pseudo en '.$sNewNick;
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 9) == '/mission ' && mb_strlen($sMessage)>9)
|
|
{
|
|
$sNewStatus = mb_substr($sMessage, 9);
|
|
$sNewFormatStatus = $this->getDescriptionFormat($sNewStatus);
|
|
|
|
//changing Nickname
|
|
$this->setOptions(array(self::OPT_STATUS=>$sNewStatus));
|
|
|
|
//Message
|
|
$sType = self::MESSAGE_STATUS;
|
|
$sChanName = self::ALL_CHAN_TEXT;
|
|
$sMessage = 'est sur une nouvelle mission : '.$sNewFormatStatus;
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 6) == '/mail ' && mb_strlen($sMessage)>6)
|
|
{
|
|
$sImagePattern = '/\/mail (?P<nickname>\w+) (?P<message>.*)/';
|
|
preg_match($sImagePattern, $sMessage, $asMatches);
|
|
|
|
//Looking for user Id
|
|
$asContraints = array( 'LOWER(`'.MySqlManager::getText(MySqlManager::OPT_TABLE).'`)'=>mb_strtolower($asMatches['nickname']),
|
|
MySqlManager::getId(MySqlManager::OPTNAME_TABLE)=>self::OPT_NICKNAME);
|
|
$iUserIdTo = $this->oMySql->selectValue(MySqlManager::OPT_TABLE, MySqlManager::getId(MySqlManager::USER_TABLE), $asContraints);
|
|
|
|
//Handling mail
|
|
if($iUserIdTo>0)
|
|
{
|
|
if(trim($asMatches['message'])!='')
|
|
{
|
|
if($this->sendPM($iUserIdTo, $asMatches['message']))
|
|
{
|
|
$sMessage = 'a envoyé un mail à '.$asMatches['nickname'];
|
|
}
|
|
else
|
|
{
|
|
$sMessage = 'n\'a pas envoyé de mail à '.$asMatches['nickname'].' (raison inconnue, voir log)';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$sMessage = 'n\'a pas envoyé de mail à '.$asMatches['nickname'].' (message vide)';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$sMessage = 'n\'a pas envoyé de mail à '.$asMatches['nickname'].' (pseudo inconnu)';
|
|
}
|
|
$sType = self::MESSAGE_ACTION;
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 5) == '/mean')
|
|
{
|
|
$sPageContent = file_get_contents('http://www.randominsults.net/');
|
|
$sStartText = '<strong><i>';
|
|
$sEndText = '</i></strong>';
|
|
$iStartPos = mb_strpos($sPageContent, $sStartText);
|
|
$iEndPos = mb_strpos($sPageContent, $sEndText);
|
|
|
|
$sMessage = mb_substr($sPageContent, $iStartPos + mb_strlen($sStartText), $iEndPos - $iStartPos);
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 5) == '/like')
|
|
{
|
|
$sType = self::MESSAGE_ACTION;
|
|
$sMessage = ' plussoie';
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 4) == '/now')
|
|
{
|
|
$sType = self::MESSAGE_ACTION;
|
|
$asWeekDays = array('lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche');
|
|
$asMonths = array('janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre');
|
|
$sMessage = ' a demandé l\'heure. Pour sa gouverne, il est exactement '.date(self::TIME_FORMAT).
|
|
', le '.$asWeekDays[date('N')-1].' '.date('j').' '.$asMonths[date('n')-1].' '.date('Y').' (semaine '.date('W').')';
|
|
}
|
|
elseif($sMessage == '/channels' || mb_substr($sMessage, 0, 5) == '/list' || $sMessage == '/chans')
|
|
{
|
|
//Always at least one channel open (the one the message is sent from)
|
|
$sMessage = ' a demandé les chans disponibles. Pour sa gouverne, les chans ayant des membres connectés sont #'.MySqlManager::implodeAll($this->getActiveChannels(), ' (', ', #', '', ')');
|
|
$sType = self::MESSAGE_ACTION;
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 5) == '/img ' && mb_strlen($sMessage)>5)
|
|
{
|
|
$sUrl = trim(mb_substr($sMessage, 4));
|
|
$asResult = $this->downloadToTmp($sUrl);
|
|
if($asResult['error']=='')
|
|
{
|
|
$sMessage = $this->getJsonMessage(array($asResult['out'], $asResult['width'], $asResult['height'], $sUrl));
|
|
$sType = self::MESSAGE_IMG;
|
|
}
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 6) == '/9gag ' && mb_strlen($sMessage)>6)
|
|
{
|
|
$sMessage = $this->getJsonMessage($this->get9gagPost(trim(mb_substr($sMessage, 6))));
|
|
$sType = self::MESSAGE_9GAG;
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 7) == '/reboot' && $this->getUserClearance()==self::CLEARANCE_ADMIN)
|
|
{
|
|
$sMessage = 'L\'administrateur a demandé un reboot. Votre page va se rafraichir automatiquement dans '.self::REBOOT_DELAY.' secondes.';
|
|
$sType = self::MESSAGE_REBOOT;
|
|
}
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 1) == '@' && mb_strpos($sMessage, ' ')>1)
|
|
{
|
|
$sType = self::MESSAGE_PRIVATE;
|
|
}
|
|
$sChanId = $this->getChanId($sChanName);
|
|
return $this->addMessage($sMessage, $sType, $sChanId);
|
|
}
|
|
|
|
private function getJsonMessage($asData)
|
|
{
|
|
return self::JSON_PREFIX.$this->jsonConvert($asData);
|
|
}
|
|
|
|
private function downloadToTmp($sUrl)
|
|
{
|
|
$sFileInfo = pathinfo($sUrl);
|
|
$sImageExt = mb_strtolower($sFileInfo['extension']);
|
|
$sFilePath = self::DOC_TMP_FOLDER.uniqid().'.'.$sImageExt;
|
|
return ToolBox::createThumbnail($sUrl, self::CHAT_IMG_MAX_WIDTH, self::CHAT_IMG_MAX_HEIGHT, $sFilePath);
|
|
}
|
|
|
|
private function sendPM($iUserIdTo, $sMessage)
|
|
{
|
|
$bSuccess = false;
|
|
$asUserFrom = $this->getUserInfo($this->getUserId());
|
|
$asUserTo = $this->getUserInfo($iUserIdTo);
|
|
$sFrom = $asUserFrom['name'].' <www-data@lutran.fr>';
|
|
|
|
$sTo = $asUserTo['name'].' <'.$asUserTo['email'].'>';
|
|
$sMessage .= "\n\n\n".'<i>Ne répondez pas à ce mail. Connectez-vous sur <a href="http://databap.lutran.fr/chat">Databap</a>.</i>';
|
|
|
|
$sResult = ToolBox::sendMail($sFrom, $sTo, 'Databap <www-data@lutran.fr>', 'Databap PM', $sMessage);
|
|
$bSuccess = ($sResult=='');
|
|
if(!$bSuccess) $this->addError($sResult);
|
|
return $bSuccess;
|
|
}
|
|
|
|
private function addMessage($sMessage, $sType, $iChanId)
|
|
{
|
|
$bResult = false;
|
|
if($iChanId>0)
|
|
{
|
|
$asInsert = array( MySqlManager::getId(MySqlManager::USER_TABLE) => $this->getUserId(),
|
|
'nickname' => $this->getChatNickNames($this->getUserId()),
|
|
MySqlManager::getId(MySqlManager::CHAN_TABLE) => $iChanId,
|
|
MySqlManager::getText(MySqlManager::MSG_TABLE) => $sMessage,
|
|
'type' => $sType,
|
|
'date' => 'CURDATE()');
|
|
$bResult = $this->oMySql->insertRow(MySqlManager::MSG_TABLE, $asInsert);
|
|
}
|
|
else
|
|
{
|
|
$this->addError('Message deleted: No channel found');
|
|
}
|
|
return $bResult;
|
|
}
|
|
|
|
public function getMessages($iFirstMsgId="0")
|
|
{
|
|
//Update chan ping
|
|
$this->pingChans();
|
|
|
|
//Get messages and users' infos
|
|
$sChanIdCol = MySqlManager::getId(MySqlManager::CHAN_TABLE, true);
|
|
$sChanTextCol = MySqlManager::getText(MySqlManager::CHAN_TABLE);
|
|
$sMsgIdCol = MySqlManager::getId(MySqlManager::MSG_TABLE, true);
|
|
$sMsgTextCol = MySqlManager::getText(MySqlManager::MSG_TABLE);
|
|
$sMsgTableLed = MySqlManager::getFullColumnName(MySqlManager::MSG_TABLE, 'led');
|
|
$sMsgTableChanIdCol = MySqlManager::getFullColumnName(MySqlManager::MSG_TABLE, MySqlManager::getId(MySqlManager::CHAN_TABLE));
|
|
$sUserIdCol = MySqlManager::getId(MySqlManager::USER_TABLE, true);
|
|
$sMsgTableUserIdCol = MySqlManager::getFullColumnName(MySqlManager::MSG_TABLE, MySqlManager::getId(MySqlManager::USER_TABLE));
|
|
$sUserTableUserIdCol = MySqlManager::getId(MySqlManager::USER_TABLE, true);
|
|
$sConnTableUserIdCol = MySqlManager::getFullColumnName(MySqlManager::CONN_TABLE, MySqlManager::getId(MySqlManager::USER_TABLE));
|
|
$sConnTableChanIdCol = MySqlManager::getFullColumnName(MySqlManager::CONN_TABLE, MySqlManager::getId(MySqlManager::CHAN_TABLE));
|
|
|
|
//channel related messages
|
|
$sCurDate = date(Databap::DATE_SQL_FORMAT);
|
|
$asInfo = array('select' => array($sMsgTableChanIdCol, $sMsgIdCol, $sMsgTextCol, 'type', $sMsgTableLed, 'first_name', 'last_name', $sUserIdCol, 'nickname'),
|
|
'from' => MySqlManager::CONN_TABLE,
|
|
'joinOn' => array( MySqlManager::MSG_TABLE =>array($sMsgTableChanIdCol, '=', $sConnTableChanIdCol),
|
|
MySqlManager::USER_TABLE=>array($sUserTableUserIdCol, '=', $sMsgTableUserIdCol)),
|
|
'constraint'=> array($sConnTableUserIdCol=>$this->getUserId(), $sMsgIdCol=>$iFirstMsgId, 'date'=>$sCurDate),
|
|
'constOpe' => array($sConnTableUserIdCol=>'=', $sMsgIdCol=>'>', 'date'=>'='));
|
|
$asSqlMessages = $this->oMySql->selectRows($asInfo, true, 'id_message');
|
|
|
|
//Global messages
|
|
$asInfo['from'] = MySqlManager::MSG_TABLE;
|
|
$asInfo['joinOn'] = array(MySqlManager::USER_TABLE=>array($sUserTableUserIdCol, '=', $sMsgTableUserIdCol));
|
|
$asInfo['constraint'] = array($sMsgTableChanIdCol=>self::ALL_CHAN_ID, $sMsgIdCol=>$iFirstMsgId, 'date'=>$sCurDate);
|
|
$asInfo['constOpe'] = array($sMsgTableChanIdCol=>'=', $sMsgIdCol=>'>', 'date'=>'=');
|
|
$asSqlGlobalMessages = $this->oMySql->selectRows($asInfo, true, 'id_message');
|
|
|
|
//Invites messages
|
|
$asInfo['constraint'] = array($sMsgIdCol=>$iFirstMsgId, 'date'=>$sCurDate, 'type'=>self::MESSAGE_INVITE, 'message'=>$this->getUserId());
|
|
$asInfo['constOpe'] = array($sMsgIdCol=>'>', 'date'=>'=', 'type'=>'=', 'message'=>'=');
|
|
$asSqlInviteMessages = $this->oMySql->selectRows($asInfo, true, 'id_message');
|
|
|
|
//Merge flows
|
|
if(!empty($asSqlGlobalMessages)) $asSqlMessages = array_diff_key($asSqlMessages, $asSqlGlobalMessages) + $asSqlGlobalMessages;
|
|
if(!empty($asSqlInviteMessages)) $asSqlMessages = array_diff_key($asSqlMessages, $asSqlInviteMessages) + $asSqlInviteMessages;
|
|
|
|
//Sort messages
|
|
ksort($asSqlMessages);
|
|
|
|
//Sort out messages for Json Export
|
|
$iPrefixLen = mb_strlen(self::JSON_PREFIX);
|
|
$asMessages = array('messages'=>array(), 'last_message_id'=>0);
|
|
foreach($asSqlMessages as $iMessageId=>$asMessageInfo)
|
|
{
|
|
$iChanId = $asMessageInfo[MySqlManager::getId(MySqlManager::CHAN_TABLE)];
|
|
$iUserId = $asMessageInfo[MySqlManager::getId(MySqlManager::USER_TABLE)];
|
|
$sMessageType = $asMessageInfo['type'];
|
|
$asMessages['messages'][$iMessageId]['id_chan'] = $iChanId;
|
|
$asMessages['messages'][$iMessageId]['message'] = $asMessageInfo[$sMsgTextCol];
|
|
$asMessages['messages'][$iMessageId]['msg_class'] = $sMessageType;
|
|
$asMessages['messages'][$iMessageId]['time'] = self::getDateFormat($asMessageInfo['led'], self::TIME_FORMAT);
|
|
$asMessages['messages'][$iMessageId]['name'] = self::getNameFormat($asMessageInfo['first_name'], $asMessageInfo['last_name']);
|
|
$asMessages['messages'][$iMessageId]['nickname'] = self::getNickNameFormat($asMessageInfo['nickname']);
|
|
|
|
//generated messages
|
|
if($sMessageType==self::MESSAGE_ADD_CODE || $sMessageType==self::MESSAGE_EDIT_CODE)
|
|
{
|
|
$asCode = $this->getCodeInfo($asMessages['messages'][$iMessageId]['message']);
|
|
$asMessages['messages'][$iMessageId]['description'] = $asCode['description'];
|
|
}
|
|
elseif($sMessageType==self::MESSAGE_ADD_PROC || $sMessageType==self::MESSAGE_EDIT_PROC)
|
|
{
|
|
$asProc = $this->getProcInfo($asMessages['messages'][$iMessageId]['message']);
|
|
$asMessages['messages'][$iMessageId]['description'] = $asProc['title'];
|
|
}
|
|
elseif($sMessageType==self::MESSAGE_ADD_DOC || $sMessageType==self::MESSAGE_EDIT_DOC)
|
|
{
|
|
$asDoc = $this->getDocInfo($asMessages['messages'][$iMessageId]['message']);
|
|
$asMessages['messages'][$iMessageId]['description'] = $asDoc['title'];
|
|
}
|
|
elseif($sMessageType==self::MESSAGE_ARTICLE)
|
|
{
|
|
$asTransferredInfo = $this->getArticleInfo($asMessages['messages'][$iMessageId]['message']);
|
|
$asMessages['messages'][$iMessageId] = array_merge($asMessages['messages'][$iMessageId], $asTransferredInfo);
|
|
}
|
|
|
|
//Switch Chan ID with name for the user to join
|
|
if($sMessageType==self::MESSAGE_INVITE)
|
|
{
|
|
$asMessages['messages'][$iMessageId]['id_chan'] = $this->oMySql->selectValue(MySqlManager::CHAN_TABLE, 'safe_name', $iChanId);
|
|
}
|
|
|
|
//Json message
|
|
if(mb_substr($asMessages['messages'][$iMessageId]['message'], 0, $iPrefixLen) == self::JSON_PREFIX)
|
|
{
|
|
$asMessages['messages'][$iMessageId]['message'] = json_decode(mb_substr($asMessages['messages'][$iMessageId]['message'], $iPrefixLen));
|
|
}
|
|
else //Normal message
|
|
{
|
|
//Dynamic web link
|
|
$asPatterns = array('`((?:https?|ftp)://\S+[[:alnum:]]/?)`si', '`((?<!//)(www\.\S+[[:alnum:]]/?))`si');
|
|
$asLinks = array('<a href="$1" target="_blank">$1</a> ', '<a href="http://$1" target="_blank">$1</a>');
|
|
$asMessages['messages'][$iMessageId]['message'] = preg_replace($asPatterns, $asLinks, $asMessages['messages'][$iMessageId]['message']);
|
|
|
|
//Dynamic chan link
|
|
$asPatterns = '/(^|\s)#(\w*[^\s]+\w*)/';
|
|
$asLinks = '\1<span class="chan_link clickable">#<span class="chan_text">\2</span></span>';
|
|
$asMessages['messages'][$iMessageId]['message'] = preg_replace($asPatterns, $asLinks, $asMessages['messages'][$iMessageId]['message']);
|
|
}
|
|
}
|
|
|
|
//Set last message Id (if new messages since $iFirstMsgId)
|
|
if(!empty($asMessages['messages']))
|
|
{
|
|
$asMessages['last_message_id'] = max(array_keys($asMessages['messages']));
|
|
}
|
|
|
|
return $this->jsonExport($asMessages);
|
|
}
|
|
|
|
private function getConnectedChans($iuserId=0)
|
|
{
|
|
$iuserId = $iuserId>0?$iuserId:$this->getUserId();
|
|
|
|
$sUserIdCol = MySqlManager::getId(MySqlManager::USER_TABLE);
|
|
$asInfo = array('select' => array(MySqlManager::getId(MySqlManager::CHAN_TABLE, true), MySqlManager::getText(MySqlManager::CHAN_TABLE)),
|
|
'from' => MySqlManager::CONN_TABLE,
|
|
'join' => array(MySqlManager::CHAN_TABLE=>MySqlManager::getId(MySqlManager::CHAN_TABLE)),
|
|
'constraint'=> array($sUserIdCol=>$iUserId, 'led'=>"DATE_SUB(NOW(), INTERVAL ".self::KEEP_ALIVE." SECOND)"),
|
|
'constOpe' => array($sUserIdCol=>'=', 'led'=>'>'),
|
|
'constVar' => true);
|
|
|
|
return $this->oMySql->selectRows($asInfo, true, MySqlManager::getId(MySqlManager::CONN_TABLE));
|
|
}
|
|
|
|
public function getConnectedUsers($bUserRestricted=false, $bJson=true)
|
|
{
|
|
$sQuery = " SELECT /* config.php 1313 */ conn2.id_channel, conn2.id_user, conn2.led, IF(DATE_SUB(NOW(), INTERVAL 1 MINUTE) < conn2.led, 0, 1) AS afk,
|
|
users.first_name, users.last_name, companies.company, companies.logo, option_nickname.option AS nickname, option_status.option AS status
|
|
FROM connections AS conn1
|
|
LEFT JOIN connections AS conn2 ON conn2.id_channel = conn1.id_channel
|
|
LEFT JOIN users ON users.id_user = conn2.id_user
|
|
LEFT JOIN companies ON companies.id_company = users.id_company
|
|
LEFT JOIN `options` AS option_nickname ON option_nickname.id_user = users.id_user AND option_nickname.id_option_name = ".self::OPT_NICKNAME."
|
|
LEFT JOIN `options` AS option_status ON option_status.id_user = users.id_user AND option_status.id_option_name = ".self::OPT_STATUS."
|
|
WHERE conn2.led > DATE_SUB(NOW(), INTERVAL ".self::KEEP_ALIVE." SECOND)".
|
|
($bUserRestricted?"AND conn1.id_user = ".$this->getUserId():"")."
|
|
GROUP BY conn2.id_channel, conn2.id_user
|
|
ORDER BY option_nickname.option ASC";
|
|
$asUserChannels = $this->oMySql->getArrayQuery($sQuery, true);
|
|
|
|
//Last messages
|
|
$iUserIdCol = MySqlManager::getId(MySqlManager::USER_TABLE);
|
|
$asLastMsg = $this->oMySql->selectRows(array('select'=>array($iUserIdCol, 'MAX(led)'), 'from'=>MySqlManager::MSG_TABLE), true, $iUserIdCol);
|
|
|
|
$asConnectedUsers = array();
|
|
foreach($asUserChannels as $asUser)
|
|
{
|
|
$sChanId = $asUser[MySqlManager::getId(MySqlManager::CHAN_TABLE)];
|
|
$iUserId = $asUser[$iUserIdCol];
|
|
$asConnectedUsers[$sChanId][$iUserId]['id_user'] = $iUserId;
|
|
$asConnectedUsers[$sChanId][$iUserId]['name'] = self::getNameFormat($asUser['first_name'], $asUser['last_name']);
|
|
$asConnectedUsers[$sChanId][$iUserId]['company'] = self::getCompanyFormat($asUser['company']);
|
|
$asConnectedUsers[$sChanId][$iUserId]['status'] = $asUser['status'];
|
|
$asConnectedUsers[$sChanId][$iUserId]['logo'] = $asUser['logo'];
|
|
$asConnectedUsers[$sChanId][$iUserId]['nickname'] = self::getNickNameFormat($asUser['nickname']==''?$asUser['first_name']:$asUser['nickname']);
|
|
$asConnectedUsers[$sChanId][$iUserId]['last_activity'] = array_key_exists($iUserId, $asLastMsg)?self::getDateFormat($asLastMsg[$iUserId], self::TIME_FORMAT):'';
|
|
$asConnectedUsers[$sChanId][$iUserId]['ping'] = self::getDateFormat($asUser['led'], self::TIME_FORMAT);
|
|
$asConnectedUsers[$sChanId][$iUserId]['afk'] = $asUser['afk'];
|
|
}
|
|
return $bJson?$this->jsonExport($asConnectedUsers):$asConnectedUsers;
|
|
}
|
|
|
|
private function getChatNickNames($iUserId=0)
|
|
{
|
|
$sUserIdCol = MySqlManager::getId(MySqlManager::USER_TABLE);
|
|
$sNicknameCol = MySqlManager::getText(MySqlManager::OPT_TABLE);
|
|
$asConstraints = array(MySqlManager::getId(MySqlManager::OPTNAME_TABLE)=>self::OPT_NICKNAME);
|
|
|
|
if($iUserId>0)
|
|
{
|
|
$asConstraints[MySqlManager::getId(MySqlManager::USER_TABLE)] = $iUserId;
|
|
$oResult = $this->oMySql->selectValue(MySqlManager::OPT_TABLE, $sNicknameCol, $asConstraints);
|
|
}
|
|
else
|
|
{
|
|
$asInfo = array('select'=>array($sUserIdCol, $sNicknameCol),
|
|
'from'=>MySqlManager::OPT_TABLE,
|
|
'constraint'=>$asConstraints);
|
|
$oResult = $this->oMySql->selectRows($asInfo, true, $sUserIdCol);
|
|
}
|
|
return $oResult;
|
|
}
|
|
|
|
private function switchCodeId(&$iCodeId, $sMode)
|
|
{
|
|
switch($sMode)
|
|
{
|
|
case 'first':
|
|
$iCodeId = $this->oMySql->selectValue(MySqlManager::CODE_TABLE, 'refer_id', $iCodeId);
|
|
break;
|
|
case 'last':
|
|
$iRefId = $this->oMySql->selectValue(MySqlManager::CODE_TABLE, 'refer_id', $iCodeId);
|
|
$iCodeId = $this->oMySql->selectValue(MySqlManager::CODE_TABLE, 'MAX(id_code)', array('refer_id'=>$iRefId));
|
|
break;
|
|
}
|
|
}
|
|
|
|
private function getIdCodeFromPhrase($sPhrase)
|
|
{
|
|
$iCodeId = $this->oMySql->selectValue(MySqlManager::URL_TABLE, MySqlManager::getId(MySqlManager::CODE_TABLE), array('phrase'=>$sPhrase));
|
|
$this->switchCodeId($iCodeId, 'last');
|
|
return $iCodeId;
|
|
}
|
|
|
|
private function getPhraseFromIdCode($iCodeId)
|
|
{
|
|
$this->switchCodeId($iCodeId, 'first');
|
|
return $this->oMySql->selectValue(MySqlManager::URL_TABLE, 'phrase', array('id_code'=>$iCodeId));
|
|
}
|
|
|
|
private function getCodeVersions($iRefCodeId)
|
|
{
|
|
$asInfo = array('select'=>array(MySqlManager::getId(MySqlManager::CODE_TABLE)),
|
|
'from'=>MySqlManager::CODE_TABLE,
|
|
'constraint'=>array('refer_id'=>$iRefCodeId),
|
|
'orderBy'=>array('id_code'=>'asc'));
|
|
$asCodeIds = $this->oMySql->selectRows($asInfo);
|
|
|
|
$asCodeVersions = array();
|
|
foreach($asCodeIds as $iCodeId)
|
|
{
|
|
$asCodeVersions[] = $this->getCodeInfo($iCodeId);
|
|
}
|
|
return $asCodeVersions;
|
|
}
|
|
|
|
public function getColoredCode($oCode)
|
|
{
|
|
$asCode = $this->getCodeInfo($oCode, '', true);
|
|
|
|
//code
|
|
$oReader = new Reader($asCode['code']);
|
|
$asCode['code'] = $oReader->getColoredCode();
|
|
|
|
//phrase
|
|
$sPhrase = $this->getPhraseFromIdCode($asCode['id_code']);
|
|
if($sPhrase !== false)
|
|
{
|
|
$asCode['phrase'] = $sPhrase;
|
|
}
|
|
|
|
//user
|
|
$asUsers[$asCode['id_user']] = $this->getUserInfo($asCode['id_user']);
|
|
$asCode = array_merge($asCode, $asUsers[$asCode['id_user']]);
|
|
|
|
//versions
|
|
$asCodeVersions = $this->getCodeVersions($asCode['refer_id']);
|
|
$iCodeRowId = 0;
|
|
foreach($asCodeVersions as $iRowId=>$asCodeVersion)
|
|
{
|
|
if($asCodeVersion['id_code']==$asCode['id_code']) $iCodeRowId = $iRowId;
|
|
}
|
|
$asCode['truncated'] = ($iCodeRowId > self::MAX_LIST_LENGTH)?$asCodeVersions[$iCodeRowId-1-self::MAX_LIST_LENGTH]['id_code']:0;
|
|
foreach($asCodeVersions as $iRowId=>$asCodeVersion)
|
|
{
|
|
if($iCodeRowId - $iRowId <= self::MAX_LIST_LENGTH)
|
|
{
|
|
if(!array_key_exists($asCodeVersion['id_user'], $asUsers))
|
|
{
|
|
$asUsers[$asCodeVersion['id_user']] = $this->getUserInfo($asCodeVersion['id_user']);
|
|
}
|
|
|
|
if($asCodeVersion['id_code']!=$asCode['id_code'])
|
|
{
|
|
$asVersionInfo = array_merge($asCodeVersion, $asUsers[$asCodeVersion['id_user']]);
|
|
$asCode['other_versions'][] = $asVersionInfo;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $this->jsonExport($asCode);
|
|
}
|
|
|
|
public function getNudeCode($oCode)
|
|
{
|
|
$asCode = $this->getCodeInfo($oCode, '', true);
|
|
//$sCode = Reader::convText2Html($asCode['code']);
|
|
return $asCode['code'];
|
|
}
|
|
|
|
public function getRawCode($oCode)
|
|
{
|
|
$asCode = $this->getCodeInfo($oCode, '', true);
|
|
$asUser = $this->getUserInfo($asCode['id_user']);
|
|
$sEncodedCode = $this->jsonConvert($asCode['code']);
|
|
$sEncodedDesc = $this->jsonConvert($asCode['description']);
|
|
|
|
return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<meta http-equiv="content-type" content="text/html; charset='.Settings::TEXT_ENC.'" />
|
|
<meta name="author" content="'.$asUser['name'].' ('.$asUser['company'].')" />
|
|
<link rel="shortcut icon" href="images/favicon_gc3.ico" />
|
|
<title>Databap •</title>
|
|
</head>
|
|
<body>
|
|
<pre id="content"></pre>
|
|
<script>
|
|
document.getElementById("content").textContent = '.$sEncodedCode.';
|
|
document.title = document.title+" "+'.$sEncodedDesc.';
|
|
</script>
|
|
</body>
|
|
</html>';
|
|
}
|
|
|
|
public function getSavedCode($oCode)
|
|
{
|
|
$asCode = $this->getCodeInfo($oCode, '', true);
|
|
$sPhrase = $this->getPhraseFromIdCode($asCode['id_code']);
|
|
if(!$sPhrase)
|
|
{
|
|
$sPhrase = 'code_numero_'.$asCode['id_code'];
|
|
}
|
|
|
|
//set headers
|
|
header('Pragma: public');
|
|
header('Expires: 0');
|
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
|
header('Cache-Control: public');
|
|
header('Content-Description: File Transfer');
|
|
header('Content-Type: application/force-download');
|
|
header('Content-Disposition: attachment; filename='.$sPhrase.'.abap');
|
|
header('Content-Transfer-Encoding: binary');
|
|
//header('Content-Length: '.filesize($sFilePath));
|
|
|
|
return $asCode['code'];
|
|
}
|
|
|
|
public function getPrintCode($oCode)
|
|
{
|
|
return $this->getRawCode($oCode).'<script>window.print();</script>';
|
|
}
|
|
|
|
public function getItemList()
|
|
{
|
|
$sIdCodeCol = MySqlManager::getId(MySqlManager::CODE_TABLE);
|
|
$sIdProcCol = MySqlManager::getId(MySqlManager::PROC_TABLE);
|
|
$sIdArtCol = MySqlManager::getId(MySqlManager::ART_TABLE);
|
|
$sIdDocCol = MySqlManager::getId(MySqlManager::DOC_TABLE);
|
|
$sIdCodeColFull = MySqlManager::getId(MySqlManager::CODE_TABLE, true);
|
|
$sIdUserCol = MySqlManager::getId(MySqlManager::USER_TABLE);
|
|
$sIdUserColFull = MySqlManager::getId(MySqlManager::USER_TABLE, true);
|
|
$sLedColFull = MySqlManager::getFullColumnName(MySqlManager::CODE_TABLE, 'led') ;
|
|
|
|
//Get code Ids
|
|
$asInfo = array('select'=>array("MAX($sIdCodeCol) AS id_item"), //selecting last version among codes having the same refer_id
|
|
'from'=>MySqlManager::CODE_TABLE,
|
|
'groupBy'=>array('refer_id'),
|
|
'orderBy'=>array('id_item'=>'desc'));
|
|
$asItemIds[Databap::CODE_TYPE] = $this->oMySql->selectRows($asInfo);
|
|
|
|
//get Proc Ids
|
|
$asInfo = array('select'=>array("MAX($sIdProcCol) AS id_item"),
|
|
'from'=>MySqlManager::PROC_TABLE,
|
|
'constraint'=>array('refer_id'=>"0"), //meaning that there is no newer version
|
|
'orderBy'=>array('id_item'=>'desc'));
|
|
$asItemIds[Databap::PROC_TYPE] = $this->oMySql->selectRows($asInfo);
|
|
|
|
//get Article Ids
|
|
$asInfo = array('select'=>array($sIdArtCol." AS id_item"),
|
|
'from'=>MySqlManager::ART_TABLE,
|
|
'orderBy'=>array('id_item'=>'desc'));
|
|
$asItemIds[Databap::ART_TYPE] = $this->oMySql->selectRows($asInfo);
|
|
|
|
//Get documentation
|
|
$asInfo = array('select'=>array("MAX($sIdDocCol) AS id_item"), //selecting last version among docs having the same refer_id
|
|
'from'=>MySqlManager::DOC_TABLE,
|
|
'groupBy'=>array('refer_id'),
|
|
'orderBy'=>array('id_item'=>'desc'));
|
|
$asItemIds[Databap::DOC_TYPE] = $this->oMySql->selectRows($asInfo);
|
|
|
|
$asTypeFunc = array(Databap::CODE_TYPE=>'Code', Databap::PROC_TYPE=>'Proc', Databap::ART_TYPE=>'Article', Databap::DOC_TYPE=>'Doc');
|
|
|
|
//Build code info structure
|
|
//TODO phrases for all item types?
|
|
$asUsers = $asCode = $asItemList = array();
|
|
foreach($asItemIds as $sType=>$asTypedItemIds)
|
|
{
|
|
$asTypedItemIds = array_filter($asTypedItemIds); //null value returned from query (MAX(...))
|
|
foreach($asTypedItemIds as $iItemId)
|
|
{
|
|
$asItem = call_user_func(array($this, 'get'.$asTypeFunc[$sType].'Info'), $iItemId);
|
|
$asItem['type'] = $sType;
|
|
$asItem['id_item'] = $iItemId;
|
|
if(array_key_exists($sIdUserCol, $asItem)) //replacing user's id with user's name & company (if not done already)
|
|
{
|
|
$iUserId = $asItem[$sIdUserCol];
|
|
if(!array_key_exists($iUserId, $asUsers)) $asUsers[$iUserId] = $this->getUserInfo($iUserId);
|
|
$asItem['name'] = $asUsers[$iUserId]['name'];
|
|
$asItem['company'] = $asUsers[$iUserId]['company'];
|
|
}
|
|
$asItemList[$asItem['timestamp'].$asItem['type'].$asItem['id_item']] = $asItem;
|
|
}
|
|
}
|
|
krsort($asItemList);
|
|
return $this->jsonExport($asItemList);
|
|
}
|
|
|
|
public function getCodeBlock()
|
|
{
|
|
$oMask = new Mask();
|
|
$oMask->initFile('code_block');
|
|
return $oMask->getMask();
|
|
}
|
|
|
|
public static function checkNoPassResetAction($sAction)
|
|
{
|
|
return in_array($sAction, array('messages', 'upload_image', 'user_info', 'rss'));
|
|
}
|
|
|
|
public function logMeIn($sName, $sCompany, $sToken, $sAction)
|
|
{
|
|
$iUserId = 0;
|
|
$bResetPass = true;
|
|
$sUserTableId = MySqlManager::getId(MySqlManager::USER_TABLE);
|
|
$sCompanyTableId = MySqlManager::getId(MySqlManager::COMP_TABLE);
|
|
$sCompanyTableText = MySqlManager::getText(MySqlManager::COMP_TABLE);
|
|
|
|
//login using form
|
|
if($sName!='' && $sCompany!='')
|
|
{
|
|
$asNames = explode(' ', mb_strtolower($sName));
|
|
$sCompany = mb_strtolower($sCompany);
|
|
|
|
//Get Company's Id
|
|
$iCompanyId = $this->oMySql->selectValue(MySqlManager::COMP_TABLE, $sCompanyTableId, array($sCompanyTableText=>$sCompany));
|
|
|
|
$asConsts = array('first_name'=>$asNames[0], 'last_name'=>$asNames[1], $sCompanyTableId=>$iCompanyId);
|
|
$iUserId = $this->oMySql->selectValue(MySqlManager::USER_TABLE, $sUserTableId, $asConsts);
|
|
if(!$iUserId)
|
|
{
|
|
$asInvConsts = array('first_name'=>$asNames[1], 'last_name'=>$asNames[0], $sCompanyTableId=>$iCompanyId);
|
|
$iUserId = $this->oMySql->selectValue(MySqlManager::USER_TABLE, $sUserTableId, $asInvConsts);
|
|
}
|
|
}
|
|
//auto login by cookie
|
|
elseif(isset($_COOKIE[self::USER_COOKIE_ID]))
|
|
{
|
|
$asConstraints = array( $sUserTableId=>$_COOKIE[self::USER_COOKIE_ID],
|
|
'pass'=>$_COOKIE[self::USER_COOKIE_PASS]);
|
|
|
|
$asUserInfo = $this->oMySql->selectRow(MySqlManager::USER_TABLE, $asConstraints, array($sUserTableId, 'led'));
|
|
$iUserId = $asUserInfo[$sUserTableId];
|
|
|
|
//Check pass reset necessity
|
|
$bResetPass = (mb_substr($asUserInfo['led'], 0, 10) != date(Databap::DATE_SQL_FORMAT));
|
|
}
|
|
//Login using Token (limited access)
|
|
elseif($sAction==self::EXT_ACCESS && $sToken!='')
|
|
{
|
|
$iUserId = $this->checkToken($sToken);
|
|
$bResetPass = false;
|
|
}
|
|
|
|
if($iUserId>0)
|
|
{
|
|
$this->setUserId($iUserId);
|
|
if(!self::checkNoPassResetAction($sAction) && $bResetPass)
|
|
{
|
|
$this->resetPassword();
|
|
}
|
|
}
|
|
|
|
return ($this->getUserId()>0);
|
|
}
|
|
|
|
public function checkToken($sKey)
|
|
{
|
|
$iUserId = mb_strstr($sKey, '_', true);
|
|
$sToken = mb_substr($sKey, mb_strlen($iUserId)+1);
|
|
return (mb_strlen($sToken)==self::TOKEN_LENGTH && $this->generateToken($iUserId)==$sToken && $this->checkValue(MySqlManager::USER_TABLE, $iUserId))?$iUserId:0;
|
|
}
|
|
|
|
public function resetNecessary($iUserId)
|
|
{
|
|
$sLed = mb_substr($this->oMySql->selectValue(MySqlManager::USER_TABLE, 'led', $iUserId), 0, 10);
|
|
return $sLed != date(Databap::DATE_SQL_FORMAT);
|
|
}
|
|
|
|
public function resetPassword()
|
|
{
|
|
$iUserId = $this->getUserId();
|
|
$sNewPass = self::getCookiePass();
|
|
$iTimeLimit = time()+60*60*24*self::COOKIE_LIFETIME;
|
|
$this->oMySql->updateRow(MySqlManager::USER_TABLE, $iUserId, array('pass'=>$sNewPass));
|
|
setcookie(self::USER_COOKIE_ID, $iUserId, $iTimeLimit);
|
|
setcookie(self::USER_COOKIE_PASS, $sNewPass, $iTimeLimit);
|
|
}
|
|
|
|
public function logMeOut()
|
|
{
|
|
$this->disconnectChat();
|
|
$this->setUserId(0);
|
|
setcookie(self::USER_COOKIE_ID, '', time()-60*60);
|
|
setcookie(self::USER_COOKIE_PASS, '', time()-60*60);
|
|
}
|
|
|
|
/* Not needed so far
|
|
public function setExpectedPage($sExpectedPage)
|
|
{
|
|
setcookie(self::EXPECTED_PAGE_COOKIE, $sExpectedPage, time()+60*60);
|
|
}
|
|
|
|
public function redirectExpectedPage()
|
|
{
|
|
if(array_key_exists(self::EXPECTED_PAGE_COOKIE, $_COOKIE))
|
|
{
|
|
$sLocation = $_COOKIE[self::EXPECTED_PAGE_COOKIE];
|
|
setcookie(self::EXPECTED_PAGE_COOKIE, '', time()-60*60);
|
|
header('Location:'.$sLocation);
|
|
}
|
|
}
|
|
*/
|
|
|
|
public function redirectArticle($iArtId)
|
|
{
|
|
$asArtInfo = $this->getArticleInfo($iArtId);
|
|
header('Location:'.$asArtInfo['link_art']);
|
|
}
|
|
|
|
public function disconnectChat()
|
|
{
|
|
$sTime = $this->oMySql->selectRows(array('select'=>'DATE_SUB(NOW(), INTERVAL '.self::KEEP_ALIVE.' SECOND)'));
|
|
|
|
//Is the user connected?
|
|
$sUserIdColName = MySqlManager::getId(MySqlManager::USER_TABLE);
|
|
$bConnected = $this->oMySql->selectRows(array('select'=>array('COUNT(1)'), 'from'=>MySqlManager::CONN_TABLE, 'constraint'=>array($sUserIdColName=>$this->getUserId(), 'led'=>$sTime), 'constOpe'=>array($sUserIdColName=>'=', 'led'=>'>')));
|
|
if($bConnected)
|
|
{
|
|
$this->oMySql->updateRows(MySqlManager::CONN_TABLE, array(MySqlManager::getId(MySqlManager::USER_TABLE)=>$this->getUserId()), array('led'=>$sTime));
|
|
$this->addMessage('se déconnecte', self::MESSAGE_CONN, self::ALL_CHAN_ID);
|
|
}
|
|
}
|
|
|
|
public function checkValue($sTableName, $asConstraints)
|
|
{
|
|
return $this->oMySql->selectValue($sTableName, 'COUNT(1)', $asConstraints);
|
|
}
|
|
|
|
private static function getCookiePass()
|
|
{
|
|
return self::encryptPassword( $_SERVER['HTTP_USER_AGENT'].
|
|
$_SERVER['REMOTE_ADDR'].
|
|
$_SERVER['REQUEST_TIME'].
|
|
mb_strstr(microtime(), ' ', true).
|
|
$_SERVER['SERVER_SIGNATURE'].
|
|
$_SERVER['SERVER_ADMIN']);
|
|
}
|
|
|
|
private 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 < mb_strlen($sPass); $iIndex++)
|
|
{
|
|
$sPass[$iIndex] = $sRandomText[$iIndex%mb_strlen($sRandomText)] ^ $sPass[$iIndex];
|
|
}
|
|
return md5($sPass);
|
|
}
|
|
|
|
public static function getChanSafeName($sChanName)
|
|
{
|
|
$sChanSafeName = preg_replace('/[^a-z0-9]/', '_', mb_strtolower($sChanName));
|
|
|
|
//Sort PM chans
|
|
$asPm = self::isPmChan($sChanSafeName);
|
|
if(!$asPm['is_pm']) $sChanSafeName = $asPm['chan_name'];
|
|
|
|
return $sChanSafeName;
|
|
}
|
|
|
|
public function getResults($sSearchWords)
|
|
{
|
|
$this->oSearchEngine->setWords($sSearchWords);
|
|
$asResults = $this->oSearchEngine->getResults();
|
|
|
|
//complementary infos
|
|
$asCompleteResults = array();
|
|
foreach($asResults as $iCodeId=>$asCodeInfo)
|
|
{
|
|
//phrase
|
|
$sPhrase = $this->getPhraseFromIdCode($asCodeInfo['id_code']);
|
|
if($sPhrase !== false)
|
|
{
|
|
$asCodeInfo['phrase'] = $sPhrase;
|
|
}
|
|
$asCompleteResults[$iCodeId] = $asCodeInfo;
|
|
}
|
|
|
|
return $this->jsonExport($asCompleteResults);
|
|
}
|
|
|
|
public function getStyleSheet()
|
|
{
|
|
$sStyle = file_get_contents(self::STYLE_PATH);
|
|
$asDefaultColors = array( self::OPT_BG=>'#04357B',
|
|
self::OPT_BRIGHT_BG=>'#D9E5F2',
|
|
self::OPT_HOVER=>'#EFAB00',
|
|
self::OPT_IMAGE_CHAT=>'images/sap_gold_332.jpg');
|
|
|
|
//Inserting Color Ids
|
|
foreach($asDefaultColors as $iOptionNameId=>$sDefaultColor)
|
|
{
|
|
$asColorAnchors[$iOptionNameId] = '[OPT#'.$iOptionNameId.']';
|
|
}
|
|
$sStyle = str_replace($asDefaultColors, $asColorAnchors, $sStyle);
|
|
|
|
//Switching color Ids with user colors
|
|
$asOptionvalues = $this->getUserOptions(array_keys($asDefaultColors));
|
|
foreach($asColorAnchors as $iOptionNameId=>$sColorAnchor)
|
|
{
|
|
$sOptionValue = (array_key_exists($iOptionNameId, $asOptionvalues) && $asOptionvalues[$iOptionNameId]['option']!='')?$asOptionvalues[$iOptionNameId]['option']:$asDefaultColors[$iOptionNameId];
|
|
$sStyle = str_replace($sColorAnchor, $sOptionValue, $sStyle);
|
|
}
|
|
|
|
//setting header content type
|
|
header("Content-Type: text/css");
|
|
return $sStyle;
|
|
}
|
|
|
|
public static function getDateFormat($oTime, $sFormat=Databap::DATE_TIME_FORMAT)
|
|
{
|
|
$iTimeStamp = is_numeric($oTime)?$oTime:strtotime($oTime);
|
|
return date($sFormat, $iTimeStamp);
|
|
}
|
|
|
|
public static function getNameFormat($sFirstName, $sLastName)
|
|
{
|
|
return ToolBox::capitalizeWords(trim($sFirstName.' '.$sLastName), ' -');;
|
|
}
|
|
|
|
public static function getNickNameFormat($sNickName)
|
|
{
|
|
$sNickName = ToolBox::capitalizeWords(trim($sNickName), ' -');
|
|
return str_replace(' ', '_', $sNickName);
|
|
}
|
|
|
|
public static function getCompanyFormat($sCompany)
|
|
{
|
|
return ToolBox::mb_ucwords($sCompany);
|
|
}
|
|
|
|
public static function getDescriptionFormat($sDescription)
|
|
{
|
|
return ucfirst($sDescription);
|
|
}
|
|
|
|
public static function jsonExport($asData)
|
|
{
|
|
header('Content-type: application/json');
|
|
return self::jsonConvert($asData);
|
|
}
|
|
|
|
public static function jsonConvert($asData)
|
|
{
|
|
//return htmlspecialchars(json_encode($asData), ENT_NOQUOTES);
|
|
return json_encode($asData);
|
|
}
|
|
|
|
public static function getMaxSize()
|
|
{
|
|
$iPostSize = self::toBytes(ini_get('post_max_size'));
|
|
$iUploadSize = self::toBytes(ini_get('upload_max_filesize'));
|
|
|
|
return min($iPostSize, $iUploadSize);
|
|
}
|
|
|
|
public static function toBytes($str)
|
|
{
|
|
$val = trim($str);
|
|
$last = mb_strtolower($str[mb_strlen($str)-1]);
|
|
switch($last) {
|
|
case 'g': $val *= 1024;
|
|
case 'm': $val *= 1024;
|
|
case 'k': $val *= 1024;
|
|
}
|
|
return $val;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* TODO
|
|
* Code Manager
|
|
* @author franzz
|
|
*/
|
|
class Code extends PhpObject
|
|
{
|
|
//Objects
|
|
private $oMySql;
|
|
|
|
//Database tables and columns
|
|
private $sProcTable;
|
|
|
|
|
|
function __construct($oMySql)
|
|
{
|
|
parent::__construct();
|
|
$this->oMySql = $oMySql;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Procedure Manager
|
|
* @author franzz
|
|
*/
|
|
class Procedure extends PhpObject
|
|
{
|
|
//Constants
|
|
const THUMB_MAX_SIZE = 100;
|
|
const IMAGE_FOLDER = 'screenshot/';
|
|
const IMAGE_FOLDER_TMP = 'screenshot/tmp/';
|
|
const IMAGE_FOLDER_THUMB = 'screenshot/thumbnails/';
|
|
|
|
//Objects
|
|
private $oMySql;
|
|
|
|
//Procedure Elements
|
|
private $iProcId;
|
|
private $iUserId;
|
|
private $sTitle;
|
|
private $sDescription;
|
|
private $dLed;
|
|
private $asSteps; // [id_step]=>text
|
|
private $asImages; // [id_step][id_image]=>array('name'=>file name, 'desc'=> description)
|
|
|
|
function __construct($oMySql)
|
|
{
|
|
parent::__construct();
|
|
$this->oMySql = $oMySql;
|
|
$this->iPrevProcId = 0;
|
|
$this->setProcedureId(0);
|
|
$this->sTitle = '';
|
|
$this->sDescription = '';
|
|
$this->dLed = '';
|
|
$this->asSteps = array();
|
|
$this->asImages = array();
|
|
}
|
|
|
|
public function getProcedureId()
|
|
{
|
|
return $this->iProcId;
|
|
}
|
|
|
|
public function getProcedureLed()
|
|
{
|
|
return $this->dLed;
|
|
}
|
|
|
|
public function setProcedureId($iProcId)
|
|
{
|
|
$this->iProcId = $iProcId;
|
|
}
|
|
|
|
public function inputForm($asPost)
|
|
{
|
|
//User
|
|
$this->iUserId = $asPost['id_user'];
|
|
|
|
//Titles
|
|
$this->sTitle = isset($asPost['title'])?$asPost['title']:'';
|
|
$this->sDescription = isset($asPost['description'])?$asPost['description']:'';
|
|
|
|
//Steps
|
|
$sStepPattern = '/c(?P<step_id>\d+)_step_text/';
|
|
$sImagePattern = '/c(?P<step_id>\d+)_(?P<image_id>\d+)_image_(?P<image_info>\w+)/';
|
|
foreach($asPost as $sFormId=>$sValue)
|
|
{
|
|
//Step Text
|
|
preg_match($sStepPattern, $sFormId, $asMatches);
|
|
if(isset($asMatches['step_id']))
|
|
{
|
|
$this->asSteps[$asMatches['step_id']] = $sValue;
|
|
}
|
|
else
|
|
{
|
|
preg_match($sImagePattern, $sFormId, $asMatches);
|
|
if
|
|
(
|
|
isset($asMatches['step_id'], $asMatches['image_id'], $asMatches['image_info']) &&
|
|
($asMatches['image_info'] == 'name' || $asMatches['image_info']== 'desc')
|
|
)
|
|
{
|
|
$this->asImages[$asMatches['step_id']][$asMatches['image_id']][$asMatches['image_info']] = $sValue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private function isImageSaved($sFileName, $bInTemp=false)
|
|
{
|
|
$sPath = $bInTemp?self::IMAGE_FOLDER_TMP:self::IMAGE_FOLDER;
|
|
return file_exists($sPath.$sFileName);
|
|
}
|
|
|
|
public function checkIntegrity()
|
|
{
|
|
$asErrors = array();
|
|
|
|
//Check title
|
|
if($this->sTitle=='') $asErrors['title'] = 'Un titre est nécessaire';
|
|
|
|
//Check steps
|
|
if(count($this->asSteps)==0)
|
|
{
|
|
$asErrors['step'] = 'Au moins une étape est nécessaire';
|
|
}
|
|
else
|
|
{
|
|
foreach($this->asSteps as $iStepId=>$sText)
|
|
{
|
|
if($sText=='')
|
|
{
|
|
$asErrors['step_'.$iStepId] = 'Une étape ne possède pas de texte';
|
|
}
|
|
}
|
|
}
|
|
|
|
//Check images
|
|
foreach($this->asImages as $iStepId=>$asImages)
|
|
{
|
|
foreach($asImages as $iImageId=>$asFileInfo)
|
|
{
|
|
//file exists in temp or already stored
|
|
if(!$this->isImageSaved($asFileInfo['name']) && !$this->isImageSaved($asFileInfo['name'], true))
|
|
{
|
|
$asErrors['image_'.$iStepId.'_'.$iImageId] = 'Une image n\'a pas été téléchargée';
|
|
}
|
|
if($asFileInfo['desc']=='')
|
|
{
|
|
$asErrors['image_'.$iStepId.'_'.$iImageId] = 'Une image n\'a pas de nom (description)';
|
|
}
|
|
}
|
|
}
|
|
return $asErrors;
|
|
}
|
|
|
|
public function saveProcedure($iPrevProcId)
|
|
{
|
|
//Add new procedure
|
|
$asData = array('title'=>$this->sTitle, 'description'=>$this->sDescription, MySqlManager::getId(MySqlManager::USER_TABLE)=>$this->iUserId);
|
|
$iDbProcId = $this->oMySql->insertRow(MySqlManager::PROC_TABLE, $asData);
|
|
|
|
//Add new steps
|
|
$asStepData = $asImgData = array(MySqlManager::getId(MySqlManager::PROC_TABLE)=>$iDbProcId);
|
|
foreach($this->asSteps as $iStepId=>$sStepDesc)
|
|
{
|
|
$asStepData['description'] = $sStepDesc;
|
|
$iDbStepId = $this->oMySql->insertRow(MySqlManager::STEP_TABLE, $asStepData);
|
|
|
|
//Add new images
|
|
$asImgData[MySqlManager::getId(MySqlManager::STEP_TABLE)] = $iDbStepId;
|
|
foreach($this->asImages[$iStepId] as $asImageInfo)
|
|
{
|
|
$asImgData['description'] = $asImageInfo['desc'];
|
|
$asImgData['file_name'] = $asImageInfo['name'];
|
|
$iDbImageId = $this->oMySql->insertRow(MySqlManager::IMG_TABLE, $asImgData);
|
|
$this->saveImage($asImgData['file_name']);
|
|
}
|
|
}
|
|
|
|
//Add this procedure to the group
|
|
$bCreation = ($iPrevProcId==0);
|
|
//$this->oMySql->deleteRow(MySqlManager::PROC_TABLE, $this->iPrevProcId);
|
|
//$this->oMySql->updateRow(MySqlManager::PROC_TABLE, $iPrevProcId, array('refer_id'=>$iDbProcId));
|
|
$iReferId = $bCreation?$iDbProcId:$this->oMySql->selectValue(MySqlManager::PROC_TABLE, 'refer_id', $iPrevProcId);
|
|
$this->oMySql->updateRow(MySqlManager::PROC_TABLE, $iDbProcId, array('refer_id'=>$iReferId));
|
|
|
|
//Update new Procedure Id
|
|
//$this->setProcedureId($iDbProcId);
|
|
|
|
//Reload Procedure
|
|
$this->loadProcedure($iDbProcId);
|
|
|
|
//return creation or edition
|
|
return $bCreation;
|
|
}
|
|
|
|
private function saveImage($sFileName)
|
|
{
|
|
if(!$this->isImageSaved($sFileName))
|
|
{
|
|
$sTempFilePath = self::IMAGE_FOLDER_TMP.$sFileName;
|
|
$sFilePath = self::IMAGE_FOLDER.$sFileName;
|
|
|
|
//Real Size Image
|
|
if(!rename($sTempFilePath, $sFilePath))
|
|
{
|
|
$this->addError('Unmoveable file : '.$sTempFilePath);
|
|
}
|
|
|
|
//Thumbnail picture
|
|
$asResult = ToolBox::createThumbnail($sFilePath, self::THUMB_MAX_SIZE, self::THUMB_MAX_SIZE, self::IMAGE_FOLDER_THUMB);
|
|
if($asResult['error']!='') $this->addError('Unable to create thumbnail : '.$asResult['out']. '('.$asResult['error'].')');
|
|
}
|
|
}
|
|
|
|
public function loadProcedure($iProcId)
|
|
{
|
|
//Column names
|
|
$sProcIdCol = MySqlManager::getId(MySqlManager::PROC_TABLE);
|
|
$sStepIdCol = MySqlManager::getId(MySqlManager::STEP_TABLE);
|
|
$sImageIdCol = MySqlManager::getId(MySqlManager::IMG_TABLE);
|
|
|
|
//Get last id available
|
|
$this->setProcedureId($iProcId);
|
|
$this->refreshProcId();
|
|
$asInfo = array('from'=>MySqlManager::PROC_TABLE, 'constraint'=>array($sProcIdCol=>$this->getProcedureId()));
|
|
|
|
//Load procedure info
|
|
$asResult = $this->oMySql->selectRow(MySqlManager::PROC_TABLE, $asInfo['constraint']);
|
|
$this->sTitle = $asResult['title'];
|
|
$this->sDescription = $asResult['description'];
|
|
$this->iUserId = $asResult[MySqlManager::getId(MySqlManager::USER_TABLE)];
|
|
$this->dLed = $asResult['led'];
|
|
|
|
//Load steps info
|
|
$asInfo['from'] = MySqlManager::STEP_TABLE;
|
|
$this->asSteps = $this->oMySql->selectRows($asInfo, true, $sStepIdCol);
|
|
|
|
//Load images info
|
|
$asInfo['from'] = MySqlManager::IMG_TABLE;
|
|
foreach($this->oMySql->selectRows($asInfo) as $asRow)
|
|
{
|
|
$this->asImages[$asRow[$sStepIdCol]][$asRow[$sImageIdCol]]['name'] = $asRow['file_name'];
|
|
$this->asImages[$asRow[$sStepIdCol]][$asRow[$sImageIdCol]]['desc'] = $asRow['description'];
|
|
}
|
|
}
|
|
|
|
public function getProcedure()
|
|
{
|
|
// [id_step]=>text
|
|
// [id_step][id_image]=>array('name'=>file name, 'desc'=> description)
|
|
/*
|
|
$asSteps = $asImages = array();
|
|
$iLocalStepId = 1;
|
|
foreach($this->asSteps as $iStepId=>$sStepDesc)
|
|
{
|
|
$asSteps[$iLocalStepId] = $sStepDesc;
|
|
if(array_key_exists($iStepId, $this->asImages))
|
|
{
|
|
$asImages[] =
|
|
}
|
|
$iLocalStepId++;
|
|
}*/
|
|
return array( 'proc_id'=>$this->iProcId,
|
|
'id_user'=>$this->iUserId,
|
|
'title'=>Databap::getDescriptionFormat($this->sTitle),
|
|
'description'=>Databap::getDescriptionFormat($this->sDescription),
|
|
'led'=>Databap::getDateFormat($this->dLed),
|
|
'steps'=>$this->asSteps,
|
|
'images'=>$this->asImages);
|
|
}
|
|
|
|
private function refreshProcId()
|
|
{
|
|
/*
|
|
$iReferId = $this->getProcedureId();
|
|
do
|
|
{
|
|
$iProcId = $iReferId;
|
|
$iReferId = $this->oMySql->selectValue(MySqlManager::PROC_TABLE, 'refer_id', $iProcId);
|
|
}
|
|
while($iReferId!=0);
|
|
$this->setProcedureId($iProcId);
|
|
*/
|
|
$iReferId = $this->oMySql->selectValue(MySqlManager::PROC_TABLE, 'refer_id', $this->getProcedureId());
|
|
$sSelect = "MAX(".MySqlManager::getId(MySqlManager::PROC_TABLE).")";
|
|
$iProcId = $this->oMySql->selectValue(MySqlManager::PROC_TABLE, $sSelect, array('refer_id'=>$iReferId));
|
|
$this->setProcedureId($iProcId);
|
|
}
|
|
}
|
|
|
|
/* if feeling the need of creating a tables for code lines :
|
|
codes :
|
|
ALTER TABLE codes ADD line_low int(10) AFTER code;
|
|
ALTER TABLE codes ADD line_high int(10) AFTER line_low;
|
|
|
|
lines :
|
|
id_line
|
|
id_code
|
|
line
|
|
*/
|
|
|
|
/**
|
|
* Search Engine : Search through all types of databap documents
|
|
*
|
|
* Procedure to add a new type in the search
|
|
* - Add type in the index builder : SearchEngine->buildIndex()
|
|
* - Add type in the rebuild index function : Databap->buildCompleteIndex()
|
|
* - Add type in item info : SearchEngine->setItemInfo()
|
|
* - Add type in .htaccess
|
|
* - Add type in getItemList() and create a get<type>info()
|
|
* - consider the message types : add + edit in Databap->getMessages() and in chat.html
|
|
*/
|
|
class SearchEngine extends PhpObject
|
|
{
|
|
//Objects
|
|
private $oMySql;
|
|
|
|
//variables
|
|
private $asWords;
|
|
private $iLevelMax;
|
|
private $asItemRanks;
|
|
private $asItemInfos;
|
|
private $asUserInfos;
|
|
|
|
//Constants
|
|
const RESULT_A_PAGE = 20;
|
|
const KEYWORDS_SEPARATOR = ' ';
|
|
|
|
function __construct($oMySql)
|
|
{
|
|
parent::__construct();
|
|
$this->oMySql = $oMySql;
|
|
$this->asWords = $this->setWords('');
|
|
$this->asItemRanks = array();
|
|
$this->asItemInfos = array();
|
|
$this->asUserInfos = array();
|
|
}
|
|
|
|
public function buildIndex($iItemId, $sType)
|
|
{
|
|
//Build keywords
|
|
switch($sType)
|
|
{
|
|
case Databap::CODE_TYPE:
|
|
$asItemData = $this->oMySql->selectRow(MySqlManager::CODE_TABLE, $iItemId);
|
|
$asWords = array($asItemData[MySqlManager::getText(MySqlManager::CODE_TABLE)], $asItemData['description']);
|
|
break;
|
|
case Databap::PROC_TYPE:
|
|
$sItemIdCol = MySqlManager::getId(MySqlManager::PROC_TABLE);
|
|
$asItemData = $this->oMySql->selectRow(MySqlManager::PROC_TABLE, $iItemId);
|
|
$asItemStepsData = $this->oMySql->selectRows(array('select'=>'description', 'from'=>MySqlManager::STEP_TABLE, 'constraint'=>array($sItemIdCol=>$iItemId)));
|
|
$asWords = array('desc'=>$asItemData['description'], 'title'=>$asItemData['title']) + $asItemStepsData;
|
|
break;
|
|
case Databap::ART_TYPE:
|
|
$asItemData = $this->oMySql->selectRow(MySqlManager::ART_TABLE, $iItemId);
|
|
$asWords = array($asItemData['first_name'], $asItemData['last_name'], $asItemData['title']);
|
|
break;
|
|
case Databap::DOC_TYPE:
|
|
$sItemIdCol = MySqlManager::getId(MySqlManager::DOC_TABLE);
|
|
$asItemData = $this->oMySql->selectRow(MySqlManager::DOC_TABLE, $iItemId);
|
|
$asItemFilesData = $this->oMySql->selectRows(array('select'=>'description', 'from'=>MySqlManager::FILE_TABLE, 'constraint'=>array($sItemIdCol=>$iItemId)));
|
|
$asWords = array('desc'=>$asItemData['description'], 'title'=>$asItemData['title']) + $asItemFilesData;
|
|
break;
|
|
default:
|
|
$this->addError('function '.__FUNCTION__.'(): Incorrect type "'.$sType.'"');
|
|
break;
|
|
}
|
|
$sWords = implode(self::KEYWORDS_SEPARATOR, $asWords);
|
|
$sWords = mb_strtolower(str_replace("\n", self::KEYWORDS_SEPARATOR, $sWords));
|
|
//TODO Fix char encoding
|
|
$sWords = preg_replace('/(\W+)/', self::KEYWORDS_SEPARATOR, $sWords); //remove all non-word characters
|
|
|
|
//Add / Modify search database
|
|
$asData = array('id_item'=>$iItemId, 'type'=>$sType, 'refer_id'=>$asItemData['refer_id'], 'keywords'=>$sWords);
|
|
$this->oMySql->insertUpdateRow(MySqlManager::SEARCH_TABLE, $asData, array('id_item', 'type'));
|
|
}
|
|
|
|
public function setWords($sSearchWords)
|
|
{
|
|
$this->asWords = $this->getParsedWords($sSearchWords);
|
|
$this->iLevelMax = count($this->asWords);
|
|
$this->setResults();
|
|
}
|
|
|
|
/**
|
|
* TODO Customized item preview
|
|
$sCodeLines = implode("\n...\n", $this->getCodeInfo($iItemId, 'code'));
|
|
$oCode = new Reader($sCodeLines);
|
|
$sCodeLines = $oCode->getColoredCode();
|
|
*/
|
|
private function setItemInfo($iSearchId, $iItemType, $iItemId)
|
|
{
|
|
if(!array_key_exists($iSearchId, $this->asItemInfos))
|
|
{
|
|
$this->asItemInfos[$iSearchId] = array('type'=>$iItemType, 'id_item'=>$iItemId);
|
|
switch($iItemType)
|
|
{
|
|
case Databap::CODE_TYPE:
|
|
$sItemTable = MySqlManager::CODE_TABLE;
|
|
$asItemFields = array(MySqlManager::getId(MySqlManager::USER_TABLE), 'description', 'led');
|
|
break;
|
|
case Databap::PROC_TYPE:
|
|
$sItemTable = MySqlManager::PROC_TABLE;
|
|
$asItemFields = array(MySqlManager::getId(MySqlManager::USER_TABLE), 'title AS description', 'led');
|
|
break;
|
|
case Databap::ART_TYPE:
|
|
$sItemTable = MySqlManager::ART_TABLE;
|
|
$asItemFields = array('first_name', 'last_name', 'title AS description', 'led');
|
|
break;
|
|
case Databap::DOC_TYPE:
|
|
$sItemTable = MySqlManager::DOC_TABLE;
|
|
$asItemFields = array(MySqlManager::getId(MySqlManager::USER_TABLE), 'title AS description', 'led');
|
|
break;
|
|
}
|
|
$this->asItemInfos[$iSearchId] += $this->oMySql->selectRow($sItemTable, $iItemId, $asItemFields);
|
|
}
|
|
}
|
|
|
|
private function getItemInfo($iSearchId, $sInfoName)
|
|
{
|
|
if(array_key_exists($iSearchId, $this->asItemInfos) && array_key_exists($sInfoName, $this->asItemInfos[$iSearchId]))
|
|
return $this->asItemInfos[$iSearchId][$sInfoName];
|
|
else return false;
|
|
}
|
|
|
|
private function setUserInfo($iUserId)
|
|
{
|
|
if(!array_key_exists($iUserId, $this->asUserInfos) && $iUserId > 0)
|
|
{
|
|
$sCompanyIdCol = MySqlManager::getId(MySqlManager::COMP_TABLE);
|
|
$this->asUserInfos[$iUserId] = $this->oMySql->selectRow
|
|
(
|
|
MySqlManager::USER_TABLE,
|
|
$iUserId,
|
|
array('first_name', 'last_name', $sCompanyIdCol)
|
|
);
|
|
|
|
$this->asUserInfos[$iUserId]['company'] = $this->oMySql->selectValue(MySqlManager::COMP_TABLE, MySqlManager::getText(MySqlManager::COMP_TABLE), $this->asUserInfos[$iUserId][$sCompanyIdCol]);
|
|
unset($this->asUserInfos[$iUserId][$sCompanyIdCol]);
|
|
}
|
|
}
|
|
|
|
private function getUserInfo($iUserId, $sInfoName)
|
|
{
|
|
if(array_key_exists($iUserId, $this->asUserInfos) && array_key_exists($sInfoName, $this->asUserInfos[$iUserId]))
|
|
return $this->asUserInfos[$iUserId][$sInfoName];
|
|
else return false;
|
|
}
|
|
|
|
private function setResults()
|
|
{
|
|
if($this->iLevelMax > 0)
|
|
{
|
|
//set Results and Ranking
|
|
$aiLevels = range(1, $this->iLevelMax);
|
|
arsort($aiLevels);
|
|
foreach($aiLevels as $iLevel)
|
|
{
|
|
//all possibilies at level $iLevel
|
|
$iIndex = 0;
|
|
while(($iIndex + $iLevel) <= $this->iLevelMax)
|
|
{
|
|
//building query
|
|
$asSequence = array_slice($this->asWords, $iIndex, $iLevel);
|
|
$this->oMySql->cleanSql($asSequence);
|
|
|
|
//$sRegExp = implode('(.{0,2})', $asSequence);
|
|
$sRegExp = implode(self::KEYWORDS_SEPARATOR.'?', $asSequence);
|
|
$sSequence = implode(self::KEYWORDS_SEPARATOR, $asSequence);
|
|
|
|
//TODO replace with selectRow()
|
|
$sQuery = "SELECT id_search, id_item, type, keywords FROM searchs WHERE keywords REGEXP '{$sRegExp}'";
|
|
|
|
//search sequence
|
|
$asItems = $this->oMySql->getArrayQuery($sQuery, true);
|
|
foreach($asItems as $asItem)
|
|
{
|
|
$iSearchId = $asItem['id_search'];
|
|
$iItemId = $asItem['id_item'];;
|
|
$iItemType = $asItem['type'];
|
|
$sWords = $asItem['keywords'];
|
|
|
|
//Calculte bonus points
|
|
$sWords = str_replace(self::KEYWORDS_SEPARATOR.$sSequence.self::KEYWORDS_SEPARATOR, self::KEYWORDS_SEPARATOR, self::KEYWORDS_SEPARATOR.$sWords.self::KEYWORDS_SEPARATOR, $iSeqCount);
|
|
$sWords = str_replace(self::KEYWORDS_SEPARATOR.$sSequence, self::KEYWORDS_SEPARATOR, self::KEYWORDS_SEPARATOR.$sWords.self::KEYWORDS_SEPARATOR, $iStaCount);
|
|
$sWords = str_replace($sSequence.self::KEYWORDS_SEPARATOR, self::KEYWORDS_SEPARATOR, self::KEYWORDS_SEPARATOR.$sWords.self::KEYWORDS_SEPARATOR, $iEndCount);
|
|
$iBonus = $iSeqCount*5 + $iStaCount*2 + $iEndCount;
|
|
|
|
$this->incItemRank($iSearchId, $iLevel*10+$iBonus);
|
|
$this->setItemInfo($iSearchId, $iItemType, $iItemId);
|
|
$this->setUserInfo($this->getItemInfo($iSearchId, MySqlManager::getId(MySqlManager::USER_TABLE)));
|
|
}
|
|
$iIndex++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public function getResults()
|
|
{
|
|
$asResult = array();
|
|
|
|
//Mixing info
|
|
arsort($this->asItemRanks);
|
|
foreach($this->asItemRanks as $iSearchId=>$iRank)
|
|
{
|
|
$iUserId = $this->getItemInfo($iSearchId, MySqlManager::getId(MySqlManager::USER_TABLE));
|
|
$sFirstName = $this->getUserInfo($iUserId, 'first_name')?$this->getUserInfo($iUserId, 'first_name'):$this->getItemInfo($iSearchId, 'first_name');
|
|
$sLastName = $this->getUserInfo($iUserId, 'last_name')?$this->getUserInfo($iUserId, 'last_name'):$this->getItemInfo($iSearchId, 'last_name');
|
|
$sCompany = $this->getUserInfo($iUserId, 'company')?$this->getUserInfo($iUserId, 'company'):'SAP';
|
|
$asResult[] = array('id_item'=>$this->getItemInfo($iSearchId, 'id_item'),
|
|
'type'=>$this->getItemInfo($iSearchId, 'type'),
|
|
'description'=>/*'['.$iRank.'] '.*/$this->getItemInfo($iSearchId, 'description'),
|
|
'name'=>Databap::getNameFormat($sFirstName, $sLastName),
|
|
'company'=>Databap::getCompanyFormat($sCompany),
|
|
'led'=>Databap::getDateFormat($this->getItemInfo($iSearchId, 'led')));
|
|
}
|
|
return $asResult;
|
|
}
|
|
|
|
private function incItemRank($iSearchId, $iRank)
|
|
{
|
|
if(array_key_exists($iSearchId, $this->asItemRanks))
|
|
{
|
|
$this->asItemRanks[$iSearchId] += $iRank;
|
|
}
|
|
else
|
|
{
|
|
$this->asItemRanks[$iSearchId] = $iRank;
|
|
}
|
|
}
|
|
|
|
private function formatCode($sCode, $sPattern)
|
|
{
|
|
preg_match_all('/\n(.*)\n(.*)'.$sPattern.'(.*)\n(.*)\n/i', $sCode, $asMatches);
|
|
if(!array_key_exists(0, $asMatches) || !is_array($asMatches[0]) || count($asMatches[0])==0)
|
|
{
|
|
$asResult = array(implode("\n", array_slice(explode("\n", $sCode), 0, 3))."\n[...]");
|
|
}
|
|
else
|
|
{
|
|
$asResult = $asMatches[0];
|
|
}
|
|
return $asResult;
|
|
}
|
|
|
|
private function getParsedWords($sSearchWords)
|
|
{
|
|
return array_unique(array_filter(explode(' ', $sSearchWords), array($this, 'checkSearchedWords')));
|
|
}
|
|
|
|
private function checkSearchedWords($sWord)
|
|
{
|
|
return (mb_strlen($sWord) >= 2);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Abap Reader
|
|
* @author franzz
|
|
*/
|
|
class Reader
|
|
{
|
|
//objects
|
|
//private $oMask;
|
|
|
|
//general
|
|
private $sCode;
|
|
private $bImprovedColoring;
|
|
|
|
//Special Wors / Chars
|
|
private $asAbap;
|
|
|
|
//constants
|
|
const CASE_SENSITIVE = false;
|
|
const NOT_FOUND = '* Code introuvable...';
|
|
|
|
function __construct($sCode, $bImprovedColoring = false)
|
|
{
|
|
//settings
|
|
$this->bImprovedColoring = $bImprovedColoring;
|
|
|
|
//get code in db
|
|
$this->sCode = $sCode;
|
|
if($this->sCode=='')
|
|
{
|
|
$this->sCode = self::NOT_FOUND;
|
|
}
|
|
|
|
//ABAP key words and chars
|
|
$this->asAbap = array
|
|
(
|
|
'word'=>array
|
|
(
|
|
'wCore'=>array( /*'<icon>','<itab>',*/'ABBREVIATED','ABSTRACT','ABSTRACTFINAL','ACCEPT','ACCEPTING','ACCORDING','ACTUAL','ADD',
|
|
'ADD-CORRESPONDING','ADDITIONS','ADJACENT','ALIASES','ALL','ALLOCATE','ANALYZER', 'AND','APPEND','APPENDING','AS',
|
|
'ASCENDING','ASCENDINGDESCENDING','AT','ATTRIBUTE','AUTHORITY-CHECK','BACKGOUND','BEFORE','BEGIN','BETWEEN',
|
|
'BIGLITTLE','BINARY','BIT','BLANK','BLOCK','BREAK-POINT','BY','BYPASSING','BYTE','BYTECHARACTER','CASE',
|
|
'CASERESPECTING','CASTING','CENTERED','CHAIN','CHANGE','CHANGING','CHARACTER','CHECK','CHECKBOX',
|
|
'CHECKBOXSYMBOLICONLINE','CLASS','CLASS-DATA','CLASS-EVENTS','CLASS-METHODS','CLEANUP','CLEAR','CLIENT','CLOCK',
|
|
'CODE','COL_BACKGROUND','COL_HEADING','COL_NORMAL','COL_TOTAL','COLLECT','COLOR','COLUMN','COMMENT','COMMIT',
|
|
'COMMON','COMMUNICATION','COMPARING','COMPONENTS','COMPUTE','CONCATENATE','CONDENSE','CONSTANTS','CONTEXT',
|
|
'CONTEXTS','CONTINUE','CONTROL','CONTROLS','CONVERSION','CONVERT','COUNTRY','COUNTY','CURRENT','CURSOR',
|
|
'CUSTOMER-FUNCTION','DATA','DATABASE','DATASET','DATE','DEALLOCATE','DECIMALS','DEFAULT','DEFAULTUTF-8NON-UNICODE',
|
|
'DEFERRED','DEFINE','DEFINING','DEFINITION','DELETE','DELETING','DEMAND','DESCENDING','DESCRIBE','DESTINATION',
|
|
'DIALOG','DIRECTORY','DISTANCE','DISTINCT','DIVIDE-CORRESPONDING','DO','DUPLICATE','DUPLICATES','DURING','DYNAMIC',
|
|
'EDIT','EDITOR-CALL','ELSE','ELSEIF','ENCODING','END','ENDAT','ENDCASE','ENDCATCH','ENDCHAIN','ENDCLASS','ENDDO',
|
|
'ENDEXEC','ENDFORM','ENDFUNCTION','ENDIAN','ENDIF','ENDING','ENDINTERFACE','ENDLOOP','ENDMETHOD','ENDMODULE',
|
|
'ENDON','ENDPROVIDE','ENDSELECT','ENDTRY','ENDWHILE','END-OF_FILE','END-OF-DEFINITION','END-OF-PAGE',
|
|
'END-OF-SELECTION','ENTRIES','EQ','ERRORS','EVENT','EVENTS','EXCEPTION','EXCEPTIONS','EXCEPTION-TABLE','EXCLUDE',
|
|
'EXCLUDING','EXEC','EXIT','EXIT-COMMAND','EXPORT','EXPORTING','EXTENDED','EXTRACT','FETCH','FIELD','FIELD-GROUPS',
|
|
'FIELDSNO','FIELD-SYMBOLS','FILTER','FINAL','FIND','FIRST','FOR','FORM','FORMAT','FORWARDBACKWARD','FOUND','FRAME',
|
|
'FREE','FRIENDS','FROM','FUNCTION','FUNCTION-POOL','GE','GET','GIVING','GROUP','GT','HANDLER','HASHED','HAVING',
|
|
'HEADER','HEADING','HELP-ID','HIDE','HIGHLOW','HOLD','HOTSPOT','ID','IF','IGNORING','IMMEDIATELY','IMPLEMENTATION',
|
|
'IMPORT','IMPORTING','IN','INCREMENT','INDEX','INDEX-LINE','INHERITING','INIT','INITIAL','INITIALIZATION','INNER',
|
|
'INNERLEFT','INSERT','INSTANCES','INTENSIFIED','INTERFACE','INTERFACES','INTERVALS','INTO','INTOAPPENDING',
|
|
'INVERTED-DATE','IS','ITAB','JOIN','KEEPING','KEY','KEYS','KIND','LANGUAGE','LAST','LE','LEAVE','LEFT',
|
|
'LEFT-JUSTIFIED','LEFTRIGHT','LEFTRIGHTCIRCULAR','LEGACY','LENGTH','LIKE','LINE','LINE-COUNT','LINES','LINES',
|
|
'LINE-SELECTION','LINE-SIZE','LIST','LIST-PROCESSING','LOAD','LOAD-OF-PROGRAM','LOCAL','LOCALE','LOOP','LT',
|
|
'MARGIN','MARK','MASK','MATCH','MAXIMUM','MEMORY','MESSAGE','MESSAGE-ID','MESSAGES','METHOD','METHODS','MOD','MODE',
|
|
'MODEIN','MODIF','MODIFIER','MODIFY','MODULE','MOVE','MOVE-CORRESPONDING','MULTIPLY-CORRESPONDING','NE','NEW',
|
|
'NEW-LINE','NEW-PAGE','NEXT','NODES','NODETABLE','NO-DISPLAY','NO-EXTENSION','NO-GAP','NO-GAPS',
|
|
'NO-HEADINGWITH-HEADING','NON','NO-SCROLLING','NO-SCROLLINGSCROLLING','NOT','NO-TITLEWITH-TITLE','NO-ZERO','NUMBER',
|
|
'OBJECT','OBLIGATORY','OCCURENCE','OCCURENCES','OCCURS','OF','OFF','OFFSET','ON','ONLY','ONOFF','OPEN','OPTION',
|
|
'OPTIONAL','OR','ORDER','OTHERS','OUTPUT-LENGTH','OVERLAY','PACK','PACKAGE','PAGE','PAGELAST','PAGEOF','PAGEPAGE',
|
|
'PAGES','PARAMETER','PARAMETERS','PARAMETER-TABLE','PART','PERFORM','PERFORMING','PFN','PF-STATUS','PLACES',
|
|
'POS_HIGH','POS_LOW','POSITION','POSITIONS','PRIMARY','PRINT','PRINT-CONTROL','PRIVATE','PROCESS','PROGRAM',
|
|
'PROPERTY','PROTECTED','PROVIDE','PUBLIC','PUBLICPROTECTEDPRIVATE','PUSHBUTTON','PUT','QUICKINFO','RADIOBUTTON',
|
|
'RAISE','RAISING','RANGE','RANGES','READ','RECEIVE','RECEIVING','REDEFINITION','REFERENCE','REFRESH','REJECT',
|
|
'RENAMING','REPLACE','REPLACEMENT','REPORT','RESERVE','RESET','RESOLUTION','RESULTS','RETURN','RETURNING','RIGHT',
|
|
'RIGHT-JUSTIFIED','ROLLBACK','ROWS','RUN','SCAN','SCREEN','SCREEN-GROUP1','SCREEN-GROUP2','SCREEN-GROUP3',
|
|
'SCREEN-GROUP4','SCREEN-GROUP5','SCREEN-INPUT','SCREEN-INTENSIFIED','SCROLL','SCROLL-BOUNDARY','SEARCH','SECTION',
|
|
'SELECT','SELECTION','SELECTIONS','SELECTION-SCREEN','SELECTION-SET','SELECTION-TABLE','SELECT-OPTIONS','SEND',
|
|
'SEPARATED','SET','SHARED','SHIFT','SIGN','SINGLE','SINGLEDISTINCT','SIZE','SKIP','SORT','SORTABLE','SPACE',
|
|
'SPECIFIED','SPLIT','SQL','STABLE','STAMP','STANDARD','START','STARTING','START-OF-SELECTION','STATICS','STEP-LOOP',
|
|
'STOP','STRLEN','STRUCTURE','SUBMIT','SUBTRACT','SUBTRACT-CORRESPONDING','SUFFIX','SUPPLY','SUPPRESS','SYMBOLS',
|
|
'SYSTEM-EXCEPTIONS','TABLE','TABLES','TABLEVIEW','TASK','TEXT','THEN','TIME','TIMES','TITLE','TITLEBAR','TO',
|
|
'TOPIC','TOP-OF-PAGE','TRAILING','TRANSACTION','TRANSFER','TRANSLATE','TRY','TYPE','TYPELIKE','TYPE-POOL',
|
|
'TYPE-POOLS','TYPES','ULINE','UNION','UNIQUE','UNTIL','UP','UPDATE','UPPERLOWER','USER-COMMAND','USING','VALUE',
|
|
'VALUES','VARY','VARYING','VERSION','VIA','WAIT','WHEN','WHERE','WHILE','WINDOW','WITH','WORK','WRITE','ZONE','ADD',
|
|
'ADD-CORRESPONDING','APPEND','BREAK-POINT','CORRESPONDING','FIELDS','ASSIGN','AVG','BACK','CALL','CATCH','CHANGE',
|
|
'CHECK','CLEAR','CLOSE','COMMIT','COMPUTE','COUNT','CREATE','DATASET','DELETE','DESCRIBE','DIVIDE','DO','ELSE',
|
|
'ELSEIF','EXIT','FIND','FOR','FORMAT','GET','IF','INCLUDE','LOOP','MAX','MESSAGE','METHOD','MIN','MODIFY','MOVE',
|
|
'MULTIPLY','NEW-PAGE','OBJECT','OPEN','ORDER','READ','SORT','SUM','TRANSLATE','ULINE','WORK','WRITE','XSTRLEN',
|
|
'ABS','ACOS','AFTER','ALL','AND','AS','ASIN','ASSIGNING','AT','ATAN','BEGIN','BUFFER','BY','CA','CEIL','CENTERED',
|
|
'CN','CO','COLOR','COMPARING','COMPONENT','COS','COSH','CP','CS','DEFAULT','END','EQ','EXP','FLOOR','FRAC','GE',
|
|
'GROUP','GT','ICON','IN','INDEX','INNER','INTENSIFIED','INTO','IS','JOIN','LE','LEADING','LEAVE','LEFT','LIKE',
|
|
'LOG','LOG10','LOWER','LT','M','MOD','NA','NE','NOT','NP','NS','O','OF','OFF','ON','OR','OTHERS','OUTER','REF',
|
|
'RIGHT','SIGN','SIN','SINH','SQRT','TABLE','TABLENAME','TAN','TANH','TITLE','TO','TRAILING','TRUNC','TYPE','UPPER',
|
|
'USING','VALUE','WITH', 'TRANSPORTING', 'TYPE-POOLS'),
|
|
'wBwCore'=>array('SOURCE_PACKAGE', 'RESULT_PACKAGE', '<SOURCE_FIELDS>', '<RESULT_FIELDS>'),
|
|
'cOperator'=>array('(', ')', ',', '.', ':', '-', '~', '[', ']', '<', '>'),
|
|
'cCalculation'=>array('+', '-', '*', '/', '=', '(', ')'),
|
|
'cComment'=>array('*'),
|
|
'cPartComment'=>array('"'),
|
|
'cString'=>array('"', '''),
|
|
'iNumber'=>array('1', '2', '3', '4', '5', '6', '7', '8', '9', '0'),
|
|
'wExpand'=>array('loop'=>'endloop', 'if'=>'endif'),
|
|
'wGlobal'=>array('SY'),
|
|
'wCodePart'=>array('main', 'global', 'global2')
|
|
),
|
|
'color'=>array
|
|
(
|
|
'wCore'=>'core',
|
|
'wBwCore'=>'core',
|
|
'cOperator'=>'operator',
|
|
'cCalculation'=>'operator',
|
|
'cComment'=>'comment',
|
|
'cPartComment'=>'comment',
|
|
'cString'=>'string',
|
|
'iNumber'=>'number',
|
|
'wExpand'=>'expand',
|
|
'wGlobal'=>'glogal',
|
|
'wCodePart'=>'code_part'
|
|
)
|
|
);
|
|
}
|
|
|
|
private function getWords($sKey)
|
|
{
|
|
return $this->asAbap['word'][$sKey];
|
|
}
|
|
|
|
private function getColor($sKey)
|
|
{
|
|
return $this->asAbap['color'][$sKey];
|
|
}
|
|
|
|
private function addColoring()
|
|
{
|
|
//Safe characters
|
|
$sCode = $this->convText2Html($this->sCode);
|
|
$sServName = $_GET['serv_name'];
|
|
$sSafeRexExServName = preg_quote(str_replace('http://', '', $sServName), '/');
|
|
|
|
$asLines = explode("\n", $sCode);
|
|
$asLineClasses = array();
|
|
$iOffSet = 0;
|
|
|
|
//building lines
|
|
foreach($asLines as $iLineNb=>$sLine)
|
|
{
|
|
/* Code ref:
|
|
* <li id="#line_nb#" class="#li_class#">
|
|
* <span class="expand_line">
|
|
* <span id="#expand_id#" class="#expand_class#">-</span>
|
|
* </span>
|
|
* <span class="#code_class#">#line#</span>
|
|
* </li>
|
|
*/
|
|
$sLiClass = $sExpandSign = $sCodeClass = $sExpandHtml = $sExpandButton = '';
|
|
$sFirstWord = $this->getFirstWord($sLine);
|
|
$sFirstChar = $this->getFirstChar($sLine);
|
|
|
|
//Apply current classes
|
|
$sLiClass = implode(' ', $asLineClasses);
|
|
|
|
//Expanding starting/ending point
|
|
if(in_array($sFirstWord, array_keys($this->getWords('wExpand')))) //start
|
|
{
|
|
$iLoopId = count($asLineClasses)+$iOffSet;
|
|
$asLineClasses[] = 'loop'.$iLoopId;
|
|
$sExpandButton = '<input type="button" id="expand_loop'.$iLoopId.'" class="minus" value="" />';
|
|
}
|
|
elseif(in_array($sFirstWord, $this->getWords('wExpand'))) //end
|
|
{
|
|
array_pop($asLineClasses);
|
|
$iOffSet++;
|
|
$sExpandButton = '<span></span>';
|
|
}
|
|
|
|
//Enlarge line
|
|
if(mb_strpos($sLine, $sServName) !== false)
|
|
{
|
|
$sLiClass .= ' bigline';
|
|
}
|
|
|
|
//comments (entire line)
|
|
$sCodeClass = (in_array($sFirstChar, $this->getWords('cComment')))?'comment':'code';
|
|
|
|
$asColoredLines[] = '<li id="'.($iLineNb+1).'" class="round_right '.$sLiClass.'"><span class="expand_line">'.$sExpandButton.'</span><span class="'.$sCodeClass.'">'.$sLine.'</span></li>';
|
|
}
|
|
$sCode = implode('', $asColoredLines);
|
|
|
|
//Strings
|
|
foreach($this->getWords('cString') as $sStringWord)
|
|
{
|
|
$sPattern = '/>([^<]*?)'.$sStringWord.'([^<]*?)'.$sStringWord.'/';
|
|
$sCode = preg_replace($sPattern, '>$1<span class="string">'.$sStringWord.'$2'.$sStringWord.'</span>', $sCode);
|
|
}
|
|
|
|
//Part comment
|
|
$sPattern = '/>([^<]*)\"\;([^<]*)\<\/span\>\<\/li\>/';
|
|
$sCode = preg_replace($sPattern, '>$1<span class="comment">"$2</span>', $sCode);
|
|
|
|
//Internal Url
|
|
//$sPattern = '/>([^<]*)'.preg_quote($_GET['serv_name'], '/').'\/r\-([^<]*)/';
|
|
$sPattern = '/>([^<\/]*)(http:\/\/'.$sSafeRexExServName.'|'.$sSafeRexExServName.')(c|code|p|proc|procedure)\-([^<]*)/';
|
|
$sCode = preg_replace($sPattern, '>$1<a class="share internal_link" href="'.$sServName.'$3-$4" target="_blank">$3 $4</a>', $sCode);
|
|
|
|
//Global / Main
|
|
$sPattern = '/>\*\ \[('.implode('|', $this->getWords('wCodePart')).')\]/';
|
|
$sCode = preg_replace($sPattern, '><span class="code_part">> $1</span>', $sCode);
|
|
|
|
//Core Words
|
|
foreach($this->getWords('wCore') as $sCoreWord)
|
|
{
|
|
$sCoreWord = mb_strtolower($sCoreWord);
|
|
$sPattern = '/>(([^<]*)([^\w&<]{1})|.{0})('.$sCoreWord.')([\W])/';
|
|
$sCode = preg_replace($sPattern, '>$1<span class="core">$4</span>$5', $sCode);
|
|
}
|
|
//$sCoreWords = str_replace(' ', '\ ', implode('|', array_map('mb_strtolower', $this->getWords('wCore'))));
|
|
//$sPattern = '/>(([^<]*)([^\w<]{1})|.{0})('.$sCoreWords.')(?=[\W])/U';
|
|
//$sCode = preg_replace($sPattern, '>$1<span class="core">$4</span>', $sCode);
|
|
|
|
//Operators
|
|
//TODO distinguer operator / calculation
|
|
$asOperators = array_unique(array_merge($this->getWords('cOperator'), $this->getWords('cCalculation')));
|
|
foreach($asOperators as $sOpWord)
|
|
{
|
|
$sPattern = '/>([^<]*)\\'.$sOpWord.'/';
|
|
$sCode = preg_replace($sPattern, '>$1<span class="operator">'.$sOpWord.'</span>', $sCode);
|
|
}
|
|
//$sPattern = '/>([^<]*)['.implode(array_map('mb_strtolower', ($this->getWords('cOperator')))).']/';
|
|
//echo $sPattern;
|
|
//$sCode = preg_replace($sPattern, '>$1<span class="operator">$2$3</span>', $sCode);
|
|
|
|
//Numbers
|
|
$sPreChar = '\\'.implode('\\', $this->getWords('cCalculation')).'\s';
|
|
$sPattern = '/>((([^<]*)['.$sPreChar.']{1})|.{0})([0-9]+)([\W])/';
|
|
$sCode = preg_replace($sPattern, '>$1<span class="number">$4</span>$5', $sCode);
|
|
|
|
return $sCode;
|
|
}
|
|
|
|
private static function getFirstWord($sText)
|
|
{
|
|
return mb_strstr(str_replace('.', ' ', trim($sText)), ' ', true);
|
|
}
|
|
|
|
private static function getFirstChar($sText)
|
|
{
|
|
return mb_substr(str_replace('.', ' ', trim($sText)), 0, 1);
|
|
}
|
|
|
|
private function addColor(&$sText, $sWord, $sClassColor)
|
|
{
|
|
$sText = str_replace($sWord, '<span class="'.$sClassColor.'">'.$sWord.'</span>', $sText);
|
|
}
|
|
|
|
private static function getColoredWord($sWord, $sClass)
|
|
{
|
|
return '<span class="'.$sClass.'">'.$sWord.'</span>';
|
|
}
|
|
|
|
public static function convText2Html($sCode)
|
|
{
|
|
return htmlspecialchars(mb_strtolower($sCode), ENT_QUOTES);
|
|
}
|
|
|
|
public function getColoredCode()
|
|
{
|
|
return $this->addColoring();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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 START_TAG = 'START';
|
|
const END_TAG = 'END';
|
|
const TAG_MARK = '#';
|
|
|
|
public function __construct($sFileName='')
|
|
{
|
|
//init
|
|
parent::__construct();
|
|
$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 function initFile($sFileName)
|
|
{
|
|
$sFilePath = self::MASK_FOLDER.basename($sFileName).'.html';
|
|
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\] --\>/', $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) + mb_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 = &$this->findPart($this, $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);
|
|
$oMask->getCurrentInstance($sPartName)->setTag($sTagName, $sTagValue);
|
|
}
|
|
|
|
private function &findPart($oMask, $sPartName)
|
|
{
|
|
if(array_key_exists($sPartName, $oMask->aoInstances))
|
|
{
|
|
return $oMask;
|
|
}
|
|
else //not tested
|
|
{
|
|
foreach($oMask->aoInstances as $sLevelPartName=>$aoInstances)
|
|
{
|
|
if(!empty($aoInstances))
|
|
{
|
|
//take last instances
|
|
return $this->findPart($oMask->getCurrentInstance($sLevelPartName), $sPartName);
|
|
}
|
|
}
|
|
}
|
|
$this->addError('No part found : '.$sPartName);
|
|
}
|
|
|
|
private function getCurrentInstance($sPartName)
|
|
{
|
|
if(!empty($this->aoInstances[$sPartName]))
|
|
{
|
|
return end($this->aoInstances[$sPartName]);
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public function setTag($sTagName, $sTagValue)
|
|
{
|
|
$this->asTags[$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);
|
|
}
|
|
}
|
|
|
|
class fileUploader
|
|
{
|
|
const GET_NAME = 'qqfile';
|
|
|
|
private $asAllowedExtensions;
|
|
private $iSizeLimit;
|
|
private $sFolderPath;
|
|
|
|
function __construct($sFolderPath, $asAllowedExtensions = array()/*, $sizeLimit = 10485760*/)
|
|
{
|
|
$this->sFolderPath = $sFolderPath;
|
|
$this->asAllowedExtensions = array_map("mb_strtolower", $asAllowedExtensions);
|
|
//$this->iSizeLimit = $sizeLimit;
|
|
//$this->checkServerSettings();
|
|
$this->iSizeLimit = Databap::getMaxSize();
|
|
|
|
/*
|
|
if(isset($_GET[self::GET_NAME]))
|
|
{
|
|
//$this->file = new qqUploadedFileXhr();
|
|
}
|
|
elseif(isset($_FILES[self::GET_NAME])) {
|
|
$this->file = new qqUploadedFileForm();
|
|
}
|
|
else
|
|
{
|
|
$this->file = false;
|
|
}
|
|
*/
|
|
}
|
|
|
|
/*
|
|
private function checkServerSettings()
|
|
{
|
|
$postSize = $this->toBytes(ini_get('post_max_size'));
|
|
$uploadSize = $this->toBytes(ini_get('upload_max_filesize'));
|
|
|
|
|
|
if($postSize < $this->iSizeLimit || $uploadSize < $this->iSizeLimit){
|
|
$size = max(1, $this->iSizeLimit / 1024 / 1024) . 'M';
|
|
die("{'error':'increase post_max_size and upload_max_filesize to $size'}");
|
|
}
|
|
}
|
|
|
|
private function toBytes($str)
|
|
{
|
|
$val = trim($str);
|
|
$last = mb_strtolower($str[mb_strlen($str)-1]);
|
|
switch($last) {
|
|
case 'g': $val *= 1024;
|
|
case 'm': $val *= 1024;
|
|
case 'k': $val *= 1024;
|
|
}
|
|
return $val;
|
|
}
|
|
*/
|
|
|
|
function save($sFileName)
|
|
{
|
|
$oInput = fopen("php://input", "r");
|
|
$sTemp = tmpfile();
|
|
$iRealSize = stream_copy_to_stream($oInput, $sTemp);
|
|
fclose($oInput);
|
|
|
|
if($iRealSize != $this->getSize())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
$sPath = $this->sFolderPath.$sFileName;
|
|
$oTarget = fopen($sPath, "w");
|
|
fseek($sTemp, 0, SEEK_SET);
|
|
stream_copy_to_stream($sTemp, $oTarget);
|
|
fclose($oTarget);
|
|
|
|
return true;
|
|
}
|
|
|
|
function getName()
|
|
{
|
|
return isset($_GET[self::GET_NAME])?$_GET[self::GET_NAME]:false;
|
|
}
|
|
|
|
function getSize()
|
|
{
|
|
if(isset($_SERVER["CONTENT_LENGTH"]))
|
|
{
|
|
return (int)$_SERVER["CONTENT_LENGTH"];
|
|
}
|
|
else
|
|
{
|
|
throw new Exception('Getting content length is not supported.');
|
|
}
|
|
}
|
|
|
|
//Returns array('success'=>true) or array('error'=>'error message')
|
|
function handleUpload(/*$sUploadDir, $replaceOldFile = false*/)
|
|
{
|
|
if(!is_writable($this->sFolderPath))
|
|
{
|
|
return array('error' => "Erreur serveur. Le dossier est protégé en écriture");
|
|
}
|
|
if(!$this->getName())
|
|
{
|
|
return array('error' => 'Aucun fichier téléchargé');
|
|
}
|
|
|
|
$iSize = $this->getSize();
|
|
if($iSize == 0)
|
|
{
|
|
return array('error' => 'Fichier vide');
|
|
}
|
|
if($iSize > $this->iSizeLimit)
|
|
{
|
|
return array('error' => 'Fichier trop volumineux');
|
|
}
|
|
|
|
$asPathInfo = pathinfo($this->getName());
|
|
$sExt = mb_strtolower($asPathInfo['extension']);
|
|
$sExt = ($sExt=='jpg')?'jpeg':$sExt;
|
|
if($this->asAllowedExtensions && !in_array($sExt, $this->asAllowedExtensions))
|
|
{
|
|
$sAuthorizedExts = implode(', ', $this->asAllowedExtensions);
|
|
return array('error' => 'Le fichier a une extension invalide, les extensions autorisées sont : '.$sAuthorizedExts);
|
|
}
|
|
|
|
//
|
|
|
|
|
|
//$sFileName = $asPathInfo['filename'];
|
|
$sFileName = md5(uniqid());
|
|
/*
|
|
if(!$replaceOldFile){
|
|
// don't overwrite previous files that were uploaded
|
|
//while (file_exists($sUploadDir . $sFileName . '.' . $sExt)) {
|
|
// $sFileName .= rand(10, 99);
|
|
//}
|
|
if(file_exists($sUploadDir . $sFileName . '.' . $sExt))
|
|
{
|
|
$sFileName .= date(Databap::DATE_COMPACT_FORMAT);
|
|
}
|
|
}
|
|
*/
|
|
|
|
if($this->save($sFileName.'.'.$sExt))
|
|
{
|
|
return array('success'=>true, 'file_name'=>$sFileName.'.'.$sExt);
|
|
}
|
|
else
|
|
{
|
|
return array('error'=> 'Erreur server. Impossible de sauvegarder le fichier.');
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* MySql query manager and generator
|
|
* @author franzz
|
|
*/
|
|
class MySqlManager extends PhpObject
|
|
{
|
|
const DB_NO_CONN = 'ERR_1';
|
|
const DB_NO_DATA = 'ERR_2';
|
|
const ID_TAG = 'id_';
|
|
|
|
const USER_TABLE = 'users';
|
|
const COMP_TABLE = 'companies';
|
|
const CODE_TABLE = 'codes';
|
|
const URL_TABLE = 'urls';
|
|
const MSG_TABLE = 'messages';
|
|
const CHAN_TABLE = 'channels';
|
|
const CONN_TABLE = 'connections';
|
|
const ART_TABLE = 'articles';
|
|
|
|
const OPT_TABLE = 'options';
|
|
const OPTVAL_TABLE = 'option_values';
|
|
const OPTNAME_TABLE = 'option_names';
|
|
|
|
const PROC_TABLE = 'procedures';
|
|
const STEP_TABLE = 'steps';
|
|
const IMG_TABLE = 'images';
|
|
|
|
const DOC_TABLE = 'docs';
|
|
const FILE_TABLE = 'files';
|
|
|
|
const SEARCH_TABLE = 'searchs';
|
|
|
|
public $sDbState;
|
|
private $oConnection;
|
|
private $sDatabase; //TODO Variable ?
|
|
private $bTrace;
|
|
|
|
public function __construct($sDbServer, $sLogin, $sPass, $sDatabase, $sEncoding)
|
|
{
|
|
parent::__construct();
|
|
$this->sDatabase = $sDatabase;
|
|
//$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 static 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;
|
|
}
|
|
|
|
public function install()
|
|
{
|
|
//Create Database
|
|
$this->setQuery("DROP DATABASE IF EXISTS ".$this->sDatabase);
|
|
$this->setQuery("CREATE DATABASE ".$this->sDatabase." DEFAULT CHARACTER SET ".Settings::SQL_ENC." DEFAULT COLLATE ".Settings::SQL_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(self::getTablecolumns($sTableName));
|
|
foreach($asTableColumns as $sColumnName)
|
|
{
|
|
if(self::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 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 static function isId($sColumnName, $sTableName='')
|
|
{
|
|
$asTables = ($sTableName=='')?self::getTables():array($sTableName);
|
|
$asTableIds = array_map(array('self', 'getId'), $asTables);
|
|
return in_array($sColumnName, $asTableIds);
|
|
}
|
|
|
|
private static function getTable($sTableId)
|
|
{
|
|
$asTables = self::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 static function getTablecolumns($sTableName)
|
|
{
|
|
$asTableColumns = array(self::getId($sTableName));
|
|
switch($sTableName)
|
|
{
|
|
case self::USER_TABLE:
|
|
$asTableColumns[] = 'first_name';
|
|
$asTableColumns[] = 'last_name';
|
|
$asTableColumns[] = 'email';
|
|
$asTableColumns[] = self::getId(self::COMP_TABLE);
|
|
$asTableColumns[] = 'pass';
|
|
$asTableColumns[] = 'clearance';
|
|
break;
|
|
case self::COMP_TABLE:
|
|
$asTableColumns[] = self::getText(self::COMP_TABLE);
|
|
$asTableColumns[] = 'logo';
|
|
break;
|
|
case self::CODE_TABLE:
|
|
$asTableColumns[] = self::getText(self::CODE_TABLE);
|
|
$asTableColumns[] = 'description';
|
|
$asTableColumns[] = self::getId(self::USER_TABLE);
|
|
$asTableColumns[] = 'refer_id';
|
|
break;
|
|
case self::URL_TABLE:
|
|
$asTableColumns[] = self::getId(self::CODE_TABLE);;
|
|
$asTableColumns[] = 'phrase';
|
|
break;
|
|
case self::MSG_TABLE:
|
|
$asTableColumns[] = self::getId(self::USER_TABLE);
|
|
$asTableColumns[] = 'nickname';
|
|
$asTableColumns[] = self::getId(self::CHAN_TABLE);
|
|
$asTableColumns[] = self::getText(self::MSG_TABLE);
|
|
$asTableColumns[] = 'type';
|
|
$asTableColumns[] = 'date';
|
|
break;
|
|
case self::CHAN_TABLE:
|
|
$asTableColumns[] = 'safe_name';
|
|
$asTableColumns[] = self::getText(self::CHAN_TABLE);
|
|
break;
|
|
case self::CONN_TABLE:
|
|
$asTableColumns[] = self::getId(self::USER_TABLE);
|
|
$asTableColumns[] = self::getId(self::CHAN_TABLE);
|
|
break;
|
|
case self::OPT_TABLE:
|
|
$asTableColumns[] = self::getId(self::USER_TABLE);
|
|
$asTableColumns[] = self::getId(self::OPTNAME_TABLE);
|
|
$asTableColumns[] = self::getId(self::OPTVAL_TABLE);
|
|
$asTableColumns[] = self::getText(self::OPT_TABLE);
|
|
break;
|
|
case self::OPTNAME_TABLE:
|
|
$asTableColumns[] = self::getText(self::OPTNAME_TABLE);
|
|
$asTableColumns[] = 'type';
|
|
$asTableColumns[] = 'language';
|
|
break;
|
|
case self::OPTVAL_TABLE:
|
|
$asTableColumns[] = self::getId(self::OPTNAME_TABLE);
|
|
$asTableColumns[] = self::getText(self::OPTVAL_TABLE);
|
|
$asTableColumns[] = 'language';
|
|
break;
|
|
case self::PROC_TABLE:
|
|
$asTableColumns[] = self::getId(self::USER_TABLE);
|
|
$asTableColumns[] = 'title';
|
|
$asTableColumns[] = 'description';
|
|
$asTableColumns[] = 'refer_id';
|
|
break;
|
|
case self::STEP_TABLE:
|
|
$asTableColumns[] = self::getId(self::PROC_TABLE);
|
|
$asTableColumns[] = 'description';
|
|
break;
|
|
case self::IMG_TABLE:
|
|
$asTableColumns[] = self::getId(self::PROC_TABLE);
|
|
$asTableColumns[] = self::getId(self::STEP_TABLE);
|
|
$asTableColumns[] = 'description';
|
|
$asTableColumns[] = 'file_name';
|
|
break;
|
|
case self::DOC_TABLE:
|
|
$asTableColumns[] = self::getId(self::USER_TABLE);
|
|
$asTableColumns[] = 'title';
|
|
$asTableColumns[] = 'description';
|
|
$asTableColumns[] = 'refer_id';
|
|
break;
|
|
case self::FILE_TABLE:
|
|
$asTableColumns[] = self::getId(self::DOC_TABLE);
|
|
$asTableColumns[] = 'description';
|
|
$asTableColumns[] = 'file_name';
|
|
break;
|
|
case self::SEARCH_TABLE:
|
|
$asTableColumns[] = 'id_item';
|
|
$asTableColumns[] = 'refer_id';
|
|
$asTableColumns[] = 'type';
|
|
$asTableColumns[] = 'keywords';
|
|
break;
|
|
case self::ART_TABLE:
|
|
$asTableColumns[] = 'title';
|
|
$asTableColumns[] = 'link';
|
|
$asTableColumns[] = 'date';
|
|
$asTableColumns[] = 'first_name';
|
|
$asTableColumns[] = 'last_name';
|
|
$asTableColumns[] = 'email';
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
$asTableColumns[] = 'led';
|
|
$asTableName = array_fill(0, count($asTableColumns), $sTableName);
|
|
return array_combine($asTableColumns, array_map(array('self', 'getColumnType'), $asTableColumns, $asTableName));
|
|
}
|
|
|
|
private static function getColumnType($sColumnName, $sTableName)
|
|
{
|
|
$sColumnType = '';
|
|
switch($sColumnName)
|
|
{
|
|
case self::getText(self::USER_TABLE): //TODO delete use and field
|
|
$sColumnType = "varchar(50) NOT NULL";
|
|
break;
|
|
case 'first_name':
|
|
$sColumnType = "varchar(20) NOT NULL";
|
|
break;
|
|
case 'last_name':
|
|
$sColumnType = "varchar(20) NOT NULL";
|
|
break;
|
|
case 'nickname':
|
|
$sColumnType = "varchar(50) NOT NULL";
|
|
break;
|
|
case 'email':
|
|
$sColumnType = "varchar(100) NOT NULL";
|
|
break;
|
|
case 'pass':
|
|
$sColumnType = "varchar(128) NOT NULL";
|
|
break;
|
|
case 'clearance':
|
|
$sColumnType = "int(1) NOT NULL";
|
|
break;
|
|
case self::getText(self::CODE_TABLE):
|
|
$sColumnType = "longtext NOT NULL";
|
|
break;
|
|
case 'title':
|
|
$sColumnType = "varchar(200) NOT NULL";
|
|
break;
|
|
case 'description':
|
|
$sColumnType = "varchar(500) NOT NULL";
|
|
break;
|
|
case 'link':
|
|
$sColumnType = "varchar(200) NOT NULL";
|
|
break;
|
|
case 'refer_id':
|
|
$sColumnType = "int(10) UNSIGNED NOT NULL";
|
|
break;
|
|
case 'phrase':
|
|
$sColumnType = "varchar(50) NOT NULL";
|
|
break;
|
|
case self::getText(self::MSG_TABLE):
|
|
$sColumnType = "varchar(500) NOT NULL";
|
|
break;
|
|
case 'type':
|
|
$sColumnType = "varchar(2) NOT NULL";
|
|
break;
|
|
case 'safe_name':
|
|
$sColumnType = "varchar(50) NOT NULL";
|
|
break;
|
|
case self::getText(self::CHAN_TABLE):
|
|
$sColumnType = "varchar(50) NOT NULL";
|
|
break;
|
|
case self::getText(self::OPT_TABLE):
|
|
$sColumnType = "varchar(100) NOT NULL";
|
|
break;
|
|
case self::getText(self::OPTNAME_TABLE):
|
|
$sColumnType = "varchar(100) NOT NULL";
|
|
break;
|
|
case self::getText(self::OPTVAL_TABLE):
|
|
$sColumnType = "varchar(50) NOT NULL";
|
|
break;
|
|
case 'language':
|
|
$sColumnType = "varchar(2) NOT NULL";
|
|
break;
|
|
case 'file_name':
|
|
$sColumnType = "varchar(40) NOT NULL";
|
|
break;
|
|
case 'preview_name':
|
|
$sColumnType = "varchar(40) NOT NULL";
|
|
break;
|
|
case 'id_item':
|
|
$sColumnType = "int(10) UNSIGNED NOT NULL";
|
|
break;
|
|
case 'keywords':
|
|
$sColumnType = "longtext NOT NULL";
|
|
break;
|
|
case self::getText(self::COMP_TABLE):
|
|
$sColumnType = "varchar(30) NOT NULL";
|
|
break;
|
|
case 'logo':
|
|
$sColumnType = "varchar(20) NOT NULL";
|
|
break;
|
|
case 'date':
|
|
$sColumnType = "date NOT NULL";
|
|
break;
|
|
case 'led':
|
|
$sColumnType = "TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP";
|
|
break;
|
|
case self::isId($sColumnName, $sTableName):
|
|
$sColumnType = "int(10) UNSIGNED auto_increment";
|
|
break;
|
|
case self::isId($sColumnName):
|
|
$sColumnType = "int(10) UNSIGNED";
|
|
break;
|
|
}
|
|
return $sColumnType;
|
|
}
|
|
|
|
private static function getTableConstraints($sTableName)
|
|
{
|
|
//Primary key
|
|
$asTableConstraints = array('PRIMARY' => "PRIMARY KEY (`".self::getId($sTableName)."`)");
|
|
|
|
//Foreign keys
|
|
//Foreign keys applied using ALTER TABLE syntax at the end to prevent scheduling CREATE TABLE queries
|
|
|
|
//Other constraints
|
|
switch($sTableName)
|
|
{
|
|
case self::USER_TABLE :
|
|
$asTableConstraints[] = "UNIQUE KEY `user_first_and_last_name` (`first_name`, `last_name`)";
|
|
break;
|
|
case self::URL_TABLE :
|
|
$asTableConstraints[] = "UNIQUE KEY `uni_phrase` (`phrase`)";
|
|
break;
|
|
case self::MSG_TABLE :
|
|
$asTableConstraints[] = "INDEX(`date`)";
|
|
break;
|
|
case self::ART_TABLE:
|
|
$asTableConstraints[] = "INDEX(`title`)";
|
|
break;
|
|
|
|
}
|
|
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 self::CODE_TABLE :
|
|
$asTables = array($sTableName, self::URL_TABLE);
|
|
break;
|
|
case self::PROC_TABLE :
|
|
$asTables = array($sTableName, self::STEP_TABLE, self::IMG_TABLE);
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* ToolBox - Only static functions missing from php librairy
|
|
* @author franzz
|
|
*/
|
|
class ToolBox
|
|
{
|
|
function __construct(){}
|
|
|
|
public function toString($sSep, $asData)
|
|
{
|
|
if(is_array($asData) && count($asData)>0)
|
|
{
|
|
$sData = $sSep;
|
|
foreach($asData as $oData)
|
|
{
|
|
$sData .= self::toString($oData).$sSep;
|
|
}
|
|
return $sData;
|
|
}
|
|
else return $asData;
|
|
}
|
|
|
|
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')) 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 ToolBox::mb_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 sendMail($sFrom, $sTo, $sReplyTo, $sSubject, $sMessage)
|
|
{
|
|
$sResult = '';
|
|
if($sFrom!='' && $sTo!='' && $sReplyTo!='' && $sSubject!='' && $sMessage!='')
|
|
{
|
|
$sHtmlMessage = str_replace("\n", '<br />', $sMessage);
|
|
$sPlainMessage = strip_tags(str_replace('<br />', "\n", $sHtmlMessage));
|
|
|
|
$iBoundary = uniqid('HTMLEMAIL');
|
|
$sHeaders = 'From: '.$sFrom."\r\n".
|
|
'Reply-To: '.$sReplyTo."\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));
|
|
|
|
if(!mail($sTo, $sSubject, '', $sHeaders))
|
|
{
|
|
$sResult = 'Email: An unknown error occured';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$sResult = 'Email: Some fields were empty';
|
|
}
|
|
}
|
|
|
|
public static function createThumbnail($sInPath, $iMaxWidth, $iMaxHeight, $sOutPath='', $bDeleteIn=false)
|
|
{
|
|
$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, Databap::$UPLOAD_IMG_EXTS))
|
|
{
|
|
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);
|
|
}
|
|
|
|
function mb_ucwords($sText)
|
|
{
|
|
return mb_convert_case($sText, MB_CASE_TITLE, "UTF-8");
|
|
}
|
|
|
|
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));
|
|
}
|
|
}
|
|
|
|
/* Debug */
|
|
|
|
function pre($sText, $sMode='return', $bDie=false, $sTitle='Test')
|
|
{
|
|
$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__.'()]');
|
|
}
|
|
|
|
return $sLog;
|
|
}
|
|
|
|
function dlog($sText, $sTitle='Test')
|
|
{
|
|
pre($sText, 'log', false, date('d/m/Y H:m:i').' - '.$sTitle, false);
|
|
}
|
|
|
|
?>
|