Files
databap/inc/databap.php
2014-12-23 16:33:08 +01:00

2842 lines
105 KiB
PHP
Executable File

<?php
/**
* Application Core
* @author franzz
*/
class Databap extends PhpObject
{
//Common Constants
const VERSION = '1.1.0'; //Versioning: <Main_Version>.<Enhancement_Package>.<Patch>-<Release_Candidate>
const VERSION_DATE = '13/12/2014';
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/databap.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 = '_';
const SYSTEM_USER_ID = 1;
//Database constant
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';
const TABL_TABLE = 'tables';
//Code
const MAX_LIST_LENGTH = 5;
//Authorizations
const MEMBER_ACTIVE = 1;
const MEMBER_INACTIVE = 0;
const CLEARANCE_MEMBER = 0;
const CLEARANCE_ADMIN = 9;
const EXT_ACCESS = 'external_access';
const USER_COOKIE_ID = 'count';
const USER_COOKIE_PASS = 'checksum';
const COOKIE_LIFESPAN = 7;
const FIRST_LAST_SEP = ' ';
const NAME_PASS_SEP = '-';
//HTTP Requests response
const ERROR = '__ERROR__';
const SUCCESS = '__SUCCESS__';
const DISCONNECTED = '__DISCONNECTED__';
const NOT_FOUND = '__NOT_FOUND__';
const NOT_AUTH = '__NOT_AUTHORIZED__';
const FAIL_INSERT = '__FAIL_INSERT__';
const FAIL_UPDATE = '__FAIL_UPDATE__';
const FAIL_DELETE = '__FAIL_DELETE__';
//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_ADD_TABLE = 'TA';
const MESSAGE_EDIT_TABLE = 'TE';
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 MESSAGE_NEWS = 'NW';
private static $MESSAGE_TYPES = array( 'user'=>self::MESSAGE_USER,
'add'=> array( 'code'=>self::MESSAGE_ADD_CODE,
'proc'=>self::MESSAGE_ADD_PROC,
'doc'=>self::MESSAGE_ADD_DOC,
'table'=>self::MESSAGE_ADD_TABLE),
'edit'=>array( 'code'=>self::MESSAGE_EDIT_CODE,
'proc'=>self::MESSAGE_EDIT_PROC,
'doc'=>self::MESSAGE_EDIT_DOC,
'table'=>self::MESSAGE_EDIT_TABLE),
'action'=>self::MESSAGE_ACTION,
'private'=>self::MESSAGE_PRIVATE,
'img'=>self::MESSAGE_IMG,
'9gag'=>self::MESSAGE_9GAG,
'nick'=>self::MESSAGE_NICK,
'status'=>self::MESSAGE_STATUS,
'conn'=>self::MESSAGE_CONN,
'invite'=>self::MESSAGE_INVITE,
'reboot'=>self::MESSAGE_REBOOT,
'article'=>self::MESSAGE_ARTICLE,
'news'=>self::MESSAGE_NEWS);
const DEFAULT_COMPANY_LOGO = 'logo_unknown_24.png';
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 DEFAULT_CHAN_ID = 2;
const DEFAULT_CHAN = 'Principal';
const KEEP_ALIVE = 600; //seconds
const REBOOT_DELAY = 15; //seconds
const PM_SEP = '___';
const CHAT_IMG_MAX_WIDTH = 700;
const CHAT_IMG_MAX_HEIGHT = 1080;
const JSON_PREFIX = '[\-JSON-/]';
const MAX_NB_NEWS = 3;
//Options Name Id Constants
const LANG_FR = 'FR';
const OPT_TEXT = 'T';
const OPT_PASS = 'P';
const OPT_SELECT = 'S';
const OPT_NICKNAME = 1;
const OPT_BG = 2;
const OPT_BG_2 = 11;
const OPT_BG_3 = 3;
const OPT_HOVER = 4;
const OPT_IMAGE_CHAT = 6;
const OPT_STATUS = 7;
const OPT_CONSOLE = 8;
const OPT_EMAIL = 9;
const OPT_CHAT_HISTO = 10;
//Options Values Constants
const OPT_VAL_YES = 'oui';
const OPT_VAL_NO = 'non';
//Search Constants
const CODE_TYPE = 'c';
const PROC_TYPE = 'p';
const ART_TYPE = 'a';
const DOC_TYPE = 'd';
const TABLE_TYPE = 't';
public static $HASH_TO_PAGE = array(self::CODE_TYPE=>'code', 'code'=>'code',
self::PROC_TYPE=>'procedure', 'proc'=>'procedure', 'procedure'=>'procedure',
self::TABLE_TYPE=>'table', 'table'=>'table',
self::DOC_TYPE=>'doc', 'documentation'=>'doc', 'doc'=>'doc',
self::ART_TYPE=>'article', 'art'=>'article', 'article'=>'article',
'n'=>'note', 'note'=>'note', 'note oss'=>'note',
'list'=>'list', 'liste'=>'list',
'chat'=>'chat',
'profil'=>'profile', 'profile'=>'profile',
'options'=>'options',
's'=>'search', 'r'=>'search', 'search'=>'search', 'recherche'=>'search',
'accueil'=>'welcome',
'erreur'=>'error',
'logout'=>'logout');
public static $TYPES = array( self::CODE_TYPE =>array('table' => self::CODE_TABLE, 'title' => 'Code'),
self::PROC_TYPE =>array('table' => self::PROC_TABLE, 'title' => 'Procédure'),
self::ART_TYPE =>array('table' => self::ART_TABLE, 'title' => 'Article'),
self::DOC_TYPE =>array('table' => self::DOC_TABLE, 'title' => 'Documentation'),
self::TABLE_TYPE=>array('table' => self::TABL_TABLE, 'title' => 'Table'));
public static $PAGE_TITLES = array( 'code'=>'Code', 'chat'=>'Chat', 'doc'=>'Documentation', 'error'=>'Page introuvable',
'list'=>'La liste', 'options'=>'Paramètres', 'procedure'=>'Procédure', 'profile'=>'Profil',
'search'=>'Recherche', 'welcome'=>'Bienvenue', 'table'=>'Table', 'article'=>'Article de blog',
'logout'=>'Déconnexion', 'note'=>'Note OSS');
//Doc constants
const DOC_FOLDER = 'docs/';
const DOC_TMP_FOLDER = 'docs/tmp/';
const DOC_THUMB_FOLDER = 'docs/thumb/';
//Objects
private $oMySql;
private $oSearchEngine;
private $oClassManagement;
private $oAuth;
//Variables
private $iUserId;
private $asUsersInfo;
private $sLanguage;
/**
* Constructor
* @param ClassManagement $oClassManagement
*/
function __construct($oClassManagement, $sLanguage=self::LANG_FR)
{
parent::__construct(__CLASS__, Settings::DEBUG);
$this->oClassManagement = $oClassManagement;
$this->oClassManagement->incClass('auth');
$this->oClassManagement->incClass('mysqlmanager');
$this->oClassManagement->incClass('procedure');
$this->oClassManagement->incClass('searchengine');
$this->oClassManagement->incClass('mask');
//Hasher
$this->oAuth = new Auth();
//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);
//Databap Settings
$this->setUserId(0);
$this->sLanguage = $sLanguage;
//Passing settings down to mySQL
$this->oMySql = new MySqlManager(Settings::DB_SERVER, Settings::DB_LOGIN, Settings::DB_PASS, Settings::DB_NAME, self::getSqlOptions(), Settings::DB_ENC);
if($this->oMySql->sDbState == MySqlManager::DB_NO_DATA && Settings::DEBUG==true) $this->install();
//Init Search Engine
$this->oSearchEngine = new SearchEngine($this->oMySql);
}
public static function getSqlOptions()
{
$asOptions = array();
$asOptions['tables'] = array
(
self::USER_TABLE => array('first_name', 'last_name', MySqlManager::getId(self::COMP_TABLE), 'pass', 'auth_cookie', 'active', 'clearance'),
self::COMP_TABLE => array(MySqlManager::getText(self::COMP_TABLE), 'logo'),
self::CODE_TABLE => array(MySqlManager::getText(self::CODE_TABLE), 'description', MySqlManager::getId(self::USER_TABLE), 'refer_id'),
self::URL_TABLE => array(MySqlManager::getId(self::CODE_TABLE), 'phrase'),
self::MSG_TABLE => array(MySqlManager::getId(self::USER_TABLE), 'nickname', MySqlManager::getId(self::CHAN_TABLE), MySqlManager::getText(self::MSG_TABLE), 'type', 'date'),
self::CHAN_TABLE => array('safe_name', MySqlManager::getText(self::CHAN_TABLE)),
self::CONN_TABLE => array(MySqlManager::getId(self::USER_TABLE), MySqlManager::getId(self::CHAN_TABLE)),
self::OPT_TABLE => array(MySqlManager::getId(self::USER_TABLE), MySqlManager::getId(self::OPTNAME_TABLE), MySqlManager::getId(self::OPTVAL_TABLE)),
self::OPTNAME_TABLE => array(MySqlManager::getText(self::OPTNAME_TABLE), 'type', 'language'),
self::OPTVAL_TABLE => array(MySqlManager::getId(self::OPTNAME_TABLE), MySqlManager::getText(self::OPTVAL_TABLE), 'default_value', 'language'),
self::PROC_TABLE => array(MySqlManager::getId(self::USER_TABLE), 'title', 'description', 'refer_id'),
self::STEP_TABLE => array(MySqlManager::getId(self::PROC_TABLE), 'description'),
self::IMG_TABLE => array(MySqlManager::getId(self::PROC_TABLE), MySqlManager::getId(self::STEP_TABLE), 'description', 'file_name'),
self::DOC_TABLE => array(MySqlManager::getId(self::USER_TABLE), 'title', 'description', 'refer_id'),
self::FILE_TABLE => array('id_item', 'type', 'description', 'hash', 'extension'),
self::SEARCH_TABLE => array('id_item', 'refer_id', 'type', 'keywords'),
self::ART_TABLE => array('title', 'link', 'date', 'first_name', 'last_name', 'email'),
self::TABL_TABLE => array(MySqlManager::getId(self::USER_TABLE), 'title', 'description', 'system', 'keywords', 'refer_id')
);
$asOptions['types'] = array
(
'first_name' => "varchar(20) NOT NULL",
'last_name' => "varchar(20) NOT NULL",
'nickname' => "varchar(50) NOT NULL",
'email' => "varchar(100) NOT NULL",
'hash' => "varchar(32) NOT NULL",
'pass' => "varchar(255) NOT NULL",
'auth_cookie' => "varchar(255) NOT NULL",
'active' => "tinyint(1) DEFAULT ".self::MEMBER_ACTIVE,
'clearance' => "int(1) DEFAULT ".self::CLEARANCE_MEMBER,
MySqlManager::getText(self::CODE_TABLE) => "longtext NOT NULL",
'title' => "varchar(200) NOT NULL",
'description' => "varchar(500) NOT NULL",
'link' => "varchar(200) NOT NULL",
'refer_id' => "int(10) UNSIGNED NOT NULL",
'phrase' => "varchar(50) NOT NULL",
MySqlManager::getText(self::MSG_TABLE) => "varchar(500) NOT NULL",
'type' => "varchar(2) NOT NULL",
'safe_name' => "varchar(50) NOT NULL",
MySqlManager::getText(self::CHAN_TABLE) => "varchar(50) NOT NULL",
MySqlManager::getText(self::OPTNAME_TABLE) => "varchar(100) NOT NULL",
MySqlManager::getText(self::OPTVAL_TABLE)=> "varchar(100) NOT NULL",
'language' => "varchar(2) NOT NULL",
'file_name' => "varchar(40) NOT NULL",
'preview_name' => "varchar(40) NOT NULL",
'id_item' => "int(10) UNSIGNED NOT NULL",
'keywords' => "longtext NOT NULL",
MySqlManager::getText(self::COMP_TABLE) => "varchar(30) NOT NULL",
'logo' => "varchar(20) NOT NULL",
'date' => "date NOT NULL",
'system' => "varchar(3)",
'extension' => "varchar(10)",
'default_value'=>"tinyint(1) DEFAULT 0"
);
$asOptions['constraints'] = array
(
self::USER_TABLE => "UNIQUE KEY `user_first_and_last_name` (`first_name`, `last_name`)",
self::URL_TABLE => "UNIQUE KEY `uni_phrase` (`phrase`)",
self::MSG_TABLE => "INDEX(`date`)",
self::ART_TABLE => "INDEX(`title`)"
);
$asOptions['cascading_delete'] = array
(
self::CODE_TABLE => array(self::URL_TABLE),
self::PROC_TABLE => array(self::STEP_TABLE, self::IMG_TABLE)
);
return $asOptions;
}
public static function getTypeInfo($oInfo=array(), $sType='')
{
if($sType!='')
{
if($sType!='' && !array_key_exists($sType, self::$TYPES)) $this->addError('Type "'.$sType.'" inconnu');
else $asResult = array($sType=>self::$TYPES[$sType]);
}
else $asResult = self::$TYPES;
//info
if(is_string($oInfo)) $oInfo = array($oInfo);
$bUnique = (count($oInfo)==1);
if(!empty($oInfo))
{
foreach($asResult as $sType=>$asTypeInfo)
{
$asResult[$sType] = array();
foreach($oInfo as $sInfo)
{
if(!array_key_exists($sInfo, $asTypeInfo)) $this->addError('Info "'.$sInfo.'" inconnue');
else $asResult[$sType][$sInfo] = $asTypeInfo[$sInfo];
}
if($bUnique) $asResult[$sType] = $asResult[$sType][$sInfo];
}
}
return $asResult;
}
private function getPageTitles($sPage='')
{
$asPageTitles = self::$PAGE_TITLES;
if($sPage!='' && !array_key_exists($sPage, $asPageTitles)) $this->addError('Page "'.$sPage.'" inconnu');
return $sPage==''?$asPageTitles:$asPageTitles[$sPage];
}
private function getPagesFromHash($sHash='')
{
$asHashToPage = self::$HASH_TO_PAGE;
if($sHash!='' && !array_key_exists($sHash, $asHashToPage)) $this->addError('Hash "'.$sHash.'" inconnu');
return $sHash==''?$asHashToPage:$asHashToPage[$sHash];
}
private function install()
{
//Install DB
$this->oMySql->install();
//Options
$sOptionNameCol = MySqlManager::getText(self::OPTNAME_TABLE);
$sOptionValueCol = MySqlManager::getText(self::OPTVAL_TABLE);
$sOptionNameIdCol = MySqlManager::getId(self::OPTNAME_TABLE);
$sOptionValueIdCol = MySqlManager::getId(self::OPTVAL_TABLE);
$this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_NICKNAME, $sOptionNameCol=>'pseudo du chat', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
$this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_BG, $sOptionNameCol=>'couleur de fond', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
$this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_BG_2, $sOptionNameCol=>'couleur de fond 2', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
$this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_BG_3, $sOptionNameCol=>'couleur de fond 3', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
$this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_HOVER, $sOptionNameCol=>'couleur de survol', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
$this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_IMAGE_CHAT, $sOptionNameCol=>'image du chat', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
$this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_STATUS, $sOptionNameCol=>'mission en cours', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
$this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_CONSOLE, $sOptionNameCol=>'afficher la console du chat', 'type'=>self::OPT_SELECT, 'language'=>self::LANG_FR));
$this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_EMAIL, $sOptionNameCol=>'email', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
$this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_CHAT_HISTO, $sOptionNameCol=>'nombre de jours d\'historique dans le chat', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
//Select and Default Option values
$asDefaultValues = array( self::OPT_CONSOLE=>array(self::OPT_VAL_YES=>false, self::OPT_VAL_NO=>true),
self::OPT_NICKNAME=>array('Utilisateur inconnu'=>true),
self::OPT_BG=>array('#04357B'=>true),
self::OPT_BG_2=>array('#88B2F0'=>true),
self::OPT_BG_3=>array('#D9E5F2'=>true),
self::OPT_HOVER=>array('#EFAB00'=>true),
self::OPT_IMAGE_CHAT=>array('images/sap_gold_332.jpg'=>true),
self::OPT_STATUS=>array('aucune mission en cours'=>true),
self::OPT_EMAIL=>array('email inconnu'=>true),
self::OPT_CHAT_HISTO=>array('0'=>true));
foreach($asDefaultValues as $sOptionNameId=>$asOptionValues)
{
foreach($asOptionValues as $sOptionValue=>$bDefault)
{
$this->oMySql->insertRow(self::OPTVAL_TABLE, array($sOptionNameIdCol=>$sOptionNameId, $sOptionValueCol=>$sOptionValue, 'default_value'=>$bDefault, 'language'=>self::LANG_FR));
}
}
//Insert default and all channels
$this->oMySql->insertRow(self::CHAN_TABLE, array('safe_name'=>self::getChanSafeName(self::ALL_CHAN_TEXT), MySqlManager::getText(self::CHAN_TABLE)=>self::ALL_CHAN_TEXT));
$this->oMySql->insertRow(self::CHAN_TABLE, array('safe_name'=>self::getChanSafeName(self::DEFAULT_CHAN), MySqlManager::getText(self::CHAN_TABLE)=>self::DEFAULT_CHAN));
//Install default users : system, admin and test
$iSystemId = $this->addUser('databap', 'bot', 'ovh', 'databap@botnet.com', self::CLEARANCE_ADMIN, self::SYSTEM_USER_ID);
$this->setOptions(array(self::OPT_NICKNAME=>'Databot'), true, $iSystemId);
$this->addUser('françois', 'lutran', 'planeum', '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\ncd /var/www\n\n/usr/bin/php -f index.php a=external_access p=blogs auth_token=".$iSystemId.'_'.str_replace('$', '\$', $this->generateExternalAccessToken($iSystemId)));
}
public function goLive()
{
$sUrl = 'http://img-9gag-ftw.9cache.com/photo/a5dmY7G_700b.jpg';
$asResult = array();
$oCurl = curl_init($sUrl);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($oCurl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($oCurl, CURLOPT_HEADER, true);
//curl_setopt($oCurl, CURLOPT_NOBODY, true);
curl_setopt($oCurl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
curl_exec($oCurl);
$asResult[] = 'curl: '.curl_getinfo($oCurl, CURLINFO_CONTENT_TYPE);
curl_close($oCurl);
$asResult[] = 'get_headers: '.print_r(get_headers($sUrl, 1), true);
stream_context_set_default(array('http' => array('method' => 'HEAD')));
$asResult[] = 'get_headers HEAD: '.print_r(get_headers($sUrl, 1), true);
file_get_contents($sUrl);
$asResult[] = '$http_response_header: '.print_r($http_response_header, true);
$size = getimagesize($sUrl);
$asResult[] = 'getimagesize: '.$size['mime'];
$oFileInfo = new finfo(FILEINFO_MIME);
$asResult[] = 'finfo: '.$oFileInfo->file($sUrl);
return implode('<br />', $asResult);
}
private function setUserId($iUserId)
{
$this->iUserId = $iUserId;
$this->setUserInfo();
}
public function getUserId()
{
return $this->iUserId;
}
public function getPage($sPage, $oItemId, $asVars=array())
{
$oPage = new Mask('index');
$oPage->setTag('version', self::VERSION);
$oPage->setTag('text_enc', Settings::TEXT_ENC);
$oPage->setTag('index_link', $_GET['serv_name']);
$oPage->setTag('rss_link', $this->generateExternalAccessLink('rss', $this->getUserid()));
//Constants
$asConstants = array( 'version'=>self::VERSION,
'version_date'=>self::VERSION_DATE,
'default_page'=>$sPage,
'default_id'=>$oItemId,
'errors'=>array('disconnected'=>self::DISCONNECTED,
'not_authorized'=>self::NOT_AUTH,
'not_found'=>self::NOT_FOUND,
'insert'=>self::FAIL_INSERT,
'update'=>self::FAIL_UPDATE,
'delete'=>self::FAIL_DELETE),
'success'=>self::SUCCESS,
'error'=>self::ERROR,
'keep_alive'=>self::KEEP_ALIVE,
'opt_type_text'=>self::OPT_TEXT,
'opt_type_pass'=>self::OPT_PASS,
'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,
'versionHtml'=>$this->getItemBlock(),
'types'=>$this->getTypeInfo('title'),
'msg_types'=>self::$MESSAGE_TYPES,
'cur_date'=>date(self::DATE_FORMAT));
$oPage->setTag('constants', $this->jsonConvert($asConstants));
//Variables
$asVars['page_titles'] = $this->getPageTitles();
$asVars['user_id'] = $this->getUserId();
$asVars['hash_to_page'] = $this->getPagesFromHash();
$asVars['page_to_hash'] = array_flip($asVars['hash_to_page']);
$asVars['opt_console'] = ($this->getUserOptionValue(self::OPT_CONSOLE)==self::OPT_VAL_YES);
$oPage->setTag('variables', $this->jsonConvert($asVars));
return $oPage->getMask();
}
public function getLogonPage($bFirstConn)
{
$oPage = new Mask('logon');
$oPage->setTag('feedback', $bFirstConn?'':'Données incorrectes');
$oPage->setTag('version', self::VERSION);
$oPage->setTag('name_pass_sep', self::NAME_PASS_SEP);
return $oPage->getMask();
}
public function getRss($sCat='')
{
//Class Feed
$this->oClassManagement->incClass('rss');
//Building header
$asDesc = array
(
'title'=>'Flux RSS Databap'.($sCat==''?'':' - '.$sCat),
'link'=>$this->getInternalLink('rss', $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
if($sCat=='news')
{
$asNews = $this->getNews(false);
$iLinkId = count($asNews);
foreach($asNews as $asRow)
{
//TODO mutualiser avec le reste
$sChatlink = $this->getInternalLink('chat', $asRow[MySqlManager::getId(self::MSG_TABLE)]);
$asItem = array
(
'title'=>'Lien'.($sCat==''?'':' - '.$sCat).' #'.$iLinkId,
'category'=>$sCat,
'description'=>$asRow['message'],
'author'=>$asRow['nickname'],
'link'=>$sChatlink,
'pub_date'=>$asRow['time'],
'guid'=>$sChatlink
);
$oFeed->addItem($asItem);
$iLinkId -= 1;
}
}
else
{
switch($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;
}
$sMessageIdCol = MySqlManager::getId(self::MSG_TABLE);
$sChanIdCol = MySqlManager::getId(self::CHAN_TABLE);
$asResult = $this->oMySql->selectRows(array('select'=>array($sMessageIdCol, 'nickname', $sChanIdCol, 'message', 'led'),
'from'=>self::MSG_TABLE,
'constraint'=>array('message'=>$sRegEx),
'constOpe'=>array('message'=>' REGEXP ')));
$asChans = $this->oMySql->selectRows(array('select'=>array($sChanIdCol, 'safe_name'), 'from'=>self::CHAN_TABLE), true, $sChanIdCol);
$sPattern = '/(https?\:\/\/|www\.)[\S]+\.[a-zA-Z]{2,4}([\S]*)/ui';
foreach($asResult as $iLinkId=>$asRow)
{
//filter on authorized chans
if($this->checkChanAuth($asChans[$asRow[$sChanIdCol]], $this->getUserId()))
{
//get link out of message
preg_match($sPattern, $asRow['message'], $asMatches);
$asRow['link'] = (substr($asMatches[0], 0, 4)=='http')?$asMatches[0]:'http://'.$asMatches[0];
//add item
$sChatlink = $this->getInternalLink('chat', $asRow['id_message']);
$asItem = array
(
'title'=>'Lien'.($sCat==''?'':' - '.$sCat).' #'.($iLinkId+1),
'category'=>$sCat,
'description'=>'Lien post&eacute; par '.self::getNickNameFormat($asRow['nickname']).' &agrave; '.self::getDateFormat($asRow['led']).' : <a href="'.$asRow['link'].'" target="_blank">'.$asRow['message'].'</a>',
'author'=>$asRow['nickname'],
'link'=>$sChatlink,
'pub_date'=>$asRow['led'],
'guid'=>$sChatlink
);
$oFeed->addItem($asItem);
}
}
}
return $oFeed->getFeed();
}
public function syncSapBlog()
{
//Get articles list
$asArticles = $this->getSAPBlogRss();
//Update and spread the news
$asResult = array();
$iTimeStamp = time();
if(date('N', $iTimeStamp)>5 || date('G', $iTimeStamp)>19) $asResult[] = "Pas de mise-à-jour pendant le week end ou en soirée.";
else
{
foreach($asArticles as $asArticle)
{
$iArticleId = $this->oMySql->selectValue(self::ART_TABLE, MySqlManager::getId(self::ART_TABLE), array('title'=>$asArticle['title']));
if(!$iArticleId)
{
$iArticleId = $this->oMySql->insertRow(self::ART_TABLE, $asArticle);
$this->addMessage($iArticleId, self::MESSAGE_ARTICLE, self::DEFAULT_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()
{
$asArticles = array();
//SCN SAP
$sSAPDomain = 'http://scn.sap.com';
$asBlogPaths = array( '/community/data-warehousing/bw/blog',
'/community/data-warehousing/blog',
'/community/bw-hana/blog',
'/community/businessobjects-design-studio/blog',
'/community/businessobjects-analysis-ms-office/blog');
foreach($asBlogPaths as $sSAPBlogPath)
{
$sSAPBlogUrl = $sSAPDomain.$sSAPBlogPath;
$oDom = $this->getRemotePageDom($sSAPBlogUrl);
$aoArticles = $oDom->getElementsByTagName('header');
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'] = 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;
}
}
}
//BI Portal
$oDom = $this->getRemotePageDom('http://www.biportal.org/sap_bi_blog');
$aoArticles = $oDom->getElementsByTagName('li');
foreach($aoArticles as $oArticle)
{
if($oArticle->getAttribute('class')=='boxesListItem' && $oArticle->getAttribute('id') > 0)
{
$asArticleInfo = array();
$aoLinks = $oArticle->getElementsByTagName('a');
$oLink = $aoLinks->item(0);
$asArticleInfo['link'] = $oLink->getAttribute('href');
$asArticleInfo['title'] = trim($oLink->nodeValue);
$aoLinks = $oArticle->getElementsByTagName('span');
foreach($aoLinks as $oLink)
{
switch($oLink->getAttribute('class'))
{
case 'postedOn':
$asArticleInfo['date'] = date(self::DATE_SQL_FORMAT, strtotime($oLink->nodeValue));
break;
case 'postedByLink':
$sName = trim($oLink->firstChild->nodeValue);
$asArticleInfo['first_name'] = strstr($sName, ' ', true);
$asArticleInfo['last_name'] = substr(strstr($sName, ' '), 1);
$asArticleInfo['email'] = $oLink->firstChild->getAttribute('href');
break;
}
}
$asArticles[] = $asArticleInfo;
}
}
//SAP BW BW
$oDom = $this->getRemotePageDom('http://sapbwbw.com/');
$aoArticles = $oDom->getElementsByTagName('header');
foreach($aoArticles as $oArticle)
{
if($oArticle->getAttribute('class')=='entry-header')
{
$asArticleInfo = array();
$aoLinks = $oArticle->getElementsByTagName('a');
$oLink = $aoLinks->item(0);
$asArticleInfo['link'] = $oLink->getAttribute('href');
$asArticleInfo['title'] = trim($oLink->nodeValue);
$aoLinks = $oArticle->getElementsByTagName('time');
$oLink = $aoLinks->item(0);
$asArticleInfo['date'] = mb_substr($oLink->getAttribute('datetime'), 0, 10);
$asArticleInfo['first_name'] = 'Claudio';
$asArticleInfo['last_name'] = 'Ciardelli';
$asArticleInfo['email'] = '';
$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;
}
}
$sUrl = $o9gagImage->getAttribute('src');
$sFilePath = self::DOC_TMP_FOLDER.uniqid();
$asResult = ToolBox::createThumbnail($sUrl, self::CHAT_IMG_MAX_WIDTH, self::CHAT_IMG_MAX_HEIGHT, $sFilePath, false, array());
if($asResult['error']=='')
{
$asPost['url_img'] = $asResult['out'];
$asPost['width'] = $asResult['width'];
$asPost['height'] = $asResult['height'];
}
else $asPost['error'] = $asResult['error'];
return $asPost;
}
private function getRemotePageDom($sUrl)
{
$oDom = new DOMDocument();
if(mb_substr($sUrl, 0, 4)!='http') $sUrl = 'http://'.$sUrl;
@$oDom->loadHTML(file_get_contents($sUrl));
return $oDom->getElementsByTagName('body')->item(0);
}
public function getNote($iNote)
{
$this->oClassManagement->incClass('note');
$oNote = new Note($iNote);
return $oNote->getNote();
}
public function addUser($sFirstName, $sLastName, $sCompany, $sEmail='', $iClearance=self::CLEARANCE_MEMBER, $iUserId=0)
{
$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(self::COMP_TABLE);
$iCompanyId = $this->oMySql->selectInsert(self::COMP_TABLE, array($sCompanyTextCol=>$sCompany, 'logo'=>self::DEFAULT_COMPANY_LOGO), array($sCompanyTextCol));
$asInfo = array('first_name'=>$sFirstName,
'last_name'=>$sLastName,
'active'=>self::MEMBER_ACTIVE,
MySqlManager::getId(self::COMP_TABLE)=>$iCompanyId,
'pass'=>$this->oAuth->HashPassword(self::getLoginToken($sCompany)),
'clearance'=>$iClearance,
'led'=>'0000-00-00 00:00:00');
if($iUserId>0) $asInfo[MySqlManager::getId(self::USER_TABLE)] = $iUserId;
$iUserId = $this->oMySql->insertRow(self::USER_TABLE, $asInfo);
//Options & default values
$sNickName = self::getNickNameFormat($sFirstName);
$this->setOptions(array(self::OPT_NICKNAME=>$sNickName, self::OPT_EMAIL=>$sEmail), true, $iUserId);
//Spread the word
if($iUserId!=self::SYSTEM_USER_ID) $this->addMessage('Nouvel utilisateur: '.self::getNameFormat($sFirstName, $sLastName).' ! Son petit nom sur le chat est '.$sNickName, self::MESSAGE_NEWS, self::DEFAULT_CHAN_ID, self::SYSTEM_USER_ID);
return $iUserId;
}
public function buildCompleteIndex()
{
$this->oMySql->emptyTable(self::SEARCH_TABLE);
foreach($this->getTypeInfo('table') 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(self::CODE_TABLE)=>$sContent,
'description'=>$sDescription,
'id_user'=>$this->getUserId());
$iCodeId = $this->oMySql->insertRow(self::CODE_TABLE, $asInsert);
//insert link if exists
if($sLink!='')
{
$asInsert = array(MySqlManager::getId(self::CODE_TABLE)=>$iCodeId, 'phrase'=>$sLink);
$this->oMySql->insertRow(self::URL_TABLE, $asInsert);
}
//refer id update
$this->oMySql->updateRow(self::CODE_TABLE, $iCodeId, array('refer_id'=>$iCodeId));
//Add message
$this->addMessage($iCodeId, self::MESSAGE_ADD_CODE, self::DEFAULT_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(self::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(self::CODE_TABLE, $asEdit);
//Add message
$this->addMessage($iCodeId, self::MESSAGE_EDIT_CODE, self::DEFAULT_CHAN_ID);
//Add record in Search Table
$this->oSearchEngine->buildIndex($iCodeId, self::CODE_TYPE);
return $iCodeId;
}
public function addProcedure($asPost)
{
$oProcedure = new Procedure($this->oMySql);
$asPost['id_user'] = $this->getUserId();
$oProcedure->inputForm($asPost);
$asErrors = $oProcedure->checkIntegrity();
if(count($asErrors)==0)
{
//Previous procedure Id
$iPrevProcId = isset($asPost['procedure_id'])?$asPost['procedure_id']:0;
//Load procedure into database
$bCreation = $oProcedure->saveProcedure($iPrevProcId);
//Extract extra data
$asProc = $oProcedure->getProcedure();
$iNewProcId = $asProc['proc_id'];
$asUser = $this->getUserInfo();
$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::DEFAULT_CHAN_ID);
}
else
{
$this->addMessage($iNewProcId, self::MESSAGE_EDIT_PROC, self::DEFAULT_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)
{
$oProcedure = new Procedure($this->oMySql);
$oProcedure->loadProcedure($iProcId);
$asProc = $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 = array_key_exists('doc_id', $asPost)?$asPost['doc_id']:0;
$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+)/u';
foreach($asPost as $sFormId=>$sValue)
{
preg_match($sImagePattern, $sFormId, $asMatches);
if(!empty($asMatches) && ($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(self::USER_TABLE)=>$iUserId);
$iDbDocId = $this->oMySql->insertRow(self::DOC_TABLE, $asData);
//Load doc files into database
$asDocData['id_item'] = $iDbDocId;
$asDocData['type'] = self::DOC_TYPE;
foreach($asDocs as $asDocInfo)
{
//insert into database
$sFileName = $asDocInfo['name'];
$asFileInfo = pathinfo($sFileName);
$asDocData['description'] = $asDocInfo['desc'];
$asDocData['hash'] = $asFileInfo['filename'];;
$asDocData['extension'] = $asFileInfo['extension'];
$iDbImageId = $this->oMySql->insertRow(self::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(self::DOC_TABLE, 'refer_id', $iPrevDocId);
$this->oMySql->updateRow(self::DOC_TABLE, $iDbDocId, array('refer_id'=>$iReferId));
//Add Message in chat
$this->addMessage($iDbDocId, $bCreation?self::MESSAGE_ADD_DOC:self::MESSAGE_EDIT_DOC, self::DEFAULT_CHAN_ID);
//Add record in Search Table
$this->oSearchEngine->buildIndex($iDbDocId, self::DOC_TYPE);
//TODO add error handling
return $this->getJsonPostResult(self::SUCCESS, '', array('doc_id'=>$iDbDocId));
}
public function getDoc($iDocId)
{
//Extract doc data
$asDoc = $this->oMySql->selectRow(self::DOC_TABLE, $iDocId);
$bSuccess = !empty($asDoc);
$sDesc = '';
if(!$bSuccess) $sDesc = self::NOT_FOUND;
else
{
$asDoc['description'] = self::getDescriptionFormat($asDoc['description']);
$asDoc['title'] = self::getDescriptionFormat($asDoc['title']);
$asDoc['led'] = self::getDateFormat($asDoc['led']);
//Extract extra data
$asUser = $this->getUserInfo($asDoc[MySqlManager::getId(self::USER_TABLE)]);
$asDoc['name'] = $asUser['name'];
$asDoc['company'] = $asUser['company'];
//Extract doc files
$sFileIdCol = MySqlManager::getId(self::FILE_TABLE);
$asFiles = $this->oMySql->selectRows(array('from'=>self::FILE_TABLE, 'constraint'=>array('id_item'=>$iDocId, 'type'=>self::DOC_TYPE)));
foreach($asFiles as $asFile)
{
$asDoc['files'][$asFile[$sFileIdCol]] = array( 'description' => self::getDescriptionFormat($asFile['description']),
'ext' => $asFile['extension']);
}
}
return $this->getJsonPostResult($bSuccess, $sDesc, $asDoc);
}
public function addTable($sSystem, $sTitle, $sDescription, $sKeyWords, $iPrevTableId, $bSimul=false)
{
$bCreation = ($iPrevTableId==0);
$iDbTableId = 0;
$sDesc = '';
//Previous table info
if(!$bCreation) $asPrevTableInfo = $this->getTableInfo($iPrevTableId, false);
//New table info
$sTitle = mb_strtolower($bCreation?trim($sTitle):$asPrevTableInfo['title']);
$sDescription = mb_strtolower(trim($sDescription));
//Check for existing table with the same name
if($bCreation && $this->checkValue(self::TABL_TABLE, array('title'=>$sTitle))) $sDesc = ToolBox::findReplaceLinks('Une documentation existe déjà pour la table '.self::getTableFormat($sTitle));
elseif(!$bCreation && $iPrevTableId!=$this->getUpToDateId(self::TABL_TABLE, $sTitle)) $sDesc = ToolBox::findReplaceLinks('Une version plus récente de la table '.self::getTableFormat($sTitle).' existe');
elseif(!$bSimul)
{
//Load table into database
$asData = array(MySqlManager::getId(self::USER_TABLE)=>$this->getUserId(), 'title'=>$sTitle, 'description'=>$sDescription, 'system'=>$sSystem, 'keywords'=>$sKeyWords);
$iDbTableId = $this->oMySql->insertRow(self::TABL_TABLE, $asData);
if(!$iDbTableId) $sDesc = 'Erreur inconnue dans la base de données';
else
{
//Add the group refer id
$iReferId = $bCreation?$iDbTableId:$this->oMySql->selectValue(self::TABL_TABLE, 'refer_id', $iPrevTableId);
$this->oMySql->updateRow(self::TABL_TABLE, $iDbTableId, array('refer_id'=>$iReferId));
//Add Message in chat
$this->addMessage($iDbTableId, $bCreation?self::MESSAGE_ADD_TABLE:self::MESSAGE_EDIT_TABLE, self::DEFAULT_CHAN_ID);
//Add record in Search Table
$this->oSearchEngine->buildIndex($iDbTableId, self::TABLE_TYPE);
}
}
return $this->getJsonPostResult($iDbTableId>0, $sDesc, array('id'=>$iDbTableId, 'name'=>$sTitle));
}
public function getTable($oTableId)
{
$bReadById = is_numeric($oTableId);
$iTableId = $bReadById?$oTableId:$this->getUpToDateId(self::TABL_TABLE, mb_strtolower($oTableId));
//Extract table data
$asTable = $this->getTableInfo($iTableId);
$bSuccess = !empty($asTable);
$sDesc = '';
if($bSuccess)
{
$asTable['date'] = self::getDateFormat($asTable['timestamp'], self::DATE_FORMAT);
$asTable['title'] = $asTable['table_name'];
unset($asTable['timestamp']);
$asTable['id'] = $asTable[MySqlManager::getId(self::TABL_TABLE)];
//Extract extra data
$asUser = $this->getUserInfo($asTable[MySqlManager::getId(self::USER_TABLE)]);
$asTable['name'] = $asUser['name'];
$asTable['company'] = $asUser['company'];
//Out of date warning
$sRightTableLink = ToolBox::findReplaceLinks('Il existe une documentation plus à jour pour la table '.self::getTableFormat($asTable['title']));
$asTable['warning'] = ($bReadById && $iTableId!=$this->getUpToDateId(self::TABL_TABLE, $iTableId))?$sRightTableLink:'';
}
else $sDesc = self::NOT_FOUND;
return $this->getJsonPostResult($bSuccess, $sDesc, $asTable);
}
//TODO good idea ? If yes, apply to all types. Put in MySqlManager ? involve switchCodeId()
private function getUpToDateId($sTableName, $oId)
{
if(is_numeric($oId)) $asConstraint = array('refer_id'=>$this->oMySql->selectValue(self::TABL_TABLE, 'refer_id', $oId)); //by Id
else $asConstraint = array('title'=>$oId); //by phrase
$sItemIdCol = 'id_item';
$asInfo = array('select'=>array("MAX(".MySqlManager::getId($sTableName).") AS ".$sItemIdCol), //selecting last version among codes having the same refer_id
'from'=>$sTableName,
'constraint'=>$asConstraint,
'groupBy'=>array('refer_id'),
'orderBy'=>array($sItemIdCol=>'desc'));
$asResult = $this->oMySql->selectRows($asInfo);
return array_shift($asResult);
}
public function getFile($iFileId)
{
//File info
$asFileInfo = $this->oMySql->selectRow(self::FILE_TABLE, $iFileId);
$sFileExt = $asFileInfo['extension'];
$sFileDesc = str_replace("&", '\&', str_replace(" ", '\ ', addslashes($asFileInfo['description']))).'.'.$sFileExt;
$sFilePath = self::DOC_FOLDER.$asFileInfo['hash'].'.'.$asFileInfo['extension'];
$sFileFullPath = dirname($_SERVER['SCRIPT_FILENAME'])."/".$sFilePath;
$sResult = '';
if(!file_exists($sFilePath)) header("HTTP/1.0 404 Not Found");
else
{
//Get mime type & set headers
if(!class_exists('finfo')) $sMimetype = 'application/force-download';
else
{
$oFileInfo = new finfo(FILEINFO_MIME);
$sMimetype = $oFileInfo->file($sFileFullPath);
}
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='.$sFileDesc);
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.@filesize($sFilePath));
//Download
if ($oFile = @fopen($sFilePath, 'rb'))
{
while(!feof($oFile))
{
$sResult .= print_r(fread($oFile, 1024*8), true);
flush();
if(connection_status() != 0) @fclose($oFile);
}
@fclose($oFile);
}
}
return $sResult;
}
public function uploadFile($sFileType)
{
switch($sFileType)
{
case 'image': $asAuthorizedTypes = self::$UPLOAD_IMG_EXTS; break;
case 'doc' : $asAuthorizedTypes = self::$UPLOAD_DOC_EXTS; break;
default : $asAuthorizedTypes = array();
}
$this->oClassManagement->incClass('fileuploader');
$oFileUploader = new fileUploader(self::DOC_TMP_FOLDER, $asAuthorizedTypes);
$asResult = $oFileUploader->handleUpload();
return $this->jsonConvert($asResult);
}
private function getItemInfo($sType, $iItemId)
{
return call_user_func(array($this, 'get'.ucfirst($this->getPagesFromHash($sType)).'Info'), $iItemId);
}
//TODO: one function only with a type parameter
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 = $this->oMySql->getTablecolumns(self::CODE_TABLE);
unset($asSelect[MySqlManager::getText(self::CODE_TABLE)]);
$asSelect = array_keys($asSelect);
}
else
{
$asSelect = "*";
}
$asCode = $this->oMySql->selectRow(self::CODE_TABLE, $iCodeId, $asSelect);
$asCode['title'] = self::getDescriptionFormat($asCode['description']);
$asCode['description'] = self::getDescriptionFormat($asCode['description']);
$asCode['timestamp'] = strtotime($asCode['led']);
$asCode['led'] = self::getDateFormat($asCode['led']);
return $asCode;
}
private function getProcedureInfo($iProcId)
{
$asProc = $this->oMySql->selectRow(self::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(self::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 getTableInfo($iTableId, $bFormatting=true)
{
$asTable = $this->oMySql->selectRow(self::TABL_TABLE, $iTableId);
if(!empty($asTable))
{
$asTable['timestamp'] = strtotime($asTable['led']);
if($bFormatting)
{
$asTable['system'] = self::getTableFormat($asTable['system']);
$asTable['description'] = self::getDescriptionFormat($asTable['description']);
$asTable['table_name'] = self::getTableFormat($asTable['title']);
$asTable['title'] = self::getTableFormat($asTable['title']).' - '.$asTable['description'];
$asTable['led'] = self::getDateFormat($asTable['led']);
$asTable['formated_keywords'] = ToolBox::formatText($asTable['keywords']);
}
}
return $asTable;
}
private function getArticleInfo($iArtId)
{
$asArt = $this->oMySql->selectRow(self::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['title'] = self::getDescriptionFormat($asArt['title']);
$asTransferredInfo['description'] = self::getDescriptionFormat($asArt['title']);
$asTransferredInfo['timestamp'] = strtotime($asArt['led']);
$asTransferredInfo['led'] = self::getDateFormat($asArt['led']);
//Domain
$asParsedUrl = parse_url($asArt['link']);
$asTransferredInfo['domain'] = $asParsedUrl['host'];
$asTransferredInfo['company'] = $asTransferredInfo['domain'];
return $asTransferredInfo;
}
public function getUserInfo($iUserId=-1, $bJson=false)
{
$asUserInfo = array();
if($iUserId==-1) $iUserId = $this->getUserId();
if(array_key_exists($iUserId, $this->asUsersInfo)) $asUserInfo = $this->asUsersInfo[$iUserId];
else
{
$this->setUserInfo($iUserId);
$asUserInfo = $this->getUserInfo($iUserId);
}
return $bJson?$this->jsonExport($asUserInfo):$asUserInfo;
}
private function setUserInfo($iUserId=-1)
{
if($iUserId==-1) $iUserId = $this->getUserId();
if($iUserId>0)
{
$asRow = $this->oMySql->selectRow(self::USER_TABLE, $iUserId);
if(empty($asRow))$this->addError('Unknown user id: '.$iUserId);
else
{
$sEmail = $this->getUserOptionValue(self::OPT_EMAIL, $iUserId);
$asCompany = $this->oMySql->selectRow(self::COMP_TABLE, $asRow[MySqlManager::getId(self::COMP_TABLE)]);
$this->asUsersInfo[$iUserId] = array( 'name'=>self::getNameFormat($asRow['first_name'], $asRow['last_name']),
'nickname'=>self::getNickNameFormat($this->getChatNickNames($iUserId)),
'email'=>$sEmail,
'company'=>self::getCompanyFormat($asCompany[MySqlManager::getText(self::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));
}
}
}
private function getUserClearance()
{
$asUserInfo = $this->getUserInfo();
return $asUserInfo['clearance'];
}
public function checkUserClearance($iClearance)
{
return ($this->getUserClearance() >= $iClearance);
}
/* Options Management */
//TODO Create class
private function getAvailableOptions()
{
$sOptNameIdCol = MySqlManager::getId(self::OPTNAME_TABLE);
$sOptNameTextCol = MySqlManager::getText(self::OPTNAME_TABLE);
$asInfo = array('select'=>array($sOptNameIdCol, $sOptNameTextCol, 'type'),
'from'=>self::OPTNAME_TABLE,
'constraint'=>array('language'=>$this->sLanguage));
return $this->oMySql->selectRows($asInfo, true, $sOptNameIdCol);
}
private function getDefaultOptionValue($sOptionNameId)
{
$asDefaultOptions = $this->getDefaultOptionValues($sOptionNameId);
$asOptionInfo = array_shift($asDefaultOptions);
return $asOptionInfo[MySqlManager::getText(self::OPTVAL_TABLE)];
}
private function getDefaultOptionValues($oOptionNameIds=array(), $bOptValId=true)
{
$sOptNameIdCol = MySqlManager::getId(self::OPTNAME_TABLE);
$sOptValIdCol = MySqlManager::getId(self::OPTVAL_TABLE);
$sOptValueTextCol = MySqlManager::getText(self::OPTVAL_TABLE);
if(!is_array($oOptionNameIds)) $oOptionNameIds = array($oOptionNameIds);
elseif(empty($oOptionNameIds)) $oOptionNameIds = array_keys($this->getAvailableOptions());
$asInfo = array('select' => array($sOptNameIdCol, $sOptValueTextCol),
'from' => self::OPTVAL_TABLE,
'constraint'=> array('default_value'=>true, $sOptNameIdCol => "(".implode(", ", $oOptionNameIds).")"),
'constOpe' => array('default_value'=>"=", $sOptNameIdCol=>" IN "),
'constVar' => true);
if($bOptValId) $asInfo['select'][] = $sOptValIdCol;
return $this->oMySql->selectRows($asInfo, true, $sOptNameIdCol);
}
private function getUserOptionValue($sOptionNameId, $iUserId=0)
{
$asUserOptions = $this->getUserOptions($sOptionNameId, $iUserId);
$asOptionInfo = array_shift($asUserOptions);
return $asOptionInfo[MySqlManager::getText(self::OPTVAL_TABLE)];
}
private function getUserOptions($oOptionNameIds=array(), $iUserId=0)
{
$iUserId = $iUserId>0?$iUserId:$this->getUserId();
$sUserIdCol = MySqlManager::getId(self::USER_TABLE);
$sOptNameIdCol = MySqlManager::getId(self::OPTNAME_TABLE);
$sOptNameIdColOptTable = MySqlManager::getFullColumnName(self::OPT_TABLE, $sOptNameIdCol);
$sOptValueIdCol = MySqlManager::getId(self::OPTVAL_TABLE);
$sOptValueIdColOptTable = MySqlManager::getFullColumnName(self::OPT_TABLE, $sOptValueIdCol);
$sOptValueTextCol = MySqlManager::getText(self::OPTVAL_TABLE);
$sOptIdCol = MySqlManager::getId(self::OPT_TABLE);
if(!is_array($oOptionNameIds)) $oOptionNameIds = array($oOptionNameIds);
elseif(empty($oOptionNameIds)) $oOptionNameIds = array_keys($this->getAvailableOptions());
$asUserinfo = array('select' => array($sOptIdCol, $sOptNameIdColOptTable, $sOptValueIdColOptTable, $sOptValueTextCol),
'from' => self::OPT_TABLE,
'join' => array(self::OPTVAL_TABLE=>MySqlManager::getId(self::OPTVAL_TABLE)),
'constraint'=> array($sUserIdCol=>$iUserId, $sOptNameIdColOptTable => "(".implode(", ", $oOptionNameIds).")"),
'constOpe' => array($sUserIdCol=>"=", $sOptNameIdColOptTable => " IN "),
'constVar' => true);
$asOptions = $this->oMySql->selectRows($asUserinfo, true, $sOptNameIdCol);
//No user value: adding default value to user values
$asDefaultOptions = $this->getDefaultOptionValues();
foreach($oOptionNameIds as $iOptionNameId)
{
if(!array_key_exists($iOptionNameId, $asOptions)) $asOptions[$iOptionNameId] = $asDefaultOptions[$iOptionNameId];
}
return $asOptions;
}
public function getOptions()
{
$sOptNameTextCol = MySqlManager::getText(self::OPTNAME_TABLE);
$sOptValueIdCol = MySqlManager::getId(self::OPTVAL_TABLE);
$sOptValueTextCol = MySqlManager::getText(self::OPTVAL_TABLE);
//Available Options
$asAvailableOptions = $this->getAvailableOptions();
//User options
$asUserOptions = $this->getUserOptions();
//Build Options panel
$asSelectedOptions = array();
foreach($asAvailableOptions as $sOptNameId=>$asOption)
{
$sOptionName = self::getDescriptionFormat($asOption[$sOptNameTextCol]);
$asSelectedOptions[$sOptionName]['option_id'] = $sOptNameId;
$asSelectedOptions[$sOptionName]['option_name'] = $sOptionName;
$asSelectedOptions[$sOptionName]['user_value_id'] = $asUserOptions[$sOptNameId][$sOptValueIdCol];
$asSelectedOptions[$sOptionName]['user_value'] = $asUserOptions[$sOptNameId][$sOptValueTextCol];
$asSelectedOptions[$sOptionName]['type'] = $asOption['type'];
if($asOption['type']==self::OPT_SELECT)
{
$asOptionValuesInfo = array('select'=>array($sOptValueIdCol, $sOptValueTextCol),
'from'=>self::OPTVAL_TABLE,
'constraint'=>array('language'=>$this->sLanguage, MySqlManager::getId(self::OPTNAME_TABLE)=>$sOptNameId),
'orderBy'=>array('led'=>'ASC'));
$asSelectedOptions[$sOptionName]['select'] = $this->oMySql->selectRows($asOptionValuesInfo, true, $sOptValueIdCol);
}
}
ksort($asSelectedOptions);
return $this->jsonExport($asSelectedOptions);
}
public function setOptions($asNewOptions, $bSilentUpdate=true, $iUserId=0)
{
$sOptIdCol = MySqlManager::getId(self::OPT_TABLE);
$sOptValueIdCol = MySqlManager::getId(self::OPTVAL_TABLE);
$sOptValueTextCol = MySqlManager::getText(self::OPTVAL_TABLE);
$sUserIdCol = MySqlManager::getId(self::USER_TABLE);
$sOptNameIdCol = MySqlManager::getId(self::OPTNAME_TABLE);
$iUserId = ($iUserId>0)?$iUserId:$this->getUserId();
$asAvailableOptions = $this->getAvailableOptions();
$asUserOptions = $this->getUserOptions(array_keys($asAvailableOptions), $iUserId);
$asDefaultOptions = $this->getDefaultOptionValues(array_keys($asAvailableOptions));
foreach($asAvailableOptions as $sOptNameId=>$asOption)
{
if(array_key_exists($sOptNameId, $asNewOptions))
{
$sUserValue = $asUserOptions[$sOptNameId][$sOptValueTextCol];
$sUserValueId = $asUserOptions[$sOptNameId][$sOptValueIdCol];
$sUserOptId = array_key_exists($sOptIdCol, $asUserOptions[$sOptNameId])?$asUserOptions[$sOptNameId][$sOptIdCol]:0;
$sDefaultValue = $asDefaultOptions[$sOptNameId][$sOptValueTextCol];
$sDefaultValueId = $asDefaultOptions[$sOptNameId][$sOptValueIdCol];
if(!$sDefaultValueId) $this->addError('Missing option default value for option id='.$sOptNameId);
switch($asOption['type'])
{
case self::OPT_SELECT:
$sNewValueId = $asNewOptions[$sOptNameId];
$sNewValue = $this->oMySql->selectValue(self::OPTVAL_TABLE, $sOptValueTextCol, $sNewValueId);
break;
case self::OPT_TEXT:
$sNewValue = $asNewOptions[$sOptNameId];
break;
}
//Update text
if($sNewValue!=$sUserValue)
{
//Clear user values if exist (back to default)
if(($sNewValue=='' || $sNewValue==$sDefaultValue) && $sUserOptId>0)
{
$this->oMySql->deleteRow(self::OPT_TABLE, $sUserOptId);
if($asOption['type']==self::OPT_TEXT) $this->oMySql->deleteRow(self::OPTVAL_TABLE, $sUserValueId);
}
//New or updated value
elseif($sNewValue!=$sDefaultValue)
{
//Update option values table
if($asOption['type']==self::OPT_TEXT)
{
$asData = array($sOptNameIdCol=>$sOptNameId, $sOptValueTextCol=>$sNewValue, 'language'=>$this->sLanguage);
if($sUserValueId==$sDefaultValueId) $sNewValueId = $this->oMySql->insertRow(self::OPTVAL_TABLE, $asData);
else $sNewValueId = $this->oMySql->updateRow(self::OPTVAL_TABLE, $sUserValueId, array($sOptValueTextCol=>$sNewValue));
}
//Update option table
$asKeys = array($sUserIdCol=>$iUserId, $sOptNameIdCol=>$sOptNameId);
$asData = array($sOptValueIdCol=>$sNewValueId) + $asKeys;
$this->oMySql->insertUpdateRow(self::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::DEFAULT_CHAN;
$sMessage = $sUserValue.' a chang&eacute; son pseudo en '.$sNewValue;
break;
case self::OPT_STATUS:
$sType = self::MESSAGE_STATUS;
$sChanName = self::DEFAULT_CHAN;
$sMessage = 'est sur une nouvelle mission : '.$this->getDescriptionFormat($sNewValue);
break;
default:
continue 2;
}
$sChanId = $this->getChanId($sChanName);
$this->addMessage($sMessage, $sType, $sChanId);
}
}
}
}
}
public function getProfile($oUser)
{
switch($oUser)
{
case '':
$iUserId = $this->getUserId();
break;
case is_numeric($oUser):
$iUserId = $oUser;
break;
default:
$iUserId = $this->getUserId();
break;
}
//User Info
$asProfile['user'] = $this->getUserInfo($iUserId);
unset($asProfile['user']['email']);
unset($asProfile['user']['clearance']);
//History Info
$asTables = $this->getTypeInfo('table');
unset($asTables[self::ART_TYPE]); //Skip articles
foreach($asTables as $sType=>$sTableName)
{
//Add Text
$sText = mb_strtolower($this->getPageTitles($this->getPagesFromHash($sType)));
if(!$sText) $this->addError('Pas de texte pour le type "'.$sType.'"');
//Loop through items
$asSqlInfo = array('select'=>MySqlManager::getId($sTableName), 'from'=>$sTableName, 'constraint'=>array(MySqlManager::getId(self::USER_TABLE)=>$iUserId));
$asHistory = $this->oMySql->selectRows($asSqlInfo);
foreach($asHistory as $iItemId)
{
$asInfo = $this->getItemInfo($sType, $iItemId);
$sKey = $asInfo['timestamp'].$sType.$iItemId;
$asProfile['history'][$sKey]['type'] = $sType;
$asProfile['history'][$sKey]['id'] = $iItemId;
$asProfile['history'][$sKey]['action'] = (($asInfo['refer_id']==$iItemId)?'Cr&eacute;ation':'Modification').' de '.$sText;
$asProfile['history'][$sKey]['date'] = $asInfo['led'];
$asProfile['history'][$sKey]['title'] = $asInfo['title'];
}
}
if(array_key_exists('history', $asProfile)) krsort($asProfile['history']);
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+)/u', $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(self::COMP_TABLE), 'from'=>self::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())
{
$bSuccess = false;
$sDesc = '';
$asVars = array();
$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(self::USER_TABLE);
$sChanIdCol = MySqlManager::getId(self::CHAN_TABLE);
$asData = array('safe_name'=>$sSafeChanName, MySqlManager::getText(self::CHAN_TABLE)=>$sChanName);
$iChanId = $this->oMySql->insertUpdateRow(self::CHAN_TABLE, $asData, array('safe_name'), false);
//Is user already connected to this chan
$bConnectedUser = $this->isUserConnected($iChanId);
$iConnId = $this->oMySql->insertUpdateRow(self::CONN_TABLE, array($sUserIdCol=>$this->getUserId(), $sChanIdCol=>$iChanId), array($sUserIdCol, $sChanIdCol), false);
if($iConnId>0) $bSuccess = true;
if($bSuccess)
{
//Return connected channels
$asVars['channels'] = $this->getChannels($this->getUserId());
//Add tab title (customized)
//FIXME delete this shit and insert the channel type into channels DB table
foreach($asVars['channels'] as $iConnectedChanId=>$sConnectedChanName)
{
$asPm = $this->isPmChan($sConnectedChanName);
$asVars['channel_tab_names'][$iConnectedChanId] = $asPm['is_pm']?$this->getChatNickNames($asPm['from']==$this->getUserId()?$asPm['to']:$asPm['from']):$sConnectedChanName;
}
$asVars['current_chan_id'] = $iChanId;
//Communicate on user's connection
if(!$bConnectedUser)
{
$asMessages[$iChanId] = $this->oMySql->selectValue(self::CHAN_TABLE, MySqlManager::getText(self::CHAN_TABLE), $iChanId);
}
$sStatus = $this->getUserOptionValue(self::OPT_STATUS);
$asUserInfo = $this->getUserInfo();
foreach($asMessages as $iChanId=>$sMsgChanName)
{
$asPm = $this->isPmChan($sMsgChanName);
$this->addMessage(' de '.$asUserInfo['company'].' ('.$this->getDescriptionFormat($sStatus).') rejoint '.($asPm['is_pm']?'le chan priv&eacute;':'#'.$sMsgChanName), self::MESSAGE_CONN, $iChanId);
}
//Send invites to attendees
if(!empty($asAttendees))
{
foreach($asAttendees as $sAttendee)
{
if($this->checkChanAuth($sSafeChanName, $sAttendee))
{
$this->addMessage($sAttendee, self::MESSAGE_INVITE, $iChanId);
}
}
}
//Update chan leds
$this->pingChans();
}
else $sDesc = self::FAIL_UPDATE;
}
else $sDesc = 'Nom de chan non autorisé (nom de personne / nom de société interdit)';
return self::getJsonPostResult($bSuccess, $sDesc, $asVars);
}
private function isUserConnected($iChanId=0, $iUserId=0)
{
$iUserId = $iUserId>0?$iUserId:$this->getUserId();
$sUserIdCol = MySqlManager::getId(self::USER_TABLE);
$asInfo = array('select' => MySqlManager::getId(self::CONN_TABLE),
'from' => self::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(self::CHAN_TABLE)] = $iChanId;
$asInfo['constOpe'][MySqlManager::getId(self::CHAN_TABLE)] = '=';
}
return (count($this->oMySql->selectRows($asInfo))>0);
}
public function pingChans()
{
$aiConstraints = array(MySqlManager::getId(self::USER_TABLE)=>$this->getUserId());
$asUpdates = array('led'=>date(self::DATE_TIME_SQL_FORMAT));
$this->oMySql->updateRows(self::CONN_TABLE, $aiConstraints, $asUpdates);
}
public function quitChan($sChanName)
{
$iChanId = $this->getChanId($sChanName);
$iConnId = $this->getConnId($iChanId);
if($iConnId>0)
{
$this->oMySql->deleteRow(self::CONN_TABLE, $iConnId);
$asPm = $this->isPmChan($sChanName);
$this->addMessage('quitte '.($asPm['is_pm']?'le chan priv&eacute;':'#'.$sChanName), self::MESSAGE_CONN, $iChanId);
}
}
public function inviteChan($iUserId, $sChanName)
{
$sSafeChanName = $this->getChanSafeName($sChanName);
$bSuccess = false;
if($iUserId>0 && $this->checkChanAuth($sSafeChanName, $iUserId))
{
$sType = self::MESSAGE_INVITE;
$sMessage = $iUserId;
$sChanId = $this->getChanId($sChanName);
$bSuccess = $this->addMessage($sMessage, $sType, $sChanId);
if($bSuccess) $sDesc = 'Invitation envoyée';
}
else $sDesc = 'Désolé, cette personne n\'est pas autorisé sur ce channel';
return $this->getJsonPostResult($bSuccess, $sDesc);
}
private function getActiveChannels()
{
//Get connected users
$asActiveChanUsers = $this->getConnectedUsers(false, false);
$asActiveChans = array_keys($asActiveChanUsers);
//Get Channel names
$sChanIdCol = MySqlManager::getId(self::CHAN_TABLE);
$asChanNames = $this->oMySql->selectRows(array('select'=>array($sChanIdCol, MySqlManager::getText(self::CHAN_TABLE)), 'from'=>self::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(self::CHAN_TABLE, true);
$sChanNameCol = MySqlManager::getText(self::CHAN_TABLE);
$asInfo = array('select'=>array($sChanIdCol, $sChanNameCol),
'from'=> self::CONN_TABLE,
'join'=> array(self::CHAN_TABLE=>MySqlManager::getId(self::CHAN_TABLE)),
'orderBy'=> array(MySqlManager::getId(self::CONN_TABLE)=>'ASC'));
if($iUserId > 0) $asInfo['constraint'] = array(MySqlManager::getId(self::USER_TABLE)=>$iUserId);
$asChannels = $this->oMySql->selectRows($asInfo, true, MySqlManager::getId(self::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(self::CHAN_TABLE);
$sSafeChanName = self::getChanSafeName($sChanName);
$iChanId = $this->oMySql->selectValue(self::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(self::USER_TABLE);
$sConnIdCol = MySqlManager::getId(self::CONN_TABLE);
$sChanIdCol = MySqlManager::getId(self::CHAN_TABLE);
if($iUserId==0) $iUserId = $this->getUserId();
$iConnId = $this->oMySql->selectValue(self::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 &agrave; '.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&eacute; son pseudo en '.$sNewNick;
}
elseif(mb_substr($sMessage, 0, 9) == '/mission ' && mb_strlen($sMessage)>9)
{
$sNewStatus = mb_substr($sMessage, 9);
$sNewFormatStatus = $sNewStatus;
//changing Nickname
$this->setOptions(array(self::OPT_STATUS=>$sNewStatus));
//Message
$sType = self::MESSAGE_STATUS;
$sChanName = self::DEFAULT_CHAN;
$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>.*)/u';
preg_match($sImagePattern, $sMessage, $asMatches);
//Looking for user Id
$iUserIdTo = $this->getUserIdFromNickName($asMatches['nickname']);
//Handling mail
if($iUserIdTo>0)
{
if(trim($asMatches['message'])!='')
{
if($this->sendPM($iUserIdTo, $asMatches['message']))
{
$sMessage = 'a envoy&eacute; un mail &agrave; '.$asMatches['nickname'];
}
else
{
$sMessage = 'n\'a pas envoy&eacute; de mail &agrave; '.$asMatches['nickname'].' (raison inconnue, voir log)';
}
}
else
{
$sMessage = 'n\'a pas envoy&eacute; de mail &agrave; '.$asMatches['nickname'].' (message vide)';
}
}
else
{
$sMessage = 'n\'a pas envoy&eacute; de mail &agrave; '.$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&eacute;vrier', 'mars', 'avril', 'mai', 'juin', 'juillet', 'ao&ucirc;t', 'septembre', 'octobre', 'novembre', 'd&eacute;cembre');
$sMessage = ' a demand&eacute; 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&eacute; les chans disponibles. Pour sa gouverne, les chans ayant des membres connect&eacute;s sont #'.MySqlManager::implodeAll($this->getActiveChannels(), ' (', ', #', '', ')');
$sType = self::MESSAGE_ACTION;
}
elseif((mb_substr($sMessage, 0, 5) == '/img ' || mb_substr($sMessage, 0, 5) == '/pic ') && 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->checkUserClearance(self::CLEARANCE_ADMIN))
{
$sMessage = 'L\'administrateur a demand&eacute; un reboot. Votre page va se rafraichir automatiquement dans '.self::REBOOT_DELAY.' secondes.';
$sType = self::MESSAGE_REBOOT;
$sChanName = self::ALL_CHAN_TEXT;
}
elseif(mb_substr($sMessage, 0, 6) == '/news ' && mb_strlen($sMessage)>6)
{
$sType = self::MESSAGE_NEWS;
$sMessage = trim(substr($sMessage, 5));
}
}
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)
{
$sFilePath = self::DOC_TMP_FOLDER.uniqid();
return ToolBox::createThumbnail($sUrl, self::CHAT_IMG_MAX_WIDTH, self::CHAT_IMG_MAX_HEIGHT, $sFilePath, false, self::$UPLOAD_IMG_EXTS);
}
private function sendPM($iUserIdTo, $sMessage)
{
$bSuccess = false;
$asUserFrom = $this->getUserInfo();
$asUserTo = $this->getUserInfo($iUserIdTo);
$sFrom = $asUserFrom['name'].' <www-data@lutran.fr>';
$sTo = $asUserTo['name'].' <'.$asUserTo['email'].'>';
$sMessage .= "\n\n\n".'<i>Ne r&eacute;pondez pas &agrave; ce mail. Connectez-vous sur <a href="http://databap.lutran.fr/#chat">Databap</a>.</i>';
$sResult = ToolBox::sendMail($sFrom, 'Databap PM', $sMessage, $sTo, array(), false);
$bSuccess = ($sResult==ToolBox::MAIL_SUCCESS);
if(!$bSuccess) $this->addError($sResult);
return $bSuccess;
}
private function addMessage($sMessage, $sType, $iChanId, $iUserId=0)
{
$bResult = false;
$iUserId = ($iUserId>0)?$iUserId:$this->getUserId();
if($iChanId>0)
{
$asInsert = array( MySqlManager::getId(self::USER_TABLE) => $iUserId,
'nickname' => $this->getChatNickNames($iUserId),
MySqlManager::getId(self::CHAN_TABLE) => $iChanId,
MySqlManager::getText(self::MSG_TABLE) => $sMessage,
'type' => $sType,
'date' => 'CURDATE()');
$bResult = $this->oMySql->insertRow(self::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(self::CHAN_TABLE, true);
$sChanTextCol = MySqlManager::getText(self::CHAN_TABLE);
$sMsgIdCol = MySqlManager::getId(self::MSG_TABLE, true);
$sMsgTextCol = MySqlManager::getText(self::MSG_TABLE);
$sMsgTableLed = MySqlManager::getFullColumnName(self::MSG_TABLE, 'led');
$sMsgTableChanIdCol = MySqlManager::getFullColumnName(self::MSG_TABLE, MySqlManager::getId(self::CHAN_TABLE));
$sUserIdCol = MySqlManager::getId(self::USER_TABLE, true);
$sMsgTableUserIdCol = MySqlManager::getFullColumnName(self::MSG_TABLE, MySqlManager::getId(self::USER_TABLE));
$sUserTableUserIdCol = MySqlManager::getId(self::USER_TABLE, true);
$sConnTableUserIdCol = MySqlManager::getFullColumnName(self::CONN_TABLE, MySqlManager::getId(self::USER_TABLE));
$sConnTableChanIdCol = MySqlManager::getFullColumnName(self::CONN_TABLE, MySqlManager::getId(self::CHAN_TABLE));
//User channels related messages
$iCurTimeStamp = time();
$sCurDate = date(Databap::DATE_SQL_FORMAT, $iCurTimeStamp);
$sLimitDate = date(Databap::DATE_SQL_FORMAT, $iCurTimeStamp - $this->getUserOptionValue(self::OPT_CHAT_HISTO)*24*60*60);
$asInfo = array('select' => array($sMsgTableChanIdCol, $sMsgIdCol, $sMsgTextCol, 'type', $sMsgTableLed, 'first_name', 'last_name', $sUserIdCol, 'nickname'),
'from' => self::CONN_TABLE,
'joinOn' => array( self::MSG_TABLE =>array($sMsgTableChanIdCol, '=', $sConnTableChanIdCol),
self::USER_TABLE=>array($sUserTableUserIdCol, '=', $sMsgTableUserIdCol)),
'constraint'=> array($sConnTableUserIdCol=>$this->getUserId(), $sMsgIdCol=>$iFirstMsgId, 'date'=>$sLimitDate),
'constOpe' => array($sConnTableUserIdCol=>'=', $sMsgIdCol=>'>', 'date'=>'>='));
$asSqlMessages = $this->oMySql->selectRows($asInfo, true, 'id_message');
//Global messages
$asInfo['from'] = self::MSG_TABLE;
$asInfo['joinOn'] = array(self::USER_TABLE=>array($sUserTableUserIdCol, '=', $sMsgTableUserIdCol));
$asInfo['constraint'] = array($sMsgTableChanIdCol=>self::ALL_CHAN_ID, $sMsgIdCol=>$iFirstMsgId, 'date'=>$sLimitDate);
$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)
{
//General message info
$iChanId = $asMessageInfo[MySqlManager::getId(self::CHAN_TABLE)];
$iUserId = $asMessageInfo[MySqlManager::getId(self::USER_TABLE)];
$sMessageType = $asMessageInfo['type'];
$asMessages['messages'][$iMessageId]['id_chan'] = $iChanId;
$asMessages['messages'][$iMessageId]['id_user'] = $iUserId;
$asMessages['messages'][$iMessageId]['message'] = $asMessageInfo[$sMsgTextCol];
$asMessages['messages'][$iMessageId]['msg_class'] = $sMessageType;
$asMessages['messages'][$iMessageId]['date'] = self::getDateFormat($asMessageInfo['led'], self::DATE_FORMAT);
$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
switch($sMessageType)
{
case self::MESSAGE_ADD_CODE:
case self::MESSAGE_EDIT_CODE:
$asCode = $this->getCodeInfo($asMessages['messages'][$iMessageId]['message']);
$asMessages['messages'][$iMessageId]['description'] = $asCode['description'];
break;
case self::MESSAGE_ADD_PROC:
case self::MESSAGE_EDIT_PROC:
$asProc = $this->getProcedureInfo($asMessages['messages'][$iMessageId]['message']);
$asMessages['messages'][$iMessageId]['description'] = $asProc['title'];
break;
case self::MESSAGE_ADD_DOC:
case self::MESSAGE_EDIT_DOC:
$asDoc = $this->getDocInfo($asMessages['messages'][$iMessageId]['message']);
$asMessages['messages'][$iMessageId]['description'] = $asDoc['title'];
break;
case self::MESSAGE_ADD_TABLE:
case self::MESSAGE_EDIT_TABLE:
$asTable = $this->getTableInfo($asMessages['messages'][$iMessageId]['message']);
$asMessages['messages'][$iMessageId]['description'] = $asTable['title'];
break;
case self::MESSAGE_ARTICLE:
$asTransferredInfo = $this->getArticleInfo($asMessages['messages'][$iMessageId]['message']);
$asMessages['messages'][$iMessageId] = array_merge($asMessages['messages'][$iMessageId], $asTransferredInfo);
break;
case self::MESSAGE_INVITE: //Switch Chan ID with name for the user to join
$asMessages['messages'][$iMessageId]['id_chan'] = $this->oMySql->selectValue(self::CHAN_TABLE, 'safe_name', $iChanId);
break;
}
//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
{
//Internal links
$asMessages['messages'][$iMessageId]['message'] = Toolbox::findReplaceLinks($asMessages['messages'][$iMessageId]['message']);
//Dynamic chan link
$asPatterns = '/(^|\s)#(\w*[^\s]+\w*)/u';
$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);
}
public function getNews($bExport=true)
{
$sMsgIdCol = MySqlManager::getId(self::MSG_TABLE);
$sMsgTxtCol = MySqlManager::getText(self::MSG_TABLE);
//News
$asInfo['select'] = array($sMsgIdCol, 'nickname', $sMsgTxtCol, 'type', 'led');
$asInfo['from'] = self::MSG_TABLE;
$asInfo['constraint'] = array('type'=>self::MESSAGE_NEWS);
$asInfo['orderBy'] = array('led'=>'DESC');
if($bExport) $asInfo['limit'] = self::MAX_NB_NEWS;
$asNews = $this->oMySql->selectRows($asInfo);
//Status
//$asInfo['select'] = array($sMsgIdCol, 'nickname', "CONCAT(nickname, SPACE(1), ".$sMsgTxtCol." AS ".$sMsgTxtCol, 'led');
$asInfo['constraint'] = array('type'=>self::MESSAGE_STATUS);
$asStatus = $this->oMySql->selectRows($asInfo);
//Sorting
//FIXME find a way to do it in SQL
$asNews = array_merge($asNews, $asStatus);
foreach($asNews as $iKey=>$asNewsInfo) $asNewsSort[$iKey] = strtotime($asNewsInfo['led']);
arsort($asNewsSort);
foreach($asNewsSort as $iKey=>$iTimestamp)
{
if($asNews[$iKey]['type']==self::MESSAGE_STATUS) $asNews[$iKey][$sMsgTxtCol] = $asNews[$iKey]['nickname'].' '.$asNews[$iKey][$sMsgTxtCol];
$asNews2[] = $asNews[$iKey];
if($bExport && count($asNews2)==self::MAX_NB_NEWS) break;
}
$asFormatNews = array();
foreach($asNews2 as $asNew)
{
$iListId = '-'.$asNew[$sMsgIdCol];
$asFormatNews[$iListId][$sMsgIdCol] = $asNew[$sMsgIdCol];
$asFormatNews[$iListId]['time'] = $asNew['led'];
$asFormatNews[$iListId]['time_desc'] = ToolBox::getDateTimeDesc($asNew['led']);
$asFormatNews[$iListId]['message'] = self::getDescriptionFormat($asNew['message']);
$asFormatNews[$iListId]['nickname'] = self::getNickNameFormat($asNew['nickname']);
}
$sSuccess = (count($asFormatNews)>0);
return $bExport?$this->getJsonPostResult($sSuccess, $sSuccess?'':'Aucune news', array('news'=>$asFormatNews)):$asFormatNews;
}
private function getConnectedChans($iuserId=0)
{
$iuserId = $iuserId>0?$iuserId:$this->getUserId();
$sUserIdCol = MySqlManager::getId(self::USER_TABLE);
$asInfo = array('select' => array(MySqlManager::getId(self::CHAN_TABLE, true), MySqlManager::getText(self::CHAN_TABLE)),
'from' => self::CONN_TABLE,
'join' => array(self::CHAN_TABLE=>MySqlManager::getId(self::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(self::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
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
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";
$asUserChannels = $this->oMySql->getArrayQuery($sQuery, true);
//Last messages
$iUserIdCol = MySqlManager::getId(self::USER_TABLE);
$asLastMsg = $this->oMySql->selectRows(array('select'=>array($iUserIdCol, 'MAX(led)'), 'from'=>self::MSG_TABLE), true, $iUserIdCol);
$asConnectedUsers = $asUserOptions = array();
foreach($asUserChannels as $asUser)
{
$sChanId = $asUser[MySqlManager::getId(self::CHAN_TABLE)];
$iUserId = $asUser[$iUserIdCol];
if(!array_key_exists($iUserId, $asUserOptions)) $asUserOptions[$iUserId] = $this->getUserOptions(array(self::OPT_NICKNAME, self::OPT_STATUS), $iUserId);
$sNickName = self::getNickNameFormat($asUserOptions[$iUserId][self::OPT_NICKNAME][MySqlManager::getText(self::OPTVAL_TABLE)]);
$asConnectedUsers[$sChanId][$sNickName.$iUserId]['id_user'] = $iUserId;
$asConnectedUsers[$sChanId][$sNickName.$iUserId]['name'] = self::getNameFormat($asUser['first_name'], $asUser['last_name']);
$asConnectedUsers[$sChanId][$sNickName.$iUserId]['company'] = self::getCompanyFormat($asUser['company']);
$asConnectedUsers[$sChanId][$sNickName.$iUserId]['status'] = $asUserOptions[$iUserId][self::OPT_STATUS][MySqlManager::getText(self::OPTVAL_TABLE)];
$asConnectedUsers[$sChanId][$sNickName.$iUserId]['logo'] = $asUser['logo'];
$asConnectedUsers[$sChanId][$sNickName.$iUserId]['nickname'] = $sNickName;
$asConnectedUsers[$sChanId][$sNickName.$iUserId]['last_activity'] = array_key_exists($iUserId, $asLastMsg)?self::getDateFormat($asLastMsg[$iUserId], self::TIME_FORMAT):'';
$asConnectedUsers[$sChanId][$sNickName.$iUserId]['ping'] = self::getDateFormat($asUser['led'], self::TIME_FORMAT);
$asConnectedUsers[$sChanId][$sNickName.$iUserId]['afk'] = $asUser['afk'];
}
return $bJson?$this->jsonExport($asConnectedUsers):$asConnectedUsers;
}
private function getUserIdFromNickName($sNickName)
{
$asContraints = array( 'LOWER(`'.MySqlManager::getText(self::OPT_TABLE).'`)' => mb_strtolower($sNickName),
MySqlManager::getId(self::OPTNAME_TABLE) => self::OPT_NICKNAME);
return $this->oMySql->selectValue(self::OPT_TABLE, MySqlManager::getId(self::USER_TABLE), $asContraints);
}
private function getChatNickNames($iUserId=0)
{
//TODO use $this->getUserOptionValue();
$sUserIdCol = MySqlManager::getId(self::USER_TABLE);
$sNicknameCol = MySqlManager::getText(self::OPTVAL_TABLE);
$sOptionNameId = MySqlManager::getFullColumnName(self::OPT_TABLE, MySqlManager::getId(self::OPTNAME_TABLE));
$asInfo = array('select'=>array($sUserIdCol, $sNicknameCol),
'from'=>self::OPT_TABLE,
'join'=> array(self::OPTVAL_TABLE=>MySqlManager::getId(self::OPTVAL_TABLE)),
'constraint'=>array($sOptionNameId=>self::OPT_NICKNAME));
if($iUserId>0) $asInfo['constraint'][MySqlManager::getId(self::USER_TABLE)] = $iUserId;
$oResult = $this->oMySql->selectRows($asInfo, true, $sUserIdCol);
if(count($oResult)==1) return $oResult[$iUserId];
return $oResult;
}
private function switchCodeId(&$iCodeId, $sMode)
{
switch($sMode)
{
case 'first':
$iCodeId = $this->oMySql->selectValue(self::CODE_TABLE, 'refer_id', $iCodeId);
break;
case 'last':
$iRefId = $this->oMySql->selectValue(self::CODE_TABLE, 'refer_id', $iCodeId);
$iCodeId = $this->oMySql->selectValue(self::CODE_TABLE, 'MAX(id_code)', array('refer_id'=>$iRefId));
break;
}
}
private function getIdCodeFromPhrase($sPhrase)
{
$iCodeId = $this->oMySql->selectValue(self::URL_TABLE, MySqlManager::getId(self::CODE_TABLE), array('phrase'=>$sPhrase));
$this->switchCodeId($iCodeId, 'last');
return $iCodeId;
}
private function getPhraseFromIdCode($iCodeId)
{
$this->switchCodeId($iCodeId, 'first');
return $this->oMySql->selectValue(self::URL_TABLE, 'phrase', array('id_code'=>$iCodeId));
}
private function getCodeVersions($iRefCodeId)
{
$asCodeVersions = array();
if($iRefCodeId>0)
{
$asInfo = array('select'=>array(MySqlManager::getId(self::CODE_TABLE)),
'from'=>self::CODE_TABLE,
'constraint'=>array('refer_id'=>$iRefCodeId),
'orderBy'=>array('id_code'=>'asc'));
$asCodeIds = $this->oMySql->selectRows($asInfo);
foreach($asCodeIds as $iCodeId)
{
$asCodeVersions[] = $this->getCodeInfo($iCodeId);
}
}
return $asCodeVersions;
}
public function getColoredCode($oCode)
{
$asCode = $this->getCodeInfo($oCode, '', true);
//code
$this->oClassManagement->incClass('reader');
$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, $bPrint=false)
{
$asCode = $this->getCodeInfo($oCode, '', true);
$asUser = $this->getUserInfo($asCode['id_user']);
$sEncodedCode = $this->jsonConvert($asCode['code']);
$sEncodedDesc = $this->jsonConvert($asCode['description']);
$oRawCodePage = new Mask('raw_code');
$oRawCodePage->setTags(array( 'text_enc'=>Settings::TEXT_ENC,
'author'=>$asUser['name'].' ('.$asUser['company'].')',
'content'=>$sEncodedCode,
'title'=>$sEncodedDesc,
'print'=>$bPrint?'true':'false'));
return $oRawCodePage->getMask();
}
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 getItemList()
{
$asUsers = $asItemList = array();
$sIdUserCol = MySqlManager::getId(self::USER_TABLE);
//TODO phrases for all item types?
$asTypeTables = $this->getTypeInfo('table');
foreach($asTypeTables as $sType=>$sTable)
{
//selecting last version among codes having the same refer_id
$sTableIdCol = MySqlManager::getId($sTable);
$asInfo = array('select' => array("MAX({$sTableIdCol}) AS id_item"),
'from' => $sTable,
'groupBy' => array(($sType==self::ART_TYPE)?$sTableIdCol:'refer_id'), //no versioning for articles
'orderBy' => array('id_item'=>'desc'));
//Build code info structure
$asTypedItemIds = array_filter($this->oMySql->selectRows($asInfo)); //null value returned from query (MAX(...))
foreach($asTypedItemIds as $iItemId)
{
//Getting item info
$asItem = $this->getItemInfo($sType, $iItemId);
$asItem['type'] = $sType;
$asItem['id_item'] = $iItemId;
//Replacing user's id with user's name & company (if not done already)
if(array_key_exists($sIdUserCol, $asItem))
{
$iUserId = $asItem[$sIdUserCol];
if(!array_key_exists($iUserId, $asUsers)) $asUsers[$iUserId] = $this->getUserInfo($iUserId);
$asItem['name'] = $asUsers[$iUserId]['name'];
$asItem['company'] = $asUsers[$iUserId]['company'];
}
//Preparing key for reverse sorting
$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');
$oMask->setTag('item', $this->getItemBlock());
return $oMask->getMask();
}
private function getItemBlock()
{
$oMask = new Mask('item');
return $oMask->getMask();
}
public function logMeIn($sToken, $sAction)
{
$iUserId = 0;
$sNameToken = '';
$bResetPass = true;
$sUserTableId = MySqlManager::getId(self::USER_TABLE);
//login using form
if($sAction!=self::EXT_ACCESS)
{
if($sToken!='')
{
$sNameToken = strstr($sToken, self::NAME_PASS_SEP, true);
$sPassToken = substr(strstr($sToken, self::NAME_PASS_SEP), 1);
//Check name
//TODO replace SPACE(1) with self::FIRST_LAST_SEP (separate first and last name on logon page)
$asConsts = array('MD5(CONCAT(first_name, SPACE(1), last_name))'=>$sNameToken, 'active'=>self::MEMBER_ACTIVE);
$asInvConsts = array('MD5(CONCAT(last_name, SPACE(1), first_name))'=>$sNameToken, 'active'=>self::MEMBER_ACTIVE);
$iUserId = $this->oMySql->selectValue(self::USER_TABLE, $sUserTableId, $asConsts);
if(!$iUserId) $iUserId = $this->oMySql->selectValue(self::USER_TABLE, $sUserTableId, $asInvConsts);
//Check Pass
if($iUserId==self::SYSTEM_USER_ID || !$this->oAuth->CheckPassword($sPassToken, $this->oMySql->selectValue(self::USER_TABLE, 'pass', $iUserId))) $iUserId = 0;
}
//auto login by cookie
elseif(isset($_COOKIE[self::USER_COOKIE_ID]) && $_COOKIE[self::USER_COOKIE_ID]!=self::SYSTEM_USER_ID)
{
$asConstraints = array( $sUserTableId=>$_COOKIE[self::USER_COOKIE_ID],
'auth_cookie'=>$_COOKIE[self::USER_COOKIE_PASS],
'active'=>self::MEMBER_ACTIVE);
$asUserInfo = $this->oMySql->selectRow(self::USER_TABLE, $asConstraints, array($sUserTableId, 'led'));
if(!empty($asUserInfo))
{
$iUserId = $asUserInfo[$sUserTableId];
//Reset pass once a day
$bResetPass = (mb_substr($asUserInfo['led'], 0, 10) != date(Databap::DATE_SQL_FORMAT));
}
}
}
//Login using Token (limited access)
elseif($sToken!='')
{
$iUserId = $this->checkExternalAccessToken($sToken);
$bResetPass = false;
}
if($iUserId>0)
{
$this->setUserId($iUserId);
if($bResetPass) $this->resetAuthCookie();
//Post-Redirect-Get if user manually logging from logon page
if($sNameToken!='')
{
header('HTTP/1.1 303 See Other');
header('Location: '.$_SERVER['REQUEST_URI']);
exit();
}
}
return ($this->getUserId()>0);
}
private static function getLoginToken($sPass)
{
return md5($sPass.$_GET['serv_name']);
}
public function checkSetPass($sToken, $sNewToken)
{
$bSuccess = false;
$sDesc = '';
if($this->oAuth->CheckPassword($sToken, $this->oMySql->selectValue(self::USER_TABLE, 'pass', $this->getUserId())))
{
$bSuccess = $this->oMySql->updateRow(self::USER_TABLE, $this->getUserId(), array('pass'=>$this->oAuth->HashPassword($sNewToken)));
$sDesc = $bSuccess?'Mot de passe modifié avec succès':'Une erreur au niveau de la base données est apparue';
}
else $sDesc = 'Le mot de passe actuel est erroné';
return $this->getJsonPostResult($bSuccess, $sDesc);
}
public function resetPass($iUserId)
{
if($iUserId>0)
{
$sUserIdCol = MySqlManager::getId(self::USER_TABLE, true);
$asInfo = array('select'=>array($sUserIdCol, MySqlManager::getText(self::COMP_TABLE)),
'from'=> self::USER_TABLE,
'join'=> array(self::COMP_TABLE=>MySqlManager::getId(self::COMP_TABLE)),
'constraint'=>array($sUserIdCol=>$iUserId));
$asUsers = $this->oMySql->selectRows($asInfo);
foreach($asUsers as $asUser)
{
$sToken = $this->oAuth->HashPassword(self::getLoginToken($asUser[MySqlManager::getText(self::COMP_TABLE)]));
$iUserId = $asUser[MySqlManager::getId(self::USER_TABLE)];
$this->oMySql->updateRow(self::USER_TABLE, $iUserId, array('pass'=>$sToken));
}
}
else return 'KO';
return 'OK';
}
private function getExternalAccessPass($iUserId)
{
$sPass = '';
if($iUserId>0)
{
$asUser = $this->oMySql->selectRow(self::USER_TABLE, $iUserId, array('first_name', 'last_name', MySqlManager::getId(self::COMP_TABLE)));
$sCompanyName = $this->oMySql->selectvalue(self::COMP_TABLE, MySqlManager::getText(self::COMP_TABLE), $asUser[MySqlManager::getId(self::COMP_TABLE)]);
$sPass = $asUser['first_name'].$asUser['last_name'].$sCompanyName;
}
else $this->addError('generating token : invalid user id "'.$iUserId.'"');
return $sPass;
}
private function generateExternalAccessToken($iUserId)
{
return $this->oAuth->HashPassword($this->getExternalAccessPass($iUserId));
}
private function checkExternalAccessToken($sKey)
{
$iUserId = mb_strstr($sKey, '_', true);
$asConstraints = array(MySqlManager::getId(self::USER_TABLE)=>$iUserId, 'active'=>self::MEMBER_ACTIVE);
$sToken = mb_substr($sKey, mb_strlen($iUserId)+1);
return ($this->checkValue(self::USER_TABLE, $asConstraints)
&& $this->oAuth->CheckPassword($this->getExternalAccessPass($iUserId), $sToken))?$iUserId:0;
}
private function generateExternalAccessLink($sType, $iUserId=0)
{
if($iUserId==0) $iUserId = $this->getUserId();
return $_GET['serv_name'].'?a='.self::EXT_ACCESS.'&p='.$sType.'&auth_token='.$iUserId.'_'.$this->generateExternalAccessToken($iUserId);
}
private function getInternalLink($sPage, $oId=0)
{
return $_GET['serv_name'].'#'.$sPage.($oId?'-'.$oId:'');
}
private function getAuthCookie()
{
return $this->oAuth->HashPassword( $_SERVER['HTTP_USER_AGENT'].
$_SERVER['REMOTE_ADDR'].
$_SERVER['REQUEST_TIME'].
mb_strstr(microtime(), ' ', true).
$_SERVER['SERVER_SIGNATURE'].
$_SERVER['SERVER_ADMIN']);
}
private function resetAuthCookie()
{
$iUserId = $this->getUserId();
$sNewPass = $this->getAuthCookie();
$iTimeLimit = time()+60*60*24*self::COOKIE_LIFESPAN;
$this->oMySql->updateRow(self::USER_TABLE, $iUserId, array('auth_cookie'=>$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 getArticle($iArtId)
{
return $this->jsonExport($this->getArticleInfo($iArtId));
}
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(self::USER_TABLE);
$bConnected = $this->oMySql->selectRows(array('select'=>array('COUNT(1)'), 'from'=>self::CONN_TABLE, 'constraint'=>array($sUserIdColName=>$this->getUserId(), 'led'=>$sTime), 'constOpe'=>array($sUserIdColName=>'=', 'led'=>'>')));
if($bConnected)
{
$this->oMySql->updateRows(self::CONN_TABLE, array(MySqlManager::getId(self::USER_TABLE)=>$this->getUserId()), array('led'=>$sTime));
$this->addMessage('se d&eacute;connecte', self::MESSAGE_CONN, self::DEFAULT_CHAN_ID);
}
}
private function checkValue($sTableName, $asConstraints)
{
return $this->oMySql->selectValue($sTableName, 'COUNT(1)', $asConstraints);
}
public function getUrlAvailability($sLink)
{
$bAvailable = !$this->checkValue(self::URL_TABLE, array('phrase'=>$sLink));
return self::getJsonPostResult($bAvailable, '');
}
public function resetChanSafeNames()
{
$iChanIdCol = MySqlManager::getId(self::CHAN_TABLE);
$asChans = $this->oMySql->selectRows(array('select'=>array($iChanIdCol, MySqlManager::getText(self::CHAN_TABLE)), 'from'=>self::CHAN_TABLE), true, $iChanIdCol);
$asResult = array();
foreach($asChans as $iChanId=>$sChanName)
{
$asResult[$iChanId] = ($this->oMySql->updateRow(self::CHAN_TABLE, $iChanId, array('safe_name'=>self::getChanSafeName($sChanName))) > 0)?'Fixed':'Not Fixed';
}
return MySqlManager::implodeAll($asResult, ' : ', "\n", 'Result reset ID channel ', '.');
}
public static function getChanSafeName($sChanName)
{
//TODO replace unsafe chars with unique id
$sChanSafeName = preg_replace('/[^a-z0-9]/u', '_', 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 $asItemInfo)
{
//Item Info
$iItemId = $asItemInfo['id_item'];
$sType = $asItemInfo['type'];
$asItemInfo += $this->getItemInfo($sType, $iItemId);
//User Info
if($sType != self::ART_TYPE) //Already available in item info
{
$asUserInfo = $this->getUserInfo($asItemInfo[MySqlManager::getId(self::USER_TABLE)]);
$asItemInfo['name'] = $asUserInfo['name'];
$asItemInfo['company'] = $asUserInfo['company'];
}
//TODO: phrase
$asCompleteResults[] = $asItemInfo;
}
return $this->jsonExport($asCompleteResults);
}
public function getStyleSheet()
{
$sStyle = file_get_contents(self::STYLE_PATH);
$asStyleParams = array(self::OPT_BG, self::OPT_BG_2, self::OPT_BG_3, self::OPT_HOVER, self::OPT_IMAGE_CHAT);
//Inserting Color Anchors
$asDefaultValues = $this->getDefaultOptionValues($asStyleParams, false);
foreach($asDefaultValues as $iOptionNameId=>$sDefaultValue) $asColorAnchors[$iOptionNameId] = '[OPT#'.$iOptionNameId.']';
$sStyle = str_replace($asDefaultValues, $asColorAnchors, $sStyle);
//Switching color Anchors with user colors
$asOptionvalues = $this->getUserOptions($asStyleParams);
foreach($asColorAnchors as $iOptionNameId=>$sColorAnchor)
{
$sStyle = str_replace($sColorAnchor, $asOptionvalues[$iOptionNameId][MySqlManager::getText(self::OPTVAL_TABLE)], $sStyle);
}
//setting header content type
header("Content-Type: text/css");
return $sStyle;
}
public function addUncaughtError($sError)
{
$this->addError('Uncaught errors:'."\n".$sError);
}
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.self::FIRST_LAST_SEP.$sLastName), ' -');;
}
public static function getNickNameFormat($sNickName)
{
$sNickName = ToolBox::capitalizeWords(trim($sNickName), ' -');
return str_replace(' ', '_', $sNickName);
}
public static function getCompanyFormat($sCompany)
{
return mb_strlen($sCompany)>3?ToolBox::mb_ucwords($sCompany):mb_strtoupper($sCompany);
}
public static function getDescriptionFormat($sDescription)
{
return ToolBox::mb_ucfirst(ToolBox::findReplaceLinks($sDescription));
}
public static function getTableFormat($sTable)
{
return mb_strtoupper($sTable);
}
public function getJsonPostResult($bSuccess, $sDesc, $asVars=array())
{
if(!$bSuccess) $this->addError($sDesc);
return self::jsonExport(array('result'=>$bSuccess?self::SUCCESS:self::ERROR, 'desc'=>$sDesc)+$asVars);
}
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;
}
}
?>