mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-09-30 05:09:06 +02:00
Merge branch '4.0' into 4
This commit is contained in:
commit
6b384f4b35
88
docs/en/04_Changelogs/rc/4.0.1-rc1.md
Normal file
88
docs/en/04_Changelogs/rc/4.0.1-rc1.md
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# 4.0.1-rc1
|
||||||
|
|
||||||
|
<!--- Changes below this line will be automatically regenerated -->
|
||||||
|
|
||||||
|
## Change Log
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
* 2017-11-30 [f1dd3d6f0]() Prevent disclosure of sensitive information via LoginAttempt (Damian Mooyman) - See [ss-2017-009](http://www.silverstripe.org/download/security-releases/ss-2017-009)
|
||||||
|
* 2017-11-29 [cfe1d4f48]() Ensure xls formulae are safely sanitised on output (Damian Mooyman) - See [ss-2017-007](http://www.silverstripe.org/download/security-releases/ss-2017-007)
|
||||||
|
* 2017-11-27 [7a79cd039]() Prevent install.php from disclosing system passwords (Damian Mooyman) - See [ss-2017-010](http://www.silverstripe.org/download/security-releases/ss-2017-010)
|
||||||
|
* 2017-11-20 [099a5a3c2]() SQL injection in full text search (Damian Mooyman) - See [ss-2017-008](http://www.silverstripe.org/download/security-releases/ss-2017-008)
|
||||||
|
|
||||||
|
### API Changes
|
||||||
|
|
||||||
|
* 2017-11-07 [96dfc95](https://github.com/silverstripe/silverstripe-versioned/commit/96dfc951c7bb76a112cb49af7f0aebf75bd29af4) Remove MemberExtension, functionality is replaced by framework update (Robbie Averill)
|
||||||
|
|
||||||
|
### Features and Enhancements
|
||||||
|
|
||||||
|
* 2017-12-04 [8ee35f4](https://github.com/silverstripe/silverstripe-asset-admin/commit/8ee35f46cbc9ae96e7927af46ea7ca8f067e55e1) added loadComponent fix for asset-admin entwine components (Christopher Joe)
|
||||||
|
* 2017-12-01 [259ae3f78]() Add ViewableData::getViewerTemplates() (Loz Calver)
|
||||||
|
* 2017-11-27 [b418616](https://github.com/silverstripe/silverstripe-admin/commit/b4186162769cee0c4fe7ab2df50781241b4e17ad) Use recipes for test configuration (Damian Mooyman)
|
||||||
|
* 2017-11-27 [33a39666b]() Promote portugese (portugal) as primary locale (Damian Mooyman)
|
||||||
|
* 2017-11-20 [3d5f4b3](https://github.com/silverstripe/silverstripe-assets/commit/3d5f4b38952d3b4d9fbf3a53767a942065490a0d) Hide Image_Backend construction behind image manipulations to improve performance (Damian Mooyman)
|
||||||
|
* 2017-11-20 [dea77c7](https://github.com/silverstripe/silverstripe-assets/commit/dea77c7792f9ee92f6c2ac600978c16cf7bf222c) Disable force_resample by default (Damian Mooyman)
|
||||||
|
* 2017-11-20 [0a37ff3](https://github.com/silverstripe/silverstripe-asset-admin/commit/0a37ff30c0d747e89dbcbd1a2a42411392aeb118) Don't request unused width / height from graphql (Damian Mooyman)
|
||||||
|
* 2017-11-15 [6a6cf2f9e]() Raise warning if DBField::create_field() would behave unpredictably and improve PHPDoc (Damian Mooyman)
|
||||||
|
* 2017-11-15 [8b063026f]() Ensure that non-writable assets files are notified during install (Damian Mooyman)
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
* 2017-12-05 [7efe667a](https://github.com/silverstripe/silverstripe-cms/commit/7efe667a487b4551dc21c0435b83cdced6290fc6) VirtualPage not using target page's template (fixes #2039) (#2041) (Loz Calver)
|
||||||
|
* 2017-12-03 [9fcebe7](https://github.com/silverstripe/silverstripe-asset-admin/commit/9fcebe7f317d2bdc7c1371ec4b4f6f20f6687e02) Fix unit tests (Christopher Joe)
|
||||||
|
* 2017-12-02 [3a4c6705c]() db autodiscover comment on loading behavior. (Russell Maclean)
|
||||||
|
* 2017-12-01 [91bd92df3]() Remove some unnecessary ClassInfo calls in DataObjectSchema (Loz Calver)
|
||||||
|
* 2017-12-01 [69295a6e2]() Ensure that all tinymce_lang mappings are valid (Damian Mooyman)
|
||||||
|
* 2017-11-28 [b3a51aa8d]() Fix broken scrutinizer (Damian Mooyman)
|
||||||
|
* 2017-11-28 [0de9b07](https://github.com/silverstripe/silverstripe-admin/commit/0de9b074fe6ac1e2d44c67b16f76fe3e01224131) Fix typo in Menu.scss (Damian Mooyman)
|
||||||
|
* 2017-11-27 [c4b366828]() Restore BackURL preservation on log out (closes #7636) (Loz Calver)
|
||||||
|
* 2017-11-27 [83cf147](https://github.com/silverstripe/silverstripe-admin/commit/83cf147649095f35ea6421a583153587c4afd8d9) Issue where logging out from the CMS presents you with a login form with no BackURL (Daniel Hensby)
|
||||||
|
* 2017-11-27 [b7ea05900]() Support self::class text collection (Robbie Averill)
|
||||||
|
* 2017-11-27 [cc72b5c85]() Added warning for auto-generated table_name for non-test classes (Christopher Joe)
|
||||||
|
* 2017-11-24 [09a003bc1]() deprecated usage of getMock in unit tests (Daniel Hensby)
|
||||||
|
* 2017-11-22 [ef6d86f2c]() Allow lowercase and uppercase delcaration of legacy Int class (Daniel Hensby)
|
||||||
|
* 2017-11-22 [d9e7a92b3]() Fix regressions in asset resize behaviour change (Damian Mooyman)
|
||||||
|
* 2017-11-21 [966622263]() Fix _configure_database.php being ignored (Damian Mooyman)
|
||||||
|
* 2017-11-21 [14b2641](https://github.com/silverstripe/silverstripe-config/commit/14b2641d0e10641817c15f1cda183b046fb86232) Fix added module fluid-prefix so module config will not require the full path to match (Christopher Joe)
|
||||||
|
* 2017-11-21 [27c079c](https://github.com/silverstripe/silverstripe-asset-admin/commit/27c079c307cb4d7ea4f0c176ad5105f37ecf3c27) Fix change in resampled config setting (Christopher Joe)
|
||||||
|
* 2017-11-21 [b1dc681](https://github.com/silverstripe/silverstripe-admin/commit/b1dc681d369899b2205340d1522441d6ccce5d24) Ensure changetracker safely defers to other init scripts (Damian Mooyman)
|
||||||
|
* 2017-11-20 [1e96989](https://github.com/silverstripe/silverstripe-config/commit/1e96989b99b108356ef349ce3a40f8681b71e925) Fix parameter order (Christopher Joe)
|
||||||
|
* 2017-11-20 [4fb0911](https://github.com/silverstripe/silverstripe-admin/commit/4fb0911290506d63d61c5a285f6ad6102cd3384f) Fix for buttons in change tracking and gridfield reloading (Christopher Joe)
|
||||||
|
* 2017-11-19 [694d2589](https://github.com/silverstripe/silverstripe-cms/commit/694d2589579f944ec714dac6aff7b888e5c42a96) Fix allowed children types now load properly (Christopher Joe)
|
||||||
|
* 2017-11-17 [509a590](https://github.com/silverstripe/silverstripe-admin/commit/509a590362d815f7d680c14a747e09674b3651b4) fix ignore `no-change-track` marked fields in changetracker (Christopher Joe)
|
||||||
|
* 2017-11-16 [cbf9e4011]() Fix postgres / PDO support (Damian Mooyman)
|
||||||
|
* 2017-11-16 [dda14e895]() HTTP::get_mime_type with uppercase filenames. (Roman Schmid)
|
||||||
|
* 2017-11-16 [52f0eadd3]() for #7606: Ensure the object we're handling is actually an Image instance before calling methods specific to that class (e.g. in case of using SVG's in <img> tag which may be File instances). (Patrick Nelson)
|
||||||
|
* 2017-11-16 [8de154d9](https://github.com/silverstripe/silverstripe-cms/commit/8de154d92cc9b044824205216683c0a187d17e5b) Restore missing '(Choose Page)' text in link insert modal (Damian Mooyman)
|
||||||
|
* 2017-11-15 [ef5879910]() Fix DBEnum ignoring empty defaults (Damian Mooyman)
|
||||||
|
* 2017-11-15 [ce3fd370f]() ManyMany link table joined with LEFT JOIN (Daniel Hensby)
|
||||||
|
* 2017-11-15 [3ad6a93](https://github.com/silverstripe/silverstripe-admin/commit/3ad6a937b8ae499f2f401c4cc1dd1193442f971e) page header center aligns when site tree is closed (Saophalkun Ponlu)
|
||||||
|
* 2017-11-15 [1c81430](https://github.com/silverstripe/silverstripe-admin/commit/1c8143078048bc0bdd516aeefcb171ec527359f2) fix show empty string title when relevant - rather than null when no options (Christopher Joe)
|
||||||
|
* 2017-11-14 [2bc7edbf4]() Fix don't treat zero-date as invalid (Christopher Joe)
|
||||||
|
* 2017-11-14 [b7e96fc](https://github.com/silverstripe/silverstripe-assets/commit/b7e96fcf3e39777d75740468ee39c224318ec68d) Prevent .htaccess operations from users in the same group failing (Damian Mooyman)
|
||||||
|
* 2017-11-14 [2e3bbe4](https://github.com/silverstripe/silverstripe-asset-admin/commit/2e3bbe437c5c7234a590c514c56b2c5674eaa051) Fix shortcodes not being parsed (Damian Mooyman)
|
||||||
|
* 2017-11-13 [3b5cee8](https://github.com/silverstripe/silverstripe-admin/commit/3b5cee8135ed444dba05bf66676ecf90c4b220e3) unsaved change dialog display just after creating a record (Saophalkun Ponlu)
|
||||||
|
* 2017-11-13 [d60f4a3](https://github.com/silverstripe/silverstripe-admin/commit/d60f4a30795a7d40d0b766bf62ed55c8291efe69) fix missing chosen sprites added to dist folder (Christopher Joe)
|
||||||
|
* 2017-11-09 [bf20d59cb]() Fixes SapphireTest masking userland coding errors. (Russell Michell)
|
||||||
|
* 2017-11-09 [1053de7ec]() Don't redirect in force_redirect() in CLI (Damian Mooyman)
|
||||||
|
* 2017-11-08 [0a87ad2](https://github.com/silverstripe/silverstripe-assets/commit/0a87ad270214563e7a90338b0a090da28dce6e1a) Remove whitespace around download link title (Robbie Averill)
|
||||||
|
* 2017-11-08 [6139de868]() Make sure plain parts are rendered when re-rendering emails (Daniel Hensby)
|
||||||
|
* 2017-11-06 [d3ff0d7](https://github.com/silverstripe/silverstripe-asset-admin/commit/d3ff0d74d2d49a2294b40f532174351bdef58101) Fix buttons in upload field to be proper button types (Christopher Joe)
|
||||||
|
* 2017-11-05 [d8b4ca91d]() Fix ContextSummary behaviour with UTF8 chars (Sam Minnee)
|
||||||
|
* 2017-11-03 [1d5cd20](https://github.com/silverstripe/silverstripe-admin/commit/1d5cd20ac553278396600e848f5482633c96a52c) Fix react-select does not return the true value when the option is missing (Christopher Joe)
|
||||||
|
* 2017-11-02 [457e653](https://github.com/silverstripe/silverstripe-asset-admin/commit/457e653867631d1fcec5676beb48ed01e05caaee) Fix native upload dialog appearing in entwine sections and added a canUpload condition for UploadField (Christopher Joe)
|
||||||
|
* 2017-11-01 [1bdfd056](https://github.com/silverstripe/silverstripe-cms/commit/1bdfd056482f1ba2c682e683a3582c682ec3dbbe) Remove usage of deprecated each() (Damian Mooyman)
|
||||||
|
* 2017-11-01 [5bc4f3d1f]() Remove usage of deprecated each() and use a helper method instead (Damian Mooyman)
|
||||||
|
* 2017-10-31 [f952ef747]() ed array/object mismatch bug in PaginatedList (Colin Tucker)
|
||||||
|
* 2017-10-25 [dd54e04](https://github.com/silverstripe/silverstripe-asset-admin/commit/dd54e04a4998ffb1968ab1e38423752f8e44b426) Fix usability issue, can tab to the upload field item even when it doesn't do anything by default (Christopher Joe)
|
||||||
|
* 2017-10-25 [cbac37559]() Helpful warning when phpunit bootstrap appears misconfigured (Daniel Hensby)
|
||||||
|
* 2017-10-25 [32cef975e]() Use self::inst() for Injector/Config nest methods (Daniel Hensby)
|
||||||
|
* 2017-10-25 [23316fc](https://github.com/silverstripe/silverstripe-asset-admin/commit/23316fccf2e1da907251614f6aaf40f58a6427ac) Fix wrong mouse cursor for description text in upload field area (Christopher Joe)
|
||||||
|
* 2017-10-19 [4965dc4](https://github.com/silverstripe/silverstripe-admin/commit/4965dc4fcb1cf650b1b4840f13e25aca39fd286f) stop bothering people with pop-ups (Christopher Joe)
|
||||||
|
* 2017-10-19 [a73d5b41](https://github.com/silverstripe/silverstripe-cms/commit/a73d5b4177be445128a6fa42e20dd8df13eaf554) revert to this button after archiving (Christopher Joe)
|
||||||
|
* 2017-10-12 [fd39faee](https://github.com/silverstripe/silverstripe-cms/commit/fd39faeefd5241cf96313e968142183de767c51b) UploadField overwriteWarning isn't working in AssetAdmin (Jason)
|
||||||
|
* 2017-10-09 [264cec123]() Dont use var_export for cache key generation as it fails on circular references (Daniel Hensby)
|
||||||
|
* 2017-10-04 [24e190ea](https://github.com/silverstripe/silverstripe-cms/commit/24e190ea8265d16445a3210f7b06de191e474004) TreeDropdownField showing broken page icons (fixes silverstripe/silverstripe-framework#7420) (Loz Calver)
|
||||||
|
* 2017-08-13 [2f579b64c]() Files without extensions (folders) do not have a trailing period added (Robbie Averill)
|
||||||
|
* 2017-07-04 [00f1ad5d6]() Fixes #7116 Improves server requirements docs viz: OpCaches. (Russell Michell)
|
@ -211,6 +211,7 @@ en:
|
|||||||
many_many_Members: Members
|
many_many_Members: Members
|
||||||
SilverStripe\Security\LoginAttempt:
|
SilverStripe\Security\LoginAttempt:
|
||||||
Email: 'Email Address'
|
Email: 'Email Address'
|
||||||
|
EmailHashed: 'Email Address (hashed)'
|
||||||
IP: 'IP Address'
|
IP: 'IP Address'
|
||||||
PLURALNAME: 'Login Attempts'
|
PLURALNAME: 'Login Attempts'
|
||||||
PLURALS:
|
PLURALS:
|
||||||
@ -269,6 +270,8 @@ en:
|
|||||||
SilverStripe\Security\MemberAuthenticator\MemberAuthenticator:
|
SilverStripe\Security\MemberAuthenticator\MemberAuthenticator:
|
||||||
ERRORWRONGCRED: 'The provided details don''t seem to be correct. Please try again.'
|
ERRORWRONGCRED: 'The provided details don''t seem to be correct. Please try again.'
|
||||||
NoPassword: 'There is no password on this member.'
|
NoPassword: 'There is no password on this member.'
|
||||||
|
SilverStripe\Security\MemberAuthenticator\MemberLoginForm:
|
||||||
|
AUTHENTICATORNAME: 'E-mail & Password'
|
||||||
SilverStripe\Security\MemberPassword:
|
SilverStripe\Security\MemberPassword:
|
||||||
PLURALNAME: 'Member Passwords'
|
PLURALNAME: 'Member Passwords'
|
||||||
PLURALS:
|
PLURALS:
|
||||||
|
@ -100,6 +100,8 @@ fi:
|
|||||||
Save: Tallenna
|
Save: Tallenna
|
||||||
SilverStripe\Forms\GridField\GridFieldEditButton_ss:
|
SilverStripe\Forms\GridField\GridFieldEditButton_ss:
|
||||||
EDIT: Muokkaa
|
EDIT: Muokkaa
|
||||||
|
SilverStripe\Forms\GridField\GridFieldGroupDeleteAction:
|
||||||
|
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
|
||||||
@ -250,6 +252,7 @@ fi:
|
|||||||
SUBJECTPASSWORDCHANGED: 'Salasanasi on vaihdettu'
|
SUBJECTPASSWORDCHANGED: 'Salasanasi on vaihdettu'
|
||||||
SUBJECTPASSWORDRESET: 'Salasanasi palautuslinkki'
|
SUBJECTPASSWORDRESET: 'Salasanasi palautuslinkki'
|
||||||
SURNAME: Sukunimi
|
SURNAME: Sukunimi
|
||||||
|
VALIDATIONADMINLOSTACCESS: 'Ylläpitäjäryhmää ei voi poistaa profiilistasi'
|
||||||
ValidationIdentifierFailed: 'Olemassa olevan käyttäjän id:n #{id} päälle ei voida kirjoittaa samalla tunnisteella ({name} = {value}))'
|
ValidationIdentifierFailed: 'Olemassa olevan käyttäjän id:n #{id} päälle ei voida kirjoittaa samalla tunnisteella ({name} = {value}))'
|
||||||
WELCOMEBACK: 'Tervetuloa takaisin, {firstname}'
|
WELCOMEBACK: 'Tervetuloa takaisin, {firstname}'
|
||||||
YOUROLDPASSWORD: 'Vanha salasanasi'
|
YOUROLDPASSWORD: 'Vanha salasanasi'
|
||||||
|
206
lang/fr.yml
206
lang/fr.yml
@ -1,63 +1,84 @@
|
|||||||
fr:
|
fr:
|
||||||
|
SilverStripe\Admin\LeftAndMain:
|
||||||
|
VersionUnknown: Inconnu
|
||||||
SilverStripe\AssetAdmin\Forms\UploadField:
|
SilverStripe\AssetAdmin\Forms\UploadField:
|
||||||
Dimensions: Dimensions
|
Dimensions: Dimensions
|
||||||
EDIT: Éditer
|
EDIT: Éditer
|
||||||
EDITINFO: 'Éditer ce fichier'
|
EDITINFO: 'Éditer ce fichier'
|
||||||
|
REMOVE: Retirer
|
||||||
SilverStripe\Control\ChangePasswordEmail_ss:
|
SilverStripe\Control\ChangePasswordEmail_ss:
|
||||||
|
CHANGEPASSWORDFOREMAIL: 'Le mot de passe du compte correspondant à l''adresse {email} a été modifié. Si vous n''avez pas modifié votre mot de passe, merci de le changer à l''aide du lien suivant'
|
||||||
CHANGEPASSWORDTEXT1: 'Votre mot de passe est maintenant'
|
CHANGEPASSWORDTEXT1: 'Votre mot de passe est maintenant'
|
||||||
CHANGEPASSWORDTEXT3: 'Changer le mot de passe'
|
CHANGEPASSWORDTEXT3: 'Changer le mot de passe'
|
||||||
HELLO: Bonjour
|
HELLO: Bonjour
|
||||||
SilverStripe\Control\Email\ForgotPasswordEmail_ss:
|
SilverStripe\Control\Email\ForgotPasswordEmail_ss:
|
||||||
HELLO: Bonjour
|
HELLO: Bonjour
|
||||||
|
TEXT1: 'Voici votre'
|
||||||
|
TEXT2: 'Lien de réinitialisation de mot de passe'
|
||||||
|
TEXT3: pour
|
||||||
|
SilverStripe\Control\RequestProcessor:
|
||||||
|
INVALID_REQUEST: 'Requête invalide'
|
||||||
|
REQUEST_ABORTED: 'Requête non aboutie'
|
||||||
|
SilverStripe\Core\Manifest\VersionProvider:
|
||||||
|
VERSIONUNKNOWN: Inconnu
|
||||||
SilverStripe\Forms\CheckboxField:
|
SilverStripe\Forms\CheckboxField:
|
||||||
NOANSWER: Non
|
NOANSWER: Non
|
||||||
YESANSWER: Oui
|
YESANSWER: Oui
|
||||||
|
SilverStripe\Forms\CheckboxSetField_ss:
|
||||||
|
NOOPTIONSAVAILABLE: 'Aucune option disponible'
|
||||||
SilverStripe\Forms\ConfirmedPasswordField:
|
SilverStripe\Forms\ConfirmedPasswordField:
|
||||||
ATLEAST: 'Le mot de passe doit comporter au moins {min} caractères.'
|
ATLEAST: 'Le mot de passe doit comporter au moins {min} caractères.'
|
||||||
BETWEEN: 'Le mot de passe doit comporter entre {min} et {max} caractères.'
|
BETWEEN: 'Le mot de passe doit comporter entre {min} et {max} caractères.'
|
||||||
CURRENT_PASSWORD_ERROR: 'Le mot de passe que vous avez saisi n''est pas correct'
|
CURRENT_PASSWORD_ERROR: 'Le mot de passe que vous avez saisi n''est pas correct'
|
||||||
CURRENT_PASSWORD_MISSING: 'Vous devez saisir votre mot de passe actuel.'
|
CURRENT_PASSWORD_MISSING: 'Vous devez saisir votre mot de passe actuel.'
|
||||||
LOGGED_IN_ERROR: 'Vous devez être connecté pour pouvoir changer votre mot de passe'
|
LOGGED_IN_ERROR: 'Vous devez être connecté pour pouvoir changer votre mot de passe'
|
||||||
MAXIMUM: 'Le mot de passe ne doit comporter plus de {max} caractères.'
|
MAXIMUM: 'Le mot de passe ne doit pas comporter plus de {max} caractères.'
|
||||||
SHOWONCLICKTITLE: 'Changer le mot de passe'
|
SHOWONCLICKTITLE: 'Changer le mot de passe'
|
||||||
SilverStripe\Forms\CurrencyField:
|
SilverStripe\Forms\CurrencyField:
|
||||||
CURRENCYSYMBOL: $
|
CURRENCYSYMBOL: $
|
||||||
SilverStripe\Forms\DateField:
|
SilverStripe\Forms\DateField:
|
||||||
NOTSET: 'non renseigné'
|
NOTSET: 'non renseigné'
|
||||||
TODAY: 'aujourd''hui'
|
TODAY: 'aujourd''hui'
|
||||||
VALIDDATEFORMAT2: 'Saisissez la date au format valide ({format})'
|
VALIDDATEFORMAT2: 'Saisissez une date au format valide ({format})'
|
||||||
VALIDDATEMAXDATE: 'La date doit être antérieure ou égale à celle qui a été autorisée ({date})'
|
VALIDDATEMAXDATE: 'La date doit être antérieure ou égale à celle autorisée ({date})'
|
||||||
VALIDDATEMINDATE: 'La date doit être plus récente ou égale à celle qui a été autorisée ({date})'
|
VALIDDATEMINDATE: 'La date doit être postérieure ou égale à celle autorisée ({date})'
|
||||||
SilverStripe\Forms\DatetimeField:
|
SilverStripe\Forms\DatetimeField:
|
||||||
|
VALIDDATEMAXDATETIME: 'La date doit être antérieure ou égale à celle autorisée ({datetime})'
|
||||||
VALIDDATETIMEFORMAT: 'Saisissez un format de date et d''heure valide ({format})'
|
VALIDDATETIMEFORMAT: 'Saisissez un format de date et d''heure valide ({format})'
|
||||||
|
VALIDDATETIMEMINDATE: 'La date doit être postérieure ou égale à celle autorisée ({datetime})'
|
||||||
SilverStripe\Forms\DropdownField:
|
SilverStripe\Forms\DropdownField:
|
||||||
CHOOSE: (Choisir)
|
CHOOSE: (Choisir)
|
||||||
CHOOSE_MODEL: '(Choisir {name})'
|
CHOOSE_MODEL: '(Choisir {name})'
|
||||||
|
SOURCE_VALIDATION: 'Merci de choisir une valeur parmi celles proposées dans la liste. {value} n''est pas une option valide'
|
||||||
SilverStripe\Forms\EmailField:
|
SilverStripe\Forms\EmailField:
|
||||||
VALIDATION: 'Saisissez une adresse de courrier électronique'
|
VALIDATION: 'Merci de saisir une adresse email'
|
||||||
SilverStripe\Forms\FileUploadReceiver:
|
SilverStripe\Forms\FileUploadReceiver:
|
||||||
FIELDNOTSET: 'Informations concernant le fichiers non-trouvées'
|
FIELDNOTSET: 'Information sur le fichier introuvable'
|
||||||
SilverStripe\Forms\Form:
|
SilverStripe\Forms\Form:
|
||||||
CSRF_EXPIRED_MESSAGE: 'Votre session a expiré. Renvoyez le formulaire.'
|
BAD_METHOD: 'Ce formulaire requiert une action {method}'
|
||||||
|
CSRF_EXPIRED_MESSAGE: 'Votre session a expiré. Merci de renvoyer le formulaire.'
|
||||||
|
CSRF_FAILED_MESSAGE: 'Un problème technique est probablement survenu. Merci de cliquer sur le bouton "retour", de rafraîchir la page de votre navigateur, et de réessayer.'
|
||||||
VALIDATIONPASSWORDSDONTMATCH: 'Les mots de passe ne correspondent pas'
|
VALIDATIONPASSWORDSDONTMATCH: 'Les mots de passe ne correspondent pas'
|
||||||
VALIDATIONPASSWORDSNOTEMPTY: 'Les mots de passe peuvent être vides'
|
VALIDATIONPASSWORDSNOTEMPTY: 'Les mots de passe ne peuvent pas être vides'
|
||||||
VALIDATIONSTRONGPASSWORD: 'Le mot de passe doit comporter au moins un chiffre et un caractère alphanumérique'
|
VALIDATIONSTRONGPASSWORD: 'Le mot de passe doit comporter au moins un chiffre et un caractère alphanumérique'
|
||||||
VALIDATOR: Validateur
|
VALIDATOR: Validateur
|
||||||
VALIDCURRENCY: 'Saisissez une monnaie valide'
|
VALIDCURRENCY: 'Saisissez une monnaie valide'
|
||||||
SilverStripe\Forms\FormField:
|
SilverStripe\Forms\FormField:
|
||||||
|
EXAMPLE: 'Par ex. {format}'
|
||||||
NONE: aucun
|
NONE: aucun
|
||||||
SilverStripe\Forms\FormScaffolder:
|
SilverStripe\Forms\FormScaffolder:
|
||||||
TABMAIN: Principal
|
TABMAIN: Principal
|
||||||
SilverStripe\Forms\GridField\GridField:
|
SilverStripe\Forms\GridField\GridField:
|
||||||
Add: 'Ajouter {name}'
|
Add: 'Ajouter {name}'
|
||||||
CSVEXPORT: 'Exporter vers un fichier CSV'
|
CSVEXPORT: 'Exporter vers un fichier CSV'
|
||||||
|
CSVIMPORT: 'Importer un fichier CSV'
|
||||||
Filter: Filtrer
|
Filter: Filtrer
|
||||||
FilterBy: 'Filtrer par'
|
FilterBy: 'Filtrer par'
|
||||||
Find: Trouver
|
Find: Trouver
|
||||||
LinkExisting: 'Lien existant'
|
LinkExisting: 'Lien existant'
|
||||||
NewRecord: 'Nouveau {type}'
|
NewRecord: 'Nouveau {type}'
|
||||||
NoItemsFound: 'Aucun élément n’a été trouvé.'
|
NoItemsFound: 'Aucun élément n’a été trouvé.'
|
||||||
PRINTEDAT: 'Imprimé le'
|
PRINTEDAT: 'Imprimé à'
|
||||||
PRINTEDBY: 'Imprimé par'
|
PRINTEDBY: 'Imprimé par'
|
||||||
PlaceHolder: 'Rechercher {type}'
|
PlaceHolder: 'Rechercher {type}'
|
||||||
PlaceHolderWithLabels: 'Rechercher {type} par {name}'
|
PlaceHolderWithLabels: 'Rechercher {type} par {name}'
|
||||||
@ -65,7 +86,7 @@ fr:
|
|||||||
RelationSearch: 'Rechercher relations'
|
RelationSearch: 'Rechercher relations'
|
||||||
ResetFilter: Réinitialiser
|
ResetFilter: Réinitialiser
|
||||||
SilverStripe\Forms\GridField\GridFieldDeleteAction:
|
SilverStripe\Forms\GridField\GridFieldDeleteAction:
|
||||||
DELETE_DESCRIPTION: Supprime
|
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'
|
||||||
@ -79,52 +100,110 @@ fr:
|
|||||||
Save: Enregistrer
|
Save: Enregistrer
|
||||||
SilverStripe\Forms\GridField\GridFieldEditButton_ss:
|
SilverStripe\Forms\GridField\GridFieldEditButton_ss:
|
||||||
EDIT: Editer
|
EDIT: Editer
|
||||||
|
SilverStripe\Forms\GridField\GridFieldGroupDeleteAction:
|
||||||
|
UnlinkSelfFailure: 'Impossible de retirer votre propre profil de ce groupe, vous perdriez vos droits d''administration'
|
||||||
SilverStripe\Forms\GridField\GridFieldPaginator:
|
SilverStripe\Forms\GridField\GridFieldPaginator:
|
||||||
OF: de
|
OF: de
|
||||||
Page: Page
|
Page: Page
|
||||||
View: Vue
|
View: Vue
|
||||||
|
SilverStripe\Forms\GridField\GridFieldVersionedState:
|
||||||
|
ADDEDTODRAFTHELP: 'L''élément n''a pas encore été publié'
|
||||||
|
ADDEDTODRAFTSHORT: Brouillon
|
||||||
|
ARCHIVEDPAGEHELP: 'Elément retiré du brouillon et du site public'
|
||||||
|
ARCHIVEDPAGESHORT: Archivé
|
||||||
|
MODIFIEDONDRAFTHELP: 'L''élément comporte des modifications non sauvegardées'
|
||||||
|
MODIFIEDONDRAFTSHORT: Modifié
|
||||||
|
ONLIVEONLYSHORT: 'Site public uniquement'
|
||||||
|
ONLIVEONLYSHORTHELP: 'L''élément a été publié, mais sa version brouillon a été supprimée'
|
||||||
SilverStripe\Forms\MoneyField:
|
SilverStripe\Forms\MoneyField:
|
||||||
FIELDLABELAMOUNT: Quantité
|
FIELDLABELAMOUNT: Quantité
|
||||||
FIELDLABELCURRENCY: Devise
|
FIELDLABELCURRENCY: Devise
|
||||||
|
INVALID_CURRENCY: '{currency} ne figure pas dans la liste des devises autorisées'
|
||||||
|
SilverStripe\Forms\MultiSelectField:
|
||||||
|
SOURCE_VALIDATION: 'Merci de choisir des valeurs parmi celles proposées dans la liste. Option(s) {value} non valide(s)'
|
||||||
SilverStripe\Forms\NullableField:
|
SilverStripe\Forms\NullableField:
|
||||||
IsNullLabel: 'Est Null'
|
IsNullLabel: 'Est Null'
|
||||||
SilverStripe\Forms\NumericField:
|
SilverStripe\Forms\NumericField:
|
||||||
VALIDATION: "«\_{value}\_» n’est pas un chiffre, seule donnée acceptée dans ce champ "
|
VALIDATION: "«\_{value}\_» n’est pas un nombre, seul type de donnée acceptée dans ce champ "
|
||||||
SilverStripe\Forms\TimeField:
|
SilverStripe\Forms\TimeField:
|
||||||
VALIDATEFORMAT: 'Saisissez l’heure au format valide ({format})'
|
VALIDATEFORMAT: 'Merci de saisir un format de date valide ({format})'
|
||||||
|
SilverStripe\ORM\DataObject:
|
||||||
|
PLURALNAME: 'Modèles de donnée'
|
||||||
|
PLURALS:
|
||||||
|
one: 'Un modèle de donnée'
|
||||||
|
other: '{count} modèles de donnée'
|
||||||
|
SINGULARNAME: 'Modèle de donnée'
|
||||||
SilverStripe\ORM\FieldType\DBBoolean:
|
SilverStripe\ORM\FieldType\DBBoolean:
|
||||||
ANY: Tout
|
ANY: Tout
|
||||||
NOANSWER: Non
|
NOANSWER: Non
|
||||||
YESANSWER: Oui
|
YESANSWER: Oui
|
||||||
SilverStripe\ORM\FieldType\DBDate:
|
SilverStripe\ORM\FieldType\DBDate:
|
||||||
|
DAYS_SHORT_PLURALS:
|
||||||
|
one: '{count} jour'
|
||||||
|
other: '{count} jours'
|
||||||
|
HOURS_SHORT_PLURALS:
|
||||||
|
one: '{count} heure'
|
||||||
|
other: '{count} heures'
|
||||||
LessThanMinuteAgo: 'moins d''une minute'
|
LessThanMinuteAgo: 'moins d''une minute'
|
||||||
|
MINUTES_SHORT_PLURALS:
|
||||||
|
one: '{count} min.'
|
||||||
|
other: '{count} min.'
|
||||||
|
MONTHS_SHORT_PLURALS:
|
||||||
|
one: '{count} mois'
|
||||||
|
other: '{count} mois'
|
||||||
|
SECONDS_SHORT_PLURALS:
|
||||||
|
one: '{count} sec.'
|
||||||
|
other: '{count} sec.'
|
||||||
TIMEDIFFAGO: 'Il y a {difference}'
|
TIMEDIFFAGO: 'Il y a {difference}'
|
||||||
TIMEDIFFIN: 'Dans {difference}'
|
TIMEDIFFIN: 'Dans {difference}'
|
||||||
|
YEARS_SHORT_PLURALS:
|
||||||
|
one: '{count} année'
|
||||||
|
other: '{count} années'
|
||||||
SilverStripe\ORM\FieldType\DBEnum:
|
SilverStripe\ORM\FieldType\DBEnum:
|
||||||
ANY: Tous
|
ANY: Tout
|
||||||
|
SilverStripe\ORM\Hierarchy:
|
||||||
|
LIMITED_TITLE: 'Enfants trop nombreux ({count})'
|
||||||
SilverStripe\ORM\Hierarchy\Hierarchy:
|
SilverStripe\ORM\Hierarchy\Hierarchy:
|
||||||
InfiniteLoopNotAllowed: "Une boucle infinie s’est produite dans la hiérarchie «\_{type}\_». Modifiez le parent pour le résoudre."
|
InfiniteLoopNotAllowed: "Une boucle sans fin s’est produite dans la hiérarchie «\_{type}\_». Merci de modifier le parent pour résoudre le problème."
|
||||||
|
LIMITED_TITLE: 'Enfants trop nombreux ({count})'
|
||||||
SilverStripe\ORM\ValidationException:
|
SilverStripe\ORM\ValidationException:
|
||||||
DEFAULT_ERROR: 'Erreur de validation'
|
DEFAULT_ERROR: 'Erreur de validation'
|
||||||
SilverStripe\Security\BasicAuth:
|
SilverStripe\Security\BasicAuth:
|
||||||
ENTERINFO: 'Entrer un identifiant et un mot de passe s''il vous plaît.'
|
ENTERINFO: 'Merci d''entrer un identifiant et un mot de passe.'
|
||||||
ERRORNOTADMIN: 'Cet utilisateur n''est pas un administrateur.'
|
ERRORNOTADMIN: 'Cet utilisateur n''est pas un administrateur.'
|
||||||
ERRORNOTREC: 'Cet identifiant / mot de passe n''est pas reconnu'
|
ERRORNOTREC: 'Identifiant et/ou mot de passe non reconnus'
|
||||||
|
SilverStripe\Security\CMSMemberLoginForm:
|
||||||
|
PASSWORDEXPIRED: '<p>Votre mot de passe a expiré. <a target="_top" href="{link}">Merci d''en choisir un nouveau.</a></p>'
|
||||||
|
SilverStripe\Security\CMSSecurity:
|
||||||
|
INVALIDUSER: '<p>Utilisateur non valide. <a target="_top" href="{link}">Merci de vous authentifier de nouveau ici</a> pour poursuivre.</p>'
|
||||||
|
LOGIN_MESSAGE: '<p>Votre session a expiré pour cause d''inactivité</p>'
|
||||||
|
LOGIN_TITLE: 'Retournez là où vous en étiez en vos connectant de nouveau'
|
||||||
|
SUCCESS: Succès
|
||||||
|
SUCCESSCONTENT: '<p>Connexion réussie. Si vous n''êtes pas automatiquement redirigé <a target="_top" href="{link}">cliquez ici</a></p>'
|
||||||
|
SUCCESS_TITLE: 'Connexion réussie'
|
||||||
|
SilverStripe\Security\DefaultAdminService:
|
||||||
|
DefaultAdminFirstname: 'Administrateur par défaut'
|
||||||
SilverStripe\Security\Group:
|
SilverStripe\Security\Group:
|
||||||
AddRole: 'Ajouter un rôle pour ce groupe'
|
AddRole: 'Ajouter un rôle pour ce groupe'
|
||||||
Code: 'Code de groupe'
|
Code: 'Code du groupe'
|
||||||
DefaultGroupTitleAdministrators: Administrateur
|
DefaultGroupTitleAdministrators: Administrateur
|
||||||
DefaultGroupTitleContentAuthors: 'Auteurs du contenu'
|
DefaultGroupTitleContentAuthors: 'Auteurs du contenu'
|
||||||
Description: Description
|
Description: Description
|
||||||
|
GROUPNAME: 'Nom du groupe'
|
||||||
GroupReminder: 'Si vous choisissez un groupe parent, ce groupe prendra tous ses rôles'
|
GroupReminder: 'Si vous choisissez un groupe parent, ce groupe prendra tous ses rôles'
|
||||||
|
HierarchyPermsError: 'Impossible d''attribuer des autorisations au groupe parent "{group}" (requiert un accès en tant qu''administrateur)'
|
||||||
Locked: 'Verrouillé?'
|
Locked: 'Verrouillé?'
|
||||||
MEMBERS: Membres
|
MEMBERS: Membres
|
||||||
NEWGROUP: 'Nouveau groupe'
|
NEWGROUP: 'Nouveau groupe'
|
||||||
NoRoles: 'Vous n’avez pas la permission pour faire ça'
|
NoRoles: 'Aucun rôle trouvé'
|
||||||
PERMISSIONS: Permissions
|
PERMISSIONS: Permissions
|
||||||
PLURALNAME: Groupes
|
PLURALNAME: Groupes
|
||||||
|
PLURALS:
|
||||||
|
one: 'Un groupe'
|
||||||
|
other: '{count} groupes'
|
||||||
Parent: 'Groupe parent'
|
Parent: 'Groupe parent'
|
||||||
ROLES: Rôles
|
ROLES: Rôles
|
||||||
|
ROLESDESCRIPTION: 'Les rôles sont des ensembles de permissions prédéfinies, et ils peuvent être attribués à des groupes. <br />Si nécessaire, ils peuvent hériter de groupes parents.'
|
||||||
RolesAddEditLink: 'Ajouter/éditer les rôles'
|
RolesAddEditLink: 'Ajouter/éditer les rôles'
|
||||||
SINGULARNAME: Groupe
|
SINGULARNAME: Groupe
|
||||||
Sort: 'Ordre de tri'
|
Sort: 'Ordre de tri'
|
||||||
@ -133,80 +212,125 @@ fr:
|
|||||||
SilverStripe\Security\LoginAttempt:
|
SilverStripe\Security\LoginAttempt:
|
||||||
Email: 'Adresse email'
|
Email: 'Adresse email'
|
||||||
IP: 'Adresse IP'
|
IP: 'Adresse IP'
|
||||||
|
PLURALNAME: 'Tentatives de connexion'
|
||||||
|
PLURALS:
|
||||||
|
one: 'Une tentative de connexion'
|
||||||
|
other: '{count} tentatives de connexion'
|
||||||
|
SINGULARNAME: 'Tentative de connexion'
|
||||||
Status: Statut
|
Status: Statut
|
||||||
SilverStripe\Security\Member:
|
SilverStripe\Security\Member:
|
||||||
ADDGROUP: 'Ajouter un groupe'
|
ADDGROUP: 'Ajouter un groupe'
|
||||||
BUTTONCHANGEPASSWORD: 'Changer mot de passe'
|
BUTTONCHANGEPASSWORD: 'Changer mot de passe'
|
||||||
BUTTONLOGIN: 'Se connecter'
|
BUTTONLOGIN: 'Se connecter'
|
||||||
BUTTONLOGINOTHER: 'Connectez vous avec un différent identifiant'
|
BUTTONLOGINOTHER: 'Se connecter avec un identifiant différent'
|
||||||
|
BUTTONLOGOUT: Déconnexion
|
||||||
BUTTONLOSTPASSWORD: 'J''ai perdu mon mot de passe'
|
BUTTONLOSTPASSWORD: 'J''ai perdu mon mot de passe'
|
||||||
CONFIRMNEWPASSWORD: 'Confirmer nouveau mot de passe'
|
CONFIRMNEWPASSWORD: 'Confirmer nouveau mot de passe'
|
||||||
CONFIRMPASSWORD: 'Confirmer Mot De Passe'
|
CONFIRMPASSWORD: 'Confirmer Mot De Passe'
|
||||||
CURRENT_PASSWORD: 'Mot de passe actuel'
|
CURRENT_PASSWORD: 'Mot de passe actuel'
|
||||||
EDIT_PASSWORD: 'Nouveau mot de passe'
|
EDIT_PASSWORD: 'Nouveau mot de passe'
|
||||||
EMAIL: Email
|
EMAIL: Email
|
||||||
EMPTYNEWPASSWORD: 'Le champs nouveau mot de passe ne peut être vide, essayez de nouveau'
|
EMPTYNEWPASSWORD: 'Le champs nouveau mot de passe ne peut être vide, merci de réessayer'
|
||||||
ENTEREMAIL: 'Veuillez écrire une adresse email pour obtenir le lien de réinitialisation du mot de passe.'
|
ENTEREMAIL: 'Veuillez entrer une adresse email pour obtenir un lien de réinitialisation du mot de passe.'
|
||||||
ERRORLOCKEDOUT2: 'Votre compte a été temporairement désactivé à cause de trop nombreux échecs d''identification. Veuillez réessayer dans {count} minutes.'
|
ERRORLOCKEDOUT2: 'Votre compte a été temporairement désactivé en raison d''un nombre trop élevé d''échecs d''identification. Veuillez réessayer dans {count} minutes.'
|
||||||
ERRORNEWPASSWORD: 'Vous avez entré votre nouveau mot de passe différemment, réessayez'
|
ERRORNEWPASSWORD: 'Vous avez entré votre nouveau mot de passe différemment, réessayez'
|
||||||
ERRORPASSWORDNOTMATCH: 'Votre actuel mot de passe ne correspond pas, essayez encore s''il vous plaît'
|
ERRORPASSWORDNOTMATCH: 'Votre actuel mot de passe ne correspond pas, merci de réessayer'
|
||||||
ERRORWRONGCRED: 'Il semble que ce ne soit pas le bon email ou mot de passe. Essayez encore s''il vous plaît.'
|
ERRORWRONGCRED: 'Il semble que ce ne soit pas le bon email ou mot de passe. Merci de réessayer.'
|
||||||
FIRSTNAME: Prénom
|
FIRSTNAME: Prénom
|
||||||
INTERFACELANG: 'Langue de l''interface'
|
INTERFACELANG: 'Langue de l''interface'
|
||||||
KEEPMESIGNEDIN: 'Se souvenir de moi'
|
KEEPMESIGNEDIN: 'Se souvenir de moi'
|
||||||
LOGGEDINAS: 'Vous êtes connecté comme {name}.'
|
LOGGEDINAS: 'Vous êtes connecté en tant que {name}.'
|
||||||
NEWPASSWORD: 'Nouveau mot de passe'
|
NEWPASSWORD: 'Nouveau mot de passe'
|
||||||
PASSWORD: 'Mot de passe'
|
PASSWORD: 'Mot de passe'
|
||||||
PASSWORDEXPIRED: 'Votre mot de passe a expiré. Choisissez-en un nouveau.'
|
PASSWORDEXPIRED: 'Votre mot de passe a expiré. Merci d''en choisir un nouveau.'
|
||||||
PLURALNAME: Membres
|
PLURALNAME: Membres
|
||||||
|
PLURALS:
|
||||||
|
one: 'Un membre'
|
||||||
|
other: '{count} membres'
|
||||||
|
REMEMBERME: 'Se souvenir de moi la prochaine fois ? (pour une durée de {count} jours sur cet appareil)'
|
||||||
SINGULARNAME: Membre
|
SINGULARNAME: Membre
|
||||||
SUBJECTPASSWORDCHANGED: 'Votre mot de passe a été changé'
|
SUBJECTPASSWORDCHANGED: 'Votre mot de passe a été changé'
|
||||||
SUBJECTPASSWORDRESET: 'Lien pour modifier votre mot de passe'
|
SUBJECTPASSWORDRESET: 'Lien pour modifier votre mot de passe'
|
||||||
SURNAME: 'Nom de famille'
|
SURNAME: 'Nom de famille'
|
||||||
ValidationIdentifierFailed: 'On ne peut pas réenregistrer le membre nº {id} avec un identifiant identique ({name} = {value}))'
|
VALIDATIONADMINLOSTACCESS: 'Impossible de retirer tous les groupes d''administrateur à partir de votre profil'
|
||||||
WELCOMEBACK: 'Bienvenue {firstname}'
|
ValidationIdentifierFailed: 'Impossible de réenregistrer le membre nº {id} avec un identifiant identique ({name} = {value}))'
|
||||||
|
WELCOMEBACK: 'Bienvenue de nouveau, {firstname}'
|
||||||
YOUROLDPASSWORD: 'Votre ancien mot de passe'
|
YOUROLDPASSWORD: 'Votre ancien mot de passe'
|
||||||
belongs_many_many_Groups: Groupes
|
belongs_many_many_Groups: Groupes
|
||||||
db_Locale: 'Langue de l''Interface'
|
db_Locale: 'Langue de l''Interface'
|
||||||
db_LockedOutUntil: 'Verrouillé jusqu''à'
|
db_LockedOutUntil: 'Verrouillé jusqu''à'
|
||||||
db_Password: 'Mot de passe'
|
db_Password: 'Mot de passe'
|
||||||
db_PasswordExpiry: 'Date d''expiration du mot de passe'
|
db_PasswordExpiry: 'Date d''expiration du mot de passe'
|
||||||
|
SilverStripe\Security\MemberAuthenticator\CMSMemberLoginForm:
|
||||||
|
AUTHENTICATORNAME: 'Formulaire de connexion pour un utilisateur du CMS'
|
||||||
|
BUTTONFORGOTPASSWORD: 'Mot de passe oublié'
|
||||||
|
BUTTONLOGIN: 'De retour dans'
|
||||||
|
BUTTONLOGOUT: 'Se déconnecter'
|
||||||
|
SilverStripe\Security\MemberAuthenticator\MemberAuthenticator:
|
||||||
|
ERRORWRONGCRED: 'Les renseignements fournis semblent incorrects. Merci de réessayer.'
|
||||||
|
NoPassword: 'Ce membre n''a pas de mot de passe'
|
||||||
SilverStripe\Security\MemberPassword:
|
SilverStripe\Security\MemberPassword:
|
||||||
PLURALNAME: 'Mots de passe du membre'
|
PLURALNAME: 'Mots de passe utilisateur'
|
||||||
SINGULARNAME: 'Mot de passe du membre'
|
PLURALS:
|
||||||
|
one: 'Un mot de passe utilisateur'
|
||||||
|
other: '{count} mots de passe utilisateur'
|
||||||
|
SINGULARNAME: 'Mot de passe utilisateur'
|
||||||
SilverStripe\Security\PasswordValidator:
|
SilverStripe\Security\PasswordValidator:
|
||||||
LOWCHARSTRENGTH: 'Veuillez augmenter la force de votre mot de passe en ajoutant certains caractères suivants : {chars}'
|
LOWCHARSTRENGTH: 'Veuillez renforcer votre mot de passe en ajoutant certains des caractères suivants : {chars}'
|
||||||
PREVPASSWORD: 'Vous avez déjà utilisé ce mot de passe par le passé, veuillez en choisir un autre'
|
PREVPASSWORD: 'Vous avez déjà utilisé ce mot de passe par le passé, veuillez en choisir un autre'
|
||||||
TOOSHORT: 'Le mot de passe est trop court, il doit contenir au moins {minimum} caractères'
|
TOOSHORT: 'Le mot de passe est trop court, il doit contenir au moins {minimum} caractères'
|
||||||
SilverStripe\Security\Permission:
|
SilverStripe\Security\Permission:
|
||||||
AdminGroup: Administrateur
|
AdminGroup: Administrateur
|
||||||
CONTENT_CATEGORY: 'Permissions du contenu'
|
CMS_ACCESS_CATEGORY: 'Accès au CMS'
|
||||||
|
CONTENT_CATEGORY: 'Permissions de contenu'
|
||||||
FULLADMINRIGHTS: 'Droits d''administration complets'
|
FULLADMINRIGHTS: 'Droits d''administration complets'
|
||||||
FULLADMINRIGHTS_HELP: 'Implique et prévaut sur toutes les autres autorisations assignées.'
|
FULLADMINRIGHTS_HELP: 'Prévaut sur toutes les autres autorisations assignées.'
|
||||||
|
PERMISSIONS_CATEGORY: 'Rôles et autorisations d’accès'
|
||||||
PLURALNAME: Permissions
|
PLURALNAME: Permissions
|
||||||
|
PLURALS:
|
||||||
|
one: 'Une autorisation'
|
||||||
|
other: '{count} autorisations'
|
||||||
SINGULARNAME: Permission
|
SINGULARNAME: Permission
|
||||||
UserPermissionsIntro: "Assigner des groupes à cet utilisateur modifiera les autorisations dont il dispose. Consultez la section «\_Groupes\_» pour plus de détails sur les autorisations associées à chaque groupe."
|
UserPermissionsIntro: "Assigner des groupes à cet utilisateur modifiera les autorisations dont il dispose. Consultez la section «\_Groupes\_» pour plus de détails sur les autorisations associées à chaque groupe."
|
||||||
SilverStripe\Security\PermissionCheckboxSetField:
|
SilverStripe\Security\PermissionCheckboxSetField:
|
||||||
AssignedTo: 'assignée au groupe « {title} »'
|
AssignedTo: 'assigné au groupe « {title} »'
|
||||||
FromGroup: "hérité du groupe «\_{title}\_»"
|
FromGroup: "hérite du groupe «\_{title}\_»"
|
||||||
FromRole: "héritée du rôle «\_{title}\_»"
|
FromRole: "hérite du rôle «\_{title}\_»"
|
||||||
FromRoleOnGroup: "hérité du rôle «\_{roletitle}\_» du groupe «\_{grouptitle}\_»"
|
FromRoleOnGroup: "hérite du rôle «\_{roletitle}\_» du groupe «\_{grouptitle}\_»"
|
||||||
SilverStripe\Security\PermissionRole:
|
SilverStripe\Security\PermissionRole:
|
||||||
OnlyAdminCanApply: 'Limité aux administrateurs'
|
OnlyAdminCanApply: 'Limité aux administrateurs'
|
||||||
PLURALNAME: Rôles
|
PLURALNAME: Rôles
|
||||||
|
PLURALS:
|
||||||
|
one: 'Un rôle'
|
||||||
|
other: '{count} rôles'
|
||||||
SINGULARNAME: Rôle
|
SINGULARNAME: Rôle
|
||||||
Title: Titre
|
Title: Titre
|
||||||
|
SilverStripe\Security\PermissionRoleCode:
|
||||||
|
PLURALNAME: 'Codes d''autorisations liés au rôle'
|
||||||
|
PLURALS:
|
||||||
|
one: 'Un code d''autorisation lié au rôle'
|
||||||
|
other: '{count} codes d''autorisation liés au rôle'
|
||||||
|
PermsError: 'Impossible d''attribuer le code "{code}" (requiert un accès en tant qu''administrateur)'
|
||||||
|
SINGULARNAME: 'Code d''autorisation lié au rôle'
|
||||||
|
SilverStripe\Security\RememberLoginHash:
|
||||||
|
PLURALNAME: 'Signatures de mot de passe'
|
||||||
|
PLURALS:
|
||||||
|
one: 'Une signature de mot de passe'
|
||||||
|
other: '{count} signatures de mot de passe'
|
||||||
|
SINGULARNAME: 'Signature de mot de passe'
|
||||||
SilverStripe\Security\Security:
|
SilverStripe\Security\Security:
|
||||||
ALREADYLOGGEDIN: 'Vous n''avez pas accès à cette page. Si vous avez un autre identifiant pouvant accéder à cette page, vous pouvez l''utiliser ci-dessous.'
|
ALREADYLOGGEDIN: 'Vous n''avez pas accès à cette page. Si un autre de vos identifiants vous permet d''accéder à cette page, merci de vous reconnecter ci-dessous en l''utilisant.'
|
||||||
BUTTONSEND: 'Envoyer moi le lien pour modifier le mot de passe'
|
BUTTONSEND: 'Envoyer moi le lien pour modifier le mot de passe'
|
||||||
CHANGEPASSWORDBELOW: 'Vous pouvez modifier votre mot de passe ci-dessous.'
|
CHANGEPASSWORDBELOW: 'Vous pouvez modifier votre mot de passe ci-dessous.'
|
||||||
CHANGEPASSWORDHEADER: 'Modifier votre mot de passe'
|
CHANGEPASSWORDHEADER: 'Modifier votre mot de passe'
|
||||||
|
CONFIRMLOGOUT: 'Merci de cliquer le bouton ci-dessous pour confirmer que vous souhaitez vous déconnecter.'
|
||||||
ENTERNEWPASSWORD: 'Entrer un nouveau mot de passe s''il vous plaît.'
|
ENTERNEWPASSWORD: 'Entrer un nouveau mot de passe s''il vous plaît.'
|
||||||
ERRORPASSWORDPERMISSION: 'Vous devez être connecté pour modifier votre mot de passe !'
|
ERRORPASSWORDPERMISSION: 'Vous devez être connecté pour modifier votre mot de passe !'
|
||||||
LOGIN: Connectez-vous
|
LOGIN: 'Se connecter'
|
||||||
|
LOGOUT: 'Se déconnecter'
|
||||||
LOSTPASSWORDHEADER: 'Mot de passe oublié'
|
LOSTPASSWORDHEADER: 'Mot de passe oublié'
|
||||||
NOTEPAGESECURED: 'Cette page est sécurisée. Entrer vos détails ci-dessous et nous vous enverrons directement.'
|
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>'
|
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: 'Entrer 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}\_»"
|
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."
|
PASSWORDSENTTEXT: "Merci\_! Un lien de réinitialisation vient d’être envoyé à «\_{email}\_», à condition que cette adresse existe."
|
||||||
|
35
lang/sk.yml
35
lang/sk.yml
@ -1,7 +1,31 @@
|
|||||||
sk:
|
sk:
|
||||||
|
SilverStripe\Admin\LeftAndMain:
|
||||||
|
VersionUnknown: neznáma
|
||||||
|
SilverStripe\AssetAdmin\Forms\UploadField:
|
||||||
|
Dimensions: Rozmery
|
||||||
|
EDIT: Editovať
|
||||||
|
EDITINFO: 'Editovať súbor'
|
||||||
|
REMOVE: Odstrániť
|
||||||
|
SilverStripe\Control\ChangePasswordEmail_ss:
|
||||||
|
CHANGEPASSWORDFOREMAIL: 'Heslo pre účet s e-mailovou adresou {email} bolo zmenené. Ak ste nemenili vaše heslo, tak ho zmeňte pomocou odkazu uvedeného nižšie, prosím.'
|
||||||
|
CHANGEPASSWORDTEXT1: 'Vaše heslo bolo zmenené pre'
|
||||||
|
CHANGEPASSWORDTEXT3: 'Zmeniť heslo'
|
||||||
|
HELLO: Ahoj
|
||||||
|
SilverStripe\Control\Email\ForgotPasswordEmail_ss:
|
||||||
|
HELLO: Ahoj
|
||||||
|
TEXT1: 'Tu je váš'
|
||||||
|
TEXT2: 'odkaz na resetovanie hesla'
|
||||||
|
TEXT3: pre
|
||||||
|
SilverStripe\Control\RequestProcessor:
|
||||||
|
INVALID_REQUEST: 'Neplatná požiadavka'
|
||||||
|
REQUEST_ABORTED: 'Požiadavka prerušená'
|
||||||
|
SilverStripe\Core\Manifest\VersionProvider:
|
||||||
|
VERSIONUNKNOWN: Neznáma
|
||||||
SilverStripe\Forms\CheckboxField:
|
SilverStripe\Forms\CheckboxField:
|
||||||
NOANSWER: Nie
|
NOANSWER: Nie
|
||||||
YESANSWER: Áno
|
YESANSWER: Áno
|
||||||
|
SilverStripe\Forms\CheckboxSetField_ss:
|
||||||
|
NOOPTIONSAVAILABLE: 'Žiadne dostupné možnosti'
|
||||||
SilverStripe\Forms\ConfirmedPasswordField:
|
SilverStripe\Forms\ConfirmedPasswordField:
|
||||||
ATLEAST: 'Heslá musia byť nejmenej {min} znakov dlhé.'
|
ATLEAST: 'Heslá musia byť nejmenej {min} znakov dlhé.'
|
||||||
BETWEEN: 'Heslá musia byť {min} až {max} znakov dlhé.'
|
BETWEEN: 'Heslá musia byť {min} až {max} znakov dlhé.'
|
||||||
@ -34,6 +58,8 @@ sk:
|
|||||||
VALIDCURRENCY: 'Prosím zadajte platnú menu'
|
VALIDCURRENCY: 'Prosím zadajte platnú menu'
|
||||||
SilverStripe\Forms\FormField:
|
SilverStripe\Forms\FormField:
|
||||||
NONE: žiadne
|
NONE: žiadne
|
||||||
|
SilverStripe\Forms\FormScaffolder:
|
||||||
|
TABMAIN: Hlavné
|
||||||
SilverStripe\Forms\GridField\GridField:
|
SilverStripe\Forms\GridField\GridField:
|
||||||
Add: 'Pridať {name}'
|
Add: 'Pridať {name}'
|
||||||
CSVEXPORT: 'Exportovať do CSV'
|
CSVEXPORT: 'Exportovať do CSV'
|
||||||
@ -66,6 +92,10 @@ sk:
|
|||||||
Save: Uložiť
|
Save: Uložiť
|
||||||
SilverStripe\Forms\GridField\GridFieldEditButton_ss:
|
SilverStripe\Forms\GridField\GridFieldEditButton_ss:
|
||||||
EDIT: Editovať
|
EDIT: Editovať
|
||||||
|
SilverStripe\Forms\GridField\GridFieldPaginator:
|
||||||
|
Page: Stránka
|
||||||
|
SilverStripe\Forms\GridField\GridFieldVersionedState:
|
||||||
|
ONLIVEONLYSHORT: 'Len publikované'
|
||||||
SilverStripe\Forms\MoneyField:
|
SilverStripe\Forms\MoneyField:
|
||||||
FIELDLABELAMOUNT: Množstvo
|
FIELDLABELAMOUNT: Množstvo
|
||||||
FIELDLABELCURRENCY: Mena
|
FIELDLABELCURRENCY: Mena
|
||||||
@ -104,6 +134,8 @@ sk:
|
|||||||
INVALIDUSER: '<p>Neplatný užívateľ. <a target="_top" href="{link}">Prosím overte sa znovu tu</a> pre pokračovanie.</p>'
|
INVALIDUSER: '<p>Neplatný užívateľ. <a target="_top" href="{link}">Prosím overte sa znovu tu</a> pre pokračovanie.</p>'
|
||||||
SUCCESS: Úspešné
|
SUCCESS: Úspešné
|
||||||
SUCCESSCONTENT: '<p>Úspešné prihlásenie. Ak nebudete automaticky presmerovaní <a target="_top" href="{link}">kliknite tu</a></p>'
|
SUCCESSCONTENT: '<p>Úspešné prihlásenie. Ak nebudete automaticky presmerovaní <a target="_top" href="{link}">kliknite tu</a></p>'
|
||||||
|
SilverStripe\Security\DefaultAdminService:
|
||||||
|
DefaultAdminFirstname: 'Predvolený administrátor'
|
||||||
SilverStripe\Security\Group:
|
SilverStripe\Security\Group:
|
||||||
AddRole: 'Pridať úlohu pre túto skupinu'
|
AddRole: 'Pridať úlohu pre túto skupinu'
|
||||||
Code: 'Kód skupiny'
|
Code: 'Kód skupiny'
|
||||||
@ -113,6 +145,7 @@ sk:
|
|||||||
GroupReminder: 'Ak vyberiete nadriadenú skupinu, bude táto skupina mať všetky úlohy'
|
GroupReminder: 'Ak vyberiete nadriadenú skupinu, bude táto skupina mať všetky úlohy'
|
||||||
HierarchyPermsError: 'Nie je možné pripojiť nadriadenú skupinu "{group}" s privilegovanými právami (vyžaduje ADMIN prístup)'
|
HierarchyPermsError: 'Nie je možné pripojiť nadriadenú skupinu "{group}" s privilegovanými právami (vyžaduje ADMIN prístup)'
|
||||||
Locked: 'Zamknuté?'
|
Locked: 'Zamknuté?'
|
||||||
|
MEMBERS: Členovia
|
||||||
NoRoles: 'Nenašli sa úlohy'
|
NoRoles: 'Nenašli sa úlohy'
|
||||||
PLURALNAME: Skupiny
|
PLURALNAME: Skupiny
|
||||||
Parent: 'Nadradená skupina'
|
Parent: 'Nadradená skupina'
|
||||||
@ -168,7 +201,7 @@ sk:
|
|||||||
SINGULARNAME: 'Heslo člena'
|
SINGULARNAME: 'Heslo člena'
|
||||||
SilverStripe\Security\PasswordValidator:
|
SilverStripe\Security\PasswordValidator:
|
||||||
LOWCHARSTRENGTH: 'Prosím posilnite heslo pridaním z týchto niektorých znakov: {chars}'
|
LOWCHARSTRENGTH: 'Prosím posilnite heslo pridaním z týchto niektorých znakov: {chars}'
|
||||||
PREVPASSWORD: 'Už ste použili toto heslo v minulosti, vyberte nové hoslo, prosím'
|
PREVPASSWORD: 'Už ste použili toto heslo v minulosti, vyberte nové heslo, prosím'
|
||||||
TOOSHORT: 'Heslo je príliš krátke, musí byť {minimum} alebo viacej znakov dlhé'
|
TOOSHORT: 'Heslo je príliš krátke, musí byť {minimum} alebo viacej znakov dlhé'
|
||||||
SilverStripe\Security\Permission:
|
SilverStripe\Security\Permission:
|
||||||
AdminGroup: Administrátor
|
AdminGroup: Administrátor
|
||||||
|
@ -260,7 +260,9 @@ class CSVParser implements Iterator
|
|||||||
array($this->enclosure, $this->delimiter),
|
array($this->enclosure, $this->delimiter),
|
||||||
$value
|
$value
|
||||||
);
|
);
|
||||||
|
// Trim leading tab
|
||||||
|
// [SS-2017-007] Ensure all cells with leading [@=+] have a leading tab
|
||||||
|
$value = ltrim($value, "\t");
|
||||||
if (array_key_exists($i, $this->headerRow)) {
|
if (array_key_exists($i, $this->headerRow)) {
|
||||||
if ($this->headerRow[$i]) {
|
if ($this->headerRow[$i]) {
|
||||||
$row[$this->headerRow[$i]] = $value;
|
$row[$this->headerRow[$i]] = $value;
|
||||||
|
@ -26,18 +26,23 @@ class InstallConfig
|
|||||||
*
|
*
|
||||||
* @param array $request Request object
|
* @param array $request Request object
|
||||||
* @param array $databaseClasses Supported database config
|
* @param array $databaseClasses Supported database config
|
||||||
|
* @param bool $realPassword Set to true to get the real password. If false, any non-posted
|
||||||
|
* password will be redacted as '********'. Note: Posted passwords are considered disclosed and
|
||||||
|
* never redacted.
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getDatabaseConfig($request, $databaseClasses)
|
public function getDatabaseConfig($request, $databaseClasses, $realPassword = true)
|
||||||
{
|
{
|
||||||
// Get config from request
|
// Get config from request
|
||||||
if (isset($request['db']['type'])) {
|
if (isset($request['db']['type'])) {
|
||||||
$type = $request['db']['type'];
|
$type = $request['db']['type'];
|
||||||
if (isset($request['db'][$type])) {
|
if (isset($request['db'][$type])) {
|
||||||
return array_merge(
|
$config = $request['db'][$type];
|
||||||
[ 'type' => $type ],
|
// The posted placeholder must be substituted with the real password
|
||||||
$request['db'][$type]
|
if (isset($config['password']) && $config['password'] === Installer::PASSWORD_PLACEHOLDER) {
|
||||||
);
|
$config['password'] = Environment::getEnv('SS_DATABASE_PASSWORD') ?: '';
|
||||||
|
}
|
||||||
|
return array_merge([ 'type' => $type ], $config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,8 +51,16 @@ class InstallConfig
|
|||||||
'type' => $this->getDatabaseClass($databaseClasses),
|
'type' => $this->getDatabaseClass($databaseClasses),
|
||||||
'server' => Environment::getEnv('SS_DATABASE_SERVER') ?: 'localhost',
|
'server' => Environment::getEnv('SS_DATABASE_SERVER') ?: 'localhost',
|
||||||
'username' => Environment::getEnv('SS_DATABASE_USERNAME') ?: 'root',
|
'username' => Environment::getEnv('SS_DATABASE_USERNAME') ?: 'root',
|
||||||
'password' => Environment::getEnv('SS_DATABASE_PASSWORD') ?: '',
|
'password' => $realPassword
|
||||||
|
? (Environment::getEnv('SS_DATABASE_PASSWORD') ?: '')
|
||||||
|
: Installer::PASSWORD_PLACEHOLDER, // Avoid password disclosure
|
||||||
'database' => Environment::getEnv('SS_DATABASE_NAME') ?: 'SS_mysite',
|
'database' => Environment::getEnv('SS_DATABASE_NAME') ?: 'SS_mysite',
|
||||||
|
'path' => Environment::getEnv('SS_DATABASE_PATH')
|
||||||
|
?: Environment::getEnv('SS_SQLITE_DATABASE_PATH') // sqlite compat
|
||||||
|
?: null,
|
||||||
|
'key' => Environment::getEnv('SS_DATABASE_KEY')
|
||||||
|
?: Environment::getEnv('SS_SQLITE_DATABASE_KEY') // sqlite compat
|
||||||
|
?: null,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,17 +68,26 @@ class InstallConfig
|
|||||||
* Get admin config from the environment
|
* Get admin config from the environment
|
||||||
*
|
*
|
||||||
* @param array $request
|
* @param array $request
|
||||||
|
* @param bool $realPassword Set to true to get the real password. If false, any non-posted
|
||||||
|
* password will be redacted as '********'. Note: Posted passwords are considered disclosed and
|
||||||
|
* never redacted.
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getAdminConfig($request)
|
public function getAdminConfig($request, $realPassword = true)
|
||||||
{
|
{
|
||||||
if (isset($request['admin'])) {
|
if (isset($request['admin'])) {
|
||||||
|
$config = $request['admin'];
|
||||||
|
if (isset($config['password']) && $config['password'] === Installer::PASSWORD_PLACEHOLDER) {
|
||||||
|
$config['password'] = Environment::getEnv('SS_DEFAULT_ADMIN_PASSWORD') ?: '';
|
||||||
|
}
|
||||||
return $request['admin'];
|
return $request['admin'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'username' => Environment::getEnv('SS_DEFAULT_ADMIN_USERNAME') ?: 'admin',
|
'username' => Environment::getEnv('SS_DEFAULT_ADMIN_USERNAME') ?: 'admin',
|
||||||
'password' => Environment::getEnv('SS_DEFAULT_ADMIN_PASSWORD') ?: '',
|
'password' => $realPassword
|
||||||
|
? (Environment::getEnv('SS_DEFAULT_ADMIN_PASSWORD') ?: '')
|
||||||
|
: Installer::PASSWORD_PLACEHOLDER, // Avoid password disclosure
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,11 @@ use SilverStripe\Security\Security;
|
|||||||
*/
|
*/
|
||||||
class Installer extends InstallRequirements
|
class Installer extends InstallRequirements
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* value='' attribute placeholder for password fields
|
||||||
|
*/
|
||||||
|
const PASSWORD_PLACEHOLDER = '********';
|
||||||
|
|
||||||
protected function installHeader()
|
protected function installHeader()
|
||||||
{
|
{
|
||||||
?>
|
?>
|
||||||
|
@ -123,13 +123,14 @@
|
|||||||
echo $checked ? '<div class="dbfields">' : '<div class="dbfields" style="display: none;">';
|
echo $checked ? '<div class="dbfields">' : '<div class="dbfields" style="display: none;">';
|
||||||
if(isset($details['fields'])) foreach($details['fields'] as $fieldName => $fieldSpec) {
|
if(isset($details['fields'])) foreach($details['fields'] as $fieldName => $fieldSpec) {
|
||||||
$fieldTitle = $fieldSpec['title'];
|
$fieldTitle = $fieldSpec['title'];
|
||||||
$fieldType = ($fieldName == 'password') ? 'password' : 'text';
|
$fieldType = ($fieldName === 'password') ? 'password' : 'text';
|
||||||
// values
|
// Get display value
|
||||||
$defaultValue = (isset($fieldSpec['default'])) ? $fieldSpec['default'] : null;
|
if (isset($databaseConfig[$fieldName]) && $databaseConfig['type'] == $class) {
|
||||||
if($usingEnv && isset($fieldSpec['envVar']) && $envVar = getenv($fieldSpec['envVar'])) {
|
$value = $databaseConfig[$fieldName];
|
||||||
$value = $envVar;
|
} elseif (isset($fieldSpec['default'])) {
|
||||||
|
$value = $fieldSpec['default'];
|
||||||
} else {
|
} else {
|
||||||
$value = (isset($databaseConfig[$fieldName]) && $databaseConfig['type'] == $class) ? $databaseConfig[$fieldName] : $defaultValue;
|
$value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// attributes
|
// attributes
|
||||||
|
@ -56,8 +56,8 @@ foreach ($databaseClasses as $class => $details) {
|
|||||||
|
|
||||||
// Build config from config / environment / request
|
// Build config from config / environment / request
|
||||||
$config = new InstallConfig();
|
$config = new InstallConfig();
|
||||||
$databaseConfig = $config->getDatabaseConfig($_REQUEST, $databaseClasses);
|
$databaseConfig = $config->getDatabaseConfig($_REQUEST, $databaseClasses, true);
|
||||||
$adminConfig = $config->getAdminConfig($_REQUEST);
|
$adminConfig = $config->getAdminConfig($_REQUEST, true);
|
||||||
$alreadyInstalled = $config->alreadyInstalled();
|
$alreadyInstalled = $config->alreadyInstalled();
|
||||||
$silverstripe_version = $config->getFrameworkVersion();
|
$silverstripe_version = $config->getFrameworkVersion();
|
||||||
$sendStats = $config->canSendStats($_REQUEST);
|
$sendStats = $config->canSendStats($_REQUEST);
|
||||||
@ -107,22 +107,6 @@ if ($installFromCli && ($req->hasErrors() || $dbReq->hasErrors())) {
|
|||||||
// Path to client resources (copied through silverstripe/vendor-plugin)
|
// Path to client resources (copied through silverstripe/vendor-plugin)
|
||||||
$clientPath = 'resources/silverstripe/framework/src/Dev/Install/client';
|
$clientPath = 'resources/silverstripe/framework/src/Dev/Install/client';
|
||||||
|
|
||||||
|
|
||||||
// config-form.html vars (placeholder to prevent deletion)
|
|
||||||
[
|
|
||||||
$theme,
|
|
||||||
$clientPath,
|
|
||||||
$adminConfig,
|
|
||||||
$usingEnv,
|
|
||||||
$silverstripe_version,
|
|
||||||
$locale,
|
|
||||||
$locales,
|
|
||||||
$webserverConfigFile,
|
|
||||||
$hasErrorOtherThanDatabase,
|
|
||||||
$hasOnlyWarnings, // If warnings but not errors
|
|
||||||
$phpIniLocation
|
|
||||||
];
|
|
||||||
|
|
||||||
// If already installed, ensure the user clicked "reinstall"
|
// If already installed, ensure the user clicked "reinstall"
|
||||||
$expectedArg = $alreadyInstalled ? 'reinstall' : 'go';
|
$expectedArg = $alreadyInstalled ? 'reinstall' : 'go';
|
||||||
if ((isset($_REQUEST[$expectedArg]) || $installFromCli)
|
if ((isset($_REQUEST[$expectedArg]) || $installFromCli)
|
||||||
@ -142,7 +126,27 @@ if ((isset($_REQUEST[$expectedArg]) || $installFromCli)
|
|||||||
'admin' => $adminConfig,
|
'admin' => $adminConfig,
|
||||||
'stats' => $sendStats,
|
'stats' => $sendStats,
|
||||||
]);
|
]);
|
||||||
// Show the config form
|
return;
|
||||||
} else {
|
|
||||||
include(__DIR__ . '/config-form.html');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanitise config prior to rendering config-form.html
|
||||||
|
$databaseConfig = $config->getDatabaseConfig($_REQUEST, $databaseClasses, false);
|
||||||
|
$adminConfig = $config->getAdminConfig($_REQUEST, false);
|
||||||
|
|
||||||
|
// config-form.html vars (placeholder to prevent deletion)
|
||||||
|
[
|
||||||
|
$theme,
|
||||||
|
$clientPath,
|
||||||
|
$adminConfig,
|
||||||
|
$databaseConfig,
|
||||||
|
$usingEnv,
|
||||||
|
$silverstripe_version,
|
||||||
|
$locale,
|
||||||
|
$locales,
|
||||||
|
$webserverConfigFile,
|
||||||
|
$hasErrorOtherThanDatabase,
|
||||||
|
$hasOnlyWarnings, // If warnings but not errors
|
||||||
|
$phpIniLocation,
|
||||||
|
];
|
||||||
|
|
||||||
|
include(__DIR__ . '/config-form.html');
|
||||||
|
@ -4,6 +4,7 @@ namespace SilverStripe\Forms\GridField;
|
|||||||
|
|
||||||
use SilverStripe\Control\HTTPRequest;
|
use SilverStripe\Control\HTTPRequest;
|
||||||
use SilverStripe\Control\HTTPResponse;
|
use SilverStripe\Control\HTTPResponse;
|
||||||
|
use SilverStripe\Core\Config\Config;
|
||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\ORM\DataObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,7 +12,6 @@ use SilverStripe\ORM\DataObject;
|
|||||||
*/
|
*/
|
||||||
class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler
|
class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array Map of a property name on the exported objects, with values being the column title in the CSV file.
|
* @var array Map of a property name on the exported objects, with values being the column title in the CSV file.
|
||||||
* Note that titles are only used when {@link $csvHasHeader} is set to TRUE.
|
* Note that titles are only used when {@link $csvHasHeader} is set to TRUE.
|
||||||
@ -38,6 +38,15 @@ class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionP
|
|||||||
*/
|
*/
|
||||||
protected $targetFragment;
|
protected $targetFragment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to true to disable XLS sanitisation
|
||||||
|
* [SS-2017-007] Ensure all cells with leading [@=+] have a leading tab
|
||||||
|
*
|
||||||
|
* @config
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private static $xls_export_disabled = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $targetFragment The HTML fragment to write the button into
|
* @param string $targetFragment The HTML fragment to write the button into
|
||||||
* @param array $exportColumns The columns to include in the export
|
* @param array $exportColumns The columns to include in the export
|
||||||
@ -170,7 +179,7 @@ class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionP
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Remove GridFieldPaginator as we're going to export the entire list.
|
//Remove GridFieldPaginator as we're going to export the entire list.
|
||||||
$gridField->getConfig()->removeComponentsByType('SilverStripe\\Forms\\GridField\\GridFieldPaginator');
|
$gridField->getConfig()->removeComponentsByType(GridFieldPaginator::class);
|
||||||
|
|
||||||
$items = $gridField->getManipulatedList();
|
$items = $gridField->getManipulatedList();
|
||||||
|
|
||||||
@ -203,6 +212,12 @@ class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [SS-2017-007] Sanitise XLS executable column values with a leading tab
|
||||||
|
if (!Config::inst()->get(get_class($this), 'xls_export_disabled')
|
||||||
|
&& preg_match('/^[-@=+].*/', $value)
|
||||||
|
) {
|
||||||
|
$value = "\t" . $value;
|
||||||
|
}
|
||||||
$columnData[] = $value;
|
$columnData[] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class TinyMCEConfig extends HTMLEditorConfig
|
|||||||
'cy_GB' => 'cy',
|
'cy_GB' => 'cy',
|
||||||
'da_DK' => 'da',
|
'da_DK' => 'da',
|
||||||
'da_GL' => 'da',
|
'da_GL' => 'da',
|
||||||
'de_AT' => 'de',
|
'de_AT' => 'de_AT',
|
||||||
'de_BE' => 'de',
|
'de_BE' => 'de',
|
||||||
'de_CH' => 'de',
|
'de_CH' => 'de',
|
||||||
'de_DE' => 'de',
|
'de_DE' => 'de',
|
||||||
@ -56,7 +56,7 @@ class TinyMCEConfig extends HTMLEditorConfig
|
|||||||
'es_GQ' => 'es',
|
'es_GQ' => 'es',
|
||||||
'es_GT' => 'es',
|
'es_GT' => 'es',
|
||||||
'es_HN' => 'es',
|
'es_HN' => 'es',
|
||||||
'es_MX' => 'es',
|
'es_MX' => 'es_MX',
|
||||||
'es_NI' => 'es',
|
'es_NI' => 'es',
|
||||||
'es_PA' => 'es',
|
'es_PA' => 'es',
|
||||||
'es_PE' => 'es',
|
'es_PE' => 'es',
|
||||||
@ -69,11 +69,9 @@ class TinyMCEConfig extends HTMLEditorConfig
|
|||||||
'es_AD' => 'es',
|
'es_AD' => 'es',
|
||||||
'es_BZ' => 'es',
|
'es_BZ' => 'es',
|
||||||
'es_US' => 'es',
|
'es_US' => 'es',
|
||||||
'fa_AF' => 'fa',
|
'fa_AF' => 'fa_IR',
|
||||||
'fa_IR' => 'fa',
|
'fa_IR' => 'fa_IR',
|
||||||
'fa_PK' => 'fa',
|
'fa_PK' => 'fa_IR',
|
||||||
'fi_FI' => 'fi',
|
|
||||||
'fi_SE' => 'fi',
|
|
||||||
'fr_BE' => 'fr_FR',
|
'fr_BE' => 'fr_FR',
|
||||||
'fr_BF' => 'fr_FR',
|
'fr_BF' => 'fr_FR',
|
||||||
'fr_BI' => 'fr_FR',
|
'fr_BI' => 'fr_FR',
|
||||||
@ -117,12 +115,11 @@ class TinyMCEConfig extends HTMLEditorConfig
|
|||||||
'fr_YT' => 'fr_FR',
|
'fr_YT' => 'fr_FR',
|
||||||
'fr_GB' => 'fr_FR',
|
'fr_GB' => 'fr_FR',
|
||||||
'fr_US' => 'fr_FR',
|
'fr_US' => 'fr_FR',
|
||||||
'he_IL' => 'he',
|
'he_IL' => 'he_IL',
|
||||||
'hu_HU' => 'hu',
|
'hu_HU' => 'hu_HU',
|
||||||
'hu_AT' => 'hu',
|
'hu_AT' => 'hu_HU',
|
||||||
'hu_RO' => 'hu',
|
'hu_RO' => 'hu_HU',
|
||||||
'hu_RS' => 'hu',
|
'hu_RS' => 'hu_HU',
|
||||||
'is_IS' => 'is',
|
|
||||||
'it_CH' => 'it',
|
'it_CH' => 'it',
|
||||||
'it_IT' => 'it',
|
'it_IT' => 'it',
|
||||||
'it_SM' => 'it',
|
'it_SM' => 'it',
|
||||||
@ -131,28 +128,26 @@ class TinyMCEConfig extends HTMLEditorConfig
|
|||||||
'it_US' => 'it',
|
'it_US' => 'it',
|
||||||
'it_VA' => 'it',
|
'it_VA' => 'it',
|
||||||
'ja_JP' => 'ja',
|
'ja_JP' => 'ja',
|
||||||
'ko_KP' => 'ko',
|
'ko_KP' => 'ko_KR',
|
||||||
'ko_KR' => 'ko',
|
'ko_KR' => 'ko_KR',
|
||||||
'ko_CN' => 'ko',
|
'ko_CN' => 'ko_KR',
|
||||||
'mi_NZ' => 'mi_NZ',
|
'nb_NO' => 'nb_NO',
|
||||||
'nb_NO' => 'nb',
|
'nb_SJ' => 'nb_NO',
|
||||||
'nb_SJ' => 'nb',
|
|
||||||
'nl_AN' => 'nl',
|
'nl_AN' => 'nl',
|
||||||
'nl_AW' => 'nl',
|
'nl_AW' => 'nl',
|
||||||
'nl_BE' => 'nl',
|
'nl_BE' => 'nl',
|
||||||
'nl_NL' => 'nl',
|
'nl_NL' => 'nl',
|
||||||
'nl_SR' => 'nl',
|
'nl_SR' => 'nl',
|
||||||
'nn_NO' => 'nn',
|
|
||||||
'pl_PL' => 'pl',
|
'pl_PL' => 'pl',
|
||||||
'pl_UA' => 'pl',
|
'pl_UA' => 'pl',
|
||||||
'pt_AO' => 'pt',
|
'pt_AO' => 'pt_PT',
|
||||||
'pt_BR' => 'pt',
|
'pt_BR' => 'pt_BR',
|
||||||
'pt_CV' => 'pt',
|
'pt_CV' => 'pt_PT',
|
||||||
'pt_GW' => 'pt',
|
'pt_GW' => 'pt_PT',
|
||||||
'pt_MZ' => 'pt',
|
'pt_MZ' => 'pt_PT',
|
||||||
'pt_PT' => 'pt',
|
'pt_PT' => 'pt_PT',
|
||||||
'pt_ST' => 'pt',
|
'pt_ST' => 'pt_PT',
|
||||||
'pt_TL' => 'pt',
|
'pt_TL' => 'pt_PT',
|
||||||
'ro_MD' => 'ro',
|
'ro_MD' => 'ro',
|
||||||
'ro_RO' => 'ro',
|
'ro_RO' => 'ro',
|
||||||
'ro_RS' => 'ro',
|
'ro_RS' => 'ro',
|
||||||
@ -162,31 +157,26 @@ class TinyMCEConfig extends HTMLEditorConfig
|
|||||||
'ru_RU' => 'ru',
|
'ru_RU' => 'ru',
|
||||||
'ru_SJ' => 'ru',
|
'ru_SJ' => 'ru',
|
||||||
'ru_UA' => 'ru',
|
'ru_UA' => 'ru',
|
||||||
'si_LK' => 'si',
|
|
||||||
'sk_SK' => 'sk',
|
'sk_SK' => 'sk',
|
||||||
'sk_RS' => 'sk',
|
'sk_RS' => 'sk',
|
||||||
'sq_AL' => 'sq',
|
'sv_FI' => 'sv_SE',
|
||||||
'sr_BA' => 'sr',
|
'sv_SE' => 'sv_SE',
|
||||||
'sr_ME' => 'sr',
|
|
||||||
'sr_RS' => 'sr',
|
|
||||||
'sv_FI' => 'sv',
|
|
||||||
'sv_SE' => 'sv',
|
|
||||||
'tr_CY' => 'tr',
|
'tr_CY' => 'tr',
|
||||||
'tr_TR' => 'tr',
|
'tr_TR' => 'tr_TR',
|
||||||
'tr_DE' => 'tr',
|
'tr_DE' => 'tr',
|
||||||
'tr_MK' => 'tr',
|
'tr_MK' => 'tr',
|
||||||
'uk_UA' => 'uk',
|
'uk_UA' => 'uk_UA',
|
||||||
'vi_VN' => 'vi',
|
'vi_VN' => 'vi_VN',
|
||||||
'vi_US' => 'vi',
|
'vi_US' => 'vi_VN',
|
||||||
'zh_CN' => 'zh-cn',
|
'zh_CN' => 'zh_CN',
|
||||||
'zh_HK' => 'zh-cn',
|
'zh_HK' => 'zh_CN',
|
||||||
'zh_MO' => 'zh-cn',
|
'zh_MO' => 'zh_CN',
|
||||||
'zh_SG' => 'zh-cn',
|
'zh_SG' => 'zh_CN',
|
||||||
'zh_TW' => 'zh-tw',
|
'zh_TW' => 'zh_TW',
|
||||||
'zh_ID' => 'zh-cn',
|
'zh_ID' => 'zh_CN',
|
||||||
'zh_MY' => 'zh-cn',
|
'zh_MY' => 'zh_CN',
|
||||||
'zh_TH' => 'zh-cn',
|
'zh_TH' => 'zh_CN',
|
||||||
'zh_US' => 'zn-cn',
|
'zh_US' => 'zh_CN',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace SilverStripe\ORM\Connect;
|
namespace SilverStripe\ORM\Connect;
|
||||||
|
|
||||||
|
use SilverStripe\Assets\File;
|
||||||
|
use SilverStripe\CMS\Model\SiteTree;
|
||||||
use SilverStripe\Core\Config\Configurable;
|
use SilverStripe\Core\Config\Configurable;
|
||||||
use SilverStripe\Core\Convert;
|
use SilverStripe\Core\Convert;
|
||||||
use SilverStripe\ORM\PaginatedList;
|
use SilverStripe\ORM\PaginatedList;
|
||||||
@ -144,7 +146,7 @@ class MySQLDatabase extends Database
|
|||||||
* @param bool $booleanSearch
|
* @param bool $booleanSearch
|
||||||
* @param string $alternativeFileFilter
|
* @param string $alternativeFileFilter
|
||||||
* @param bool $invertedMatch
|
* @param bool $invertedMatch
|
||||||
* @return \SilverStripe\ORM\PaginatedList
|
* @return PaginatedList
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function searchEngine(
|
public function searchEngine(
|
||||||
@ -158,10 +160,8 @@ class MySQLDatabase extends Database
|
|||||||
$alternativeFileFilter = "",
|
$alternativeFileFilter = "",
|
||||||
$invertedMatch = false
|
$invertedMatch = false
|
||||||
) {
|
) {
|
||||||
$pageClass = 'SilverStripe\\CMS\\Model\\SiteTree';
|
$pageClass = SiteTree::class;
|
||||||
$fileClass = 'SilverStripe\\Assets\\File';
|
$fileClass = File::class;
|
||||||
$pageTable = DataObject::getSchema()->tableName($pageClass);
|
|
||||||
$fileTable = DataObject::getSchema()->tableName($fileClass);
|
|
||||||
if (!class_exists($pageClass)) {
|
if (!class_exists($pageClass)) {
|
||||||
throw new Exception('MySQLDatabase->searchEngine() requires "SiteTree" class');
|
throw new Exception('MySQLDatabase->searchEngine() requires "SiteTree" class');
|
||||||
}
|
}
|
||||||
@ -194,12 +194,13 @@ class MySQLDatabase extends Database
|
|||||||
|
|
||||||
// File.ShowInSearch was added later, keep the database driver backwards compatible
|
// File.ShowInSearch was added later, keep the database driver backwards compatible
|
||||||
// by checking for its existence first
|
// by checking for its existence first
|
||||||
|
$fileTable = DataObject::getSchema()->tableName($fileClass);
|
||||||
$fields = $this->getSchemaManager()->fieldList($fileTable);
|
$fields = $this->getSchemaManager()->fieldList($fileTable);
|
||||||
if (array_key_exists('ShowInSearch', $fields)) {
|
if (array_key_exists('ShowInSearch', $fields)) {
|
||||||
$extraFilters[$fileClass] .= " AND ShowInSearch <> 0";
|
$extraFilters[$fileClass] .= " AND ShowInSearch <> 0";
|
||||||
}
|
}
|
||||||
|
|
||||||
$limit = $start . ", " . (int) $pageLength;
|
$limit = (int)$start . ", " . (int)$pageLength;
|
||||||
|
|
||||||
$notMatch = $invertedMatch
|
$notMatch = $invertedMatch
|
||||||
? "NOT "
|
? "NOT "
|
||||||
@ -257,7 +258,6 @@ class MySQLDatabase extends Database
|
|||||||
$queryParameters = array();
|
$queryParameters = array();
|
||||||
$totalCount = 0;
|
$totalCount = 0;
|
||||||
foreach ($lists as $class => $list) {
|
foreach ($lists as $class => $list) {
|
||||||
$table = DataObject::getSchema()->tableName($class);
|
|
||||||
/** @var SQLSelect $query */
|
/** @var SQLSelect $query */
|
||||||
$query = $list->dataQuery()->query();
|
$query = $list->dataQuery()->query();
|
||||||
|
|
||||||
|
@ -2,35 +2,36 @@
|
|||||||
|
|
||||||
namespace SilverStripe\ORM;
|
namespace SilverStripe\ORM;
|
||||||
|
|
||||||
|
use BadMethodCallException;
|
||||||
|
use Exception;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use LogicException;
|
||||||
|
use SilverStripe\Control\HTTP;
|
||||||
use SilverStripe\Core\ClassInfo;
|
use SilverStripe\Core\ClassInfo;
|
||||||
use SilverStripe\Core\Config\Config;
|
use SilverStripe\Core\Config\Config;
|
||||||
use SilverStripe\Core\Injector\Injector;
|
use SilverStripe\Core\Injector\Injector;
|
||||||
use SilverStripe\Core\Resettable;
|
use SilverStripe\Core\Resettable;
|
||||||
use SilverStripe\Dev\Deprecation;
|
|
||||||
use SilverStripe\Dev\Debug;
|
use SilverStripe\Dev\Debug;
|
||||||
use SilverStripe\Control\HTTP;
|
use SilverStripe\Dev\Deprecation;
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
use SilverStripe\Forms\FormField;
|
use SilverStripe\Forms\FormField;
|
||||||
use SilverStripe\Forms\FormScaffolder;
|
use SilverStripe\Forms\FormScaffolder;
|
||||||
use SilverStripe\i18n\i18n;
|
use SilverStripe\i18n\i18n;
|
||||||
use SilverStripe\i18n\i18nEntityProvider;
|
use SilverStripe\i18n\i18nEntityProvider;
|
||||||
use SilverStripe\ORM\Connect\MySQLSchemaManager;
|
use SilverStripe\ORM\Connect\MySQLSchemaManager;
|
||||||
use SilverStripe\ORM\Filters\SearchFilter;
|
|
||||||
use SilverStripe\ORM\Search\SearchContext;
|
|
||||||
use SilverStripe\ORM\Queries\SQLInsert;
|
|
||||||
use SilverStripe\ORM\Queries\SQLDelete;
|
|
||||||
use SilverStripe\ORM\FieldType\DBField;
|
|
||||||
use SilverStripe\ORM\FieldType\DBDatetime;
|
|
||||||
use SilverStripe\ORM\FieldType\DBComposite;
|
|
||||||
use SilverStripe\ORM\FieldType\DBClassName;
|
use SilverStripe\ORM\FieldType\DBClassName;
|
||||||
|
use SilverStripe\ORM\FieldType\DBComposite;
|
||||||
|
use SilverStripe\ORM\FieldType\DBDatetime;
|
||||||
|
use SilverStripe\ORM\FieldType\DBField;
|
||||||
|
use SilverStripe\ORM\Filters\SearchFilter;
|
||||||
|
use SilverStripe\ORM\Queries\SQLDelete;
|
||||||
|
use SilverStripe\ORM\Queries\SQLInsert;
|
||||||
|
use SilverStripe\ORM\Search\SearchContext;
|
||||||
use SilverStripe\Security\Member;
|
use SilverStripe\Security\Member;
|
||||||
use SilverStripe\Security\Permission;
|
use SilverStripe\Security\Permission;
|
||||||
use SilverStripe\Security\Security;
|
use SilverStripe\Security\Security;
|
||||||
|
use SilverStripe\View\SSViewer;
|
||||||
use SilverStripe\View\ViewableData;
|
use SilverStripe\View\ViewableData;
|
||||||
use LogicException;
|
|
||||||
use InvalidArgumentException;
|
|
||||||
use BadMethodCallException;
|
|
||||||
use Exception;
|
|
||||||
use stdClass;
|
use stdClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2154,6 +2155,11 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
return $untabbedFields;
|
return $untabbedFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getViewerTemplates($suffix = '')
|
||||||
|
{
|
||||||
|
return SSViewer::get_templates_by_class(static::class, $suffix, $this->baseClass());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the value of a field.
|
* Gets the value of a field.
|
||||||
* Called by {@link __get()} and any getFieldName() methods you might create.
|
* Called by {@link __get()} and any getFieldName() methods you might create.
|
||||||
|
@ -138,11 +138,11 @@ class DataObjectSchema
|
|||||||
*/
|
*/
|
||||||
public function baseDataClass($class)
|
public function baseDataClass($class)
|
||||||
{
|
{
|
||||||
$class = ClassInfo::class_name($class);
|
|
||||||
$current = $class;
|
$current = $class;
|
||||||
while ($next = get_parent_class($current)) {
|
while ($next = get_parent_class($current)) {
|
||||||
if ($next === DataObject::class) {
|
if ($next === DataObject::class) {
|
||||||
return $current;
|
// Only use ClassInfo::class_name() to format the class if we've not used get_parent_class()
|
||||||
|
return ($current === $class) ? ClassInfo::class_name($current) : $current;
|
||||||
}
|
}
|
||||||
$current = $next;
|
$current = $next;
|
||||||
}
|
}
|
||||||
@ -201,6 +201,11 @@ class DataObjectSchema
|
|||||||
$db = [];
|
$db = [];
|
||||||
$classes = $uninherited ? [$class] : ClassInfo::ancestry($class);
|
$classes = $uninherited ? [$class] : ClassInfo::ancestry($class);
|
||||||
foreach ($classes as $tableClass) {
|
foreach ($classes as $tableClass) {
|
||||||
|
// Skip irrelevant parent classes
|
||||||
|
if (!is_subclass_of($tableClass, DataObject::class)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Find all fields on this class
|
// Find all fields on this class
|
||||||
$fields = $this->databaseFields($tableClass, false);
|
$fields = $this->databaseFields($tableClass, false);
|
||||||
// Merge with composite fields
|
// Merge with composite fields
|
||||||
@ -394,6 +399,10 @@ class DataObjectSchema
|
|||||||
*/
|
*/
|
||||||
public function classHasTable($class)
|
public function classHasTable($class)
|
||||||
{
|
{
|
||||||
|
if (!is_subclass_of($class, DataObject::class)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$fields = $this->databaseFields($class, false);
|
$fields = $this->databaseFields($class, false);
|
||||||
return !empty($fields);
|
return !empty($fields);
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ class PaginatedList extends ListDecorator
|
|||||||
*/
|
*/
|
||||||
public function setPageLength($length)
|
public function setPageLength($length)
|
||||||
{
|
{
|
||||||
$this->pageLength = $length;
|
$this->pageLength = (int)$length;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ class PaginatedList extends ListDecorator
|
|||||||
*/
|
*/
|
||||||
public function setCurrentPage($page)
|
public function setCurrentPage($page)
|
||||||
{
|
{
|
||||||
$this->pageStart = ($page - 1) * $this->getPageLength();
|
$this->pageStart = ((int)$page - 1) * $this->getPageLength();
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ class PaginatedList extends ListDecorator
|
|||||||
*/
|
*/
|
||||||
public function setPageStart($start)
|
public function setPageStart($start)
|
||||||
{
|
{
|
||||||
$this->pageStart = $start;
|
$this->pageStart = (int)$start;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ class PaginatedList extends ListDecorator
|
|||||||
*/
|
*/
|
||||||
public function setTotalItems($items)
|
public function setTotalItems($items)
|
||||||
{
|
{
|
||||||
$this->totalItems = $items;
|
$this->totalItems = (int)$items;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace SilverStripe\Security;
|
namespace SilverStripe\Security;
|
||||||
|
|
||||||
|
use SilverStripe\ORM\DataList;
|
||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\ORM\DataObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -14,11 +15,11 @@ use SilverStripe\ORM\DataObject;
|
|||||||
* complies with your privacy standards. We're logging
|
* complies with your privacy standards. We're logging
|
||||||
* username and IP.
|
* username and IP.
|
||||||
*
|
*
|
||||||
* @property string Email Email address used for login attempt
|
* @property string $Email Email address used for login attempt. @deprecated 3.0...5.0
|
||||||
* @property string Status Status of the login attempt, either 'Success' or 'Failure'
|
* @property string $EmailHashed sha1 hashed Email address used for login attempt
|
||||||
* @property string IP IP address of user attempting to login
|
* @property string $Status Status of the login attempt, either 'Success' or 'Failure'
|
||||||
*
|
* @property string $IP IP address of user attempting to login
|
||||||
* @property int MemberID ID of the Member, only if Member with Email exists
|
* @property int $MemberID ID of the Member, only if Member with Email exists
|
||||||
*
|
*
|
||||||
* @method Member Member() Member object of the user trying to log in, only if Member with Email exists
|
* @method Member Member() Member object of the user trying to log in, only if Member with Email exists
|
||||||
*/
|
*/
|
||||||
@ -35,7 +36,8 @@ class LoginAttempt extends DataObject
|
|||||||
const FAILURE = 'Failure';
|
const FAILURE = 'Failure';
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'Email' => 'Varchar(255)',
|
'Email' => 'Varchar(255)', // Remove in 5.0
|
||||||
|
'EmailHashed' => 'Varchar(255)',
|
||||||
'Status' => "Enum('Success,Failure')",
|
'Status' => "Enum('Success,Failure')",
|
||||||
'IP' => 'Varchar(255)',
|
'IP' => 'Varchar(255)',
|
||||||
);
|
);
|
||||||
@ -55,9 +57,37 @@ class LoginAttempt extends DataObject
|
|||||||
{
|
{
|
||||||
$labels = parent::fieldLabels($includerelations);
|
$labels = parent::fieldLabels($includerelations);
|
||||||
$labels['Email'] = _t(__CLASS__.'.Email', 'Email Address');
|
$labels['Email'] = _t(__CLASS__.'.Email', 'Email Address');
|
||||||
|
$labels['EmailHashed'] = _t(__CLASS__.'.EmailHashed', 'Email Address (hashed)');
|
||||||
$labels['Status'] = _t(__CLASS__.'.Status', 'Status');
|
$labels['Status'] = _t(__CLASS__.'.Status', 'Status');
|
||||||
$labels['IP'] = _t(__CLASS__.'.IP', 'IP Address');
|
$labels['IP'] = _t(__CLASS__.'.IP', 'IP Address');
|
||||||
|
|
||||||
return $labels;
|
return $labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set email used for this attempt
|
||||||
|
*
|
||||||
|
* @param string $email
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setEmail($email)
|
||||||
|
{
|
||||||
|
// Store hashed email only
|
||||||
|
$this->EmailHashed = sha1($email);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all login attempts for the given email address
|
||||||
|
*
|
||||||
|
* @param string $email
|
||||||
|
* @return DataList|LoginAttempt[]
|
||||||
|
*/
|
||||||
|
public static function getByEmail($email)
|
||||||
|
{
|
||||||
|
return static::get()->filterAny(array(
|
||||||
|
'Email' => $email,
|
||||||
|
'EmailHashed' => sha1($email),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -384,8 +384,7 @@ class Member extends DataObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
$idField = static::config()->get('unique_identifier_field');
|
$idField = static::config()->get('unique_identifier_field');
|
||||||
$attempts = LoginAttempt::get()
|
$attempts = LoginAttempt::getByEmail($this->{$idField})
|
||||||
->filter('Email', $this->{$idField})
|
|
||||||
->sort('Created', 'DESC')
|
->sort('Created', 'DESC')
|
||||||
->limit($maxAttempts);
|
->limit($maxAttempts);
|
||||||
|
|
||||||
|
@ -2,25 +2,26 @@
|
|||||||
|
|
||||||
namespace SilverStripe\View;
|
namespace SilverStripe\View;
|
||||||
|
|
||||||
|
use ArrayIterator;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use IteratorAggregate;
|
||||||
|
use LogicException;
|
||||||
|
use SilverStripe\Core\ClassInfo;
|
||||||
use SilverStripe\Core\Config\Config;
|
use SilverStripe\Core\Config\Config;
|
||||||
use SilverStripe\Core\Config\Configurable;
|
use SilverStripe\Core\Config\Configurable;
|
||||||
|
use SilverStripe\Core\Convert;
|
||||||
use SilverStripe\Core\Extensible;
|
use SilverStripe\Core\Extensible;
|
||||||
use SilverStripe\Core\Injector\Injectable;
|
use SilverStripe\Core\Injector\Injectable;
|
||||||
|
use SilverStripe\Core\Injector\Injector;
|
||||||
use SilverStripe\Core\Manifest\ModuleResourceLoader;
|
use SilverStripe\Core\Manifest\ModuleResourceLoader;
|
||||||
|
use SilverStripe\Dev\Debug;
|
||||||
use SilverStripe\Dev\Deprecation;
|
use SilverStripe\Dev\Deprecation;
|
||||||
use SilverStripe\ORM\ArrayLib;
|
use SilverStripe\ORM\ArrayLib;
|
||||||
use SilverStripe\ORM\FieldType\DBField;
|
use SilverStripe\ORM\FieldType\DBField;
|
||||||
use SilverStripe\ORM\FieldType\DBHTMLText;
|
use SilverStripe\ORM\FieldType\DBHTMLText;
|
||||||
use SilverStripe\Core\ClassInfo;
|
use SilverStripe\View\SSViewer;
|
||||||
use SilverStripe\Core\Convert;
|
|
||||||
use SilverStripe\Core\Injector\Injector;
|
|
||||||
use SilverStripe\Dev\Debug;
|
|
||||||
use IteratorAggregate;
|
|
||||||
use LogicException;
|
|
||||||
use InvalidArgumentException;
|
|
||||||
use UnexpectedValueException;
|
use UnexpectedValueException;
|
||||||
use ArrayIterator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A ViewableData object is any object that can be rendered into a template/view.
|
* A ViewableData object is any object that can be rendered into a template/view.
|
||||||
@ -578,6 +579,17 @@ class ViewableData implements IteratorAggregate
|
|||||||
|
|
||||||
// UTILITY METHODS -------------------------------------------------------------------------------------------------
|
// UTILITY METHODS -------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find appropriate templates for SSViewer to use to render this object
|
||||||
|
*
|
||||||
|
* @param string $suffix
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getViewerTemplates($suffix = '')
|
||||||
|
{
|
||||||
|
return SSViewer::get_templates_by_class(static::class, $suffix, self::class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When rendering some objects it is necessary to iterate over the object being rendered, to do this, you need
|
* When rendering some objects it is necessary to iterate over the object being rendered, to do this, you need
|
||||||
* access to itself.
|
* access to itself.
|
||||||
|
@ -29,31 +29,44 @@ class CSVParserTest extends SapphireTest
|
|||||||
$firstNames = $birthdays = $biographies = $registered = array();
|
$firstNames = $birthdays = $biographies = $registered = array();
|
||||||
foreach ($csv as $record) {
|
foreach ($csv as $record) {
|
||||||
/* Each row in the CSV file will be keyed with the header row */
|
/* Each row in the CSV file will be keyed with the header row */
|
||||||
$this->assertEquals(array('FirstName','Biography','Birthday','IsRegistered'), array_keys($record));
|
$this->assertEquals(
|
||||||
|
['FirstName','Biography','Birthday','IsRegistered'],
|
||||||
|
array_keys($record)
|
||||||
|
);
|
||||||
$firstNames[] = $record['FirstName'];
|
$firstNames[] = $record['FirstName'];
|
||||||
$biographies[] = $record['Biography'];
|
$biographies[] = $record['Biography'];
|
||||||
$birthdays[] = $record['Birthday'];
|
$birthdays[] = $record['Birthday'];
|
||||||
$registered[] = $record['IsRegistered'];
|
$registered[] = $record['IsRegistered'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assertEquals(array('John','Jane','Jamie','Järg'), $firstNames);
|
$this->assertEquals(
|
||||||
|
['John','Jane','Jamie','Järg','Jacob'],
|
||||||
|
$firstNames
|
||||||
|
);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
array(
|
[
|
||||||
"He's a good guy",
|
"He's a good guy",
|
||||||
"She is awesome." . PHP_EOL
|
"She is awesome."
|
||||||
|
. PHP_EOL
|
||||||
. "So awesome that she gets multiple rows and \"escaped\" strings in her biography",
|
. "So awesome that she gets multiple rows and \"escaped\" strings in her biography",
|
||||||
"Pretty old, with an escaped comma",
|
"Pretty old, with an escaped comma",
|
||||||
"Unicode FTW"),
|
"Unicode FTW",
|
||||||
|
"Likes leading tabs in his biography",
|
||||||
|
],
|
||||||
$biographies
|
$biographies
|
||||||
);
|
);
|
||||||
$this->assertEquals([
|
$this->assertEquals([
|
||||||
"1988-01-31",
|
"1988-01-31",
|
||||||
"1982-01-31",
|
"1982-01-31",
|
||||||
"1882-01-31",
|
"1882-01-31",
|
||||||
"1982-06-30"
|
"1982-06-30",
|
||||||
|
"2000-04-30",
|
||||||
], $birthdays);
|
], $birthdays);
|
||||||
$this->assertEquals(array('1', '0', '1', '1'), $registered);
|
$this->assertEquals(
|
||||||
|
['1', '0', '1', '1', '0'],
|
||||||
|
$registered
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testParsingWithHeadersAndColumnMap()
|
public function testParsingWithHeadersAndColumnMap()
|
||||||
@ -62,41 +75,43 @@ class CSVParserTest extends SapphireTest
|
|||||||
$csv = new CSVParser($this->csvPath . 'PlayersWithHeader.csv');
|
$csv = new CSVParser($this->csvPath . 'PlayersWithHeader.csv');
|
||||||
|
|
||||||
/* We can set up column remapping. The keys are case-insensitive. */
|
/* We can set up column remapping. The keys are case-insensitive. */
|
||||||
$csv->mapColumns(
|
$csv->mapColumns([
|
||||||
array(
|
|
||||||
'FirstName' => '__fn',
|
'FirstName' => '__fn',
|
||||||
'bIoGrApHy' => '__BG',
|
'bIoGrApHy' => '__BG',
|
||||||
)
|
]);
|
||||||
);
|
|
||||||
|
|
||||||
$firstNames = $birthdays = $biographies = $registered = array();
|
$firstNames = $birthdays = $biographies = $registered = array();
|
||||||
foreach ($csv as $record) {
|
foreach ($csv as $record) {
|
||||||
/* Each row in the CSV file will be keyed with the renamed columns. Any unmapped column names will be
|
/* Each row in the CSV file will be keyed with the renamed columns. Any unmapped column names will be
|
||||||
* left as-is. */
|
* left as-is. */
|
||||||
$this->assertEquals(array('__fn','__BG','Birthday','IsRegistered'), array_keys($record));
|
$this->assertEquals(['__fn','__BG','Birthday','IsRegistered'], array_keys($record));
|
||||||
$firstNames[] = $record['__fn'];
|
$firstNames[] = $record['__fn'];
|
||||||
$biographies[] = $record['__BG'];
|
$biographies[] = $record['__BG'];
|
||||||
$birthdays[] = $record['Birthday'];
|
$birthdays[] = $record['Birthday'];
|
||||||
$registered[] = $record['IsRegistered'];
|
$registered[] = $record['IsRegistered'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assertEquals(array('John','Jane','Jamie','Järg'), $firstNames);
|
$this->assertEquals(['John','Jane','Jamie','Järg','Jacob'], $firstNames);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
array(
|
[
|
||||||
"He's a good guy",
|
"He's a good guy",
|
||||||
"She is awesome."
|
"She is awesome."
|
||||||
. PHP_EOL . "So awesome that she gets multiple rows and \"escaped\" strings in her biography",
|
. PHP_EOL
|
||||||
|
. "So awesome that she gets multiple rows and \"escaped\" strings in her biography",
|
||||||
"Pretty old, with an escaped comma",
|
"Pretty old, with an escaped comma",
|
||||||
"Unicode FTW"),
|
"Unicode FTW",
|
||||||
|
"Likes leading tabs in his biography",
|
||||||
|
],
|
||||||
$biographies
|
$biographies
|
||||||
);
|
);
|
||||||
$this->assertEquals([
|
$this->assertEquals([
|
||||||
"1988-01-31",
|
"1988-01-31",
|
||||||
"1982-01-31",
|
"1982-01-31",
|
||||||
"1882-01-31",
|
"1882-01-31",
|
||||||
"1982-06-30"
|
"1982-06-30",
|
||||||
|
"2000-04-30",
|
||||||
], $birthdays);
|
], $birthdays);
|
||||||
$this->assertEquals(array('1', '0', '1', '1'), $registered);
|
$this->assertEquals(array('1', '0', '1', '1', '0'), $registered);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testParsingWithExplicitHeaderRow()
|
public function testParsingWithExplicitHeaderRow()
|
||||||
@ -117,15 +132,18 @@ class CSVParserTest extends SapphireTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* And the first row will be returned in the data */
|
/* And the first row will be returned in the data */
|
||||||
$this->assertEquals(array('FirstName','John','Jane','Jamie','Järg'), $firstNames);
|
$this->assertEquals(['FirstName','John','Jane','Jamie','Järg','Jacob'], $firstNames);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
array(
|
[
|
||||||
'Biography',
|
'Biography',
|
||||||
"He's a good guy",
|
"He's a good guy",
|
||||||
"She is awesome." . PHP_EOL
|
"She is awesome."
|
||||||
|
. PHP_EOL
|
||||||
. "So awesome that she gets multiple rows and \"escaped\" strings in her biography",
|
. "So awesome that she gets multiple rows and \"escaped\" strings in her biography",
|
||||||
"Pretty old, with an escaped comma",
|
"Pretty old, with an escaped comma",
|
||||||
"Unicode FTW"),
|
"Unicode FTW",
|
||||||
|
"Likes leading tabs in his biography"
|
||||||
|
],
|
||||||
$biographies
|
$biographies
|
||||||
);
|
);
|
||||||
$this->assertEquals([
|
$this->assertEquals([
|
||||||
@ -133,8 +151,9 @@ class CSVParserTest extends SapphireTest
|
|||||||
"1988-01-31",
|
"1988-01-31",
|
||||||
"1982-01-31",
|
"1982-01-31",
|
||||||
"1882-01-31",
|
"1882-01-31",
|
||||||
"1982-06-30"
|
"1982-06-30",
|
||||||
|
"2000-04-30",
|
||||||
], $birthdays);
|
], $birthdays);
|
||||||
$this->assertEquals(array('IsRegistered', '1', '0', '1', '1'), $registered);
|
$this->assertEquals(['IsRegistered', '1', '0', '1', '1', '0'], $registered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ class CsvBulkLoaderTest extends SapphireTest
|
|||||||
$results = $loader->load($filepath);
|
$results = $loader->load($filepath);
|
||||||
|
|
||||||
// Test that right amount of columns was imported
|
// Test that right amount of columns was imported
|
||||||
$this->assertEquals(4, $results->Count(), 'Test correct count of imported data');
|
$this->assertEquals(5, $results->Count(), 'Test correct count of imported data');
|
||||||
|
|
||||||
// Test that columns were correctly imported
|
// Test that columns were correctly imported
|
||||||
$obj = DataObject::get_one(
|
$obj = DataObject::get_one(
|
||||||
@ -76,7 +76,7 @@ class CsvBulkLoaderTest extends SapphireTest
|
|||||||
$filepath = $this->csvPath . 'PlayersWithHeader.csv';
|
$filepath = $this->csvPath . 'PlayersWithHeader.csv';
|
||||||
$loader->deleteExistingRecords = true;
|
$loader->deleteExistingRecords = true;
|
||||||
$results1 = $loader->load($filepath);
|
$results1 = $loader->load($filepath);
|
||||||
$this->assertEquals(4, $results1->Count(), 'Test correct count of imported data on first load');
|
$this->assertEquals(5, $results1->Count(), 'Test correct count of imported data on first load');
|
||||||
|
|
||||||
//delete existing data before doing second CSV import
|
//delete existing data before doing second CSV import
|
||||||
$results2 = $loader->load($filepath);
|
$results2 = $loader->load($filepath);
|
||||||
@ -84,7 +84,7 @@ class CsvBulkLoaderTest extends SapphireTest
|
|||||||
$resultDataObject = DataObject::get(Player::class);
|
$resultDataObject = DataObject::get(Player::class);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
4,
|
5,
|
||||||
$resultDataObject->count(),
|
$resultDataObject->count(),
|
||||||
'Test if existing data is deleted before new data is added'
|
'Test if existing data is deleted before new data is added'
|
||||||
);
|
);
|
||||||
|
@ -4,3 +4,4 @@
|
|||||||
So awesome that she gets multiple rows and \"escaped\" strings in her biography","1982-01-31","0"
|
So awesome that she gets multiple rows and \"escaped\" strings in her biography","1982-01-31","0"
|
||||||
"Jamie","Pretty old\, with an escaped comma","1882-01-31","1"
|
"Jamie","Pretty old\, with an escaped comma","1882-01-31","1"
|
||||||
"Järg","Unicode FTW","1982-06-30","1"
|
"Järg","Unicode FTW","1982-06-30","1"
|
||||||
|
"Jacob"," Likes leading tabs in his biography","2000-04-30","0"
|
||||||
|
Can't render this file because it contains an unexpected character in line 4 and column 45.
|
@ -12,22 +12,27 @@ use SilverStripe\Forms\GridField\GridFieldConfig;
|
|||||||
use SilverStripe\Forms\GridField\GridFieldExportButton;
|
use SilverStripe\Forms\GridField\GridFieldExportButton;
|
||||||
use SilverStripe\Forms\GridField\GridField;
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
use SilverStripe\Forms\GridField\GridFieldPaginator;
|
use SilverStripe\Forms\GridField\GridFieldPaginator;
|
||||||
|
use SilverStripe\ORM\FieldType\DBField;
|
||||||
|
|
||||||
class GridFieldExportButtonTest extends SapphireTest
|
class GridFieldExportButtonTest extends SapphireTest
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var DataList
|
||||||
|
*/
|
||||||
protected $list;
|
protected $list;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var GridField
|
||||||
|
*/
|
||||||
protected $gridField;
|
protected $gridField;
|
||||||
|
|
||||||
protected $form;
|
|
||||||
|
|
||||||
protected static $fixture_file = 'GridFieldExportButtonTest.yml';
|
protected static $fixture_file = 'GridFieldExportButtonTest.yml';
|
||||||
|
|
||||||
protected static $extra_dataobjects = array(
|
protected static $extra_dataobjects = [
|
||||||
Team::class,
|
Team::class,
|
||||||
NoView::class,
|
NoView::class,
|
||||||
);
|
];
|
||||||
|
|
||||||
protected function setUp()
|
protected function setUp()
|
||||||
{
|
{
|
||||||
@ -44,7 +49,7 @@ class GridFieldExportButtonTest extends SapphireTest
|
|||||||
$list = new DataList(NoView::class);
|
$list = new DataList(NoView::class);
|
||||||
|
|
||||||
$button = new GridFieldExportButton();
|
$button = new GridFieldExportButton();
|
||||||
$button->setExportColumns(array('Name' => 'My Name'));
|
$button->setExportColumns(['Name' => 'My Name']);
|
||||||
|
|
||||||
$config = GridFieldConfig::create()->addComponent(new GridFieldExportButton());
|
$config = GridFieldConfig::create()->addComponent(new GridFieldExportButton());
|
||||||
$gridField = new GridField('testfield', 'testfield', $list, $config);
|
$gridField = new GridField('testfield', 'testfield', $list, $config);
|
||||||
@ -58,7 +63,7 @@ class GridFieldExportButtonTest extends SapphireTest
|
|||||||
public function testGenerateFileDataBasicFields()
|
public function testGenerateFileDataBasicFields()
|
||||||
{
|
{
|
||||||
$button = new GridFieldExportButton();
|
$button = new GridFieldExportButton();
|
||||||
$button->setExportColumns(array('Name' => 'My Name'));
|
$button->setExportColumns(['Name' => 'My Name']);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
'"My Name"'."\n".
|
'"My Name"'."\n".
|
||||||
@ -68,17 +73,32 @@ class GridFieldExportButtonTest extends SapphireTest
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testXLSSanitisation()
|
||||||
|
{
|
||||||
|
// Create risky object
|
||||||
|
$object = new Team();
|
||||||
|
$object->Name = '=SUM(1, 2)';
|
||||||
|
$object->write();
|
||||||
|
|
||||||
|
// Export
|
||||||
|
$button = new GridFieldExportButton();
|
||||||
|
$button->setExportColumns(['Name' => 'My Name']);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
"\"My Name\"\n\"\t=SUM(1, 2)\"\nTest\nTest2\n",
|
||||||
|
$button->generateExportFileData($this->gridField)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testGenerateFileDataAnonymousFunctionField()
|
public function testGenerateFileDataAnonymousFunctionField()
|
||||||
{
|
{
|
||||||
$button = new GridFieldExportButton();
|
$button = new GridFieldExportButton();
|
||||||
$button->setExportColumns(
|
$button->setExportColumns([
|
||||||
array(
|
|
||||||
'Name' => 'Name',
|
'Name' => 'Name',
|
||||||
'City' => function ($obj) {
|
'City' => function (DBField $obj) {
|
||||||
return $obj->getValue() . ' city';
|
return $obj->getValue() . ' city';
|
||||||
}
|
}
|
||||||
)
|
]);
|
||||||
);
|
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
'Name,City'."\n".
|
'Name,City'."\n".
|
||||||
@ -91,12 +111,10 @@ class GridFieldExportButtonTest extends SapphireTest
|
|||||||
public function testBuiltInFunctionNameCanBeUsedAsHeader()
|
public function testBuiltInFunctionNameCanBeUsedAsHeader()
|
||||||
{
|
{
|
||||||
$button = new GridFieldExportButton();
|
$button = new GridFieldExportButton();
|
||||||
$button->setExportColumns(
|
$button->setExportColumns([
|
||||||
array(
|
|
||||||
'Name' => 'Name',
|
'Name' => 'Name',
|
||||||
'City' => 'strtolower'
|
'City' => 'strtolower',
|
||||||
)
|
]);
|
||||||
);
|
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
'Name,strtolower'."\n".
|
'Name,strtolower'."\n".
|
||||||
@ -109,12 +127,10 @@ class GridFieldExportButtonTest extends SapphireTest
|
|||||||
public function testNoCsvHeaders()
|
public function testNoCsvHeaders()
|
||||||
{
|
{
|
||||||
$button = new GridFieldExportButton();
|
$button = new GridFieldExportButton();
|
||||||
$button->setExportColumns(
|
$button->setExportColumns([
|
||||||
array(
|
|
||||||
'Name' => 'Name',
|
'Name' => 'Name',
|
||||||
'City' => 'City'
|
'City' => 'City',
|
||||||
)
|
]);
|
||||||
);
|
|
||||||
$button->setCsvHasHeader(false);
|
$button->setCsvHasHeader(false);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
@ -132,9 +148,7 @@ class GridFieldExportButtonTest extends SapphireTest
|
|||||||
//Create an ArrayList 1 greater the Paginator's default 15 rows
|
//Create an ArrayList 1 greater the Paginator's default 15 rows
|
||||||
$arrayList = new ArrayList();
|
$arrayList = new ArrayList();
|
||||||
for ($i = 1; $i <= 16; $i++) {
|
for ($i = 1; $i <= 16; $i++) {
|
||||||
$dataobject = new DataObject(
|
$dataobject = new DataObject(['ID' => $i]);
|
||||||
array ( 'ID' => $i )
|
|
||||||
);
|
|
||||||
$arrayList->add($dataobject);
|
$arrayList->add($dataobject);
|
||||||
}
|
}
|
||||||
$this->gridField->setList($arrayList);
|
$this->gridField->setList($arrayList);
|
||||||
@ -164,11 +178,9 @@ class GridFieldExportButtonTest extends SapphireTest
|
|||||||
public function testZeroValue()
|
public function testZeroValue()
|
||||||
{
|
{
|
||||||
$button = new GridFieldExportButton();
|
$button = new GridFieldExportButton();
|
||||||
$button->setExportColumns(
|
$button->setExportColumns([
|
||||||
array(
|
|
||||||
'RugbyTeamNumber' => 'Rugby Team Number'
|
'RugbyTeamNumber' => 'Rugby Team Number'
|
||||||
)
|
]);
|
||||||
);
|
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
"\"Rugby Team Number\"\n2\n0\n",
|
"\"Rugby Team Number\"\n2\n0\n",
|
||||||
|
40
tests/php/Forms/HTMLEditor/TinyMCEConfigTest.php
Normal file
40
tests/php/Forms/HTMLEditor/TinyMCEConfigTest.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Forms\Tests\HTMLEditor;
|
||||||
|
|
||||||
|
use SilverStripe\Control\Director;
|
||||||
|
use SilverStripe\Core\Manifest\ModuleResourceLoader;
|
||||||
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
use SilverStripe\Forms\HTMLEditor\TinyMCEConfig;
|
||||||
|
|
||||||
|
class TinyMCEConfigTest extends SapphireTest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Ensure that all TinyMCEConfig.tinymce_lang are valid
|
||||||
|
*/
|
||||||
|
public function testLanguagesValid()
|
||||||
|
{
|
||||||
|
$configDir = TinyMCEConfig::config()->get('base_dir');
|
||||||
|
if (!$configDir) {
|
||||||
|
$this->markTestSkipped("Test skipped without TinyMCE resources folder being installed");
|
||||||
|
}
|
||||||
|
|
||||||
|
$langs = Director::baseFolder().'/'.ModuleResourceLoader::resourcePath($configDir).'/langs';
|
||||||
|
|
||||||
|
// Test all langs exist as real files
|
||||||
|
foreach (TinyMCEConfig::config()->get('tinymce_lang') as $locale => $resource) {
|
||||||
|
// Check valid
|
||||||
|
$this->assertFileExists(
|
||||||
|
"{$langs}/{$resource}.js",
|
||||||
|
"Locale code {$locale} maps to {$resource}.js which exists"
|
||||||
|
);
|
||||||
|
// Check we don't simplify to locale when a specific version exists
|
||||||
|
if (strpos($resource, '_') === false) {
|
||||||
|
$this->assertFileNotExists(
|
||||||
|
"{$langs}/{$locale}.js",
|
||||||
|
"Locale code {$locale} doesn't map to simple {$resource}.js when a better {$locale}.js is available"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1342,10 +1342,7 @@ class DataObjectTest extends SapphireTest
|
|||||||
$this->assertFalse($schema->classHasTable(DataObject::class));
|
$this->assertFalse($schema->classHasTable(DataObject::class));
|
||||||
$this->assertFalse($schema->classHasTable(ViewableData::class));
|
$this->assertFalse($schema->classHasTable(ViewableData::class));
|
||||||
|
|
||||||
// Invalid class
|
/* Invalid class name */
|
||||||
$this->expectException(ReflectionException::class);
|
|
||||||
$this->expectExceptionMessage('Class ThisIsntADataObject does not exist');
|
|
||||||
|
|
||||||
$this->assertFalse($schema->classHasTable("ThisIsntADataObject"));
|
$this->assertFalse($schema->classHasTable("ThisIsntADataObject"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +265,8 @@ class MemberAuthenticatorTest extends SapphireTest
|
|||||||
$this->assertNull($member);
|
$this->assertNull($member);
|
||||||
$this->assertCount(1, LoginAttempt::get());
|
$this->assertCount(1, LoginAttempt::get());
|
||||||
$attempt = LoginAttempt::get()->first();
|
$attempt = LoginAttempt::get()->first();
|
||||||
$this->assertEquals($email, $attempt->Email);
|
$this->assertEmpty($attempt->Email); // Doesn't store potentially sensitive data
|
||||||
|
$this->assertEquals(sha1($email), $attempt->EmailHashed);
|
||||||
$this->assertEquals(LoginAttempt::FAILURE, $attempt->Status);
|
$this->assertEquals(LoginAttempt::FAILURE, $attempt->Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
namespace SilverStripe\Security\Tests;
|
namespace SilverStripe\Security\Tests;
|
||||||
|
|
||||||
use Page;
|
use Page;
|
||||||
use PageController;
|
|
||||||
use SilverStripe\Control\Controller;
|
use SilverStripe\Control\Controller;
|
||||||
use SilverStripe\Control\Director;
|
use SilverStripe\Control\Director;
|
||||||
use SilverStripe\Control\HTTPRequest;
|
use SilverStripe\Control\HTTPRequest;
|
||||||
@ -615,34 +614,21 @@ class SecurityTest extends FunctionalTest
|
|||||||
/* UNSUCCESSFUL ATTEMPTS WITH WRONG PASSWORD FOR EXISTING USER ARE LOGGED */
|
/* UNSUCCESSFUL ATTEMPTS WITH WRONG PASSWORD FOR EXISTING USER ARE LOGGED */
|
||||||
$this->doTestLoginForm('testuser@example.com', 'wrongpassword');
|
$this->doTestLoginForm('testuser@example.com', 'wrongpassword');
|
||||||
/** @var LoginAttempt $attempt */
|
/** @var LoginAttempt $attempt */
|
||||||
$attempt = DataObject::get_one(
|
$attempt = LoginAttempt::getByEmail('testuser@example.com')->first();
|
||||||
LoginAttempt::class,
|
|
||||||
array(
|
|
||||||
'"LoginAttempt"."Email"' => 'testuser@example.com'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$this->assertInstanceOf(LoginAttempt::class, $attempt);
|
$this->assertInstanceOf(LoginAttempt::class, $attempt);
|
||||||
$member = DataObject::get_one(
|
$member = Member::get()->filter('Email', 'testuser@example.com')->first();
|
||||||
Member::class,
|
|
||||||
array(
|
|
||||||
'"Member"."Email"' => 'testuser@example.com'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$this->assertEquals($attempt->Status, 'Failure');
|
$this->assertEquals($attempt->Status, 'Failure');
|
||||||
$this->assertEquals($attempt->Email, 'testuser@example.com');
|
$this->assertEmpty($attempt->Email); // Doesn't store potentially sensitive data
|
||||||
|
$this->assertEquals($attempt->EmailHashed, sha1('testuser@example.com'));
|
||||||
$this->assertEquals($attempt->Member()->toMap(), $member->toMap());
|
$this->assertEquals($attempt->Member()->toMap(), $member->toMap());
|
||||||
|
|
||||||
/* UNSUCCESSFUL ATTEMPTS WITH NONEXISTING USER ARE LOGGED */
|
/* UNSUCCESSFUL ATTEMPTS WITH NONEXISTING USER ARE LOGGED */
|
||||||
$this->doTestLoginForm('wronguser@silverstripe.com', 'wrongpassword');
|
$this->doTestLoginForm('wronguser@silverstripe.com', 'wrongpassword');
|
||||||
$attempt = DataObject::get_one(
|
$attempt = LoginAttempt::getByEmail('wronguser@silverstripe.com')->first();
|
||||||
LoginAttempt::class,
|
$this->assertInstanceOf(LoginAttempt::class, $attempt);
|
||||||
array(
|
|
||||||
'"LoginAttempt"."Email"' => 'wronguser@silverstripe.com'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$this->assertTrue(is_object($attempt));
|
|
||||||
$this->assertEquals($attempt->Status, 'Failure');
|
$this->assertEquals($attempt->Status, 'Failure');
|
||||||
$this->assertEquals($attempt->Email, 'wronguser@silverstripe.com');
|
$this->assertEmpty($attempt->Email); // Doesn't store potentially sensitive data
|
||||||
|
$this->assertEquals($attempt->EmailHashed, sha1('wronguser@silverstripe.com'));
|
||||||
$this->assertNotEmpty($this->getValidationResult()->getMessages(), 'An invalid email returns a message.');
|
$this->assertNotEmpty($this->getValidationResult()->getMessages(), 'An invalid email returns a message.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,22 +639,12 @@ class SecurityTest extends FunctionalTest
|
|||||||
/* SUCCESSFUL ATTEMPTS ARE LOGGED */
|
/* SUCCESSFUL ATTEMPTS ARE LOGGED */
|
||||||
$this->doTestLoginForm('testuser@example.com', '1nitialPassword');
|
$this->doTestLoginForm('testuser@example.com', '1nitialPassword');
|
||||||
/** @var LoginAttempt $attempt */
|
/** @var LoginAttempt $attempt */
|
||||||
$attempt = DataObject::get_one(
|
$attempt = LoginAttempt::getByEmail('testuser@example.com')->first();
|
||||||
LoginAttempt::class,
|
$member = Member::get()->filter('Email', 'testuser@example.com')->first();
|
||||||
array(
|
$this->assertInstanceOf(LoginAttempt::class, $attempt);
|
||||||
'"LoginAttempt"."Email"' => 'testuser@example.com'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
/** @var Member $member */
|
|
||||||
$member = DataObject::get_one(
|
|
||||||
Member::class,
|
|
||||||
array(
|
|
||||||
'"Member"."Email"' => 'testuser@example.com'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$this->assertTrue(is_object($attempt));
|
|
||||||
$this->assertEquals($attempt->Status, 'Success');
|
$this->assertEquals($attempt->Status, 'Success');
|
||||||
$this->assertEquals($attempt->Email, 'testuser@example.com');
|
$this->assertEmpty($attempt->Email); // Doesn't store potentially sensitive data
|
||||||
|
$this->assertEquals($attempt->EmailHashed, sha1('testuser@example.com'));
|
||||||
$this->assertEquals($attempt->Member()->toMap(), $member->toMap());
|
$this->assertEquals($attempt->Member()->toMap(), $member->toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -725,6 +701,7 @@ class SecurityTest extends FunctionalTest
|
|||||||
|
|
||||||
// Ensure page shares the same controller as security
|
// Ensure page shares the same controller as security
|
||||||
$securityClass = Config::inst()->get(Security::class, 'page_class');
|
$securityClass = Config::inst()->get(Security::class, 'page_class');
|
||||||
|
/** @var Page $securityPage */
|
||||||
$securityPage = new $securityClass();
|
$securityPage = new $securityClass();
|
||||||
$this->assertInstanceOf($securityPage->getControllerName(), $result);
|
$this->assertInstanceOf($securityPage->getControllerName(), $result);
|
||||||
$this->assertEquals($request, $result->getRequest());
|
$this->assertEquals($request, $result->getRequest());
|
||||||
|
Loading…
Reference in New Issue
Block a user