summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/composer/composer/autoload_classmap.php4
-rw-r--r--lib/composer/composer/autoload_static.php4
-rw-r--r--lib/l10n/cs.js1
-rw-r--r--lib/l10n/cs.json1
-rw-r--r--lib/l10n/fr.js1
-rw-r--r--lib/l10n/fr.json1
-rw-r--r--lib/l10n/pl.js3
-rw-r--r--lib/l10n/pl.json3
-rw-r--r--lib/private/Contacts/ContactsMenu/ContactsStore.php8
-rw-r--r--lib/private/DB/MigrationService.php24
-rw-r--r--lib/private/Files/Config/UserMountCache.php2
-rw-r--r--lib/private/Files/Utils/Scanner.php5
-rw-r--r--lib/private/Log/ExceptionSerializer.php10
-rw-r--r--lib/private/Log/File.php3
-rw-r--r--lib/private/Mail/EMailTemplate.php14
-rw-r--r--lib/private/NavigationManager.php4
-rw-r--r--lib/private/Notification/Manager.php36
-rw-r--r--lib/private/Server.php4
-rw-r--r--lib/private/Settings/Manager.php2
-rw-r--r--lib/private/Share/Share.php1
-rw-r--r--lib/private/Share20/DefaultShareProvider.php137
-rw-r--r--lib/private/Share20/Manager.php12
-rw-r--r--lib/private/Share20/ProviderFactory.php6
-rw-r--r--lib/private/Share20/Share.php37
-rw-r--r--lib/private/Template/IconsCacher.php147
-rw-r--r--lib/private/Template/SCSSCacher.php118
-rw-r--r--lib/private/TemplateLayout.php4
-rw-r--r--lib/private/legacy/util.php25
-rw-r--r--lib/public/Notification/IManager.php12
-rw-r--r--lib/public/Share/IShare.php41
-rw-r--r--lib/public/Util.php10
31 files changed, 597 insertions, 83 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 1c67fb9327f..44b7cd5244f 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -594,6 +594,7 @@ return array(
'OC\\Core\\Controller\\PreviewController' => $baseDir . '/core/Controller/PreviewController.php',
'OC\\Core\\Controller\\SearchController' => $baseDir . '/core/Controller/SearchController.php',
'OC\\Core\\Controller\\SetupController' => $baseDir . '/core/Controller/SetupController.php',
+ 'OC\\Core\\Controller\\SvgController' => $baseDir . '/core/Controller/SvgController.php',
'OC\\Core\\Controller\\TwoFactorChallengeController' => $baseDir . '/core/Controller/TwoFactorChallengeController.php',
'OC\\Core\\Controller\\UserController' => $baseDir . '/core/Controller/UserController.php',
'OC\\Core\\Controller\\WalledGardenController' => $baseDir . '/core/Controller/WalledGardenController.php',
@@ -610,6 +611,8 @@ return array(
'OC\\Core\\Migrations\\Version14000Date20180518120534' => $baseDir . '/core/Migrations/Version14000Date20180518120534.php',
'OC\\Core\\Migrations\\Version14000Date20180522074438' => $baseDir . '/core/Migrations/Version14000Date20180522074438.php',
'OC\\Core\\Migrations\\Version14000Date20180626223656' => $baseDir . '/core/Migrations/Version14000Date20180626223656.php',
+ 'OC\\Core\\Migrations\\Version14000Date20180710092004' => $baseDir . '/core/Migrations/Version14000Date20180710092004.php',
+ 'OC\\Core\\Migrations\\Version14000Date20180712153140' => $baseDir . '/core/Migrations/Version14000Date20180712153140.php',
'OC\\DB\\Adapter' => $baseDir . '/lib/private/DB/Adapter.php',
'OC\\DB\\AdapterMySQL' => $baseDir . '/lib/private/DB/AdapterMySQL.php',
'OC\\DB\\AdapterOCI8' => $baseDir . '/lib/private/DB/AdapterOCI8.php',
@@ -1016,6 +1019,7 @@ return array(
'OC\\TemplateLayout' => $baseDir . '/lib/private/TemplateLayout.php',
'OC\\Template\\Base' => $baseDir . '/lib/private/Template/Base.php',
'OC\\Template\\CSSResourceLocator' => $baseDir . '/lib/private/Template/CSSResourceLocator.php',
+ 'OC\\Template\\IconsCacher' => $baseDir . '/lib/private/Template/IconsCacher.php',
'OC\\Template\\JSCombiner' => $baseDir . '/lib/private/Template/JSCombiner.php',
'OC\\Template\\JSConfigHelper' => $baseDir . '/lib/private/Template/JSConfigHelper.php',
'OC\\Template\\JSResourceLocator' => $baseDir . '/lib/private/Template/JSResourceLocator.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index e40a5ea75db..815f94d5711 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -624,6 +624,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Core\\Controller\\PreviewController' => __DIR__ . '/../../..' . '/core/Controller/PreviewController.php',
'OC\\Core\\Controller\\SearchController' => __DIR__ . '/../../..' . '/core/Controller/SearchController.php',
'OC\\Core\\Controller\\SetupController' => __DIR__ . '/../../..' . '/core/Controller/SetupController.php',
+ 'OC\\Core\\Controller\\SvgController' => __DIR__ . '/../../..' . '/core/Controller/SvgController.php',
'OC\\Core\\Controller\\TwoFactorChallengeController' => __DIR__ . '/../../..' . '/core/Controller/TwoFactorChallengeController.php',
'OC\\Core\\Controller\\UserController' => __DIR__ . '/../../..' . '/core/Controller/UserController.php',
'OC\\Core\\Controller\\WalledGardenController' => __DIR__ . '/../../..' . '/core/Controller/WalledGardenController.php',
@@ -640,6 +641,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Core\\Migrations\\Version14000Date20180518120534' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180518120534.php',
'OC\\Core\\Migrations\\Version14000Date20180522074438' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180522074438.php',
'OC\\Core\\Migrations\\Version14000Date20180626223656' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180626223656.php',
+ 'OC\\Core\\Migrations\\Version14000Date20180710092004' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180710092004.php',
+ 'OC\\Core\\Migrations\\Version14000Date20180712153140' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180712153140.php',
'OC\\DB\\Adapter' => __DIR__ . '/../../..' . '/lib/private/DB/Adapter.php',
'OC\\DB\\AdapterMySQL' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterMySQL.php',
'OC\\DB\\AdapterOCI8' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterOCI8.php',
@@ -1046,6 +1049,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\TemplateLayout' => __DIR__ . '/../../..' . '/lib/private/TemplateLayout.php',
'OC\\Template\\Base' => __DIR__ . '/../../..' . '/lib/private/Template/Base.php',
'OC\\Template\\CSSResourceLocator' => __DIR__ . '/../../..' . '/lib/private/Template/CSSResourceLocator.php',
+ 'OC\\Template\\IconsCacher' => __DIR__ . '/../../..' . '/lib/private/Template/IconsCacher.php',
'OC\\Template\\JSCombiner' => __DIR__ . '/../../..' . '/lib/private/Template/JSCombiner.php',
'OC\\Template\\JSConfigHelper' => __DIR__ . '/../../..' . '/lib/private/Template/JSConfigHelper.php',
'OC\\Template\\JSResourceLocator' => __DIR__ . '/../../..' . '/lib/private/Template/JSResourceLocator.php',
diff --git a/lib/l10n/cs.js b/lib/l10n/cs.js
index f7dd8cd72cc..8de62521afc 100644
--- a/lib/l10n/cs.js
+++ b/lib/l10n/cs.js
@@ -231,6 +231,7 @@ OC.L10N.register(
"Storage is temporarily not available" : "Úložiště je dočasně nedostupné",
"Storage connection timeout. %s" : "Vypršení připojení k úložišti. %s",
"Personal" : "Osobní",
+ "Admin" : "Správce",
"APCu" : "APCu",
"Redis" : "Redis",
"Tips & tricks" : "Tipy a triky",
diff --git a/lib/l10n/cs.json b/lib/l10n/cs.json
index 228b06a682f..0c5c7309b03 100644
--- a/lib/l10n/cs.json
+++ b/lib/l10n/cs.json
@@ -229,6 +229,7 @@
"Storage is temporarily not available" : "Úložiště je dočasně nedostupné",
"Storage connection timeout. %s" : "Vypršení připojení k úložišti. %s",
"Personal" : "Osobní",
+ "Admin" : "Správce",
"APCu" : "APCu",
"Redis" : "Redis",
"Tips & tricks" : "Tipy a triky",
diff --git a/lib/l10n/fr.js b/lib/l10n/fr.js
index eaeb1f50b1e..7a95348d341 100644
--- a/lib/l10n/fr.js
+++ b/lib/l10n/fr.js
@@ -229,6 +229,7 @@ OC.L10N.register(
"Your data directory is invalid" : "Votre répertoire n'est pas valide",
"Ensure there is a file called \".ocdata\" in the root of the data directory." : "Assurez-vous que le répertoire de données contient un fichier \".ocdata\" à sa racine.",
"Action \"%s\" not supported or implemented." : "Action \"%s\" non supportée ou implémentée.",
+ "Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "Paramètres manquants pour compléter la requête. Paramètres manquants : \"%s\"",
"Could not obtain lock type %d on \"%s\"." : "Impossible d'obtenir le verrouillage de type %d sur \"%s\".",
"Storage unauthorized. %s" : "Espace de stockage non autorisé. %s",
"Storage incomplete configuration. %s" : "Configuration de l'espace de stockage incomplète. %s",
diff --git a/lib/l10n/fr.json b/lib/l10n/fr.json
index 50416a619a8..77835280ed9 100644
--- a/lib/l10n/fr.json
+++ b/lib/l10n/fr.json
@@ -227,6 +227,7 @@
"Your data directory is invalid" : "Votre répertoire n'est pas valide",
"Ensure there is a file called \".ocdata\" in the root of the data directory." : "Assurez-vous que le répertoire de données contient un fichier \".ocdata\" à sa racine.",
"Action \"%s\" not supported or implemented." : "Action \"%s\" non supportée ou implémentée.",
+ "Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "Paramètres manquants pour compléter la requête. Paramètres manquants : \"%s\"",
"Could not obtain lock type %d on \"%s\"." : "Impossible d'obtenir le verrouillage de type %d sur \"%s\".",
"Storage unauthorized. %s" : "Espace de stockage non autorisé. %s",
"Storage incomplete configuration. %s" : "Configuration de l'espace de stockage incomplète. %s",
diff --git a/lib/l10n/pl.js b/lib/l10n/pl.js
index 7f64cc6d33e..eb0e65e28f1 100644
--- a/lib/l10n/pl.js
+++ b/lib/l10n/pl.js
@@ -60,6 +60,9 @@ OC.L10N.register(
"Log out" : "Wyloguj",
"Users" : "Użytkownicy",
"Unknown user" : "Nieznany użytkownik",
+ "Create" : "Utwórz",
+ "Change" : "Zmień",
+ "Delete" : "Usuń",
"Basic settings" : "Ustawienia podstawowe",
"Sharing" : "Udostępnianie",
"Security" : "Bepieczeństwo",
diff --git a/lib/l10n/pl.json b/lib/l10n/pl.json
index 3e16ed67807..7c70d4dd1f5 100644
--- a/lib/l10n/pl.json
+++ b/lib/l10n/pl.json
@@ -58,6 +58,9 @@
"Log out" : "Wyloguj",
"Users" : "Użytkownicy",
"Unknown user" : "Nieznany użytkownik",
+ "Create" : "Utwórz",
+ "Change" : "Zmień",
+ "Delete" : "Usuń",
"Basic settings" : "Ustawienia podstawowe",
"Sharing" : "Udostępnianie",
"Security" : "Bepieczeństwo",
diff --git a/lib/private/Contacts/ContactsMenu/ContactsStore.php b/lib/private/Contacts/ContactsMenu/ContactsStore.php
index bfce7deafa4..05ef9cca53a 100644
--- a/lib/private/Contacts/ContactsMenu/ContactsStore.php
+++ b/lib/private/Contacts/ContactsMenu/ContactsStore.php
@@ -155,7 +155,13 @@ class ContactsStore implements IContactsStore {
}
if ($ownGroupsOnly && $entry->getProperty('isLocalSystemBook') === true) {
- $contactGroups = $this->groupManager->getUserGroupIds($this->userManager->get($entry->getProperty('UID')));
+ $uid = $this->userManager->get($entry->getProperty('UID'));
+
+ if ($uid === NULL) {
+ return false;
+ }
+
+ $contactGroups = $this->groupManager->getUserGroupIds($uid);
if (count(array_intersect($contactGroups, $selfGroups)) === 0) {
// no groups in common, so shouldn't see the contact
return false;
diff --git a/lib/private/DB/MigrationService.php b/lib/private/DB/MigrationService.php
index cc2889dae0c..6f5a74103a5 100644
--- a/lib/private/DB/MigrationService.php
+++ b/lib/private/DB/MigrationService.php
@@ -376,13 +376,14 @@ class MigrationService {
* Applies all not yet applied versions up to $to
*
* @param string $to
+ * @param bool $schemaOnly
* @throws \InvalidArgumentException
*/
- public function migrate($to = 'latest') {
+ public function migrate($to = 'latest', $schemaOnly = false) {
// read known migrations
$toBeExecuted = $this->getMigrationsToExecute($to);
foreach ($toBeExecuted as $version) {
- $this->executeStep($version);
+ $this->executeStep($version, $schemaOnly);
}
}
@@ -432,14 +433,17 @@ class MigrationService {
* Executes one explicit version
*
* @param string $version
+ * @param bool $schemaOnly
* @throws \InvalidArgumentException
*/
- public function executeStep($version) {
+ public function executeStep($version, $schemaOnly = false) {
$instance = $this->createInstance($version);
- $instance->preSchemaChange($this->output, function() {
- return new SchemaWrapper($this->connection);
- }, ['tablePrefix' => $this->connection->getPrefix()]);
+ if (!$schemaOnly) {
+ $instance->preSchemaChange($this->output, function() {
+ return new SchemaWrapper($this->connection);
+ }, ['tablePrefix' => $this->connection->getPrefix()]);
+ }
$toSchema = $instance->changeSchema($this->output, function() {
return new SchemaWrapper($this->connection);
@@ -450,9 +454,11 @@ class MigrationService {
$toSchema->performDropTableCalls();
}
- $instance->postSchemaChange($this->output, function() {
- return new SchemaWrapper($this->connection);
- }, ['tablePrefix' => $this->connection->getPrefix()]);
+ if (!$schemaOnly) {
+ $instance->postSchemaChange($this->output, function() {
+ return new SchemaWrapper($this->connection);
+ }, ['tablePrefix' => $this->connection->getPrefix()]);
+ }
$this->markAsExecuted($version);
}
diff --git a/lib/private/Files/Config/UserMountCache.php b/lib/private/Files/Config/UserMountCache.php
index cc655018f8d..a6741652308 100644
--- a/lib/private/Files/Config/UserMountCache.php
+++ b/lib/private/Files/Config/UserMountCache.php
@@ -375,7 +375,7 @@ class UserMountCache implements IUserMountCache {
->innerJoin('m', 'filecache', 'f',
$builder->expr()->andX(
$builder->expr()->eq('m.storage_id', 'f.storage'),
- $builder->expr()->eq('f.path', $builder->createNamedParameter('files'))
+ $builder->expr()->eq('f.path_hash', $builder->createNamedParameter(md5('files')))
))
->where($builder->expr()->eq('m.mount_point', $mountPoint))
->andWhere($builder->expr()->in('m.user_id', $builder->createNamedParameter($userIds, IQueryBuilder::PARAM_STR_ARRAY)));
diff --git a/lib/private/Files/Utils/Scanner.php b/lib/private/Files/Utils/Scanner.php
index fe2bf4ccb58..28921973fcf 100644
--- a/lib/private/Files/Utils/Scanner.php
+++ b/lib/private/Files/Utils/Scanner.php
@@ -151,11 +151,6 @@ class Scanner extends PublicEmitter {
continue;
}
- // don't scan the root storage
- if ($storage->instanceOfStorage('\OC\Files\Storage\Local') && $mount->getMountPoint() === '/') {
- continue;
- }
-
// don't scan received local shares, these can be scanned when scanning the owner's storage
if ($storage->instanceOfStorage(SharedStorage::class)) {
continue;
diff --git a/lib/private/Log/ExceptionSerializer.php b/lib/private/Log/ExceptionSerializer.php
index ecba043da44..768c6484963 100644
--- a/lib/private/Log/ExceptionSerializer.php
+++ b/lib/private/Log/ExceptionSerializer.php
@@ -82,7 +82,9 @@ class ExceptionSerializer {
return $traceLine;
}, $trace);
return array_map(function (array $traceLine) use ($sensitiveValues) {
- $traceLine['args'] = $this->removeValuesFromArgs($traceLine['args'], $sensitiveValues);
+ if (isset($traceLine['args'])) {
+ $traceLine['args'] = $this->removeValuesFromArgs($traceLine['args'], $sensitiveValues);
+ }
return $traceLine;
}, $trace);
}
@@ -101,7 +103,9 @@ class ExceptionSerializer {
private function encodeTrace($trace) {
$filteredTrace = $this->filterTrace($trace);
return array_map(function (array $line) {
- $line['args'] = array_map([$this, 'encodeArg'], $line['args']);
+ if (isset($line['args'])) {
+ $line['args'] = array_map([$this, 'encodeArg'], $line['args']);
+ }
return $line;
}, $filteredTrace);
}
@@ -138,4 +142,4 @@ class ExceptionSerializer {
return $data;
}
-} \ No newline at end of file
+}
diff --git a/lib/private/Log/File.php b/lib/private/Log/File.php
index 597cb54e402..c881c6dd9de 100644
--- a/lib/private/Log/File.php
+++ b/lib/private/Log/File.php
@@ -145,6 +145,9 @@ class File implements IWriter, IFileBased {
error_log($entry);
}
if (php_sapi_name() === 'cli-server') {
+ if (!\is_string($message)) {
+ $message = json_encode($message);
+ }
error_log($message, 4);
}
}
diff --git a/lib/private/Mail/EMailTemplate.php b/lib/private/Mail/EMailTemplate.php
index 0ba411d6926..4c56a316042 100644
--- a/lib/private/Mail/EMailTemplate.php
+++ b/lib/private/Mail/EMailTemplate.php
@@ -229,13 +229,13 @@ EOF;
<tr style="padding:0;text-align:left;vertical-align:top">
<th style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left">
<center data-parsed="" style="min-width:490px;width:100%%">
- <table class="button btn default primary float-center" style="Margin:0 0 30px 0;border-collapse:collapse;border-spacing:0;display:inline-block;float:none;margin:0 0 30px 0;margin-right:15px;max-height:40px;max-width:200px;padding:0;text-align:center;vertical-align:top;width:auto">
+ <table class="button btn default primary float-center" style="Margin:0 0 30px 0;border-collapse:collapse;border-spacing:0;display:inline-block;float:none;margin:0 0 30px 0;margin-right:15px;max-height:40px;max-width:200px;padding:0;text-align:center;vertical-align:top;width:auto;background:%1\$s;background-color:%1\$s;color:#fefefe;">
<tr style="padding:0;text-align:left;vertical-align:top">
<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
<tr style="padding:0;text-align:left;vertical-align:top">
- <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;background:%s;border:0 solid %s;border-collapse:collapse!important;color:#fefefe;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
- <a href="%s" style="Margin:0;border:0 solid %s;border-radius:2px;color:%s;display:inline-block;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:regular;line-height:1.3;margin:0;padding:10px 25px 10px 25px;text-align:left;outline:1px solid %s;text-decoration:none">%s</a>
+ <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border:0 solid %2\$s;border-collapse:collapse!important;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+ <a href="%3\$s" style="Margin:0;border:0 solid %4\$s;border-radius:2px;color:%5\$s;display:inline-block;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:regular;line-height:1.3;margin:0;padding:10px 25px 10px 25px;text-align:left;outline:1px solid %6\$s;text-decoration:none">%7\$s</a>
</td>
</tr>
</table>
@@ -248,7 +248,7 @@ EOF;
<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
<tr style="padding:0;text-align:left;vertical-align:top">
<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;background:#777;border:0 solid #777;border-collapse:collapse!important;color:#fefefe;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
- <a href="%s" style="Margin:0;background-color:#fff;border:0 solid #777;border-radius:2px;color:#6C6C6C!important;display:inline-block;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:regular;line-height:1.3;margin:0;outline:1px solid #CBCBCB;padding:10px 25px 10px 25px;text-align:left;text-decoration:none">%s</a>
+ <a href="%8\$s" style="Margin:0;background-color:#fff;border:0 solid #777;border-radius:2px;color:#6C6C6C!important;display:inline-block;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:regular;line-height:1.3;margin:0;outline:1px solid #CBCBCB;padding:10px 25px 10px 25px;text-align:left;text-decoration:none">%9\$s</a>
</td>
</tr>
</table>
@@ -282,13 +282,13 @@ EOF;
<tr style="padding:0;text-align:left;vertical-align:top">
<th style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left">
<center data-parsed="" style="min-width:490px;width:100%%">
- <table class="button btn default primary float-center" style="Margin:0;border-collapse:collapse;border-spacing:0;display:inline-block;float:none;margin:0;max-height:40px;padding:0;text-align:center;vertical-align:top;width:auto">
+ <table class="button btn default primary float-center" style="Margin:0;border-collapse:collapse;border-spacing:0;display:inline-block;float:none;margin:0;max-height:40px;padding:0;text-align:center;vertical-align:top;width:auto;background:%1\$s;color:#fefefe;background-color:%1\$s;">
<tr style="padding:0;text-align:left;vertical-align:top">
<td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
<tr style="padding:0;text-align:left;vertical-align:top">
- <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;background:%s;border:0 solid %s;border-collapse:collapse!important;color:#fefefe;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
- <a href="%s" style="Margin:0;border:0 solid %s;border-radius:2px;color:%s;display:inline-block;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:regular;line-height:1.3;margin:0;padding:10px 25px 10px 25px;text-align:left;outline:1px solid %s;text-decoration:none">%s</a>
+ <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border:0 solid %2\$;border-collapse:collapse!important;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+ <a href="%3\$s" style="Margin:0;border:0 solid %4\$s;border-radius:2px;color:%5\$s;display:inline-block;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:regular;line-height:1.3;margin:0;padding:10px 25px 10px 25px;text-align:left;outline:1px solid %5\$s;text-decoration:none">%7\$s</a>
</td>
</tr>
</table>
diff --git a/lib/private/NavigationManager.php b/lib/private/NavigationManager.php
index 1c764f9c1ff..1874cd0e4ff 100644
--- a/lib/private/NavigationManager.php
+++ b/lib/private/NavigationManager.php
@@ -100,7 +100,7 @@ class NavigationManager implements INavigationManager {
if(!isset($entry['type'])) {
$entry['type'] = 'link';
}
- $this->entries[] = $entry;
+ $this->entries[$entry['id']] = $entry;
}
/**
@@ -133,7 +133,7 @@ class NavigationManager implements INavigationManager {
* @return array
*/
private function proceedNavigation(array $list): array {
- usort($list, function($a, $b) {
+ uasort($list, function($a, $b) {
if (isset($a['order']) && isset($b['order'])) {
return ($a['order'] < $b['order']) ? -1 : 1;
} else if (isset($a['order']) || isset($b['order'])) {
diff --git a/lib/private/Notification/Manager.php b/lib/private/Notification/Manager.php
index bf0e8abadbb..4c3f7a2453c 100644
--- a/lib/private/Notification/Manager.php
+++ b/lib/private/Notification/Manager.php
@@ -53,6 +53,9 @@ class Manager implements IManager {
/** @var \Closure[] */
protected $notifiersInfoClosures;
+ /** @var bool */
+ protected $preparingPushNotification;
+
/**
* Manager constructor.
*
@@ -66,6 +69,7 @@ class Manager implements IManager {
$this->appsClosures = [];
$this->notifiersClosures = [];
$this->notifiersInfoClosures = [];
+ $this->preparingPushNotification = false;
}
/**
@@ -95,7 +99,7 @@ class Manager implements IManager {
/**
* @return IApp[]
*/
- protected function getApps() {
+ protected function getApps(): array {
if (!empty($this->apps)) {
return $this->apps;
}
@@ -115,7 +119,7 @@ class Manager implements IManager {
/**
* @return INotifier[]
*/
- protected function getNotifiers() {
+ protected function getNotifiers(): array {
if (!empty($this->notifiers)) {
return $this->notifiers;
}
@@ -135,7 +139,7 @@ class Manager implements IManager {
/**
* @return array[]
*/
- public function listNotifiers() {
+ public function listNotifiers(): array {
if (!empty($this->notifiersInfo)) {
return $this->notifiersInfo;
}
@@ -143,7 +147,7 @@ class Manager implements IManager {
$this->notifiersInfo = [];
foreach ($this->notifiersInfoClosures as $closure) {
$notifier = $closure();
- if (!is_array($notifier) || count($notifier) !== 2 || !isset($notifier['id']) || !isset($notifier['name'])) {
+ if (!\is_array($notifier) || \count($notifier) !== 2 || !isset($notifier['id'], $notifier['name'])) {
throw new \InvalidArgumentException('The given notifier information is invalid');
}
if (isset($this->notifiersInfo[$notifier['id']])) {
@@ -159,7 +163,7 @@ class Manager implements IManager {
* @return INotification
* @since 8.2.0
*/
- public function createNotification() {
+ public function createNotification(): INotification {
return new Notification($this->validator);
}
@@ -167,11 +171,27 @@ class Manager implements IManager {
* @return bool
* @since 8.2.0
*/
- public function hasNotifiers() {
+ public function hasNotifiers(): bool {
return !empty($this->notifiersClosures);
}
/**
+ * @param bool $preparingPushNotification
+ * @since 14.0.0
+ */
+ public function setPreparingPushNotification($preparingPushNotification) {
+ $this->preparingPushNotification = $preparingPushNotification;
+ }
+
+ /**
+ * @return bool
+ * @since 14.0.0
+ */
+ public function isPreparingPushNotification(): bool {
+ return $this->preparingPushNotification;
+ }
+
+ /**
* @param INotification $notification
* @throws \InvalidArgumentException When the notification is not valid
* @since 8.2.0
@@ -198,7 +218,7 @@ class Manager implements IManager {
* @throws \InvalidArgumentException When the notification was not prepared by a notifier
* @since 8.2.0
*/
- public function prepare(INotification $notification, $languageCode) {
+ public function prepare(INotification $notification, $languageCode): INotification {
$notifiers = $this->getNotifiers();
foreach ($notifiers as $notifier) {
@@ -235,7 +255,7 @@ class Manager implements IManager {
* @param INotification $notification
* @return int
*/
- public function getCount(INotification $notification) {
+ public function getCount(INotification $notification): int {
$apps = $this->getApps();
$count = 0;
diff --git a/lib/private/Server.php b/lib/private/Server.php
index c9f8001631e..0f406ebe9b7 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -116,6 +116,7 @@ use OC\Share20\ProviderFactory;
use OC\Share20\ShareHelper;
use OC\SystemTag\ManagerFactory as SystemTagManagerFactory;
use OC\Tagging\TagMapper;
+use OC\Template\IconsCacher;
use OC\Template\JSCombiner;
use OC\Template\SCSSCacher;
use OCA\Theming\ImageManager;
@@ -963,7 +964,8 @@ class Server extends ServerContainer implements IServerContainer {
$c->getConfig(),
$c->getThemingDefaults(),
\OC::$SERVERROOT,
- $this->getMemCacheFactory()
+ $this->getMemCacheFactory(),
+ $c->query(IconsCacher::class)
);
});
$this->registerService(JSCombiner::class, function (Server $c) {
diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php
index 82cb223bb9f..e9f2a6f5976 100644
--- a/lib/private/Settings/Manager.php
+++ b/lib/private/Settings/Manager.php
@@ -231,7 +231,7 @@ class Manager implements IManager {
5 => [new Section('sharing', $this->l->t('Sharing'), 0, $this->url->imagePath('core', 'actions/share.svg'))],
10 => [new Section('security', $this->l->t('Security'), 0, $this->url->imagePath('core', 'actions/password.svg'))],
45 => [new Section('encryption', $this->l->t('Encryption'), 0, $this->url->imagePath('core', 'actions/password.svg'))],
- 50 => [new Section('groupware', $this->l->t('Groupware'), 0, $this->url->imagePath('core', 'places/contacts-dark.svg'))],
+ 50 => [new Section('groupware', $this->l->t('Groupware'), 0, $this->url->imagePath('core', 'places/contacts.svg'))],
98 => [new Section('additional', $this->l->t('Additional settings'), 0, $this->url->imagePath('core', 'actions/settings-dark.svg'))],
];
diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php
index 52e0628987b..0a9371d35b8 100644
--- a/lib/private/Share/Share.php
+++ b/lib/private/Share/Share.php
@@ -86,7 +86,6 @@ class Share extends Constants {
);
if(count(self::$backendTypes) === 1) {
Util::addScript('core', 'merged-share-backend');
- \OC_Util::addStyle('core', 'share');
}
return true;
}
diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php
index 5e52156d1d0..9c5d78a5958 100644
--- a/lib/private/Share20/DefaultShareProvider.php
+++ b/lib/private/Share20/DefaultShareProvider.php
@@ -30,8 +30,14 @@
namespace OC\Share20;
use OC\Files\Cache\Cache;
+use OCP\Defaults;
use OCP\Files\Folder;
+use OCP\IL10N;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\Mail\IMailer;
use OCP\Share\IShare;
+use OCP\Share\IShareHelper;
use OCP\Share\IShareProvider;
use OC\Share20\Exception\InvalidShare;
use OC\Share20\Exception\ProviderException;
@@ -67,6 +73,18 @@ class DefaultShareProvider implements IShareProvider {
/** @var IRootFolder */
private $rootFolder;
+ /** @var IMailer */
+ private $mailer;
+
+ /** @var Defaults */
+ private $defaults;
+
+ /** @var IL10N */
+ private $l;
+
+ /** @var IURLGenerator */
+ private $urlGenerator;
+
/**
* DefaultShareProvider constructor.
*
@@ -74,16 +92,28 @@ class DefaultShareProvider implements IShareProvider {
* @param IUserManager $userManager
* @param IGroupManager $groupManager
* @param IRootFolder $rootFolder
+ * @param IMailer $mailer ;
+ * @param Defaults $defaults
+ * @param IL10N $l
+ * @param IURLGenerator $urlGenerator
*/
public function __construct(
IDBConnection $connection,
IUserManager $userManager,
IGroupManager $groupManager,
- IRootFolder $rootFolder) {
+ IRootFolder $rootFolder,
+ IMailer $mailer,
+ Defaults $defaults,
+ IL10N $l,
+ IURLGenerator $urlGenerator) {
$this->dbConn = $connection;
$this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->rootFolder = $rootFolder;
+ $this->mailer = $mailer;
+ $this->defaults = $defaults;
+ $this->l = $l;
+ $this->urlGenerator = $urlGenerator;
}
/**
@@ -197,6 +227,9 @@ class DefaultShareProvider implements IShareProvider {
* @return \OCP\Share\IShare The share object
*/
public function update(\OCP\Share\IShare $share) {
+
+ $originalShare = $this->getShareById($share->getId());
+
if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
/*
* We allow updating the recipient on user shares.
@@ -211,6 +244,7 @@ class DefaultShareProvider implements IShareProvider {
->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
+ ->set('note', $qb->createNamedParameter($share->getNote()))
->execute();
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
$qb = $this->dbConn->getQueryBuilder();
@@ -222,6 +256,7 @@ class DefaultShareProvider implements IShareProvider {
->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
+ ->set('note', $qb->createNamedParameter($share->getNote()))
->execute();
/*
@@ -235,6 +270,7 @@ class DefaultShareProvider implements IShareProvider {
->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
+ ->set('note', $qb->createNamedParameter($share->getNote()))
->execute();
/*
@@ -259,9 +295,15 @@ class DefaultShareProvider implements IShareProvider {
->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
->set('token', $qb->createNamedParameter($share->getToken()))
->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
+ ->set('note', $qb->createNamedParameter($share->getNote()))
->execute();
}
+ if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
+ $this->propagateNote($share);
+ }
+
+
return $share;
}
@@ -875,6 +917,7 @@ class DefaultShareProvider implements IShareProvider {
->setShareType((int)$data['share_type'])
->setPermissions((int)$data['permissions'])
->setTarget($data['file_target'])
+ ->setNote($data['note'])
->setMailSend((bool)$data['mail_send']);
$shareTime = new \DateTime();
@@ -1227,4 +1270,96 @@ class DefaultShareProvider implements IShareProvider {
return $best;
}
+
+ /**
+ * propagate notes to the recipients
+ *
+ * @param IShare $share
+ * @throws \OCP\Files\NotFoundException
+ */
+ private function propagateNote(IShare $share) {
+ if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
+ $user = $this->userManager->get($share->getSharedWith());
+ $this->sendNote([$user], $share);
+ } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
+ $group = $this->groupManager->get($share->getSharedWith());
+ $groupMembers = $group->getUsers();
+ $this->sendNote($groupMembers, $share);
+ }
+ }
+
+ /**
+ * send note by mail
+ *
+ * @param array $recipients
+ * @param IShare $share
+ * @throws \OCP\Files\NotFoundException
+ */
+ private function sendNote(array $recipients, IShare $share) {
+
+ $toList = [];
+
+ foreach ($recipients as $recipient) {
+ /** @var IUser $recipient */
+ $email = $recipient->getEMailAddress();
+ if ($email) {
+ $toList[$email] = $recipient->getDisplayName();
+ }
+ }
+
+ if (!empty($toList)) {
+
+ $filename = $share->getNode()->getName();
+ $initiator = $share->getSharedBy();
+ $note = $share->getNote();
+
+ $initiatorUser = $this->userManager->get($initiator);
+ $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
+ $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
+ $plainHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
+ $htmlHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
+ $message = $this->mailer->createMessage();
+
+ $emailTemplate = $this->mailer->createEMailTemplate('defaultShareProvider.sendNote');
+
+ $emailTemplate->setSubject($this->l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
+ $emailTemplate->addHeader();
+ $emailTemplate->addHeading($htmlHeading, $plainHeading);
+ $emailTemplate->addBodyText(htmlspecialchars($note), $note);
+
+ $link = $this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $share->getNode()->getId()]);
+ $emailTemplate->addBodyButton(
+ $this->l->t('Open »%s«', [$filename]),
+ $link
+ );
+
+
+ // The "From" contains the sharers name
+ $instanceName = $this->defaults->getName();
+ $senderName = $this->l->t(
+ '%1$s via %2$s',
+ [
+ $initiatorDisplayName,
+ $instanceName
+ ]
+ );
+ $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
+ if ($initiatorEmailAddress !== null) {
+ $message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
+ $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
+ } else {
+ $emailTemplate->addFooter();
+ }
+
+ if (count($toList) === 1) {
+ $message->setTo($toList);
+ } else {
+ $message->setTo([]);
+ $message->setBcc($toList);
+ }
+ $message->useTemplate($emailTemplate);
+ $this->mailer->send($message);
+ }
+
+ }
}
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index 76b523afd10..d0316b44c1a 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -827,10 +827,20 @@ class Manager implements IManager {
$expirationDateUpdated = true;
}
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
+ // The new password is not set again if it is the same as the old
+ // one, unless when switching from sending by Talk to sending by
+ // mail.
$plainTextPassword = $share->getPassword();
- if (!$this->updateSharePasswordIfNeeded($share, $originalShare)) {
+ if (!empty($plainTextPassword) && !$this->updateSharePasswordIfNeeded($share, $originalShare) &&
+ !($originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk())) {
$plainTextPassword = null;
}
+ if (empty($plainTextPassword) && !$originalShare->getSendPasswordByTalk() && $share->getSendPasswordByTalk()) {
+ // If the same password was already sent by mail the recipient
+ // would already have access to the share without having to call
+ // the sharer to verify her identity
+ throw new \InvalidArgumentException('Can’t enable sending the password by Talk without setting a new password');
+ }
}
$this->pathCreateChecks($share->getNode());
diff --git a/lib/private/Share20/ProviderFactory.php b/lib/private/Share20/ProviderFactory.php
index e4d34146911..0aacca409d1 100644
--- a/lib/private/Share20/ProviderFactory.php
+++ b/lib/private/Share20/ProviderFactory.php
@@ -81,7 +81,11 @@ class ProviderFactory implements IProviderFactory {
$this->serverContainer->getDatabaseConnection(),
$this->serverContainer->getUserManager(),
$this->serverContainer->getGroupManager(),
- $this->serverContainer->getLazyRootFolder()
+ $this->serverContainer->getLazyRootFolder(),
+ $this->serverContainer->getMailer(),
+ $this->serverContainer->query(Defaults::class),
+ $this->serverContainer->getL10N('sharing'),
+ $this->serverContainer->getURLGenerator()
);
}
diff --git a/lib/private/Share20/Share.php b/lib/private/Share20/Share.php
index d7810165dac..71c0453d9e5 100644
--- a/lib/private/Share20/Share.php
+++ b/lib/private/Share20/Share.php
@@ -57,10 +57,14 @@ class Share implements \OCP\Share\IShare {
private $shareOwner;
/** @var int */
private $permissions;
+ /** @var string */
+ private $note = '';
/** @var \DateTime */
private $expireDate;
/** @var string */
private $password;
+ /** @var bool */
+ private $sendPasswordByTalk = false;
/** @var string */
private $token;
/** @var int */
@@ -311,6 +315,24 @@ class Share implements \OCP\Share\IShare {
/**
* @inheritdoc
*/
+ public function setNote($note) {
+ $this->note = $note;
+ return $this;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getNote() {
+ if (is_string($this->note)) {
+ return $this->note;
+ }
+ return '';
+ }
+
+ /**
+ * @inheritdoc
+ */
public function setExpirationDate($expireDate) {
//TODO checks
@@ -385,6 +407,21 @@ class Share implements \OCP\Share\IShare {
/**
* @inheritdoc
*/
+ public function setSendPasswordByTalk(bool $sendPasswordByTalk) {
+ $this->sendPasswordByTalk = $sendPasswordByTalk;
+ return $this;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getSendPasswordByTalk(): bool {
+ return $this->sendPasswordByTalk;
+ }
+
+ /**
+ * @inheritdoc
+ */
public function setToken($token) {
$this->token = $token;
return $this;
diff --git a/lib/private/Template/IconsCacher.php b/lib/private/Template/IconsCacher.php
new file mode 100644
index 00000000000..e5ebecaf169
--- /dev/null
+++ b/lib/private/Template/IconsCacher.php
@@ -0,0 +1,147 @@
+<?php
+declare (strict_types = 1);
+/**
+ * @copyright Copyright (c) 2018, John Molakvoæ (skjnldsv@protonmail.com)
+ *
+ * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
+ *
+ * @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\Template;
+
+use OCP\Files\IAppData;
+use OCP\Files\NotFoundException;
+use OCP\Files\SimpleFS\ISimpleFolder;
+use OCP\Files\SimpleFS\ISimpleFile;
+use OCP\ILogger;
+use OCP\IURLGenerator;
+use OC\Files\AppData\Factory;
+
+class IconsCacher {
+
+ /** @var ILogger */
+ protected $logger;
+
+ /** @var IAppData */
+ protected $appData;
+
+ /** @var ISimpleFolder */
+ private $folder;
+
+ /** @var IURLGenerator */
+ protected $urlGenerator;
+
+ /** @var string */
+ private $iconVarRE = '/--(icon-[a-zA-Z0-9-]+): url\(["\']([a-z0-9-_\~\/\.]+)[^;]+;/m';
+
+ /** @var string */
+ private $fileName = 'icons-vars.css';
+
+ /**
+ * @param ILogger $logger
+ * @param Factory $appDataFactory
+ * @param IURLGenerator $urlGenerator
+ */
+ public function __construct(ILogger $logger,
+ Factory $appDataFactory,
+ IURLGenerator $urlGenerator) {
+ $this->logger = $logger;
+ $this->appData = $appDataFactory->get('css');
+ $this->urlGenerator = $urlGenerator;
+
+ try {
+ $this->folder = $this->appData->getFolder('icons');
+ } catch (NotFoundException $e) {
+ $this->folder = $this->appData->newFolder('icons');
+ }
+ }
+
+ private function getIconsFromCss(string $css): array{
+ preg_match_all($this->iconVarRE, $css, $matches, PREG_SET_ORDER);
+ $icons = [];
+ foreach ($matches as $icon) {
+ $icons[$icon[1]] = $icon[2];
+ }
+
+ return $icons;
+ }
+ /**
+ * Parse and cache css
+ *
+ * @param string $css
+ */
+ public function setIconsCss(string $css) {
+
+ $cachedFile = $this->getCachedCSS();
+ if (!$cachedFile) {
+ $currentData = '';
+ } else {
+ $currentData = $cachedFile->getContent();
+ }
+
+ // remove :root
+ $currentData = str_replace([':root {', '}'], '', $currentData);
+
+ $icons = $this->getIconsFromCss($currentData . $css);
+
+ $data = '';
+ foreach ($icons as $icon => $url) {
+ $data .= "--$icon: url('$url?v=1');";
+ }
+
+ if (strlen($data) > 0) {
+ if (!$cachedFile) {
+ $cachedFile = $this->folder->newFile($this->fileName);
+ }
+
+ $data = ":root {
+ $data
+ }";
+ $cachedFile->putContent($data);
+ }
+
+ return preg_replace($this->iconVarRE, '', $css);
+ }
+
+ /**
+ * Get icons css file
+ * @return ISimpleFile|boolean
+ */
+ public function getCachedCSS() {
+ try {
+ return $this->folder->getFile($this->fileName);
+ } catch (NotFoundException $e) {
+ return false;
+ }
+ }
+
+ public function injectCss() {
+ // Only inject once
+ foreach (\OC_Util::$headers as $header) {
+ if (
+ array_key_exists('attributes', $header) &&
+ array_key_exists('href', $header['attributes']) &&
+ strpos($header['attributes']['href'], $this->fileName) !== false) {
+ return;
+ }
+ }
+ $linkToCSS = substr($this->urlGenerator->linkToRoute('core.Css.getCss', ['appName' => 'icons', 'fileName' => $this->fileName]), strlen(\OC::$WEBROOT));
+ \OC_Util::addHeader('link', ['rel' => 'stylesheet', 'href' => $linkToCSS], null, true);
+ }
+
+} \ No newline at end of file
diff --git a/lib/private/Template/SCSSCacher.php b/lib/private/Template/SCSSCacher.php
index 6e25e1fa5de..9dcedb94daf 100644
--- a/lib/private/Template/SCSSCacher.php
+++ b/lib/private/Template/SCSSCacher.php
@@ -32,7 +32,6 @@ use Leafo\ScssPhp\Compiler;
use Leafo\ScssPhp\Exception\ParserException;
use Leafo\ScssPhp\Formatter\Crunched;
use Leafo\ScssPhp\Formatter\Expanded;
-use OC\Files\AppData\Factory;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
@@ -43,6 +42,8 @@ use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\ILogger;
use OCP\IURLGenerator;
+use OC\Files\AppData\Factory;
+use OC\Template\IconsCacher;
class SCSSCacher {
@@ -73,6 +74,9 @@ class SCSSCacher {
/** @var ICacheFactory */
private $cacheFactory;
+ /** @var IconsCacher */
+ private $iconsCacher;
+
/**
* @param ILogger $logger
* @param Factory $appDataFactory
@@ -81,6 +85,7 @@ class SCSSCacher {
* @param \OC_Defaults $defaults
* @param string $serverRoot
* @param ICacheFactory $cacheFactory
+ * @param IconsCacher $iconsCacher
*/
public function __construct(ILogger $logger,
Factory $appDataFactory,
@@ -88,15 +93,17 @@ class SCSSCacher {
IConfig $config,
\OC_Defaults $defaults,
$serverRoot,
- ICacheFactory $cacheFactory) {
- $this->logger = $logger;
- $this->appData = $appDataFactory->get('css');
+ ICacheFactory $cacheFactory,
+ IconsCacher $iconsCacher) {
+ $this->logger = $logger;
+ $this->appData = $appDataFactory->get('css');
$this->urlGenerator = $urlGenerator;
- $this->config = $config;
- $this->defaults = $defaults;
- $this->serverRoot = $serverRoot;
+ $this->config = $config;
+ $this->defaults = $defaults;
+ $this->serverRoot = $serverRoot;
$this->cacheFactory = $cacheFactory;
- $this->depsCache = $cacheFactory->createDistributed('SCSS-' . md5($this->urlGenerator->getBaseUrl()));
+ $this->depsCache = $cacheFactory->createDistributed('SCSS-' . md5($this->urlGenerator->getBaseUrl()));
+ $this->iconsCacher = $iconsCacher;
}
/**
@@ -112,23 +119,34 @@ class SCSSCacher {
$path = explode('/', $root . '/' . $file);
$fileNameSCSS = array_pop($path);
- $fileNameCSS = $this->prependVersionPrefix($this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileNameSCSS)), $app);
+ $fileNameCSS = $this->prependVersionPrefix($this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileNameSCSS)), $app);
- $path = implode('/', $path);
+ $path = implode('/', $path);
$webDir = $this->getWebDir($path, $app, $this->serverRoot, \OC::$WEBROOT);
try {
$folder = $this->appData->getFolder($app);
- } catch(NotFoundException $e) {
+ } catch (NotFoundException $e) {
// creating css appdata folder
$folder = $this->appData->newFolder($app);
}
-
- if(!$this->variablesChanged() && $this->isCached($fileNameCSS, $folder)) {
+ if (!$this->variablesChanged() && $this->isCached($fileNameCSS, $folder)) {
+ // Inject icons vars css if any
+ if ($this->iconsCacher->getCachedCSS() && $this->iconsCacher->getCachedCSS()->getSize() > 0) {
+ $this->iconsCacher->injectCss();
+ }
return true;
}
- return $this->cache($path, $fileNameCSS, $fileNameSCSS, $folder, $webDir);
+
+ $cached = $this->cache($path, $fileNameCSS, $fileNameSCSS, $folder, $webDir);
+
+ // Inject icons vars css if any
+ if ($this->iconsCacher->getCachedCSS() && $this->iconsCacher->getCachedCSS()->getSize() > 0) {
+ $this->iconsCacher->injectCss();
+ }
+
+ return $cached;
}
/**
@@ -137,8 +155,9 @@ class SCSSCacher {
* @return ISimpleFile
*/
public function getCachedCSS(string $appName, string $fileName): ISimpleFile {
- $folder = $this->appData->getFolder($appName);
+ $folder = $this->appData->getFolder($appName);
$cachedFileName = $this->prependVersionPrefix($this->prependBaseurlPrefix($fileName), $appName);
+
return $folder->getFile($cachedFileName);
}
@@ -153,24 +172,26 @@ class SCSSCacher {
$cachedFile = $folder->getFile($fileNameCSS);
if ($cachedFile->getSize() > 0) {
$depFileName = $fileNameCSS . '.deps';
- $deps = $this->depsCache->get($folder->getName() . '-' . $depFileName);
+ $deps = $this->depsCache->get($folder->getName() . '-' . $depFileName);
if ($deps === null) {
$depFile = $folder->getFile($depFileName);
- $deps = $depFile->getContent();
+ $deps = $depFile->getContent();
//Set to memcache for next run
$this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
}
$deps = json_decode($deps, true);
- foreach ((array)$deps as $file=>$mtime) {
+ foreach ((array) $deps as $file => $mtime) {
if (!file_exists($file) || filemtime($file) > $mtime) {
return false;
}
}
+
return true;
}
+
return false;
- } catch(NotFoundException $e) {
+ } catch (NotFoundException $e) {
return false;
}
}
@@ -181,11 +202,13 @@ class SCSSCacher {
*/
private function variablesChanged(): bool {
$injectedVariables = $this->getInjectedVariables();
- if($this->config->getAppValue('core', 'scss.variables') !== md5($injectedVariables)) {
+ if ($this->config->getAppValue('core', 'scss.variables') !== md5($injectedVariables)) {
$this->resetCache();
$this->config->setAppValue('core', 'scss.variables', md5($injectedVariables));
+
return true;
}
+
return false;
}
@@ -204,11 +227,12 @@ class SCSSCacher {
$scss = new Compiler();
$scss->setImportPaths([
$path,
- $this->serverRoot . '/core/css/',
+ $this->serverRoot . '/core/css/'
]);
+
// Continue after throw
$scss->setIgnoreErrors(true);
- if($this->config->getSystemValue('debug')) {
+ if ($this->config->getSystemValue('debug')) {
// Debug mode
$scss->setFormatter(Expanded::class);
$scss->setLineNumberStyle(Compiler::LINE_COMMENTS);
@@ -219,7 +243,7 @@ class SCSSCacher {
try {
$cachedfile = $folder->getFile($fileNameCSS);
- } catch(NotFoundException $e) {
+ } catch (NotFoundException $e) {
$cachedfile = $folder->newFile($fileNameCSS);
}
@@ -233,14 +257,20 @@ class SCSSCacher {
// Compile
try {
$compiledScss = $scss->compile(
+ '$webroot: \'' . $this->getRoutePrefix() . '\';' .
'@import "variables.scss";' .
+ '@import "functions.scss";' .
$this->getInjectedVariables() .
- '@import "'.$fileNameSCSS.'";');
- } catch(ParserException $e) {
+ '@import "' . $fileNameSCSS . '";');
+ } catch (ParserException $e) {
$this->logger->error($e, ['app' => 'core']);
+
return false;
}
+ // Parse Icons and create related css variables
+ $compiledScss = $this->iconsCacher->setIconsCss($compiledScss);
+
// Gzip file
try {
$gzipFile = $folder->getFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz
@@ -255,10 +285,12 @@ class SCSSCacher {
$depFile->putContent($deps);
$this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
$gzipFile->putContent(gzencode($data, 9));
- $this->logger->debug('SCSSCacher: '.$webDir.'/'.$fileNameSCSS.' compiled and successfully cached', ['app' => 'core']);
+ $this->logger->debug('SCSSCacher: ' . $webDir . '/' . $fileNameSCSS . ' compiled and successfully cached', ['app' => 'core']);
+
return true;
- } catch(NotPermittedException $e) {
+ } catch (NotPermittedException $e) {
$this->logger->error('SCSSCacher: unable to cache: ' . $fileNameSCSS);
+
return false;
}
}
@@ -275,7 +307,7 @@ class SCSSCacher {
foreach ($folder->getDirectoryListing() as $file) {
try {
$file->delete();
- } catch(NotPermittedException $e) {
+ } catch (NotPermittedException $e) {
$this->logger->logException($e, ['message' => 'SCSSCacher: unable to delete file: ' . $file->getName()]);
}
}
@@ -313,8 +345,9 @@ class SCSSCacher {
* @return string
*/
private function rebaseUrls(string $css, string $webDir): string {
- $re = '/url\([\'"]([^\/][\.\w?=\/-]*)[\'"]\)/x';
- $subst = 'url(\''.$webDir.'/$1\')';
+ $re = '/url\([\'"]([^\/][\.\w?=\/-]*)[\'"]\)/x';
+ $subst = 'url(\'' . $webDir . '/$1\')';
+
return preg_replace($re, $subst, $css);
}
@@ -326,8 +359,8 @@ class SCSSCacher {
*/
public function getCachedSCSS(string $appName, string $fileName): string {
$tmpfileLoc = explode('/', $fileName);
- $fileName = array_pop($tmpfileLoc);
- $fileName = $this->prependVersionPrefix($this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileName)), $appName);
+ $fileName = array_pop($tmpfileLoc);
+ $fileName = $this->prependVersionPrefix($this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileName)), $appName);
return substr($this->urlGenerator->linkToRoute('core.Css.getCss', ['fileName' => $fileName, 'appName' => $appName]), strlen(\OC::$WEBROOT) + 1);
}
@@ -338,8 +371,16 @@ class SCSSCacher {
* @return string
*/
private function prependBaseurlPrefix(string $cssFile): string {
- $frontendController = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true');
- return substr(md5($this->urlGenerator->getBaseUrl() . $frontendController), 0, 4) . '-' . $cssFile;
+ return substr(md5($this->urlGenerator->getBaseUrl() . $this->getRoutePrefix()), 0, 4) . '-' . $cssFile;
+ }
+
+ private function getRoutePrefix() {
+ $frontControllerActive = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true');
+ $prefix = \OC::$WEBROOT . '/index.php';
+ if ($frontControllerActive) {
+ $prefix = \OC::$WEBROOT;
+ }
+ return $prefix;
}
/**
@@ -354,6 +395,7 @@ class SCSSCacher {
return substr(md5($appVersion), 0, 4) . '-' . $cssFile;
}
$coreVersion = \OC_Util::getVersionString();
+
return substr(md5($coreVersion), 0, 4) . '-' . $cssFile;
}
@@ -367,12 +409,14 @@ class SCSSCacher {
*/
private function getWebDir(string $path, string $appName, string $serverRoot, string $webRoot): string {
// Detect if path is within server root AND if path is within an app path
- if ( strpos($path, $serverRoot) === false && $appWebPath = \OC_App::getAppWebPath($appName)) {
+ if (strpos($path, $serverRoot) === false && $appWebPath = \OC_App::getAppWebPath($appName)) {
// Get the file path within the app directory
$appDirectoryPath = explode($appName, $path)[1];
// Remove the webroot
- return str_replace($webRoot, '', $appWebPath.$appDirectoryPath);
+
+ return str_replace($webRoot, '', $appWebPath . $appDirectoryPath);
}
- return $webRoot.substr($path, strlen($serverRoot));
+
+ return $webRoot . substr($path, strlen($serverRoot));
}
}
diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php
index 1efdf8b441c..fc2e5798e1c 100644
--- a/lib/private/TemplateLayout.php
+++ b/lib/private/TemplateLayout.php
@@ -42,6 +42,7 @@ use OC\Template\JSCombiner;
use OC\Template\JSConfigHelper;
use OC\Template\SCSSCacher;
use OCP\Defaults;
+use OC\AppFramework\Http\Request;
class TemplateLayout extends \OC_Template {
@@ -61,6 +62,9 @@ class TemplateLayout extends \OC_Template {
// yes - should be injected ....
$this->config = \OC::$server->getConfig();
+ if(\OCP\Util::isIE()) {
+ \OC_Util::addStyle('ie');
+ }
// Decide which page we show
if($renderAs == 'user') {
diff --git a/lib/private/legacy/util.php b/lib/private/legacy/util.php
index ab595d885cb..a581397212a 100644
--- a/lib/private/legacy/util.php
+++ b/lib/private/legacy/util.php
@@ -64,6 +64,7 @@ use OCP\IConfig;
use OCP\IGroupManager;
use OCP\ILogger;
use OCP\IUser;
+use OC\AppFramework\Http\Request;
class OC_Util {
public static $scripts = array();
@@ -687,13 +688,20 @@ class OC_Util {
* @param string $tag tag name of the element
* @param array $attributes array of attributes for the element
* @param string $text the text content for the element
+ * @param bool $prepend prepend the header to the beginning of the list
*/
- public static function addHeader($tag, $attributes, $text=null) {
- self::$headers[] = array(
+ public static function addHeader($tag, $attributes, $text = null, $prepend = false) {
+ $header = array(
'tag' => $tag,
'attributes' => $attributes,
'text' => $text
);
+ if ($prepend === true) {
+ array_unshift (self::$headers, $header);
+
+ } else {
+ self::$headers[] = $header;
+ }
}
/**
@@ -1371,7 +1379,7 @@ class OC_Util {
}
// Zend OpCache >= 7.0.0, PHP >= 5.5.0
if (function_exists('opcache_invalidate')) {
- $ret = opcache_invalidate($path);
+ $ret = @opcache_invalidate($path);
}
}
return $ret;
@@ -1405,7 +1413,7 @@ class OC_Util {
}
// Opcache (PHP >= 5.5)
if (function_exists('opcache_reset')) {
- opcache_reset();
+ @opcache_reset();
}
}
@@ -1521,4 +1529,13 @@ class OC_Util {
}
}
+ /**
+ * is this Internet explorer ?
+ *
+ * @return boolean
+ */
+ public static function isIe() {
+ return preg_match(Request::USER_AGENT_IE, $_SERVER['HTTP_USER_AGENT']) === 1;
+ }
+
}
diff --git a/lib/public/Notification/IManager.php b/lib/public/Notification/IManager.php
index cbc48142cbb..003e5f1bad1 100644
--- a/lib/public/Notification/IManager.php
+++ b/lib/public/Notification/IManager.php
@@ -62,4 +62,16 @@ interface IManager extends IApp, INotifier {
* @since 9.0.0
*/
public function hasNotifiers();
+
+ /**
+ * @param bool $preparingPushNotification
+ * @since 14.0.0
+ */
+ public function setPreparingPushNotification($preparingPushNotification);
+
+ /**
+ * @return bool
+ * @since 14.0.0
+ */
+ public function isPreparingPushNotification();
}
diff --git a/lib/public/Share/IShare.php b/lib/public/Share/IShare.php
index 870794d6536..43543fdad47 100644
--- a/lib/public/Share/IShare.php
+++ b/lib/public/Share/IShare.php
@@ -223,6 +223,24 @@ interface IShare {
public function getPermissions();
/**
+ * Attach a note to a share
+ *
+ * @param string $note
+ * @return \OCP\Share\IShare The modified object
+ * @since 14.0.0
+ */
+ public function setNote($note);
+
+ /**
+ * Get note attached to a share
+ *
+ * @return string
+ * @since 14.0.0
+ */
+ public function getNote();
+
+
+ /**
* Set the expiration date
*
* @param null|\DateTime $expireDate
@@ -294,6 +312,29 @@ interface IShare {
*/
public function getPassword();
+
+ /**
+ * Set if the recipient can start a conversation with the owner to get the
+ * password using Nextcloud Talk.
+ *
+ * @param bool $sendPasswordByTalk
+ * @return \OCP\Share\IShare The modified object
+ * @since 14.0.0
+ */
+ public function setSendPasswordByTalk(bool $sendPasswordByTalk);
+
+ /**
+ * Get if the recipient can start a conversation with the owner to get the
+ * password using Nextcloud Talk.
+ * The returned value does not take into account other factors, like Talk
+ * being enabled for the owner of the share or not; it just cover whether
+ * the option is enabled for the share itself or not.
+ *
+ * @return bool
+ * @since 14.0.0
+ */
+ public function getSendPasswordByTalk(): bool;
+
/**
* Set the public link token.
*
diff --git a/lib/public/Util.php b/lib/public/Util.php
index 27b703ea2d8..9892f4a1ecb 100644
--- a/lib/public/Util.php
+++ b/lib/public/Util.php
@@ -558,4 +558,14 @@ class Util {
}
return self::$needUpgradeCache;
}
+
+ /**
+ * is this Internet explorer ?
+ *
+ * @return boolean
+ * @since 14.0.0
+ */
+ public static function isIe() {
+ return \OC_Util::isIe();
+ }
}