richdocuments/lib/db/session.php

219 lines
5.7 KiB
PHP
Raw Normal View History

2013-09-27 18:43:10 +03:00
<?php
/**
* ownCloud - Documents App
*
* @author Victor Dubiniuk
* @copyright 2013 Victor Dubiniuk victor.dubiniuk@gmail.com
*
* This file is licensed under the Affero General Public License version 3 or
* later.
*/
2014-08-04 20:51:50 +03:00
namespace OCA\Documents\Db;
2013-09-27 18:43:10 +03:00
2015-08-26 20:16:53 +03:00
use OCP\Security\ISecureRandom;
2015-01-23 18:34:58 +03:00
use OCA\Documents\Filter;
2013-09-27 18:43:10 +03:00
/**
2014-05-13 23:17:25 +03:00
* Session management
*
* @method string getEsId()
* @method int getFileId()
* @method string getGenesisUrl()
* @method string getOwner()
* @method string getGenesisHash()
*
2013-09-27 18:43:10 +03:00
*/
2014-08-04 20:51:50 +03:00
class Session extends \OCA\Documents\Db {
2013-09-27 18:43:10 +03:00
/**
* DB table
*/
const DB_TABLE = '`*PREFIX*documents_session`';
protected $tableName = '`*PREFIX*documents_session`';
protected $insertStatement = 'INSERT INTO `*PREFIX*documents_session` (`es_id`, `genesis_url`, `genesis_hash`, `owner`, `file_id`)
VALUES (?, ?, ?, ?, ?)';
protected $loadStatement = 'SELECT * FROM `*PREFIX*documents_session` WHERE `es_id`= ?';
/**
* Start a editing session or return an existing one
* @param string $uid of the user starting a session
* @param \OCA\Documents\File $file - file object
* @return array
* @throws \Exception
*/
public static function start($uid, $file){
// Create a directory to store genesis
2014-08-04 20:51:50 +03:00
$genesis = new \OCA\Documents\Genesis($file);
2014-04-10 19:53:56 +03:00
list($ownerView, $path) = $file->getOwnerViewAndPath();
2015-01-23 18:34:58 +03:00
$mimetype = $ownerView->getMimeType($path);
if (!Filter::isSupportedMimetype($mimetype)){
throw new \Exception( $path . ' is ' . $mimetype . ' and is not supported by Documents app');
}
2014-08-04 20:51:50 +03:00
$oldSession = new Session();
2013-09-27 18:43:10 +03:00
$oldSession->loadBy('file_id', $file->getFileId());
2013-09-27 18:43:10 +03:00
//If there is no existing session we need to start a new one
if (!$oldSession->hasData()){
2014-08-04 20:51:50 +03:00
$newSession = new Session(array(
$genesis->getPath(),
$genesis->getHash(),
$file->getOwner(),
$file->getFileId()
2013-09-27 18:43:10 +03:00
));
if (!$newSession->insert()){
throw new \Exception('Failed to add session into database');
}
}
2014-04-11 23:12:23 +03:00
$sessionData = $oldSession
2013-09-27 18:43:10 +03:00
->loadBy('file_id', $file->getFileId())
->getData()
;
2013-09-27 18:43:10 +03:00
2014-08-04 20:51:50 +03:00
$memberColor = \OCA\Documents\Helper::getMemberColor($uid);
2014-08-04 21:00:58 +03:00
$member = new \OCA\Documents\Db\Member(array(
2014-04-11 23:12:23 +03:00
$sessionData['es_id'],
2013-11-25 23:14:32 +03:00
$uid,
$memberColor,
time(),
2014-04-11 00:59:51 +03:00
intval($file->isPublicShare()),
$file->getToken()
2013-09-27 18:43:10 +03:00
));
2013-11-25 23:14:32 +03:00
2014-11-19 03:37:09 +03:00
if (!$member->insert()){
throw new \Exception('Failed to add member into database');
}
2015-08-27 01:57:31 +03:00
$sessionData['member_id'] = (string) $member->getLastInsertId();
2014-11-19 03:37:09 +03:00
// Do we have OC_Avatar in out disposal?
if (\OC_Config::getValue('enable_avatars', true) !== true){
$imageUrl = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==';
} else {
$imageUrl = $uid;
}
2015-08-27 01:57:31 +03:00
$displayName = $file->isPublicShare()
? $uid . ' ' . \OCA\Documents\Db\Member::getGuestPostfix()
: \OC::$server->getUserSession()->getUser()->getDisplayName($uid)
;
$userId = $file->isPublicShare() ? $displayName : \OC::$server->getUserSession()->getUser()->getUID();
2014-11-19 03:37:09 +03:00
$op = new \OCA\Documents\Db\Op();
$op->addMember(
2014-04-11 23:12:23 +03:00
$sessionData['es_id'],
$sessionData['member_id'],
$displayName,
2014-11-19 03:37:09 +03:00
$userId,
2013-11-25 23:14:32 +03:00
$memberColor,
$imageUrl
2014-11-19 03:37:09 +03:00
);
2014-04-11 23:12:23 +03:00
$sessionData['title'] = basename($path);
$fileInfo = $ownerView->getFileInfo($path);
$sessionData['permissions'] = $fileInfo->getPermissions();
2013-09-27 18:43:10 +03:00
2014-04-11 23:12:23 +03:00
return $sessionData;
2013-09-27 18:43:10 +03:00
}
public static function cleanUp($esId){
2014-08-04 20:51:50 +03:00
$session = new Session();
2013-09-27 18:43:10 +03:00
$session->deleteBy('es_id', $esId);
2014-08-04 21:00:58 +03:00
$member = new \OCA\Documents\Db\Member();
2013-09-27 18:43:10 +03:00
$member->deleteBy('es_id', $esId);
2014-08-04 20:56:24 +03:00
$op= new \OCA\Documents\Db\Op();
2013-09-27 18:43:10 +03:00
$op->deleteBy('es_id', $esId);
}
2014-11-11 23:06:27 +03:00
public function syncOps($memberId, $currentHead, $clientHead, $clientOps){
$hasOps = count($clientOps)>0;
$op = new \OCA\Documents\Db\Op();
// TODO handle the case ($currentHead == "") && ($seqHead != "")
if ($clientHead == $currentHead) {
// matching heads
if ($hasOps) {
// incoming ops without conflict
// Add incoming ops, respond with a new head
$newHead = \OCA\Documents\Db\Op::addOpsArray($this->getEsId(), $memberId, $clientOps);
$result = array(
'result' => 'added',
'head_seq' => $newHead ? $newHead : $currentHead
);
} else {
// no incoming ops (just checking for new ops...)
$result = array(
'result' => 'new_ops',
'ops' => array(),
'head_seq' => $currentHead
);
}
} else { // HEADs do not match
$result = array(
'result' => $hasOps ? 'conflict' : 'new_ops',
'ops' => $op->getOpsAfterJson($this->getEsId(), $clientHead),
'head_seq' => $currentHead,
);
}
return $result;
}
2013-09-27 18:43:10 +03:00
public function insert(){
$esId = $this->getUniqueSessionId();
array_unshift($this->data, $esId);
2014-11-11 21:00:33 +03:00
return parent::insert();
2013-09-27 18:43:10 +03:00
}
public function updateGenesisHash($esId, $genesisHash){
return $this->execute(
'UPDATE `*PREFIX*documents_session` SET `genesis_hash`=? WHERE `es_id`=?',
array(
$genesisHash, $esId
)
);
}
2013-09-27 18:43:10 +03:00
public function getInfo($esId){
$result = $this->execute('
SELECT `s`.*, COUNT(`m`.`member_id`) AS `users`
FROM ' . $this->tableName . ' AS `s`
LEFT JOIN `*PREFIX*documents_member` AS `m` ON `s`.`es_id`=`m`.`es_id`
2014-08-04 21:00:58 +03:00
AND `m`.`status`=' . Db\Member::MEMBER_STATUS_ACTIVE . '
2013-09-27 18:43:10 +03:00
AND `m`.`uid` != ?
WHERE `s`.`es_id` = ?
GROUP BY `m`.`es_id`
',
2015-08-27 01:57:31 +03:00
[
\OC::$server->getUserSession()->getUser()->getUID(),
2013-09-27 18:43:10 +03:00
$esId
2015-08-27 01:57:31 +03:00
]
2013-09-27 18:43:10 +03:00
);
$info = $result->fetchRow();
if (!is_array($info)){
$info = array();
}
return $info;
}
protected function getUniqueSessionId(){
2014-08-04 20:51:50 +03:00
$testSession = new Session();
2013-09-27 18:43:10 +03:00
do{
2015-08-26 20:16:53 +03:00
$id = \OC::$server->getSecureRandom()
->getMediumStrengthGenerator()
->generate(30, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS);
2014-04-10 17:13:19 +03:00
} while ($testSession->load($id)->hasData());
2013-09-27 18:43:10 +03:00
return $id;
}
}