2692 lines
98 KiB
PHP
2692 lines
98 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Application Core
|
|
* @author franzz
|
|
*/
|
|
class Databap extends PhpObject
|
|
{
|
|
//Common Constants
|
|
const VERSION = '1.0.2'; //Versioning: <Main_Version>.<Enhancement_Package>.<Patch>-<Release_Candidate>
|
|
const VERSION_DATE = '24/10/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 = '_';
|
|
|
|
//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';
|
|
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_BRIGHT_BG = 3;
|
|
const OPT_HOVER = 4;
|
|
const OPT_IMAGE_CHAT = 6;
|
|
const OPT_STATUS = 7;
|
|
const OPT_CONSOLE = 8;
|
|
const OPT_EMAIL = 9;
|
|
|
|
//Options Values Id Constants
|
|
const OPT_CONSOLE_YES = 1;
|
|
const OPT_CONSOLE_NO = 2;
|
|
|
|
//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 $asUserInfo;
|
|
private $sLanguage;
|
|
|
|
/**
|
|
* Constructor
|
|
* @param ClassManagement $oClassManagement
|
|
*/
|
|
function __construct($oClassManagement)
|
|
{
|
|
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);
|
|
|
|
//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) $this->install();
|
|
|
|
//Init other variables
|
|
$this->setUserId(0);
|
|
$this->sLanguage = self::LANG_FR;
|
|
$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), MySqlManager::getText(self::OPT_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), '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(MySqlManager::getId(self::DOC_TABLE), 'description', 'file_name'),
|
|
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",
|
|
'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::OPT_TABLE) => "varchar(100) NOT NULL",
|
|
MySqlManager::getText(self::OPTNAME_TABLE) => "varchar(100) NOT NULL",
|
|
MySqlManager::getText(self::OPTVAL_TABLE)=> "varchar(50) 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)"
|
|
);
|
|
$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);
|
|
$iNicknameOptId = $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_NICKNAME, $sOptionNameCol=>'pseudo du chat', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
|
|
$iBgColorOptId = $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_BG, $sOptionNameCol=>'couleur de fond', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
|
|
$iBgColorOpt2Id = $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_BRIGHT_BG, $sOptionNameCol=>'couleur de fond 2 (claire)', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
|
|
$iHoverColorOptId = $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_HOVER, $sOptionNameCol=>'couleur de survol', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
|
|
$iChatImageOptId = $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_IMAGE_CHAT, $sOptionNameCol=>'image du chat', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
|
|
$iStatusOptId = $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_STATUS, $sOptionNameCol=>'mission en cours', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
|
|
$iConsoleOptId = $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));
|
|
$iEmailOptId = $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_EMAIL, $sOptionNameCol=>'Email', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR));
|
|
|
|
//Console Option
|
|
$asConsoleValues = array(self::OPT_CONSOLE_YES=>self::OPT_VAL_YES, self::OPT_CONSOLE_NO=>self::OPT_VAL_NO);
|
|
foreach($asConsoleValues as $sConsoleValId=>$sConsoleValue){$this->oMySql->insertRow(self::OPTVAL_TABLE, array($sOptionValueIdCol=>$sConsoleValId, $sOptionNameIdCol=>self::OPT_CONSOLE, $sOptionValueCol=>$sConsoleValue, '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 : admin and test
|
|
$iAdminId = $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\n/usr/bin/php -f index.php a=external_access p=blogs auth_token=".$iAdminId.'_'.str_replace('$', '\$', $this->generateExternalAccessToken($iAdminId)));
|
|
}
|
|
|
|
private function setUserId($iUserId)
|
|
{
|
|
$this->iUserId = $iUserId;
|
|
$this->asUserInfo = ($iUserId>0)?$this->getUserInfo($iUserId):array();
|
|
}
|
|
|
|
public function getUserId()
|
|
{
|
|
return $this->iUserId;
|
|
}
|
|
|
|
public function getPage($sPage, $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(),
|
|
'opt_console_no'=>self::OPT_CONSOLE_NO,
|
|
'types'=>$this->getTypeInfo('title'));
|
|
$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);
|
|
$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;
|
|
}
|
|
$asResult = $this->oMySql->selectRows(array('select'=>array('id_message', 'nickname', 'message', 'led'), 'from'=>'messages', 'constraint'=>array('message'=>$sRegEx), 'constOpe'=>array('message'=>' REGEXP ')));
|
|
|
|
$sPattern = '/(https?\:\/\/|www\.)[\S]+\.[a-zA-Z]{2,4}([\S]*)/ui';
|
|
foreach($asResult as $iLinkId=>$asRow)
|
|
{
|
|
//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é par '.self::getNickNameFormat($asRow['nickname']).' à '.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==0)
|
|
{
|
|
$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');
|
|
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;
|
|
}
|
|
}
|
|
$asResult = $this->downloadToTmp($o9gagImage->getAttribute('src'));
|
|
|
|
if($asResult['error']=='')
|
|
{
|
|
$asPost['url_img'] = $asResult['out'];
|
|
$asPost['width'] = $asResult['width'];
|
|
$asPost['height'] = $asResult['height'];
|
|
}
|
|
|
|
return $asPost;
|
|
}
|
|
|
|
private function getRemotePageDom($sUrl)
|
|
{
|
|
$oDom = new DOMDocument();
|
|
@$oDom->loadHTML(file_get_contents($sUrl));
|
|
return $oDom->getElementsByTagName('body')->item(0);
|
|
}
|
|
|
|
public function getNote($iNote)
|
|
{
|
|
$this->oClassManagement->incClass('note');
|
|
$oNote = new Note($iNote);
|
|
return $oNote->getNote();
|
|
}
|
|
|
|
public function addUser($sFirstName, $sLastName, $sCompany, $sEmail='', $iClearance=self::CLEARANCE_MEMBER)
|
|
{
|
|
$sFirstName = mb_strtolower($sFirstName);
|
|
$sLastName = mb_strtolower($sLastName);
|
|
$sCompany = mb_strtolower($sCompany);
|
|
$sEmail = mb_strtolower($sEmail);
|
|
|
|
//Checking company existency in company table
|
|
$sCompanyTextCol = MySqlManager::getText(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');
|
|
$iUserId = $this->oMySql->insertRow(self::USER_TABLE, $asInfo);
|
|
|
|
//Admin Options
|
|
$sOptionTable = self::OPT_TABLE;
|
|
$sUserIdCol = MySqlManager::getId(self::USER_TABLE);
|
|
$sOptNameIdCol = MySqlManager::getId(self::OPTNAME_TABLE);
|
|
$sOptionTextCol = MySqlManager::getText(self::OPT_TABLE);
|
|
$sOptionValIdCol = MySqlManager::getId(self::OPTVAL_TABLE);
|
|
$this->oMySql->insertRow($sOptionTable, array($sUserIdCol=>$iUserId, $sOptNameIdCol=>self::OPT_NICKNAME, $sOptionTextCol=>$sFirstName));
|
|
//$this->oMySql->insertRow($sOptionTable, array($sUserIdCol=>$iUserId, $sOptNameIdCol=>self::OPT_BG, $sOptionTextCol=>'#04357B'));
|
|
//$this->oMySql->insertRow($sOptionTable, array($sUserIdCol=>$iUserId, $sOptNameIdCol=>self::OPT_BRIGHT_BG, $sOptionTextCol=>'#D9E5F2'));
|
|
//$this->oMySql->insertRow($sOptionTable, array($sUserIdCol=>$iUserId, $sOptNameIdCol=>self::OPT_HOVER, $sOptionTextCol=>'#EFAB00'));
|
|
//$this->oMySql->insertRow($sOptionTable, array($sUserIdCol=>$iUserId, $sOptNameIdCol=>self::OPT_TOKEN, $sOptionTextCol=>$this->generateExternalAccessLink('rss', $iUserId)));
|
|
//$this->oMySql->insertRow($sOptionTable, array($sUserIdCol=>$iUserId, $sOptNameIdCol=>self::OPT_IMAGE_CHAT, $sOptionTextCol=>'images/sap_gold_332.jpg'));
|
|
$this->oMySql->insertRow($sOptionTable, array($sUserIdCol=>$iUserId, $sOptNameIdCol=>self::OPT_CONSOLE, $sOptionValIdCol=>self::OPT_CONSOLE_NO));
|
|
$this->oMySql->insertRow($sOptionTable, array($sUserIdCol=>$iUserId, $sOptNameIdCol=>self::OPT_EMAIL, $sOptionTextCol=>$sEmail));
|
|
|
|
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($this->getUserId());
|
|
|
|
$oResult = array('result'=>'success',
|
|
'proc_id'=>$iNewProcId,
|
|
'led'=>$asProc['led'],
|
|
'name'=>$asUser['name'],
|
|
'company'=>$asUser['company']);
|
|
|
|
//Add Message in chat
|
|
if($bCreation)
|
|
{
|
|
$this->addMessage($iNewProcId, self::MESSAGE_ADD_PROC, self::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[MySqlManager::getId(self::DOC_TABLE)] = $iDbDocId;
|
|
foreach($asDocs as $asDocInfo)
|
|
{
|
|
//insert into database
|
|
$sFileName = $asDocInfo['name'];
|
|
$asDocData['description'] = $asDocInfo['desc'];
|
|
$asDocData['file_name'] = $sFileName;
|
|
$iDbImageId = $this->oMySql->insertRow(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);
|
|
|
|
return self::jsonExport(array('result'=>'success','doc_id'=>$iDbDocId));
|
|
}
|
|
|
|
public function getDoc($iDocId)
|
|
{
|
|
//Extract doc data
|
|
$asDoc = $this->oMySql->selectRow(self::DOC_TABLE, $iDocId);
|
|
$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
|
|
$asFiles = $this->oMySql->selectRows(array('from'=>self::FILE_TABLE, 'constraint'=>array('id_doc'=>$iDocId)));
|
|
foreach($asFiles as $asFile)
|
|
{
|
|
$asDoc['files'][$asFile[MySqlManager::getId(self::FILE_TABLE)]] = array('description'=>self::getDescriptionFormat($asFile['description']),
|
|
'ext'=>pathinfo($asFile['file_name'], PATHINFO_EXTENSION));
|
|
}
|
|
|
|
return self::jsonExport($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)
|
|
{
|
|
$sFileName = $this->oMySql->selectValue(self::FILE_TABLE, 'file_name', $iFileId);
|
|
$sFilePath = self::DOC_FOLDER.$sFileName;
|
|
$sFileFullPath = dirname($_SERVER['SCRIPT_FILENAME'])."/".$sFilePath;
|
|
|
|
if(!file_exists($sFilePath))
|
|
{
|
|
die();
|
|
}
|
|
else
|
|
{
|
|
//get mime type
|
|
if(class_exists('finfo'))
|
|
{
|
|
$oFileInfo = new finfo(FILEINFO_MIME);
|
|
$sMimetype = $oFileInfo->file($sFileFullPath);
|
|
}
|
|
else
|
|
{
|
|
$sMimetype = 'application/force-download';
|
|
}
|
|
|
|
//set headers
|
|
header('Pragma: public');
|
|
header('Expires: 0');
|
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
|
header('Cache-Control: public');
|
|
header('Content-Description: File Transfer');
|
|
header('Content-Type: '.$sMimetype);
|
|
header('Content-Disposition: attachment; filename='.$sFileName);
|
|
header('Content-Transfer-Encoding: binary');
|
|
header('Content-Length: '.@filesize($sFilePath));
|
|
|
|
// download
|
|
if ($oFile = @fopen($sFilePath, 'rb'))
|
|
{
|
|
while(!feof($oFile))
|
|
{
|
|
print(fread($oFile, 1024*8));
|
|
flush();
|
|
if(connection_status() != 0)
|
|
{
|
|
@fclose($oFile);
|
|
}
|
|
}
|
|
@fclose($oFile);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function uploadImage()
|
|
{
|
|
$this->oClassManagement->incClass('fileuploader');
|
|
$oFileUploader = new fileUploader(Procedure::IMAGE_FOLDER_TMP, self::$UPLOAD_IMG_EXTS);
|
|
$asResult = $oFileUploader->handleUpload();
|
|
|
|
return $this->jsonConvert($asResult);
|
|
}
|
|
|
|
public function uploadDoc()
|
|
{
|
|
$this->oClassManagement->incClass('fileuploader');
|
|
$oFileUploader = new fileUploader(self::DOC_TMP_FOLDER, self::$UPLOAD_DOC_EXTS);
|
|
$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(!$asTable) $asTable = array(); //return false on empty
|
|
else
|
|
{
|
|
$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, $bJson=false)
|
|
{
|
|
$asUserInfo = array();
|
|
if($iUserId==$this->getUserId() && !empty($this->asUserInfo))
|
|
{
|
|
$asUserInfo = $this->asUserInfo;
|
|
}
|
|
elseif($iUserId > 0)
|
|
{
|
|
$asRow = $this->oMySql->selectRow(self::USER_TABLE, $iUserId);
|
|
$sEmail = $this->getUserOptionValue(self::OPT_EMAIL, $iUserId);
|
|
|
|
$asCompany = $this->oMySql->selectRow(self::COMP_TABLE, $asRow[MySqlManager::getId(self::COMP_TABLE)]);
|
|
$asUserInfo = 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));
|
|
}
|
|
return $bJson?$this->jsonExport($asUserInfo):$asUserInfo;
|
|
}
|
|
|
|
private function getUserClearance()
|
|
{
|
|
$asUserInfo = $this->getUserInfo($this->getUserId());
|
|
return $asUserInfo['clearance'];
|
|
}
|
|
|
|
public function checkUserClearance($iClearance)
|
|
{
|
|
return ($this->getUserClearance() >= $iClearance);
|
|
}
|
|
|
|
public function getOptions()
|
|
{
|
|
$sOptValueIdCol = MySqlManager::getId(self::OPTVAL_TABLE);
|
|
$sOptionTextCol = MySqlManager::getText(self::OPT_TABLE);
|
|
$sOptNameTextCol = MySqlManager::getText(self::OPTNAME_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)
|
|
{
|
|
$asSelectedOptions[$sOptNameId]['option_name'] = self::getDescriptionFormat($asOption[$sOptNameTextCol]);
|
|
$asSelectedOptions[$sOptNameId]['user_value_id'] = array_key_exists($sOptNameId, $asUserOptions)?$asUserOptions[$sOptNameId][$sOptValueIdCol]:0;
|
|
$asSelectedOptions[$sOptNameId]['user_value'] = array_key_exists($sOptNameId, $asUserOptions)?$asUserOptions[$sOptNameId][$sOptionTextCol]:'';
|
|
$asSelectedOptions[$sOptNameId]['type'] = $asOption['type'];
|
|
if($asOption['type']==self::OPT_SELECT)
|
|
{
|
|
$asOptionValuesInfo = array('select'=>array($sOptValueIdCol, $sOptValueTextCol),
|
|
'from'=>self::OPTVAL_TABLE,
|
|
'constraint'=>array('language'=>$this->sLanguage,
|
|
MySqlManager::getId(self::OPTNAME_TABLE)=>$sOptNameId),
|
|
'orderBy'=>array('led'=>'ASC'));
|
|
$asSelectedOptions[$sOptNameId]['select'] = $this->oMySql->selectRows($asOptionValuesInfo, true, $sOptValueIdCol);
|
|
}
|
|
}
|
|
return $this->jsonExport($asSelectedOptions);
|
|
}
|
|
|
|
public function setOptions($asUserOptions, $bSilentUpdate=true)
|
|
{
|
|
foreach($this->getAvailableOptions() as $sOptNameId=>$asOption)
|
|
{
|
|
if(array_key_exists($sOptNameId, $asUserOptions))
|
|
{
|
|
switch($asOption['type'])
|
|
{
|
|
case self::OPT_SELECT: //insert id of option value table
|
|
$sUpdateCol = MySqlManager::getId(self::OPTVAL_TABLE);
|
|
break;
|
|
case self::OPT_TEXT: //insert value
|
|
$sUpdateCol = MySqlManager::getText(self::OPT_TABLE);
|
|
break;
|
|
default:
|
|
continue 2;
|
|
}
|
|
$sNewValue = $asUserOptions[$sOptNameId];
|
|
|
|
//Check identical data
|
|
$asKeys = array(MySqlManager::getId(self::USER_TABLE)=>$this->getUserId(), MySqlManager::getId(self::OPTNAME_TABLE)=>$sOptNameId);
|
|
$asData = array($sUpdateCol=>$sNewValue) + $asKeys;
|
|
$sOldValue = $this->oMySql->selectValue(self::OPT_TABLE, $sUpdateCol, $asKeys);
|
|
|
|
//Update value
|
|
if($sOldValue!=$sNewValue)
|
|
{
|
|
//Update value
|
|
$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 = $sOldValue.' a changé 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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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 getUserOptionValue($sOptionNameId, $iUserId=0)
|
|
{
|
|
$asUserOptions = $this->getUserOptions($sOptionNameId, $iUserId);
|
|
$asOptionInfo = array_shift($asUserOptions);
|
|
return $asOptionInfo[MySqlManager::getId(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);
|
|
$sOptValueIdCol = MySqlManager::getId(self::OPTVAL_TABLE);
|
|
$sOptionTextCol = MySqlManager::getText(self::OPT_TABLE);
|
|
|
|
if(!is_array($oOptionNameIds))
|
|
{
|
|
$oOptionNameIds = array($oOptionNameIds);
|
|
}
|
|
|
|
$asUserinfo = array('select'=>array($sOptNameIdCol, $sOptValueIdCol, $sOptionTextCol),
|
|
'from'=>self::OPT_TABLE,
|
|
'constraint'=>array($sUserIdCol=>$iUserId));
|
|
if(count($oOptionNameIds)>0)
|
|
{
|
|
$asUserinfo['constraint'][$sOptNameIdCol] = "(".implode(", ", $oOptionNameIds).")";
|
|
$asUserinfo['constOpe'] = array($sUserIdCol=>"=", $sOptNameIdCol=>" IN ");
|
|
$asUserinfo['constVar'] = true;
|
|
}
|
|
$asOptions = $this->oMySql->selectRows($asUserinfo, true, $sOptNameIdCol);
|
|
foreach($asOptions as $iOptionId=>$asOption)
|
|
{
|
|
if(!$asOption[$sOptValueIdCol]) $asOptions[$iOptionId][$sOptValueIdCol] = $asOptions[$iOptionId][$sOptionTextCol];
|
|
}
|
|
return $asOptions;
|
|
}
|
|
|
|
public function getProfile($oUser)
|
|
{
|
|
switch($oUser)
|
|
{
|
|
case '':
|
|
$iUserId = $this->getUserId();
|
|
break;
|
|
case is_numeric($oUser):
|
|
$iUserId = $oUser;
|
|
break;
|
|
case is_string($oUser):
|
|
$oRes = $this->oMySql->selectValue(self::OPT_TABLE, MySqlManager::getId(self::USER_TABLE), array('option'=>mb_strtolower($oUser), MySqlManager::getId(self::OPTNAME_TABLE)=>self::OPT_NICKNAME));
|
|
$iUserId = !$oRes?$this->getUserId():$oRes;
|
|
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éation':'Modification').' de '.$sText;
|
|
$asProfile['history'][$sKey]['date'] = $asInfo['led'];
|
|
$asProfile['history'][$sKey]['title'] = $asInfo['title'];
|
|
}
|
|
}
|
|
|
|
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($this->getUserId());
|
|
foreach($asMessages as $iChanId=>$sMsgChanName)
|
|
{
|
|
$asPm = $this->isPmChan($sMsgChanName);
|
|
$this->addMessage(' de '.$asUserInfo['company'].' ('.($sStatus==''?'aucune mission en cours':$this->getDescriptionFormat($sStatus)).') rejoint '.($asPm['is_pm']?'le chan privé':'#'.$sMsgChanName), self::MESSAGE_CONN, $iChanId);
|
|
}
|
|
|
|
//Send invites to attendees
|
|
if(!empty($asAttendees))
|
|
{
|
|
$asUserInfo = $this->getUserInfo($this->getUserId());
|
|
foreach($asAttendees as $sAttendee)
|
|
{
|
|
if($this->checkChanAuth($sSafeChanName, $sAttendee))
|
|
{
|
|
$this->addMessage($sAttendee, self::MESSAGE_INVITE, $iChanId);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Update chan leds
|
|
$this->pingChans();
|
|
}
|
|
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é':'#'.$sChanName), self::MESSAGE_CONN, $iChanId);
|
|
}
|
|
}
|
|
|
|
private function getActiveChannels()
|
|
{
|
|
//Get connected users
|
|
$asActiveChanUsers = $this->getConnectedUsers(false, false);
|
|
$asActiveChans = array_keys($asActiveChanUsers);
|
|
|
|
//Get Channel names
|
|
$sChanIdCol = MySqlManager::getId(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 à '.mb_substr($sMessage, 5);
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 4) == '/bs ')
|
|
{
|
|
$sType = self::MESSAGE_ACTION;
|
|
$sMessage = ' bitch-slaps '.mb_substr($sMessage, 3);
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 6) == '/kick ')
|
|
{
|
|
$sType = self::MESSAGE_ACTION;
|
|
$sMessage = ' met un coup de pied au cul de '.mb_substr($sMessage, 5);
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 6) == '/nick ' && mb_strlen($sMessage)>6)
|
|
{
|
|
$sNewNick = $this->getNickNameFormat(mb_substr($sMessage, 5));
|
|
$sOldNick = $this->getNickNameFormat($this->getChatNickNames($this->getUserId()));
|
|
|
|
//changing Nickname
|
|
$this->setOptions(array(self::OPT_NICKNAME=>$sNewNick));
|
|
|
|
//Message
|
|
$sType = self::MESSAGE_NICK;
|
|
$sChanName = self::ALL_CHAN_TEXT;
|
|
$sMessage = $sOldNick.' a changé son pseudo en '.$sNewNick;
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 9) == '/mission ' && mb_strlen($sMessage)>9)
|
|
{
|
|
$sNewStatus = mb_substr($sMessage, 9);
|
|
$sNewFormatStatus = $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é un mail à '.$asMatches['nickname'];
|
|
}
|
|
else
|
|
{
|
|
$sMessage = 'n\'a pas envoyé de mail à '.$asMatches['nickname'].' (raison inconnue, voir log)';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$sMessage = 'n\'a pas envoyé de mail à '.$asMatches['nickname'].' (message vide)';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$sMessage = 'n\'a pas envoyé de mail à '.$asMatches['nickname'].' (pseudo inconnu)';
|
|
}
|
|
$sType = self::MESSAGE_ACTION;
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 5) == '/mean')
|
|
{
|
|
$sPageContent = file_get_contents('http://www.randominsults.net/');
|
|
$sStartText = '<strong><i>';
|
|
$sEndText = '</i></strong>';
|
|
$iStartPos = mb_strpos($sPageContent, $sStartText);
|
|
$iEndPos = mb_strpos($sPageContent, $sEndText);
|
|
|
|
$sMessage = mb_substr($sPageContent, $iStartPos + mb_strlen($sStartText), $iEndPos - $iStartPos);
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 5) == '/like')
|
|
{
|
|
$sType = self::MESSAGE_ACTION;
|
|
$sMessage = ' plussoie';
|
|
}
|
|
elseif(mb_substr($sMessage, 0, 4) == '/now')
|
|
{
|
|
$sType = self::MESSAGE_ACTION;
|
|
$asWeekDays = array('lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche');
|
|
$asMonths = array('janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre');
|
|
$sMessage = ' a demandé l\'heure. Pour sa gouverne, il est exactement '.date(self::TIME_FORMAT).
|
|
', le '.$asWeekDays[date('N')-1].' '.date('j').' '.$asMonths[date('n')-1].' '.date('Y').' (semaine '.date('W').')';
|
|
}
|
|
elseif($sMessage == '/channels' || mb_substr($sMessage, 0, 5) == '/list' || $sMessage == '/chans')
|
|
{
|
|
//Always at least one channel open (the one the message is sent from)
|
|
$sMessage = ' a demandé les chans disponibles. Pour sa gouverne, les chans ayant des membres connectés sont #'.MySqlManager::implodeAll($this->getActiveChannels(), ' (', ', #', '', ')');
|
|
$sType = self::MESSAGE_ACTION;
|
|
}
|
|
elseif((mb_substr($sMessage, 0, 5) == '/img ' || mb_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é 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, 8) == '/invite ' && mb_strlen($sMessage)>8)
|
|
{
|
|
$sSafeChanName = $this->getChanSafeName($sChanName);
|
|
$iUserId = $this->getUserIdFromNickName(trim(mb_substr($sMessage, 8)));
|
|
if($iUserId>0 && $this->checkChanAuth($sSafeChanName, $iUserId))
|
|
{
|
|
$sType = self::MESSAGE_INVITE;
|
|
$sMessage = $iUserId;
|
|
}
|
|
}
|
|
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)
|
|
{
|
|
$sFileInfo = pathinfo($sUrl);
|
|
$sImageExt = mb_strtolower($sFileInfo['extension']);
|
|
$sFilePath = self::DOC_TMP_FOLDER.uniqid().'.'.$sImageExt;
|
|
return ToolBox::createThumbnail($sUrl, self::CHAT_IMG_MAX_WIDTH, self::CHAT_IMG_MAX_HEIGHT, $sFilePath, false, Databap::$UPLOAD_IMG_EXTS);
|
|
}
|
|
|
|
private function sendPM($iUserIdTo, $sMessage)
|
|
{
|
|
$bSuccess = false;
|
|
$asUserFrom = $this->getUserInfo($this->getUserId());
|
|
$asUserTo = $this->getUserInfo($iUserIdTo);
|
|
$sFrom = $asUserFrom['name'].' <www-data@lutran.fr>';
|
|
|
|
$sTo = $asUserTo['name'].' <'.$asUserTo['email'].'>';
|
|
$sMessage .= "\n\n\n".'<i>Ne répondez pas à ce mail. Connectez-vous sur <a href="http://databap.lutran.fr/chat">Databap</a>.</i>';
|
|
|
|
$sResult = ToolBox::sendMail($sFrom, 'Databap PM', $sMessage, $sTo, array(), false);
|
|
$bSuccess = ($sResult==ToolBox::MAIL_SUCCESS);
|
|
if(!$bSuccess) $this->addError($sResult);
|
|
return $bSuccess;
|
|
}
|
|
|
|
private function addMessage($sMessage, $sType, $iChanId)
|
|
{
|
|
$bResult = false;
|
|
if($iChanId>0)
|
|
{
|
|
$asInsert = array( MySqlManager::getId(self::USER_TABLE) => $this->getUserId(),
|
|
'nickname' => $this->getChatNickNames($this->getUserId()),
|
|
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));
|
|
|
|
//channel related messages
|
|
$sCurDate = date(Databap::DATE_SQL_FORMAT);
|
|
$asInfo = array('select' => array($sMsgTableChanIdCol, $sMsgIdCol, $sMsgTextCol, 'type', $sMsgTableLed, 'first_name', 'last_name', $sUserIdCol, 'nickname'),
|
|
'from' => 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'=>$sCurDate),
|
|
'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'=>$sCurDate);
|
|
$asInfo['constOpe'] = array($sMsgTableChanIdCol=>'=', $sMsgIdCol=>'>', 'date'=>'=');
|
|
$asSqlGlobalMessages = $this->oMySql->selectRows($asInfo, true, 'id_message');
|
|
|
|
//Invites messages
|
|
$asInfo['constraint'] = array($sMsgIdCol=>$iFirstMsgId, 'date'=>$sCurDate, 'type'=>self::MESSAGE_INVITE, 'message'=>$this->getUserId());
|
|
$asInfo['constOpe'] = array($sMsgIdCol=>'>', 'date'=>'=', 'type'=>'=', 'message'=>'=');
|
|
$asSqlInviteMessages = $this->oMySql->selectRows($asInfo, true, 'id_message');
|
|
|
|
//Merge flows
|
|
if(!empty($asSqlGlobalMessages)) $asSqlMessages = array_diff_key($asSqlMessages, $asSqlGlobalMessages) + $asSqlGlobalMessages;
|
|
if(!empty($asSqlInviteMessages)) $asSqlMessages = array_diff_key($asSqlMessages, $asSqlInviteMessages) + $asSqlInviteMessages;
|
|
|
|
//Sort messages
|
|
ksort($asSqlMessages);
|
|
|
|
//Sort out messages for Json Export
|
|
$iPrefixLen = mb_strlen(self::JSON_PREFIX);
|
|
//$iConsoleDisplay = $this->getUserOptionValue(self::OPT_CONSOLE);
|
|
$asMessages = array('messages'=>array(), 'last_message_id'=>0);
|
|
foreach($asSqlMessages as $iMessageId=>$asMessageInfo)
|
|
{
|
|
//Connection message filter
|
|
//if($iConsoleDisplay==self::OPT_CONSOLE_NO && $asMessageInfo['type']==self::MESSAGE_CONN) continue;
|
|
|
|
//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]['message'] = $asMessageInfo[$sMsgTextCol];
|
|
$asMessages['messages'][$iMessageId]['msg_class'] = $sMessageType;
|
|
$asMessages['messages'][$iMessageId]['time'] = self::getDateFormat($asMessageInfo['led'], self::TIME_FORMAT);
|
|
$asMessages['messages'][$iMessageId]['name'] = self::getNameFormat($asMessageInfo['first_name'], $asMessageInfo['last_name']);
|
|
$asMessages['messages'][$iMessageId]['nickname'] = self::getNickNameFormat($asMessageInfo['nickname']);
|
|
|
|
//generated messages
|
|
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'] = 3;
|
|
$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, option_nickname.option AS nickname, option_status.option AS status
|
|
FROM connections AS conn1
|
|
LEFT JOIN connections AS conn2 ON conn2.id_channel = conn1.id_channel
|
|
LEFT JOIN users ON users.id_user = conn2.id_user
|
|
LEFT JOIN companies ON companies.id_company = users.id_company
|
|
LEFT JOIN `options` AS option_nickname ON option_nickname.id_user = users.id_user AND option_nickname.id_option_name = ".self::OPT_NICKNAME."
|
|
LEFT JOIN `options` AS option_status ON option_status.id_user = users.id_user AND option_status.id_option_name = ".self::OPT_STATUS."
|
|
WHERE conn2.led > DATE_SUB(NOW(), INTERVAL ".self::KEEP_ALIVE." SECOND)".
|
|
($bUserRestricted?"AND conn1.id_user = ".$this->getUserId():"")."
|
|
GROUP BY conn2.id_channel, conn2.id_user
|
|
ORDER BY option_nickname.option ASC";
|
|
$asUserChannels = $this->oMySql->getArrayQuery($sQuery, true);
|
|
|
|
//Last messages
|
|
$iUserIdCol = MySqlManager::getId(self::USER_TABLE);
|
|
$asLastMsg = $this->oMySql->selectRows(array('select'=>array($iUserIdCol, 'MAX(led)'), 'from'=>self::MSG_TABLE), true, $iUserIdCol);
|
|
|
|
$asConnectedUsers = array();
|
|
foreach($asUserChannels as $asUser)
|
|
{
|
|
$sChanId = $asUser[MySqlManager::getId(self::CHAN_TABLE)];
|
|
$iUserId = $asUser[$iUserIdCol];
|
|
$sNickName = $asUser['nickname'];
|
|
$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'] = $asUser['status'];
|
|
$asConnectedUsers[$sChanId][$sNickName.$iUserId]['logo'] = $asUser['logo'];
|
|
$asConnectedUsers[$sChanId][$sNickName.$iUserId]['nickname'] = self::getNickNameFormat($sNickName==''?$asUser['first_name']:$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)
|
|
{
|
|
$sUserIdCol = MySqlManager::getId(self::USER_TABLE);
|
|
$sNicknameCol = MySqlManager::getText(self::OPT_TABLE);
|
|
$asConstraints = array(MySqlManager::getId(self::OPTNAME_TABLE)=>self::OPT_NICKNAME);
|
|
|
|
if($iUserId>0)
|
|
{
|
|
$asConstraints[MySqlManager::getId(self::USER_TABLE)] = $iUserId;
|
|
$oResult = $this->oMySql->selectValue(self::OPT_TABLE, $sNicknameCol, $asConstraints);
|
|
}
|
|
else
|
|
{
|
|
$asInfo = array('select'=>array($sUserIdCol, $sNicknameCol),
|
|
'from'=>self::OPT_TABLE,
|
|
'constraint'=>$asConstraints);
|
|
$oResult = $this->oMySql->selectRows($asInfo, true, $sUserIdCol);
|
|
}
|
|
return $oResult;
|
|
}
|
|
|
|
private function switchCodeId(&$iCodeId, $sMode)
|
|
{
|
|
switch($sMode)
|
|
{
|
|
case 'first':
|
|
$iCodeId = $this->oMySql->selectValue(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 static function checkNoAuthCookieResetAction($sAction)
|
|
{
|
|
return in_array($sAction, array('messages', 'upload_image', 'user_info', 'rss'));
|
|
}
|
|
|
|
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(!$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]))
|
|
{
|
|
$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'));
|
|
$iUserId = $asUserInfo[$sUserTableId];
|
|
|
|
//Check pass reset necessity
|
|
$bResetPass = (mb_substr($asUserInfo['led'], 0, 10) != date(Databap::DATE_SQL_FORMAT));
|
|
}
|
|
}
|
|
//Login using Token (limited access)
|
|
elseif($sToken!='')
|
|
{
|
|
$iUserId = $this->checkExternalAccessToken($sToken);
|
|
$bResetPass = false;
|
|
}
|
|
|
|
if($iUserId>0)
|
|
{
|
|
$this->setUserId($iUserId);
|
|
if(!self::checkNoAuthCookieResetAction($sAction) && $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éconnecte', self::MESSAGE_CONN, self::DEFAULT_CHAN_ID);
|
|
}
|
|
}
|
|
|
|
public function checkValue($sTableName, $asConstraints)
|
|
{
|
|
return $this->oMySql->selectValue($sTableName, 'COUNT(1)', $asConstraints);
|
|
}
|
|
|
|
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);
|
|
$asDefaultColors = array( self::OPT_BG=>'#04357B',
|
|
self::OPT_BRIGHT_BG=>'#D9E5F2',
|
|
self::OPT_HOVER=>'#EFAB00',
|
|
self::OPT_IMAGE_CHAT=>'images/sap_gold_332.jpg');
|
|
|
|
//Inserting Color Ids
|
|
foreach($asDefaultColors as $iOptionNameId=>$sDefaultColor)
|
|
{
|
|
$asColorAnchors[$iOptionNameId] = '[OPT#'.$iOptionNameId.']';
|
|
}
|
|
$sStyle = str_replace($asDefaultColors, $asColorAnchors, $sStyle);
|
|
|
|
//Switching color Ids with user colors
|
|
$asOptionvalues = $this->getUserOptions(array_keys($asDefaultColors));
|
|
foreach($asColorAnchors as $iOptionNameId=>$sColorAnchor)
|
|
{
|
|
$sOptionValue = (array_key_exists($iOptionNameId, $asOptionvalues) && $asOptionvalues[$iOptionNameId]['option']!='')?$asOptionvalues[$iOptionNameId]['option']:$asDefaultColors[$iOptionNameId];
|
|
$sStyle = str_replace($sColorAnchor, $sOptionValue, $sStyle);
|
|
}
|
|
|
|
//setting header content type
|
|
header("Content-Type: text/css");
|
|
return $sStyle;
|
|
}
|
|
|
|
public static function getDateFormat($oTime, $sFormat=Databap::DATE_TIME_FORMAT)
|
|
{
|
|
$iTimeStamp = is_numeric($oTime)?$oTime:strtotime($oTime);
|
|
return date($sFormat, $iTimeStamp);
|
|
}
|
|
|
|
public static function getNameFormat($sFirstName, $sLastName)
|
|
{
|
|
return ToolBox::capitalizeWords(trim($sFirstName.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;
|
|
}
|
|
}
|
|
|
|
?>
|