* @copyright (c) 2016 by Stylite AG * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @version $Id$ */ use EGroupware\Api; /** * Storage Object of the filemanager */ class filemanager_collab_bo { /** * session table name */ const SESSION_TABLE = 'egw_collab_session'; /** * member table name */ const MEMBER_TABLE = 'egw_collab_member'; /** * op table name */ const OP_TABLE = 'egw_collab_op'; /** * prefix value used for naming fields in DB */ const DB_FILEDS_PREFIX = 'collab_'; /** * Exception message for no session found */ const EXCEPTION_MESSAGE_NO_SESSION = 'Session id must be given, none given!'; /** * Exception message for no OP */ const EXCEPTION_MESSAGE_NO_OPS = 'ops need to be an array of op data, none array given!'; /** * Database object * @var Api\Db */ protected $db; public function __construct() { $this->db = $GLOBALS['egw']->db; } /** * Init session check for existing session or create one there's none * * @param string $es_id session id * * @return array returns an array contains of mapped session data */ protected function initSession ($es_id) { $query = $this->db->select(self::SESSION_TABLE,'*', array('collab_es_id' => $es_id),__LINE__,__FILE__); $full_name = $GLOBALS['egw_info']['user']['account_fullname']; $color = $GLOBALS['egw_info']['user']['preferences']['filemanager']['collab_user_color']; $user_id = $GLOBALS['egw_info']['user']['account_id']; $imageUrl = $GLOBALS['egw_info']['server']['webserver_url'].'/index.php?menuaction=addressbook.addressbook_ui.photo&account_id='.$user_id; if (!($result = self::db2id($query->fetchRow())) && $es_id) { $result = self::db2id($this->SESSION_add2Db($es_id)); } $this->MEMBER_add2Db($es_id, $user_id, $color); $result['member_id'] = $this->MEMBER_getLastMember(); $this->OP_addMember($es_id, $result['member_id'], $full_name, $user_id, $color, $imageUrl); return $result; } /** * Add session data with provided session id into DB * * @param string $es_id session id * * @return array returns an array contains of session data */ protected function SESSION_add2Db ($es_id) { if ($es_id) { $data = array ( 'collab_es_id' => $es_id, 'collab_genesis_url' => '', 'collab_genesis_hash' => '', 'collab_last_saved' => self::getTimeStamp(), 'account_id' => $GLOBALS['egw_info']['user']['account_id'] ); $this->db->insert(self::SESSION_TABLE, $data,false,__LINE__, __FILE__,'filemanager'); } return $data; } /** * Method to clean up left over modifications data * * @param type $es_id session id * * @throws Exception */ public function SESSION_cleanup ($es_id) { if (!$es_id) throw new Exception (self::EXCEPTION_MESSAGE_NO_SESSION); $this->db->delete( self::OP_TABLE, array('collab_es_id' => $es_id), __LINE__, __FILE__ ); $this->db->delete( self::SESSION_TABLE, array('collab_es_id' => $es_id), __LINE__, __FILE__ ); $this->db->delete( self::MEMBER_TABLE, array('collab_es_id' => $es_id), __LINE__, __FILE__ ); } /** * Method to update last time saved in session table * * @param type $es_id * * @return boolean returns true if update is successful otherwise false * @throws Exception */ public function SESSION_Save ($es_id) { if (!$es_id) throw new Exception (self::EXCEPTION_MESSAGE_NO_SESSION); $query = $this->db->update( self::SESSION_TABLE, array('collab_last_save' => self::getTimeStamp()), array('collab_es_id' => $es_id), __LINE__, __FILE__, 'filemanager'); return !$query? false: true; } /** * OP addMember function is backend equivalent to addMember from frontend * * @param string $es_id session id * @param string $member_id * @param string $full_name * @param string $user_id * @param string $color * @param string $imageUrl */ protected function OP_addMember($es_id, $member_id, $full_name, $user_id, $color='', $imageUrl='') { $op = array( 'optype' => 'AddMember', 'memberid' => (string) $member_id, 'timestamp' => self::getTimeStamp(), 'setProperties' => array( 'fullName' => $full_name, 'color' => $color, 'imageUrl' => $imageUrl, 'uid' => $user_id, ) ); $this->OP_add2Db($op, $es_id); } /** * Function to remove cursor for a member * * @param string $es_id session id * @param string $member_id member id */ protected function OP_removeCursor ($es_id, $member_id) { $op = array( 'optype' => 'RemoveCursor', 'memberid' => (string) $member_id, 'reason' => 'server-idle', 'timestamp' => self::getTimeStamp() ); $this->OP_add2Db($op, $es_id); } /** * Function to remove member from list * * @param string $es_id session id * @param string $member_id membe id * * @return boolean returns true if remove member is successful otherwise false */ function OP_removeMember ($es_id, $member_id) { $op = array ( 'optype' => 'RemoveMember', 'memberid' => (string) $member_id, 'timestamp' => self::getTimeStamp() ); return $this->OP_add2Db($op, $es_id)?true:false; } /** * Function to get top head seq for a given session * * @param string $es_id * * @return string returns head seq or '' if none exists * @throws Exception throws exception if no session is given */ protected function OP_getHeadSeq($es_id) { if (!$es_id) throw new Exception (self::EXCEPTION_MESSAGE_NO_SESSION); $query = $this->db->select( self::OP_TABLE, 'collab_seq', array('collab_es_id' => $es_id), __LINE__, __FILE__, FALSE, 'ORDER BY collab_seq DESC LIMIT 1', 'filemanager' ); $head_seq = $query->fetchRow(); return is_array($head_seq)? $head_seq['collab_seq']: ''; } /** * Function to get opsepcs of session base on seq head * * @param string $es_id session id * @param string $seq_head sequence head * * @return array returns array of opspecs */ protected function OP_getOPSECS($es_id, $seq_head) { if ($seq_head == "") { $seq_head = -1; } $ops = array(); $query = $this->db->select( self::OP_TABLE, 'collab_opspec', 'collab_es_id ="'. $es_id.'" AND collab_seq >'.$seq_head, __LINE__, __FILE__, false, 'ORDER BY collab_seq ASC','filemanager'); foreach ($query as $spec) { $op = json_decode($spec['collab_opspec'], true); $op['memberid'] = strval($op['memberid']); $ops [] = $op; } return $ops; } /** * Function to ops data array into op table * * @param string $es_id session id * @param string $member_id member id * @param array $client_ops array of ops * @throws Exception if no array of ops given */ protected function OP_addOPS ($es_id, $member_id, $client_ops) { if (count($client_ops)<= 0) throw new Exception (self::EXCEPTION_MESSAGE_NO_OPS); foreach ($client_ops as $op) { $this->OP_add2Db($op, $es_id); } } /** * Insert op data into OP table in database * * @param array $op op data * @param string $es_id session id */ protected function OP_add2Db ($op, $es_id) { $data = array ( 'collab_es_id' => $es_id, 'collab_member' => $op['memberid'], 'collab_optype' => $op['optype'], 'collab_opspec' => json_encode($op) ); return $this->db->insert(self::OP_TABLE, $data,false,__LINE__, __FILE__,'filemanager'); } /** * Add member data into member table in database * * @param type $es_id session id * @param type $user_id user id * @param type $color user color code */ protected function MEMBER_add2Db ($es_id, $user_id, $color) { $data = array ( 'collab_es_id' => $es_id, 'collab_uid' => $user_id, 'collab_color' => $color ); $this->db->insert(self::MEMBER_TABLE, $data,false,__LINE__, __FILE__,'filemanager'); } /** * Function to get member record of specific member id * * @param string $member_id member id * * @return string member id or null * @throws Exception throws exception if no member id is given */ protected function MEMBER_getUserMemberId ($es_id, $user_id) { if (!$es_id || !$user_id) throw new Exception (self::EXCEPTION_MESSAGE_NO_SESSION); $query = $this->db->select( self::MEMBER_TABLE, 'collab_member_id', array('collab_es_id' => $es_id, 'collab_uid' => $user_id), __LINE__, __FILE__ ); $member = $query->fetchRow(); return is_array($member)? $member['collab_member_id']: null; } /** * Function to get member record of specific member id * * @param string $member_id member id * * @return string member id or null * @throws Exception throws exception if no member id is given */ protected function MEMBER_getUserLastMemberId ($es_id, $user_id) { if (!$es_id || !$user_id) throw new Exception (self::EXCEPTION_MESSAGE_NO_SESSION); $query = $this->db->select( self::MEMBER_TABLE, 'collab_member_id', array('collab_es_id' => $es_id, 'collab_uid' => $user_id), __LINE__, __FILE__, false, "ORDER BY `collab_member_id` DESC LIMIT 1;" ); $member = $query->fetchRow(); return is_array($member)? $member['collab_member_id']: null; } /** * Utility function to map DB fields to ids * * @param array $data * @return array|boolean returns an array contains of mapped DB data, otherwise false */ protected static function db2id($data) { if (!is_array($data)) return false; $keys = array_keys($data); array_walk($keys,function (&$key){$key = str_replace(self::DB_FILEDS_PREFIX, '', $key);}); return array_combine ($keys, $data); } /** * Return last member id from member table in db * * @return int returns the last member id or if it's not exist returns 0 */ protected function MEMBER_getLastMember() { $query = $this->db->select( self::MEMBER_TABLE, 'collab_member_id', '', __LINE__, __FILE__, false, "ORDER BY `collab_member_id` DESC LIMIT 1;" ); $last_row = $query->fetchRow(); return is_array($last_row)? $last_row['collab_member_id']: 0; } /** * Get timestamp * @return int returns current time as timestamp */ static function getTimeStamp () { $date = new DateTime(); return $date->getTimestamp(); } }