diff options
Diffstat (limited to 'apps/dav')
-rw-r--r-- | apps/dav/appinfo/info.xml | 3 | ||||
-rw-r--r-- | apps/dav/composer/composer/autoload_classmap.php | 1 | ||||
-rw-r--r-- | apps/dav/composer/composer/autoload_static.php | 1 | ||||
-rw-r--r-- | apps/dav/l10n/fr.js | 16 | ||||
-rw-r--r-- | apps/dav/l10n/fr.json | 16 | ||||
-rw-r--r-- | apps/dav/l10n/hr.js | 14 | ||||
-rw-r--r-- | apps/dav/l10n/hr.json | 14 | ||||
-rw-r--r-- | apps/dav/l10n/it.js | 19 | ||||
-rw-r--r-- | apps/dav/l10n/it.json | 19 | ||||
-rw-r--r-- | apps/dav/l10n/pt_BR.js | 2 | ||||
-rw-r--r-- | apps/dav/l10n/pt_BR.json | 2 | ||||
-rw-r--r-- | apps/dav/l10n/sl.js | 3 | ||||
-rw-r--r-- | apps/dav/l10n/sl.json | 3 | ||||
-rw-r--r-- | apps/dav/l10n/tr.js | 4 | ||||
-rw-r--r-- | apps/dav/l10n/tr.json | 4 | ||||
-rw-r--r-- | apps/dav/lib/CalDAV/CalDavBackend.php | 3 | ||||
-rw-r--r-- | apps/dav/lib/CardDAV/AddressBookImpl.php | 2 | ||||
-rw-r--r-- | apps/dav/lib/CardDAV/CardDavBackend.php | 8 | ||||
-rw-r--r-- | apps/dav/lib/Migration/RemoveDeletedUsersCalendarSubscriptions.php | 144 | ||||
-rw-r--r-- | apps/dav/tests/unit/Migration/RemoveDeletedUsersCalendarSubscriptionsTest.php | 169 |
20 files changed, 441 insertions, 6 deletions
diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml index 0f1696f3db9..8bbfbbdeba1 100644 --- a/apps/dav/appinfo/info.xml +++ b/apps/dav/appinfo/info.xml @@ -5,7 +5,7 @@ <name>WebDAV</name> <summary>WebDAV endpoint</summary> <description>WebDAV endpoint</description> - <version>1.19.0</version> + <version>1.20.0</version> <licence>agpl</licence> <author>owncloud.org</author> <namespace>DAV</namespace> @@ -38,6 +38,7 @@ <step>OCA\DAV\Migration\RegisterBuildReminderIndexBackgroundJob</step> <step>OCA\DAV\Migration\RemoveOrphanEventsAndContacts</step> <step>OCA\DAV\Migration\RemoveClassifiedEventActivity</step> + <step>OCA\DAV\Migration\RemoveDeletedUsersCalendarSubscriptions</step> </post-migration> <live-migration> <step>OCA\DAV\Migration\ChunkCleanup</step> diff --git a/apps/dav/composer/composer/autoload_classmap.php b/apps/dav/composer/composer/autoload_classmap.php index 13e78cee716..0572fe3cff8 100644 --- a/apps/dav/composer/composer/autoload_classmap.php +++ b/apps/dav/composer/composer/autoload_classmap.php @@ -242,6 +242,7 @@ return array( 'OCA\\DAV\\Migration\\RegenerateBirthdayCalendars' => $baseDir . '/../lib/Migration/RegenerateBirthdayCalendars.php', 'OCA\\DAV\\Migration\\RegisterBuildReminderIndexBackgroundJob' => $baseDir . '/../lib/Migration/RegisterBuildReminderIndexBackgroundJob.php', 'OCA\\DAV\\Migration\\RemoveClassifiedEventActivity' => $baseDir . '/../lib/Migration/RemoveClassifiedEventActivity.php', + 'OCA\\DAV\\Migration\\RemoveDeletedUsersCalendarSubscriptions' => $baseDir . '/../lib/Migration/RemoveDeletedUsersCalendarSubscriptions.php', 'OCA\\DAV\\Migration\\RemoveOrphanEventsAndContacts' => $baseDir . '/../lib/Migration/RemoveOrphanEventsAndContacts.php', 'OCA\\DAV\\Migration\\Version1004Date20170825134824' => $baseDir . '/../lib/Migration/Version1004Date20170825134824.php', 'OCA\\DAV\\Migration\\Version1004Date20170919104507' => $baseDir . '/../lib/Migration/Version1004Date20170919104507.php', diff --git a/apps/dav/composer/composer/autoload_static.php b/apps/dav/composer/composer/autoload_static.php index 42ba59e0582..01a5df8c1b8 100644 --- a/apps/dav/composer/composer/autoload_static.php +++ b/apps/dav/composer/composer/autoload_static.php @@ -257,6 +257,7 @@ class ComposerStaticInitDAV 'OCA\\DAV\\Migration\\RegenerateBirthdayCalendars' => __DIR__ . '/..' . '/../lib/Migration/RegenerateBirthdayCalendars.php', 'OCA\\DAV\\Migration\\RegisterBuildReminderIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/Migration/RegisterBuildReminderIndexBackgroundJob.php', 'OCA\\DAV\\Migration\\RemoveClassifiedEventActivity' => __DIR__ . '/..' . '/../lib/Migration/RemoveClassifiedEventActivity.php', + 'OCA\\DAV\\Migration\\RemoveDeletedUsersCalendarSubscriptions' => __DIR__ . '/..' . '/../lib/Migration/RemoveDeletedUsersCalendarSubscriptions.php', 'OCA\\DAV\\Migration\\RemoveOrphanEventsAndContacts' => __DIR__ . '/..' . '/../lib/Migration/RemoveOrphanEventsAndContacts.php', 'OCA\\DAV\\Migration\\Version1004Date20170825134824' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170825134824.php', 'OCA\\DAV\\Migration\\Version1004Date20170919104507' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170919104507.php', diff --git a/apps/dav/l10n/fr.js b/apps/dav/l10n/fr.js index eb1ed400b83..653126284cc 100644 --- a/apps/dav/l10n/fr.js +++ b/apps/dav/l10n/fr.js @@ -121,7 +121,21 @@ OC.L10N.register( "Due on %s" : "Echéance le %s", "WebDAV" : "WebDAV", "WebDAV endpoint" : "Point d'accès WebDAV", + "Availability" : "Disponibilité", + "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Si vous configurez vos heures de travail, les autres utilisateurs verront si vous êtes disponible quand ils planifient une réunion.", + "Time zone:" : "Fuseau horaire :", + "to" : "à", + "Delete slot" : "Supprimer le créneau", + "No working hours set" : "Heures de travail non définies", + "Add slot" : "Ajouter un créneau", "Save" : "Enregistrer", + "Monday" : "Lundi", + "Tuesday" : "Mardi", + "Wednesday" : "Mercredi", + "Thursday" : "Jeudi", + "Friday" : "Vendredi", + "Saturday" : "Samedi", + "Sunday" : "Dimanche", "Calendar server" : "Serveur de calendrier", "Send invitations to attendees" : "Envoyer des invitations aux participants", "Automatically generate a birthday calendar" : "Générer automatiquement un agenda d'anniversaire", @@ -136,6 +150,8 @@ OC.L10N.register( "Please contact the organizer directly." : "Merci de contacter l'organisateur directement.", "Are you accepting the invitation?" : "Acceptez-vous l'invitation ?", "Tentative" : "Provisoire", + "Number of guests" : "Nombre d'invités", + "Comment" : "Commentaire", "Your attendance was updated successfully." : "Votre présence a été mise à jour avec succès.", "Calendar and tasks" : "Agenda et tâches" }, diff --git a/apps/dav/l10n/fr.json b/apps/dav/l10n/fr.json index 38919f2a08f..9525c5389e4 100644 --- a/apps/dav/l10n/fr.json +++ b/apps/dav/l10n/fr.json @@ -119,7 +119,21 @@ "Due on %s" : "Echéance le %s", "WebDAV" : "WebDAV", "WebDAV endpoint" : "Point d'accès WebDAV", + "Availability" : "Disponibilité", + "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Si vous configurez vos heures de travail, les autres utilisateurs verront si vous êtes disponible quand ils planifient une réunion.", + "Time zone:" : "Fuseau horaire :", + "to" : "à", + "Delete slot" : "Supprimer le créneau", + "No working hours set" : "Heures de travail non définies", + "Add slot" : "Ajouter un créneau", "Save" : "Enregistrer", + "Monday" : "Lundi", + "Tuesday" : "Mardi", + "Wednesday" : "Mercredi", + "Thursday" : "Jeudi", + "Friday" : "Vendredi", + "Saturday" : "Samedi", + "Sunday" : "Dimanche", "Calendar server" : "Serveur de calendrier", "Send invitations to attendees" : "Envoyer des invitations aux participants", "Automatically generate a birthday calendar" : "Générer automatiquement un agenda d'anniversaire", @@ -134,6 +148,8 @@ "Please contact the organizer directly." : "Merci de contacter l'organisateur directement.", "Are you accepting the invitation?" : "Acceptez-vous l'invitation ?", "Tentative" : "Provisoire", + "Number of guests" : "Nombre d'invités", + "Comment" : "Commentaire", "Your attendance was updated successfully." : "Votre présence a été mise à jour avec succès.", "Calendar and tasks" : "Agenda et tâches" },"pluralForm" :"nplurals=2; plural=(n > 1);" diff --git a/apps/dav/l10n/hr.js b/apps/dav/l10n/hr.js index 0e4264cc9c2..dfdd44d0d89 100644 --- a/apps/dav/l10n/hr.js +++ b/apps/dav/l10n/hr.js @@ -121,7 +121,19 @@ OC.L10N.register( "Due on %s" : "Treba završiti do %s", "WebDAV" : "WebDAV", "WebDAV endpoint" : "WebDAV krajnja točka", + "Availability" : "Raspoloživost", + "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Ako konfigurirate svoje radno vrijeme, drugi korisnici moći će vidjeti jeste li izvan ureda kada rezerviraju sastanak.", + "to" : "do", + "Delete slot" : "Izbriši mjesto", + "Add slot" : "Dodaj mjesto", "Save" : "Spremi", + "Monday" : "Ponedjeljak", + "Tuesday" : "Utorak", + "Wednesday" : "Srijeda", + "Thursday" : "Četvrtak", + "Friday" : "Petak", + "Saturday" : "Subota", + "Sunday" : "Nedjelja", "Calendar server" : "Poslužitelj kalendara", "Send invitations to attendees" : "Pošaljite pozive sudionicima", "Automatically generate a birthday calendar" : "Automatski generiraj kalendar rođendana", @@ -136,6 +148,8 @@ OC.L10N.register( "Please contact the organizer directly." : "Izravno se obratite organizatoru.", "Are you accepting the invitation?" : "Prihvaćate li poziv?", "Tentative" : "Uvjetno", + "Number of guests" : "Broj gostiju", + "Comment" : "Komentar", "Your attendance was updated successfully." : "Vaša je prisutnost uspješno ažurirana.", "Calendar and tasks" : "Kalendar i zadaci" }, diff --git a/apps/dav/l10n/hr.json b/apps/dav/l10n/hr.json index 23c3ab4a114..16577cd1af2 100644 --- a/apps/dav/l10n/hr.json +++ b/apps/dav/l10n/hr.json @@ -119,7 +119,19 @@ "Due on %s" : "Treba završiti do %s", "WebDAV" : "WebDAV", "WebDAV endpoint" : "WebDAV krajnja točka", + "Availability" : "Raspoloživost", + "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Ako konfigurirate svoje radno vrijeme, drugi korisnici moći će vidjeti jeste li izvan ureda kada rezerviraju sastanak.", + "to" : "do", + "Delete slot" : "Izbriši mjesto", + "Add slot" : "Dodaj mjesto", "Save" : "Spremi", + "Monday" : "Ponedjeljak", + "Tuesday" : "Utorak", + "Wednesday" : "Srijeda", + "Thursday" : "Četvrtak", + "Friday" : "Petak", + "Saturday" : "Subota", + "Sunday" : "Nedjelja", "Calendar server" : "Poslužitelj kalendara", "Send invitations to attendees" : "Pošaljite pozive sudionicima", "Automatically generate a birthday calendar" : "Automatski generiraj kalendar rođendana", @@ -134,6 +146,8 @@ "Please contact the organizer directly." : "Izravno se obratite organizatoru.", "Are you accepting the invitation?" : "Prihvaćate li poziv?", "Tentative" : "Uvjetno", + "Number of guests" : "Broj gostiju", + "Comment" : "Komentar", "Your attendance was updated successfully." : "Vaša je prisutnost uspješno ažurirana.", "Calendar and tasks" : "Kalendar i zadaci" },"pluralForm" :"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;" diff --git a/apps/dav/l10n/it.js b/apps/dav/l10n/it.js index 7309124b454..e56c11e0e1d 100644 --- a/apps/dav/l10n/it.js +++ b/apps/dav/l10n/it.js @@ -65,8 +65,11 @@ OC.L10N.register( "Description: %s" : "Descrizione: %s", "Where: %s" : "Dove: %s", "%1$s via %2$s" : "%1$s tramite %2$s", + "Cancelled: %1$s" : "Cancellato: %1$s", "Invitation canceled" : "Invito annullato", + "Re: %1$s" : "Re: %1$s", "Invitation updated" : "Invito aggiornato", + "Invitation: %1$s" : "Invito: %1$s", "Invitation" : "Invito", "Title:" : "Titolo:", "Time:" : "Ora:", @@ -79,6 +82,7 @@ OC.L10N.register( "More options …" : "Altre opzioni...", "More options at %s" : "Altre opzioni alle %s", "Contacts" : "Contatti", + "A <strong>contact</strong> or <strong>address book</strong> was modified" : "Un <strong>contatto</strong> o <strong>rubrica</strong> sono stati modificati ", "System is in maintenance mode." : "Il sistema è in modalità di manutenzione.", "Upgrade needed" : "Aggiornamento necessario", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "Il tuo %s deve essere configurato all'uso di HTTPS per poter usare CalDAV e CardDAV con iOS/macOS.", @@ -92,7 +96,20 @@ OC.L10N.register( "Due on %s" : "Scade il %s", "WebDAV" : "WebDAV", "WebDAV endpoint" : "Terminatore WebDAV", + "Availability" : "Disponibilità", + "Time zone:" : "Fuso orario:", + "to" : "a", + "Delete slot" : "Elimina slot", + "No working hours set" : "Orari lavorativi non impostati", + "Add slot" : "Aggiungi slot", "Save" : "Salva", + "Monday" : "Lunedì", + "Tuesday" : "Martedì", + "Wednesday" : "Mercoledì", + "Thursday" : "Giovedì", + "Friday" : "Venerdì", + "Saturday" : "Sabato", + "Sunday" : "Domenica", "Calendar server" : "Server di calendari", "Send invitations to attendees" : "Invia gli inviti ai partecipanti", "Automatically generate a birthday calendar" : "Genera automaticamente un calendario dei compleanni", @@ -107,6 +124,8 @@ OC.L10N.register( "Please contact the organizer directly." : "Contatta direttamente l'amministratore.", "Are you accepting the invitation?" : "Accetti l'invito?", "Tentative" : "Provvisorio", + "Number of guests" : "Numero di ospiti", + "Comment" : "Commento", "Your attendance was updated successfully." : "La tua partecipazione è stata aggiornata correttamente.", "Calendar and tasks" : "Calendario e attività" }, diff --git a/apps/dav/l10n/it.json b/apps/dav/l10n/it.json index 017e5d26f39..bdb1a63e932 100644 --- a/apps/dav/l10n/it.json +++ b/apps/dav/l10n/it.json @@ -63,8 +63,11 @@ "Description: %s" : "Descrizione: %s", "Where: %s" : "Dove: %s", "%1$s via %2$s" : "%1$s tramite %2$s", + "Cancelled: %1$s" : "Cancellato: %1$s", "Invitation canceled" : "Invito annullato", + "Re: %1$s" : "Re: %1$s", "Invitation updated" : "Invito aggiornato", + "Invitation: %1$s" : "Invito: %1$s", "Invitation" : "Invito", "Title:" : "Titolo:", "Time:" : "Ora:", @@ -77,6 +80,7 @@ "More options …" : "Altre opzioni...", "More options at %s" : "Altre opzioni alle %s", "Contacts" : "Contatti", + "A <strong>contact</strong> or <strong>address book</strong> was modified" : "Un <strong>contatto</strong> o <strong>rubrica</strong> sono stati modificati ", "System is in maintenance mode." : "Il sistema è in modalità di manutenzione.", "Upgrade needed" : "Aggiornamento necessario", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "Il tuo %s deve essere configurato all'uso di HTTPS per poter usare CalDAV e CardDAV con iOS/macOS.", @@ -90,7 +94,20 @@ "Due on %s" : "Scade il %s", "WebDAV" : "WebDAV", "WebDAV endpoint" : "Terminatore WebDAV", + "Availability" : "Disponibilità", + "Time zone:" : "Fuso orario:", + "to" : "a", + "Delete slot" : "Elimina slot", + "No working hours set" : "Orari lavorativi non impostati", + "Add slot" : "Aggiungi slot", "Save" : "Salva", + "Monday" : "Lunedì", + "Tuesday" : "Martedì", + "Wednesday" : "Mercoledì", + "Thursday" : "Giovedì", + "Friday" : "Venerdì", + "Saturday" : "Sabato", + "Sunday" : "Domenica", "Calendar server" : "Server di calendari", "Send invitations to attendees" : "Invia gli inviti ai partecipanti", "Automatically generate a birthday calendar" : "Genera automaticamente un calendario dei compleanni", @@ -105,6 +122,8 @@ "Please contact the organizer directly." : "Contatta direttamente l'amministratore.", "Are you accepting the invitation?" : "Accetti l'invito?", "Tentative" : "Provvisorio", + "Number of guests" : "Numero di ospiti", + "Comment" : "Commento", "Your attendance was updated successfully." : "La tua partecipazione è stata aggiornata correttamente.", "Calendar and tasks" : "Calendario e attività" },"pluralForm" :"nplurals=2; plural=(n != 1);" diff --git a/apps/dav/l10n/pt_BR.js b/apps/dav/l10n/pt_BR.js index 15d39b552a5..aa131264819 100644 --- a/apps/dav/l10n/pt_BR.js +++ b/apps/dav/l10n/pt_BR.js @@ -123,8 +123,10 @@ OC.L10N.register( "WebDAV endpoint" : "Endpoint WebDAV", "Availability" : "Disponibilidade", "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Se você configurar seu horário de trabalho, outros usuários verão quando você estiver fora do escritório quando marcarem uma reunião. ", + "Time zone:" : "Fuso horário:", "to" : "para", "Delete slot" : "Excluir slot", + "No working hours set" : "Sem horário de trabalho definido", "Add slot" : "Adicionar slot ", "Save" : "Salvar", "Monday" : "Segunda-feira", diff --git a/apps/dav/l10n/pt_BR.json b/apps/dav/l10n/pt_BR.json index bbe5120e527..afad93a9325 100644 --- a/apps/dav/l10n/pt_BR.json +++ b/apps/dav/l10n/pt_BR.json @@ -121,8 +121,10 @@ "WebDAV endpoint" : "Endpoint WebDAV", "Availability" : "Disponibilidade", "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Se você configurar seu horário de trabalho, outros usuários verão quando você estiver fora do escritório quando marcarem uma reunião. ", + "Time zone:" : "Fuso horário:", "to" : "para", "Delete slot" : "Excluir slot", + "No working hours set" : "Sem horário de trabalho definido", "Add slot" : "Adicionar slot ", "Save" : "Salvar", "Monday" : "Segunda-feira", diff --git a/apps/dav/l10n/sl.js b/apps/dav/l10n/sl.js index 263cd115e7b..0e8f436e7b8 100644 --- a/apps/dav/l10n/sl.js +++ b/apps/dav/l10n/sl.js @@ -80,6 +80,7 @@ OC.L10N.register( "More options …" : "Več možnosti ...", "More options at %s" : "Več možnosti je na %s", "Contacts" : "Stiki", + "You deleted address book {addressbook}" : "Izbrišete imenik {addressbook}", "System is in maintenance mode." : "Sistem je v vzdrževalnem načinu.", "Upgrade needed" : "Zahtevana je posodobitev", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "Za uporabo CalDAV in CardDAV v okoljih iOS/macOS je treba %s nastaviti za uporabo HTTPS.", @@ -94,7 +95,9 @@ OC.L10N.register( "WebDAV" : "WebDAV", "WebDAV endpoint" : "Končna točka WebDAV", "Availability" : "Razpoložljivost", + "Time zone:" : "Časovni pas:", "Delete slot" : "Izbriši možnost", + "No working hours set" : "Ni navedenih delovnih ur", "Add slot" : "Dodaj polje", "Save" : "Shrani", "Monday" : "ponedeljek", diff --git a/apps/dav/l10n/sl.json b/apps/dav/l10n/sl.json index 4eda7391749..9e3e7d974f2 100644 --- a/apps/dav/l10n/sl.json +++ b/apps/dav/l10n/sl.json @@ -78,6 +78,7 @@ "More options …" : "Več možnosti ...", "More options at %s" : "Več možnosti je na %s", "Contacts" : "Stiki", + "You deleted address book {addressbook}" : "Izbrišete imenik {addressbook}", "System is in maintenance mode." : "Sistem je v vzdrževalnem načinu.", "Upgrade needed" : "Zahtevana je posodobitev", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "Za uporabo CalDAV in CardDAV v okoljih iOS/macOS je treba %s nastaviti za uporabo HTTPS.", @@ -92,7 +93,9 @@ "WebDAV" : "WebDAV", "WebDAV endpoint" : "Končna točka WebDAV", "Availability" : "Razpoložljivost", + "Time zone:" : "Časovni pas:", "Delete slot" : "Izbriši možnost", + "No working hours set" : "Ni navedenih delovnih ur", "Add slot" : "Dodaj polje", "Save" : "Shrani", "Monday" : "ponedeljek", diff --git a/apps/dav/l10n/tr.js b/apps/dav/l10n/tr.js index 8911d8aa116..6318381efa4 100644 --- a/apps/dav/l10n/tr.js +++ b/apps/dav/l10n/tr.js @@ -54,7 +54,7 @@ OC.L10N.register( "Date:" : "Tarih:", "Where:" : "Yer:", "Description:" : "Açıklama:", - "Untitled event" : "Başlıksız etkinlik", + "Untitled event" : "Adsız etkinlik", "_%n year_::_%n years_" : ["%n yıl","%n yıl"], "_%n month_::_%n months_" : ["%n ay","%n ay"], "_%n day_::_%n days_" : ["%n gün","%n gün"], @@ -115,7 +115,7 @@ OC.L10N.register( "Configures a CardDAV account" : "Bir CardDAV hesabı yapılandırır", "Events" : "Etkinlikler", "Tasks" : "Görevler", - "Untitled task" : "Başlıksız görev", + "Untitled task" : "Adsız görev", "Completed on %s" : "%s tarihinde tamamlandı", "Due on %s by %s" : "%s tarihine kadar %s tarafından", "Due on %s" : "%s tarihine kadar", diff --git a/apps/dav/l10n/tr.json b/apps/dav/l10n/tr.json index 926eda487d3..223c628d716 100644 --- a/apps/dav/l10n/tr.json +++ b/apps/dav/l10n/tr.json @@ -52,7 +52,7 @@ "Date:" : "Tarih:", "Where:" : "Yer:", "Description:" : "Açıklama:", - "Untitled event" : "Başlıksız etkinlik", + "Untitled event" : "Adsız etkinlik", "_%n year_::_%n years_" : ["%n yıl","%n yıl"], "_%n month_::_%n months_" : ["%n ay","%n ay"], "_%n day_::_%n days_" : ["%n gün","%n gün"], @@ -113,7 +113,7 @@ "Configures a CardDAV account" : "Bir CardDAV hesabı yapılandırır", "Events" : "Etkinlikler", "Tasks" : "Görevler", - "Untitled task" : "Başlıksız görev", + "Untitled task" : "Adsız görev", "Completed on %s" : "%s tarihinde tamamlandı", "Due on %s by %s" : "%s tarihine kadar %s tarafından", "Due on %s" : "%s tarihine kadar", diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 5f0c1bf3c48..ab1f8780651 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -1899,6 +1899,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $result = $outerQuery->executeQuery(); $calendarObjects = $result->fetchAll(); + $result->closeCursor(); return array_map(function ($o) { $calendarData = Reader::read($o['calendardata']); @@ -2613,6 +2614,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription 'size' => (int)$row['size'], ]; } + $stmt->closeCursor(); return $result; } @@ -2992,6 +2994,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription ->executeQuery(); $ids = $result->fetchAll(); + $result->closeCursor(); foreach ($ids as $id) { $this->deleteCalendar( $id['id'], diff --git a/apps/dav/lib/CardDAV/AddressBookImpl.php b/apps/dav/lib/CardDAV/AddressBookImpl.php index 8b0d494fd01..3db20cb4220 100644 --- a/apps/dav/lib/CardDAV/AddressBookImpl.php +++ b/apps/dav/lib/CardDAV/AddressBookImpl.php @@ -107,6 +107,8 @@ class AddressBookImpl implements IAddressBook { * - 'escape_like_param' - If set to false wildcards _ and % are not escaped * - 'limit' - Set a numeric limit for the search results * - 'offset' - Set the offset for the limited search results + * - 'wildcard' - Whether the search should use wildcards + * @psalm-param array{types?: bool, escape_like_param?: bool, limit?: int, offset?: int, wildcard?: bool} $options * @return array an array of contacts which are arrays of key-value-pairs * example result: * [ diff --git a/apps/dav/lib/CardDAV/CardDavBackend.php b/apps/dav/lib/CardDAV/CardDavBackend.php index 13926ef12ce..3e360fb2e41 100644 --- a/apps/dav/lib/CardDAV/CardDavBackend.php +++ b/apps/dav/lib/CardDAV/CardDavBackend.php @@ -1024,6 +1024,8 @@ class CardDavBackend implements BackendInterface, SyncSupport { * - 'escape_like_param' - If set to false wildcards _ and % are not escaped, otherwise they are * - 'limit' - Set a numeric limit for the search results * - 'offset' - Set the offset for the limited search results + * - 'wildcard' - Whether the search should use wildcards + * @psalm-param array{escape_like_param?: bool, limit?: int, offset?: int, wildcard?: bool} $options * @return array an array of contacts which are arrays of key-value-pairs */ public function search($addressBookId, $pattern, $searchProperties, $options = []): array { @@ -1055,6 +1057,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { * @param string $pattern * @param array $searchProperties * @param array $options + * @psalm-param array{types?: bool, escape_like_param?: bool, limit?: int, offset?: int, wildcard?: bool} $options * @return array */ private function searchByAddressBookIds(array $addressBookIds, @@ -1062,6 +1065,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { array $searchProperties, array $options = []): array { $escapePattern = !\array_key_exists('escape_like_param', $options) || $options['escape_like_param'] !== false; + $useWildcards = !\array_key_exists('wildcard', $options) || $options['wildcard'] !== false; $query2 = $this->db->getQueryBuilder(); @@ -1103,7 +1107,9 @@ class CardDavBackend implements BackendInterface, SyncSupport { // No need for like when the pattern is empty if ('' !== $pattern) { - if (!$escapePattern) { + if (!$useWildcards) { + $query2->andWhere($query2->expr()->eq('cp.value', $query2->createNamedParameter($pattern))); + } elseif (!$escapePattern) { $query2->andWhere($query2->expr()->ilike('cp.value', $query2->createNamedParameter($pattern))); } else { $query2->andWhere($query2->expr()->ilike('cp.value', $query2->createNamedParameter('%' . $this->db->escapeLikeParameter($pattern) . '%'))); diff --git a/apps/dav/lib/Migration/RemoveDeletedUsersCalendarSubscriptions.php b/apps/dav/lib/Migration/RemoveDeletedUsersCalendarSubscriptions.php new file mode 100644 index 00000000000..50becf81e78 --- /dev/null +++ b/apps/dav/lib/Migration/RemoveDeletedUsersCalendarSubscriptions.php @@ -0,0 +1,144 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2021 Thomas Citharel <nextcloud@tcit.fr> + * + * @author Thomas Citharel <nextcloud@tcit.fr> + * + * @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 OCA\DAV\Migration; + +use OCP\DB\Exception; +use OCP\IDBConnection; +use OCP\IUserManager; +use OCP\Migration\IOutput; +use OCP\Migration\IRepairStep; + +class RemoveDeletedUsersCalendarSubscriptions implements IRepairStep { + /** @var IDBConnection */ + private $connection; + + /** @var IUserManager */ + private $userManager; + + /** @var int */ + private $progress = 0; + + private $orphanSubscriptions = []; + + private const SUBSCRIPTIONS_CHUNK_SIZE = 1000; + + public function __construct(IDBConnection $connection, IUserManager $userManager) { + $this->connection = $connection; + $this->userManager = $userManager; + } + + /** + * @inheritdoc + */ + public function getName(): string { + return 'Clean up old calendar subscriptions from deleted users that were not cleaned-up'; + } + + /** + * @inheritdoc + */ + public function run(IOutput $output) { + $nbSubscriptions = $this->countSubscriptions(); + + $output->startProgress($nbSubscriptions); + + while ($this->progress < $nbSubscriptions) { + $this->checkSubscriptions(); + + $this->progress += self::SUBSCRIPTIONS_CHUNK_SIZE; + $output->advance(min(self::SUBSCRIPTIONS_CHUNK_SIZE, $nbSubscriptions)); + } + $output->finishProgress(); + $this->deleteOrphanSubscriptions(); + + $output->info(sprintf('%d calendar subscriptions without an user have been cleaned up', count($this->orphanSubscriptions))); + } + + /** + * @throws Exception + */ + private function countSubscriptions(): int { + $qb = $this->connection->getQueryBuilder(); + $query = $qb->select($qb->func()->count('*')) + ->from('calendarsubscriptions'); + + $result = $query->execute(); + $count = $result->fetchOne(); + $result->closeCursor(); + + if ($count !== false) { + $count = (int)$count; + } else { + $count = 0; + } + + return $count; + } + + /** + * @throws Exception + */ + private function checkSubscriptions(): void { + $qb = $this->connection->getQueryBuilder(); + $query = $qb->selectDistinct(['id', 'principaluri']) + ->from('calendarsubscriptions') + ->setMaxResults(self::SUBSCRIPTIONS_CHUNK_SIZE) + ->setFirstResult($this->progress); + + $result = $query->execute(); + while ($row = $result->fetch()) { + $username = $this->getPrincipal($row['principaluri']); + if (!$this->userManager->userExists($username)) { + $this->orphanSubscriptions[] = $row['id']; + } + } + $result->closeCursor(); + } + + /** + * @throws Exception + */ + private function deleteOrphanSubscriptions(): void { + foreach ($this->orphanSubscriptions as $orphanSubscriptionID) { + $this->deleteOrphanSubscription($orphanSubscriptionID); + } + } + + /** + * @throws Exception + */ + private function deleteOrphanSubscription(int $orphanSubscriptionID): void { + $qb = $this->connection->getQueryBuilder(); + $qb->delete('calendarsubscriptions') + ->where($qb->expr()->eq('id', $qb->createNamedParameter($orphanSubscriptionID))) + ->executeStatement(); + } + + private function getPrincipal(string $principalUri): string { + $uri = explode('/', $principalUri); + return array_pop($uri); + } +} diff --git a/apps/dav/tests/unit/Migration/RemoveDeletedUsersCalendarSubscriptionsTest.php b/apps/dav/tests/unit/Migration/RemoveDeletedUsersCalendarSubscriptionsTest.php new file mode 100644 index 00000000000..c0d6518d205 --- /dev/null +++ b/apps/dav/tests/unit/Migration/RemoveDeletedUsersCalendarSubscriptionsTest.php @@ -0,0 +1,169 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2021 Thomas Citharel <nextcloud@tcit.fr> + * + * @author Thomas Citharel <nextcloud@tcit.fr> + * + * @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 OCA\DAV\Tests\unit\DAV\Migration; + +use OCA\DAV\Migration\RemoveDeletedUsersCalendarSubscriptions; +use OCP\DB\IResult; +use OCP\DB\QueryBuilder\IExpressionBuilder; +use OCP\DB\QueryBuilder\IFunctionBuilder; +use OCP\DB\QueryBuilder\IParameter; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\DB\QueryBuilder\IQueryFunction; +use OCP\IDBConnection; +use OCP\IUserManager; +use OCP\Migration\IOutput; +use PHPUnit\Framework\MockObject\MockObject; +use Test\TestCase; + +class RemoveDeletedUsersCalendarSubscriptionsTest extends TestCase { + /** + * @var IDBConnection|MockObject + */ + private $dbConnection; + /** + * @var IUserManager|MockObject + */ + private $userManager; + + /** + * @var IOutput|MockObject + */ + private $output; + /** + * @var RemoveDeletedUsersCalendarSubscriptions + */ + private $migration; + + + protected function setUp(): void { + parent::setUp(); + + $this->dbConnection = $this->createMock(IDBConnection::class); + $this->userManager = $this->createMock(IUserManager::class); + $this->output = $this->createMock(IOutput::class); + + $this->migration = new RemoveDeletedUsersCalendarSubscriptions($this->dbConnection, $this->userManager); + } + + public function testGetName(): void { + $this->assertEquals( + 'Clean up old calendar subscriptions from deleted users that were not cleaned-up', + $this->migration->getName() + ); + } + + /** + * @dataProvider dataTestRun + * @param array $subscriptions + * @param array $userExists + * @param int $deletions + * @throws \Exception + */ + public function testRun(array $subscriptions, array $userExists, int $deletions): void { + $qb = $this->createMock(IQueryBuilder::class); + + $qb->method('select')->willReturn($qb); + + $functionBuilder = $this->createMock(IFunctionBuilder::class); + + $qb->method('func')->willReturn($functionBuilder); + $functionBuilder->method('count')->willReturn($this->createMock(IQueryFunction::class)); + + $qb->method('selectDistinct') + ->with(['id', 'principaluri']) + ->willReturn($qb); + + $qb->method('from') + ->with('calendarsubscriptions') + ->willReturn($qb); + + $qb->method('setMaxResults') + ->willReturn($qb); + + $qb->method('setFirstResult') + ->willReturn($qb); + + $result = $this->createMock(IResult::class); + + $qb->method('execute') + ->willReturn($result); + + $result->expects($this->at(0)) + ->method('fetchOne') + ->willReturn(count($subscriptions)); + + $result + ->method('fetch') + ->willReturnOnConsecutiveCalls(...$subscriptions); + + $qb->method('delete') + ->with('calendarsubscriptions') + ->willReturn($qb); + + $expr = $this->createMock(IExpressionBuilder::class); + + $qb->method('expr')->willReturn($expr); + $qb->method('createNamedParameter')->willReturn($this->createMock(IParameter::class)); + $qb->method('where')->willReturn($qb); + // Only when user exists + $qb->expects($this->exactly($deletions))->method('executeStatement'); + + $this->dbConnection->method('getQueryBuilder')->willReturn($qb); + + + $this->output->expects($this->once())->method('startProgress'); + + $this->output->expects($subscriptions === [] ? $this->never(): $this->once())->method('advance'); + if (count($subscriptions)) { + $this->userManager->method('userExists') + ->willReturnCallback(function (string $username) use ($userExists) { + return $userExists[$username]; + }); + } + $this->output->expects($this->once())->method('finishProgress'); + $this->output->expects($this->once())->method('info')->with(sprintf('%d calendar subscriptions without an user have been cleaned up', $deletions)); + + $this->migration->run($this->output); + } + + public function dataTestRun(): array { + return [ + [[], [], 0], + [[[ + 'id' => 1, + 'principaluri' => 'users/principals/foo1', + ], + [ + 'id' => 2, + 'principaluri' => 'users/principals/bar1', + ], + [ + 'id' => 3, + 'principaluri' => 'users/principals/bar1', + ]], ['foo1' => true, 'bar1' => false], 2] + ]; + } +} |