diff options
30 files changed, 296 insertions, 60 deletions
diff --git a/README.md b/README.md index eafad0b9c8c..2c0f11b43bd 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,16 @@ changed it substantially: More information how to contribute: [https://nextcloud.com/contribute/](https://nextcloud.com/contribute/) +## Running master checkouts + +Third-party components are handled as git submodules which have to be initialized first. So aside from the regular git checkout invoking `git submodule update --init` or a similar command is needed, for details see Git documentation. + +Several apps by default included in regular releases like [firstrunwizard](https://github.com/nextcloud/firstrunwizard) or [gallery](https://github.com/nextcloud/gallery) are missing in `master` and have to be installed manually as required. + +That aside Git checkouts can be handled the same as release archives. + +Note they should never be used on production systems. + ## Nextcloud VM If you're not familiar with Linux, or simply just want to get up and running on a pre-configured system in no time - we have developed a VM that you can download. Just extract it and mount it in VMware or VirtualBox and you're all set. diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml index 19b65d84327..14849b714a7 100644 --- a/apps/dav/appinfo/info.xml +++ b/apps/dav/appinfo/info.xml @@ -23,6 +23,7 @@ <repair-steps> <post-migration> <step>OCA\DAV\Migration\Classification</step> + <step>OCA\DAV\Migration\FixBirthdayCalendarComponent</step> </post-migration> <live-migration> <step>OCA\DAV\Migration\GenerateBirthdays</step> diff --git a/apps/dav/lib/CalDAV/BirthdayService.php b/apps/dav/lib/CalDAV/BirthdayService.php index ab2794e67db..71f4940a2c8 100644 --- a/apps/dav/lib/CalDAV/BirthdayService.php +++ b/apps/dav/lib/CalDAV/BirthdayService.php @@ -116,6 +116,7 @@ class BirthdayService { $this->calDavBackEnd->createCalendar($principal, self::BIRTHDAY_CALENDAR_URI, [ '{DAV:}displayname' => 'Contact birthdays', '{http://apple.com/ns/ical/}calendar-color' => '#FFFFCA', + 'components' => 'VEVENT', ]); return $this->calDavBackEnd->getCalendarByUri($principal, self::BIRTHDAY_CALENDAR_URI); diff --git a/apps/dav/lib/Migration/FixBirthdayCalendarComponent.php b/apps/dav/lib/Migration/FixBirthdayCalendarComponent.php new file mode 100644 index 00000000000..03bd298ff1d --- /dev/null +++ b/apps/dav/lib/Migration/FixBirthdayCalendarComponent.php @@ -0,0 +1,62 @@ +<?php +/** + * @author Thomas Müller <thomas.mueller@tmit.eu> + * + * @copyright Copyright (c) 2016, ownCloud GmbH. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program 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, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OCA\DAV\Migration; + +use OCA\DAV\CalDAV\BirthdayService; +use OCP\IDBConnection; +use OCP\Migration\IOutput; +use OCP\Migration\IRepairStep; + +class FixBirthdayCalendarComponent implements IRepairStep { + + /** @var IDBConnection */ + private $connection; + + /** + * FixBirthdayCalendarComponent constructor. + * + * @param IDBConnection $connection + */ + public function __construct(IDBConnection $connection) { + $this->connection = $connection; + } + + /** + * @inheritdoc + */ + public function getName() { + return 'Fix component of birthday calendars'; + } + + /** + * @inheritdoc + */ + public function run(IOutput $output) { + $query = $this->connection->getQueryBuilder(); + $updated = $query->update('calendars') + ->set('components', $query->createNamedParameter('VEVENT')) + ->where($query->expr()->eq('uri', $query->createNamedParameter(BirthdayService::BIRTHDAY_CALENDAR_URI))) + ->execute(); + + $output->info("$updated birthday calendars updated."); + } +} diff --git a/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php b/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php index 33968ec242d..7c772184fef 100644 --- a/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php +++ b/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php @@ -182,6 +182,17 @@ class BirthdayServiceTest extends TestCase { ], $users); } + public function testBirthdayCalendarHasComponentEvent() { + $this->calDav->expects($this->once()) + ->method('createCalendar') + ->with('principal001', 'contact_birthdays', [ + '{DAV:}displayname' => 'Contact birthdays', + '{http://apple.com/ns/ical/}calendar-color' => '#FFFFCA', + 'components' => 'VEVENT', + ]); + $this->service->ensureCalendarExists('principal001'); + } + public function providesBirthday() { return [ [true, diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index e07093dd17b..56ea384c9e0 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -347,10 +347,6 @@ OC.Upload = { //file is a directory dirUploadFailure = true; } - if (file.size === 0) { - // file is empty or a directory - dirUploadFailure = true; - } if (dirUploadFailure) { data.textStatus = 'dirorzero'; @@ -667,8 +663,23 @@ OC.Upload = { OC.Upload._hideProgressBar(); } }); + var disableDropState = function() { + $('#app-content').removeClass('file-drag'); + $('.dropping-to-dir').removeClass('dropping-to-dir'); + $('.dir-drop').removeClass('dir-drop'); + $('.icon-filetype-folder-drag-accept').removeClass('icon-filetype-folder-drag-accept'); + }; + var disableClassOnFirefox = _.debounce(function() { + disableDropState(); + }, 100); fileupload.on('fileuploaddragover', function(e){ $('#app-content').addClass('file-drag'); + // dropping a folder in firefox doesn't cause a drop event + // this is simulated by simply invoke disabling all classes + // once no dragover event isn't noticed anymore + if ($.browser['mozilla']) { + disableClassOnFirefox(); + } $('#emptycontent .icon-folder').addClass('icon-filetype-folder-drag-accept'); var filerow = $(e.delegatedEvent.target).closest('tr'); @@ -685,12 +696,7 @@ OC.Upload = { filerow.find('.thumbnail').addClass('icon-filetype-folder-drag-accept'); } }); - fileupload.on('fileuploaddragleave fileuploaddrop', function (){ - $('#app-content').removeClass('file-drag'); - $('.dropping-to-dir').removeClass('dropping-to-dir'); - $('.dir-drop').removeClass('dir-drop'); - $('.icon-filetype-folder-drag-accept').removeClass('icon-filetype-folder-drag-accept'); - }); + fileupload.on('fileuploaddragleave fileuploaddrop', disableDropState); } else { // for all browsers that don't support the progress bar // IE 8 & 9 diff --git a/apps/files/lib/Controller/ViewController.php b/apps/files/lib/Controller/ViewController.php index db8f32ddf73..d3708915273 100644 --- a/apps/files/lib/Controller/ViewController.php +++ b/apps/files/lib/Controller/ViewController.php @@ -160,16 +160,16 @@ class ViewController extends Controller { \OCP\Util::addStyle('files', 'files'); \OCP\Util::addStyle('files', 'upload'); \OCP\Util::addStyle('files', 'mobile'); - \OCP\Util::addscript('files', 'app'); - \OCP\Util::addscript('files', 'file-upload'); - \OCP\Util::addscript('files', 'newfilemenu'); - \OCP\Util::addscript('files', 'jquery.fileupload'); - \OCP\Util::addscript('files', 'jquery-visibility'); - \OCP\Util::addscript('files', 'fileinfomodel'); - \OCP\Util::addscript('files', 'filesummary'); - \OCP\Util::addscript('files', 'breadcrumb'); - \OCP\Util::addscript('files', 'filelist'); - \OCP\Util::addscript('files', 'search'); + \OCP\Util::addScript('files', 'app'); + \OCP\Util::addScript('files', 'file-upload'); + \OCP\Util::addScript('files', 'newfilemenu'); + \OCP\Util::addScript('files', 'jquery.fileupload'); + \OCP\Util::addScript('files', 'jquery-visibility'); + \OCP\Util::addScript('files', 'fileinfomodel'); + \OCP\Util::addScript('files', 'filesummary'); + \OCP\Util::addScript('files', 'breadcrumb'); + \OCP\Util::addScript('files', 'filelist'); + \OCP\Util::addScript('files', 'search'); \OCP\Util::addScript('files', 'favoritesfilelist'); \OCP\Util::addScript('files', 'recentfilelist'); @@ -188,11 +188,11 @@ class ViewController extends Controller { \OC_Util::addVendorScript('core', 'handlebars/handlebars'); - \OCP\Util::addscript('files', 'fileactions'); - \OCP\Util::addscript('files', 'fileactionsmenu'); - \OCP\Util::addscript('files', 'files'); - \OCP\Util::addscript('files', 'keyboardshortcuts'); - \OCP\Util::addscript('files', 'navigation'); + \OCP\Util::addScript('files', 'fileactions'); + \OCP\Util::addScript('files', 'fileactionsmenu'); + \OCP\Util::addScript('files', 'files'); + \OCP\Util::addScript('files', 'keyboardshortcuts'); + \OCP\Util::addScript('files', 'navigation'); // mostly for the home storage's free space // FIXME: Make non static diff --git a/apps/files/templates/admin.php b/apps/files/templates/admin.php index ef357245df7..1cbb339fee7 100644 --- a/apps/files/templates/admin.php +++ b/apps/files/templates/admin.php @@ -1,4 +1,4 @@ - <?php OCP\Util::addscript('files', 'admin'); ?> + <?php OCP\Util::addScript('files', 'admin'); ?> <div class="section"> <h2><?php p($l->t('File handling')); ?></h2> diff --git a/apps/files_sharing/lib/External/Storage.php b/apps/files_sharing/lib/External/Storage.php index 1ed6375cd4f..caa2bcf2a79 100644 --- a/apps/files_sharing/lib/External/Storage.php +++ b/apps/files_sharing/lib/External/Storage.php @@ -186,7 +186,7 @@ class Storage extends DAV implements ISharedStorage { public function test() { try { - parent::test(); + return parent::test(); } catch (StorageInvalidException $e) { // check if it needs to be removed $this->checkStorageAvailability(); diff --git a/apps/files_sharing/tests/ExternalStorageTest.php b/apps/files_sharing/tests/ExternalStorageTest.php index 48c348667c5..e84d2bb0e17 100644 --- a/apps/files_sharing/tests/ExternalStorageTest.php +++ b/apps/files_sharing/tests/ExternalStorageTest.php @@ -67,14 +67,11 @@ class ExternalStorageTest extends \Test\TestCase { ); } - /** - * @dataProvider optionsProvider - */ - public function testStorageMountOptions($inputUri, $baseUri) { + private function getTestStorage($uri) { $certificateManager = \OC::$server->getCertificateManager(); - $storage = new TestSharingExternalStorage( + return new TestSharingExternalStorage( array( - 'remote' => $inputUri, + 'remote' => $uri, 'owner' => 'testOwner', 'mountpoint' => 'remoteshare', 'token' => 'abcdef', @@ -83,8 +80,20 @@ class ExternalStorageTest extends \Test\TestCase { 'certificateManager' => $certificateManager ) ); + } + + /** + * @dataProvider optionsProvider + */ + public function testStorageMountOptions($inputUri, $baseUri) { + $storage = $this->getTestStorage($inputUri); $this->assertEquals($baseUri, $storage->getBaseUri()); } + + public function testIfTestReturnsTheValue() { + $result = $this->getTestStorage('https://remoteserver')->test(); + $this->assertSame(true, $result); + } } /** @@ -95,4 +104,11 @@ class TestSharingExternalStorage extends \OCA\Files_Sharing\External\Storage { public function getBaseUri() { return $this->createBaseUri(); } + + public function stat($path) { + if ($path === '') { + return true; + } + return parent::stat($path); + } } diff --git a/apps/updatenotification/js/admin.js b/apps/updatenotification/js/admin.js index e60e77ab89a..3ca45a191d4 100644 --- a/apps/updatenotification/js/admin.js +++ b/apps/updatenotification/js/admin.js @@ -13,7 +13,33 @@ /** * Creates a new authentication token and loads the updater URL */ +var loginToken = ''; $(document).ready(function(){ + $('#oca_updatenotification_button').click(function() { + // Load the new token + $.ajax({ + url: OC.generateUrl('/apps/updatenotification/credentials') + }).success(function(data) { + loginToken = data; + $.ajax({ + url: OC.webroot+'/updater/', + headers: { + 'X-Updater-Auth': loginToken + }, + method: 'POST', + success: function(data){ + if(data !== 'false') { + var body = $('body'); + $('head').remove(); + body.html(data); + body.removeAttr('id'); + body.attr('id', 'body-settings'); + } + } + }); + }); + }); + $('#release-channel').change(function() { var newChannel = $('#release-channel').find(":selected").val(); diff --git a/apps/updatenotification/lib/Controller/AdminController.php b/apps/updatenotification/lib/Controller/AdminController.php index 16ae8144b16..9f10f1b32f2 100644 --- a/apps/updatenotification/lib/Controller/AdminController.php +++ b/apps/updatenotification/lib/Controller/AdminController.php @@ -112,7 +112,6 @@ class AdminController extends Controller implements ISettings { 'currentChannel' => $currentChannel, 'channels' => $channels, 'newVersionString' => ($updateState === []) ? '' : $updateState['updateVersion'], - 'downloadLink' => (empty($updateState['downloadLink'])) ? '' : $updateState['downloadLink'], 'notify_groups' => implode('|', $notifyGroups), ]; diff --git a/apps/updatenotification/lib/UpdateChecker.php b/apps/updatenotification/lib/UpdateChecker.php index 5f759b7c843..dd51831007c 100644 --- a/apps/updatenotification/lib/UpdateChecker.php +++ b/apps/updatenotification/lib/UpdateChecker.php @@ -49,9 +49,6 @@ class UpdateChecker { if(substr($data['web'], 0, 8) === 'https://') { $result['updateLink'] = $data['web']; } - if(substr($data['url'], 0, 8) === 'https://') { - $result['downloadLink'] = $data['url']; - } return $result; } diff --git a/apps/updatenotification/templates/admin.php b/apps/updatenotification/templates/admin.php index 0dd8aec4a04..68ef1d423b4 100644 --- a/apps/updatenotification/templates/admin.php +++ b/apps/updatenotification/templates/admin.php @@ -16,9 +16,7 @@ <form id="oca_updatenotification_section" class="followupsection"> <?php if($isNewVersionAvailable === true): ?> <strong><?php p($l->t('A new version is available: %s', [$newVersionString])); ?></strong> - <?php if ($_['downloadLink']): ?> - <a href="<?php p($_['downloadLink']); ?>" class="button"><?php p($l->t('Download now')) ?></a> - <?php endif; ?> + <input type="button" id="oca_updatenotification_button" value="<?php p($l->t('Open updater')) ?>"> <?php else: ?> <strong><?php print_unescaped($l->t('Your version is up to date.')); ?></strong> <span class="icon-info svg" title="<?php p($l->t('Checked on %s', [$lastCheckedDate])) ?>"></span> diff --git a/apps/updatenotification/tests/Controller/AdminControllerTest.php b/apps/updatenotification/tests/Controller/AdminControllerTest.php index 6d1ee219561..336edffc957 100644 --- a/apps/updatenotification/tests/Controller/AdminControllerTest.php +++ b/apps/updatenotification/tests/Controller/AdminControllerTest.php @@ -111,10 +111,7 @@ class AdminControllerTest extends TestCase { $this->updateChecker ->expects($this->once()) ->method('getUpdateState') - ->willReturn([ - 'updateVersion' => '8.1.2', - 'downloadLink' => 'https://downloads.nextcloud.org/server', - ]); + ->willReturn(['updateVersion' => '8.1.2']); $params = [ 'isNewVersionAvailable' => true, @@ -123,7 +120,6 @@ class AdminControllerTest extends TestCase { 'channels' => $channels, 'newVersionString' => '8.1.2', 'notify_groups' => 'admin', - 'downloadLink' => 'https://downloads.nextcloud.org/server', ]; $expected = new TemplateResponse('updatenotification', 'admin', $params, ''); @@ -168,7 +164,6 @@ class AdminControllerTest extends TestCase { 'channels' => $channels, 'newVersionString' => '', 'notify_groups' => 'admin', - 'downloadLink' => '', ]; $expected = new TemplateResponse('updatenotification', 'admin', $params, ''); diff --git a/apps/updatenotification/tests/UpdateCheckerTest.php b/apps/updatenotification/tests/UpdateCheckerTest.php index 38e64b6b5e5..ce19cc60f2c 100644 --- a/apps/updatenotification/tests/UpdateCheckerTest.php +++ b/apps/updatenotification/tests/UpdateCheckerTest.php @@ -74,7 +74,6 @@ class UpdateCheckerTest extends TestCase { 'updateAvailable' => true, 'updateVersion' => 'Nextcloud 123', 'updateLink' => 'https://docs.nextcloud.com/myUrl', - 'downloadLink' => 'https://downloads.nextcloud.org/server', ]; $this->assertSame($expected, $this->updateChecker->getUpdateState()); } diff --git a/apps/workflowengine/js/admin.js b/apps/workflowengine/js/admin.js index 2c6fa54d87d..0357d741ab1 100644 --- a/apps/workflowengine/js/admin.js +++ b/apps/workflowengine/js/admin.js @@ -21,7 +21,7 @@ (function() { Handlebars.registerHelper('selectItem', function(currentValue, itemValue) { if(currentValue === itemValue) { - return 'selected=selected'; + return 'selected="selected"'; } return ""; diff --git a/apps/workflowengine/js/filemimetypeplugin.js b/apps/workflowengine/js/filemimetypeplugin.js index 9fc9e3452f4..fd3f6a9ae63 100644 --- a/apps/workflowengine/js/filemimetypeplugin.js +++ b/apps/workflowengine/js/filemimetypeplugin.js @@ -41,9 +41,9 @@ return; } - var placeholder = t('workflowengine', 'text/plain'); + var placeholder = 'text/plain'; if (check['operator'] === 'matches' || check['operator'] === '!matches') { - placeholder = t('workflowengine', '/^text\\/(plain|html)$/i'); + placeholder = '/^text\\/(plain|html)$/i'; if (this._validateRegex(check['value'])) { $(element).removeClass('invalid-input'); diff --git a/apps/workflowengine/js/requesturlplugin.js b/apps/workflowengine/js/requesturlplugin.js index 5f21d2a59fc..7c81deaaf33 100644 --- a/apps/workflowengine/js/requesturlplugin.js +++ b/apps/workflowengine/js/requesturlplugin.js @@ -42,10 +42,10 @@ return; } - var placeholder = t('workflowengine', 'https://localhost/index.php'); + var placeholder = 'https://localhost/index.php'; if (check['operator'] === 'matches' || check['operator'] === '!matches') { - placeholder = t('workflowengine', '/^https\\:\\/\\/localhost\\/index\\.php$/i'); + placeholder = '/^https\\:\\/\\/localhost\\/index\\.php$/i'; } $(element).css('width', '250px') diff --git a/apps/workflowengine/js/requestuseragentplugin.js b/apps/workflowengine/js/requestuseragentplugin.js index 8413d52ac43..42e3f6b13d2 100644 --- a/apps/workflowengine/js/requestuseragentplugin.js +++ b/apps/workflowengine/js/requestuseragentplugin.js @@ -42,10 +42,10 @@ return; } - var placeholder = t('workflowengine', 'Mozilla/5.0 User Agent'); + var placeholder = 'Mozilla/5.0 User Agent'; if (check['operator'] === 'matches' || check['operator'] === '!matches') { - placeholder = t('workflowengine', '/^Mozilla\\/5\\.0 (.?)$/i'); + placeholder = '/^Mozilla\\/5\\.0 (.?)$/i'; } $(element).css('width', '250px') diff --git a/apps/workflowengine/templates/admin.php b/apps/workflowengine/templates/admin.php index 8f0124c5cbe..500300f93b3 100644 --- a/apps/workflowengine/templates/admin.php +++ b/apps/workflowengine/templates/admin.php @@ -55,12 +55,12 @@ <div class="check" data-id="{{@index}}"> <select class="check-class"> {{#each ../classes}} - <option value="{{class}}" {{selectItem class ../class}}>{{name}}</option> + <option value="{{class}}" {{{selectItem class ../class}}}>{{name}}</option> {{/each}} </select> <select class="check-operator"> {{#each (getOperators class)}} - <option value="{{operator}}" {{selectItem operator ../operator}}>{{name}}</option> + <option value="{{operator}}" {{{selectItem operator ../operator}}}>{{name}}</option> {{/each}} </select> <input type="text" class="check-value" value="{{value}}"> diff --git a/build/signed-off-checker.php b/build/signed-off-checker.php index 2a9df75b45c..d4aaf044481 100644 --- a/build/signed-off-checker.php +++ b/build/signed-off-checker.php @@ -28,15 +28,27 @@ $baseDir = __DIR__ . '/../'; $pullRequestNumber = getenv('DRONE_PULL_REQUEST'); +$repoOwner = getenv('DRONE_REPO_OWNER'); +$repoName = getenv('DRONE_REPO_NAME'); if(!is_string($pullRequestNumber) || $pullRequestNumber === '') { echo("The environment variable DRONE_PULL_REQUEST has no proper value.\n"); exit(1); } +if(!is_string($repoOwner) || $repoOwner === '') { + echo("The environment variable DRONE_REPO_OWNER has no proper value.\n"); + exit(1); +} + +if(!is_string($repoName) || $repoName === '') { + echo("The environment variable DRONE_REPO_NAME has no proper value.\n"); + exit(1); +} + $ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); -curl_setopt($ch, CURLOPT_URL, 'https://api.github.com/repos/nextcloud/server/pulls/'.$pullRequestNumber.'/commits'); +curl_setopt($ch, CURLOPT_URL, 'https://api.github.com/repos/'.$repoOwner.'/'.$repoName.'/pulls/'.$pullRequestNumber.'/commits'); curl_setopt($ch, CURLOPT_USERAGENT, 'CI for Nextcloud (https://github.com/nextcloud/server)'); $response = curl_exec($ch); curl_close($ch); diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 2dbb0075f7e..1d18674f656 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -635,6 +635,7 @@ return array( 'OC\\Repair\\DropOldTables' => $baseDir . '/lib/private/Repair/DropOldTables.php', 'OC\\Repair\\FillETags' => $baseDir . '/lib/private/Repair/FillETags.php', 'OC\\Repair\\InnoDB' => $baseDir . '/lib/private/Repair/InnoDB.php', + 'OC\\Repair\\MoveUpdaterStepFile' => $baseDir . '/lib/private/Repair/MoveUpdaterStepFile.php', 'OC\\Repair\\OldGroupMembershipShares' => $baseDir . '/lib/private/Repair/OldGroupMembershipShares.php', 'OC\\Repair\\Preview' => $baseDir . '/lib/private/Repair/Preview.php', 'OC\\Repair\\RemoveGetETagEntries' => $baseDir . '/lib/private/Repair/RemoveGetETagEntries.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 3e39b83fdd7..1051bca2f7e 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -665,6 +665,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Repair\\DropOldTables' => __DIR__ . '/../../..' . '/lib/private/Repair/DropOldTables.php', 'OC\\Repair\\FillETags' => __DIR__ . '/../../..' . '/lib/private/Repair/FillETags.php', 'OC\\Repair\\InnoDB' => __DIR__ . '/../../..' . '/lib/private/Repair/InnoDB.php', + 'OC\\Repair\\MoveUpdaterStepFile' => __DIR__ . '/../../..' . '/lib/private/Repair/MoveUpdaterStepFile.php', 'OC\\Repair\\OldGroupMembershipShares' => __DIR__ . '/../../..' . '/lib/private/Repair/OldGroupMembershipShares.php', 'OC\\Repair\\Preview' => __DIR__ . '/../../..' . '/lib/private/Repair/Preview.php', 'OC\\Repair\\RemoveGetETagEntries' => __DIR__ . '/../../..' . '/lib/private/Repair/RemoveGetETagEntries.php', diff --git a/lib/private/AppFramework/Utility/SimpleContainer.php b/lib/private/AppFramework/Utility/SimpleContainer.php index 60496ca329e..8d5bceb0b87 100644 --- a/lib/private/AppFramework/Utility/SimpleContainer.php +++ b/lib/private/AppFramework/Utility/SimpleContainer.php @@ -166,7 +166,10 @@ class SimpleContainer extends Container implements IContainer { * @return string */ protected function sanitizeName($name) { - return ltrim($name, '\\'); + if (isset($name[0]) && $name[0] === '\\') { + return ltrim($name, '\\'); + } + return $name; } } diff --git a/lib/private/Log.php b/lib/private/Log.php index 3e0734965b0..b76cb4f8c28 100644 --- a/lib/private/Log.php +++ b/lib/private/Log.php @@ -233,7 +233,7 @@ class Log implements ILogger { * @return void */ public function log($level, $message, array $context = array()) { - $minLevel = min($this->config->getValue('loglevel', Util::WARN), Util::ERROR); + $minLevel = min($this->config->getValue('loglevel', Util::WARN), Util::FATAL); $logCondition = $this->config->getValue('log.condition', []); array_walk($context, [$this->normalizer, 'format']); diff --git a/lib/private/Repair.php b/lib/private/Repair.php index cd23f5cb806..bf441d03c35 100644 --- a/lib/private/Repair.php +++ b/lib/private/Repair.php @@ -35,6 +35,7 @@ use OC\Repair\AvatarPermissions; use OC\Repair\CleanTags; use OC\Repair\Collation; use OC\Repair\DropOldJobs; +use OC\Repair\MoveUpdaterStepFile; use OC\Repair\OldGroupMembershipShares; use OC\Repair\RemoveGetETagEntries; use OC\Repair\RemoveOldShares; @@ -147,6 +148,7 @@ class Repair implements IOutput{ \OC::$server->getUserManager(), \OC::$server->getGroupManager() ), + new MoveUpdaterStepFile(\OC::$server->getConfig()), ]; } diff --git a/lib/private/Repair/MoveUpdaterStepFile.php b/lib/private/Repair/MoveUpdaterStepFile.php new file mode 100644 index 00000000000..fabaff40d24 --- /dev/null +++ b/lib/private/Repair/MoveUpdaterStepFile.php @@ -0,0 +1,80 @@ +<?php +/** + * @copyright Copyright (c) 2016 Morris Jobke <hey@morrisjobke.de> + * + * @author Morris Jobke <hey@morrisjobke.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Repair; + +use OCP\Migration\IOutput; +use OCP\Migration\IRepairStep; + +class MoveUpdaterStepFile implements IRepairStep { + + /** @var \OCP\IConfig */ + protected $config; + + /** + * @param \OCP\IConfig $config + */ + public function __construct($config) { + $this->config = $config; + } + + public function getName() { + return 'Move .step file of updater to backup location'; + } + + public function run(IOutput $output) { + + $dataDir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT); + $instanceId = $this->config->getSystemValue('instanceid', null); + + if(!is_string($instanceId) || empty($instanceId)) { + return; + } + + $updaterFolderPath = $dataDir . '/updater-' . $instanceId; + $stepFile = $updaterFolderPath . '/.step'; + if(file_exists($stepFile)) { + $output->info('.step file exists'); + + $previousStepFile = $updaterFolderPath . '/.step-previous-update'; + + // cleanup + if(file_exists($previousStepFile)) { + if(\OC_Helper::rmdirr($previousStepFile)) { + $output->info('.step-previous-update removed'); + } else { + $output->info('.step-previous-update can\'t be removed - abort move of .step file'); + return; + } + } + + // move step file + if(rename($stepFile, $previousStepFile)) { + $output->info('.step file moved to .step-previous-update'); + } else { + $output->warning('.step file can\'t be moved'); + } + } + } +} + diff --git a/lib/private/legacy/util.php b/lib/private/legacy/util.php index 04dcb8fc896..cb52949779f 100644 --- a/lib/private/legacy/util.php +++ b/lib/private/legacy/util.php @@ -336,7 +336,16 @@ class OC_Util { * @return void */ public static function copyr($source, \OCP\Files\Folder $target) { + $logger = \OC::$server->getLogger(); + + // Verify if folder exists $dir = opendir($source); + if($dir === false) { + $logger->error(sprintf('Could not opendir "%s"', $source), ['app' => 'core']); + return; + } + + // Copy the files while (false !== ($file = readdir($dir))) { if (!\OC\Files\Filesystem::isIgnoredDir($file)) { if (is_dir($source . '/' . $file)) { @@ -344,7 +353,13 @@ class OC_Util { self::copyr($source . '/' . $file, $child); } else { $child = $target->newFile($file); - stream_copy_to_stream(fopen($source . '/' . $file,'r'), $child->fopen('w')); + $sourceStream = fopen($source . '/' . $file, 'r'); + if($sourceStream === false) { + $logger->error(sprintf('Could not fopen "%s"', $source . '/' . $file), ['app' => 'core']); + closedir($dir); + return; + } + stream_copy_to_stream($sourceStream, $child->fopen('w')); } } } diff --git a/lib/public/Util.php b/lib/public/Util.php index aa8e5288c74..d5b0752553d 100644 --- a/lib/public/Util.php +++ b/lib/public/Util.php @@ -85,6 +85,7 @@ class Util { //Flush timestamp to reload version.php \OC::$server->getSession()->set('OC_Version_Timestamp', 0); \OC::$server->getAppConfig()->setValue('core', 'OC_Channel', $channel); + \OC::$server->getConfig()->setSystemValue('updater.release.channel', $channel); } /** |