Merge pull request #236 from owncloud/get-path-refactoring

Get path refactoring
This commit is contained in:
VicDeo 2014-04-14 18:06:30 +03:00
commit 3788512dff
22 changed files with 200 additions and 205 deletions

View File

@ -5,8 +5,6 @@ namespace OCA\Documents;
\OCP\JSON::callCheck();
\OCP\JSON::checkAdminUser();
$l10n = \OCP\Util::getL10N('documents');
$converter = isset($_POST['converter']) ? $_POST['converter'] : null;
$url = isset($_POST['url']) ? $_POST['url'] : null;
try {
@ -21,7 +19,7 @@ try {
if (Config::getConverter()!='local'){
if (!Converter::checkConnection()){
Helper::warnLog('Bad response from Format Filter Server');
\OCP\JSON::error(array('message' => $l10n->t('Format filter server is down or misconfigured') ));
\OCP\JSON::error(array('message' => Config::getL10n()->t('Format filter server is down or misconfigured') ));
exit();
}
}

View File

@ -37,7 +37,6 @@ class Controller {
\OCP\JSON::callCheck();
}
\OCP\JSON::checkAppEnabled('documents');
return '(guest)';
}
}

File diff suppressed because one or more lines are too long

View File

@ -32,35 +32,38 @@ try{
$esId = $request->getParam('args/es_id');
$session = new Db_Session();
$sessionData = $session->load($esId)->getData();
$session->load($esId);
$memberId = $request->getParam('args/member_id');
$member = new Db_Member();
$member->load($memberId);
if ($member->getIsGuest() || is_null($member->getIsGuest())){
Controller::preDispatchGuest(false);
} else {
Controller::preDispatch(false);
}
try {
$file = new File(@$sessionData['file_id']);
$file = new File($session->getFileId());
} catch (\Exception $e){
Helper::warnLog('Error. Session no longer exists. ' . $e->getMessage());
$ex = new BadRequestException();
$ex->setBody($request->getRawRequest());
throw $ex;
}
if (!$file->isPublicShare()){
Controller::preDispatch(false);
} else {
Controller::preDispatchGuest(false);
}
$command = $request->getParam('command');
switch ($command){
case 'sync_ops':
$seqHead = (string) $request->getParam('args/seq_head');
if (!is_null($seqHead)){
$memberId = $request->getParam('args/member_id');
$ops = $request->getParam('args/client_ops');
$hasOps = is_array($ops) && count($ops)>0;
$op = new Db_Op();
$currentHead = $op->getHeadSeq($esId);
$member = new Db_Member();
try {
$member->updateActivity($memberId);
} catch (\Exception $e){

View File

@ -15,12 +15,16 @@ namespace OCA\Documents;
class SessionController extends Controller{
public static function joinAsGuest($args){
$uid = self::preDispatchGuest();
$uid = substr(@$_POST['name'], 0, 16) .' '. $uid;
$token = @$args['token'];
self::preDispatchGuest();
$uid = Helper::getArrayValueByKey($_POST, 'name');
$guestUid = substr($uid, 0, 16);
try {
$token = Helper::getArrayValueByKey($args, 'token');
$file = File::getByShareToken($token);
self::join($uid, $file);
$session = Db_Session::start($uid, $file, true);
\OCP\JSON::success($session);
} catch (\Exception $e){
Helper::warnLog('Starting a session failed. Reason: ' . $e->getMessage());
\OCP\JSON::error();
@ -30,16 +34,20 @@ class SessionController extends Controller{
public static function joinAsUser($args){
$uid = self::preDispatch();
$fileId = intval(@$args['file_id']);
$fileId = Helper::getArrayValueByKey($args, 'file_id');
try {
$file = new File($fileId);
if ($file->getPermissions() & \OCP\PERMISSION_UPDATE) {
self::join($uid, $file);
$view = \OC\Files\Filesystem::getView();
$path = $view->getPath($fileId);
if ($view->isUpdatable($path)) {
$file = new File($fileId);
$session = Db_Session::start($uid, $file);
\OCP\JSON::success($session);
} else {
$info = $view->getFileInfo();
\OCP\JSON::success(array(
'permissions' => $file->getPermissions(),
'permissions' => $info['permissions'],
'id' => $fileId
));
}
@ -51,11 +59,6 @@ class SessionController extends Controller{
}
}
protected static function join($uid, $file){
$session = Db_Session::start($uid, $file);
\OCP\JSON::success($session);
exit();
}
/**
* Store the document content to its origin
@ -68,6 +71,19 @@ class SessionController extends Controller{
}
$memberId = @$_SERVER['HTTP_WEBODF_MEMBER_ID'];
$currentMember = new Db_Member();
$currentMember->load($memberId);
if (is_null($currentMember->getIsGuest()) || $currentMember->getIsGuest()){
$uid = self::preDispatchGuest();
} else {
self::preDispatch();
}
//check if member belongs to the session
if ($esId != $currentMember->getEsId()){
throw new \Exception($memberId . ' does not belong to session ' . $esId);
}
$sessionRevision = @$_SERVER['HTTP_WEBODF_SESSION_REVISION'];
$stream = fopen('php://input','r');
@ -79,22 +95,21 @@ class SessionController extends Controller{
$session = new Db_Session();
$session->load($esId);
if (!$session->hasData()){
if (!$session->getEsId()){
throw new \Exception('Session does not exist');
}
$sessionData = $session->getData();
try {
$file = new File($sessionData['file_id']);
if (!$file->isPublicShare()){
self::preDispatch();
if ($currentMember->getIsGuest()){
$file = File::getByShareToken($currentMember->getToken());
} else {
self::preDispatchGuest();
$file = new File($session->getFileId());
}
list($view, $path) = $file->getOwnerViewAndPath();
} catch (\Exception $e){
//File was deleted or unshared. We need to save content as new file anyway
//Sorry, but for guests it would be lost :(
$uid = self::preDispatch();
$view = new \OC\Files\View('/' . $uid . '/files');
$dir = \OCP\Config::getUserValue(\OCP\User::getUser(), 'documents', 'save_path', '');
@ -109,23 +124,17 @@ class SessionController extends Controller{
},
$members
);
//check if member belongs to the session
if (!in_array($memberId, $memberIds)){
throw new \Exception($memberId . ' does not belong to session ' . $esId);
}
// Active users except current user
$memberCount = count($memberIds) - 1;
if ($view->file_exists($path)){
if ($view->file_exists($path)){
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$currentHash = sha1($view->file_get_contents($path));
\OC_FileProxy::$enabled = $proxyStatus;
if (!Helper::isVersionsEnabled() && $currentHash !== $sessionData['genesis_hash']){
if (!Helper::isVersionsEnabled() && $currentHash !== $session->getGenesisHash()){
// Original file was modified externally. Save to a new one
$path = Helper::getNewFileName($view, $path, '-conflict');
}
@ -142,7 +151,6 @@ class SessionController extends Controller{
if ($memberCount>0){
// Update genesis hash to prevent conflicts
Helper::debugLog('Update hash');
$session->updateGenesisHash($esId, sha1($data['content']));
} else {
// Last user. Kill session data

View File

@ -29,8 +29,7 @@ class UserController extends Controller{
$member = new Db_Member();
$member->loadBy('member_id', $args['member_id']);
if ($esId && $member->hasData()){
$memberData = $member->getData();
if ($memberData['es_id']===$esId && $memberData['status']==Db_Member::MEMBER_STATUS_ACTIVE){
if ($member->getEsId() === $esId && $member->getStatus() == Db_Member::MEMBER_STATUS_ACTIVE){
$member->deactivate(array($args['member_id']));
$op = new Db_Op();
$op->removeMember($esId, $args['member_id']);
@ -40,19 +39,24 @@ class UserController extends Controller{
}
public static function rename($args){
self::preDispatchGuest();
$memberId = Helper::getArrayValueByKey($args, 'member_id');
$name = Helper::getArrayValueByKey($_POST, 'name');
$member = new Db_Member();
$member->load($memberId);
$memberData = $member->getData();
if (count($memberData) && $memberData['status']==Db_Member::MEMBER_STATUS_ACTIVE
&& preg_match('/.* \(guest\)$/', $memberData['uid'])
if ($member->getEsId()
&& $member->getStatus() == Db_Member::MEMBER_STATUS_ACTIVE
&& $member->getIsGuest()
){
if (!preg_match('/.* \(guest\)$/', $name)){
$name .= ' (guest)';
$guestMark = Db_Member::getGuestPostfix();
if (substr($name, -strlen($guestMark)) !== $guestMark){
$name = $name . ' ' . $guestMark;
}
$op = new Db_Op();
$op->changeNick($memberData['es_id'], $memberId, $name);
$op->changeNick($member->getEsId(), $memberId, $name);
}
\OCP\JSON::success();
}

View File

@ -4,7 +4,7 @@
* ownCloud - Documents App
*
* @author Frank Karlitschek
* @copyright 2011 Frank Karlitschek karlitschek@kde.org
* @copyright 2013-2014 Frank Karlitschek karlitschek@kde.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@ -26,14 +26,12 @@ OCP\App::register(array('order' => 70, 'id' => 'documents', 'name' => 'Documents
\OCP\App::registerAdmin('documents', 'admin');
OCP\App::registerPersonal('documents', 'personal');
$l10n = \OCP\Util::getL10N('documents');
OCP\App::addNavigationEntry(array(
'id' => 'documents_index',
'order' => 2,
'href' => OCP\Util::linkTo('documents', 'index.php'),
'icon' => OCP\Util::imagePath('documents', 'documents.svg'),
'name' => $l10n->t('Documents'))
'name' => OCA\Documents\Config::getL10n()->t('Documents'))
);
OC::$CLASSPATH['OCA\Documents\Controller'] = 'documents/ajax/controller.php';

View File

@ -91,6 +91,21 @@
<unsigned>true</unsigned>
<length>4</length>
</field>
<field>
<name>is_guest</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<unsigned>true</unsigned>
<length>1</length>
</field>
<field>
<name>token</name>
<type>text</type>
<default></default>
<notnull>false</notnull>
<length>32</length>
</field>
<field>
<name>status</name>
<type>integer</type>

View File

@ -5,7 +5,7 @@
<description>An ownCloud app to work with office documents</description>
<licence>AGPL</licence>
<author>Frank Karlitschek</author>
<require>5.0.19</require>
<require>6.0</require>
<shipped>true</shipped>
<default_enable/>
<public>

View File

@ -28,4 +28,8 @@ if (version_compare($installedVersion, '0.7', '<=')) {
));
}
}
if (version_compare($installedVersion, '0.8', '<')) {
$query = \OC_DB::prepare('UPDATE `*PREFIX*documents_member` SET `is_guest`=1 WHERE `uid` LIKE \'%(guest)\' ');
$query->execute(array());
}

View File

@ -1 +1 @@
0.7.2
0.8.1

View File

@ -4,7 +4,7 @@
* ownCloud - Documents App
*
* @author Frank Karlitschek
* @copyright 2011 Frank Karlitschek karlitschek@kde.org
* @copyright 2013-2014 Frank Karlitschek karlitschek@kde.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE

View File

@ -714,9 +714,9 @@ var Files = Files || {
if ( $('#isPublic').length ) {
urlSpec.t = $('#dirToken').val();
previewURL = OC.Router.generate('core_ajax_public_preview', urlSpec);
previewURL = OC.generateUrl('core_ajax_public_preview/{url_spec}', {url_spec : urlSpec});
} else {
previewURL = OC.Router.generate('core_ajax_preview', urlSpec);
previewURL = OC.generateUrl('core_ajax_preview/{url_spec}', {url_spec : urlSpec});
}
previewURL = previewURL.replace('(', '%28');
previewURL = previewURL.replace(')', '%29');

View File

@ -15,6 +15,10 @@ namespace OCA\Documents;
class Config {
const APP_NAME = 'documents';
public static function getL10n(){
return \OCP\Util::getL10N(self::APP_NAME);
}
public static function getConverter(){
return self::getAppValue('converter', 'local');
}

View File

@ -206,4 +206,15 @@ abstract class Db {
return $result;
}
protected function __call($name, $arguments){
if (substr($name, 0, 3) === 'get'){
$requestedProperty = substr($name, 3);
$property = strtolower(preg_replace('/(.)([A-Z])/', "$1_$2", $requestedProperty));
if (isset($this->data[$property])){
return $this->data[$property];
}
}
return null;
}
}

View File

@ -15,7 +15,7 @@ namespace OCA\Documents;
class Db_Member extends Db{
const DB_TABLE = '`*PREFIX*documents_member`';
const ACTIVITY_THRESHOLD = 90; // 1.5 Minutes
const MEMBER_STATUS_ACTIVE = 1;
@ -23,11 +23,16 @@ class Db_Member extends Db{
protected $tableName = '`*PREFIX*documents_member`';
protected $insertStatement = 'INSERT INTO `*PREFIX*documents_member` (`es_id`, `uid`, `color`, `last_activity`)
VALUES (?, ?, ?, ?)';
protected $insertStatement = 'INSERT INTO `*PREFIX*documents_member` (`es_id`, `uid`, `color`, `last_activity`, `is_guest`, `token`)
VALUES (?, ?, ?, ?, ?, ?)';
protected $loadStatement = 'SELECT * FROM `*PREFIX*documents_member` WHERE `member_id`= ?';
public static function getGuestPostfix(){
return '(' . Config::getL10n()->t('guest') . ')';
}
public function updateActivity($memberId){
return $this->execute(
'UPDATE ' . $this->tableName . ' SET `last_activity`=?, `status`=? WHERE `member_id`=?',

View File

@ -35,13 +35,11 @@ class Db_Session extends \OCA\Documents\Db {
* @return array
* @throws \Exception
*/
public static function start($uid, File $file){
list($ownerView, $path) = $file->getOwnerViewAndPath();
public static function start($uid, $file){
// Create a directory to store genesis
$genesis = new Genesis($file);
$genesis = new Genesis($ownerView, $path, $file->getOwner());
list($ownerView, $path) = $file->getOwnerViewAndPath();
$oldSession = new Db_Session();
$oldSession->loadBy('file_id', $file->getFileId());
@ -59,55 +57,37 @@ class Db_Session extends \OCA\Documents\Db {
}
}
$session = $oldSession
$sessionData = $oldSession
->loadBy('file_id', $file->getFileId())
->getData()
;
$session['title'] = basename($path);
$memberColor = Helper::getMemberColor($uid);
$member = new Db_Member(array(
$session['es_id'],
$sessionData['es_id'],
$uid,
$memberColor,
time()
time(),
intval($file->isPublicShare()),
$file->getToken()
));
if ($member->insert()){
// Do we have OC_Avatar in out disposal?
if (!class_exists('\OC_Avatar') || \OC_Config::getValue('enable_avatars', true) !== true){
//$x['avatar_url'] = \OCP\Util::linkToRoute('documents_user_avatar');
$imageUrl = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==';
} else {
// https://github.com/owncloud/documents/issues/51
// Temporary stub
$imageUrl = $uid;
/*
$avatar = new \OC_Avatar($uid);
$image = $avatar->get(64);
// User has an avatar
if ($image instanceof \OC_Image) {
$imageUrl = \OC_Helper::linkToRoute(
'core_avatar_get',
array( 'user' => $uid, 'size' => 64)
) . '?requesttoken=' . \OC::$session->get('requesttoken');
} else {
//shortcircuit if it's not an image
$imageUrl = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==';
}
*/
}
$displayName = $file->isPublicShare() ? $uid . ' ' . Db_Member::getGuestPostfix() : \OCP\User::getDisplayName($uid);
$session['member_id'] = (string) $member->getLastInsertId();
$sessionData['member_id'] = (string) $member->getLastInsertId();
$op = new Db_Op();
$op->addMember(
$session['es_id'],
$session['member_id'],
\OCP\User::getDisplayName($uid),
$sessionData['es_id'],
$sessionData['member_id'],
$displayName,
$memberColor,
$imageUrl
);
@ -115,9 +95,10 @@ class Db_Session extends \OCA\Documents\Db {
throw new \Exception('Failed to add member into database');
}
$session['permissions'] = $ownerView->getFilePermissions($path);
$sessionData['title'] = basename($path);
$sessionData['permissions'] = $ownerView->getFilePermissions($path);
return $session;
return $sessionData;
}
public static function cleanUp($esId){
@ -196,14 +177,8 @@ class Db_Session extends \OCA\Documents\Db {
protected function getUniqueSessionId(){
$testSession = new Db_Session();
do{
// this prevents branching for stable5 for now:
// OC_Util::generate_random_bytes was camelCased
if (method_exists('\OC_Util', 'generate_random_bytes')){
$id = \OC_Util::generate_random_bytes(30);
} else {
$id = \OC_Util::generateRandomBytes(30);
}
}while ($testSession->load($id)->hasData());
$id = \OC_Util::generateRandomBytes(30);
} while ($testSession->load($id)->hasData());
return $id;
}

View File

@ -28,6 +28,7 @@ class File {
protected $owner;
protected $path;
protected $sharing;
protected $token ='';
protected $passwordProtected = false;
@ -47,28 +48,18 @@ class File {
}
}
public static function getByShareToken($token){
$linkItem = \OCP\Share::getShareByToken($token, false);
if (is_array($linkItem) && isset($linkItem['uid_owner'])) {
// seems to be a valid share
$rootLinkItem = \OCP\Share::resolveReShare($linkItem);
$fileOwner = $rootLinkItem['uid_owner'];
} else {
throw new \Exception('This file was probably unshared');
}
if (!isset($rootLinkItem['path']) && isset($rootLinkItem['file_target'])){
$rootLinkItem['path'] = $rootLinkItem['file_target'];
}
$file = new File($rootLinkItem['file_source'], array($rootLinkItem));
if (isset($rootLinkItem['uid_owner'])){
\OC_Util::tearDownFS();
\OC_Util::setupFS($rootLinkItem['uid_owner']);
$file->setOwner($rootLinkItem['uid_owner']);
$file->setPath(\OC\Files\Filesystem::getPath($linkItem['file_source']));
}
$file->setToken($token);
if (isset($linkItem['share_with']) && !empty($linkItem['share_with'])){
$file->setPasswordProtected(true);
@ -77,6 +68,10 @@ class File {
return $file;
}
public function getToken($token){
return $this->token;
}
public function getFileId(){
return $this->fileId;
}
@ -89,16 +84,12 @@ class File {
$this->path = $path;
}
public function setToken($token){
$this->token = $token;
}
public function isPublicShare(){
foreach ($this->sharing as $share){
if (
$share['share_type'] == \OCP\Share::SHARE_TYPE_LINK
|| $share['share_type'] == \OCP\Share::SHARE_TYPE_EMAIL
){
return true;
}
}
return false;
return !empty($this->token);
}
public function isPasswordProtected(){
@ -158,28 +149,34 @@ class File {
* @throws \Exception
*/
public function getOwnerViewAndPath(){
if (!$this->owner || !$this->path){
if ($this->isPublicShare()){
list($owner, $path) = $this->getSharedFileOwnerAndPath();
if ($this->isPublicShare()){
$rootLinkItem = \OCP\Share::resolveReShare($this->sharing[0]);
if (isset($rootLinkItem['uid_owner'])){
$owner = $rootLinkItem['uid_owner'];
} else {
$owner = \OCP\User::getUser();
$path = Storage::resolvePath($this->fileId);
if (!$path){
throw new \Exception($this->fileId . ' can not be resolved');
}
throw new \Exception($this->fileId . ' is a broken share');
}
$this->path = $path;
$this->owner = $owner;
$view = new View('/' . $owner . '/files');
$path = $rootLinkItem['file_target'];
} else {
$owner = \OCP\User::getUser();
$view = new View('/' . $this->owner);
$path = $view->getPath($this->fileId);
}
if (!$path){
throw new \Exception($this->fileId . ' can not be resolved');
}
$this->path = $path;
$this->owner = $owner;
$view = new View('/' . $this->owner . '/files');
if (!$view->file_exists($this->path)){
throw new \Exception($this->path . ' doesn\'t exist');
}
return array($view, $this->path);
}
public function getOwner(){
if (!$this->owner){
@ -188,28 +185,6 @@ class File {
return $this->owner;
}
/**
* public links only
* @return array
*/
protected function getSharedFileOwnerAndPath(){
foreach ($this->sharing as $share){
$rootLinkItem = \OCP\Share::resolveReShare($share);
if (isset($rootLinkItem['uid_owner'])){
$owner = $rootLinkItem['uid_owner'];
} else {
$owner = false;
}
\OC_Util::tearDownFS();
\OC_Util::setupFS($owner);
return array(
$owner,
\OC\Files\Filesystem::getPath($rootLinkItem['file_source'])
);
}
return $result;
}
protected function getPassword(){
return $this->sharing[0]['share_with'];

View File

@ -15,8 +15,8 @@ namespace OCA\Documents;
class Filter_Office {
const NATIVE_MIMETYPE = 'application/vnd.oasis.opendocument.text';
private static $readSpec;
private static $writeSpec;
private $readSpec;
private $writeSpec;
/* sample mimespec
array (

View File

@ -35,11 +35,12 @@ class Genesis {
/**
* Create new genesis document
* @param OCA\Documents\View $view Filesystem view with root '/user/files'
* @param string $path relative path
* @param string $owner file owner
* @param OCA\Documents\File $file
* */
public function __construct(\OCA\Documents\View $view, $path, $owner){
public function __construct(\OCA\Documents\File $file){
list($view, $path) = $file->getOwnerViewAndPath();
$owner = $file->getOwner();
$this->view = new View('/' . $owner);
if (!$this->view->file_exists(self::DOCUMENTS_DIRNAME)){

View File

@ -4,7 +4,7 @@
* ownCloud - Documents App
*
* @author Frank Karlitschek
* @copyright 2012 Frank Karlitschek frank@owncloud.org
* @copyright 2013-2014 Frank Karlitschek frank@owncloud.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@ -71,25 +71,22 @@ class Storage {
return;
}
$sessionObj = new Db_Session();
$session = $sessionObj
->loadBy('file_id', $fileId)
->getData()
;
$session = new Db_Session();
$session->loadBy('file_id', $fileId);
if (!is_array($session) || !isset($session['es_id'])){
if (!$session->getEsId()){
return;
}
$member = new Db_Member();
$sessionMembers = $member->getCollectionBy('es_id', $session['es_id']);
$sessionMembers = $member->getCollectionBy('es_id', $session->getEsId());
foreach ($sessionMembers as $memberData){
if (intval($memberData['status'])===Db_Member::MEMBER_STATUS_ACTIVE){
return;
}
}
Db_Session::cleanUp($session['es_id']);
Db_Session::cleanUp($session->getEsId());
}
protected static function searchDocuments(){

View File

@ -40,9 +40,14 @@ if (isset($_GET['t'])) {
\OCP\Util::addScript('documents', 'documents');
if ($file->getFileId()){
$session = new Db_Session();
$sessionData = $session->loadBy('file_id', $file->getFileId())->getData();
$member = new Db_Member();
$members = $member->getCollectionBy('es_id', $sessionData['es_id']);
$session->loadBy('file_id', $file->getFileId());
if ($session->getEsId()){
$member = new Db_Member();
$members = $member->getCollectionBy('es_id', $session->getEsId());
} else {
$members = 0;
}
$tmpl->assign('total', count($members)+1);
} else {
$tmpl->assign('total', 1);