summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/comments/appinfo/info.xml1
-rw-r--r--apps/contactsinteraction/appinfo/info.xml1
-rw-r--r--apps/dashboard/appinfo/info.xml1
-rw-r--r--apps/dashboard/lib/Controller/DashboardController.php12
-rw-r--r--apps/dav/appinfo/info.xml1
-rw-r--r--apps/federation/appinfo/info.xml1
-rw-r--r--apps/files/appinfo/info.xml1
-rw-r--r--apps/files_sharing/appinfo/info.xml1
-rw-r--r--apps/files_trashbin/appinfo/info.xml1
-rw-r--r--apps/files_versions/appinfo/info.xml1
-rw-r--r--apps/lookup_server_connector/appinfo/info.xml1
-rw-r--r--apps/oauth2/appinfo/info.xml1
-rw-r--r--apps/provisioning_api/appinfo/info.xml1
-rw-r--r--apps/settings/appinfo/info.xml1
-rw-r--r--apps/sharebymail/appinfo/info.xml1
-rw-r--r--apps/systemtags/appinfo/info.xml1
-rw-r--r--apps/theming/appinfo/info.xml1
-rw-r--r--apps/updatenotification/appinfo/info.xml1
-rw-r--r--apps/updatenotification/tests/Settings/AdminTest.php43
-rw-r--r--apps/user_status/appinfo/info.xml1
-rw-r--r--apps/weather_status/appinfo/info.xml1
-rw-r--r--core/shipped.json40
-rw-r--r--lib/private/App/AppManager.php22
-rw-r--r--lib/private/Files/Stream/SeekableHttpStream.php81
-rw-r--r--lib/private/Installer.php3
-rw-r--r--lib/public/App/IAppManager.php17
-rw-r--r--tests/acceptance/features/bootstrap/AppsManagementContext.php2
-rw-r--r--tests/lib/Files/ObjectStore/AzureTest.php4
-rw-r--r--tests/lib/Files/ObjectStore/ObjectStoreTest.php15
-rw-r--r--tests/lib/Files/Storage/Storage.php14
30 files changed, 202 insertions, 70 deletions
diff --git a/apps/comments/appinfo/info.xml b/apps/comments/appinfo/info.xml
index 88f780cf7de..70a1695b923 100644
--- a/apps/comments/appinfo/info.xml
+++ b/apps/comments/appinfo/info.xml
@@ -9,7 +9,6 @@
<licence>agpl</licence>
<author>Arthur Schiwon</author>
<author>Vincent Petry</author>
- <default_enable/>
<types>
<logging/>
</types>
diff --git a/apps/contactsinteraction/appinfo/info.xml b/apps/contactsinteraction/appinfo/info.xml
index 8ea086712c0..2f52ff2c030 100644
--- a/apps/contactsinteraction/appinfo/info.xml
+++ b/apps/contactsinteraction/appinfo/info.xml
@@ -13,7 +13,6 @@
<types>
<dav/>
</types>
- <default_enable/>
<category>integration</category>
<category>social</category>
<bugs>https://github.com/nextcloud/server/issues</bugs>
diff --git a/apps/dashboard/appinfo/info.xml b/apps/dashboard/appinfo/info.xml
index a21f3ab47b1..5969c5d1dee 100644
--- a/apps/dashboard/appinfo/info.xml
+++ b/apps/dashboard/appinfo/info.xml
@@ -14,7 +14,6 @@ they like and change the background to their liking.]]></description>
<licence>agpl</licence>
<author>Julius Härtl</author>
<namespace>Dashboard</namespace>
- <default_enable/>
<category>customization</category>
diff --git a/apps/dashboard/lib/Controller/DashboardController.php b/apps/dashboard/lib/Controller/DashboardController.php
index 6a7690b535c..b0e150e00f7 100644
--- a/apps/dashboard/lib/Controller/DashboardController.php
+++ b/apps/dashboard/lib/Controller/DashboardController.php
@@ -45,7 +45,7 @@ use OCP\IRequest;
class DashboardController extends Controller {
/** @var IInitialState */
- private $inititalState;
+ private $initialState;
/** @var IEventDispatcher */
private $eventDispatcher;
/** @var IManager */
@@ -66,7 +66,7 @@ class DashboardController extends Controller {
) {
parent::__construct($appName, $request);
- $this->inititalState = $initialState;
+ $this->initialState = $initialState;
$this->eventDispatcher = $eventDispatcher;
$this->dashboardManager = $dashboardManager;
$this->config = $config;
@@ -105,10 +105,10 @@ class DashboardController extends Controller {
// It does not matter if some statuses are missing from the array, missing ones are considered enabled
$statuses = ($statuses && count($statuses) > 0) ? $statuses : ['weather' => true];
- $this->inititalState->provideInitialState('panels', $widgets);
- $this->inititalState->provideInitialState('statuses', $statuses);
- $this->inititalState->provideInitialState('layout', $userLayout);
- $this->inititalState->provideInitialState('firstRun', $this->config->getUserValue($this->userId, 'dashboard', 'firstRun', '1') === '1');
+ $this->initialState->provideInitialState('panels', $widgets);
+ $this->initialState->provideInitialState('statuses', $statuses);
+ $this->initialState->provideInitialState('layout', $userLayout);
+ $this->initialState->provideInitialState('firstRun', $this->config->getUserValue($this->userId, 'dashboard', 'firstRun', '1') === '1');
$this->config->setUserValue($this->userId, 'dashboard', 'firstRun', '0');
$response = new TemplateResponse('dashboard', 'index', [
diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml
index deb99b1c33b..02fbe970c47 100644
--- a/apps/dav/appinfo/info.xml
+++ b/apps/dav/appinfo/info.xml
@@ -9,7 +9,6 @@
<licence>agpl</licence>
<author>owncloud.org</author>
<namespace>DAV</namespace>
- <default_enable/>
<types>
<filesystem/>
</types>
diff --git a/apps/federation/appinfo/info.xml b/apps/federation/appinfo/info.xml
index 67280335769..263ffad2092 100644
--- a/apps/federation/appinfo/info.xml
+++ b/apps/federation/appinfo/info.xml
@@ -9,7 +9,6 @@
<licence>agpl</licence>
<author>Bjoern Schiessle</author>
<namespace>Federation</namespace>
- <default_enable/>
<types>
<authentication/>
diff --git a/apps/files/appinfo/info.xml b/apps/files/appinfo/info.xml
index f62a913e8f4..6c8c043cd2c 100644
--- a/apps/files/appinfo/info.xml
+++ b/apps/files/appinfo/info.xml
@@ -9,7 +9,6 @@
<licence>agpl</licence>
<author>Robin Appelman</author>
<author>Vincent Petry</author>
- <default_enable/>
<types>
<filesystem/>
</types>
diff --git a/apps/files_sharing/appinfo/info.xml b/apps/files_sharing/appinfo/info.xml
index 44f3e3a45cd..66c49d6eeb6 100644
--- a/apps/files_sharing/appinfo/info.xml
+++ b/apps/files_sharing/appinfo/info.xml
@@ -14,7 +14,6 @@ Turning the feature off removes shared files and folders on the server for all s
<author>Michael Gapczynski</author>
<author>Bjoern Schiessle</author>
<namespace>Files_Sharing</namespace>
- <default_enable/>
<types>
<filesystem/>
</types>
diff --git a/apps/files_trashbin/appinfo/info.xml b/apps/files_trashbin/appinfo/info.xml
index b8f4b5ea6b1..f63953ade9b 100644
--- a/apps/files_trashbin/appinfo/info.xml
+++ b/apps/files_trashbin/appinfo/info.xml
@@ -13,7 +13,6 @@ To prevent a user from running out of disk space, the Deleted files app will not
<licence>agpl</licence>
<author>Bjoern Schiessle</author>
<namespace>Files_Trashbin</namespace>
- <default_enable/>
<types>
<filesystem/>
<dav/>
diff --git a/apps/files_versions/appinfo/info.xml b/apps/files_versions/appinfo/info.xml
index 49e48e6e436..bdd699d620c 100644
--- a/apps/files_versions/appinfo/info.xml
+++ b/apps/files_versions/appinfo/info.xml
@@ -13,7 +13,6 @@
<author>Frank Karlitschek</author>
<author>Bjoern Schiessle</author>
<namespace>Files_Versions</namespace>
- <default_enable/>
<types>
<filesystem/>
<dav/>
diff --git a/apps/lookup_server_connector/appinfo/info.xml b/apps/lookup_server_connector/appinfo/info.xml
index cf486e06228..5cc54c7e9f2 100644
--- a/apps/lookup_server_connector/appinfo/info.xml
+++ b/apps/lookup_server_connector/appinfo/info.xml
@@ -9,7 +9,6 @@
<licence>agpl</licence>
<author>Bjoern Schiessle</author>
<namespace>LookupServerConnector</namespace>
- <default_enable/>
<types>
<authentication/>
</types>
diff --git a/apps/oauth2/appinfo/info.xml b/apps/oauth2/appinfo/info.xml
index ae2fcb09986..6eed9b9d18e 100644
--- a/apps/oauth2/appinfo/info.xml
+++ b/apps/oauth2/appinfo/info.xml
@@ -9,7 +9,6 @@
<licence>agpl</licence>
<author>Lukas Reschke</author>
<namespace>OAuth2</namespace>
- <default_enable/>
<types>
<authentication/>
</types>
diff --git a/apps/provisioning_api/appinfo/info.xml b/apps/provisioning_api/appinfo/info.xml
index dd01689950a..56dc6e610d4 100644
--- a/apps/provisioning_api/appinfo/info.xml
+++ b/apps/provisioning_api/appinfo/info.xml
@@ -17,7 +17,6 @@
<licence>agpl</licence>
<author>Tom Needham</author>
<namespace>Provisioning_API</namespace>
- <default_enable/>
<types>
<prevent_group_restriction/>
</types>
diff --git a/apps/settings/appinfo/info.xml b/apps/settings/appinfo/info.xml
index 13e5eddcdf2..f030c1e5c50 100644
--- a/apps/settings/appinfo/info.xml
+++ b/apps/settings/appinfo/info.xml
@@ -9,7 +9,6 @@
<licence>agpl</licence>
<author>Nextcloud</author>
<namespace>Settings</namespace>
- <default_enable/>
<category>customization</category>
<bugs>https://github.com/nextcloud/server/issues</bugs>
diff --git a/apps/sharebymail/appinfo/info.xml b/apps/sharebymail/appinfo/info.xml
index f4d2900c80d..70458f44d19 100644
--- a/apps/sharebymail/appinfo/info.xml
+++ b/apps/sharebymail/appinfo/info.xml
@@ -9,7 +9,6 @@
<licence>agpl</licence>
<author>Bjoern Schiessle</author>
<namespace>ShareByMail</namespace>
- <default_enable/>
<types>
<filesystem/>
diff --git a/apps/systemtags/appinfo/info.xml b/apps/systemtags/appinfo/info.xml
index 9e0b347acbd..1f572a831d6 100644
--- a/apps/systemtags/appinfo/info.xml
+++ b/apps/systemtags/appinfo/info.xml
@@ -11,7 +11,6 @@
<author>Vincent Petry</author>
<author>Joas Schilling</author>
<namespace>SystemTags</namespace>
- <default_enable/>
<types>
<logging/>
</types>
diff --git a/apps/theming/appinfo/info.xml b/apps/theming/appinfo/info.xml
index b67b461c410..6823a9fbd88 100644
--- a/apps/theming/appinfo/info.xml
+++ b/apps/theming/appinfo/info.xml
@@ -9,7 +9,6 @@
<licence>agpl</licence>
<author>Nextcloud</author>
<namespace>Theming</namespace>
- <default_enable/>
<types>
<logging/>
diff --git a/apps/updatenotification/appinfo/info.xml b/apps/updatenotification/appinfo/info.xml
index 44fa6b9c50f..626316f04aa 100644
--- a/apps/updatenotification/appinfo/info.xml
+++ b/apps/updatenotification/appinfo/info.xml
@@ -9,7 +9,6 @@
<licence>agpl</licence>
<author>Lukas Reschke</author>
<namespace>UpdateNotification</namespace>
- <default_enable/>
<category>monitoring</category>
<bugs>https://github.com/nextcloud/server/issues</bugs>
<dependencies>
diff --git a/apps/updatenotification/tests/Settings/AdminTest.php b/apps/updatenotification/tests/Settings/AdminTest.php
index 489679dfabd..784e56e79ed 100644
--- a/apps/updatenotification/tests/Settings/AdminTest.php
+++ b/apps/updatenotification/tests/Settings/AdminTest.php
@@ -42,6 +42,7 @@ use OCP\L10N\ILanguageIterator;
use OCP\Support\Subscription\IRegistry;
use OCP\UserInterface;
use OCP\User\Backend\ICountUsersBackend;
+use OCP\AppFramework\Services\IInitialState;
use OCP\Util;
use OC\User\Backend;
use Psr\Log\LoggerInterface;
@@ -66,6 +67,8 @@ class AdminTest extends TestCase {
private $userManager;
/** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */
private $logger;
+ /** IInitialState|\PHPUnit\Framework\MockObject\MockObject */
+ private $initialState;
protected function setUp(): void {
parent::setUp();
@@ -78,6 +81,7 @@ class AdminTest extends TestCase {
$this->subscriptionRegistry = $this->createMock(IRegistry::class);
$this->userManager = $this->createMock(IUserManager::class);
$this->logger = $this->createMock(LoggerInterface::class);
+ $this->initialState = $this->createMock(IInitialState::class);
$this->admin = new Admin(
$this->config,
@@ -87,7 +91,8 @@ class AdminTest extends TestCase {
$this->l10nFactory,
$this->subscriptionRegistry,
$this->userManager,
- $this->logger
+ $this->logger,
+ $this->initialState
);
}
@@ -187,8 +192,9 @@ class AdminTest extends TestCase {
->method('delegateHasValidSubscription')
->willReturn(true);
- $params = [
- 'json' => json_encode([
+ $this->initialState->expects($this->once())
+ ->method('provideInitialState')
+ ->with('data', [
'isNewVersionAvailable' => true,
'isUpdateChecked' => true,
'lastChecked' => 'LastCheckedReturnValue',
@@ -205,13 +211,12 @@ class AdminTest extends TestCase {
'isDefaultUpdateServerURL' => true,
'updateServerURL' => 'https://updates.nextcloud.com/updater_server/',
'notifyGroups' => [
- ['value' => 'admin', 'label' => 'Administrators'],
+ ['id' => 'admin', 'displayname' => 'Administrators'],
],
'hasValidSubscription' => true,
- ]),
- ];
+ ]);
- $expected = new TemplateResponse('updatenotification', 'admin', $params, '');
+ $expected = new TemplateResponse('updatenotification', 'admin', [], '');
$this->assertEquals($expected, $this->admin->getForm());
}
@@ -311,8 +316,9 @@ class AdminTest extends TestCase {
->method('delegateHasValidSubscription')
->willReturn(true);
- $params = [
- 'json' => json_encode([
+ $this->initialState->expects($this->once())
+ ->method('provideInitialState')
+ ->with('data', [
'isNewVersionAvailable' => true,
'isUpdateChecked' => true,
'lastChecked' => 'LastCheckedReturnValue',
@@ -329,13 +335,12 @@ class AdminTest extends TestCase {
'isDefaultUpdateServerURL' => false,
'updateServerURL' => 'https://updates.nextcloud.com/updater_server_changed/',
'notifyGroups' => [
- ['value' => 'admin', 'label' => 'Administrators'],
+ ['id' => 'admin', 'displayname' => 'Administrators'],
],
'hasValidSubscription' => true,
- ]),
- ];
+ ]);
- $expected = new TemplateResponse('updatenotification', 'admin', $params, '');
+ $expected = new TemplateResponse('updatenotification', 'admin', [], '');
$this->assertEquals($expected, $this->admin->getForm());
}
@@ -435,8 +440,9 @@ class AdminTest extends TestCase {
->method('delegateHasValidSubscription')
->willReturn(true);
- $params = [
- 'json' => json_encode([
+ $this->initialState->expects($this->once())
+ ->method('provideInitialState')
+ ->with('data', [
'isNewVersionAvailable' => true,
'isUpdateChecked' => true,
'lastChecked' => 'LastCheckedReturnValue',
@@ -453,13 +459,12 @@ class AdminTest extends TestCase {
'isDefaultUpdateServerURL' => true,
'updateServerURL' => 'https://updates.nextcloud.com/customers/ABC-DEF/',
'notifyGroups' => [
- ['value' => 'admin', 'label' => 'Administrators'],
+ ['id' => 'admin', 'displayname' => 'Administrators'],
],
'hasValidSubscription' => true,
- ]),
- ];
+ ]);
- $expected = new TemplateResponse('updatenotification', 'admin', $params, '');
+ $expected = new TemplateResponse('updatenotification', 'admin', [], '');
$this->assertEquals($expected, $this->admin->getForm());
}
diff --git a/apps/user_status/appinfo/info.xml b/apps/user_status/appinfo/info.xml
index c385886e946..23f07eb325a 100644
--- a/apps/user_status/appinfo/info.xml
+++ b/apps/user_status/appinfo/info.xml
@@ -9,7 +9,6 @@
<licence>agpl</licence>
<author mail="oc.list@georgehrke.com" >Georg Ehrke</author>
<namespace>UserStatus</namespace>
- <default_enable/>
<category>social</category>
<bugs>https://github.com/nextcloud/server</bugs>
<navigations>
diff --git a/apps/weather_status/appinfo/info.xml b/apps/weather_status/appinfo/info.xml
index 50d107855fd..403d5eb3e5d 100644
--- a/apps/weather_status/appinfo/info.xml
+++ b/apps/weather_status/appinfo/info.xml
@@ -11,7 +11,6 @@
<licence>agpl</licence>
<author mail="eneiluj@posteo.net">Julien Veyssier</author>
<namespace>WeatherStatus</namespace>
- <default_enable/>
<category>integration</category>
<category>dashboard</category>
<bugs>https://github.com/nextcloud/server</bugs>
diff --git a/core/shipped.json b/core/shipped.json
index 33980afb7c4..e1407798289 100644
--- a/core/shipped.json
+++ b/core/shipped.json
@@ -47,6 +47,46 @@
"weather_status",
"workflowengine"
],
+ "defaultEnabled": [
+ "activity",
+ "circles",
+ "comments",
+ "contactsinteraction",
+ "dashboard",
+ "dav",
+ "federation",
+ "files",
+ "files_pdfviewer",
+ "files_rightclick",
+ "files_sharing",
+ "files_trashbin",
+ "files_versions",
+ "files_videoplayer",
+ "firstrunwizard",
+ "logreader",
+ "lookup_server_connector",
+ "nextcloud_announcements",
+ "notifications",
+ "oauth2",
+ "password_policy",
+ "photos",
+ "privacy",
+ "provisioning_api",
+ "recommendations",
+ "related_resources",
+ "serverinfo",
+ "settings",
+ "sharebymail",
+ "support",
+ "survey_client",
+ "systemtags",
+ "text",
+ "theming",
+ "updatenotification",
+ "user_status",
+ "viewer",
+ "weather_status"
+ ],
"alwaysEnabled": [
"files",
"cloud_federation_api",
diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php
index f154bd854ad..6d2fe51d0ed 100644
--- a/lib/private/App/AppManager.php
+++ b/lib/private/App/AppManager.php
@@ -13,6 +13,7 @@
* @author Julius Haertl <jus@bitgrid.net>
* @author Julius Härtl <jus@bitgrid.net>
* @author Lukas Reschke <lukas@statuscode.ch>
+ * @author Maxence Lange <maxence@artificial-owl.com>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <robin@icewind.nl>
* @author Roeland Jago Douma <roeland@famdouma.nl>
@@ -91,8 +92,8 @@ class AppManager implements IAppManager {
/** @var string[] */
private $shippedApps;
- /** @var string[] */
- private $alwaysEnabled;
+ private array $alwaysEnabled = [];
+ private array $defaultEnabled = [];
/** @var array */
private $appInfos = [];
@@ -574,6 +575,7 @@ class AppManager implements IAppManager {
$content = json_decode(file_get_contents($shippedJson), true);
$this->shippedApps = $content['shippedApps'];
$this->alwaysEnabled = $content['alwaysEnabled'];
+ $this->defaultEnabled = $content['defaultEnabled'];
}
}
@@ -584,4 +586,20 @@ class AppManager implements IAppManager {
$this->loadShippedJson();
return $this->alwaysEnabled;
}
+
+ /**
+ * @inheritdoc
+ */
+ public function isDefaultEnabled(string $appId): bool {
+ return (in_array($appId, $this->getDefaultEnabledApps()));
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getDefaultEnabledApps():array {
+ $this->loadShippedJson();
+
+ return $this->defaultEnabled;
+ }
}
diff --git a/lib/private/Files/Stream/SeekableHttpStream.php b/lib/private/Files/Stream/SeekableHttpStream.php
index 820a681bd07..df37fd29f42 100644
--- a/lib/private/Files/Stream/SeekableHttpStream.php
+++ b/lib/private/Files/Stream/SeekableHttpStream.php
@@ -32,7 +32,7 @@ use Icewind\Streams\Wrapper;
class SeekableHttpStream implements File {
private const PROTOCOL = 'httpseek';
- private static $registered = false;
+ private static bool $registered = false;
/**
* Registers the stream wrapper using the `httpseek://` url scheme
@@ -73,24 +73,26 @@ class SeekableHttpStream implements File {
/** @var callable */
private $openCallback;
- /** @var resource */
+ /** @var ?resource|closed-resource */
private $current;
- /** @var int */
- private $offset = 0;
- /** @var int */
- private $length = 0;
+ private int $offset = 0;
+ private int $length = 0;
+ private bool $needReconnect = false;
- private function reconnect(int $start) {
+ private function reconnect(int $start): bool {
+ $this->needReconnect = false;
$range = $start . '-';
- if ($this->current != null) {
+ if ($this->hasOpenStream()) {
fclose($this->current);
}
- $this->current = ($this->openCallback)($range);
+ $stream = ($this->openCallback)($range);
- if ($this->current === false) {
+ if ($stream === false) {
+ $this->current = null;
return false;
}
+ $this->current = $stream;
$responseHead = stream_get_meta_data($this->current)['wrapper_data'];
@@ -109,6 +111,7 @@ class SeekableHttpStream implements File {
return preg_match('#^content-range:#i', $v) === 1;
}));
if (!$rangeHeaders) {
+ $this->current = null;
return false;
}
$contentRange = $rangeHeaders[0];
@@ -119,6 +122,7 @@ class SeekableHttpStream implements File {
$length = intval(explode('/', $range)[1]);
if ($begin !== $start) {
+ $this->current = null;
return false;
}
@@ -128,6 +132,28 @@ class SeekableHttpStream implements File {
return true;
}
+ /**
+ * @return ?resource
+ */
+ private function getCurrent() {
+ if ($this->needReconnect) {
+ $this->reconnect($this->offset);
+ }
+ if (is_resource($this->current)) {
+ return $this->current;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @return bool
+ * @psalm-assert-if-true resource $this->current
+ */
+ private function hasOpenStream(): bool {
+ return is_resource($this->current);
+ }
+
public function stream_open($path, $mode, $options, &$opened_path) {
$options = stream_context_get_options($this->context)[self::PROTOCOL];
$this->openCallback = $options['callback'];
@@ -136,10 +162,10 @@ class SeekableHttpStream implements File {
}
public function stream_read($count) {
- if (!$this->current) {
+ if (!$this->getCurrent()) {
return false;
}
- $ret = fread($this->current, $count);
+ $ret = fread($this->getCurrent(), $count);
$this->offset += strlen($ret);
return $ret;
}
@@ -149,22 +175,34 @@ class SeekableHttpStream implements File {
case SEEK_SET:
if ($offset === $this->offset) {
return true;
+ } else {
+ $this->offset = $offset;
}
- return $this->reconnect($offset);
+ break;
case SEEK_CUR:
if ($offset === 0) {
return true;
+ } else {
+ $this->offset += $offset;
}
- return $this->reconnect($this->offset + $offset);
+ break;
case SEEK_END:
if ($this->length === 0) {
return false;
} elseif ($this->length + $offset === $this->offset) {
return true;
+ } else {
+ $this->offset = $this->length + $offset;
}
- return $this->reconnect($this->length + $offset);
+ break;
}
- return false;
+
+ if ($this->hasOpenStream()) {
+ fclose($this->current);
+ }
+ $this->current = null;
+ $this->needReconnect = true;
+ return true;
}
public function stream_tell() {
@@ -172,25 +210,26 @@ class SeekableHttpStream implements File {
}
public function stream_stat() {
- if (is_resource($this->current)) {
- return fstat($this->current);
+ if ($this->getCurrent()) {
+ return fstat($this->getCurrent());
} else {
return false;
}
}
public function stream_eof() {
- if (is_resource($this->current)) {
- return feof($this->current);
+ if ($this->getCurrent()) {
+ return feof($this->getCurrent());
} else {
return true;
}
}
public function stream_close() {
- if (is_resource($this->current)) {
+ if ($this->hasOpenStream()) {
fclose($this->current);
}
+ $this->current = null;
}
public function stream_write($data) {
diff --git a/lib/private/Installer.php b/lib/private/Installer.php
index 86d933b6fbd..43c3db7c3fd 100644
--- a/lib/private/Installer.php
+++ b/lib/private/Installer.php
@@ -545,8 +545,7 @@ class Installer {
if ($filename[0] !== '.' and is_dir($app_dir['path']."/$filename")) {
if (file_exists($app_dir['path']."/$filename/appinfo/info.xml")) {
if ($config->getAppValue($filename, "installed_version", null) === null) {
- $info = OC_App::getAppInfo($filename);
- $enabled = isset($info['default_enable']);
+ $enabled = $appManager->isDefaultEnabled($filename);
if (($enabled || in_array($filename, $appManager->getAlwaysEnabledApps()))
&& $config->getAppValue($filename, 'enabled') !== 'no') {
if ($softErrors) {
diff --git a/lib/public/App/IAppManager.php b/lib/public/App/IAppManager.php
index e0b5c049290..f7c9d848099 100644
--- a/lib/public/App/IAppManager.php
+++ b/lib/public/App/IAppManager.php
@@ -84,6 +84,17 @@ interface IAppManager {
public function isInstalled($appId);
/**
+ * Check if an app should be enabled by default
+ *
+ * Notice: This actually checks if the app should be enabled by default
+ * and not if currently installed/enabled
+ *
+ * @param string $appId ID of the app
+ * @since 25.0.0
+ */
+ public function isDefaultEnabled(string $appId):bool;
+
+ /**
* Enable an app for every user
*
* @param string $appId
@@ -179,6 +190,12 @@ interface IAppManager {
public function getAlwaysEnabledApps();
/**
+ * @return string[] app IDs
+ * @since 25.0.0
+ */
+ public function getDefaultEnabledApps(): array;
+
+ /**
* @param \OCP\IGroup $group
* @return String[]
* @since 17.0.0
diff --git a/tests/acceptance/features/bootstrap/AppsManagementContext.php b/tests/acceptance/features/bootstrap/AppsManagementContext.php
index 747ef3d96b5..908754163d7 100644
--- a/tests/acceptance/features/bootstrap/AppsManagementContext.php
+++ b/tests/acceptance/features/bootstrap/AppsManagementContext.php
@@ -243,7 +243,7 @@ class AppsManagementContext implements Context, ActorAwareInterface {
*/
public function iSeeTheAppBundles() {
Assert::assertTrue(
- $this->actor->find(self::rowForApp('Auditing / Logging'), 2)->isVisible()
+ $this->actor->find(self::rowForApp('Auditing / Logging'), 10)->isVisible()
);
Assert::assertTrue(
$this->actor->find(self::rowForApp('LDAP user and group backend'), 2)->isVisible()
diff --git a/tests/lib/Files/ObjectStore/AzureTest.php b/tests/lib/Files/ObjectStore/AzureTest.php
index 716d06f48c9..054dc36cce4 100644
--- a/tests/lib/Files/ObjectStore/AzureTest.php
+++ b/tests/lib/Files/ObjectStore/AzureTest.php
@@ -35,4 +35,8 @@ class AzureTest extends ObjectStoreTest {
return new Azure($config['arguments']);
}
+
+ public function testFseekSize() {
+ $this->markTestSkipped('azure does not support seeking at the moment');
+ }
}
diff --git a/tests/lib/Files/ObjectStore/ObjectStoreTest.php b/tests/lib/Files/ObjectStore/ObjectStoreTest.php
index a245f0ae366..2333168d838 100644
--- a/tests/lib/Files/ObjectStore/ObjectStoreTest.php
+++ b/tests/lib/Files/ObjectStore/ObjectStoreTest.php
@@ -143,4 +143,19 @@ abstract class ObjectStoreTest extends TestCase {
$this->assertEquals('foobar', stream_get_contents($instance->readObject('target')));
}
+
+ public function testFseekSize() {
+ $instance = $this->getInstance();
+
+ $textFile = \OC::$SERVERROOT . '/tests/data/lorem.txt';
+ $size = filesize($textFile);
+ $instance->writeObject('source', fopen($textFile, 'r'));
+
+ $fh = $instance->readObject('source');
+
+ fseek($fh, 0, SEEK_END);
+ $pos = ftell($fh);
+
+ $this->assertEquals($size, $pos);
+ }
}
diff --git a/tests/lib/Files/Storage/Storage.php b/tests/lib/Files/Storage/Storage.php
index c4248b7e0da..a646fd5fd0b 100644
--- a/tests/lib/Files/Storage/Storage.php
+++ b/tests/lib/Files/Storage/Storage.php
@@ -664,4 +664,18 @@ abstract class Storage extends \Test\TestCase {
$this->assertStringEqualsFile($textFile, $storage->file_get_contents('test.txt'));
$this->assertEquals('resource (closed)', gettype($source));
}
+
+ public function testFseekSize() {
+ $textFile = \OC::$SERVERROOT . '/tests/data/lorem.txt';
+ $this->instance->file_put_contents('bar.txt', file_get_contents($textFile));
+
+ $size = $this->instance->filesize('bar.txt');
+ $this->assertEquals(filesize($textFile), $size);
+ $fh = $this->instance->fopen('bar.txt', 'r');
+
+ fseek($fh, 0, SEEK_END);
+ $pos = ftell($fh);
+
+ $this->assertEquals($size, $pos);
+ }
}