Compare commits
176 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9aae21db79 | ||
|
|
536117da2a | ||
|
|
29054c27c9 | ||
|
|
207bf4bffe | ||
|
|
4e11814a0c | ||
|
|
32667f8c38 | ||
|
|
1c06bec262 | ||
|
|
a82965edf2 | ||
|
|
76f12567be | ||
|
|
d7cbf45d15 | ||
|
|
05a2f31352 | ||
|
|
811d649262 | ||
|
|
6e32fc1db7 | ||
|
|
e718a728c4 | ||
|
|
a065ae5db2 | ||
|
|
623db8549e | ||
|
|
16ef7c62dc | ||
|
|
0978ebd195 | ||
|
|
1ddfefed3f | ||
|
|
16b62c697f | ||
|
|
f70b1c1b0d | ||
|
|
b400c29944 | ||
|
|
86d8b831f2 | ||
|
|
5fbb8b374d | ||
|
|
0a3e87c890 | ||
|
|
2220802cdd | ||
|
|
0ff7aa4436 | ||
|
|
5e817584db | ||
|
|
fbcb4b2673 | ||
|
|
edae196f34 | ||
|
|
11dcc29c0c | ||
|
|
d068325bdb | ||
|
|
6dc66e14fb | ||
|
|
30d5c70180 | ||
|
|
e9c3caeb9b | ||
|
|
9a0344f1d5 | ||
|
|
33b27362ff | ||
|
|
15c50017cc | ||
|
|
c43e33cdf5 | ||
|
|
ef1481c7bb | ||
|
|
892d85556b | ||
|
|
5fb891e20a | ||
|
|
c241985f04 | ||
|
|
9a4fe09979 | ||
|
|
e26cdc4cdd | ||
|
|
317b00988a | ||
|
|
9159d55639 | ||
|
|
06ab314c15 | ||
|
|
f26a4e0b80 | ||
|
|
2c3d66c776 | ||
|
|
aef66e06b3 | ||
|
|
67a84ad487 | ||
|
|
440148aa1f | ||
|
|
b35148bbb6 | ||
|
|
5ef8762886 | ||
|
|
b52666567a | ||
|
|
1e580bf04b | ||
|
|
2a5599b3e0 | ||
|
|
f82799cf7d | ||
|
|
e6d286b449 | ||
|
|
dc3a7e09af | ||
|
|
5add001373 | ||
|
|
5317e7071e | ||
|
|
f5592cc88e | ||
|
|
09f11c2679 | ||
|
|
db48f5302a | ||
|
|
4cd4bbd489 | ||
|
|
7b42c20180 | ||
|
|
835df6c177 | ||
|
|
5268aadb62 | ||
|
|
d7dccfb648 | ||
|
|
cc204a608a | ||
|
|
22c8194cc8 | ||
|
|
8231f657d9 | ||
|
|
4f9f5a41b1 | ||
|
|
5944ee6ebe | ||
|
|
e1b6574ce7 | ||
|
|
c16860e648 | ||
|
|
d4a492d321 | ||
|
|
a004266b7c | ||
|
|
da96d1adb0 | ||
|
|
ed39e47c9d | ||
|
|
b9213cf451 | ||
|
|
f308b0e321 | ||
|
|
eeebf21fce | ||
|
|
75d944f96a | ||
|
|
9bfdfdf071 | ||
|
|
2bb22d3aab | ||
|
|
4742d0eb94 | ||
|
|
c901709d53 | ||
|
|
84bc4c175a | ||
|
|
4d50a21eb4 | ||
|
|
37971133f1 | ||
|
|
c962f9db47 | ||
|
|
6333036a1a | ||
|
|
73758c1f78 | ||
|
|
7e9e94d8d7 | ||
|
|
07d0245336 | ||
|
|
0bbac66ec5 | ||
|
|
4411de0dbf | ||
|
|
871bbbba8a | ||
|
|
4384cf70da | ||
|
|
e0cf61dfc8 | ||
|
|
2387fbd9dd | ||
|
|
0b6b5e807c | ||
|
|
b2b78228d6 | ||
|
|
2e5829445f | ||
|
|
e63a12a481 | ||
|
|
56302ff9cf | ||
|
|
707de3e644 | ||
|
|
19a65f6c3f | ||
|
|
011ab3a11c | ||
|
|
ad62d89f2b | ||
|
|
9b84c50f15 | ||
|
|
01ffa519d5 | ||
|
|
fe73b5919d | ||
|
|
5ad7eb080e | ||
|
|
2ce8329503 | ||
|
|
83e5383912 | ||
|
|
660d204cbf | ||
|
|
d091db4bc7 | ||
|
|
d61e820285 | ||
|
|
85613cc66c | ||
|
|
0fb9cc3c25 | ||
|
|
76e5ffaa92 | ||
|
|
9a26b1e0a6 | ||
|
|
bfd69dc8e0 | ||
|
|
0d075df15e | ||
|
|
c82f43ee55 | ||
|
|
0eaf141528 | ||
|
|
ee0dab1b13 | ||
|
|
98ee292c93 | ||
|
|
4ff5658475 | ||
|
|
7de540b8ee | ||
|
|
9a41453254 | ||
|
|
707b319157 | ||
|
|
f7911412e0 | ||
|
|
1cb3872df0 | ||
|
|
432fb55d91 | ||
|
|
98c5d10bb5 | ||
|
|
84a2be1aad | ||
|
|
9e383db75b | ||
|
|
c12b30f7a2 | ||
|
|
5bf111e75f | ||
|
|
f42d98edab | ||
|
|
d392aa81c7 | ||
|
|
532e5463db | ||
|
|
cfea3ce2d7 | ||
|
|
2c76ee1c8b | ||
|
|
9a2c1cbcc3 | ||
|
|
e6616ed758 | ||
|
|
b51b41468d | ||
|
|
6f86802a48 | ||
|
|
0c6c175d62 | ||
|
|
885b81ba23 | ||
|
|
fc86815a2c | ||
|
|
6ca2abc108 | ||
|
|
0fe2f81a0c | ||
|
|
2cd52e52c8 | ||
|
|
d06fec658c | ||
|
|
049329588f | ||
|
|
09d3b9ef26 | ||
|
|
92ce2bf89b | ||
|
|
ca93f6e1de | ||
|
|
d166471a46 | ||
|
|
896c56996e | ||
|
|
6017ca5ddd | ||
|
|
eedc1e76db | ||
|
|
510cbc4ff9 | ||
|
|
9b9497bedf | ||
|
|
8846edd919 | ||
|
|
253f7ec932 | ||
|
|
8bafcd1414 | ||
|
|
40bb805b83 | ||
|
|
00030a6c24 | ||
|
|
2afece459a |
@@ -12,3 +12,10 @@ OCP\App::addNavigationEntry( array( "id" => "files_index",
|
||||
"name" => $l->t("Files") ));
|
||||
|
||||
OC_Search::registerProvider('OC_Search_Provider_File');
|
||||
|
||||
// cache hooks must be connected before all other apps.
|
||||
// since 'files' is always loaded first the hooks need to be connected here
|
||||
\OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Updater', 'writeHook');
|
||||
\OC_Hook::connect('OC_Filesystem', 'post_touch', '\OC\Files\Cache\Updater', 'touchHook');
|
||||
\OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Updater', 'deleteHook');
|
||||
\OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Updater', 'renameHook');
|
||||
@@ -84,7 +84,7 @@ table td.filename input.filename { width:100%; cursor:text; }
|
||||
table td.filename a, table td.login, table td.logout, table td.download, table td.upload, table td.create, table td.delete { padding:.2em .5em .5em 0; }
|
||||
table td.filename .nametext, .uploadtext, .modified { float:left; padding:.3em 0; }
|
||||
/* TODO fix usability bug (accidental file/folder selection) */
|
||||
table td.filename .nametext { overflow:hidden; text-overflow:ellipsis; }
|
||||
table td.filename .nametext { overflow:hidden; text-overflow:ellipsis; max-width:800px; }
|
||||
table td.filename .uploadtext { font-weight:normal; margin-left:.5em; }
|
||||
table td.filename form { font-size:.85em; margin-left:3em; margin-right:3em; }
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ var FileActions = {
|
||||
addAction(name, action);
|
||||
}
|
||||
});
|
||||
if(actions.Share){
|
||||
if(actions.Share && !($('#dir').val() === '/' && file === 'Shared')){
|
||||
addAction('Share', actions.Share);
|
||||
}
|
||||
|
||||
|
||||
@@ -226,14 +226,14 @@ $(document).ready(function() {
|
||||
OC.Notification.show(t('files','Your download is being prepared. This might take some time if the files are big.'));
|
||||
// use special download URL if provided, e.g. for public shared files
|
||||
if ( (downloadURL = document.getElementById("downloadURL")) ) {
|
||||
window.location=downloadURL.value+"&download&files="+files;
|
||||
window.location=downloadURL.value+"&download&files="+encodeURIComponent(fileslist);
|
||||
} else {
|
||||
window.location=OC.filePath('files', 'ajax', 'download.php') + '?'+ $.param({ dir: dir, files: fileslist });
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
$('.delete').click(function(event) {
|
||||
$('.delete-selected').click(function(event) {
|
||||
var files=getSelectedFiles('name');
|
||||
event.preventDefault();
|
||||
FileList.do_delete(files);
|
||||
@@ -407,7 +407,9 @@ $(document).ready(function() {
|
||||
$('tr').filterAttr('data-file',file.name).data('mime',file.mime).data('id',file.id);
|
||||
var size = $('tr').filterAttr('data-file',file.name).find('td.filesize').text();
|
||||
if(size==t('files','Pending')){
|
||||
$('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size);
|
||||
var sizeElement = $('tr').filterAttr('data-file',file.name).find('td.filesize');
|
||||
sizeElement.text(simpleFileSize(file.size));
|
||||
sizeElement.attr('title',humanFileSize(file.size));
|
||||
}
|
||||
//TODO update file upload size limit
|
||||
FileList.loadingDone(file.name, file.id);
|
||||
@@ -438,7 +440,9 @@ $(document).ready(function() {
|
||||
$('tr').filterAttr('data-file',file.name).data('mime',file.mime).data('id',file.id);
|
||||
var size = $('tr').filterAttr('data-file',file.name).find('td.filesize').text();
|
||||
if(size==t('files','Pending')){
|
||||
$('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size);
|
||||
var sizeElement = $('tr').filterAttr('data-file',file.name).find('td.filesize');
|
||||
sizeElement.text(simpleFileSize(file.size));
|
||||
sizeElement.attr('title',humanFileSize(file.size));
|
||||
}
|
||||
//TODO update file upload size limit
|
||||
FileList.loadingDone(file.name, file.id);
|
||||
@@ -459,6 +463,10 @@ $(document).ready(function() {
|
||||
// TODO: show nice progress bar in file row
|
||||
},
|
||||
progressall: function(e, data) {
|
||||
//IE < 10 does not fire the necessary events for the progress bar.
|
||||
if($.browser.msie && parseInt($.browser.version) < 10) {
|
||||
return;
|
||||
}
|
||||
var progress = (data.loaded/data.total)*100;
|
||||
$('#uploadprogressbar').progressbar('value',progress);
|
||||
},
|
||||
@@ -477,6 +485,11 @@ $(document).ready(function() {
|
||||
if(data.dataType != 'iframe ') {
|
||||
$('#upload input.stop').hide();
|
||||
}
|
||||
//IE < 10 does not fire the necessary events for the progress bar.
|
||||
if($.browser.msie && parseInt($.browser.version) < 10) {
|
||||
return;
|
||||
}
|
||||
|
||||
$('#uploadprogressbar').progressbar('value',100);
|
||||
$('#uploadprogressbar').fadeOut();
|
||||
}
|
||||
@@ -637,12 +650,19 @@ $(document).ready(function() {
|
||||
localName=(localName.match(/:\/\/(.[^/]+)/)[1]).replace('www.','');
|
||||
}
|
||||
localName = getUniqueName(localName);
|
||||
$('#uploadprogressbar').progressbar({value:0});
|
||||
$('#uploadprogressbar').fadeIn();
|
||||
//IE < 10 does not fire the necessary events for the progress bar.
|
||||
if($.browser.msie && parseInt($.browser.version) < 10) {
|
||||
} else {
|
||||
$('#uploadprogressbar').progressbar({value:0});
|
||||
$('#uploadprogressbar').fadeIn();
|
||||
}
|
||||
|
||||
var eventSource=new OC.EventSource(OC.filePath('files','ajax','newfile.php'),{dir:$('#dir').val(),source:name,filename:localName});
|
||||
eventSource.listen('progress',function(progress){
|
||||
$('#uploadprogressbar').progressbar('value',progress);
|
||||
if($.browser.msie && parseInt($.browser.version) < 10) {
|
||||
} else {
|
||||
$('#uploadprogressbar').progressbar('value',progress);
|
||||
}
|
||||
});
|
||||
eventSource.listen('success',function(data){
|
||||
var mime=data.mime;
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
</div>
|
||||
<div id="file_action_panel"></div>
|
||||
<?php else:?>
|
||||
<div class="crumb last"><?php p($l->t('You don’t have write permissions here.'))?></div>
|
||||
<div class="actions"><input type="button" disabled value="<?php p($l->t('You don’t have write permissions here.'))?>"></div>
|
||||
<input type="hidden" name="dir" value="<?php p($_['dir']) ?>" id="dir">
|
||||
<?php endif;?>
|
||||
<input type="hidden" name="permissions" value="<?php p($_['permissions']); ?>" id="permissions">
|
||||
@@ -82,13 +82,13 @@
|
||||
<?php if ($_['permissions'] & OCP\PERMISSION_DELETE): ?>
|
||||
<!-- NOTE: Temporary fix to allow unsharing of files in root of Shared folder -->
|
||||
<?php if ($_['dir'] == '/Shared'): ?>
|
||||
<span class="selectedActions"><a href="" class="delete">
|
||||
<span class="selectedActions"><a href="" class="delete-selected">
|
||||
<?php p($l->t('Unshare'))?>
|
||||
<img class="svg" alt="<?php p($l->t('Unshare'))?>"
|
||||
src="<?php print_unescaped(OCP\image_path("core", "actions/delete.svg")); ?>" />
|
||||
</a></span>
|
||||
<?php else: ?>
|
||||
<span class="selectedActions"><a href="" class="delete">
|
||||
<span class="selectedActions"><a href="" class="delete-selected">
|
||||
<?php p($l->t('Delete'))?>
|
||||
<img class="svg" alt="<?php p($l->t('Delete'))?>"
|
||||
src="<?php print_unescaped(OCP\image_path("core", "actions/delete.svg")); ?>" />
|
||||
|
||||
@@ -32,6 +32,7 @@ $tmpl->assign('mounts', OC_Mount_Config::getSystemMountPoints());
|
||||
$tmpl->assign('backends', OC_Mount_Config::getBackends());
|
||||
$tmpl->assign('groups', OC_Group::getGroups());
|
||||
$tmpl->assign('users', OCP\User::getUsers());
|
||||
$tmpl->assign('userDisplayNames', OC_User::getDisplayNames());
|
||||
$tmpl->assign('dependencies', OC_Mount_Config::checkDependencies());
|
||||
$tmpl->assign('allowUserMounting', OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes'));
|
||||
return $tmpl->fetchPage();
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
<option value="<?php p($user); ?>"
|
||||
<?php if (isset($mount['applicable']['users']) && in_array($user, $mount['applicable']['users'])): ?>
|
||||
selected="selected"
|
||||
<?php endif; ?>><?php p($user); ?></option>
|
||||
<?php endif; ?>><?php p($_['userDisplayNames'][$user]); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
</select>
|
||||
|
||||
@@ -12,7 +12,7 @@ OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
|
||||
OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
|
||||
OCP\Util::addScript('files_sharing', 'share');
|
||||
\OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Shared_Updater', 'writeHook');
|
||||
\OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Shared_Updater', 'deleteHook');
|
||||
\OC_Hook::connect('OC_Filesystem', 'delete', '\OC\Files\Cache\Shared_Updater', 'deleteHook');
|
||||
\OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Shared_Updater', 'renameHook');
|
||||
\OC_Hook::connect('OCP\Share', 'post_shared', '\OC\Files\Cache\Shared_Updater', 'shareHook');
|
||||
\OC_Hook::connect('OCP\Share', 'pre_unshare', '\OC\Files\Cache\Shared_Updater', 'shareHook');
|
||||
@@ -38,10 +38,12 @@ class Shared_Updater {
|
||||
while (!empty($users)) {
|
||||
$reshareUsers = array();
|
||||
foreach ($users as $user) {
|
||||
$etag = \OC\Files\Filesystem::getETag('');
|
||||
\OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag);
|
||||
// Look for reshares
|
||||
$reshareUsers = array_merge($reshareUsers, \OCP\Share::getUsersItemShared('file', $info['fileid'], $user, true));
|
||||
if ( $user !== $uidOwner ) {
|
||||
$etag = \OC\Files\Filesystem::getETag('');
|
||||
\OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag);
|
||||
// Look for reshares
|
||||
$reshareUsers = array_merge($reshareUsers, \OCP\Share::getUsersItemShared('file', $info['fileid'], $user, true));
|
||||
}
|
||||
}
|
||||
$users = $reshareUsers;
|
||||
}
|
||||
@@ -66,8 +68,8 @@ class Shared_Updater {
|
||||
* @param array $params
|
||||
*/
|
||||
static public function renameHook($params) {
|
||||
self::correctFolders($params['oldpath']);
|
||||
self::correctFolders($params['newpath']);
|
||||
self::correctFolders(pathinfo($params['oldpath'], PATHINFO_DIRNAME));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,10 +90,12 @@ class Shared_Updater {
|
||||
while (!empty($users)) {
|
||||
$reshareUsers = array();
|
||||
foreach ($users as $user) {
|
||||
$etag = \OC\Files\Filesystem::getETag('');
|
||||
\OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag);
|
||||
// Look for reshares
|
||||
$reshareUsers = array_merge($reshareUsers, \OCP\Share::getUsersItemShared('file', $params['fileSource'], $user, true));
|
||||
if ($user !== $uidOwner) {
|
||||
$etag = \OC\Files\Filesystem::getETag('');
|
||||
\OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag);
|
||||
// Look for reshares
|
||||
$reshareUsers = array_merge($reshareUsers, \OCP\Share::getUsersItemShared('file', $params['fileSource'], $user, true));
|
||||
}
|
||||
}
|
||||
$users = $reshareUsers;
|
||||
}
|
||||
|
||||
@@ -113,7 +113,13 @@ if (isset($path)) {
|
||||
// Download the file
|
||||
if (isset($_GET['download'])) {
|
||||
if (isset($_GET['files'])) { // download selected files
|
||||
OC_Files::get($path, $_GET['files'], $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
$files = urldecode($_GET['files']);
|
||||
$files_list = json_decode($files);
|
||||
// in case we get only a single file
|
||||
if ($files_list === NULL ) {
|
||||
$files_list = array($files);
|
||||
}
|
||||
OC_Files::get($path, $files_list, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
} else {
|
||||
OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
}
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
OC::$CLASSPATH['OCA\Files_Trashbin\Hooks'] = 'files_trashbin/lib/hooks.php';
|
||||
OC::$CLASSPATH['OCA\Files_Trashbin\Trashbin'] = 'files_trashbin/lib/trash.php';
|
||||
|
||||
|
||||
//Listen to delete file signal
|
||||
OCP\Util::connectHook('OC_Filesystem', 'delete', "OCA\Files_Trashbin\Hooks", "remove_hook");
|
||||
//Listen to delete user signal
|
||||
OCP\Util::connectHook('OC_User', 'pre_deleteUser', "OCA\Files_Trashbin\Hooks", "deleteUser_hook");
|
||||
@@ -2,7 +2,20 @@
|
||||
<info>
|
||||
<id>files_trashbin</id>
|
||||
<name>Deleted files</name>
|
||||
<description>Keep a copy of deleted files so that they can be restored if needed</description>
|
||||
<description>
|
||||
ownCloud keeps a copy of your deleted files in case you need them again.
|
||||
To make sure that the user doesn't run out of memory the deleted files app
|
||||
manages the size of the deleted files for the user. By default deleted files
|
||||
stay in the trash bin for 180 days. ownCloud checks the age of the files
|
||||
every time a new files gets moved to the deleted files and remove all files
|
||||
older than 180 days. The user can adjust this value in the config.php by
|
||||
setting the "trashbin_retention_obligation" value.
|
||||
|
||||
Beside that the delted files app take care to never use more that 50% of
|
||||
your currently available free space. If your deleted files exceed this limit
|
||||
ownCloud deletes the oldest versions until it meets the memory usage limit
|
||||
again.
|
||||
</description>
|
||||
<licence>AGPL</licence>
|
||||
<author>Bjoern Schiessle</author>
|
||||
<shipped>true</shipped>
|
||||
|
||||
@@ -1,40 +1,10 @@
|
||||
<?php
|
||||
|
||||
$installedVersion=OCP\Config::getAppValue('files_trashbin', 'installed_version');
|
||||
// move versions to new directory
|
||||
|
||||
if (version_compare($installedVersion, '0.2', '<')) {
|
||||
$datadir = \OCP\Config::getSystemValue('datadirectory').'/';
|
||||
|
||||
$users = \OCP\User::getUsers();
|
||||
foreach ($users as $user) {
|
||||
|
||||
//create new folders
|
||||
@mkdir($datadir.$user.'/files_trashbin/files');
|
||||
@mkdir($datadir.$user.'/files_trashbin/versions');
|
||||
@mkdir($datadir.$user.'/files_trashbin/keyfiles');
|
||||
|
||||
// move files to the new folders
|
||||
if ($handle = opendir($datadir.$user.'/files_trashbin')) {
|
||||
while (false !== ($file = readdir($handle))) {
|
||||
if ($file != "." && $file != ".." && $file != 'files' && $file != 'versions' && $file != 'keyfiles') {
|
||||
rename($datadir.$user.'/files_trashbin/'.$file,
|
||||
$datadir.$user.'/files_trashbin/files/'.$file);
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
|
||||
// move versions to the new folder
|
||||
if ($handle = opendir($datadir.$user.'/versions_trashbin')) {
|
||||
while (false !== ($file = readdir($handle))) {
|
||||
rename($datadir.$user.'/versions_trashbin/'.$file,
|
||||
$datadir.$user.'/files_trashbin/versions/'.$file);
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
|
||||
@rmdir($datadir.$user.'/versions_trashbin');
|
||||
|
||||
}
|
||||
if (version_compare($installedVersion, '0.4', '<')) {
|
||||
//size of the trash bin could be incorrect, remove it for all users to
|
||||
//enforce a recalculation during next usage.
|
||||
$query = \OC_DB::prepare('DELETE FROM `*PREFIX*files_trashsize`');
|
||||
$result = $query->execute();
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
0.3
|
||||
0.4
|
||||
|
||||
@@ -43,7 +43,7 @@ if ($dir) {
|
||||
|
||||
} else {
|
||||
$dirlisting = false;
|
||||
$query = \OC_DB::prepare('SELECT `id`,`location`,`timestamp`,`type`,`mime` FROM `*PREFIX*files_trash` WHERE user = ?');
|
||||
$query = \OC_DB::prepare('SELECT `id`,`location`,`timestamp`,`type`,`mime` FROM `*PREFIX*files_trash` WHERE `user` = ?');
|
||||
$result = $query->execute(array($user))->fetchAll();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,4 +42,18 @@ class Hooks {
|
||||
Trashbin::move2trash($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief clean up user specific settings if user gets deleted
|
||||
* @param array with uid
|
||||
*
|
||||
* This function is connected to the pre_deleteUser signal of OC_Users
|
||||
* to remove the used space for the trash bin stored in the database
|
||||
*/
|
||||
public static function deleteUser_hook($params) {
|
||||
if( \OCP\App::isEnabled('files_trashbin') ) {
|
||||
$uid = $params['uid'];
|
||||
Trashbin::deleteUser($uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,10 +61,12 @@ class Trashbin {
|
||||
if ( $trashbinSize === false || $trashbinSize < 0 ) {
|
||||
$trashbinSize = self::calculateSize(new \OC\Files\View('/'. $user.'/files_trashbin'));
|
||||
}
|
||||
$trashbinSize += self::copy_recursive($file_path, 'files_trashbin/files/'.$deleted.'.d'.$timestamp, $view);
|
||||
|
||||
|
||||
$sizeOfAddedFiles = self::copy_recursive($file_path, 'files_trashbin/files/'.$deleted.'.d'.$timestamp, $view);
|
||||
|
||||
if ( $view->file_exists('files_trashbin/files/'.$deleted.'.d'.$timestamp) ) {
|
||||
$query = \OC_DB::prepare("INSERT INTO *PREFIX*files_trash (id,timestamp,location,type,mime,user) VALUES (?,?,?,?,?,?)");
|
||||
$trashbinSize += $sizeOfAddedFiles;
|
||||
$query = \OC_DB::prepare("INSERT INTO `*PREFIX*files_trash` (`id`,`timestamp`,`location`,`type`,`mime`,`user`) VALUES (?,?,?,?,?,?)");
|
||||
$result = $query->execute(array($deleted, $timestamp, $location, $type, $mime, $user));
|
||||
if ( !$result ) { // if file couldn't be added to the database than also don't store it in the trash bin.
|
||||
$view->deleteAll('files_trashbin/files/'.$deleted.'.d'.$timestamp);
|
||||
@@ -102,27 +104,8 @@ class Trashbin {
|
||||
} else {
|
||||
\OC_Log::write('files_trashbin', 'Couldn\'t move '.$file_path.' to the trash bin', \OC_log::ERROR);
|
||||
}
|
||||
|
||||
// get available disk space for user
|
||||
$quota = \OC_Preferences::getValue($user, 'files', 'quota');
|
||||
if ( $quota === null || $quota === 'default') {
|
||||
$quota = \OC_Appconfig::getValue('files', 'default_quota');
|
||||
}
|
||||
if ( $quota === null || $quota === 'none' ) {
|
||||
$quota = \OC\Files\Filesystem::free_space('/') / count(\OCP\User::getUsers());
|
||||
} else {
|
||||
$quota = \OCP\Util::computerFileSize($quota);
|
||||
}
|
||||
|
||||
// calculate available space for trash bin
|
||||
$rootInfo = $view->getFileInfo('/files');
|
||||
$free = $quota-$rootInfo['size']; // remaining free space for user
|
||||
if ( $free > 0 ) {
|
||||
$availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - $trashbinSize; // how much space can be used for versions
|
||||
} else {
|
||||
$availableSpace = $free-$trashbinSize;
|
||||
}
|
||||
$trashbinSize -= self::expire($availableSpace);
|
||||
|
||||
$trashbinSize -= self::expire($trashbinSize);
|
||||
|
||||
self::setTrashbinSize($user, $trashbinSize);
|
||||
|
||||
@@ -144,8 +127,8 @@ class Trashbin {
|
||||
$trashbinSize = self::calculateSize(new \OC\Files\View('/'. $user.'/files_trashbin'));
|
||||
}
|
||||
if ( $timestamp ) {
|
||||
$query = \OC_DB::prepare('SELECT location,type FROM *PREFIX*files_trash'
|
||||
.' WHERE user=? AND id=? AND timestamp=?');
|
||||
$query = \OC_DB::prepare('SELECT `location`,`type` FROM `*PREFIX*files_trash`'
|
||||
.' WHERE `user`=? AND `id`=? AND `timestamp`=?');
|
||||
$result = $query->execute(array($user,$filename,$timestamp))->fetchAll();
|
||||
if ( count($result) != 1 ) {
|
||||
\OC_Log::write('files_trashbin', 'trash bin database inconsistent!', \OC_Log::ERROR);
|
||||
@@ -228,7 +211,7 @@ class Trashbin {
|
||||
}
|
||||
|
||||
if ( $timestamp ) {
|
||||
$query = \OC_DB::prepare('DELETE FROM *PREFIX*files_trash WHERE user=? AND id=? AND timestamp=?');
|
||||
$query = \OC_DB::prepare('DELETE FROM `*PREFIX*files_trash` WHERE `user`=? AND `id`=? AND `timestamp`=?');
|
||||
$query->execute(array($user,$filename,$timestamp));
|
||||
}
|
||||
|
||||
@@ -259,7 +242,7 @@ class Trashbin {
|
||||
}
|
||||
|
||||
if ( $timestamp ) {
|
||||
$query = \OC_DB::prepare('DELETE FROM *PREFIX*files_trash WHERE user=? AND id=? AND timestamp=?');
|
||||
$query = \OC_DB::prepare('DELETE FROM `*PREFIX*files_trash` WHERE `user`=? AND `id`=? AND `timestamp`=?');
|
||||
$query->execute(array($user,$filename,$timestamp));
|
||||
$file = $filename.'.d'.$timestamp;
|
||||
} else {
|
||||
@@ -335,16 +318,71 @@ class Trashbin {
|
||||
}
|
||||
|
||||
/**
|
||||
* clean up the trash bin
|
||||
* @param max. available disk space for trashbin
|
||||
* @brief deletes used space for trash bin in db if user was deleted
|
||||
*
|
||||
* @param type $uid id of deleted user
|
||||
* @return result of db delete operation
|
||||
*/
|
||||
private static function expire($availableSpace) {
|
||||
public static function deleteUser($uid) {
|
||||
$query = \OC_DB::prepare('DELETE FROM `*PREFIX*files_trash` WHERE `user`=?');
|
||||
$result = $query->execute(array($uid));
|
||||
if ($result) {
|
||||
$query = \OC_DB::prepare('DELETE FROM `*PREFIX*files_trashsize` WHERE `user`=?');
|
||||
return $query->execute(array($uid));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate remaining free space for trash bin
|
||||
*
|
||||
* @param $trashbinSize current size of the trash bin
|
||||
* @return available free space for trash bin
|
||||
*/
|
||||
private static function calculateFreeSpace($trashbinSize) {
|
||||
$softQuota = true;
|
||||
$user = \OCP\User::getUser();
|
||||
$quota = \OC_Preferences::getValue($user, 'files', 'quota');
|
||||
$view = new \OC\Files\View('/'.$user);
|
||||
if ( $quota === null || $quota === 'default') {
|
||||
$quota = \OC_Appconfig::getValue('files', 'default_quota');
|
||||
}
|
||||
if ( $quota === null || $quota === 'none' ) {
|
||||
$quota = \OC\Files\Filesystem::free_space('/');
|
||||
$softQuota = false;
|
||||
} else {
|
||||
$quota = \OCP\Util::computerFileSize($quota);
|
||||
}
|
||||
|
||||
// calculate available space for trash bin
|
||||
// subtract size of files and current trash bin size from quota
|
||||
if ($softQuota) {
|
||||
$rootInfo = $view->getFileInfo('/files/');
|
||||
$free = $quota-$rootInfo['size']; // remaining free space for user
|
||||
if ( $free > 0 ) {
|
||||
$availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - $trashbinSize; // how much space can be used for versions
|
||||
} else {
|
||||
$availableSpace = $free-$trashbinSize;
|
||||
}
|
||||
} else {
|
||||
$availableSpace = $quota;
|
||||
}
|
||||
|
||||
return $availableSpace;
|
||||
}
|
||||
|
||||
/**
|
||||
* clean up the trash bin
|
||||
* @param current size of the trash bin
|
||||
*/
|
||||
private static function expire($trashbinSize) {
|
||||
|
||||
$user = \OCP\User::getUser();
|
||||
$view = new \OC\Files\View('/'.$user);
|
||||
$availableSpace = self::calculateFreeSpace($trashbinSize);
|
||||
$size = 0;
|
||||
|
||||
$query = \OC_DB::prepare('SELECT location,type,id,timestamp FROM *PREFIX*files_trash WHERE user=?');
|
||||
$query = \OC_DB::prepare('SELECT `location`,`type`,`id`,`timestamp` FROM `*PREFIX*files_trash` WHERE `user`=?');
|
||||
$result = $query->execute(array($user))->fetchAll();
|
||||
|
||||
$retention_obligation = \OC_Config::getValue('trashbin_retention_obligation',
|
||||
@@ -357,18 +395,20 @@ class Trashbin {
|
||||
$filename = $r['id'];
|
||||
if ( $r['timestamp'] < $limit ) {
|
||||
$size += self::delete($filename, $timestamp);
|
||||
\OC_Log::write('files_trashbin', 'remove "'.$filename.'" fom trash bin because it is older than '.$retention_obligation, \OC_log::INFO);
|
||||
}
|
||||
}
|
||||
$availableSpace = $availableSpace + $size;
|
||||
// if size limit for trash bin reached, delete oldest files in trash bin
|
||||
if ($availableSpace < 0) {
|
||||
$query = \OC_DB::prepare('SELECT location,type,id,timestamp FROM *PREFIX*files_trash'
|
||||
.' WHERE user=? ORDER BY timestamp ASC');
|
||||
$query = \OC_DB::prepare('SELECT `location`,`type`,`id`,`timestamp` FROM `*PREFIX*files_trash`'
|
||||
.' WHERE `user`=? ORDER BY `timestamp` ASC');
|
||||
$result = $query->execute(array($user))->fetchAll();
|
||||
$length = count($result);
|
||||
$i = 0;
|
||||
while ( $i < $length && $availableSpace < 0 ) {
|
||||
$tmp = self::delete($result[$i]['id'], $result[$i]['timestamp']);
|
||||
\OC_Log::write('files_trashbin', 'remove "'.$result[$i]['id'].'" ('.$tmp.'B) to meet the limit of trash bin size (50% of available quota)', \OC_log::INFO);
|
||||
$availableSpace += $tmp;
|
||||
$size += $tmp;
|
||||
$i++;
|
||||
@@ -490,7 +530,7 @@ class Trashbin {
|
||||
* @return mixed trash bin size or false if no trash bin size is stored
|
||||
*/
|
||||
private static function getTrashbinSize($user) {
|
||||
$query = \OC_DB::prepare('SELECT size FROM *PREFIX*files_trashsize WHERE user=?');
|
||||
$query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*files_trashsize` WHERE `user`=?');
|
||||
$result = $query->execute(array($user))->fetchAll();
|
||||
|
||||
if ($result) {
|
||||
@@ -507,9 +547,9 @@ class Trashbin {
|
||||
*/
|
||||
private static function setTrashbinSize($user, $size) {
|
||||
if ( self::getTrashbinSize($user) === false) {
|
||||
$query = \OC_DB::prepare('INSERT INTO *PREFIX*files_trashsize (size, user) VALUES (?, ?)');
|
||||
$query = \OC_DB::prepare('INSERT INTO `*PREFIX*files_trashsize` (`size`, `user`) VALUES (?, ?)');
|
||||
}else {
|
||||
$query = \OC_DB::prepare('UPDATE *PREFIX*files_trashsize SET size=? WHERE user=?');
|
||||
$query = \OC_DB::prepare('UPDATE `*PREFIX*files_trashsize` SET `size`=? WHERE `user`=?');
|
||||
}
|
||||
$query->execute(array($size, $user));
|
||||
}
|
||||
|
||||
@@ -12,3 +12,5 @@ OCP\Util::connectHook('OC_Filesystem', 'write', "OCA\Files_Versions\Hooks", "wri
|
||||
// Listen to delete and rename signals
|
||||
OCP\Util::connectHook('OC_Filesystem', 'post_delete', "OCA\Files_Versions\Hooks", "remove_hook");
|
||||
OCP\Util::connectHook('OC_Filesystem', 'rename', "OCA\Files_Versions\Hooks", "rename_hook");
|
||||
//Listen to delete user signal
|
||||
OCP\Util::connectHook('OC_User', 'pre_deleteUser', "OCA\Files_Versions\Hooks", "deleteUser_hook");
|
||||
|
||||
@@ -6,7 +6,25 @@
|
||||
<author>Frank Karlitschek</author>
|
||||
<require>4.93</require>
|
||||
<shipped>true</shipped>
|
||||
<description>Versioning of files</description>
|
||||
<description>
|
||||
ownCloud supports simple version control for files. The versioning app
|
||||
expires old versions automatically to make sure that
|
||||
the user doesn't run out of space. Following pattern is used to delete
|
||||
old versions:
|
||||
For the first 10 seconds ownCloud keeps one version every 2 seconds;
|
||||
For the first hour ownCloud keeps one version every minute;
|
||||
For the first 24 hours ownCloud keeps one version every hour;
|
||||
For the first 30 days ownCloud keeps one version every day;
|
||||
After the first 30 days ownCloud keeps one version every week.
|
||||
|
||||
The versions are adjusted along this pattern every time a new version gets
|
||||
created.
|
||||
|
||||
Beside that the version app takes care to never use more that 50% of the users
|
||||
currently available free space. If the stored versions exceed this limit
|
||||
ownCloud deletes the oldest versions until it meets the memory usage limit
|
||||
again.
|
||||
</description>
|
||||
<types>
|
||||
<filesystem/>
|
||||
</types>
|
||||
|
||||
@@ -63,4 +63,18 @@ class Hooks {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief clean up user specific settings if user gets deleted
|
||||
* @param array with uid
|
||||
*
|
||||
* This function is connected to the pre_deleteUser signal of OC_Users
|
||||
* to remove the used space for versions stored in the database
|
||||
*/
|
||||
public static function deleteUser_hook($params) {
|
||||
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
|
||||
$uid = $params['uid'];
|
||||
Storage::deleteUser($uid);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ class Storage {
|
||||
* @return mixed versions size or false if no versions size is stored
|
||||
*/
|
||||
private static function getVersionsSize($user) {
|
||||
$query = \OC_DB::prepare('SELECT size FROM *PREFIX*files_versions WHERE user=?');
|
||||
$query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*files_versions` WHERE `user`=?');
|
||||
$result = $query->execute(array($user))->fetchAll();
|
||||
|
||||
if ($result) {
|
||||
@@ -70,9 +70,9 @@ class Storage {
|
||||
*/
|
||||
private static function setVersionsSize($user, $size) {
|
||||
if ( self::getVersionsSize($user) === false) {
|
||||
$query = \OC_DB::prepare('INSERT INTO *PREFIX*files_versions (size, user) VALUES (?, ?)');
|
||||
$query = \OC_DB::prepare('INSERT INTO `*PREFIX*files_versions` (`size`, `user`) VALUES (?, ?)');
|
||||
}else {
|
||||
$query = \OC_DB::prepare('UPDATE *PREFIX*files_versions SET size=? WHERE user=?');
|
||||
$query = \OC_DB::prepare('UPDATE `*PREFIX*files_versions` SET `size`=? WHERE `user`=?');
|
||||
}
|
||||
$query->execute(array($size, $user));
|
||||
}
|
||||
@@ -156,11 +156,18 @@ class Storage {
|
||||
/**
|
||||
* rename versions of a file
|
||||
*/
|
||||
public static function rename($oldpath, $newpath) {
|
||||
list($uid, $oldpath) = self::getUidAndFilename($oldpath);
|
||||
list($uidn, $newpath) = self::getUidAndFilename($newpath);
|
||||
public static function rename($old_path, $new_path) {
|
||||
list($uid, $oldpath) = self::getUidAndFilename($old_path);
|
||||
list($uidn, $newpath) = self::getUidAndFilename($new_path);
|
||||
$versions_view = new \OC\Files\View('/'.$uid .'/files_versions');
|
||||
$files_view = new \OC\Files\View('/'.$uid .'/files');
|
||||
|
||||
// if the file already exists than it was a upload of a existing file
|
||||
// over the web interface -> store() is the right function we need here
|
||||
if ($files_view->file_exists($newpath)) {
|
||||
return self::store($new_path);
|
||||
}
|
||||
|
||||
$abs_newpath = $versions_view->getLocalFile($newpath);
|
||||
|
||||
if ( $files_view->is_dir($oldpath) && $versions_view->is_dir($oldpath) ) {
|
||||
@@ -272,6 +279,18 @@ class Storage {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief deletes used space for files versions in db if user was deleted
|
||||
*
|
||||
* @param type $uid id of deleted user
|
||||
* @return result of db delete operation
|
||||
*/
|
||||
public static function deleteUser($uid) {
|
||||
$query = \OC_DB::prepare('DELETE FROM `*PREFIX*files_versions` WHERE `user`=?');
|
||||
return $query->execute(array($uid));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get the size of all stored versions from a given user
|
||||
* @param $uid id from the user
|
||||
@@ -359,12 +378,14 @@ class Storage {
|
||||
$versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions');
|
||||
|
||||
// get available disk space for user
|
||||
$softQuota = true;
|
||||
$quota = \OC_Preferences::getValue($uid, 'files', 'quota');
|
||||
if ( $quota === null || $quota === 'default') {
|
||||
$quota = \OC_Appconfig::getValue('files', 'default_quota');
|
||||
}
|
||||
if ( $quota === null || $quota === 'none' ) {
|
||||
$quota = \OC\Files\Filesystem::free_space('/') / count(\OCP\User::getUsers());
|
||||
$quota = \OC\Files\Filesystem::free_space('/');
|
||||
$softQuota = false;
|
||||
} else {
|
||||
$quota = \OCP\Util::computerFileSize($quota);
|
||||
}
|
||||
@@ -378,15 +399,21 @@ class Storage {
|
||||
}
|
||||
|
||||
// calculate available space for version history
|
||||
$files_view = new \OC\Files\View('/'.$uid.'/files');
|
||||
$rootInfo = $files_view->getFileInfo('/');
|
||||
$free = $quota-$rootInfo['size']; // remaining free space for user
|
||||
if ( $free > 0 ) {
|
||||
$availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - $versionsSize; // how much space can be used for versions
|
||||
// subtract size of files and current versions size from quota
|
||||
if ($softQuota) {
|
||||
$files_view = new \OC\Files\View('/'.$uid.'/files');
|
||||
$rootInfo = $files_view->getFileInfo('/');
|
||||
$free = $quota-$rootInfo['size']; // remaining free space for user
|
||||
if ( $free > 0 ) {
|
||||
$availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - $versionsSize; // how much space can be used for versions
|
||||
} else {
|
||||
$availableSpace = $free-$versionsSize;
|
||||
}
|
||||
} else {
|
||||
$availableSpace = $free-$versionsSize;
|
||||
$availableSpace = $quota;
|
||||
}
|
||||
|
||||
|
||||
// after every 1000s run reduce the number of all versions not only for the current file
|
||||
$random = rand(0, 1000);
|
||||
if ($random == 0) {
|
||||
|
||||
@@ -139,6 +139,9 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface {
|
||||
if(!$this->enabled) {
|
||||
return array();
|
||||
}
|
||||
if(!$this->groupExists($gid)) {
|
||||
return array();
|
||||
}
|
||||
$cachekey = 'usersInGroup-'.$gid.'-'.$search.'-'.$limit.'-'.$offset;
|
||||
// check for cache of the exact query
|
||||
$groupUsers = $this->connection->getFromCache($cachekey);
|
||||
@@ -178,7 +181,7 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface {
|
||||
//we got uids, need to get their DNs to 'tranlsate' them to usernames
|
||||
$filter = $this->combineFilterWithAnd(array(
|
||||
\OCP\Util::mb_str_replace('%uid', $member,
|
||||
$this->connection>ldapLoginFilter, 'UTF-8'),
|
||||
$this->connection->ldapLoginFilter, 'UTF-8'),
|
||||
$this->getFilterPartForUserSearch($search)
|
||||
));
|
||||
$ldap_users = $this->fetchListOfUsers($filter, 'dn');
|
||||
@@ -214,6 +217,12 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface {
|
||||
* @returns array with display names (value) and user ids(key)
|
||||
*/
|
||||
public function displayNamesInGroup($gid, $search, $limit, $offset) {
|
||||
if(!$this->enabled) {
|
||||
return array();
|
||||
}
|
||||
if(!$this->groupExists($gid)) {
|
||||
return array();
|
||||
}
|
||||
$users = $this->usersInGroup($gid, $search, $limit, $offset);
|
||||
$displayNames = array();
|
||||
foreach($users as $user) {
|
||||
|
||||
@@ -62,7 +62,10 @@ abstract class Access {
|
||||
$dn = $this->DNasBaseParameter($dn);
|
||||
$rr = @ldap_read($cr, $dn, $filter, array($attr));
|
||||
if(!is_resource($rr)) {
|
||||
\OCP\Util::writeLog('user_ldap', 'readAttribute failed for DN '.$dn, \OCP\Util::DEBUG);
|
||||
if(!empty($attr)) {
|
||||
//do not throw this message on userExists check, irritates
|
||||
\OCP\Util::writeLog('user_ldap', 'readAttribute failed for DN '.$dn, \OCP\Util::DEBUG);
|
||||
}
|
||||
//in case an error occurs , e.g. object does not exist
|
||||
return false;
|
||||
}
|
||||
@@ -84,7 +87,7 @@ abstract class Access {
|
||||
for($i=0;$i<$result[$attr]['count'];$i++) {
|
||||
if($this->resemblesDN($attr)) {
|
||||
$values[] = $this->sanitizeDN($result[$attr][$i]);
|
||||
} elseif(strtolower($attr) == 'objectguid') {
|
||||
} elseif(strtolower($attr) == 'objectguid' || strtolower($attr) == 'guid') {
|
||||
$values[] = $this->convertObjectGUID2Str($result[$attr][$i]);
|
||||
} else {
|
||||
$values[] = $result[$attr][$i];
|
||||
@@ -895,7 +898,7 @@ abstract class Access {
|
||||
}
|
||||
|
||||
//for now, supported (known) attributes are entryUUID, nsuniqueid, objectGUID
|
||||
$testAttributes = array('entryuuid', 'nsuniqueid', 'objectguid');
|
||||
$testAttributes = array('entryuuid', 'nsuniqueid', 'objectguid', 'guid');
|
||||
|
||||
foreach($testAttributes as $attribute) {
|
||||
\OCP\Util::writeLog('user_ldap', 'Testing '.$attribute.' as UUID attr', \OCP\Util::DEBUG);
|
||||
|
||||
@@ -212,7 +212,6 @@ class Connection {
|
||||
*/
|
||||
private function readConfiguration($force = false) {
|
||||
if((!$this->configured || $force) && !is_null($this->configID)) {
|
||||
$defaults = $this->getDefaults();
|
||||
$v = 'getValue';
|
||||
$this->config['ldapHost'] = $this->$v('ldap_host');
|
||||
$this->config['ldapBackupHost'] = $this->$v('ldap_backup_host');
|
||||
|
||||
@@ -51,7 +51,8 @@ class Helper {
|
||||
$query = '
|
||||
SELECT DISTINCT `configkey`
|
||||
FROM `*PREFIX*appconfig`
|
||||
WHERE `configkey` LIKE ?
|
||||
WHERE `appid` = \'user_ldap\'
|
||||
AND `configkey` LIKE ?
|
||||
';
|
||||
if($activeConfigurations) {
|
||||
$query .= ' AND `configvalue` = \'1\'';
|
||||
|
||||
@@ -180,6 +180,11 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface {
|
||||
* @return boolean
|
||||
*/
|
||||
public function getHome($uid) {
|
||||
// user Exists check required as it is not done in user proxy!
|
||||
if(!$this->userExists($uid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cacheKey = 'getHome'.$uid;
|
||||
if($this->connection->isCached($cacheKey)) {
|
||||
return $this->connection->getFromCache($cacheKey);
|
||||
@@ -217,6 +222,10 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface {
|
||||
* @return display name
|
||||
*/
|
||||
public function getDisplayName($uid) {
|
||||
if(!$this->userExists($uid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cacheKey = 'getDisplayName'.$uid;
|
||||
if(!is_null($displayName = $this->connection->getFromCache($cacheKey))) {
|
||||
return $displayName;
|
||||
|
||||
@@ -95,12 +95,12 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo
|
||||
|
||||
// setup the email
|
||||
$subject = (string)$l->t('User %s shared a file with you', $displayName);
|
||||
if ($type === 'dir')
|
||||
if ($type === 'folder')
|
||||
$subject = (string)$l->t('User %s shared a folder with you', $displayName);
|
||||
|
||||
$text = (string)$l->t('User %s shared the file "%s" with you. It is available for download here: %s',
|
||||
array($displayName, $file, $link));
|
||||
if ($type === 'dir')
|
||||
if ($type === 'folder')
|
||||
$text = (string)$l->t('User %s shared the folder "%s" with you. It is available for download here: %s',
|
||||
array($displayName, $file, $link));
|
||||
|
||||
@@ -110,7 +110,7 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo
|
||||
|
||||
// send it out now
|
||||
try {
|
||||
OCP\Util::sendMail($to_address, $to_address, $subject, $text, $from_address, $user);
|
||||
OCP\Util::sendMail($to_address, $to_address, $subject, $text, $from_address, $displayName);
|
||||
OCP\JSON::success();
|
||||
} catch (Exception $exception) {
|
||||
OCP\JSON::error(array('data' => array('message' => OC_Util::sanitizeHTML($exception->getMessage()))));
|
||||
|
||||
@@ -14,6 +14,10 @@ if (OC::checkUpgrade(false)) {
|
||||
try {
|
||||
$result = OC_DB::updateDbFromStructure(OC::$SERVERROOT.'/db_structure.xml');
|
||||
$watcher->success('Updated database');
|
||||
|
||||
// do a file cache upgrade for users with files
|
||||
// this can take loooooooooooooooooooooooong
|
||||
__doFileCacheUpgrade($watcher);
|
||||
} catch (Exception $exception) {
|
||||
$watcher->failure($exception->getMessage());
|
||||
}
|
||||
@@ -26,6 +30,49 @@ if (OC::checkUpgrade(false)) {
|
||||
$watcher->done();
|
||||
}
|
||||
|
||||
/**
|
||||
* The FileCache Upgrade routine
|
||||
*
|
||||
* @param UpdateWatcher $watcher
|
||||
*/
|
||||
function __doFileCacheUpgrade($watcher) {
|
||||
try {
|
||||
$query = \OC_DB::prepare('
|
||||
SELECT DISTINCT `user`
|
||||
FROM `*PREFIX*fscache`
|
||||
');
|
||||
$result = $query->execute();
|
||||
} catch (\Exception $e) {
|
||||
return;
|
||||
}
|
||||
$users = $result->fetchAll();
|
||||
if(count($users) == 0) {
|
||||
return;
|
||||
}
|
||||
$step = 100 / count($users);
|
||||
$percentCompleted = 0;
|
||||
$lastPercentCompletedOutput = 0;
|
||||
$startInfoShown = false;
|
||||
foreach($users as $userRow) {
|
||||
$user = $userRow['user'];
|
||||
\OC\Files\Filesystem::initMountPoints($user);
|
||||
\OC\Files\Cache\Upgrade::doSilentUpgrade($user);
|
||||
if(!$startInfoShown) {
|
||||
//We show it only now, because otherwise Info about upgraded apps
|
||||
//will appear between this and progress info
|
||||
$watcher->success('Updating filecache, this may take really long...');
|
||||
$startInfoShown = true;
|
||||
}
|
||||
$percentCompleted += $step;
|
||||
$out = floor($percentCompleted);
|
||||
if($out != $lastPercentCompletedOutput) {
|
||||
$watcher->success('... '. $out.'% done ...');
|
||||
$lastPercentCompletedOutput = $out;
|
||||
}
|
||||
}
|
||||
$watcher->success('Updated filecache');
|
||||
}
|
||||
|
||||
class UpdateWatcher {
|
||||
/**
|
||||
* @var \OC_EventSource $eventSource;
|
||||
|
||||
@@ -12,7 +12,7 @@ table, td, th { vertical-align:middle; }
|
||||
a { border:0; color:#000; text-decoration:none;}
|
||||
a, a *, input, input *, select, .button span, li, label { cursor:pointer; }
|
||||
ul { list-style:none; }
|
||||
body { background:#fefefe; font:normal .8em/1.6em "Lucida Grande", Arial, Verdana, sans-serif; color:#000; }
|
||||
body { background:#fefefe; font:normal .8em/1.6em "Helvetica Neue",Helvetica,Arial,FreeSans,sans-serif; color:#000; }
|
||||
|
||||
|
||||
/* HEADERS */
|
||||
@@ -40,7 +40,7 @@ filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#35537a', endC
|
||||
input[type="text"], input[type="password"], input[type="search"], input[type="number"], input[type="email"],
|
||||
textarea, select, button, .button, #quota, div.jp-progress, .pager li a {
|
||||
width:10em; margin:.3em; padding:.6em .5em .4em;
|
||||
font-size:1em; font-family:Arial, Verdana, sans-serif;
|
||||
font-size:1em;
|
||||
background:#fff; color:#333; border:1px solid #ddd; outline:none;
|
||||
-moz-box-shadow:0 1px 1px #fff, 0 2px 0 #bbb inset; -webkit-box-shadow:0 1px 1px #fff, 0 1px 0 #bbb inset; box-shadow:0 1px 1px #fff, 0 1px 0 #bbb inset;
|
||||
-moz-border-radius:.5em; -webkit-border-radius:.5em; border-radius:.5em;
|
||||
@@ -80,12 +80,27 @@ input[type="submit"], input[type="button"], button, .button, #quota, div.jp-prog
|
||||
-moz-box-shadow:0 1px 1px rgba(255,255,255,.9), 0 1px 1px rgba(255,255,255,.9) inset; -webkit-box-shadow:0 1px 1px rgba(255,255,255,.9), 0 1px 1px rgba(255,255,255,.9) inset; box-shadow:0 1px 1px rgba(255,255,255,.9), 0 1px 1px rgba(255,255,255,.9) inset;
|
||||
-moz-border-radius:.5em; -webkit-border-radius:.5em; border-radius:.5em;
|
||||
}
|
||||
input[type="submit"]:hover, input[type="submit"]:focus, input[type="button"]:hover, select:hover, select:focus, select:active, input[type="button"]:focus, .button:hover {
|
||||
background:rgba(250,250,250,.9); color:#333;
|
||||
input[type="submit"]:hover, input[type="submit"]:focus,
|
||||
input[type="button"]:hover, input[type="button"]:focus,
|
||||
button:hover, button:focus,
|
||||
.button:hover, .button:focus,
|
||||
select:hover, select:focus, select:active {
|
||||
background-color:rgba(250,250,250,.9);
|
||||
color:#333;
|
||||
}
|
||||
input[type="submit"] img, input[type="button"] img, button img, .button img { cursor:pointer; }
|
||||
#header .button { border:none; -moz-box-shadow:none; -webkit-box-shadow:none; box-shadow:none; }
|
||||
|
||||
/* disabled input fields and buttons */
|
||||
input:disabled, input:disabled:hover, input:disabled:focus,
|
||||
button:disabled, button:disabled:hover, button:disabled:focus,
|
||||
.button:disabled, .button:disabled:hover, .button:disabled:focus,
|
||||
a.disabled, a.disabled:hover, a.disabled:focus {
|
||||
background: rgba(230,230,230,.9);
|
||||
color: #999;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* Primary action button, use sparingly */
|
||||
.primary, input[type="submit"].primary, input[type="button"].primary, button.primary, .button.primary {
|
||||
border:1px solid #1d2d44;
|
||||
@@ -242,22 +257,48 @@ fieldset.warning a { color:#b94a48 !important; font-weight:bold; }
|
||||
|
||||
/* NAVIGATION ------------------------------------------------------------- */
|
||||
#navigation {
|
||||
position:fixed; top:3.5em; float:left; width:64px; padding:0; z-index:75; height:100%;
|
||||
position:fixed; float:left; width:64px; padding-top:3.5em; z-index:75; height:100%;
|
||||
background:#383c43 url('../img/noise.png') repeat; border-right:1px #333 solid;
|
||||
-moz-box-shadow:0 0 7px #000; -webkit-box-shadow:0 0 7px #000; box-shadow:0 0 7px #000;
|
||||
overflow:hidden;
|
||||
overflow:hidden; box-sizing:border-box; -moz-box-sizing:border-box;
|
||||
}
|
||||
#navigation:hover { overflow-y:auto; }
|
||||
#navigation a {
|
||||
display:block; padding:8px 0 4px;
|
||||
#navigation:hover { overflow-y:auto; } /* show scrollbar only on hover */
|
||||
#navigation a span {
|
||||
display:block;
|
||||
text-decoration:none; font-size:10px; text-align:center;
|
||||
color:#fff; text-shadow:#000 0 -1px 0;
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; filter:alpha(opacity=50); opacity:.5;
|
||||
white-space:nowrap; overflow:hidden; text-overflow:ellipsis; // ellipsize long app names
|
||||
white-space:nowrap; overflow:hidden; text-overflow:ellipsis; /* ellipsize long app names */
|
||||
}
|
||||
#navigation a:hover, #navigation a:focus { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; filter:alpha(opacity=80); opacity:.8; }
|
||||
#navigation a.active { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); opacity:1; }
|
||||
#navigation .icon { display:block; width:32px; height:32px; margin:0 16px 0; }
|
||||
|
||||
/* icon opacity and hover effect */
|
||||
#navigation a img,
|
||||
#navigation a span {
|
||||
/* 50% opacity when inactive */
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
|
||||
filter: alpha(opacity=50);
|
||||
opacity: .5;
|
||||
}
|
||||
#navigation a:hover img, #navigation a:focus img,
|
||||
#navigation a:hover span, #navigation a:focus span {
|
||||
/* 80% opacity when hovered or focused */
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
|
||||
filter: alpha(opacity=80);
|
||||
opacity: .8;
|
||||
}
|
||||
#navigation a.active img,
|
||||
#navigation a.active span {
|
||||
/* full opacity for the active app */
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
|
||||
filter: alpha(opacity=100);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* positioning */
|
||||
#navigation .icon {
|
||||
display:block;
|
||||
width:32px; height:32px;
|
||||
margin:0 16px 0; padding:8px 0 4px;
|
||||
}
|
||||
#navigation li:first-child a { padding-top:16px; }
|
||||
|
||||
|
||||
@@ -360,3 +401,212 @@ div.crumb { float:left; display:block; background:url('../img/breadcrumb.svg') n
|
||||
div.crumb:first-child { padding:10px 20px 10px 5px; }
|
||||
div.crumb.last { font-weight:bold; background:none; padding-right:10px; }
|
||||
div.crumb a{ padding: 0.9em 0 0.7em 0; }
|
||||
|
||||
|
||||
|
||||
/* ---- APP STYLING ---- */
|
||||
#app {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Navigation: folder like structure */
|
||||
#app-navigation {
|
||||
width: 250px;
|
||||
height: 100%;
|
||||
float: left;
|
||||
padding-bottom: 32px;
|
||||
-moz-box-sizing: border-box; box-sizing: border-box;
|
||||
background-color: #f8f8f8;
|
||||
border-right: 1px solid #ccc;
|
||||
}
|
||||
#app-navigation > ul {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
-moz-box-sizing: border-box; box-sizing: border-box;
|
||||
}
|
||||
#app-navigation li {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
-moz-box-sizing: border-box; box-sizing: border-box;
|
||||
text-shadow: 0 1px 0 rgba(255,255,255,.9);
|
||||
}
|
||||
#app-navigation .active,
|
||||
#app-navigation .active a { /* active navigation entry or folder */
|
||||
background-color: #ddd;
|
||||
text-shadow: 0 1px 0 rgba(255,255,255,.7);
|
||||
}
|
||||
|
||||
/* special rules for first-level entries and folders */
|
||||
#app-navigation > ul > li {
|
||||
background-color: #eee;
|
||||
border-top: 1px solid #fff;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
#app-navigation > ul > .active {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
#app-navigation .with-icon a {
|
||||
padding-left: 32px;
|
||||
background-size: 16px 16px; background-position: 10px center; background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#app-navigation li > a {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0 16px;
|
||||
overflow: hidden;
|
||||
-moz-box-sizing: border-box; box-sizing: border-box;
|
||||
line-height: 32px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
color: #333;
|
||||
}
|
||||
#app-navigation li:hover > a {
|
||||
background-color: #ddd;
|
||||
}
|
||||
#app-navigation > ul > li:hover {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
#app-navigation .collapse {
|
||||
display: none; /* hide collapse button intially */
|
||||
}
|
||||
#app-navigation .collapsible > .collapse {
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
top: 5px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
background: none; background-image: url('../img/actions/triangle-s.svg');
|
||||
background-size: 16px 16px; background-repeat: no-repeat;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
outline: none !important;
|
||||
box-shadow: none;
|
||||
}
|
||||
#app-navigation .collapsible:hover > a {
|
||||
background-image: none;
|
||||
}
|
||||
#app-navigation .collapsible:hover > .collapse {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#app-navigation .collapsible .collapse {
|
||||
-moz-transform: rotate(-90deg);
|
||||
-webkit-transform: rotate(-90deg);
|
||||
-ms-transform:rotate(-90deg);
|
||||
-o-transform:rotate(-90deg);
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
#app-navigation .collapsible.open .collapse {
|
||||
-moz-transform: rotate(0);
|
||||
-webkit-transform: rotate(0);
|
||||
-ms-transform:rotate(0);
|
||||
-o-transform:rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
/* Second level nesting for lists */
|
||||
#app-navigation > ul ul {
|
||||
display: none;
|
||||
}
|
||||
#app-navigation > ul ul li > a {
|
||||
padding-left: 32px;
|
||||
}
|
||||
#app-navigation > .with-icon ul li > a {
|
||||
padding-left: 48px;
|
||||
background-position: 24px center;
|
||||
}
|
||||
|
||||
#app-navigation .open {
|
||||
background-image: linear-gradient(top, rgb(238,238,238) 0%, rgb(245,245,245) 100%);
|
||||
background-image: -o-linear-gradient(top, rgb(238,238,238) 0%, rgb(245,245,245) 100%);
|
||||
background-image: -moz-linear-gradient(top, rgb(238,238,238) 0%, rgb(245,245,245) 100%);
|
||||
background-image: -webkit-linear-gradient(top, rgb(238,238,238) 0%, rgb(245,245,245) 100%);
|
||||
background-image: -ms-linear-gradient(top, rgb(238,238,238) 0%, rgb(245,245,245) 100%);
|
||||
}
|
||||
|
||||
#app-navigation > ul .open:hover {
|
||||
-moz-box-shadow: inset 0 0 3px #ccc; -webkit-box-shadow: inset 0 0 3px #ccc; box-shadow: inset 0 0 3px #ccc;
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
|
||||
#app-navigation > ul .open ul {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* drag and drop */
|
||||
#app-navigation .drag-and-drop {
|
||||
-moz-transition: padding-bottom 500ms ease 0s;
|
||||
-o-transition: padding-bottom 500ms ease 0s;
|
||||
-webkit-transition: padding-bottom 500ms ease 0s;
|
||||
-ms-transition: padding-bottom 500ms ease 0s;
|
||||
transition: padding-bottom 500ms ease 0s;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
#app-navigation .personalblock > legend { /* TODO @Raydiation: still needed? */
|
||||
padding: 10px 0; margin: 0;
|
||||
}
|
||||
#app-navigation .error {
|
||||
color: #dd1144;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Part where the content will be loaded into */
|
||||
#app-content {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* settings area */
|
||||
#app-settings {
|
||||
position: fixed;
|
||||
width: 249px;
|
||||
bottom: 0;
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
#app-settings-header {
|
||||
background-color: #eee;
|
||||
}
|
||||
#app-settings-content {
|
||||
display: none;
|
||||
padding: 10px;
|
||||
background-color: #eee;
|
||||
}
|
||||
#app-settings.open #app-settings-content {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.settings-button {
|
||||
display: block;
|
||||
height: 32px;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background-color: transparent; background-image: url('../img/actions/settings.svg');
|
||||
background-position: 10px center; background-repeat: no-repeat;
|
||||
box-shadow: none;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.settings-button:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
/* icons */
|
||||
.folder-icon { background-image: url('../img/places/folder.svg'); }
|
||||
.delete-icon { background-image: url('../img/actions/delete.svg'); }
|
||||
.delete-icon:hover { background-image: url('../img/actions/delete-hover.svg'); }
|
||||
.edit-icon { background-image: url('../img/actions/rename.svg'); }
|
||||
|
||||
/* buttons */
|
||||
button.loading {
|
||||
background-image: url('../img/loading.gif');
|
||||
background-position: right 10px center; background-repeat: no-repeat;
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
@@ -133,14 +133,14 @@ OC.Share={
|
||||
callback();
|
||||
}
|
||||
} else {
|
||||
OC.dialogs.alert(t('core', 'Error'), t('core', 'Error while unsharing'));
|
||||
OC.dialogs.alert(t('core', 'Error while unsharing'), t('core', 'Error'));
|
||||
}
|
||||
});
|
||||
},
|
||||
setPermissions:function(itemType, itemSource, shareType, shareWith, permissions) {
|
||||
$.post(OC.filePath('core', 'ajax', 'share.php'), { action: 'setPermissions', itemType: itemType, itemSource: itemSource, shareType: shareType, shareWith: shareWith, permissions: permissions }, function(result) {
|
||||
if (!result || result.status !== 'success') {
|
||||
OC.dialogs.alert(t('core', 'Error'), t('core', 'Error while changing permissions'));
|
||||
OC.dialogs.alert(t('core', 'Error while changing permissions'), t('core', 'Error'));
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -271,7 +271,7 @@ OC.Share={
|
||||
}
|
||||
var collectionList = $('#shareWithList li').filterAttr('data-collection', item);
|
||||
if (collectionList.length > 0) {
|
||||
$(collectionList).append(', '+shareWith);
|
||||
$(collectionList).append(', '+shareWithDisplayName);
|
||||
} else {
|
||||
var html = '<li style="clear: both;" data-collection="'+item+'">'+t('core', 'Shared in {item} with {user}', {'item': item, user: shareWithDisplayName})+'</li>';
|
||||
$('#shareWithList').prepend(html);
|
||||
@@ -383,7 +383,7 @@ OC.Share={
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
|
||||
if(typeof monthNames != 'undefined'){
|
||||
$.datepicker.setDefaults({
|
||||
monthNames: monthNames,
|
||||
@@ -421,7 +421,7 @@ $(document).ready(function() {
|
||||
|
||||
$(this).click(function(event) {
|
||||
var target = $(event.target);
|
||||
var isMatched = !target.is('.drop, .ui-datepicker-next, .ui-datepicker-prev, .ui-icon')
|
||||
var isMatched = !target.is('.drop, .ui-datepicker-next, .ui-datepicker-prev, .ui-icon')
|
||||
&& !target.closest('#ui-datepicker-div').length;
|
||||
if (OC.Share.droppedDown && isMatched && $('#dropdown').has(event.target).length === 0) {
|
||||
OC.Share.hideDropDown();
|
||||
@@ -563,19 +563,19 @@ $(document).ready(function() {
|
||||
var itemSource = $('#dropdown').data('item-source');
|
||||
$.post(OC.filePath('core', 'ajax', 'share.php'), { action: 'setExpirationDate', itemType: itemType, itemSource: itemSource, date: '' }, function(result) {
|
||||
if (!result || result.status !== 'success') {
|
||||
OC.dialogs.alert(t('core', 'Error'), t('core', 'Error unsetting expiration date'));
|
||||
OC.dialogs.alert(t('core', 'Error unsetting expiration date'), t('core', 'Error'));
|
||||
}
|
||||
$('#expirationDate').hide();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$(document).on('change', '#dropdown #expirationDate', function() {
|
||||
var itemType = $('#dropdown').data('item-type');
|
||||
var itemSource = $('#dropdown').data('item-source');
|
||||
$.post(OC.filePath('core', 'ajax', 'share.php'), { action: 'setExpirationDate', itemType: itemType, itemSource: itemSource, date: $(this).val() }, function(result) {
|
||||
if (!result || result.status !== 'success') {
|
||||
OC.dialogs.alert(t('core', 'Error'), t('core', 'Error setting expiration date'));
|
||||
OC.dialogs.alert(t('core', 'Error setting expiration date'), t('core', 'Error'));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,6 +18,10 @@ $hasPostgreSQL = is_callable('pg_connect');
|
||||
$hasOracle = is_callable('oci_connect');
|
||||
$hasMSSQL = is_callable('sqlsrv_connect');
|
||||
$datadir = OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data');
|
||||
$vulnerableToNullByte = false;
|
||||
if(@file_exists(__FILE__."\0Nullbyte")) { // Check if the used PHP version is vulnerable to the NULL Byte attack (CVE-2006-7243)
|
||||
$vulnerableToNullByte = true;
|
||||
}
|
||||
|
||||
// Protect data directory here, so we can test if the protection is working
|
||||
OC_Setup::protectDataDirectory();
|
||||
@@ -31,6 +35,7 @@ $opts = array(
|
||||
'directory' => $datadir,
|
||||
'secureRNG' => OC_Util::secureRNG_available(),
|
||||
'htaccessWorking' => OC_Util::ishtaccessworking(),
|
||||
'vulnerableToNullByte' => $vulnerableToNullByte,
|
||||
'errors' => array(),
|
||||
);
|
||||
|
||||
|
||||
@@ -19,6 +19,13 @@
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
<?php if($_['vulnerableToNullByte']): ?>
|
||||
<fieldset class="warning">
|
||||
<legend><strong><?php p($l->t('Security Warning'));?></strong></legend>
|
||||
<p><?php p($l->t('Your PHP version is vulnerable to the NULL Byte attack (CVE-2006-7243)'));?><br/>
|
||||
<?php p($l->t('Please update your PHP installation to use ownCloud securely.'));?></p>
|
||||
</fieldset>
|
||||
<?php endif; ?>
|
||||
<?php if(!$_['secureRNG']): ?>
|
||||
<fieldset class="warning">
|
||||
<legend><strong><?php p($l->t('Security Warning'));?></strong></legend>
|
||||
|
||||
@@ -75,7 +75,9 @@
|
||||
<a href="<?php print_unescaped($entry['href']); ?>" title=""
|
||||
<?php if( $entry['active'] ): ?> class="active"<?php endif; ?>>
|
||||
<img class="icon svg" src="<?php print_unescaped($entry['icon']); ?>"/>
|
||||
<?php p($entry['name']); ?>
|
||||
<span>
|
||||
<?php p($entry['name']); ?>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
|
||||
2
cron.php
2
cron.php
@@ -48,6 +48,8 @@ function handleUnexpectedShutdown() {
|
||||
$RUNTIME_NOSETUPFS = true;
|
||||
require_once 'lib/base.php';
|
||||
|
||||
session_write_close();
|
||||
|
||||
// Don't do anything if ownCloud has not been installed
|
||||
if( !OC_Config::getValue( 'installed', false )) {
|
||||
exit( 0 );
|
||||
|
||||
@@ -651,6 +651,14 @@
|
||||
<length>255</length>
|
||||
</field>
|
||||
|
||||
<index>
|
||||
<name>property_index</name>
|
||||
<field>
|
||||
<name>userid</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
</index>
|
||||
|
||||
</declaration>
|
||||
|
||||
</table>
|
||||
@@ -859,7 +867,6 @@
|
||||
<name>displayname</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>64</length>
|
||||
</field>
|
||||
|
||||
|
||||
@@ -851,7 +851,11 @@ class OC_App{
|
||||
foreach($apps as $app) {
|
||||
// check if the app is compatible with this version of ownCloud
|
||||
$info = OC_App::getAppInfo($app);
|
||||
if(!isset($info['require']) or !self::isAppVersionCompatible($version, $info['require'])) {
|
||||
if(!isset($info['require'])
|
||||
or !self::isAppVersionCompatible($version, $info['require'])
|
||||
// manually disable files_archive app since it has been removed
|
||||
// and cause update problems
|
||||
or $app === 'files_archive') {
|
||||
OC_Log::write('core',
|
||||
'App "'.$info['name'].'" ('.$app.') can\'t be used because it is'
|
||||
.' not compatible with this version of ownCloud',
|
||||
|
||||
@@ -78,6 +78,8 @@ class OC {
|
||||
* SPL autoload
|
||||
*/
|
||||
public static function autoload($className) {
|
||||
$className = trim($className, '\\');
|
||||
|
||||
if (array_key_exists($className, OC::$CLASSPATH)) {
|
||||
$path = OC::$CLASSPATH[$className];
|
||||
/** @TODO: Remove this when necessary
|
||||
@@ -276,7 +278,7 @@ class OC {
|
||||
OC_Config::setValue('maintenance', true);
|
||||
OC_Log::write('core',
|
||||
'starting upgrade from ' . $installedVersion . ' to ' . $currentVersion,
|
||||
OC_Log::DEBUG);
|
||||
OC_Log::WARN);
|
||||
$minimizerCSS = new OC_Minimizer_CSS();
|
||||
$minimizerCSS->clearCache();
|
||||
$minimizerJS = new OC_Minimizer_JS();
|
||||
@@ -398,8 +400,8 @@ class OC {
|
||||
ini_set('arg_separator.output', '&');
|
||||
|
||||
// try to switch magic quotes off.
|
||||
if (get_magic_quotes_gpc()) {
|
||||
@set_magic_quotes_runtime(false);
|
||||
if (get_magic_quotes_gpc()==1) {
|
||||
ini_set('magic_quotes_runtime', 0);
|
||||
}
|
||||
|
||||
//try to configure php to enable big file uploads.
|
||||
|
||||
@@ -292,8 +292,10 @@ class OC_DB {
|
||||
'username' => $user,
|
||||
'password' => $pass,
|
||||
'hostspec' => $host,
|
||||
'database' => $name
|
||||
);
|
||||
'database' => $name,
|
||||
'charset' => 'UTF-8'
|
||||
);
|
||||
$options['portability'] = $options['portability'] - MDB2_PORTABILITY_EMPTY_TO_NULL;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -50,7 +50,7 @@ class OC_Files {
|
||||
$xsendfile = true;
|
||||
}
|
||||
|
||||
if (count($files) == 1) {
|
||||
if (is_array($files) && count($files) == 1) {
|
||||
$files = $files[0];
|
||||
}
|
||||
|
||||
|
||||
9
lib/files/cache/cache.php
vendored
9
lib/files/cache/cache.php
vendored
@@ -203,7 +203,10 @@ class Cache {
|
||||
|
||||
$query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ')'
|
||||
. ' VALUES(' . implode(', ', $valuesPlaceholder) . ')');
|
||||
$query->execute($params);
|
||||
$result = $query->execute($params);
|
||||
if (\OC_DB::isError($result)) {
|
||||
\OCP\Util::writeLog('cache', 'Insert to cache failed: '.$result, \OCP\Util::ERROR);
|
||||
}
|
||||
|
||||
return (int)\OC_DB::insertid('*PREFIX*filecache');
|
||||
}
|
||||
@@ -340,9 +343,9 @@ class Cache {
|
||||
$query->execute(array($targetPath, md5($targetPath), $child['fileid']));
|
||||
}
|
||||
|
||||
$query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET `path` = ?, `path_hash` = ?, `parent` =?'
|
||||
$query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET `path` = ?, `path_hash` = ?, `name` = ?, `parent` =?'
|
||||
. ' WHERE `fileid` = ?');
|
||||
$query->execute(array($target, md5($target), $newParentId, $sourceId));
|
||||
$query->execute(array($target, md5($target), basename($target), $newParentId, $sourceId));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
45
lib/files/cache/legacy.php
vendored
45
lib/files/cache/legacy.php
vendored
@@ -72,7 +72,44 @@ class Legacy {
|
||||
$query = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` WHERE `path` = ?');
|
||||
}
|
||||
$result = $query->execute(array($path));
|
||||
return $result->fetchRow();
|
||||
$data = $result->fetchRow();
|
||||
$data['etag'] = $this->getEtag($data['path'], $data['user']);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ETag for the given path
|
||||
*
|
||||
* @param type $path
|
||||
* @return string
|
||||
*/
|
||||
function getEtag($path, $user = null) {
|
||||
static $query = null;
|
||||
|
||||
$pathDetails = explode('/', $path, 4);
|
||||
if((!$user) && !isset($pathDetails[1])) {
|
||||
//no user!? Too odd, return empty string.
|
||||
return '';
|
||||
} else if(!$user) {
|
||||
//guess user from path, if no user passed.
|
||||
$user = $pathDetails[1];
|
||||
}
|
||||
|
||||
if(!isset($pathDetails[3]) || is_null($pathDetails[3])) {
|
||||
$relativePath = '';
|
||||
} else {
|
||||
$relativePath = $pathDetails[3];
|
||||
}
|
||||
|
||||
if(is_null($query)){
|
||||
$query = \OC_DB::prepare('SELECT `propertyvalue` FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = \'{DAV:}getetag\'');
|
||||
}
|
||||
$result = $query->execute(array($user, '/' . $relativePath));
|
||||
if ($row = $result->fetchRow()) {
|
||||
return trim($row['propertyvalue'], '"');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,6 +119,10 @@ class Legacy {
|
||||
function getChildren($id) {
|
||||
$query = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` WHERE `parent` = ?');
|
||||
$result = $query->execute(array($id));
|
||||
return $result->fetchAll();
|
||||
$data = $result->fetchAll();
|
||||
foreach ($data as $i => $item) {
|
||||
$data[$i]['etag'] = $this->getEtag($item['path'], $item['user']);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
66
lib/files/cache/scanner.php
vendored
66
lib/files/cache/scanner.php
vendored
@@ -62,36 +62,42 @@ class Scanner {
|
||||
* @return array with metadata of the scanned file
|
||||
*/
|
||||
public function scanFile($file, $checkExisting = false) {
|
||||
\OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId));
|
||||
$data = $this->getData($file);
|
||||
if ($data) {
|
||||
if ($file) {
|
||||
$parent = dirname($file);
|
||||
if ($parent === '.') {
|
||||
$parent = '';
|
||||
if (!self::isIgnoredFile($file)) {
|
||||
\OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId));
|
||||
$data = $this->getData($file);
|
||||
if ($data) {
|
||||
if ($file) {
|
||||
$parent = dirname($file);
|
||||
if ($parent === '.') {
|
||||
$parent = '';
|
||||
}
|
||||
if (!$this->cache->inCache($parent)) {
|
||||
$this->scanFile($parent);
|
||||
}
|
||||
}
|
||||
if (!$this->cache->inCache($parent)) {
|
||||
$this->scanFile($parent);
|
||||
if($cacheData = $this->cache->get($file)) {
|
||||
if ($data['mtime'] === $cacheData['mtime'] &&
|
||||
$data['size'] === $cacheData['size']) {
|
||||
$data['etag'] = $cacheData['etag'];
|
||||
}
|
||||
}
|
||||
if ($checkExisting and $cacheData) {
|
||||
if ($data['size'] === -1) {
|
||||
$data['size'] = $cacheData['size'];
|
||||
}
|
||||
}
|
||||
$this->cache->put($file, $data);
|
||||
}
|
||||
if ($checkExisting and $cacheData = $this->cache->get($file)) {
|
||||
if ($data['size'] === -1) {
|
||||
$data['size'] = $cacheData['size'];
|
||||
}
|
||||
if ($data['mtime'] === $cacheData['mtime']) {
|
||||
$data['etag'] = $cacheData['etag'];
|
||||
}
|
||||
}
|
||||
$this->cache->put($file, $data);
|
||||
return $data;
|
||||
}
|
||||
return $data;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* scan all the files in a folder and store them in the cache
|
||||
*
|
||||
* @param string $path
|
||||
* @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive
|
||||
* @param bool $recursive
|
||||
* @param bool $onlyChilds
|
||||
* @return int the size of the scanned folder or -1 if the size is unknown at this stage
|
||||
*/
|
||||
@@ -106,7 +112,7 @@ class Scanner {
|
||||
if ($this->storage->is_dir($path) && ($dh = $this->storage->opendir($path))) {
|
||||
\OC_DB::beginTransaction();
|
||||
while ($file = readdir($dh)) {
|
||||
if (!$this->isIgnoredFile($file)) {
|
||||
if (!$this->isIgnoredDir($file)) {
|
||||
$child = ($path) ? $path . '/' . $file : $file;
|
||||
$data = $this->scanFile($child, $recursive === self::SCAN_SHALLOW);
|
||||
if ($data) {
|
||||
@@ -141,6 +147,18 @@ class Scanner {
|
||||
return $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check if the directory should be ignored when scanning
|
||||
* NOTE: the special directories . and .. would cause never ending recursion
|
||||
* @param String $dir
|
||||
* @return boolean
|
||||
*/
|
||||
private function isIgnoredDir($dir) {
|
||||
if ($dir === '.' || $dir === '..') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* @brief check if the file should be ignored when scanning
|
||||
* NOTE: files with a '.part' extension are ignored as well!
|
||||
@@ -148,9 +166,9 @@ class Scanner {
|
||||
* @param String $file
|
||||
* @return boolean
|
||||
*/
|
||||
private function isIgnoredFile($file) {
|
||||
if ($file === '.' || $file === '..'
|
||||
|| pathinfo($file, PATHINFO_EXTENSION) === 'part'
|
||||
public static function isIgnoredFile($file) {
|
||||
if (pathinfo($file, PATHINFO_EXTENSION) === 'part'
|
||||
|| \OC\Files\Filesystem::isFileBlacklisted($file)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
50
lib/files/cache/updater.php
vendored
50
lib/files/cache/updater.php
vendored
@@ -53,12 +53,36 @@ class Updater {
|
||||
}
|
||||
}
|
||||
|
||||
static public function renameUpdate($from, $to) {
|
||||
/**
|
||||
* @var \OC\Files\Storage\Storage $storageFrom
|
||||
* @var \OC\Files\Storage\Storage $storageTo
|
||||
* @var string $internalFrom
|
||||
* @var string $internalTo
|
||||
*/
|
||||
list($storageFrom, $internalFrom) = self::resolvePath($from);
|
||||
list($storageTo, $internalTo) = self::resolvePath($to);
|
||||
if ($storageFrom && $storageTo) {
|
||||
if ($storageFrom === $storageTo) {
|
||||
$cache = $storageFrom->getCache($internalFrom);
|
||||
$cache->move($internalFrom, $internalTo);
|
||||
$cache->correctFolderSize($internalFrom);
|
||||
$cache->correctFolderSize($internalTo);
|
||||
self::correctFolder($from, time());
|
||||
self::correctFolder($to, time());
|
||||
} else {
|
||||
self::deleteUpdate($from);
|
||||
self::writeUpdate($to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the mtime and ETag of all parent folders
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $time
|
||||
*/
|
||||
* Update the mtime and ETag of all parent folders
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $time
|
||||
*/
|
||||
static public function correctFolder($path, $time) {
|
||||
if ($path !== '' && $path !== '/') {
|
||||
$parent = dirname($path);
|
||||
@@ -66,9 +90,9 @@ class Updater {
|
||||
$parent = '';
|
||||
}
|
||||
/**
|
||||
* @var \OC\Files\Storage\Storage $storage
|
||||
* @var string $internalPath
|
||||
*/
|
||||
* @var \OC\Files\Storage\Storage $storage
|
||||
* @var string $internalPath
|
||||
*/
|
||||
list($storage, $internalPath) = self::resolvePath($parent);
|
||||
if ($storage) {
|
||||
$cache = $storage->getCache();
|
||||
@@ -88,12 +112,18 @@ class Updater {
|
||||
self::writeUpdate($params['path']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
*/
|
||||
static public function touchHook($params) {
|
||||
self::writeUpdate($params['path']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
*/
|
||||
static public function renameHook($params) {
|
||||
self::deleteUpdate($params['oldpath']);
|
||||
self::writeUpdate($params['newpath']);
|
||||
self::renameUpdate($params['oldpath'], $params['newpath']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
103
lib/files/cache/upgrade.php
vendored
103
lib/files/cache/upgrade.php
vendored
@@ -36,12 +36,12 @@ class Upgrade {
|
||||
return;
|
||||
}
|
||||
\OC_Hook::emit('\OC\Files\Cache\Upgrade', 'migrate_path', $path);
|
||||
|
||||
if ($row = $this->legacy->get($path)) {
|
||||
$data = $this->getNewData($row);
|
||||
$this->insert($data);
|
||||
|
||||
$this->upgradeChilds($data['id'], $mode);
|
||||
if ($data) {
|
||||
$this->insert($data);
|
||||
$this->upgradeChilds($data['id'], $mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,9 +53,11 @@ class Upgrade {
|
||||
foreach ($children as $child) {
|
||||
$childData = $this->getNewData($child);
|
||||
\OC_Hook::emit('\OC\Files\Cache\Upgrade', 'migrate_path', $child['path']);
|
||||
$this->insert($childData);
|
||||
if ($mode == Scanner::SCAN_RECURSIVE) {
|
||||
$this->upgradeChilds($child['id']);
|
||||
if ($childData) {
|
||||
$this->insert($childData);
|
||||
if ($mode == Scanner::SCAN_RECURSIVE) {
|
||||
$this->upgradeChilds($child['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,14 +66,16 @@ class Upgrade {
|
||||
* @param array $data the data for the new cache
|
||||
*/
|
||||
function insert($data) {
|
||||
if (!$this->inCache($data['storage'], $data['path_hash'], $data['id'])) {
|
||||
static $insertQuery = null;
|
||||
if(is_null($insertQuery)) {
|
||||
$insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`
|
||||
( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` )
|
||||
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
||||
|
||||
( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag` )
|
||||
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
||||
}
|
||||
if (!$this->inCache($data['storage'], $data['path_hash'], $data['id'])) {
|
||||
$insertQuery->execute(array($data['id'], $data['storage'],
|
||||
$data['path'], $data['path_hash'], $data['parent'], $data['name'],
|
||||
$data['mimetype'], $data['mimepart'], $data['size'], $data['mtime'], $data['encrypted']));
|
||||
$data['mimetype'], $data['mimepart'], $data['size'], $data['mtime'], $data['encrypted'], $data['etag']));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +86,10 @@ class Upgrade {
|
||||
* @return bool
|
||||
*/
|
||||
function inCache($storage, $pathHash, $id) {
|
||||
$query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE (`storage` = ? AND `path_hash` = ?) OR `fileid` = ?');
|
||||
static $query = null;
|
||||
if(is_null($query)) {
|
||||
$query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE (`storage` = ? AND `path_hash` = ?) OR `fileid` = ?');
|
||||
}
|
||||
$result = $query->execute(array($storage, $pathHash, $id));
|
||||
return (bool)$result->fetchRow();
|
||||
}
|
||||
@@ -91,24 +98,53 @@ class Upgrade {
|
||||
* get the new data array from the old one
|
||||
*
|
||||
* @param array $data the data from the old cache
|
||||
* Example data array
|
||||
* Array
|
||||
* (
|
||||
* [id] => 418
|
||||
* [path] => /tina/files/picture.jpg //relative to datadir
|
||||
* [path_hash] => 66d4547e372888deed80b24fec9b192b
|
||||
* [parent] => 234
|
||||
* [name] => picture.jpg
|
||||
* [user] => tina
|
||||
* [size] => 1265283
|
||||
* [ctime] => 1363909709
|
||||
* [mtime] => 1363909709
|
||||
* [mimetype] => image/jpeg
|
||||
* [mimepart] => image
|
||||
* [encrypted] => 0
|
||||
* [versioned] => 0
|
||||
* [writable] => 1
|
||||
* )
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getNewData($data) {
|
||||
//Make sure there is a path, otherwise we can do nothing.
|
||||
if(!isset($data['path'])) {
|
||||
return false;
|
||||
}
|
||||
$newData = $data;
|
||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($data['path']);
|
||||
/**
|
||||
* @var \OC\Files\Storage\Storage $storage
|
||||
* @var string $internalPath;
|
||||
*/
|
||||
$newData['path_hash'] = md5($internalPath);
|
||||
$newData['path'] = $internalPath;
|
||||
$newData['storage'] = $this->getNumericId($storage);
|
||||
$newData['parent'] = ($internalPath === '') ? -1 : $data['parent'];
|
||||
$newData['permissions'] = ($data['writable']) ? \OCP\PERMISSION_ALL : \OCP\PERMISSION_READ;
|
||||
$newData['storage_object'] = $storage;
|
||||
$newData['mimetype'] = $this->getMimetypeId($newData['mimetype'], $storage);
|
||||
$newData['mimepart'] = $this->getMimetypeId($newData['mimepart'], $storage);
|
||||
return $newData;
|
||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($data['path']);
|
||||
if ($storage) {
|
||||
$newData['etag'] = $data['etag'];
|
||||
$newData['path_hash'] = md5($internalPath);
|
||||
$newData['path'] = $internalPath;
|
||||
$newData['storage'] = $this->getNumericId($storage);
|
||||
$newData['parent'] = ($internalPath === '') ? -1 : $data['parent'];
|
||||
$newData['permissions'] = ($data['writable']) ? \OCP\PERMISSION_ALL : \OCP\PERMISSION_READ;
|
||||
$newData['storage_object'] = $storage;
|
||||
$newData['mimetype'] = $this->getMimetypeId($newData['mimetype'], $storage);
|
||||
$newData['mimepart'] = $this->getMimetypeId($newData['mimepart'], $storage);
|
||||
return $newData;
|
||||
} else {
|
||||
\OC_Log::write('core', 'Unable to migrate data from old cache for '.$data['path'].' because the storage was not found', \OC_Log::ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,4 +194,25 @@ class Upgrade {
|
||||
static function upgradeDone($user) {
|
||||
\OCP\Config::setUserValue($user, 'files', 'cache_version', 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a "silent" upgrade, i.e. without an Event-Source as triggered
|
||||
* on User-Login via Ajax. This method is called within the regular
|
||||
* ownCloud upgrade.
|
||||
*
|
||||
* @param string $user a User ID
|
||||
*/
|
||||
public static function doSilentUpgrade($user) {
|
||||
if(!self::needUpgrade($user)) {
|
||||
return;
|
||||
}
|
||||
$legacy = new \OC\Files\Cache\Legacy($user);
|
||||
if ($legacy->hasItems()) {
|
||||
\OC_DB::beginTransaction();
|
||||
$upgrade = new \OC\Files\Cache\Upgrade($legacy);
|
||||
$upgrade->upgradePath('/' . $user . '/files');
|
||||
\OC_DB::commit();
|
||||
}
|
||||
\OC\Files\Cache\Upgrade::upgradeDone($user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
* post_rename(oldpath,newpath)
|
||||
* copy(oldpath,newpath, &run) (if the newpath doesn't exists yes, copy, create and write will be emitted in that order)
|
||||
* post_rename(oldpath,newpath)
|
||||
* post_initMountPoints(user, user_dir)
|
||||
*
|
||||
* the &run parameter can be set to false to prevent the operation from occurring
|
||||
*/
|
||||
@@ -279,6 +280,9 @@ class Filesystem {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Chance to mount for other storages
|
||||
\OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user, 'user_dir' => $root));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -659,8 +663,4 @@ class Filesystem {
|
||||
}
|
||||
}
|
||||
|
||||
\OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Updater', 'writeHook');
|
||||
\OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Updater', 'deleteHook');
|
||||
\OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Updater', 'renameHook');
|
||||
|
||||
\OC_Util::setupFS();
|
||||
|
||||
@@ -77,7 +77,9 @@ class Mapper
|
||||
$result = $query->execute(array($path1.'%'));
|
||||
$updateQuery = \OC_DB::prepare('UPDATE `*PREFIX*file_map`'
|
||||
.' SET `logic_path` = ?'
|
||||
.' AND `physic_path` = ?'
|
||||
.' , `logic_path_hash` = ?'
|
||||
.' , `physic_path` = ?'
|
||||
.' , `physic_path_hash` = ?'
|
||||
.' WHERE `logic_path` = ?');
|
||||
while( $row = $result->fetchRow()) {
|
||||
$currentLogic = $row['logic_path'];
|
||||
@@ -86,7 +88,7 @@ class Mapper
|
||||
$newPhysic = $physicPath2.$this->stripRootFolder($currentPhysic, $physicPath1);
|
||||
if ($path1 !== $currentLogic) {
|
||||
try {
|
||||
$updateQuery->execute(array($newLogic, $newPhysic, $currentLogic));
|
||||
$updateQuery->execute(array($newLogic, md5($newLogic), $newPhysic, md5($newPhysic), $currentLogic));
|
||||
} catch (\Exception $e) {
|
||||
error_log('Mapper::Copy failed '.$currentLogic.' -> '.$newLogic.'\n'.$e);
|
||||
throw $e;
|
||||
@@ -149,7 +151,7 @@ class Mapper
|
||||
|
||||
// detect duplicates
|
||||
while ($this->resolvePhysicalPath($physicalPath) !== null) {
|
||||
$physicalPath = $this->slugifyPath($physicalPath, $index++);
|
||||
$physicalPath = $this->slugifyPath($logicPath, $index++);
|
||||
}
|
||||
|
||||
// insert the new path mapping if requested
|
||||
@@ -165,32 +167,41 @@ class Mapper
|
||||
$query->execute(array($logicPath, $physicalPath, md5($logicPath), md5($physicalPath)));
|
||||
}
|
||||
|
||||
private function slugifyPath($path, $index=null) {
|
||||
public function slugifyPath($path, $index=null) {
|
||||
$path = $this->stripRootFolder($path, $this->unchangedPhysicalRoot);
|
||||
|
||||
$pathElements = explode('/', $path);
|
||||
$sluggedElements = array();
|
||||
|
||||
// rip off the extension ext from last element
|
||||
$last= end($pathElements);
|
||||
$parts = pathinfo($last);
|
||||
$filename = $parts['filename'];
|
||||
array_pop($pathElements);
|
||||
array_push($pathElements, $filename);
|
||||
|
||||
foreach ($pathElements as $pathElement) {
|
||||
// remove empty elements
|
||||
if (empty($pathElement)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: remove file ext before slugify on last element
|
||||
$sluggedElements[] = self::slugify($pathElement);
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: add the index before the file extension
|
||||
//
|
||||
// apply index to file name
|
||||
if ($index !== null) {
|
||||
$last= end($sluggedElements);
|
||||
array_pop($sluggedElements);
|
||||
$last= array_pop($sluggedElements);
|
||||
array_push($sluggedElements, $last.'-'.$index);
|
||||
}
|
||||
|
||||
$sluggedPath = $this->unchangedPhysicalRoot.implode(DIRECTORY_SEPARATOR, $sluggedElements);
|
||||
// add back the extension
|
||||
if (isset($parts['extension'])) {
|
||||
$last= array_pop($sluggedElements);
|
||||
array_push($sluggedElements, $last.'.'.$parts['extension']);
|
||||
}
|
||||
|
||||
$sluggedPath = $this->unchangedPhysicalRoot.implode('/', $sluggedElements);
|
||||
return $this->stripLast($sluggedPath);
|
||||
}
|
||||
|
||||
@@ -210,7 +221,7 @@ class Mapper
|
||||
|
||||
// transliterate
|
||||
if (function_exists('iconv')) {
|
||||
$text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
|
||||
$text = iconv('utf-8', 'us-ascii//TRANSLIT//IGNORE', $text);
|
||||
}
|
||||
|
||||
// lowercase
|
||||
@@ -219,10 +230,8 @@ class Mapper
|
||||
// remove unwanted characters
|
||||
$text = preg_replace('~[^-\w]+~', '', $text);
|
||||
|
||||
if (empty($text))
|
||||
{
|
||||
// TODO: we better generate a guid in this case
|
||||
return 'n-a';
|
||||
if (empty($text)) {
|
||||
return uniqid();
|
||||
}
|
||||
|
||||
return $text;
|
||||
|
||||
@@ -90,7 +90,11 @@ class Mount {
|
||||
public function getStorageId() {
|
||||
if (!$this->storageId) {
|
||||
if (is_null($this->storage)) {
|
||||
$this->storage = $this->createStorage();
|
||||
$storage = $this->createStorage(); //FIXME: start using exceptions
|
||||
if (is_null($storage)) {
|
||||
return null;
|
||||
}
|
||||
$this->storage = $storage;
|
||||
}
|
||||
$this->storageId = $this->storage->getId();
|
||||
if (strlen($this->storageId) > 64) {
|
||||
|
||||
@@ -95,6 +95,9 @@ class Local extends \OC\Files\Storage\Common{
|
||||
// sets the modification time of the file to the given value.
|
||||
// If mtime is nil the current time is set.
|
||||
// note that the access time of the file always changes to the current time.
|
||||
if($this->file_exists($path) and !$this->isUpdatable($path)) {
|
||||
return false;
|
||||
}
|
||||
if(!is_null($mtime)) {
|
||||
$result=touch( $this->datadir.$path, $mtime );
|
||||
}else{
|
||||
|
||||
@@ -50,7 +50,7 @@ class MappedLocal extends \OC\Files\Storage\Common{
|
||||
continue;
|
||||
}
|
||||
|
||||
$logicalFilePath = $this->mapper->physicalToLogic($physicalPath.DIRECTORY_SEPARATOR.$file);
|
||||
$logicalFilePath = $this->mapper->physicalToLogic($physicalPath.'/'.$file);
|
||||
|
||||
$file= $this->mapper->stripRootFolder($logicalFilePath, $logicalPath);
|
||||
$file = $this->stripLeading($file);
|
||||
@@ -130,7 +130,7 @@ class MappedLocal extends \OC\Files\Storage\Common{
|
||||
public function file_get_contents($path) {
|
||||
return file_get_contents($this->buildPath($path));
|
||||
}
|
||||
public function file_put_contents($path, $data) {//trigger_error("$path = ".var_export($path, 1));
|
||||
public function file_put_contents($path, $data) {
|
||||
return file_put_contents($this->buildPath($path), $data);
|
||||
}
|
||||
public function unlink($path) {
|
||||
@@ -280,7 +280,7 @@ class MappedLocal extends \OC\Files\Storage\Common{
|
||||
foreach (scandir($physicalDir) as $item) {
|
||||
if ($item == '.' || $item == '..')
|
||||
continue;
|
||||
$physicalItem = $this->mapper->physicalToLogic($physicalDir.DIRECTORY_SEPARATOR.$item);
|
||||
$physicalItem = $this->mapper->physicalToLogic($physicalDir.'/'.$item);
|
||||
$item = substr($physicalItem, strlen($physicalDir)+1);
|
||||
|
||||
if(strstr(strtolower($item), strtolower($query)) !== false) {
|
||||
@@ -331,6 +331,9 @@ class MappedLocal extends \OC\Files\Storage\Common{
|
||||
if(strpos($path, '/') === 0) {
|
||||
$path = substr($path, 1);
|
||||
}
|
||||
if(strpos($path, '\\') === 0) {
|
||||
$path = substr($path, 1);
|
||||
}
|
||||
if ($path === false) {
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -267,7 +267,7 @@ class View {
|
||||
$path = $this->getRelativePath($absolutePath);
|
||||
$exists = $this->file_exists($path);
|
||||
$run = true;
|
||||
if ($this->fakeRoot == Filesystem::getRoot()) {
|
||||
if ($this->fakeRoot == Filesystem::getRoot() && ! Cache\Scanner::isIgnoredFile($path) ) {
|
||||
if (!$exists) {
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME,
|
||||
@@ -295,7 +295,7 @@ class View {
|
||||
list ($count, $result) = \OC_Helper::streamCopy($data, $target);
|
||||
fclose($target);
|
||||
fclose($data);
|
||||
if ($this->fakeRoot == Filesystem::getRoot()) {
|
||||
if ($this->fakeRoot == Filesystem::getRoot() && ! Cache\Scanner::isIgnoredFile($path) ) {
|
||||
if (!$exists) {
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME,
|
||||
@@ -627,7 +627,7 @@ class View {
|
||||
private function runHooks($hooks, $path, $post = false) {
|
||||
$prefix = ($post) ? 'post_' : '';
|
||||
$run = true;
|
||||
if (Filesystem::$loaded and $this->fakeRoot == Filesystem::getRoot()) {
|
||||
if (Filesystem::$loaded and $this->fakeRoot == Filesystem::getRoot() && ! Cache\Scanner::isIgnoredFile($path) ) {
|
||||
foreach ($hooks as $hook) {
|
||||
if ($hook != 'read') {
|
||||
\OC_Hook::emit(
|
||||
|
||||
@@ -135,7 +135,7 @@ class OC_Installer{
|
||||
|
||||
// check if the app is compatible with this version of ownCloud
|
||||
$version=OC_Util::getVersion();
|
||||
if(!isset($info['require']) or ($version[0]>$info['require'])) {
|
||||
if(!isset($info['require']) or !OC_App::isAppVersionCompatible($version, $info['require'])) {
|
||||
OC_Log::write('core',
|
||||
'App can\'t be installed because it is not compatible with this version of ownCloud',
|
||||
OC_Log::ERROR);
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
"Offending command was: \"%s\", name: %s, password: %s" => "Fehlerhafter Befehl war: \"%s\", Name: %s, Passwort: %s",
|
||||
"MS SQL username and/or password not valid: %s" => "MS SQL Benutzername und/oder Password ungültig: %s",
|
||||
"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Dein Web-Server ist noch nicht für Datei-Synchronisation bereit, weil die WebDAV-Schnittstelle vermutlich defekt ist.",
|
||||
"Please double check the <a href='%s'>installation guides</a>." => "Bitte prüfe die <a href='%s'>Instalationsanleitungen</a>.",
|
||||
"Please double check the <a href='%s'>installation guides</a>." => "Bitte prüfe die <a href='%s'>Installationsanleitungen</a>.",
|
||||
"seconds ago" => "Gerade eben",
|
||||
"1 minute ago" => "Vor einer Minute",
|
||||
"%d minutes ago" => "Vor %d Minuten",
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
"Offending command was: \"%s\", name: %s, password: %s" => "Fehlerhafter Befehl war: \"%s\", Name: %s, Passwort: %s",
|
||||
"MS SQL username and/or password not valid: %s" => "MS SQL Benutzername und/oder Passwort ungültig: %s",
|
||||
"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Ihr Web-Server ist noch nicht für Datei-Synchronisation bereit, weil die WebDAV-Schnittstelle vermutlich defekt ist.",
|
||||
"Please double check the <a href='%s'>installation guides</a>." => "Bitte prüfen Sie die <a href='%s'>Instalationsanleitungen</a>.",
|
||||
"Please double check the <a href='%s'>installation guides</a>." => "Bitte prüfen Sie die <a href='%s'>Installationsanleitungen</a>.",
|
||||
"seconds ago" => "Gerade eben",
|
||||
"1 minute ago" => "Vor einer Minute",
|
||||
"%d minutes ago" => "Vor %d Minuten",
|
||||
|
||||
@@ -70,6 +70,10 @@ class OC_Setup {
|
||||
$password = htmlspecialchars_decode($options['adminpass']);
|
||||
$datadir = htmlspecialchars_decode($options['directory']);
|
||||
|
||||
if (OC_Util::runningOnWindows()) {
|
||||
$datadir = rtrim(realpath($datadir), '\\');
|
||||
}
|
||||
|
||||
//use sqlite3 when available, otherise sqlite2 will be used.
|
||||
if($dbtype=='sqlite' and class_exists('SQLite3')) {
|
||||
$dbtype='sqlite3';
|
||||
@@ -329,7 +333,7 @@ class OC_Setup {
|
||||
//add prefix to the postgresql user name to prevent collisions
|
||||
$dbusername='oc_'.$username;
|
||||
//create a new password so we don't need to store the admin config in the config file
|
||||
$dbpassword=md5(time());
|
||||
$dbpassword=md5(OC_Util::generate_random_bytes(30));
|
||||
|
||||
self::pg_createDBUser($dbusername, $dbpassword, $connection);
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ class OC_TemplateLayout extends OC_Template {
|
||||
} else {
|
||||
parent::__construct('core', 'layout.base');
|
||||
}
|
||||
$versionParameter = '?v=' . md5(implode(OC_Util::getVersion()));
|
||||
// Add the js files
|
||||
$jsfiles = self::findJavascriptFiles(OC_Util::$scripts);
|
||||
$this->assign('jsfiles', array(), false);
|
||||
@@ -44,20 +45,20 @@ class OC_TemplateLayout extends OC_Template {
|
||||
$this->append( 'jsfiles', OC_Helper::linkToRoute('js_config'));
|
||||
}
|
||||
if (!empty(OC_Util::$core_scripts)) {
|
||||
$this->append( 'jsfiles', OC_Helper::linkToRemoteBase('core.js', false));
|
||||
$this->append( 'jsfiles', OC_Helper::linkToRemoteBase('core.js', false) . $versionParameter);
|
||||
}
|
||||
foreach($jsfiles as $info) {
|
||||
$root = $info[0];
|
||||
$web = $info[1];
|
||||
$file = $info[2];
|
||||
$this->append( 'jsfiles', $web.'/'.$file);
|
||||
$this->append( 'jsfiles', $web.'/'.$file . $versionParameter);
|
||||
}
|
||||
|
||||
// Add the css files
|
||||
$cssfiles = self::findStylesheetFiles(OC_Util::$styles);
|
||||
$this->assign('cssfiles', array());
|
||||
if (!empty(OC_Util::$core_styles)) {
|
||||
$this->append( 'cssfiles', OC_Helper::linkToRemoteBase('core.css', false));
|
||||
$this->append( 'cssfiles', OC_Helper::linkToRemoteBase('core.css', false) . $versionParameter);
|
||||
}
|
||||
foreach($cssfiles as $info) {
|
||||
$root = $info[0];
|
||||
@@ -77,10 +78,10 @@ class OC_TemplateLayout extends OC_Template {
|
||||
$app = $paths[0];
|
||||
unset($paths[0]);
|
||||
$path = implode('/', $paths);
|
||||
$this->append( 'cssfiles', OC_Helper::linkTo($app, $path));
|
||||
$this->append( 'cssfiles', OC_Helper::linkTo($app, $path) . $versionParameter);
|
||||
}
|
||||
else {
|
||||
$this->append( 'cssfiles', $web.'/'.$file);
|
||||
$this->append( 'cssfiles', $web.'/'.$file . $versionParameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
25
lib/util.php
25
lib/util.php
@@ -75,7 +75,7 @@ class OC_Util {
|
||||
public static function getVersion() {
|
||||
// hint: We only can count up. Reset minor/patchlevel when
|
||||
// updating major/minor version number.
|
||||
return array(5, 00, 00);
|
||||
return array(5, 00, 6);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,7 +83,7 @@ class OC_Util {
|
||||
* @return string
|
||||
*/
|
||||
public static function getVersionString() {
|
||||
return '5.0';
|
||||
return '5.0.5';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -278,7 +278,10 @@ class OC_Util {
|
||||
'hint'=>'Please ask your server administrator to install the module.');
|
||||
$web_server_restart= false;
|
||||
}
|
||||
if(ini_get('safe_mode')) {
|
||||
if (((strtolower(@ini_get('safe_mode')) == 'on')
|
||||
|| (strtolower(@ini_get('safe_mode')) == 'yes')
|
||||
|| (strtolower(@ini_get('safe_mode')) == 'true')
|
||||
|| (ini_get("safe_mode") == 1 ))) {
|
||||
$errors[]=array('error'=>'PHP Safe Mode is enabled. ownCloud requires that it is disabled to work properly.',
|
||||
'hint'=>'PHP Safe Mode is a deprecated and mostly useless setting that should be disabled. Please ask your server administrator to disable it in php.ini or in your webserver config.');
|
||||
$web_server_restart= false;
|
||||
@@ -630,16 +633,26 @@ class OC_Util {
|
||||
* Check if the ownCloud server can connect to the internet
|
||||
*/
|
||||
public static function isinternetconnectionworking() {
|
||||
|
||||
$proxy = OC_Config::getValue('proxy', '');
|
||||
if($proxy <> '') {
|
||||
list($proxy_host, $proxy_port) = explode(':',$proxy);
|
||||
$connected = @fsockopen($proxy_host, $proxy_port, $errno, $errstr, 5);
|
||||
if ($connected) {
|
||||
fclose($connected);
|
||||
return true;
|
||||
}
|
||||
\OC_Log::write('core', 'Couldn\'t connect to proxy server', \OC_log::WARN);
|
||||
return false;
|
||||
}
|
||||
// try to connect to owncloud.org to see if http connections to the internet are possible.
|
||||
$connected = @fsockopen("www.owncloud.org", 80);
|
||||
$connected = @fsockopen("www.owncloud.org", 80, $errno, $errstr, 10);
|
||||
if ($connected) {
|
||||
fclose($connected);
|
||||
return true;
|
||||
}else{
|
||||
|
||||
// second try in case one server is down
|
||||
$connected = @fsockopen("apps.owncloud.com", 80);
|
||||
$connected = @fsockopen("apps.owncloud.com", 80, $errno, $errstr, 10);
|
||||
if ($connected) {
|
||||
fclose($connected);
|
||||
return true;
|
||||
|
||||
@@ -44,7 +44,7 @@ if (OC_User::isAdminUser(OC_User::getUser())) {
|
||||
foreach ($batch as $user) {
|
||||
$users[] = array(
|
||||
'name' => $user,
|
||||
'displayname' => OC_User::determineDisplayName($user),
|
||||
'displayname' => OC_User::getDisplayName($user),
|
||||
'groups' => join(', ', OC_Group::getUserGroups($user)),
|
||||
'quota' => OC_Preferences::getValue($user, 'files', 'quota', 'default'));
|
||||
}
|
||||
|
||||
@@ -75,7 +75,13 @@ OC.Settings.Apps = OC.Settings.Apps || {
|
||||
element.data('active',true);
|
||||
element.val(t('settings','Disable'));
|
||||
}
|
||||
},'json');
|
||||
},'json')
|
||||
.fail(function() {
|
||||
OC.dialogs.alert('Error while enabling app','Error');
|
||||
element.data('active',false);
|
||||
OC.Settings.Apps.removeNavigation(appid);
|
||||
element.val(t('settings','Enable'));
|
||||
});
|
||||
$('#leftcontent li[data-id="'+appid+'"]').addClass('active');
|
||||
}
|
||||
},
|
||||
@@ -136,7 +142,9 @@ OC.Settings.Apps = OC.Settings.Apps || {
|
||||
li.attr('data-id', entry.id);
|
||||
var img= $('<img class="icon"/>').attr({ src: entry.icon});
|
||||
var a=$('<a></a>').attr('href', entry.href);
|
||||
a.text(entry.name);
|
||||
var filename=$('<span></span>')
|
||||
filename.text(entry.name);
|
||||
a.prepend(filename);
|
||||
a.prepend(img);
|
||||
li.append(a);
|
||||
container.append(li);
|
||||
|
||||
@@ -4,8 +4,21 @@
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
function setQuota (uid, quota, ready) {
|
||||
$.post(
|
||||
OC.filePath('settings', 'ajax', 'setquota.php'),
|
||||
{username: uid, quota: quota},
|
||||
function (result) {
|
||||
if (ready) {
|
||||
ready(result.data.quota);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
var UserList = {
|
||||
useUndo: true,
|
||||
availableGroups: [],
|
||||
|
||||
/**
|
||||
* @brief Initiate user deletion process in UI
|
||||
@@ -71,15 +84,14 @@ var UserList = {
|
||||
tr.attr('data-uid', username);
|
||||
tr.attr('data-displayName', displayname);
|
||||
tr.find('td.name').text(username);
|
||||
tr.find('td.displayName').text(username);
|
||||
tr.find('td.displayName').text(displayname);
|
||||
var groupsSelect = $('<select multiple="multiple" class="groupsselect" data-placehoder="Groups" title="' + t('settings', 'Groups') + '"></select>').attr('data-username', username).attr('data-user-groups', groups);
|
||||
tr.find('td.groups').empty();
|
||||
if (tr.find('td.subadmins').length > 0) {
|
||||
var subadminSelect = $('<select multiple="multiple" class="subadminsselect" data-placehoder="subadmins" title="' + t('settings', 'Group Admin') + '">').attr('data-username', username).attr('data-user-groups', groups).attr('data-subadmin', subadmin);
|
||||
tr.find('td.subadmins').empty();
|
||||
}
|
||||
var allGroups = String($('#content table').attr('data-groups')).split(', ');
|
||||
$.each(allGroups, function (i, group) {
|
||||
$.each(this.availableGroups, function (i, group) {
|
||||
groupsSelect.append($('<option value="' + escapeHTML(group) + '">' + escapeHTML(group) + '</option>'));
|
||||
if (typeof subadminSelect !== 'undefined' && group != 'admin') {
|
||||
subadminSelect.append($('<option value="' + escapeHTML(group) + '">' + escapeHTML(group) + '</option>'));
|
||||
@@ -114,30 +126,78 @@ var UserList = {
|
||||
quotaSelect.append('<option value="' + escapeHTML(quota) + '" selected="selected">' + escapeHTML(quota) + '</option>');
|
||||
}
|
||||
}
|
||||
var added = false;
|
||||
$(tr).appendTo('tbody');
|
||||
if (sort) {
|
||||
displayname = displayname.toLowerCase();
|
||||
$('tbody tr').each(function () {
|
||||
if (displayname < $(this).attr('data-uid').toLowerCase()) {
|
||||
$(tr).insertBefore($(this));
|
||||
added = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
UserList.doSort();
|
||||
}
|
||||
if (!added) {
|
||||
$(tr).appendTo('tbody');
|
||||
}
|
||||
return tr;
|
||||
},
|
||||
|
||||
update: function () {
|
||||
if (typeof UserList.offset === 'undefined') {
|
||||
UserList.offset = $('tbody tr').length;
|
||||
quotaSelect.singleSelect();
|
||||
quotaSelect.on('change', function () {
|
||||
var uid = $(this).parent().parent().attr('data-uid');
|
||||
var quota = $(this).val();
|
||||
setQuota(uid, quota);
|
||||
});
|
||||
},
|
||||
// From http://my.opera.com/GreyWyvern/blog/show.dml/1671288
|
||||
alphanum: function(a, b) {
|
||||
function chunkify(t) {
|
||||
var tz = [], x = 0, y = -1, n = 0, i, j;
|
||||
|
||||
while (i = (j = t.charAt(x++)).charCodeAt(0)) {
|
||||
var m = (i == 46 || (i >=48 && i <= 57));
|
||||
if (m !== n) {
|
||||
tz[++y] = "";
|
||||
n = m;
|
||||
}
|
||||
tz[y] += j;
|
||||
}
|
||||
return tz;
|
||||
}
|
||||
|
||||
var aa = chunkify(a.toLowerCase());
|
||||
var bb = chunkify(b.toLowerCase());
|
||||
|
||||
for (x = 0; aa[x] && bb[x]; x++) {
|
||||
if (aa[x] !== bb[x]) {
|
||||
var c = Number(aa[x]), d = Number(bb[x]);
|
||||
if (c == aa[x] && d == bb[x]) {
|
||||
return c - d;
|
||||
} else return (aa[x] > bb[x]) ? 1 : -1;
|
||||
}
|
||||
}
|
||||
return aa.length - bb.length;
|
||||
},
|
||||
doSort: function() {
|
||||
var self = this;
|
||||
var rows = $('tbody tr').get();
|
||||
|
||||
rows.sort(function(a, b) {
|
||||
return UserList.alphanum($(a).find('td.name').text(), $(b).find('td.name').text());
|
||||
});
|
||||
|
||||
var items = [];
|
||||
$.each(rows, function(index, row) {
|
||||
items.push(row);
|
||||
if(items.length === 100) {
|
||||
$('tbody').append(items);
|
||||
items = [];
|
||||
}
|
||||
});
|
||||
if(items.length > 0) {
|
||||
$('tbody').append(items);
|
||||
}
|
||||
},
|
||||
update: function () {
|
||||
if (UserList.updating) {
|
||||
return;
|
||||
}
|
||||
UserList.updating = true;
|
||||
$.get(OC.Router.generate('settings_ajax_userlist', { offset: UserList.offset }), function (result) {
|
||||
if (result.status === 'success') {
|
||||
$.each(result.data, function (index, user) {
|
||||
if($('tr[data-uid="' + user.name + '"]').length > 0) {
|
||||
return true;
|
||||
}
|
||||
var tr = UserList.add(user.name, user.displayname, user.groups, user.subadmin, user.quota, false);
|
||||
UserList.offset++;
|
||||
if (index == 9) {
|
||||
@@ -147,7 +207,11 @@ var UserList = {
|
||||
});
|
||||
}
|
||||
});
|
||||
if (result.data.length > 0) {
|
||||
UserList.doSort();
|
||||
}
|
||||
}
|
||||
UserList.updating = false;
|
||||
});
|
||||
},
|
||||
|
||||
@@ -172,7 +236,14 @@ var UserList = {
|
||||
username: user,
|
||||
group: group
|
||||
},
|
||||
function () {
|
||||
function (response) {
|
||||
if(response.status === 'success' && response.data.action === 'add') {
|
||||
if(UserList.availableGroups.indexOf(response.data.gropname) === -1) {
|
||||
UserList.availableGroups.push(response.data.gropname);
|
||||
}
|
||||
} else {
|
||||
OC.Notification.show(response.data.message);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
@@ -242,24 +313,15 @@ var UserList = {
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
UserList.doSort();
|
||||
UserList.availableGroups = $('#content table').attr('data-groups').split(', ');
|
||||
UserList.offset = $('tbody tr').length;
|
||||
$('tbody tr:last').bind('inview', function (event, isInView, visiblePartX, visiblePartY) {
|
||||
OC.Router.registerLoadedCallback(function () {
|
||||
UserList.update();
|
||||
});
|
||||
});
|
||||
|
||||
function setQuota (uid, quota, ready) {
|
||||
$.post(
|
||||
OC.filePath('settings', 'ajax', 'setquota.php'),
|
||||
{username: uid, quota: quota},
|
||||
function (result) {
|
||||
if (ready) {
|
||||
ready(result.data.quota);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$('select[multiple]').each(function (index, element) {
|
||||
UserList.applyMultiplySelect($(element));
|
||||
});
|
||||
@@ -373,7 +435,11 @@ $(document).ready(function () {
|
||||
OC.dialogs.alert(result.data.message,
|
||||
t('settings', 'Error creating user'));
|
||||
} else {
|
||||
UserList.add(username, username, result.data.groups, null, 'default', true);
|
||||
var addedGroups = result.data.groups.split(', ');
|
||||
UserList.availableGroups = $.unique($.merge(UserList.availableGroups, addedGroups));
|
||||
if($('tr[data-uid="' + username + '"]').length === 0) {
|
||||
UserList.add(username, username, result.data.groups, null, 'default', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -14,15 +14,15 @@
|
||||
"Admins can't remove themself from the admin group" => "Administratoren können sich nicht selbst aus der Admin-Gruppe löschen.",
|
||||
"Unable to add user to group %s" => "Der Benutzer konnte nicht zur Gruppe %s hinzugefügt werden",
|
||||
"Unable to remove user from group %s" => "Der Benutzer konnte nicht aus der Gruppe %s entfernt werden",
|
||||
"Couldn't update app." => "Die App konnte nicht geupdated werden.",
|
||||
"Update to {appversion}" => "Update zu {appversion}",
|
||||
"Couldn't update app." => "Die App konnte nicht aktualisiert werden.",
|
||||
"Update to {appversion}" => "Aktualisierung zu {appversion}",
|
||||
"Disable" => "Deaktivieren",
|
||||
"Enable" => "Aktivieren",
|
||||
"Please wait...." => "Bitte warten...",
|
||||
"Updating...." => "Update...",
|
||||
"Updating...." => "Aktualisieren...",
|
||||
"Error while updating app" => "Fehler beim Aktualisieren der App",
|
||||
"Error" => "Fehler",
|
||||
"Updated" => "Geupdated",
|
||||
"Updated" => "Aktualisiert",
|
||||
"Saving..." => "Speichern...",
|
||||
"deleted" => "gelöscht",
|
||||
"undo" => "rückgängig machen",
|
||||
@@ -32,14 +32,14 @@
|
||||
"Delete" => "Löschen",
|
||||
"add group" => "Gruppe hinzufügen",
|
||||
"A valid username must be provided" => "Es muss ein gültiger Benutzername angegeben werden",
|
||||
"Error creating user" => "Beim anlegen des Benutzers ist ein Fehler aufgetreten",
|
||||
"Error creating user" => "Beim Anlegen des Benutzers ist ein Fehler aufgetreten",
|
||||
"A valid password must be provided" => "Es muss ein gültiges Passwort angegeben werden",
|
||||
"__language_name__" => "Deutsch (Persönlich)",
|
||||
"Security Warning" => "Sicherheitswarnung",
|
||||
"Your data directory and your files are probably accessible from the internet. The .htaccess file that ownCloud provides is not working. We strongly suggest that you configure your webserver in a way that the data directory is no longer accessible or you move the data directory outside the webserver document root." => "Dein Datenverzeichnis und Deine Datein sind vielleicht vom Internet aus erreichbar. Die .htaccess Datei, die ownCloud verwendet, arbeitet nicht richtig. Wir schlagen Dir dringend vor, dass Du Deinen Webserver so konfigurierst, dass das Datenverzeichnis nicht länger erreichbar ist oder, dass Du Dein Datenverzeichnis aus dem Dokumenten-root des Webservers bewegst.",
|
||||
"Setup Warning" => "Einrichtungswarnung",
|
||||
"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Dein Web-Server ist noch nicht für Datei-Synchronisation bereit, weil die WebDAV-Schnittstelle vermutlich defekt ist.",
|
||||
"Please double check the <a href='%s'>installation guides</a>." => "Bitte prüfen Sie die <a href='%s'>Instalationsanleitungen</a>.",
|
||||
"Please double check the <a href='%s'>installation guides</a>." => "Bitte prüfe die <a href='%s'>Instalationsanleitungen</a>.",
|
||||
"Module 'fileinfo' missing" => "Modul 'fileinfo' fehlt ",
|
||||
"The PHP module 'fileinfo' is missing. We strongly recommend to enable this module to get best results with mime-type detection." => "Das PHP-Modul 'fileinfo' fehlt. Wir empfehlen dieses Modul zu aktivieren um die besten Resultate bei der Erkennung der Dateitypen zu erreichen.",
|
||||
"Locale not working" => "Ländereinstellung funktioniert nicht",
|
||||
@@ -49,20 +49,20 @@
|
||||
"Cron" => "Cron",
|
||||
"Execute one task with each page loaded" => "Führe eine Aufgabe mit jeder geladenen Seite aus",
|
||||
"cron.php is registered at a webcron service. Call the cron.php page in the owncloud root once a minute over http." => "cron.php ist an einem Webcron-Service registriert. Die cron.php Seite wird einmal pro Minute über http abgerufen.",
|
||||
"Use systems cron service. Call the cron.php file in the owncloud folder via a system cronjob once a minute." => "Nutze den Cron Systemdienst. Rufe die Datei cron.php im owncloud Ordner einmal pro Minute über einen Cronjob auf.",
|
||||
"Use systems cron service. Call the cron.php file in the owncloud folder via a system cronjob once a minute." => "Verwende den Cron Systemdienst. Rufe die Datei cron.php im owncloud Ordner einmal pro Minute über einen Cronjob auf.",
|
||||
"Sharing" => "Teilen",
|
||||
"Enable Share API" => "Aktiviere Sharing-API",
|
||||
"Allow apps to use the Share API" => "Erlaube Apps die Nutzung der Share-API",
|
||||
"Allow links" => "Erlaube Links",
|
||||
"Allow users to share items to the public with links" => "Erlaube Benutzern Inhalte über öffentliche Links zu teilen",
|
||||
"Allow resharing" => "Erlaube erneutes teilen",
|
||||
"Allow users to share items shared with them again" => "Erlaube Benutzern mit ihnen geteilte Inhalte erneut zu teilen",
|
||||
"Allow users to share with anyone" => "Erlaube Benutzern mit jedem zu teilen",
|
||||
"Allow users to only share with users in their groups" => "Erlaube Benutzern nur mit Benutzern ihrer Gruppe zu teilen",
|
||||
"Allow users to share items to the public with links" => "Erlaube Benutzern, Inhalte über öffentliche Links zu teilen",
|
||||
"Allow resharing" => "Erlaube erneutes Teilen",
|
||||
"Allow users to share items shared with them again" => "Erlaube Benutzern, mit ihnen geteilte Inhalte erneut zu teilen",
|
||||
"Allow users to share with anyone" => "Erlaube Benutzern, mit jedem zu teilen",
|
||||
"Allow users to only share with users in their groups" => "Erlaube Benutzern, nur mit Benutzern ihrer Gruppe zu teilen",
|
||||
"Security" => "Sicherheit",
|
||||
"Enforce HTTPS" => "Erzwinge HTTPS",
|
||||
"Enforces the clients to connect to ownCloud via an encrypted connection." => "Erzwingt die Verwendung einer verschlüsselten Verbindung",
|
||||
"Please connect to this ownCloud instance via HTTPS to enable or disable the SSL enforcement." => "Bitte verbinden Sie sich über eine HTTPS Verbindung mit diesem ownCloud Server um diese Einstellung zu ändern",
|
||||
"Please connect to this ownCloud instance via HTTPS to enable or disable the SSL enforcement." => "Bitte verbinde Dich über eine HTTPS Verbindung mit diesem ownCloud Server um diese Einstellung zu ändern",
|
||||
"Log" => "Log",
|
||||
"Log level" => "Loglevel",
|
||||
"More" => "Mehr",
|
||||
@@ -91,7 +91,7 @@
|
||||
"Change password" => "Passwort ändern",
|
||||
"Display Name" => "Anzeigename",
|
||||
"Your display name was changed" => "Dein Anzeigename wurde geändert",
|
||||
"Unable to change your display name" => "Das Ändern deines Anzeigenamens ist nicht möglich",
|
||||
"Unable to change your display name" => "Das Ändern Deines Anzeigenamens ist nicht möglich",
|
||||
"Change display name" => "Anzeigenamen ändern",
|
||||
"Email" => "E-Mail",
|
||||
"Your email address" => "Deine E-Mail-Adresse",
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
"Admins can't remove themself from the admin group" => "Administratoren können sich nicht selbst aus der admin-Gruppe löschen",
|
||||
"Unable to add user to group %s" => "Der Benutzer konnte nicht zur Gruppe %s hinzugefügt werden",
|
||||
"Unable to remove user from group %s" => "Der Benutzer konnte nicht aus der Gruppe %s entfernt werden",
|
||||
"Couldn't update app." => "Die App konnte nicht geupdated werden.",
|
||||
"Update to {appversion}" => "Update zu {appversion}",
|
||||
"Couldn't update app." => "Die App konnte nicht aktualisiert werden.",
|
||||
"Update to {appversion}" => "Aktualisierung zu {appversion}",
|
||||
"Disable" => "Deaktivieren",
|
||||
"Enable" => "Aktivieren",
|
||||
"Please wait...." => "Bitte warten....",
|
||||
"Updating...." => "Update...",
|
||||
"Error while updating app" => "Es ist ein Fehler während des Updates aufgetreten",
|
||||
"Updating...." => "Aktualisieren...",
|
||||
"Error while updating app" => "Fehler beim Aktualisieren der App",
|
||||
"Error" => "Fehler",
|
||||
"Updated" => "Aktualisiert",
|
||||
"Saving..." => "Speichern...",
|
||||
@@ -32,7 +32,7 @@
|
||||
"Delete" => "Löschen",
|
||||
"add group" => "Gruppe hinzufügen",
|
||||
"A valid username must be provided" => "Es muss ein gültiger Benutzername angegeben werden",
|
||||
"Error creating user" => "Beim Erstellen des Benutzers ist ein Fehler aufgetreten",
|
||||
"Error creating user" => "Beim Anlegen des Benutzers ist ein Fehler aufgetreten",
|
||||
"A valid password must be provided" => "Es muss ein gültiges Passwort angegeben werden",
|
||||
"__language_name__" => "Deutsch (Förmlich: Sie)",
|
||||
"Security Warning" => "Sicherheitshinweis",
|
||||
@@ -49,16 +49,16 @@
|
||||
"Cron" => "Cron",
|
||||
"Execute one task with each page loaded" => "Führe eine Aufgabe bei jedem Laden der Seite aus",
|
||||
"cron.php is registered at a webcron service. Call the cron.php page in the owncloud root once a minute over http." => "cron.php ist bei einem Webcron-Service registriert. Die cron.php Seite im ownCloud Wurzelverzeichniss wird einmal pro Minute über http abgerufen.",
|
||||
"Use systems cron service. Call the cron.php file in the owncloud folder via a system cronjob once a minute." => "Nutzen Sie den Cron Systemdienst. Rufen Sie die Datei cron.php im ownCloud Ordner einmal pro Minute über einen Cronjob auf.",
|
||||
"Use systems cron service. Call the cron.php file in the owncloud folder via a system cronjob once a minute." => "Verwenden Sie den Cron Systemdienst. Rufen Sie die Datei cron.php im ownCloud Ordner einmal pro Minute über einen Cronjob auf.",
|
||||
"Sharing" => "Teilen",
|
||||
"Enable Share API" => "Share-API aktivieren",
|
||||
"Allow apps to use the Share API" => "Erlaube es Anwendungen, die Share-API zu benutzen",
|
||||
"Allow links" => "Links erlauben",
|
||||
"Allow users to share items to the public with links" => "Erlaube es Benutzern, Items per öffentlichem Link zu teilen",
|
||||
"Allow users to share items to the public with links" => "Erlaube es Benutzern, Inhalte per öffentlichem Link zu teilen",
|
||||
"Allow resharing" => "Erlaube weiterverteilen",
|
||||
"Allow users to share items shared with them again" => "Erlaubt Nutzern mit ihnen geteilte Inhalte erneut zu teilen",
|
||||
"Allow users to share with anyone" => "Erlaube Nutzern mit jedem zu teilen",
|
||||
"Allow users to only share with users in their groups" => "Erlaube Nutzern nur mit Nutzern in ihrer Gruppe zu teilen",
|
||||
"Allow users to share items shared with them again" => "Erlaubt Benutzern, mit ihnen geteilte Inhalte erneut zu teilen",
|
||||
"Allow users to share with anyone" => "Erlaube Benutzern, mit jedem zu teilen",
|
||||
"Allow users to only share with users in their groups" => "Erlaube Benutzern, nur mit Nutzern in ihrer Gruppe zu teilen",
|
||||
"Security" => "Sicherheit",
|
||||
"Enforce HTTPS" => "HTTPS erzwingen",
|
||||
"Enforces the clients to connect to ownCloud via an encrypted connection." => "Zwingt die Clients, sich über eine verschlüsselte Verbindung mit ownCloud zu verbinden.",
|
||||
|
||||
@@ -229,7 +229,7 @@ endfor;?>
|
||||
<fieldset class="personalblock">
|
||||
<legend><strong><?php p($l->t('Version'));?></strong></legend>
|
||||
<strong>ownCloud</strong> <?php p(OC_Util::getVersionString()); ?> <?php p(OC_Util::getEditionString()); ?>
|
||||
(<?php p(OC_Updater::ShowUpdatingHint()); ?>)<br/>
|
||||
(<?php print_unescaped(OC_Updater::ShowUpdatingHint()); ?>)<br/>
|
||||
<?php print_unescaped($l->t('Developed by the <a href="http://ownCloud.org/contact" target="_blank">ownCloud community</a>, the <a href="https://github.com/owncloud" target="_blank">source code</a> is licensed under the <a href="http://www.gnu.org/licenses/agpl-3.0.html" target="_blank"><abbr title="Affero General Public License">AGPL</abbr></a>.')); ?>
|
||||
</fieldset>
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ $_['subadmingroups'] = array_flip($items);
|
||||
<?php p($_['default_quota']);?>
|
||||
</option>
|
||||
<?php endif;?>
|
||||
<option value='other'>
|
||||
<option data-new value='other'>
|
||||
<?php p($l->t('Other'));?>
|
||||
...
|
||||
</option>
|
||||
|
||||
@@ -64,6 +64,14 @@ class Test_App extends PHPUnit_Framework_TestCase {
|
||||
}
|
||||
|
||||
|
||||
public function testIsAppVersionCompatibleShouldWorkForPreAlpha(){
|
||||
$oc = array(5, 0, 3);
|
||||
$app = '4.93';
|
||||
|
||||
$this->assertTrue(OC_App::isAppVersionCompatible($oc, $app));
|
||||
}
|
||||
|
||||
|
||||
public function testIsAppVersionCompatibleShouldFailOneVersionNumbers(){
|
||||
$oc = array(4, 3, 1);
|
||||
$app = '5';
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
require_once 'archive.php';
|
||||
|
||||
if (!OC_Util::runningOnWindows()) {
|
||||
class Test_Archive_TAR extends Test_Archive {
|
||||
protected function getExisting() {
|
||||
$dir = OC::$SERVERROOT . '/tests/data';
|
||||
@@ -18,3 +19,4 @@ class Test_Archive_TAR extends Test_Archive {
|
||||
return new OC_Archive_TAR(OCP\Files::tmpFile('.tar.gz'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
require_once 'archive.php';
|
||||
|
||||
if (!OC_Util::runningOnWindows()) {
|
||||
class Test_Archive_ZIP extends Test_Archive {
|
||||
protected function getExisting() {
|
||||
$dir = OC::$SERVERROOT . '/tests/data';
|
||||
@@ -18,3 +19,4 @@ class Test_Archive_ZIP extends Test_Archive {
|
||||
return new OC_Archive_ZIP(OCP\Files::tmpFile('.zip'));
|
||||
}
|
||||
}
|
||||
}
|
||||
19
tests/lib/autoloader.php
Normal file
19
tests/lib/autoloader.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) 2013 Thomas Müller <thomas.mueller@tmit.eu>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
class Test_AutoLoader extends PHPUnit_Framework_TestCase {
|
||||
|
||||
public function testLeadingSlashOnClassName(){
|
||||
$this->assertTrue(class_exists('\OC\Files\Storage\Local'));
|
||||
}
|
||||
|
||||
public function testNoLeadingSlashOnClassName(){
|
||||
$this->assertTrue(class_exists('OC\Files\Storage\Local'));
|
||||
}
|
||||
|
||||
}
|
||||
5
tests/lib/files/cache/updater.php
vendored
5
tests/lib/files/cache/updater.php
vendored
@@ -54,6 +54,8 @@ class Updater extends \PHPUnit_Framework_TestCase {
|
||||
Filesystem::clearMounts();
|
||||
Filesystem::mount($this->storage, array(), '/' . self::$user . '/files');
|
||||
|
||||
\OC_Hook::clear('OC_Filesystem');
|
||||
|
||||
\OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Updater', 'writeHook');
|
||||
\OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Updater', 'deleteHook');
|
||||
\OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Updater', 'renameHook');
|
||||
@@ -137,11 +139,10 @@ class Updater extends \PHPUnit_Framework_TestCase {
|
||||
$this->assertFalse($this->cache->inCache('foo.txt'));
|
||||
$this->assertTrue($this->cache->inCache('bar.txt'));
|
||||
$cachedData = $this->cache->get('bar.txt');
|
||||
$this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']);
|
||||
$this->assertEquals($fooCachedData['fileid'], $cachedData['fileid']);
|
||||
$mtime = $cachedData['mtime'];
|
||||
$cachedData = $this->cache->get('');
|
||||
$this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']);
|
||||
$this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']);
|
||||
$this->assertEquals($mtime, $cachedData['mtime']);
|
||||
}
|
||||
}
|
||||
|
||||
52
tests/lib/files/mapper.php
Normal file
52
tests/lib/files/mapper.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Thomas Müller
|
||||
* @copyright 2013 Thomas Müller thomas.mueller@owncloud.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Test\Files;
|
||||
|
||||
class Mapper extends \PHPUnit_Framework_TestCase {
|
||||
|
||||
/**
|
||||
* @var \OC\Files\Mapper
|
||||
*/
|
||||
private $mapper = null;
|
||||
|
||||
public function setUp() {
|
||||
$this->mapper = new \OC\Files\Mapper('D:/');
|
||||
}
|
||||
|
||||
public function testSlugifyPath() {
|
||||
// with extension
|
||||
$this->assertEquals('D:/text.txt', $this->mapper->slugifyPath('D:/text.txt'));
|
||||
$this->assertEquals('D:/text-2.txt', $this->mapper->slugifyPath('D:/text.txt', 2));
|
||||
$this->assertEquals('D:/a/b/text.txt', $this->mapper->slugifyPath('D:/a/b/text.txt'));
|
||||
|
||||
// without extension
|
||||
$this->assertEquals('D:/text', $this->mapper->slugifyPath('D:/text'));
|
||||
$this->assertEquals('D:/text-2', $this->mapper->slugifyPath('D:/text', 2));
|
||||
$this->assertEquals('D:/a/b/text', $this->mapper->slugifyPath('D:/a/b/text'));
|
||||
|
||||
// with double dot
|
||||
$this->assertEquals('D:/text-text.txt', $this->mapper->slugifyPath('D:/text.text.txt'));
|
||||
$this->assertEquals('D:/text-text-2.txt', $this->mapper->slugifyPath('D:/text.text.txt', 2));
|
||||
$this->assertEquals('D:/a/b/text-text.txt', $this->mapper->slugifyPath('D:/a/b/text.text.txt'));
|
||||
}
|
||||
}
|
||||
@@ -224,8 +224,7 @@ abstract class Storage extends \PHPUnit_Framework_TestCase {
|
||||
}
|
||||
|
||||
public function testSearchInSubFolder() {
|
||||
$this->instance->mkdir('sub')
|
||||
;
|
||||
$this->instance->mkdir('sub');
|
||||
$textFile = \OC::$SERVERROOT . '/tests/data/lorem.txt';
|
||||
$this->instance->file_put_contents('/sub/lorem.txt', file_get_contents($textFile, 'r'));
|
||||
$pngFile = \OC::$SERVERROOT . '/tests/data/logo-wide.png';
|
||||
@@ -258,4 +257,10 @@ abstract class Storage extends \PHPUnit_Framework_TestCase {
|
||||
$content = stream_get_contents($fh);
|
||||
$this->assertEquals(file_get_contents($textFile), $content);
|
||||
}
|
||||
|
||||
public function testTouchCreateFile(){
|
||||
$this->assertFalse($this->instance->file_exists('foo'));
|
||||
$this->instance->touch('foo');
|
||||
$this->assertTrue($this->instance->file_exists('foo'));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user