mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge branch '4.3' into 4
This commit is contained in:
commit
76936d863d
13
docs/en/04_Changelogs/rc/4.3.0-rc1.md
Normal file
13
docs/en/04_Changelogs/rc/4.3.0-rc1.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# 4.3.0-rc1
|
||||||
|
|
||||||
|
<!--- Changes below this line will be automatically regenerated -->
|
||||||
|
|
||||||
|
## Change Log
|
||||||
|
|
||||||
|
### Features and Enhancements
|
||||||
|
|
||||||
|
* 2018-07-25 [79a5ea3](https://github.com/silverstripe/recipe-cms/commit/79a5ea3dace336558ef4d5be4a86cc1a0e84badc) Add versioned-admin (Luke Edwards)
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
* 2018-06-15 [5e4ad34](https://github.com/silverstripe/silverstripe-installer/commit/5e4ad341622565cc998bd8537ad3ec7a6a6a7913) Fix incorrect base recipe dependency (Damian Mooyman)
|
@ -150,7 +150,4 @@ ar:
|
|||||||
LOGIN: دخول
|
LOGIN: دخول
|
||||||
LOSTPASSWORDHEADER: 'كلمة مرور مفقودة'
|
LOSTPASSWORDHEADER: 'كلمة مرور مفقودة'
|
||||||
NOTEPAGESECURED: 'هذه الصفحة محمية بكلمة مرور ، أدخل بيانات دخولك بالأسفل ليتم السماح لك بالوصول للصفحة'
|
NOTEPAGESECURED: 'هذه الصفحة محمية بكلمة مرور ، أدخل بيانات دخولك بالأسفل ليتم السماح لك بالوصول للصفحة'
|
||||||
NOTERESETLINKINVALID: "<p> رابط إعادة تعيين كلمة المرور غير صحيح أو نفذت صلاحيته.</p>\n<p> \nيمكنك طلب رابط جديد <\"{a href=\"{link1\"> هنا </a>\n أو تغيير كلمة المرور الخاصة بك بعد <\"{a href=\"{link2\"> تسجيل دخولك</a>.\n</p>"
|
|
||||||
NOTERESETPASSWORD: 'أدخل بريدك الإلكتروني و سيتم إرسال رابط إعادة تهيئة كلمة المرور '
|
NOTERESETPASSWORD: 'أدخل بريدك الإلكتروني و سيتم إرسال رابط إعادة تهيئة كلمة المرور '
|
||||||
PASSWORDSENTHEADER: 'رابط استعادة كلمة المرور تم إرساله إلى ''{بريدك}'''
|
|
||||||
PASSWORDSENTTEXT: 'شكرا لك! تم إرسال رابط إعادة تعيين إلى ''{بريدك}''، بشرط وجود حساب قائم بالنسبة لعنوان هذا البريد الإلكتروني .'
|
|
||||||
|
@ -313,7 +313,4 @@ bg:
|
|||||||
LOGOUT: Изход
|
LOGOUT: Изход
|
||||||
LOSTPASSWORDHEADER: 'Забравена парола'
|
LOSTPASSWORDHEADER: 'Забравена парола'
|
||||||
NOTEPAGESECURED: 'Тази страница е защитена. Въведете вашите данни по-долу, за да продължите.'
|
NOTEPAGESECURED: 'Тази страница е защитена. Въведете вашите данни по-долу, за да продължите.'
|
||||||
NOTERESETLINKINVALID: '<p>Връзката за нулиране на парола не е вярна или е просрочена.</p><p>Можете да заявите нова <a href="{link1}">тук</a> или да промените паролата си след като <a href="{link2}">влезете</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Въведете вашият email адрес и ще ви изпратим линк, с който ще можете да смените паролата си'
|
NOTERESETPASSWORD: 'Въведете вашият email адрес и ще ви изпратим линк, с който ще можете да смените паролата си'
|
||||||
PASSWORDSENTHEADER: 'Връзка за нулиране на парола беше изпратена на ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Благодарим ви! Връзка за нулиране на паролата беше изпратен на ''{email}'', ако съществува акаунт с този имейл адрес.'
|
|
||||||
|
@ -194,7 +194,4 @@ cs:
|
|||||||
LOGIN: Přihlásit
|
LOGIN: Přihlásit
|
||||||
LOSTPASSWORDHEADER: 'Zapomenuté heslo'
|
LOSTPASSWORDHEADER: 'Zapomenuté heslo'
|
||||||
NOTEPAGESECURED: 'Tato stránka je zabezpečená. Vložte své přihlašovací údaje a my Vám zároveň pošleme práva.'
|
NOTEPAGESECURED: 'Tato stránka je zabezpečená. Vložte své přihlašovací údaje a my Vám zároveň pošleme práva.'
|
||||||
NOTERESETLINKINVALID: '<p>Odkaz na resetování hesla není platný nebo je prošlý.</p><p>Můžete požádat o nový <a href="{link1}">zde</a> nebo změňte své heslo až <a href="{link2}">se přihlásíte</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Zadejte svou e-mailovou adresu a bude vám zaslán nulovací odkaz pro Vaše heslo'
|
NOTERESETPASSWORD: 'Zadejte svou e-mailovou adresu a bude vám zaslán nulovací odkaz pro Vaše heslo'
|
||||||
PASSWORDSENTHEADER: 'Odkaz na resetování hesla byl odeslán na ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Děkujeme! Resetovací odkaz byl odeslán na ''{email}'', pokud účet existuje pro tuto emailovou adresu.'
|
|
||||||
|
325
lang/da.yml
325
lang/da.yml
@ -1,5 +1,328 @@
|
|||||||
da:
|
da:
|
||||||
|
SilverStripe\Admin\LeftAndMain:
|
||||||
|
VersionUnknown: ukendt
|
||||||
|
SilverStripe\AssetAdmin\Forms\UploadField:
|
||||||
|
Dimensions: Dimensioner
|
||||||
|
EDIT: Rediger
|
||||||
|
EDITINFO: 'Rediger denne fil'
|
||||||
|
REMOVE: Fjern
|
||||||
|
SilverStripe\Control\ChangePasswordEmail_ss:
|
||||||
|
CHANGEPASSWORDFOREMAIL: 'Koden for kontoen med email addressen {email} er ændret. Hvis du ikke har skiftet din kode, så skift venligst din kode ved at klikke på linket herunder'
|
||||||
|
CHANGEPASSWORDTEXT1: 'Du skiftede dit kodeord for'
|
||||||
|
CHANGEPASSWORDTEXT3: 'Skift kodeord'
|
||||||
|
HELLO: Hej
|
||||||
|
SilverStripe\Control\Email\ForgotPasswordEmail_ss:
|
||||||
|
HELLO: Hej
|
||||||
|
TEXT1: 'Her er din'
|
||||||
|
TEXT2: 'link til at nulstille dit kodeord'
|
||||||
|
TEXT3: for
|
||||||
|
SilverStripe\Control\RequestProcessor:
|
||||||
|
INVALID_REQUEST: 'Ugyldig forespørgsel'
|
||||||
|
REQUEST_ABORTED: 'Forespørgsel annulleret'
|
||||||
|
SilverStripe\Core\Manifest\VersionProvider:
|
||||||
|
VERSIONUNKNOWN: Ukendt
|
||||||
|
SilverStripe\Forms\CheckboxField:
|
||||||
|
NOANSWER: Nej
|
||||||
|
YESANSWER: Ja
|
||||||
|
SilverStripe\Forms\CheckboxSetField_ss:
|
||||||
|
NOOPTIONSAVAILABLE: 'Ingen tilgængelige muligheder'
|
||||||
|
SilverStripe\Forms\ConfirmedPasswordField:
|
||||||
|
ATLEAST: 'Kodeord skal være mindst {min} tegn lang.'
|
||||||
|
BETWEEN: 'Kodeord skal være {min} til {max} karakterer lang.'
|
||||||
|
CURRENT_PASSWORD_ERROR: 'Det nuværende kodeord du har indtastet er ikke korrekt.'
|
||||||
|
CURRENT_PASSWORD_MISSING: 'Du skal indtaste dit nuværende kodeord.'
|
||||||
|
LOGGED_IN_ERROR: 'Du skal være logget ind for at skifte dit kodeord.'
|
||||||
|
MAXIMUM: 'Kodeord må maks være {max} tegn lang'
|
||||||
|
SHOWONCLICKTITLE: 'Skift kodeord'
|
||||||
|
SilverStripe\Forms\CurrencyField:
|
||||||
|
CURRENCYSYMBOL: DKK
|
||||||
|
SilverStripe\Forms\DateField:
|
||||||
|
VALIDDATEFORMAT2: 'Indtats venligst et gyldigt datoformat ({format})'
|
||||||
|
VALIDDATEMAXDATE: 'Din dato skal være ældre end eller matche den maksimalt tilladte dato ({date})'
|
||||||
|
VALIDDATEMINDATE: 'Din dato skal være yngre end eller matche den minimum tilladte dato ({date})'
|
||||||
|
SilverStripe\Forms\DatetimeField:
|
||||||
|
VALIDDATEMAXDATETIME: 'Din dato skal være ældre end eller matche den maksimalt tilladte dato ({datetime})'
|
||||||
|
VALIDDATETIMEFORMAT: 'Indtats venligst et gyldigt dato- og tidsformat ({format})'
|
||||||
|
VALIDDATETIMEMINDATE: 'Din dato skal være yngre end eller matche den minimum tilladte dato og tid ({datetime})'
|
||||||
|
SilverStripe\Forms\DropdownField:
|
||||||
|
CHOOSE: (Vælg)
|
||||||
|
CHOOSE_MODEL: '(Vælg {name})'
|
||||||
|
SOURCE_VALIDATION: 'Venligst vælg en eksisterende værdi fra listen. {value} er ikke en tilladt mulighed'
|
||||||
|
SilverStripe\Forms\EmailField:
|
||||||
|
VALIDATION: 'Indtast venligst en emailadresse'
|
||||||
|
SilverStripe\Forms\FileUploadReceiver:
|
||||||
|
FIELDNOTSET: 'Fil information ikke fundet'
|
||||||
|
SilverStripe\Forms\Form:
|
||||||
|
BAD_METHOD: 'Denne form kræver en {method} indsendelse'
|
||||||
|
CSRF_EXPIRED_MESSAGE: 'Din session er udløbet. Venligst gensend formularen.'
|
||||||
|
CSRF_FAILED_MESSAGE: 'Det ser ud til der har været et teknisk problem. Klik venligst på tilbageknappen, tryk opdater i din browser og prøv igen.'
|
||||||
|
VALIDATIONPASSWORDSDONTMATCH: 'Kodeordene er ikke identiske'
|
||||||
|
VALIDATIONPASSWORDSNOTEMPTY: 'Kodeord kan ikke være tomme'
|
||||||
|
VALIDATIONSTRONGPASSWORD: 'Kodeord skal mindst have et tal og et alfanumerisk tegn'
|
||||||
|
VALIDATOR: Validering
|
||||||
|
VALIDCURRENCY: 'Indtast venligst en gyldig valuta'
|
||||||
|
SilverStripe\Forms\FormField:
|
||||||
|
EXAMPLE: 'f.eks. {format}'
|
||||||
|
NONE: ingen
|
||||||
|
SilverStripe\Forms\FormScaffolder:
|
||||||
|
TABMAIN: Primær
|
||||||
SilverStripe\Forms\GridField\GridField:
|
SilverStripe\Forms\GridField\GridField:
|
||||||
Filter: Filter
|
Add: 'Tilføj {name}'
|
||||||
|
CSVEXPORT: 'Eksporter til CSV'
|
||||||
|
CSVIMPORT: 'Importer CSV'
|
||||||
|
Filter: Filtrer
|
||||||
|
FilterBy: 'Filtrer på'
|
||||||
|
Find: Find
|
||||||
|
LinkExisting: 'Link eksisterende'
|
||||||
|
NewRecord: 'Ny {type}'
|
||||||
|
NoItemsFound: 'Ingen elementer fundet'
|
||||||
|
PRINTEDAT: 'Printet d.'
|
||||||
|
PRINTEDBY: 'Printet af'
|
||||||
|
PlaceHolder: 'Find {type}'
|
||||||
|
PlaceHolderWithLabels: 'Find {type} på {name}'
|
||||||
|
Print: Print
|
||||||
|
RelationSearch: Relationssøgning
|
||||||
|
ResetFilter: Nulstil
|
||||||
|
SilverStripe\Forms\GridField\GridFieldDeleteAction:
|
||||||
|
Delete: Slet
|
||||||
|
DeletePermissionsFailure: 'Ingen slette rettigheder'
|
||||||
|
EditPermissionsFailure: 'Ingen rettighed til at fjerne emnet'
|
||||||
|
UnlinkRelation: Fjern
|
||||||
|
SilverStripe\Forms\GridField\GridFieldDetailForm:
|
||||||
|
CancelBtn: Annuller
|
||||||
|
Create: Opret
|
||||||
|
Delete: Slet
|
||||||
|
DeletePermissionsFailure: 'Ingen slette rettigheder'
|
||||||
|
Deleted: 'Slet {type} {name}'
|
||||||
|
Save: Gem
|
||||||
|
SilverStripe\Forms\GridField\GridFieldEditButton:
|
||||||
|
EDIT: Rediger
|
||||||
|
SilverStripe\Forms\GridField\GridFieldGroupDeleteAction:
|
||||||
|
UnlinkSelfFailure: 'Kan ikke fjerne dig selv fra denne gruppe, du vil miste administrator rettigheder'
|
||||||
|
SilverStripe\Forms\GridField\GridFieldPaginator:
|
||||||
|
OF: af
|
||||||
|
Page: Side
|
||||||
|
View: Vis
|
||||||
|
SilverStripe\Forms\MoneyField:
|
||||||
|
FIELDLABELAMOUNT: Beløb
|
||||||
|
FIELDLABELCURRENCY: Valuta
|
||||||
|
INVALID_CURRENCY: 'Valuta {currency} er ikke i listen over tilladte valutaer'
|
||||||
|
SilverStripe\Forms\MultiSelectField:
|
||||||
|
SOURCE_VALIDATION: 'Vælg venligst eksisterende værdier fra listen. Ugyldig mulighed(er) {value} valgt'
|
||||||
|
SilverStripe\Forms\NullableField:
|
||||||
|
IsNullLabel: 'Er Null'
|
||||||
|
SilverStripe\Forms\NumericField:
|
||||||
|
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:
|
||||||
|
PLURALNAME: Dataobjekter
|
||||||
|
PLURALS:
|
||||||
|
one: 'Et dataobjekt'
|
||||||
|
other: '{count} dataobjekter'
|
||||||
|
SINGULARNAME: Dataobjekt
|
||||||
|
SilverStripe\ORM\FieldType\DBBoolean:
|
||||||
|
ANY: Enhver
|
||||||
|
NOANSWER: Nej
|
||||||
|
YESANSWER: Ja
|
||||||
|
SilverStripe\ORM\FieldType\DBDate:
|
||||||
|
DAYS_SHORT_PLURALS:
|
||||||
|
one: '{count} dag'
|
||||||
|
other: '{count} dage'
|
||||||
|
HOURS_SHORT_PLURALS:
|
||||||
|
one: '{count} time'
|
||||||
|
other: '{count} timer'
|
||||||
|
LessThanMinuteAgo: 'mindre end et minut'
|
||||||
|
MINUTES_SHORT_PLURALS:
|
||||||
|
one: '{count} minut'
|
||||||
|
other: '{count} minutter'
|
||||||
|
MONTHS_SHORT_PLURALS:
|
||||||
|
one: '{count} måned'
|
||||||
|
other: '{count} måneder'
|
||||||
|
SECONDS_SHORT_PLURALS:
|
||||||
|
one: '{count} sekund'
|
||||||
|
other: '{count} sekunder'
|
||||||
|
TIMEDIFFAGO: '{difference} siden'
|
||||||
|
TIMEDIFFIN: 'i {difference}'
|
||||||
|
YEARS_SHORT_PLURALS:
|
||||||
|
one: '{count} år'
|
||||||
|
other: '{count} år'
|
||||||
|
SilverStripe\ORM\FieldType\DBEnum:
|
||||||
|
ANY: Enhver
|
||||||
|
SilverStripe\ORM\FieldType\DBForeignKey:
|
||||||
|
DROPDOWN_THRESHOLD_FALLBACK_MESSAGE: 'For mange relaterede objekter; fallback felt i brug'
|
||||||
|
SilverStripe\ORM\Hierarchy:
|
||||||
|
LIMITED_TITLE: 'For mange underelementer ({count})'
|
||||||
|
SilverStripe\ORM\Hierarchy\Hierarchy:
|
||||||
|
InfiniteLoopNotAllowed: 'Uendeligt løkke fundet i "{type}" hierarkiet. Ændre venligst det overliggende element for at løse dette'
|
||||||
|
LIMITED_TITLE: 'For mange underelementer ({count})'
|
||||||
|
SilverStripe\ORM\ValidationException:
|
||||||
|
DEFAULT_ERROR: Valideringsfejl
|
||||||
|
SilverStripe\Security\BasicAuth:
|
||||||
|
ENTERINFO: 'Indtast venligst et brugernavn og kodeord.'
|
||||||
|
ERRORNOTADMIN: 'Den bruger er ikke en administrator.'
|
||||||
|
ERRORNOTREC: 'Brugernavn / kodeord kunne ikke genkendes'
|
||||||
|
SilverStripe\Security\CMSMemberLoginForm:
|
||||||
|
PASSWORDEXPIRED: '<p>Dit kodeord er udløbet. <a target="_top" href="{link}">Vælg venligst et nyt.</a></p>'
|
||||||
|
SilverStripe\Security\CMSSecurity:
|
||||||
|
INVALIDUSER: '<p>Ugyldig bruger. <a target="_top" href="{link}">Log venligst ind igen her</a> for at fortsætte.</p>'
|
||||||
|
LOGIN_MESSAGE: '<p>Din session er løbet ud pga. inaktivitet</p>'
|
||||||
|
LOGIN_TITLE: 'Log ind igen, for at fortsætte hvor du slap.'
|
||||||
|
SUCCESS: Succes
|
||||||
|
SUCCESSCONTENT: '<p>Logget ind. Hvis du ikke automatisk viderestilles så <a target="_top" href="{link}">klik her</a></p>'
|
||||||
|
SUCCESS_TITLE: 'Logget ind med sucess'
|
||||||
|
SilverStripe\Security\DefaultAdminService:
|
||||||
|
DefaultAdminFirstname: 'Standard admin'
|
||||||
|
SilverStripe\Security\Group:
|
||||||
|
AddRole: 'Tilføj en rolle for denne gruppe'
|
||||||
|
Code: 'Gruppe kode'
|
||||||
|
DefaultGroupTitleAdministrators: Administratorer
|
||||||
|
DefaultGroupTitleContentAuthors: Indholdsforfattere
|
||||||
|
Description: Beskrivelse
|
||||||
|
GROUPNAME: Gruppenavn
|
||||||
|
GroupReminder: 'Hvis du vælger en overliggende gruppe, får denne gruppe alle dens roller'
|
||||||
|
HierarchyPermsError: 'Kan ikke tildele overliggende gruppe "{group}" med fortrinsrettigheder (kræver ADMIN adgang)'
|
||||||
|
Locked: 'Låst?'
|
||||||
|
MEMBERS: Brugere
|
||||||
|
NEWGROUP: 'Ny gruppe'
|
||||||
|
NoRoles: 'Ingen roller fundet'
|
||||||
|
PERMISSIONS: Rettigheder
|
||||||
|
PLURALNAME: Grupper
|
||||||
|
PLURALS:
|
||||||
|
one: 'En gruppe'
|
||||||
|
other: '{count} grupper'
|
||||||
|
Parent: 'Overliggende gruppe'
|
||||||
|
ROLES: Roller
|
||||||
|
ROLESDESCRIPTION: 'Roller er et prædefineret sæt af rettigheder, som kan tildeles grupper.<br />De bliver nedarvet fra en overliggende grupper hvis krævet.'
|
||||||
|
RolesAddEditLink: 'Administrer roller'
|
||||||
|
SINGULARNAME: Gruppe
|
||||||
|
Sort: Sortering
|
||||||
|
has_many_Permissions: Rettigheder
|
||||||
|
many_many_Members: Brugere
|
||||||
|
SilverStripe\Security\LoginAttempt:
|
||||||
|
Email: 'Email adresse'
|
||||||
|
EmailHashed: 'Email adresse (hashed)'
|
||||||
|
IP: 'IP addresse'
|
||||||
|
PLURALNAME: Loginforsøg
|
||||||
|
PLURALS:
|
||||||
|
one: 'Et loginforsøg'
|
||||||
|
other: '{count} loginforsøg'
|
||||||
|
SINGULARNAME: 'Login forsøg'
|
||||||
|
Status: Status
|
||||||
|
SilverStripe\Security\Member:
|
||||||
|
ADDGROUP: 'Tilføj gruppe'
|
||||||
|
BUTTONCHANGEPASSWORD: 'Skift kodeord'
|
||||||
|
BUTTONLOGIN: 'Log ind'
|
||||||
|
BUTTONLOGINOTHER: 'Log ind med en anden bruger'
|
||||||
|
BUTTONLOGOUT: 'Log ud'
|
||||||
|
BUTTONLOSTPASSWORD: 'Jeg har glemt mit kodeord'
|
||||||
|
CONFIRMNEWPASSWORD: 'Bekræft nyt kodeord'
|
||||||
|
CONFIRMPASSWORD: 'Bekræft kodeord'
|
||||||
|
CURRENT_PASSWORD: 'Nuværende kodeord'
|
||||||
|
EDIT_PASSWORD: 'Nyt kodeord'
|
||||||
|
EMAIL: Email
|
||||||
|
EMPTYNEWPASSWORD: 'Det nye kodeord kan ikke være tom, prøv venligst igen'
|
||||||
|
ENTEREMAIL: 'Indtast venligst en email adresse for at få et nulstillingslink.'
|
||||||
|
ERRORLOCKEDOUT2: 'Din konto er blevet midlertidigt deaktiveret pga. for mange fejlslagne loginforsøg. Forsøg venligst igen om {count} minutter.'
|
||||||
|
ERRORNEWPASSWORD: 'Du har indtastet dit nye kodeord forskelligt, forsøg igen'
|
||||||
|
ERRORPASSWORDNOTMATCH: 'Dit nuværende kodeord matcher ikke, forsøg venligst igen'
|
||||||
|
ERRORWRONGCRED: 'De indtastede værdier ser ikke ud til at være korrekte. Forsøg venligst igen.'
|
||||||
|
FIRSTNAME: Fornavn
|
||||||
|
INTERFACELANG: 'Sprog i brugerfladen'
|
||||||
|
KEEPMESIGNEDIN: 'Hold mig logget ind'
|
||||||
|
LOGGEDINAS: 'Du er logget ind som {name}.'
|
||||||
|
NEWPASSWORD: 'Nyt kodeord'
|
||||||
|
PASSWORD: Kodeord
|
||||||
|
PASSWORDEXPIRED: 'Dit kodeord er udløbet. Vælg venligst et nyt.'
|
||||||
|
PLURALNAME: Brugere
|
||||||
|
PLURALS:
|
||||||
|
one: 'En bruger'
|
||||||
|
other: '{count} brugere'
|
||||||
|
REMEMBERME: 'Husk mig til næste gang? (i {count} dage på denne enhed)'
|
||||||
|
SINGULARNAME: Bruger
|
||||||
|
SUBJECTPASSWORDCHANGED: 'Dit kodeord er blevet ændret'
|
||||||
|
SUBJECTPASSWORDRESET: 'Link til at nulstille dit kodeord'
|
||||||
|
SURNAME: Efternavn
|
||||||
|
VALIDATIONADMINLOSTACCESS: 'Kan ikke fjerne alle admin grupper fra din profil'
|
||||||
|
ValidationIdentifierFailed: 'Kan ikke overskrive eksisterende bruger #{id} med identisk identifikator ({name} = {value}))'
|
||||||
|
WELCOMEBACK: 'Velkommen tilbage, {firstname}'
|
||||||
|
YOUROLDPASSWORD: 'Dit gamle kodeord'
|
||||||
|
belongs_many_many_Groups: Grupper
|
||||||
|
db_Locale: 'Sprog i brugerfladen'
|
||||||
|
db_LockedOutUntil: 'Låst ude indtil'
|
||||||
|
db_Password: Kodeord
|
||||||
|
db_PasswordExpiry: Kodeordsudløbsdato
|
||||||
|
SilverStripe\Security\MemberAuthenticator\CMSMemberLoginForm:
|
||||||
|
AUTHENTICATORNAME: 'CMS bruger loginform'
|
||||||
|
BUTTONFORGOTPASSWORD: 'Glemt kodeord'
|
||||||
|
BUTTONLOGIN: 'Log mig ind igen'
|
||||||
|
BUTTONLOGOUT: 'Log ud'
|
||||||
|
SilverStripe\Security\MemberAuthenticator\MemberAuthenticator:
|
||||||
|
ERRORWRONGCRED: 'De indtastede værdier ser ikke ud til at være korrekte. Forsøg venligst igen.'
|
||||||
|
NoPassword: 'Der er ikke en kode på denne bruger.'
|
||||||
|
SilverStripe\Security\MemberAuthenticator\MemberLoginForm:
|
||||||
|
AUTHENTICATORNAME: 'Email og kodeord'
|
||||||
|
SilverStripe\Security\MemberPassword:
|
||||||
|
PLURALNAME: 'Bruger kodeord'
|
||||||
|
PLURALS:
|
||||||
|
one: 'Et bruger kodeord'
|
||||||
|
other: '{count} bruger kodeord'
|
||||||
|
SINGULARNAME: 'Bruger kodeord'
|
||||||
|
SilverStripe\Security\PasswordValidator:
|
||||||
|
LOWCHARSTRENGTH: 'Forøg venligst kodeordets styrke, ved at tilføje nogle af følgende tegn: {chars}'
|
||||||
|
PREVPASSWORD: 'Du har tidligere brugt dette kodeord, vælg venligst et nyt kodeord'
|
||||||
|
TOOSHORT: 'Kodeordet er for kort, det skal mindst være {minimum} eller flere tegn langt'
|
||||||
SilverStripe\Security\Permission:
|
SilverStripe\Security\Permission:
|
||||||
|
AdminGroup: Administrator
|
||||||
|
CMS_ACCESS_CATEGORY: 'CMS Adgang'
|
||||||
CONTENT_CATEGORY: Indholdsrettigheder
|
CONTENT_CATEGORY: Indholdsrettigheder
|
||||||
|
FULLADMINRIGHTS: 'Fuld administrator rettighed'
|
||||||
|
FULLADMINRIGHTS_HELP: 'Indebærer og overskriver alle andre tildelte rettigheder.'
|
||||||
|
PERMISSIONS_CATEGORY: 'Roller og adgangsrettigheder'
|
||||||
|
PLURALNAME: Rettigheder
|
||||||
|
PLURALS:
|
||||||
|
one: 'En rettighed'
|
||||||
|
other: '{count} rettigheder'
|
||||||
|
SINGULARNAME: Rettighed
|
||||||
|
UserPermissionsIntro: 'Tildeling af grupper til denne bruger, ændrer de rettigheder brugeren har. Se gruppe området for rettigheds detaljer på de individuelle grupper.'
|
||||||
|
SilverStripe\Security\PermissionCheckboxSetField:
|
||||||
|
AssignedTo: 'tildelt til "{title}"'
|
||||||
|
FromGroup: 'nedarvet fra gruppen "{title}"'
|
||||||
|
FromRole: 'nedarvet fra rollen "{title}"'
|
||||||
|
FromRoleOnGroup: 'nedarvet fra rollen "{roletitle}" på gruppen "{grouptitle}"'
|
||||||
|
SilverStripe\Security\PermissionRole:
|
||||||
|
OnlyAdminCanApply: 'Kun administratorer kan tilføje'
|
||||||
|
PLURALNAME: Roller
|
||||||
|
PLURALS:
|
||||||
|
one: 'En rolle'
|
||||||
|
other: '{count} roller'
|
||||||
|
SINGULARNAME: Rolle
|
||||||
|
Title: Titel
|
||||||
|
SilverStripe\Security\PermissionRoleCode:
|
||||||
|
PLURALNAME: 'Rettigheds rolle koder'
|
||||||
|
PLURALS:
|
||||||
|
one: 'En rettigheds rolle kode'
|
||||||
|
other: '{count} rettigheds rolle koder'
|
||||||
|
PermsError: 'Kan ikke tildele koden "{code}" med fortrinsrettigheder (kræver ADMIN adgang)'
|
||||||
|
SINGULARNAME: 'Rettighed rolle kode'
|
||||||
|
SilverStripe\Security\RememberLoginHash:
|
||||||
|
PLURALNAME: 'Login hashes'
|
||||||
|
PLURALS:
|
||||||
|
one: 'Et login hash'
|
||||||
|
other: '{count} Login Hashes'
|
||||||
|
SINGULARNAME: 'Login hash'
|
||||||
|
SilverStripe\Security\Security:
|
||||||
|
ALREADYLOGGEDIN: 'Du har ikke adgang til denne side. Hvis du har en anden bruger der har adgang til denne side, kan du logge ind med denne herunder.'
|
||||||
|
BUTTONSEND: 'Send mig linket til at nulstille kodeordet'
|
||||||
|
CHANGEPASSWORDBELOW: 'Du kan ændre dit kodeord herunder.'
|
||||||
|
CHANGEPASSWORDHEADER: 'Skift dit kodeord'
|
||||||
|
CONFIRMLOGOUT: 'Klik venligst på knappen herunder, for at bekræfte at du vil logge ud.'
|
||||||
|
ENTERNEWPASSWORD: 'Indtast venligst et nyt kodeord.'
|
||||||
|
ERRORPASSWORDPERMISSION: 'Du skal være logget ind, for at kunne ændre dit kodeord!'
|
||||||
|
LOGIN: 'Log ind'
|
||||||
|
LOGOUT: 'Log ud'
|
||||||
|
LOSTPASSWORDHEADER: 'Glemt kodeord'
|
||||||
|
NOTEPAGESECURED: 'Denne side er beskyttet. Indtast dine loginoplysninger herunder for at få adgang.'
|
||||||
|
NOTERESETPASSWORD: 'Indtast din email adresse, så sender vi dig et link som du kan nulstille dit kodeord med'
|
||||||
|
PASSWORDRESETSENTHEADER: 'link til at nulstille kodeord afsendt'
|
||||||
|
PASSWORDRESETSENTTEXT: 'Tak for det. Et link til at nulstille dit kodeord er afsendt, hvis der findes en bruger med denne email adresse.'
|
||||||
|
@ -190,7 +190,4 @@ de:
|
|||||||
LOGIN: Anmelden
|
LOGIN: Anmelden
|
||||||
LOSTPASSWORDHEADER: 'Passwort vergessen'
|
LOSTPASSWORDHEADER: 'Passwort vergessen'
|
||||||
NOTEPAGESECURED: 'Diese Seite ist geschützt. Bitte melden Sie sich an und Sie werden sofort weitergeleitet.'
|
NOTEPAGESECURED: 'Diese Seite ist geschützt. Bitte melden Sie sich an und Sie werden sofort weitergeleitet.'
|
||||||
NOTERESETLINKINVALID: '<p>Der Link zum Zurücksetzen des Passworts ist entweder nicht korrekt oder abgelaufen</p><p>Sie können <a href="{link1}">einen neuen Link anfordern</a> oder Ihr Passwort nach dem <a href="{link2}">einloggen</a> ändern.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Geben Sie Ihre E-Mail-Adresse ein und wir werden Ihnen einen Link zuschicken, mit dem Sie Ihr Passwort zurücksetzen können.'
|
NOTERESETPASSWORD: 'Geben Sie Ihre E-Mail-Adresse ein und wir werden Ihnen einen Link zuschicken, mit dem Sie Ihr Passwort zurücksetzen können.'
|
||||||
PASSWORDSENTHEADER: 'Der Link zum Zurücksetzen des Passworts wurde an ''{email}'' gesendet'
|
|
||||||
PASSWORDSENTTEXT: 'Vielen Dank! Wenn ein Account zu der E-Mail Adresse ''{email}'' existiert, wurde eine E-Mail mit dem Link zum Zurücksetzen des Passworts verschickt.'
|
|
||||||
|
@ -78,6 +78,7 @@ en:
|
|||||||
LinkExisting: 'Link Existing'
|
LinkExisting: 'Link Existing'
|
||||||
NewRecord: 'New {type}'
|
NewRecord: 'New {type}'
|
||||||
NoItemsFound: 'No items found'
|
NoItemsFound: 'No items found'
|
||||||
|
OpenFilter: 'Open search and filter'
|
||||||
PRINTEDAT: 'Printed at'
|
PRINTEDAT: 'Printed at'
|
||||||
PRINTEDBY: 'Printed by'
|
PRINTEDBY: 'Printed by'
|
||||||
PlaceHolder: 'Find {type}'
|
PlaceHolder: 'Find {type}'
|
||||||
@ -85,10 +86,6 @@ en:
|
|||||||
Print: Print
|
Print: Print
|
||||||
RelationSearch: 'Relation search'
|
RelationSearch: 'Relation search'
|
||||||
ResetFilter: Reset
|
ResetFilter: Reset
|
||||||
OpenFilter: 'Open search and filter'
|
|
||||||
SilverStripe\Forms\GridField\GridFieldFilterHeader:
|
|
||||||
Search: 'Search "{name}"'
|
|
||||||
SearchFormFaliure: 'No search form could be generated'
|
|
||||||
SilverStripe\Forms\GridField\GridFieldDeleteAction:
|
SilverStripe\Forms\GridField\GridFieldDeleteAction:
|
||||||
Delete: Delete
|
Delete: Delete
|
||||||
DeletePermissionsFailure: 'No delete permissions'
|
DeletePermissionsFailure: 'No delete permissions'
|
||||||
@ -103,6 +100,9 @@ en:
|
|||||||
Save: Save
|
Save: Save
|
||||||
SilverStripe\Forms\GridField\GridFieldEditButton:
|
SilverStripe\Forms\GridField\GridFieldEditButton:
|
||||||
EDIT: Edit
|
EDIT: Edit
|
||||||
|
SilverStripe\Forms\GridField\GridFieldFilterHeader:
|
||||||
|
Search: 'Search "{name}"'
|
||||||
|
SearchFormFaliure: 'No search form could be generated'
|
||||||
SilverStripe\Forms\GridField\GridFieldGroupDeleteAction:
|
SilverStripe\Forms\GridField\GridFieldGroupDeleteAction:
|
||||||
UnlinkSelfFailure: 'Cannot remove yourself from this group, you will lose admin rights'
|
UnlinkSelfFailure: 'Cannot remove yourself from this group, you will lose admin rights'
|
||||||
SilverStripe\Forms\GridField\GridFieldPaginator:
|
SilverStripe\Forms\GridField\GridFieldPaginator:
|
||||||
|
@ -95,6 +95,8 @@ eo:
|
|||||||
DeletePermissionsFailure: 'Mankas permeso forigi'
|
DeletePermissionsFailure: 'Mankas permeso forigi'
|
||||||
Deleted: 'Forigita {type} {name}'
|
Deleted: 'Forigita {type} {name}'
|
||||||
Save: Konservi
|
Save: Konservi
|
||||||
|
SilverStripe\Forms\GridField\GridFieldEditButton:
|
||||||
|
EDIT: Redakti
|
||||||
SilverStripe\Forms\GridField\GridFieldGroupDeleteAction:
|
SilverStripe\Forms\GridField\GridFieldGroupDeleteAction:
|
||||||
UnlinkSelfFailure: 'Ne povas forigi vin el ĉi tiu grupo; vi perdus administrajn rajtojn'
|
UnlinkSelfFailure: 'Ne povas forigi vin el ĉi tiu grupo; vi perdus administrajn rajtojn'
|
||||||
SilverStripe\Forms\GridField\GridFieldPaginator:
|
SilverStripe\Forms\GridField\GridFieldPaginator:
|
||||||
@ -147,6 +149,8 @@ eo:
|
|||||||
other: '{count} jaroj'
|
other: '{count} jaroj'
|
||||||
SilverStripe\ORM\FieldType\DBEnum:
|
SilverStripe\ORM\FieldType\DBEnum:
|
||||||
ANY: Ajna
|
ANY: Ajna
|
||||||
|
SilverStripe\ORM\FieldType\DBForeignKey:
|
||||||
|
DROPDOWN_THRESHOLD_FALLBACK_MESSAGE: 'Tro multaj objektoj; retropaŝa kampo uzata'
|
||||||
SilverStripe\ORM\Hierarchy:
|
SilverStripe\ORM\Hierarchy:
|
||||||
LIMITED_TITLE: 'Tro da idoj ({count})'
|
LIMITED_TITLE: 'Tro da idoj ({count})'
|
||||||
SilverStripe\ORM\Hierarchy\Hierarchy:
|
SilverStripe\ORM\Hierarchy\Hierarchy:
|
||||||
@ -319,7 +323,6 @@ eo:
|
|||||||
LOGOUT: Elsaluti
|
LOGOUT: Elsaluti
|
||||||
LOSTPASSWORDHEADER: 'Perdis pasvorton'
|
LOSTPASSWORDHEADER: 'Perdis pasvorton'
|
||||||
NOTEPAGESECURED: 'Tiu paĝo estas sekurigita. Enigu viajn akreditaĵojn sube kaj vi aliros pluen.'
|
NOTEPAGESECURED: 'Tiu paĝo estas sekurigita. Enigu viajn akreditaĵojn sube kaj vi aliros pluen.'
|
||||||
NOTERESETLINKINVALID: '<p>La pasvorta reagorda ligilo estas malvalida aŭ finiĝis.</p><p>Vi povas peti novan <a href="{link1}">ĉi tie</a> aŭ ŝanĝi vian pasvorton post <a href="{link2}">vi ensalutis</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Enigu vian retpoŝtan adreson kaj ni sendos al vi ligilon per kiu vi povas reagordi vian pasvorton'
|
NOTERESETPASSWORD: 'Enigu vian retpoŝtan adreson kaj ni sendos al vi ligilon per kiu vi povas reagordi vian pasvorton'
|
||||||
PASSWORDSENTHEADER: 'Pasvorta reagorda ligilo sendiĝis al ''{email}'''
|
PASSWORDRESETSENTHEADER: 'Pasvorta reagorda ligilo sendiĝis'
|
||||||
PASSWORDSENTTEXT: 'Dankon! Reagordita ligilo sendiĝis al ''{email}'', kondiĉe ke konto ekzistas por tiu retadreso.'
|
PASSWORDRESETSENTTEXT: 'Dankon. Reagorda ligilo sendiĝis, kondiĉe ke konto ekzistas por ĉi tiu retadreso.'
|
||||||
|
@ -249,7 +249,4 @@ es:
|
|||||||
LOGIN: Entrar
|
LOGIN: Entrar
|
||||||
LOSTPASSWORDHEADER: '¿Contraseña Perdida?'
|
LOSTPASSWORDHEADER: '¿Contraseña Perdida?'
|
||||||
NOTEPAGESECURED: 'Esa página está protegida. Introduzca sus datos de acreditación a continuación y lo enviaremos a ella en un momento.'
|
NOTEPAGESECURED: 'Esa página está protegida. Introduzca sus datos de acreditación a continuación y lo enviaremos a ella en un momento.'
|
||||||
NOTERESETLINKINVALID: '<p>El enlace para restablecer la contraseña es inválido o ha expirado.</p><p>Usted puede solicitar uno nuevo <a href="{link1}">aqui</a> o cambiar su contraseña después de que se haya <a href="{link2}">conectado</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Introduzca su dirección de e-mail, y le enviaremos un enlace, con el cual podrá restaurar su contraseña'
|
NOTERESETPASSWORD: 'Introduzca su dirección de e-mail, y le enviaremos un enlace, con el cual podrá restaurar su contraseña'
|
||||||
PASSWORDSENTHEADER: 'Un enlace para restablecer la contraseña ha sido enviado a ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Gracias! Un enlace para restablecer la contraseña ha sido enviado a ''{email}'', siempre que una cuenta exista para la dirección de email indicada.'
|
|
||||||
|
@ -139,7 +139,4 @@ et_EE:
|
|||||||
ERRORPASSWORDPERMISSION: 'Pead olema sisseloginud, et parooli muuta!'
|
ERRORPASSWORDPERMISSION: 'Pead olema sisseloginud, et parooli muuta!'
|
||||||
LOGIN: 'Logi sisse'
|
LOGIN: 'Logi sisse'
|
||||||
NOTEPAGESECURED: 'See leht on turvatud. Sisesta enda andmed allpool ja me saadame sind otse edasi'
|
NOTEPAGESECURED: 'See leht on turvatud. Sisesta enda andmed allpool ja me saadame sind otse edasi'
|
||||||
NOTERESETLINKINVALID: '<p>Parooli lähtestamise link on kehtetu või aegunud.</p><p>Saate taotleda uut linki <a href="{link1}">siin</a> või muuta parooli pärast <a href="{link2}">sisselogimist</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Sisesta oma email ja me saadame sulle lingi kus saad oma parooli tühistada.'
|
NOTERESETPASSWORD: 'Sisesta oma email ja me saadame sulle lingi kus saad oma parooli tühistada.'
|
||||||
PASSWORDSENTHEADER: 'Parooli lähtestamise link saadeti aadressile ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Aitäh! Lähtestamislink saadeti aadressile ''{email}'' eeldusel, et selle e-posti aadressiga seotud konto on olemas.'
|
|
||||||
|
@ -168,4 +168,3 @@ fa_IR:
|
|||||||
ERRORPASSWORDPERMISSION: 'جهت تغییر گذرواژه خود باید وارد شده باشید!'
|
ERRORPASSWORDPERMISSION: 'جهت تغییر گذرواژه خود باید وارد شده باشید!'
|
||||||
LOGIN: ورود
|
LOGIN: ورود
|
||||||
LOSTPASSWORDHEADER: 'فراموشی گذرواژه'
|
LOSTPASSWORDHEADER: 'فراموشی گذرواژه'
|
||||||
PASSWORDSENTHEADER: 'لینک ازنوسازی گذرواژه به ''{email}'' ارسال شد'
|
|
||||||
|
17
lang/fi.yml
17
lang/fi.yml
@ -76,6 +76,7 @@ fi:
|
|||||||
LinkExisting: 'Linkitä olemassaoleva'
|
LinkExisting: 'Linkitä olemassaoleva'
|
||||||
NewRecord: 'Uusi {type}'
|
NewRecord: 'Uusi {type}'
|
||||||
NoItemsFound: 'Ei kohteita'
|
NoItemsFound: 'Ei kohteita'
|
||||||
|
OpenFilter: 'Avaa haku ja suodatus'
|
||||||
PRINTEDAT: Tulostettu
|
PRINTEDAT: Tulostettu
|
||||||
PRINTEDBY: Tulostaja
|
PRINTEDBY: Tulostaja
|
||||||
PlaceHolder: 'Etsi {type}'
|
PlaceHolder: 'Etsi {type}'
|
||||||
@ -95,12 +96,19 @@ fi:
|
|||||||
DeletePermissionsFailure: 'Ei oikeuksia poistamiseen'
|
DeletePermissionsFailure: 'Ei oikeuksia poistamiseen'
|
||||||
Deleted: 'Poistettiin {type} {name}'
|
Deleted: 'Poistettiin {type} {name}'
|
||||||
Save: Tallenna
|
Save: Tallenna
|
||||||
|
SilverStripe\Forms\GridField\GridFieldEditButton:
|
||||||
|
EDIT: Muokkaa
|
||||||
|
SilverStripe\Forms\GridField\GridFieldFilterHeader:
|
||||||
|
Search: 'Haku "{name}"'
|
||||||
|
SearchFormFaliure: 'Hakulomaketta ei pystytty luomaan.'
|
||||||
SilverStripe\Forms\GridField\GridFieldGroupDeleteAction:
|
SilverStripe\Forms\GridField\GridFieldGroupDeleteAction:
|
||||||
UnlinkSelfFailure: 'Et voi siirtää itseäsi pois tästä ryhmästä: menettäisit pääkäyttäjän oikeudet'
|
UnlinkSelfFailure: 'Et voi siirtää itseäsi pois tästä ryhmästä: menettäisit pääkäyttäjän oikeudet'
|
||||||
SilverStripe\Forms\GridField\GridFieldPaginator:
|
SilverStripe\Forms\GridField\GridFieldPaginator:
|
||||||
OF: /
|
OF: /
|
||||||
Page: Sivu
|
Page: Sivu
|
||||||
View: Näytä
|
View: Näytä
|
||||||
|
SilverStripe\Forms\GridField\GridFieldViewButton:
|
||||||
|
VIEW: Avaa
|
||||||
SilverStripe\Forms\MoneyField:
|
SilverStripe\Forms\MoneyField:
|
||||||
FIELDLABELAMOUNT: Määrä
|
FIELDLABELAMOUNT: Määrä
|
||||||
FIELDLABELCURRENCY: Valuutta
|
FIELDLABELCURRENCY: Valuutta
|
||||||
@ -147,6 +155,8 @@ fi:
|
|||||||
other: '{count} vuotta'
|
other: '{count} vuotta'
|
||||||
SilverStripe\ORM\FieldType\DBEnum:
|
SilverStripe\ORM\FieldType\DBEnum:
|
||||||
ANY: Yhtään
|
ANY: Yhtään
|
||||||
|
SilverStripe\ORM\FieldType\DBForeignKey:
|
||||||
|
DROPDOWN_THRESHOLD_FALLBACK_MESSAGE: 'Liian monta samaan liittyvää objektia: oletuskenttä käytössä'
|
||||||
SilverStripe\ORM\Hierarchy:
|
SilverStripe\ORM\Hierarchy:
|
||||||
LIMITED_TITLE: 'Liian monta lapsiobjektia ({count}}'
|
LIMITED_TITLE: 'Liian monta lapsiobjektia ({count}}'
|
||||||
SilverStripe\ORM\Hierarchy\Hierarchy:
|
SilverStripe\ORM\Hierarchy\Hierarchy:
|
||||||
@ -197,6 +207,7 @@ fi:
|
|||||||
many_many_Members: Jäsenet
|
many_many_Members: Jäsenet
|
||||||
SilverStripe\Security\LoginAttempt:
|
SilverStripe\Security\LoginAttempt:
|
||||||
Email: Sähköpostiosoite
|
Email: Sähköpostiosoite
|
||||||
|
EmailHashed: 'Sähköpostiosoite (tiivistetty)'
|
||||||
IP: IP-osoite
|
IP: IP-osoite
|
||||||
PLURALNAME: Kirjautumisyritykset
|
PLURALNAME: Kirjautumisyritykset
|
||||||
PLURALS:
|
PLURALS:
|
||||||
@ -255,6 +266,8 @@ fi:
|
|||||||
SilverStripe\Security\MemberAuthenticator\MemberAuthenticator:
|
SilverStripe\Security\MemberAuthenticator\MemberAuthenticator:
|
||||||
ERRORWRONGCRED: 'Antamasi tiedot eivät näytä oikeilta. Yritä uudelleen.'
|
ERRORWRONGCRED: 'Antamasi tiedot eivät näytä oikeilta. Yritä uudelleen.'
|
||||||
NoPassword: 'Tällä käyttäjällä ei ole salasanaa'
|
NoPassword: 'Tällä käyttäjällä ei ole salasanaa'
|
||||||
|
SilverStripe\Security\MemberAuthenticator\MemberLoginForm:
|
||||||
|
AUTHENTICATORNAME: 'Sähköpostiosoite & salasana'
|
||||||
SilverStripe\Security\MemberPassword:
|
SilverStripe\Security\MemberPassword:
|
||||||
PLURALNAME: 'Käyttäjän salasanat'
|
PLURALNAME: 'Käyttäjän salasanat'
|
||||||
PLURALS:
|
PLURALS:
|
||||||
@ -318,5 +331,5 @@ fi:
|
|||||||
NOTEPAGESECURED: 'Tämä sivu on suojattu. Syötä tunnistetietosi alle niin pääset eteenpäin.'
|
NOTEPAGESECURED: 'Tämä sivu on suojattu. Syötä tunnistetietosi alle niin pääset eteenpäin.'
|
||||||
NOTERESETLINKINVALID: '<p>Salasanan palautuslinkki on virheellinen tai vanhentunut.</p><p>Voit pyytää uuden <a href="{link1}">napsauttamalla tästä</a> tai vaihtaa salasanasi <a href="{link2}">kirjautumisen jälkeen</a>.</p>'
|
NOTERESETLINKINVALID: '<p>Salasanan palautuslinkki on virheellinen tai vanhentunut.</p><p>Voit pyytää uuden <a href="{link1}">napsauttamalla tästä</a> tai vaihtaa salasanasi <a href="{link2}">kirjautumisen jälkeen</a>.</p>'
|
||||||
NOTERESETPASSWORD: 'Syötä sähköpostiosoitteesi ja lähetämme sinulle linkin, jonka avulla saat palautettua salasanasi'
|
NOTERESETPASSWORD: 'Syötä sähköpostiosoitteesi ja lähetämme sinulle linkin, jonka avulla saat palautettua salasanasi'
|
||||||
PASSWORDSENTHEADER: 'Salasanan palautuslinkki lähetettiin osoitteeseen ''{email}'''
|
PASSWORDRESETSENTHEADER: 'Salasanan palautuslinkki lähetetty'
|
||||||
PASSWORDSENTTEXT: 'Kiitos! Salasanan palautuslinkki lähetettiin osoitteeseen ''{email}'', joka on liitettynä tähän käyttäjätiliin.'
|
PASSWORDRESETSENTTEXT: 'Kiitos, palautuslinkki on lähetetty käyttäjätilille asetettuun sähköpostiosoitteeseen.'
|
||||||
|
@ -84,7 +84,6 @@ fr:
|
|||||||
RelationSearch: 'Rechercher relations'
|
RelationSearch: 'Rechercher relations'
|
||||||
ResetFilter: Réinitialiser
|
ResetFilter: Réinitialiser
|
||||||
SilverStripe\Forms\GridField\GridFieldDeleteAction:
|
SilverStripe\Forms\GridField\GridFieldDeleteAction:
|
||||||
DELETE_DESCRIPTION: Supprimer
|
|
||||||
Delete: Supprimer
|
Delete: Supprimer
|
||||||
DeletePermissionsFailure: 'Vous n’avez pas les autorisations pour 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'
|
||||||
@ -96,8 +95,6 @@ fr:
|
|||||||
DeletePermissionsFailure: 'Vous n’avez pas les autorisations pour supprimer'
|
DeletePermissionsFailure: 'Vous n’avez pas les autorisations pour supprimer'
|
||||||
Deleted: '{type} {name} supprimés'
|
Deleted: '{type} {name} supprimés'
|
||||||
Save: Enregistrer
|
Save: Enregistrer
|
||||||
SilverStripe\Forms\GridField\GridFieldEditButton_ss:
|
|
||||||
EDIT: Éditer
|
|
||||||
SilverStripe\Forms\GridField\GridFieldGroupDeleteAction:
|
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:
|
SilverStripe\Forms\GridField\GridFieldPaginator:
|
||||||
@ -322,7 +319,4 @@ fr:
|
|||||||
LOGOUT: 'Se déconnecter'
|
LOGOUT: 'Se déconnecter'
|
||||||
LOSTPASSWORDHEADER: 'Mot de passe oublié'
|
LOSTPASSWORDHEADER: 'Mot de passe oublié'
|
||||||
NOTEPAGESECURED: 'Cette page est sécurisée. Entrez vos identifiants ci-dessous et vous pourrez y avoir accès.'
|
NOTEPAGESECURED: 'Cette page est sécurisée. Entrez vos identifiants ci-dessous et vous pourrez y avoir accès.'
|
||||||
NOTERESETLINKINVALID: '<p>Le lien de réinitialisation du mot de passe n’est pas valide ou a expiré.</p><p>Vous pouvez en demander un nouveau <a href="{link1}">en suivant ce lien</a> ou changer de mot de passe après <a href="{link2}">connexion</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Entrez votre adresse email et nous vous enverrons un lien pour modifier votre mot de passe'
|
NOTERESETPASSWORD: 'Entrez votre adresse email et nous vous enverrons un lien pour modifier votre mot de passe'
|
||||||
PASSWORDSENTHEADER: "Lien de réinitialisation de mot de passe envoyé à «\_{email}\_»"
|
|
||||||
PASSWORDSENTTEXT: "Merci\_! Un lien de réinitialisation vient d’être envoyé à «\_{email}\_», à condition que cette adresse existe."
|
|
||||||
|
@ -167,7 +167,4 @@ id:
|
|||||||
LOGIN: Masuk
|
LOGIN: Masuk
|
||||||
LOSTPASSWORDHEADER: 'Kata Kunci yang Terlupa'
|
LOSTPASSWORDHEADER: 'Kata Kunci yang Terlupa'
|
||||||
NOTEPAGESECURED: 'Laman ini diamankan. Isikan data berikut untuk dikirimkan hak akses Anda.'
|
NOTEPAGESECURED: 'Laman ini diamankan. Isikan data berikut untuk dikirimkan hak akses Anda.'
|
||||||
NOTERESETLINKINVALID: '<p>Tautan penggantian kata kunci tidak valid atau sudah kadaluarsa.</p><p>Anda dapat meminta yang baru <a href="{link1}">di sini</a> atau mengganti kata kunci setelah Anda <a href="{link2}">masuk</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Isikan alamat email Anda untuk mendapatkan tautan penggantian kata kunci'
|
NOTERESETPASSWORD: 'Isikan alamat email Anda untuk mendapatkan tautan penggantian kata kunci'
|
||||||
PASSWORDSENTHEADER: 'Tautan penggantian kata kunci dikirimkan ke ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Terimakasih! Tautan reset telah dikirim ke ''{email}'', berisi informasi akun untuk alamat email ini.'
|
|
||||||
|
@ -166,7 +166,4 @@ id_ID:
|
|||||||
LOGIN: Masuk
|
LOGIN: Masuk
|
||||||
LOSTPASSWORDHEADER: 'Kata Kunci yang Terlupa'
|
LOSTPASSWORDHEADER: 'Kata Kunci yang Terlupa'
|
||||||
NOTEPAGESECURED: 'Laman ini diamankan. Isikan data berikut untuk dikirimkan hak akses Anda.'
|
NOTEPAGESECURED: 'Laman ini diamankan. Isikan data berikut untuk dikirimkan hak akses Anda.'
|
||||||
NOTERESETLINKINVALID: '<p>Tautan penggantian kata kunci tidak valid atau sudah kadaluarsa.</p><p>Anda dapat meminta yang baru <a href="{link1}">di sini</a> atau mengganti kata kunci setelah Anda <a href="{link2}">masuk</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Isikan alamat email Anda untuk mendapatkan tautan penggantian kata kunci'
|
NOTERESETPASSWORD: 'Isikan alamat email Anda untuk mendapatkan tautan penggantian kata kunci'
|
||||||
PASSWORDSENTHEADER: 'Tautan penggantian kata kunci dikirimkan ke ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Terimakasih! Tautan reset telah dikirim ke ''{email}'', berisi informasi akun untuk alamat email ini.'
|
|
||||||
|
15
lang/it.yml
15
lang/it.yml
@ -95,6 +95,10 @@ it:
|
|||||||
DeletePermissionsFailure: 'Non hai i permessi per eliminare'
|
DeletePermissionsFailure: 'Non hai i permessi per eliminare'
|
||||||
Deleted: 'Eliminato {type} {name}'
|
Deleted: 'Eliminato {type} {name}'
|
||||||
Save: Salva
|
Save: Salva
|
||||||
|
SilverStripe\Forms\GridField\GridFieldEditButton:
|
||||||
|
EDIT: Modifica
|
||||||
|
SilverStripe\Forms\GridField\GridFieldGroupDeleteAction:
|
||||||
|
UnlinkSelfFailure: 'Non è possibile rimuovere te stesso da questo gruppo, perderesti i diritti di admin'
|
||||||
SilverStripe\Forms\GridField\GridFieldPaginator:
|
SilverStripe\Forms\GridField\GridFieldPaginator:
|
||||||
OF: di
|
OF: di
|
||||||
Page: Pagina
|
Page: Pagina
|
||||||
@ -145,6 +149,8 @@ it:
|
|||||||
other: '{count} anni'
|
other: '{count} anni'
|
||||||
SilverStripe\ORM\FieldType\DBEnum:
|
SilverStripe\ORM\FieldType\DBEnum:
|
||||||
ANY: Qualsiasi
|
ANY: Qualsiasi
|
||||||
|
SilverStripe\ORM\FieldType\DBForeignKey:
|
||||||
|
DROPDOWN_THRESHOLD_FALLBACK_MESSAGE: 'Troppi oggetti correlati; campo di fallback in uso'
|
||||||
SilverStripe\ORM\Hierarchy:
|
SilverStripe\ORM\Hierarchy:
|
||||||
LIMITED_TITLE: 'Troppi figli ({count})'
|
LIMITED_TITLE: 'Troppi figli ({count})'
|
||||||
SilverStripe\ORM\Hierarchy\Hierarchy:
|
SilverStripe\ORM\Hierarchy\Hierarchy:
|
||||||
@ -195,6 +201,7 @@ it:
|
|||||||
many_many_Members: Membri
|
many_many_Members: Membri
|
||||||
SilverStripe\Security\LoginAttempt:
|
SilverStripe\Security\LoginAttempt:
|
||||||
Email: 'Indirizzo e-mail'
|
Email: 'Indirizzo e-mail'
|
||||||
|
EmailHashed: 'Indirizzo email (hash)'
|
||||||
IP: 'Indirizzo IP'
|
IP: 'Indirizzo IP'
|
||||||
PLURALNAME: 'Tentativi d''accesso'
|
PLURALNAME: 'Tentativi d''accesso'
|
||||||
PLURALS:
|
PLURALS:
|
||||||
@ -236,6 +243,7 @@ it:
|
|||||||
SUBJECTPASSWORDCHANGED: 'La tua password è stata cambiata'
|
SUBJECTPASSWORDCHANGED: 'La tua password è stata cambiata'
|
||||||
SUBJECTPASSWORDRESET: 'Link per azzerare la tua password'
|
SUBJECTPASSWORDRESET: 'Link per azzerare la tua password'
|
||||||
SURNAME: Cognome
|
SURNAME: Cognome
|
||||||
|
VALIDATIONADMINLOSTACCESS: 'Non è possibile rimuovere tutti i gruppi admin dal tuo profilo'
|
||||||
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}'
|
WELCOMEBACK: 'Bentornato, {firstname}'
|
||||||
YOUROLDPASSWORD: 'La tua vecchia password'
|
YOUROLDPASSWORD: 'La tua vecchia password'
|
||||||
@ -252,6 +260,8 @@ it:
|
|||||||
SilverStripe\Security\MemberAuthenticator\MemberAuthenticator:
|
SilverStripe\Security\MemberAuthenticator\MemberAuthenticator:
|
||||||
ERRORWRONGCRED: 'I dettagli forniti non sembrano corretti. Per favore riprovare.'
|
ERRORWRONGCRED: 'I dettagli forniti non sembrano corretti. Per favore riprovare.'
|
||||||
NoPassword: 'Manca la password per questo utente.'
|
NoPassword: 'Manca la password per questo utente.'
|
||||||
|
SilverStripe\Security\MemberAuthenticator\MemberLoginForm:
|
||||||
|
AUTHENTICATORNAME: 'E-mail & Password'
|
||||||
SilverStripe\Security\MemberPassword:
|
SilverStripe\Security\MemberPassword:
|
||||||
PLURALNAME: 'Password utenti'
|
PLURALNAME: 'Password utenti'
|
||||||
PLURALS:
|
PLURALS:
|
||||||
@ -313,7 +323,6 @@ it:
|
|||||||
LOGOUT: Scollegati
|
LOGOUT: Scollegati
|
||||||
LOSTPASSWORDHEADER: 'Password smarrita'
|
LOSTPASSWORDHEADER: 'Password smarrita'
|
||||||
NOTEPAGESECURED: 'La pagina è protetta. Inserisci le credenziali qui sotto per poter andare avanti.'
|
NOTEPAGESECURED: 'La pagina è protetta. Inserisci le credenziali qui sotto per poter andare avanti.'
|
||||||
NOTERESETLINKINVALID: '<p>Il link per azzerare la password non è valido o è scaduto.</p><p>Puoi richiederne uno nuovo <a href="{link1}">qui</a> o cambiare la tua password dopo che ti sei <a href="{link2}">connesso</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Inserisci il tuo indirizzo e-mail e ti verrà inviato un link per poter azzerare la tua password.'
|
NOTERESETPASSWORD: 'Inserisci il tuo indirizzo e-mail e ti verrà inviato un link per poter azzerare la tua password.'
|
||||||
PASSWORDSENTHEADER: 'Link per azzeramento della password inviato a ''{email}'''
|
PASSWORDRESETSENTHEADER: 'Link di azzeramento password inviato'
|
||||||
PASSWORDSENTTEXT: 'Grazie! Un link di azzeramento è stato inviato a ''{email}'', fornito un account esistente per questo indirizzo e-mail.'
|
PASSWORDRESETSENTTEXT: 'Grazie! Un link di azzeramento è stato inviato, supponendo un account esista a quell''indirizzo e-mail.'
|
||||||
|
@ -146,7 +146,4 @@ ja:
|
|||||||
ERRORPASSWORDPERMISSION: パスワードを変更する為に、ログインしなければなりません!
|
ERRORPASSWORDPERMISSION: パスワードを変更する為に、ログインしなければなりません!
|
||||||
LOGIN: ログイン
|
LOGIN: ログイン
|
||||||
NOTEPAGESECURED: このページはセキュリティで保護されております証明書キーを下記に入力してください。こちらからすぐに送信します
|
NOTEPAGESECURED: このページはセキュリティで保護されております証明書キーを下記に入力してください。こちらからすぐに送信します
|
||||||
NOTERESETLINKINVALID: '<p>パスワードのリセットリンクは有効でないか期限切れです。</p><p> 新しいパスワードを要求することができます <a href="{link1}"> ここ </a> もしくはパスワードを変更することができます <a href="{link2}"> ログインした後 </a>.</p>'
|
|
||||||
NOTERESETPASSWORD: メールアドレスを入力してください、パスワードをリセットするURLを送信致します
|
NOTERESETPASSWORD: メールアドレスを入力してください、パスワードをリセットするURLを送信致します
|
||||||
PASSWORDSENTHEADER: 'パスワードリセットリンクは ''{email}'' に送信されました'
|
|
||||||
PASSWORDSENTTEXT: 'ありがとうございました! リセットリンクは、''{email}'' に、このアカウントが存在することを前提として送信されました。'
|
|
||||||
|
@ -167,7 +167,4 @@ lt:
|
|||||||
LOGIN: Prisijungti
|
LOGIN: Prisijungti
|
||||||
LOSTPASSWORDHEADER: 'Slaptažodžio atstatymas'
|
LOSTPASSWORDHEADER: 'Slaptažodžio atstatymas'
|
||||||
NOTEPAGESECURED: 'Šis puslapis yra apsaugotas. Įveskite savo duomenis į žemiau esančius laukelius.'
|
NOTEPAGESECURED: 'Šis puslapis yra apsaugotas. Įveskite savo duomenis į žemiau esančius laukelius.'
|
||||||
NOTERESETLINKINVALID: '<p>Neteisinga arba negaliojanti slaptažodžio atstatymo nuoroda.</p><p>Galite atsisiųsti naują <a href="{link1}">čia</a> arba pasikeisti slaptažodį po to, kai <a href="{link2}">prisijungsite</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Įveskite savo e. pašto adresą ir atsiųsime slaptažodžio atstatymui skirtą nuorodą'
|
NOTERESETPASSWORD: 'Įveskite savo e. pašto adresą ir atsiųsime slaptažodžio atstatymui skirtą nuorodą'
|
||||||
PASSWORDSENTHEADER: 'Slaptažodžio atstatymo nuoroda nusiųsta į ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Atstatymo nuoroda nusiųsta į ''{email}'''
|
|
||||||
|
@ -149,7 +149,4 @@ mi:
|
|||||||
LOGIN: Takiuru
|
LOGIN: Takiuru
|
||||||
LOSTPASSWORDHEADER: 'Kupuhipa Ngaro'
|
LOSTPASSWORDHEADER: 'Kupuhipa Ngaro'
|
||||||
NOTEPAGESECURED: 'Kua ngita tēnā whārangi. Tāurua ō taipitoptio tuakiri ki raro, ā, mā mātou koe e tuku kia haere tonu.'
|
NOTEPAGESECURED: 'Kua ngita tēnā whārangi. Tāurua ō taipitoptio tuakiri ki raro, ā, mā mātou koe e tuku kia haere tonu.'
|
||||||
NOTERESETLINKINVALID: '<p>He muhu, kua mōnehu rānei te hono tautuhi kupuhipa anō.</p><p>Ka taea te tono i te mea hōu<a href="{link1}">i konei</a> ka huri rānei i tō kupuhipa ā muri i tō<a href="{link2}">takiuru</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Tāurua tō wāhitau īmēra, mā mātou e tuku tētahi hono ki a koe e taea ai te tautuhi anō i tō kupuhipa'
|
NOTERESETPASSWORD: 'Tāurua tō wāhitau īmēra, mā mātou e tuku tētahi hono ki a koe e taea ai te tautuhi anō i tō kupuhipa'
|
||||||
PASSWORDSENTHEADER: 'I tukuna he hono tautuhi kupuhipa anō ki ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Kia ora! Kua tukuna he hono tautuhi anō ki ''{email}'',engari rā kei te tīariari he pūkete mō taua wāhitau īmēra.'
|
|
||||||
|
@ -152,7 +152,4 @@ nb:
|
|||||||
LOGIN: 'Logg inn'
|
LOGIN: 'Logg inn'
|
||||||
LOSTPASSWORDHEADER: 'Mistet passord'
|
LOSTPASSWORDHEADER: 'Mistet passord'
|
||||||
NOTEPAGESECURED: 'Den siden er sikret. Skriv inn gyldig innloggingsinfo så kommer du inn.'
|
NOTEPAGESECURED: 'Den siden er sikret. Skriv inn gyldig innloggingsinfo så kommer du inn.'
|
||||||
NOTERESETLINKINVALID: '<p>Lenken for å nullstille passordet er ugyldig eller utgått.</p><p>Du kan kreve en ny <a href="{link1}">her</a> eller endre passordet etter at du har <a href="{link2}">logget inn</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Skriv inn epostadressen din og vi vil sende deg en lenke som nullstiller passordet.'
|
NOTERESETPASSWORD: 'Skriv inn epostadressen din og vi vil sende deg en lenke som nullstiller passordet.'
|
||||||
PASSWORDSENTHEADER: 'Lenke for nullstilling av passord ble sendt til ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Takk! En lenke for å lage nytt passord er sendt til ''{email}'', forutsatt at det eksisterer en konto for denne epostadressen.'
|
|
||||||
|
160
lang/nl.yml
160
lang/nl.yml
@ -1,4 +1,26 @@
|
|||||||
nl:
|
nl:
|
||||||
|
SilverStripe\Admin\LeftAndMain:
|
||||||
|
VersionUnknown: onbekend
|
||||||
|
SilverStripe\AssetAdmin\Forms\UploadField:
|
||||||
|
Dimensions: Afmetingen
|
||||||
|
EDIT: Bewerken
|
||||||
|
EDITINFO: 'Bewerk dit bestand'
|
||||||
|
REMOVE: Verwijder
|
||||||
|
SilverStripe\Control\ChangePasswordEmail_ss:
|
||||||
|
CHANGEPASSWORDFOREMAIL: 'Het wachtwoord voor het account met e-mailadres {email} is aangepast. Indien u uw wachtwoord niet heeft aangepast kunt u dat doen met onderstaande link.'
|
||||||
|
CHANGEPASSWORDTEXT1: 'U heeft het wachtwoord veranderd voor'
|
||||||
|
CHANGEPASSWORDTEXT3: 'Wachtwoord veranderen'
|
||||||
|
HELLO: Hallo
|
||||||
|
SilverStripe\Control\Email\ForgotPasswordEmail_ss:
|
||||||
|
HELLO: Hallo
|
||||||
|
TEXT1: 'Hier is uw'
|
||||||
|
TEXT2: 'link om uw wachtwoord opnieuw aan te maken'
|
||||||
|
TEXT3: voor
|
||||||
|
SilverStripe\Control\RequestProcessor:
|
||||||
|
INVALID_REQUEST: 'Fout bij verwerken'
|
||||||
|
REQUEST_ABORTED: 'Fout bij verwerken (geannuleerd)'
|
||||||
|
SilverStripe\Core\Manifest\VersionProvider:
|
||||||
|
VERSIONUNKNOWN: Onbekend
|
||||||
SilverStripe\Forms\CheckboxField:
|
SilverStripe\Forms\CheckboxField:
|
||||||
NOANSWER: Nee
|
NOANSWER: Nee
|
||||||
YESANSWER: Ja
|
YESANSWER: Ja
|
||||||
@ -8,6 +30,8 @@ nl:
|
|||||||
ATLEAST: 'Een wachtwoord moet tenminste {min} karakters hebben.'
|
ATLEAST: 'Een wachtwoord moet tenminste {min} karakters hebben.'
|
||||||
BETWEEN: 'Een wachtwoord moet tussen de {min} en {max} karakters hebben'
|
BETWEEN: 'Een wachtwoord moet tussen de {min} en {max} karakters hebben'
|
||||||
CURRENT_PASSWORD_ERROR: 'Het wachtwoord dat u heeft ingevoerd is niet juist.'
|
CURRENT_PASSWORD_ERROR: 'Het wachtwoord dat u heeft ingevoerd is niet juist.'
|
||||||
|
CURRENT_PASSWORD_MISSING: 'Voer uw huidige wachtwoord in.'
|
||||||
|
LOGGED_IN_ERROR: 'U moet ingelogd zijn om uw wachtwoord te kunnen veranderen!'
|
||||||
MAXIMUM: 'Een wachtwoord mag maximaal {max} karakters hebben.'
|
MAXIMUM: 'Een wachtwoord mag maximaal {max} karakters hebben.'
|
||||||
SHOWONCLICKTITLE: 'Verander wachtwoord'
|
SHOWONCLICKTITLE: 'Verander wachtwoord'
|
||||||
SilverStripe\Forms\CurrencyField:
|
SilverStripe\Forms\CurrencyField:
|
||||||
@ -16,12 +40,20 @@ nl:
|
|||||||
VALIDDATEFORMAT2: 'Vul een geldig datumformaat in ({format})'
|
VALIDDATEFORMAT2: 'Vul een geldig datumformaat in ({format})'
|
||||||
VALIDDATEMAXDATE: 'De datum moet ouder of gelijk zijn aan de maximale datum ({date})'
|
VALIDDATEMAXDATE: 'De datum moet ouder of gelijk zijn aan de maximale datum ({date})'
|
||||||
VALIDDATEMINDATE: 'De datum moet nieuwer of gelijk zijn aan de minimale datum ({date})'
|
VALIDDATEMINDATE: 'De datum moet nieuwer of gelijk zijn aan de minimale datum ({date})'
|
||||||
|
SilverStripe\Forms\DatetimeField:
|
||||||
|
VALIDDATEMAXDATETIME: 'De datum moet ouder of gelijk zijn aan de maximale datum ({datetime})'
|
||||||
|
VALIDDATETIMEFORMAT: 'Vul een geldige datum in ({format})'
|
||||||
|
VALIDDATETIMEMINDATE: 'De datum moet nieuwer of gelijk zijn aan de minimale datum ({datetime})'
|
||||||
SilverStripe\Forms\DropdownField:
|
SilverStripe\Forms\DropdownField:
|
||||||
CHOOSE: (Kies)
|
CHOOSE: (Kies)
|
||||||
|
CHOOSE_MODEL: '(Selecteer {name})'
|
||||||
SOURCE_VALIDATION: 'Selecteer een optie uit de lijst. {value} is geen geldige keuze.'
|
SOURCE_VALIDATION: 'Selecteer een optie uit de lijst. {value} is geen geldige keuze.'
|
||||||
SilverStripe\Forms\EmailField:
|
SilverStripe\Forms\EmailField:
|
||||||
VALIDATION: 'Gelieve een e-mailadres in te voeren.'
|
VALIDATION: 'Gelieve een e-mailadres in te voeren.'
|
||||||
|
SilverStripe\Forms\FileUploadReceiver:
|
||||||
|
FIELDNOTSET: 'Bestandsinformatie niet gevonden'
|
||||||
SilverStripe\Forms\Form:
|
SilverStripe\Forms\Form:
|
||||||
|
BAD_METHOD: 'Dit formulier moet middels {method} verzonden worden'
|
||||||
CSRF_EXPIRED_MESSAGE: 'Uw sessie is verlopen. Verzend het formulier opnieuw.'
|
CSRF_EXPIRED_MESSAGE: 'Uw sessie is verlopen. Verzend het formulier opnieuw.'
|
||||||
CSRF_FAILED_MESSAGE: 'Er lijkt een technisch probleem te zijn. Klik op de knop terug, vernieuw uw browser, en probeer het opnieuw.'
|
CSRF_FAILED_MESSAGE: 'Er lijkt een technisch probleem te zijn. Klik op de knop terug, vernieuw uw browser, en probeer het opnieuw.'
|
||||||
VALIDATIONPASSWORDSDONTMATCH: 'Wachtwoorden komen niet overeen'
|
VALIDATIONPASSWORDSDONTMATCH: 'Wachtwoorden komen niet overeen'
|
||||||
@ -30,7 +62,10 @@ nl:
|
|||||||
VALIDATOR: Validator
|
VALIDATOR: Validator
|
||||||
VALIDCURRENCY: 'Vul een geldige munteenheid in'
|
VALIDCURRENCY: 'Vul een geldige munteenheid in'
|
||||||
SilverStripe\Forms\FormField:
|
SilverStripe\Forms\FormField:
|
||||||
|
EXAMPLE: 'bijv. {format}'
|
||||||
NONE: geen
|
NONE: geen
|
||||||
|
SilverStripe\Forms\FormScaffolder:
|
||||||
|
TABMAIN: Hoofdgedeelte
|
||||||
SilverStripe\Forms\GridField\GridField:
|
SilverStripe\Forms\GridField\GridField:
|
||||||
Add: '{name} toevoegen'
|
Add: '{name} toevoegen'
|
||||||
CSVEXPORT: 'Exporteer naar CSV'
|
CSVEXPORT: 'Exporteer naar CSV'
|
||||||
@ -41,6 +76,7 @@ nl:
|
|||||||
LinkExisting: 'Koppel een bestaand item'
|
LinkExisting: 'Koppel een bestaand item'
|
||||||
NewRecord: 'Nieuw {type}'
|
NewRecord: 'Nieuw {type}'
|
||||||
NoItemsFound: 'Geen items gevonden.'
|
NoItemsFound: 'Geen items gevonden.'
|
||||||
|
OpenFilter: 'Zoeken en filteren openen'
|
||||||
PRINTEDAT: 'Geprint op'
|
PRINTEDAT: 'Geprint op'
|
||||||
PRINTEDBY: 'Geprint door'
|
PRINTEDBY: 'Geprint door'
|
||||||
PlaceHolder: 'Zoek {type}'
|
PlaceHolder: 'Zoek {type}'
|
||||||
@ -60,27 +96,72 @@ nl:
|
|||||||
DeletePermissionsFailure: 'Onvoldoende rechten om te verwijderen'
|
DeletePermissionsFailure: 'Onvoldoende rechten om te verwijderen'
|
||||||
Deleted: '{type} {name} verwijderd'
|
Deleted: '{type} {name} verwijderd'
|
||||||
Save: Opslaan
|
Save: Opslaan
|
||||||
|
SilverStripe\Forms\GridField\GridFieldEditButton:
|
||||||
|
EDIT: Bewerken
|
||||||
|
SilverStripe\Forms\GridField\GridFieldFilterHeader:
|
||||||
|
Search: 'Zoek naar "{name}"'
|
||||||
|
SearchFormFaliure: 'Er kon geen zoekformulier worden aangemaakt'
|
||||||
|
SilverStripe\Forms\GridField\GridFieldGroupDeleteAction:
|
||||||
|
UnlinkSelfFailure: 'U kunt uzelf niet verwijderen van deze groep, omdat u dan geen admin-rechten meer heeft.'
|
||||||
|
SilverStripe\Forms\GridField\GridFieldPaginator:
|
||||||
|
OF: van
|
||||||
|
Page: Pagina
|
||||||
|
View: Bekijk
|
||||||
|
SilverStripe\Forms\GridField\GridFieldViewButton:
|
||||||
|
VIEW: Bekijk
|
||||||
SilverStripe\Forms\MoneyField:
|
SilverStripe\Forms\MoneyField:
|
||||||
FIELDLABELAMOUNT: Aantal
|
FIELDLABELAMOUNT: Aantal
|
||||||
FIELDLABELCURRENCY: Munteenheid
|
FIELDLABELCURRENCY: Munteenheid
|
||||||
|
INVALID_CURRENCY: 'Valuta {currency} is niet toegestaan'
|
||||||
|
SilverStripe\Forms\MultiSelectField:
|
||||||
|
SOURCE_VALIDATION: 'Selecteer een optie uit de lijst. {value} is geen geldige keuze.'
|
||||||
SilverStripe\Forms\NullableField:
|
SilverStripe\Forms\NullableField:
|
||||||
IsNullLabel: 'Is null'
|
IsNullLabel: 'Is null'
|
||||||
SilverStripe\Forms\NumericField:
|
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\TimeField:
|
SilverStripe\Forms\TimeField:
|
||||||
VALIDATEFORMAT: 'Vul een geldig datumformaat in ({format})'
|
VALIDATEFORMAT: 'Vul een geldig datumformaat in ({format})'
|
||||||
|
SilverStripe\ORM\DataObject:
|
||||||
|
PLURALNAME: 'Data objecten'
|
||||||
|
PLURALS:
|
||||||
|
one: 'Data object'
|
||||||
|
other: '{count} Data objecten'
|
||||||
|
SINGULARNAME: 'Data object'
|
||||||
SilverStripe\ORM\FieldType\DBBoolean:
|
SilverStripe\ORM\FieldType\DBBoolean:
|
||||||
ANY: Elke
|
ANY: Elke
|
||||||
NOANSWER: Nee
|
NOANSWER: Nee
|
||||||
YESANSWER: Ja
|
YESANSWER: Ja
|
||||||
SilverStripe\ORM\FieldType\DBDate:
|
SilverStripe\ORM\FieldType\DBDate:
|
||||||
|
DAYS_SHORT_PLURALS:
|
||||||
|
one: '{count} dag'
|
||||||
|
other: '{count} dagen'
|
||||||
|
HOURS_SHORT_PLURALS:
|
||||||
|
one: '{count} uur'
|
||||||
|
other: '{count} uren'
|
||||||
LessThanMinuteAgo: 'minder dan één minuut'
|
LessThanMinuteAgo: 'minder dan één minuut'
|
||||||
|
MINUTES_SHORT_PLURALS:
|
||||||
|
one: '{count} minuut'
|
||||||
|
other: '{count} minuten'
|
||||||
|
MONTHS_SHORT_PLURALS:
|
||||||
|
one: '{count} maand'
|
||||||
|
other: '{count} maanden'
|
||||||
|
SECONDS_SHORT_PLURALS:
|
||||||
|
one: '{count} seconde'
|
||||||
|
other: '{count} seconden'
|
||||||
TIMEDIFFAGO: '{difference} geleden'
|
TIMEDIFFAGO: '{difference} geleden'
|
||||||
TIMEDIFFIN: 'in {difference}'
|
TIMEDIFFIN: 'in {difference}'
|
||||||
|
YEARS_SHORT_PLURALS:
|
||||||
|
one: '{count} jaar'
|
||||||
|
other: '{count} jaren'
|
||||||
SilverStripe\ORM\FieldType\DBEnum:
|
SilverStripe\ORM\FieldType\DBEnum:
|
||||||
ANY: Elke
|
ANY: Elke
|
||||||
|
SilverStripe\ORM\FieldType\DBForeignKey:
|
||||||
|
DROPDOWN_THRESHOLD_FALLBACK_MESSAGE: 'Teveel keuzes in de lijst; een alternatief veld wordt getoond.'
|
||||||
|
SilverStripe\ORM\Hierarchy:
|
||||||
|
LIMITED_TITLE: 'Teveel onderliggende items ({count})'
|
||||||
SilverStripe\ORM\Hierarchy\Hierarchy:
|
SilverStripe\ORM\Hierarchy\Hierarchy:
|
||||||
InfiniteLoopNotAllowed: 'Oneindige lus gevonden in "{type}" hiërarchie. Wijzig het hogere niveau om dit op te lossen'
|
InfiniteLoopNotAllowed: 'Oneindige lus gevonden in "{type}" hiërarchie. Wijzig het hogere niveau om dit op te lossen'
|
||||||
|
LIMITED_TITLE: 'Teveel onderliggende items ({count})'
|
||||||
SilverStripe\ORM\ValidationException:
|
SilverStripe\ORM\ValidationException:
|
||||||
DEFAULT_ERROR: Validatiefout
|
DEFAULT_ERROR: Validatiefout
|
||||||
SilverStripe\Security\BasicAuth:
|
SilverStripe\Security\BasicAuth:
|
||||||
@ -91,34 +172,60 @@ nl:
|
|||||||
PASSWORDEXPIRED: '<p>Uw wachtwoord is verlopen. <a target="_top" href="{link}">Kies een nieuw wachtwoord.</a></p>'
|
PASSWORDEXPIRED: '<p>Uw wachtwoord is verlopen. <a target="_top" href="{link}">Kies een nieuw wachtwoord.</a></p>'
|
||||||
SilverStripe\Security\CMSSecurity:
|
SilverStripe\Security\CMSSecurity:
|
||||||
INVALIDUSER: '<p>Ongeldige gebruiker <a target="_top" href="{link}">Log hier opnieuw in</a> om verder te gaan.</p>'
|
INVALIDUSER: '<p>Ongeldige gebruiker <a target="_top" href="{link}">Log hier opnieuw in</a> om verder te gaan.</p>'
|
||||||
|
LOGIN_MESSAGE: 'Sessie is verlopen'
|
||||||
|
LOGIN_TITLE: '<p>U kunt verder met wat u aan het doen was, door opnieuw in te loggen.</p>'
|
||||||
SUCCESS: Succes
|
SUCCESS: Succes
|
||||||
SUCCESSCONTENT: '<p>U bent ingelogd. <a target="_top" href="{link}">Klik hier</a> als u niet automatisch wordt doorgestuurd.</p>'
|
SUCCESSCONTENT: '<p>U bent ingelogd. <a target="_top" href="{link}">Klik hier</a> als u niet automatisch wordt doorgestuurd.</p>'
|
||||||
|
SUCCESS_TITLE: 'Inloggen is gelukt'
|
||||||
|
SilverStripe\Security\DefaultAdminService:
|
||||||
|
DefaultAdminFirstname: 'Standaard Beheerder'
|
||||||
SilverStripe\Security\Group:
|
SilverStripe\Security\Group:
|
||||||
AddRole: 'Voeg een rol toe aan deze groep'
|
AddRole: 'Voeg een rol toe aan deze groep'
|
||||||
Code: 'Groep code'
|
Code: 'Groep code'
|
||||||
DefaultGroupTitleAdministrators: Beheerders
|
DefaultGroupTitleAdministrators: Beheerders
|
||||||
DefaultGroupTitleContentAuthors: 'Inhoud Auteurs'
|
DefaultGroupTitleContentAuthors: 'Inhoud Auteurs'
|
||||||
Description: 'Omschrijving '
|
Description: 'Omschrijving '
|
||||||
|
GROUPNAME: 'Groep naam'
|
||||||
GroupReminder: 'Als u de bovenliggende groep selecteert, neemt deze groep alle rollen over'
|
GroupReminder: 'Als u de bovenliggende groep selecteert, neemt deze groep alle rollen over'
|
||||||
HierarchyPermsError: 'U moet (ADMIN) rechten hebben om de bovenliggende groep "{group}" toe te kennen'
|
HierarchyPermsError: 'U moet (ADMIN) rechten hebben om de bovenliggende groep "{group}" toe te kennen'
|
||||||
Locked: 'Gesloten?'
|
Locked: 'Gesloten?'
|
||||||
|
MEMBERS: Leden
|
||||||
|
NEWGROUP: 'Nieuwe groep'
|
||||||
NoRoles: 'Geen rollen gevonden'
|
NoRoles: 'Geen rollen gevonden'
|
||||||
|
PERMISSIONS: Rechten
|
||||||
|
PLURALNAME: Groepen
|
||||||
|
PLURALS:
|
||||||
|
one: 'Een groep'
|
||||||
|
other: '{count} groepen'
|
||||||
Parent: 'Bovenliggende groep'
|
Parent: 'Bovenliggende groep'
|
||||||
|
ROLES: Rollen
|
||||||
|
ROLESDESCRIPTION: 'Rollen zijn logische groeperingen van rechten die in het Rollen tabblad gewijzigd kunnen worden.<br />Rollen worden automatisch overgenomen van bovenliggende groepen.'
|
||||||
RolesAddEditLink: 'Rollen beheren'
|
RolesAddEditLink: 'Rollen beheren'
|
||||||
|
SINGULARNAME: Groep
|
||||||
Sort: Sorteer-richting
|
Sort: Sorteer-richting
|
||||||
has_many_Permissions: Rechten
|
has_many_Permissions: Rechten
|
||||||
many_many_Members: Leden
|
many_many_Members: Leden
|
||||||
SilverStripe\Security\LoginAttempt:
|
SilverStripe\Security\LoginAttempt:
|
||||||
|
Email: 'E-mailadres '
|
||||||
|
EmailHashed: 'E-mailadres (versleuteld)'
|
||||||
IP: 'IP adres'
|
IP: 'IP adres'
|
||||||
|
PLURALNAME: Inlogpogingen
|
||||||
|
PLURALS:
|
||||||
|
one: 'Een inlogpoging'
|
||||||
|
other: '{count} inlogpogingen'
|
||||||
|
SINGULARNAME: Inlogpogingen
|
||||||
Status: Status
|
Status: Status
|
||||||
SilverStripe\Security\Member:
|
SilverStripe\Security\Member:
|
||||||
ADDGROUP: 'Groep toevoegen'
|
ADDGROUP: 'Groep toevoegen'
|
||||||
BUTTONCHANGEPASSWORD: 'Wachtwoord veranderen'
|
BUTTONCHANGEPASSWORD: 'Wachtwoord veranderen'
|
||||||
BUTTONLOGIN: Inloggen
|
BUTTONLOGIN: Inloggen
|
||||||
BUTTONLOGINOTHER: 'Als iemand anders inloggen'
|
BUTTONLOGINOTHER: 'Als iemand anders inloggen'
|
||||||
|
BUTTONLOGOUT: Uitloggen
|
||||||
BUTTONLOSTPASSWORD: 'Ik ben mijn wachtwoord vergeten'
|
BUTTONLOSTPASSWORD: 'Ik ben mijn wachtwoord vergeten'
|
||||||
CONFIRMNEWPASSWORD: 'Bevestig het nieuwe wachtwoord'
|
CONFIRMNEWPASSWORD: 'Bevestig het nieuwe wachtwoord'
|
||||||
CONFIRMPASSWORD: 'Bevestig wachtwoord'
|
CONFIRMPASSWORD: 'Bevestig wachtwoord'
|
||||||
|
CURRENT_PASSWORD: 'Huidige wachtwoord'
|
||||||
|
EDIT_PASSWORD: 'Nieuw wachtwoord'
|
||||||
EMAIL: E-mail
|
EMAIL: E-mail
|
||||||
EMPTYNEWPASSWORD: 'Het nieuwe wachtwoord mag niet leeg zijn, probeer opnieuw'
|
EMPTYNEWPASSWORD: 'Het nieuwe wachtwoord mag niet leeg zijn, probeer opnieuw'
|
||||||
ENTEREMAIL: 'Typ uw e-mailadres om een link te ontvangen waarmee u uw wachtwoord kunt resetten.'
|
ENTEREMAIL: 'Typ uw e-mailadres om een link te ontvangen waarmee u uw wachtwoord kunt resetten.'
|
||||||
@ -128,13 +235,21 @@ nl:
|
|||||||
ERRORWRONGCRED: 'De ingevulde gegevens lijken niet correct. Probeer het nog een keer.'
|
ERRORWRONGCRED: 'De ingevulde gegevens lijken niet correct. Probeer het nog een keer.'
|
||||||
FIRSTNAME: Voornaam
|
FIRSTNAME: Voornaam
|
||||||
INTERFACELANG: 'Interface taal'
|
INTERFACELANG: 'Interface taal'
|
||||||
|
KEEPMESIGNEDIN: 'Houd mij ingelogd'
|
||||||
LOGGEDINAS: 'U bent ingelogd als {name}.'
|
LOGGEDINAS: 'U bent ingelogd als {name}.'
|
||||||
NEWPASSWORD: 'Nieuw wachtwoord'
|
NEWPASSWORD: 'Nieuw wachtwoord'
|
||||||
PASSWORD: Wachtwoord
|
PASSWORD: Wachtwoord
|
||||||
PASSWORDEXPIRED: 'Uw wachtwoord is verlopen. Kies een nieuw wachtwoord.'
|
PASSWORDEXPIRED: 'Uw wachtwoord is verlopen. Kies een nieuw wachtwoord.'
|
||||||
|
PLURALNAME: Leden
|
||||||
|
PLURALS:
|
||||||
|
one: 'Een lid'
|
||||||
|
other: '{count} leden'
|
||||||
|
REMEMBERME: 'Onthoud mij voor volgende keer? (voor {count} dagen op dit apparaat)'
|
||||||
|
SINGULARNAME: Lid
|
||||||
SUBJECTPASSWORDCHANGED: 'Uw wachtwoord is veranderd'
|
SUBJECTPASSWORDCHANGED: 'Uw wachtwoord is veranderd'
|
||||||
SUBJECTPASSWORDRESET: 'Link om uw wachtwoord opnieuw aan te maken'
|
SUBJECTPASSWORDRESET: 'Link om uw wachtwoord opnieuw aan te maken'
|
||||||
SURNAME: Achternaam
|
SURNAME: Achternaam
|
||||||
|
VALIDATIONADMINLOSTACCESS: 'Niet mogelijk om alle admin-groepen te verwijderen van uw profiel'
|
||||||
ValidationIdentifierFailed: 'Een bestaande gebruiker #{id} kan niet dezelfde unieke velden hebben ({name} = {value}))'
|
ValidationIdentifierFailed: 'Een bestaande gebruiker #{id} kan niet dezelfde unieke velden hebben ({name} = {value}))'
|
||||||
WELCOMEBACK: 'Welkom terug, {firstname}'
|
WELCOMEBACK: 'Welkom terug, {firstname}'
|
||||||
YOUROLDPASSWORD: 'Uw oude wachtwoord'
|
YOUROLDPASSWORD: 'Uw oude wachtwoord'
|
||||||
@ -143,15 +258,38 @@ nl:
|
|||||||
db_LockedOutUntil: 'Gesloten tot'
|
db_LockedOutUntil: 'Gesloten tot'
|
||||||
db_Password: Wachtwoord
|
db_Password: Wachtwoord
|
||||||
db_PasswordExpiry: 'Wachtwoord vervaldatum'
|
db_PasswordExpiry: 'Wachtwoord vervaldatum'
|
||||||
|
SilverStripe\Security\MemberAuthenticator\CMSMemberLoginForm:
|
||||||
|
AUTHENTICATORNAME: Inlogformulier
|
||||||
|
BUTTONFORGOTPASSWORD: 'Wachtwoord vergeten'
|
||||||
|
BUTTONLOGIN: 'Opnieuw inloggen'
|
||||||
|
BUTTONLOGOUT: Uitloggen
|
||||||
|
SilverStripe\Security\MemberAuthenticator\MemberAuthenticator:
|
||||||
|
ERRORWRONGCRED: 'De ingevulde gegevens lijken niet correct. Probeer het nog een keer.'
|
||||||
|
NoPassword: 'Er is geen wachtwoord voor deze gebruiker.'
|
||||||
|
SilverStripe\Security\MemberAuthenticator\MemberLoginForm:
|
||||||
|
AUTHENTICATORNAME: 'E-mail & wachtwoord'
|
||||||
|
SilverStripe\Security\MemberPassword:
|
||||||
|
PLURALNAME: Gebruikerswachtwoorden
|
||||||
|
PLURALS:
|
||||||
|
one: 'Een gebruikerswachtwoord'
|
||||||
|
other: '{count} Gebruikerswachtwoorden'
|
||||||
|
SINGULARNAME: Gebruikerswachtwoord
|
||||||
SilverStripe\Security\PasswordValidator:
|
SilverStripe\Security\PasswordValidator:
|
||||||
LOWCHARSTRENGTH: 'Maak a.u.b. uw wachtwoord sterker door enkele van de volgende karakters te gebruiken: {chars}'
|
LOWCHARSTRENGTH: 'Maak a.u.b. uw wachtwoord sterker door enkele van de volgende karakters te gebruiken: {chars}'
|
||||||
PREVPASSWORD: 'U heeft dit wachtwoord in het verleden al gebruikt, kies a.u.b. een nieuw wachtwoord.'
|
PREVPASSWORD: 'U heeft dit wachtwoord in het verleden al gebruikt, kies a.u.b. een nieuw wachtwoord.'
|
||||||
TOOSHORT: 'Het wachtwoord is te kort, het moet minimaal {minimum} karakters hebben'
|
TOOSHORT: 'Het wachtwoord is te kort, het moet minimaal {minimum} karakters hebben'
|
||||||
SilverStripe\Security\Permission:
|
SilverStripe\Security\Permission:
|
||||||
AdminGroup: Beheerder
|
AdminGroup: Beheerder
|
||||||
|
CMS_ACCESS_CATEGORY: 'CMS toegang'
|
||||||
CONTENT_CATEGORY: Inhoudsrechten
|
CONTENT_CATEGORY: Inhoudsrechten
|
||||||
FULLADMINRIGHTS: 'Volledige admin rechten'
|
FULLADMINRIGHTS: 'Volledige admin rechten'
|
||||||
FULLADMINRIGHTS_HELP: 'Impliceert en overstemt alle andere toegewezen rechten.'
|
FULLADMINRIGHTS_HELP: 'Impliceert en overstemt alle andere toegewezen rechten.'
|
||||||
|
PERMISSIONS_CATEGORY: 'Rollen en toegangsrechten'
|
||||||
|
PLURALNAME: Rechten
|
||||||
|
PLURALS:
|
||||||
|
one: Machtiging
|
||||||
|
other: '{count} rechten'
|
||||||
|
SINGULARNAME: Machtiging
|
||||||
UserPermissionsIntro: 'Groepen aan deze gebruiker toewijzen zullen diens permissies aanpassen. Zie de sectie Groepen voor meer informatie over machtigingen voor afzonderlijke groepen.'
|
UserPermissionsIntro: 'Groepen aan deze gebruiker toewijzen zullen diens permissies aanpassen. Zie de sectie Groepen voor meer informatie over machtigingen voor afzonderlijke groepen.'
|
||||||
SilverStripe\Security\PermissionCheckboxSetField:
|
SilverStripe\Security\PermissionCheckboxSetField:
|
||||||
AssignedTo: 'toegewezen aan "{title}"'
|
AssignedTo: 'toegewezen aan "{title}"'
|
||||||
@ -161,21 +299,37 @@ nl:
|
|||||||
SilverStripe\Security\PermissionRole:
|
SilverStripe\Security\PermissionRole:
|
||||||
OnlyAdminCanApply: 'Alleen admin kan doorvoeren'
|
OnlyAdminCanApply: 'Alleen admin kan doorvoeren'
|
||||||
PLURALNAME: Rollen
|
PLURALNAME: Rollen
|
||||||
|
PLURALS:
|
||||||
|
one: 'Een rol'
|
||||||
|
other: '{count} rollen'
|
||||||
SINGULARNAME: Rol
|
SINGULARNAME: Rol
|
||||||
Title: Titel
|
Title: Titel
|
||||||
SilverStripe\Security\PermissionRoleCode:
|
SilverStripe\Security\PermissionRoleCode:
|
||||||
|
PLURALNAME: 'Permissie codes'
|
||||||
|
PLURALS:
|
||||||
|
one: 'Een permissiecode'
|
||||||
|
other: '{count} permissiecodes'
|
||||||
PermsError: 'U moet (ADMIN) rechten hebben om de code "{code}" toe te kennen'
|
PermsError: 'U moet (ADMIN) rechten hebben om de code "{code}" toe te kennen'
|
||||||
|
SINGULARNAME: Permissiecode
|
||||||
|
SilverStripe\Security\RememberLoginHash:
|
||||||
|
PLURALNAME: 'Versleutelde logins'
|
||||||
|
PLURALS:
|
||||||
|
one: 'Een versleutelde login'
|
||||||
|
other: '{count} versleutelde logins'
|
||||||
|
SINGULARNAME: 'Versleutelde login'
|
||||||
SilverStripe\Security\Security:
|
SilverStripe\Security\Security:
|
||||||
ALREADYLOGGEDIN: 'U hebt geen toegang tot deze pagina. Als u een andere account met de nodige rechten hebt, kan u hieronder opnieuw inloggen.'
|
ALREADYLOGGEDIN: 'U hebt geen toegang tot deze pagina. Als u een andere account met de nodige rechten hebt, kan u hieronder opnieuw inloggen.'
|
||||||
BUTTONSEND: 'Nieuw wachtwoord aanmaken'
|
BUTTONSEND: 'Nieuw wachtwoord aanmaken'
|
||||||
CHANGEPASSWORDBELOW: 'U kunt uw wachtwoord hieronder veranderen.'
|
CHANGEPASSWORDBELOW: 'U kunt uw wachtwoord hieronder veranderen.'
|
||||||
CHANGEPASSWORDHEADER: 'Verander uw wachtwoord'
|
CHANGEPASSWORDHEADER: 'Verander uw wachtwoord'
|
||||||
|
CONFIRMLOGOUT: 'Klik op onderstaande knop om uit te loggen.'
|
||||||
ENTERNEWPASSWORD: 'Voer een nieuw wachtwoord in.'
|
ENTERNEWPASSWORD: 'Voer een nieuw wachtwoord in.'
|
||||||
ERRORPASSWORDPERMISSION: 'U moet ingelogd zijn om uw wachtwoord te kunnen veranderen!'
|
ERRORPASSWORDPERMISSION: 'U moet ingelogd zijn om uw wachtwoord te kunnen veranderen!'
|
||||||
LOGIN: 'Meld aan'
|
LOGIN: 'Meld aan'
|
||||||
|
LOGOUT: Uitloggen
|
||||||
LOSTPASSWORDHEADER: 'Wachtwoord vergeten'
|
LOSTPASSWORDHEADER: 'Wachtwoord vergeten'
|
||||||
NOTEPAGESECURED: 'Deze pagina is beveiligd. Voer uw gegevens in en u wordt automatisch doorgestuurd.'
|
NOTEPAGESECURED: 'Deze pagina is beveiligd. Voer uw gegevens in en u wordt automatisch doorgestuurd.'
|
||||||
NOTERESETLINKINVALID: '<p>De link om uw wachtwoord te kunnen wijzigen is niet meer geldig.</p><p>U kunt <a href="{link1}">een nieuwe link aanvragen</a> of uw wachtwoord aanpassen door <a href="{link2}">in te loggen</a>.</p>'
|
NOTERESETLINKINVALID: '<p>De reset link is ongeldig of komen te vervallen.</p><p>Je kan <a href="{link1}">hier</a> een nieuwe link aanvragen of het wachtwoord veranderen nadat je bent <a href="{link2}">ingelogd</a>.</p>'
|
||||||
NOTERESETPASSWORD: 'Voer uw e-mailadres in en we sturen een link waarmee u een nieuw wachtwoord kunt instellen.'
|
NOTERESETPASSWORD: 'Voer uw e-mailadres in en we sturen een link waarmee u een nieuw wachtwoord kunt instellen.'
|
||||||
PASSWORDSENTHEADER: 'Wachtwoord herstel link verzonden naar {email}'
|
PASSWORDRESETSENTHEADER: 'link om uw wachtwoord opnieuw aan te maken'
|
||||||
PASSWORDSENTTEXT: 'Bedankt! Er is een link verstuurd naar {email} om uw wachtwoord opnieuw in te stellen, in de veronderstelling dat er een account bestaat voor dit e-mailadres.'
|
PASSWORDRESETSENTTEXT: 'Bedankt! Er is een link verstuurd om uw wachtwoord opnieuw in te stellen (mits het mailadres reeds bekend is bij ons).'
|
||||||
|
@ -84,7 +84,6 @@ pl:
|
|||||||
RelationSearch: 'Wyszukiwanie powiązań'
|
RelationSearch: 'Wyszukiwanie powiązań'
|
||||||
ResetFilter: Resetuj
|
ResetFilter: Resetuj
|
||||||
SilverStripe\Forms\GridField\GridFieldDeleteAction:
|
SilverStripe\Forms\GridField\GridFieldDeleteAction:
|
||||||
DELETE_DESCRIPTION: Usuń
|
|
||||||
Delete: Usuń
|
Delete: Usuń
|
||||||
DeletePermissionsFailure: 'Brak uprawnień do usuwania'
|
DeletePermissionsFailure: 'Brak uprawnień do usuwania'
|
||||||
EditPermissionsFailure: 'Nie masz uprawnień, aby odłączyć rekord'
|
EditPermissionsFailure: 'Nie masz uprawnień, aby odłączyć rekord'
|
||||||
@ -96,8 +95,6 @@ pl:
|
|||||||
DeletePermissionsFailure: 'Brak uprawnień do usuwania'
|
DeletePermissionsFailure: 'Brak uprawnień do usuwania'
|
||||||
Deleted: 'Usunięto {type} {name}'
|
Deleted: 'Usunięto {type} {name}'
|
||||||
Save: Zapisz
|
Save: Zapisz
|
||||||
SilverStripe\Forms\GridField\GridFieldEditButton_ss:
|
|
||||||
EDIT: Edytuj
|
|
||||||
SilverStripe\Forms\GridField\GridFieldGroupDeleteAction:
|
SilverStripe\Forms\GridField\GridFieldGroupDeleteAction:
|
||||||
UnlinkSelfFailure: 'Nie możesz usunąć siebie z tej grupy, stracone zostałby prawa administratora'
|
UnlinkSelfFailure: 'Nie możesz usunąć siebie z tej grupy, stracone zostałby prawa administratora'
|
||||||
SilverStripe\Forms\GridField\GridFieldPaginator:
|
SilverStripe\Forms\GridField\GridFieldPaginator:
|
||||||
@ -352,7 +349,4 @@ pl:
|
|||||||
LOGOUT: 'Wyloguj się'
|
LOGOUT: 'Wyloguj się'
|
||||||
LOSTPASSWORDHEADER: 'Nie pamiętam hasła'
|
LOSTPASSWORDHEADER: 'Nie pamiętam hasła'
|
||||||
NOTEPAGESECURED: 'Ta strona jest zabezpieczona. Wpisz swoje dane a my wyślemy Ci potwierdzenie niebawem'
|
NOTEPAGESECURED: 'Ta strona jest zabezpieczona. Wpisz swoje dane a my wyślemy Ci potwierdzenie niebawem'
|
||||||
NOTERESETLINKINVALID: '<p>Link resetujący hasło wygasł lub jest nieprawidłowy.</p><p>Możesz poprosić o nowy <a href="{link1}">tutaj</a> lub zmień swoje hasło po <a href="{link2}">zalogowaniu się</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Wpisz adres e-mail, na który mamy wysłać link gdzie możesz zresetować swoje hasło'
|
NOTERESETPASSWORD: 'Wpisz adres e-mail, na który mamy wysłać link gdzie możesz zresetować swoje hasło'
|
||||||
PASSWORDSENTHEADER: 'Link resetujący hasła został wysłany do ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Dziękujemy! Link resetujący hasło został wysłany do ''{email}'', o ile konto użytkownika dla takiego e-maila istnieje.'
|
|
||||||
|
@ -339,7 +339,4 @@ ru:
|
|||||||
LOGOUT: Выйти
|
LOGOUT: Выйти
|
||||||
LOSTPASSWORDHEADER: 'Восстановление пароля'
|
LOSTPASSWORDHEADER: 'Восстановление пароля'
|
||||||
NOTEPAGESECURED: 'Эта страница защищена. Пожалуйста, введите свои учетные данные для входа.'
|
NOTEPAGESECURED: 'Эта страница защищена. Пожалуйста, введите свои учетные данные для входа.'
|
||||||
NOTERESETLINKINVALID: '<p>Неверная ссылка переустановки пароля или время действия ссылки истекло.</p><p>Вы можете повторно запросить ссылку, щелкнув <a href="{link1}">здесь</a>, или поменять пароль, <a href="{link2}">войдя в систему</a>.</p> '
|
|
||||||
NOTERESETPASSWORD: 'Введите Ваш адрес email, и Вам будет отправлена ссылка, по которой Вы сможете переустановить свой пароль'
|
NOTERESETPASSWORD: 'Введите Ваш адрес email, и Вам будет отправлена ссылка, по которой Вы сможете переустановить свой пароль'
|
||||||
PASSWORDSENTHEADER: 'Ссылка для переустановки пароля выслана на ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Ссылка переустановки пароля была выслана на адрес ''{email}'' (письмо дойдет до получателя только в том случае, если аккаунт с таким электронным адресом действительно зарегистрирован).'
|
|
||||||
|
@ -228,7 +228,4 @@ sk:
|
|||||||
LOGIN: Prihlásiť
|
LOGIN: Prihlásiť
|
||||||
LOSTPASSWORDHEADER: 'Zabudnuté heslo'
|
LOSTPASSWORDHEADER: 'Zabudnuté heslo'
|
||||||
NOTEPAGESECURED: 'Táto stránka je zabezpečená. Zadajte svoje prihlasovacie údaje a my Vám zároveň pošleme práva.'
|
NOTEPAGESECURED: 'Táto stránka je zabezpečená. Zadajte svoje prihlasovacie údaje a my Vám zároveň pošleme práva.'
|
||||||
NOTERESETLINKINVALID: '<p>Odkaz na resetovanie hesla nie je platný alebo je vypršala jeho platnosť.</p><p>Môžete požiadať o nový <a href="{link1}">tu</a> alebo zmeňte svoje heslo po <a href="{link2}">prihlásení</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Zadajte svoju e-mailovú adresu a my Vám pošleme odkaz na resetovanie hesla'
|
NOTERESETPASSWORD: 'Zadajte svoju e-mailovú adresu a my Vám pošleme odkaz na resetovanie hesla'
|
||||||
PASSWORDSENTHEADER: 'Odkaz na resetovanie hesla bol odoslaný na ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Ďakujeme! Resetovací odkaz bol odoslaný na ''''{email}'''', pokiaľ účet existuje pre túto emailovú adresu.'
|
|
||||||
|
@ -135,7 +135,4 @@ sl:
|
|||||||
LOGIN: Prijava
|
LOGIN: Prijava
|
||||||
LOSTPASSWORDHEADER: 'Izgubljeno geslo'
|
LOSTPASSWORDHEADER: 'Izgubljeno geslo'
|
||||||
NOTEPAGESECURED: 'Stran je zaščitena. Da bi lahko nadaljevali, vpišite svoje podatke.'
|
NOTEPAGESECURED: 'Stran je zaščitena. Da bi lahko nadaljevali, vpišite svoje podatke.'
|
||||||
NOTERESETLINKINVALID: '<p>Povezava za ponastavitev gesla je napačna ali pa je njena veljavnost potekla.</p><p><a href="{link1}">Tukaj</a> lahko zaprosite za novo povezavo or pa zamenjate geslo, ko <a href="{link2}">se prijavite v sistem</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Vpišite e-naslov, na katerega vam bomo poslali povezavo za ponastavitev gesla'
|
NOTERESETPASSWORD: 'Vpišite e-naslov, na katerega vam bomo poslali povezavo za ponastavitev gesla'
|
||||||
PASSWORDSENTHEADER: 'Povezava za ponastavitev gesla je bila poslana na e-naslov ''{email}''.'
|
|
||||||
PASSWORDSENTTEXT: 'Hvala! Povezava za ponastavitev gesla je bila poslana na e-naslov ''{email}'', ki je naveden kot e-naslov vašega računa. '
|
|
||||||
|
@ -151,7 +151,4 @@ sr:
|
|||||||
ERRORPASSWORDPERMISSION: 'Морате да будете пријављени да бисте променили своју лозинку!'
|
ERRORPASSWORDPERMISSION: 'Морате да будете пријављени да бисте променили своју лозинку!'
|
||||||
LOGIN: Пријављивање
|
LOGIN: Пријављивање
|
||||||
NOTEPAGESECURED: 'Ова страна је обезбеђена. Унесите своје податке и ми ћемо вам послати садржај.'
|
NOTEPAGESECURED: 'Ова страна је обезбеђена. Унесите своје податке и ми ћемо вам послати садржај.'
|
||||||
NOTERESETLINKINVALID: '<p>Линк за ресетовање лозинке је погрешан или је истекло време за његово коришћење.</p><p>Можете да захтевате нови <a href="{link1}">овде</a> или да промените Вашу лозинку након што се <a href="{link2}">пријавите</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Унесите своју адресу е-поште и ми ћемо вам послати линк помоћу којег можете да промените своју лозинку'
|
NOTERESETPASSWORD: 'Унесите своју адресу е-поште и ми ћемо вам послати линк помоћу којег можете да промените своју лозинку'
|
||||||
PASSWORDSENTHEADER: 'Линк за ресетовање лозинке послат је на адресу е-поште: ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Хвала Вам! Линк за ресетовање лозинке је послат не адресу е-поште ''{email}''. Порука ће стићи примаоцу само ако постоји регистрован налог са том адресом е-поште.'
|
|
||||||
|
@ -150,7 +150,4 @@ sr@latin:
|
|||||||
ERRORPASSWORDPERMISSION: 'Morate da budete prijavljeni da biste promenili svoju lozinku!'
|
ERRORPASSWORDPERMISSION: 'Morate da budete prijavljeni da biste promenili svoju lozinku!'
|
||||||
LOGIN: Prijavljivanje
|
LOGIN: Prijavljivanje
|
||||||
NOTEPAGESECURED: 'Ova strana je obezbeđena. Unesite svoje podatke i mi ćemo vam poslati sadržaj.'
|
NOTEPAGESECURED: 'Ova strana je obezbeđena. Unesite svoje podatke i mi ćemo vam poslati sadržaj.'
|
||||||
NOTERESETLINKINVALID: '<p>Link za resetovanje lozinke je pogrešan ili je isteklo vreme za njegovo korišćenje.</p><p>Možete da zahtevate novi <a href="{link1}">ovde</a> ili da promenite Vašu lozinku nakon što se <a href="{link2}">prijavite</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Unesite svoju adresu e-pošte i mi ćemo vam poslati link pomoću kojeg možete da promenite svoju lozinku'
|
NOTERESETPASSWORD: 'Unesite svoju adresu e-pošte i mi ćemo vam poslati link pomoću kojeg možete da promenite svoju lozinku'
|
||||||
PASSWORDSENTHEADER: 'Link za resetovanje lozinke poslat je na adresu e-pošte: ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Hvala Vam! Link za resetovanje lozinke je poslat ne adresu e-pošte ''{email}''. Poruka će stići primaocu samo ako postoji registrovan nalog sa tom adresom e-pošte.'
|
|
||||||
|
@ -150,7 +150,4 @@ sr_RS:
|
|||||||
ERRORPASSWORDPERMISSION: 'Морате да будете пријављени да бисте променили своју лозинку!'
|
ERRORPASSWORDPERMISSION: 'Морате да будете пријављени да бисте променили своју лозинку!'
|
||||||
LOGIN: Пријављивање
|
LOGIN: Пријављивање
|
||||||
NOTEPAGESECURED: 'Ова страна је обезбеђена. Унесите своје податке и ми ћемо вам послати садржај.'
|
NOTEPAGESECURED: 'Ова страна је обезбеђена. Унесите своје податке и ми ћемо вам послати садржај.'
|
||||||
NOTERESETLINKINVALID: '<p>Линк за ресетовање лозинке је погрешан или је истекло време за његово коришћење.</p><p>Можете да захтевате нови <a href="{link1}">овде</a> или да промените Вашу лозинку након што се <a href="{link2}">пријавите</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Унесите своју адресу е-поште и ми ћемо вам послати линк помоћу којег можете да промените своју лозинку'
|
NOTERESETPASSWORD: 'Унесите своју адресу е-поште и ми ћемо вам послати линк помоћу којег можете да промените своју лозинку'
|
||||||
PASSWORDSENTHEADER: 'Линк за ресетовање лозинке послат је на адресу е-поште: ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Хвала Вам! Линк за ресетовање лозинке је послат не адресу е-поште ''{email}''. Порука ће стићи примаоцу само ако постоји регистрован налог са том адресом е-поште.'
|
|
||||||
|
@ -151,7 +151,4 @@ sr_RS@latin:
|
|||||||
ERRORPASSWORDPERMISSION: 'Morate da budete prijavljeni da biste promenili svoju lozinku!'
|
ERRORPASSWORDPERMISSION: 'Morate da budete prijavljeni da biste promenili svoju lozinku!'
|
||||||
LOGIN: Prijavljivanje
|
LOGIN: Prijavljivanje
|
||||||
NOTEPAGESECURED: 'Ova strana je obezbeđena. Unesite svoje podatke i mi ćemo vam poslati sadržaj.'
|
NOTEPAGESECURED: 'Ova strana je obezbeđena. Unesite svoje podatke i mi ćemo vam poslati sadržaj.'
|
||||||
NOTERESETLINKINVALID: '<p>Link za resetovanje lozinke je pogrešan ili je isteklo vreme za njegovo korišćenje.</p><p>Možete da zahtevate novi <a href="{link1}">ovde</a> ili da promenite Vašu lozinku nakon što se <a href="{link2}">prijavite</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Unesite svoju adresu e-pošte i mi ćemo vam poslati link pomoću kojeg možete da promenite svoju lozinku'
|
NOTERESETPASSWORD: 'Unesite svoju adresu e-pošte i mi ćemo vam poslati link pomoću kojeg možete da promenite svoju lozinku'
|
||||||
PASSWORDSENTHEADER: 'Link za resetovanje lozinke poslat je na adresu e-pošte: ''{email}'''
|
|
||||||
PASSWORDSENTTEXT: 'Hvala Vam! Link za resetovanje lozinke je poslat ne adresu e-pošte ''{email}''. Poruka će stići primaocu samo ako postoji registrovan nalog sa tom adresom e-pošte.'
|
|
||||||
|
19
lang/sv.yml
19
lang/sv.yml
@ -93,7 +93,12 @@ sv:
|
|||||||
DeletePermissionsFailure: 'Rättighet för att radera saknas'
|
DeletePermissionsFailure: 'Rättighet för att radera saknas'
|
||||||
Deleted: 'Raderade {type} {name}'
|
Deleted: 'Raderade {type} {name}'
|
||||||
Save: Spara
|
Save: Spara
|
||||||
|
SilverStripe\Forms\GridField\GridFieldEditButton:
|
||||||
|
EDIT: Ändra
|
||||||
|
SilverStripe\Forms\GridField\GridFieldGroupDeleteAction:
|
||||||
|
UnlinkSelfFailure: 'Du kan inte radera dig själv från den här gruppen, då du då kommer att förlora dina admin-rättigheter'
|
||||||
SilverStripe\Forms\GridField\GridFieldPaginator:
|
SilverStripe\Forms\GridField\GridFieldPaginator:
|
||||||
|
OF: av
|
||||||
Page: Sida
|
Page: Sida
|
||||||
View: Visa
|
View: Visa
|
||||||
SilverStripe\Forms\MoneyField:
|
SilverStripe\Forms\MoneyField:
|
||||||
@ -108,6 +113,12 @@ sv:
|
|||||||
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\TimeField:
|
SilverStripe\Forms\TimeField:
|
||||||
VALIDATEFORMAT: 'Var god att ange tid i ett giltigt format ({format})'
|
VALIDATEFORMAT: 'Var god att ange tid i ett giltigt format ({format})'
|
||||||
|
SilverStripe\ORM\DataObject:
|
||||||
|
PLURALNAME: Dataobjekt
|
||||||
|
PLURALS:
|
||||||
|
one: 'Ett dataobjekt'
|
||||||
|
other: '{count} Dataobjekt'
|
||||||
|
SINGULARNAME: Dataobjekt
|
||||||
SilverStripe\ORM\FieldType\DBBoolean:
|
SilverStripe\ORM\FieldType\DBBoolean:
|
||||||
ANY: 'Vilken som helst'
|
ANY: 'Vilken som helst'
|
||||||
NOANSWER: Nej
|
NOANSWER: Nej
|
||||||
@ -136,6 +147,8 @@ sv:
|
|||||||
other: '{count} år'
|
other: '{count} år'
|
||||||
SilverStripe\ORM\FieldType\DBEnum:
|
SilverStripe\ORM\FieldType\DBEnum:
|
||||||
ANY: 'Vilken som helst'
|
ANY: 'Vilken som helst'
|
||||||
|
SilverStripe\ORM\FieldType\DBForeignKey:
|
||||||
|
DROPDOWN_THRESHOLD_FALLBACK_MESSAGE: 'För många relaterade objekt; använder fallback-fält'
|
||||||
SilverStripe\ORM\Hierarchy:
|
SilverStripe\ORM\Hierarchy:
|
||||||
LIMITED_TITLE: 'För många barn ({count})'
|
LIMITED_TITLE: 'För många barn ({count})'
|
||||||
SilverStripe\ORM\Hierarchy\Hierarchy:
|
SilverStripe\ORM\Hierarchy\Hierarchy:
|
||||||
@ -221,6 +234,7 @@ sv:
|
|||||||
PLURALS:
|
PLURALS:
|
||||||
one: 'En medlem'
|
one: 'En medlem'
|
||||||
other: '{count} medlemmar'
|
other: '{count} medlemmar'
|
||||||
|
REMEMBERME: 'Kom ihåg mig nästa gång? (i {count} dagar på denna enhet)'
|
||||||
SINGULARNAME: Medlem
|
SINGULARNAME: Medlem
|
||||||
SUBJECTPASSWORDCHANGED: 'Ditt lösenord har ändrats'
|
SUBJECTPASSWORDCHANGED: 'Ditt lösenord har ändrats'
|
||||||
SUBJECTPASSWORDRESET: 'Din återställningslänk'
|
SUBJECTPASSWORDRESET: 'Din återställningslänk'
|
||||||
@ -288,7 +302,6 @@ sv:
|
|||||||
LOGOUT: 'Logga ut'
|
LOGOUT: 'Logga ut'
|
||||||
LOSTPASSWORDHEADER: 'Bortglömt lösenord'
|
LOSTPASSWORDHEADER: 'Bortglömt lösenord'
|
||||||
NOTEPAGESECURED: 'Den här sidan är låst. Fyll i dina uppgifter nedan så skickar vi dig vidare.'
|
NOTEPAGESECURED: 'Den här sidan är låst. Fyll i dina uppgifter nedan så skickar vi dig vidare.'
|
||||||
NOTERESETLINKINVALID: '<p>Återställningslänk för lösenord är felaktig eller för gammal.</p><p>Du kan begära en ny <a href="{link1}">här</a> eller ändra ditt lösenord när du <a href="{link2}">loggat in</a>.</p>'
|
|
||||||
NOTERESETPASSWORD: 'Ange din e-postadress så skickar vi en länk med vilken du kan återställa ditt lösenord'
|
NOTERESETPASSWORD: 'Ange din e-postadress så skickar vi en länk med vilken du kan återställa ditt lösenord'
|
||||||
PASSWORDSENTHEADER: 'Återställningslänk för lösenord har skickats till ''{email}'''
|
PASSWORDRESETSENTHEADER: 'Återställningslänk för lösenord skickad'
|
||||||
PASSWORDSENTTEXT: 'Tack en återställningslänk har skickats till ''{email}'', förutsatt att ett konto med den addressen finns.'
|
PASSWORDRESETSENTTEXT: 'Tack. En återställningslänk har skickats, förutsatt att ett konto med denna adress existerar.'
|
||||||
|
@ -166,7 +166,4 @@ zh:
|
|||||||
LOGIN: 登录
|
LOGIN: 登录
|
||||||
LOSTPASSWORDHEADER: 忘记密码
|
LOSTPASSWORDHEADER: 忘记密码
|
||||||
NOTEPAGESECURED: 该页面受安全保护。请在下面输入您的证书,然后我们会立即将您引导至该页面。
|
NOTEPAGESECURED: 该页面受安全保护。请在下面输入您的证书,然后我们会立即将您引导至该页面。
|
||||||
NOTERESETLINKINVALID: '<p>密码重设链接无效或已过期。</p><p>您可以在<a href="{link1}">这里</a> 要求一个新的或在<a href="{link2}">登录</a>后更改您的密码。</p>'
|
|
||||||
NOTERESETPASSWORD: 请输入您的电子邮件地址,然后我们会将一个链接发送给您,您可以用它来重设您的密码
|
NOTERESETPASSWORD: 请输入您的电子邮件地址,然后我们会将一个链接发送给您,您可以用它来重设您的密码
|
||||||
PASSWORDSENTHEADER: '密码重设链接已发送至''{email}'''
|
|
||||||
PASSWORDSENTTEXT: '谢谢!复位链接已发送到 ''{email}'',假定此电子邮件地址存在一个帐户。'
|
|
||||||
|
@ -41,7 +41,7 @@ class HTTPApplication implements Application
|
|||||||
*/
|
*/
|
||||||
public function handle(HTTPRequest $request)
|
public function handle(HTTPRequest $request)
|
||||||
{
|
{
|
||||||
$flush = array_key_exists('flush', $request->getVars()) || strpos($request->getURL(), 'dev/build') === 0;
|
$flush = array_key_exists('flush', $request->getVars()) || ($request->getURL() === 'dev/build');
|
||||||
|
|
||||||
// Ensure boot is invoked
|
// Ensure boot is invoked
|
||||||
return $this->execute($request, function (HTTPRequest $request) {
|
return $this->execute($request, function (HTTPRequest $request) {
|
||||||
|
192
src/Core/Startup/AbstractConfirmationToken.php
Normal file
192
src/Core/Startup/AbstractConfirmationToken.php
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Core\Startup;
|
||||||
|
|
||||||
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Control\Director;
|
||||||
|
use SilverStripe\Control\HTTPRequest;
|
||||||
|
use SilverStripe\Control\HTTPResponse;
|
||||||
|
use SilverStripe\Core\Convert;
|
||||||
|
use SilverStripe\Security\RandomGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared functionality for token-based authentication of potentially dangerous URLs or query
|
||||||
|
* string parameters
|
||||||
|
*
|
||||||
|
* @internal This class is designed specifically for use pre-startup and may change without warning
|
||||||
|
*/
|
||||||
|
abstract class AbstractConfirmationToken
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var HTTPRequest
|
||||||
|
*/
|
||||||
|
protected $request = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The validated and checked token for this parameter
|
||||||
|
*
|
||||||
|
* @var string|null A string value, or null if either not provided or invalid
|
||||||
|
*/
|
||||||
|
protected $token = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a list of token names, suppress all tokens that have not been validated, and
|
||||||
|
* return the non-validated token with the highest priority
|
||||||
|
*
|
||||||
|
* @param array $keys List of token keys in ascending priority (low to high)
|
||||||
|
* @param HTTPRequest $request
|
||||||
|
* @return static The token container for the unvalidated $key given with the highest priority
|
||||||
|
*/
|
||||||
|
public static function prepare_tokens($keys, HTTPRequest $request)
|
||||||
|
{
|
||||||
|
$target = null;
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$token = new static($key, $request);
|
||||||
|
// Validate this token
|
||||||
|
if ($token->reloadRequired() || $token->reloadRequiredIfError()) {
|
||||||
|
$token->suppress();
|
||||||
|
$target = $token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $target;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a local filesystem path to store a token
|
||||||
|
*
|
||||||
|
* @param $token
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function pathForToken($token)
|
||||||
|
{
|
||||||
|
return TEMP_PATH . DIRECTORY_SEPARATOR . 'token_' . preg_replace('/[^a-z0-9]+/', '', $token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a new random token and store it
|
||||||
|
*
|
||||||
|
* @return string Token name
|
||||||
|
*/
|
||||||
|
protected function genToken()
|
||||||
|
{
|
||||||
|
// Generate a new random token (as random as possible)
|
||||||
|
$rg = new RandomGenerator();
|
||||||
|
$token = $rg->randomToken('md5');
|
||||||
|
|
||||||
|
// Store a file in the session save path (safer than /tmp, as open_basedir might limit that)
|
||||||
|
file_put_contents($this->pathForToken($token), $token);
|
||||||
|
|
||||||
|
return $token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the necessary token provided for this parameter?
|
||||||
|
* A value must be provided for the token
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function tokenProvided()
|
||||||
|
{
|
||||||
|
return !empty($this->token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a token
|
||||||
|
*
|
||||||
|
* @param string $token
|
||||||
|
* @return boolean True if the token is valid
|
||||||
|
*/
|
||||||
|
protected function checkToken($token)
|
||||||
|
{
|
||||||
|
if (!$token) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $this->pathForToken($token);
|
||||||
|
$content = null;
|
||||||
|
|
||||||
|
if (file_exists($file)) {
|
||||||
|
$content = file_get_contents($file);
|
||||||
|
unlink($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $content === $token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get redirect url, excluding querystring
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function currentURL()
|
||||||
|
{
|
||||||
|
return Controller::join_links(Director::baseURL(), $this->request->getURL(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces a reload of the request with the token included
|
||||||
|
*
|
||||||
|
* @return HTTPResponse
|
||||||
|
*/
|
||||||
|
public function reloadWithToken()
|
||||||
|
{
|
||||||
|
$location = $this->redirectURL();
|
||||||
|
$locationJS = Convert::raw2js($location);
|
||||||
|
$locationATT = Convert::raw2att($location);
|
||||||
|
$body = <<<HTML
|
||||||
|
<script>location.href='$locationJS';</script>
|
||||||
|
<noscript><meta http-equiv="refresh" content="0; url=$locationATT"></noscript>
|
||||||
|
You are being redirected. If you are not redirected soon, <a href="$locationATT">click here to continue</a>
|
||||||
|
HTML;
|
||||||
|
|
||||||
|
// Build response
|
||||||
|
$result = new HTTPResponse($body);
|
||||||
|
$result->redirect($location);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this parameter requested without a valid token?
|
||||||
|
*
|
||||||
|
* @return bool True if the parameter is given without a valid token
|
||||||
|
*/
|
||||||
|
abstract public function reloadRequired();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this token is provided either in the backurl, or directly,
|
||||||
|
* but without a token
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
abstract public function reloadRequiredIfError();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suppress the current parameter for the duration of this request
|
||||||
|
*/
|
||||||
|
abstract public function suppress();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the querystring parameters to include
|
||||||
|
*
|
||||||
|
* @param bool $includeToken Include the token value?
|
||||||
|
* @return array List of querystring parameters, possibly including token parameter
|
||||||
|
*/
|
||||||
|
abstract public function params($includeToken = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
abstract public function getRedirectUrlBase();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
abstract public function getRedirectUrlParams();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get redirection URL
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
abstract protected function redirectURL();
|
||||||
|
}
|
178
src/Core/Startup/ConfirmationTokenChain.php
Normal file
178
src/Core/Startup/ConfirmationTokenChain.php
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Core\Startup;
|
||||||
|
|
||||||
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Control\Director;
|
||||||
|
use SilverStripe\Control\HTTPResponse;
|
||||||
|
use SilverStripe\Core\Convert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A chain of confirmation tokens to be validated on each request. This allows the application to
|
||||||
|
* check multiple tokens at once without having to potentially redirect the user for each of them
|
||||||
|
*
|
||||||
|
* @internal This class is designed specifically for use pre-startup and may change without warning
|
||||||
|
*/
|
||||||
|
class ConfirmationTokenChain
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $tokens = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param AbstractConfirmationToken $token
|
||||||
|
*/
|
||||||
|
public function pushToken(AbstractConfirmationToken $token)
|
||||||
|
{
|
||||||
|
$this->tokens[] = $token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collect all tokens that require a redirect
|
||||||
|
*
|
||||||
|
* @return \Generator
|
||||||
|
*/
|
||||||
|
protected function filteredTokens()
|
||||||
|
{
|
||||||
|
foreach ($this->tokens as $token) {
|
||||||
|
if ($token->reloadRequired() || $token->reloadRequiredIfError()) {
|
||||||
|
yield $token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function suppressionRequired()
|
||||||
|
{
|
||||||
|
foreach ($this->tokens as $token) {
|
||||||
|
if ($token->reloadRequired()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suppress URLs & GET vars from tokens that require a redirect
|
||||||
|
*/
|
||||||
|
public function suppressTokens()
|
||||||
|
{
|
||||||
|
foreach ($this->filteredTokens() as $token) {
|
||||||
|
$token->suppress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function reloadRequired()
|
||||||
|
{
|
||||||
|
foreach ($this->tokens as $token) {
|
||||||
|
if ($token->reloadRequired()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function reloadRequiredIfError()
|
||||||
|
{
|
||||||
|
foreach ($this->tokens as $token) {
|
||||||
|
if ($token->reloadRequiredIfError()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $includeToken
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function params($includeToken = true)
|
||||||
|
{
|
||||||
|
$params = [];
|
||||||
|
foreach ($this->tokens as $token) {
|
||||||
|
$params = array_merge($params, $token->params($includeToken));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the URL we want to redirect to, excluding query string parameters. This may
|
||||||
|
* be the same URL (with a token to be added outside this method), or to a different
|
||||||
|
* URL if the current one has been suppressed
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getRedirectUrlBase()
|
||||||
|
{
|
||||||
|
// URLConfirmationTokens may alter the URL to suppress the URL they're protecting,
|
||||||
|
// so we need to ensure they're inspected last and therefore take priority
|
||||||
|
$tokens = iterator_to_array($this->filteredTokens(), false);
|
||||||
|
usort($tokens, function ($a, $b) {
|
||||||
|
return ($a instanceof URLConfirmationToken) ? 1 : 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
$urlBase = Director::baseURL();
|
||||||
|
foreach ($tokens as $token) {
|
||||||
|
$urlBase = $token->getRedirectUrlBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $urlBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collate GET vars from all token providers that need to apply a token
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getRedirectUrlParams()
|
||||||
|
{
|
||||||
|
$params = [];
|
||||||
|
foreach ($this->filteredTokens() as $token) {
|
||||||
|
$params = array_merge($params, $token->getRedirectUrlParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function redirectURL()
|
||||||
|
{
|
||||||
|
$params = http_build_query($this->getRedirectUrlParams());
|
||||||
|
return Controller::join_links($this->getRedirectUrlBase(), '?' . $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return HTTPResponse
|
||||||
|
*/
|
||||||
|
public function reloadWithTokens()
|
||||||
|
{
|
||||||
|
$location = $this->redirectURL();
|
||||||
|
$locationJS = Convert::raw2js($location);
|
||||||
|
$locationATT = Convert::raw2att($location);
|
||||||
|
$body = <<<HTML
|
||||||
|
<script>location.href='$locationJS';</script>
|
||||||
|
<noscript><meta http-equiv="refresh" content="0; url=$locationATT"></noscript>
|
||||||
|
You are being redirected. If you are not redirected soon, <a href="$locationATT">click here to continue</a>
|
||||||
|
HTML;
|
||||||
|
|
||||||
|
// Build response
|
||||||
|
$result = new HTTPResponse($body);
|
||||||
|
$result->redirect($location);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
@ -15,8 +15,7 @@ use Exception;
|
|||||||
* $chain = new ErrorControlChain();
|
* $chain = new ErrorControlChain();
|
||||||
* $chain->then($callback1)->then($callback2)->thenIfErrored($callback3)->execute();
|
* $chain->then($callback1)->then($callback2)->thenIfErrored($callback3)->execute();
|
||||||
*
|
*
|
||||||
* WARNING: This class is experimental and designed specifically for use pre-startup.
|
* @internal This class is designed specifically for use pre-startup and may change without warning
|
||||||
* It will likely be heavily refactored before the release of 3.2
|
|
||||||
*/
|
*/
|
||||||
class ErrorControlChain
|
class ErrorControlChain
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,8 @@ use SilverStripe\Security\Security;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorates application bootstrapping with errorcontrolchain
|
* Decorates application bootstrapping with errorcontrolchain
|
||||||
|
*
|
||||||
|
* @internal This class is designed specifically for use pre-startup and may change without warning
|
||||||
*/
|
*/
|
||||||
class ErrorControlChainMiddleware implements HTTPMiddleware
|
class ErrorControlChainMiddleware implements HTTPMiddleware
|
||||||
{
|
{
|
||||||
@ -30,27 +32,42 @@ class ErrorControlChainMiddleware implements HTTPMiddleware
|
|||||||
$this->application = $application;
|
$this->application = $application;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param HTTPRequest $request
|
||||||
|
* @return ConfirmationTokenChain
|
||||||
|
*/
|
||||||
|
protected function prepareConfirmationTokenChain(HTTPRequest $request)
|
||||||
|
{
|
||||||
|
$chain = new ConfirmationTokenChain();
|
||||||
|
$chain->pushToken(new URLConfirmationToken('dev/build', $request));
|
||||||
|
|
||||||
|
foreach (['isTest', 'isDev', 'flush'] as $parameter) {
|
||||||
|
$chain->pushToken(new ParameterConfirmationToken($parameter, $request));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $chain;
|
||||||
|
}
|
||||||
|
|
||||||
public function process(HTTPRequest $request, callable $next)
|
public function process(HTTPRequest $request, callable $next)
|
||||||
{
|
{
|
||||||
$result = null;
|
$result = null;
|
||||||
|
|
||||||
// Prepare tokens and execute chain
|
// Prepare tokens and execute chain
|
||||||
$reloadToken = ParameterConfirmationToken::prepare_tokens(
|
$confirmationTokenChain = $this->prepareConfirmationTokenChain($request);
|
||||||
['isTest', 'isDev', 'flush'],
|
$errorControlChain = new ErrorControlChain();
|
||||||
$request
|
$errorControlChain
|
||||||
);
|
->then(function () use ($request, $errorControlChain, $confirmationTokenChain, $next, &$result) {
|
||||||
$chain = new ErrorControlChain();
|
if ($confirmationTokenChain->suppressionRequired()) {
|
||||||
$chain
|
$confirmationTokenChain->suppressTokens();
|
||||||
->then(function () use ($request, $chain, $reloadToken, $next, &$result) {
|
} else {
|
||||||
// If no redirection is necessary then we can disable error supression
|
// If no redirection is necessary then we can disable error supression
|
||||||
if (!$reloadToken) {
|
$errorControlChain->setSuppression(false);
|
||||||
$chain->setSuppression(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Check if a token is requesting a redirect
|
// Check if a token is requesting a redirect
|
||||||
if ($reloadToken && $reloadToken->reloadRequired()) {
|
if ($confirmationTokenChain && $confirmationTokenChain->reloadRequired()) {
|
||||||
$result = $this->safeReloadWithToken($request, $reloadToken);
|
$result = $this->safeReloadWithTokens($request, $confirmationTokenChain);
|
||||||
} else {
|
} else {
|
||||||
// If no reload necessary, process application
|
// If no reload necessary, process application
|
||||||
$result = call_user_func($next, $request);
|
$result = call_user_func($next, $request);
|
||||||
@ -60,10 +77,16 @@ class ErrorControlChainMiddleware implements HTTPMiddleware
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
// Finally if a token was requested but there was an error while figuring out if it's allowed, do it anyway
|
// Finally if a token was requested but there was an error while figuring out if it's allowed, do it anyway
|
||||||
->thenIfErrored(function () use ($reloadToken) {
|
->thenIfErrored(function () use ($confirmationTokenChain) {
|
||||||
if ($reloadToken && $reloadToken->reloadRequiredIfError()) {
|
if ($confirmationTokenChain && $confirmationTokenChain->reloadRequiredIfError()) {
|
||||||
$result = $reloadToken->reloadWithToken();
|
try {
|
||||||
$result->output();
|
// Reload requires manual boot
|
||||||
|
$this->getApplication()->getKernel()->boot(false);
|
||||||
|
} finally {
|
||||||
|
// Given we're in an error state here, try to continue even if the kernel boot fails
|
||||||
|
$result = $confirmationTokenChain->reloadWithTokens();
|
||||||
|
$result->output();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
->execute();
|
->execute();
|
||||||
@ -75,10 +98,10 @@ class ErrorControlChainMiddleware implements HTTPMiddleware
|
|||||||
* or authentication is impossible.
|
* or authentication is impossible.
|
||||||
*
|
*
|
||||||
* @param HTTPRequest $request
|
* @param HTTPRequest $request
|
||||||
* @param ParameterConfirmationToken $reloadToken
|
* @param ConfirmationTokenChain $confirmationTokenChain
|
||||||
* @return HTTPResponse
|
* @return HTTPResponse
|
||||||
*/
|
*/
|
||||||
protected function safeReloadWithToken(HTTPRequest $request, $reloadToken)
|
protected function safeReloadWithTokens(HTTPRequest $request, ConfirmationTokenChain $confirmationTokenChain)
|
||||||
{
|
{
|
||||||
// Safe reload requires manual boot
|
// Safe reload requires manual boot
|
||||||
$this->getApplication()->getKernel()->boot(false);
|
$this->getApplication()->getKernel()->boot(false);
|
||||||
@ -87,9 +110,9 @@ class ErrorControlChainMiddleware implements HTTPMiddleware
|
|||||||
$request->getSession()->init($request);
|
$request->getSession()->init($request);
|
||||||
|
|
||||||
// Request with ErrorDirector
|
// Request with ErrorDirector
|
||||||
$result = ErrorDirector::singleton()->handleRequestWithToken(
|
$result = ErrorDirector::singleton()->handleRequestWithTokenChain(
|
||||||
$request,
|
$request,
|
||||||
$reloadToken,
|
$confirmationTokenChain,
|
||||||
$this->getApplication()->getKernel()
|
$this->getApplication()->getKernel()
|
||||||
);
|
);
|
||||||
if ($result) {
|
if ($result) {
|
||||||
@ -97,8 +120,8 @@ class ErrorControlChainMiddleware implements HTTPMiddleware
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fail and redirect the user to the login page
|
// Fail and redirect the user to the login page
|
||||||
$params = array_merge($request->getVars(), $reloadToken->params(false));
|
$params = array_merge($request->getVars(), $confirmationTokenChain->params(false));
|
||||||
$backURL = $request->getURL() . '?' . http_build_query($params);
|
$backURL = $confirmationTokenChain->getRedirectUrlBase() . '?' . http_build_query($params);
|
||||||
$loginPage = Director::absoluteURL(Security::config()->get('login_url'));
|
$loginPage = Director::absoluteURL(Security::config()->get('login_url'));
|
||||||
$loginPage .= "?BackURL=" . urlencode($backURL);
|
$loginPage .= "?BackURL=" . urlencode($backURL);
|
||||||
$result = new HTTPResponse();
|
$result = new HTTPResponse();
|
||||||
|
@ -21,18 +21,21 @@ class ErrorDirector extends Director
|
|||||||
* Redirect with token if allowed, or null if not allowed
|
* Redirect with token if allowed, or null if not allowed
|
||||||
*
|
*
|
||||||
* @param HTTPRequest $request
|
* @param HTTPRequest $request
|
||||||
* @param ParameterConfirmationToken $token
|
* @param ConfirmationTokenChain $confirmationTokenChain
|
||||||
* @param Kernel $kernel
|
* @param Kernel $kernel
|
||||||
* @return null|HTTPResponse Redirection response, or null if not able to redirect
|
* @return null|HTTPResponse Redirection response, or null if not able to redirect
|
||||||
*/
|
*/
|
||||||
public function handleRequestWithToken(HTTPRequest $request, ParameterConfirmationToken $token, Kernel $kernel)
|
public function handleRequestWithTokenChain(
|
||||||
{
|
HTTPRequest $request,
|
||||||
|
ConfirmationTokenChain $confirmationTokenChain,
|
||||||
|
Kernel $kernel
|
||||||
|
) {
|
||||||
Injector::inst()->registerService($request, HTTPRequest::class);
|
Injector::inst()->registerService($request, HTTPRequest::class);
|
||||||
|
|
||||||
// Next, check if we're in dev mode, or the database doesn't have any security data, or we are admin
|
// Next, check if we're in dev mode, or the database doesn't have any security data, or we are admin
|
||||||
$reload = function (HTTPRequest $request) use ($token, $kernel) {
|
$reload = function (HTTPRequest $request) use ($confirmationTokenChain, $kernel) {
|
||||||
if ($kernel->getEnvironment() === Kernel::DEV || !Security::database_is_ready() || Permission::check('ADMIN')) {
|
if ($kernel->getEnvironment() === Kernel::DEV || !Security::database_is_ready() || Permission::check('ADMIN')) {
|
||||||
return $token->reloadWithToken();
|
return $confirmationTokenChain->reloadWithTokens();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
@ -3,24 +3,21 @@
|
|||||||
namespace SilverStripe\Core\Startup;
|
namespace SilverStripe\Core\Startup;
|
||||||
|
|
||||||
use SilverStripe\Control\Controller;
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Control\Director;
|
||||||
use SilverStripe\Control\HTTPRequest;
|
use SilverStripe\Control\HTTPRequest;
|
||||||
use SilverStripe\Control\HTTPResponse;
|
use SilverStripe\Control\HTTPResponse;
|
||||||
use SilverStripe\Core\Convert;
|
use SilverStripe\Core\Convert;
|
||||||
use SilverStripe\Security\RandomGenerator;
|
use SilverStripe\Security\RandomGenerator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ParameterConfirmationToken
|
* This is used to protect dangerous GET parameters that need to be detected early in the request
|
||||||
|
* lifecycle by generating a one-time-use token & redirecting with that token included in the
|
||||||
|
* redirected URL
|
||||||
*
|
*
|
||||||
* When you need to use a dangerous GET parameter that needs to be set before core/Core.php is
|
* @internal This class is designed specifically for use pre-startup and may change without warning
|
||||||
* established, this class takes care of allowing some other code of confirming the parameter,
|
|
||||||
* by generating a one-time-use token & redirecting with that token included in the redirected URL
|
|
||||||
*
|
|
||||||
* WARNING: This class is experimental and designed specifically for use pre-startup.
|
|
||||||
* It will likely be heavily refactored before the release of 3.2
|
|
||||||
*/
|
*/
|
||||||
class ParameterConfirmationToken
|
class ParameterConfirmationToken extends AbstractConfirmationToken
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the parameter
|
* The name of the parameter
|
||||||
*
|
*
|
||||||
@ -28,11 +25,6 @@ class ParameterConfirmationToken
|
|||||||
*/
|
*/
|
||||||
protected $parameterName = null;
|
protected $parameterName = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var HTTPRequest
|
|
||||||
*/
|
|
||||||
protected $request = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The parameter given in the main request
|
* The parameter given in the main request
|
||||||
*
|
*
|
||||||
@ -48,60 +40,6 @@ class ParameterConfirmationToken
|
|||||||
protected $parameterBackURL = null;
|
protected $parameterBackURL = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The validated and checked token for this parameter
|
|
||||||
*
|
|
||||||
* @var string|null A string value, or null if either not provided or invalid
|
|
||||||
*/
|
|
||||||
protected $token = null;
|
|
||||||
|
|
||||||
protected function pathForToken($token)
|
|
||||||
{
|
|
||||||
return TEMP_PATH . DIRECTORY_SEPARATOR . 'token_' . preg_replace('/[^a-z0-9]+/', '', $token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a new random token and store it
|
|
||||||
*
|
|
||||||
* @return string Token name
|
|
||||||
*/
|
|
||||||
protected function genToken()
|
|
||||||
{
|
|
||||||
// Generate a new random token (as random as possible)
|
|
||||||
$rg = new RandomGenerator();
|
|
||||||
$token = $rg->randomToken('md5');
|
|
||||||
|
|
||||||
// Store a file in the session save path (safer than /tmp, as open_basedir might limit that)
|
|
||||||
file_put_contents($this->pathForToken($token), $token);
|
|
||||||
|
|
||||||
return $token;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate a token
|
|
||||||
*
|
|
||||||
* @param string $token
|
|
||||||
* @return boolean True if the token is valid
|
|
||||||
*/
|
|
||||||
protected function checkToken($token)
|
|
||||||
{
|
|
||||||
if (!$token) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$file = $this->pathForToken($token);
|
|
||||||
$content = null;
|
|
||||||
|
|
||||||
if (file_exists($file)) {
|
|
||||||
$content = file_get_contents($file);
|
|
||||||
unlink($file);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $content == $token;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new ParameterConfirmationToken
|
|
||||||
*
|
|
||||||
* @param string $parameterName Name of the querystring parameter to check
|
* @param string $parameterName Name of the querystring parameter to check
|
||||||
* @param HTTPRequest $request
|
* @param HTTPRequest $request
|
||||||
*/
|
*/
|
||||||
@ -176,54 +114,23 @@ class ParameterConfirmationToken
|
|||||||
return $this->parameterBackURL !== null;
|
return $this->parameterBackURL !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Is the necessary token provided for this parameter?
|
|
||||||
* A value must be provided for the token
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function tokenProvided()
|
|
||||||
{
|
|
||||||
return !empty($this->token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is this parameter requested without a valid token?
|
|
||||||
*
|
|
||||||
* @return bool True if the parameter is given without a valid token
|
|
||||||
*/
|
|
||||||
public function reloadRequired()
|
public function reloadRequired()
|
||||||
{
|
{
|
||||||
return $this->parameterProvided() && !$this->tokenProvided();
|
return $this->parameterProvided() && !$this->tokenProvided();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if this token is provided either in the backurl, or directly,
|
|
||||||
* but without a token
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function reloadRequiredIfError()
|
public function reloadRequiredIfError()
|
||||||
{
|
{
|
||||||
// Don't reload if token exists
|
// Don't reload if token exists
|
||||||
return $this->reloadRequired() || $this->existsInReferer();
|
return $this->reloadRequired() || $this->existsInReferer();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Suppress the current parameter by unsetting it from $_GET
|
|
||||||
*/
|
|
||||||
public function suppress()
|
public function suppress()
|
||||||
{
|
{
|
||||||
unset($_GET[$this->parameterName]);
|
unset($_GET[$this->parameterName]);
|
||||||
$this->request->offsetUnset($this->parameterName);
|
$this->request->offsetUnset($this->parameterName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine the querystring parameters to include
|
|
||||||
*
|
|
||||||
* @param bool $includeToken Include the token value as well?
|
|
||||||
* @return array List of querystring parameters with name and token parameters
|
|
||||||
*/
|
|
||||||
public function params($includeToken = true)
|
public function params($includeToken = true)
|
||||||
{
|
{
|
||||||
$params = array(
|
$params = array(
|
||||||
@ -235,80 +142,21 @@ class ParameterConfirmationToken
|
|||||||
return $params;
|
return $params;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getRedirectUrlBase()
|
||||||
* Get redirect url, excluding querystring
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function currentURL()
|
|
||||||
{
|
{
|
||||||
return Controller::join_links(
|
return ($this->existsInReferer() && !$this->parameterProvided()) ? Director::baseURL() : $this->currentURL();
|
||||||
BASE_URL ?: '/',
|
}
|
||||||
$this->request->getURL(false)
|
|
||||||
);
|
public function getRedirectUrlParams()
|
||||||
|
{
|
||||||
|
return ($this->existsInReferer() && !$this->parameterProvided())
|
||||||
|
? $this->params()
|
||||||
|
: array_merge($this->request->getVars(), $this->params());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get redirection URL
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function redirectURL()
|
protected function redirectURL()
|
||||||
{
|
{
|
||||||
// If url is encoded via BackURL, defer to home page (prevent redirect to form action)
|
$query = http_build_query($this->getRedirectUrlParams());
|
||||||
if ($this->existsInReferer() && !$this->parameterProvided()) {
|
return Controller::join_links($this->getRedirectUrlBase(), '?' . $query);
|
||||||
$url = BASE_URL ?: '/';
|
|
||||||
$params = $this->params();
|
|
||||||
} else {
|
|
||||||
$url = $this->currentURL();
|
|
||||||
$params = array_merge($this->request->getVars(), $this->params());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Merge get params with current url
|
|
||||||
return Controller::join_links($url, '?' . http_build_query($params));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Forces a reload of the request with the token included
|
|
||||||
*
|
|
||||||
* @return HTTPResponse
|
|
||||||
*/
|
|
||||||
public function reloadWithToken()
|
|
||||||
{
|
|
||||||
$location = $this->redirectURL();
|
|
||||||
$locationJS = Convert::raw2js($location);
|
|
||||||
$locationATT = Convert::raw2att($location);
|
|
||||||
$body = <<<HTML
|
|
||||||
<script>location.href='$locationJS';</script>
|
|
||||||
<noscript><meta http-equiv="refresh" content="0; url=$locationATT"></noscript>
|
|
||||||
You are being redirected. If you are not redirected soon, <a href="$locationATT">click here to continue the flush</a>
|
|
||||||
HTML;
|
|
||||||
|
|
||||||
// Build response
|
|
||||||
$result = new HTTPResponse($body);
|
|
||||||
$result->redirect($location);
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a list of token names, suppress all tokens that have not been validated, and
|
|
||||||
* return the non-validated token with the highest priority
|
|
||||||
*
|
|
||||||
* @param array $keys List of token keys in ascending priority (low to high)
|
|
||||||
* @param HTTPRequest $request
|
|
||||||
* @return ParameterConfirmationToken The token container for the unvalidated $key given with the highest priority
|
|
||||||
*/
|
|
||||||
public static function prepare_tokens($keys, HTTPRequest $request)
|
|
||||||
{
|
|
||||||
$target = null;
|
|
||||||
foreach ($keys as $key) {
|
|
||||||
$token = new ParameterConfirmationToken($key, $request);
|
|
||||||
// Validate this token
|
|
||||||
if ($token->reloadRequired() || $token->reloadRequiredIfError()) {
|
|
||||||
$token->suppress();
|
|
||||||
$target = $token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $target;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
139
src/Core/Startup/URLConfirmationToken.php
Normal file
139
src/Core/Startup/URLConfirmationToken.php
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Core\Startup;
|
||||||
|
|
||||||
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Control\Director;
|
||||||
|
use SilverStripe\Control\HTTPRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is used to protect dangerous URLs that need to be detected early in the request lifecycle
|
||||||
|
* by generating a one-time-use token & redirecting with that token included in the redirected URL
|
||||||
|
*
|
||||||
|
* @internal This class is designed specifically for use pre-startup and may change without warning
|
||||||
|
*/
|
||||||
|
class URLConfirmationToken extends AbstractConfirmationToken
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $urlToCheck;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $currentURL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $tokenParameterName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $urlExistsInBackURL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $urlToCheck URL to check
|
||||||
|
* @param HTTPRequest $request
|
||||||
|
*/
|
||||||
|
public function __construct($urlToCheck, HTTPRequest $request)
|
||||||
|
{
|
||||||
|
$this->urlToCheck = $urlToCheck;
|
||||||
|
$this->request = $request;
|
||||||
|
$this->currentURL = $request->getURL(false);
|
||||||
|
|
||||||
|
$this->tokenParameterName = preg_replace('/[^a-z0-9]/i', '', $urlToCheck) . 'token';
|
||||||
|
$this->urlExistsInBackURL = $this->getURLExistsInBackURL($request);
|
||||||
|
|
||||||
|
// If the token provided is valid, mark it as such
|
||||||
|
$token = $request->getVar($this->tokenParameterName);
|
||||||
|
if ($this->checkToken($token)) {
|
||||||
|
$this->token = $token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param HTTPRequest $request
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function getURLExistsInBackURL(HTTPRequest $request)
|
||||||
|
{
|
||||||
|
$backURL = ltrim($request->getVar('BackURL'), '/');
|
||||||
|
return (strpos($backURL, $this->urlToCheck) === 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function urlMatches()
|
||||||
|
{
|
||||||
|
return ($this->currentURL === $this->urlToCheck);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getURLToCheck()
|
||||||
|
{
|
||||||
|
return $this->urlToCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function urlExistsInBackURL()
|
||||||
|
{
|
||||||
|
return $this->urlExistsInBackURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function reloadRequired()
|
||||||
|
{
|
||||||
|
return $this->urlMatches() && !$this->tokenProvided();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function reloadRequiredIfError()
|
||||||
|
{
|
||||||
|
return $this->reloadRequired() || $this->urlExistsInBackURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function suppress()
|
||||||
|
{
|
||||||
|
$_SERVER['REQUEST_URI'] = '/';
|
||||||
|
$this->request->setURL('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function params($includeToken = true)
|
||||||
|
{
|
||||||
|
$params = [];
|
||||||
|
if ($includeToken) {
|
||||||
|
$params[$this->tokenParameterName] = $this->genToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function currentURL()
|
||||||
|
{
|
||||||
|
return Controller::join_links(Director::baseURL(), $this->currentURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRedirectUrlBase()
|
||||||
|
{
|
||||||
|
return ($this->urlExistsInBackURL && !$this->urlMatches()) ? Director::baseURL() : $this->currentURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRedirectUrlParams()
|
||||||
|
{
|
||||||
|
return ($this->urlExistsInBackURL && !$this->urlMatches())
|
||||||
|
? $this->params()
|
||||||
|
: array_merge($this->request->getVars(), $this->params());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function redirectURL()
|
||||||
|
{
|
||||||
|
$query = http_build_query($this->getRedirectUrlParams());
|
||||||
|
return Controller::join_links($this->getRedirectUrlBase(), '?' . $query);
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,7 @@ class Backtrace
|
|||||||
array('PDO', '__construct'),
|
array('PDO', '__construct'),
|
||||||
array('mysqli', 'mysqli'),
|
array('mysqli', 'mysqli'),
|
||||||
array('mysqli', 'select_db'),
|
array('mysqli', 'select_db'),
|
||||||
|
array('mysqli', 'real_connect'),
|
||||||
array('SilverStripe\\ORM\\DB', 'connect'),
|
array('SilverStripe\\ORM\\DB', 'connect'),
|
||||||
array('SilverStripe\\Security\\Security', 'check_default_admin'),
|
array('SilverStripe\\Security\\Security', 'check_default_admin'),
|
||||||
array('SilverStripe\\Security\\Security', 'encrypt_password'),
|
array('SilverStripe\\Security\\Security', 'encrypt_password'),
|
||||||
|
185
tests/php/Core/Startup/ConfirmationTokenChainTest.php
Normal file
185
tests/php/Core/Startup/ConfirmationTokenChainTest.php
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Core\Tests\Startup;
|
||||||
|
|
||||||
|
use SilverStripe\Core\Startup\ConfirmationTokenChain;
|
||||||
|
use SilverStripe\Core\Startup\ParameterConfirmationToken;
|
||||||
|
use SilverStripe\Core\Startup\URLConfirmationToken;
|
||||||
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
|
||||||
|
class ConfirmationTokenChainTest extends SapphireTest
|
||||||
|
{
|
||||||
|
protected function getTokenRequiringReload($requiresReload = true, $extraMethods = [])
|
||||||
|
{
|
||||||
|
$methods = array_merge(['reloadRequired'], $extraMethods);
|
||||||
|
$mock = $this->createPartialMock(ParameterConfirmationToken::class, $methods);
|
||||||
|
$mock->expects($this->any())
|
||||||
|
->method('reloadRequired')
|
||||||
|
->will($this->returnValue($requiresReload));
|
||||||
|
return $mock;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getTokenRequiringReloadIfError($requiresReload = true, $extraMethods = [])
|
||||||
|
{
|
||||||
|
$methods = array_merge(['reloadRequired', 'reloadRequiredIfError'], $extraMethods);
|
||||||
|
$mock = $this->createPartialMock(ParameterConfirmationToken::class, $methods);
|
||||||
|
$mock->expects($this->any())
|
||||||
|
->method('reloadRequired')
|
||||||
|
->will($this->returnValue(false));
|
||||||
|
$mock->expects($this->any())
|
||||||
|
->method('reloadRequiredIfError')
|
||||||
|
->will($this->returnValue($requiresReload));
|
||||||
|
return $mock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFilteredTokens()
|
||||||
|
{
|
||||||
|
$chain = new ConfirmationTokenChain();
|
||||||
|
$chain->pushToken($tokenRequiringReload = $this->getTokenRequiringReload());
|
||||||
|
$chain->pushToken($tokenNotRequiringReload = $this->getTokenRequiringReload(false));
|
||||||
|
$chain->pushToken($tokenRequiringReloadIfError = $this->getTokenRequiringReloadIfError());
|
||||||
|
$chain->pushToken($tokenNotRequiringReloadIfError = $this->getTokenRequiringReloadIfError(false));
|
||||||
|
|
||||||
|
$reflectionMethod = new \ReflectionMethod(ConfirmationTokenChain::class, 'filteredTokens');
|
||||||
|
$reflectionMethod->setAccessible(true);
|
||||||
|
$tokens = iterator_to_array($reflectionMethod->invoke($chain));
|
||||||
|
|
||||||
|
$this->assertContains($tokenRequiringReload, $tokens, 'Token requiring a reload was not returned');
|
||||||
|
$this->assertNotContains($tokenNotRequiringReload, $tokens, 'Token not requiring a reload was returned');
|
||||||
|
$this->assertContains($tokenRequiringReloadIfError, $tokens, 'Token requiring a reload on error was not returned');
|
||||||
|
$this->assertNotContains($tokenNotRequiringReloadIfError, $tokens, 'Token not requiring a reload on error was returned');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSuppressionRequired()
|
||||||
|
{
|
||||||
|
$chain = new ConfirmationTokenChain();
|
||||||
|
$chain->pushToken($this->getTokenRequiringReload(false));
|
||||||
|
$this->assertFalse($chain->suppressionRequired(), 'Suppression incorrectly marked as required');
|
||||||
|
|
||||||
|
$chain = new ConfirmationTokenChain();
|
||||||
|
$chain->pushToken($this->getTokenRequiringReloadIfError(false));
|
||||||
|
$this->assertFalse($chain->suppressionRequired(), 'Suppression incorrectly marked as required');
|
||||||
|
|
||||||
|
$chain = new ConfirmationTokenChain();
|
||||||
|
$chain->pushToken($this->getTokenRequiringReload());
|
||||||
|
$this->assertTrue($chain->suppressionRequired(), 'Suppression not marked as required');
|
||||||
|
|
||||||
|
$chain = new ConfirmationTokenChain();
|
||||||
|
$chain->pushToken($this->getTokenRequiringReloadIfError());
|
||||||
|
$this->assertFalse($chain->suppressionRequired(), 'Suppression incorrectly marked as required');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSuppressTokens()
|
||||||
|
{
|
||||||
|
$mockToken = $this->getTokenRequiringReload(true, ['suppress']);
|
||||||
|
$mockToken->expects($this->once())
|
||||||
|
->method('suppress');
|
||||||
|
$secondMockToken = $this->getTokenRequiringReloadIfError(true, ['suppress']);
|
||||||
|
$secondMockToken->expects($this->once())
|
||||||
|
->method('suppress');
|
||||||
|
|
||||||
|
$chain = new ConfirmationTokenChain();
|
||||||
|
$chain->pushToken($mockToken);
|
||||||
|
$chain->pushToken($secondMockToken);
|
||||||
|
$chain->suppressTokens();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReloadRequired()
|
||||||
|
{
|
||||||
|
$mockToken = $this->getTokenRequiringReload(true);
|
||||||
|
$secondMockToken = $this->getTokenRequiringReload(false);
|
||||||
|
|
||||||
|
$chain = new ConfirmationTokenChain();
|
||||||
|
$chain->pushToken($mockToken);
|
||||||
|
$chain->pushToken($secondMockToken);
|
||||||
|
$this->assertTrue($chain->reloadRequired());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReloadRequiredIfError()
|
||||||
|
{
|
||||||
|
$mockToken = $this->getTokenRequiringReloadIfError(true);
|
||||||
|
$secondMockToken = $this->getTokenRequiringReloadIfError(false);
|
||||||
|
|
||||||
|
$chain = new ConfirmationTokenChain();
|
||||||
|
$chain->pushToken($mockToken);
|
||||||
|
$chain->pushToken($secondMockToken);
|
||||||
|
$this->assertTrue($chain->reloadRequiredIfError());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testParams()
|
||||||
|
{
|
||||||
|
$mockToken = $this->getTokenRequiringReload(true, ['params']);
|
||||||
|
$mockToken->expects($this->once())
|
||||||
|
->method('params')
|
||||||
|
->with($this->isTrue())
|
||||||
|
->will($this->returnValue(['mockTokenParam' => '1']));
|
||||||
|
$secondMockToken = $this->getTokenRequiringReload(true, ['params']);
|
||||||
|
$secondMockToken->expects($this->once())
|
||||||
|
->method('params')
|
||||||
|
->with($this->isTrue())
|
||||||
|
->will($this->returnValue(['secondMockTokenParam' => '2']));
|
||||||
|
|
||||||
|
$chain = new ConfirmationTokenChain();
|
||||||
|
$chain->pushToken($mockToken);
|
||||||
|
$chain->pushToken($secondMockToken);
|
||||||
|
$this->assertEquals(['mockTokenParam' => '1', 'secondMockTokenParam' => '2'], $chain->params(true));
|
||||||
|
|
||||||
|
$mockToken = $this->getTokenRequiringReload(true, ['params']);
|
||||||
|
$mockToken->expects($this->once())
|
||||||
|
->method('params')
|
||||||
|
->with($this->isFalse())
|
||||||
|
->will($this->returnValue(['mockTokenParam' => '1']));
|
||||||
|
|
||||||
|
$chain = new ConfirmationTokenChain();
|
||||||
|
$chain->pushToken($mockToken);
|
||||||
|
$this->assertEquals(['mockTokenParam' => '1'], $chain->params(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetRedirectUrlBase()
|
||||||
|
{
|
||||||
|
$mockUrlToken = $this->createPartialMock(URLConfirmationToken::class, ['reloadRequired', 'getRedirectUrlBase']);
|
||||||
|
$mockUrlToken->expects($this->any())
|
||||||
|
->method('reloadRequired')
|
||||||
|
->will($this->returnValue(true));
|
||||||
|
$mockUrlToken->expects($this->any())
|
||||||
|
->method('getRedirectUrlBase')
|
||||||
|
->will($this->returnValue('url-base'));
|
||||||
|
|
||||||
|
$mockParameterToken = $this->createPartialMock(ParameterConfirmationToken::class, ['reloadRequired', 'getRedirectUrlBase']);
|
||||||
|
$mockParameterToken->expects($this->any())
|
||||||
|
->method('reloadRequired')
|
||||||
|
->will($this->returnValue(true));
|
||||||
|
$mockParameterToken->expects($this->any())
|
||||||
|
->method('getRedirectUrlBase')
|
||||||
|
->will($this->returnValue('parameter-base'));
|
||||||
|
|
||||||
|
$chain = new ConfirmationTokenChain();
|
||||||
|
$chain->pushToken($mockParameterToken);
|
||||||
|
$chain->pushToken($mockUrlToken);
|
||||||
|
$this->assertEquals('url-base', $chain->getRedirectUrlBase(), 'URLConfirmationToken url base should take priority');
|
||||||
|
|
||||||
|
// Push them in reverse order to check priority still correct
|
||||||
|
$chain = new ConfirmationTokenChain();
|
||||||
|
$chain->pushToken($mockUrlToken);
|
||||||
|
$chain->pushToken($mockParameterToken);
|
||||||
|
$this->assertEquals('url-base', $chain->getRedirectUrlBase(), 'URLConfirmationToken url base should take priority');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetRedirectUrlParams()
|
||||||
|
{
|
||||||
|
$mockToken = $this->getTokenRequiringReload(true, ['getRedirectUrlParams']);
|
||||||
|
$mockToken->expects($this->once())
|
||||||
|
->method('getRedirectUrlParams')
|
||||||
|
->will($this->returnValue(['mockTokenParam' => '1']));
|
||||||
|
|
||||||
|
$secondMockToken = $this->getTokenRequiringReload(true, ['getRedirectUrlParams']);
|
||||||
|
$secondMockToken->expects($this->once())
|
||||||
|
->method('getRedirectUrlParams')
|
||||||
|
->will($this->returnValue(['secondMockTokenParam' => '2']));
|
||||||
|
|
||||||
|
$chain = new ConfirmationTokenChain();
|
||||||
|
$chain->pushToken($mockToken);
|
||||||
|
$chain->pushToken($secondMockToken);
|
||||||
|
$this->assertEquals(['mockTokenParam' => '1', 'secondMockTokenParam' => '2'], $chain->getRedirectUrlParams());
|
||||||
|
}
|
||||||
|
}
|
@ -73,4 +73,104 @@ class ErrorControlChainMiddlewareTest extends SapphireTest
|
|||||||
$this->assertNotContains('?flush=1&flushtoken=', $location);
|
$this->assertNotContains('?flush=1&flushtoken=', $location);
|
||||||
$this->assertContains('Security/login', $location);
|
$this->assertContains('Security/login', $location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testLiveBuildAdmin()
|
||||||
|
{
|
||||||
|
// Mock admin
|
||||||
|
$adminID = $this->logInWithPermission('ADMIN');
|
||||||
|
$this->logOut();
|
||||||
|
|
||||||
|
// Mock app
|
||||||
|
$app = new HTTPApplication(new BlankKernel(BASE_PATH));
|
||||||
|
$app->getKernel()->setEnvironment(Kernel::LIVE);
|
||||||
|
|
||||||
|
// Test being logged in as admin
|
||||||
|
$chain = new ErrorControlChainMiddleware($app);
|
||||||
|
$request = new HTTPRequest('GET', '/dev/build/');
|
||||||
|
$request->setSession(new Session(['loggedInAs' => $adminID]));
|
||||||
|
$result = $chain->process($request, function () {
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->assertInstanceOf(HTTPResponse::class, $result);
|
||||||
|
$location = $result->getHeader('Location');
|
||||||
|
$this->assertContains('/dev/build', $location);
|
||||||
|
$this->assertContains('?devbuildtoken=', $location);
|
||||||
|
$this->assertNotContains('Security/login', $location);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLiveBuildUnauthenticated()
|
||||||
|
{
|
||||||
|
// Mock app
|
||||||
|
$app = new HTTPApplication(new BlankKernel(BASE_PATH));
|
||||||
|
$app->getKernel()->setEnvironment(Kernel::LIVE);
|
||||||
|
|
||||||
|
// Test being logged in as no one
|
||||||
|
Security::setCurrentUser(null);
|
||||||
|
$chain = new ErrorControlChainMiddleware($app);
|
||||||
|
$request = new HTTPRequest('GET', '/dev/build');
|
||||||
|
$request->setSession(new Session(['loggedInAs' => 0]));
|
||||||
|
$result = $chain->process($request, function () {
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Should be directed to login, not to flush
|
||||||
|
$this->assertInstanceOf(HTTPResponse::class, $result);
|
||||||
|
$location = $result->getHeader('Location');
|
||||||
|
$this->assertNotContains('/dev/build', $location);
|
||||||
|
$this->assertNotContains('?devbuildtoken=', $location);
|
||||||
|
$this->assertContains('Security/login', $location);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLiveBuildAndFlushAdmin()
|
||||||
|
{
|
||||||
|
// Mock admin
|
||||||
|
$adminID = $this->logInWithPermission('ADMIN');
|
||||||
|
$this->logOut();
|
||||||
|
|
||||||
|
// Mock app
|
||||||
|
$app = new HTTPApplication(new BlankKernel(BASE_PATH));
|
||||||
|
$app->getKernel()->setEnvironment(Kernel::LIVE);
|
||||||
|
|
||||||
|
// Test being logged in as admin
|
||||||
|
$chain = new ErrorControlChainMiddleware($app);
|
||||||
|
$request = new HTTPRequest('GET', '/dev/build/', ['flush' => '1']);
|
||||||
|
$request->setSession(new Session(['loggedInAs' => $adminID]));
|
||||||
|
$result = $chain->process($request, function () {
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->assertInstanceOf(HTTPResponse::class, $result);
|
||||||
|
$location = $result->getHeader('Location');
|
||||||
|
$this->assertContains('/dev/build', $location);
|
||||||
|
$this->assertContains('flush=1', $location);
|
||||||
|
$this->assertContains('devbuildtoken=', $location);
|
||||||
|
$this->assertContains('flushtoken=', $location);
|
||||||
|
$this->assertNotContains('Security/login', $location);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLiveBuildAndFlushUnauthenticated()
|
||||||
|
{
|
||||||
|
// Mock app
|
||||||
|
$app = new HTTPApplication(new BlankKernel(BASE_PATH));
|
||||||
|
$app->getKernel()->setEnvironment(Kernel::LIVE);
|
||||||
|
|
||||||
|
// Test being logged in as no one
|
||||||
|
Security::setCurrentUser(null);
|
||||||
|
$chain = new ErrorControlChainMiddleware($app);
|
||||||
|
$request = new HTTPRequest('GET', '/dev/build', ['flush' => '1']);
|
||||||
|
$request->setSession(new Session(['loggedInAs' => 0]));
|
||||||
|
$result = $chain->process($request, function () {
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Should be directed to login, not to flush
|
||||||
|
$this->assertInstanceOf(HTTPResponse::class, $result);
|
||||||
|
$location = $result->getHeader('Location');
|
||||||
|
$this->assertNotContains('/dev/build', $location);
|
||||||
|
$this->assertNotContains('flush=1', $location);
|
||||||
|
$this->assertNotContains('devbuildtoken=', $location);
|
||||||
|
$this->assertNotContains('flushtoken=', $location);
|
||||||
|
$this->assertContains('Security/login', $location);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,14 +149,14 @@ class ParameterConfirmationTokenTest extends SapphireTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* currentAbsoluteURL needs to handle base or url being missing, or any combination of slashes.
|
* currentURL needs to handle base or url being missing, or any combination of slashes.
|
||||||
*
|
*
|
||||||
* There should always be exactly one slash between each part in the result, and any trailing slash
|
* There should always be exactly one slash between each part in the result, and any trailing slash
|
||||||
* should be preserved.
|
* should be preserved.
|
||||||
*
|
*
|
||||||
* @dataProvider dataProviderURLs
|
* @dataProvider dataProviderURLs
|
||||||
*/
|
*/
|
||||||
public function testCurrentAbsoluteURLHandlesSlashes($url)
|
public function testCurrentURLHandlesSlashes($url)
|
||||||
{
|
{
|
||||||
$this->request->setUrl($url);
|
$this->request->setUrl($url);
|
||||||
|
|
||||||
|
148
tests/php/Core/Startup/URLConfirmationTokenTest.php
Normal file
148
tests/php/Core/Startup/URLConfirmationTokenTest.php
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Core\Tests\Startup;
|
||||||
|
|
||||||
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Control\HTTPRequest;
|
||||||
|
use SilverStripe\Control\Session;
|
||||||
|
use SilverStripe\Core\Startup\URLConfirmationToken;
|
||||||
|
use SilverStripe\Core\Tests\Startup\URLConfirmationTokenTest\StubToken;
|
||||||
|
use SilverStripe\Core\Tests\Startup\URLConfirmationTokenTest\StubValidToken;
|
||||||
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
|
||||||
|
class URLConfirmationTokenTest extends SapphireTest
|
||||||
|
{
|
||||||
|
public function testValidToken()
|
||||||
|
{
|
||||||
|
$request = new HTTPRequest('GET', 'token/test/url', ['tokentesturltoken' => 'value']);
|
||||||
|
$validToken = new StubValidToken('token/test/url', $request);
|
||||||
|
$this->assertTrue($validToken->urlMatches());
|
||||||
|
$this->assertFalse($validToken->urlExistsInBackURL());
|
||||||
|
$this->assertTrue($validToken->tokenProvided()); // Actually forced to true for this test
|
||||||
|
$this->assertFalse($validToken->reloadRequired());
|
||||||
|
$this->assertFalse($validToken->reloadRequiredIfError());
|
||||||
|
$this->assertStringStartsWith(Controller::join_links(BASE_URL, '/', 'token/test/url'), $validToken->redirectURL());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTokenWithLeadingSlashInUrl()
|
||||||
|
{
|
||||||
|
$request = new HTTPRequest('GET', '/leading/slash/url', []);
|
||||||
|
$leadingSlash = new StubToken('leading/slash/url', $request);
|
||||||
|
$this->assertTrue($leadingSlash->urlMatches());
|
||||||
|
$this->assertFalse($leadingSlash->urlExistsInBackURL());
|
||||||
|
$this->assertFalse($leadingSlash->tokenProvided());
|
||||||
|
$this->assertTrue($leadingSlash->reloadRequired());
|
||||||
|
$this->assertTrue($leadingSlash->reloadRequiredIfError());
|
||||||
|
$this->assertContains('leading/slash/url', $leadingSlash->redirectURL());
|
||||||
|
$this->assertContains('leadingslashurltoken', $leadingSlash->redirectURL());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTokenWithTrailingSlashInUrl()
|
||||||
|
{
|
||||||
|
$request = new HTTPRequest('GET', 'trailing/slash/url/', []);
|
||||||
|
$trailingSlash = new StubToken('trailing/slash/url', $request);
|
||||||
|
$this->assertTrue($trailingSlash->urlMatches());
|
||||||
|
$this->assertFalse($trailingSlash->urlExistsInBackURL());
|
||||||
|
$this->assertFalse($trailingSlash->tokenProvided());
|
||||||
|
$this->assertTrue($trailingSlash->reloadRequired());
|
||||||
|
$this->assertTrue($trailingSlash->reloadRequiredIfError());
|
||||||
|
$this->assertContains('trailing/slash/url', $trailingSlash->redirectURL());
|
||||||
|
$this->assertContains('trailingslashurltoken', $trailingSlash->redirectURL());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTokenWithUrlMatchedInBackUrl()
|
||||||
|
{
|
||||||
|
$request = new HTTPRequest('GET', '/', ['BackURL' => 'back/url']);
|
||||||
|
$backUrl = new StubToken('back/url', $request);
|
||||||
|
$this->assertFalse($backUrl->urlMatches());
|
||||||
|
$this->assertTrue($backUrl->urlExistsInBackURL());
|
||||||
|
$this->assertFalse($backUrl->tokenProvided());
|
||||||
|
$this->assertFalse($backUrl->reloadRequired());
|
||||||
|
$this->assertTrue($backUrl->reloadRequiredIfError());
|
||||||
|
$home = (BASE_URL ?: '/') . '?';
|
||||||
|
$this->assertStringStartsWith($home, $backUrl->redirectURL());
|
||||||
|
$this->assertContains('backurltoken', $backUrl->redirectURL());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUrlSuppressionWhenTokenMissing()
|
||||||
|
{
|
||||||
|
// Check suppression
|
||||||
|
$request = new HTTPRequest('GET', 'test/url', []);
|
||||||
|
$token = new StubToken('test/url', $request);
|
||||||
|
$this->assertEquals('test/url', $request->getURL(false));
|
||||||
|
$token->suppress();
|
||||||
|
$this->assertEquals('', $request->getURL(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPrepareTokens()
|
||||||
|
{
|
||||||
|
$request = new HTTPRequest('GET', 'test/url', []);
|
||||||
|
$token = URLConfirmationToken::prepare_tokens(
|
||||||
|
[
|
||||||
|
'test/url',
|
||||||
|
'test',
|
||||||
|
'url'
|
||||||
|
],
|
||||||
|
$request
|
||||||
|
);
|
||||||
|
// Test no invalid tokens
|
||||||
|
$this->assertEquals('test/url', $token->getURLToCheck());
|
||||||
|
$this->assertNotEquals('test/url', $request->getURL(false), 'prepare_tokens() did not suppress URL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPrepareTokensDoesntSuppressWhenNotMatched()
|
||||||
|
{
|
||||||
|
$request = new HTTPRequest('GET', 'test/url', []);
|
||||||
|
$token = URLConfirmationToken::prepare_tokens(
|
||||||
|
['another/url'],
|
||||||
|
$request
|
||||||
|
);
|
||||||
|
$this->assertEmpty($token);
|
||||||
|
$this->assertEquals('test/url', $request->getURL(false), 'prepare_tokens() incorrectly suppressed URL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPrepareTokensWithUrlMatchedInBackUrl()
|
||||||
|
{
|
||||||
|
// Test backurl token
|
||||||
|
$request = new HTTPRequest('GET', '/', ['BackURL' => 'back/url']);
|
||||||
|
$token = URLConfirmationToken::prepare_tokens(
|
||||||
|
[ 'back/url' ],
|
||||||
|
$request
|
||||||
|
);
|
||||||
|
$this->assertNotEmpty($token);
|
||||||
|
$this->assertEquals('back/url', $token->getURLToCheck());
|
||||||
|
$this->assertNotEquals('back/url', $request->getURL(false), 'prepare_tokens() did not suppress URL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataProviderURLs()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[''],
|
||||||
|
['/'],
|
||||||
|
['bar'],
|
||||||
|
['bar/'],
|
||||||
|
['/bar'],
|
||||||
|
['/bar/'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* currentURL needs to handle base or url being missing, or any combination of slashes.
|
||||||
|
*
|
||||||
|
* There should always be exactly one slash between each part in the result, and any trailing slash
|
||||||
|
* should be preserved.
|
||||||
|
*
|
||||||
|
* @dataProvider dataProviderURLs
|
||||||
|
*/
|
||||||
|
public function testCurrentURLHandlesSlashes($url)
|
||||||
|
{
|
||||||
|
$request = new HTTPRequest('GET', $url, []);
|
||||||
|
|
||||||
|
$token = new StubToken(
|
||||||
|
'another/url',
|
||||||
|
$request
|
||||||
|
);
|
||||||
|
$expected = rtrim(Controller::join_links(BASE_URL, '/', $url), '/') ?: '/';
|
||||||
|
$this->assertEquals($expected, $token->currentURL(), "Invalid redirect for request url $url");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Core\Tests\Startup\URLConfirmationTokenTest;
|
||||||
|
|
||||||
|
use SilverStripe\Core\Startup\URLConfirmationToken;
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dummy url token
|
||||||
|
*/
|
||||||
|
class StubToken extends URLConfirmationToken implements TestOnly
|
||||||
|
{
|
||||||
|
public function urlMatches()
|
||||||
|
{
|
||||||
|
return parent::urlMatches();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function currentURL()
|
||||||
|
{
|
||||||
|
return parent::currentURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function redirectURL()
|
||||||
|
{
|
||||||
|
return parent::redirectURL();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Core\Tests\Startup\URLConfirmationTokenTest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A token that always validates a given token
|
||||||
|
*/
|
||||||
|
class StubValidToken extends StubToken
|
||||||
|
{
|
||||||
|
|
||||||
|
protected function checkToken($token)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user