..- const VERSION_DATE = '08/06/2015'; const EXPECTED_PAGE_COOKIE = 'exp_page'; const MAIN_SEPARATOR = ' '; const DATE_FORMAT = 'd/m/Y'; const TIME_FORMAT = 'H:i:s'; const DATE_TIME_FORMAT = 'd/m/Y H:i:s'; const DATE_COMPACT_FORMAT = 'YmdHis'; const DATE_TIME_SQL_FORMAT = 'Y-m-d H:i:s'; const DATE_SQL_FORMAT = 'Y-m-d'; const HISTORY_LENGTH = 10; const STYLE_PATH = 'style/databap.css'; public static $UPLOAD_IMG_EXTS = array('jpg', 'jpeg', 'gif', 'png'); public static $UPLOAD_DOC_EXTS = array('jpg', 'jpeg', 'gif', 'png', 'doc', 'ppt', 'pdf', 'xls', 'docx', 'pptx', 'xlsx'); const ID_SEPARATOR = '_'; const SYSTEM_USER_ID = 1; //Database constant const USER_TABLE = 'users'; const COMP_TABLE = 'companies'; const CODE_TABLE = 'codes'; const URL_TABLE = 'urls'; const MSG_TABLE = 'messages'; const CHAN_TABLE = 'channels'; const CONN_TABLE = 'connections'; const ART_TABLE = 'articles'; const OPT_TABLE = 'options'; const OPTVAL_TABLE = 'option_values'; const OPTNAME_TABLE = 'option_names'; const PROC_TABLE = 'procedures'; const STEP_TABLE = 'steps'; const IMG_TABLE = 'images'; const DOC_TABLE = 'docs'; const FILE_TABLE = 'files'; const SEARCH_TABLE = 'searchs'; const TABL_TABLE = 'tables'; //Code const MAX_LIST_LENGTH = 5; //Authorizations const MEMBER_ACTIVE = 1; const MEMBER_INACTIVE = 0; const CLEARANCE_MEMBER = 0; const CLEARANCE_ADMIN = 9; const EXT_ACCESS = 'external_access'; const USER_COOKIE_ID = 'count'; const USER_COOKIE_PASS = 'checksum'; const COOKIE_LIFESPAN = 7; const FIRST_LAST_SEP = ' '; const NAME_PASS_SEP = '-'; //HTTP Requests response const ERROR = '__ERROR__'; const SUCCESS = '__SUCCESS__'; const DISCONNECTED = '__DISCONNECTED__'; const NOT_FOUND = '__NOT_FOUND__'; const NOT_AUTH = '__NOT_AUTHORIZED__'; const FAIL_INSERT = '__FAIL_INSERT__'; const FAIL_UPDATE = '__FAIL_UPDATE__'; const FAIL_DELETE = '__FAIL_DELETE__'; //Chat Constants //TODO Transfer these constants to chat page const MESSAGE_USER = 'U'; const MESSAGE_ADD_CODE = 'A'; const MESSAGE_EDIT_CODE = 'E'; const MESSAGE_ADD_PROC = 'PA'; const MESSAGE_EDIT_PROC = 'PE'; const MESSAGE_ADD_DOC = 'DA'; const MESSAGE_EDIT_DOC = 'DE'; const MESSAGE_ADD_TABLE = 'TA'; const MESSAGE_EDIT_TABLE = 'TE'; const MESSAGE_ACTION = 'M'; const MESSAGE_PRIVATE = 'P'; const MESSAGE_IMG = 'I'; const MESSAGE_9GAG = '9'; const MESSAGE_NICK = 'N'; const MESSAGE_STATUS = 'S'; const MESSAGE_CONN = 'C'; const MESSAGE_INVITE = 'V'; const MESSAGE_REBOOT = 'R'; const MESSAGE_ARTICLE = 'B'; const MESSAGE_NEWS = 'NW'; private static $MESSAGE_TYPES = array( 'user'=>self::MESSAGE_USER, 'add'=> array( 'code'=>self::MESSAGE_ADD_CODE, 'proc'=>self::MESSAGE_ADD_PROC, 'doc'=>self::MESSAGE_ADD_DOC, 'table'=>self::MESSAGE_ADD_TABLE), 'edit'=>array( 'code'=>self::MESSAGE_EDIT_CODE, 'proc'=>self::MESSAGE_EDIT_PROC, 'doc'=>self::MESSAGE_EDIT_DOC, 'table'=>self::MESSAGE_EDIT_TABLE), 'action'=>self::MESSAGE_ACTION, 'private'=>self::MESSAGE_PRIVATE, 'img'=>self::MESSAGE_IMG, '9gag'=>self::MESSAGE_9GAG, 'nick'=>self::MESSAGE_NICK, 'status'=>self::MESSAGE_STATUS, 'conn'=>self::MESSAGE_CONN, 'invite'=>self::MESSAGE_INVITE, 'reboot'=>self::MESSAGE_REBOOT, 'article'=>self::MESSAGE_ARTICLE, 'news'=>self::MESSAGE_NEWS); const DEFAULT_COMPANY_LOGO = 'logo_unknown_24.png'; const ADMIN_COMPANY_LOGO = 'logo_planeum_24.png'; const SYSTEM_COMPANY_LOGO = 'logo_ovh_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 = 800; 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_CHECKBOX = 'C'; const OPT_COLOR = 'R'; const OPT_NICKNAME = 1; const OPT_BG = 2; const OPT_BG_2 = 11; const OPT_BG_3 = 3; const OPT_HOVER = 4; const OPT_CHAT_BG = 6; const OPT_CHAT_HISTO = 10; const OPT_CHAT_IMAGES = 12; const OPT_STATUS = 7; const OPT_CONSOLE = 8; const OPT_EMAIL = 9; //Search Constants const CODE_TYPE = 'c'; const PROC_TYPE = 'p'; const ART_TYPE = 'a'; const DOC_TYPE = 'd'; const TABLE_TYPE = 't'; public static $HASH_TO_PAGE = array(self::CODE_TYPE=>'code', 'code'=>'code', self::PROC_TYPE=>'procedure', 'proc'=>'procedure', 'procedure'=>'procedure', self::TABLE_TYPE=>'table', 'table'=>'table', self::DOC_TYPE=>'doc', 'documentation'=>'doc', 'doc'=>'doc', self::ART_TYPE=>'article', 'art'=>'article', 'article'=>'article', 'n'=>'note', 'note'=>'note', 'note oss'=>'note', 'list'=>'list', 'liste'=>'list', 'chat'=>'chat', 'profil'=>'profile', 'profile'=>'profile', 'options'=>'options', 's'=>'search', 'r'=>'search', 'search'=>'search', 'recherche'=>'search', 'accueil'=>'welcome', 'erreur'=>'error', 'logout'=>'logout'); public static $TYPES = array( self::CODE_TYPE =>array('table' => self::CODE_TABLE, 'title' => 'Code'), self::PROC_TYPE =>array('table' => self::PROC_TABLE, 'title' => 'Procédure'), self::ART_TYPE =>array('table' => self::ART_TABLE, 'title' => 'Article'), self::DOC_TYPE =>array('table' => self::DOC_TABLE, 'title' => 'Documentation'), self::TABLE_TYPE=>array('table' => self::TABL_TABLE, 'title' => 'Table')); public static $PAGE_TITLES = array( 'code'=>'Code', 'chat'=>'Chat', 'doc'=>'Documentation', 'error'=>'Page introuvable', 'list'=>'La liste', 'options'=>'Paramètres', 'procedure'=>'Procédure', 'profile'=>'Profil', 'search'=>'Recherche', 'welcome'=>'Bienvenue', 'table'=>'Table', 'article'=>'Article de blog', 'logout'=>'Déconnexion', 'note'=>'Note OSS'); //Doc constants const DOC_FOLDER = 'docs/'; const DOC_TMP_FOLDER = 'docs/tmp/'; const DOC_THUMB_FOLDER = 'docs/thumb/'; //Objects private $oMySql; private $oSearchEngine; private $oClassManagement; private $oAuth; //Variables private $iUserId; private $asUsersInfo; private $sLanguage; /** * Constructor * @param ClassManagement $oClassManagement */ function __construct($oClassManagement, $sLanguage=self::LANG_FR) { parent::__construct(__CLASS__, Settings::DEBUG); $this->oClassManagement = $oClassManagement; $this->oClassManagement->incClass('auth'); $this->oClassManagement->incClass('mysqlmanager'); $this->oClassManagement->incClass('procedure'); $this->oClassManagement->incClass('searchengine'); $this->oClassManagement->incClass('mask'); //Hasher $this->oAuth = new Auth(); //Browser <> PHP <> MySql synchronization date_default_timezone_set(Settings::TIMEZONE); ini_set('default_charset', Settings::TEXT_ENC); header('Content-Type: text/html; charset='.Settings::TEXT_ENC); mb_internal_encoding(Settings::TEXT_ENC); mb_http_output(Settings::TEXT_ENC); mb_http_input(Settings::TEXT_ENC); mb_language('uni'); mb_regex_encoding(Settings::TEXT_ENC); //Databap Settings $this->setUserId(0); $this->sLanguage = $sLanguage; //Passing settings down to mySQL $this->oMySql = new MySqlManager(Settings::DB_SERVER, Settings::DB_LOGIN, Settings::DB_PASS, Settings::DB_NAME, self::getSqlOptions(), Settings::DB_ENC); if($this->oMySql->sDbState == MySqlManager::DB_NO_DATA && Settings::DEBUG==true) $this->install(); //Init Search Engine $this->oSearchEngine = new SearchEngine($this->oMySql); } public static function getSqlOptions() { $asOptions = array(); $asOptions['tables'] = array ( self::USER_TABLE => array('first_name', 'last_name', MySqlManager::getId(self::COMP_TABLE), 'pass', 'auth_cookie', 'active', 'clearance'), self::COMP_TABLE => array(MySqlManager::getText(self::COMP_TABLE), 'logo'), self::CODE_TABLE => array(MySqlManager::getText(self::CODE_TABLE), 'description', MySqlManager::getId(self::USER_TABLE), 'refer_id'), self::URL_TABLE => array(MySqlManager::getId(self::CODE_TABLE), 'phrase'), self::MSG_TABLE => array(MySqlManager::getId(self::USER_TABLE), 'nickname', MySqlManager::getId(self::CHAN_TABLE), MySqlManager::getText(self::MSG_TABLE), 'type', 'date'), self::CHAN_TABLE => array('safe_name', MySqlManager::getText(self::CHAN_TABLE)), self::CONN_TABLE => array(MySqlManager::getId(self::USER_TABLE), MySqlManager::getId(self::CHAN_TABLE)), self::OPT_TABLE => array(MySqlManager::getId(self::USER_TABLE), MySqlManager::getId(self::OPTNAME_TABLE), MySqlManager::getId(self::OPTVAL_TABLE)), self::OPTNAME_TABLE => array(MySqlManager::getText(self::OPTNAME_TABLE), 'type', 'language'), self::OPTVAL_TABLE => array(MySqlManager::getId(self::OPTNAME_TABLE), MySqlManager::getText(self::OPTVAL_TABLE), 'default_value', 'language'), self::PROC_TABLE => array(MySqlManager::getId(self::USER_TABLE), 'title', 'description', 'refer_id'), self::STEP_TABLE => array(MySqlManager::getId(self::PROC_TABLE), 'description'), self::IMG_TABLE => array(MySqlManager::getId(self::PROC_TABLE), MySqlManager::getId(self::STEP_TABLE), 'description', 'file_name'), self::DOC_TABLE => array(MySqlManager::getId(self::USER_TABLE), 'title', 'description', 'refer_id'), self::FILE_TABLE => array('id_item', 'type', 'description', 'hash', 'extension'), self::SEARCH_TABLE => array('id_item', 'refer_id', 'type', 'keywords'), self::ART_TABLE => array('title', 'link', 'date', 'first_name', 'last_name', 'email'), self::TABL_TABLE => array(MySqlManager::getId(self::USER_TABLE), 'title', 'description', 'system', 'keywords', 'refer_id') ); $asOptions['types'] = array ( 'first_name' => "varchar(20) NOT NULL", 'last_name' => "varchar(20) NOT NULL", 'nickname' => "varchar(50) NOT NULL", 'email' => "varchar(100) NOT NULL", 'hash' => "varchar(32) NOT NULL", 'pass' => "varchar(255) NOT NULL", 'auth_cookie' => "varchar(255) NOT NULL", 'active' => "tinyint(1) DEFAULT ".self::MEMBER_ACTIVE, 'clearance' => "int(1) DEFAULT ".self::CLEARANCE_MEMBER, MySqlManager::getText(self::CODE_TABLE) => "longtext NOT NULL", 'title' => "varchar(200) NOT NULL", 'description' => "varchar(500) NOT NULL", 'link' => "varchar(200) NOT NULL", 'refer_id' => "int(10) UNSIGNED NOT NULL", 'phrase' => "varchar(50) NOT NULL", MySqlManager::getText(self::MSG_TABLE) => "varchar(500) NOT NULL", 'type' => "varchar(2) NOT NULL", 'safe_name' => "varchar(50) NOT NULL", MySqlManager::getText(self::CHAN_TABLE) => "varchar(50) NOT NULL", MySqlManager::getText(self::OPTNAME_TABLE) => "varchar(100) NOT NULL", MySqlManager::getText(self::OPTVAL_TABLE)=> "varchar(100) NOT NULL", 'language' => "varchar(2) NOT NULL", 'file_name' => "varchar(40) NOT NULL", 'preview_name' => "varchar(40) NOT NULL", 'id_item' => "int(10) UNSIGNED NOT NULL", 'keywords' => "longtext NOT NULL", MySqlManager::getText(self::COMP_TABLE) => "varchar(30) NOT NULL", 'logo' => "varchar(20) NOT NULL", 'date' => "date NOT NULL", 'system' => "varchar(3)", 'extension' => "varchar(10)", 'default_value'=>"tinyint(1) DEFAULT 0" ); $asOptions['constraints'] = array ( self::USER_TABLE => "UNIQUE KEY `user_first_and_last_name` (`first_name`, `last_name`)", self::URL_TABLE => "UNIQUE KEY `uni_phrase` (`phrase`)", self::MSG_TABLE => "INDEX(`date`)", self::ART_TABLE => "INDEX(`title`)" ); $asOptions['cascading_delete'] = array ( self::CODE_TABLE => array(self::URL_TABLE), self::PROC_TABLE => array(self::STEP_TABLE, self::IMG_TABLE) ); return $asOptions; } public static function getTypeInfo($oInfo=array(), $sType='') { if($sType!='') { if($sType!='' && !array_key_exists($sType, self::$TYPES)) $this->addError('Type "'.$sType.'" inconnu'); else $asResult = array($sType=>self::$TYPES[$sType]); } else $asResult = self::$TYPES; //info if(is_string($oInfo)) $oInfo = array($oInfo); $bUnique = (count($oInfo)==1); if(!empty($oInfo)) { foreach($asResult as $sType=>$asTypeInfo) { $asResult[$sType] = array(); foreach($oInfo as $sInfo) { if(!array_key_exists($sInfo, $asTypeInfo)) $this->addError('Info "'.$sInfo.'" inconnue'); else $asResult[$sType][$sInfo] = $asTypeInfo[$sInfo]; } if($bUnique) $asResult[$sType] = $asResult[$sType][$sInfo]; } } return $asResult; } private function getPageTitles($sPage='') { $asPageTitles = self::$PAGE_TITLES; if($sPage!='' && !array_key_exists($sPage, $asPageTitles)) $this->addError('Page "'.$sPage.'" inconnu'); return $sPage==''?$asPageTitles:$asPageTitles[$sPage]; } private function getPagesFromHash($sHash='') { $asHashToPage = self::$HASH_TO_PAGE; if($sHash!='' && !array_key_exists($sHash, $asHashToPage)) $this->addError('Hash "'.$sHash.'" inconnu'); return $sHash==''?$asHashToPage:$asHashToPage[$sHash]; } private function install() { //Install DB $this->oMySql->install(); //Options $sOptionNameCol = MySqlManager::getText(self::OPTNAME_TABLE); $sOptionValueCol = MySqlManager::getText(self::OPTVAL_TABLE); $sOptionNameIdCol = MySqlManager::getId(self::OPTNAME_TABLE); $sOptionValueIdCol = MySqlManager::getId(self::OPTVAL_TABLE); $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_NICKNAME, $sOptionNameCol=>'pseudo du chat', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR)); $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_BG, $sOptionNameCol=>'couleur de fond', 'type'=>self::OPT_COLOR, 'language'=>self::LANG_FR)); $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_BG_2, $sOptionNameCol=>'couleur de fond 2', 'type'=>self::OPT_COLOR, 'language'=>self::LANG_FR)); $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_BG_3, $sOptionNameCol=>'couleur de fond 3', 'type'=>self::OPT_COLOR, 'language'=>self::LANG_FR)); $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_HOVER, $sOptionNameCol=>'couleur de survol', 'type'=>self::OPT_COLOR, 'language'=>self::LANG_FR)); $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_CHAT_BG, $sOptionNameCol=>'image du chat', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR)); $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_STATUS, $sOptionNameCol=>'mission en cours', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR)); $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_CONSOLE, $sOptionNameCol=>'afficher la console du chat', 'type'=>self::OPT_CHECKBOX, 'language'=>self::LANG_FR)); $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_EMAIL, $sOptionNameCol=>'email', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR)); $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_CHAT_HISTO, $sOptionNameCol=>'historique du chat (jours)', 'type'=>self::OPT_TEXT, 'language'=>self::LANG_FR)); $this->oMySql->insertRow(self::OPTNAME_TABLE, array($sOptionNameIdCol=>self::OPT_CHAT_IMAGES, $sOptionNameCol=>'afficher les images du chat', 'type'=>self::OPT_CHECKBOX, 'language'=>self::LANG_FR)); //Select/checkbox and Default Option values: option_name => array(option_value => is_default, ...) $asDefaultValues = array( self::OPT_CONSOLE=>array(true=>false, false=>true), self::OPT_NICKNAME=>array('Utilisateur inconnu'=>true), self::OPT_BG=>array('#04357B'=>true), self::OPT_BG_2=>array('#88B2F0'=>true), self::OPT_BG_3=>array('#D9E5F2'=>true), self::OPT_HOVER=>array('#EFAB00'=>true), self::OPT_CHAT_BG=>array('images/sap_gold_332.jpg'=>true), self::OPT_STATUS=>array('aucune mission en cours'=>true), self::OPT_EMAIL=>array('email inconnu'=>true), self::OPT_CHAT_HISTO=>array('0'=>true), self::OPT_CHAT_IMAGES=>array(true=>true, false=>false) ); foreach($asDefaultValues as $sOptionNameId=>$asOptionValues) { foreach($asOptionValues as $sOptionValue=>$bDefault) { $this->oMySql->insertRow(self::OPTVAL_TABLE, array($sOptionNameIdCol=>$sOptionNameId, $sOptionValueCol=>$sOptionValue, 'default_value'=>$bDefault, 'language'=>self::LANG_FR)); } } //Insert default and all channels $this->oMySql->insertRow(self::CHAN_TABLE, array('safe_name'=>self::getChanSafeName(self::ALL_CHAN_TEXT), MySqlManager::getText(self::CHAN_TABLE)=>self::ALL_CHAN_TEXT)); $this->oMySql->insertRow(self::CHAN_TABLE, array('safe_name'=>self::getChanSafeName(self::DEFAULT_CHAN), MySqlManager::getText(self::CHAN_TABLE)=>self::DEFAULT_CHAN)); //Install default users : system, admin and test $iSystemCompanyId = $this->addCompany('ovh', self::SYSTEM_COMPANY_LOGO, false); $this->addUser('databap', 'bot', $iSystemCompanyId, 'databap@botnet.com', self::CLEARANCE_ADMIN, self::SYSTEM_USER_ID, false); $this->setOptions(array(self::OPT_NICKNAME=>'Databot'), true, self::SYSTEM_USER_ID); $iAdminCompanyId = $this->addCompany('planeum', self::ADMIN_COMPANY_LOGO, false); $this->addUser('françois', 'lutran', $iAdminCompanyId, 'francois@lutran.fr', self::CLEARANCE_ADMIN, 0, false); $this->addUser('test', 'test', $iAdminCompanyId, 'test@test.com', self::CLEARANCE_MEMBER, 0, false); //Write the SAP blog parser bash script to main folder $this->updateWebCrawler(); } public function updateWebCrawler() { $sContent = "#!/bin/bash\n\ncd /var/www\n\n/usr/bin/php -f index.php a=external_access p=blogs auth_token=".self::SYSTEM_USER_ID.'_'.str_replace('$', '\$', $this->generateExternalAccessToken(self::SYSTEM_USER_ID)); $bSuccess = !(file_put_contents('sap_website_parser.sh', $sContent)===false); $sDesc = $bSuccess?'Fichier écrit avec succès':'Erreur lors de l\'écriture du fichier à la racine de l\'application. Vérifier les droits sur ce dossier'; return $this->getJsonPostResult($bSuccess, $sDesc); } public function goLive() { } private function setUserId($iUserId) { $this->iUserId = $iUserId; $this->setUserInfo(); } public function getUserId() { return $this->iUserId; } public function getPage($sPage, $oItemId, $asVars=array()) { $oPage = new Mask('index'); $oPage->setTag('version', self::VERSION); $oPage->setTag('text_enc', Settings::TEXT_ENC); $oPage->setTag('index_link', $_GET['serv_name']); $oPage->setTag('rss_link', $this->generateExternalAccessLink('rss', $this->getUserid())); //Constants $asConstants = array( 'version'=>self::VERSION, 'version_date'=>self::VERSION_DATE, 'default_page'=>$sPage, 'default_id'=>$oItemId, 'errors'=>array('disconnected'=>self::DISCONNECTED, 'not_authorized'=>self::NOT_AUTH, 'not_found'=>self::NOT_FOUND, 'system'=>array(self::FAIL_INSERT, self::FAIL_UPDATE, 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, 'opt_type_checkbox'=>self::OPT_CHECKBOX, 'opt_type_color'=>self::OPT_COLOR, 'max_size'=>self::getMaxSize(), 'authorized_img_exts'=>self::$UPLOAD_IMG_EXTS, 'authorized_file_exts'=>self::$UPLOAD_DOC_EXTS, 'id_sep'=>self::ID_SEPARATOR, 'mask_folder'=>Mask::MASK_FOLDER, 'image_folder'=>Procedure::IMAGE_FOLDER, 'image_folder_tmp'=>Procedure::IMAGE_FOLDER_TMP, 'image_folder_thumb'=>Procedure::IMAGE_FOLDER_THUMB, 'default_chan'=>self::DEFAULT_CHAN, 'all_chan_id'=>self::ALL_CHAN_ID, 'all_chan_text'=>self::ALL_CHAN_TEXT, 'pm_separator'=>self::PM_SEP, 'reboot_delay'=>self::REBOOT_DELAY, 'versionHtml'=>$this->getItemBlock(), 'types'=>$this->getTypeInfo('title'), 'msg_types'=>self::$MESSAGE_TYPES, 'cur_date'=>date(self::DATE_FORMAT)); $oPage->setTag('constants', $this->jsonConvert($asConstants)); //Variables $asVars['page_titles'] = $this->getPageTitles(); $asVars['user_id'] = $this->getUserId(); $asVars['hash_to_page'] = $this->getPagesFromHash(); $asVars['page_to_hash'] = array_flip($asVars['hash_to_page']); $asVars['opt_console'] = ($this->getUserOptionValue(self::OPT_CONSOLE)==true); $asVars['opt_chat_images'] = ($this->getUserOptionValue(self::OPT_CHAT_IMAGES)==true); $oPage->setTag('variables', $this->jsonConvert($asVars)); return $oPage->getMask(); } public function getLogonPage($bFirstConn) { $oPage = new Mask('logon'); $oPage->setTag('text_enc', Settings::TEXT_ENC); $oPage->setTag('feedback', $bFirstConn?'':'Données incorrectes'); $oPage->setTag('version', self::VERSION); $oPage->setTag('name_pass_sep', self::NAME_PASS_SEP); return $oPage->getMask(); } public function getRss($sCat='') { //Class Feed $this->oClassManagement->incClass('rss'); //Building header $asDesc = array ( 'title'=>'Flux RSS Databap'.($sCat==''?'':' - '.$sCat), 'link'=>$this->getInternalLink('rss', $sCat), 'copyright'=>'Powered by Francois Lutran. RSS Feed Generator under GPLv3 License', 'description'=>'Flux RSS du chat'.($sCat==''?'':', section '.$sCat), 'language'=>'fr', 'webmaster_mail'=>'francois@lutran.fr' ); $oFeed = new Feed($asDesc); //Building items if($sCat=='news') { $asNews = $this->getNews(false); $iLinkId = count($asNews); foreach($asNews as $asRow) { //TODO mutualiser avec le reste $sChatlink = $this->getInternalLink('chat', $asRow[MySqlManager::getId(self::MSG_TABLE)]); $asItem = array ( 'title'=>'Lien'.($sCat==''?'':' - '.$sCat).' #'.$iLinkId, 'category'=>$sCat, 'description'=>$asRow['message'], 'author'=>$asRow['nickname'], 'link'=>$sChatlink, 'pub_date'=>$asRow['time'], 'guid'=>$sChatlink ); $oFeed->addItem($asItem); $iLinkId -= 1; } } else { switch($sCat) { case '9gag': $sRegEx = '(https?://|www\\.)(.*)9gag\\.com'; break; case 'youtube': $sRegEx = '(https?://|www\\.)(.*)youtube\\.com'; break; case '': $sRegEx = '(https?://|www\\.)[\.A-Za-z0-9\-]+\\.[a-zA-Z]{2,4}'; break; default: $sRegEx = '(https?://|www\\.)(.*)'.$sCat.'(.*)\\.[a-zA-Z]{2,4}'; break; } $sMessageIdCol = MySqlManager::getId(self::MSG_TABLE); $sChanIdCol = MySqlManager::getId(self::CHAN_TABLE); $asResult = $this->oMySql->selectRows(array('select'=>array($sMessageIdCol, 'nickname', $sChanIdCol, 'message', 'led'), 'from'=>self::MSG_TABLE, 'constraint'=>array('message'=>$sRegEx), 'constOpe'=>array('message'=>' REGEXP '))); $asChans = $this->oMySql->selectRows(array('select'=>array($sChanIdCol, 'safe_name'), 'from'=>self::CHAN_TABLE), true, $sChanIdCol); $sPattern = '/(https?\:\/\/|www\.)[\S]+\.[a-zA-Z]{2,4}([\S]*)/ui'; foreach($asResult as $iLinkId=>$asRow) { //filter on authorized chans if($this->checkChanAuth($asChans[$asRow[$sChanIdCol]], $this->getUserId())) { //get link out of message preg_match($sPattern, $asRow['message'], $asMatches); $asRow['link'] = (substr($asMatches[0], 0, 4)=='http')?$asMatches[0]:'http://'.$asMatches[0]; //add item $sChatlink = $this->getInternalLink('chat', $asRow['id_message']); $asItem = array ( 'title'=>'Lien'.($sCat==''?'':' - '.$sCat).' #'.($iLinkId+1), 'category'=>$sCat, 'description'=>'Lien posté par '.self::getNickNameFormat($asRow['nickname']).' à '.self::getDateFormat($asRow['led']).' : '.$asRow['message'].'', 'author'=>$asRow['nickname'], 'link'=>$sChatlink, 'pub_date'=>$asRow['led'], 'guid'=>$sChatlink ); $oFeed->addItem($asItem); } } } return $oFeed->getFeed(); } public function syncSapBlog() { //Get articles list $asArticles = $this->getSAPBlogRss(); //Update and spread the news $asResult = array(); $iTimeStamp = time(); if(date('N', $iTimeStamp)>5 || date('G', $iTimeStamp)>19) $asResult[] = "Pas de mise-à-jour pendant le week end ou en soirée."; else { foreach($asArticles as $asArticle) { $iArticleId = $this->oMySql->selectValue(self::ART_TABLE, MySqlManager::getId(self::ART_TABLE), array('title'=>$asArticle['title'])); if(!$iArticleId) { $iArticleId = $this->oMySql->insertRow(self::ART_TABLE, $asArticle); $this->addMessage($iArticleId, self::MESSAGE_ARTICLE, self::DEFAULT_CHAN_ID); $this->oSearchEngine->buildIndex($iArticleId, self::ART_TYPE); $sResult = 'ADDED'; } else $sResult = 'OK'; $asResult[$iArticleId] = $sResult.' | '.implode(' | ', $asArticle); } } return MySqlManager::implodeAll($asResult, '->', "\n"); } private function getSAPBlogRss() { $asArticles = array(); //SCN SAP $sSAPDomain = 'http://scn.sap.com'; $asBlogPaths = array( '/community/data-warehousing/bw/blog', '/community/data-warehousing/blog', '/community/bw-hana/blog', '/community/businessobjects-design-studio/blog', '/community/businessobjects-analysis-ms-office/blog'); foreach($asBlogPaths as $sSAPBlogPath) { $sSAPBlogUrl = $sSAPDomain.$sSAPBlogPath; $oDom = $this->getRemotePageDom($sSAPBlogUrl); $aoArticles = $oDom->getElementsByTagName('header'); foreach($aoArticles as $oArticle) { if($oArticle->getAttribute('class')=='jive-blog-post-subject') { $asArticleInfo = array(); $aoLinks = $oArticle->getElementsByTagName('a'); foreach($aoLinks as $oLink) { switch($oLink->getAttribute('class')) { //Title & link case 'font-color-normal': $asArticleInfo['title'] = trim($oLink->nodeValue); $asArticleInfo['title'] = mb_substr($asArticleInfo['title'], -1)=='.'?mb_substr($asArticleInfo['title'], 0, -1):$asArticleInfo['title']; $asArticleInfo['link'] = $oLink->getAttribute('href'); $asArticleInfo['date'] = mb_substr(str_replace(array($sSAPBlogUrl.'/', '/'), array('', '-'), $asArticleInfo['link']), 0, 10); break; //Author case 'jiveTT-hover-user jive-username-link': $asNames = array_filter(explode(' ', ToolBox::mb_ucwords(trim($oLink->nodeValue)))); $asArticleInfo['first_name'] = array_shift($asNames); $asArticleInfo['last_name'] = implode('-', $asNames); $asArticleInfo['email'] = $sSAPDomain.$oLink->getAttribute('href'); break; } } $asArticles[] = $asArticleInfo; } } } //BI Portal $oDom = $this->getRemotePageDom('http://www.biportal.org/sap_bi_blog'); $aoArticles = $oDom->getElementsByTagName('li'); foreach($aoArticles as $oArticle) { if($oArticle->getAttribute('class')=='boxesListItem' && $oArticle->getAttribute('id') > 0) { $asArticleInfo = array(); $aoLinks = $oArticle->getElementsByTagName('a'); $oLink = $aoLinks->item(0); $asArticleInfo['link'] = $oLink->getAttribute('href'); $asArticleInfo['title'] = trim($oLink->nodeValue); $aoLinks = $oArticle->getElementsByTagName('span'); foreach($aoLinks as $oLink) { switch($oLink->getAttribute('class')) { case 'postedOn': $asArticleInfo['date'] = date(self::DATE_SQL_FORMAT, strtotime($oLink->nodeValue)); break; case 'postedByLink': $sName = trim($oLink->firstChild->nodeValue); $asArticleInfo['first_name'] = strstr($sName, ' ', true); $asArticleInfo['last_name'] = substr(strstr($sName, ' '), 1); $asArticleInfo['email'] = $oLink->firstChild->getAttribute('href'); break; } } $asArticles[] = $asArticleInfo; } } //SAP BW BW $oDom = $this->getRemotePageDom('http://sapbwbw.com/'); $aoArticles = $oDom->getElementsByTagName('header'); foreach($aoArticles as $oArticle) { if($oArticle->getAttribute('class')=='entry-header') { $asArticleInfo = array(); $aoLinks = $oArticle->getElementsByTagName('a'); $oLink = $aoLinks->item(0); $asArticleInfo['link'] = $oLink->getAttribute('href'); $asArticleInfo['title'] = trim($oLink->nodeValue); $aoLinks = $oArticle->getElementsByTagName('time'); $oLink = $aoLinks->item(0); $asArticleInfo['date'] = mb_substr($oLink->getAttribute('datetime'), 0, 10); $asArticleInfo['first_name'] = 'Claudio'; $asArticleInfo['last_name'] = 'Ciardelli'; $asArticleInfo['email'] = ''; $asArticles[] = $asArticleInfo; } } return $asArticles; } private function get9gagPost($sUrl) { $asPost = array('url'=>$sUrl); $oDom = $this->getRemotePageDom($sUrl); $oDivs = $oDom->getElementsByTagName('section'); foreach($oDivs as $oPost) {if($oPost->getAttribute('id')=='individual-post') break;} //Title $asPost['title'] = $oPost->getElementsByTagName('h2')->item(0)->nodeValue; //Movie $sSource = ''; $oMovies = $oPost->getElementsByTagName('div'); foreach($oMovies as $oMovie) { if($oMovie->getAttribute('class')=='badge-animated-container-animated post-view') { $sSource = $oMovie->getAttribute('data-image'); break; } } //Image if($sSource=='') { $oImages = $oPost->getElementsByTagName('img'); foreach($oImages as $oImage) { switch($oImage->getAttribute('class')) { case 'badge-item-animated-img': $o9gagImage = $oImage; break 2; //exit case 'badge-item-img': $o9gagImage = $oImage; break; //keep on looking for animated gif } } if(isset($o9gagImage)) $sSource = $o9gagImage->getAttribute('src'); } $asResult = array(); if(isset($sSource)) $asResult = $this->downloadToTmp($sSource); else $asResult['error'] = 'Not safe for work'; if($asResult['error']=='') { $asPost['url_img'] = $asResult['out']; $asPost['width'] = $asResult['width']; $asPost['height'] = $asResult['height']; } $asPost['error'] = $asResult['error']; return $asPost; } private function getRemotePageDom($sUrl) { $oDom = new DOMDocument(); if(mb_substr($sUrl, 0, 4)!='http') $sUrl = 'http://'.$sUrl; @$oDom->loadHTML(file_get_contents($sUrl)); return $oDom->getElementsByTagName('body')->item(0); } public function getNote($iNote) { $this->oClassManagement->incClass('note'); $oNote = new Note($iNote); return $oNote->getNote(); } public function addUser($sFirstName, $sLastName, $iCompanyId, $sEmail='', $iClearance=self::CLEARANCE_MEMBER, $iUserId=0, $bExt=true) { $sFirstName = trim(mb_strtolower($sFirstName)); $sLastName = trim(mb_strtolower($sLastName)); $sEmail = trim(mb_strtolower($sEmail)); //Get Company $sCompany = $this->oMySql->selectValue(self::COMP_TABLE, MySqlManager::getText(self::COMP_TABLE), $iCompanyId); if(!$sCompany) $sDesc = 'ID entreprise inconnu : '.$iCompanyId; else { //Checking company existency in company table $asInfo = array('first_name'=>$sFirstName, 'last_name'=>$sLastName, 'active'=>self::MEMBER_ACTIVE, MySqlManager::getId(self::COMP_TABLE)=>$iCompanyId, 'pass'=>$this->oAuth->HashPassword(self::getLoginToken($sCompany)), 'clearance'=>$iClearance, 'led'=>'0000-00-00 00:00:00'); if($iUserId>0) $asInfo[MySqlManager::getId(self::USER_TABLE)] = $iUserId; $iUserId = $this->oMySql->insertRow(self::USER_TABLE, $asInfo); $bSuccess = ($iUserId>0); if($bSuccess) { //Options & default values $sNickName = self::getNickNameFormat($sFirstName); $this->setOptions(array(self::OPT_NICKNAME=>$sNickName, self::OPT_EMAIL=>$sEmail), true, $iUserId); //Spread the word if($iUserId!=self::SYSTEM_USER_ID) $this->addMessage('Nouvel utilisateur: '.self::getNameFormat($sFirstName, $sLastName).' ! Son petit nom sur le chat est '.$sNickName, self::MESSAGE_NEWS, self::DEFAULT_CHAN_ID, self::SYSTEM_USER_ID); $sDesc = 'Utilisateur '.$iUserId.' ajouté avec succès'; } else $sDesc = 'Erreur lors de l\'ajout de l\'utilisateur '.$sFirstName.' '.$sLastName.' (company : '.$sCompany.')'; } return $bExt?$this->getJsonPostResult($bSuccess, $sDesc):$iUserId; } public function addCompany($sCompany, $sLogo='', $bExt=true) { $sCompany = trim(mb_strtolower($sCompany)); $sLogo = $sLogo==''?self::DEFAULT_COMPANY_LOGO:$sLogo; $iCompanyId = 0; $bSuccess = false; $sDesc = ''; if($sCompany!='') { $sCompanyTextCol = MySqlManager::getText(self::COMP_TABLE); $iCompanyId = $this->oMySql->selectInsert(self::COMP_TABLE, array($sCompanyTextCol=>$sCompany, 'logo'=>$sLogo), array($sCompanyTextCol)); if($iCompanyId>0) { $bSuccess = true; $sDesc = 'Entreprise '.$iCompanyId.' créée'; } else $sDesc = 'Erreur lors de la création de l\'entreprise '.$sCompany; } else $sDesc = 'Nom d\'entreprise vide'; return $bExt?$this->getJsonPostResult($bSuccess, $sDesc):$iCompanyId; } public function buildCompleteIndex() { $this->oMySql->emptyTable(self::SEARCH_TABLE); foreach($this->getTypeInfo('table') as $sSearchType=>$sSearchTable) { $asItemIds = $this->oMySql->selectRows(array('select'=>MySqlManager::getId($sSearchTable), 'from'=>$sSearchTable)); foreach($asItemIds as $iItemId) $this->oSearchEngine->buildIndex($iItemId, $sSearchType); } } //insert new code / version public function addCode($asData) { $sContent = $asData['content']; $sDescription = $asData['description']; $sLink = str_replace(' ', '_', $asData['link']); //insert value in db $asInsert = array( MySqlManager::getText(self::CODE_TABLE)=>$sContent, 'description'=>$sDescription, 'id_user'=>$this->getUserId()); $iCodeId = $this->oMySql->insertRow(self::CODE_TABLE, $asInsert); //insert link if exists if($sLink!='') { $asInsert = array(MySqlManager::getId(self::CODE_TABLE)=>$iCodeId, 'phrase'=>$sLink); $this->oMySql->insertRow(self::URL_TABLE, $asInsert); } //refer id update $this->oMySql->updateRow(self::CODE_TABLE, $iCodeId, array('refer_id'=>$iCodeId)); //Add message $this->addMessage($iCodeId, self::MESSAGE_ADD_CODE, self::DEFAULT_CHAN_ID); //Add record in Search Table $this->oSearchEngine->buildIndex($iCodeId, self::CODE_TYPE); return $iCodeId; } public function editCode($oCode, $sContent) { $asRef = $this->getCodeInfo($oCode, 'first'); $iVersion = $this->oMySql->selectValue(self::CODE_TABLE, 'COUNT(id_code)', array('refer_id'=>$asRef['id_code']))+1; $asEdit = array('code'=>$sContent, 'description'=>$asRef['description'].' (v'.$iVersion.')', 'id_user'=>$this->iUserId, 'refer_id'=>$asRef['id_code']); $iCodeId = $this->oMySql->insertRow(self::CODE_TABLE, $asEdit); //Add message $this->addMessage($iCodeId, self::MESSAGE_EDIT_CODE, self::DEFAULT_CHAN_ID); //Add record in Search Table $this->oSearchEngine->buildIndex($iCodeId, self::CODE_TYPE); return $iCodeId; } public function addProcedure($asPost) { $oProcedure = new Procedure($this->oMySql); $asPost['id_user'] = $this->getUserId(); $oProcedure->inputForm($asPost); $asErrors = $oProcedure->checkIntegrity(); if(count($asErrors)==0) { //Previous procedure Id $iPrevProcId = isset($asPost['procedure_id'])?$asPost['procedure_id']:0; //Load procedure into database $bCreation = $oProcedure->saveProcedure($iPrevProcId); //Extract extra data $asProc = $oProcedure->getProcedure(); $iNewProcId = $asProc['proc_id']; $asUser = $this->getUserInfo(); $oResult = array('result'=>'success', 'proc_id'=>$iNewProcId, 'led'=>$asProc['led'], 'name'=>$asUser['name'], 'company'=>$asUser['company']); //Add Message in chat if($bCreation) { $this->addMessage($iNewProcId, self::MESSAGE_ADD_PROC, self::DEFAULT_CHAN_ID); } else { $this->addMessage($iNewProcId, self::MESSAGE_EDIT_PROC, self::DEFAULT_CHAN_ID); } //Add record in Search Table $this->oSearchEngine->buildIndex($iNewProcId, self::PROC_TYPE); } else { $oResult = array('result'=>'fail', 'errors'=>$asErrors); } return self::jsonExport($oResult); } public function getProcedure($iProcId) { $oProcedure = new Procedure($this->oMySql); $oProcedure->loadProcedure($iProcId); $asProc = $oProcedure->getProcedure(); //Adding user info $asUser = $this->getUserInfo($asProc['id_user']); $asProc['name'] = $asUser['name']; $asProc['company'] = $asUser['company']; return self::jsonExport($asProc); } public function addDoc($asPost) { //Previous Doc Id $iPrevDocId = array_key_exists('doc_id', $asPost)?$asPost['doc_id']:0; $bCreation = ($iPrevDocId==0); //User $iUserId = $this->getUserId(); //Titles $sTitle = isset($asPost['title'])?$asPost['title']:''; $sDescription = isset($asPost['description'])?$asPost['description']:''; //Get docs $sImagePattern = '/c1_(?P\d+)_image_(?P\w+)/u'; foreach($asPost as $sFormId=>$sValue) { preg_match($sImagePattern, $sFormId, $asMatches); if(!empty($asMatches) && ($asMatches['doc_info'] == 'name' || $asMatches['doc_info'] == 'desc')) { $asDocs[$asMatches['doc_id']][$asMatches['doc_info']] = $sValue; } } //Load doc into database $asData = array('title'=>$sTitle, 'description'=>$sDescription, MySqlManager::getId(self::USER_TABLE)=>$iUserId); $iDbDocId = $this->oMySql->insertRow(self::DOC_TABLE, $asData); //Load doc files into database $asDocData['id_item'] = $iDbDocId; $asDocData['type'] = self::DOC_TYPE; foreach($asDocs as $asDocInfo) { //insert into database $sFileName = $asDocInfo['name']; $asFileInfo = pathinfo($sFileName); $asDocData['description'] = $asDocInfo['desc']; $asDocData['hash'] = $asFileInfo['filename'];; $asDocData['extension'] = $asFileInfo['extension']; $iDbImageId = $this->oMySql->insertRow(self::FILE_TABLE, $asDocData); //Move file $sTempFilePath = self::DOC_TMP_FOLDER.$sFileName; $sFilePath = self::DOC_FOLDER.$sFileName; if(!rename($sTempFilePath, $sFilePath)) $this->addError('Unmoveable file : '.$sTempFilePath); } //Add this doc to the group $iReferId = $bCreation?$iDbDocId:$this->oMySql->selectValue(self::DOC_TABLE, 'refer_id', $iPrevDocId); $this->oMySql->updateRow(self::DOC_TABLE, $iDbDocId, array('refer_id'=>$iReferId)); //Add Message in chat $this->addMessage($iDbDocId, $bCreation?self::MESSAGE_ADD_DOC:self::MESSAGE_EDIT_DOC, self::DEFAULT_CHAN_ID); //Add record in Search Table $this->oSearchEngine->buildIndex($iDbDocId, self::DOC_TYPE); //TODO add error handling return $this->getJsonPostResult(true, '', array('doc_id'=>$iDbDocId)); } public function getDoc($iDocId) { //Extract doc data $asDoc = $this->oMySql->selectRow(self::DOC_TABLE, $iDocId); $bSuccess = !empty($asDoc); $sDesc = ''; if(!$bSuccess) $sDesc = self::NOT_FOUND; else { $asDoc['description'] = self::getDescriptionFormat($asDoc['description']); $asDoc['title'] = self::getDescriptionFormat($asDoc['title']); $asDoc['led'] = self::getDateFormat($asDoc['led']); //Extract extra data $asUser = $this->getUserInfo($asDoc[MySqlManager::getId(self::USER_TABLE)]); $asDoc['name'] = $asUser['name']; $asDoc['company'] = $asUser['company']; //Extract doc files $sFileIdCol = MySqlManager::getId(self::FILE_TABLE); $asFiles = $this->oMySql->selectRows(array('from'=>self::FILE_TABLE, 'constraint'=>array('id_item'=>$iDocId, 'type'=>self::DOC_TYPE))); foreach($asFiles as $asFile) { $asDoc['files'][$asFile[$sFileIdCol]] = array( 'description' => self::getDescriptionFormat($asFile['description']), 'ext' => $asFile['extension']); } } return $this->getJsonPostResult($bSuccess, $sDesc, $asDoc); } public function addTable($sSystem, $sTitle, $sDescription, $sKeyWords, $iPrevTableId, $bSimul=false) { $bCreation = ($iPrevTableId==0); $iDbTableId = 0; $sDesc = ''; //Previous table info if(!$bCreation) $asPrevTableInfo = $this->getTableInfo($iPrevTableId, false); //New table info $sTitle = mb_strtolower($bCreation?trim($sTitle):$asPrevTableInfo['title']); $sDescription = mb_strtolower(trim($sDescription)); //Check for existing table with the same name if($bCreation && $this->checkValue(self::TABL_TABLE, array('title'=>$sTitle))) $sDesc = ToolBox::findReplaceLinks('Une documentation existe déjà pour la table '.self::getTableFormat($sTitle)); elseif(!$bCreation && $iPrevTableId!=$this->getUpToDateId(self::TABL_TABLE, $sTitle)) $sDesc = ToolBox::findReplaceLinks('Une version plus récente de la table '.self::getTableFormat($sTitle).' existe'); elseif(!$bSimul) { //Load table into database $asData = array(MySqlManager::getId(self::USER_TABLE)=>$this->getUserId(), 'title'=>$sTitle, 'description'=>$sDescription, 'system'=>$sSystem, 'keywords'=>$sKeyWords); $iDbTableId = $this->oMySql->insertRow(self::TABL_TABLE, $asData); if(!$iDbTableId) $sDesc = 'Erreur inconnue dans la base de données'; else { //Add the group refer id $iReferId = $bCreation?$iDbTableId:$this->oMySql->selectValue(self::TABL_TABLE, 'refer_id', $iPrevTableId); $this->oMySql->updateRow(self::TABL_TABLE, $iDbTableId, array('refer_id'=>$iReferId)); //Add Message in chat $this->addMessage($iDbTableId, $bCreation?self::MESSAGE_ADD_TABLE:self::MESSAGE_EDIT_TABLE, self::DEFAULT_CHAN_ID); //Add record in Search Table $this->oSearchEngine->buildIndex($iDbTableId, self::TABLE_TYPE); } } return $this->getJsonPostResult($iDbTableId>0, $sDesc, array('id'=>$iDbTableId, 'name'=>$sTitle)); } public function getTable($oTableId) { $bReadById = is_numeric($oTableId); $iTableId = $bReadById?$oTableId:$this->getUpToDateId(self::TABL_TABLE, mb_strtolower($oTableId)); //Extract table data $asTable = $this->getTableInfo($iTableId); $bSuccess = !empty($asTable); $sDesc = ''; if($bSuccess) { $asTable['date'] = self::getDateFormat($asTable['timestamp'], self::DATE_FORMAT); $asTable['title'] = $asTable['table_name']; unset($asTable['timestamp']); $asTable['id'] = $asTable[MySqlManager::getId(self::TABL_TABLE)]; //Extract extra data $asUser = $this->getUserInfo($asTable[MySqlManager::getId(self::USER_TABLE)]); $asTable['name'] = $asUser['name']; $asTable['company'] = $asUser['company']; //Out of date warning $sRightTableLink = ToolBox::findReplaceLinks('Il existe une documentation plus à jour pour la table '.self::getTableFormat($asTable['title'])); $asTable['warning'] = ($bReadById && $iTableId!=$this->getUpToDateId(self::TABL_TABLE, $iTableId))?$sRightTableLink:''; } else $sDesc = self::NOT_FOUND; return $this->getJsonPostResult($bSuccess, $sDesc, $asTable); } //TODO good idea ? If yes, apply to all types. Put in MySqlManager ? involve switchCodeId() private function getUpToDateId($sTableName, $oId) { if(is_numeric($oId)) $asConstraint = array('refer_id'=>$this->oMySql->selectValue(self::TABL_TABLE, 'refer_id', $oId)); //by Id else $asConstraint = array('title'=>$oId); //by phrase $sItemIdCol = 'id_item'; $asInfo = array('select'=>array("MAX(".MySqlManager::getId($sTableName).") AS ".$sItemIdCol), //selecting last version among codes having the same refer_id 'from'=>$sTableName, 'constraint'=>$asConstraint, 'groupBy'=>array('refer_id'), 'orderBy'=>array($sItemIdCol=>'desc')); $asResult = $this->oMySql->selectRows($asInfo); return array_shift($asResult); } public function getFile($iFileId) { //File info $asFileInfo = $this->oMySql->selectRow(self::FILE_TABLE, $iFileId); $sFileExt = $asFileInfo['extension']; $sFileDesc = str_replace("&", '\&', str_replace(" ", '\ ', addslashes($asFileInfo['description']))).'.'.$sFileExt; $sFilePath = self::DOC_FOLDER.$asFileInfo['hash'].'.'.$asFileInfo['extension']; $sFileFullPath = dirname($_SERVER['SCRIPT_FILENAME'])."/".$sFilePath; $sResult = ''; if(!file_exists($sFilePath)) header("HTTP/1.0 404 Not Found"); else { //Get mime type & set headers if(!class_exists('finfo')) $sMimetype = 'application/force-download'; else { $oFileInfo = new finfo(FILEINFO_MIME); $sMimetype = $oFileInfo->file($sFileFullPath); } header('Pragma: public'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Cache-Control: public'); header('Content-Description: File Transfer'); header('Content-Type: '.$sMimetype); header('Content-Disposition: attachment; filename='.$sFileDesc); header('Content-Transfer-Encoding: binary'); header('Content-Length: '.@filesize($sFilePath)); //Download if ($oFile = @fopen($sFilePath, 'rb')) { while(!feof($oFile)) { $sResult .= print_r(fread($oFile, 1024*8), true); flush(); if(connection_status() != 0) @fclose($oFile); } @fclose($oFile); } } return $sResult; } public function uploadFile($sFileType) { switch($sFileType) { case 'image': $asAuthorizedTypes = self::$UPLOAD_IMG_EXTS; break; case 'doc' : $asAuthorizedTypes = self::$UPLOAD_DOC_EXTS; break; default : $asAuthorizedTypes = array(); } $this->oClassManagement->incClass('fileuploader'); $oFileUploader = new fileUploader(self::DOC_TMP_FOLDER, $asAuthorizedTypes); $asResult = $oFileUploader->handleUpload(); return $this->jsonConvert($asResult); } private function getItemInfo($sType, $iItemId) { return call_user_func(array($this, 'get'.ucfirst($this->getPagesFromHash($sType)).'Info'), $iItemId); } //TODO: one function only with a type parameter private function getCodeInfo($oCode, $sMode='', $bCode=false) { $iCodeId = is_numeric($oCode)?$oCode:$this->getIdCodeFromPhrase($oCode); //Mode (get last or first id_code) if($sMode!='') { $this->switchCodeId($iCodeId, $sMode); } //Efficient request : don't request for the entire code if(!$bCode) { $asSelect = $this->oMySql->getTablecolumns(self::CODE_TABLE); unset($asSelect[MySqlManager::getText(self::CODE_TABLE)]); $asSelect = array_keys($asSelect); } else { $asSelect = "*"; } $asCode = $this->oMySql->selectRow(self::CODE_TABLE, $iCodeId, $asSelect); $asCode['title'] = self::getDescriptionFormat($asCode['description']); $asCode['description'] = self::getDescriptionFormat($asCode['description']); $asCode['timestamp'] = strtotime($asCode['led']); $asCode['led'] = self::getDateFormat($asCode['led']); return $asCode; } private function getProcedureInfo($iProcId) { $asProc = $this->oMySql->selectRow(self::PROC_TABLE, $iProcId); $asProc['title'] = self::getDescriptionFormat($asProc['title']); $asProc['description'] = self::getDescriptionFormat($asProc['description']); $asProc['timestamp'] = strtotime($asProc['led']); $asProc['led'] = self::getDateFormat($asProc['led']); return $asProc; } private function getDocInfo($iDocId) { $asDoc = $this->oMySql->selectRow(self::DOC_TABLE, $iDocId); $asDoc['title'] = self::getDescriptionFormat($asDoc['title']); $asDoc['description'] = self::getDescriptionFormat($asDoc['description']); $asDoc['timestamp'] = strtotime($asDoc['led']); $asDoc['led'] = self::getDateFormat($asDoc['led']); return $asDoc; } private function getTableInfo($iTableId, $bFormatting=true) { $asTable = $this->oMySql->selectRow(self::TABL_TABLE, $iTableId); if(!empty($asTable)) { $asTable['timestamp'] = strtotime($asTable['led']); if($bFormatting) { $asTable['system'] = self::getTableFormat($asTable['system']); $asTable['description'] = self::getDescriptionFormat($asTable['description']); $asTable['table_name'] = self::getTableFormat($asTable['title']); $asTable['title'] = self::getTableFormat($asTable['title']).' - '.$asTable['description']; $asTable['led'] = self::getDateFormat($asTable['led']); $asTable['formated_keywords'] = ToolBox::formatText($asTable['keywords']); } } return $asTable; } private function getArticleInfo($iArtId) { $asArt = $this->oMySql->selectRow(self::ART_TABLE, $iArtId); $asTransferredInfo = array('link_art'=>$asArt['link'], 'art_title'=>$asArt['title'], 'link_auth'=>$asArt['email']); $asTransferredInfo['art_date'] = self::getDateFormat($asArt['date'], self::DATE_FORMAT); $asTransferredInfo['name'] = self::getNameFormat($asArt['first_name'], $asArt['last_name']); $asTransferredInfo['title'] = self::getDescriptionFormat($asArt['title']); $asTransferredInfo['description'] = self::getDescriptionFormat($asArt['title']); $asTransferredInfo['timestamp'] = strtotime($asArt['led']); $asTransferredInfo['led'] = self::getDateFormat($asArt['led']); //Domain $asParsedUrl = parse_url($asArt['link']); $asTransferredInfo['domain'] = $asParsedUrl['host']; $asTransferredInfo['company'] = $asTransferredInfo['domain']; return $asTransferredInfo; } public function getUserInfo($iUserId=-1, $bJson=false) { $asUserInfo = array(); if($iUserId==-1) $iUserId = $this->getUserId(); if(array_key_exists($iUserId, $this->asUsersInfo)) $asUserInfo = $this->asUsersInfo[$iUserId]; else { $this->setUserInfo($iUserId); $asUserInfo = $this->getUserInfo($iUserId); } return $bJson?$this->jsonExport($asUserInfo):$asUserInfo; } private function setUserInfo($iUserId=-1) { if($iUserId==-1) $iUserId = $this->getUserId(); if($iUserId>0) { $asRow = $this->oMySql->selectRow(self::USER_TABLE, $iUserId); if(empty($asRow))$this->addError('Unknown user id: '.$iUserId); else { $sEmail = $this->getUserOptionValue(self::OPT_EMAIL, $iUserId); $asCompany = $this->oMySql->selectRow(self::COMP_TABLE, $asRow[MySqlManager::getId(self::COMP_TABLE)]); $this->asUsersInfo[$iUserId] = array( 'name'=>self::getNameFormat($asRow['first_name'], $asRow['last_name']), 'nickname'=>self::getNickNameFormat($this->getChatNickNames($iUserId)), 'email'=>$sEmail, 'company'=>self::getCompanyFormat($asCompany[MySqlManager::getText(self::COMP_TABLE)]), 'status'=>$this->getDescriptionFormat($this->getUserOptionValue(self::OPT_STATUS, $iUserId)), 'logo'=>$asCompany['logo'], 'clearance'=>$asRow['clearance'], 'user_led'=>self::getDateFormat($asRow['led'], self::DATE_FORMAT)); } } } private function getUserClearance() { $asUserInfo = $this->getUserInfo(); return $asUserInfo['clearance']; } public function checkUserClearance($iClearance) { return ($this->getUserClearance() >= $iClearance); } /* Options Management */ //TODO Create class private function getAvailableOptions() { $sOptNameIdCol = MySqlManager::getId(self::OPTNAME_TABLE); $sOptNameTextCol = MySqlManager::getText(self::OPTNAME_TABLE); $asInfo = array('select'=>array($sOptNameIdCol, $sOptNameTextCol, 'type'), 'from'=>self::OPTNAME_TABLE, 'constraint'=>array('language'=>$this->sLanguage)); return $this->oMySql->selectRows($asInfo, true, $sOptNameIdCol); } private function getDefaultOptionValue($sOptionNameId) { $asDefaultOptions = $this->getDefaultOptionValues($sOptionNameId); $asOptionInfo = array_shift($asDefaultOptions); return $asOptionInfo[MySqlManager::getText(self::OPTVAL_TABLE)]; } private function getDefaultOptionValues($oOptionNameIds=array(), $bOptValId=true) { $sOptNameIdCol = MySqlManager::getId(self::OPTNAME_TABLE); $sOptValIdCol = MySqlManager::getId(self::OPTVAL_TABLE); $sOptValueTextCol = MySqlManager::getText(self::OPTVAL_TABLE); if(!is_array($oOptionNameIds)) $oOptionNameIds = array($oOptionNameIds); elseif(empty($oOptionNameIds)) $oOptionNameIds = array_keys($this->getAvailableOptions()); $asInfo = array('select' => array($sOptNameIdCol, $sOptValueTextCol), 'from' => self::OPTVAL_TABLE, 'constraint'=> array('default_value'=>true, $sOptNameIdCol => "(".implode(", ", $oOptionNameIds).")"), 'constOpe' => array('default_value'=>"=", $sOptNameIdCol=>" IN "), 'constVar' => true); if($bOptValId) $asInfo['select'][] = $sOptValIdCol; return $this->oMySql->selectRows($asInfo, true, $sOptNameIdCol); } private function getUserOptionValue($sOptionNameId, $iUserId=0) { $asUserOptions = $this->getUserOptions($sOptionNameId, $iUserId); $asOptionInfo = array_shift($asUserOptions); return $asOptionInfo[MySqlManager::getText(self::OPTVAL_TABLE)]; } private function getUserOptions($oOptionNameIds=array(), $iUserId=0) { $iUserId = $iUserId>0?$iUserId:$this->getUserId(); $sUserIdCol = MySqlManager::getId(self::USER_TABLE); $sOptNameIdCol = MySqlManager::getId(self::OPTNAME_TABLE); $sOptNameIdColOptTable = MySqlManager::getFullColumnName(self::OPT_TABLE, $sOptNameIdCol); $sOptValueIdCol = MySqlManager::getId(self::OPTVAL_TABLE); $sOptValueIdColOptTable = MySqlManager::getFullColumnName(self::OPT_TABLE, $sOptValueIdCol); $sOptValueTextCol = MySqlManager::getText(self::OPTVAL_TABLE); $sOptIdCol = MySqlManager::getId(self::OPT_TABLE); if(!is_array($oOptionNameIds)) $oOptionNameIds = array($oOptionNameIds); elseif(empty($oOptionNameIds)) $oOptionNameIds = array_keys($this->getAvailableOptions()); $asUserinfo = array('select' => array($sOptIdCol, $sOptNameIdColOptTable, $sOptValueIdColOptTable, $sOptValueTextCol), 'from' => self::OPT_TABLE, 'join' => array(self::OPTVAL_TABLE=>MySqlManager::getId(self::OPTVAL_TABLE)), 'constraint'=> array($sUserIdCol=>$iUserId, $sOptNameIdColOptTable => "(".implode(", ", $oOptionNameIds).")"), 'constOpe' => array($sUserIdCol=>"=", $sOptNameIdColOptTable => " IN "), 'constVar' => true); $asOptions = $this->oMySql->selectRows($asUserinfo, true, $sOptNameIdCol); //No user value: adding default value to user values $asDefaultOptions = $this->getDefaultOptionValues(); foreach($oOptionNameIds as $iOptionNameId) { if(!array_key_exists($iOptionNameId, $asOptions)) $asOptions[$iOptionNameId] = $asDefaultOptions[$iOptionNameId]; } return $asOptions; } public function getOptions() { $sOptNameTextCol = MySqlManager::getText(self::OPTNAME_TABLE); $sOptValueIdCol = MySqlManager::getId(self::OPTVAL_TABLE); $sOptValueTextCol = MySqlManager::getText(self::OPTVAL_TABLE); //Available Options $asAvailableOptions = $this->getAvailableOptions(); //User options $asUserOptions = $this->getUserOptions(); //Build Options panel $asSelectedOptions = array(); foreach($asAvailableOptions as $sOptNameId=>$asOption) { $sOptionName = self::getDescriptionFormat($asOption[$sOptNameTextCol]); $asSelectedOptions[$sOptionName]['option_id'] = $sOptNameId; $asSelectedOptions[$sOptionName]['option_name'] = $sOptionName; $asSelectedOptions[$sOptionName]['user_value_id'] = $asUserOptions[$sOptNameId][$sOptValueIdCol]; $asSelectedOptions[$sOptionName]['user_value'] = $asUserOptions[$sOptNameId][$sOptValueTextCol]; $asSelectedOptions[$sOptionName]['type'] = $asOption['type']; if($asOption['type']==self::OPT_SELECT || $asOption['type']==self::OPT_CHECKBOX) { $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')); $asOptionValues = $this->oMySql->selectRows($asOptionValuesInfo, true, $sOptValueIdCol); $asSelectedOptions[$sOptionName]['select'] = $asOptionValues; $asSelectedOptions[$sOptionName]['select_inv'] = array_flip($asOptionValues); } } ksort($asSelectedOptions); //Admin options $asAdminOptions = array(); if($this->checkUserClearance(self::CLEARANCE_ADMIN)) { //Companies $asAdminOptions['companies'] = array_map(array('self', 'getCompanyFormat'), $this->oMySql->selectList(self::COMP_TABLE)); //User Names $asFirstNames = $this->oMySql->selectList(self::USER_TABLE, 'first_name'); $asLastNames = $this->oMySql->selectList(self::USER_TABLE, 'last_name'); foreach($asLastNames as $iUserId=>$sLastName) $asAdminOptions['users'][$iUserId] = self::getNameFormat($asFirstNames[$iUserId], $sLastName); } return $this->jsonExport(array('admin'=>$asAdminOptions, 'options'=>$asSelectedOptions)); } public function setOptions($asNewOptions, $bSilentUpdate=true, $iUserId=0) { $sOptIdCol = MySqlManager::getId(self::OPT_TABLE); $sOptValueIdCol = MySqlManager::getId(self::OPTVAL_TABLE); $sOptValueTextCol = MySqlManager::getText(self::OPTVAL_TABLE); $sUserIdCol = MySqlManager::getId(self::USER_TABLE); $sOptNameIdCol = MySqlManager::getId(self::OPTNAME_TABLE); $iUserId = ($iUserId>0)?$iUserId:$this->getUserId(); $asAvailableOptions = $this->getAvailableOptions(); $asUserOptions = $this->getUserOptions(array_keys($asAvailableOptions), $iUserId); $asDefaultOptions = $this->getDefaultOptionValues(array_keys($asAvailableOptions)); foreach($asAvailableOptions as $sOptNameId=>$asOption) { if(array_key_exists($sOptNameId, $asNewOptions)) { $sUserValue = $asUserOptions[$sOptNameId][$sOptValueTextCol]; $sUserValueId = $asUserOptions[$sOptNameId][$sOptValueIdCol]; $sUserOptId = array_key_exists($sOptIdCol, $asUserOptions[$sOptNameId])?$asUserOptions[$sOptNameId][$sOptIdCol]:0; $sDefaultValue = $asDefaultOptions[$sOptNameId][$sOptValueTextCol]; $sDefaultValueId = $asDefaultOptions[$sOptNameId][$sOptValueIdCol]; if(!$sDefaultValueId) $this->addError('Missing option default value for option id='.$sOptNameId); switch($asOption['type']) { case self::OPT_SELECT: case self::OPT_CHECKBOX: $sNewValueId = $asNewOptions[$sOptNameId]; $sNewValue = $this->oMySql->selectValue(self::OPTVAL_TABLE, $sOptValueTextCol, $sNewValueId); break; case self::OPT_TEXT: case self::OPT_COLOR: $sNewValue = $asNewOptions[$sOptNameId]; break; } //Update text if($sNewValue!=$sUserValue) { //Clear user values if exist (back to default) if(($sNewValue=='' || $sNewValue==$sDefaultValue) && $sUserOptId>0) { $this->oMySql->deleteRow(self::OPT_TABLE, $sUserOptId); if($asOption['type']==self::OPT_TEXT || $asOption['type']==self::OPT_COLOR) $this->oMySql->deleteRow(self::OPTVAL_TABLE, $sUserValueId); } //New or updated value elseif($sNewValue!=$sDefaultValue) { //Update option values table if($asOption['type']==self::OPT_TEXT || $asOption['type']==self::OPT_COLOR) { $asData = array($sOptNameIdCol=>$sOptNameId, $sOptValueTextCol=>$sNewValue, 'language'=>$this->sLanguage); if($sUserValueId==$sDefaultValueId) $sNewValueId = $this->oMySql->insertRow(self::OPTVAL_TABLE, $asData); else $sNewValueId = $this->oMySql->updateRow(self::OPTVAL_TABLE, $sUserValueId, array($sOptValueTextCol=>$sNewValue)); } //Update option table $asKeys = array($sUserIdCol=>$iUserId, $sOptNameIdCol=>$sOptNameId); $asData = array($sOptValueIdCol=>$sNewValueId) + $asKeys; $this->oMySql->insertUpdateRow(self::OPT_TABLE, $asData, array_keys($asKeys)); } //Spread the word if(!$bSilentUpdate) { //TODO rassembler les messages similaires dans une fonction de template switch($sOptNameId) { case self::OPT_NICKNAME: $sType = self::MESSAGE_NICK; $sChanName = self::DEFAULT_CHAN; $sMessage = $sUserValue.' a changé son pseudo en '.$sNewValue; break; case self::OPT_STATUS: $sType = self::MESSAGE_STATUS; $sChanName = self::DEFAULT_CHAN; $sMessage = 'est sur une nouvelle mission : '.$this->getDescriptionFormat($sNewValue); break; default: continue 2; } $sChanId = $this->getChanId($sChanName); $this->addMessage($sMessage, $sType, $sChanId); } } } } } public function getProfile($oUser) { switch($oUser) { case '': $iUserId = $this->getUserId(); break; case is_numeric($oUser): $iUserId = $oUser; break; default: $iUserId = $this->getUserId(); break; } //User Info $asProfile['user'] = $this->getUserInfo($iUserId); unset($asProfile['user']['email']); unset($asProfile['user']['clearance']); //History Info $asTables = $this->getTypeInfo('table'); foreach($asTables as $sType=>$sTableName) { //skip articles for users $bArticle = ($sType==self::ART_TYPE); if($bArticle && $iUserId!= self::SYSTEM_USER_ID) continue; //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); if(!$bArticle) $asSqlInfo['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'] = (($bArticle || $asInfo['refer_id']==$iItemId)?'Création':'Modification').' de '.$sText; $asProfile['history'][$sKey]['date'] = $asInfo['led']; $asProfile['history'][$sKey]['title'] = $asInfo['title']; } } if(array_key_exists('history', $asProfile)) krsort($asProfile['history']); return $this->jsonExport($asProfile); } private static function isPmChan($sChanSafeName) { $asResult = array('is_pm'=>false, 'chan_name'=>$sChanSafeName); preg_match('/(?P\d+)'.self::PM_SEP.'(?P\d+)/u', $sChanSafeName, $asMatch); if(!empty($asMatch)) { $asResult['is_pm'] = true; $asResult['from'] = $asMatch['from']; $asResult['to'] = $asMatch['to']; if($asMatch['from'] > $asMatch['to']) $asResult['chan_name'] = $asMatch['to'].self::PM_SEP.$asMatch['from']; else $asResult['chan_name'] = $asMatch['from'].self::PM_SEP.$asMatch['to']; } return $asResult; } private function checkChanAuth($sChanSafeName, $iUserId=0) { $asUserInfo = ($iUserId > 0)?$this->getUserInfo($iUserId):array('company'=>''); $asCompanies = $this->oMySql->selectRows(array('select'=>MySqlManager::getText(self::COMP_TABLE), 'from'=>self::COMP_TABLE)); $iCompChan = array_search($sChanSafeName, array_map(array('self', 'getChanSafeName'), $asCompanies)); $asPm = $this->isPmChan($sChanSafeName); return $sChanSafeName!='' && //Empty channel name ($iCompChan===false || $asUserInfo['company']==self::getCompanyFormat($asCompanies[$iCompChan])) && //Test Company Channel (!$asPm['is_pm'] || $iUserId==$asPm['from'] || $iUserId==$asPm['to']); //Test PM } public function joinChan($sChanName, $bFirstConn=false, $asAttendees=array()) { $bSuccess = false; $sDesc = ''; $asVars = array(); $sSafeChanName = self::getChanSafeName($sChanName); //Authorization to join channel $asMessages = array(); if($this->checkChanAuth($sSafeChanName, $this->getUserId())) { //On first connection, display on-join message for all channels if($bFirstConn) { $asConnChans = $this->getChannels($this->getUserId()); $bFirstChan = true; foreach($asConnChans as $iConnChanId=>$sConnChanName) { //Checking once for all channels if(!$bFirstChan || !$this->isUserConnected($iConnChanId)) { $asMessages[$iConnChanId] = $sConnChanName; } else break; $bFirstChan = false; } } //Add connection link in DB $sUserIdCol = MySqlManager::getId(self::USER_TABLE); $sChanIdCol = MySqlManager::getId(self::CHAN_TABLE); $asData = array('safe_name'=>$sSafeChanName, MySqlManager::getText(self::CHAN_TABLE)=>$sChanName); $iChanId = $this->oMySql->insertUpdateRow(self::CHAN_TABLE, $asData, array('safe_name'), false); //Is user already connected to this chan $bConnectedUser = $this->isUserConnected($iChanId); $iConnId = $this->oMySql->insertUpdateRow(self::CONN_TABLE, array($sUserIdCol=>$this->getUserId(), $sChanIdCol=>$iChanId), array($sUserIdCol, $sChanIdCol), false); if($iConnId>0) $bSuccess = true; if($bSuccess) { //Return connected channels $asVars['channels'] = $this->getChannels($this->getUserId()); //Add tab title (customized) //FIXME delete this shit and insert the channel type into channels DB table foreach($asVars['channels'] as $iConnectedChanId=>$sConnectedChanName) { $asPm = $this->isPmChan($sConnectedChanName); $asVars['channel_tab_names'][$iConnectedChanId] = $asPm['is_pm']?$this->getChatNickNames($asPm['from']==$this->getUserId()?$asPm['to']:$asPm['from']):$sConnectedChanName; } $asVars['current_chan_id'] = $iChanId; //Communicate on user's connection if(!$bConnectedUser) { $asMessages[$iChanId] = $this->oMySql->selectValue(self::CHAN_TABLE, MySqlManager::getText(self::CHAN_TABLE), $iChanId); } $sStatus = $this->getUserOptionValue(self::OPT_STATUS); $asUserInfo = $this->getUserInfo(); foreach($asMessages as $iChanId=>$sMsgChanName) { $asPm = $this->isPmChan($sMsgChanName); $this->addMessage(' de '.$asUserInfo['company'].' ('.$this->getDescriptionFormat($sStatus).') rejoint '.($asPm['is_pm']?'le chan privé':'#'.$sMsgChanName), self::MESSAGE_CONN, $iChanId); } //Send invites to attendees if(!empty($asAttendees)) { foreach($asAttendees as $sAttendee) { if($this->checkChanAuth($sSafeChanName, $sAttendee)) { $this->addMessage($sAttendee, self::MESSAGE_INVITE, $iChanId); } } } //Update chan leds $this->pingChans(); } else $sDesc = self::FAIL_UPDATE; } else $sDesc = 'Nom de chan non autorisé (nom de personne / nom de société interdit)'; return self::getJsonPostResult($bSuccess, $sDesc, $asVars); } private function isUserConnected($iChanId=0, $iUserId=0) { $iUserId = $iUserId>0?$iUserId:$this->getUserId(); $sUserIdCol = MySqlManager::getId(self::USER_TABLE); $asInfo = array('select' => MySqlManager::getId(self::CONN_TABLE), 'from' => self::CONN_TABLE, 'constraint'=> array($sUserIdCol=>$iUserId, 'led'=>"DATE_SUB(NOW(), INTERVAL ".self::KEEP_ALIVE." SECOND)"), 'constOpe' => array($sUserIdCol=>'=', 'led'=>'>'), 'constVar' => true, 'groupBy' => $sUserIdCol); //Add chan constraint if($iChanId>0) { $asInfo['constraint'][MySqlManager::getId(self::CHAN_TABLE)] = $iChanId; $asInfo['constOpe'][MySqlManager::getId(self::CHAN_TABLE)] = '='; } return (count($this->oMySql->selectRows($asInfo))>0); } public function pingChans() { $aiConstraints = array(MySqlManager::getId(self::USER_TABLE)=>$this->getUserId()); $asUpdates = array('led'=>date(self::DATE_TIME_SQL_FORMAT)); $this->oMySql->updateRows(self::CONN_TABLE, $aiConstraints, $asUpdates); } public function quitChan($sChanName) { $iChanId = $this->getChanId($sChanName); $iConnId = $this->getConnId($iChanId); if($iConnId>0) { $this->oMySql->deleteRow(self::CONN_TABLE, $iConnId); $asPm = $this->isPmChan($sChanName); $this->addMessage('quitte '.($asPm['is_pm']?'le chan privé':'#'.$sChanName), self::MESSAGE_CONN, $iChanId); } } public function inviteChan($iUserId, $sChanName) { $sSafeChanName = $this->getChanSafeName($sChanName); $bSuccess = false; if($iUserId>0 && $this->checkChanAuth($sSafeChanName, $iUserId)) { $sType = self::MESSAGE_INVITE; $sMessage = $iUserId; $sChanId = $this->getChanId($sChanName); $bSuccess = $this->addMessage($sMessage, $sType, $sChanId); if($bSuccess) $sDesc = 'Invitation envoyée'; } else $sDesc = 'Désolé, cette personne n\'est pas autorisé sur ce channel'; return $this->getJsonPostResult($bSuccess, $sDesc); } private function getActiveChannels() { //Get connected users $asActiveChanUsers = $this->getConnectedUsers(false, false); $asActiveChans = array_keys($asActiveChanUsers); //Get Channel names $sChanIdCol = MySqlManager::getId(self::CHAN_TABLE); $asChanNames = $this->oMySql->selectRows(array('select'=>array($sChanIdCol, MySqlManager::getText(self::CHAN_TABLE)), 'from'=>self::CHAN_TABLE), true, $sChanIdCol); foreach($asActiveChans as $iChanId) { $asChannels[$asChanNames[$iChanId]] = count($asActiveChanUsers[$iChanId]); } //remove restricted channels $asPublicChannels = array(); foreach($asChannels as $sChanName=>$iChanCount) { if($this->checkChanAuth($this->getChanSafeName($sChanName))) $asPublicChannels[$sChanName] = $iChanCount; } return $asPublicChannels; } private function getChannels($iUserId=0) { $sChanIdCol = MySqlManager::getId(self::CHAN_TABLE, true); $sChanNameCol = MySqlManager::getText(self::CHAN_TABLE); $asInfo = array('select'=>array($sChanIdCol, $sChanNameCol), 'from'=> self::CONN_TABLE, 'join'=> array(self::CHAN_TABLE=>MySqlManager::getId(self::CHAN_TABLE)), 'orderBy'=> array(MySqlManager::getId(self::CONN_TABLE)=>'ASC')); if($iUserId > 0) $asInfo['constraint'] = array(MySqlManager::getId(self::USER_TABLE)=>$iUserId); $asChannels = $this->oMySql->selectRows($asInfo, true, MySqlManager::getId(self::CHAN_TABLE)); //remove restricted channels $asPublicChannels = array(); foreach($asChannels as $iChanId=>$sChanName) { if($this->checkChanAuth($this->getChanSafeName($sChanName), $iUserId)) $asPublicChannels[$iChanId] = $sChanName; } return $asPublicChannels; } private function getChanId($sChanName) { $sChanIdCol = MySqlManager::getId(self::CHAN_TABLE); $sSafeChanName = self::getChanSafeName($sChanName); $iChanId = $this->oMySql->selectValue(self::CHAN_TABLE, $sChanIdCol, array('safe_name'=>$sSafeChanName)); if($iChanId==0) { $this->addError('No channel id found with channel name (safe): '.$sSafeChanName.', unsafe: '.$sChanName); } return $iChanId; } private function getConnId($iChanId, $iUserId=0) { $sUserIdCol = MySqlManager::getId(self::USER_TABLE); $sConnIdCol = MySqlManager::getId(self::CONN_TABLE); $sChanIdCol = MySqlManager::getId(self::CHAN_TABLE); if($iUserId==0) $iUserId = $this->getUserId(); $iConnId = $this->oMySql->selectValue(self::CONN_TABLE, $sConnIdCol, array($sUserIdCol=>$iUserId, $sChanIdCol=>$iChanId)); if($iConnId==0) { $this->addError('No connection found for user: '.$iUserId.' and channel id: '.$iChanId); } return $iConnId; } public function addChatMessage($sMessage, $sChanName) { $sMessage = htmlspecialchars($sMessage); $sType = self::MESSAGE_USER; $bSuccess = true; $sDesc = ''; 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\w+) (?P.*)/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 = ''; $sEndText = ''; $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)); $asImage = $this->downloadToTmp($sUrl); $bSuccess = ($asImage['error']==''); if($bSuccess) { $sMessage = $this->getJsonMessage(array($asImage['out'], $asImage['width'], $asImage['height'], $sUrl)); $sType = self::MESSAGE_IMG; } else $sDesc = $asImage['error']; } elseif(mb_substr($sMessage, 0, 8) == '/imgsrc ' && mb_strlen($sMessage)>8) { //Store locally $sSourceString = mb_substr($sMessage, 8); $oImage = imagecreatefromstring(base64_decode($sSourceString)); $sRawPath = self::DOC_TMP_FOLDER.uniqid().'.jpeg'; imagejpeg($oImage, $sRawPath, 100); //Create thumbnail & display on chat $asImage = $this->downloadToTmp($sRawPath); $bSuccess = ($asImage['error']==''); if($bSuccess) { $sMessage = $this->getJsonMessage(array($asImage['out'], $asImage['width'], $asImage['height'], $sRawPath)); $sType = self::MESSAGE_IMG; } else $sDesc = $asImage['error']; } elseif(mb_substr($sMessage, 0, 6) == '/9gag ' && mb_strlen($sMessage)>6) { $asImage = $this->get9gagPost(trim(mb_substr($sMessage, 6))); $bSuccess = ($asImage['error']==''); if($bSuccess) { $sMessage = $this->getJsonMessage($asImage); $sType = self::MESSAGE_9GAG; } else $sDesc = $asImage['error']; } 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, 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; } //Storing message if($bSuccess) { $sChanId = $this->getChanId($sChanName); $bSuccess = $this->addMessage($sMessage, $sType, $sChanId); if(!$bSuccess) $sDesc = self::FAIL_INSERT; } return $this->getJsonPostResult($bSuccess, $sDesc); } private function getJsonMessage($asData) { return self::JSON_PREFIX.$this->jsonConvert($asData); } private function downloadToTmp($sUrl) { $sFilePath = self::DOC_TMP_FOLDER.uniqid(); return ToolBox::createThumbnail($sUrl, self::CHAT_IMG_MAX_WIDTH, self::CHAT_IMG_MAX_HEIGHT, $sFilePath, false, self::$UPLOAD_IMG_EXTS); } private function sendPM($iUserIdTo, $sMessage) { $bSuccess = false; $asUserFrom = $this->getUserInfo(); $asUserTo = $this->getUserInfo($iUserIdTo); $sFrom = $asUserFrom['name'].' '; $sTo = $asUserTo['name'].' <'.$asUserTo['email'].'>'; $sMessage .= "\n\n\n".'Ne répondez pas à ce mail. Connectez-vous sur Databap.'; $sResult = ToolBox::sendMail($sFrom, 'Databap PM', $sMessage, $sTo, array(), false); $bSuccess = ($sResult==ToolBox::MAIL_SUCCESS); if(!$bSuccess) $this->addError($sResult); return $bSuccess; } private function addMessage($sMessage, $sType, $iChanId, $iUserId=0) { $bResult = false; $iUserId = ($iUserId>0)?$iUserId:$this->getUserId(); if($iChanId>0) { $asInsert = array( MySqlManager::getId(self::USER_TABLE) => $iUserId, 'nickname' => $this->getChatNickNames($iUserId), MySqlManager::getId(self::CHAN_TABLE) => $iChanId, MySqlManager::getText(self::MSG_TABLE) => $sMessage, 'type' => $sType, 'date' => 'CURDATE()'); $bResult = $this->oMySql->insertRow(self::MSG_TABLE, $asInsert); } else { $this->addError('Message deleted: No channel found'); } return $bResult; } public function getMessages($iFirstMsgId="0") { //Update chan ping $this->pingChans(); //Get messages and users' infos $sChanIdCol = MySqlManager::getId(self::CHAN_TABLE, true); $sChanTextCol = MySqlManager::getText(self::CHAN_TABLE); $sMsgIdCol = MySqlManager::getId(self::MSG_TABLE, true); $sMsgTextCol = MySqlManager::getText(self::MSG_TABLE); $sMsgTableLed = MySqlManager::getFullColumnName(self::MSG_TABLE, 'led'); $sMsgTableChanIdCol = MySqlManager::getFullColumnName(self::MSG_TABLE, MySqlManager::getId(self::CHAN_TABLE)); $sUserIdCol = MySqlManager::getId(self::USER_TABLE, true); $sMsgTableUserIdCol = MySqlManager::getFullColumnName(self::MSG_TABLE, MySqlManager::getId(self::USER_TABLE)); $sUserTableUserIdCol = MySqlManager::getId(self::USER_TABLE, true); $sConnTableUserIdCol = MySqlManager::getFullColumnName(self::CONN_TABLE, MySqlManager::getId(self::USER_TABLE)); $sConnTableChanIdCol = MySqlManager::getFullColumnName(self::CONN_TABLE, MySqlManager::getId(self::CHAN_TABLE)); //User channels related messages $iCurTimeStamp = time(); $sCurDate = date(Databap::DATE_SQL_FORMAT, $iCurTimeStamp); $sLimitDate = date(Databap::DATE_SQL_FORMAT, $iCurTimeStamp - $this->getUserOptionValue(self::OPT_CHAT_HISTO)*24*60*60); $asInfo = array('select' => array($sMsgTableChanIdCol, $sMsgIdCol, $sMsgTextCol, 'type', $sMsgTableLed, 'first_name', 'last_name', $sUserIdCol, 'nickname'), 'from' => self::CONN_TABLE, 'joinOn' => array( self::MSG_TABLE =>array($sMsgTableChanIdCol, '=', $sConnTableChanIdCol), self::USER_TABLE=>array($sUserTableUserIdCol, '=', $sMsgTableUserIdCol)), 'constraint'=> array($sConnTableUserIdCol=>$this->getUserId(), $sMsgIdCol=>$iFirstMsgId, 'date'=>$sLimitDate), 'constOpe' => array($sConnTableUserIdCol=>'=', $sMsgIdCol=>'>', 'date'=>'>=')); $asSqlMessages = $this->oMySql->selectRows($asInfo, true, 'id_message'); //Global messages $asInfo['from'] = self::MSG_TABLE; $asInfo['joinOn'] = array(self::USER_TABLE=>array($sUserTableUserIdCol, '=', $sMsgTableUserIdCol)); $asInfo['constraint'] = array($sMsgTableChanIdCol=>self::ALL_CHAN_ID, $sMsgIdCol=>$iFirstMsgId, 'date'=>$sLimitDate); $asInfo['constOpe'] = array($sMsgTableChanIdCol=>'=', $sMsgIdCol=>'>', 'date'=>'>='); $asSqlGlobalMessages = $this->oMySql->selectRows($asInfo, true, 'id_message'); //Invites messages $asInfo['constraint'] = array($sMsgIdCol=>$iFirstMsgId, 'date'=>$sCurDate, 'type'=>self::MESSAGE_INVITE, 'message'=>$this->getUserId()); $asInfo['constOpe'] = array($sMsgIdCol=>'>', 'date'=>'=', 'type'=>'=', 'message'=>'='); $asSqlInviteMessages = $this->oMySql->selectRows($asInfo, true, 'id_message'); //Merge flows if(!empty($asSqlGlobalMessages)) $asSqlMessages = array_diff_key($asSqlMessages, $asSqlGlobalMessages) + $asSqlGlobalMessages; if(!empty($asSqlInviteMessages)) $asSqlMessages = array_diff_key($asSqlMessages, $asSqlInviteMessages) + $asSqlInviteMessages; //Sort messages ksort($asSqlMessages); //Sort out messages for Json Export $iPrefixLen = mb_strlen(self::JSON_PREFIX); $asMessages = array('messages'=>array(), 'last_message_id'=>0); foreach($asSqlMessages as $iMessageId=>$asMessageInfo) { //General message info $iChanId = $asMessageInfo[MySqlManager::getId(self::CHAN_TABLE)]; $iUserId = $asMessageInfo[MySqlManager::getId(self::USER_TABLE)]; $sMessageType = $asMessageInfo['type']; $asMessages['messages'][$iMessageId]['id_chan'] = $iChanId; $asMessages['messages'][$iMessageId]['id_user'] = $iUserId; $asMessages['messages'][$iMessageId]['message'] = $asMessageInfo[$sMsgTextCol]; $asMessages['messages'][$iMessageId]['msg_class'] = $sMessageType; $asMessages['messages'][$iMessageId]['date'] = self::getDateFormat($asMessageInfo['led'], self::DATE_FORMAT); $asMessages['messages'][$iMessageId]['time'] = self::getDateFormat($asMessageInfo['led'], self::TIME_FORMAT); $asMessages['messages'][$iMessageId]['name'] = self::getNameFormat($asMessageInfo['first_name'], $asMessageInfo['last_name']); $asMessages['messages'][$iMessageId]['nickname'] = self::getNickNameFormat($asMessageInfo['nickname']); //generated messages switch($sMessageType) { case self::MESSAGE_ADD_CODE: case self::MESSAGE_EDIT_CODE: $asCode = $this->getCodeInfo($asMessages['messages'][$iMessageId]['message']); $asMessages['messages'][$iMessageId]['description'] = $asCode['description']; break; case self::MESSAGE_ADD_PROC: case self::MESSAGE_EDIT_PROC: $asProc = $this->getProcedureInfo($asMessages['messages'][$iMessageId]['message']); $asMessages['messages'][$iMessageId]['description'] = $asProc['title']; break; case self::MESSAGE_ADD_DOC: case self::MESSAGE_EDIT_DOC: $asDoc = $this->getDocInfo($asMessages['messages'][$iMessageId]['message']); $asMessages['messages'][$iMessageId]['description'] = $asDoc['title']; break; case self::MESSAGE_ADD_TABLE: case self::MESSAGE_EDIT_TABLE: $asTable = $this->getTableInfo($asMessages['messages'][$iMessageId]['message']); $asMessages['messages'][$iMessageId]['description'] = $asTable['title']; break; case self::MESSAGE_ARTICLE: $asTransferredInfo = $this->getArticleInfo($asMessages['messages'][$iMessageId]['message']); $asMessages['messages'][$iMessageId] = array_merge($asMessages['messages'][$iMessageId], $asTransferredInfo); break; case self::MESSAGE_INVITE: //Switch Chan ID with name for the user to join $asMessages['messages'][$iMessageId]['id_chan'] = $this->oMySql->selectValue(self::CHAN_TABLE, 'safe_name', $iChanId); break; } //Json message if(mb_substr($asMessages['messages'][$iMessageId]['message'], 0, $iPrefixLen) == self::JSON_PREFIX) { $asMessages['messages'][$iMessageId]['message'] = json_decode(mb_substr($asMessages['messages'][$iMessageId]['message'], $iPrefixLen)); } else //Normal message { //Internal links $asMessages['messages'][$iMessageId]['message'] = Toolbox::findReplaceLinks($asMessages['messages'][$iMessageId]['message']); //Dynamic chan link $asPatterns = '/(^|\s)#(\w*[^\s]+\w*)/u'; $asLinks = '\1#\2'; $asMessages['messages'][$iMessageId]['message'] = preg_replace($asPatterns, $asLinks, $asMessages['messages'][$iMessageId]['message']); } } //Set last message Id (if new messages since $iFirstMsgId) if(!empty($asMessages['messages'])) { $asMessages['last_message_id'] = max(array_keys($asMessages['messages'])); } return $this->jsonExport($asMessages); } public function getNews($bExport=true) { $sMsgIdCol = MySqlManager::getId(self::MSG_TABLE); $sMsgTxtCol = MySqlManager::getText(self::MSG_TABLE); //News $asInfo['select'] = array($sMsgIdCol, 'nickname', $sMsgTxtCol, 'type', 'led'); $asInfo['from'] = self::MSG_TABLE; $asInfo['constraint'] = array('type'=>self::MESSAGE_NEWS); $asInfo['orderBy'] = array('led'=>'DESC'); if($bExport) $asInfo['limit'] = self::MAX_NB_NEWS; $asNews = $this->oMySql->selectRows($asInfo); //Status //$asInfo['select'] = array($sMsgIdCol, 'nickname', "CONCAT(nickname, SPACE(1), ".$sMsgTxtCol." AS ".$sMsgTxtCol, 'led'); $asInfo['constraint'] = array('type'=>self::MESSAGE_STATUS); $asStatus = $this->oMySql->selectRows($asInfo); //Sorting //FIXME find a way to do it in SQL $asNews = array_merge($asNews, $asStatus); foreach($asNews as $iKey=>$asNewsInfo) $asNewsSort[$iKey] = strtotime($asNewsInfo['led']); arsort($asNewsSort); foreach($asNewsSort as $iKey=>$iTimestamp) { if($asNews[$iKey]['type']==self::MESSAGE_STATUS) $asNews[$iKey][$sMsgTxtCol] = $asNews[$iKey]['nickname'].' '.$asNews[$iKey][$sMsgTxtCol]; $asNews2[] = $asNews[$iKey]; if($bExport && count($asNews2)==self::MAX_NB_NEWS) break; } $asFormatNews = array(); foreach($asNews2 as $asNew) { $iListId = '-'.$asNew[$sMsgIdCol]; $asFormatNews[$iListId][$sMsgIdCol] = $asNew[$sMsgIdCol]; $asFormatNews[$iListId]['time'] = $asNew['led']; $asFormatNews[$iListId]['time_desc'] = ToolBox::getDateTimeDesc($asNew['led']); $asFormatNews[$iListId]['message'] = self::getDescriptionFormat($asNew['message']); $asFormatNews[$iListId]['nickname'] = self::getNickNameFormat($asNew['nickname']); } $sSuccess = (count($asFormatNews)>0); return $bExport?$this->getJsonPostResult($sSuccess, $sSuccess?'':'Aucune news', array('news'=>$asFormatNews)):$asFormatNews; } private function getConnectedChans($iuserId=0) { $iuserId = $iuserId>0?$iuserId:$this->getUserId(); $sUserIdCol = MySqlManager::getId(self::USER_TABLE); $asInfo = array('select' => array(MySqlManager::getId(self::CHAN_TABLE, true), MySqlManager::getText(self::CHAN_TABLE)), 'from' => self::CONN_TABLE, 'join' => array(self::CHAN_TABLE=>MySqlManager::getId(self::CHAN_TABLE)), 'constraint'=> array($sUserIdCol=>$iUserId, 'led'=>"DATE_SUB(NOW(), INTERVAL ".self::KEEP_ALIVE." SECOND)"), 'constOpe' => array($sUserIdCol=>'=', 'led'=>'>'), 'constVar' => true); return $this->oMySql->selectRows($asInfo, true, MySqlManager::getId(self::CONN_TABLE)); } public function getConnectedUsers($bUserRestricted=false, $bJson=true) { $sQuery = " SELECT /* config.php 1313 */ conn2.id_channel, conn2.id_user, conn2.led, IF(DATE_SUB(NOW(), INTERVAL 1 MINUTE) < conn2.led, 0, 1) AS afk, users.first_name, users.last_name, companies.company, companies.logo FROM connections AS conn1 LEFT JOIN connections AS conn2 ON conn2.id_channel = conn1.id_channel LEFT JOIN users ON users.id_user = conn2.id_user LEFT JOIN companies ON companies.id_company = users.id_company WHERE conn2.led > DATE_SUB(NOW(), INTERVAL ".self::KEEP_ALIVE." SECOND)". ($bUserRestricted?"AND conn1.id_user = ".$this->getUserId():"")." GROUP BY conn2.id_channel, conn2.id_user"; $asUserChannels = $this->oMySql->getArrayQuery($sQuery, true); //Last messages $iUserIdCol = MySqlManager::getId(self::USER_TABLE); $asLastMsg = $this->oMySql->selectRows(array('select'=>array($iUserIdCol, 'MAX(led)'), 'from'=>self::MSG_TABLE), true, $iUserIdCol); $asConnectedUsers = $asUserOptions = array(); foreach($asUserChannels as $asUser) { $iChanId = $asUser[MySqlManager::getId(self::CHAN_TABLE)]; $iUserId = $asUser[$iUserIdCol]; if(!array_key_exists($iUserId, $asUserOptions)) $asUserOptions[$iUserId] = $this->getUserOptions(array(self::OPT_NICKNAME, self::OPT_STATUS), $iUserId); $sNickName = self::getNickNameFormat($asUserOptions[$iUserId][self::OPT_NICKNAME][MySqlManager::getText(self::OPTVAL_TABLE)]); $asConnectedUsers[$iChanId][] = array ( 'id_user' => $iUserId, 'name' => self::getNameFormat($asUser['first_name'], $asUser['last_name']), 'company' => self::getCompanyFormat($asUser['company']), 'status' => $asUserOptions[$iUserId][self::OPT_STATUS][MySqlManager::getText(self::OPTVAL_TABLE)], 'logo' => $asUser['logo'], 'nickname' => $sNickName, 'last_activity' => array_key_exists($iUserId, $asLastMsg)?self::getDateFormat($asLastMsg[$iUserId], self::TIME_FORMAT):'', 'ping' => self::getDateFormat($asUser['led'], self::TIME_FORMAT), 'afk' => $asUser['afk'] ); } return $bJson?$this->jsonExport($asConnectedUsers):$asConnectedUsers; } private function getUserIdFromNickName($sNickName) { $asContraints = array( 'LOWER(`'.MySqlManager::getText(self::OPT_TABLE).'`)' => mb_strtolower($sNickName), MySqlManager::getId(self::OPTNAME_TABLE) => self::OPT_NICKNAME); return $this->oMySql->selectValue(self::OPT_TABLE, MySqlManager::getId(self::USER_TABLE), $asContraints); } private function getChatNickNames($iUserId=0) { //TODO use $this->getUserOptionValue(); $sUserIdCol = MySqlManager::getId(self::USER_TABLE); $sNicknameCol = MySqlManager::getText(self::OPTVAL_TABLE); $sOptionNameId = MySqlManager::getFullColumnName(self::OPT_TABLE, MySqlManager::getId(self::OPTNAME_TABLE)); $asInfo = array('select'=>array($sUserIdCol, $sNicknameCol), 'from'=>self::OPT_TABLE, 'join'=> array(self::OPTVAL_TABLE=>MySqlManager::getId(self::OPTVAL_TABLE)), 'constraint'=>array($sOptionNameId=>self::OPT_NICKNAME)); if($iUserId>0) $asInfo['constraint'][MySqlManager::getId(self::USER_TABLE)] = $iUserId; $oResult = $this->oMySql->selectRows($asInfo, true, $sUserIdCol); if(count($oResult)==1) return $oResult[$iUserId]; return $oResult; } private function switchCodeId(&$iCodeId, $sMode) { switch($sMode) { case 'first': $iCodeId = $this->oMySql->selectValue(self::CODE_TABLE, 'refer_id', $iCodeId); break; case 'last': $iRefId = $this->oMySql->selectValue(self::CODE_TABLE, 'refer_id', $iCodeId); $iCodeId = $this->oMySql->selectValue(self::CODE_TABLE, 'MAX(id_code)', array('refer_id'=>$iRefId)); break; } } private function getIdCodeFromPhrase($sPhrase) { $iCodeId = $this->oMySql->selectValue(self::URL_TABLE, MySqlManager::getId(self::CODE_TABLE), array('phrase'=>$sPhrase)); $this->switchCodeId($iCodeId, 'last'); return $iCodeId; } private function getPhraseFromIdCode($iCodeId) { $this->switchCodeId($iCodeId, 'first'); return $this->oMySql->selectValue(self::URL_TABLE, 'phrase', array('id_code'=>$iCodeId)); } private function getCodeVersions($iRefCodeId) { $asCodeVersions = array(); if($iRefCodeId>0) { $asInfo = array('select'=>array(MySqlManager::getId(self::CODE_TABLE)), 'from'=>self::CODE_TABLE, 'constraint'=>array('refer_id'=>$iRefCodeId), 'orderBy'=>array('id_code'=>'asc')); $asCodeIds = $this->oMySql->selectRows($asInfo); foreach($asCodeIds as $iCodeId) { $asCodeVersions[] = $this->getCodeInfo($iCodeId); } } return $asCodeVersions; } public function getColoredCode($oCode) { $asCode = $this->getCodeInfo($oCode, '', true); //code $this->oClassManagement->incClass('reader'); $oReader = new Reader($asCode['code']); $asCode['code'] = $oReader->getColoredCode(); //phrase $sPhrase = $this->getPhraseFromIdCode($asCode['id_code']); if($sPhrase !== false) { $asCode['phrase'] = $sPhrase; } //user $asUsers[$asCode['id_user']] = $this->getUserInfo($asCode['id_user']); $asCode = array_merge($asCode, $asUsers[$asCode['id_user']]); //versions $asCodeVersions = $this->getCodeVersions($asCode['refer_id']); $iCodeRowId = 0; foreach($asCodeVersions as $iRowId=>$asCodeVersion) { if($asCodeVersion['id_code']==$asCode['id_code']) $iCodeRowId = $iRowId; } $asCode['truncated'] = ($iCodeRowId > self::MAX_LIST_LENGTH)?$asCodeVersions[$iCodeRowId - 1 - self::MAX_LIST_LENGTH]['id_code']:0; foreach($asCodeVersions as $iRowId=>$asCodeVersion) { if($iCodeRowId - $iRowId <= self::MAX_LIST_LENGTH) { if(!array_key_exists($asCodeVersion['id_user'], $asUsers)) { $asUsers[$asCodeVersion['id_user']] = $this->getUserInfo($asCodeVersion['id_user']); } if($asCodeVersion['id_code']!=$asCode['id_code']) { $asVersionInfo = array_merge($asCodeVersion, $asUsers[$asCodeVersion['id_user']]); $asCode['other_versions'][] = $asVersionInfo; } } } return $this->jsonExport($asCode); } public function getNudeCode($oCode) { $asCode = $this->getCodeInfo($oCode, '', true); //$sCode = Reader::convText2Html($asCode['code']); return $asCode['code']; } public function getRawCode($oCode, $bPrint=false) { $asCode = $this->getCodeInfo($oCode, '', true); $asUser = $this->getUserInfo($asCode['id_user']); $sEncodedCode = $this->jsonConvert($asCode['code']); $sEncodedDesc = $this->jsonConvert($asCode['description']); $oRawCodePage = new Mask('raw_code'); $oRawCodePage->setTags(array( 'text_enc'=>Settings::TEXT_ENC, 'author'=>$asUser['name'].' ('.$asUser['company'].')', 'content'=>$sEncodedCode, 'title'=>$sEncodedDesc, 'print'=>$bPrint?'true':'false')); return $oRawCodePage->getMask(); } public function getSavedCode($oCode) { $asCode = $this->getCodeInfo($oCode, '', true); $sPhrase = $this->getPhraseFromIdCode($asCode['id_code']); if(!$sPhrase) { $sPhrase = 'code_numero_'.$asCode['id_code']; } //set headers header('Pragma: public'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Cache-Control: public'); header('Content-Description: File Transfer'); header('Content-Type: application/force-download'); header('Content-Disposition: attachment; filename='.$sPhrase.'.abap'); header('Content-Transfer-Encoding: binary'); //header('Content-Length: '.filesize($sFilePath)); return $asCode['code']; } public function getItemList() { $asUsers = $asItemList = array(); $sIdUserCol = MySqlManager::getId(self::USER_TABLE); //TODO phrases for all item types? $asTypeTables = $this->getTypeInfo('table'); foreach($asTypeTables as $sType=>$sTable) { //selecting last version among codes having the same refer_id $sTableIdCol = MySqlManager::getId($sTable); $asInfo = array('select' => array("MAX({$sTableIdCol}) AS id_item"), 'from' => $sTable, 'groupBy' => array(($sType==self::ART_TYPE)?$sTableIdCol:'refer_id'), //no versioning for articles 'orderBy' => array('id_item'=>'desc')); //Build code info structure $asTypedItemIds = array_filter($this->oMySql->selectRows($asInfo)); //null value returned from query (MAX(...)) foreach($asTypedItemIds as $iItemId) { //Getting item info $asItem = $this->getItemInfo($sType, $iItemId); $asItem['type'] = $sType; $asItem['id_item'] = $iItemId; //Replacing user's id with user's name & company (if not done already) if(array_key_exists($sIdUserCol, $asItem)) { $iUserId = $asItem[$sIdUserCol]; if(!array_key_exists($iUserId, $asUsers)) $asUsers[$iUserId] = $this->getUserInfo($iUserId); $asItem['name'] = $asUsers[$iUserId]['name']; $asItem['company'] = $asUsers[$iUserId]['company']; } //Preparing key for reverse sorting $asItemList[$asItem['timestamp'].$asItem['type'].$asItem['id_item']] = $asItem; } } krsort($asItemList); return $this->jsonExport($asItemList); } public function getCodeBlock() { $oMask = new Mask(); $oMask->initFile('code_block'); $oMask->setTag('item', $this->getItemBlock()); return $oMask->getMask(); } private function getItemBlock() { $oMask = new Mask('item'); return $oMask->getMask(); } public function logMeIn($sToken, $sAction) { $iUserId = 0; $sNameToken = ''; $bResetPass = true; $sUserTableId = MySqlManager::getId(self::USER_TABLE); //login using form if($sAction!=self::EXT_ACCESS) { if($sToken!='') { $sNameToken = strstr($sToken, self::NAME_PASS_SEP, true); $sPassToken = substr(strstr($sToken, self::NAME_PASS_SEP), 1); //Check name //TODO replace SPACE(1) with self::FIRST_LAST_SEP (separate first and last name on logon page) $asConsts = array('MD5(CONCAT(first_name, SPACE(1), last_name))'=>$sNameToken, 'active'=>self::MEMBER_ACTIVE); $asInvConsts = array('MD5(CONCAT(last_name, SPACE(1), first_name))'=>$sNameToken, 'active'=>self::MEMBER_ACTIVE); $iUserId = $this->oMySql->selectValue(self::USER_TABLE, $sUserTableId, $asConsts); if(!$iUserId) $iUserId = $this->oMySql->selectValue(self::USER_TABLE, $sUserTableId, $asInvConsts); //Check Pass if($iUserId==self::SYSTEM_USER_ID || !$this->oAuth->CheckPassword($sPassToken, $this->oMySql->selectValue(self::USER_TABLE, 'pass', $iUserId))) $iUserId = 0; } //auto login by cookie elseif(isset($_COOKIE[self::USER_COOKIE_ID]) && $_COOKIE[self::USER_COOKIE_ID]!=self::SYSTEM_USER_ID) { $asConstraints = array( $sUserTableId=>$_COOKIE[self::USER_COOKIE_ID], 'auth_cookie'=>$_COOKIE[self::USER_COOKIE_PASS], 'active'=>self::MEMBER_ACTIVE); $asUserInfo = $this->oMySql->selectRow(self::USER_TABLE, $asConstraints, array($sUserTableId, 'led')); if(!empty($asUserInfo)) { $iUserId = $asUserInfo[$sUserTableId]; //Reset pass once a day $bResetPass = (mb_substr($asUserInfo['led'], 0, 10) != date(Databap::DATE_SQL_FORMAT)); } } } //Login using Token (limited access) elseif($sToken!='') { $iUserId = $this->checkExternalAccessToken($sToken); $bResetPass = false; } if($iUserId>0) { $this->setUserId($iUserId); if($bResetPass) $this->resetAuthCookie(); //Post-Redirect-Get if user manually logging from logon page if($sNameToken!='') { header('HTTP/1.1 303 See Other'); header('Location: '.$_SERVER['REQUEST_URI']); exit(); } } return ($this->getUserId()>0); } private static function getLoginToken($sPass) { return md5($sPass.str_replace('https://', 'http://', $_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) { $bSuccess = false; $sDesc = ''; 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); if(empty($asUsers)) $sDesc = 'Aucun utilisateur trouvé (id='.$iUserId.')'; else { 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)); $bSuccess = true; $sDesc = 'Mot de passe réinitialisé'; } } } else $sDesc = 'Aucun id reçu'; return $this->getJsonPostResult($bSuccess, $sDesc); } 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); } } private function checkValue($sTableName, $asConstraints) { return $this->oMySql->selectValue($sTableName, 'COUNT(1)', $asConstraints); } public function getUrlAvailability($sLink) { $bAvailable = !$this->checkValue(self::URL_TABLE, array('phrase'=>$sLink)); return self::getJsonPostResult($bAvailable, ''); } public function resetChanSafeNames() { $iChanIdCol = MySqlManager::getId(self::CHAN_TABLE); $asChans = $this->oMySql->selectRows(array('select'=>array($iChanIdCol, MySqlManager::getText(self::CHAN_TABLE)), 'from'=>self::CHAN_TABLE), true, $iChanIdCol); $asResult = array(); foreach($asChans as $iChanId=>$sChanName) { $asResult[$iChanId] = ($this->oMySql->updateRow(self::CHAN_TABLE, $iChanId, array('safe_name'=>self::getChanSafeName($sChanName))) > 0)?'Fixed':'Not Fixed'; } return MySqlManager::implodeAll($asResult, ' : ', "\n", 'Result reset ID channel ', '.'); } public static function getChanSafeName($sChanName) { //TODO replace unsafe chars with unique id $sChanSafeName = preg_replace('/[^a-z0-9]/u', '_', mb_strtolower($sChanName)); //Sort PM chans $asPm = self::isPmChan($sChanSafeName); if(!$asPm['is_pm']) $sChanSafeName = $asPm['chan_name']; return $sChanSafeName; } public function getResults($sSearchWords) { $this->oSearchEngine->setWords($sSearchWords); $asResults = $this->oSearchEngine->getResults(); //complementary infos $asCompleteResults = array(); foreach($asResults as $asItemInfo) { //Item Info $iItemId = $asItemInfo['id_item']; $sType = $asItemInfo['type']; $asItemInfo += $this->getItemInfo($sType, $iItemId); //User Info if($sType != self::ART_TYPE) //Already available in item info { $asUserInfo = $this->getUserInfo($asItemInfo[MySqlManager::getId(self::USER_TABLE)]); $asItemInfo['name'] = $asUserInfo['name']; $asItemInfo['company'] = $asUserInfo['company']; } //TODO: phrase $asCompleteResults[] = $asItemInfo; } return $this->jsonExport($asCompleteResults); } public function getStyleSheet() { $sStyle = file_get_contents(self::STYLE_PATH); $asStyleParams = array(self::OPT_BG, self::OPT_BG_2, self::OPT_BG_3, self::OPT_HOVER, self::OPT_CHAT_BG); //Inserting Color Anchors $asDefaultValues = $this->getDefaultOptionValues($asStyleParams, false); foreach($asDefaultValues as $iOptionNameId=>$sDefaultValue) $asColorAnchors[$iOptionNameId] = '[OPT#'.$iOptionNameId.']'; $sStyle = str_replace($asDefaultValues, $asColorAnchors, $sStyle); //Switching color Anchors with user colors $asOptionvalues = $this->getUserOptions($asStyleParams); foreach($asColorAnchors as $iOptionNameId=>$sColorAnchor) { $sStyle = str_replace($sColorAnchor, $asOptionvalues[$iOptionNameId][MySqlManager::getText(self::OPTVAL_TABLE)], $sStyle); } //setting header content type header("Content-Type: text/css"); return $sStyle; } public function addUncaughtError($sError) { $this->addError('Uncaught errors:'."\n".$sError); } public static function getDateFormat($oTime, $sFormat=Databap::DATE_TIME_FORMAT) { $iTimeStamp = is_numeric($oTime)?$oTime:strtotime($oTime); return date($sFormat, $iTimeStamp); } public static function getNameFormat($sFirstName, $sLastName) { return ToolBox::capitalizeWords(trim($sFirstName.self::FIRST_LAST_SEP.$sLastName), ' -');; } public static function getNickNameFormat($sNickName) { $sNickName = ToolBox::capitalizeWords(trim($sNickName), ' -'); return str_replace(' ', '_', $sNickName); } public static function getCompanyFormat($sCompany) { return mb_strlen($sCompany)>3?ToolBox::mb_ucwords($sCompany):mb_strtoupper($sCompany); } public static function getDescriptionFormat($sDescription) { return ToolBox::mb_ucfirst(ToolBox::findReplaceLinks($sDescription)); } public static function getTableFormat($sTable) { return mb_strtoupper($sTable); } public function getJsonPostResult($bSuccess, $sDesc, $asVars=array()) { if(!$bSuccess) $this->addError($sDesc); return self::jsonExport(array('result'=>$bSuccess?self::SUCCESS:self::ERROR, 'desc'=>$sDesc)+$asVars); } public static function jsonExport($asData) { header('Content-type: application/json'); return self::jsonConvert($asData); } public static function jsonConvert($asData) { //return htmlspecialchars(json_encode($asData), ENT_NOQUOTES); return json_encode($asData); } public static function getMaxSize() { $iPostSize = self::toBytes(ini_get('post_max_size')); $iUploadSize = self::toBytes(ini_get('upload_max_filesize')); return min($iPostSize, $iUploadSize); } public static function toBytes($str) { $val = trim($str); $last = mb_strtolower($str[mb_strlen($str)-1]); switch($last) { case 'g': $val *= 1024; case 'm': $val *= 1024; case 'k': $val *= 1024; } return $val; } } ?>