summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/base.php11
-rw-r--r--lib/composer/composer/autoload_classmap.php23
-rw-r--r--lib/composer/composer/autoload_static.php23
-rw-r--r--lib/l10n/el.js1
-rw-r--r--lib/l10n/el.json1
-rw-r--r--lib/l10n/nb.js1
-rw-r--r--lib/l10n/nb.json1
-rw-r--r--lib/l10n/pt_BR.js18
-rw-r--r--lib/l10n/pt_BR.json18
-rw-r--r--lib/private/App/AppStore/Bundles/Bundle.php59
-rw-r--r--lib/private/App/AppStore/Bundles/BundleFetcher.php80
-rw-r--r--lib/private/App/AppStore/Bundles/CoreBundle.php42
-rw-r--r--lib/private/App/AppStore/Bundles/EnterpriseBundle.php47
-rw-r--r--lib/private/App/AppStore/Bundles/GroupwareBundle.php44
-rw-r--r--lib/private/App/AppStore/Bundles/SocialSharingBundle.php46
-rw-r--r--lib/private/Contacts/ContactsMenu/ActionFactory.php57
-rw-r--r--lib/private/Contacts/ContactsMenu/ActionProviderStore.php114
-rw-r--r--lib/private/Contacts/ContactsMenu/Actions/LinkAction.php103
-rw-r--r--lib/private/Contacts/ContactsMenu/ContactsStore.php139
-rw-r--r--lib/private/Contacts/ContactsMenu/Entry.php169
-rw-r--r--lib/private/Contacts/ContactsMenu/Manager.php111
-rw-r--r--lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php60
-rw-r--r--lib/private/DB/Connection.php3
-rw-r--r--lib/private/Diagnostics/EventLogger.php39
-rw-r--r--lib/private/Diagnostics/NullEventLogger.php58
-rw-r--r--lib/private/Diagnostics/NullQueryLogger.php46
-rw-r--r--lib/private/Diagnostics/Query.php9
-rw-r--r--lib/private/Diagnostics/QueryLogger.php29
-rw-r--r--lib/private/Files/Utils/Scanner.php45
-rw-r--r--lib/private/Installer.php33
-rw-r--r--lib/private/Mail/EMailTemplate.php146
-rw-r--r--lib/private/Memcache/Redis.php28
-rw-r--r--lib/private/RedisFactory.php68
-rw-r--r--lib/private/Repair.php7
-rw-r--r--lib/private/Repair/NC12/InstallCoreBundle.php78
-rw-r--r--lib/private/Repair/RepairMimeTypes.php13
-rw-r--r--lib/private/Server.php34
-rw-r--r--lib/private/Session/CryptoSessionData.php7
-rw-r--r--lib/private/Session/Internal.php2
-rw-r--r--lib/private/Setup.php20
-rw-r--r--lib/private/TemplateLayout.php2
-rw-r--r--lib/private/Updater.php7
-rw-r--r--lib/private/User/User.php6
-rw-r--r--lib/private/legacy/api.php19
-rw-r--r--lib/private/legacy/app.php74
-rw-r--r--lib/private/legacy/db/statementwrapper.php9
-rw-r--r--lib/private/legacy/template.php1
-rw-r--r--lib/private/legacy/user.php5
-rw-r--r--lib/private/legacy/util.php6
-rw-r--r--lib/public/Contacts/ContactsMenu/IAction.php65
-rw-r--r--lib/public/Contacts/ContactsMenu/IActionFactory.php54
-rw-r--r--lib/public/Contacts/ContactsMenu/IEntry.php66
-rw-r--r--lib/public/Contacts/ContactsMenu/ILinkAction.php43
-rw-r--r--lib/public/Contacts/ContactsMenu/IProvider.php38
-rw-r--r--lib/public/Diagnostics/IEventLogger.php25
-rw-r--r--lib/public/Diagnostics/IQuery.php5
-rw-r--r--lib/public/Diagnostics/IQueryLogger.php21
-rw-r--r--lib/public/Mail/IEMailTemplate.php14
58 files changed, 1968 insertions, 325 deletions
diff --git a/lib/base.php b/lib/base.php
index 1db6b84c5fb..3ca4775dbe2 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -935,14 +935,15 @@ class OC {
// emergency app disabling
if ($requestPath === '/disableapp'
&& $request->getMethod() === 'POST'
- && ((string)$request->getParam('appid')) !== ''
+ && ((array)$request->getParam('appid')) !== ''
) {
\OCP\JSON::callCheck();
\OCP\JSON::checkAdminUser();
- $appId = (string)$request->getParam('appid');
- $appId = \OC_App::cleanAppId($appId);
-
- \OC_App::disable($appId);
+ $appIds = (array)$request->getParam('appid');
+ foreach($appIds as $appId) {
+ $appId = \OC_App::cleanAppId($appId);
+ \OC_App::disable($appId);
+ }
\OC_JSON::success();
exit();
}
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 0d5f067779d..8a883938b55 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -80,6 +80,11 @@ return array(
'OCP\\Console\\ConsoleEvent' => $baseDir . '/lib/public/Console/ConsoleEvent.php',
'OCP\\Constants' => $baseDir . '/lib/public/Constants.php',
'OCP\\Contacts' => $baseDir . '/lib/public/Contacts.php',
+ 'OCP\\Contacts\\ContactsMenu\\IAction' => $baseDir . '/lib/public/Contacts/ContactsMenu/IAction.php',
+ 'OCP\\Contacts\\ContactsMenu\\IActionFactory' => $baseDir . '/lib/public/Contacts/ContactsMenu/IActionFactory.php',
+ 'OCP\\Contacts\\ContactsMenu\\IEntry' => $baseDir . '/lib/public/Contacts/ContactsMenu/IEntry.php',
+ 'OCP\\Contacts\\ContactsMenu\\ILinkAction' => $baseDir . '/lib/public/Contacts/ContactsMenu/ILinkAction.php',
+ 'OCP\\Contacts\\ContactsMenu\\IProvider' => $baseDir . '/lib/public/Contacts/ContactsMenu/IProvider.php',
'OCP\\Contacts\\IManager' => $baseDir . '/lib/public/Contacts/IManager.php',
'OCP\\DB' => $baseDir . '/lib/public/DB.php',
'OCP\\DB\\QueryBuilder\\ICompositeExpression' => $baseDir . '/lib/public/DB/QueryBuilder/ICompositeExpression.php',
@@ -313,6 +318,12 @@ return array(
'OC\\AppFramework\\Utility\\TimeFactory' => $baseDir . '/lib/private/AppFramework/Utility/TimeFactory.php',
'OC\\AppHelper' => $baseDir . '/lib/private/AppHelper.php',
'OC\\App\\AppManager' => $baseDir . '/lib/private/App/AppManager.php',
+ 'OC\\App\\AppStore\\Bundles\\Bundle' => $baseDir . '/lib/private/App/AppStore/Bundles/Bundle.php',
+ 'OC\\App\\AppStore\\Bundles\\BundleFetcher' => $baseDir . '/lib/private/App/AppStore/Bundles/BundleFetcher.php',
+ 'OC\\App\\AppStore\\Bundles\\CoreBundle' => $baseDir . '/lib/private/App/AppStore/Bundles/CoreBundle.php',
+ 'OC\\App\\AppStore\\Bundles\\EnterpriseBundle' => $baseDir . '/lib/private/App/AppStore/Bundles/EnterpriseBundle.php',
+ 'OC\\App\\AppStore\\Bundles\\GroupwareBundle' => $baseDir . '/lib/private/App/AppStore/Bundles/GroupwareBundle.php',
+ 'OC\\App\\AppStore\\Bundles\\SocialSharingBundle' => $baseDir . '/lib/private/App/AppStore/Bundles/SocialSharingBundle.php',
'OC\\App\\AppStore\\Fetcher\\AppFetcher' => $baseDir . '/lib/private/App/AppStore/Fetcher/AppFetcher.php',
'OC\\App\\AppStore\\Fetcher\\CategoryFetcher' => $baseDir . '/lib/private/App/AppStore/Fetcher/CategoryFetcher.php',
'OC\\App\\AppStore\\Fetcher\\Fetcher' => $baseDir . '/lib/private/App/AppStore/Fetcher/Fetcher.php',
@@ -373,6 +384,13 @@ return array(
'OC\\Console\\Application' => $baseDir . '/lib/private/Console/Application.php',
'OC\\Console\\TimestampFormatter' => $baseDir . '/lib/private/Console/TimestampFormatter.php',
'OC\\ContactsManager' => $baseDir . '/lib/private/ContactsManager.php',
+ 'OC\\Contacts\\ContactsMenu\\ActionFactory' => $baseDir . '/lib/private/Contacts/ContactsMenu/ActionFactory.php',
+ 'OC\\Contacts\\ContactsMenu\\ActionProviderStore' => $baseDir . '/lib/private/Contacts/ContactsMenu/ActionProviderStore.php',
+ 'OC\\Contacts\\ContactsMenu\\Actions\\LinkAction' => $baseDir . '/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php',
+ 'OC\\Contacts\\ContactsMenu\\ContactsStore' => $baseDir . '/lib/private/Contacts/ContactsMenu/ContactsStore.php',
+ 'OC\\Contacts\\ContactsMenu\\Entry' => $baseDir . '/lib/private/Contacts/ContactsMenu/Entry.php',
+ 'OC\\Contacts\\ContactsMenu\\Manager' => $baseDir . '/lib/private/Contacts/ContactsMenu/Manager.php',
+ 'OC\\Contacts\\ContactsMenu\\Providers\\EMailProvider' => $baseDir . '/lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php',
'OC\\Core\\Application' => $baseDir . '/core/Application.php',
'OC\\Core\\Command\\App\\CheckCode' => $baseDir . '/core/Command/App/CheckCode.php',
'OC\\Core\\Command\\App\\Disable' => $baseDir . '/core/Command/App/Disable.php',
@@ -444,6 +462,8 @@ return array(
'OC\\Core\\Command\\User\\ResetPassword' => $baseDir . '/core/Command/User/ResetPassword.php',
'OC\\Core\\Command\\User\\Setting' => $baseDir . '/core/Command/User/Setting.php',
'OC\\Core\\Controller\\AvatarController' => $baseDir . '/core/Controller/AvatarController.php',
+ 'OC\\Core\\Controller\\ClientFlowLoginController' => $baseDir . '/core/Controller/ClientFlowLoginController.php',
+ 'OC\\Core\\Controller\\ContactsMenuController' => $baseDir . '/core/Controller/ContactsMenuController.php',
'OC\\Core\\Controller\\CssController' => $baseDir . '/core/Controller/CssController.php',
'OC\\Core\\Controller\\JsController' => $baseDir . '/core/Controller/JsController.php',
'OC\\Core\\Controller\\LoginController' => $baseDir . '/core/Controller/LoginController.php',
@@ -497,8 +517,6 @@ return array(
'OC\\DateTimeZone' => $baseDir . '/lib/private/DateTimeZone.php',
'OC\\Diagnostics\\Event' => $baseDir . '/lib/private/Diagnostics/Event.php',
'OC\\Diagnostics\\EventLogger' => $baseDir . '/lib/private/Diagnostics/EventLogger.php',
- 'OC\\Diagnostics\\NullEventLogger' => $baseDir . '/lib/private/Diagnostics/NullEventLogger.php',
- 'OC\\Diagnostics\\NullQueryLogger' => $baseDir . '/lib/private/Diagnostics/NullQueryLogger.php',
'OC\\Diagnostics\\Query' => $baseDir . '/lib/private/Diagnostics/Query.php',
'OC\\Diagnostics\\QueryLogger' => $baseDir . '/lib/private/Diagnostics/QueryLogger.php',
'OC\\Encryption\\DecryptAll' => $baseDir . '/lib/private/Encryption/DecryptAll.php',
@@ -713,6 +731,7 @@ return array(
'OC\\Repair\\NC11\\FixMountStorages' => $baseDir . '/lib/private/Repair/NC11/FixMountStorages.php',
'OC\\Repair\\NC11\\MoveAvatars' => $baseDir . '/lib/private/Repair/NC11/MoveAvatars.php',
'OC\\Repair\\NC11\\MoveAvatarsBackgroundJob' => $baseDir . '/lib/private/Repair/NC11/MoveAvatarsBackgroundJob.php',
+ 'OC\\Repair\\NC12\\InstallCoreBundle' => $baseDir . '/lib/private/Repair/NC12/InstallCoreBundle.php',
'OC\\Repair\\NC12\\UpdateLanguageCodes' => $baseDir . '/lib/private/Repair/NC12/UpdateLanguageCodes.php',
'OC\\Repair\\OldGroupMembershipShares' => $baseDir . '/lib/private/Repair/OldGroupMembershipShares.php',
'OC\\Repair\\RemoveRootShares' => $baseDir . '/lib/private/Repair/RemoveRootShares.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 82c31c24a21..70761572620 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -110,6 +110,11 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OCP\\Console\\ConsoleEvent' => __DIR__ . '/../../..' . '/lib/public/Console/ConsoleEvent.php',
'OCP\\Constants' => __DIR__ . '/../../..' . '/lib/public/Constants.php',
'OCP\\Contacts' => __DIR__ . '/../../..' . '/lib/public/Contacts.php',
+ 'OCP\\Contacts\\ContactsMenu\\IAction' => __DIR__ . '/../../..' . '/lib/public/Contacts/ContactsMenu/IAction.php',
+ 'OCP\\Contacts\\ContactsMenu\\IActionFactory' => __DIR__ . '/../../..' . '/lib/public/Contacts/ContactsMenu/IActionFactory.php',
+ 'OCP\\Contacts\\ContactsMenu\\IEntry' => __DIR__ . '/../../..' . '/lib/public/Contacts/ContactsMenu/IEntry.php',
+ 'OCP\\Contacts\\ContactsMenu\\ILinkAction' => __DIR__ . '/../../..' . '/lib/public/Contacts/ContactsMenu/ILinkAction.php',
+ 'OCP\\Contacts\\ContactsMenu\\IProvider' => __DIR__ . '/../../..' . '/lib/public/Contacts/ContactsMenu/IProvider.php',
'OCP\\Contacts\\IManager' => __DIR__ . '/../../..' . '/lib/public/Contacts/IManager.php',
'OCP\\DB' => __DIR__ . '/../../..' . '/lib/public/DB.php',
'OCP\\DB\\QueryBuilder\\ICompositeExpression' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/ICompositeExpression.php',
@@ -343,6 +348,12 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\AppFramework\\Utility\\TimeFactory' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Utility/TimeFactory.php',
'OC\\AppHelper' => __DIR__ . '/../../..' . '/lib/private/AppHelper.php',
'OC\\App\\AppManager' => __DIR__ . '/../../..' . '/lib/private/App/AppManager.php',
+ 'OC\\App\\AppStore\\Bundles\\Bundle' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/Bundles/Bundle.php',
+ 'OC\\App\\AppStore\\Bundles\\BundleFetcher' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/Bundles/BundleFetcher.php',
+ 'OC\\App\\AppStore\\Bundles\\CoreBundle' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/Bundles/CoreBundle.php',
+ 'OC\\App\\AppStore\\Bundles\\EnterpriseBundle' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/Bundles/EnterpriseBundle.php',
+ 'OC\\App\\AppStore\\Bundles\\GroupwareBundle' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/Bundles/GroupwareBundle.php',
+ 'OC\\App\\AppStore\\Bundles\\SocialSharingBundle' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/Bundles/SocialSharingBundle.php',
'OC\\App\\AppStore\\Fetcher\\AppFetcher' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/Fetcher/AppFetcher.php',
'OC\\App\\AppStore\\Fetcher\\CategoryFetcher' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/Fetcher/CategoryFetcher.php',
'OC\\App\\AppStore\\Fetcher\\Fetcher' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/Fetcher/Fetcher.php',
@@ -403,6 +414,13 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Console\\Application' => __DIR__ . '/../../..' . '/lib/private/Console/Application.php',
'OC\\Console\\TimestampFormatter' => __DIR__ . '/../../..' . '/lib/private/Console/TimestampFormatter.php',
'OC\\ContactsManager' => __DIR__ . '/../../..' . '/lib/private/ContactsManager.php',
+ 'OC\\Contacts\\ContactsMenu\\ActionFactory' => __DIR__ . '/../../..' . '/lib/private/Contacts/ContactsMenu/ActionFactory.php',
+ 'OC\\Contacts\\ContactsMenu\\ActionProviderStore' => __DIR__ . '/../../..' . '/lib/private/Contacts/ContactsMenu/ActionProviderStore.php',
+ 'OC\\Contacts\\ContactsMenu\\Actions\\LinkAction' => __DIR__ . '/../../..' . '/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php',
+ 'OC\\Contacts\\ContactsMenu\\ContactsStore' => __DIR__ . '/../../..' . '/lib/private/Contacts/ContactsMenu/ContactsStore.php',
+ 'OC\\Contacts\\ContactsMenu\\Entry' => __DIR__ . '/../../..' . '/lib/private/Contacts/ContactsMenu/Entry.php',
+ 'OC\\Contacts\\ContactsMenu\\Manager' => __DIR__ . '/../../..' . '/lib/private/Contacts/ContactsMenu/Manager.php',
+ 'OC\\Contacts\\ContactsMenu\\Providers\\EMailProvider' => __DIR__ . '/../../..' . '/lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php',
'OC\\Core\\Application' => __DIR__ . '/../../..' . '/core/Application.php',
'OC\\Core\\Command\\App\\CheckCode' => __DIR__ . '/../../..' . '/core/Command/App/CheckCode.php',
'OC\\Core\\Command\\App\\Disable' => __DIR__ . '/../../..' . '/core/Command/App/Disable.php',
@@ -474,6 +492,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Core\\Command\\User\\ResetPassword' => __DIR__ . '/../../..' . '/core/Command/User/ResetPassword.php',
'OC\\Core\\Command\\User\\Setting' => __DIR__ . '/../../..' . '/core/Command/User/Setting.php',
'OC\\Core\\Controller\\AvatarController' => __DIR__ . '/../../..' . '/core/Controller/AvatarController.php',
+ 'OC\\Core\\Controller\\ClientFlowLoginController' => __DIR__ . '/../../..' . '/core/Controller/ClientFlowLoginController.php',
+ 'OC\\Core\\Controller\\ContactsMenuController' => __DIR__ . '/../../..' . '/core/Controller/ContactsMenuController.php',
'OC\\Core\\Controller\\CssController' => __DIR__ . '/../../..' . '/core/Controller/CssController.php',
'OC\\Core\\Controller\\JsController' => __DIR__ . '/../../..' . '/core/Controller/JsController.php',
'OC\\Core\\Controller\\LoginController' => __DIR__ . '/../../..' . '/core/Controller/LoginController.php',
@@ -527,8 +547,6 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\DateTimeZone' => __DIR__ . '/../../..' . '/lib/private/DateTimeZone.php',
'OC\\Diagnostics\\Event' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/Event.php',
'OC\\Diagnostics\\EventLogger' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/EventLogger.php',
- 'OC\\Diagnostics\\NullEventLogger' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/NullEventLogger.php',
- 'OC\\Diagnostics\\NullQueryLogger' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/NullQueryLogger.php',
'OC\\Diagnostics\\Query' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/Query.php',
'OC\\Diagnostics\\QueryLogger' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/QueryLogger.php',
'OC\\Encryption\\DecryptAll' => __DIR__ . '/../../..' . '/lib/private/Encryption/DecryptAll.php',
@@ -743,6 +761,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Repair\\NC11\\FixMountStorages' => __DIR__ . '/../../..' . '/lib/private/Repair/NC11/FixMountStorages.php',
'OC\\Repair\\NC11\\MoveAvatars' => __DIR__ . '/../../..' . '/lib/private/Repair/NC11/MoveAvatars.php',
'OC\\Repair\\NC11\\MoveAvatarsBackgroundJob' => __DIR__ . '/../../..' . '/lib/private/Repair/NC11/MoveAvatarsBackgroundJob.php',
+ 'OC\\Repair\\NC12\\InstallCoreBundle' => __DIR__ . '/../../..' . '/lib/private/Repair/NC12/InstallCoreBundle.php',
'OC\\Repair\\NC12\\UpdateLanguageCodes' => __DIR__ . '/../../..' . '/lib/private/Repair/NC12/UpdateLanguageCodes.php',
'OC\\Repair\\OldGroupMembershipShares' => __DIR__ . '/../../..' . '/lib/private/Repair/OldGroupMembershipShares.php',
'OC\\Repair\\RemoveRootShares' => __DIR__ . '/../../..' . '/lib/private/Repair/RemoveRootShares.php',
diff --git a/lib/l10n/el.js b/lib/l10n/el.js
index febd6fce10d..eca3d48a22c 100644
--- a/lib/l10n/el.js
+++ b/lib/l10n/el.js
@@ -40,6 +40,7 @@ OC.L10N.register(
"Help" : "Βοήθεια",
"Apps" : "Εφαρμογές",
"Personal" : "Προσωπικά",
+ "Log out" : "Έξοδος",
"Users" : "Χρήστες",
"Admin" : "Διαχείριση",
"APCu" : "APCu",
diff --git a/lib/l10n/el.json b/lib/l10n/el.json
index 0e4e26fb7fe..d1f0b3bd491 100644
--- a/lib/l10n/el.json
+++ b/lib/l10n/el.json
@@ -38,6 +38,7 @@
"Help" : "Βοήθεια",
"Apps" : "Εφαρμογές",
"Personal" : "Προσωπικά",
+ "Log out" : "Έξοδος",
"Users" : "Χρήστες",
"Admin" : "Διαχείριση",
"APCu" : "APCu",
diff --git a/lib/l10n/nb.js b/lib/l10n/nb.js
index 3e824b6376e..606de2c8dc2 100644
--- a/lib/l10n/nb.js
+++ b/lib/l10n/nb.js
@@ -158,6 +158,7 @@ OC.L10N.register(
"Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-'\"" : "Bare disse tegnene tillates i et brukernavn: \"a-z\", \"A-Z\", \"0-9\" og \"_.@-'\"",
"A valid username must be provided" : "Oppgi et gyldig brukernavn",
"Username contains whitespace at the beginning or at the end" : "Brukernavn inneholder blanke på begynnelsen eller slutten",
+ "Username must not consist of dots only" : "Brukernavn kan ikke bare bestå av punktum",
"A valid password must be provided" : "Oppgi et gyldig passord",
"The username is already being used" : "Brukernavnet er allerede i bruk",
"User disabled" : "Brukeren er deaktivert",
diff --git a/lib/l10n/nb.json b/lib/l10n/nb.json
index 246bea1e256..97c0d164723 100644
--- a/lib/l10n/nb.json
+++ b/lib/l10n/nb.json
@@ -156,6 +156,7 @@
"Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-'\"" : "Bare disse tegnene tillates i et brukernavn: \"a-z\", \"A-Z\", \"0-9\" og \"_.@-'\"",
"A valid username must be provided" : "Oppgi et gyldig brukernavn",
"Username contains whitespace at the beginning or at the end" : "Brukernavn inneholder blanke på begynnelsen eller slutten",
+ "Username must not consist of dots only" : "Brukernavn kan ikke bare bestå av punktum",
"A valid password must be provided" : "Oppgi et gyldig passord",
"The username is already being used" : "Brukernavnet er allerede i bruk",
"User disabled" : "Brukeren er deaktivert",
diff --git a/lib/l10n/pt_BR.js b/lib/l10n/pt_BR.js
index 4b58876ddbc..4f2dd051538 100644
--- a/lib/l10n/pt_BR.js
+++ b/lib/l10n/pt_BR.js
@@ -16,7 +16,7 @@ OC.L10N.register(
"PHP with a version lower than %s is required." : "É requerida uma versão PHP mais antiga que a %s .",
"%sbit or higher PHP required." : "%sbit ou maior é requerido.",
"Following databases are supported: %s" : "Os seguintes bancos de dados são suportados: %s",
- "The command line tool %s could not be found" : "A ferramenta de linha de comando %s não pode ser encontrada",
+ "The command line tool %s could not be found" : "A ferramenta de linha de comando %s não pôde ser encontrada",
"The library %s is not available." : "A biblioteca %s não está disponível.",
"Library %s with a version higher than %s is required - available version %s." : "É requerida uma biblioteca %s com uma versão maior que %s - versão disponível %s.",
"Library %s with a version lower than %s is required - available version %s." : "É requerida uma biblioteca %s com uma versão menor que %s - versão disponível %s.",
@@ -61,7 +61,7 @@ OC.L10N.register(
"%s enter the database username." : "%s insira o nome de usuário do banco de dados.",
"%s enter the database name." : "%s insira o nome do banco de dados.",
"%s you may not use dots in the database name" : "%s você não pode usar pontos no nome do banco de dados",
- "Oracle connection could not be established" : "Conexão Oracle não pode ser estabelecida",
+ "Oracle connection could not be established" : "Conexão Oracle não pôde ser estabelecida",
"Oracle username and/or password not valid" : "Nome de usuário e/ou senha Oracle inválidos",
"DB Error: \"%s\"" : "Erro no BD: \"%s\"",
"Offending command was: \"%s\"" : "Comando ofensivo era: \"%s\"",
@@ -94,7 +94,7 @@ OC.L10N.register(
"Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "A definição de permissões para %s falhou pois as permissões excedem as permissões concedidas a %s",
"Setting permissions for %s failed, because the item was not found" : "A definição de permissões para %s falhou pois o item não foi encontrado",
"Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Não é possível definir a data de expiração. Os compartilhamentos não podem expirar mais tarde que %s depois de terem sido compartilhados",
- "Cannot set expiration date. Expiration date is in the past" : "Não é possível definir a data de validade. A data de expiração está no passado",
+ "Cannot set expiration date. Expiration date is in the past" : "Não é possível definir a data de expiração pois ela está no passado",
"Cannot clear expiration date. Shares are required to have an expiration date." : "Não é possível eliminar a data de expiração. Compartilhamentos devem ter uma data de expiração.",
"Sharing backend %s must implement the interface OCP\\Share_Backend" : "Compartilhamento backend %s deve implementar a interface OCP\\Share_Backend",
"Sharing backend %s not found" : "Compartilhamento backend %s não encontrado",
@@ -103,7 +103,7 @@ OC.L10N.register(
"Sharing %s failed, because the permissions exceed permissions granted to %s" : "Compartilhamento %s falhou pois as permissões excedem as permissões concedidas a %s",
"Sharing %s failed, because resharing is not allowed" : "O compartilhamento %s falhou pois recompartilhamentos não são permitidos",
"Sharing %s failed, because the sharing backend for %s could not find its source" : "O compartilhamento %s falhou, pois a infraestrutura de compartilhamento para %s não conseguiu encontrar a sua fonte",
- "Sharing %s failed, because the file could not be found in the file cache" : "O compartilhamento %s falhou pois o arquivo não pode ser encontrado no cache de arquivos",
+ "Sharing %s failed, because the file could not be found in the file cache" : "O compartilhamento %s falhou pois o arquivo não pôde ser encontrado no cache de arquivos",
"Cannot increase permissions of %s" : "Não é possível aumentar as permissões de %s",
"Files can't be shared with delete permissions" : "Os arquivos não podem ser compartilhadas com permissões de exclusão",
"Files can't be shared with create permissions" : "Os arquivos não podem ser compartilhados com permissões de criação",
@@ -163,15 +163,15 @@ OC.L10N.register(
"The username is already being used" : "Este nome de usuário já está em uso",
"User disabled" : "Usuário desativado",
"Login canceled by app" : "Login cancelado pelo aplicativo",
- "App \"%s\" cannot be installed because appinfo file cannot be read." : "O aplicativo \"%s\" não pode ser instalado pois o arquivo appinfo não pode ser lido.",
+ "App \"%s\" cannot be installed because appinfo file cannot be read." : "O aplicativo \"%s\" não pode ser instalado pois o arquivo appinfo não pôde ser lido.",
"App \"%s\" cannot be installed because it is not compatible with this version of the server." : "O aplicativo \"%s\" não pode ser instalado pois não é compatível com a versão do servidor.",
"No app name specified" : "O nome do aplicativo não foi especificado.",
- "App '%s' could not be installed!" : "O aplicativo '%s' não pode ser instalado!",
- "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "O aplicativo \"%s\" não pode ser instalado porque as seguintes dependências não foram cumpridas: %s",
+ "App '%s' could not be installed!" : "O aplicativo '%s' não pôde ser instalado!",
+ "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "O aplicativo \"%s\" não pode ser instalado pois as seguintes dependências não foram cumpridas: %s",
"a safe home for all your data" : "um local seguro para todos os seus dados",
"File is currently busy, please try again later" : "O arquivo está ocupado, tente novamente mais tarde",
"Can't read file" : "Não é possível ler arquivo",
- "Application is not enabled" : "Aplicação não está habilitada",
+ "Application is not enabled" : "O aplicativo não está habilitado",
"Authentication error" : "Erro de autenticação",
"Token expired. Please reload page." : "O token expirou. Por favor recarregue a página.",
"Unknown user" : "Usuário desconhecido",
@@ -214,7 +214,7 @@ OC.L10N.register(
"You need to enter either an existing account or the administrator." : "Você precisa inserir uma conta existente ou a do administrador.",
"%s shared »%s« with you" : "%s compartilhou »%s« com você",
"%s via %s" : "%s via %s",
- "Cannot create \"data\" directory (%s)" : "Não pode ser criado \"dados\" no diretório (%s)",
+ "Cannot create \"data\" directory (%s)" : "Não pôde ser criado o diretório \"dados\" (%s)",
"Data directory (%s) is readable by other users" : "Diretório de dados (%s) pode ser lido por outros usuários",
"Data directory (%s) must be an absolute path" : "Diretório de dados (%s) deve ser um caminho absoluto",
"Data directory (%s) is invalid" : "Diretório de dados (%s) é inválido"
diff --git a/lib/l10n/pt_BR.json b/lib/l10n/pt_BR.json
index 580af8db048..5a965bd867b 100644
--- a/lib/l10n/pt_BR.json
+++ b/lib/l10n/pt_BR.json
@@ -14,7 +14,7 @@
"PHP with a version lower than %s is required." : "É requerida uma versão PHP mais antiga que a %s .",
"%sbit or higher PHP required." : "%sbit ou maior é requerido.",
"Following databases are supported: %s" : "Os seguintes bancos de dados são suportados: %s",
- "The command line tool %s could not be found" : "A ferramenta de linha de comando %s não pode ser encontrada",
+ "The command line tool %s could not be found" : "A ferramenta de linha de comando %s não pôde ser encontrada",
"The library %s is not available." : "A biblioteca %s não está disponível.",
"Library %s with a version higher than %s is required - available version %s." : "É requerida uma biblioteca %s com uma versão maior que %s - versão disponível %s.",
"Library %s with a version lower than %s is required - available version %s." : "É requerida uma biblioteca %s com uma versão menor que %s - versão disponível %s.",
@@ -59,7 +59,7 @@
"%s enter the database username." : "%s insira o nome de usuário do banco de dados.",
"%s enter the database name." : "%s insira o nome do banco de dados.",
"%s you may not use dots in the database name" : "%s você não pode usar pontos no nome do banco de dados",
- "Oracle connection could not be established" : "Conexão Oracle não pode ser estabelecida",
+ "Oracle connection could not be established" : "Conexão Oracle não pôde ser estabelecida",
"Oracle username and/or password not valid" : "Nome de usuário e/ou senha Oracle inválidos",
"DB Error: \"%s\"" : "Erro no BD: \"%s\"",
"Offending command was: \"%s\"" : "Comando ofensivo era: \"%s\"",
@@ -92,7 +92,7 @@
"Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "A definição de permissões para %s falhou pois as permissões excedem as permissões concedidas a %s",
"Setting permissions for %s failed, because the item was not found" : "A definição de permissões para %s falhou pois o item não foi encontrado",
"Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Não é possível definir a data de expiração. Os compartilhamentos não podem expirar mais tarde que %s depois de terem sido compartilhados",
- "Cannot set expiration date. Expiration date is in the past" : "Não é possível definir a data de validade. A data de expiração está no passado",
+ "Cannot set expiration date. Expiration date is in the past" : "Não é possível definir a data de expiração pois ela está no passado",
"Cannot clear expiration date. Shares are required to have an expiration date." : "Não é possível eliminar a data de expiração. Compartilhamentos devem ter uma data de expiração.",
"Sharing backend %s must implement the interface OCP\\Share_Backend" : "Compartilhamento backend %s deve implementar a interface OCP\\Share_Backend",
"Sharing backend %s not found" : "Compartilhamento backend %s não encontrado",
@@ -101,7 +101,7 @@
"Sharing %s failed, because the permissions exceed permissions granted to %s" : "Compartilhamento %s falhou pois as permissões excedem as permissões concedidas a %s",
"Sharing %s failed, because resharing is not allowed" : "O compartilhamento %s falhou pois recompartilhamentos não são permitidos",
"Sharing %s failed, because the sharing backend for %s could not find its source" : "O compartilhamento %s falhou, pois a infraestrutura de compartilhamento para %s não conseguiu encontrar a sua fonte",
- "Sharing %s failed, because the file could not be found in the file cache" : "O compartilhamento %s falhou pois o arquivo não pode ser encontrado no cache de arquivos",
+ "Sharing %s failed, because the file could not be found in the file cache" : "O compartilhamento %s falhou pois o arquivo não pôde ser encontrado no cache de arquivos",
"Cannot increase permissions of %s" : "Não é possível aumentar as permissões de %s",
"Files can't be shared with delete permissions" : "Os arquivos não podem ser compartilhadas com permissões de exclusão",
"Files can't be shared with create permissions" : "Os arquivos não podem ser compartilhados com permissões de criação",
@@ -161,15 +161,15 @@
"The username is already being used" : "Este nome de usuário já está em uso",
"User disabled" : "Usuário desativado",
"Login canceled by app" : "Login cancelado pelo aplicativo",
- "App \"%s\" cannot be installed because appinfo file cannot be read." : "O aplicativo \"%s\" não pode ser instalado pois o arquivo appinfo não pode ser lido.",
+ "App \"%s\" cannot be installed because appinfo file cannot be read." : "O aplicativo \"%s\" não pode ser instalado pois o arquivo appinfo não pôde ser lido.",
"App \"%s\" cannot be installed because it is not compatible with this version of the server." : "O aplicativo \"%s\" não pode ser instalado pois não é compatível com a versão do servidor.",
"No app name specified" : "O nome do aplicativo não foi especificado.",
- "App '%s' could not be installed!" : "O aplicativo '%s' não pode ser instalado!",
- "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "O aplicativo \"%s\" não pode ser instalado porque as seguintes dependências não foram cumpridas: %s",
+ "App '%s' could not be installed!" : "O aplicativo '%s' não pôde ser instalado!",
+ "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "O aplicativo \"%s\" não pode ser instalado pois as seguintes dependências não foram cumpridas: %s",
"a safe home for all your data" : "um local seguro para todos os seus dados",
"File is currently busy, please try again later" : "O arquivo está ocupado, tente novamente mais tarde",
"Can't read file" : "Não é possível ler arquivo",
- "Application is not enabled" : "Aplicação não está habilitada",
+ "Application is not enabled" : "O aplicativo não está habilitado",
"Authentication error" : "Erro de autenticação",
"Token expired. Please reload page." : "O token expirou. Por favor recarregue a página.",
"Unknown user" : "Usuário desconhecido",
@@ -212,7 +212,7 @@
"You need to enter either an existing account or the administrator." : "Você precisa inserir uma conta existente ou a do administrador.",
"%s shared »%s« with you" : "%s compartilhou »%s« com você",
"%s via %s" : "%s via %s",
- "Cannot create \"data\" directory (%s)" : "Não pode ser criado \"dados\" no diretório (%s)",
+ "Cannot create \"data\" directory (%s)" : "Não pôde ser criado o diretório \"dados\" (%s)",
"Data directory (%s) is readable by other users" : "Diretório de dados (%s) pode ser lido por outros usuários",
"Data directory (%s) must be an absolute path" : "Diretório de dados (%s) deve ser um caminho absoluto",
"Data directory (%s) is invalid" : "Diretório de dados (%s) é inválido"
diff --git a/lib/private/App/AppStore/Bundles/Bundle.php b/lib/private/App/AppStore/Bundles/Bundle.php
new file mode 100644
index 00000000000..47efc4e0cce
--- /dev/null
+++ b/lib/private/App/AppStore/Bundles/Bundle.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
+ *
+ * @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\App\AppStore\Bundles;
+
+use OCP\IL10N;
+
+abstract class Bundle {
+ /** @var IL10N */
+ protected $l10n;
+
+ /**
+ * @param IL10N $l10n
+ */
+ public function __construct(IL10N $l10n) {
+ $this->l10n = $l10n;
+ }
+
+ /**
+ * Get the identifier of the bundle
+ *
+ * @return string
+ */
+ public final function getIdentifier() {
+ return substr(strrchr(get_class($this), '\\'), 1);
+ }
+
+ /**
+ * Get the name of the bundle
+ *
+ * @return string
+ */
+ public abstract function getName();
+
+ /**
+ * Get the list of app identifiers in the bundle
+ *
+ * @return array
+ */
+ public abstract function getAppIdentifiers();
+}
diff --git a/lib/private/App/AppStore/Bundles/BundleFetcher.php b/lib/private/App/AppStore/Bundles/BundleFetcher.php
new file mode 100644
index 00000000000..01cd4d6a518
--- /dev/null
+++ b/lib/private/App/AppStore/Bundles/BundleFetcher.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
+ *
+ * @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\App\AppStore\Bundles;
+
+use OCP\IL10N;
+
+class BundleFetcher {
+ /** @var IL10N */
+ private $l10n;
+
+ /**
+ * @param IL10N $l10n
+ */
+ public function __construct(IL10N $l10n) {
+ $this->l10n = $l10n;
+ }
+
+ /**
+ * @return Bundle[]
+ */
+ public function getBundles() {
+ return [
+ new EnterpriseBundle($this->l10n),
+ new GroupwareBundle($this->l10n),
+ new SocialSharingBundle($this->l10n),
+ ];
+ }
+
+ /**
+ * Bundles that should be installed by default after installation
+ *
+ * @return Bundle[]
+ */
+ public function getDefaultInstallationBundle() {
+ return [
+ new CoreBundle($this->l10n),
+ ];
+ }
+
+ /**
+ * Get the bundle with the specified identifier
+ *
+ * @param string $identifier
+ * @return Bundle
+ * @throws \BadMethodCallException If the bundle does not exist
+ */
+ public function getBundleByIdentifier($identifier) {
+ /** @var Bundle[] $bundles */
+ $bundles = array_merge(
+ $this->getBundles(),
+ $this->getDefaultInstallationBundle()
+ );
+ foreach($bundles as $bundle) {
+ if($bundle->getIdentifier() === $identifier) {
+ return $bundle;
+ }
+ }
+
+ throw new \BadMethodCallException('Bundle with specified identifier does not exist');
+ }
+}
diff --git a/lib/private/App/AppStore/Bundles/CoreBundle.php b/lib/private/App/AppStore/Bundles/CoreBundle.php
new file mode 100644
index 00000000000..a87292b9ec9
--- /dev/null
+++ b/lib/private/App/AppStore/Bundles/CoreBundle.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
+ *
+ * @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\App\AppStore\Bundles;
+
+class CoreBundle extends Bundle {
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getName() {
+ return 'Core bundle';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAppIdentifiers() {
+ return [
+ 'bruteforcesettings',
+ ];
+ }
+
+}
diff --git a/lib/private/App/AppStore/Bundles/EnterpriseBundle.php b/lib/private/App/AppStore/Bundles/EnterpriseBundle.php
new file mode 100644
index 00000000000..6d43a6210fa
--- /dev/null
+++ b/lib/private/App/AppStore/Bundles/EnterpriseBundle.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
+ *
+ * @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\App\AppStore\Bundles;
+
+class EnterpriseBundle extends Bundle {
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getName() {
+ return (string)$this->l10n->t('Enterprise bundle');
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAppIdentifiers() {
+ return [
+ 'admin_audit',
+ 'user_ldap',
+ 'files_retention',
+ 'files_automatedtagging',
+ 'user_saml',
+ 'files_accesscontrol',
+ ];
+ }
+
+}
diff --git a/lib/private/App/AppStore/Bundles/GroupwareBundle.php b/lib/private/App/AppStore/Bundles/GroupwareBundle.php
new file mode 100644
index 00000000000..7e7414f69c7
--- /dev/null
+++ b/lib/private/App/AppStore/Bundles/GroupwareBundle.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
+ *
+ * @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\App\AppStore\Bundles;
+
+class GroupwareBundle extends Bundle {
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getName() {
+ return (string)$this->l10n->t('Groupware bundle');
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAppIdentifiers() {
+ return [
+ 'calendar',
+ 'contacts',
+ 'spreed',
+ ];
+ }
+
+}
diff --git a/lib/private/App/AppStore/Bundles/SocialSharingBundle.php b/lib/private/App/AppStore/Bundles/SocialSharingBundle.php
new file mode 100644
index 00000000000..8da84e8d1ef
--- /dev/null
+++ b/lib/private/App/AppStore/Bundles/SocialSharingBundle.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
+ *
+ * @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\App\AppStore\Bundles;
+
+class SocialSharingBundle extends Bundle {
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getName() {
+ return (string)$this->l10n->t('Social sharing bundle');
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAppIdentifiers() {
+ return [
+ 'socialsharing_twitter',
+ 'socialsharing_googleplus',
+ 'socialsharing_facebook',
+ 'socialsharing_email',
+ 'socialsharing_diaspora',
+ ];
+ }
+
+}
diff --git a/lib/private/Contacts/ContactsMenu/ActionFactory.php b/lib/private/Contacts/ContactsMenu/ActionFactory.php
new file mode 100644
index 00000000000..1d2a69c904d
--- /dev/null
+++ b/lib/private/Contacts/ContactsMenu/ActionFactory.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @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\Contacts\ContactsMenu;
+
+use OC\Contacts\ContactsMenu\Actions\LinkAction;
+use OCP\Contacts\ContactsMenu\IActionFactory;
+use OCP\Contacts\ContactsMenu\ILinkAction;
+
+class ActionFactory implements IActionFactory {
+
+ /**
+ * @param string $icon
+ * @param string $name
+ * @param string $href
+ * @return ILinkAction
+ */
+ public function newLinkAction($icon, $name, $href) {
+ $action = new LinkAction();
+ $action->setName($name);
+ $action->setIcon($icon);
+ $action->setHref($href);
+ return $action;
+ }
+
+ /**
+ * @param string $icon
+ * @param string $name
+ * @param string $email
+ * @return ILinkAction
+ */
+ public function newEMailAction($icon, $name, $email) {
+ return $this->newLinkAction($icon, $name, 'mailto:' . urlencode($email));
+ }
+
+}
diff --git a/lib/private/Contacts/ContactsMenu/ActionProviderStore.php b/lib/private/Contacts/ContactsMenu/ActionProviderStore.php
new file mode 100644
index 00000000000..ae6436095d8
--- /dev/null
+++ b/lib/private/Contacts/ContactsMenu/ActionProviderStore.php
@@ -0,0 +1,114 @@
+<?php
+
+/**
+ * @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @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\Contacts\ContactsMenu;
+
+use Exception;
+use OC\App\AppManager;
+use OC\Contacts\ContactsMenu\Providers\EMailProvider;
+use OCP\AppFramework\QueryException;
+use OCP\Contacts\ContactsMenu\IProvider;
+use OCP\ILogger;
+use OCP\IServerContainer;
+use OCP\IUser;
+
+class ActionProviderStore {
+
+ /** @var IServerContainer */
+ private $serverContainer;
+
+ /** @var AppManager */
+ private $appManager;
+
+ /** @var ILogger */
+ private $logger;
+
+ /**
+ * @param IServerContainer $serverContainer
+ * @param AppManager $appManager
+ * @param ILogger $logger
+ */
+ public function __construct(IServerContainer $serverContainer, AppManager $appManager, ILogger $logger) {
+ $this->serverContainer = $serverContainer;
+ $this->appManager = $appManager;
+ $this->logger = $logger;
+ }
+
+ /**
+ * @param IUser $user
+ * @return IProvider[]
+ * @throws Exception
+ */
+ public function getProviders(IUser $user) {
+ $appClasses = $this->getAppProviderClasses($user);
+ $providerClasses = $this->getServerProviderClasses();
+ $allClasses = array_merge($providerClasses, $appClasses);
+ $providers = [];
+
+ foreach ($allClasses as $class) {
+ try {
+ $providers[] = $this->serverContainer->query($class);
+ } catch (QueryException $ex) {
+ $this->logger->logException($ex, [
+ 'message' => "Could not load contacts menu action provider $class",
+ 'app' => 'core',
+ ]);
+ throw new Exception("Could not load contacts menu action provider");
+ }
+ }
+
+ return $providers;
+ }
+
+ /**
+ * @return string[]
+ */
+ private function getServerProviderClasses() {
+ return [
+ EMailProvider::class,
+ ];
+ }
+
+ /**
+ * @param IUser $user
+ * @return string[]
+ */
+ private function getAppProviderClasses(IUser $user) {
+ return array_reduce($this->appManager->getEnabledAppsForUser($user), function($all, $appId) {
+ $info = $this->appManager->getAppInfo($appId);
+
+ if (!isset($info['contactsmenu']) || !isset($info['contactsmenu'])) {
+ // Nothing to add
+ return $all;
+ }
+
+ $providers = array_reduce($info['contactsmenu'], function($all, $provider) {
+ return array_merge($all, [$provider]);
+ }, []);
+
+ return array_merge($all, $providers);
+ }, []);
+ }
+
+}
diff --git a/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php b/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php
new file mode 100644
index 00000000000..5b8b0524a21
--- /dev/null
+++ b/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php
@@ -0,0 +1,103 @@
+<?php
+
+/**
+ * @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @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\Contacts\ContactsMenu\Actions;
+
+use OCP\Contacts\ContactsMenu\ILinkAction;
+
+class LinkAction implements ILinkAction {
+
+ /** @var string */
+ private $icon;
+
+ /** @var string */
+ private $name;
+
+ /** @var string */
+ private $href;
+
+ /** @var int */
+ private $priority = 10;
+
+ /**
+ * @param string $icon absolute URI to an icon
+ */
+ public function setIcon($icon) {
+ $this->icon = $icon;
+ }
+
+ /**
+ * @param string $name
+ */
+ public function setName($name) {
+ $this->name = $name;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * @param int $priority
+ */
+ public function setPriority($priority) {
+ $this->priority = $priority;
+ }
+
+ /**
+ * @return int
+ */
+ public function getPriority() {
+ return $this->priority;
+ }
+
+ /**
+ * @param string $href
+ */
+ public function setHref($href) {
+ $this->href = $href;
+ }
+
+ /**
+ * @return string
+ */
+ public function getHref() {
+ return $this->href;
+ }
+
+ /**
+ * @return array
+ */
+ public function jsonSerialize() {
+ return [
+ 'title' => $this->name,
+ 'icon' => $this->icon,
+ 'hyperlink' => $this->href,
+ ];
+ }
+
+}
diff --git a/lib/private/Contacts/ContactsMenu/ContactsStore.php b/lib/private/Contacts/ContactsMenu/ContactsStore.php
new file mode 100644
index 00000000000..40a0bf87031
--- /dev/null
+++ b/lib/private/Contacts/ContactsMenu/ContactsStore.php
@@ -0,0 +1,139 @@
+<?php
+
+/**
+ * @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @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\Contacts\ContactsMenu;
+
+use OCP\Contacts\ContactsMenu\IEntry;
+use OCP\Contacts\IManager;
+use OCP\IUser;
+
+class ContactsStore {
+
+ /** @var IManager */
+ private $contactsManager;
+
+ /**
+ * @param IManager $contactsManager
+ */
+ public function __construct(IManager $contactsManager) {
+ $this->contactsManager = $contactsManager;
+ }
+
+ /**
+ * @param IUser $user
+ * @param string|null $filter
+ * @return IEntry[]
+ */
+ public function getContacts(IUser $user, $filter) {
+ $allContacts = $this->contactsManager->search($filter ?: '', [
+ 'FN',
+ ]);
+
+ $self = $user->getUID();
+ $entries = array_map(function(array $contact) {
+ return $this->contactArrayToEntry($contact);
+ }, $allContacts);
+ return array_filter($entries, function(IEntry $entry) use ($self) {
+ return $entry->getProperty('UID') !== $self;
+ });
+ }
+
+ /**
+ * @param IUser $user
+ * @param integer $shareType
+ * @param string $shareWith
+ * @return IEntry|null
+ */
+ public function findOne(IUser $user, $shareType, $shareWith) {
+ switch($shareType) {
+ case 0:
+ case 6:
+ $filter = ['UID'];
+ break;
+ case 4:
+ $filter = ['EMAIL'];
+ break;
+ default:
+ return null;
+ }
+
+ $userId = $user->getUID();
+ $allContacts = $this->contactsManager->search($shareWith, $filter);
+ $contacts = array_filter($allContacts, function($contact) use ($userId) {
+ return $contact['UID'] !== $userId;
+ });
+ $match = null;
+
+ foreach ($contacts as $contact) {
+ if ($shareType === 4 && isset($contact['EMAIL'])) {
+ if (in_array($shareWith, $contact['EMAIL'])) {
+ $match = $contact;
+ break;
+ }
+ }
+ if ($shareType === 0 || $shareType === 6) {
+ if ($contact['UID'] === $shareWith && $contact['isLocalSystemBook'] === true) {
+ $match = $contact;
+ break;
+ }
+ }
+ }
+
+ return $match ? $this->contactArrayToEntry($match) : null;
+ }
+
+ /**
+ * @param array $contact
+ * @return Entry
+ */
+ private function contactArrayToEntry(array $contact) {
+ $entry = new Entry();
+
+ if (isset($contact['id'])) {
+ $entry->setId($contact['id']);
+ }
+
+ if (isset($contact['FN'])) {
+ $entry->setFullName($contact['FN']);
+ }
+
+ $avatarPrefix = "VALUE=uri:";
+ if (isset($contact['PHOTO']) && strpos($contact['PHOTO'], $avatarPrefix) === 0) {
+ $entry->setAvatar(substr($contact['PHOTO'], strlen($avatarPrefix)));
+ }
+
+ if (isset($contact['EMAIL'])) {
+ foreach ($contact['EMAIL'] as $email) {
+ $entry->addEMailAddress($email);
+ }
+ }
+
+ // Attach all other properties to the entry too because some
+ // providers might make use of it.
+ $entry->setProperties($contact);
+
+ return $entry;
+ }
+
+}
diff --git a/lib/private/Contacts/ContactsMenu/Entry.php b/lib/private/Contacts/ContactsMenu/Entry.php
new file mode 100644
index 00000000000..9ea0511b9cc
--- /dev/null
+++ b/lib/private/Contacts/ContactsMenu/Entry.php
@@ -0,0 +1,169 @@
+<?php
+
+/**
+ * @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @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\Contacts\ContactsMenu;
+
+use OCP\Contacts\ContactsMenu\IAction;
+use OCP\Contacts\ContactsMenu\IEntry;
+
+class Entry implements IEntry {
+
+ /** @var string|int|null */
+ private $id = null;
+
+ /** @var string */
+ private $fullName = '';
+
+ /** @var string[] */
+ private $emailAddresses = [];
+
+ /** @var string|null */
+ private $avatar;
+
+ /** @var IAction[] */
+ private $actions = [];
+
+ /** @var array */
+ private $properties = [];
+
+ /**
+ * @param string $id
+ */
+ public function setId($id) {
+ $this->id = $id;
+ }
+
+ /**
+ * @param string $displayName
+ */
+ public function setFullName($displayName) {
+ $this->fullName = $displayName;
+ }
+
+ /**
+ * @return string
+ */
+ public function getFullName() {
+ return $this->fullName;
+ }
+
+ /**
+ * @param string $address
+ */
+ public function addEMailAddress($address) {
+ $this->emailAddresses[] = $address;
+ }
+
+ /**
+ * @return string
+ */
+ public function getEMailAddresses() {
+ return $this->emailAddresses;
+ }
+
+ /**
+ * @param string $avatar
+ */
+ public function setAvatar($avatar) {
+ $this->avatar = $avatar;
+ }
+
+ /**
+ * @return string
+ */
+ public function getAvatar() {
+ return $this->avatar;
+ }
+
+ /**
+ * @param IAction $action
+ */
+ public function addAction(IAction $action) {
+ $this->actions[] = $action;
+ $this->sortActions();
+ }
+
+ /**
+ * @return IAction[]
+ */
+ public function getActions() {
+ return $this->actions;
+ }
+
+ /**
+ * sort the actions by priority and name
+ */
+ private function sortActions() {
+ usort($this->actions, function(IAction $action1, IAction $action2) {
+ $prio1 = $action1->getPriority();
+ $prio2 = $action2->getPriority();
+
+ if ($prio1 === $prio2) {
+ // Ascending order for same priority
+ return strcasecmp($action1->getName(), $action2->getName());
+ }
+
+ // Descending order when priority differs
+ return $prio2 - $prio1;
+ });
+ }
+
+ /**
+ * @param array $contact key-value array containing additional properties
+ */
+ public function setProperties(array $contact) {
+ $this->properties = $contact;
+ }
+
+ /**
+ * @param string $key
+ * @return mixed
+ */
+ public function getProperty($key) {
+ if (!isset($this->properties[$key])) {
+ return null;
+ }
+ return $this->properties[$key];
+ }
+
+ /**
+ * @return array
+ */
+ public function jsonSerialize() {
+ $topAction = !empty($this->actions) ? $this->actions[0]->jsonSerialize() : null;
+ $otherActions = array_map(function(IAction $action) {
+ return $action->jsonSerialize();
+ }, array_slice($this->actions, 1));
+
+ return [
+ 'id' => $this->id,
+ 'fullName' => $this->fullName,
+ 'avatar' => $this->getAvatar(),
+ 'topAction' => $topAction,
+ 'actions' => $otherActions,
+ 'lastMessage' => '',
+ ];
+ }
+
+}
diff --git a/lib/private/Contacts/ContactsMenu/Manager.php b/lib/private/Contacts/ContactsMenu/Manager.php
new file mode 100644
index 00000000000..766b4623253
--- /dev/null
+++ b/lib/private/Contacts/ContactsMenu/Manager.php
@@ -0,0 +1,111 @@
+<?php
+
+/**
+ * @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @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\Contacts\ContactsMenu;
+
+use OCP\App\IAppManager;
+use OCP\Contacts\ContactsMenu\IEntry;
+use OCP\IUser;
+
+class Manager {
+
+ /** @var ContactsStore */
+ private $store;
+
+ /** @var ActionProviderStore */
+ private $actionProviderStore;
+
+ /** @var IAppManager */
+ private $appManager;
+
+ /**
+ * @param ContactsStore $store
+ * @param ActionProviderStore $actionProviderStore
+ * @param IAppManager $appManager
+ */
+ public function __construct(ContactsStore $store, ActionProviderStore $actionProviderStore, IAppManager $appManager) {
+ $this->store = $store;
+ $this->actionProviderStore = $actionProviderStore;
+ $this->appManager = $appManager;
+ }
+
+ /**
+ * @param IUser $user
+ * @param string $filter
+ * @return array
+ */
+ public function getEntries(IUser $user, $filter) {
+ $entries = $this->store->getContacts($user, $filter);
+
+ $sortedEntries = $this->sortEntries($entries);
+ $topEntries = array_slice($sortedEntries, 0, 25);
+ $this->processEntries($topEntries, $user);
+
+ $contactsEnabled = $this->appManager->isEnabledForUser('contacts', $user);
+ return [
+ 'contacts' => $topEntries,
+ 'contactsAppEnabled' => $contactsEnabled,
+ ];
+ }
+
+ /**
+ * @param IUser $user
+ * @param integer $shareType
+ * @param string $shareWith
+ * @return IEntry
+ */
+ public function findOne(IUser $user, $shareType, $shareWith) {
+ $entry = $this->store->findOne($user, $shareType, $shareWith);
+ if ($entry) {
+ $this->processEntries([$entry], $user);
+ }
+
+ return $entry;
+ }
+
+ /**
+ * @param IEntry[] $entries
+ * @return IEntry[]
+ */
+ private function sortEntries(array $entries) {
+ usort($entries, function(IEntry $entryA, IEntry $entryB) {
+ return strcasecmp($entryA->getFullName(), $entryB->getFullName());
+ });
+ return $entries;
+ }
+
+ /**
+ * @param IEntry[] $entries
+ * @param IUser $user
+ */
+ private function processEntries(array $entries, IUser $user) {
+ $providers = $this->actionProviderStore->getProviders($user);
+ foreach ($entries as $entry) {
+ foreach ($providers as $provider) {
+ $provider->process($entry);
+ }
+ }
+ }
+
+}
diff --git a/lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php b/lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php
new file mode 100644
index 00000000000..d5630e6420d
--- /dev/null
+++ b/lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @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\Contacts\ContactsMenu\Providers;
+
+use OCP\Contacts\ContactsMenu\IActionFactory;
+use OCP\Contacts\ContactsMenu\IEntry;
+use OCP\Contacts\ContactsMenu\IProvider;
+use OCP\IURLGenerator;
+
+class EMailProvider implements IProvider {
+
+ /** @var IActionFactory */
+ private $actionFactory;
+
+ /** @var IURLGenerator */
+ private $urlGenerator;
+
+ /**
+ * @param IActionFactory $actionFactory
+ * @param IURLGenerator $urlGenerator
+ */
+ public function __construct(IActionFactory $actionFactory, IURLGenerator $urlGenerator) {
+ $this->actionFactory = $actionFactory;
+ $this->urlGenerator = $urlGenerator;
+ }
+
+ /**
+ * @param IEntry $entry
+ */
+ public function process(IEntry $entry) {
+ $iconUrl = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'actions/mail.svg'));
+ foreach ($entry->getEMailAddresses() as $address) {
+ $action = $this->actionFactory->newEMailAction($iconUrl, $address, $address);
+ $entry->addAction($action);
+ }
+ }
+
+}
diff --git a/lib/private/DB/Connection.php b/lib/private/DB/Connection.php
index 9e116712642..6b56ae8ad5c 100644
--- a/lib/private/DB/Connection.php
+++ b/lib/private/DB/Connection.php
@@ -167,9 +167,6 @@ class Connection extends \Doctrine\DBAL\Connection implements IDBConnection {
$statement = $this->replaceTablePrefix($statement);
$statement = $this->adapter->fixupStatement($statement);
- if(\OC::$server->getSystemConfig()->getValue( 'log_query', false)) {
- \OCP\Util::writeLog('core', 'DB prepare : '.$statement, \OCP\Util::DEBUG);
- }
return parent::prepare($statement);
}
diff --git a/lib/private/Diagnostics/EventLogger.php b/lib/private/Diagnostics/EventLogger.php
index 5abaae3f1dd..846be7efc5b 100644
--- a/lib/private/Diagnostics/EventLogger.php
+++ b/lib/private/Diagnostics/EventLogger.php
@@ -4,6 +4,8 @@
*
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <robin@icewind.nl>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Piotr Mrowczynski <piotr@owncloud.com>
*
* @license AGPL-3.0
*
@@ -29,28 +31,53 @@ class EventLogger implements IEventLogger {
/**
* @var \OC\Diagnostics\Event[]
*/
- private $events = array();
+ private $events = [];
+
+ /**
+ * @var bool - Module needs to be activated by some app
+ */
+ private $activated = false;
+ /**
+ * @inheritdoc
+ */
public function start($id, $description) {
- $this->events[$id] = new Event($id, $description, microtime(true));
+ if ($this->activated){
+ $this->events[$id] = new Event($id, $description, microtime(true));
+ }
}
+ /**
+ * @inheritdoc
+ */
public function end($id) {
- if (isset($this->events[$id])) {
+ if ($this->activated && isset($this->events[$id])) {
$timing = $this->events[$id];
$timing->end(microtime(true));
}
}
+ /**
+ * @inheritdoc
+ */
public function log($id, $description, $start, $end) {
- $this->events[$id] = new Event($id, $description, $start);
- $this->events[$id]->end($end);
+ if ($this->activated) {
+ $this->events[$id] = new Event($id, $description, $start);
+ $this->events[$id]->end($end);
+ }
}
/**
- * @return \OCP\Diagnostics\IEvent[]
+ * @inheritdoc
*/
public function getEvents() {
return $this->events;
}
+
+ /**
+ * @inheritdoc
+ */
+ public function activate() {
+ $this->activated = true;
+ }
}
diff --git a/lib/private/Diagnostics/NullEventLogger.php b/lib/private/Diagnostics/NullEventLogger.php
deleted file mode 100644
index 9fe7461eb45..00000000000
--- a/lib/private/Diagnostics/NullEventLogger.php
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- *
- * @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 OC\Diagnostics;
-
-use OCP\Diagnostics\IEventLogger;
-
-/**
- * Dummy event logger that doesn't actually log anything
- */
-class NullEventLogger implements IEventLogger {
- /**
- * Mark the start of an event
- *
- * @param $id
- * @param $description
- */
- public function start($id, $description) {
- }
-
- /**
- * Mark the end of an event
- *
- * @param $id
- */
- public function end($id) {
- }
-
- public function log($id, $description, $start, $end) {
- }
-
- /**
- * @return \OCP\Diagnostics\IEvent[]
- */
- public function getEvents() {
- return array();
- }
-}
diff --git a/lib/private/Diagnostics/NullQueryLogger.php b/lib/private/Diagnostics/NullQueryLogger.php
deleted file mode 100644
index 873f556f90e..00000000000
--- a/lib/private/Diagnostics/NullQueryLogger.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- *
- * @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 OC\Diagnostics;
-
-use OCP\Diagnostics\IQueryLogger;
-
-class NullQueryLogger implements IQueryLogger {
- /**
- * @param string $sql
- * @param array $params
- * @param array $types
- */
- public function startQuery($sql, array $params = null, array $types = null) {
- }
-
- public function stopQuery() {
- }
-
- /**
- * @return \OCP\Diagnostics\IQuery[]
- */
- public function getQueries() {
- return array();
- }
-}
diff --git a/lib/private/Diagnostics/Query.php b/lib/private/Diagnostics/Query.php
index 8ac2cc0eeac..7b083ed41b7 100644
--- a/lib/private/Diagnostics/Query.php
+++ b/lib/private/Diagnostics/Query.php
@@ -67,7 +67,14 @@ class Query implements IQuery {
}
/**
- * @return int
+ * @return float
+ */
+ public function getStart() {
+ return $this->start;
+ }
+
+ /**
+ * @return float
*/
public function getDuration() {
return $this->end - $this->start;
diff --git a/lib/private/Diagnostics/QueryLogger.php b/lib/private/Diagnostics/QueryLogger.php
index 5f2a061a910..875d25e9be3 100644
--- a/lib/private/Diagnostics/QueryLogger.php
+++ b/lib/private/Diagnostics/QueryLogger.php
@@ -4,6 +4,8 @@
*
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <robin@icewind.nl>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Piotr Mrowczynski <piotr@owncloud.com>
*
* @license AGPL-3.0
*
@@ -46,12 +48,17 @@ class QueryLogger implements IQueryLogger {
/**
- * @param string $sql
- * @param array $params
- * @param array $types
+ * @var bool - Module needs to be activated by some app
+ */
+ private $activated = false;
+
+ /**
+ * @inheritdoc
*/
public function startQuery($sql, array $params = null, array $types = null) {
- $this->activeQuery = new Query($sql, $params, microtime(true), $this->getStack());
+ if ($this->activated) {
+ $this->activeQuery = new Query($sql, $params, microtime(true), $this->getStack());
+ }
}
private function getStack() {
@@ -62,8 +69,11 @@ class QueryLogger implements IQueryLogger {
return $stack;
}
+ /**
+ * @inheritdoc
+ */
public function stopQuery() {
- if ($this->activeQuery) {
+ if ($this->activated && $this->activeQuery) {
$this->activeQuery->end(microtime(true));
$this->queries[] = $this->activeQuery;
$this->activeQuery = null;
@@ -71,9 +81,16 @@ class QueryLogger implements IQueryLogger {
}
/**
- * @return Query[]
+ * @inheritdoc
*/
public function getQueries() {
return $this->queries->getData();
}
+
+ /**
+ * @inheritdoc
+ */
+ public function activate() {
+ $this->activated = true;
+ }
}
diff --git a/lib/private/Files/Utils/Scanner.php b/lib/private/Files/Utils/Scanner.php
index 02f355fd4d9..fac95462ce5 100644
--- a/lib/private/Files/Utils/Scanner.php
+++ b/lib/private/Files/Utils/Scanner.php
@@ -47,6 +47,8 @@ use OCP\ILogger;
* @package OC\Files\Utils
*/
class Scanner extends PublicEmitter {
+ const MAX_ENTRIES_TO_COMMIT = 10000;
+
/**
* @var string $user
*/
@@ -63,6 +65,20 @@ class Scanner extends PublicEmitter {
protected $logger;
/**
+ * Whether to use a DB transaction
+ *
+ * @var bool
+ */
+ protected $useTransaction;
+
+ /**
+ * Number of entries scanned to commit
+ *
+ * @var int
+ */
+ protected $entriesToCommit;
+
+ /**
* @param string $user
* @param \OCP\IDBConnection $db
* @param ILogger $logger
@@ -71,6 +87,8 @@ class Scanner extends PublicEmitter {
$this->logger = $logger;
$this->user = $user;
$this->db = $db;
+ // when DB locking is used, no DB transactions will be used
+ $this->useTransaction = !(\OC::$server->getLockingProvider() instanceof DBLockingProvider);
}
/**
@@ -200,22 +218,22 @@ class Scanner extends PublicEmitter {
$scanner = $storage->getScanner();
$scanner->setUseTransactions(false);
$this->attachListener($mount);
- $isDbLocking = \OC::$server->getLockingProvider() instanceof DBLockingProvider;
$scanner->listen('\OC\Files\Cache\Scanner', 'removeFromCache', function ($path) use ($storage) {
- $this->triggerPropagator($storage, $path);
+ $this->postProcessEntry($storage, $path);
});
$scanner->listen('\OC\Files\Cache\Scanner', 'updateCache', function ($path) use ($storage) {
- $this->triggerPropagator($storage, $path);
+ $this->postProcessEntry($storage, $path);
});
$scanner->listen('\OC\Files\Cache\Scanner', 'addToCache', function ($path) use ($storage) {
- $this->triggerPropagator($storage, $path);
+ $this->postProcessEntry($storage, $path);
});
if (!$storage->file_exists($relativePath)) {
throw new NotFoundException($dir);
}
- if (!$isDbLocking) {
+
+ if ($this->useTransaction) {
$this->db->beginTransaction();
}
try {
@@ -233,7 +251,7 @@ class Scanner extends PublicEmitter {
$this->logger->logException($e);
$this->emit('\OC\Files\Utils\Scanner', 'StorageNotAvailable', [$e]);
}
- if (!$isDbLocking) {
+ if ($this->useTransaction) {
$this->db->commit();
}
}
@@ -242,5 +260,20 @@ class Scanner extends PublicEmitter {
private function triggerPropagator(IStorage $storage, $internalPath) {
$storage->getPropagator()->propagateChange($internalPath, time());
}
+
+ private function postProcessEntry(IStorage $storage, $internalPath) {
+ $this->triggerPropagator($storage, $internalPath);
+ if ($this->useTransaction) {
+ $this->entriesToCommit++;
+ if ($this->entriesToCommit >= self::MAX_ENTRIES_TO_COMMIT) {
+ $propagator = $storage->getPropagator();
+ $this->entriesToCommit = 0;
+ $this->db->commit();
+ $propagator->commitBatch();
+ $this->db->beginTransaction();
+ $propagator->beginBatch();
+ }
+ }
+ }
}
diff --git a/lib/private/Installer.php b/lib/private/Installer.php
index 0d6030d5744..8702f264e54 100644
--- a/lib/private/Installer.php
+++ b/lib/private/Installer.php
@@ -42,6 +42,8 @@
namespace OC;
use Doctrine\DBAL\Exception\TableExistsException;
+use OC\App\AppManager;
+use OC\App\AppStore\Bundles\Bundle;
use OC\App\AppStore\Fetcher\AppFetcher;
use OC\App\CodeChecker\CodeChecker;
use OC\App\CodeChecker\EmptyCheck;
@@ -50,7 +52,9 @@ use OC\Archive\TAR;
use OC_App;
use OC_DB;
use OC_Helper;
+use OCP\App\IAppManager;
use OCP\Http\Client\IClientService;
+use OCP\IConfig;
use OCP\ILogger;
use OCP\ITempManager;
use phpseclib\File\X509;
@@ -67,21 +71,26 @@ class Installer {
private $tempManager;
/** @var ILogger */
private $logger;
+ /** @var IConfig */
+ private $config;
/**
* @param AppFetcher $appFetcher
* @param IClientService $clientService
* @param ITempManager $tempManager
* @param ILogger $logger
+ * @param IConfig $config
*/
public function __construct(AppFetcher $appFetcher,
IClientService $clientService,
ITempManager $tempManager,
- ILogger $logger) {
+ ILogger $logger,
+ IConfig $config) {
$this->appFetcher = $appFetcher;
$this->clientService = $clientService;
$this->tempManager = $tempManager;
$this->logger = $logger;
+ $this->config = $config;
}
/**
@@ -109,6 +118,7 @@ class Installer {
}
}
+ \OC_App::registerAutoloading($appId, $basedir);
\OC_App::setupBackgroundJobs($info['background-jobs']);
//run appinfo/install.php
@@ -420,6 +430,27 @@ class Installer {
}
/**
+ * Installs the app within the bundle and marks the bundle as installed
+ *
+ * @param Bundle $bundle
+ * @throws \Exception If app could not get installed
+ */
+ public function installAppBundle(Bundle $bundle) {
+ $appIds = $bundle->getAppIdentifiers();
+ foreach($appIds as $appId) {
+ if(!$this->isDownloaded($appId)) {
+ $this->downloadApp($appId);
+ }
+ $this->installApp($appId);
+ $app = new OC_App();
+ $app->enable($appId);
+ }
+ $bundles = json_decode($this->config->getAppValue('core', 'installed.bundles', json_encode([])), true);
+ $bundles[] = $bundle->getIdentifier();
+ $this->config->setAppValue('core', 'installed.bundles', json_encode($bundles));
+ }
+
+ /**
* Installs shipped apps
*
* This function installs all apps found in the 'apps' directory that should be enabled by default;
diff --git a/lib/private/Mail/EMailTemplate.php b/lib/private/Mail/EMailTemplate.php
index 4e00eb153a3..3442e8e9430 100644
--- a/lib/private/Mail/EMailTemplate.php
+++ b/lib/private/Mail/EMailTemplate.php
@@ -54,6 +54,8 @@ class EMailTemplate implements IEMailTemplate {
protected $headerAdded = false;
/** @var bool indicated if the body is already opened */
protected $bodyOpened = false;
+ /** @var bool indicated if there is a list open in the body */
+ protected $bodyListOpened = false;
/** @var bool indicated if the footer is added */
protected $footerAdded = false;
@@ -174,6 +176,34 @@ EOF;
</table>
EOF;
+ protected $listBegin = <<<EOF
+<table class="row description" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%%">
+ <tbody>
+ <tr style="padding:0;text-align:left;vertical-align:top">
+ <th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0 auto;padding:0;padding-bottom:30px;padding-left:30px;padding-right:30px;text-align:left;width:550px">
+ <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
+EOF;
+
+ protected $listItem = <<<EOF
+ <tr style="padding:0;text-align:left;vertical-align:top">
+ <td 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;width:15px;">
+ <p class="text-left" style="Margin:0;Margin-bottom:10px;color:#777;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;padding-left:10px;text-align:left">%s</p>
+ </td>
+ <td 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">
+ <p class="text-left" style="Margin:0;Margin-bottom:10px;color:#555;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;padding-left:10px;text-align:left">%s</p>
+ </td>
+ <td class="expander" 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!important;text-align:left;visibility:hidden;width:0"></td>
+ </tr>
+EOF;
+
+ protected $listEnd = <<<EOF
+ </table>
+ </th>
+ </tr>
+ </tbody>
+</table>
+EOF;
+
protected $buttonGroup = <<<EOF
<table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
<tbody>
@@ -353,6 +383,18 @@ EOF;
}
/**
+ * Open the HTML body when it is not already
+ */
+ protected function ensureBodyIsOpened() {
+ if ($this->bodyOpened) {
+ return;
+ }
+
+ $this->htmlBody .= $this->bodyBegin;
+ $this->bodyOpened = true;
+ }
+
+ /**
* Adds a paragraph to the body of the email
*
* @param string $text
@@ -367,10 +409,7 @@ EOF;
$plainText = $text;
}
- if (!$this->bodyOpened) {
- $this->htmlBody .= $this->bodyBegin;
- $this->bodyOpened = true;
- }
+ $this->ensureBodyIsOpened();
$this->htmlBody .= vsprintf($this->bodyText, [htmlspecialchars($text)]);
if ($plainText !== false) {
@@ -379,6 +418,66 @@ EOF;
}
/**
+ * Adds a list item to the body of the email
+ *
+ * @param string $text
+ * @param string $metaInfo
+ * @param string $icon Absolute path, must be 16*16 pixels
+ * @param string $plainText Text that is used in the plain text email
+ * if empty the $text is used, if false none will be used
+ * @param string $plainMetaInfo Meta info that is used in the plain text email
+ * if empty the $metaInfo is used, if false none will be used
+ * @since 12.0.0
+ */
+ public function addBodyListItem($text, $metaInfo = '', $icon = '', $plainText = '', $plainMetaInfo = '') {
+ $this->ensureBodyListOpened();
+
+ if ($plainText === '') {
+ $plainText = $text;
+ }
+ if ($plainMetaInfo === '') {
+ $plainMetaInfo = $metaInfo;
+ }
+
+ $htmlText = htmlspecialchars($text);
+ if ($metaInfo) {
+ $htmlText = '<em style="color:#777;">' . htmlspecialchars($metaInfo) . '</em><br>' . $htmlText;
+ }
+ if ($icon !== '') {
+ $icon = '<img src="' . htmlspecialchars($icon) . '" alt="&bull;">';
+ } else {
+ $icon = '&bull;';
+ }
+ $this->htmlBody .= vsprintf($this->listItem, [$icon, $htmlText]);
+ if ($plainText !== false) {
+ $this->plainBody .= ' * ' . $plainText;
+ if ($plainMetaInfo !== false) {
+ $this->plainBody .= ' (' . $plainMetaInfo . ')';
+ }
+ $this->plainBody .= PHP_EOL;
+ }
+ }
+
+ protected function ensureBodyListOpened() {
+ if ($this->bodyListOpened) {
+ return;
+ }
+
+ $this->ensureBodyIsOpened();
+ $this->bodyListOpened = true;
+ $this->htmlBody .= $this->listBegin;
+ }
+
+ protected function ensureBodyListClosed() {
+ if (!$this->bodyListOpened) {
+ return;
+ }
+
+ $this->bodyListOpened = false;
+ $this->htmlBody .= $this->listEnd;
+ }
+
+ /**
* Adds a button group of two buttons to the body of the email
*
* @param string $textLeft Text of left button
@@ -405,10 +504,8 @@ EOF;
$plainTextRight = $textRight;
}
- if (!$this->bodyOpened) {
- $this->htmlBody .= $this->bodyBegin;
- $this->bodyOpened = true;
- }
+ $this->ensureBodyIsOpened();
+ $this->ensureBodyListClosed();
$color = $this->themingDefaults->getColorPrimary();
@@ -433,10 +530,8 @@ EOF;
return;
}
- if (!$this->bodyOpened) {
- $this->htmlBody .= $this->bodyBegin;
- $this->bodyOpened = true;
- }
+ $this->ensureBodyIsOpened();
+ $this->ensureBodyListClosed();
if ($plainText === '') {
$plainText = $text;
@@ -454,6 +549,20 @@ EOF;
}
/**
+ * Close the HTML body when it is open
+ */
+ protected function ensureBodyIsClosed() {
+ if (!$this->bodyOpened) {
+ return;
+ }
+
+ $this->ensureBodyListClosed();
+
+ $this->htmlBody .= $this->bodyEnd;
+ $this->bodyOpened = false;
+ }
+
+ /**
* Adds a logo and a text to the footer. <br> in the text will be replaced by new lines in the plain text email
*
* @param string $text If the text is empty the default "Name - Slogan<br>This is an automatically sent email" will be used
@@ -468,10 +577,7 @@ EOF;
}
$this->footerAdded = true;
- if ($this->bodyOpened) {
- $this->htmlBody .= $this->bodyEnd;
- $this->bodyOpened = false;
- }
+ $this->ensureBodyIsClosed();
$this->htmlBody .= vsprintf($this->footer, [$text]);
$this->htmlBody .= $this->tail;
@@ -487,9 +593,7 @@ EOF;
public function renderHtml() {
if (!$this->footerAdded) {
$this->footerAdded = true;
- if ($this->bodyOpened) {
- $this->htmlBody .= $this->bodyEnd;
- }
+ $this->ensureBodyIsClosed();
$this->htmlBody .= $this->tail;
}
return $this->htmlBody;
@@ -503,9 +607,7 @@ EOF;
public function renderText() {
if (!$this->footerAdded) {
$this->footerAdded = true;
- if ($this->bodyOpened) {
- $this->htmlBody .= $this->bodyEnd;
- }
+ $this->ensureBodyIsClosed();
$this->htmlBody .= $this->tail;
}
return $this->plainBody;
diff --git a/lib/private/Memcache/Redis.php b/lib/private/Memcache/Redis.php
index c3184e45856..d423b134f95 100644
--- a/lib/private/Memcache/Redis.php
+++ b/lib/private/Memcache/Redis.php
@@ -49,8 +49,8 @@ class Redis extends Cache implements IMemcacheTTL {
}
public function get($key) {
- $result = self::$cache->get($this->getNamespace() . $key);
- if ($result === false && !self::$cache->exists($this->getNamespace() . $key)) {
+ $result = self::$cache->get($this->getNameSpace() . $key);
+ if ($result === false && !self::$cache->exists($this->getNameSpace() . $key)) {
return null;
} else {
return json_decode($result, true);
@@ -59,18 +59,18 @@ class Redis extends Cache implements IMemcacheTTL {
public function set($key, $value, $ttl = 0) {
if ($ttl > 0) {
- return self::$cache->setex($this->getNamespace() . $key, $ttl, json_encode($value));
+ return self::$cache->setex($this->getNameSpace() . $key, $ttl, json_encode($value));
} else {
- return self::$cache->set($this->getNamespace() . $key, json_encode($value));
+ return self::$cache->set($this->getNameSpace() . $key, json_encode($value));
}
}
public function hasKey($key) {
- return self::$cache->exists($this->getNamespace() . $key);
+ return self::$cache->exists($this->getNameSpace() . $key);
}
public function remove($key) {
- if (self::$cache->delete($this->getNamespace() . $key)) {
+ if (self::$cache->delete($this->getNameSpace() . $key)) {
return true;
} else {
return false;
@@ -78,7 +78,7 @@ class Redis extends Cache implements IMemcacheTTL {
}
public function clear($prefix = '') {
- $prefix = $this->getNamespace() . $prefix . '*';
+ $prefix = $this->getNameSpace() . $prefix . '*';
$it = null;
self::$cache->setOption(\Redis::OPT_SCAN, \Redis::SCAN_RETRY);
while ($keys = self::$cache->scan($it, $prefix)) {
@@ -111,7 +111,7 @@ class Redis extends Cache implements IMemcacheTTL {
* @return int | bool
*/
public function inc($key, $step = 1) {
- return self::$cache->incrBy($this->getNamespace() . $key, $step);
+ return self::$cache->incrBy($this->getNameSpace() . $key, $step);
}
/**
@@ -125,7 +125,7 @@ class Redis extends Cache implements IMemcacheTTL {
if (!$this->hasKey($key)) {
return false;
}
- return self::$cache->decrBy($this->getNamespace() . $key, $step);
+ return self::$cache->decrBy($this->getNameSpace() . $key, $step);
}
/**
@@ -140,10 +140,10 @@ class Redis extends Cache implements IMemcacheTTL {
if (!is_int($new)) {
$new = json_encode($new);
}
- self::$cache->watch($this->getNamespace() . $key);
+ self::$cache->watch($this->getNameSpace() . $key);
if ($this->get($key) === $old) {
$result = self::$cache->multi()
- ->set($this->getNamespace() . $key, $new)
+ ->set($this->getNameSpace() . $key, $new)
->exec();
return ($result === false) ? false : true;
}
@@ -159,10 +159,10 @@ class Redis extends Cache implements IMemcacheTTL {
* @return bool
*/
public function cad($key, $old) {
- self::$cache->watch($this->getNamespace() . $key);
+ self::$cache->watch($this->getNameSpace() . $key);
if ($this->get($key) === $old) {
$result = self::$cache->multi()
- ->del($this->getNamespace() . $key)
+ ->del($this->getNameSpace() . $key)
->exec();
return ($result === false) ? false : true;
}
@@ -171,7 +171,7 @@ class Redis extends Cache implements IMemcacheTTL {
}
public function setTTL($key, $ttl) {
- self::$cache->expire($this->getNamespace() . $key, $ttl);
+ self::$cache->expire($this->getNameSpace() . $key, $ttl);
}
static public function isAvailable() {
diff --git a/lib/private/RedisFactory.php b/lib/private/RedisFactory.php
index 3ba637c4142..701e15325c3 100644
--- a/lib/private/RedisFactory.php
+++ b/lib/private/RedisFactory.php
@@ -39,32 +39,54 @@ class RedisFactory {
}
private function create() {
- $this->instance = new \Redis();
- // TODO allow configuring a RedisArray, see https://github.com/nicolasff/phpredis/blob/master/arrays.markdown#redis-arrays
- $config = $this->config->getValue('redis', array());
- if (isset($config['host'])) {
- $host = $config['host'];
- } else {
- $host = '127.0.0.1';
- }
- if (isset($config['port'])) {
- $port = $config['port'];
- } else {
- $port = 6379;
- }
- if (isset($config['timeout'])) {
- $timeout = $config['timeout'];
+ if ($config = $this->config->getValue('redis.cluster', [])) {
+ if (!class_exists('RedisCluster')) {
+ throw new \Exception('Redis Cluster support is not available');
+ }
+ // cluster config
+ if (isset($config['timeout'])) {
+ $timeout = $config['timeout'];
+ } else {
+ $timeout = null;
+ }
+ if (isset($config['read_timeout'])) {
+ $readTimeout = $config['read_timeout'];
+ } else {
+ $readTimeout = null;
+ }
+ $this->instance = new \RedisCluster(null, $config['seeds'], $timeout, $readTimeout);
+
+ if (isset($config['failover_mode'])) {
+ $this->instance->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, $config['failover_mode']);
+ }
} else {
- $timeout = 0.0; // unlimited
- }
- $this->instance->connect($host, $port, $timeout);
- if (isset($config['password']) && $config['password'] !== '') {
- $this->instance->auth($config['password']);
- }
+ $this->instance = new \Redis();
+ $config = $this->config->getValue('redis', []);
+ if (isset($config['host'])) {
+ $host = $config['host'];
+ } else {
+ $host = '127.0.0.1';
+ }
+ if (isset($config['port'])) {
+ $port = $config['port'];
+ } else {
+ $port = 6379;
+ }
+ if (isset($config['timeout'])) {
+ $timeout = $config['timeout'];
+ } else {
+ $timeout = 0.0; // unlimited
+ }
+
+ $this->instance->connect($host, $port, $timeout);
+ if (isset($config['password']) && $config['password'] !== '') {
+ $this->instance->auth($config['password']);
+ }
- if (isset($config['dbindex'])) {
- $this->instance->select($config['dbindex']);
+ if (isset($config['dbindex'])) {
+ $this->instance->select($config['dbindex']);
+ }
}
}
diff --git a/lib/private/Repair.php b/lib/private/Repair.php
index e808774ec93..65e0342905a 100644
--- a/lib/private/Repair.php
+++ b/lib/private/Repair.php
@@ -30,12 +30,14 @@
namespace OC;
+use OC\App\AppStore\Bundles\BundleFetcher;
use OC\Repair\CleanTags;
use OC\Repair\Collation;
use OC\Repair\MoveUpdaterStepFile;
use OC\Repair\NC11\CleanPreviews;
use OC\Repair\NC11\FixMountStorages;
use OC\Repair\NC11\MoveAvatars;
+use OC\Repair\NC12\InstallCoreBundle;
use OC\Repair\NC12\UpdateLanguageCodes;
use OC\Repair\OldGroupMembershipShares;
use OC\Repair\RemoveRootShares;
@@ -136,6 +138,11 @@ class Repair implements IOutput{
),
new FixMountStorages(\OC::$server->getDatabaseConnection()),
new UpdateLanguageCodes(\OC::$server->getDatabaseConnection(), \OC::$server->getConfig()),
+ new InstallCoreBundle(
+ \OC::$server->query(BundleFetcher::class),
+ \OC::$server->getConfig(),
+ \OC::$server->query(Installer::class)
+ )
];
}
diff --git a/lib/private/Repair/NC12/InstallCoreBundle.php b/lib/private/Repair/NC12/InstallCoreBundle.php
new file mode 100644
index 00000000000..38583b09a89
--- /dev/null
+++ b/lib/private/Repair/NC12/InstallCoreBundle.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
+ *
+ * @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\NC12;
+
+use OC\App\AppStore\Bundles\BundleFetcher;
+use OC\Installer;
+use OCP\IConfig;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+
+class InstallCoreBundle implements IRepairStep {
+ /** @var BundleFetcher */
+ private $bundleFetcher;
+ /** @var IConfig */
+ private $config;
+ /** @var Installer */
+ private $installer;
+
+ /**
+ * @param BundleFetcher $bundleFetcher
+ * @param IConfig $config
+ * @param Installer $installer
+ */
+ public function __construct(BundleFetcher $bundleFetcher,
+ IConfig $config,
+ Installer $installer) {
+ $this->bundleFetcher = $bundleFetcher;
+ $this->config = $config;
+ $this->installer = $installer;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName() {
+ return 'Install new core bundle components';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function run(IOutput $output) {
+ $versionFromBeforeUpdate = $this->config->getSystemValue('version', '0.0.0');
+
+ if (version_compare($versionFromBeforeUpdate, '12.0.0.14', '>')) {
+ return;
+ }
+
+ $defaultBundle = $this->bundleFetcher->getDefaultInstallationBundle();
+ foreach($defaultBundle as $bundle) {
+ try {
+ $this->installer->installAppBundle($bundle);
+ $output->info('Successfully installed core app bundle.');
+ } catch (\Exception $e) {
+ $output->warning('Could not install core app bundle: ' . $e->getMessage());
+ }
+ }
+ }
+}
diff --git a/lib/private/Repair/RepairMimeTypes.php b/lib/private/Repair/RepairMimeTypes.php
index 534b5ce2c28..d60b507e932 100644
--- a/lib/private/Repair/RepairMimeTypes.php
+++ b/lib/private/Repair/RepairMimeTypes.php
@@ -110,6 +110,15 @@ class RepairMimeTypes implements IRepairStep {
}
}
+ private function introduceImageTypes() {
+ $updatedMimetypes = array(
+ 'jp2' => 'image/jp2',
+ 'webp' => 'image/webp',
+ );
+
+ $this->updateMimetypes($updatedMimetypes);
+ }
+
private function introduceWindowsProgramTypes() {
$updatedMimetypes = array(
'htaccess' => 'text/plain',
@@ -130,6 +139,10 @@ class RepairMimeTypes implements IRepairStep {
// NOTE TO DEVELOPERS: when adding new mime types, please make sure to
// add a version comparison to avoid doing it every time
+ if (version_compare($ocVersionFromBeforeUpdate, '12.0.0.14', '<') && $this->introduceImageTypes()) {
+ $out->info('Fixed image mime types');
+ }
+
if (version_compare($ocVersionFromBeforeUpdate, '12.0.0.13', '<') && $this->introduceWindowsProgramTypes()) {
$out->info('Fixed windows program mime types');
}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index f40a59ad334..25c0b5d9cc9 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -43,6 +43,7 @@ namespace OC;
use bantu\IniGetWrapper\IniGetWrapper;
use OC\App\AppManager;
+use OC\App\AppStore\Bundles\BundleFetcher;
use OC\App\AppStore\Fetcher\AppFetcher;
use OC\App\AppStore\Fetcher\CategoryFetcher;
use OC\AppFramework\Http\Request;
@@ -50,6 +51,7 @@ use OC\AppFramework\Utility\SimpleContainer;
use OC\AppFramework\Utility\TimeFactory;
use OC\Authentication\LoginCredentials\Store;
use OC\Command\AsyncBus;
+use OC\Contacts\ContactsMenu\ActionFactory;
use OC\Diagnostics\EventLogger;
use OC\Diagnostics\NullEventLogger;
use OC\Diagnostics\NullQueryLogger;
@@ -108,6 +110,8 @@ use OCP\IDBConnection;
use OCP\IL10N;
use OCP\IServerContainer;
use OCP\ITempManager;
+use OCP\Contacts\ContactsMenu\IActionFactory;
+use OCP\IURLGenerator;
use OCP\RichObjectStrings\IValidator;
use OCP\Security\IContentSecurityPolicyManager;
use OCP\Share\IShareHelper;
@@ -133,9 +137,17 @@ class Server extends ServerContainer implements IServerContainer {
parent::__construct();
$this->webRoot = $webRoot;
+ $this->registerService(\OCP\IServerContainer::class, function(IServerContainer $c) {
+ return $c;
+ });
+
$this->registerAlias(\OCP\Contacts\IManager::class, \OC\ContactsManager::class);
$this->registerAlias('ContactsManager', \OCP\Contacts\IManager::class);
+ $this->registerAlias(IActionFactory::class, ActionFactory::class);
+
+
+
$this->registerService(\OCP\IPreview::class, function (Server $c) {
return new PreviewManager(
$c->getConfig(),
@@ -591,22 +603,23 @@ class Server extends ServerContainer implements IServerContainer {
);
});
$this->registerAlias('HttpClientService', \OCP\Http\Client\IClientService::class);
-
$this->registerService(\OCP\Diagnostics\IEventLogger::class, function (Server $c) {
+ $eventLogger = new EventLogger();
if ($c->getSystemConfig()->getValue('debug', false)) {
- return new EventLogger();
- } else {
- return new NullEventLogger();
+ // In debug mode, module is being activated by default
+ $eventLogger->activate();
}
+ return $eventLogger;
});
$this->registerAlias('EventLogger', \OCP\Diagnostics\IEventLogger::class);
$this->registerService(\OCP\Diagnostics\IQueryLogger::class, function (Server $c) {
+ $queryLogger = new QueryLogger();
if ($c->getSystemConfig()->getValue('debug', false)) {
- return new QueryLogger();
- } else {
- return new NullQueryLogger();
+ // In debug mode, module is being activated by default
+ $queryLogger->activate();
}
+ return $queryLogger;
});
$this->registerAlias('QueryLogger', \OCP\Diagnostics\IQueryLogger::class);
@@ -805,7 +818,12 @@ class Server extends ServerContainer implements IServerContainer {
);
});
$this->registerAlias('MimeTypeLoader', \OCP\Files\IMimeTypeLoader::class);
-
+ $this->registerService(BundleFetcher::class, function () {
+ return new BundleFetcher($this->getL10N('lib'));
+ });
+ $this->registerService(AppFetcher::class, function() {
+ return $this->getAppFetcher();
+ });
$this->registerService(\OCP\Notification\IManager::class, function (Server $c) {
return new Manager(
$c->query(IValidator::class)
diff --git a/lib/private/Session/CryptoSessionData.php b/lib/private/Session/CryptoSessionData.php
index 4e0b852cb35..31fcea4a7a6 100644
--- a/lib/private/Session/CryptoSessionData.php
+++ b/lib/private/Session/CryptoSessionData.php
@@ -64,7 +64,12 @@ class CryptoSessionData implements \ArrayAccess, ISession {
* Close session if class gets destructed
*/
public function __destruct() {
- $this->close();
+ try {
+ $this->close();
+ } catch (SessionNotAvailableException $e){
+ // This exception can occur if session is already closed
+ // So it is safe to ignore it and let the garbage collector to proceed
+ }
}
protected function initializeSession() {
diff --git a/lib/private/Session/Internal.php b/lib/private/Session/Internal.php
index 22878154c05..72af5727a54 100644
--- a/lib/private/Session/Internal.php
+++ b/lib/private/Session/Internal.php
@@ -151,7 +151,7 @@ class Internal extends Session {
*/
private function validateSession() {
if ($this->sessionClosed) {
- throw new \Exception('Session has been closed - no further changes to the session are allowed');
+ throw new SessionNotAvailableException('Session has been closed - no further changes to the session are allowed');
}
}
}
diff --git a/lib/private/Setup.php b/lib/private/Setup.php
index e2806efad48..b1cf289d9aa 100644
--- a/lib/private/Setup.php
+++ b/lib/private/Setup.php
@@ -41,6 +41,7 @@ namespace OC;
use bantu\IniGetWrapper\IniGetWrapper;
use Exception;
+use OC\App\AppStore\Bundles\BundleFetcher;
use OCP\Defaults;
use OCP\IL10N;
use OCP\ILogger;
@@ -63,11 +64,12 @@ class Setup {
/**
* @param SystemConfig $config
* @param IniGetWrapper $iniWrapper
+ * @param IL10N $l10n
* @param Defaults $defaults
* @param ILogger $logger
* @param ISecureRandom $random
*/
- function __construct(SystemConfig $config,
+ public function __construct(SystemConfig $config,
IniGetWrapper $iniWrapper,
IL10N $l10n,
Defaults $defaults,
@@ -364,8 +366,22 @@ class Setup {
$group =\OC::$server->getGroupManager()->createGroup('admin');
$group->addUser($user);
- //guess what this does
+ // Install shipped apps and specified app bundles
Installer::installShippedApps();
+ $installer = new Installer(
+ \OC::$server->getAppFetcher(),
+ \OC::$server->getHTTPClientService(),
+ \OC::$server->getTempManager(),
+ \OC::$server->getLogger(),
+ \OC::$server->getConfig()
+ );
+ $bundleFetcher = new BundleFetcher(\OC::$server->getL10N('lib'));
+ $defaultInstallationBundles = $bundleFetcher->getDefaultInstallationBundle();
+ foreach($defaultInstallationBundles as $bundle) {
+ try {
+ $installer->installAppBundle($bundle);
+ } catch (Exception $e) {}
+ }
// create empty file in data dir, so we can later find
// out that this is indeed an ownCloud data directory
diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php
index d7249a44293..f7bb23cd3de 100644
--- a/lib/private/TemplateLayout.php
+++ b/lib/private/TemplateLayout.php
@@ -79,8 +79,6 @@ class TemplateLayout extends \OC_Template {
$this->assign( 'appid', $appId );
$navigation = \OC_App::getNavigation();
$this->assign( 'navigation', $navigation);
- $navigation = \OC_App::getHeaderNavigation();
- $this->assign( 'headernavigation', $navigation);
$settingsNavigation = \OC_App::getSettingsNavigation();
$this->assign( 'settingsnavigation', $settingsNavigation);
foreach($navigation as $entry) {
diff --git a/lib/private/Updater.php b/lib/private/Updater.php
index 4427e4c48dc..c080ee0eb43 100644
--- a/lib/private/Updater.php
+++ b/lib/private/Updater.php
@@ -243,11 +243,11 @@ class Updater extends BasicEmitter {
}
// update all shipped apps
- $disabledApps = $this->checkAppsRequirements();
+ $this->checkAppsRequirements();
$this->doAppUpgrade();
// upgrade appstore apps
- $this->upgradeAppStoreApps($disabledApps);
+ $this->upgradeAppStoreApps(\OC::$server->getAppManager()->getInstalledApps());
// install new shipped apps on upgrade
OC_App::loadApps('authentication');
@@ -441,7 +441,8 @@ class Updater extends BasicEmitter {
\OC::$server->getAppFetcher(),
\OC::$server->getHTTPClientService(),
\OC::$server->getTempManager(),
- $this->log
+ $this->log,
+ \OC::$server->getConfig()
);
if (Installer::isUpdateAvailable($app, \OC::$server->getAppFetcher())) {
$this->emit('\OC\Updater', 'upgradeAppStoreApp', [$app]);
diff --git a/lib/private/User/User.php b/lib/private/User/User.php
index a3be0c24bb9..f55807bc769 100644
--- a/lib/private/User/User.php
+++ b/lib/private/User/User.php
@@ -342,9 +342,13 @@ class User implements IUser {
* @param bool $enabled
*/
public function setEnabled($enabled) {
+ $oldStatus = $this->isEnabled();
$this->enabled = $enabled;
$enabled = ($enabled) ? 'true' : 'false';
- $this->config->setUserValue($this->uid, 'core', 'enabled', $enabled);
+ if ($oldStatus !== $this->enabled) {
+ $this->triggerChange('enabled', $enabled);
+ $this->config->setUserValue($this->uid, 'core', 'enabled', $enabled);
+ }
}
/**
diff --git a/lib/private/legacy/api.php b/lib/private/legacy/api.php
index 17ee9c5d468..894aee28560 100644
--- a/lib/private/legacy/api.php
+++ b/lib/private/legacy/api.php
@@ -332,25 +332,20 @@ class OC_API {
$userSession = \OC::$server->getUserSession();
$request = \OC::$server->getRequest();
try {
- $loginSuccess = $userSession->tryTokenLogin($request);
- if (!$loginSuccess) {
- $loginSuccess = $userSession->tryBasicAuthLogin($request, \OC::$server->getBruteForceThrottler());
+ if ($userSession->tryTokenLogin($request)
+ || $userSession->tryBasicAuthLogin($request, \OC::$server->getBruteForceThrottler())) {
+ self::$logoutRequired = true;
+ } else {
+ return false;
}
- } catch (\OC\User\LoginException $e) {
- return false;
- }
-
- if ($loginSuccess === true) {
- self::$logoutRequired = true;
-
// initialize the user's filesystem
\OC_Util::setupFS(\OC_User::getUser());
self::$isLoggedIn = true;
return \OC_User::getUser();
+ } catch (\OC\User\LoginException $e) {
+ return false;
}
-
- return false;
}
/**
diff --git a/lib/private/legacy/app.php b/lib/private/legacy/app.php
index e6b811aa845..111da7d0d40 100644
--- a/lib/private/legacy/app.php
+++ b/lib/private/legacy/app.php
@@ -365,7 +365,8 @@ class OC_App {
\OC::$server->getAppFetcher(),
\OC::$server->getHTTPClientService(),
\OC::$server->getTempManager(),
- \OC::$server->getLogger()
+ \OC::$server->getLogger(),
+ \OC::$server->getConfig()
);
$isDownloaded = $installer->isDownloaded($appId);
@@ -427,7 +428,8 @@ class OC_App {
\OC::$server->getAppFetcher(),
\OC::$server->getHTTPClientService(),
\OC::$server->getTempManager(),
- \OC::$server->getLogger()
+ \OC::$server->getLogger(),
+ \OC::$server->getConfig()
);
return $installer->removeApp($app);
}
@@ -468,69 +470,16 @@ class OC_App {
}
});
- $activeAppIndex = -1;
$activeApp = OC::$server->getNavigationManager()->getActiveEntry();
foreach ($list as $index => &$navEntry) {
- $navEntry['showInHeader'] = true;
if ($navEntry['id'] == $activeApp) {
$navEntry['active'] = true;
- $activeAppIndex = $index;
} else {
$navEntry['active'] = false;
}
}
unset($navEntry);
- if (count($list) <= 8) {
- return $list;
- }
-
- $headerIconCount = 7;
- if($activeAppIndex > ($headerIconCount-1)) {
- $active = $list[$activeAppIndex];
- $lastInHeader = $list[$headerIconCount-1];
- $list[$headerIconCount-1] = $active;
- $list[$activeAppIndex] = $lastInHeader;
- }
-
- foreach ($list as $index => &$navEntry) {
- if($index >= $headerIconCount) {
- $navEntry['showInHeader'] = false;
- }
- }
-
- return $list;
- }
-
- public static function proceedAppNavigation($entries) {
- $activeAppIndex = -1;
- $list = self::proceedNavigation($entries);
-
- $activeApp = OC::$server->getNavigationManager()->getActiveEntry();
- foreach ($list as $index => &$navEntry) {
- if ($navEntry['id'] == $activeApp) {
- $navEntry['active'] = true;
- $activeAppIndex = $index;
- } else {
- $navEntry['active'] = false;
- }
- }
-
-
- if (count($list) <= 8) {
- return $list;
- }
-
- $headerIconCount = 7;
- // move active item to last position
- if($activeAppIndex > ($headerIconCount-1)) {
- $active = $list[$activeAppIndex];
- $lastInHeader = $list[$headerIconCount-1];
- $list[$headerIconCount-1] = $active;
- $list[$activeAppIndex] = $lastInHeader;
- }
- $list = array_slice($list, 0, $headerIconCount);
-
return $list;
}
@@ -723,21 +672,6 @@ class OC_App {
}
/**
- * Returns the navigation inside the header bar
- *
- * @return array
- *
- * This function returns an array containing all entries added. The
- * entries are sorted by the key 'order' ascending. Additional to the keys
- * given for each app the following keys exist:
- * - active: boolean, signals if the user is on this navigation entry
- */
- public static function getHeaderNavigation() {
- $entries = OC::$server->getNavigationManager()->getAll();
- return self::proceedAppNavigation($entries);
- }
-
- /**
* Returns the Settings Navigation
*
* @return string[]
diff --git a/lib/private/legacy/db/statementwrapper.php b/lib/private/legacy/db/statementwrapper.php
index dedaf2d8cef..53f7b484d04 100644
--- a/lib/private/legacy/db/statementwrapper.php
+++ b/lib/private/legacy/db/statementwrapper.php
@@ -64,14 +64,7 @@ class OC_DB_StatementWrapper {
* @param array $input
* @return \OC_DB_StatementWrapper|int
*/
- public function execute($input=array()) {
- if(\OC::$server->getSystemConfig()->getValue( "log_query", false)) {
- $backTrace = debug_backtrace();
- $class = $backTrace[1]['class'] . ':' . $backTrace[1]['function'];
- $file = substr($backTrace[0]['file'], strlen(\OC::$SERVERROOT)) . ':' . $backTrace[0]['line'];
- $params_str = str_replace("\n", " ", var_export($input, true));
- \OCP\Util::writeLog('core', "DB execute with arguments : $params_str in $class; $file", \OCP\Util::DEBUG);
- }
+ public function execute($input= []) {
$this->lastArguments = $input;
if (count($input) > 0) {
$result = $this->statement->execute($input);
diff --git a/lib/private/legacy/template.php b/lib/private/legacy/template.php
index 19b5e418110..9a919ff12f2 100644
--- a/lib/private/legacy/template.php
+++ b/lib/private/legacy/template.php
@@ -118,6 +118,7 @@ class OC_Template extends \OC\Template\Base {
OC_Util::addScript('jquery-ui-fixes');
OC_Util::addScript('files/fileinfo');
OC_Util::addScript('files/client');
+ OC_Util::addScript('contactsmenu');
if (\OC::$server->getConfig()->getSystemValue('debug')) {
// Add the stuff we need always
diff --git a/lib/private/legacy/user.php b/lib/private/legacy/user.php
index 621ea3535b1..7e7cbab3bce 100644
--- a/lib/private/legacy/user.php
+++ b/lib/private/legacy/user.php
@@ -199,9 +199,10 @@ class OC_User {
if($setUidAsDisplayName) {
self::setDisplayName($uid);
}
- self::getUserSession()->setLoginName($uid);
+ $userSession = self::getUserSession();
+ $userSession->setLoginName($uid);
$request = OC::$server->getRequest();
- self::getUserSession()->createSessionToken($request, $uid, $uid);
+ $userSession->createSessionToken($request, $uid, $uid);
// setup the filesystem
OC_Util::setupFS($uid);
// first call the post_login hooks, the login-process needs to be
diff --git a/lib/private/legacy/util.php b/lib/private/legacy/util.php
index 9516a67af48..d49599cb8a1 100644
--- a/lib/private/legacy/util.php
+++ b/lib/private/legacy/util.php
@@ -1388,6 +1388,12 @@ class OC_Util {
if (\OC\Files\Filesystem::isIgnoredDir($trimmed)) {
return false;
}
+
+ // detect part files
+ if (preg_match('/' . \OCP\Files\FileInfo::BLACKLIST_FILES_REGEX . '/', $trimmed) !== 0) {
+ return false;
+ }
+
foreach (str_split($trimmed) as $char) {
if (strpos(\OCP\Constants::FILENAME_INVALID_CHARS, $char) !== false) {
return false;
diff --git a/lib/public/Contacts/ContactsMenu/IAction.php b/lib/public/Contacts/ContactsMenu/IAction.php
new file mode 100644
index 00000000000..44ad1af5ae8
--- /dev/null
+++ b/lib/public/Contacts/ContactsMenu/IAction.php
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @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 OCP\Contacts\ContactsMenu;
+
+use JsonSerializable;
+
+/**
+ * Apps should use the IActionFactory to create new action objects
+ *
+ * @since 12.0
+ */
+interface IAction extends JsonSerializable {
+
+ /**
+ * @param string $icon absolute URI to an icon
+ * @since 12.0
+ */
+ public function setIcon($icon);
+
+ /**
+ * @return string localized action name, e.g. 'Call'
+ * @since 12.0
+ */
+ public function getName();
+
+ /**
+ * @param string $name localized action name, e.g. 'Call'
+ * @since 12.0
+ */
+ public function setName($name);
+
+ /**
+ * @param int $priority priorize actions, high order ones are shown on top
+ * @since 12.0
+ */
+ public function setPriority($priority);
+
+ /**
+ * @return int priority to priorize actions, high order ones are shown on top
+ * @since 12.0
+ */
+ public function getPriority();
+}
diff --git a/lib/public/Contacts/ContactsMenu/IActionFactory.php b/lib/public/Contacts/ContactsMenu/IActionFactory.php
new file mode 100644
index 00000000000..8778a729a56
--- /dev/null
+++ b/lib/public/Contacts/ContactsMenu/IActionFactory.php
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ * @author 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @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 OCP\Contacts\ContactsMenu;
+
+/**
+ * @since 12.0
+ */
+interface IActionFactory {
+
+ /**
+ * Construct and return a new link action for the contacts menu
+ *
+ * @since 12.0
+ *
+ * @param string $icon full path to the action's icon
+ * @param string $name localized name of the action
+ * @param string $href target URL
+ * @return ILinkAction
+ */
+ public function newLinkAction($icon, $name, $href);
+
+ /**
+ * Construct and return a new email action for the contacts menu
+ *
+ * @since 12.0
+ *
+ * @param string $icon full path to the action's icon
+ * @param string $name localized name of the action
+ * @param string $email target e-mail address
+ * @return ILinkAction
+ */
+ public function newEMailAction($icon, $name, $email);
+}
diff --git a/lib/public/Contacts/ContactsMenu/IEntry.php b/lib/public/Contacts/ContactsMenu/IEntry.php
new file mode 100644
index 00000000000..eb04147a1bc
--- /dev/null
+++ b/lib/public/Contacts/ContactsMenu/IEntry.php
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @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 OCP\Contacts\ContactsMenu;
+
+use JsonSerializable;
+
+/**
+ * @since 12.0
+ */
+interface IEntry extends JsonSerializable {
+
+ /**
+ * @since 12.0
+ * @return string
+ */
+ public function getFullName();
+
+ /**
+ * @since 12.0
+ * @return string[]
+ */
+ public function getEMailAddresses();
+
+ /**
+ * @since 12.0
+ * @return string|null image URI
+ */
+ public function getAvatar();
+
+ /**
+ * @since 12.0
+ * @param IAction $action an action to show in the contacts menu
+ */
+ public function addAction(IAction $action);
+
+ /**
+ * Get an arbitrary property from the contact
+ *
+ * @since 12.0
+ * @param string $key
+ * @return mixed the value of the property or null
+ */
+ public function getProperty($key);
+}
diff --git a/lib/public/Contacts/ContactsMenu/ILinkAction.php b/lib/public/Contacts/ContactsMenu/ILinkAction.php
new file mode 100644
index 00000000000..4e29f757c26
--- /dev/null
+++ b/lib/public/Contacts/ContactsMenu/ILinkAction.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @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 OCP\Contacts\ContactsMenu;
+
+/**
+ * @since 12.0
+ */
+interface ILinkAction extends IAction {
+
+ /**
+ * @since 12.0
+ * @param string $href the target URL of the action
+ */
+ public function setHref($href);
+
+ /**
+ * @since 12.0
+ * @return string
+ */
+ public function getHref();
+}
diff --git a/lib/public/Contacts/ContactsMenu/IProvider.php b/lib/public/Contacts/ContactsMenu/IProvider.php
new file mode 100644
index 00000000000..e41b1c7c639
--- /dev/null
+++ b/lib/public/Contacts/ContactsMenu/IProvider.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @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 OCP\Contacts\ContactsMenu;
+
+/**
+ * @since 12.0
+ */
+interface IProvider {
+
+ /**
+ * @since 12.0
+ * @param IEntry $entry
+ * @return void
+ */
+ public function process(IEntry $entry);
+}
diff --git a/lib/public/Diagnostics/IEventLogger.php b/lib/public/Diagnostics/IEventLogger.php
index 517a131d436..c76e96c5674 100644
--- a/lib/public/Diagnostics/IEventLogger.php
+++ b/lib/public/Diagnostics/IEventLogger.php
@@ -4,6 +4,7 @@
*
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <robin@icewind.nl>
+ * @author Piotr Mrowczynski <piotr@owncloud.com>
*
* @license AGPL-3.0
*
@@ -31,7 +32,7 @@ namespace OCP\Diagnostics;
*/
interface IEventLogger {
/**
- * Mark the start of an event
+ * Mark the start of an event setting its ID $id and providing event description $description.
*
* @param string $id
* @param string $description
@@ -40,7 +41,9 @@ interface IEventLogger {
public function start($id, $description);
/**
- * Mark the end of an event
+ * Mark the end of an event with specific ID $id, marked by start() method.
+ * Ending event should store \OCP\Diagnostics\IEvent to
+ * be returned with getEvents() method.
*
* @param string $id
* @since 8.0.0
@@ -48,6 +51,11 @@ interface IEventLogger {
public function end($id);
/**
+ * Mark the start and the end of an event with specific ID $id and description $description,
+ * explicitly marking start and end of the event, represented by $start and $end timestamps.
+ * Logging event should store \OCP\Diagnostics\IEvent to
+ * be returned with getEvents() method.
+ *
* @param string $id
* @param string $description
* @param float $start
@@ -57,8 +65,21 @@ interface IEventLogger {
public function log($id, $description, $start, $end);
/**
+ * This method should return all \OCP\Diagnostics\IEvent objects stored using
+ * start()/end() or log() methods
+ *
* @return \OCP\Diagnostics\IEvent[]
* @since 8.0.0
*/
public function getEvents();
+
+ /**
+ * Activate the module for the duration of the request. Deactivated module
+ * does not create and store \OCP\Diagnostics\IEvent objects.
+ * Only activated module should create and store objects to be
+ * returned with getEvents() call.
+ *
+ * @since 12.0.0
+ */
+ public function activate();
}
diff --git a/lib/public/Diagnostics/IQuery.php b/lib/public/Diagnostics/IQuery.php
index 7f26bd7f1b8..ceaee191b39 100644
--- a/lib/public/Diagnostics/IQuery.php
+++ b/lib/public/Diagnostics/IQuery.php
@@ -59,4 +59,9 @@ interface IQuery {
* @since 11.0.0
*/
public function getStacktrace();
+ /**
+ * @return array
+ * @since 12.0.0
+ */
+ public function getStart();
}
diff --git a/lib/public/Diagnostics/IQueryLogger.php b/lib/public/Diagnostics/IQueryLogger.php
index 58ea78795e2..32723a56cb9 100644
--- a/lib/public/Diagnostics/IQueryLogger.php
+++ b/lib/public/Diagnostics/IQueryLogger.php
@@ -4,6 +4,7 @@
*
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <robin@icewind.nl>
+ * @author Piotr Mrowczynski <piotr@owncloud.com>
*
* @license AGPL-3.0
*
@@ -33,6 +34,10 @@ use Doctrine\DBAL\Logging\SQLLogger;
*/
interface IQueryLogger extends SQLLogger {
/**
+ * Mark the start of a query providing query SQL statement, its parameters and types.
+ * This method should be called as close to the DB as possible and after
+ * query is finished finalized with stopQuery() method.
+ *
* @param string $sql
* @param array $params
* @param array $types
@@ -41,14 +46,30 @@ interface IQueryLogger extends SQLLogger {
public function startQuery($sql, array $params = null, array $types = null);
/**
+ * Mark the end of the current active query. Ending query should store \OCP\Diagnostics\IQuery to
+ * be returned with getQueries() method.
+ *
* @return mixed
* @since 8.0.0
*/
public function stopQuery();
/**
+ * This method should return all \OCP\Diagnostics\IQuery objects stored using
+ * startQuery()/stopQuery() methods.
+ *
* @return \OCP\Diagnostics\IQuery[]
* @since 8.0.0
*/
public function getQueries();
+
+ /**
+ * Activate the module for the duration of the request. Deactivated module
+ * does not create and store \OCP\Diagnostics\IQuery objects.
+ * Only activated module should create and store objects to be
+ * returned with getQueries() call.
+ *
+ * @since 12.0.0
+ */
+ public function activate();
}
diff --git a/lib/public/Mail/IEMailTemplate.php b/lib/public/Mail/IEMailTemplate.php
index 05e2fe92beb..6df83b4d10e 100644
--- a/lib/public/Mail/IEMailTemplate.php
+++ b/lib/public/Mail/IEMailTemplate.php
@@ -81,6 +81,20 @@ interface IEMailTemplate {
public function addBodyText($text, $plainText = '');
/**
+ * Adds a list item to the body of the email
+ *
+ * @param string $text
+ * @param string $metaInfo
+ * @param string $icon Absolute path, must be 16*16 pixels
+ * @param string $plainText Text that is used in the plain text email
+ * if empty the $text is used, if false none will be used
+ * @param string $plainMetaInfo Meta info that is used in the plain text email
+ * if empty the $metaInfo is used, if false none will be used
+ * @since 12.0.0
+ */
+ public function addBodyListItem($text, $metaInfo = '', $icon = '', $plainText = '', $plainMetaInfo = '');
+
+ /**
* Adds a button group of two buttons to the body of the email
*
* @param string $textLeft Text of left button