diff --git a/lang/af.yml b/lang/af.yml index 6972d4f3b..b1846a08f 100644 --- a/lang/af.yml +++ b/lang/af.yml @@ -17,13 +17,13 @@ af: SilverStripe\Forms\DateField: NOTSET: 'Nie gestel nie' TODAY: vandag - VALIDDATEFORMAT2: 'Sleutel asseblief ''n geldige datum formaat in ({format})' + VALIDDATEFORMAT2: "Sleutel asseblief 'n geldige datum formaat in ({format})" VALIDDATEMAXDATE: 'Jou datum moet gelykstaande of ouer wees as die maksimum toelaatbare datum ({date})' VALIDDATEMINDATE: 'Jou datum moet net so out of nuwer wees as die minimum toelaatbare datum ({date})' SilverStripe\Forms\DropdownField: CHOOSE: (Kies) SilverStripe\Forms\EmailField: - VALIDATION: 'Verskaf asseblief ''n epos adres ' + VALIDATION: "Verskaf asseblief 'n epos adres " SilverStripe\Forms\FileUploadReceiver: FIELDNOTSET: 'Die lêer informasie kan nie gevind word nie' SilverStripe\Forms\Form: @@ -31,7 +31,7 @@ af: VALIDATIONPASSWORDSNOTEMPTY: 'Wagwoorde kan nie leeg wees nie' VALIDATIONSTRONGPASSWORD: 'Wagwoorde moet minstens een nommer en een alfa-numeriese karaketer bevat' VALIDATOR: Vergeldiger - VALIDCURRENCY: 'Tik asseblief ''n geldige geldeenheid in ' + VALIDCURRENCY: "Tik asseblief 'n geldige geldeenheid in " SilverStripe\Forms\FormField: NONE: geen SilverStripe\Forms\FormScaffolder: @@ -74,9 +74,9 @@ af: FIELDLABELAMOUNT: Bedrag FIELDLABELCURRENCY: 'Geld eenheid' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}''is nie ''n nommer nie, slegs die nommers kan aanvaar word vir hierdie veld' + VALIDATION: "'{value}'is nie 'n nommer nie, slegs die nommers kan aanvaar word vir hierdie veld" SilverStripe\Forms\TimeField: - VALIDATEFORMAT: 'Sleutel asseblief ''n geldige tyd formaat ({format})' + VALIDATEFORMAT: "Sleutel asseblief 'n geldige tyd formaat ({format})" SilverStripe\ORM\DataObject: PLURALNAME: 'Data Voorwerpe' SINGULARNAME: 'Data Voorwerp' @@ -87,8 +87,8 @@ af: SilverStripe\ORM\FieldType\DBEnum: ANY: Enige SilverStripe\Security\BasicAuth: - ENTERINFO: 'Tik asseblief ''n verbruikersnaam en wagwoord in' - ERRORNOTADMIN: 'Daardie verbruiker is nie ''n administreerder nie' + ENTERINFO: "Tik asseblief 'n verbruikersnaam en wagwoord in" + ERRORNOTADMIN: "Daardie verbruiker is nie 'n administreerder nie" ERRORNOTREC: 'Daar die verbruikersnaam / wagwoord is nie herken nie' SilverStripe\Security\Confirmation\Form: REFUSE: 'Kanselleer ' @@ -100,7 +100,7 @@ af: DefaultGroupTitleContentAuthors: 'Inhouds Outeurs' Description: Beskrywing GROUPNAME: 'Groep naam' - GroupReminder: 'As jy ''n ouer groep kies sal hierdie groep al daardie rolle aanneem' + GroupReminder: "As jy 'n ouer groep kies sal hierdie groep al daardie rolle aanneem" Locked: 'Gesluit?' MEMBERS: Lidde NoRoles: 'Geen rolle gevind nie' @@ -137,7 +137,7 @@ af: EDIT_PASSWORD: 'Nuwe wagwoord' EMAIL: Epos EMPTYNEWPASSWORD: 'Die nuwe wagwoord kan nie leeg wees nie. Probeer asseblief weer' - ENTEREMAIL: 'Verskaf asseblief ''n epos adres sodat ons vir u ''n wagwoord herstel skakel kan epos' + ENTEREMAIL: "Verskaf asseblief 'n epos adres sodat ons vir u 'n wagwoord herstel skakel kan epos" ERRORNEWPASSWORD: 'Jy het jou nuwe wagwoord anders ingetik. Probeer weer' ERRORPASSWORDNOTMATCH: 'U huidige wagwoord pas nie, probeer asseblief weer' FIRSTNAME: Voornaam @@ -194,13 +194,13 @@ af: SilverStripe\Security\RememberLoginHash: has_one_Member: Lid SilverStripe\Security\Security: - ALREADYLOGGEDIN: 'U het nie toegang tot hierdie bladsy nie. As u n'' ander rekening het wat toegang tot hierdie bladsy het, kan u weer inteken.' + ALREADYLOGGEDIN: "U het nie toegang tot hierdie bladsy nie. As u n' ander rekening het wat toegang tot hierdie bladsy het, kan u weer inteken." BUTTONSEND: 'Stuur vir my die wagwoord herstel skakel' CHANGEPASSWORDBELOW: 'Jy kan jou wagwoord onder verander' CHANGEPASSWORDHEADER: 'Verander jou wagwoord' - ENTERNEWPASSWORD: 'Sleutel asseblief ''n nuwe wagwoord in' + ENTERNEWPASSWORD: "Sleutel asseblief 'n nuwe wagwoord in" ERRORPASSWORDPERMISSION: 'Jy moet ingeteken wees om jou wagwoord te verander' LOGIN: 'Teken in' LOGOUT: 'Teken af' NOTEPAGESECURED: 'Daai bladsy is beveilig. Sleutel jou informasie onder in sodat ons jou op jou pad kan stuur' - NOTERESETPASSWORD: 'Sleutel you epos adres in sodat ons vir jou ''n herstel skakel kan epos' + NOTERESETPASSWORD: "Sleutel you epos adres in sodat ons vir jou 'n herstel skakel kan epos" diff --git a/lang/ar.yml b/lang/ar.yml index c815eee99..ab0ccd09e 100644 --- a/lang/ar.yml +++ b/lang/ar.yml @@ -91,7 +91,7 @@ ar: SilverStripe\Forms\NullableField: IsNullLabel: باطل SilverStripe\Forms\NumericField: - VALIDATION: '''{قيمة}'' ليس برقم و الأرقام فقط يمكن قبولها لهذا الحقل' + VALIDATION: "'{قيمة}' ليس برقم و الأرقام فقط يمكن قبولها لهذا الحقل" SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'الرجاء إدخال صيغة وقت صحيحة ({صيغة})' SilverStripe\ORM\DataObject: diff --git a/lang/ast.yml b/lang/ast.yml index 401aeffd1..d9d857a23 100644 --- a/lang/ast.yml +++ b/lang/ast.yml @@ -4,7 +4,7 @@ ast: SilverStripe\Forms\ConfirmedPasswordField: SHOWONCLICKTITLE: 'Camudar contraseña' SilverStripe\Forms\DateField: - NOTSET: 'nun s''establez' + NOTSET: "nun s'establez" TODAY: hoi SilverStripe\Forms\DropdownField: CHOOSE: (Escoyer) @@ -42,7 +42,7 @@ ast: db_Email: Corréu db_LockedOutUntil: 'Bloquiáu fasta' db_Password: Contraseña - db_PasswordExpiry: 'Data d''espiración de la contraseña' + db_PasswordExpiry: "Data d'espiración de la contraseña" SilverStripe\Security\MemberPassword: db_Password: Contraseña has_one_Member: Miembru diff --git a/lang/bg.yml b/lang/bg.yml index 707ec5c7b..59af3fa84 100644 --- a/lang/bg.yml +++ b/lang/bg.yml @@ -107,7 +107,7 @@ bg: SilverStripe\Forms\MultiSelectField: SOURCE_VALIDATION: 'Изберете стойност от списъка. {value} не е валидна опция(и)' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' не е число, само числа могат да се въвеждат в това поле' + VALIDATION: "'{value}' не е число, само числа могат да се въвеждат в това поле" SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'Моля, въведете валиден формат за дата ({format})' SilverStripe\ORM\DataObject: diff --git a/lang/ca.yml b/lang/ca.yml index 8e4530480..9df22df1e 100644 --- a/lang/ca.yml +++ b/lang/ca.yml @@ -36,9 +36,9 @@ ca: PLURALNAME: 'Objectes de dades' SINGULARNAME: 'Objecte de dades' SilverStripe\Security\BasicAuth: - ENTERINFO: 'Si us plau, introduïu un nom d''usuari i contrasenya' + ENTERINFO: "Si us plau, introduïu un nom d'usuari i contrasenya" ERRORNOTADMIN: 'Aquest usuari no és un administrador.' - ERRORNOTREC: 'Aquest nom d''usuari / contrasenya no es reconeix' + ERRORNOTREC: "Aquest nom d'usuari / contrasenya no es reconeix" SilverStripe\Security\Group: Code: 'Codi de grup' Description: Descripció @@ -79,17 +79,17 @@ ca: PASSWORD: Contrasenya PLURALNAME: Membres SINGULARNAME: Membre - SUBJECTPASSWORDCHANGED: 'La vostra contrasenya s''ha canviat' + SUBJECTPASSWORDCHANGED: "La vostra contrasenya s'ha canviat" SUBJECTPASSWORDRESET: 'Enllaç per canviar la contrasenya' SURNAME: Cognom YOUROLDPASSWORD: 'La vostra contrasenya anterior' belongs_many_many_Groups: Grups db_Email: 'Correu electrònic' db_FirstName: Nom - db_Locale: 'Idioma d''interfície' + db_Locale: "Idioma d'interfície" db_LockedOutUntil: 'Bloquejat fins a' db_Password: Contrasenya - db_PasswordExpiry: 'Data d''expiració de la contrasenya' + db_PasswordExpiry: "Data d'expiració de la contrasenya" db_Surname: Cognom SilverStripe\Security\MemberAuthenticator\CMSMemberLoginForm: BUTTONFORGOTPASSWORD: 'He oblidat la contrasenya' @@ -108,11 +108,11 @@ ca: has_one_Member: Membre SilverStripe\Security\Security: ALREADYLOGGEDIN: 'No teniu accés a aquesta pàgina. Si teniu un altre compte que pot accedir a aquesta pàgina, podeu entrar-hi a sota.' - BUTTONSEND: 'Envia''m l''enllaç per reiniciar la contrasenya' + BUTTONSEND: "Envia'm l'enllaç per reiniciar la contrasenya" CHANGEPASSWORDBELOW: 'Podeu canviar la vostra contrasenya a sota.' CHANGEPASSWORDHEADER: 'Canviar la vostra contrasenya' ENTERNEWPASSWORD: 'Si us plau, introduïu una nova contrasenya.' - ERRORPASSWORDPERMISSION: 'Heu d''estar connectat per a canviar la vostra contrasenya!' + ERRORPASSWORDPERMISSION: "Heu d'estar connectat per a canviar la vostra contrasenya!" LOGIN: Entrar NOTEPAGESECURED: 'Aquesta pàgina està protegida. Introduïu les vostres credencials a sota i us hi enviarem.' NOTERESETPASSWORD: 'Introduïu la vostra adreça de correu electrònic i us enviarem un enllaç amb el qual reiniciar la vostra contrasenya' diff --git a/lang/cs.yml b/lang/cs.yml index eeb928f56..21054b331 100644 --- a/lang/cs.yml +++ b/lang/cs.yml @@ -100,7 +100,7 @@ cs: SilverStripe\Forms\NullableField: IsNullLabel: 'Je nulové' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' není číslo, pouze čísla mohou být akceptována pro toto pole' + VALIDATION: "'{value}' není číslo, pouze čísla mohou být akceptována pro toto pole" SilverStripe\Forms\TextField: VALIDATEMAXLENGTH: 'Hodnota pro {name} nesmí překročit {maxLength} v délce znaků' SilverStripe\Forms\TimeField: diff --git a/lang/da.yml b/lang/da.yml index 9064c3ae0..eeb43a98e 100644 --- a/lang/da.yml +++ b/lang/da.yml @@ -105,7 +105,7 @@ da: SilverStripe\Forms\NullableField: IsNullLabel: 'Er Null' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' er ikke et tal, kun tal accepteres i dette felt' + VALIDATION: "'{value}' er ikke et tal, kun tal accepteres i dette felt" SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'Indtats venligst et gyldigt tidsformat ({format})' SilverStripe\ORM\DataObject: diff --git a/lang/de.yml b/lang/de.yml index f5b55d425..e13317605 100644 --- a/lang/de.yml +++ b/lang/de.yml @@ -137,7 +137,7 @@ de: SilverStripe\Forms\NullableField: IsNullLabel: 'ist NULL' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' ist kein numerischer Wert, nur nummerische Werte sind in diesem Feld erlaubt' + VALIDATION: "'{value}' ist kein numerischer Wert, nur nummerische Werte sind in diesem Feld erlaubt" SilverStripe\Forms\TextField: VALIDATEMAXLENGTH: 'Der für {name} eingegebene Wert darf nicht mehr als {maxLength} Zeichen lang sein' SilverStripe\Forms\TimeField: diff --git a/lang/en_GB.yml b/lang/en_GB.yml index a31ad1ab5..bd8aa4686 100644 --- a/lang/en_GB.yml +++ b/lang/en_GB.yml @@ -1,3 +1,3 @@ en_GB: SilverStripe\Security\Security: - ALREADYLOGGEDIN: 'You don''t have access to this page. If you have another account that can access that page, you can log in again.' + ALREADYLOGGEDIN: "You don't have access to this page. If you have another account that can access that page, you can log in again." diff --git a/lang/eo.yml b/lang/eo.yml index a237ed0eb..1d1a79e51 100644 --- a/lang/eo.yml +++ b/lang/eo.yml @@ -27,9 +27,22 @@ eo: SilverStripe\Control\RequestProcessor: INVALID_REQUEST: 'Malvalida peto' REQUEST_ABORTED: 'Ĉesigis peton' + SilverStripe\Dev\DevBuildController: + CAN_DEV_BUILD_DESCRIPTION: 'Povas ruli je /dev/build' + CAN_DEV_BUILD_HELP: 'Povas ruli la komandon konstrui (/dev/build)' + SilverStripe\Dev\DevConfigController: + CAN_DEV_CONFIG_DESCRIPTION: 'Povas vidi je /dev/config' + CAN_DEV_CONFIG_HELP: 'Povas vidi la tutan aranĝon (/dev/config)' SilverStripe\Dev\DevConfirmationController: INFO_DESCRIPTION: 'Konfirmi eble danĝeran operacion' INFO_TITLE: 'Sekurecon konfirmi' + SilverStripe\Dev\DevelopmentAdmin: + ALL_DEV_ADMIN_DESCRIPTION: 'Povas vidi kaj ruli ĉiujn finpunktojn /dev' + ALL_DEV_ADMIN_HELP: 'Povas vidi kaj ruli ĉiujn finpunktojn /dev' + PERMISSIONS_CATEGORY: Dev-permesoj + SilverStripe\Dev\TaskRunner: + BUILDTASK_CAN_RUN_DESCRIPTION: 'Povas vidi kaj ruli ĉiujn taskojn /dev/tasks' + BUILDTASK_CAN_RUN_HELP: 'Povas vidi kaj ruli ĉiujn konstruajn taskojn (/dev/tasks). Unuopaj taskaj vidaj permesoj povas transpasi ĉi tiun permeson.' SilverStripe\Forms\CheckboxField: NOANSWER: Ne YESANSWER: Jes @@ -105,7 +118,7 @@ eo: Create: Krei Delete: Forigi DeletePermissionsFailure: 'Mankas permeso forigi' - Deleted: 'Forigita {type} {name}' + Deleted: 'Forigita {tipo} "{nomo}"' Save: Konservi Saved: 'Konservita {name} {link}' SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest: @@ -113,6 +126,8 @@ eo: NEW: 'Aldoni novan rikordon' NEXT: 'Iri al la sekva rikordo' PREVIOUS: 'Iri al la antaŭa rikordo' + SAVEDUP: 'Konservis sukcese' + SAVETOASTMESSAGE: 'Konservis {tipo} "{titolo}" sukcese' ViewPermissionsFailure: 'Ŝajnas ke vi ne havas la bezonatajn permesojn por vidi je {ObjectTitle}' SilverStripe\Forms\GridField\GridFieldEditButton: EDIT: Redakti @@ -140,7 +155,11 @@ eo: SilverStripe\Forms\NullableField: IsNullLabel: 'Estas senvalora' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' ne estas numero, nur numeroj estas akcepteblaj por ĉi tiu kampo' + VALIDATION: "'{value}' ne estas numero, nur numeroj estas akcepteblaj por ĉi tiu kampo" + SilverStripe\Forms\SearchableDropdownTrait: + SELECT: Elekti... + SELECT_OR_TYPE_TO_SEARCH: 'Elekti aŭ tajpi por serĉi...' + TYPE_TO_SEARCH: 'Tajpi por serĉi...' SilverStripe\Forms\TextField: VALIDATEMAXLENGTH: 'La valoro por {name} devas ne havi longon pli ol {maxLength} signoj' SilverStripe\Forms\TimeField: @@ -287,6 +306,7 @@ eo: CURRENT_PASSWORD: 'Aktuala pasvorto' EDIT_PASSWORD: 'Nova pasvorto' EMAIL: Retpoŝto + EMAIL_FAILED: 'Eraro okazis provante retpoŝti al vi pasvortan reagordan ligilon.' EMPTYNEWPASSWORD: 'La nova pasvorto ne povas esti nula, bonvole refaru' ENTEREMAIL: 'Bonvolu enigi retadreson por atingi ligilon por reagordi pasvorton.' ERRORLOCKEDOUT2: 'Via konto estas provizore malvalidigita pro troaj provoj ensaluti. Bonvole reprovu post {count} minutoj.' diff --git a/lang/es.yml b/lang/es.yml index 02042ba56..194ddb4e9 100644 --- a/lang/es.yml +++ b/lang/es.yml @@ -102,7 +102,7 @@ es: SilverStripe\Forms\NullableField: IsNullLabel: 'Es Nulo' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' no es un número, sólo números pueden ser aceptados para este campo' + VALIDATION: "'{value}' no es un número, sólo números pueden ser aceptados para este campo" SilverStripe\Forms\TextField: VALIDATEMAXLENGTH: 'El valor para {name} no puede exceder los {maxLength} caracteres de longitud' SilverStripe\Forms\TimeField: diff --git a/lang/es_MX.yml b/lang/es_MX.yml index 0d2f56aaf..967aeb4f3 100644 --- a/lang/es_MX.yml +++ b/lang/es_MX.yml @@ -73,7 +73,7 @@ es_MX: SilverStripe\Forms\NullableField: IsNullLabel: 'Es Nulo' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' no es un número, solo números son aceptados por este campo' + VALIDATION: "'{value}' no es un número, solo números son aceptados por este campo" SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'Por favor ingresar un formato válido de fecha ({format})' SilverStripe\ORM\DataObject: diff --git a/lang/et_EE.yml b/lang/et_EE.yml index fa24c5186..d6d99c1fa 100644 --- a/lang/et_EE.yml +++ b/lang/et_EE.yml @@ -84,7 +84,7 @@ et_EE: SilverStripe\Forms\NullableField: IsNullLabel: 'On tühi' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' ei ole number, sellele väljale võib sisestada ainult numbreid' + VALIDATION: "'{value}' ei ole number, sellele väljale võib sisestada ainult numbreid" SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'Sisestage sobivas vormingus kellaaeg ({format})' SilverStripe\ORM\DataObject: diff --git a/lang/fi.yml b/lang/fi.yml index eb3fed36b..94c2e7813 100644 --- a/lang/fi.yml +++ b/lang/fi.yml @@ -117,7 +117,7 @@ fi: SilverStripe\Forms\NullableField: IsNullLabel: 'On nolla' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' ei ole numero: tähän kenttään hyväksytään vain numeroita' + VALIDATION: "'{value}' ei ole numero: tähän kenttään hyväksytään vain numeroita" SilverStripe\Forms\TextField: VALIDATEMAXLENGTH: '{name}-arvo ei voi ylittää {maxLength} merkin määrää.' SilverStripe\Forms\TimeField: diff --git a/lang/fi_FI.yml b/lang/fi_FI.yml index aae1c3b16..0a9462341 100644 --- a/lang/fi_FI.yml +++ b/lang/fi_FI.yml @@ -136,7 +136,7 @@ fi_FI: SilverStripe\Forms\NullableField: IsNullLabel: 'On nolla' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' ei ole numero: tähän kenttään hyväksytään vain numeroita' + VALIDATION: "'{value}' ei ole numero: tähän kenttään hyväksytään vain numeroita" SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'Ole hyvä ja kirjaa päivämäärä sallitussa muodossa ({format})' SilverStripe\ORM\DataObject: diff --git a/lang/fr.yml b/lang/fr.yml index 885d97c04..374827ee8 100644 --- a/lang/fr.yml +++ b/lang/fr.yml @@ -6,8 +6,8 @@ fr: EDITINFO: 'Éditer ce fichier' REMOVE: Retirer SilverStripe\Control\ChangePasswordEmail_ss: - CHANGEPASSWORDFOREMAIL: 'Le mot de passe du compte correspondant à l''adresse {email} a été modifié. Si vous n''avez pas modifié votre mot de passe, merci de le changer à l''aide du lien suivant' - CHANGEPASSWORDTEXT1: 'Votre mot de passe est maintenant' + CHANGEPASSWORDFOREMAIL: "Le mot de passe du compte correspondant à l'adresse {email} a été modifié. Si vous n'avez pas modifié votre mot de passe, merci de le changer à l'aide du lien suivant" + CHANGEPASSWORDTEXT1: 'Vous avez modifié votre mot de passe pour' CHANGEPASSWORDTEXT3: 'Changer le mot de passe' HELLO: Bonjour SilverStripe\Control\Email\ForgotPasswordEmail_ss: @@ -15,6 +15,9 @@ fr: TEXT1: 'Voici votre' TEXT2: 'Lien de réinitialisation de mot de passe' TEXT3: pour + SilverStripe\Control\Middleware\ConfirmationMiddleware\Url: + CONFIRMATION_DESCRIPTION: 'L''url est : "{url}"' + CONFIRMATION_NAME: "L'url est protégée" SilverStripe\Control\RequestProcessor: INVALID_REQUEST: 'Requête invalide' REQUEST_ABORTED: 'Requête non aboutie' @@ -26,24 +29,24 @@ fr: SilverStripe\Forms\ConfirmedPasswordField: ATLEAST: 'Le mot de passe doit comporter au moins {min} caractères.' BETWEEN: 'Le mot de passe doit comporter entre {min} et {max} caractères.' - CURRENT_PASSWORD_ERROR: 'Le mot de passe que vous avez saisi n''est pas correct' + CURRENT_PASSWORD_ERROR: "Le mot de passe que vous avez saisi n'est pas correct" CURRENT_PASSWORD_MISSING: 'Vous devez saisir votre mot de passe actuel.' LOGGED_IN_ERROR: 'Vous devez être connecté pour pouvoir changer votre mot de passe' MAXIMUM: 'Le mot de passe ne doit pas comporter plus de {max} caractères.' SHOWONCLICKTITLE: 'Changer le mot de passe' SilverStripe\Forms\DateField: NOTSET: 'non renseigné' - TODAY: 'aujourd''hui' + TODAY: "aujourd'hui" VALIDDATEFORMAT2: 'Saisissez une date au format valide ({format})' VALIDDATEMAXDATE: 'La date doit être antérieure ou égale à celle autorisée ({date})' VALIDDATEMINDATE: 'La date doit être postérieure ou égale à celle autorisée ({date})' SilverStripe\Forms\DatetimeField: VALIDDATEMAXDATETIME: 'La date doit être antérieure ou égale à celle autorisée ({datetime})' - VALIDDATETIMEFORMAT: 'Saisissez un format de date et d''heure valide ({format})' + VALIDDATETIMEFORMAT: "Saisissez un format de date et d'heure valide ({format})" VALIDDATETIMEMINDATE: 'La date doit être postérieure ou égale à celle autorisée ({datetime})' SilverStripe\Forms\DropdownField: CHOOSE: (Choisir) - SOURCE_VALIDATION: 'Merci de choisir une valeur parmi celles proposées dans la liste. {value} n''est pas une option valide' + SOURCE_VALIDATION: "Merci de choisir une valeur parmi celles proposées dans la liste. {value} n'est pas une option valide" SilverStripe\Forms\EmailField: VALIDATION: 'Merci de saisir une adresse email' SilverStripe\Forms\FileUploadReceiver: @@ -83,7 +86,7 @@ fr: SilverStripe\Forms\GridField\GridFieldDeleteAction: Delete: Supprimer DeletePermissionsFailure: 'Vous n’avez pas les autorisations pour supprimer' - EditPermissionsFailure: 'Pas de permissions pour délier l''enregistrement' + EditPermissionsFailure: "Pas de permissions pour délier l'enregistrement" UnlinkRelation: Séparer SilverStripe\Forms\GridField\GridFieldDetailForm: CancelBtn: Annuler @@ -93,10 +96,13 @@ fr: Deleted: '{type} {name} supprimés' Save: Enregistrer Saved: '{name} {link} sauvegardé' + SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest: + SAVEDUP: 'Sauvegardé avec succès.' + SAVETOASTMESSAGE: 'Sauvegardé {type} "{title}" avec succès.' SilverStripe\Forms\GridField\GridFieldEditButton: EDIT: Éditer SilverStripe\Forms\GridField\GridFieldGroupDeleteAction: - UnlinkSelfFailure: 'Impossible de retirer votre propre profil de ce groupe, vous perdriez vos droits d''administration' + UnlinkSelfFailure: "Impossible de retirer votre propre profil de ce groupe, vous perdriez vos droits d'administration" SilverStripe\Forms\GridField\GridFieldPaginator: OF: de View: Vue @@ -112,6 +118,8 @@ fr: IsNullLabel: 'Est Null' SilverStripe\Forms\NumericField: VALIDATION: "«\_{value}\_» n’est pas un nombre, seul type de donnée acceptée dans ce champ " + SilverStripe\Forms\SearchableDropdownTrait: + SELECT: Choisir... SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'Merci de saisir un format de date valide ({format})' SilverStripe\Forms\UrlField: @@ -136,7 +144,7 @@ fr: many: '{count} heures' one: '{count} heure' other: '{count} heures' - LessThanMinuteAgo: 'moins d''une minute' + LessThanMinuteAgo: "moins d'une minute" MINUTES_SHORT_PLURALS: many: '{count} min.' one: '{count} min.' @@ -165,14 +173,14 @@ fr: SilverStripe\ORM\ValidationException: DEFAULT_ERROR: 'Erreur de validation' SilverStripe\Security\BasicAuth: - ENTERINFO: 'Merci d''entrer un identifiant et un mot de passe.' - ERRORNOTADMIN: 'Cet utilisateur n''est pas un administrateur.' + ENTERINFO: "Merci d'entrer un identifiant et un mot de passe." + ERRORNOTADMIN: "Cet utilisateur n'est pas un administrateur." ERRORNOTREC: 'Identifiant et/ou mot de passe non reconnus' SilverStripe\Security\CMSMemberLoginForm: PASSWORDEXPIRED: '
Votre mot de passe a expiré. Merci d''en choisir un nouveau.
' SilverStripe\Security\CMSSecurity: INVALIDUSER: 'Utilisateur non valide. Merci de vous authentifier de nouveau ici pour poursuivre.
' - LOGIN_MESSAGE: 'Votre session a expiré pour cause d''inactivité
' + LOGIN_MESSAGE: "Votre session a expiré pour cause d'inactivité
" LOGIN_TITLE: 'Retournez là où vous en étiez en vos connectant de nouveau' SUCCESS: Succès SUCCESSCONTENT: 'Connexion réussie. Si vous n''êtes pas automatiquement redirigé cliquez ici
' @@ -229,43 +237,46 @@ fr: BUTTONLOGIN: 'Se connecter' BUTTONLOGINOTHER: 'Se connecter avec un identifiant différent' BUTTONLOGOUT: Déconnexion - BUTTONLOSTPASSWORD: 'J''ai perdu mon mot de passe' + BUTTONLOSTPASSWORD: "J'ai perdu mon mot de passe" CONFIRMNEWPASSWORD: 'Confirmer nouveau mot de passe' CONFIRMPASSWORD: 'Confirmer Mot De Passe' CURRENT_PASSWORD: 'Mot de passe actuel' EDIT_PASSWORD: 'Nouveau mot de passe' EMPTYNEWPASSWORD: 'Le champs nouveau mot de passe ne peut être vide, merci de réessayer' ENTEREMAIL: 'Veuillez entrer une adresse email pour obtenir un lien de réinitialisation du mot de passe.' - ERRORLOCKEDOUT2: 'Votre compte a été temporairement désactivé en raison d''un nombre trop élevé d''échecs d''identification. Veuillez réessayer dans {count} minutes.' + ERRORLOCKEDOUT2: "Votre compte a été temporairement désactivé en raison d'un nombre trop élevé d'échecs d'identification. Veuillez réessayer dans {count} minutes." ERRORNEWPASSWORD: 'Vous avez entré votre nouveau mot de passe différemment, réessayez' ERRORPASSWORDNOTMATCH: 'Votre actuel mot de passe ne correspond pas, merci de réessayer' ERRORWRONGCRED: 'Il semble que ce ne soit pas le bon email ou mot de passe. Merci de réessayer.' FIRSTNAME: Prénom - INTERFACELANG: 'Langue de l''interface' + INTERFACELANG: "Langue de l'interface" + KEEP_ME_SIGNED_IN: 'Gardez-moi connecté pendant {count} jours' LOGGEDINAS: 'Vous êtes connecté en tant que {name}.' NEWPASSWORD: 'Nouveau mot de passe' PASSWORD: 'Mot de passe' - PASSWORDEXPIRED: 'Votre mot de passe a expiré. Merci d''en choisir un nouveau.' + PASSWORDEXPIRED: "Votre mot de passe a expiré. Merci d'en choisir un nouveau." PLURALNAME: Membres PLURALS: many: '{count} membres' one: 'Un membre' other: '{count} membres' + RequiresPasswordChangeOnNextLogin: 'Changement de mot de passe requis lors de la prochaine connexion' SINGULARNAME: Membre SUBJECTPASSWORDCHANGED: 'Votre mot de passe a été changé' SUBJECTPASSWORDRESET: 'Lien pour modifier votre mot de passe' SURNAME: 'Nom de famille' - VALIDATIONADMINLOSTACCESS: 'Impossible de retirer tous les groupes d''administrateur à partir de votre profil' + VALIDATIONADMINLOSTACCESS: "Impossible de retirer tous les groupes d'administrateur à partir de votre profil" ValidationIdentifierFailed: 'Impossible de réenregistrer le membre nº {id} avec un identifiant identique ({name} = {value}))' + WELCOMEBACK: 'Bienvenue, {firstname}' YOUROLDPASSWORD: 'Votre ancien mot de passe' belongs_many_many_Groups: Groupes db_FirstName: Prénom - db_Locale: 'Langue de l''Interface' - db_LockedOutUntil: 'Verrouillé jusqu''à' + db_Locale: "Langue de l'Interface" + db_LockedOutUntil: "Verrouillé jusqu'à" db_Password: 'Mot de passe' - db_PasswordExpiry: 'Date d''expiration du mot de passe' + db_PasswordExpiry: "Date d'expiration du mot de passe" db_Surname: 'Nom de famille' - db_URLSegment: 'Segment d''URL' + db_URLSegment: "Segment d'URL" SilverStripe\Security\MemberAuthenticator\CMSMemberLoginForm: AUTHENTICATORNAME: 'Formulaire de connexion pour un utilisateur du CMS' BUTTONFORGOTPASSWORD: 'Mot de passe oublié' @@ -273,7 +284,7 @@ fr: BUTTONLOGOUT: 'Se déconnecter' SilverStripe\Security\MemberAuthenticator\MemberAuthenticator: ERRORWRONGCRED: 'Les renseignements fournis semblent incorrects. Merci de réessayer.' - NoPassword: 'Ce membre n''a pas de mot de passe' + NoPassword: "Ce membre n'a pas de mot de passe" SilverStripe\Security\MemberAuthenticator\MemberLoginForm: AUTHENTICATORNAME: 'Email & Mot de passe' SilverStripe\Security\MemberPassword: @@ -293,7 +304,7 @@ fr: AdminGroup: Administrateur CMS_ACCESS_CATEGORY: 'Accès au CMS' CONTENT_CATEGORY: 'Permissions de contenu' - FULLADMINRIGHTS: 'Droits d''administration complets' + FULLADMINRIGHTS: "Droits d'administration complets" FULLADMINRIGHTS_HELP: 'Prévaut sur toutes les autres autorisations assignées.' PERMISSIONS_CATEGORY: 'Rôles et autorisations d’accès' PLURALS: @@ -320,13 +331,13 @@ fr: db_OnlyAdminCanApply: 'Limité aux administrateurs' db_Title: Titre SilverStripe\Security\PermissionRoleCode: - PLURALNAME: 'Codes d''autorisations liés au rôle' + PLURALNAME: "Codes d'autorisations liés au rôle" PLURALS: - many: '{count} codes d''autorisation liés au rôle' - one: 'Un code d''autorisation lié au rôle' - other: '{count} codes d''autorisation liés au rôle' + many: "{count} codes d'autorisation liés au rôle" + one: "Un code d'autorisation lié au rôle" + other: "{count} codes d'autorisation liés au rôle" PermsError: 'Impossible d''attribuer le code "{code}" (requiert un accès en tant qu''administrateur)' - SINGULARNAME: 'Code d''autorisation lié au rôle' + SINGULARNAME: "Code d'autorisation lié au rôle" has_one_Role: Rôle SilverStripe\Security\RememberLoginHash: PLURALNAME: 'Signatures de mot de passe' @@ -337,15 +348,17 @@ fr: SINGULARNAME: 'Signature de mot de passe' has_one_Member: Membre SilverStripe\Security\Security: - ALREADYLOGGEDIN: 'Vous n''avez pas accès à cette page. Si un autre de vos identifiants vous permet d''accéder à cette page, merci de vous reconnecter ci-dessous en l''utilisant.' + ALREADYLOGGEDIN: "Vous n'avez pas accès à cette page. Si un autre de vos identifiants vous permet d'accéder à cette page, merci de vous reconnecter ci-dessous en l'utilisant." BUTTONSEND: 'Envoyer moi le lien pour modifier le mot de passe' CHANGEPASSWORDBELOW: 'Vous pouvez modifier votre mot de passe ci-dessous.' CHANGEPASSWORDHEADER: 'Modifier votre mot de passe' CONFIRMLOGOUT: 'Merci de cliquer le bouton ci-dessous pour confirmer que vous souhaitez vous déconnecter.' - ENTERNEWPASSWORD: 'Entrer un nouveau mot de passe s''il vous plaît.' + ENTERNEWPASSWORD: "Entrer un nouveau mot de passe s'il vous plaît." ERRORPASSWORDPERMISSION: 'Vous devez être connecté pour modifier votre mot de passe !' LOGIN: 'Se connecter' LOGOUT: 'Se déconnecter' LOSTPASSWORDHEADER: 'Mot de passe oublié' NOTEPAGESECURED: 'Cette page est sécurisée. Entrez vos identifiants ci-dessous et vous pourrez y avoir accès.' NOTERESETPASSWORD: 'Entrez votre adresse email et nous vous enverrons un lien pour modifier votre mot de passe' + PASSWORDRESETSENTHEADER: 'Le lien de réinitialisation du mot de passe a été envoyé' + PASSWORDRESETSENTTEXT: "Nous vous remercions. Un lien de réinitialisation a été envoyé, à condition qu'un compte existe pour cette adresse électronique." diff --git a/lang/id.yml b/lang/id.yml index 908364c1f..e3a6649c8 100644 --- a/lang/id.yml +++ b/lang/id.yml @@ -31,7 +31,7 @@ id: VALIDDATEMINDATE: 'Tanggal Anda harus lebih baru atau sama dengan tanggal minimum ({date})' SilverStripe\Forms\DropdownField: CHOOSE: (Pilih) - SOURCE_VALIDATION: 'Mohon pilih nilai dari daftar yang ada. ''{value}'' bukan pilihan valid' + SOURCE_VALIDATION: "Mohon pilih nilai dari daftar yang ada. '{value}' bukan pilihan valid" SilverStripe\Forms\EmailField: VALIDATION: 'Mohon isikan alamat email' SilverStripe\Forms\FileUploadReceiver: @@ -88,7 +88,7 @@ id: SilverStripe\Forms\NullableField: IsNullLabel: N/A SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' bukan angka, hanya angka yang dapat diterima isian ini' + VALIDATION: "'{value}' bukan angka, hanya angka yang dapat diterima isian ini" SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'Isikan format waktu yang benar ({format})' SilverStripe\Forms\UrlField: diff --git a/lang/id_ID.yml b/lang/id_ID.yml index e7420d595..07aac5daa 100644 --- a/lang/id_ID.yml +++ b/lang/id_ID.yml @@ -29,7 +29,7 @@ id_ID: VALIDDATEMINDATE: 'Tanggal Anda harus lebih baru atau sama dengan tanggal minimum ({date})' SilverStripe\Forms\DropdownField: CHOOSE: (Pilih) - SOURCE_VALIDATION: 'Mohon pilih nilai dari daftar yang ada. ''{value}'' bukan pilihan valid' + SOURCE_VALIDATION: "Mohon pilih nilai dari daftar yang ada. '{value}' bukan pilihan valid" SilverStripe\Forms\EmailField: VALIDATION: 'Mohon isikan alamat email' SilverStripe\Forms\FileUploadReceiver: @@ -86,7 +86,7 @@ id_ID: SilverStripe\Forms\NullableField: IsNullLabel: N/A SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' bukan angka, hanya angka yang dapat diterima isian ini' + VALIDATION: "'{value}' bukan angka, hanya angka yang dapat diterima isian ini" SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'Isikan format waktu yang benar ({format})' SilverStripe\ORM\DataObject: diff --git a/lang/it.yml b/lang/it.yml index 13442ea20..81558df26 100644 --- a/lang/it.yml +++ b/lang/it.yml @@ -7,20 +7,20 @@ it: EDITINFO: 'Modifica questo file' REMOVE: Elimina SilverStripe\Control\ChangePasswordEmail_ss: - CHANGEPASSWORDFOREMAIL: 'La password per l''account con l''email {email} è cambiata. Se non l''hai ancora fatto, prego cambiare la password usando il link sottostante' + CHANGEPASSWORDFOREMAIL: "La password per l'account con l'email {email} è cambiata. Se non l'hai ancora fatto, prego cambiare la password usando il link sottostante" CHANGEPASSWORDTEXT1: 'Hai cambiato la password per' CHANGEPASSWORDTEXT3: 'Cambia password' HELLO: Salve SilverStripe\Control\Email\ForgotPasswordEmail_ss: HELLO: Salve TEXT1: 'Questo è il tuo' - TEXT2: 'link per l''azzeramento della password' + TEXT2: "link per l'azzeramento della password" TEXT3: per SilverStripe\Control\Middleware\ConfirmationMiddleware\GetParameter: CONFIRMATION_NAME: '"{key}" parametro GET' SilverStripe\Control\Middleware\ConfirmationMiddleware\Url: CONFIRMATION_DESCRIPTION: 'L''URL è: "{url}"' - CONFIRMATION_NAME: 'L''URL è protetto' + CONFIRMATION_NAME: "L'URL è protetto" SilverStripe\Control\Middleware\ConfirmationMiddleware\UrlPathStartswith: CONFIRMATION_DESCRIPTION: 'L''URL completo è: "{url}"' CONFIRMATION_NAME: 'L''URL comincia con "{path}"' @@ -28,7 +28,7 @@ it: INVALID_REQUEST: 'Richiesta non valida' REQUEST_ABORTED: 'Richiesta annullata' SilverStripe\Dev\DevConfirmationController: - INFO_DESCRIPTION: 'Confermare l''operazione potenzialmente pericolosa' + INFO_DESCRIPTION: "Confermare l'operazione potenzialmente pericolosa" INFO_TITLE: 'Conferma di Sicurezza' SilverStripe\Forms\CheckboxField: YESANSWER: Sì @@ -55,7 +55,7 @@ it: SilverStripe\Forms\DropdownField: CHOOSE: (Scegli) SEARCH_OR_CHOOSE_MODEL: '(Cercare o scegliere {name})' - SOURCE_VALIDATION: 'Per favore selezionare un valore tra quelli forniti. {value} non è un''opzione valida' + SOURCE_VALIDATION: "Per favore selezionare un valore tra quelli forniti. {value} non è un'opzione valida" SilverStripe\Forms\EmailField: VALIDATION: 'Inserisci un indirizzo e-mail' SilverStripe\Forms\FileUploadReceiver: @@ -132,17 +132,17 @@ it: SilverStripe\Forms\MoneyField: FIELDLABELAMOUNT: Importo FIELDLABELCURRENCY: Valuta - INVALID_CURRENCY: 'La valuta {currency} non è nell''elenco delle valute disponibili' + INVALID_CURRENCY: "La valuta {currency} non è nell'elenco delle valute disponibili" SilverStripe\Forms\MultiSelectField: - SOURCE_VALIDATION: 'Per favore selezionare un valore tra quelli forniti. È stata fornita l''opzione non valida {value}' + SOURCE_VALIDATION: "Per favore selezionare un valore tra quelli forniti. È stata fornita l'opzione non valida {value}" SilverStripe\Forms\NullableField: IsNullLabel: 'è nullo.' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' non è un numero, solo numeri possono essere accettati per questo campo' + VALIDATION: "'{value}' non è un numero, solo numeri possono essere accettati per questo campo" SilverStripe\Forms\TextField: VALIDATEMAXLENGTH: 'Il valore di {name} non deve superare i {maxLength} caratteri di lunghezza' SilverStripe\Forms\TimeField: - VALIDATEFORMAT: 'Inserisci un formato d''ora valido ({format})' + VALIDATEFORMAT: "Inserisci un formato d'ora valido ({format})" SilverStripe\ORM\DataObject: PLURALNAME: 'Data Object' PLURALS: @@ -204,7 +204,7 @@ it: SUCCESSCONTENT: 'Accesso eseguito. Se non sarai ridirezionato automaticamente, cliccare qui
' SUCCESS_TITLE: 'Login completato' SilverStripe\Security\Confirmation\Form: - CONFIRM: 'Esegui l''azione' + CONFIRM: "Esegui l'azione" EMPTY_TITLE: 'Nulla da confermare' REFUSE: Annulla SilverStripe\Security\Confirmation\Handler: @@ -250,12 +250,12 @@ it: Email: 'Indirizzo e-mail' EmailHashed: 'Indirizzo email (hash)' IP: 'Indirizzo IP' - PLURALNAME: 'Tentativi d''accesso' + PLURALNAME: "Tentativi d'accesso" PLURALS: - many: '{count} tentativi d''accesso' - one: 'Un tentativo d''accesso' - other: '{count} tentativi d''accesso' - SINGULARNAME: 'Tentativo d''accesso' + many: "{count} tentativi d'accesso" + one: "Un tentativo d'accesso" + other: "{count} tentativi d'accesso" + SINGULARNAME: "Tentativo d'accesso" Status: Stato db_Status: Stato has_one_Member: Utente @@ -277,7 +277,7 @@ it: ERRORPASSWORDNOTMATCH: 'La tua password attuale non corrisponde, per favore prova ancora' ERRORWRONGCRED: 'I dettagli forniti non sembrano corretti. Per favore riprovare.' FIRSTNAME: Nome - INTERFACELANG: 'Lingua dell''interfaccia' + INTERFACELANG: "Lingua dell'interfaccia" KEEP_ME_SIGNED_IN: 'Lasciami autenticato per {count} giorni' KEEP_ME_SIGNED_IN_TOOLTIP: 'Rimarrai autenticato su questo dispositivo per {count} giorni. Usa questa funzionalità solo se il dispositivo che stai usando è sicuro.' LOGGEDINAS: 'Sei collegato come {name}.' @@ -294,7 +294,7 @@ it: SURNAME: Cognome VALIDATIONADMINLOSTACCESS: 'Non è possibile rimuovere tutti i gruppi admin dal tuo profilo' VALIDATIONMEMBEREXISTS: 'Esiste già un utente con lo stesso {identifier}' - ValidationIdentifierFailed: 'Non posso sovrascrivere l''utente esistente #{id} con identificatore identico ({name} = {value}))' + ValidationIdentifierFailed: "Non posso sovrascrivere l'utente esistente #{id} con identificatore identico ({name} = {value}))" WELCOMEBACK: 'Bentornato, {firstname}' YOUROLDPASSWORD: 'La tua vecchia password' belongs_many_many_Groups: Gruppi @@ -331,7 +331,7 @@ it: CONTENT_CATEGORY: 'Permessi sui contenuti' FULLADMINRIGHTS: 'Diritti di amministrazione' FULLADMINRIGHTS_HELP: 'Implica e annulla tutti gli altri permessi assegnati.' - PERMISSIONS_CATEGORY: 'Ruoli e permessi d''accesso' + PERMISSIONS_CATEGORY: "Ruoli e permessi d'accesso" PLURALNAME: Permessi PLURALS: many: '{count} Permessi' @@ -347,7 +347,7 @@ it: FromRole: 'ereditato dal ruolo "{title}"' FromRoleOnGroup: 'ereditato dal ruolo "{roletitle}" nel gruppo "{grouptitle}"' SilverStripe\Security\PermissionRole: - OnlyAdminCanApply: 'Solo l''amministratore può applicare' + OnlyAdminCanApply: "Solo l'amministratore può applicare" PLURALNAME: Ruoli PLURALS: many: '{count} Ruoli' @@ -356,7 +356,7 @@ it: SINGULARNAME: Ruolo Title: Titolo belongs_many_many_Groups: Gruppi - db_OnlyAdminCanApply: 'Solo l''amministratore può applicare' + db_OnlyAdminCanApply: "Solo l'amministratore può applicare" db_Title: Titolo SilverStripe\Security\PermissionRoleCode: PLURALNAME: 'Codici di ruolo' diff --git a/lang/ja.yml b/lang/ja.yml index 909fa8569..5ea88709b 100644 --- a/lang/ja.yml +++ b/lang/ja.yml @@ -9,7 +9,7 @@ ja: HELLO: こんにちわ! SilverStripe\Control\Email\ForgotPasswordEmail_ss: HELLO: こんにちわ! - TEXT1: 'ここ''貴方の' + TEXT1: "ここ'貴方の" TEXT2: パスワードリセットのリンク TEXT3: は SilverStripe\Control\RequestProcessor: @@ -83,7 +83,7 @@ ja: SilverStripe\Forms\NullableField: IsNullLabel: NULLである SilverStripe\Forms\NumericField: - VALIDATION: '''{value}''は数値ではありません。このフィールドには数値のみが入力できます。' + VALIDATION: "'{value}'は数値ではありません。このフィールドには数値のみが入力できます。" SilverStripe\Forms\TimeField: VALIDATEFORMAT: '正しい時間フォーマット{{format}}を入力してください' SilverStripe\ORM\DataObject: diff --git a/lang/ja_JP.yml b/lang/ja_JP.yml index 06812cdd4..f15586c76 100644 --- a/lang/ja_JP.yml +++ b/lang/ja_JP.yml @@ -8,7 +8,7 @@ ja_JP: HELLO: こんにちわ! SilverStripe\Control\Email\ForgotPasswordEmail_ss: HELLO: こんにちわ! - TEXT1: 'ここ''貴方の' + TEXT1: "ここ'貴方の" TEXT2: パスワードリセットのリンク TEXT3: は SilverStripe\Control\RequestProcessor: @@ -61,7 +61,7 @@ ja_JP: SilverStripe\Forms\NullableField: IsNullLabel: NULLである SilverStripe\Forms\NumericField: - VALIDATION: '''{value}''は数値ではありません。このフィールドには数値のみが入力できます。' + VALIDATION: "'{value}'は数値ではありません。このフィールドには数値のみが入力できます。" SilverStripe\Forms\TimeField: VALIDATEFORMAT: '正しい時間フォーマット{{format}}を入力してください' SilverStripe\ORM\DataObject: diff --git a/lang/lt.yml b/lang/lt.yml index 5c1926a20..e498ceb36 100644 --- a/lang/lt.yml +++ b/lang/lt.yml @@ -32,7 +32,7 @@ lt: VALIDDATEMINDATE: 'Data privalo būti naujesnė arba lygi anksčiausiai galimai datai ({date})' SilverStripe\Forms\DropdownField: CHOOSE: (Pasirinkti) - SOURCE_VALIDATION: 'Prašome pasirinkti reikšmę iš pateikto sąrašo. ''{value}'' yra negalima reikšmė.' + SOURCE_VALIDATION: "Prašome pasirinkti reikšmę iš pateikto sąrašo. '{value}' yra negalima reikšmė." SilverStripe\Forms\EmailField: VALIDATION: 'Prašome suvesti el. pašto adresą' SilverStripe\Forms\FileUploadReceiver: @@ -93,9 +93,9 @@ lt: SilverStripe\Forms\NullableField: IsNullLabel: Tuščias SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' nėra skaičius, prašome įvesti skaičių' + VALIDATION: "'{value}' nėra skaičius, prašome įvesti skaičių" SilverStripe\Forms\TextField: - VALIDATEMAXLENGTH: '''{name}'' reikšmė negali būti ilgesnė nei {maxLength} simbolių ilgio.' + VALIDATEMAXLENGTH: "'{name}' reikšmė negali būti ilgesnė nei {maxLength} simbolių ilgio." SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'Prašome suvesti laiką teisingu formatu ({format})' SilverStripe\Forms\UrlField: diff --git a/lang/mi.yml b/lang/mi.yml index 4d2a39152..32481c6a2 100644 --- a/lang/mi.yml +++ b/lang/mi.yml @@ -88,7 +88,7 @@ mi: SilverStripe\Forms\NullableField: IsNullLabel: 'He Kore Tēnei' SilverStripe\Forms\NumericField: - VALIDATION: 'Ehara te ''{value}'' i te tau, ka taea ngā tau anake ki tēnei āpure' + VALIDATION: "Ehara te '{value}' i te tau, ka taea ngā tau anake ki tēnei āpure" SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'Tāurua he hōputu wā tika ({format})' SilverStripe\ORM\DataObject: diff --git a/lang/nb.yml b/lang/nb.yml index 2127c6ca3..63403d243 100644 --- a/lang/nb.yml +++ b/lang/nb.yml @@ -86,7 +86,7 @@ nb: SilverStripe\Forms\NullableField: IsNullLabel: 'Er tom' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' er ikke et tall, kun tall aksepteres i dette feltet' + VALIDATION: "'{value}' er ikke et tall, kun tall aksepteres i dette feltet" SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'Vennligst skriv inn et gyldig tidsformat ({format}]' SilverStripe\ORM\DataObject: diff --git a/lang/nl.yml b/lang/nl.yml index 102345ecc..2fb4b5005 100644 --- a/lang/nl.yml +++ b/lang/nl.yml @@ -135,7 +135,7 @@ nl: SilverStripe\Forms\NullableField: IsNullLabel: 'Is null' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' is geen getal, enkel getallen worden door dit veld geaccepteerd' + VALIDATION: "'{value}' is geen getal, enkel getallen worden door dit veld geaccepteerd" SilverStripe\Forms\TextField: VALIDATEMAXLENGTH: 'De waarde voor {name} mag niet langer zijn dan {maxLength} tekens.' SilverStripe\Forms\TimeField: diff --git a/lang/pa.yml b/lang/pa.yml index 7ff43d462..b613c78ad 100644 --- a/lang/pa.yml +++ b/lang/pa.yml @@ -37,7 +37,7 @@ pa: db_Email: ਇਮੇਲ db_Surname: ਗੋਤ SilverStripe\Security\Security: - ALREADYLOGGEDIN: 'You don''t have access to this page. If you have another account that can access that page, you can log in below.' + ALREADYLOGGEDIN: "You don't have access to this page. If you have another account that can access that page, you can log in below." CHANGEPASSWORDBELOW: 'ਤੁਸੀਂ ਆਪਣਾ password ਹੇਠਾਂ ਬਦਲ ਸਕਦੇ ਹੋ।ੋ' CHANGEPASSWORDHEADER: 'password ਬਦਲੋ ' ENTERNEWPASSWORD: 'ਿਕ੍ਰਪਾ ਕਰਕੇ ਇੱਕ ਨਵਾਂ password ਪਾਉ।' diff --git a/lang/pl.yml b/lang/pl.yml index 6c5e1af74..e446ff937 100644 --- a/lang/pl.yml +++ b/lang/pl.yml @@ -139,7 +139,7 @@ pl: SilverStripe\Forms\NullableField: IsNullLabel: 'Jest Pusty' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' nie jest liczbą, to pole przyjmuje tylko liczby' + VALIDATION: "'{value}' nie jest liczbą, to pole przyjmuje tylko liczby" SilverStripe\Forms\TextField: VALIDATEMAXLENGTH: 'Wartość {name} nie może przekraczać {maxLength} znaków długości' SilverStripe\Forms\TimeField: @@ -252,6 +252,7 @@ pl: Sort: 'Kolejność Sortowania' ValidationIdentifierAlreadyExists: 'Grupa ({group}) już istnieje z tym samym {identifier}' db_Description: Opis + db_Sort: Sortuj db_Title: Tytuł has_many_Groups: Grupy has_many_Permissions: Zezwolenia @@ -343,7 +344,7 @@ pl: PREVPASSWORD: 'Użyłeś już tego hasła wcześniej, proszę wybrać nowe' TOOSHORT: 'Hasło jest za krótkie, proszę podać {minimum} znaków lub więcej' SilverStripe\Security\Permission: - CMS_ACCESS_CATEGORY: 'Dostęp do CMS''a' + CMS_ACCESS_CATEGORY: "Dostęp do CMS'a" CONTENT_CATEGORY: 'Uprawnienie edycji treści' FULLADMINRIGHTS: 'Pełne prawa administracyjne' FULLADMINRIGHTS_HELP: 'Zatwierdza i nadpisuje wszystkie istniejące uprawnienia' @@ -410,6 +411,6 @@ pl: NOTERESETLINKINVALID: 'Link resetujący hasło wygasł lub jest nieprawidłowy.
Możesz poprosić o nowy tutaj lub zmień swoje hasło po zalogowaniu się.
' NOTERESETPASSWORD: 'Wpisz adres e-mail, na który mamy wysłać link gdzie możesz zresetować swoje hasło' PASSWORDRESETSENTHEADER: 'Link resetowania hasła wysłany' - PASSWORDRESETSENTTEXT: 'Dziękujemy! Link resetujący hasło został wysłany do ''{email}'', o ile konto użytkownika dla takiego e-maila istnieje.' + PASSWORDRESETSENTTEXT: "Dziękujemy! Link resetujący hasło został wysłany do '{email}', o ile konto użytkownika dla takiego e-maila istnieje." SilverStripe\View\Shortcodes\EmbedShortcodeProvider: INVALID_URL: 'Podczas ładowania pliku wystąpił problem.' diff --git a/lang/ru.yml b/lang/ru.yml index 5353b0589..3f7a3d34b 100644 --- a/lang/ru.yml +++ b/lang/ru.yml @@ -109,7 +109,7 @@ ru: SilverStripe\Forms\NullableField: IsNullLabel: Недействительно SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' - не числовое значение; для этого поля допустимы только числовые значения' + VALIDATION: "'{value}' - не числовое значение; для этого поля допустимы только числовые значения" SilverStripe\Forms\TextField: VALIDATEMAXLENGTH: 'Значение для {name} не должно превышать {maxLength} символов' SilverStripe\Forms\TimeField: diff --git a/lang/sk.yml b/lang/sk.yml index 203e9fab8..1d0c2c5ab 100644 --- a/lang/sk.yml +++ b/lang/sk.yml @@ -25,9 +25,22 @@ sk: SilverStripe\Control\RequestProcessor: INVALID_REQUEST: 'Neplatná požiadavka' REQUEST_ABORTED: 'Požiadavka prerušená' + SilverStripe\Dev\DevBuildController: + CAN_DEV_BUILD_DESCRIPTION: 'Môže vykonať /dev/build' + CAN_DEV_BUILD_HELP: 'Môže vykonať príkaz build (/dev/build).' + SilverStripe\Dev\DevConfigController: + CAN_DEV_CONFIG_DESCRIPTION: 'Môže vidieť /dev/config' + CAN_DEV_CONFIG_HELP: 'Môže zobraziť všetku konfiguráciu aplikácie (/dev/config).' SilverStripe\Dev\DevConfirmationController: INFO_DESCRIPTION: 'Potvrďte potenciálne nebezpečnú operáciu' INFO_TITLE: 'Bezpečnostné potvrdenie' + SilverStripe\Dev\DevelopmentAdmin: + ALL_DEV_ADMIN_DESCRIPTION: 'Môže zobraziť a vykonať všetky koncové body /dev' + ALL_DEV_ADMIN_HELP: 'Môže zobraziť a vykonať všetky koncové body /dev' + PERMISSIONS_CATEGORY: 'Dev povolenia' + SilverStripe\Dev\TaskRunner: + BUILDTASK_CAN_RUN_DESCRIPTION: 'Môže zobraziť a vykonať všetky /dev/tasks.' + BUILDTASK_CAN_RUN_HELP: 'Môže zobraziť a vykonať všetky úlohy zostavenia (/dev/tasks). Toto môže byť stále prepísané individuálnymi oprávneniami pre zobrazenie úloh.' SilverStripe\Forms\CheckboxField: NOANSWER: Nie YESANSWER: Áno @@ -100,7 +113,7 @@ sk: Create: Vytvoriť Delete: Zmazať DeletePermissionsFailure: 'Žiadne oprávnenia zmazať' - Deleted: 'Zmazané {type} {name}' + Deleted: 'Zmazané {type} "{name}"' Save: Uložiť Saved: 'Uložené {name} {link}' SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest: @@ -108,6 +121,8 @@ sk: NEW: 'Pridať nový záznam' NEXT: 'Prejsť na ďalší záznam' PREVIOUS: 'Prejsť na predchádzajúci záznam' + SAVEDUP: 'Úspešne uložené.' + SAVETOASTMESSAGE: '{type} "{title}" úspešne uložené.' ViewPermissionsFailure: 'Zdá sa, že nemáte potrebné oprávnenia na zobrazenie "{ObjectTitle}"' SilverStripe\Forms\GridField\GridFieldEditButton: EDIT: Editovať @@ -135,7 +150,11 @@ sk: SilverStripe\Forms\NullableField: IsNullLabel: 'Je Null' SilverStripe\Forms\NumericField: - VALIDATION: 'Zadaná hodnota ''{value}'' nie je číslo. Iba čísla môžu byť akceptované pre toto pole!' + VALIDATION: "Zadaná hodnota '{value}' nie je číslo. Iba čísla môžu byť akceptované pre toto pole!" + SilverStripe\Forms\SearchableDropdownTrait: + SELECT: Vyberte... + SELECT_OR_TYPE_TO_SEARCH: 'Vyberte alebo zadajte hľadaný výraz...' + TYPE_TO_SEARCH: Hľadať... SilverStripe\Forms\TextField: VALIDATEMAXLENGTH: 'Hodnota pre {name} nesmie prekročiť {maxLength} v dĺžke znakov' SilverStripe\Forms\TimeField: @@ -300,12 +319,13 @@ sk: CURRENT_PASSWORD: 'Terajšie heslo' EDIT_PASSWORD: 'Nové heslo' EMAIL: E-mail + EMAIL_FAILED: 'Vyskytla sa chyba pri pokuse o odoslanie e-mailu s odkazom na obnovenie hesla.' EMPTYNEWPASSWORD: 'Nové heslo nesmie byť prázdne, skúste to prosím znova' ENTEREMAIL: 'Prosím zadajte emailovú adresu pre zaslanie odkazu na resetovanie hesla.' ERRORLOCKEDOUT2: 'Váš účet bol dočasne zablokovaný, kvôli množstvu neúspešných pokusov o prihlásenie. Prosím skúste to znova za {count} minút.' ERRORNEWPASSWORD: 'Zadali ste rozdielne nové heslo, skúste to znovu' ERRORPASSWORDNOTMATCH: 'Vaše súčasné heslo nie je správne, prosím skúste to znovu' - ERRORWRONGCRED: 'Poskytnuté detaily vyzerajú byť nesprávne. Prosím skúste opäť.' + ERRORWRONGCRED: 'Poskytnuté detaily vyzerajú byť nesprávne. Prosím, skúste to znova.' FIRSTNAME: Meno INTERFACELANG: 'Jazyk rozhrania' KEEP_ME_SIGNED_IN: 'Zostať prihlásený na {count} dní' @@ -370,7 +390,7 @@ sk: BUTTONLOGIN: 'Pustite ma späť' BUTTONLOGOUT: 'Odhlásiť sa' SilverStripe\Security\MemberAuthenticator\MemberAuthenticator: - ERRORWRONGCRED: 'Poskytnuté detaily vyzerajú byť nesprávne. Prosím skúste opäť.' + ERRORWRONGCRED: 'Poskytnuté detaily vyzerajú byť nesprávne. Prosím, skúste to znova.' NoPassword: 'Nie je tu heslo pre tohto člena.' SilverStripe\Security\MemberAuthenticator\MemberLoginForm: AUTHENTICATORNAME: 'E-mail & heslo' diff --git a/lang/sl.yml b/lang/sl.yml index 487dd4559..f5384456c 100644 --- a/lang/sl.yml +++ b/lang/sl.yml @@ -139,7 +139,7 @@ sl: SilverStripe\Forms\NullableField: IsNullLabel: 'Prazno polje' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' ni številka. V to polje lahko vnesete samo številke.' + VALIDATION: "'{value}' ni številka. V to polje lahko vnesete samo številke." SilverStripe\Forms\TextField: VALIDATEMAXLENGTH: 'Vrednost za {name} ne sme presegati predpisanega števila znakov ({maxLength}).' SilverStripe\Forms\TimeField: diff --git a/lang/sr.yml b/lang/sr.yml index bd3640523..51f70736d 100644 --- a/lang/sr.yml +++ b/lang/sr.yml @@ -86,7 +86,7 @@ sr: SilverStripe\Forms\NullableField: IsNullLabel: 'је Null' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' није број. Само бројеви могу бити прихваћени за ово поље' + VALIDATION: "'{value}' није број. Само бројеви могу бити прихваћени за ово поље" SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'Унесите исправан формат времена ({format})' SilverStripe\ORM\DataObject: diff --git a/lang/sr@latin.yml b/lang/sr@latin.yml index 0a1d06d78..6f0c2fbfc 100644 --- a/lang/sr@latin.yml +++ b/lang/sr@latin.yml @@ -85,7 +85,7 @@ sr@latin: SilverStripe\Forms\NullableField: IsNullLabel: 'je Null' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' nije broj. Samo brojevi mogu biti prihvaćeni za ovo polje' + VALIDATION: "'{value}' nije broj. Samo brojevi mogu biti prihvaćeni za ovo polje" SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'Unesite ispravan format vremena ({format})' SilverStripe\Forms\UrlField: diff --git a/lang/sr_RS.yml b/lang/sr_RS.yml index 5514395ad..bf64837f0 100644 --- a/lang/sr_RS.yml +++ b/lang/sr_RS.yml @@ -86,7 +86,7 @@ sr_RS: SilverStripe\Forms\NullableField: IsNullLabel: 'је Null' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' није број. Само бројеви могу бити прихваћени за ово поље' + VALIDATION: "'{value}' није број. Само бројеви могу бити прихваћени за ово поље" SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'Унесите исправан формат времена ({format})' SilverStripe\ORM\DataObject: diff --git a/lang/sr_RS@latin.yml b/lang/sr_RS@latin.yml index 0d31bf801..d1f572ef9 100644 --- a/lang/sr_RS@latin.yml +++ b/lang/sr_RS@latin.yml @@ -85,7 +85,7 @@ sr_RS@latin: SilverStripe\Forms\NullableField: IsNullLabel: 'je Null' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' nije broj. Samo brojevi mogu biti prihvaćeni za ovo polje' + VALIDATION: "'{value}' nije broj. Samo brojevi mogu biti prihvaćeni za ovo polje" SilverStripe\Forms\TimeField: VALIDATEFORMAT: 'Unesite ispravan format vremena ({format})' SilverStripe\ORM\DataObject: diff --git a/lang/sv.yml b/lang/sv.yml index c748f0641..bc131363a 100644 --- a/lang/sv.yml +++ b/lang/sv.yml @@ -112,7 +112,7 @@ sv: SilverStripe\Forms\NullableField: IsNullLabel: 'Är NULL' SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' är inget nummer, bara siffror (utan mellanslag) kan accepteras för det här fältet' + VALIDATION: "'{value}' är inget nummer, bara siffror (utan mellanslag) kan accepteras för det här fältet" SilverStripe\Forms\TextField: VALIDATEMAXLENGTH: 'Värdet för {name} får inte överstiga {MaxLength} tecken' SilverStripe\Forms\TimeField: diff --git a/lang/uk.yml b/lang/uk.yml index b119978ee..a92caeeb6 100644 --- a/lang/uk.yml +++ b/lang/uk.yml @@ -51,9 +51,9 @@ uk: SilverStripe\ORM\FieldType\DBEnum: ANY: Будь-який SilverStripe\Security\BasicAuth: - ENTERINFO: 'Будь ласка, введіть ім''я користувача та пароль.' + ENTERINFO: "Будь ласка, введіть ім'я користувача та пароль." ERRORNOTADMIN: 'Цей користувач не є адміністратором.' - ERRORNOTREC: 'Таке ім''я користувача / пароль не існує' + ERRORNOTREC: "Таке ім'я користувача / пароль не існує" SilverStripe\Security\Confirmation\Form: REFUSE: Відмінити SilverStripe\Security\Group: @@ -88,7 +88,7 @@ uk: ENTEREMAIL: 'Введіть, будь-ласка, електронну адресу щоб отримати посилання для відновлення паролю.' ERRORNEWPASSWORD: 'Ви ввели новий пароль із відмінностями, спробуйте знову' ERRORPASSWORDNOTMATCH: 'Ваш теперішній пароль не збігається, будь ласка, повторіть' - FIRSTNAME: 'Ім''я' + FIRSTNAME: "Ім'я" INTERFACELANG: 'Мова Інтерфейсу' NEWPASSWORD: 'Новий пароль' PASSWORD: Пароль diff --git a/lang/zh.yml b/lang/zh.yml index 9b5d376e5..7fbd6b5d4 100644 --- a/lang/zh.yml +++ b/lang/zh.yml @@ -92,7 +92,7 @@ zh: SilverStripe\Forms\NullableField: IsNullLabel: 为空 SilverStripe\Forms\NumericField: - VALIDATION: '''{value}'' 不是数字,该区域只接受数字' + VALIDATION: "'{value}' 不是数字,该区域只接受数字" SilverStripe\Forms\TextField: VALIDATEMAXLENGTH: '{name} 的长度必须至多{maxLength} 个字符。' SilverStripe\Forms\TimeField: diff --git a/src/Core/Path.php b/src/Core/Path.php index ac19475ba..891dc3754 100644 --- a/src/Core/Path.php +++ b/src/Core/Path.php @@ -34,7 +34,7 @@ class Path $fullPath = static::normalise(implode(DIRECTORY_SEPARATOR, $parts)); // Protect against directory traversal vulnerability (OTG-AUTHZ-001) - if (strpos($fullPath ?? '', '..') !== false) { + if ($fullPath === '..' || str_ends_with($fullPath, '/..') || str_contains($fullPath, '../')) { throw new InvalidArgumentException('Can not collapse relative folders'); } diff --git a/src/ORM/DataList.php b/src/ORM/DataList.php index 3dd0f435e..d69c5a789 100644 --- a/src/ORM/DataList.php +++ b/src/ORM/DataList.php @@ -979,7 +979,10 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li return [ $hasOneComponent, 'has_one', - $relationName . 'ID', + [ + 'joinField' => $relationName . 'ID', + 'joinClass' => $hasOneComponent == DataObject::class ? $relationName . 'Class' : null, + ], ]; } $belongsToComponent = $schema->belongsToComponent($parentDataClass, $relationName); @@ -1109,7 +1112,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li private function fetchEagerLoadHasOne( Query|array $parents, - string $hasOneIDField, + array $hasOneRelation, string $relationDataClass, string $relationChain, string $relationName, @@ -1120,6 +1123,9 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li throw new LogicException("Cannot manipulate eagerloading query for $relationType relation $relationName"); } + $hasOneIDField = $hasOneRelation['joinField']; + $hasOneClassField = $hasOneRelation['joinClass']; + $fetchedIDs = []; $addTo = []; @@ -1128,41 +1134,63 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li if (is_array($parentData)) { // $parentData represents a record in this DataList $hasOneID = $parentData[$hasOneIDField]; - $fetchedIDs[] = $hasOneID; - $addTo[$hasOneID][] = $parentData['ID']; + + if ($hasOneID) { + // Class field is only set for polymorphic has_one relations + $hasOneClass = $hasOneClassField ? $parentData[$hasOneClassField] : $relationDataClass; + + $fetchedIDs[$hasOneClass][$hasOneID] = $hasOneID; + $addTo[$hasOneClass][$hasOneID][] = $parentData['ID']; + } } elseif ($parentData instanceof DataObject) { // $parentData represents another has_one record $hasOneID = $parentData->$hasOneIDField; - $fetchedIDs[] = $hasOneID; - $addTo[$hasOneID][] = $parentData; + + if ($hasOneID) { + // Class field is only set for polymorphic has_one relations + $hasOneClass = $hasOneClassField ? $parentData->$hasOneClassField : $relationDataClass; + + $fetchedIDs[$hasOneClass][$hasOneID] = $hasOneID; + $addTo[$hasOneClass][$hasOneID][] = $parentData; + } } elseif ($parentData instanceof EagerLoadedList) { // $parentData represents a has_many or many_many relation foreach ($parentData->getRows() as $parentRow) { + // $parentData represents another has_one record $hasOneID = $parentRow[$hasOneIDField]; - $fetchedIDs[] = $hasOneID; - $addTo[$hasOneID][] = ['ID' => $parentRow['ID'], 'list' => $parentData]; + + if ($hasOneID) { + // Class field is only set for polymorphic has_one relations + $hasOneClass = $hasOneClassField ? $parentRow[$hasOneClassField] : $relationDataClass; + + $fetchedIDs[$hasOneClass][$hasOneID] = $hasOneID; + $addTo[$hasOneClass][$hasOneID][] = ['ID' => $parentRow['ID'], 'list' => $parentData]; + } } } else { throw new LogicException("Invalid parent for eager loading $relationType relation $relationName"); } } - $fetchedRecords = DataObject::get($relationDataClass)->byIDs($fetchedIDs)->toArray(); + $fetchedRecords = []; - // Add each fetched record to the appropriate place - foreach ($fetchedRecords as $fetched) { - if (isset($addTo[$fetched->ID])) { - foreach ($addTo[$fetched->ID] as $addHere) { - if ($addHere instanceof DataObject) { - $addHere->setEagerLoadedData($relationName, $fetched); - } elseif (is_array($addHere)) { - $addHere['list']->addEagerLoadedData($relationName, $addHere['ID'], $fetched); - } else { - $this->eagerLoadedData[$relationChain][$addHere][$relationName] = $fetched; + foreach ($fetchedIDs as $class => $ids) { + foreach (DataObject::get($class)->byIDs($ids) as $fetched) { + $fetchedRecords[] = $fetched; + + if (isset($addTo[$class][$fetched->ID])) { + foreach ($addTo[$class][$fetched->ID] as $addHere) { + if ($addHere instanceof DataObject) { + $addHere->setEagerLoadedData($relationName, $fetched); + } elseif (is_array($addHere)) { + $addHere['list']->addEagerLoadedData($relationName, $addHere['ID'], $fetched); + } else { + $this->eagerLoadedData[$relationChain][$addHere][$relationName] = $fetched; + } } + } else { + throw new LogicException("Couldn't find parent for record $class on $relationType relation $relationName"); } - } else { - throw new LogicException("Couldn't find parent for record $fetchedID on $relationType relation $relationName"); } } @@ -1321,17 +1349,21 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li } // Get the join records so we can correctly identify which children belong to which parents - // This also holds extra fields data - $fetchedIDsAsString = implode(',', $fetchedIDs); - $joinRows = DB::query( - 'SELECT * FROM "' . $joinTable - // Only get joins relevant for the parent list - . '" WHERE "' . $parentIDField . '" IN (' . implode(',', $parentIDs) . ')' - // Exclude any children that got filtered out - . ' AND ' . $childIDField . ' IN (' . $fetchedIDsAsString . ')' - // Respect sort order of fetched items - . ' ORDER BY FIELD(' . $childIDField . ', ' . $fetchedIDsAsString . ')' - ); + // If there are no parents and no children, skip this to avoid an error (and to skip an unnecessary DB call) + // Note that $joinRows also holds extra fields data + $joinRows = []; + if (!empty($parentIDs) && !empty($fetchedIDs)) { + $fetchedIDsAsString = implode(',', $fetchedIDs); + $joinRows = DB::query( + 'SELECT * FROM "' . $joinTable + // Only get joins relevant for the parent list + . '" WHERE "' . $parentIDField . '" IN (' . implode(',', $parentIDs) . ')' + // Exclude any children that got filtered out + . ' AND ' . $childIDField . ' IN (' . $fetchedIDsAsString . ')' + // Respect sort order of fetched items + . ' ORDER BY FIELD(' . $childIDField . ', ' . $fetchedIDsAsString . ')' + ); + } // Store the children in an EagerLoadedList against the correct parent foreach ($joinRows as $row) { diff --git a/tests/php/Core/PathTest.php b/tests/php/Core/PathTest.php index 02580de74..10dff0e8d 100644 --- a/tests/php/Core/PathTest.php +++ b/tests/php/Core/PathTest.php @@ -48,6 +48,8 @@ class PathTest extends SapphireTest [['\\', '', '/root', '/', ' ', '/', '\\'], '/root'], // join blocks of paths [['/root/dir', 'another/path\\to/join'], '/root/dir/another/path/to/join'], + // Double dot is fine if it's not attempting directory traversal + [['/root/my..name/', 'another/path\\to/join'], '/root/my..name/another/path/to/join'], ]; // Rewrite tests for other filesystems (output arg only) @@ -79,6 +81,8 @@ class PathTest extends SapphireTest [['/base', '../passwd'], 'Can not collapse relative folders'], [['/base/../', 'passwd/path'], 'Can not collapse relative folders'], [['../', 'passwd/path'], 'Can not collapse relative folders'], + [['..', 'passwd/path'], 'Can not collapse relative folders'], + [['base/..', 'passwd/path'], 'Can not collapse relative folders'], ]; } diff --git a/tests/php/ORM/DataListEagerLoadingTest.php b/tests/php/ORM/DataListEagerLoadingTest.php index 44ce1e36e..65950a9ae 100644 --- a/tests/php/ORM/DataListEagerLoadingTest.php +++ b/tests/php/ORM/DataListEagerLoadingTest.php @@ -12,7 +12,9 @@ use SilverStripe\ORM\DataQuery; use SilverStripe\ORM\DB; use SilverStripe\ORM\EagerLoadedList; use SilverStripe\ORM\ManyManyThroughList; +use SilverStripe\ORM\SS_List; use SilverStripe\ORM\Tests\DataListTest\EagerLoading\EagerLoadObject; +use SilverStripe\ORM\Tests\DataListTest\EagerLoading\EagerLoadSubClassObject; use SilverStripe\ORM\Tests\DataListTest\EagerLoading\HasOneEagerLoadObject; use SilverStripe\ORM\Tests\DataListTest\EagerLoading\HasOneSubEagerLoadObject; use SilverStripe\ORM\Tests\DataListTest\EagerLoading\HasOneSubSubEagerLoadObject; @@ -754,6 +756,63 @@ class DataListEagerLoadingTest extends SapphireTest return [$results, $selectCount]; } + /** + * @dataProvider provideEagerLoadRelationsEmpty + */ + public function testEagerLoadRelationsEmpty(string $eagerLoadRelation, int $expectedNumQueries): void + { + EagerLoadObject::create(['Title' => 'test object'])->write(); + $dataList = EagerLoadObject::get()->eagerLoad($eagerLoadRelation); + $this->startCountingSelectQueries(); + foreach ($dataList as $record) { + $relation = $record->$eagerLoadRelation(); + if ($relation instanceof SS_List) { + // The list should be an empty eagerloaded list + $this->assertInstanceOf(EagerLoadedList::class, $relation); + $this->assertCount(0, $relation); + } elseif ($relation !== null) { + // There should be no record here + $this->assertSame($relation->ID, 0); + } + } + $numQueries = $this->stopCountingSelectQueries(); + $this->assertSame($expectedNumQueries, $numQueries); + } + + public function provideEagerLoadRelationsEmpty(): array + { + return [ + 'has_one' => [ + 'eagerLoad' => 'HasOneEagerLoadObject', + 'expectedNumQueries' => 1, + ], + 'polymorph_has_one' => [ + 'eagerLoad' => 'HasOnePolymorphObject', + 'expectedNumQueries' => 1, + ], + 'belongs_to' => [ + 'eagerLoad' => 'BelongsToEagerLoadObject', + 'expectedNumQueries' => 2, + ], + 'has_many' => [ + 'eagerLoad' => 'HasManyEagerLoadObjects', + 'expectedNumQueries' => 2, + ], + 'many_many' => [ + 'eagerLoad' => 'ManyManyEagerLoadObjects', + 'expectedNumQueries' => 2, + ], + 'many_many through' => [ + 'eagerLoad' => 'ManyManyThroughEagerLoadObjects', + 'expectedNumQueries' => 2, + ], + 'belongs_many_many' => [ + 'eagerLoad' => 'BelongsManyManyEagerLoadObjects', + 'expectedNumQueries' => 2, + ], + ]; + } + public function testEagerLoadFourthLevelException(): void { $eagerLoadRelation = implode('.', [ @@ -1591,28 +1650,12 @@ class DataListEagerLoadingTest extends SapphireTest public function testHasOneMultipleAppearance(): void { - $this->provideHasOneObjects(); - $this->validateMultipleAppearance(6, EagerLoadObject::get()); - $this->validateMultipleAppearance(2, EagerLoadObject::get()->eagerLoad('HasOneEagerLoadObject')); + $items = $this->provideHasOneObjects(); + $this->validateMultipleAppearance($items, 6, EagerLoadObject::get()); + $this->validateMultipleAppearance($items, 2, EagerLoadObject::get()->eagerLoad('HasOneEagerLoadObject')); } - protected function validateMultipleAppearance(int $expected, DataList $list): void - { - try { - $this->startCountingSelectQueries(); - - /** @var EagerLoadObject $item */ - foreach ($list as $item) { - $item->HasOneEagerLoadObject()->Title; - } - - $this->assertSame($expected, $this->stopCountingSelectQueries()); - } finally { - $this->resetShowQueries(); - } - } - - protected function provideHasOneObjects(): void + protected function provideHasOneObjects(): array { $subA = new HasOneEagerLoadObject(); $subA->Title = 'A'; @@ -1655,5 +1698,102 @@ class DataListEagerLoadingTest extends SapphireTest $baseF->Title = 'F'; $baseF->HasOneEagerLoadObjectID = 0; $baseF->write(); + + return [ + $baseA->ID => [$subA->ClassName, $subA->ID], + $baseB->ID => [$subA->ClassName, $subA->ID], + $baseC->ID => [$subB->ClassName, $subB->ID], + $baseD->ID => [$subC->ClassName, $subC->ID], + $baseE->ID => [$subB->ClassName, $subB->ID], + $baseF->ID => [null, 0], + ]; + } + + public function testPolymorphEagerLoading(): void + { + $items = $this->providePolymorphHasOne(); + $this->validateMultipleAppearance($items, 5, EagerLoadObject::get(), 'HasOnePolymorphObject'); + $this->validateMultipleAppearance($items, 4, EagerLoadObject::get()->eagerLoad('HasOnePolymorphObject'), 'HasOnePolymorphObject'); + } + + protected function providePolymorphHasOne(): array + { + $subA = new HasOneEagerLoadObject(); + $subA->Title = 'A'; + $subA->write(); + + $subB = new HasOneEagerLoadObject(); + $subB->Title = 'B'; + $subB->write(); + + $subC = new HasOneSubSubEagerLoadObject(); + $subC->Title = 'C'; + $subC->write(); + + $subD = new EagerLoadSubClassObject(); + $subD->Title = 'D'; + $subD->write(); + + $baseA = new EagerLoadObject(); + $baseA->Title = 'A'; + $baseA->HasOnePolymorphObjectClass = $subA->ClassName; + $baseA->HasOnePolymorphObjectID = $subA->ID; + $baseA->write(); + + $baseB = new EagerLoadObject(); + $baseB->Title = 'B'; + $baseB->HasOnePolymorphObjectClass = $subB->ClassName; + $baseB->HasOnePolymorphObjectID = $subB->ID; + $baseB->write(); + + $baseC = new EagerLoadObject(); + $baseC->Title = 'C'; + $baseC->HasOnePolymorphObjectClass = $subC->ClassName; + $baseC->HasOnePolymorphObjectID = $subC->ID; + $baseC->write(); + + $baseD = new EagerLoadObject(); + $baseD->Title = 'D'; + $baseD->HasOnePolymorphObjectClass = $subD->ClassName; + $baseD->HasOnePolymorphObjectID = $subD->ID; + $baseD->write(); + + $baseE = new EagerLoadObject(); + $baseE->Title = 'E'; + $baseE->HasOnePolymorphObjectClass = null; + $baseE->HasOnePolymorphObjectID = 0; + $baseE->write(); + + return [ + $baseA->ID => [$subA->ClassName, $subA->ID], + $baseB->ID => [$subB->ClassName, $subB->ID], + $baseC->ID => [$subC->ClassName, $subC->ID], + $baseD->ID => [$subD->ClassName, $subD->ID], + $baseE->ID => [null, 0], + ]; + } + + protected function validateMultipleAppearance( + array $expectedRelations, + int $expected, + DataList $list, + string $relation = 'HasOneEagerLoadObject', + ): void { + try { + $this->startCountingSelectQueries(); + + /** @var EagerLoadObject $item */ + foreach ($list as $item) { + $rel = $item->{$relation}(); + + $this->assertArrayHasKey($item->ID, $expectedRelations, $relation . ' should be loaded'); + $this->assertEquals($expectedRelations[$item->ID][0], $rel?->ID ? $rel?->ClassName : null); + $this->assertEquals($expectedRelations[$item->ID][1], $rel?->ID ?? 0); + } + + $this->assertSame($expected, $this->stopCountingSelectQueries()); + } finally { + $this->resetShowQueries(); + } } } diff --git a/tests/php/ORM/DataListTest/EagerLoading/EagerLoadObject.php b/tests/php/ORM/DataListTest/EagerLoading/EagerLoadObject.php index 9d753dc9f..568d71520 100644 --- a/tests/php/ORM/DataListTest/EagerLoading/EagerLoadObject.php +++ b/tests/php/ORM/DataListTest/EagerLoading/EagerLoadObject.php @@ -14,7 +14,8 @@ class EagerLoadObject extends DataObject implements TestOnly ]; private static $has_one = [ - 'HasOneEagerLoadObject' => HasOneEagerLoadObject::class + 'HasOneEagerLoadObject' => HasOneEagerLoadObject::class, + 'HasOnePolymorphObject' => DataObject::class, ]; private static $belongs_to = [ diff --git a/tests/php/ORM/DataListTest/EagerLoading/EagerLoadSubClassObject.php b/tests/php/ORM/DataListTest/EagerLoading/EagerLoadSubClassObject.php new file mode 100644 index 000000000..cff8de952 --- /dev/null +++ b/tests/php/ORM/DataListTest/EagerLoading/EagerLoadSubClassObject.php @@ -0,0 +1,8 @@ +