Merge branch 'master' into fix-7307

Conflicts:
	core/js/router.js
	settings/js/admin.js
This commit is contained in:
Thomas Müller 2014-03-06 00:15:08 +01:00
commit 32b29c9d73
47 changed files with 481 additions and 230 deletions

23
.scrutinizer.yml Normal file
View File

@ -0,0 +1,23 @@
filter:
excluded_paths:
- '3rdparty/*'
- 'apps/*/3rdparty/*'
- 'l10n/*'
- 'core/l10n/*'
- 'apps/*/l10n/*'
- 'lib/l10n/*'
- 'core/js/tests/lib/*.js'
- 'core/js/jquery-1.10.0.min.js'
- 'core/js/jquery-migrate-1.2.1.min.js'
- 'core/js/jquery-showpassword.js'
- 'core/js/jquery-tipsy.js'
- 'core/js/jquery.infieldlabel.js'
- 'core/js/jquery-ui-1.10.0.custom.js'
- 'core/js/jquery.inview.js'
- 'core/js/jquery.placeholder.js'
imports:
- javascript
- php

@ -1 +1 @@
Subproject commit c77c4ddbd4ae86a307d073647e76d602eafd0c64 Subproject commit 184f0a59f87c590ee7e89ced401205a87f213954

View File

@ -18,7 +18,7 @@ if(\OC\Files\Filesystem::file_exists($target . '/' . $file)) {
exit; exit;
} }
if ($dir != '' || $file != 'Shared') { if ($target != '' || strtolower($file) != 'shared') {
$targetFile = \OC\Files\Filesystem::normalizePath($target . '/' . $file); $targetFile = \OC\Files\Filesystem::normalizePath($target . '/' . $file);
$sourceFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $file); $sourceFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $file);
if(\OC\Files\Filesystem::rename($sourceFile, $targetFile)) { if(\OC\Files\Filesystem::rename($sourceFile, $targetFile)) {

View File

@ -82,7 +82,7 @@ OC.Upload = {
*/ */
isProcessing:function() { isProcessing:function() {
var count = 0; var count = 0;
jQuery.each(this._uploads,function(i, data) { jQuery.each(this._uploads,function(i, data) {
if (data.state() === 'pending') { if (data.state() === 'pending') {
count++; count++;
@ -208,13 +208,13 @@ $(document).ready(function() {
add: function(e, data) { add: function(e, data) {
OC.Upload.log('add', e, data); OC.Upload.log('add', e, data);
var that = $(this); var that = $(this);
// we need to collect all data upload objects before starting the upload so we can check their existence // we need to collect all data upload objects before starting the upload so we can check their existence
// and set individual conflict actions. unfortunately there is only one variable that we can use to identify // and set individual conflict actions. unfortunately there is only one variable that we can use to identify
// the selection a data upload is part of, so we have to collect them in data.originalFiles // the selection a data upload is part of, so we have to collect them in data.originalFiles
// turning singleFileUploads off is not an option because we want to gracefully handle server errors like // turning singleFileUploads off is not an option because we want to gracefully handle server errors like
// already exists // already exists
// create a container where we can store the data objects // create a container where we can store the data objects
if ( ! data.originalFiles.selection ) { if ( ! data.originalFiles.selection ) {
// initialize selection and remember number of files to upload // initialize selection and remember number of files to upload
@ -225,34 +225,34 @@ $(document).ready(function() {
}; };
} }
var selection = data.originalFiles.selection; var selection = data.originalFiles.selection;
// add uploads // add uploads
if ( selection.uploads.length < selection.filesToUpload ) { if ( selection.uploads.length < selection.filesToUpload ) {
// remember upload // remember upload
selection.uploads.push(data); selection.uploads.push(data);
} }
//examine file //examine file
var file = data.files[0]; var file = data.files[0];
try { try {
// FIXME: not so elegant... need to refactor that method to return a value // FIXME: not so elegant... need to refactor that method to return a value
Files.isFileNameValid(file.name); Files.isFileNameValid(file.name, FileList.getCurrentDirectory());
} }
catch (errorMessage) { catch (errorMessage) {
data.textStatus = 'invalidcharacters'; data.textStatus = 'invalidcharacters';
data.errorThrown = errorMessage; data.errorThrown = errorMessage;
} }
if (file.type === '' && file.size === 4096) { if (file.type === '' && file.size === 4096) {
data.textStatus = 'dirorzero'; data.textStatus = 'dirorzero';
data.errorThrown = t('files', 'Unable to upload {filename} as it is a directory or has 0 bytes', data.errorThrown = t('files', 'Unable to upload {filename} as it is a directory or has 0 bytes',
{filename: file.name} {filename: file.name}
); );
} }
// add size // add size
selection.totalBytes += file.size; selection.totalBytes += file.size;
// check PHP upload limit // check PHP upload limit
if (selection.totalBytes > $('#upload_limit').val()) { if (selection.totalBytes > $('#upload_limit').val()) {
data.textStatus = 'sizeexceedlimit'; data.textStatus = 'sizeexceedlimit';
@ -270,7 +270,7 @@ $(document).ready(function() {
'size2': humanFileSize($('#free_space').val()) 'size2': humanFileSize($('#free_space').val())
}); });
} }
// end upload for whole selection on error // end upload for whole selection on error
if (data.errorThrown) { if (data.errorThrown) {
// trigger fileupload fail // trigger fileupload fail
@ -281,12 +281,12 @@ $(document).ready(function() {
// check existing files when all is collected // check existing files when all is collected
if ( selection.uploads.length >= selection.filesToUpload ) { if ( selection.uploads.length >= selection.filesToUpload ) {
//remove our selection hack: //remove our selection hack:
delete data.originalFiles.selection; delete data.originalFiles.selection;
var callbacks = { var callbacks = {
onNoConflicts: function (selection) { onNoConflicts: function (selection) {
$.each(selection.uploads, function(i, upload) { $.each(selection.uploads, function(i, upload) {
upload.submit(); upload.submit();
@ -309,7 +309,7 @@ $(document).ready(function() {
}; };
OC.Upload.checkExistingFiles(selection, callbacks); OC.Upload.checkExistingFiles(selection, callbacks);
} }
return true; // continue adding files return true; // continue adding files
@ -439,7 +439,7 @@ $(document).ready(function() {
}); });
fileupload.on('fileuploadstop', function(e, data) { fileupload.on('fileuploadstop', function(e, data) {
OC.Upload.log('progress handle fileuploadstop', e, data); OC.Upload.log('progress handle fileuploadstop', e, data);
$('#uploadprogresswrapper input.stop').fadeOut(); $('#uploadprogresswrapper input.stop').fadeOut();
$('#uploadprogressbar').fadeOut(); $('#uploadprogressbar').fadeOut();
Files.updateStorageStatistics(); Files.updateStorageStatistics();
@ -531,7 +531,7 @@ $(document).ready(function() {
if ($(this).children('p').length === 0) { if ($(this).children('p').length === 0) {
return; return;
} }
$('#new .error').tipsy('hide'); $('#new .error').tipsy('hide');
$('#new li').each(function(i,element) { $('#new li').each(function(i,element) {
@ -545,7 +545,7 @@ $(document).ready(function() {
var text=$(this).children('p').text(); var text=$(this).children('p').text();
$(this).data('text',text); $(this).data('text',text);
$(this).children('p').remove(); $(this).children('p').remove();
// add input field // add input field
var form = $('<form></form>'); var form = $('<form></form>');
var input = $('<input type="text">'); var input = $('<input type="text">');
@ -562,7 +562,7 @@ $(document).ready(function() {
throw t('files', 'URL cannot be empty'); throw t('files', 'URL cannot be empty');
} else if (type !== 'web' && !Files.isFileNameValid(filename)) { } else if (type !== 'web' && !Files.isFileNameValid(filename)) {
// Files.isFileNameValid(filename) throws an exception itself // Files.isFileNameValid(filename) throws an exception itself
} else if ($('#dir').val() === '/' && filename === 'Shared') { } else if (FileList.getCurrentDirectory() === '/' && filename.toLowerCase() === 'shared') {
throw t('files', 'In the home folder \'Shared\' is a reserved filename'); throw t('files', 'In the home folder \'Shared\' is a reserved filename');
} else if (FileList.inList(filename)) { } else if (FileList.inList(filename)) {
throw t('files', '{new_name} already exists', {new_name: filename}); throw t('files', '{new_name} already exists', {new_name: filename});

View File

@ -421,15 +421,12 @@ window.FileList={
len = input.val().length; len = input.val().length;
} }
input.selectRange(0, len); input.selectRange(0, len);
var checkInput = function () { var checkInput = function () {
var filename = input.val(); var filename = input.val();
if (filename !== oldname) { if (filename !== oldname) {
if (!Files.isFileNameValid(filename)) { // Files.isFileNameValid(filename) throws an exception itself
// Files.isFileNameValid(filename) throws an exception itself Files.isFileNameValid(filename, FileList.getCurrentDirectory());
} else if($('#dir').val() === '/' && filename === 'Shared') { if (FileList.inList(filename)) {
throw t('files','In the home folder \'Shared\' is a reserved filename');
} else if (FileList.inList(filename)) {
throw t('files', '{new_name} already exists', {new_name: filename}); throw t('files', '{new_name} already exists', {new_name: filename});
} }
} }
@ -1158,9 +1155,9 @@ $(document).ready(function() {
// need to initially switch the dir to the one from the hash (IE8) // need to initially switch the dir to the one from the hash (IE8)
FileList.changeDirectory(parseCurrentDirFromUrl(), false, true); FileList.changeDirectory(parseCurrentDirFromUrl(), false, true);
} }
}
FileList.setCurrentDir(parseCurrentDirFromUrl(), false); FileList.setCurrentDir(parseCurrentDirFromUrl(), false);
}
FileList.createFileSummary(); FileList.createFileSummary();
}); });

View File

@ -87,9 +87,12 @@ var Files = {
* Throws a string exception with an error message if * Throws a string exception with an error message if
* the file name is not valid * the file name is not valid
*/ */
isFileNameValid: function (name) { isFileNameValid: function (name, root) {
var trimmedName = name.trim(); var trimmedName = name.trim();
if (trimmedName === '.' || trimmedName === '..') { if (trimmedName === '.'
|| trimmedName === '..'
|| (root === '/' && trimmedName.toLowerCase() === 'shared'))
{
throw t('files', '"{name}" is an invalid file name.', {name: name}); throw t('files', '"{name}" is an invalid file name.', {name: name});
} else if (trimmedName.length === 0) { } else if (trimmedName.length === 0) {
throw t('files', 'File name cannot be empty.'); throw t('files', 'File name cannot be empty.');

View File

@ -17,7 +17,13 @@ $totalsize = 0; ?>
data-mime="<?php p($file['mimetype'])?>" data-mime="<?php p($file['mimetype'])?>"
data-size="<?php p($file['size']);?>" data-size="<?php p($file['size']);?>"
data-etag="<?php p($file['etag']);?>" data-etag="<?php p($file['etag']);?>"
data-permissions="<?php p($file['permissions']); ?>"> data-permissions="<?php p($file['permissions']); ?>"
<?php if(isset($file['displayname_owner'])): ?>
data-share-owner="<?php p($file['displayname_owner']) ?>"
<?php endif; ?>
>
<?php if(isset($file['isPreviewAvailable']) and $file['isPreviewAvailable']): ?> <?php if(isset($file['isPreviewAvailable']) and $file['isPreviewAvailable']): ?>
<td class="filename svg preview-icon" <td class="filename svg preview-icon"
<?php else: ?> <?php else: ?>
@ -34,17 +40,15 @@ $totalsize = 0; ?>
<span class="nametext"> <span class="nametext">
<?php print_unescaped(htmlspecialchars($file['name']));?> <?php print_unescaped(htmlspecialchars($file['name']));?>
</span> </span>
<span class="uploadtext" currentUploads="0">
</span>
</a>
<?php else: ?> <?php else: ?>
<a class="name" href="<?php p(rtrim($_['downloadURL'],'/').'/'.trim($directory,'/').'/'.$name); ?>"> <a class="name" href="<?php p(rtrim($_['downloadURL'],'/').'/'.trim($directory,'/').'/'.$name); ?>">
<label class="filetext" title="" for="select-<?php p($file['fileid']); ?>"></label> <label class="filetext" title="" for="select-<?php p($file['fileid']); ?>"></label>
<span class="nametext"><?php print_unescaped(htmlspecialchars($file['basename']));?><span class='extension'><?php p($file['extension']);?></span></span> <span class="nametext"><?php print_unescaped(htmlspecialchars($file['basename']));?><span class='extension'><?php p($file['extension']);?></span></span>
</a> </a>
<?php endif; ?> <?php endif; ?>
<?php if($file['type'] == 'dir'):?>
<span class="uploadtext" currentUploads="0">
</span>
<?php endif;?>
</a>
</td> </td>
<td class="filesize" <td class="filesize"
style="color:rgb(<?php p($simple_size_color.','.$simple_size_color.','.$simple_size_color) ?>)"> style="color:rgb(<?php p($simple_size_color.','.$simple_size_color.','.$simple_size_color) ?>)">

View File

@ -48,6 +48,41 @@ describe('Files tests', function() {
expect(error).toEqual(false); expect(error).toEqual(false);
} }
}); });
it('Validates correct file names do not create Shared folder in root', function() {
// create shared file in subfolder
var error = false;
try {
expect(Files.isFileNameValid('shared', '/foo')).toEqual(true);
expect(Files.isFileNameValid('Shared', '/foo')).toEqual(true);
}
catch (e) {
error = e;
}
expect(error).toEqual(false);
// create shared file in root
var threwException = false;
try {
Files.isFileNameValid('Shared', '/');
console.error('Invalid file name not detected');
}
catch (e) {
threwException = true;
}
expect(threwException).toEqual(true);
// create shared file in root
var threwException = false;
try {
Files.isFileNameValid('shared', '/');
console.error('Invalid file name not detected');
}
catch (e) {
threwException = true;
}
expect(threwException).toEqual(true);
});
it('Detects invalid file names', function() { it('Detects invalid file names', function() {
var fileNames = [ var fileNames = [
'', '',

View File

@ -135,7 +135,6 @@ class Util {
// Set directories to check / create // Set directories to check / create
$setUpDirs = array( $setUpDirs = array(
$this->userDir, $this->userDir,
$this->userFilesDir,
$this->publicKeyDir, $this->publicKeyDir,
$this->encryptionDir, $this->encryptionDir,
$this->keyfilesPath, $this->keyfilesPath,

View File

@ -264,7 +264,7 @@ $(document).ready(function() {
OC.MountConfig.saveStorage($(this).parent().parent()); OC.MountConfig.saveStorage($(this).parent().parent());
}); });
$('#sslCertificate').on('click', 'td.remove>img', function() { $('#sslCertificate').on('click', 'td.remove>img', function() {
var $tr = $(this).parent().parent(); var $tr = $(this).parent().parent();
var row = this.parentNode.parentNode; var row = this.parentNode.parentNode;
$.post(OC.filePath('files_external', 'ajax', 'removeRootCertificate.php'), {cert: row.id}); $.post(OC.filePath('files_external', 'ajax', 'removeRootCertificate.php'), {cert: row.id});
@ -302,13 +302,23 @@ $(document).ready(function() {
}); });
$('#allowUserMounting').bind('change', function() { $('#allowUserMounting').bind('change', function() {
OC.msg.startSaving('#userMountingMsg');
if (this.checked) { if (this.checked) {
OC.AppConfig.setValue('files_external', 'allow_user_mounting', 'yes'); OC.AppConfig.setValue('files_external', 'allow_user_mounting', 'yes');
$('#userMountingBackups').removeClass('hidden');
} else { } else {
OC.AppConfig.setValue('files_external', 'allow_user_mounting', 'no'); OC.AppConfig.setValue('files_external', 'allow_user_mounting', 'no');
$('#userMountingBackups').addClass('hidden');
} }
OC.msg.finishedSaving('#userMountingMsg', {status: 'success', data: {message: t('settings', 'Saved')}});
}); });
$('input[name="allowUserMountingBackends\\[\\]"]').bind('change', function() {
OC.msg.startSaving('#userMountingMsg');
var user_mounting_backends = $('input[name="allowUserMountingBackends\\[\\]"]:checked').map(function(){return $(this).val();}).get();
OC.AppConfig.setValue('files_external', 'user_mounting_backends', user_mounting_backends.join());
OC.msg.finishedSaving('#userMountingMsg', {status: 'success', data: {message: t('settings', 'Saved')}});
});
}); });
})(); })();

View File

@ -45,7 +45,7 @@ class OC_Mount_Config {
'datadir' => 'Location')); 'datadir' => 'Location'));
$backends['\OC\Files\Storage\AmazonS3']=array( $backends['\OC\Files\Storage\AmazonS3']=array(
'backend' => 'Amazon S3', 'backend' => 'Amazon S3 and compliant',
'configuration' => array( 'configuration' => array(
'key' => 'Access Key', 'key' => 'Access Key',
'secret' => '*Secret Key', 'secret' => '*Secret Key',
@ -155,6 +155,35 @@ class OC_Mount_Config {
return($backends); return($backends);
} }
/**
* Get details on each of the external storage backends, used for the mount config UI
* Some backends are not available as a personal backend, f.e. Local and such that have
* been disabled by the admin.
*
* If a custom UI is needed, add the key 'custom' and a javascript file with that name will be loaded
* If the configuration parameter should be secret, add a '*' to the beginning of the value
* If the configuration parameter is a boolean, add a '!' to the beginning of the value
* If the configuration parameter is optional, add a '&' to the beginning of the value
* If the configuration parameter is hidden, add a '#' to the beginning of the value
* @return array
*/
public static function getPersonalBackends() {
$backends = self::getBackends();
// Remove local storage and other disabled storages
unset($backends['\OC\Files\Storage\Local']);
$allowed_backends = explode(',', OCP\Config::getAppValue('files_external', 'user_mounting_backends', ''));
foreach ($backends as $backend => $null) {
if (!in_array($backend, $allowed_backends)) {
unset($backends[$backend]);
}
}
return $backends;
}
/** /**
* Get the system mount points * Get the system mount points
* The returned array is not in the same format as getUserMountPoints() * The returned array is not in the same format as getUserMountPoints()
@ -287,11 +316,12 @@ class OC_Mount_Config {
if (!isset($backends[$class])) { if (!isset($backends[$class])) {
// invalid backend // invalid backend
return false; return false;
} }
if ($isPersonal) { if ($isPersonal) {
// Verify that the mount point applies for the current user // Verify that the mount point applies for the current user
// Prevent non-admin users from mounting local storage // Prevent non-admin users from mounting local storage and other disabled backends
if ($applicable !== OCP\User::getUser() || strtolower($class) === '\oc\files\storage\local') { $allowed_backends = self::getPersonalBackends();
if ($applicable != OCP\User::getUser() || !in_array($class, $allowed_backends)) {
return false; return false;
} }
$mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/'); $mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/');
@ -446,7 +476,7 @@ class OC_Mount_Config {
*/ */
public static function checksmbclient() { public static function checksmbclient() {
if(function_exists('shell_exec')) { if(function_exists('shell_exec')) {
$output=shell_exec('which smbclient 2> /dev/null'); $output=shell_exec('command -v smbclient 2> /dev/null');
return !empty($output); return !empty($output);
}else{ }else{
return false; return false;

View File

@ -22,9 +22,8 @@
OCP\Util::addScript('files_external', 'settings'); OCP\Util::addScript('files_external', 'settings');
OCP\Util::addStyle('files_external', 'settings'); OCP\Util::addStyle('files_external', 'settings');
$backends = OC_Mount_Config::getBackends(); $backends = OC_Mount_Config::getPersonalBackends();
// Remove local storage
unset($backends['\OC\Files\Storage\Local']);
$tmpl = new OCP\Template('files_external', 'settings'); $tmpl = new OCP\Template('files_external', 'settings');
$tmpl->assign('isAdminPage', false); $tmpl->assign('isAdminPage', false);
$tmpl->assign('mounts', OC_Mount_Config::getPersonalMountPoints()); $tmpl->assign('mounts', OC_Mount_Config::getPersonalMountPoints());

View File

@ -26,10 +26,26 @@ OCP\Util::addScript('files_external', 'settings');
OCP\Util::addscript('3rdparty', 'chosen/chosen.jquery.min'); OCP\Util::addscript('3rdparty', 'chosen/chosen.jquery.min');
OCP\Util::addStyle('files_external', 'settings'); OCP\Util::addStyle('files_external', 'settings');
OCP\Util::addStyle('3rdparty', 'chosen/chosen'); OCP\Util::addStyle('3rdparty', 'chosen/chosen');
$backends = OC_Mount_Config::getBackends();
$personal_backends = array();
$enabled_backends = explode(',', OCP\Config::getAppValue('files_external', 'user_mounting_backends', ''));
foreach ($backends as $class => $backend)
{
if ($class != '\OC\Files\Storage\Local')
{
$personal_backends[$class] = array(
'backend' => $backend['backend'],
'enabled' => in_array($class, $enabled_backends),
);
}
}
$tmpl = new OCP\Template('files_external', 'settings'); $tmpl = new OCP\Template('files_external', 'settings');
$tmpl->assign('isAdminPage', true); $tmpl->assign('isAdminPage', true);
$tmpl->assign('mounts', OC_Mount_Config::getSystemMountPoints()); $tmpl->assign('mounts', OC_Mount_Config::getSystemMountPoints());
$tmpl->assign('backends', OC_Mount_Config::getBackends()); $tmpl->assign('backends', $backends);
$tmpl->assign('personal_backends', $personal_backends);
$tmpl->assign('groups', OC_Group::getGroups()); $tmpl->assign('groups', OC_Group::getGroups());
$tmpl->assign('users', OCP\User::getUsers()); $tmpl->assign('users', OCP\User::getUsers());
$tmpl->assign('userDisplayNames', OC_User::getDisplayNames()); $tmpl->assign('userDisplayNames', OC_User::getDisplayNames());

View File

@ -122,12 +122,18 @@
<?php if ($_['isAdminPage']): ?> <?php if ($_['isAdminPage']): ?>
<br /> <br />
<input type="checkbox" <input type="checkbox" name="allowUserMounting" id="allowUserMounting"
name="allowUserMounting" value="1" <?php if ($_['allowUserMounting'] == 'yes') print_unescaped(' checked="checked"'); ?> />
id="allowUserMounting" <label for="allowUserMounting"><?php p($l->t('Enable User External Storage')); ?></label> <span id="userMountingMsg" class="msg"></span>
value="1" <?php if ($_['allowUserMounting'] == 'yes') print_unescaped(' checked="checked"'); ?> />
<label for="allowUserMounting"><?php p($l->t('Enable User External Storage')); ?></label><br/> <p id="userMountingBackups"<?php if ($_['allowUserMounting'] != 'yes'): ?> class="hidden"<?php endif; ?>>
<em><?php p($l->t('Allow users to mount their own external storage')); ?></em> <?php p($l->t('Allow users to mount the following external storage')); ?><br />
<?php $i = 0; foreach ($_['personal_backends'] as $class => $backend): ?>
<input type="checkbox" id="allowUserMountingBackends<?php p($i); ?>" name="allowUserMountingBackends[]" value="<?php p($class); ?>" <?php if ($backend['enabled']) print_unescaped(' checked="checked"'); ?> />
<label for="allowUserMountingBackends<?php p($i); ?>"><?php p($backend['backend']); ?></label> <br />
<?php $i++; ?>
<?php endforeach; ?>
</p>
<?php endif; ?> <?php endif; ?>
</fieldset> </fieldset>
</form> </form>

View File

@ -5,6 +5,14 @@ $(document).ready(function() {
if (typeof OC.Share !== 'undefined' && typeof FileActions !== 'undefined' && !disableSharing) { if (typeof OC.Share !== 'undefined' && typeof FileActions !== 'undefined' && !disableSharing) {
$('#fileList').on('fileActionsReady',function(){ $('#fileList').on('fileActionsReady',function(){
var allShared = $('#fileList').find('[data-share-owner]').find('[data-Action="Share"]');
allShared.addClass('permanent');
allShared.find('span').text(function(){
$owner = $(this).closest('tr').attr('data-share-owner');
return ' ' + t('files_sharing', 'Shared by {owner}', {owner: $owner});
});
if (!sharesLoaded){ if (!sharesLoaded){
OC.Share.loadIcons('file'); OC.Share.loadIcons('file');
// assume that we got all shares, so switching directories // assume that we got all shares, so switching directories
@ -17,16 +25,15 @@ $(document).ready(function() {
}); });
FileActions.register('all', 'Share', OC.PERMISSION_READ, OC.imagePath('core', 'actions/share'), function(filename) { FileActions.register('all', 'Share', OC.PERMISSION_READ, OC.imagePath('core', 'actions/share'), function(filename) {
if ($('#dir').val() == '/') { var dir = $('#dir').val();
var item = $('#dir').val() + filename; var item = dir + '/' + filename;
} else { if (dir == '/') {
var item = $('#dir').val() + '/' + filename; item = dir + filename;
} }
var tr = FileList.findFileEl(filename); var tr = FileList.findFileEl(filename);
var itemType = 'file';
if ($(tr).data('type') == 'dir') { if ($(tr).data('type') == 'dir') {
var itemType = 'folder'; itemType = 'folder';
} else {
var itemType = 'file';
} }
var possiblePermissions = $(tr).data('permissions'); var possiblePermissions = $(tr).data('permissions');
var appendTo = $(tr).find('td.filename'); var appendTo = $(tr).find('td.filename');

View File

@ -137,9 +137,12 @@ class Shared_Cache extends Cache {
} else { } else {
$cache = $this->getSourceCache($folder); $cache = $this->getSourceCache($folder);
if ($cache) { if ($cache) {
$parent = $this->storage->getFile($folder);
$sourceFolderContent = $cache->getFolderContents($this->files[$folder]); $sourceFolderContent = $cache->getFolderContents($this->files[$folder]);
foreach ($sourceFolderContent as $key => $c) { foreach ($sourceFolderContent as $key => $c) {
$sourceFolderContent[$key]['usersPath'] = 'files/Shared/' . $folder . '/' . $c['name']; $sourceFolderContent[$key]['usersPath'] = 'files/Shared/' . $folder . '/' . $c['name'];
$sourceFolderContent[$key]['uid_owner'] = $parent['uid_owner'];
$sourceFolderContent[$key]['displayname_owner'] = $parent['uid_owner'];
} }
return $sourceFolderContent; return $sourceFolderContent;

View File

@ -94,6 +94,9 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
$file['mtime'] = $item['mtime']; $file['mtime'] = $item['mtime'];
$file['encrypted'] = $item['encrypted']; $file['encrypted'] = $item['encrypted'];
$file['etag'] = $item['etag']; $file['etag'] = $item['etag'];
$file['uid_owner'] = $item['uid_owner'];
$file['displayname_owner'] = $item['displayname_owner'];
$storage = \OC\Files\Filesystem::getStorage('/'); $storage = \OC\Files\Filesystem::getStorage('/');
$cache = $storage->getCache(); $cache = $storage->getCache();
if ($item['encrypted'] or ($item['unencrypted_size'] > 0 and $cache->getMimetype($item['mimetype']) === 'httpd/unix-directory')) { if ($item['encrypted'] or ($item['unencrypted_size'] > 0 and $cache->getMimetype($item['mimetype']) === 'httpd/unix-directory')) {

View File

@ -120,7 +120,7 @@ class Helper {
$saveOtherConfigurations = ''; $saveOtherConfigurations = '';
if(empty($prefix)) { if(empty($prefix)) {
$saveOtherConfigurations = 'AND `Configkey` NOT LIKE \'s%\''; $saveOtherConfigurations = 'AND `configkey` NOT LIKE \'s%\'';
} }
$query = \OCP\DB::prepare(' $query = \OCP\DB::prepare('

View File

@ -54,11 +54,15 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface {
protected function walkBackends($uid, $method, $parameters) { protected function walkBackends($uid, $method, $parameters) {
$cacheKey = $this->getUserCacheKey($uid); $cacheKey = $this->getUserCacheKey($uid);
foreach($this->backends as $configPrefix => $backend) { foreach($this->backends as $configPrefix => $backend) {
// print("walkBackend '$configPrefix'<br/>"); $instance = $backend;
if($result = call_user_func_array(array($backend, $method), $parameters)) { if(!method_exists($instance, $method)
&& method_exists($this->getAccess($configPrefix), $method)) {
$instance = $this->getAccess($configPrefix);
}
if($result = call_user_func_array(array($instance, $method), $parameters)) {
$this->writeToCache($cacheKey, $configPrefix); $this->writeToCache($cacheKey, $configPrefix);
return $result; return $result;
} }
} }
return false; return false;
} }
@ -77,7 +81,12 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface {
//in case the uid has been found in the past, try this stored connection first //in case the uid has been found in the past, try this stored connection first
if(!is_null($prefix)) { if(!is_null($prefix)) {
if(isset($this->backends[$prefix])) { if(isset($this->backends[$prefix])) {
$result = call_user_func_array(array($this->backends[$prefix], $method), $parameters); $instance = $this->backends[$prefix];
if(!method_exists($instance, $method)
&& method_exists($this->getAccess($prefix), $method)) {
$instance = $this->getAccess($prefix);
}
$result = call_user_func_array(array($instance, $method), $parameters);
if($result === $passOnWhen) { if($result === $passOnWhen) {
//not found here, reset cache to null if user vanished //not found here, reset cache to null if user vanished
//because sometimes methods return false with a reason //because sometimes methods return false with a reason

View File

@ -178,6 +178,9 @@ $CONFIG = array(
/* Enable or disable the logging of IP addresses in case of webform auth failures */ /* Enable or disable the logging of IP addresses in case of webform auth failures */
"log_authfailip" => false, "log_authfailip" => false,
/* Whether http-basic username must equal username to login */
"basic_auth" => true,
/* /*
* Configure the size in bytes log rotation should happen, 0 or false disables the rotation. * Configure the size in bytes log rotation should happen, 0 or false disables the rotation.
* This rotates the current owncloud logfile to a new name, this way the total log usage * This rotates the current owncloud logfile to a new name, this way the total log usage

View File

@ -156,11 +156,15 @@
background-image: url('../img/actions/sound-off.svg'); background-image: url('../img/actions/sound-off.svg');
} }
.icon-star { .icon-star,
.icon-starred:hover,
.icon-starred:focus {
background-image: url('../img/actions/star.svg'); background-image: url('../img/actions/star.svg');
} }
.icon-starred { .icon-starred,
.icon-star:hover,
.icon-star:focus {
background-image: url('../img/actions/starred.svg'); background-image: url('../img/actions/starred.svg');
} }

View File

@ -175,6 +175,7 @@ button, .button,
border: 1px solid rgba(190,190,190,.9); border: 1px solid rgba(190,190,190,.9);
cursor: pointer; cursor: pointer;
border-radius: 3px; border-radius: 3px;
outline: none;
} }
input[type="submit"]:hover, input[type="submit"]:focus, input[type="submit"]:hover, input[type="submit"]:focus,
input[type="button"]:hover, input[type="button"]:focus, input[type="button"]:hover, input[type="button"]:focus,
@ -204,18 +205,18 @@ textarea:disabled {
/* Primary action button, use sparingly */ /* Primary action button, use sparingly */
.primary, input[type="submit"].primary, input[type="button"].primary, button.primary, .button.primary { .primary, input[type="submit"].primary, input[type="button"].primary, button.primary, .button.primary {
border: 1px solid #1d2d44; border: 1px solid #1d2d44;
background: #35537a; background-color: #35537a;
color: #ddd; color: #ddd;
} }
.primary:hover, input[type="submit"].primary:hover, input[type="button"].primary:hover, button.primary:hover, .button.primary:hover, .primary:hover, input[type="submit"].primary:hover, input[type="button"].primary:hover, button.primary:hover, .button.primary:hover,
.primary:focus, input[type="submit"].primary:focus, input[type="button"].primary:focus, button.primary:focus, .button.primary:focus { .primary:focus, input[type="submit"].primary:focus, input[type="button"].primary:focus, button.primary:focus, .button.primary:focus {
border: 1px solid #1d2d44; border: 1px solid #1d2d44;
background: #304d76; background-color: #304d76;
color: #fff; color: #fff;
} }
.primary:active, input[type="submit"].primary:active, input[type="button"].primary:active, button.primary:active, .button.primary:active { .primary:active, input[type="submit"].primary:active, input[type="button"].primary:active, button.primary:active, .button.primary:active {
border: 1px solid #1d2d44; border: 1px solid #1d2d44;
background: #1d2d44; background-color: #1d2d44;
color: #bbb; color: #bbb;
} }
@ -233,7 +234,7 @@ textarea:disabled {
} }
input[type="submit"].enabled { input[type="submit"].enabled {
background: #66f866; background-color: #66f866;
border: 1px solid #5e5; border: 1px solid #5e5;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -36,6 +36,7 @@ $(document).ready(function() {
$('#showAdvanced').click(function() { $('#showAdvanced').click(function() {
$('#datadirContent').slideToggle(250); $('#datadirContent').slideToggle(250);
$('#databaseBackend').slideToggle(250);
$('#databaseField').slideToggle(250); $('#databaseField').slideToggle(250);
}); });
$("form").submit(function(){ $("form").submit(function(){
@ -73,6 +74,7 @@ $(document).ready(function() {
if (currentDbType === 'sqlite' || (dbtypes.sqlite && currentDbType === undefined)){ if (currentDbType === 'sqlite' || (dbtypes.sqlite && currentDbType === undefined)){
$('#datadirContent').hide(250); $('#datadirContent').hide(250);
$('#databaseBackend').hide(250);
$('#databaseField').hide(250); $('#databaseField').hide(250);
} }

View File

@ -584,8 +584,8 @@ $(document).ready(function() {
$(checkboxes).filter('input[name="edit"]').attr('checked', false); $(checkboxes).filter('input[name="edit"]').attr('checked', false);
// Check Edit if Create, Update, or Delete is checked // Check Edit if Create, Update, or Delete is checked
} else if (($(this).attr('name') == 'create' } else if (($(this).attr('name') == 'create'
|| $(this).attr('name') == 'update' || $(this).attr('name') == 'update'
|| $(this).attr('name') == 'delete')) || $(this).attr('name') == 'delete'))
{ {
$(checkboxes).filter('input[name="edit"]').attr('checked', true); $(checkboxes).filter('input[name="edit"]').attr('checked', true);
} }

View File

@ -84,7 +84,7 @@
<?php endif; ?> <?php endif; ?>
<?php if(!$_['dbIsSet'] OR count($_['errors']) > 0): ?> <?php if(!$_['dbIsSet'] OR count($_['errors']) > 0): ?>
<fieldset id='databaseField'> <fieldset id='databaseBackend'>
<?php if($_['hasMySQL'] or $_['hasPostgreSQL'] or $_['hasOracle'] or $_['hasMSSQL']) <?php if($_['hasMySQL'] or $_['hasPostgreSQL'] or $_['hasOracle'] or $_['hasMSSQL'])
$hasOtherDB = true; else $hasOtherDB =false; //other than SQLite ?> $hasOtherDB = true; else $hasOtherDB =false; //other than SQLite ?>
<legend><?php p($l->t( 'Configure the database' )); ?></legend> <legend><?php p($l->t( 'Configure the database' )); ?></legend>
@ -100,8 +100,10 @@
<?php endif; ?> <?php endif; ?>
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
</fieldset>
<?php if($hasOtherDB): ?> <?php if($hasOtherDB): ?>
<fieldset id='databaseField'>
<div id="use_other_db"> <div id="use_other_db">
<p class="infield grouptop"> <p class="infield grouptop">
<label for="dbuser" class="infield"><?php p($l->t( 'Database user' )); ?></label> <label for="dbuser" class="infield"><?php p($l->t( 'Database user' )); ?></label>
@ -141,8 +143,8 @@
autocomplete="off" autocapitalize="off" autocorrect="off" /> autocomplete="off" autocapitalize="off" autocorrect="off" />
</p> </p>
</div> </div>
</fieldset>
<?php endif; ?> <?php endif; ?>
</fieldset>
<?php endif; ?> <?php endif; ?>
<div class="buttons"><input type="submit" class="primary" value="<?php p($l->t( 'Finish setup' )); ?>" data-finishing="<?php p($l->t( 'Finishing …' )); ?>" /></div> <div class="buttons"><input type="submit" class="primary" value="<?php p($l->t( 'Finish setup' )); ?>" data-finishing="<?php p($l->t( 'Finishing …' )); ?>" /></div>

View File

@ -2,15 +2,15 @@
<tr><td> <tr><td>
<table cellspacing="0" cellpadding="0" border="0" width="600px"> <table cellspacing="0" cellpadding="0" border="0" width="600px">
<tr> <tr>
<td bgcolor="#1d2d44" width="20px">&nbsp;</td> <td bgcolor="<?php p($theme->getMailHeaderColor());?>" width="20px">&nbsp;</td>
<td bgcolor="#1d2d44"> <td bgcolor="<?php p($theme->getMailHeaderColor());?>">
<img src="<?php print_unescaped(OC_Helper::makeURLAbsolute(image_path('', 'logo-mail.gif'))); ?>" alt="<?php p($theme->getName()); ?>"/> <img src="<?php p(OC_Helper::makeURLAbsolute(image_path('', 'logo-mail.gif'))); ?>" alt="<?php p($theme->getName()); ?>"/>
</td> </td>
</tr> </tr>
<tr><td bgcolor="#f8f8f8" colspan="2">&nbsp;</td></tr> <tr><td colspan="2">&nbsp;</td></tr>
<tr> <tr>
<td bgcolor="#f8f8f8" width="20px">&nbsp;</td> <td width="20px">&nbsp;</td>
<td bgcolor="#f8f8f8" style="font-weight:normal; font-size:0.8em; line-height:1.2em; font-family:verdana,'arial',sans;"> <td style="font-weight:normal; font-size:0.8em; line-height:1.2em; font-family:verdana,'arial',sans;">
<?php <?php
print_unescaped($l->t('Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href="%s">View it!</a><br><br>', array($_['user_displayname'], $_['filename'], $_['link']))); print_unescaped($l->t('Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href="%s">View it!</a><br><br>', array($_['user_displayname'], $_['filename'], $_['link'])));
if ( isset($_['expiration']) ) { if ( isset($_['expiration']) ) {
@ -21,17 +21,17 @@ p($l->t('Cheers!'));
?> ?>
</td> </td>
</tr> </tr>
<tr><td bgcolor="#f8f8f8" colspan="2">&nbsp;</td></tr> <tr><td colspan="2">&nbsp;</td></tr>
<tr> <tr>
<td bgcolor="#f8f8f8" width="20px">&nbsp;</td> <td width="20px">&nbsp;</td>
<td bgcolor="#f8f8f8" style="font-weight:normal; font-size:0.8em; line-height:1.2em; font-family:verdana,'arial',sans;">--<br> <td style="font-weight:normal; font-size:0.8em; line-height:1.2em; font-family:verdana,'arial',sans;">--<br>
<?php p($theme->getName()); ?> - <?php p($theme->getName()); ?> -
<?php p($theme->getSlogan()); ?> <?php p($theme->getSlogan()); ?>
<br><a href="<?php print_unescaped($theme->getBaseUrl()); ?>"><?php print_unescaped($theme->getBaseUrl());?></a> <br><a href="<?php p($theme->getBaseUrl()); ?>"><?php p($theme->getBaseUrl());?></a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td bgcolor="#f8f8f8" colspan="2">&nbsp;</td> <td colspan="2">&nbsp;</td>
</tr> </tr>
</table> </table>
</td></tr> </td></tr>

View File

@ -553,7 +553,8 @@ class OC {
OC_User::useBackend(new OC_User_Database()); OC_User::useBackend(new OC_User_Database());
OC_Group::useBackend(new OC_Group_Database()); OC_Group::useBackend(new OC_Group_Database());
if (isset($_SERVER['PHP_AUTH_USER']) && self::$session->exists('loginname') $basic_auth = OC_Config::getValue('basic_auth', true);
if ($basic_auth && isset($_SERVER['PHP_AUTH_USER']) && self::$session->exists('loginname')
&& $_SERVER['PHP_AUTH_USER'] !== self::$session->get('loginname')) { && $_SERVER['PHP_AUTH_USER'] !== self::$session->get('loginname')) {
$sessionUser = self::$session->get('loginname'); $sessionUser = self::$session->get('loginname');
$serverUser = $_SERVER['PHP_AUTH_USER']; $serverUser = $_SERVER['PHP_AUTH_USER'];

View File

@ -219,6 +219,8 @@ class OC_App{
$appdata=OC_OCSClient::getApplication($app); $appdata=OC_OCSClient::getApplication($app);
$download=OC_OCSClient::getApplicationDownload($app, 1); $download=OC_OCSClient::getApplicationDownload($app, 1);
if(isset($download['downloadlink']) and $download['downloadlink']!='') { if(isset($download['downloadlink']) and $download['downloadlink']!='') {
// Replace spaces in download link without encoding entire URL
$download['downloadlink'] = str_replace(' ', '%20', $download['downloadlink']);
$info = array('source'=>'http', 'href'=>$download['downloadlink'], 'appdata'=>$appdata); $info = array('source'=>'http', 'href'=>$download['downloadlink'], 'appdata'=>$appdata);
$app=OC_Installer::installApp($info); $app=OC_Installer::installApp($info);
} }

View File

@ -77,7 +77,7 @@ class Config {
/** /**
* @brief Gets a value from config.php * @brief Gets a value from config.php
* @param string $key key * @param string $key key
* @param string|null $default = null default value * @param array|bool|string|null $default = null default value
* @return string the value or $default * @return string the value or $default
* *
* This function gets the value from config.php. If it does not exist, * This function gets the value from config.php. If it does not exist,

View File

@ -50,7 +50,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
*/ */
public function createFile($name, $data = null) { public function createFile($name, $data = null) {
if ($name === 'Shared' && empty($this->path)) { if (strtolower($name) === 'shared' && empty($this->path)) {
throw new \Sabre_DAV_Exception_Forbidden(); throw new \Sabre_DAV_Exception_Forbidden();
} }
@ -86,7 +86,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
*/ */
public function createDirectory($name) { public function createDirectory($name) {
if ($name === 'Shared' && empty($this->path)) { if (strtolower($name) === 'shared' && empty($this->path)) {
throw new \Sabre_DAV_Exception_Forbidden(); throw new \Sabre_DAV_Exception_Forbidden();
} }

View File

@ -94,6 +94,9 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
} }
if ($sourceDir !== $destinationDir) { if ($sourceDir !== $destinationDir) {
// for a full move we need update privileges on sourcePath and sourceDir as well as destinationDir // for a full move we need update privileges on sourcePath and sourceDir as well as destinationDir
if (ltrim($destinationDir, '/') === '' && strtolower($sourceNode->getName()) === 'shared') {
throw new \Sabre_DAV_Exception_Forbidden();
}
if (!$fs->isUpdatable($sourceDir)) { if (!$fs->isUpdatable($sourceDir)) {
throw new \Sabre_DAV_Exception_Forbidden(); throw new \Sabre_DAV_Exception_Forbidden();
} }

View File

@ -41,7 +41,9 @@ class MDB2SchemaReader {
*/ */
public function loadSchemaFromFile($file) { public function loadSchemaFromFile($file) {
$schema = new \Doctrine\DBAL\Schema\Schema(); $schema = new \Doctrine\DBAL\Schema\Schema();
$loadEntities = libxml_disable_entity_loader(false);
$xml = simplexml_load_file($file); $xml = simplexml_load_file($file);
libxml_disable_entity_loader($loadEntities);
foreach ($xml->children() as $child) { foreach ($xml->children() as $child) {
/** /**
* @var \SimpleXMLElement $child * @var \SimpleXMLElement $child

View File

@ -21,6 +21,7 @@ class OC_Defaults {
private $defaultDocBaseUrl; private $defaultDocBaseUrl;
private $defaultSlogan; private $defaultSlogan;
private $defaultLogoClaim; private $defaultLogoClaim;
private $defaultMailHeaderColor;
function __construct() { function __construct() {
$this->l = OC_L10N::get('core'); $this->l = OC_L10N::get('core');
@ -33,6 +34,7 @@ class OC_Defaults {
$this->defaultDocBaseUrl = "http://doc.owncloud.org"; $this->defaultDocBaseUrl = "http://doc.owncloud.org";
$this->defaultSlogan = $this->l->t("web services under your control"); $this->defaultSlogan = $this->l->t("web services under your control");
$this->defaultLogoClaim = ""; $this->defaultLogoClaim = "";
$this->defaultMailHeaderColor = "#1d2d44"; /* header color of mail notifications */
if (class_exists("OC_Theme")) { if (class_exists("OC_Theme")) {
$this->theme = new OC_Theme(); $this->theme = new OC_Theme();
@ -181,4 +183,16 @@ class OC_Defaults {
return $this->getDocBaseUrl() . '/server/6.0/go.php?to=' . $key; return $this->getDocBaseUrl() . '/server/6.0/go.php?to=' . $key;
} }
/**
* Returns mail header color
* @return mail header color
*/
public function getMailHeaderColor() {
if ($this->themeExist('getMailHeaderColor')) {
return $this->theme->getMailHeaderColor();
} else {
return $this->defaultMailHeaderColor;
}
}
} }

View File

@ -464,7 +464,7 @@ class OC_Installer{
// is the code checker enabled? // is the code checker enabled?
if(OC_Config::getValue('appcodechecker', true)) { if(OC_Config::getValue('appcodechecker', true)) {
// check if grep is installed // check if grep is installed
$grep = exec('which grep'); $grep = exec('command -v grep');
if($grep=='') { if($grep=='') {
OC_Log::write('core', OC_Log::write('core',
'grep not installed. So checking the code of the app "'.$appname.'" was not possible', 'grep not installed. So checking the code of the app "'.$appname.'" was not possible',

View File

@ -73,8 +73,8 @@ class OC_L10N implements \OCP\IL10N {
/** /**
* get an L10N instance * get an L10N instance
* @param $app string * @param string $app
* @param $lang string|null * @param string|null $lang
* @return OC_L10N * @return OC_L10N
*/ */
public static function get($app, $lang=null) { public static function get($app, $lang=null) {
@ -87,8 +87,8 @@ class OC_L10N implements \OCP\IL10N {
/** /**
* @brief The constructor * @brief The constructor
* @param $app string app requesting l10n * @param string $app app requesting l10n
* @param $lang string default: null Language * @param string $lang default: null Language
* @returns OC_L10N-Object * @returns OC_L10N-Object
* *
* If language is not set, the constructor tries to find the right * If language is not set, the constructor tries to find the right
@ -237,7 +237,7 @@ class OC_L10N implements \OCP\IL10N {
/** /**
* @brief Translating * @brief Translating
* @param $text String The text we need a translation for * @param string $text The text we need a translation for
* @param array $parameters default:array() Parameters for sprintf * @param array $parameters default:array() Parameters for sprintf
* @return \OC_L10N_String Translation or the same text * @return \OC_L10N_String Translation or the same text
* *
@ -250,9 +250,9 @@ class OC_L10N implements \OCP\IL10N {
/** /**
* @brief Translating * @brief Translating
* @param $text_singular String the string to translate for exactly one object * @param string $text_singular the string to translate for exactly one object
* @param $text_plural String the string to translate for n objects * @param string $text_plural the string to translate for n objects
* @param $count Integer Number of objects * @param integer $count Number of objects
* @param array $parameters default:array() Parameters for sprintf * @param array $parameters default:array() Parameters for sprintf
* @return \OC_L10N_String Translation or the same text * @return \OC_L10N_String Translation or the same text
* *
@ -351,7 +351,7 @@ class OC_L10N implements \OCP\IL10N {
/** /**
* @brief Localization * @brief Localization
* @param $type Type of localization * @param string $type Type of localization
* @param $params parameters for this localization * @param $params parameters for this localization
* @returns String or false * @returns String or false
* *
@ -406,7 +406,7 @@ class OC_L10N implements \OCP\IL10N {
/** /**
* @brief Choose a language * @brief Choose a language
* @param $texts Associative Array with possible strings * @param array $text Associative Array with possible strings
* @returns String * @returns String
* *
* $text is an array 'de' => 'hallo welt', 'en' => 'hello world', ... * $text is an array 'de' => 'hallo welt', 'en' => 'hello world', ...
@ -421,7 +421,7 @@ class OC_L10N implements \OCP\IL10N {
/** /**
* @brief find the best language * @brief find the best language
* @param $app Array or string, details below * @param array|string $app details below
* @returns string language * @returns string language
* *
* If $app is an array, ownCloud assumes that these are the available * If $app is an array, ownCloud assumes that these are the available
@ -494,7 +494,7 @@ class OC_L10N implements \OCP\IL10N {
/** /**
* @brief find the l10n directory * @brief find the l10n directory
* @param $app App that needs to be translated * @param string $app App that needs to be translated
* @returns directory * @returns directory
*/ */
protected static function findI18nDir($app) { protected static function findI18nDir($app) {
@ -514,7 +514,7 @@ class OC_L10N implements \OCP\IL10N {
/** /**
* @brief find all available languages for an app * @brief find all available languages for an app
* @param $app App that needs to be translated * @param string $app App that needs to be translated
* @returns array an array of available languages * @returns array an array of available languages
*/ */
public static function findAvailableLanguages($app=null) { public static function findAvailableLanguages($app=null) {
@ -533,7 +533,9 @@ class OC_L10N implements \OCP\IL10N {
} }
/** /**
* @param string $app
* @param string $lang * @param string $lang
* @returns bool
*/ */
public static function languageExists($app, $lang) { public static function languageExists($app, $lang) {
if ($lang == 'en') {//english is always available if ($lang == 'en') {//english is always available

View File

@ -61,17 +61,29 @@ class OC_OCS_Cloud {
* the user from whom the information will be returned * the user from whom the information will be returned
*/ */
public static function getUser($parameters) { public static function getUser($parameters) {
$return = array();
// Check if they are viewing information on themselves // Check if they are viewing information on themselves
if($parameters['userid'] === OC_User::getUser()) { if($parameters['userid'] === OC_User::getUser()) {
// Self lookup // Self lookup
$storage = OC_Helper::getStorageInfo('/'); $storage = OC_Helper::getStorageInfo('/');
$quota = array( $return['quota'] = array(
'free' => $storage['free'], 'free' => $storage['free'],
'used' => $storage['used'], 'used' => $storage['used'],
'total' => $storage['total'], 'total' => $storage['total'],
'relative' => $storage['relative'], 'relative' => $storage['relative'],
); );
return new OC_OCS_Result(array('quota' => $quota)); }
if(OC_User::isAdminUser(OC_User::getUser())
|| OC_Subadmin::isUserAccessible(OC_User::getUser(), $parameters['userid'])) {
if(OC_User::userExists($parameters['userid'])) {
// Is an admin/subadmin so can see display name
$return['displayname'] = OC_User::getDisplayName($parameters['userid']);
} else {
return new OC_OCS_Result(null, 101);
}
}
if(count($return)) {
return new OC_OCS_Result($return);
} else { } else {
// No permission to view this user data // No permission to view this user data
return new OC_OCS_Result(null, 997); return new OC_OCS_Result(null, 997);

View File

@ -52,6 +52,11 @@ class Preview {
static private $providers = array(); static private $providers = array();
static private $registeredProviders = array(); static private $registeredProviders = array();
/**
* @var \OCP\Files\FileInfo
*/
protected $info;
/** /**
* @brief check if thumbnail or bigger version of thumbnail of file is cached * @brief check if thumbnail or bigger version of thumbnail of file is cached
* @param string $user userid - if no user is given, OC_User::getUser will be used * @param string $user userid - if no user is given, OC_User::getUser will be used
@ -61,12 +66,12 @@ class Preview {
* @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image
* @param bool $scalingUp Disable/Enable upscaling of previews * @param bool $scalingUp Disable/Enable upscaling of previews
* @return mixed (bool / string) * @return mixed (bool / string)
* false if thumbnail does not exist * false if thumbnail does not exist
* path to thumbnail if thumbnail exists * path to thumbnail if thumbnail exists
*/ */
public function __construct($user='', $root='/', $file='', $maxX=1, $maxY=1, $scalingUp=true) { public function __construct($user = '', $root = '/', $file = '', $maxX = 1, $maxY = 1, $scalingUp = true) {
//init fileviews //init fileviews
if($user === ''){ if ($user === '') {
$user = \OC_User::getUser(); $user = \OC_User::getUser();
} }
$this->fileView = new \OC\Files\View('/' . $user . '/' . $root); $this->fileView = new \OC\Files\View('/' . $user . '/' . $root);
@ -86,11 +91,11 @@ class Preview {
$this->preview = null; $this->preview = null;
//check if there are preview backends //check if there are preview backends
if(empty(self::$providers)) { if (empty(self::$providers)) {
self::initProviders(); self::initProviders();
} }
if(empty(self::$providers)) { if (empty(self::$providers)) {
\OC_Log::write('core', 'No preview providers exist', \OC_Log::ERROR); \OC_Log::write('core', 'No preview providers exist', \OC_Log::ERROR);
throw new \Exception('No preview providers'); throw new \Exception('No preview providers');
} }
@ -99,15 +104,15 @@ class Preview {
/** /**
* @brief returns the path of the file you want a thumbnail from * @brief returns the path of the file you want a thumbnail from
* @return string * @return string
*/ */
public function getFile() { public function getFile() {
return $this->file; return $this->file;
} }
/** /**
* @brief returns the max width of the preview * @brief returns the max width of the preview
* @return integer * @return integer
*/ */
public function getMaxX() { public function getMaxX() {
return $this->maxX; return $this->maxX;
} }
@ -115,7 +120,7 @@ class Preview {
/** /**
* @brief returns the max height of the preview * @brief returns the max height of the preview
* @return integer * @return integer
*/ */
public function getMaxY() { public function getMaxY() {
return $this->maxY; return $this->maxY;
} }
@ -123,7 +128,7 @@ class Preview {
/** /**
* @brief returns whether or not scalingup is enabled * @brief returns whether or not scalingup is enabled
* @return bool * @return bool
*/ */
public function getScalingUp() { public function getScalingUp() {
return $this->scalingup; return $this->scalingup;
} }
@ -131,7 +136,7 @@ class Preview {
/** /**
* @brief returns the name of the thumbnailfolder * @brief returns the name of the thumbnailfolder
* @return string * @return string
*/ */
public function getThumbnailsFolder() { public function getThumbnailsFolder() {
return self::THUMBNAILS_FOLDER; return self::THUMBNAILS_FOLDER;
} }
@ -139,7 +144,7 @@ class Preview {
/** /**
* @brief returns the max scale factor * @brief returns the max scale factor
* @return string * @return string
*/ */
public function getMaxScaleFactor() { public function getMaxScaleFactor() {
return $this->maxScaleFactor; return $this->maxScaleFactor;
} }
@ -147,7 +152,7 @@ class Preview {
/** /**
* @brief returns the max width set in ownCloud's config * @brief returns the max width set in ownCloud's config
* @return string * @return string
*/ */
public function getConfigMaxX() { public function getConfigMaxX() {
return $this->configMaxX; return $this->configMaxX;
} }
@ -155,20 +160,28 @@ class Preview {
/** /**
* @brief returns the max height set in ownCloud's config * @brief returns the max height set in ownCloud's config
* @return string * @return string
*/ */
public function getConfigMaxY() { public function getConfigMaxY() {
return $this->configMaxY; return $this->configMaxY;
} }
protected function getFileInfo() {
if (!$this->info) {
$this->info = $this->fileView->getFileInfo($this->file);
}
return $this->info;
}
/** /**
* @brief set the path of the file you want a thumbnail from * @brief set the path of the file you want a thumbnail from
* @param string $file * @param string $file
* @return $this * @return $this
*/ */
public function setFile($file) { public function setFile($file) {
$this->file = $file; $this->file = $file;
$this->info = null;
if ($file !== '') { if ($file !== '') {
$this->mimetype = $this->fileView->getMimeType($this->file); $this->mimetype = $this->getFileInfo()->getMimetype();
} }
return $this; return $this;
} }
@ -185,14 +198,14 @@ class Preview {
* @brief set the the max width of the preview * @brief set the the max width of the preview
* @param int $maxX * @param int $maxX
* @return $this * @return $this
*/ */
public function setMaxX($maxX=1) { public function setMaxX($maxX = 1) {
if($maxX <= 0) { if ($maxX <= 0) {
throw new \Exception('Cannot set width of 0 or smaller!'); throw new \Exception('Cannot set width of 0 or smaller!');
} }
$configMaxX = $this->getConfigMaxX(); $configMaxX = $this->getConfigMaxX();
if(!is_null($configMaxX)) { if (!is_null($configMaxX)) {
if($maxX > $configMaxX) { if ($maxX > $configMaxX) {
\OC_Log::write('core', 'maxX reduced from ' . $maxX . ' to ' . $configMaxX, \OC_Log::DEBUG); \OC_Log::write('core', 'maxX reduced from ' . $maxX . ' to ' . $configMaxX, \OC_Log::DEBUG);
$maxX = $configMaxX; $maxX = $configMaxX;
} }
@ -205,14 +218,14 @@ class Preview {
* @brief set the the max height of the preview * @brief set the the max height of the preview
* @param int $maxY * @param int $maxY
* @return $this * @return $this
*/ */
public function setMaxY($maxY=1) { public function setMaxY($maxY = 1) {
if($maxY <= 0) { if ($maxY <= 0) {
throw new \Exception('Cannot set height of 0 or smaller!'); throw new \Exception('Cannot set height of 0 or smaller!');
} }
$configMaxY = $this->getConfigMaxY(); $configMaxY = $this->getConfigMaxY();
if(!is_null($configMaxY)) { if (!is_null($configMaxY)) {
if($maxY > $configMaxY) { if ($maxY > $configMaxY) {
\OC_Log::write('core', 'maxX reduced from ' . $maxY . ' to ' . $configMaxY, \OC_Log::DEBUG); \OC_Log::write('core', 'maxX reduced from ' . $maxY . ' to ' . $configMaxY, \OC_Log::DEBUG);
$maxY = $configMaxY; $maxY = $configMaxY;
} }
@ -225,9 +238,9 @@ class Preview {
* @brief set whether or not scalingup is enabled * @brief set whether or not scalingup is enabled
* @param bool $scalingUp * @param bool $scalingUp
* @return $this * @return $this
*/ */
public function setScalingup($scalingUp) { public function setScalingup($scalingUp) {
if($this->getMaxScaleFactor() === 1) { if ($this->getMaxScaleFactor() === 1) {
$scalingUp = false; $scalingUp = false;
} }
$this->scalingup = $scalingUp; $this->scalingup = $scalingUp;
@ -237,15 +250,15 @@ class Preview {
/** /**
* @brief check if all parameters are valid * @brief check if all parameters are valid
* @return bool * @return bool
*/ */
public function isFileValid() { public function isFileValid() {
$file = $this->getFile(); $file = $this->getFile();
if($file === '') { if ($file === '') {
\OC_Log::write('core', 'No filename passed', \OC_Log::DEBUG); \OC_Log::write('core', 'No filename passed', \OC_Log::DEBUG);
return false; return false;
} }
if(!$this->fileView->file_exists($file)) { if (!$this->fileView->file_exists($file)) {
\OC_Log::write('core', 'File:"' . $file . '" not found', \OC_Log::DEBUG); \OC_Log::write('core', 'File:"' . $file . '" not found', \OC_Log::DEBUG);
return false; return false;
} }
@ -256,40 +269,38 @@ class Preview {
/** /**
* @brief deletes previews of a file with specific x and y * @brief deletes previews of a file with specific x and y
* @return bool * @return bool
*/ */
public function deletePreview() { public function deletePreview() {
$file = $this->getFile(); $file = $this->getFile();
$fileInfo = $this->fileView->getFileInfo($file); $fileInfo = $this->getFileInfo($file);
$fileId = $fileInfo['fileid']; $fileId = $fileInfo->getId();
$previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/' . $this->getMaxX() . '-' . $this->getMaxY() . '.png'; $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/' . $this->getMaxX() . '-' . $this->getMaxY() . '.png';
$this->userView->unlink($previewPath); return $this->userView->unlink($previewPath);
return !$this->userView->file_exists($previewPath);
} }
/** /**
* @brief deletes all previews of a file * @brief deletes all previews of a file
* @return bool * @return bool
*/ */
public function deleteAllPreviews() { public function deleteAllPreviews() {
$file = $this->getFile(); $file = $this->getFile();
$fileInfo = $this->fileView->getFileInfo($file); $fileInfo = $this->getFileInfo($file);
$fileId = $fileInfo['fileid']; $fileId = $fileInfo->getId();
$previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
$this->userView->deleteAll($previewPath); $this->userView->deleteAll($previewPath);
$this->userView->rmdir($previewPath); return $this->userView->rmdir($previewPath);
return !$this->userView->is_dir($previewPath);
} }
/** /**
* @brief check if thumbnail or bigger version of thumbnail of file is cached * @brief check if thumbnail or bigger version of thumbnail of file is cached
* @return mixed (bool / string) * @return mixed (bool / string)
* false if thumbnail does not exist * false if thumbnail does not exist
* path to thumbnail if thumbnail exists * path to thumbnail if thumbnail exists
*/ */
private function isCached() { private function isCached() {
$file = $this->getFile(); $file = $this->getFile();
$maxX = $this->getMaxX(); $maxX = $this->getMaxX();
@ -297,75 +308,75 @@ class Preview {
$scalingUp = $this->getScalingUp(); $scalingUp = $this->getScalingUp();
$maxScaleFactor = $this->getMaxScaleFactor(); $maxScaleFactor = $this->getMaxScaleFactor();
$fileInfo = $this->fileView->getFileInfo($file); $fileInfo = $this->getFileInfo($file);
$fileId = $fileInfo['fileid']; $fileId = $fileInfo->getId();
if(is_null($fileId)) { if (is_null($fileId)) {
return false; return false;
} }
$previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
if(!$this->userView->is_dir($previewPath)) { if (!$this->userView->is_dir($previewPath)) {
return false; return false;
} }
//does a preview with the wanted height and width already exist? //does a preview with the wanted height and width already exist?
if($this->userView->file_exists($previewPath . $maxX . '-' . $maxY . '.png')) { if ($this->userView->file_exists($previewPath . $maxX . '-' . $maxY . '.png')) {
return $previewPath . $maxX . '-' . $maxY . '.png'; return $previewPath . $maxX . '-' . $maxY . '.png';
} }
$wantedAspectRatio = (float) ($maxX / $maxY); $wantedAspectRatio = (float)($maxX / $maxY);
//array for usable cached thumbnails //array for usable cached thumbnails
$possibleThumbnails = array(); $possibleThumbnails = array();
$allThumbnails = $this->userView->getDirectoryContent($previewPath); $allThumbnails = $this->userView->getDirectoryContent($previewPath);
foreach($allThumbnails as $thumbnail) { foreach ($allThumbnails as $thumbnail) {
$name = rtrim($thumbnail['name'], '.png'); $name = rtrim($thumbnail['name'], '.png');
$size = explode('-', $name); $size = explode('-', $name);
$x = (int) $size[0]; $x = (int)$size[0];
$y = (int) $size[1]; $y = (int)$size[1];
$aspectRatio = (float) ($x / $y); $aspectRatio = (float)($x / $y);
if($aspectRatio !== $wantedAspectRatio) { if ($aspectRatio !== $wantedAspectRatio) {
continue; continue;
} }
if($x < $maxX || $y < $maxY) { if ($x < $maxX || $y < $maxY) {
if($scalingUp) { if ($scalingUp) {
$scalefactor = $maxX / $x; $scalefactor = $maxX / $x;
if($scalefactor > $maxScaleFactor) { if ($scalefactor > $maxScaleFactor) {
continue; continue;
} }
}else{ } else {
continue; continue;
} }
} }
$possibleThumbnails[$x] = $thumbnail['path']; $possibleThumbnails[$x] = $thumbnail['path'];
} }
if(count($possibleThumbnails) === 0) { if (count($possibleThumbnails) === 0) {
return false; return false;
} }
if(count($possibleThumbnails) === 1) { if (count($possibleThumbnails) === 1) {
return current($possibleThumbnails); return current($possibleThumbnails);
} }
ksort($possibleThumbnails); ksort($possibleThumbnails);
if(key(reset($possibleThumbnails)) > $maxX) { if (key(reset($possibleThumbnails)) > $maxX) {
return current(reset($possibleThumbnails)); return current(reset($possibleThumbnails));
} }
if(key(end($possibleThumbnails)) < $maxX) { if (key(end($possibleThumbnails)) < $maxX) {
return current(end($possibleThumbnails)); return current(end($possibleThumbnails));
} }
foreach($possibleThumbnails as $width => $path) { foreach ($possibleThumbnails as $width => $path) {
if($width < $maxX) { if ($width < $maxX) {
continue; continue;
}else{ } else {
return $path; return $path;
} }
} }
@ -374,9 +385,9 @@ class Preview {
/** /**
* @brief return a preview of a file * @brief return a preview of a file
* @return \OC_Image * @return \OC_Image
*/ */
public function getPreview() { public function getPreview() {
if(!is_null($this->preview) && $this->preview->valid()){ if (!is_null($this->preview) && $this->preview->valid()) {
return $this->preview; return $this->preview;
} }
@ -386,22 +397,25 @@ class Preview {
$maxY = $this->getMaxY(); $maxY = $this->getMaxY();
$scalingUp = $this->getScalingUp(); $scalingUp = $this->getScalingUp();
$fileInfo = $this->fileView->getFileInfo($file); $fileInfo = $this->getFileInfo($file);
$fileId = $fileInfo['fileid']; $fileId = $fileInfo->getId();
$cached = $this->isCached(); $cached = $this->isCached();
if($cached) { if ($cached) {
$image = new \OC_Image($this->userView->file_get_contents($cached, 'r')); $stream = $this->userView->fopen($cached, 'r');
$image = new \OC_Image();
$image->loadFromFileHandle($stream);
$this->preview = $image->valid() ? $image : null; $this->preview = $image->valid() ? $image : null;
$this->resizeAndCrop(); $this->resizeAndCrop();
fclose($stream);
} }
if(is_null($this->preview)) { if (is_null($this->preview)) {
$preview = null; $preview = null;
foreach(self::$providers as $supportedMimetype => $provider) { foreach (self::$providers as $supportedMimetype => $provider) {
if(!preg_match($supportedMimetype, $this->mimetype)) { if (!preg_match($supportedMimetype, $this->mimetype)) {
continue; continue;
} }
@ -409,7 +423,7 @@ class Preview {
$preview = $provider->getThumbnail($file, $maxX, $maxY, $scalingUp, $this->fileView); $preview = $provider->getThumbnail($file, $maxX, $maxY, $scalingUp, $this->fileView);
if(!($preview instanceof \OC_Image)) { if (!($preview instanceof \OC_Image)) {
continue; continue;
} }
@ -419,11 +433,11 @@ class Preview {
$previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
$cachePath = $previewPath . $maxX . '-' . $maxY . '.png'; $cachePath = $previewPath . $maxX . '-' . $maxY . '.png';
if($this->userView->is_dir($this->getThumbnailsFolder() . '/') === false) { if ($this->userView->is_dir($this->getThumbnailsFolder() . '/') === false) {
$this->userView->mkdir($this->getThumbnailsFolder() . '/'); $this->userView->mkdir($this->getThumbnailsFolder() . '/');
} }
if($this->userView->is_dir($previewPath) === false) { if ($this->userView->is_dir($previewPath) === false) {
$this->userView->mkdir($previewPath); $this->userView->mkdir($previewPath);
} }
@ -433,7 +447,7 @@ class Preview {
} }
} }
if(is_null($this->preview)) { if (is_null($this->preview)) {
$this->preview = new \OC_Image(); $this->preview = new \OC_Image();
} }
@ -443,10 +457,10 @@ class Preview {
/** /**
* @brief show preview * @brief show preview
* @return void * @return void
*/ */
public function showPreview() { public function showPreview() {
\OCP\Response::enableCaching(3600 * 24); // 24 hours \OCP\Response::enableCaching(3600 * 24); // 24 hours
if(is_null($this->preview)) { if (is_null($this->preview)) {
$this->getPreview(); $this->getPreview();
} }
$this->preview->show(); $this->preview->show();
@ -456,7 +470,7 @@ class Preview {
/** /**
* @brief show preview * @brief show preview
* @return void * @return void
*/ */
public function show() { public function show() {
$this->showPreview(); $this->showPreview();
return; return;
@ -465,7 +479,7 @@ class Preview {
/** /**
* @brief resize, crop and fix orientation * @brief resize, crop and fix orientation
* @return void * @return void
*/ */
private function resizeAndCrop() { private function resizeAndCrop() {
$image = $this->preview; $image = $this->preview;
$x = $this->getMaxX(); $x = $this->getMaxX();
@ -473,17 +487,17 @@ class Preview {
$scalingUp = $this->getScalingUp(); $scalingUp = $this->getScalingUp();
$maxscalefactor = $this->getMaxScaleFactor(); $maxscalefactor = $this->getMaxScaleFactor();
if(!($image instanceof \OC_Image)) { if (!($image instanceof \OC_Image)) {
\OC_Log::write('core', '$this->preview is not an instance of OC_Image', \OC_Log::DEBUG); \OC_Log::write('core', '$this->preview is not an instance of OC_Image', \OC_Log::DEBUG);
return; return;
} }
$image->fixOrientation(); $image->fixOrientation();
$realx = (int) $image->width(); $realx = (int)$image->width();
$realy = (int) $image->height(); $realy = (int)$image->height();
if($x === $realx && $y === $realy) { if ($x === $realx && $y === $realy) {
$this->preview = $image; $this->preview = $image;
return; return;
} }
@ -491,36 +505,36 @@ class Preview {
$factorX = $x / $realx; $factorX = $x / $realx;
$factorY = $y / $realy; $factorY = $y / $realy;
if($factorX >= $factorY) { if ($factorX >= $factorY) {
$factor = $factorX; $factor = $factorX;
}else{ } else {
$factor = $factorY; $factor = $factorY;
} }
if($scalingUp === false) { if ($scalingUp === false) {
if($factor > 1) { if ($factor > 1) {
$factor = 1; $factor = 1;
} }
} }
if(!is_null($maxscalefactor)) { if (!is_null($maxscalefactor)) {
if($factor > $maxscalefactor) { if ($factor > $maxscalefactor) {
\OC_Log::write('core', 'scalefactor reduced from ' . $factor . ' to ' . $maxscalefactor, \OC_Log::DEBUG); \OC_Log::write('core', 'scalefactor reduced from ' . $factor . ' to ' . $maxscalefactor, \OC_Log::DEBUG);
$factor = $maxscalefactor; $factor = $maxscalefactor;
} }
} }
$newXsize = (int) ($realx * $factor); $newXsize = (int)($realx * $factor);
$newYsize = (int) ($realy * $factor); $newYsize = (int)($realy * $factor);
$image->preciseResize($newXsize, $newYsize); $image->preciseResize($newXsize, $newYsize);
if($newXsize === $x && $newYsize === $y) { if ($newXsize === $x && $newYsize === $y) {
$this->preview = $image; $this->preview = $image;
return; return;
} }
if($newXsize >= $x && $newYsize >= $y) { if ($newXsize >= $x && $newYsize >= $y) {
$cropX = floor(abs($x - $newXsize) * 0.5); $cropX = floor(abs($x - $newXsize) * 0.5);
//don't crop previews on the Y axis, this sucks if it's a document. //don't crop previews on the Y axis, this sucks if it's a document.
//$cropY = floor(abs($y - $newYsize) * 0.5); //$cropY = floor(abs($y - $newYsize) * 0.5);
@ -532,19 +546,19 @@ class Preview {
return; return;
} }
if($newXsize < $x || $newYsize < $y) { if ($newXsize < $x || $newYsize < $y) {
if($newXsize > $x) { if ($newXsize > $x) {
$cropX = floor(($newXsize - $x) * 0.5); $cropX = floor(($newXsize - $x) * 0.5);
$image->crop($cropX, 0, $x, $newYsize); $image->crop($cropX, 0, $x, $newYsize);
} }
if($newYsize > $y) { if ($newYsize > $y) {
$cropY = floor(($newYsize - $y) * 0.5); $cropY = floor(($newYsize - $y) * 0.5);
$image->crop(0, $cropY, $newXsize, $y); $image->crop(0, $cropY, $newXsize, $y);
} }
$newXsize = (int) $image->width(); $newXsize = (int)$image->width();
$newYsize = (int) $image->height(); $newYsize = (int)$image->height();
//create transparent background layer //create transparent background layer
$backgroundlayer = imagecreatetruecolor($x, $y); $backgroundlayer = imagecreatetruecolor($x, $y);
@ -573,8 +587,8 @@ class Preview {
* @param array $options * @param array $options
* @return void * @return void
*/ */
public static function registerProvider($class, $options=array()) { public static function registerProvider($class, $options = array()) {
self::$registeredProviders[]=array('class'=>$class, 'options'=>$options); self::$registeredProviders[] = array('class' => $class, 'options' => $options);
} }
/** /**
@ -582,19 +596,19 @@ class Preview {
* @return void * @return void
*/ */
private static function initProviders() { private static function initProviders() {
if(!\OC_Config::getValue('enable_previews', true)) { if (!\OC_Config::getValue('enable_previews', true)) {
$provider = new Preview\Unknown(array()); $provider = new Preview\Unknown(array());
self::$providers = array($provider->getMimeType() => $provider); self::$providers = array($provider->getMimeType() => $provider);
return; return;
} }
if(count(self::$providers)>0) { if (count(self::$providers) > 0) {
return; return;
} }
foreach(self::$registeredProviders as $provider) { foreach (self::$registeredProviders as $provider) {
$class=$provider['class']; $class = $provider['class'];
$options=$provider['options']; $options = $provider['options'];
$object = new $class($options); $object = new $class($options);
@ -611,7 +625,7 @@ class Preview {
public static function post_delete($args) { public static function post_delete($args) {
$path = $args['path']; $path = $args['path'];
if(substr($path, 0, 1) === '/') { if (substr($path, 0, 1) === '/') {
$path = substr($path, 1); $path = substr($path, 1);
} }
$preview = new Preview(\OC_User::getUser(), 'files/', $path); $preview = new Preview(\OC_User::getUser(), 'files/', $path);
@ -622,19 +636,19 @@ class Preview {
* @param string $mimetype * @param string $mimetype
*/ */
public static function isMimeSupported($mimetype) { public static function isMimeSupported($mimetype) {
if(!\OC_Config::getValue('enable_previews', true)) { if (!\OC_Config::getValue('enable_previews', true)) {
return false; return false;
} }
//check if there are preview backends //check if there are preview backends
if(empty(self::$providers)) { if (empty(self::$providers)) {
self::initProviders(); self::initProviders();
} }
//remove last element because it has the mimetype * //remove last element because it has the mimetype *
$providers = array_slice(self::$providers, 0, -1); $providers = array_slice(self::$providers, 0, -1);
foreach($providers as $supportedMimetype => $provider) { foreach ($providers as $supportedMimetype => $provider) {
if(preg_match($supportedMimetype, $mimetype)) { if (preg_match($supportedMimetype, $mimetype)) {
return true; return true;
} }
} }

View File

@ -9,7 +9,7 @@
namespace OC\Preview; namespace OC\Preview;
function findBinaryPath($program) { function findBinaryPath($program) {
exec('which ' . escapeshellarg($program) . ' 2> /dev/null', $output, $returnCode); exec('command -v ' . escapeshellarg($program) . ' 2> /dev/null', $output, $returnCode);
if ($returnCode === 0 && count($output) > 0) { if ($returnCode === 0 && count($output) > 0) {
return escapeshellcmd($output[0]); return escapeshellcmd($output[0]);
} }

View File

@ -64,12 +64,12 @@ if (!\OC_Util::runningOnWindows()) {
$cmd = \OC_Config::getValue('preview_libreoffice_path', null); $cmd = \OC_Config::getValue('preview_libreoffice_path', null);
} }
$whichLibreOffice = shell_exec('which libreoffice'); $whichLibreOffice = shell_exec('command -v libreoffice');
if($cmd === '' && !empty($whichLibreOffice)) { if($cmd === '' && !empty($whichLibreOffice)) {
$cmd = 'libreoffice'; $cmd = 'libreoffice';
} }
$whichOpenOffice = shell_exec('which openoffice'); $whichOpenOffice = shell_exec('command -v openoffice');
if($cmd === '' && !empty($whichOpenOffice)) { if($cmd === '' && !empty($whichOpenOffice)) {
$cmd = 'openoffice'; $cmd = 'openoffice';
} }

View File

@ -11,9 +11,9 @@ if (extension_loaded('imagick') && count(@\Imagick::queryFormats("PDF")) === 1)
// LibreOffice preview is currently not supported on Windows // LibreOffice preview is currently not supported on Windows
if (!\OC_Util::runningOnWindows()) { if (!\OC_Util::runningOnWindows()) {
$whichLibreOffice = ($isShellExecEnabled ? shell_exec('which libreoffice') : ''); $whichLibreOffice = ($isShellExecEnabled ? shell_exec('command -v libreoffice') : '');
$isLibreOfficeAvailable = !empty($whichLibreOffice); $isLibreOfficeAvailable = !empty($whichLibreOffice);
$whichOpenOffice = ($isShellExecEnabled ? shell_exec('which libreoffice') : ''); $whichOpenOffice = ($isShellExecEnabled ? shell_exec('command -v libreoffice') : '');
$isOpenOfficeAvailable = !empty($whichOpenOffice); $isOpenOfficeAvailable = !empty($whichOpenOffice);
//let's see if there is libreoffice or openoffice on this machine //let's see if there is libreoffice or openoffice on this machine
if($isShellExecEnabled && ($isLibreOfficeAvailable || $isOpenOfficeAvailable || is_string(\OC_Config::getValue('preview_libreoffice_path', null)))) { if($isShellExecEnabled && ($isLibreOfficeAvailable || $isOpenOfficeAvailable || is_string(\OC_Config::getValue('preview_libreoffice_path', null)))) {

View File

@ -61,7 +61,7 @@ class Base {
/** /**
* @brief Assign variables * @brief Assign variables
* @param string $key key * @param string $key key
* @param string $value value * @param array|bool|integer|string $value value
* @return bool * @return bool
* *
* This function assigns a variable. It can be accessed via $_[$key] in * This function assigns a variable. It can be accessed via $_[$key] in

View File

@ -73,6 +73,36 @@ class Controller {
\OC_JSON::success(array("data" => array( "message" => $l->t("Saved") ))); \OC_JSON::success(array("data" => array( "message" => $l->t("Saved") )));
} }
/**
* Send a mail to test the settings
*/
public static function sendTestMail() {
\OC_Util::checkAdminUser();
\OCP\JSON::callCheck();
$l = \OC_L10N::get('settings');
$email = \OC_Preferences::getValue(\OC_User::getUser(), 'settings', 'email', '');
if (!empty($email)) {
$defaults = new \OC_Defaults();
try {
\OC_Mail::send($email, $_POST['user'],
$l->t('test email settings'),
$l->t('If you received this email, the settings seem to be correct.'),
\OCP\Util::getDefaultEmailAddress('no-reply'), $defaults->getName());
} catch (\Exception $e) {
$message = $l->t('A problem occurred while sending the e-mail. Please revisit your settings.');
\OC_JSON::error( array( "data" => array( "message" => $message)) );
exit;
}
\OC_JSON::success(array("data" => array( "message" => $l->t("Email sent") )));
} else {
$message = $l->t('You need to set your user email before being able to send test emails.');
\OC_JSON::error( array( "data" => array( "message" => $message)) );
}
}
/** /**
* Get the field name to use it in error messages * Get the field name to use it in error messages
* *

View File

@ -62,10 +62,18 @@ $(document).ready(function(){
}); });
$('#mail_settings').change(function(){ $('#mail_settings').change(function(){
OC.msg.startSaving('#mail_settings .msg'); OC.msg.startSaving('#mail_settings_msg');
var post = $( "#mail_settings" ).serialize(); var post = $( "#mail_settings" ).serialize();
$.post(OC.generateUrl('/settings/admin/mailsettings'), post, function(data){ $.post(OC.generateUrl('/settings/admin/mailsettings'), post, function(data){
OC.msg.finishedSaving('#mail_settings .msg', data); OC.msg.finishedSaving('#mail_settings .msg', data);
}); });
}); });
$('#sendtestemail').click(function(){
OC.msg.startAction('#sendtestmail_msg', t('settings', 'Sending...'));
var post = $( "#sendtestemail" ).serialize();
$.post(OC.generateUrl('/settings/admin/mailtest'), post, function(data){
OC.msg.finishedAction('#sendtestmail_msg', data);
});
});
}); });

View File

@ -75,5 +75,8 @@ $this->create('settings_ajax_setloglevel', '/settings/ajax/setloglevel.php')
$this->create('settings_mail_settings', '/settings/admin/mailsettings') $this->create('settings_mail_settings', '/settings/admin/mailsettings')
->post() ->post()
->action('OC\Settings\Admin\Controller', 'setMailSettings'); ->action('OC\Settings\Admin\Controller', 'setMailSettings');
$this->create('settings_admin_mail_test', '/settings/admin/mailtest')
->post()
->action('OC\Settings\Admin\Controller', 'sendTestMail');
$this->create('settings_ajax_setsecurity', '/settings/ajax/setsecurity.php') $this->create('settings_ajax_setsecurity', '/settings/ajax/setsecurity.php')
->actionInclude('settings/ajax/setsecurity.php'); ->actionInclude('settings/ajax/setsecurity.php');

View File

@ -272,7 +272,7 @@ if (!$_['internetconnectionworking']) {
</fieldset> </fieldset>
<fieldset id="mail_settings" class="personalblock"> <fieldset id="mail_settings" class="personalblock">
<h2><?php p($l->t('Email Server'));?> <span class="msg"></span></h2> <h2><?php p($l->t('Email Server'));?> <span id="mail_settings_msg" class="msg"></span></h2>
<p><?php p($l->t('This is used for sending out notifications.')); ?></p> <p><?php p($l->t('This is used for sending out notifications.')); ?></p>
@ -347,6 +347,10 @@ if (!$_['internetconnectionworking']) {
placeholder="<?php p($l->t('SMTP Password'))?>" value='<?php p($_['mail_smtppassword']) ?>' /> placeholder="<?php p($l->t('SMTP Password'))?>" value='<?php p($_['mail_smtppassword']) ?>' />
</p> </p>
<br />
<em><?php p($l->t( 'Test email settings' )); ?></em>
<input type="submit" name="sendtestemail" id="sendtestemail" value="<?php p($l->t( 'Send email' )); ?>"/>
<span id="sendtestmail_msg" class="msg"></span>
</fieldset> </fieldset>
<fieldset class="personalblock"> <fieldset class="personalblock">

View File

@ -83,7 +83,7 @@ if($_['passwordChangeSupported']) {
placeholder="<?php p($l->t('Your email address'));?>" placeholder="<?php p($l->t('Your email address'));?>"
autocomplete="on" autocapitalize="off" autocorrect="off" /> autocomplete="on" autocapitalize="off" autocorrect="off" />
<span class="msg"></span><br /> <span class="msg"></span><br />
<em><?php p($l->t('Fill in an email address to enable password recovery'));?></em> <em><?php p($l->t('Fill in an email address to enable password recovery and receive notifications'));?></em>
</fieldset> </fieldset>
</form> </form>
<?php <?php