Compare commits

...

269 Commits
2.1.3 ... 3

Author SHA1 Message Date
Guy Sartorelli 277f84392f
Merge branch '3.10' into 3 2023-08-29 10:28:27 +12:00
Steve Boyd ca593443d1
Merge pull request #374 from creative-commoners/pulls/3.10/tx-1692323162
ENH Update translations
2023-08-21 12:13:40 +12:00
Guy Sartorelli 67c42b363e
ENH Update translations 2023-08-18 13:46:02 +12:00
Guy Sartorelli 7e202debb7
Merge pull request #370 from silverstripe/dependabot/npm_and_yarn/word-wrap-1.2.5
Bump word-wrap from 1.2.3 to 1.2.5
2023-08-04 12:19:06 +12:00
dependabot[bot] b988465bf1
Bump word-wrap from 1.2.3 to 1.2.5
Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.5.
- [Release notes](https://github.com/jonschlinkert/word-wrap/releases)
- [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.5)

---
updated-dependencies:
- dependency-name: word-wrap
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-03 05:28:15 +00:00
Guy Sartorelli 4a9af98a70
Merge branch '3.10' into 3 2023-04-26 12:46:13 +12:00
Steve Boyd f5157aaf3c
Merge pull request #365 from creative-commoners/pulls/3.10/fix-constraints
MNT Revert erroneous dependency changes
2023-03-28 17:04:12 +13:00
Guy Sartorelli dde8ac9bac
MNT Revert erroneous dependency changes 2023-03-28 14:54:42 +13:00
Maxime Rainville dda2dcbfff
Merge pull request #364 from creative-commoners/pulls/3.10/no-deprecations
FIX Don't use deprecated API
2023-03-28 11:15:44 +13:00
Guy Sartorelli 7448c2050a
FIX Don't use deprecated API 2023-03-28 09:52:10 +13:00
Maxime Rainville 2fccdbe916
Merge pull request #363 from creative-commoners/pulls/3/dispatch-ci
MNT Use gha-dispatch-ci
2023-03-23 14:10:18 +13:00
Steve Boyd 5729dc5c70 MNT Use gha-dispatch-ci 2023-03-21 12:23:30 +13:00
Guy Sartorelli 428b503a70
MNT Update development dependencies 2023-03-10 16:33:11 +13:00
Guy Sartorelli 1dc37ac0c1
MNT Update release dependencies 2023-03-10 16:33:07 +13:00
Guy Sartorelli 1ad761698b
MNT Update development dependencies 2023-03-10 12:21:29 +13:00
Guy Sartorelli e08e51d7f3
Merge pull request #362 from creative-commoners/pulls/3/tx-1678079758
ENH Update translations
2023-03-08 10:25:09 +13:00
Steve Boyd 0c7b2e987b ENH Update translations 2023-03-06 18:15:58 +13:00
Sabina Talipova 5d044bd6eb
Merge pull request #352 from creative-commoners/pulls/3/stop-using-depr
API Stop using deprecated API
2022-12-06 09:44:15 +13:00
Steve Boyd b771bb624a API Stop using deprecated API 2022-11-29 09:35:55 +13:00
Guy Sartorelli 9bfef9e931
Merge pull request #350 from creative-commoners/pulls/3/depr-messages
API Update deprecations
2022-11-21 09:52:02 +13:00
Guy Sartorelli 2b5bde3d8f
Merge pull request #351 from steffen-maass/allow-extension-override
Add a key when enabling the CommentsExtension in the config.
2022-11-20 17:44:39 +13:00
Steffen Maass 57a9617d5b Add a key when enabling the CommentsExtension.
This allows modules to unset it if necessary.
2022-11-19 16:42:56 -08:00
Steve Boyd c3ef4d6efc API Update deprecations 2022-11-16 12:13:50 +13:00
Steve Boyd a88bd6fff6 Merge branch '3.8' into 3 2022-08-02 18:47:23 +12:00
Steve Boyd 068f283833 Merge branch '3.7' into 3.8 2022-08-02 18:47:19 +12:00
Guy Sartorelli bffe690afd
Merge pull request #345 from creative-commoners/pulls/3.7/standardise-modules
MNT Standardise modules
2022-08-02 15:01:30 +12:00
Steve Boyd 6081aeba8f MNT Standardise modules 2022-08-01 16:21:22 +12:00
Guy Sartorelli 6974bfd8ba
Merge pull request #344 from creative-commoners/pulls/3/update-js
MNT Use up­date-js action
2022-07-29 17:06:35 +12:00
Steve Boyd b9341d6185 MNT Use update-js action 2022-07-29 13:07:50 +12:00
Steve Boyd a3f2f3cd48 Merge branch '3.8' into 3 2022-07-25 11:20:55 +12:00
Steve Boyd 05a3628471 Merge branch '3.7' into 3.8 2022-07-25 11:20:39 +12:00
Guy Sartorelli bf6e56bd10
Merge pull request #342 from creative-commoners/pulls/3.7/module-standards
MNT Use GitHub Actions CI
2022-07-15 11:27:29 +12:00
Steve Boyd ff6db7d480 MNT Use GitHub Actions CI 2022-07-14 12:06:51 +12:00
Will Rossiter d87dbc8367
fix: field formatting to correct include link 2022-06-13 11:53:44 +12:00
Steve Boyd 6782048463
Merge pull request #337 from silverstripe/pulls/3/update-js-1648772023
DEP Update JS dependencies
2022-05-31 11:02:37 +12:00
dependabot[bot] a3479443df
Merge pull request #339 from silverstripe/dependabot/npm_and_yarn/async-2.6.4 2022-05-03 09:51:13 +00:00
dependabot[bot] 9ef77e393c
Bump async from 2.6.3 to 2.6.4
Bumps [async](https://github.com/caolan/async) from 2.6.3 to 2.6.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/v2.6.4/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v2.6.3...v2.6.4)

---
updated-dependencies:
- dependency-name: async
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-28 19:49:18 +00:00
Guy Sartorelli 3dc22e9c39
Merge pull request #338 from creative-commoners/pulls/3/php81
ENH PHP 8.1 compatibility
2022-04-26 17:58:35 +12:00
Steve Boyd e7f9e60352 ENH PHP 8.1 compatibility 2022-04-13 10:22:29 +12:00
github-actions efe5b1ef6f DEP Update JS dependencies 2022-04-01 00:13:43 +00:00
Maxime Rainville 3d6e44aaa1
Merge pull request #336 from creative-commoners/pulls/3/update-js-deps
MNT Add update JS deps workflow
2022-03-23 15:45:13 +13:00
Steve Boyd 1d6eae193c MNT Add update JS deps workflow 2022-03-22 12:06:51 +13:00
Daniel Hensby 7284a920ed
Merge pull request #335 from creative-commoners/pulls/3/php74
DEP Set PHP 7.4 as the minimum version
2022-02-10 12:05:31 +00:00
Steve Boyd 536d965d9c DEP Set PHP 7.4 as the minimum version 2022-02-10 15:55:36 +13:00
Steve Boyd 1aa560ff74 Merge branch '3.7' into 3 2021-12-22 10:25:58 +13:00
Steve Boyd 421e08cba5
Merge pull request #334 from creative-commoners/pulls/3.7/cherry-pick
MNT Fix unit test
2021-11-29 17:25:45 +13:00
Steve Boyd 91d2db1020 MNT Fix unit test 2021-11-29 17:24:29 +13:00
Steve Boyd 9258ce6fa4 Merge branch '3.7' into 3 2021-11-25 13:16:34 +13:00
Maxime Rainville 8a3b569653
Merge pull request #333 from creative-commoners/pulls/3.7/js
DEP Update JS dependencies
2021-11-24 17:26:28 +13:00
Steve Boyd aa81f8cdd2 DEP Update JS dependencies 2021-11-23 10:45:13 +13:00
Steve Boyd 6895ac4f9d
Merge pull request #331 from creative-commoners/pulls/3/eslint
MNT Use caret for eslint
2021-11-22 13:35:29 +13:00
Steve Boyd a3c7943fdd
Merge pull request #330 from creative-commoners/pulls/3/fix-test
MNT Fix unit test
2021-11-22 11:56:08 +13:00
Steve Boyd 43e221daa8 MNT Use caret for eslint 2021-11-19 12:29:17 +13:00
Steve Boyd 6d9a808cd4 MNT Fix unit test 2021-11-19 10:55:22 +13:00
Maxime Rainville 7eb8ebedf4
Merge pull request #329 from creative-commoners/pulls/3/sapphire-test-nine
API phpunit 9 support
2021-11-01 17:52:24 +13:00
Steve Boyd 305ae6b4b8 API phpunit 9 support 2021-10-27 18:03:55 +13:00
Loz Calver 066b28bb3d
Fix broken link in README.md 2021-10-14 16:22:35 +01:00
dependabot[bot] 5cee54faca
Merge pull request #324 from silverstripe/dependabot/npm_and_yarn/hosted-git-info-2.8.9 2021-08-05 06:25:32 +00:00
dependabot[bot] 4cfecdfcd6
Merge pull request #325 from silverstripe/dependabot/npm_and_yarn/ws-6.2.2 2021-06-06 15:57:51 +00:00
dependabot[bot] 3a4130302d
Bump ws from 6.2.1 to 6.2.2
Bumps [ws](https://github.com/websockets/ws) from 6.2.1 to 6.2.2.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/commits)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-05 15:06:53 +00:00
dependabot[bot] a4eeec4bba
Bump hosted-git-info from 2.8.8 to 2.8.9
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-10 06:32:37 +00:00
Steve Boyd 545df1d54f Merge branch '3.4' into 3 2021-03-21 10:31:41 +13:00
Steve Boyd 9c3c1e8120 Fix merge conflict 2021-03-21 10:31:02 +13:00
Steve Boyd 38495c69f0 Merge branch '3.4' into 3 2021-03-21 10:28:31 +13:00
Steve Boyd e6971b82c6 Merge branch '3.3' into 3.4 2021-03-21 10:27:53 +13:00
Steve Boyd 362cb05029 Merge branch '3.4' into 3 2021-03-20 10:03:18 +13:00
Steve Boyd 5bda1a7076 Merge branch '3.3' into 3.4 2021-03-20 09:58:21 +13:00
Garion Herman 175664d5a8
Merge pull request #320 from creative-commoners/pulls/3.4/jquery-yarn
ENH Use yarn and webpack to upgrade jquery
2021-03-04 17:29:12 +13:00
Steve Boyd 3b37fdb1ae ENH Use yarn and webpack to upgrade jquery 2021-03-04 17:05:29 +13:00
Steve Boyd fb15ba7d43
Update build status badge 2021-01-21 16:32:17 +13:00
Garion Herman 06b243b1e4
Merge pull request #316 from creative-commoners/pulls/3.3/shared-config
MNT Use shared travis config, use sminnee/phpunit
2021-01-18 10:30:53 +13:00
Steve Boyd 668f90d2f9 Merge branch '3.4' into 3 2021-01-02 19:42:12 +13:00
Maxime Rainville 867d0e8281
Merge pull request #318 from creative-commoners/pulls/3.4/travis-shared
MNT Travis shared config, use sminnee/phpunit
2020-12-21 14:46:25 +13:00
Steve Boyd c065d0c5de MNT Travis shared config, use sminnee/phpunit 2020-12-01 20:34:24 +13:00
Steve Boyd 739b211afb ENH Update translations 2020-11-18 12:56:01 +13:00
Garion Herman d12a71ddff
Merge pull request #311 from silverstripe/dependabot/npm_and_yarn/node-sass-4.14.1
Bump node-sass from 4.13.0 to 4.14.1
2020-11-17 10:42:35 +13:00
Steve Boyd c834e19631 MNT Use shared travis config, use sminnee/phpunit 2020-11-16 15:24:51 +13:00
dependabot[bot] a8d1cf1355
Bump node-sass from 4.13.0 to 4.14.1
Bumps [node-sass](https://github.com/sass/node-sass) from 4.13.0 to 4.14.1.
- [Release notes](https://github.com/sass/node-sass/releases)
- [Changelog](https://github.com/sass/node-sass/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sass/node-sass/compare/v4.13.0...v4.14.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-04 10:37:02 +00:00
Garion Herman f5f6e8f08f
Merge pull request #309 from silverstripe/dependabot/npm_and_yarn/elliptic-6.5.3
Bump elliptic from 6.5.1 to 6.5.3
2020-08-19 16:33:48 +12:00
dependabot[bot] 8bc492bb77
Bump elliptic from 6.5.1 to 6.5.3
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.1 to 6.5.3.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.1...v6.5.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-30 14:08:55 +00:00
dependabot[bot] 68ec979987
Merge pull request #308 from silverstripe/dependabot/npm_and_yarn/npm-6.14.7 2020-07-22 10:37:41 +00:00
dependabot[bot] f91b13ad96
Bump npm from 6.13.4 to 6.14.7
Bumps [npm](https://github.com/npm/cli) from 6.13.4 to 6.14.7.
- [Release notes](https://github.com/npm/cli/releases)
- [Changelog](https://github.com/npm/cli/blob/v6.14.7/CHANGELOG.md)
- [Commits](https://github.com/npm/cli/compare/v6.13.4...v6.14.7)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-21 20:23:55 +00:00
dependabot[bot] 6972da84a6
Merge pull request #306 from silverstripe/dependabot/npm_and_yarn/npm-registry-fetch-4.0.5 2020-07-21 20:22:31 +00:00
dependabot[bot] 99b2ed4dfc
Merge pull request #307 from silverstripe/dependabot/npm_and_yarn/lodash-4.17.19 2020-07-21 20:22:23 +00:00
dependabot[bot] 1e9d8fcd1b
Bump lodash from 4.17.15 to 4.17.19
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-16 22:42:39 +00:00
dependabot[bot] bcbc58f46e
Bump npm-registry-fetch from 4.0.2 to 4.0.5
Bumps [npm-registry-fetch](https://github.com/npm/registry-fetch) from 4.0.2 to 4.0.5.
- [Release notes](https://github.com/npm/registry-fetch/releases)
- [Changelog](https://github.com/npm/npm-registry-fetch/blob/latest/CHANGELOG.md)
- [Commits](https://github.com/npm/registry-fetch/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-08 00:40:27 +00:00
Steve Boyd e88c7d5154
Merge pull request #301 from torleif/patch-1
FIX Broken action checkboxes
2020-07-03 11:23:50 +12:00
Maxime Rainville edfb9d7b74 Merge branch '3.3' into 3 2020-06-12 14:15:04 +12:00
Maxime Rainville 932ef5d284 Merge branch '3.2' into 3.3 2020-06-12 14:14:32 +12:00
torleif 82c817c452
Fixes #300 2020-04-20 09:40:57 +12:00
Robbie Averill aaa9328a72
Merge pull request #299 from silverstripe/dependabot/npm_and_yarn/npm-6.13.4
Bump npm from 6.13.0 to 6.13.4
2019-12-13 14:05:12 -08:00
dependabot[bot] e2db114158
Bump npm from 6.13.0 to 6.13.4
Bumps [npm](https://github.com/npm/cli) from 6.13.0 to 6.13.4.
- [Release notes](https://github.com/npm/cli/releases)
- [Changelog](https://github.com/npm/cli/blob/latest/CHANGELOG.md)
- [Commits](https://github.com/npm/cli/compare/v6.13.0...v6.13.4)

Signed-off-by: dependabot[bot] <support@github.com>
2019-12-13 20:02:32 +00:00
Garion Herman cfdffb394a Merge branch '3.3' into 3 2019-11-18 12:13:59 +13:00
Garion Herman d0b6181b48 Update config for 3.3 / CMS 4.5 branches 2019-11-18 12:12:58 +13:00
Andre Kiste ce450103ac
Merge pull request #298 from creative-commoners/pulls/3/upgrade-dependnecies
Restore empty comments.css file
2019-11-12 12:26:55 +13:00
Maxime Rainville 05c5cb64a7 Restore empty comments.css file 2019-11-12 11:53:35 +13:00
Andre Kiste 408845b01a
Merge pull request #297 from creative-commoners/pulls/3/upgrade-dependnecies
Upgrade dependencies and build settings
2019-11-12 11:42:30 +13:00
Maxime Rainville 85374a1f76 Upgrade dependencies and build settings 2019-11-11 12:18:54 +13:00
Dylan Wagstaff 07b24073dd
Merge pull request #295 from silverstripe/dependabot/npm_and_yarn/mixin-deep-1.3.2
Bump mixin-deep from 1.3.1 to 1.3.2
2019-10-04 10:55:56 +13:00
dependabot[bot] 250e522887
Bump mixin-deep from 1.3.1 to 1.3.2
Bumps [mixin-deep](https://github.com/jonschlinkert/mixin-deep) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/jonschlinkert/mixin-deep/releases)
- [Commits](https://github.com/jonschlinkert/mixin-deep/compare/1.3.1...1.3.2)

Signed-off-by: dependabot[bot] <support@github.com>
2019-10-03 21:09:03 +00:00
Dylan Wagstaff 9d9ab35cc6
Merge pull request #294 from AdamSawoscianik/patch-1
Update Installing.md
2019-10-04 10:07:48 +13:00
AdamSawoscianik d5b9a2818c
Update Installing.md
Adding information about $CommentsForm tag to help people with this module.
2019-10-03 10:32:22 +02:00
Guy Marriott e21a09234a
Update translations 2019-08-20 16:37:58 +12:00
Jason Irish fbfead9c9e BUGFIX CommentAdmin implements PermissionProvider
fixes #288
2019-08-15 09:50:36 +12:00
Will Rossiter b3fe6d82b4 Add legacy YAML for upgrading 2019-08-15 09:50:27 +12:00
Heath Dunlop 617501efed comments extension filters on Parent Class
This allows both pages and DataObjects to have comments without the ParentID clashing and showing comments on a page where the ParentID is the Same as a DataObjects or even two DataObjects having the sameID
2019-08-15 09:50:19 +12:00
Robbie Averill f4c82f238e
Merge pull request #292 from jsirish/bugfix/adminPermissionProvider
BUGFIX CommentAdmin implements PermissionProvider
2019-07-15 22:03:28 +01:00
Jason Irish c0f0c99e56 BUGFIX CommentAdmin implements PermissionProvider
fixes #288
2019-07-15 12:02:50 -05:00
Dylan Wagstaff f8eeeee4b8
Merge pull request #290 from GOVTNZ/pulls/legacy
Add legacy YAML for upgrading
2019-07-03 12:47:47 +12:00
Will Rossiter cad9369f7b
Add legacy YAML for upgrading 2019-07-03 11:40:42 +12:00
Robbie Averill c16ca56408
Merge pull request #289 from creative-commoners/pulls/3.2/focus-comment-submission-message
NEW Add tabindex="-1" to comment submission message for a11y support
2019-06-28 16:15:27 +12:00
Garion Herman 67167c0809 NEW Add tabindex="-1" to comment submission message for a11y support 2019-06-28 15:56:09 +12:00
Robbie Averill 8397bb5792
Merge pull request #287 from creative-commoners/pulls/master/update-vuln-dependencies
Update @silverstripe/webpack-config to patch vulnerable deps, add NVM config
2019-06-14 15:04:14 +12:00
Garion Herman 2d0d949fc3 Update @silverstripe/webpack-config to patch vulnerable deps 2019-06-14 14:47:09 +12:00
Garion Herman 14675b53bf Add NVM config 2019-06-14 13:59:23 +12:00
Robbie Averill 9c4ec173fd
Merge pull request #285 from dunatron/patch-2
comments extension filters on Parent Class
2019-05-16 15:33:09 +12:00
Heath Dunlop 82845626bc
comments extension filters on Parent Class
This allows both pages and DataObjects to have comments without the ParentID clashing and showing comments on a page where the ParentID is the Same as a DataObjects or even two DataObjects having the sameID
2019-05-16 13:46:28 +12:00
Robbie Averill 780ea22b93 Merge branch '3.2' 2019-05-10 09:35:00 +12:00
Robbie Averill f65f5b5697 FIX Remove reliance on translations in fieldLabels test, run textcollector, remove deprecated code from CommentsTest 2019-05-10 09:33:18 +12:00
Guy Marriott 74a317ab46
Update translations 2019-05-09 15:44:57 +12:00
Robbie Averill 161f5f88bd Merge branch '3.2' 2019-05-08 11:28:18 +12:00
Robbie Averill 67faa822f7 Update dependencies 2019-05-08 11:26:56 +12:00
Guy Marriott aec3e2ba5b
FIX "Allow Comments" label now reads "Allow comments" - should not have been capitalised (#283)
FIX "Allow Comments" label now reads "Allow comments" - should not have been capitalised
2019-05-02 13:12:10 +12:00
Robbie Averill 89204c0c1c FIX "Allow Comments" label now reads "Allow comments" - should not have been capitalised 2019-05-02 11:31:32 +12:00
Robbie Averill d8602d0e02 Merge branch '3.2' 2019-04-15 15:34:34 +12:00
Robbie Averill 4d19e6c43e Merge branch '3.1' into 3.2 2019-04-15 15:33:53 +12:00
Robbie Averill 303bdef1c8 Remove obsolete branch alias and add PHP 7.3 to Travis builds 2019-04-15 15:33:44 +12:00
Guy Marriott 1358594070
Merge pull request #275 from creative-commoners/pulls/3.1/update-jquery-validator
Update jQuery.validation to 1.19.0
2019-04-05 09:17:06 +13:00
Dylan Wagstaff 6fcc040485 Update jQuery.validation to 1.19.0
jQuery 3.3.1 is still the latest release
2019-03-25 09:56:58 +13:00
Dylan Wagstaff 8b178b63ac
Merge pull request #280 from creative-commoners/pulls/master/improve-compat-with-bulk-editing-tools
Adjust the output of CommentHandler to use HTTPBulkToolsResponse
2019-03-24 13:34:21 +13:00
Garion Herman 1e4378d212 Tighten version constraint for Bulk Editing Tools dependency 2019-03-22 15:53:12 +13:00
Robbie Averill f0998faafb
Allow translation of 'Changes applied' message on CommentHandler
Co-Authored-By: Cheddam <cheddam@me.com>
2019-03-22 15:43:19 +13:00
Garion Herman 74afde6d9b Adjust the output of CommentHandler to use HTTPBulkToolsResponse
GridFieldBulkEditingTools has introduced a common output schema
in the form of HTTPBulkToolsResponse. This commit adopts that API.
2019-03-22 15:00:19 +13:00
Garion Herman 9ff1db403e
Merge pull request #277 from creative-commoners/pulls/4.0/infix-spam-flicks
NEW relocate spam and approve admin actions
2019-03-22 11:10:29 +13:00
Robbie Averill ce1e934d57
Merge pull request #278 from SpeksForks/doc-link
Fix documentation link
2019-02-19 05:09:33 +07:00
Peter Thaleikis 005f58f1ee
Fix documentation link 2019-02-19 02:32:09 +07:00
Robbie Averill 647c634dc4
Update .travis.yml
Co-Authored-By: NightJar <NightJar@users.noreply.github.com>
2019-02-11 09:22:02 +13:00
Guy Marriott 7d60fc2fe2
Update src/Admin/CommentsGridFieldSpamAction.php
Co-Authored-By: NightJar <NightJar@users.noreply.github.com>
2019-02-11 09:19:31 +13:00
Guy Marriott 18fbdfc94b
Update src/Admin/CommentsGridFieldApproveAction.php
Co-Authored-By: NightJar <NightJar@users.noreply.github.com>
2019-02-11 09:19:18 +13:00
Robbie Averill c4cfc44643 Update Scrutinizer configuration to use new build engine 2019-02-10 07:01:57 +03:00
Dylan Wagstaff b6a2c608ac NEW relocate spam and approve admin actions
Previous versions had individual spam and approve buttons for a comment
in the admin area on the GridField row. However with the upgrade to
SilverStripe 4, and particularly 4.2, these were having layout issues
with the new GridField Action Menu component that groups actions
together.

The solution here is to put them into aforementioned gridfield action
menu component, with the other actions for that row. However this
requires two separate grid field components (one each for the two
comment actions) - previously these were a single component that output
two buttons instead of one each. This also reduces coupling, which is
nice :)

The previous class is still maintained for backwards compatibilty, but
is deprecated.
2019-02-08 15:19:45 +13:00
Robbie Averill d504d4a847 Merge branch '3.1' 2019-01-11 09:13:31 +01:00
Guy Marriott f5c7024aaf
Merge pull request #276 from creative-commoners/pulls/3.1/deprotocol-my-site
Validate protocol-less URLs
2019-01-11 15:18:27 +13:00
Dylan Wagstaff 3812057b00 Add ability for commenters to enter a URL without a protocol
When posting a comment on the a page with this module applied, there is
an optional input for the commenter to give their URL,presumably their
website. However this input currently validates (via JavaScript) to
allow URLs only iff they have a protocol.

Common use cases when someone is asked for their website in my
experience is to then receive a URL without a protocol, confounded in
that most web browsers will accept this form and automatically add the
http protocol, where a webserver may then redirect to https by default.
This means that all the magic happens behind the scenes and most folks
don't particularly care to think about protocols when entering web
addresses.

Yest this input will only validate true and allow comment submission if
they do.

So now it will allow a protocol-less entry into the URL box.
2019-01-11 15:01:34 +13:00
Guy Marriott 20c6a50f12
Merge pull request #273 from creative-commoners/pulls/3.1/name-that-member
FIX show name of members in summary tables
2019-01-11 14:56:20 +13:00
Dylan Wagstaff 0535d29f8d
Merge pull request #274 from creative-commoners/pulls/3.1/i-de-test-those-labels
FIX Correcting inconsistent capitalisation of label and cleaning up tests
2019-01-11 14:49:02 +13:00
Guy Marriott 7691237fe5
FIX Correcting inconsistent capitalisation of label 2019-01-11 14:17:36 +13:00
Guy Marriott a57c83c121
Removing superflous i18n test and updating label test to only test labels specifically added 2019-01-11 12:22:31 +13:00
Dylan Wagstaff dc1f8622e0 FIX show name of members in summary tables
Anonymous comments (posted by the public at large) must have a name
and an email address associated with them. On the other hand, a logged
in user will have the `Member` record details used for this information,
via the Author relationship.

However the summary fields do not allow for this, and only reference
Name and Email on the Comment model directly, so any comment posted by a
logged in member has no data for name and email displayed in the various
GridFields in the CMS for administering comments (either per page, or in
the global ModelAdmin).

To recitfy this we can change the summary fields to use getter methods
that will return the Comment model info, or fall back to the Author
associated Member record if Name and Email are unset on the Comment.
2019-01-11 11:48:51 +13:00
Dylan Wagstaff 4ee9720081
Merge pull request #269 from creative-commoners/pulls/3.1/moderation-labels
FIX Capitalise comment moderation action labels and update i18n syntax in templates
2018-11-28 14:36:30 +13:00
Dylan Wagstaff d7761290f8
Merge pull request #268 from creative-commoners/pulls/3.1/fix-rss-comments-on-page
FIX RSS feed for comments now render correctly
2018-11-28 14:35:48 +13:00
Robbie Averill e101b74778 FIX Capitalise comment moderation action labels and update i18n syntax in templates 2018-11-27 13:27:19 +01:00
Robbie Averill 8c08f43376 FIX RSS feed for comments now render correctly
The comment DataList filter applies ParentClass = $className - when this
is the base class, it fails to recognise comments for a BlogPost. This
change uses the late class name instead.
2018-11-27 13:19:55 +01:00
Dylan Wagstaff f74d91041b
Merge pull request #267 from creative-commoners/pulls/3.1/remove-json-methods
FIX Replace Convert JSON methods with json_* methods, deprecated from SilverStripe 4.4
2018-10-29 11:05:43 +13:00
Robbie Averill d38e7c5b67 FIX Replace Convert JSON methods with json_* methods, deprecated from SilverStripe 4.4 2018-10-28 21:31:19 +00:00
Robbie Averill 97461f8f35 Merge branch '3.1' 2018-10-05 11:51:41 +02:00
Guy Marriott def91bb6d1
Merge pull request #265 from creative-commoners/pulls/3.1/minor-tidyups
Minor tidy ups to code formatting
2018-09-25 11:07:07 +12:00
Robbie Averill ec60328a0c Use short brackets, injection where possible and type hint injector created objects 2018-09-24 18:20:38 +02:00
Robbie Averill c0ca79090b Use injection where possible and remove redundant code lines 2018-09-24 18:11:26 +02:00
Robbie Averill 9a57c3802c Remove redundant phpcs rules, reduce some line lengths and use injector to create checkbox fields 2018-09-24 18:09:25 +02:00
Robbie Averill 9f9dc67950
Merge pull request #264 from caffeineinc/bugfix-3.1/xss-session-cookies
Prevent storing formdata to cookies.
2018-09-24 18:07:07 +02:00
Robbie Averill 94950ee79c Tidy up phpcs violations, use short array syntax, optimise class imports 2018-09-24 17:57:31 +02:00
Simon Gow 747d4f4402 Prevent storing formdata to cookies.
- XSS an be stored in a cookie and potentially abused in other ways, so
to prevent this we need to use session instead. This requires the user
to have a session with silverstripe, but this is better than saving
potentially malicious content in cookies. (Also some cookies have
limited length).

@see https://github.com/silverstripe/silverstripe-comments/issues/263
2018-09-20 14:53:35 +12:00
Robbie Averill cf86b2bb21
Merge pull request #262 from lukereative/pulls/3.1/fix-admin-height
FIX Comment admin form should fill height
2018-08-27 14:59:30 +12:00
Luke Edwards 75d63209aa FIX Comment admin form should fill height 2018-08-27 14:36:44 +12:00
Robbie Averill 04a5257e40 Merge branch '3.1' 2018-07-26 14:56:38 +12:00
Robbie Averill 19619b083e
Merge pull request #261 from micmania1/bugfix/canpostcomment-not-passed-to-include
BUGFIX canPostComment was being called out of scope
2018-07-03 11:43:34 +12:00
micmania1 c0a01dbc91 BUGFIX created way of knowing whether user has permission to post 2018-07-03 11:00:40 +12:00
Robbie Averill 6d7b14367a
Merge pull request #259 from quantum-dragons/bugfix/reply-form-js-fix
Added JS fix for reply forms
2018-06-25 14:08:08 +12:00
pjayme 77f47af5cb Added JS fix for reply forms - fixes issue where the submit button breaks due to incorrect use of the jQuery validate function 2018-06-25 13:25:08 +12:00
Dylan Wagstaff a1a42009cc
Merge pull request #258 from creative-commoners/pulls/3.1/travis-recipes
Add various recipe versions to Travis build matrix
2018-06-22 20:10:14 +12:00
Robbie Averill c7235e1c5d FIX Comments GridField tests now use their own test stubs 2018-06-20 16:53:14 +12:00
Robbie Averill 4e23771d79 Add Team stub class to extra_dataobjects 2018-06-20 16:48:26 +12:00
Robbie Averill 52b8ea9104 Add various recipe versions to Travis build matrix 2018-06-20 16:39:46 +12:00
Robbie Averill 8bd79eac1f Merge branch '3.1' 2018-06-20 16:28:40 +12:00
Robbie Averill f357ca6b7f
Merge pull request #257 from creative-commoners/pulls/3.1/reply-bug
FIX Bug with requiring login when posting a comment, pass correct controller in
2018-06-20 14:28:22 +12:00
Robbie Averill 886c5be21a FIX Bug with requiring login when posting a comment, pass correct controller in 2018-06-20 14:20:50 +12:00
Robbie Averill 9dab444f33
Merge pull request #255 from creative-commoners/pulls/master/add-supported-module-badge
Add supported module badge to readme
2018-06-18 10:49:55 +12:00
Dylan Wagstaff 2c00421cd2
Merge pull request #254 from creative-commoners/pulls/3.1/akismet-test-error
FIX Mock akismet spam protector if installed, fixes broken integration tests
2018-06-18 09:59:05 +12:00
Robbie Averill 32ec3bde50
FIX Add getDate method to return created date for comments, tidy up translations
RSS feeds are looking for $Date, so this method maps to the created field in these cases
2018-06-15 16:40:44 +01:00
Dylan Wagstaff be71d19d9e Add supported module badge to readme 2018-06-15 17:32:42 +12:00
Robbie Averill 788cb6e6d1 FIX Mock akismet spam protector if installed, fixes broken integration tests 2018-06-15 16:50:14 +12:00
Robbie Averill eca3ac0e94
FIX Allow tests to handle extra field labels being added in global state 2018-06-13 09:59:23 +12:00
Robbie Averill 01cc198a2d Merge branch '3.1' 2018-06-11 12:15:31 +12:00
Robbie Averill 06acad661f Remove obsolete branch alias 2018-06-11 12:15:09 +12:00
Robbie Averill 42a15f7241
Merge pull request #253 from creative-commoners/pulls/3.1/fix-tests
Fix Tests
2018-05-30 14:36:27 +12:00
Guy c22daa2ee0 FIX Removing ID from match in tests 2018-05-30 12:25:49 +12:00
Robbie Averill 614b525c04
FIX Loosen assertions in case extension provide extra columns in global state 2018-05-29 18:56:32 +12:00
Dylan Wagstaff 02db1cc86e [SS-2018-015] Update jQuery version, remove entwine from frontend use
jQuery version was extremely old, and was probably stuck at that as a way
of enabling the frivilous use of entwine on the front end for somewhat
trivial ajax submisions. A mild refactor has taken place to leverage newer
jQuery features, and remove outdated dependencies.

Also accompanying this commit are alterations to the markup to make it
more semantically correct (probably not entirely though), and help with
testing the JS functionality of reply forms (when enabled).
2018-05-29 11:40:18 +12:00
Daniel Hensby aa46291adf
Merge pull request #249 from Dennisprins93/master 2018-05-11 14:14:58 +01:00
Dennisprins93 386f8602f0
Omit http because of potential https conflicts 2018-05-11 14:11:22 +02:00
Robbie Averill eb0415a938
Merge pull request #245 from creative-commoners/pulls/2.0/reallow-commentform-alterations
FIX reintroduce extension hook for comment form rendering
2018-04-04 16:36:51 +12:00
Raissa North a886f68c58 FIX reintroduce extension hook for comment form rendering
In CWP 1.x there was an extension hook to allow alterations to the commenting form.
Since the upgrade of this module for CWP 2.x this was no longer there, meaning functionality
that relied upon it no longer worked. This commit reintroduces this functionality to keep
other modules that apply extensions to that hook, happy.
2018-04-04 15:45:45 +12:00
Dylan 276ddb0c86 Update translations 2018-04-04 10:17:01 +12:00
Dylan Wagstaff cc46ccf89e
Merge pull request #244 from creative-commoners/pulls/3.1/revert-and-deprecate
API Reintroduce abstract handler (previously removed in 192ddbb) and deprecate for future removal
2018-04-04 08:34:08 +12:00
Robbie Averill 3e0cae0cc9 API Reintroduce abstract handler (previously removed in 192ddbb) and deprecate for future removal 2018-04-03 12:22:15 +12:00
Robbie Averill 4385299f1f
Merge pull request #240 from sasky/master
Tiny bug fixes to work with SS4.
2018-03-14 13:18:55 +13:00
Cameron Grant abb45aa733 Setting the http error to come from the request handler, and the session coming form the Request objects. Just small bugs fix's so the comment form works with ss4. 2018-03-14 11:18:30 +13:00
Robbie Averill 532b49c537
Merge pull request #235 from creative-commoners/pulls/3.0/run-test-independent-from-template
Use FunctionalTest instead of SapphireTest to disable themes.
2018-03-09 17:02:47 +13:00
Raissa North 8d5edc7821 Use FunctionalTest instead of SapphireTest to disable themes. 2018-03-09 16:45:38 +13:00
Robbie Averill 90c42ff027
Merge pull request #232 from creative-commoners/pulls/3.0/bulk-editing-compat
API Use concrete Handler implementations for Spam and Approve bulk editing
2018-02-27 09:29:26 +13:00
Daniel Hensby 909066c0a8
Move comment handles to shared parent class 2018-02-26 11:40:49 +00:00
Robbie Averill 192ddbb4b5 API Use concrete Handler implementations for Spam and Approve bulk editing 2018-02-26 23:24:34 +13:00
Daniel Hensby b90ec7715e
Merge pull request #228 from benwrighton/master 2018-02-02 10:45:48 +00:00
Unknown ae59e82021 Improve A11y of comment reply.
Currently this is a link. Users will expect this link to take them to another part of the page or another page altogether. 

There is no indication that it opens or closes an associated form on the same page, nor does it indicate the current state of the “reply to” form.

So, instead of a link, use a button. Add to that button an aria-controls attribute that references the id of the associated form’s container, and an aria-expanded attribute that indicates (true or false) the state of the associated form.
2018-02-01 16:27:30 +13:00
Robbie Averill 17714f221a
Merge pull request #227 from creative-commoners/pulls/3.0/tx-me-js
FIX: update javascript requirements so user JS doesn't error
2018-01-29 16:06:27 +13:00
Dylan Wagstaff a25668eba0 Remove SS 2.x upgrade code that runs every build 2018-01-29 15:26:16 +13:00
Dylan Wagstaff 7b38707fde FIX: update javascript requirements so user JS doesn't error 2018-01-29 13:04:34 +13:00
Robbie Averill 4bf0a83ad3 FIX Update CommentAdmin test to create a mock session and not assert missing translation 2017-12-19 09:32:56 +13:00
Robbie Averill b02928e02a Merge branch '2' 2017-12-19 09:14:47 +13:00
Robbie Averill 4136bd7a63 Update branch alias for 2.x-dev 2017-12-18 18:18:32 +13:00
Robbie Averill b68ff56624 Merge branch '2.0' into 2.1 2017-12-18 18:17:06 +13:00
Robbie Averill 4e2965e86b Remove PHP 5.3 from Travis builds 2017-12-18 18:16:58 +13:00
Robbie Averill 85c9981962 Remove Transifex configuration. Commit directly to lang files for SS3. 2017-12-18 18:14:53 +13:00
Robbie Averill 82c4a1b9be
DOCS Update readme badges and add version support note 2017-12-18 14:11:51 +13:00
Dylan Wagstaff 3501ef7490
Merge pull request #224 from creative-commoners/pulls/3.0/fix-comments-admin
FIX Duplicated tabset, invalid Pjax request, update translations and Spam/Approve buttons
2017-12-15 10:09:32 +13:00
Robbie Averill 75d7de9aa6 FIX Add extra DataObject stub to CommentsGridFieldActionTest and update expectations 2017-12-14 17:57:03 +13:00
Robbie Averill 216ad8eb54 FIX Duplicated tabset, invalid Pjax request, update translations and Spam/Approve buttons 2017-12-14 16:08:43 +13:00
Daniel Hensby 118de6b595
Merge pull request #222 from creative-commoners/pulls/2.0/vendorise
NEW Convert to vendor module, add table_name to test stubs and add PHP 7.2 to travis
2017-12-13 12:07:34 +00:00
Robbie Averill 3f6f651eea FIX Replace French translation in CommentAdminTest now that it's available 2017-12-12 17:12:10 +13:00
Robbie Averill c6f8973342 NEW Convert to vendor module, add table_name to test stubs and add PHP 7.2 to travis 2017-12-12 17:03:04 +13:00
Dylan Wagstaff 8919f6da2a Merge pull request #220 from sheadawson/patch-1
FIX SS4: use SilverStripe\CMS\Model\SiteTree in Comment.php
2017-10-26 14:16:05 +13:00
Shea Dawson b1e9722320 use SilverStripe\CMS\Model\SiteTree; 2017-10-26 13:54:49 +13:00
Will Rossiter 8c43e097cd Merge pull request #216 from fullscreeninteractive/pulls/travis-fix
Travis, 4.0 API fixes
2017-10-10 09:49:13 +13:00
Robbie Averill 7700d88d4a FIX Remove base path assertions from tests which behave differently using phpdbg 2017-10-10 09:26:17 +13:00
Robbie Averill fa61608c7d FIX Merge config in tests, add phpcs and add HTML purifier to Travis builds 2017-10-09 17:26:07 +13:00
Will Rossiter f294ab26d6 Update tests and lang’s for 4.0 2017-09-18 14:16:24 +12:00
Will Rossiter 9366ef603e Split comment form out to its’ own class 2017-09-16 09:06:03 +12:00
Will Rossiter d9333b3160 Test fixes 2017-09-14 11:12:07 +12:00
Will Rossiter 7fff17b317 Correct extra dataobjects array name 2017-09-14 10:28:29 +12:00
Will Rossiter 73a981456f Use trusty 2017-09-14 10:09:21 +12:00
Will Rossiter 2fc7e7a004 Add phpunit, lint fixes and removed compass for webpack 2017-09-14 10:01:09 +12:00
Will Rossiter 0c964d1ed8 Composer lint 2017-09-14 09:41:11 +12:00
Will Rossiter 82c139e30a Travis fix 2017-09-13 09:12:09 +12:00
Will Rossiter 18761879cf Remove old email 2017-09-13 08:52:41 +12:00
Will Rossiter 4e2d22e16d Merge pull request #214 from fullscreeninteractive/wilr-patch-1
If user cannot view record then prevent comment
2017-09-13 08:36:18 +12:00
Franco Springveldt 8e79a1368e Update translations 2017-08-28 16:35:55 +12:00
Will Rossiter 85e8384151 If user cannot view record then prevent comment 2017-07-28 17:12:01 +12:00
Daniel Hensby fb3cc1b861 Add .codecov.yml file 2017-07-19 16:04:34 +01:00
Robbie Averill 4df49c8db7 Merge pull request #201 from rasstislav/patch-1
Added missing translation to Comments TabSet Title
2017-07-06 10:31:38 +12:00
Daniel Hensby 06439dde1f Merge pull request #209 from andrewandante/FIX/update_session
update thirdpartydir and session non-statics
2017-07-05 11:50:02 +01:00
Daniel Hensby d74bc59b98 Merge pull request #210 from dhensby/pulls/remove-travis-5.5
Remove PHP 5.5 build from travis
2017-07-05 11:49:34 +01:00
Daniel Hensby f276983611
Remove PHP 5.5 build from travis 2017-07-05 11:02:59 +01:00
Andrew Aitken-Fincham e7c358f730 update thirdpartydir and session non-statics 2017-07-04 15:53:38 +01:00
Daniel Hensby 8383ff1f81 Stop codecov comments 2017-06-18 01:04:58 +01:00
Daniel Hensby bd5b007394 Merge pull request #206 from creative-commoners/pulls/2.1/remove-broken-i18n-tests
FIX Remove providePermissions tests and update Travis build configuration
2017-06-15 19:24:00 +01:00
Robbie Averill 8ede35e6bd Update Travis build matrix to include PHP 7.1, SS 3.5, 3.6 and 3.x-dev explicitly 2017-06-13 11:13:48 +12:00
Robbie Averill c02d851500 FIX Remove providePermissions tests
Removed the testProvidePermissions case since it is testing localisations that do not exist, and a localisation that belongs to the framework which should not be tested here.
2017-06-13 11:09:56 +12:00
Rastislav Brandobur 9912285761 added CommentsExtension.COMMENTSTABSET definition to lang subfolder 2017-06-12 23:59:13 +02:00
Robbie Averill f27b357b06 Update translations 2017-05-12 15:06:51 +12:00
Rastislav Brandobur 79e16d5661 Added missing translation to Comments TabSet Title 2017-04-14 17:09:33 +02:00
Paul 2d076e4267 Merge pull request #200 from robbieaverill/bugfix/improve-delete-message
FIX Improve delete reply confirmation message
2017-03-16 09:14:14 +13:00
Robbie Averill 5a22f6faa5 FIX Improve delete reply confirmation message 2017-03-15 15:59:31 +13:00
Daniel Hensby 2ccd8d8af5 Merge pull request #197 from rasstislav/patch-1
added missing _t() function
2017-01-31 21:46:16 +00:00
Rastislav Brandobur b3dac91090 added missing _t() function 2017-01-31 21:06:06 +01:00
Daniel Hensby 5181ac8be3 Merge pull request #196 from robbieaverill/bugfix/fix-ci-builds
FIX Fix CI builds, remove excessive Travis builds matrixes, update composer constraint for gridfield-bulk-tools
2017-01-27 10:42:02 +00:00
Robbie Averill f8d5b27d50 Remove @dev from gridfield bulk editing tools constraint 2017-01-27 23:23:56 +13:00
Robbie Averill fc4d78605a FIX Use a CommentableItem as the parent for the test Comment 2017-01-27 16:42:26 +13:00
Robbie Averill d1697606e1 FIX Change BaseClass to ParentClass 2017-01-27 16:20:14 +13:00
Robbie Averill d1b947afbe FIX Use test database in GridFieldAction test class 2017-01-27 15:56:19 +13:00
Robbie Averill 07586d7579 FIX Fix CI builds, remove excessive Travis builds matrixes, update composer constraint for gridfield-bulk-tools 2017-01-27 12:48:57 +13:00
Damian Mooyman 19224d9813 Merge pull request #195 from robbieaverill/feature/ss4-compat
SilverStripe 4 compatibility
2017-01-25 17:52:20 +13:00
Damian Mooyman 978879e01c Fix incorrect namespace 2017-01-25 17:51:21 +13:00
Robbie Averill d4e58316e5 Merge pull request #1 from andrewandante/patch-1
FIX namespacing for BulkManager
2017-01-20 06:16:51 +13:00
Andrew Aitken-Fincham 279d47f43c FIX namespacing for BulkManager
This namespace changes once BulkManager gets updated to ss4.
2017-01-19 13:23:00 +00:00
Robbie Averill 7a92b0915d Remove deprecated@2.0. Update Migrate task to check table name. Minor tweaks to class names. Use Director::absoluteURL. 2017-01-17 17:39:06 +13:00
Robbie Averill 6aeab9f823 FIX Update upgrade mapping, add purifier back into composer and travis build 2017-01-17 16:56:30 +13:00
Robbie Averill ab3f35257b SS4 compatibility updates - ORM, Form, Controller changes
* Remove CommentList and replace with a polymorphic has_one relationship
* Tweaks for unit tests. Add tests for encode/decodeClassName.
2017-01-17 16:25:09 +13:00
Robbie Averill c698632aae SS4 compat: Update composer and YAML config, rename classes, update readme 2017-01-16 18:10:05 +13:00
257 changed files with 15248 additions and 8095 deletions

View File

@ -1,6 +1,6 @@
# For more information about the properties used in this file,
# please see the EditorConfig documentation:
# http://editorconfig.org
# For more information about the properties used in
# this file, please see the EditorConfig documentation:
# http://editorconfig.org/
[*]
charset = utf-8
@ -10,8 +10,17 @@ indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[{*.yml,package.json}]
indent_size = 2
[*.md]
trim_trailing_whitespace = false
# The indent size used in the package.json file cannot be changed:
# https://github.com/npm/npm/pull/3180#issuecomment-16336516
[*.{yml,js,json,css,scss,feature}]
indent_size = 2
indent_style = space
[composer.json]
indent_size = 4
# Don't perform any clean-up on thirdparty files
[thirdparty/**]
trim_trailing_whitespace = false
insert_final_newline = false

8
.eslintignore Normal file
View File

@ -0,0 +1,8 @@
# Ignore dist files
client/dist/
# Ignore legacy files
client/src/legacy/
# Ignore auto-generated language files
client/lang/

1
.eslintrc.js Normal file
View File

@ -0,0 +1 @@
module.exports = require('@silverstripe/eslint-config/.eslintrc');

1
.gitattributes vendored
View File

@ -4,3 +4,4 @@
/.gitignore export-ignore
/.travis.yml export-ignore
/.scrutinizer.yml export-ignore
/codecov.yml export-ignore

11
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,11 @@
name: CI
on:
push:
pull_request:
workflow_dispatch:
jobs:
ci:
name: CI
uses: silverstripe/gha-ci/.github/workflows/ci.yml@v1

16
.github/workflows/dispatch-ci.yml vendored Normal file
View File

@ -0,0 +1,16 @@
name: Dispatch CI
on:
# At 11:10 AM UTC, only on Wednesday and Thursday
schedule:
- cron: '10 11 * * 3,4'
jobs:
dispatch-ci:
name: Dispatch CI
# Only run cron on the silverstripe account
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
runs-on: ubuntu-latest
steps:
- name: Dispatch CI
uses: silverstripe/gha-dispatch-ci@v1

17
.github/workflows/keepalive.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: Keepalive
on:
workflow_dispatch:
# The 4th of every month at 10:50am UTC
schedule:
- cron: '50 10 4 * *'
jobs:
keepalive:
name: Keepalive
# Only run cron on the silverstripe account
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
runs-on: ubuntu-latest
steps:
- name: Keepalive
uses: silverstripe/gha-keepalive@v1

17
.github/workflows/update-js.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: Update JS
on:
workflow_dispatch:
# Run on a schedule of once per quarter
schedule:
- cron: '0 0 1 */3 *'
jobs:
update-js:
name: Update JS
# Only run cron on the silverstripe account
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
runs-on: ubuntu-latest
steps:
- name: Update JS
uses: silverstripe/gha-update-js@v1

2
.gitignore vendored
View File

@ -1 +1,3 @@
.sass-cache
/.php_cs.cache
/node_modules/

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
10

View File

@ -1,69 +0,0 @@
inherit: true
checks:
php:
verify_property_names: true
verify_argument_usable_as_reference: true
verify_access_scope_valid: true
useless_calls: true
use_statement_alias_conflict: true
variable_existence: true
unused_variables: true
unused_properties: true
unused_parameters: true
unused_methods: true
unreachable_code: true
too_many_arguments: true
sql_injection_vulnerabilities: true
simplify_boolean_return: true
side_effects_or_types: true
security_vulnerabilities: true
return_doc_comments: true
return_doc_comment_if_not_inferrable: true
require_scope_for_properties: true
require_scope_for_methods: true
require_php_tag_first: true
psr2_switch_declaration: true
psr2_class_declaration: true
property_assignments: true
prefer_while_loop_over_for_loop: true
precedence_mistakes: true
precedence_in_conditions: true
phpunit_assertions: true
php5_style_constructor: true
parse_doc_comments: true
parameter_non_unique: true
parameter_doc_comments: true
param_doc_comment_if_not_inferrable: true
optional_parameters_at_the_end: true
one_class_per_file: true
no_unnecessary_if: true
no_trailing_whitespace: true
no_property_on_interface: true
no_non_implemented_abstract_methods: true
no_error_suppression: true
no_duplicate_arguments: true
no_commented_out_code: true
newline_at_end_of_file: true
missing_arguments: true
method_calls_on_non_object: true
instanceof_class_exists: true
foreach_traversable: true
fix_line_ending: true
fix_doc_comments: true
duplication: true
deprecated_code_usage: true
deadlock_detection_in_loops: true
code_rating: true
closure_use_not_conflicting: true
catch_class_exists: true
blank_line_after_namespace_declaration: false
avoid_multiple_statements_on_same_line: true
avoid_duplicate_types: true
avoid_conflicting_incrementers: true
avoid_closing_tag: true
assignment_of_null_return: true
argument_type_checks: true
filter:
paths: [code/*, tests/*]

View File

@ -1,61 +0,0 @@
language: php
sudo: true
addons:
apt:
packages:
- tidy
php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
before_install:
- pip install --user codecov
env:
global:
- DB=MYSQL CORE_RELEASE=3.1
- MODULE_PATH=comments
# Set to 1 in the matrix to enable code coverage
- COVERAGE=0
matrix:
include:
- php: 5.6
#CommentsListTest breaks with this env: DB=MYSQL CORE_RELEASE=3.2 COVERAGE=1
env: DB=SQLITE CORE_RELEASE=3.2 COVERAGE=1
- php: 5.6
env: DB=MYSQL CORE_RELEASE=3
- php: 5.6
env: DB=MYSQL CORE_RELEASE=3.1
- php: 5.6
env: DB=PGSQL CORE_RELEASE=3.2
allow_failures:
- php: 7.0
before_script:
- phpenv rehash
- composer self-update || true
- git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support
# Install suggested modules in order to maximize test coverage
- php ~/travis-support/travis_setup.php --source `pwd` --target ~/builds/ss --require "ezyang/htmlpurifier:4.*,silverstripe/cms:~3.1"
- cd ~/builds/ss
script:
# Execute tests with no coverage. This is the fastest option
- "if [ \"$COVERAGE\" = \"0\" ]; then vendor/bin/phpunit $MODULE_PATH/tests/; fi"
# Execute tests with coverage. Do this for a small
- "if [ \"$COVERAGE\" = \"1\" ]; then vendor/bin/phpunit --coverage-clover=coverage.clover $MODULE_PATH/tests/; fi"
after_script:
- "if [ \"$COVERAGE\" = \"1\" ]; then mv coverage.clover ~/build/$TRAVIS_REPO_SLUG/; fi"
- cd ~/build/$TRAVIS_REPO_SLUG
- wget https://scrutinizer-ci.com/ocular.phar
- "if [ \"$COVERAGE\" = \"1\" ]; then travis_retry codecov && travis_retry php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi"

View File

@ -1,8 +1,9 @@
[main]
host = https://www.transifex.com
[silverstripe-comments.master]
[o:silverstripe:p:silverstripe-comments:r:master]
file_filter = lang/<lang>.yml
source_file = lang/en.yml
source_lang = en
type = YML
type = YML

25
.upgrade.yml Normal file
View File

@ -0,0 +1,25 @@
mappings:
CommentAdmin: SilverStripe\Comments\Admin\CommentAdmin
CommentsGridField: SilverStripe\Comments\Admin\CommentsGridField
CommentsGridFieldAction: SilverStripe\Comments\Admin\CommentsGridFieldAction
CommentsGridFieldBulkAction_Handlers: SilverStripe\Comments\Admin\CommentsGridFieldBulkAction\Handlers
CommentsGridFieldConfig: SilverStripe\Comments\Admin\CommentsGridFieldConfig
CommentingController: SilverStripe\Comments\Controllers\CommentingController
CommentsExtension: SilverStripe\Comments\Extensions\CommentsExtension
Comment: SilverStripe\Comments\Model\Comment
Comment_SecurityToken: SilverStripe\Comments\Model\Comment\SecurityToken
CommentAdminTest: SilverStripe\Comments\Tests\CommentAdminTest
CommentingControllerTest: SilverStripe\Comments\Tests\CommentingControllerTest
CommentingTest: SilverStripe\Comments\Tests\CommentingTest
CommentListTest: SilverStripe\Comments\Tests\CommentListTest
CommentsExtensionTest: SilverStripe\Comments\Tests\CommentsExtensionTest
CommentsGridFieldActionTest: SilverStripe\Comments\Tests\CommentsGridFieldActionTest
CommentsGridFieldBulkActionTest: SilverStripe\Comments\Tests\CommentsGridFieldBulkActionTest
CommentsGridFieldConfigTest: SilverStripe\Comments\Tests\CommentsGridFieldConfigTest
CommentsGridFieldTest: SilverStripe\Comments\Tests\CommentsGridFieldTest
CommentsTest: SilverStripe\Comments\Tests\CommentsTest
CommentableItem: SilverStripe\Comments\Tests\Stubs\CommentableItem
CommentableItemEnabled: SilverStripe\Comments\Tests\Stubs\CommentableItemEnabled
CommentableItemDisabled: SilverStripe\Comments\Tests\Stubs\CommentableItemDisabled
CommentableItem_Controller: SilverStripe\Comments\Tests\Stubs\CommentableItemController
CommentTestHelper: SilverStripe\Comments\Tests\CommentTestHelper

View File

@ -1,50 +1,31 @@
# Comments
[![Build Status](https://travis-ci.org/silverstripe/silverstripe-comments.svg?branch=master)](https://travis-ci.org/silverstripe/silverstripe-comments)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/silverstripe/silverstripe-comments/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/silverstripe/silverstripe-comments/?branch=master)
[![Code Coverage](https://scrutinizer-ci.com/g/silverstripe/silverstripe-comments/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/silverstripe/silverstripe-comments/?branch=master)
[![Build Status](https://scrutinizer-ci.com/g/silverstripe/silverstripe-comments/badges/build.png?b=master)](https://scrutinizer-ci.com/g/silverstripe/silverstripe-comments/build-status/master)
[![codecov.io](https://codecov.io/github/silverstripe/silverstripe-comments/coverage.svg?branch=master)](https://codecov.io/github/silverstripe/silverstripe-comments?branch=master)
[![Latest Stable Version](https://poser.pugx.org/silverstripe/comments/version)](https://packagist.org/packages/silverstripe/comments)
[![Latest Unstable Version](https://poser.pugx.org/silverstripe/comments/v/unstable)](//packagist.org/packages/silverstripe/comments)
[![Total Downloads](https://poser.pugx.org/silverstripe/comments/downloads)](https://packagist.org/packages/silverstripe/comments)
[![License](https://poser.pugx.org/silverstripe/comments/license)](https://packagist.org/packages/silverstripe/comments)
[![Monthly Downloads](https://poser.pugx.org/silverstripe/comments/d/monthly)](https://packagist.org/packages/silverstripe/comments)
[![Daily Downloads](https://poser.pugx.org/silverstripe/comments/d/daily)](https://packagist.org/packages/silverstripe/comments)
[![Dependency Status](https://www.versioneye.com/php/silverstripe:comments/badge.svg)](https://www.versioneye.com/php/silverstripe:comments)
[![Reference Status](https://www.versioneye.com/php/silverstripe:comments/reference_badge.svg?style=flat)](https://www.versioneye.com/php/silverstripe:comments/references)
![codecov.io](https://codecov.io/github/silverstripe/silverstripe-comments/branch.svg?branch=master)
![helpfulrobot](https://helpfulrobot.io/silverstripe/comments/badge)
[Changelog](CHANGELOG.md)
## Maintainers
* Will Rossiter (Nickname: willr, wrossiter)
<will at silverstripe dot com>
[![CI](https://github.com/silverstripe/silverstripe-comments/actions/workflows/ci.yml/badge.svg)](https://github.com/silverstripe/silverstripe-comments/actions/workflows/ci.yml)
[![Silverstripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/)
## Introduction
This module provides commenting functionality for Pages and other DataObjects
on your SilverStripe site.
This module provides commenting functionality for Pages and other DataObjects on your Silverstripe site.
For more documentation about the module see the provided documentation located
inside the docs folder.
For more documentation about the module see the provided documentation located inside the docs folder.
## Requirements
* SilverStripe 3.1
* Silverstripe ^4.0
**Note:** This branch is compatible with Silverstripe 4. For a Silverstripe 3 release, please see the 2.x release line.
## Installation
```
composer require silverstripe/comments
```
See docs/en/Installing.md
## Related
* [silverstripe/silverstripe-comments-notifications](https://github.com/silverstripe/silverstripe-comments-notifications): Comment admin email notifications module
* [silverstripe/comment-notifications](https://github.com/silverstripe/comment-notifications): Comment admin email notifications module
## Contributing
@ -58,4 +39,4 @@ and any new translations will be merged back to the project source code.
Please use https://www.transifex.com/projects/p/silverstripe-comments/ to contribute translations,
rather than sending pull requests with YAML files.
See the ["i18n" topic](http://doc.silverstripe.org/framework/en/trunk/topics/i18n) on doc.silverstripe.org for more details.
See the ["i18n" topic](https://docs.silverstripe.org/en/4/developer_guides/i18n/) on doc.silverstripe.org for more details.

View File

@ -1,6 +0,0 @@
<?php
Deprecation::notification_version('2.0', 'comments');
define('COMMENTS_DIR', basename(__DIR__));
define('COMMENTS_THIRDPARTY', COMMENTS_DIR . DIRECTORY_SEPARATOR . 'thirdparty');

View File

@ -4,6 +4,8 @@ Name: commentssitetree
only:
moduleexists: 'cms'
---
SiteTree:
SilverStripe\CMS\Model\SiteTree:
extensions:
comments: SilverStripe\Comments\Extensions\CommentsExtension
comments:
enabled_cms: true

3
_config/legacy.yml Normal file
View File

@ -0,0 +1,3 @@
SilverStripe\ORM\DatabaseAdmin:
classname_value_remapping:
Comment: SilverStripe\Comments\Model\Comment

View File

@ -2,9 +2,6 @@
Name: commentroutes
After: framework/routes#coreroutes
---
Director:
SilverStripe\Control\Director:
rules:
# handle old 2.4 style urls
'CommentingController//$Action/$ID/$OtherID': 'CommentingController'
'PageComments/$Action/$ID/$OtherID': 'CommentingController'
'PageComments_Controller/$Action/$ID/$OtherID': 'CommentingController'
comments: SilverStripe\Comments\Controllers\CommentingController

View File

@ -1,41 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [2.1.1]
* Update translations
## [2.1.0]
* BUG Fix missing hash change for #177
* BUG: Fix infinite loop in requireDefaultRecords()
* FIX: Redirect to a URL that does not indicate an error, style moderation method
* Reformat as PSR-2
* FIX: Layout with Gravatar fixed
* FIX: Non JS spam/ham/approve now redirect back to relevant comment
* ENHANCEMENT: Ajax spam/ham/approve/delete resurrected.
* FIX: Take account of spam/moderation status when enabling replies to a comment
* Minor: Turn off line numbers for generated CSS
* FIX: When viewing a comment permalink full comment and posting data shows
* MINOR: Update version of notifications module to one that is not deprecated
* FIX: Add missing parameters for nested comments to example configuration
## [2.0.3]
* Update documentation and configuration to supported module standard
* Increase test coverage from 54% to 92%
* Add cms as suggested module
* FIX: The AutoFormat.AutoParagraph injector of HTMLPurifier fails if the p tag is not allowed.
* FIX: Change creation of CreatedField to unchained as setName() method of DatetimeField is not chainable
## [2.0.2]
* Changelog added.
* Removed deprecated example configuration
* Handle when extension has been removed from object
* BUG Fix each gridfield having triple gridstate components
* Prevented duplicate IDs on action buttons
* Update translations

1
client/dist/js/CommentsInterface.js vendored Normal file
View File

@ -0,0 +1 @@
!function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s="./client/src/legacy/CommentsInterface.js")}({"./client/src/legacy/CommentsInterface.js":function(e,t,n){"use strict";(function(e){!function(e){e(function(){e.validator.methods.url=function(e,t){return this.optional(t)||/^(?:(?:(?:https?|ftp):)?\/\/)?(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[\/?#]\S*)?$/i.test(e)},e(".comments-holder-container form").each(function(){e(this).validate({ignore:":hidden",errorClass:"required",errorElement:"span",invalidHandler:function(t,n){e("html, body").animate({scrollTop:e(n.errorList[0].element).offset().top-30},200)},errorPlacement:function(e,t){e.addClass("message").insertAfter(t)}})}),e(".comment").children(".info").not(window.document.location.hash).nextAll(".comment-replies-container").children(".comment-reply-form-holder").hide(),e(".comments-holder").on("click",".comment-reply-link",function(t){var n=e(".comment-reply-form-holder"),r="#"+e(this).attr("aria-controls"),o=e(r).closest(".comment-reply-form-holder");e(this).attr("aria-expanded",function(e,t){return"true"==t?"false":"true"}),t.preventDefault(),o.is(":visible")?n.slideUp():(n.not(o).slideUp(),o.slideDown())}),e(".comments-holder .comments-list").on("click","div.comment-moderation-options a",function(t){t.stopPropagation();var n=e(this);if(n.hasClass("delete")){var r=ss.i18n._t("CommentsInterface_singlecomment_ss.DELETE_CONFIRMATION");if(!window.confirm(r))return t.preventDefault(),!1}var o=n.parents(".comment:first");e.ajax({url:e(this).attr("href"),cache:!1,success:function(t){n.hasClass("ham")?(o.html(t),o.removeClass("spam")):n.hasClass("approve")?(o.html(t),o.removeClass("unmoderated")):n.hasClass("delete")?o.fadeOut(1e3,function(){o.remove(),0===e(".comments-holder .comments-list").children().length&&e(".no-comments-yet").show()}):n.hasClass("spam")&&o.html(t).addClass("spam")},failure:function(e){var t=ss.i18n._t("CommentsInterface_singlecomment_ss.AJAX_ERROR");alert(t)}}),t.preventDefault()})})}(e)}).call(t,n(0))},0:function(e,t){e.exports=jQuery}});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return function(){function b(a){return a.replace(/<.[^<>]*?>/g," ").replace(/&nbsp;|&#160;/gi," ").replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g,"")}a.validator.addMethod("maxWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length<=d},a.validator.format("Please enter {0} words or less.")),a.validator.addMethod("minWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length>=d},a.validator.format("Please enter at least {0} words.")),a.validator.addMethod("rangeWords",function(a,c,d){var e=b(a),f=/\b\w+\b/g;return this.optional(c)||e.match(f).length>=d[0]&&e.match(f).length<=d[1]},a.validator.format("Please enter between {0} and {1} words."))}(),a.validator.addMethod("abaRoutingNumber",function(a){var b=0,c=a.split(""),d=c.length;if(9!==d)return!1;for(var e=0;e<d;e+=3)b+=3*parseInt(c[e],10)+7*parseInt(c[e+1],10)+parseInt(c[e+2],10);return 0!==b&&b%10===0},"Please enter a valid routing number."),a.validator.addMethod("accept",function(b,c,d){var e,f,g,h="string"==typeof d?d.replace(/\s/g,""):"image/*",i=this.optional(c);if(i)return i;if("file"===a(c).attr("type")&&(h=h.replace(/[\-\[\]\/\{\}\(\)\+\?\.\\\^\$\|]/g,"\\$&").replace(/,/g,"|").replace(/\/\*/g,"/.*"),c.files&&c.files.length))for(g=new RegExp(".?("+h+")$","i"),e=0;e<c.files.length;e++)if(f=c.files[e],!f.type.match(g))return!1;return!0},a.validator.format("Please enter a value with a valid mimetype.")),a.validator.addMethod("alphanumeric",function(a,b){return this.optional(b)||/^\w+$/i.test(a)},"Letters, numbers, and underscores only please"),a.validator.addMethod("bankaccountNL",function(a,b){if(this.optional(b))return!0;if(!/^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test(a))return!1;var c,d,e,f=a.replace(/ /g,""),g=0,h=f.length;for(c=0;c<h;c++)d=h-c,e=f.substring(c,c+1),g+=d*e;return g%11===0},"Please specify a valid bank account number"),a.validator.addMethod("bankorgiroaccountNL",function(b,c){return this.optional(c)||a.validator.methods.bankaccountNL.call(this,b,c)||a.validator.methods.giroaccountNL.call(this,b,c)},"Please specify a valid bank or giro account number"),a.validator.addMethod("bic",function(a,b){return this.optional(b)||/^([A-Z]{6}[A-Z2-9][A-NP-Z1-9])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test(a.toUpperCase())},"Please specify a valid BIC code"),a.validator.addMethod("cifES",function(a,b){"use strict";function c(a){return a%2===0}if(this.optional(b))return!0;var d,e,f,g,h=new RegExp(/^([ABCDEFGHJKLMNPQRSUVW])(\d{7})([0-9A-J])$/gi),i=a.substring(0,1),j=a.substring(1,8),k=a.substring(8,9),l=0,m=0,n=0;if(9!==a.length||!h.test(a))return!1;for(d=0;d<j.length;d++)e=parseInt(j[d],10),c(d)?(e*=2,n+=e<10?e:e-9):m+=e;return l=m+n,f=(10-l.toString().substr(-1)).toString(),f=parseInt(f,10)>9?"0":f,g="JABCDEFGHI".substr(f,1).toString(),i.match(/[ABEH]/)?k===f:i.match(/[KPQS]/)?k===g:k===f||k===g},"Please specify a valid CIF number."),a.validator.addMethod("cnhBR",function(a){if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;var b,c,d,e,f,g,h=0,i=0;if(b=a.charAt(0),new Array(12).join(b)===a)return!1;for(e=0,f=9,g=0;e<9;++e,--f)h+=+(a.charAt(e)*f);for(c=h%11,c>=10&&(c=0,i=2),h=0,e=0,f=1,g=0;e<9;++e,++f)h+=+(a.charAt(e)*f);return d=h%11,d>=10?d=0:d-=i,String(c).concat(d)===a.substr(-2)},"Please specify a valid CNH number"),a.validator.addMethod("cnpjBR",function(a,b){"use strict";if(this.optional(b))return!0;if(a=a.replace(/[^\d]+/g,""),14!==a.length)return!1;if("00000000000000"===a||"11111111111111"===a||"22222222222222"===a||"33333333333333"===a||"44444444444444"===a||"55555555555555"===a||"66666666666666"===a||"77777777777777"===a||"88888888888888"===a||"99999999999999"===a)return!1;for(var c=a.length-2,d=a.substring(0,c),e=a.substring(c),f=0,g=c-7,h=c;h>=1;h--)f+=d.charAt(c-h)*g--,g<2&&(g=9);var i=f%11<2?0:11-f%11;if(i!==parseInt(e.charAt(0),10))return!1;c+=1,d=a.substring(0,c),f=0,g=c-7;for(var j=c;j>=1;j--)f+=d.charAt(c-j)*g--,g<2&&(g=9);return i=f%11<2?0:11-f%11,i===parseInt(e.charAt(1),10)},"Please specify a CNPJ value number"),a.validator.addMethod("cpfBR",function(a,b){"use strict";if(this.optional(b))return!0;if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;var c,d,e,f,g=0;if(c=parseInt(a.substring(9,10),10),d=parseInt(a.substring(10,11),10),e=function(a,b){var c=10*a%11;return 10!==c&&11!==c||(c=0),c===b},""===a||"00000000000"===a||"11111111111"===a||"22222222222"===a||"33333333333"===a||"44444444444"===a||"55555555555"===a||"66666666666"===a||"77777777777"===a||"88888888888"===a||"99999999999"===a)return!1;for(f=1;f<=9;f++)g+=parseInt(a.substring(f-1,f),10)*(11-f);if(e(g,c)){for(g=0,f=1;f<=10;f++)g+=parseInt(a.substring(f-1,f),10)*(12-f);return e(g,d)}return!1},"Please specify a valid CPF number"),a.validator.addMethod("creditcard",function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},"Please enter a valid credit card number."),a.validator.addMethod("creditcardtypes",function(a,b,c){if(/[^0-9\-]+/.test(a))return!1;a=a.replace(/\D/g,"");var d=0;return c.mastercard&&(d|=1),c.visa&&(d|=2),c.amex&&(d|=4),c.dinersclub&&(d|=8),c.enroute&&(d|=16),c.discover&&(d|=32),c.jcb&&(d|=64),c.unknown&&(d|=128),c.all&&(d=255),1&d&&(/^(5[12345])/.test(a)||/^(2[234567])/.test(a))?16===a.length:2&d&&/^(4)/.test(a)?16===a.length:4&d&&/^(3[47])/.test(a)?15===a.length:8&d&&/^(3(0[012345]|[68]))/.test(a)?14===a.length:16&d&&/^(2(014|149))/.test(a)?15===a.length:32&d&&/^(6011)/.test(a)?16===a.length:64&d&&/^(3)/.test(a)?16===a.length:64&d&&/^(2131|1800)/.test(a)?15===a.length:!!(128&d)},"Please enter a valid credit card number."),a.validator.addMethod("currency",function(a,b,c){var d,e="string"==typeof c,f=e?c:c[0],g=!!e||c[1];return f=f.replace(/,/g,""),f=g?f+"]":f+"]?",d="^["+f+"([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$",d=new RegExp(d),this.optional(b)||d.test(a)},"Please specify a valid currency"),a.validator.addMethod("dateFA",function(a,b){return this.optional(b)||/^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(a)},a.validator.messages.date),a.validator.addMethod("dateITA",function(a,b){var c,d,e,f,g,h=!1,i=/^\d{1,2}\/\d{1,2}\/\d{4}$/;return i.test(a)?(c=a.split("/"),d=parseInt(c[0],10),e=parseInt(c[1],10),f=parseInt(c[2],10),g=new Date(Date.UTC(f,e-1,d,12,0,0,0)),h=g.getUTCFullYear()===f&&g.getUTCMonth()===e-1&&g.getUTCDate()===d):h=!1,this.optional(b)||h},a.validator.messages.date),a.validator.addMethod("dateNL",function(a,b){return this.optional(b)||/^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(a)},a.validator.messages.date),a.validator.addMethod("extension",function(a,b,c){return c="string"==typeof c?c.replace(/,/g,"|"):"png|jpe?g|gif",this.optional(b)||a.match(new RegExp("\\.("+c+")$","i"))},a.validator.format("Please enter a value with a valid extension.")),a.validator.addMethod("giroaccountNL",function(a,b){return this.optional(b)||/^[0-9]{1,7}$/.test(a)},"Please specify a valid giro account number"),a.validator.addMethod("greaterThan",function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-greaterThan-blur").length&&e.addClass("validate-greaterThan-blur").on("blur.validate-greaterThan",function(){a(c).valid()}),b>e.val()},"Please enter a greater value."),a.validator.addMethod("greaterThanEqual",function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-greaterThanEqual-blur").length&&e.addClass("validate-greaterThanEqual-blur").on("blur.validate-greaterThanEqual",function(){a(c).valid()}),b>=e.val()},"Please enter a greater value."),a.validator.addMethod("iban",function(a,b){if(this.optional(b))return!0;var c,d,e,f,g,h,i,j,k,l=a.replace(/ /g,"").toUpperCase(),m="",n=!0,o="",p="",q=5;if(l.length<q)return!1;if(c=l.substring(0,2),h={AL:"\\d{8}[\\dA-Z]{16}",AD:"\\d{8}[\\dA-Z]{12}",AT:"\\d{16}",AZ:"[\\dA-Z]{4}\\d{20}",BE:"\\d{12}",BH:"[A-Z]{4}[\\dA-Z]{14}",BA:"\\d{16}",BR:"\\d{23}[A-Z][\\dA-Z]",BG:"[A-Z]{4}\\d{6}[\\dA-Z]{8}",CR:"\\d{17}",HR:"\\d{17}",CY:"\\d{8}[\\dA-Z]{16}",CZ:"\\d{20}",DK:"\\d{14}",DO:"[A-Z]{4}\\d{20}",EE:"\\d{16}",FO:"\\d{14}",FI:"\\d{14}",FR:"\\d{10}[\\dA-Z]{11}\\d{2}",GE:"[\\dA-Z]{2}\\d{16}",DE:"\\d{18}",GI:"[A-Z]{4}[\\dA-Z]{15}",GR:"\\d{7}[\\dA-Z]{16}",GL:"\\d{14}",GT:"[\\dA-Z]{4}[\\dA-Z]{20}",HU:"\\d{24}",IS:"\\d{22}",IE:"[\\dA-Z]{4}\\d{14}",IL:"\\d{19}",IT:"[A-Z]\\d{10}[\\dA-Z]{12}",KZ:"\\d{3}[\\dA-Z]{13}",KW:"[A-Z]{4}[\\dA-Z]{22}",LV:"[A-Z]{4}[\\dA-Z]{13}",LB:"\\d{4}[\\dA-Z]{20}",LI:"\\d{5}[\\dA-Z]{12}",LT:"\\d{16}",LU:"\\d{3}[\\dA-Z]{13}",MK:"\\d{3}[\\dA-Z]{10}\\d{2}",MT:"[A-Z]{4}\\d{5}[\\dA-Z]{18}",MR:"\\d{23}",MU:"[A-Z]{4}\\d{19}[A-Z]{3}",MC:"\\d{10}[\\dA-Z]{11}\\d{2}",MD:"[\\dA-Z]{2}\\d{18}",ME:"\\d{18}",NL:"[A-Z]{4}\\d{10}",NO:"\\d{11}",PK:"[\\dA-Z]{4}\\d{16}",PS:"[\\dA-Z]{4}\\d{21}",PL:"\\d{24}",PT:"\\d{21}",RO:"[A-Z]{4}[\\dA-Z]{16}",SM:"[A-Z]\\d{10}[\\dA-Z]{12}",SA:"\\d{2}[\\dA-Z]{18}",RS:"\\d{18}",SK:"\\d{20}",SI:"\\d{15}",ES:"\\d{20}",SE:"\\d{20}",CH:"\\d{5}[\\dA-Z]{12}",TN:"\\d{20}",TR:"\\d{5}[\\dA-Z]{17}",AE:"\\d{3}\\d{16}",GB:"[A-Z]{4}\\d{14}",VG:"[\\dA-Z]{4}\\d{16}"},g=h[c],"undefined"!=typeof g&&(i=new RegExp("^[A-Z]{2}\\d{2}"+g+"$",""),!i.test(l)))return!1;for(d=l.substring(4,l.length)+l.substring(0,4),j=0;j<d.length;j++)e=d.charAt(j),"0"!==e&&(n=!1),n||(m+="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(e));for(k=0;k<m.length;k++)f=m.charAt(k),p=""+o+f,o=p%97;return 1===o},"Please specify a valid IBAN"),a.validator.addMethod("integer",function(a,b){return this.optional(b)||/^-?\d+$/.test(a)},"A positive or negative non-decimal number please"),a.validator.addMethod("ipv4",function(a,b){return this.optional(b)||/^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test(a)},"Please enter a valid IP v4 address."),a.validator.addMethod("ipv6",function(a,b){return this.optional(b)||/^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(a)},"Please enter a valid IP v6 address."),a.validator.addMethod("lessThan",function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-lessThan-blur").length&&e.addClass("validate-lessThan-blur").on("blur.validate-lessThan",function(){a(c).valid()}),b<e.val()},"Please enter a lesser value."),a.validator.addMethod("lessThanEqual",function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-lessThanEqual-blur").length&&e.addClass("validate-lessThanEqual-blur").on("blur.validate-lessThanEqual",function(){a(c).valid()}),b<=e.val()},"Please enter a lesser value."),a.validator.addMethod("lettersonly",function(a,b){return this.optional(b)||/^[a-z]+$/i.test(a)},"Letters only please"),a.validator.addMethod("letterswithbasicpunc",function(a,b){return this.optional(b)||/^[a-z\-.,()'"\s]+$/i.test(a)},"Letters or punctuation only please"),a.validator.addMethod("maxfiles",function(b,c,d){return!!this.optional(c)||!("file"===a(c).attr("type")&&c.files&&c.files.length>d)},a.validator.format("Please select no more than {0} files.")),a.validator.addMethod("maxsize",function(b,c,d){if(this.optional(c))return!0;if("file"===a(c).attr("type")&&c.files&&c.files.length)for(var e=0;e<c.files.length;e++)if(c.files[e].size>d)return!1;return!0},a.validator.format("File size must not exceed {0} bytes each.")),a.validator.addMethod("maxsizetotal",function(b,c,d){if(this.optional(c))return!0;if("file"===a(c).attr("type")&&c.files&&c.files.length)for(var e=0,f=0;f<c.files.length;f++)if(e+=c.files[f].size,e>d)return!1;return!0},a.validator.format("Total size of all files must not exceed {0} bytes.")),a.validator.addMethod("mobileNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid mobile number"),a.validator.addMethod("mobileRU",function(a,b){var c=a.replace(/\(|\)|\s+|-/g,"");return this.optional(b)||c.length>9&&/^((\+7|7|8)+([0-9]){10})$/.test(c)},"Please specify a valid mobile number"),a.validator.addMethod("mobileUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/)},"Please specify a valid mobile number"),a.validator.addMethod("netmask",function(a,b){return this.optional(b)||/^(254|252|248|240|224|192|128)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(254|252|248|240|224|192|128|0)/i.test(a)},"Please enter a valid netmask."),a.validator.addMethod("nieES",function(a,b){"use strict";if(this.optional(b))return!0;var c,d=new RegExp(/^[MXYZ]{1}[0-9]{7,8}[TRWAGMYFPDXBNJZSQVHLCKET]{1}$/gi),e="TRWAGMYFPDXBNJZSQVHLCKET",f=a.substr(a.length-1).toUpperCase();return a=a.toString().toUpperCase(),!(a.length>10||a.length<9||!d.test(a))&&(a=a.replace(/^[X]/,"0").replace(/^[Y]/,"1").replace(/^[Z]/,"2"),c=9===a.length?a.substr(0,8):a.substr(0,9),e.charAt(parseInt(c,10)%23)===f)},"Please specify a valid NIE number."),a.validator.addMethod("nifES",function(a,b){"use strict";return!!this.optional(b)||(a=a.toUpperCase(),!!a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")&&(/^[0-9]{8}[A-Z]{1}$/.test(a)?"TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,0)%23)===a.charAt(8):!!/^[KLM]{1}/.test(a)&&a[8]==="TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,1)%23)))},"Please specify a valid NIF number."),a.validator.addMethod("nipPL",function(a){"use strict";if(a=a.replace(/[^0-9]/g,""),10!==a.length)return!1;for(var b=[6,5,7,2,3,4,5,6,7],c=0,d=0;d<9;d++)c+=b[d]*a[d];var e=c%11,f=10===e?0:e;return f===parseInt(a[9],10)},"Please specify a valid NIP number."),a.validator.addMethod("nisBR",function(a){var b,c,d,e,f,g=0;if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;for(c=parseInt(a.substring(10,11),10),b=parseInt(a.substring(0,10),10),e=2;e<12;e++)f=e,10===e&&(f=2),11===e&&(f=3),g+=b%10*f,b=parseInt(b/10,10);return d=g%11,d=d>1?11-d:0,c===d},"Please specify a valid NIS/PIS number"),a.validator.addMethod("notEqualTo",function(b,c,d){return this.optional(c)||!a.validator.methods.equalTo.call(this,b,c,d)},"Please enter a different value, values must not be the same."),a.validator.addMethod("nowhitespace",function(a,b){return this.optional(b)||/^\S+$/i.test(a)},"No white space please"),a.validator.addMethod("pattern",function(a,b,c){return!!this.optional(b)||("string"==typeof c&&(c=new RegExp("^(?:"+c+")$")),c.test(a))},"Invalid format."),a.validator.addMethod("phoneNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid phone number."),a.validator.addMethod("phonePL",function(a,b){a=a.replace(/\s+/g,"");var c=/^(?:(?:(?:\+|00)?48)|(?:\(\+?48\)))?(?:1[2-8]|2[2-69]|3[2-49]|4[1-68]|5[0-9]|6[0-35-9]|[7-8][1-9]|9[145])\d{7}$/;return this.optional(b)||c.test(a)},"Please specify a valid phone number"),a.validator.addMethod("phonesUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/)},"Please specify a valid uk phone number"),a.validator.addMethod("phoneUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/)},"Please specify a valid phone number"),a.validator.addMethod("phoneUS",function(a,b){return a=a.replace(/\s+/g,""),this.optional(b)||a.length>9&&a.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]\d{2}-?\d{4}$/)},"Please specify a valid phone number"),a.validator.addMethod("postalcodeBR",function(a,b){return this.optional(b)||/^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test(a)},"Informe um CEP válido."),a.validator.addMethod("postalCodeCA",function(a,b){return this.optional(b)||/^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeIT",function(a,b){return this.optional(b)||/^\d{5}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeNL",function(a,b){return this.optional(b)||/^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postcodeUK",function(a,b){return this.optional(b)||/^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(a)},"Please specify a valid UK postcode"),a.validator.addMethod("require_from_group",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_req_grp")?f.data("valid_req_grp"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length>=d[0];return f.data("valid_req_grp",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),h},a.validator.format("Please fill at least {0} of these fields.")),a.validator.addMethod("skip_or_fill_minimum",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_skip")?f.data("valid_skip"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length,i=0===h||h>=d[0];return f.data("valid_skip",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),i},a.validator.format("Please either skip these fields or fill at least {0} of them.")),a.validator.addMethod("stateUS",function(a,b,c){var d,e="undefined"==typeof c,f=!e&&"undefined"!=typeof c.caseSensitive&&c.caseSensitive,g=!e&&"undefined"!=typeof c.includeTerritories&&c.includeTerritories,h=!e&&"undefined"!=typeof c.includeMilitary&&c.includeMilitary;return d=g||h?g&&h?"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":g?"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$":"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$",d=f?new RegExp(d):new RegExp(d,"i"),this.optional(b)||d.test(a)},"Please specify a valid state"),a.validator.addMethod("strippedminlength",function(b,c,d){return a(b).text().length>=d},a.validator.format("Please enter at least {0} characters")),a.validator.addMethod("time",function(a,b){return this.optional(b)||/^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test(a)},"Please enter a valid time, between 00:00 and 23:59"),a.validator.addMethod("time12h",function(a,b){return this.optional(b)||/^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(a)},"Please enter a valid time in 12-hour am/pm format"),a.validator.addMethod("url2",function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},a.validator.messages.url),a.validator.addMethod("vinUS",function(a){if(17!==a.length)return!1;var b,c,d,e,f,g,h=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"],i=[1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9],j=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2],k=0;for(b=0;b<17;b++){if(e=j[b],d=a.slice(b,b+1),8===b&&(g=d),isNaN(d)){for(c=0;c<h.length;c++)if(d.toUpperCase()===h[c]){d=i[c],d*=e,isNaN(g)&&8===c&&(g=h[c]);break}}else d*=e;k+=d}return f=k%11,10===f&&(f="X"),f===g},"The specified vehicle identification number (VIN) is invalid."),a.validator.addMethod("zipcodeUS",function(a,b){return this.optional(b)||/^\d{5}(-\d{4})?$/.test(a)},"The specified US ZIP Code is invalid"),a.validator.addMethod("ziprange",function(a,b){return this.optional(b)||/^90[2-5]\d\{2\}-\d{4}$/.test(a)},"Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx"),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.on("click.validate",":submit",function(b){c.submitButton=b.currentTarget,a(this).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(this).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.on("submit.validate",function(b){function d(){var d,e;return c.submitButton&&(c.settings.submitHandler||c.formSubmitted)&&(d=a("<input type='hidden'/>").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),!(c.settings.submitHandler&&!c.settings.debug)||(e=c.settings.submitHandler.call(c,c.currentForm,b),d&&d.remove(),void 0!==e&&e)}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,b||(d=d.concat(c.errorList))}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0],k="undefined"!=typeof this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=j&&(!j.form&&k&&(j.form=this.closest("form")[0],j.name=this.attr("name")),null!=j.form)){if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(a,b){i[b]=f[b],delete f[b]}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g)),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}});var b=function(a){return a.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")};a.extend(a.expr.pseudos||a.expr[":"],{blank:function(c){return!b(""+a(c).val())},filled:function(c){var d=a(c).val();return null!==d&&!!b(""+d)},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:void 0===c?b:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",pendingClass:"pending",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||a.inArray(c.keyCode,d)!==-1||(b.name in this.submitted||b.name in this.invalid)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}."),step:a.validator.format("Please enter a multiple of {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){var c="undefined"!=typeof a(this).attr("contenteditable")&&"false"!==a(this).attr("contenteditable");if(!this.form&&c&&(this.form=a(this).closest("form")[0],this.name=a(this).attr("name")),d===this.form){var e=a.data(this.form,"validator"),f="on"+b.type.replace(/^validate/,""),g=e.settings;g[f]&&!a(this).is(g.ignore)&&g[f].call(e,this,b)}}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.currentForm,e=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){e[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox'], [contenteditable], [type='button']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c,d,e=this.clean(b),f=this.validationTargetFor(e),g=this,h=!0;return void 0===f?delete this.invalid[e.name]:(this.prepareElement(f),this.currentElements=a(f),d=this.groups[f.name],d&&a.each(this.groups,function(a,b){b===d&&a!==f.name&&(e=g.validationTargetFor(g.clean(g.findByName(a))),e&&e.name in g.invalid&&(g.currentElements.push(e),h=g.check(e)&&h))}),c=this.check(f)!==!1,h=h&&c,c?this.invalid[f.name]=!1:this.invalid[f.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),a(b).attr("aria-invalid",!c)),h},showErrors:function(b){if(b){var c=this;a.extend(this.errorMap,b),this.errorList=a.map(this.errorMap,function(a,b){return{message:a,element:c.findByName(b)[0]}}),this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.invalid={},this.submitted={},this.prepareForm(),this.hideErrors();var b=this.elements().removeData("previousValue").removeAttr("aria-invalid");this.resetElements(b)},resetElements:function(a){var b;if(this.settings.unhighlight)for(b=0;a[b];b++)this.settings.unhighlight.call(this,a[b],this.settings.errorClass,""),this.findByName(a[b].name).removeClass(this.settings.validClass);else a.removeClass(this.settings.errorClass).removeClass(this.settings.validClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)void 0!==a[b]&&null!==a[b]&&a[b]!==!1&&c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").trigger("focus").trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea, [contenteditable]").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){var d=this.name||a(this).attr("name"),e="undefined"!=typeof a(this).attr("contenteditable")&&"false"!==a(this).attr("contenteditable");return!d&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),e&&(this.form=a(this).closest("form")[0],this.name=d),this.form===b.currentForm&&(!(d in c||!b.objectLength(a(this).rules()))&&(c[d]=!0,!0))})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},resetInternals:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([])},reset:function(){this.resetInternals(),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d,e=a(b),f=b.type,g="undefined"!=typeof e.attr("contenteditable")&&"false"!==e.attr("contenteditable");return"radio"===f||"checkbox"===f?this.findByName(b.name).filter(":checked").val():"number"===f&&"undefined"!=typeof b.validity?b.validity.badInput?"NaN":e.val():(c=g?e.text():e.val(),"file"===f?"C:\\fakepath\\"===c.substr(0,12)?c.substr(12):(d=c.lastIndexOf("/"),d>=0?c.substr(d+1):(d=c.lastIndexOf("\\"),d>=0?c.substr(d+1):c)):"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f,g=a(b).rules(),h=a.map(g,function(a,b){return b}).length,i=!1,j=this.elementValue(b);"function"==typeof g.normalizer?f=g.normalizer:"function"==typeof this.settings.normalizer&&(f=this.settings.normalizer),f&&(j=f.call(b,j),delete g.normalizer);for(d in g){e={method:d,parameters:g[d]};try{if(c=a.validator.methods[d].call(this,j,b,e.parameters),"dependency-mismatch"===c&&1===h){i=!0;continue}if(i=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(k){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",k),k instanceof TypeError&&(k.message+=". Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),k}}if(!i)return this.objectLength(g)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(void 0!==arguments[a])return arguments[a]},defaultMessage:function(b,c){"string"==typeof c&&(c={method:c});var d=this.findDefined(this.customMessage(b.name,c.method),this.customDataMessage(b,c.method),!this.settings.ignoreTitle&&b.title||void 0,a.validator.messages[c.method],"<strong>Warning: No message defined for "+b.name+"</strong>"),e=/\$?\{(\d+)\}/g;return"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),d},formatAndAdd:function(a,b){var c=this.defaultMessage(a,b);this.errorList.push({message:c,element:a,method:b.method}),this.errorMap[a.name]=c,this.submitted[a.name]=c},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g,h=this.errorsFor(b),i=this.idOrName(b),j=a(b).attr("aria-describedby");h.length?(h.removeClass(this.settings.validClass).addClass(this.settings.errorClass),h.html(c)):(h=a("<"+this.settings.errorElement+">").attr("id",i+"-error").addClass(this.settings.errorClass).html(c||""),d=h,this.settings.wrapper&&(d=h.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement.call(this,d,a(b)):d.insertAfter(b),h.is("label")?h.attr("for",i):0===h.parents("label[for='"+this.escapeCssMeta(i)+"']").length&&(f=h.attr("id"),j?j.match(new RegExp("\\b"+this.escapeCssMeta(f)+"\\b"))||(j+=" "+f):j=f,a(b).attr("aria-describedby",j),e=this.groups[b.name],e&&(g=this,a.each(g.groups,function(b,c){c===e&&a("[name='"+g.escapeCssMeta(b)+"']",g.currentForm).attr("aria-describedby",h.attr("id"))})))),!c&&this.settings.success&&(h.text(""),"string"==typeof this.settings.success?h.addClass(this.settings.success):this.settings.success(h,b)),this.toShow=this.toShow.add(h)},errorsFor:function(b){var c=this.escapeCssMeta(this.idOrName(b)),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+this.escapeCssMeta(d).replace(/\s+/g,", #")),this.errors().filter(e)},escapeCssMeta:function(a){return a.replace(/([\\!"#$%&'()*+,.\/:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+this.escapeCssMeta(b)+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return!this.dependTypes[typeof a]||this.dependTypes[typeof a](a,b)},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(b){this.pending[b.name]||(this.pendingRequest++,a(b).addClass(this.settings.pendingClass),this.pending[b.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],a(b).removeClass(this.settings.pendingClass),c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.submitButton&&a("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b,c){return c="string"==typeof c&&c||"remote",a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,{method:c})})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max|step/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),""===d&&(d=!0),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0===e.param||e.param:(a.data(c.form,"validator").resetElements(a(c)),delete b[d])}}),a.each(b,function(a,d){b[a]="function"==typeof d&&"normalizer"!==a?d(c):d}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var a;b[this]&&(Array.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(a=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(a[0]),Number(a[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:void 0!==b&&null!==b&&b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[\/?#]\S*)?$/i.test(a)},date:function(){var a=!1;return function(b,c){return a||(a=!0,this.settings.debug&&window.console&&console.warn("The `date` method is deprecated and will be removed in version '2.0.0'.\nPlease don't use it, since it relies on the Date constructor, which\nbehaves very differently across browsers and locales. Use `dateISO`\ninstead or one of the locale specific methods in `localizations/`\nand `additional-methods.js`.")),this.optional(c)||!/Invalid|NaN/.test(new Date(b).toString())}}(),dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},minlength:function(a,b,c){var d=Array.isArray(a)?a.length:this.getLength(a,b);return this.optional(b)||d>=c},maxlength:function(a,b,c){var d=Array.isArray(a)?a.length:this.getLength(a,b);return this.optional(b)||d<=c},rangelength:function(a,b,c){var d=Array.isArray(a)?a.length:this.getLength(a,b);return this.optional(b)||d>=c[0]&&d<=c[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||a<=c},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},step:function(b,c,d){var e,f=a(c).attr("type"),g="Step attribute on input type "+f+" is not supported.",h=["text","number","range"],i=new RegExp("\\b"+f+"\\b"),j=f&&!i.test(h.join()),k=function(a){var b=(""+a).match(/(?:\.(\d+))?$/);return b&&b[1]?b[1].length:0},l=function(a){return Math.round(a*Math.pow(10,e))},m=!0;if(j)throw new Error(g);return e=k(d),(k(b)>e||l(b)%l(d)!==0)&&(m=!1),this.optional(c)||m},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-equalTo-blur").length&&e.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d,e){if(this.optional(c))return"dependency-mismatch";e="string"==typeof e&&e||"remote";var f,g,h,i=this.previousValue(c,e);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),i.originalMessage=i.originalMessage||this.settings.messages[c.name][e],this.settings.messages[c.name][e]=i.message,d="string"==typeof d&&{url:d}||d,h=a.param(a.extend({data:b},d.data)),i.old===h?i.valid:(i.old=h,f=this,this.startRequest(c),g={},g[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:g,context:f.currentForm,success:function(a){var d,g,h,j=a===!0||"true"===a;f.settings.messages[c.name][e]=i.originalMessage,j?(h=f.formSubmitted,f.resetInternals(),f.toHide=f.errorsFor(c),f.formSubmitted=h,f.successList.push(c),f.invalid[c.name]=!1,f.showErrors()):(d={},g=a||f.defaultMessage(c,{method:e,parameters:b}),d[c.name]=i.message=g,f.invalid[c.name]=!0,f.showErrors(d)),i.valid=j,f.stopRequest(c,j)}},d)),"pending")}}});var c,d={};return a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,c){var e=a.port;"abort"===a.mode&&(d[e]&&d[e].abort(),d[e]=c)}):(c=a.ajax,a.ajax=function(b){var e=("mode"in b?b:a.ajaxSettings).mode,f=("port"in b?b:a.ajaxSettings).port;return"abort"===e?(d[f]&&d[f].abort(),d[f]=c.apply(this,arguments),d[f]):c.apply(this,arguments)}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"هذا الحقل إلزامي",remote:"يرجى تصحيح هذا الحقل للمتابعة",email:"رجاء إدخال عنوان بريد إلكتروني صحيح",url:"رجاء إدخال عنوان موقع إلكتروني صحيح",date:"رجاء إدخال تاريخ صحيح",dateISO:"رجاء إدخال تاريخ صحيح (ISO)",number:"رجاء إدخال عدد بطريقة صحيحة",digits:"رجاء إدخال أرقام فقط",creditcard:"رجاء إدخال رقم بطاقة ائتمان صحيح",equalTo:"رجاء إدخال نفس القيمة",extension:"رجاء إدخال ملف بامتداد موافق عليه",maxlength:a.validator.format("الحد الأقصى لعدد الحروف هو {0}"),minlength:a.validator.format("الحد الأدنى لعدد الحروف هو {0}"),rangelength:a.validator.format("عدد الحروف يجب أن يكون بين {0} و {1}"),range:a.validator.format("رجاء إدخال عدد قيمته بين {0} و {1}"),max:a.validator.format("رجاء إدخال عدد أقل من أو يساوي {0}"),min:a.validator.format("رجاء إدخال عدد أكبر من أو يساوي {0}")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Bu xana mütləq doldurulmalıdır.",remote:"Zəhmət olmasa, düzgün məna daxil edin.",email:"Zəhmət olmasa, düzgün elektron poçt daxil edin.",url:"Zəhmət olmasa, düzgün URL daxil edin.",date:"Zəhmət olmasa, düzgün tarix daxil edin.",dateISO:"Zəhmət olmasa, düzgün ISO formatlı tarix daxil edin.",number:"Zəhmət olmasa, düzgün rəqəm daxil edin.",digits:"Zəhmət olmasa, yalnız rəqəm daxil edin.",creditcard:"Zəhmət olmasa, düzgün kredit kart nömrəsini daxil edin.",equalTo:"Zəhmət olmasa, eyni mənanı bir daha daxil edin.",extension:"Zəhmət olmasa, düzgün genişlənməyə malik faylı seçin.",maxlength:a.validator.format("Zəhmət olmasa, {0} simvoldan çox olmayaraq daxil edin."),minlength:a.validator.format("Zəhmət olmasa, {0} simvoldan az olmayaraq daxil edin."),rangelength:a.validator.format("Zəhmət olmasa, {0} - {1} aralığında uzunluğa malik simvol daxil edin."),range:a.validator.format("Zəhmət olmasa, {0} - {1} aralığında rəqəm daxil edin."),max:a.validator.format("Zəhmət olmasa, {0} və ondan kiçik rəqəm daxil edin."),min:a.validator.format("Zəhmət olmasa, {0} və ondan böyük rəqəm daxil edin")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Полето е задължително.",remote:"Моля, въведете правилната стойност.",email:"Моля, въведете валиден email.",url:"Моля, въведете валидно URL.",date:"Моля, въведете валидна дата.",dateISO:"Моля, въведете валидна дата (ISO).",number:"Моля, въведете валиден номер.",digits:"Моля, въведете само цифри.",creditcard:"Моля, въведете валиден номер на кредитна карта.",equalTo:"Моля, въведете същата стойност отново.",extension:"Моля, въведете стойност с валидно разширение.",maxlength:a.validator.format("Моля, въведете не повече от {0} символа."),minlength:a.validator.format("Моля, въведете поне {0} символа."),rangelength:a.validator.format("Моля, въведете стойност с дължина между {0} и {1} символа."),range:a.validator.format("Моля, въведете стойност между {0} и {1}."),max:a.validator.format("Моля, въведете стойност по-малка или равна на {0}."),min:a.validator.format("Моля, въведете стойност по-голяма или равна на {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"এই তথ্যটি আবশ্যক।",remote:"এই তথ্যটি ঠিক করুন।",email:"অনুগ্রহ করে একটি সঠিক মেইল ঠিকানা লিখুন।",url:"অনুগ্রহ করে একটি সঠিক লিঙ্ক দিন।",date:"তারিখ সঠিক নয়।",dateISO:"অনুগ্রহ করে একটি সঠিক (ISO) তারিখ লিখুন।",number:"অনুগ্রহ করে একটি সঠিক নম্বর লিখুন।",digits:"এখানে শুধু সংখ্যা ব্যবহার করা যাবে।",creditcard:"অনুগ্রহ করে একটি ক্রেডিট কার্ডের সঠিক নম্বর লিখুন।",equalTo:"একই মান আবার লিখুন।",extension:"সঠিক ধরনের ফাইল আপলোড করুন।",maxlength:a.validator.format("{0}টির বেশি অক্ষর লেখা যাবে না।"),minlength:a.validator.format("{0}টির কম অক্ষর লেখা যাবে না।"),rangelength:a.validator.format("{0} থেকে {1} টি অক্ষর সম্বলিত মান লিখুন।"),range:a.validator.format("{0} থেকে {1} এর মধ্যে একটি মান ব্যবহার করুন।"),max:a.validator.format("অনুগ্রহ করে {0} বা তার চাইতে কম মান ব্যবহার করুন।"),min:a.validator.format("অনুগ্রহ করে {0} বা তার চাইতে বেশি মান ব্যবহার করুন।")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Aquest camp és obligatori.",remote:"Si us plau, omple aquest camp.",email:"Si us plau, escriu una adreça de correu-e vàlida",url:"Si us plau, escriu una URL vàlida.",date:"Si us plau, escriu una data vàlida.",dateISO:"Si us plau, escriu una data (ISO) vàlida.",number:"Si us plau, escriu un número enter vàlid.",digits:"Si us plau, escriu només dígits.",creditcard:"Si us plau, escriu un número de tarjeta vàlid.",equalTo:"Si us plau, escriu el mateix valor de nou.",extension:"Si us plau, escriu un valor amb una extensió acceptada.",maxlength:a.validator.format("Si us plau, no escriguis més de {0} caracters."),minlength:a.validator.format("Si us plau, no escriguis menys de {0} caracters."),rangelength:a.validator.format("Si us plau, escriu un valor entre {0} i {1} caracters."),range:a.validator.format("Si us plau, escriu un valor entre {0} i {1}."),max:a.validator.format("Si us plau, escriu un valor menor o igual a {0}."),min:a.validator.format("Si us plau, escriu un valor major o igual a {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Tento údaj je povinný.",remote:"Prosím, opravte tento údaj.",email:"Prosím, zadejte platný e-mail.",url:"Prosím, zadejte platné URL.",date:"Prosím, zadejte platné datum.",dateISO:"Prosím, zadejte platné datum (ISO).",number:"Prosím, zadejte číslo.",digits:"Prosím, zadávejte pouze číslice.",creditcard:"Prosím, zadejte číslo kreditní karty.",equalTo:"Prosím, zadejte znovu stejnou hodnotu.",extension:"Prosím, zadejte soubor se správnou příponou.",maxlength:a.validator.format("Prosím, zadejte nejvíce {0} znaků."),minlength:a.validator.format("Prosím, zadejte nejméně {0} znaků."),rangelength:a.validator.format("Prosím, zadejte od {0} do {1} znaků."),range:a.validator.format("Prosím, zadejte hodnotu od {0} do {1}."),max:a.validator.format("Prosím, zadejte hodnotu menší nebo rovnu {0}."),min:a.validator.format("Prosím, zadejte hodnotu větší nebo rovnu {0}."),step:a.validator.format("Musí být násobkem čísla {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Dette felt er påkrævet.",remote:"Ret venligst dette felt",email:"Indtast en gyldig email-adresse.",url:"Indtast en gyldig URL.",date:"Indtast en gyldig dato.",number:"Indtast et tal.",digits:"Indtast kun cifre.",creditcard:"Indtast et gyldigt kreditkortnummer.",equalTo:"Indtast den samme værdi igen.",time:"Angiv en gyldig tid mellem kl. 00:00 og 23:59.",ipv4:"Angiv venligst en gyldig IPv4-adresse.",ipv6:"Angiv venligst en gyldig IPv6-adresse.",require_from_group:a.validator.format("Angiv mindst {0} af disse felter."),extension:"Indtast venligst en værdi med en gyldig endelse",pattern:"Ugyldigt format",lettersonly:"Angiv venligst kun bogstaver.",nowhitespace:"Må ikke indholde mellemrum",maxlength:a.validator.format("Indtast højst {0} tegn."),minlength:a.validator.format("Indtast mindst {0} tegn."),rangelength:a.validator.format("Indtast mindst {0} og højst {1} tegn."),range:a.validator.format("Angiv en værdi mellem {0} og {1}."),max:a.validator.format("Angiv en værdi der højst er {0}."),min:a.validator.format("Angiv en værdi der mindst er {0}."),minWords:a.validator.format("Indtast venligst mindst {0} ord"),maxWords:a.validator.format("Indtast venligst højst {0} ord"),step:a.validator.format("Angiv en værdi gange {0}."),notEqualTo:"Angiv en anden værdi, værdierne må ikke være det samme.",integer:"Angiv et ikke-decimaltal, der er positivt eller negativt."}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Dieses Feld ist ein Pflichtfeld.",maxlength:a.validator.format("Geben Sie bitte maximal {0} Zeichen ein."),minlength:a.validator.format("Geben Sie bitte mindestens {0} Zeichen ein."),rangelength:a.validator.format("Geben Sie bitte mindestens {0} und maximal {1} Zeichen ein."),email:"Geben Sie bitte eine gültige E-Mail-Adresse ein.",url:"Geben Sie bitte eine gültige URL ein.",date:"Geben Sie bitte ein gültiges Datum ein.",number:"Geben Sie bitte eine Nummer ein.",digits:"Geben Sie bitte nur Ziffern ein.",equalTo:"Wiederholen Sie bitte denselben Wert.",range:a.validator.format("Geben Sie bitte einen Wert zwischen {0} und {1} ein."),max:a.validator.format("Geben Sie bitte einen Wert kleiner oder gleich {0} ein."),min:a.validator.format("Geben Sie bitte einen Wert größer oder gleich {0} ein."),creditcard:"Geben Sie bitte eine gültige Kreditkarten-Nummer ein.",remote:"Korrigieren Sie bitte dieses Feld.",dateISO:"Geben Sie bitte ein gültiges Datum ein (ISO-Format).",step:a.validator.format("Geben Sie bitte ein Vielfaches von {0} ein."),maxWords:a.validator.format("Geben Sie bitte {0} Wörter oder weniger ein."),minWords:a.validator.format("Geben Sie bitte mindestens {0} Wörter ein."),rangeWords:a.validator.format("Geben Sie bitte zwischen {0} und {1} Wörtern ein."),accept:"Geben Sie bitte einen Wert mit einem gültigen MIME-Typ ein.",alphanumeric:"Geben Sie bitte nur Buchstaben (keine Umlaute), Zahlen oder Unterstriche ein.",bankaccountNL:"Geben Sie bitte eine gültige Kontonummer ein.",bankorgiroaccountNL:"Geben Sie bitte eine gültige Bank- oder Girokontonummer ein.",bic:"Geben Sie bitte einen gültigen BIC-Code ein.",cifES:"Geben Sie bitte eine gültige CIF-Nummer ein.",cpfBR:"Geben Sie bitte eine gültige CPF-Nummer ein.",creditcardtypes:"Geben Sie bitte eine gültige Kreditkarten-Nummer ein.",currency:"Geben Sie bitte eine gültige Währung ein.",extension:"Geben Sie bitte einen Wert mit einer gültigen Erweiterung ein.",giroaccountNL:"Geben Sie bitte eine gültige Girokontonummer ein.",iban:"Geben Sie bitte eine gültige IBAN ein.",integer:"Geben Sie bitte eine positive oder negative Nicht-Dezimalzahl ein.",ipv4:"Geben Sie bitte eine gültige IPv4-Adresse ein.",ipv6:"Geben Sie bitte eine gültige IPv6-Adresse ein.",lettersonly:"Geben Sie bitte nur Buchstaben ein.",letterswithbasicpunc:"Geben Sie bitte nur Buchstaben oder Interpunktion ein.",mobileNL:"Geben Sie bitte eine gültige Handynummer ein.",mobileUK:"Geben Sie bitte eine gültige Handynummer ein.",netmask:"Geben Sie bitte eine gültige Netzmaske ein.",nieES:"Geben Sie bitte eine gültige NIE-Nummer ein.",nifES:"Geben Sie bitte eine gültige NIF-Nummer ein.",nipPL:"Geben Sie bitte eine gültige NIP-Nummer ein.",notEqualTo:"Geben Sie bitte einen anderen Wert ein. Die Werte dürfen nicht gleich sein.",nowhitespace:"Kein Leerzeichen bitte.",pattern:"Ungültiges Format.",phoneNL:"Geben Sie bitte eine gültige Telefonnummer ein.",phonesUK:"Geben Sie bitte eine gültige britische Telefonnummer ein.",phoneUK:"Geben Sie bitte eine gültige Telefonnummer ein.",phoneUS:"Geben Sie bitte eine gültige Telefonnummer ein.",postalcodeBR:"Geben Sie bitte eine gültige brasilianische Postleitzahl ein.",postalCodeCA:"Geben Sie bitte eine gültige kanadische Postleitzahl ein.",postalcodeIT:"Geben Sie bitte eine gültige italienische Postleitzahl ein.",postalcodeNL:"Geben Sie bitte eine gültige niederländische Postleitzahl ein.",postcodeUK:"Geben Sie bitte eine gültige britische Postleitzahl ein.",require_from_group:a.validator.format("Füllen Sie bitte mindestens {0} dieser Felder aus."),skip_or_fill_minimum:a.validator.format("Überspringen Sie bitte diese Felder oder füllen Sie mindestens {0} von ihnen aus."),stateUS:"Geben Sie bitte einen gültigen US-Bundesstaat ein.",strippedminlength:a.validator.format("Geben Sie bitte mindestens {0} Zeichen ein."),time:"Geben Sie bitte eine gültige Uhrzeit zwischen 00:00 und 23:59 ein.",time12h:"Geben Sie bitte eine gültige Uhrzeit im 12-Stunden-Format ein.",vinUS:"Die angegebene Fahrzeugidentifikationsnummer (VIN) ist ungültig.",zipcodeUS:"Die angegebene US-Postleitzahl ist ungültig.",ziprange:"Ihre Postleitzahl muss im Bereich 902xx-xxxx bis 905xx-xxxx liegen."}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Αυτό το πεδίο είναι υποχρεωτικό.",remote:"Παρακαλώ διορθώστε αυτό το πεδίο.",email:"Παρακαλώ εισάγετε μια έγκυρη διεύθυνση email.",url:"Παρακαλώ εισάγετε ένα έγκυρο URL.",date:"Παρακαλώ εισάγετε μια έγκυρη ημερομηνία.",dateISO:"Παρακαλώ εισάγετε μια έγκυρη ημερομηνία (ISO).",number:"Παρακαλώ εισάγετε έναν έγκυρο αριθμό.",digits:"Παρακαλώ εισάγετε μόνο αριθμητικά ψηφία.",creditcard:"Παρακαλώ εισάγετε έναν έγκυρο αριθμό πιστωτικής κάρτας.",equalTo:"Παρακαλώ εισάγετε την ίδια τιμή ξανά.",extension:"Παρακαλώ εισάγετε μια τιμή με έγκυρη επέκταση αρχείου.",maxlength:a.validator.format("Παρακαλώ εισάγετε μέχρι και {0} χαρακτήρες."),minlength:a.validator.format("Παρακαλώ εισάγετε τουλάχιστον {0} χαρακτήρες."),rangelength:a.validator.format("Παρακαλώ εισάγετε μια τιμή με μήκος μεταξύ {0} και {1} χαρακτήρων."),range:a.validator.format("Παρακαλώ εισάγετε μια τιμή μεταξύ {0} και {1}."),max:a.validator.format("Παρακαλώ εισάγετε μια τιμή μικρότερη ή ίση του {0}."),min:a.validator.format("Παρακαλώ εισάγετε μια τιμή μεγαλύτερη ή ίση του {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Este campo es obligatorio.",remote:"Por favor, rellena este campo.",email:"Por favor, escribe una dirección de correo válida.",url:"Por favor, escribe una URL válida.",date:"Por favor, escribe una fecha válida.",dateISO:"Por favor, escribe una fecha (ISO) válida.",number:"Por favor, escribe un número válido.",digits:"Por favor, escribe sólo dígitos.",creditcard:"Por favor, escribe un número de tarjeta válido.",equalTo:"Por favor, escribe el mismo valor de nuevo.",extension:"Por favor, escribe un valor con una extensión aceptada.",maxlength:a.validator.format("Por favor, no escribas más de {0} caracteres."),minlength:a.validator.format("Por favor, no escribas menos de {0} caracteres."),rangelength:a.validator.format("Por favor, escribe un valor entre {0} y {1} caracteres."),range:a.validator.format("Por favor, escribe un valor entre {0} y {1}."),max:a.validator.format("Por favor, escribe un valor menor o igual a {0}."),min:a.validator.format("Por favor, escribe un valor mayor o igual a {0}."),nifES:"Por favor, escribe un NIF válido.",nieES:"Por favor, escribe un NIE válido.",cifES:"Por favor, escribe un CIF válido."}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Este campo es obligatorio.",remote:"Por favor, completá este campo.",email:"Por favor, escribí una dirección de correo válida.",url:"Por favor, escribí una URL válida.",date:"Por favor, escribí una fecha válida.",dateISO:"Por favor, escribí una fecha (ISO) válida.",number:"Por favor, escribí un número entero válido.",digits:"Por favor, escribí sólo dígitos.",creditcard:"Por favor, escribí un número de tarjeta válido.",equalTo:"Por favor, escribí el mismo valor de nuevo.",extension:"Por favor, escribí un valor con una extensión aceptada.",maxlength:a.validator.format("Por favor, no escribas más de {0} caracteres."),minlength:a.validator.format("Por favor, no escribas menos de {0} caracteres."),rangelength:a.validator.format("Por favor, escribí un valor entre {0} y {1} caracteres."),range:a.validator.format("Por favor, escribí un valor entre {0} y {1}."),max:a.validator.format("Por favor, escribí un valor menor o igual a {0}."),min:a.validator.format("Por favor, escribí un valor mayor o igual a {0}."),nifES:"Por favor, escribí un NIF válido.",nieES:"Por favor, escribí un NIE válido.",cifES:"Por favor, escribí un CIF válido."}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Este campo es obligatorio.",remote:"Por favor, llene este campo.",email:"Por favor, escriba un correo electrónico válido.",url:"Por favor, escriba una URL válida.",date:"Por favor, escriba una fecha válida.",dateISO:"Por favor, escriba una fecha (ISO) válida.",number:"Por favor, escriba un número válido.",digits:"Por favor, escriba sólo dígitos.",creditcard:"Por favor, escriba un número de tarjeta válido.",equalTo:"Por favor, escriba el mismo valor de nuevo.",extension:"Por favor, escriba un valor con una extensión permitida.",maxlength:a.validator.format("Por favor, no escriba más de {0} caracteres."),minlength:a.validator.format("Por favor, no escriba menos de {0} caracteres."),rangelength:a.validator.format("Por favor, escriba un valor entre {0} y {1} caracteres."),range:a.validator.format("Por favor, escriba un valor entre {0} y {1}."),max:a.validator.format("Por favor, escriba un valor menor o igual a {0}."),min:a.validator.format("Por favor, escriba un valor mayor o igual a {0}."),nifES:"Por favor, escriba un NIF válido.",nieES:"Por favor, escriba un NIE válido.",cifES:"Por favor, escriba un CIF válido."}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"See väli peab olema täidetud.",maxlength:a.validator.format("Palun sisestage vähem kui {0} tähemärki."),minlength:a.validator.format("Palun sisestage vähemalt {0} tähemärki."),rangelength:a.validator.format("Palun sisestage väärtus vahemikus {0} kuni {1} tähemärki."),email:"Palun sisestage korrektne e-maili aadress.",url:"Palun sisestage korrektne URL.",date:"Palun sisestage korrektne kuupäev.",dateISO:"Palun sisestage korrektne kuupäev (YYYY-MM-DD).",number:"Palun sisestage korrektne number.",digits:"Palun sisestage ainult numbreid.",equalTo:"Palun sisestage sama väärtus uuesti.",range:a.validator.format("Palun sisestage väärtus vahemikus {0} kuni {1}."),max:a.validator.format("Palun sisestage väärtus, mis on väiksem või võrdne arvuga {0}."),min:a.validator.format("Palun sisestage väärtus, mis on suurem või võrdne arvuga {0}."),creditcard:"Palun sisestage korrektne krediitkaardi number."}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Eremu hau beharrezkoa da.",remote:"Mesedez, bete eremu hau.",email:"Mesedez, idatzi baliozko posta helbide bat.",url:"Mesedez, idatzi baliozko URL bat.",date:"Mesedez, idatzi baliozko data bat.",dateISO:"Mesedez, idatzi baliozko (ISO) data bat.",number:"Mesedez, idatzi baliozko zenbaki oso bat.",digits:"Mesedez, idatzi digituak soilik.",creditcard:"Mesedez, idatzi baliozko txartel zenbaki bat.",equalTo:"Mesedez, idatzi berdina berriro ere.",extension:"Mesedez, idatzi onartutako luzapena duen balio bat.",maxlength:a.validator.format("Mesedez, ez idatzi {0} karaktere baino gehiago."),minlength:a.validator.format("Mesedez, ez idatzi {0} karaktere baino gutxiago."),rangelength:a.validator.format("Mesedez, idatzi {0} eta {1} karaktere arteko balio bat."),range:a.validator.format("Mesedez, idatzi {0} eta {1} arteko balio bat."),max:a.validator.format("Mesedez, idatzi {0} edo txikiagoa den balio bat."),min:a.validator.format("Mesedez, idatzi {0} edo handiagoa den balio bat.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"تکمیل این فیلد اجباری است.",remote:"لطفا این فیلد را تصحیح کنید.",email:"لطفا یک ایمیل صحیح وارد کنید.",url:"لطفا آدرس صحیح وارد کنید.",date:"لطفا تاریخ صحیح وارد کنید.",dateFA:"لطفا یک تاریخ صحیح وارد کنید.",dateISO:"لطفا تاریخ صحیح وارد کنید (ISO).",number:"لطفا عدد صحیح وارد کنید.",digits:"لطفا تنها رقم وارد کنید.",creditcard:"لطفا کریدیت کارت صحیح وارد کنید.",equalTo:"لطفا مقدار برابری وارد کنید.",extension:"لطفا مقداری وارد کنید که",alphanumeric:"لطفا مقدار را عدد (انگلیسی) وارد کنید.",maxlength:a.validator.format("لطفا بیشتر از {0} حرف وارد نکنید."),minlength:a.validator.format("لطفا کمتر از {0} حرف وارد نکنید."),rangelength:a.validator.format("لطفا مقداری بین {0} تا {1} حرف وارد کنید."),range:a.validator.format("لطفا مقداری بین {0} تا {1} حرف وارد کنید."),max:a.validator.format("لطفا مقداری کمتر از {0} وارد کنید."),min:a.validator.format("لطفا مقداری بیشتر از {0} وارد کنید."),minWords:a.validator.format("لطفا حداقل {0} کلمه وارد کنید."),maxWords:a.validator.format("لطفا حداکثر {0} کلمه وارد کنید.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"T&auml;m&auml; kentt&auml; on pakollinen.",email:"Sy&ouml;t&auml; oikea s&auml;hk&ouml;postiosoite.",url:"Sy&ouml;t&auml; oikea URL-osoite.",date:"Sy&ouml;t&auml; oikea p&auml;iv&auml;m&auml;&auml;r&auml;.",dateISO:"Sy&ouml;t&auml; oikea p&auml;iv&auml;m&auml;&auml;r&auml; muodossa VVVV-KK-PP.",number:"Sy&ouml;t&auml; luku.",creditcard:"Sy&ouml;t&auml; voimassa oleva luottokorttinumero.",digits:"Sy&ouml;t&auml; pelk&auml;st&auml;&auml;n numeroita.",equalTo:"Sy&ouml;t&auml; sama arvo uudestaan.",maxlength:a.validator.format("Voit sy&ouml;tt&auml;&auml; enint&auml;&auml;n {0} merkki&auml;."),minlength:a.validator.format("V&auml;hint&auml;&auml;n {0} merkki&auml;."),rangelength:a.validator.format("Sy&ouml;t&auml; v&auml;hint&auml;&auml;n {0} ja enint&auml;&auml;n {1} merkki&auml;."),range:a.validator.format("Sy&ouml;t&auml; arvo v&auml;lilt&auml; {0}&ndash;{1}."),max:a.validator.format("Sy&ouml;t&auml; arvo, joka on enint&auml;&auml;n {0}."),min:a.validator.format("Sy&ouml;t&auml; arvo, joka on v&auml;hint&auml;&auml;n {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Ce champ est obligatoire.",remote:"Veuillez corriger ce champ.",email:"Veuillez fournir une adresse électronique valide.",url:"Veuillez fournir une adresse URL valide.",date:"Veuillez fournir une date valide.",dateISO:"Veuillez fournir une date valide (ISO).",number:"Veuillez fournir un numéro valide.",digits:"Veuillez fournir seulement des chiffres.",creditcard:"Veuillez fournir un numéro de carte de crédit valide.",equalTo:"Veuillez fournir encore la même valeur.",notEqualTo:"Veuillez fournir une valeur différente, les valeurs ne doivent pas être identiques.",extension:"Veuillez fournir une valeur avec une extension valide.",maxlength:a.validator.format("Veuillez fournir au plus {0} caractères."),minlength:a.validator.format("Veuillez fournir au moins {0} caractères."),rangelength:a.validator.format("Veuillez fournir une valeur qui contient entre {0} et {1} caractères."),range:a.validator.format("Veuillez fournir une valeur entre {0} et {1}."),max:a.validator.format("Veuillez fournir une valeur inférieure ou égale à {0}."),min:a.validator.format("Veuillez fournir une valeur supérieure ou égale à {0}."),step:a.validator.format("Veuillez fournir une valeur multiple de {0}."),maxWords:a.validator.format("Veuillez fournir au plus {0} mots."),minWords:a.validator.format("Veuillez fournir au moins {0} mots."),rangeWords:a.validator.format("Veuillez fournir entre {0} et {1} mots."),letterswithbasicpunc:"Veuillez fournir seulement des lettres et des signes de ponctuation.",alphanumeric:"Veuillez fournir seulement des lettres, nombres, espaces et soulignages.",lettersonly:"Veuillez fournir seulement des lettres.",nowhitespace:"Veuillez ne pas inscrire d'espaces blancs.",ziprange:"Veuillez fournir un code postal entre 902xx-xxxx et 905-xx-xxxx.",integer:"Veuillez fournir un nombre non décimal qui est positif ou négatif.",vinUS:"Veuillez fournir un numéro d'identification du véhicule (VIN).",dateITA:"Veuillez fournir une date valide.",time:"Veuillez fournir une heure valide entre 00:00 et 23:59.",phoneUS:"Veuillez fournir un numéro de téléphone valide.",phoneUK:"Veuillez fournir un numéro de téléphone valide.",mobileUK:"Veuillez fournir un numéro de téléphone mobile valide.",strippedminlength:a.validator.format("Veuillez fournir au moins {0} caractères."),email2:"Veuillez fournir une adresse électronique valide.",url2:"Veuillez fournir une adresse URL valide.",creditcardtypes:"Veuillez fournir un numéro de carte de crédit valide.",ipv4:"Veuillez fournir une adresse IP v4 valide.",ipv6:"Veuillez fournir une adresse IP v6 valide.",require_from_group:a.validator.format("Veuillez fournir au moins {0} de ces champs."),nifES:"Veuillez fournir un numéro NIF valide.",nieES:"Veuillez fournir un numéro NIE valide.",cifES:"Veuillez fournir un numéro CIF valide.",postalCodeCA:"Veuillez fournir un code postal valide.",pattern:"Format non valide."}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"ეს ველი სავალდებულოა",remote:"გთხოვთ შეასწოროთ.",email:"გთხოვთ შეიყვანოთ სწორი ფორმატით.",url:"გთხოვთ შეიყვანოთ სწორი ფორმატით.",date:"გთხოვთ შეიყვანოთ სწორი თარიღი.",dateISO:"გთხოვთ შეიყვანოთ სწორი ფორმატით (ISO).",number:"გთხოვთ შეიყვანოთ რიცხვი.",digits:"დაშვებულია მხოლოდ ციფრები.",creditcard:"გთხოვთ შეიყვანოთ სწორი ფორმატის ბარათის კოდი.",equalTo:"გთხოვთ შეიყვანოთ იგივე მნიშვნელობა.",maxlength:a.validator.format("გთხოვთ შეიყვანოთ არა უმეტეს {0} სიმბოლოსი."),minlength:a.validator.format("შეიყვანეთ მინიმუმ {0} სიმბოლო."),rangelength:a.validator.format("გთხოვთ შეიყვანოთ {0} -დან {1} -მდე რაოდენობის სიმბოლოები."),range:a.validator.format("შეიყვანეთ {0} -სა {1} -ს შორის."),max:a.validator.format("გთხოვთ შეიყვანოთ მნიშვნელობა ნაკლები ან ტოლი {0} -ს."),min:a.validator.format("გთხოვთ შეიყვანოთ მნიშვნელობა მეტი ან ტოლი {0} -ს.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return function(a){a.extend(a.validator.messages,{required:"Este campo é obrigatorio.",remote:"Por favor, cubre este campo.",email:"Por favor, escribe unha dirección de correo válida.",url:"Por favor, escribe unha URL válida.",date:"Por favor, escribe unha data válida.",dateISO:"Por favor, escribe unha data (ISO) válida.",number:"Por favor, escribe un número válido.",digits:"Por favor, escribe só díxitos.",creditcard:"Por favor, escribe un número de tarxeta válido.",equalTo:"Por favor, escribe o mesmo valor de novo.",extension:"Por favor, escribe un valor cunha extensión aceptada.",maxlength:a.validator.format("Por favor, non escribas máis de {0} caracteres."),minlength:a.validator.format("Por favor, non escribas menos de {0} caracteres."),rangelength:a.validator.format("Por favor, escribe un valor entre {0} e {1} caracteres."),range:a.validator.format("Por favor, escribe un valor entre {0} e {1}."),max:a.validator.format("Por favor, escribe un valor menor ou igual a {0}."),min:a.validator.format("Por favor, escribe un valor maior ou igual a {0}."),nifES:"Por favor, escribe un NIF válido.",nieES:"Por favor, escribe un NIE válido.",cifES:"Por favor, escribe un CIF válido."})}(jQuery),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"השדה הזה הינו שדה חובה",remote:"נא לתקן שדה זה",email:'נא למלא כתובת דוא"ל חוקית',url:"נא למלא כתובת אינטרנט חוקית",date:"נא למלא תאריך חוקי",dateISO:"נא למלא תאריך חוקי (ISO)",number:"נא למלא מספר",digits:"נא למלא רק מספרים",creditcard:"נא למלא מספר כרטיס אשראי חוקי",equalTo:"נא למלא את אותו ערך שוב",extension:"נא למלא ערך עם סיומת חוקית",maxlength:a.validator.format(".נא לא למלא יותר מ- {0} תווים"),minlength:a.validator.format("נא למלא לפחות {0} תווים"),rangelength:a.validator.format("נא למלא ערך בין {0} ל- {1} תווים"),range:a.validator.format("נא למלא ערך בין {0} ל- {1}"),max:a.validator.format("נא למלא ערך קטן או שווה ל- {0}"),min:a.validator.format("נא למלא ערך גדול או שווה ל- {0}")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Ovo polje je obavezno.",remote:"Ovo polje treba popraviti.",email:"Unesite ispravnu e-mail adresu.",url:"Unesite ispravan URL.",date:"Unesite ispravan datum.",dateISO:"Unesite ispravan datum (ISO).",number:"Unesite ispravan broj.",digits:"Unesite samo brojeve.",creditcard:"Unesite ispravan broj kreditne kartice.",equalTo:"Unesite ponovo istu vrijednost.",extension:"Unesite vrijednost sa ispravnom ekstenzijom.",maxlength:a.validator.format("Maksimalni broj znakova je {0} ."),minlength:a.validator.format("Minimalni broj znakova je {0} ."),rangelength:a.validator.format("Unesite vrijednost između {0} i {1} znakova."),range:a.validator.format("Unesite vrijednost između {0} i {1}."),max:a.validator.format("Unesite vrijednost manju ili jednaku {0}."),min:a.validator.format("Unesite vrijednost veću ili jednaku {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Kötelező megadni.",maxlength:a.validator.format("Legfeljebb {0} karakter hosszú legyen."),minlength:a.validator.format("Legalább {0} karakter hosszú legyen."),rangelength:a.validator.format("Legalább {0} és legfeljebb {1} karakter hosszú legyen."),email:"Érvényes e-mail címnek kell lennie.",url:"Érvényes URL-nek kell lennie.",date:"Dátumnak kell lennie.",number:"Számnak kell lennie.",digits:"Csak számjegyek lehetnek.",equalTo:"Meg kell egyeznie a két értéknek.",range:a.validator.format("{0} és {1} közé kell esnie."),max:a.validator.format("Nem lehet nagyobb, mint {0}."),min:a.validator.format("Nem lehet kisebb, mint {0}."),creditcard:"Érvényes hitelkártyaszámnak kell lennie.",remote:"Kérem javítsa ki ezt a mezőt.",dateISO:"Kérem írjon be egy érvényes dátumot (ISO).",step:a.validator.format("A {0} egyik többszörösét adja meg.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Պարտադիր լրացման դաշտ",remote:"Ներմուծեք ճիշտ արժեքը",email:"Ներմուծեք վավեր էլեկտրոնային փոստի հասցե",url:"Ներմուծեք վավեր URL",date:"Ներմուծեք վավեր ամսաթիվ",dateISO:"Ներմուծեք ISO ֆորմատով վավեր ամսաթիվ։",number:"Ներմուծեք թիվ",digits:"Ներմուծեք միայն թվեր",creditcard:"Ներմուծեք ճիշտ բանկային քարտի համար",equalTo:"Ներմուծեք միևնուն արժեքը ևս մեկ անգամ",extension:"Ընտրեք ճիշտ ընդլանումով ֆայլ",maxlength:a.validator.format("Ներմուծեք ոչ ավել քան {0} նիշ"),minlength:a.validator.format("Ներմուծեք ոչ պակաս քան {0} նիշ"),rangelength:a.validator.format("Ներմուծեք {0}֊ից {1} երկարությամբ արժեք"),range:a.validator.format("Ներմուծեք թիվ {0}֊ից {1} միջակայքում"),max:a.validator.format("Ներմուծեք թիվ, որը փոքր կամ հավասար է {0}֊ին"),min:a.validator.format("Ներմուծեք թիվ, որը մեծ կամ հավասար է {0}֊ին")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Kolom ini diperlukan.",remote:"Harap benarkan kolom ini.",email:"Silakan masukkan format email yang benar.",url:"Silakan masukkan format URL yang benar.",date:"Silakan masukkan format tanggal yang benar.",dateISO:"Silakan masukkan format tanggal(ISO) yang benar.",number:"Silakan masukkan angka yang benar.",digits:"Harap masukan angka saja.",creditcard:"Harap masukkan format kartu kredit yang benar.",equalTo:"Harap masukkan nilai yg sama dengan sebelumnya.",maxlength:a.validator.format("Input dibatasi hanya {0} karakter."),minlength:a.validator.format("Input tidak kurang dari {0} karakter."),rangelength:a.validator.format("Panjang karakter yg diizinkan antara {0} dan {1} karakter."),range:a.validator.format("Harap masukkan nilai antara {0} dan {1}."),max:a.validator.format("Harap masukkan nilai lebih kecil atau sama dengan {0}."),min:a.validator.format("Harap masukkan nilai lebih besar atau sama dengan {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Þessi reitur er nauðsynlegur.",remote:"Lagaðu þennan reit.",maxlength:a.validator.format("Sláðu inn mest {0} stafi."),minlength:a.validator.format("Sláðu inn minnst {0} stafi."),rangelength:a.validator.format("Sláðu inn minnst {0} og mest {1} stafi."),email:"Sláðu inn gilt netfang.",url:"Sláðu inn gilda vefslóð.",date:"Sláðu inn gilda dagsetningu.",number:"Sláðu inn tölu.",digits:"Sláðu inn tölustafi eingöngu.",equalTo:"Sláðu sama gildi inn aftur.",range:a.validator.format("Sláðu inn gildi milli {0} og {1}."),max:a.validator.format("Sláðu inn gildi sem er minna en eða jafnt og {0}."),min:a.validator.format("Sláðu inn gildi sem er stærra en eða jafnt og {0}."),creditcard:"Sláðu inn gilt greiðslukortanúmer."}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Campo obbligatorio",remote:"Controlla questo campo",email:"Inserisci un indirizzo email valido",url:"Inserisci un indirizzo web valido",date:"Inserisci una data valida",dateISO:"Inserisci una data valida (ISO)",number:"Inserisci un numero valido",digits:"Inserisci solo numeri",creditcard:"Inserisci un numero di carta di credito valido",equalTo:"Il valore non corrisponde",extension:"Inserisci un valore con un&apos;estensione valida",maxlength:a.validator.format("Non inserire pi&ugrave; di {0} caratteri"),minlength:a.validator.format("Inserisci almeno {0} caratteri"),rangelength:a.validator.format("Inserisci un valore compreso tra {0} e {1} caratteri"),range:a.validator.format("Inserisci un valore compreso tra {0} e {1}"),max:a.validator.format("Inserisci un valore minore o uguale a {0}"),min:a.validator.format("Inserisci un valore maggiore o uguale a {0}"),nifES:"Inserisci un NIF valido",nieES:"Inserisci un NIE valido",cifES:"Inserisci un CIF valido",currency:"Inserisci una valuta valida"}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"このフィールドは必須です。",remote:"このフィールドを修正してください。",email:"有効なEメールアドレスを入力してください。",url:"有効なURLを入力してください。",date:"有効な日付を入力してください。",dateISO:"有効な日付ISOを入力してください。",number:"有効な数字を入力してください。",digits:"数字のみを入力してください。",creditcard:"有効なクレジットカード番号を入力してください。",equalTo:"同じ値をもう一度入力してください。",extension:"有効な拡張子を含む値を入力してください。",maxlength:a.validator.format("{0} 文字以内で入力してください。"),minlength:a.validator.format("{0} 文字以上で入力してください。"),rangelength:a.validator.format("{0} 文字から {1} 文字までの値を入力してください。"),range:a.validator.format("{0} から {1} までの値を入力してください。"),step:a.validator.format("{0} の倍数を入力してください。"),max:a.validator.format("{0} 以下の値を入力してください。"),min:a.validator.format("{0} 以上の値を入力してください。")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"ამ ველის შევსება აუცილებელია.",remote:"გთხოვთ მიუთითოთ სწორი მნიშვნელობა.",email:"გთხოვთ მიუთითოთ ელ-ფოსტის კორექტული მისამართი.",url:"გთხოვთ მიუთითოთ კორექტული URL.",date:"გთხოვთ მიუთითოთ კორექტული თარიღი.",dateISO:"გთხოვთ მიუთითოთ კორექტული თარიღი ISO ფორმატში.",number:"გთხოვთ მიუთითოთ ციფრი.",digits:"გთხოვთ მიუთითოთ მხოლოდ ციფრები.",creditcard:"გთხოვთ მიუთითოთ საკრედიტო ბარათის კორექტული ნომერი.",equalTo:"გთხოვთ მიუთითოთ ასეთივე მნიშვნელობა კიდევ ერთხელ.",extension:"გთხოვთ აირჩიოთ ფაილი კორექტული გაფართოებით.",maxlength:a.validator.format("დასაშვებია არაუმეტეს {0} სიმბოლო."),minlength:a.validator.format("აუცილებელია შეიყვანოთ მინიმუმ {0} სიმბოლო."),rangelength:a.validator.format("ტექსტში სიმბოლოების რაოდენობა უნდა იყოს {0}-დან {1}-მდე."),range:a.validator.format("გთხოვთ შეიყვანოთ ციფრი {0}-დან {1}-მდე."),max:a.validator.format("გთხოვთ შეიყვანოთ ციფრი რომელიც ნაკლებია ან უდრის {0}-ს."),min:a.validator.format("გთხოვთ შეიყვანოთ ციფრი რომელიც მეტია ან უდრის {0}-ს.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Бұл өрісті міндетті түрде толтырыңыз.",remote:"Дұрыс мағына енгізуіңізді сұраймыз.",email:"Нақты электронды поштаңызды енгізуіңізді сұраймыз.",url:"Нақты URL-ды енгізуіңізді сұраймыз.",date:"Нақты URL-ды енгізуіңізді сұраймыз.",dateISO:"Нақты ISO форматымен сәйкес датасын енгізуіңізді сұраймыз.",number:"Күнді енгізуіңізді сұраймыз.",digits:"Тек қана сандарды енгізуіңізді сұраймыз.",creditcard:"Несие картасының нөмірін дұрыс енгізуіңізді сұраймыз.",equalTo:"Осы мәнді қайта енгізуіңізді сұраймыз.",extension:"Файлдың кеңейтуін дұрыс таңдаңыз.",maxlength:a.validator.format("Ұзындығы {0} символдан көр болмасын."),minlength:a.validator.format("Ұзындығы {0} символдан аз болмасын."),rangelength:a.validator.format("Ұзындығы {0}-{1} дейін мән енгізуіңізді сұраймыз."),range:a.validator.format("Пожалуйста, введите число от {0} до {1}. - {0} - {1} санын енгізуіңізді сұраймыз."),max:a.validator.format("{0} аз немесе тең санын енгізуіңіді сұраймыз."),min:a.validator.format("{0} көп немесе тең санын енгізуіңізді сұраймыз.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"필수 항목입니다.",remote:"항목을 수정하세요.",email:"유효하지 않은 E-Mail주소입니다.",url:"유효하지 않은 URL입니다.",date:"올바른 날짜를 입력하세요.",dateISO:"올바른 날짜(ISO)를 입력하세요.",number:"유효한 숫자가 아닙니다.",digits:"숫자만 입력 가능합니다.",creditcard:"신용카드 번호가 바르지 않습니다.",equalTo:"같은 값을 다시 입력하세요.",extension:"올바른 확장자가 아닙니다.",maxlength:a.validator.format("{0}자를 넘을 수 없습니다. "),minlength:a.validator.format("{0}자 이상 입력하세요."),rangelength:a.validator.format("문자 길이가 {0} 에서 {1} 사이의 값을 입력하세요."),range:a.validator.format("{0} 에서 {1} 사이의 값을 입력하세요."),max:a.validator.format("{0} 이하의 값을 입력하세요."),min:a.validator.format("{0} 이상의 값을 입력하세요.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Šis laukas yra privalomas.",remote:"Prašau pataisyti šį lauką.",email:"Prašau įvesti teisingą elektroninio pašto adresą.",url:"Prašau įvesti teisingą URL.",date:"Prašau įvesti teisingą datą.",dateISO:"Prašau įvesti teisingą datą (ISO).",number:"Prašau įvesti teisingą skaičių.",digits:"Prašau naudoti tik skaitmenis.",creditcard:"Prašau įvesti teisingą kreditinės kortelės numerį.",equalTo:"Prašau įvestį tą pačią reikšmę dar kartą.",extension:"Prašau įvesti reikšmę su teisingu plėtiniu.",maxlength:a.validator.format("Prašau įvesti ne daugiau kaip {0} simbolių."),minlength:a.validator.format("Prašau įvesti bent {0} simbolius."),rangelength:a.validator.format("Prašau įvesti reikšmes, kurių ilgis nuo {0} iki {1} simbolių."),range:a.validator.format("Prašau įvesti reikšmę intervale nuo {0} iki {1}."),max:a.validator.format("Prašau įvesti reikšmę mažesnę arba lygią {0}."),min:a.validator.format("Prašau įvesti reikšmę didesnę arba lygią {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Šis lauks ir obligāts.",remote:"Lūdzu, pārbaudiet šo lauku.",email:"Lūdzu, ievadiet derīgu e-pasta adresi.",url:"Lūdzu, ievadiet derīgu URL adresi.",date:"Lūdzu, ievadiet derīgu datumu.",dateISO:"Lūdzu, ievadiet derīgu datumu (ISO).",number:"Lūdzu, ievadiet derīgu numuru.",digits:"Lūdzu, ievadiet tikai ciparus.",creditcard:"Lūdzu, ievadiet derīgu kredītkartes numuru.",equalTo:"Lūdzu, ievadiet to pašu vēlreiz.",extension:"Lūdzu, ievadiet vērtību ar derīgu paplašinājumu.",maxlength:a.validator.format("Lūdzu, ievadiet ne vairāk kā {0} rakstzīmes."),minlength:a.validator.format("Lūdzu, ievadiet vismaz {0} rakstzīmes."),rangelength:a.validator.format("Lūdzu ievadiet {0} līdz {1} rakstzīmes."),range:a.validator.format("Lūdzu, ievadiet skaitli no {0} līdz {1}."),max:a.validator.format("Lūdzu, ievadiet skaitli, kurš ir mazāks vai vienāds ar {0}."),min:a.validator.format("Lūdzu, ievadiet skaitli, kurš ir lielāks vai vienāds ar {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Полето е задолжително.",remote:"Поправете го ова поле",email:"Внесете правилна e-mail адреса",url:"Внесете правилен URL.",date:"Внесете правилен датум",dateISO:"Внесете правилен датум (ISO).",number:"Внесете правилен број.",digits:"Внесете само бројки.",creditcard:"Внесете правилен број на кредитната картичка.",equalTo:"Внесете ја истата вредност повторно.",extension:"Внесете вредност со соодветна екстензија.",maxlength:a.validator.format("Внесете максимално {0} знаци."),minlength:a.validator.format("Внесете барем {0} знаци."),rangelength:a.validator.format("Внесете вредност со должина помеѓу {0} и {1} знаци."),range:a.validator.format("Внесете вредност помеѓу {0} и {1}."),max:a.validator.format("Внесете вредност помала или еднаква на {0}."),min:a.validator.format("Внесете вредност поголема или еднаква на {0}")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Medan ini diperlukan.",remote:"Sila betulkan medan ini.",email:"Sila masukkan alamat emel yang betul.",url:"Sila masukkan URL yang betul.",date:"Sila masukkan tarikh yang betul.",dateISO:"Sila masukkan tarikh(ISO) yang betul.",number:"Sila masukkan nombor yang betul.",digits:"Sila masukkan nilai digit sahaja.",creditcard:"Sila masukkan nombor kredit kad yang betul.",equalTo:"Sila masukkan nilai yang sama semula.",extension:"Sila masukkan nilai yang telah diterima.",maxlength:a.validator.format("Sila masukkan tidak lebih dari {0} aksara."),minlength:a.validator.format("Sila masukkan sekurang-kurangnya {0} aksara."),rangelength:a.validator.format("Sila masukkan antara {0} dan {1} panjang aksara."),range:a.validator.format("Sila masukkan nilai antara {0} dan {1} aksara."),max:a.validator.format("Sila masukkan nilai yang kurang atau sama dengan {0}."),min:a.validator.format("Sila masukkan nilai yang lebih atau sama dengan {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Dit is een verplicht veld.",remote:"Controleer dit veld.",email:"Vul hier een geldig e-mailadres in.",url:"Vul hier een geldige URL in.",date:"Vul hier een geldige datum in.",dateISO:"Vul hier een geldige datum in (ISO-formaat).",number:"Vul hier een geldig getal in.",digits:"Vul hier alleen getallen in.",creditcard:"Vul hier een geldig creditcardnummer in.",equalTo:"Vul hier dezelfde waarde in.",extension:"Vul hier een waarde in met een geldige extensie.",maxlength:a.validator.format("Vul hier maximaal {0} tekens in."),minlength:a.validator.format("Vul hier minimaal {0} tekens in."),rangelength:a.validator.format("Vul hier een waarde in van minimaal {0} en maximaal {1} tekens."),range:a.validator.format("Vul hier een waarde in van minimaal {0} en maximaal {1}."),max:a.validator.format("Vul hier een waarde in kleiner dan of gelijk aan {0}."),min:a.validator.format("Vul hier een waarde in groter dan of gelijk aan {0}."),step:a.validator.format("Vul hier een veelvoud van {0} in."),iban:"Vul hier een geldig IBAN in.",dateNL:"Vul hier een geldige datum in.",phoneNL:"Vul hier een geldig Nederlands telefoonnummer in.",mobileNL:"Vul hier een geldig Nederlands mobiel telefoonnummer in.",postalcodeNL:"Vul hier een geldige postcode in.",bankaccountNL:"Vul hier een geldig bankrekeningnummer in.",giroaccountNL:"Vul hier een geldig gironummer in.",bankorgiroaccountNL:"Vul hier een geldig bank- of gironummer in."}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Angi en verdi.",remote:"Ugyldig verdi.",email:"Angi en gyldig epostadresse.",url:"Angi en gyldig URL.",date:"Angi en gyldig dato.",dateISO:"Angi en gyldig dato (&ARING;&ARING;&ARING;&ARING;-MM-DD).",number:"Angi et gyldig tall.",digits:"Skriv kun tall.",equalTo:"Skriv samme verdi igjen.",maxlength:a.validator.format("Maksimalt {0} tegn."),minlength:a.validator.format("Minimum {0} tegn."),rangelength:a.validator.format("Angi minimum {0} og maksimum {1} tegn."),range:a.validator.format("Angi en verdi mellom {0} og {1}."),max:a.validator.format("Angi en verdi som er mindre eller lik {0}."),min:a.validator.format("Angi en verdi som er st&oslash;rre eller lik {0}."),step:a.validator.format("Angi en verdi ganger {0}."),creditcard:"Angi et gyldig kredittkortnummer."}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"To pole jest wymagane.",remote:"Proszę o wypełnienie tego pola.",email:"Proszę o podanie prawidłowego adresu email.",url:"Proszę o podanie prawidłowego URL.",date:"Proszę o podanie prawidłowej daty.",dateISO:"Proszę o podanie prawidłowej daty (ISO).",number:"Proszę o podanie prawidłowej liczby.",digits:"Proszę o podanie samych cyfr.",creditcard:"Proszę o podanie prawidłowej karty kredytowej.",equalTo:"Proszę o podanie tej samej wartości ponownie.",extension:"Proszę o podanie wartości z prawidłowym rozszerzeniem.",nipPL:"Proszę o podanie prawidłowego numeru NIP.",phonePL:"Proszę o podanie prawidłowego numeru telefonu",maxlength:a.validator.format("Proszę o podanie nie więcej niż {0} znaków."),minlength:a.validator.format("Proszę o podanie przynajmniej {0} znaków."),rangelength:a.validator.format("Proszę o podanie wartości o długości od {0} do {1} znaków."),range:a.validator.format("Proszę o podanie wartości z przedziału od {0} do {1}."),max:a.validator.format("Proszę o podanie wartości mniejszej bądź równej {0}."),min:a.validator.format("Proszę o podanie wartości większej bądź równej {0}."),pattern:a.validator.format("Pole zawiera niedozwolone znaki.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Este campo &eacute; requerido.",remote:"Por favor, corrija este campo.",email:"Por favor, forne&ccedil;a um endere&ccedil;o de email v&aacute;lido.",url:"Por favor, forne&ccedil;a uma URL v&aacute;lida.",date:"Por favor, forne&ccedil;a uma data v&aacute;lida.",dateISO:"Por favor, forne&ccedil;a uma data v&aacute;lida (ISO).",number:"Por favor, forne&ccedil;a um n&uacute;mero v&aacute;lido.",digits:"Por favor, forne&ccedil;a somente d&iacute;gitos.",creditcard:"Por favor, forne&ccedil;a um cart&atilde;o de cr&eacute;dito v&aacute;lido.",equalTo:"Por favor, forne&ccedil;a o mesmo valor novamente.",maxlength:a.validator.format("Por favor, forne&ccedil;a n&atilde;o mais que {0} caracteres."),minlength:a.validator.format("Por favor, forne&ccedil;a ao menos {0} caracteres."),rangelength:a.validator.format("Por favor, forne&ccedil;a um valor entre {0} e {1} caracteres de comprimento."),range:a.validator.format("Por favor, forne&ccedil;a um valor entre {0} e {1}."),max:a.validator.format("Por favor, forne&ccedil;a um valor menor ou igual a {0}."),min:a.validator.format("Por favor, forne&ccedil;a um valor maior ou igual a {0}."),step:a.validator.format("Por favor, forne&ccedil;a um valor m&uacute;ltiplo de {0}."),maxWords:a.validator.format("Por favor, forne&ccedil;a com {0} palavras ou menos."),minWords:a.validator.format("Por favor, forne&ccedil;a pelo menos {0} palavras."),rangeWords:a.validator.format("Por favor, forne&ccedil;a entre {0} e {1} palavras."),accept:"Por favor, forne&ccedil;a um tipo v&aacute;lido.",alphanumeric:"Por favor, forne&ccedil;a somente com letras, n&uacute;meros e sublinhados.",bankaccountNL:"Por favor, forne&ccedil;a com um n&uacute;mero de conta banc&aacute;ria v&aacute;lida.",bankorgiroaccountNL:"Por favor, forne&ccedil;a um banco v&aacute;lido ou n&uacute;mero de conta.",bic:"Por favor, forne&ccedil;a um c&oacute;digo BIC v&aacute;lido.",cifES:"Por favor, forne&ccedil;a um c&oacute;digo CIF v&aacute;lido.",creditcardtypes:"Por favor, forne&ccedil;a um n&uacute;mero de cart&atilde;o de cr&eacute;dito v&aacute;lido.",currency:"Por favor, forne&ccedil;a uma moeda v&aacute;lida.",dateFA:"Por favor, forne&ccedil;a uma data correta.",dateITA:"Por favor, forne&ccedil;a uma data correta.",dateNL:"Por favor, forne&ccedil;a uma data correta.",extension:"Por favor, forne&ccedil;a um valor com uma extens&atilde;o v&aacute;lida.",giroaccountNL:"Por favor, forne&ccedil;a um n&uacute;mero de conta corrente v&aacute;lido.",iban:"Por favor, forne&ccedil;a um c&oacute;digo IBAN v&aacute;lido.",integer:"Por favor, forne&ccedil;a um n&uacute;mero n&atilde;o decimal.",ipv4:"Por favor, forne&ccedil;a um IPv4 v&aacute;lido.",ipv6:"Por favor, forne&ccedil;a um IPv6 v&aacute;lido.",lettersonly:"Por favor, forne&ccedil;a apenas com letras.",letterswithbasicpunc:"Por favor, forne&ccedil;a apenas letras ou pontua&ccedil;ões.",mobileNL:"Por favor, fornece&ccedil;a um n&uacute;mero v&aacute;lido de telefone.",mobileUK:"Por favor, fornece&ccedil;a um n&uacute;mero v&aacute;lido de telefone.",nieES:"Por favor, forne&ccedil;a um NIE v&aacute;lido.",nifES:"Por favor, forne&ccedil;a um NIF v&aacute;lido.",nowhitespace:"Por favor, n&atilde;o utilize espa&ccedil;os em branco.",pattern:"O formato fornecido &eacute; inv&aacute;lido.",phoneNL:"Por favor, forne&ccedil;a um n&uacute;mero de telefone v&aacute;lido.",phoneUK:"Por favor, forne&ccedil;a um n&uacute;mero de telefone v&aacute;lido.",phoneUS:"Por favor, forne&ccedil;a um n&uacute;mero de telefone v&aacute;lido.",phonesUK:"Por favor, forne&ccedil;a um n&uacute;mero de telefone v&aacute;lido.",postalCodeCA:"Por favor, forne&ccedil;a um n&uacute;mero de c&oacute;digo postal v&aacute;lido.",postalcodeIT:"Por favor, forne&ccedil;a um n&uacute;mero de c&oacute;digo postal v&aacute;lido.",postalcodeNL:"Por favor, forne&ccedil;a um n&uacute;mero de c&oacute;digo postal v&aacute;lido.",postcodeUK:"Por favor, forne&ccedil;a um n&uacute;mero de c&oacute;digo postal v&aacute;lido.",postalcodeBR:"Por favor, forne&ccedil;a um CEP v&aacute;lido.",require_from_group:a.validator.format("Por favor, forne&ccedil;a pelo menos {0} destes campos."),skip_or_fill_minimum:a.validator.format("Por favor, optar entre ignorar esses campos ou preencher pelo menos {0} deles."),stateUS:"Por favor, forne&ccedil;a um estado v&aacute;lido.",strippedminlength:a.validator.format("Por favor, forne&ccedil;a pelo menos {0} caracteres."),time:"Por favor, forne&ccedil;a um hor&aacute;rio v&aacute;lido, no intervado de 00:00 a 23:59.",time12h:"Por favor, forne&ccedil;a um hor&aacute;rio v&aacute;lido, no intervado de 01:00 a 12:59 am/pm.",url2:"Por favor, forne&ccedil;a uma URL v&aacute;lida.",vinUS:"O n&uacute;mero de identifica&ccedil;&atilde;o de ve&iacute;culo informado (VIN) &eacute; inv&aacute;lido.",zipcodeUS:"Por favor, forne&ccedil;a um c&oacute;digo postal americano v&aacute;lido.",ziprange:"O c&oacute;digo postal deve estar entre 902xx-xxxx e 905xx-xxxx",cpfBR:"Por favor, forne&ccedil;a um CPF v&aacute;lido.",nisBR:"Por favor, forne&ccedil;a um NIS/PIS v&aacute;lido",cnhBR:"Por favor, forne&ccedil;a um CNH v&aacute;lido.",cnpjBR:"Por favor, forne&ccedil;a um CNPJ v&aacute;lido."}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Campo de preenchimento obrigat&oacute;rio.",remote:"Por favor, corrija este campo.",email:"Por favor, introduza um endere&ccedil;o eletr&oacute;nico v&aacute;lido.",url:"Por favor, introduza um URL v&aacute;lido.",date:"Por favor, introduza uma data v&aacute;lida.",dateISO:"Por favor, introduza uma data v&aacute;lida (ISO).",number:"Por favor, introduza um n&uacute;mero v&aacute;lido.",digits:"Por favor, introduza apenas d&iacute;gitos.",creditcard:"Por favor, introduza um n&uacute;mero de cart&atilde;o de cr&eacute;dito v&aacute;lido.",equalTo:"Por favor, introduza de novo o mesmo valor.",extension:"Por favor, introduza um ficheiro com uma extens&atilde;o v&aacute;lida.",maxlength:a.validator.format("Por favor, n&atilde;o introduza mais do que {0} caracteres."),minlength:a.validator.format("Por favor, introduza pelo menos {0} caracteres."),rangelength:a.validator.format("Por favor, introduza entre {0} e {1} caracteres."),range:a.validator.format("Por favor, introduza um valor entre {0} e {1}."),max:a.validator.format("Por favor, introduza um valor menor ou igual a {0}."),min:a.validator.format("Por favor, introduza um valor maior ou igual a {0}."),nifES:"Por favor, introduza um NIF v&aacute;lido.",nieES:"Por favor, introduza um NIE v&aacute;lido.",cifES:"Por favor, introduza um CIF v&aacute;lido."}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Acest câmp este obligatoriu.",remote:"Te rugăm să completezi acest câmp.",email:"Te rugăm să introduci o adresă de email validă",url:"Te rugăm sa introduci o adresă URL validă.",date:"Te rugăm să introduci o dată corectă.",dateISO:"Te rugăm să introduci o dată (ISO) corectă.",number:"Te rugăm să introduci un număr întreg valid.",digits:"Te rugăm să introduci doar cifre.",creditcard:"Te rugăm să introduci un numar de carte de credit valid.",equalTo:"Te rugăm să reintroduci valoarea.",extension:"Te rugăm să introduci o valoare cu o extensie validă.",maxlength:a.validator.format("Te rugăm să nu introduci mai mult de {0} caractere."),minlength:a.validator.format("Te rugăm să introduci cel puțin {0} caractere."),rangelength:a.validator.format("Te rugăm să introduci o valoare între {0} și {1} caractere."),range:a.validator.format("Te rugăm să introduci o valoare între {0} și {1}."),max:a.validator.format("Te rugăm să introduci o valoare egal sau mai mică decât {0}."),min:a.validator.format("Te rugăm să introduci o valoare egal sau mai mare decât {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Это поле необходимо заполнить.",remote:"Пожалуйста, введите правильное значение.",email:"Пожалуйста, введите корректный адрес электронной почты.",url:"Пожалуйста, введите корректный URL.",date:"Пожалуйста, введите корректную дату.",dateISO:"Пожалуйста, введите корректную дату в формате ISO.",number:"Пожалуйста, введите число.",digits:"Пожалуйста, вводите только цифры.",creditcard:"Пожалуйста, введите правильный номер кредитной карты.",equalTo:"Пожалуйста, введите такое же значение ещё раз.",extension:"Пожалуйста, выберите файл с правильным расширением.",maxlength:a.validator.format("Пожалуйста, введите не больше {0} символов."),minlength:a.validator.format("Пожалуйста, введите не меньше {0} символов."),rangelength:a.validator.format("Пожалуйста, введите значение длиной от {0} до {1} символов."),range:a.validator.format("Пожалуйста, введите число от {0} до {1}."),max:a.validator.format("Пожалуйста, введите число, меньшее или равное {0}."),min:a.validator.format("Пожалуйста, введите число, большее или равное {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"هنن جاين جي ضرورت آهي",remote:"هنن جاين جي ضرورت آهي",email:"لکيل اي ميل غلط آهي",url:"لکيل ايڊريس غلط آهي",date:"لکيل تاريخ غلط آهي",dateISO:"جي معيار جي مطابق نه آهي (ISO) لکيل تاريخ",number:"لکيل انگ صحيح ناهي",digits:"رڳو انگ داخل ڪري سگهجي ٿو",creditcard:"لکيل ڪارڊ نمبر صحيح نه آهي",equalTo:"داخل ٿيل ڀيٽ صحيح نه آهي",extension:"لکيل غلط آهي",maxlength:a.validator.format("وڌ کان وڌ {0} جي داخلا ڪري سگهجي ٿي"),minlength:a.validator.format("گهٽ ۾ گهٽ {0} جي داخلا ڪرڻ ضروري آهي"),rangelength:a.validator.format("داخلا جو {0} ۽ {1}جي وچ ۾ هجڻ ضروري آهي"),range:a.validator.format("داخلا جو {0} ۽ {1}جي وچ ۾ هجڻ ضروري آهي"),max:a.validator.format("وڌ کان وڌ {0} جي داخلا ڪري سگهجي ٿي"),min:a.validator.format("گهٽ ۾ گهٽ {0} جي داخلا ڪرڻ ضروري آهي")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"To polje je obvezno.",remote:"Vpis v tem polju ni v pravi obliki.",email:"Prosimo, vnesite pravi email naslov.",url:"Prosimo, vnesite pravi URL.",date:"Prosimo, vnesite pravi datum.",dateISO:"Prosimo, vnesite pravi datum (ISO).",number:"Prosimo, vnesite pravo številko.",digits:"Prosimo, vnesite samo številke.",creditcard:"Prosimo, vnesite pravo številko kreditne kartice.",equalTo:"Prosimo, ponovno vnesite enako vsebino.",extension:"Prosimo, vnesite vsebino z pravo končnico.",maxlength:a.validator.format("Prosimo, da ne vnašate več kot {0} znakov."),minlength:a.validator.format("Prosimo, vnesite vsaj {0} znakov."),rangelength:a.validator.format("Prosimo, vnesite od {0} do {1} znakov."),range:a.validator.format("Prosimo, vnesite vrednost med {0} in {1}."),max:a.validator.format("Prosimo, vnesite vrednost manjšo ali enako {0}."),min:a.validator.format("Prosimo, vnesite vrednost večjo ali enako {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Povinné zadať.",maxlength:a.validator.format("Maximálne {0} znakov."),minlength:a.validator.format("Minimálne {0} znakov."),rangelength:a.validator.format("Minimálne {0} a maximálne {1} znakov."),email:"E-mailová adresa musí byť platná.",url:"URL musí byť platná.",date:"Musí byť dátum.",number:"Musí byť číslo.",digits:"Môže obsahovať iba číslice.",equalTo:"Dve hodnoty sa musia rovnať.",range:a.validator.format("Musí byť medzi {0} a {1}."),max:a.validator.format("Nemôže byť viac ako {0}."),min:a.validator.format("Nemôže byť menej ako {0}."),creditcard:"Číslo platobnej karty musí byť platné.",step:a.validator.format("Musí byť násobkom čísla {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"To polje je obvezno.",remote:"Prosimo popravite to polje.",email:"Prosimo vnesite veljaven email naslov.",url:"Prosimo vnesite veljaven URL naslov.",date:"Prosimo vnesite veljaven datum.",dateISO:"Prosimo vnesite veljaven ISO datum.",number:"Prosimo vnesite veljavno število.",digits:"Prosimo vnesite samo števila.",creditcard:"Prosimo vnesite veljavno številko kreditne kartice.",equalTo:"Prosimo ponovno vnesite vrednost.",extension:"Prosimo vnesite vrednost z veljavno končnico.",maxlength:a.validator.format("Prosimo vnesite največ {0} znakov."),minlength:a.validator.format("Prosimo vnesite najmanj {0} znakov."),rangelength:a.validator.format("Prosimo vnesite najmanj {0} in največ {1} znakov."),range:a.validator.format("Prosimo vnesite vrednost med {0} in {1}."),max:a.validator.format("Prosimo vnesite vrednost manjše ali enako {0}."),min:a.validator.format("Prosimo vnesite vrednost večje ali enako {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Поље је обавезно.",remote:"Средите ово поље.",email:"Унесите исправну и-мејл адресу.",url:"Унесите исправан URL.",date:"Унесите исправан датум.",dateISO:"Унесите исправан датум (ISO).",number:"Унесите исправан број.",digits:"Унесите само цифе.",creditcard:"Унесите исправан број кредитне картице.",equalTo:"Унесите исту вредност поново.",extension:"Унесите вредност са одговарајућом екстензијом.",maxlength:a.validator.format("Унесите мање од {0} карактера."),minlength:a.validator.format("Унесите барем {0} карактера."),rangelength:a.validator.format("Унесите вредност дугачку између {0} и {1} карактера."),range:a.validator.format("Унесите вредност између {0} и {1}."),max:a.validator.format("Унесите вредност мању или једнаку {0}."),min:a.validator.format("Унесите вредност већу или једнаку {0}."),step:a.validator.format("Унесите вредност која је умножак броја {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Polje je obavezno.",remote:"Sredite ovo polje.",email:"Unesite ispravnu e-mail adresu",url:"Unesite ispravan URL.",date:"Unesite ispravan datum.",dateISO:"Unesite ispravan datum (ISO).",number:"Unesite ispravan broj.",digits:"Unesite samo cifre.",creditcard:"Unesite ispravan broj kreditne kartice.",equalTo:"Unesite istu vrednost ponovo.",extension:"Unesite vrednost sa odgovarajućom ekstenzijom.",maxlength:a.validator.format("Unesite manje od {0} karaktera."),minlength:a.validator.format("Unesite barem {0} karaktera."),rangelength:a.validator.format("Unesite vrednost dugačku između {0} i {1} karaktera."),range:a.validator.format("Unesite vrednost između {0} i {1}."),max:a.validator.format("Unesite vrednost manju ili jednaku {0}."),min:a.validator.format("Unesite vrednost veću ili jednaku {0}."),step:a.validator.format("Unesite vrednost koja je umnožak broja {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Detta f&auml;lt &auml;r obligatoriskt.",remote:"Var snäll och åtgärda detta fält.",maxlength:a.validator.format("Du f&aring;r ange h&ouml;gst {0} tecken."),minlength:a.validator.format("Du m&aring;ste ange minst {0} tecken."),rangelength:a.validator.format("Ange minst {0} och max {1} tecken."),email:"Ange en korrekt e-postadress.",url:"Ange en korrekt URL.",date:"Ange ett korrekt datum.",dateISO:"Ange ett korrekt datum (&Aring;&Aring;&Aring;&Aring;-MM-DD).",number:"Ange ett korrekt nummer.",digits:"Ange endast siffror.",equalTo:"Ange samma v&auml;rde igen.",range:a.validator.format("Ange ett v&auml;rde mellan {0} och {1}."),max:a.validator.format("Ange ett v&auml;rde som &auml;r mindre eller lika med {0}."),min:a.validator.format("Ange ett v&auml;rde som &auml;r st&ouml;rre eller lika med {0}."),creditcard:"Ange ett korrekt kreditkortsnummer.",pattern:"Ogiltigt format."}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"โปรดระบุ",remote:"โปรดแก้ไขให้ถูกต้อง",email:"โปรดระบุที่อยู่อีเมล์ที่ถูกต้อง",url:"โปรดระบุ URL ที่ถูกต้อง",date:"โปรดระบุวันที่ ที่ถูกต้อง",dateISO:"โปรดระบุวันที่ ที่ถูกต้อง (ระบบ ISO).",number:"โปรดระบุทศนิยมที่ถูกต้อง",digits:"โปรดระบุจำนวนเต็มที่ถูกต้อง",creditcard:"โปรดระบุรหัสบัตรเครดิตที่ถูกต้อง",equalTo:"โปรดระบุค่าเดิมอีกครั้ง",extension:"โปรดระบุค่าที่มีส่วนขยายที่ถูกต้อง",maxlength:a.validator.format("โปรดอย่าระบุค่าที่ยาวกว่า {0} อักขระ"),minlength:a.validator.format("โปรดอย่าระบุค่าที่สั้นกว่า {0} อักขระ"),rangelength:a.validator.format("โปรดอย่าระบุค่าความยาวระหว่าง {0} ถึง {1} อักขระ"),range:a.validator.format("โปรดระบุค่าระหว่าง {0} และ {1}"),max:a.validator.format("โปรดระบุค่าน้อยกว่าหรือเท่ากับ {0}"),min:a.validator.format("โปรดระบุค่ามากกว่าหรือเท่ากับ {0}")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Ворид кардани ин филд маҷбури аст.",remote:"Илтимос, маълумоти саҳеҳ ворид кунед.",email:"Илтимос, почтаи электронии саҳеҳ ворид кунед.",url:"Илтимос, URL адреси саҳеҳ ворид кунед.",date:"Илтимос, таърихи саҳеҳ ворид кунед.",dateISO:"Илтимос, таърихи саҳеҳи (ISO)ӣ ворид кунед.",number:"Илтимос, рақамҳои саҳеҳ ворид кунед.",digits:"Илтимос, танҳо рақам ворид кунед.",creditcard:"Илтимос, кредит карди саҳеҳ ворид кунед.",equalTo:"Илтимос, миқдори баробар ворид кунед.",extension:"Илтимос, қофияи файлро дуруст интихоб кунед",maxlength:a.validator.format("Илтимос, бештар аз {0} рамз ворид накунед."),minlength:a.validator.format("Илтимос, камтар аз {0} рамз ворид накунед."),rangelength:a.validator.format("Илтимос, камтар аз {0} ва зиёда аз {1} рамз ворид кунед."),range:a.validator.format("Илтимос, аз {0} то {1} рақам зиёд ворид кунед."),max:a.validator.format("Илтимос, бештар аз {0} рақам ворид накунед."),min:a.validator.format("Илтимос, камтар аз {0} рақам ворид накунед.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Bu alanın doldurulması zorunludur.",remote:"Lütfen bu alanı düzeltin.",email:"Lütfen geçerli bir e-posta adresi giriniz.",url:"Lütfen geçerli bir web adresi (URL) giriniz.",date:"Lütfen geçerli bir tarih giriniz.",dateISO:"Lütfen geçerli bir tarih giriniz(ISO formatında)",number:"Lütfen geçerli bir sayı giriniz.",digits:"Lütfen sadece sayısal karakterler giriniz.",creditcard:"Lütfen geçerli bir kredi kartı giriniz.",equalTo:"Lütfen aynı değeri tekrar giriniz.",extension:"Lütfen geçerli uzantıya sahip bir değer giriniz.",phone:"Lütfen geçerli bir telefon numarası giriniz.",maxlength:a.validator.format("Lütfen en fazla {0} karakter uzunluğunda bir değer giriniz."),minlength:a.validator.format("Lütfen en az {0} karakter uzunluğunda bir değer giriniz."),rangelength:a.validator.format("Lütfen en az {0} ve en fazla {1} uzunluğunda bir değer giriniz."),range:a.validator.format("Lütfen {0} ile {1} arasında bir değer giriniz."),max:a.validator.format("Lütfen {0} değerine eşit ya da daha küçük bir değer giriniz."),min:a.validator.format("Lütfen {0} değerine eşit ya da daha büyük bir değer giriniz."),require_from_group:a.validator.format("Lütfen bu alanların en az {0} tanesini doldurunuz.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Це поле необхідно заповнити.",remote:"Будь ласка, введіть правильне значення.",email:"Будь ласка, введіть коректну адресу електронної пошти.",url:"Будь ласка, введіть коректний URL.",date:"Будь ласка, введіть коректну дату.",dateISO:"Будь ласка, введіть коректну дату у форматі ISO.",number:"Будь ласка, введіть число.",digits:"Вводите потрібно лише цифри.",creditcard:"Будь ласка, введіть правильний номер кредитної карти.",equalTo:"Будь ласка, введіть таке ж значення ще раз.",extension:"Будь ласка, виберіть файл з правильним розширенням.",maxlength:a.validator.format("Будь ласка, введіть не більше {0} символів."),minlength:a.validator.format("Будь ласка, введіть не менше {0} символів."),rangelength:a.validator.format("Будь ласка, введіть значення довжиною від {0} до {1} символів."),range:a.validator.format("Будь ласка, введіть число від {0} до {1}."),max:a.validator.format("Будь ласка, введіть число, менше або рівно {0}."),min:a.validator.format("Будь ласка, введіть число, більше або рівно {0}.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"ان معلومات کا اندراج ضروری ہے",remote:"ان معلومات کا اندراج ضروری ہے",email:"درج کی ہوئی ای میل درست نہیں ہے",url:"درج کیا گیا پتہ درست نہیں ہے",date:"درج کی گئی تاریخ درست نہیں ہے",dateISO:"معیار کے مطابق نہیں ہے (ISO) درج کی گئی تاریخ",number:"درج کیےگئے ہندسے درست نہیں ہیں",digits:"صرف ہندسے اندراج کئے جاسکتے ہیں",creditcard:"درج کیا گیا کارڈ نمبر درست نہیں ہے",equalTo:"اندراج کا موازنہ درست نہیں ہے",extension:"اندراج درست نہیں ہے",maxlength:a.validator.format("زیادہ سے زیادہ {0} کا اندراج کر سکتے ہیں"),minlength:a.validator.format("کم سے کم {0} کا اندراج کرنا ضروری ہے"),rangelength:a.validator.format("اندراج کا {0} اور {1}کے درمیان ہونا ضروری ہے"),range:a.validator.format("اندراج کا {0} اور {1} کے درمیان ہونا ضروری ہے"),max:a.validator.format("زیادہ سے زیادہ {0} کا اندراج کر سکتے ہیں"),min:a.validator.format("کم سے کم {0} کا اندراج کرنا ضروری ہے")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"Hãy nhập.",remote:"Hãy sửa cho đúng.",email:"Hãy nhập email.",url:"Hãy nhập URL.",date:"Hãy nhập ngày.",dateISO:"Hãy nhập ngày (ISO).",number:"Hãy nhập số.",digits:"Hãy nhập chữ số.",creditcard:"Hãy nhập số thẻ tín dụng.",equalTo:"Hãy nhập thêm lần nữa.",extension:"Phần mở rộng không đúng.",maxlength:a.validator.format("Hãy nhập từ {0} kí tự trở xuống."),minlength:a.validator.format("Hãy nhập từ {0} kí tự trở lên."),rangelength:a.validator.format("Hãy nhập từ {0} đến {1} kí tự."),range:a.validator.format("Hãy nhập từ {0} đến {1}."),max:a.validator.format("Hãy nhập từ {0} trở xuống."),min:a.validator.format("Hãy nhập từ {0} trở lên.")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"这是必填字段",remote:"请修正此字段",email:"请输入有效的电子邮件地址",url:"请输入有效的网址",date:"请输入有效的日期",dateISO:"请输入有效的日期 (YYYY-MM-DD)",number:"请输入有效的数字",digits:"只能输入数字",creditcard:"请输入有效的信用卡号码",equalTo:"你的输入不相同",extension:"请输入有效的后缀",maxlength:a.validator.format("最多可以输入 {0} 个字符"),minlength:a.validator.format("最少要输入 {0} 个字符"),rangelength:a.validator.format("请输入长度在 {0} 到 {1} 之间的字符串"),range:a.validator.format("请输入范围在 {0} 到 {1} 之间的数值"),step:a.validator.format("请输入 {0} 的整数倍值"),max:a.validator.format("请输入不大于 {0} 的数值"),min:a.validator.format("请输入不小于 {0} 的数值")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"必須填寫",remote:"請修正此欄位",email:"請輸入有效的電子郵件",url:"請輸入有效的網址",date:"請輸入有效的日期",dateISO:"請輸入有效的日期 (YYYY-MM-DD)",number:"請輸入正確的數值",digits:"只可輸入數字",creditcard:"請輸入有效的信用卡號碼",equalTo:"請重複輸入一次",extension:"請輸入有效的後綴",maxlength:a.validator.format("最多 {0} 個字"),minlength:a.validator.format("最少 {0} 個字"),rangelength:a.validator.format("請輸入長度為 {0} 至 {1} 之間的字串"),range:a.validator.format("請輸入 {0} 至 {1} 之間的數值"),step:a.validator.format("請輸入 {0} 的整數倍值"),max:a.validator.format("請輸入不大於 {0} 的數值"),min:a.validator.format("請輸入不小於 {0} 的數值")}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.methods,{date:function(a,b){return this.optional(b)||/^\d\d?\.\d\d?\.\d\d\d?\d?$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(a)}}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.methods,{date:function(a,b){return this.optional(b)||/^\d\d?\-\d\d?\-\d\d\d?\d?$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(a)}}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.methods,{date:function(a,b){return this.optional(b)||/^\d{1,2}\.\d{1,2}\.\d{4}$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+)(?:,\d+)?$/.test(a)}}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.methods,{date:function(a,b){return this.optional(b)||/^\d\d?\-\d\d?\-\d\d\d?\d?$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(a)}}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.methods,{date:function(a,b){return this.optional(b)||/^\d\d?[\.\/\-]\d\d?[\.\/\-]\d\d\d?\d?$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(a)}}),a});

View File

@ -0,0 +1,4 @@
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
* https://jqueryvalidation.org/
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.methods,{date:function(a,b){return this.optional(b)||/^\d\d?\/\d\d?\/\d\d\d?\d?$/.test(a)}}),a});

2
client/dist/js/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
client/dist/styles/cms.css vendored Normal file
View File

@ -0,0 +1 @@
.cms table.ss-gridfield-table tr.spam{background-color:#ffd8d8}.cms table.ss-gridfield-table tr.spam:hover{background-color:#fff2f2}

1
client/dist/styles/comments.css vendored Normal file
View File

@ -0,0 +1 @@
.comments-holder-container{clear:both}.comments-holder-container .field{clear:left}.comments-holder-container .author,.comments-holder-container .num{font-size:1.3em}.comments-holder-container .num{color:#999;margin-right:5px}.comments-holder-container .num-total{line-height:40px;margin-bottom:0}.comments-holder-container #moderated{border:1px solid #999;padding:20px;font-style:italic}.comments-holder-container .comments-list{margin:0}.comments-holder-container .comment-count{margin:15px 0}.comments-holder-container .commenting-area{margin-top:50px}.comments-holder-container .commenting-area label.left{font-weight:400}.comments-holder-container .commenting-rss-feed{margin-top:4em;text-align:right}.comments-holder-container .commenting-rss-feed .action-links{margin:20px 0 10px}.comments-holder-container .commenting-rss-feed .action-links li{display:inline;list-style-type:none;margin-left:20px}.comments-holder-container .commenting-rss-feed .action-links li:first-child{margin-left:0}.comments-holder-container .commenting-rss-feed .action-links li.comment-reply-action{float:right}.comments-holder-container .commenting-rss-feed .action-links a{background-image:none}.comments-holder-container .commenting-rss-feed .action-links a:first-letter{text-transform:capitalize}.comments-holder-container .no-comments-yet{display:inline-block;margin-top:10px}.comment{clear:both;list-style-type:none;overflow:hidden;padding:20px 0;position:relative}.comment.author-comment:after{content:"Author";float:right;position:absolute;top:1.5em;right:.5em;font-size:1em;font-weight:700}.comment.author-comment>.comment-text{border:1px solid blue}.comment.spam .comment-text{border:1px dashed orange}.comment img.gravatar{float:left;margin:20px;width:90px;height:90px;border:none}.comment .comment-text{background-color:#fff;border:1px solid #ddd;-webkit-box-shadow:none;box-shadow:none;margin:0;padding:0 20px;min-height:130px;white-space:pre;white-space:pre-wrap;white-space:pre-line;word-wrap:break-word}.comment .comment-text p:last-child{margin-bottom:0}.comment .comment-text.hasGravatar{padding:0 20px 0 130px;min-height:130px}.comment .date{font-size:16px}.comment .date:before{content:"\A0\A0\A0\A0"}.comment.unmoderated>.comment-text{border:1px solid #ff0}.comment .info{margin-bottom:10px}.comment.spam .comment{border:1px dashed orange;border-radius:4px;padding:2.5em 1em 1em}.comment .comment-replies-container{clear:both;padding-left:10px;margin:80px 0 0;border-left:1px dashed #999}.comment .comment-replies-container .comment-reply-form-holder{padding:0 10px}.comment .comment-replies-container .comment-replies-holder{padding:0 0 0 10px}.comments-list.root-level{margin-left:0}.comment-reply-link{float:right}.comment-moderation-options{float:left}.comment-action-links{margin:20px 0 10px}.comment-action-links a:not(:last-child){margin-right:12px}.commenting-rss-feed ul{list-style:none}

View File

@ -4,7 +4,7 @@ if (typeof(ss) == 'undefined' || typeof(ss.i18n) == 'undefined') {
if (typeof(console) != 'undefined') console.error('Class ss.i18n not defined');
} else {
ss.i18n.addDictionary('en', {
"CommentsInterface_singlecomment_ss.DELETE_CONFIRMATION": "Are you sure?",
"CommentsInterface_singlecomment_ss.DELETE_CONFIRMATION": "Are you sure you want to delete this comment?",
"CommentsInterface_singlecomment_ss.AJAX_ERROR": "An error occurred whilst updating the comment",
});
}

4
client/lang/src/en.json Normal file
View File

@ -0,0 +1,4 @@
{
"CommentsInterface_singlecomment_ss.DELETE_CONFIRMATION": "Are you sure you want to delete this comment?",
"CommentsInterface_singlecomment_ss.AJAX_ERROR": "An error occurred whilst updating the comment",
}

View File

@ -0,0 +1,133 @@
/**
* @package comments
*/
(function($) {
// The above closure encapsulates the $ variable away from the global scope
// and the one below is the `$(document).ready(...)` shorthand.
$(function() {
// Override the default URL validator in order to extend it to allow protocol-less URLs
$.validator.methods.url = function( value, element ) {
// This line is copied directly from the jQuery.validation source (version 1.19.0)
// the only change is a single question mark added here ---------v
return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)?(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value );
}
/**
* Enable form validation
*/
$('.comments-holder-container form').each(function() {
$(this).validate({
// Ignore hidden elements in this form
ignore: ':hidden',
// Use default 'required' for error labels
errorClass: "required",
// Use span instead of labels
errorElement: "span",
// On error, scroll to the invalid element
invalidHandler : function(form, validator){
$('html, body').animate({
scrollTop: $(validator.errorList[0].element).offset().top - 30
}, 200);
},
// Ensure any new error message has the correct class and placement
errorPlacement: function(error, element) {
error
.addClass('message')
.insertAfter(element);
}
});
});
/**
* Hide comment reply forms by default (unless visiting via permalink)
*/
$(".comment")
.children('.info')
.not(window.document.location.hash)
.nextAll(".comment-replies-container")
.children(".comment-reply-form-holder")
.hide();
/**
* Toggle on/off reply form
*/
$('.comments-holder').on('click', '.comment-reply-link', function(e) {
var allForms = $('.comment-reply-form-holder');
var formID = '#' + $(this).attr('aria-controls');
var form = $(formID).closest('.comment-reply-form-holder');
$(this).attr('aria-expanded', function (i, attr) {
return attr == 'true' ? 'false' : 'true'
});
// Prevent focus
e.preventDefault();
if(form.is(':visible')) {
allForms.slideUp();
} else {
allForms.not(form).slideUp();
form.slideDown();
}
});
/**
* Clicking one of the metalinks performs the operation via ajax
* this inclues the spam and approve links
*/
$('.comments-holder .comments-list').on('click', 'div.comment-moderation-options a', function(e) {
e.stopPropagation();
var link = $(this);
if (link.hasClass('delete')) {
var confirmationMsg = ss.i18n._t('CommentsInterface_singlecomment_ss.DELETE_CONFIRMATION');
var confirmation = window.confirm(confirmationMsg);
if (!confirmation) {
e.preventDefault();
return false;
}
}
var comment = link.parents('.comment:first');
$.ajax({
url: $(this).attr('href'),
cache: false,
success: function(html){
if(link.hasClass('ham')) {
// comment has been marked as not spam
comment.html(html);
comment.removeClass('spam');
}
else if(link.hasClass('approve')) {
// comment has been approved
comment.html(html);
comment.removeClass('unmoderated');
}
else if(link.hasClass('delete')) {
comment.fadeOut(1000, function() {
comment.remove();
if($('.comments-holder .comments-list').children().length === 0) {
$('.no-comments-yet').show();
}
});
}
else if(link.hasClass('spam')) {
comment.html(html).addClass('spam');
}
},
failure: function(html) {
var errorMsg = ss.i18n._t('CommentsInterface_singlecomment_ss.AJAX_ERROR');
alert(errorMsg);
}
});
e.preventDefault();
});
});
})(jQuery);

View File

@ -1,162 +0,0 @@
<?php
/**
* Helper Class for storing the configuration options. Retains the mapping between
* objects which have comments attached and the related configuration options.
*
* Also handles adding the Commenting extension to the {@link DataObject} on behalf
* of the user.
*
* For documentation on how to use this class see docs/en/Configuration.md
*
* @deprecated since version 2.0
*
* @package comments
*/
class Commenting
{
/**
* Adds commenting to a {@link DataObject}
*
* @deprecated since version 2.0
*
* @param string classname to add commenting to
* @param array $settings Settings. See {@link self::$default_config} for
* available settings
*
* @throws InvalidArgumentException
*/
public static function add($class, $settings = false)
{
Deprecation::notice('2.0', 'Using Commenting::add is deprecated. Please use the config API instead');
Config::inst()->update($class, 'extensions', array('CommentsExtension'));
// Check if settings must be customised
if ($settings === false) {
return;
}
if (!is_array($settings)) {
throw new InvalidArgumentException('$settings needs to be an array or null');
}
Config::inst()->update($class, 'comments', $settings);
}
/**
* Removes commenting from a {@link DataObject}. Does not remove existing comments
* but does remove the extension.
*
* @deprecated since version 2.0
*
* @param string $class Class to remove {@link CommentsExtension} from
*/
public static function remove($class)
{
Deprecation::notice('2.0', 'Using Commenting::remove is deprecated. Please use the config API instead');
$class::remove_extension('CommentsExtension');
}
/**
* Returns whether a given class name has commenting enabled
*
* @deprecated since version 2.0
*
* @return bool
*/
public static function has_commenting($class)
{
Deprecation::notice('2.0', 'Using Commenting::has_commenting is deprecated. Please use the config API instead');
return $class::has_extension('CommentsExtension');
}
/**
* Sets a value for a class of a given config setting. Passing 'all' as the class
* sets it for everything
*
* @deprecated since version 2.0
*
* @param string $class Class to set the value on. Passing 'all' will set it to all
* active mappings
* @param string $key setting to change
* @param mixed $value value of the setting
*/
public static function set_config_value($class, $key, $value = false)
{
Deprecation::notice('2.0', 'Commenting::set_config_value is deprecated. Use the config api instead');
if ($class === "all") {
$class = 'CommentsExtension';
}
Config::inst()->update($class, 'comments', array($key => $value));
}
/**
* Returns a given config value for a commenting class
*
* @deprecated since version 2.0
*
* @param string $class
* @param string $key config value to return
*
* @throws Exception
* @return mixed
*/
public static function get_config_value($class, $key)
{
Deprecation::notice(
'2.0',
'Using Commenting::get_config_value is deprecated. Please use $parent->getCommentsOption() or '
. 'CommentingController::getOption() instead'
);
// Get settings
if (!$class) {
$class = 'CommentsExtension';
} elseif (!$class::has_extension('CommentsExtension')) {
throw new InvalidArgumentException("$class does not have commenting enabled");
}
return singleton($class)->getCommentsOption($key);
}
/**
* Determines whether a config value on the commenting extension
* matches a given value.
*
* @deprecated since version 2.0
*
* @param string $class
* @param string $key
* @param string $value Expected value
* @return boolean
*/
public static function config_value_equals($class, $key, $value)
{
$check = self::get_config_value($class, $key);
if ($check && ($check == $value)) {
return true;
}
}
/**
* Return whether a user can post on a given commenting instance
*
* @deprecated since version 2.0
*
* @param string $class
* @return boolean true
*/
public static function can_member_post($class)
{
Deprecation::notice('2.0', 'Use $instance->canPostComment() directly instead');
$member = Member::currentUser();
// Check permission
$permission = self::get_config_value($class, 'required_permission');
if ($permission && !Permission::check($permission)) {
return false;
}
// Check login required
$requireLogin = self::get_config_value($class, 'require_login');
return !$requireLogin || $member;
}
}

View File

@ -1,24 +0,0 @@
<?php
class CommentsGridField extends GridField
{
/**
* {@inheritdoc}
*/
protected function newRow($total, $index, $record, $attributes, $content)
{
if (!isset($attributes['class'])) {
$attributes['class'] = '';
}
if ($record->IsSpam) {
$attributes['class'] .= ' spam';
}
return FormField::create_tag(
'tr',
$attributes,
$content
);
}
}

View File

@ -1,55 +0,0 @@
<?php
class CommentsGridFieldConfig extends GridFieldConfig_RecordEditor
{
public function __construct($itemsPerPage = 25)
{
parent::__construct($itemsPerPage);
// $this->addComponent(new GridFieldExportButton());
$this->addComponent(new CommentsGridFieldAction());
// Format column
$columns = $this->getComponentByType('GridFieldDataColumns');
$columns->setFieldFormatting(array(
'ParentTitle' => function ($value, &$item) {
return sprintf(
'<a href="%s" class="cms-panel-link external-link action" target="_blank">%s</a>',
Convert::raw2att($item->Link()),
$item->obj('ParentTitle')->forTemplate()
);
}
));
// Add bulk option
$manager = new GridFieldBulkManager();
$manager->addBulkAction(
'spam',
_t('CommentsGridFieldConfig.SPAM', 'Spam'),
'CommentsGridFieldBulkAction_Handlers',
array(
'isAjax' => true,
'icon' => 'cross',
'isDestructive' => false
)
);
$manager->addBulkAction(
'approve',
_t('CommentsGridFieldConfig.APPROVE', 'Approve'),
'CommentsGridFieldBulkAction_Handlers',
array(
'isAjax' => true,
'icon' => 'cross',
'isDestructive' => false
)
);
$manager->removeBulkAction('bulkEdit');
$manager->removeBulkAction('unLink');
$this->addComponent($manager);
}
}

View File

@ -1,681 +0,0 @@
<?php
/**
* @package comments
*/
class CommentingController extends Controller
{
private static $allowed_actions = array(
'delete',
'spam',
'ham',
'approve',
'rss',
'CommentsForm',
'reply',
'doPostComment',
'doPreviewComment'
);
private static $url_handlers = array(
'reply/$ParentCommentID//$ID/$OtherID' => 'reply',
);
/**
* Fields required for this form
*
* @var array
* @config
*/
private static $required_fields = array(
'Name',
'Email',
'Comment'
);
/**
* Base class this commenting form is for
*
* @var string
*/
private $baseClass = "";
/**
* The record this commenting form is for
*
* @var DataObject
*/
private $ownerRecord = null;
/**
* Parent controller record
*
* @var Controller
*/
private $ownerController = null;
/**
* Backup url to return to
*
* @var string
*/
protected $fallbackReturnURL = null;
/**
* Set the base class to use
*
* @param string $class
*/
public function setBaseClass($class)
{
$this->baseClass = $class;
}
/**
* Get the base class used
*
* @return string
*/
public function getBaseClass()
{
return $this->baseClass;
}
/**
* Set the record this controller is working on
*
* @param DataObject $record
*/
public function setOwnerRecord($record)
{
$this->ownerRecord = $record;
}
/**
* Get the record
*
* @return DataObject
*/
public function getOwnerRecord()
{
return $this->ownerRecord;
}
/**
* Set the parent controller
*
* @param Controller $controller
*/
public function setOwnerController($controller)
{
$this->ownerController = $controller;
}
/**
* Get the parent controller
*
* @return Controller
*/
public function getOwnerController()
{
return $this->ownerController;
}
/**
* Get the commenting option for the current state
*
* @param string $key
* @return mixed Result if the setting is available, or null otherwise
*/
public function getOption($key)
{
// If possible use the current record
if ($record = $this->getOwnerRecord()) {
return $record->getCommentsOption($key);
}
// Otherwise a singleton of that record
if ($class = $this->getBaseClass()) {
return singleton($class)->getCommentsOption($key);
}
// Otherwise just use the default options
return singleton('CommentsExtension')->getCommentsOption($key);
}
/**
* Workaround for generating the link to this controller
*
* @return string
*/
public function Link($action = '', $id = '', $other = '')
{
return Controller::join_links(Director::baseURL(), __CLASS__, $action, $id, $other);
}
/**
* Outputs the RSS feed of comments
*
* @return HTMLText
*/
public function rss()
{
return $this->getFeed($this->request)->outputToBrowser();
}
/**
* Return an RSSFeed of comments for a given set of comments or all
* comments on the website.
*
* To maintain backwards compatibility with 2.4 this supports mapping
* of PageComment/rss?pageid= as well as the new RSS format for comments
* of CommentingController/rss/{classname}/{id}
*
* @param SS_HTTPRequest
*
* @return RSSFeed
*/
public function getFeed(SS_HTTPRequest $request)
{
$link = $this->Link('rss');
$class = $request->param('ID');
$id = $request->param('OtherID');
// Support old pageid param
if (!$id && !$class && ($id = $request->getVar('pageid'))) {
$class = 'SiteTree';
}
$comments = Comment::get()->filter(array(
'Moderated' => 1,
'IsSpam' => 0,
));
// Check if class filter
if ($class) {
if (!is_subclass_of($class, 'DataObject') || !$class::has_extension('CommentsExtension')) {
return $this->httpError(404);
}
$this->setBaseClass($class);
$comments = $comments->filter('BaseClass', $class);
$link = Controller::join_links($link, $class);
// Check if id filter
if ($id) {
$comments = $comments->filter('ParentID', $id);
$link = Controller::join_links($link, $id);
$this->setOwnerRecord(DataObject::get_by_id($class, $id));
}
}
$title = _t('CommentingController.RSSTITLE', "Comments RSS Feed");
$comments = new PaginatedList($comments, $request);
$comments->setPageLength($this->getOption('comments_per_page'));
return new RSSFeed(
$comments,
$link,
$title,
$link,
'Title', 'EscapedComment', 'AuthorName'
);
}
/**
* Deletes a given {@link Comment} via the URL.
*/
public function delete()
{
$comment = $this->getComment();
if (!$comment) {
return $this->httpError(404);
}
if (!$comment->canDelete()) {
return Security::permissionFailure($this, 'You do not have permission to delete this comment');
}
if (!$comment->getSecurityToken()->checkRequest($this->request)) {
return $this->httpError(400);
}
$comment->delete();
return $this->request->isAjax()
? true
: $this->redirectBack();
}
/**
* Marks a given {@link Comment} as spam. Removes the comment from display
*/
public function spam()
{
$comment = $this->getComment();
if (!$comment) {
return $this->httpError(404);
}
if (!$comment->canEdit()) {
return Security::permissionFailure($this, 'You do not have permission to edit this comment');
}
if (!$comment->getSecurityToken()->checkRequest($this->request)) {
return $this->httpError(400);
}
$comment->markSpam();
return $this->renderChangedCommentState($comment);
}
/**
* Marks a given {@link Comment} as ham (not spam).
*/
public function ham()
{
$comment = $this->getComment();
if (!$comment) {
return $this->httpError(404);
}
if (!$comment->canEdit()) {
return Security::permissionFailure($this, 'You do not have permission to edit this comment');
}
if (!$comment->getSecurityToken()->checkRequest($this->request)) {
return $this->httpError(400);
}
$comment->markApproved();
return $this->renderChangedCommentState($comment);
}
/**
* Marks a given {@link Comment} as approved.
*/
public function approve()
{
$comment = $this->getComment();
if (!$comment) {
return $this->httpError(404);
}
if (!$comment->canEdit()) {
return Security::permissionFailure($this, 'You do not have permission to approve this comment');
}
if (!$comment->getSecurityToken()->checkRequest($this->request)) {
return $this->httpError(400);
}
$comment->markApproved();
return $this->renderChangedCommentState($comment);
}
/**
* Redirect back to referer if available, ensuring that only site URLs
* are allowed to avoid phishing. If it's an AJAX request render the
* comment in it's new state
*/
private function renderChangedCommentState($comment)
{
$referer = $this->request->getHeader('Referer');
// Render comment using AJAX
if ($this->request->isAjax()) {
return $comment->renderWith('CommentsInterface_singlecomment');
} else {
// Redirect to either the comment or start of the page
if (empty($referer)) {
return $this->redirectBack();
} else {
// Redirect to the comment, but check for phishing
$url = $referer . '#comment-' . $comment->ID;
// absolute redirection URLs not located on this site may cause phishing
if (Director::is_site_url($url)) {
return $this->redirect($url);
} else {
return false;
}
}
}
}
/**
* Returns the comment referenced in the URL (by ID). Permission checking
* should be done in the callee.
*
* @return Comment|false
*/
public function getComment()
{
$id = isset($this->urlParams['ID']) ? $this->urlParams['ID'] : false;
if ($id) {
$comment = DataObject::get_by_id('Comment', $id);
if ($comment) {
$this->fallbackReturnURL = $comment->Link();
return $comment;
}
}
return false;
}
/**
* Create a reply form for a specified comment
*
* @param Comment $comment
*/
public function ReplyForm($comment)
{
// Enables multiple forms with different names to use the same handler
$form = $this->CommentsForm();
$form->setName('ReplyForm_'.$comment->ID);
$form->addExtraClass('reply-form');
// Load parent into reply form
$form->loadDataFrom(array(
'ParentCommentID' => $comment->ID
));
// Customise action
$form->setFormAction($this->Link('reply', $comment->ID));
$this->extend('updateReplyForm', $form);
return $form;
}
/**
* Request handler for reply form.
* This method will disambiguate multiple reply forms in the same method
*
* @param SS_HTTPRequest $request
*/
public function reply(SS_HTTPRequest $request)
{
// Extract parent comment from reply and build this way
if ($parentID = $request->param('ParentCommentID')) {
$comment = DataObject::get_by_id('Comment', $parentID, true);
if ($comment) {
return $this->ReplyForm($comment);
}
}
return $this->httpError(404);
}
/**
* Post a comment form
*
* @return Form
*/
public function CommentsForm()
{
$usePreview = $this->getOption('use_preview');
$nameRequired = _t('CommentInterface.YOURNAME_MESSAGE_REQUIRED', 'Please enter your name');
$emailRequired = _t('CommentInterface.EMAILADDRESS_MESSAGE_REQUIRED', 'Please enter your email address');
$emailInvalid = _t('CommentInterface.EMAILADDRESS_MESSAGE_EMAIL', 'Please enter a valid email address');
$urlInvalid = _t('CommentInterface.COMMENT_MESSAGE_URL', 'Please enter a valid URL');
$commentRequired = _t('CommentInterface.COMMENT_MESSAGE_REQUIRED', 'Please enter your comment');
$fields = new FieldList(
$dataFields = new CompositeField(
// Name
TextField::create("Name", _t('CommentInterface.YOURNAME', 'Your name'))
->setCustomValidationMessage($nameRequired)
->setAttribute('data-msg-required', $nameRequired),
// Email
EmailField::create(
"Email",
_t('CommentingController.EMAILADDRESS', "Your email address (will not be published)")
)
->setCustomValidationMessage($emailRequired)
->setAttribute('data-msg-required', $emailRequired)
->setAttribute('data-msg-email', $emailInvalid)
->setAttribute('data-rule-email', true),
// Url
TextField::create("URL", _t('CommentingController.WEBSITEURL', "Your website URL"))
->setAttribute('data-msg-url', $urlInvalid)
->setAttribute('data-rule-url', true),
// Comment
TextareaField::create("Comment", _t('CommentingController.COMMENTS', "Comments"))
->setCustomValidationMessage($commentRequired)
->setAttribute('data-msg-required', $commentRequired)
),
HiddenField::create("ParentID"),
HiddenField::create("ReturnURL"),
HiddenField::create("ParentCommentID"),
HiddenField::create("BaseClass")
);
// Preview formatted comment. Makes most sense when shortcodes or
// limited HTML is allowed. Populated by JS/Ajax.
if ($usePreview) {
$fields->insertAfter(
ReadonlyField::create('PreviewComment', _t('CommentInterface.PREVIEWLABEL', 'Preview'))
->setAttribute('style', 'display: none'), // enable through JS
'Comment'
);
}
$dataFields->addExtraClass('data-fields');
// save actions
$actions = new FieldList(
new FormAction("doPostComment", _t('CommentInterface.POST', 'Post'))
);
if ($usePreview) {
$actions->push(
FormAction::create('doPreviewComment', _t('CommentInterface.PREVIEW', 'Preview'))
->addExtraClass('action-minor')
->setAttribute('style', 'display: none') // enable through JS
);
}
// required fields for server side
$required = new RequiredFields($this->config()->required_fields);
// create the comment form
$form = new Form($this, 'CommentsForm', $fields, $actions, $required);
// if the record exists load the extra required data
if ($record = $this->getOwnerRecord()) {
// Load member data
$member = Member::currentUser();
if (($record->CommentsRequireLogin || $record->PostingRequiredPermission) && $member) {
$fields = $form->Fields();
$fields->removeByName('Name');
$fields->removeByName('Email');
$fields->insertBefore(new ReadonlyField("NameView", _t('CommentInterface.YOURNAME', 'Your name'), $member->getName()), 'URL');
$fields->push(new HiddenField("Name", "", $member->getName()));
$fields->push(new HiddenField("Email", "", $member->Email));
}
// we do not want to read a new URL when the form has already been submitted
// which in here, it hasn't been.
$form->loadDataFrom(array(
'ParentID' => $record->ID,
'ReturnURL' => $this->request->getURL(),
'BaseClass' => $this->getBaseClass()
));
}
// Set it so the user gets redirected back down to the form upon form fail
$form->setRedirectToFormOnValidationError(true);
// load any data from the cookies
if ($data = Cookie::get('CommentsForm_UserData')) {
$data = Convert::json2array($data);
$form->loadDataFrom(array(
"Name" => isset($data['Name']) ? $data['Name'] : '',
"URL" => isset($data['URL']) ? $data['URL'] : '',
"Email" => isset($data['Email']) ? $data['Email'] : ''
));
// allow previous value to fill if comment not stored in cookie (i.e. validation error)
$prevComment = Cookie::get('CommentsForm_Comment');
if ($prevComment && $prevComment != '') {
$form->loadDataFrom(array("Comment" => $prevComment));
}
}
if (!empty($member)) {
$form->loadDataFrom($member);
}
// hook to allow further extensions to alter the comments form
$this->extend('alterCommentForm', $form);
return $form;
}
/**
* Process which creates a {@link Comment} once a user submits a comment from this form.
*
* @param array $data
* @param Form $form
*/
public function doPostComment($data, $form)
{
// Load class and parent from data
if (isset($data['BaseClass'])) {
$this->setBaseClass($data['BaseClass']);
}
if (isset($data['ParentID']) && ($class = $this->getBaseClass())) {
$this->setOwnerRecord($class::get()->byID($data['ParentID']));
}
if (!$this->getOwnerRecord()) {
return $this->httpError(404);
}
// cache users data
Cookie::set("CommentsForm_UserData", Convert::raw2json($data));
Cookie::set("CommentsForm_Comment", $data['Comment']);
// extend hook to allow extensions. Also see onAfterPostComment
$this->extend('onBeforePostComment', $form);
// If commenting can only be done by logged in users, make sure the user is logged in
if (!$this->getOwnerRecord()->canPostComment()) {
return Security::permissionFailure(
$this,
_t(
'CommentingController.PERMISSIONFAILURE',
"You're not able to post comments to this page. Please ensure you are logged in and have an "
. "appropriate permission level."
)
);
}
if ($member = Member::currentUser()) {
$form->Fields()->push(new HiddenField("AuthorID", "Author ID", $member->ID));
}
// What kind of moderation is required?
switch ($this->getOwnerRecord()->ModerationRequired) {
case 'Required':
$requireModeration = true;
break;
case 'NonMembersOnly':
$requireModeration = empty($member);
break;
case 'None':
default:
$requireModeration = false;
break;
}
$comment = new Comment();
$form->saveInto($comment);
$comment->AllowHtml = $this->getOption('html_allowed');
$comment->Moderated = !$requireModeration;
// Save into DB, or call pre-save hooks to give accurate preview
$usePreview = $this->getOption('use_preview');
$isPreview = $usePreview && !empty($data['IsPreview']);
if ($isPreview) {
$comment->extend('onBeforeWrite');
} else {
$comment->write();
// extend hook to allow extensions. Also see onBeforePostComment
$this->extend('onAfterPostComment', $comment);
}
// we want to show a notification if comments are moderated
if ($requireModeration && !$comment->IsSpam) {
Session::set('CommentsModerated', 1);
}
// clear the users comment since it passed validation
Cookie::set('CommentsForm_Comment', false);
// Find parent link
if (!empty($data['ReturnURL'])) {
$url = $data['ReturnURL'];
} elseif ($parent = $comment->getParent()) {
$url = $parent->Link();
} else {
return $this->redirectBack();
}
// Given a redirect page exists, attempt to link to the correct anchor
if ($comment->IsSpam) {
// Link to the form with the error message contained
$hash = $form->FormName();
} elseif (!$comment->Moderated) {
// Display the "awaiting moderation" text
$hash = "moderated";
} else {
// Link to the moderated, non-spam comment
$hash = $comment->Permalink();
}
return $this->redirect(Controller::join_links($url, "#{$hash}"));
}
public function doPreviewComment($data, $form)
{
$data['IsPreview'] = 1;
return $this->doPostComment($data, $form);
}
public function redirectBack()
{
// Don't cache the redirect back ever
HTTP::set_cache_age(0);
$url = null;
// In edge-cases, this will be called outside of a handleRequest() context; in that case,
// redirect to the homepage - don't break into the global state at this stage because we'll
// be calling from a test context or something else where the global state is inappropraite
if ($this->request) {
if ($this->request->requestVar('BackURL')) {
$url = $this->request->requestVar('BackURL');
} elseif ($this->request->isAjax() && $this->request->getHeader('X-Backurl')) {
$url = $this->request->getHeader('X-Backurl');
} elseif ($this->request->getHeader('Referer')) {
$url = $this->request->getHeader('Referer');
}
}
if (!$url) {
$url = $this->fallbackReturnURL;
}
if (!$url) {
$url = Director::baseURL();
}
// absolute redirection URLs not located on this site may cause phishing
if (Director::is_site_url($url)) {
return $this->redirect($url);
} else {
return false;
}
}
}

View File

@ -1,98 +0,0 @@
<?php
/**
* Handles polymorphic relation for commentlist
*
* Uses elements of PolymorphicHasManyList in 3.2
*
* @author dmooyman
*/
class CommentList extends HasManyList
{
/**
* Retrieve the name of the class this relation is filtered by
*
* @return string
*/
public function getForeignClass()
{
return $this->dataQuery->getQueryParam('Foreign.Class');
}
public function __construct($parentClassName)
{
parent::__construct('Comment', 'ParentID');
// Ensure underlying DataQuery globally references the class filter
$this->dataQuery->setQueryParam('Foreign.Class', $parentClassName);
// For queries with multiple foreign IDs (such as that generated by
// DataList::relation) the filter must be generalised to filter by subclasses
$classNames = Convert::raw2sql(ClassInfo::subclassesFor($parentClassName));
$this->dataQuery->where(sprintf(
"\"BaseClass\" IN ('%s')", implode("', '", $classNames)
));
}
/**
* Adds the item to this relation.
*
* @param Comment $item The comment to be added
*/
public function add($item)
{
// Check item given
if (is_numeric($item)) {
$item = Comment::get()->byID($item);
}
if (!($item instanceof Comment)) {
throw new InvalidArgumentException("CommentList::add() expecting a Comment object, or ID value");
}
// Validate foreignID
$foreignID = $this->getForeignID();
if (!$foreignID || is_array($foreignID)) {
throw new InvalidArgumentException("CommentList::add() can't be called until a single foreign ID is set");
}
$item->ParentID = $foreignID;
$item->BaseClass = $this->getForeignClass();
$item->write();
}
/**
* Remove a Comment from this relation by clearing the foreign key. Does not actually delete the comment.
*
* @param Comment $item The Comment to be removed
*/
public function remove($item)
{
// Check item given
if (is_numeric($item)) {
$item = Comment::get()->byID($item);
}
if (!($item instanceof Comment)) {
throw new InvalidArgumentException("CommentList::remove() expecting a Comment object, or ID",
E_USER_ERROR);
}
// Don't remove item with unrelated class key
$foreignClass = $this->getForeignClass();
$classNames = ClassInfo::subclassesFor($foreignClass);
if (!in_array($item->BaseClass, $classNames)) {
return;
}
// Don't remove item which doesn't belong to this list
$foreignID = $this->getForeignID();
if (empty($foreignID)
|| (is_array($foreignID) && in_array($item->ParentID, $foreignID))
|| $foreignID == $item->ParentID
) {
$item->ParentID = null;
$item->BaseClass = null;
$item->write();
}
}
}

View File

@ -1,7 +1,7 @@
{
"name": "silverstripe/comments",
"description": "This module provides commenting functionality for Pages and other DataObjects on your SilverStripe site.",
"type": "silverstripe-module",
"type": "silverstripe-vendormodule",
"keywords": [
"silverstripe",
"comments"
@ -13,17 +13,37 @@
}
],
"require": {
"assertchris/hash-compat": "~1.0",
"silverstripe/framework": "~3.1",
"colymba/gridfield-bulk-editing-tools": "~2.1"
"php": "^7.4 || ^8.0",
"silverstripe/framework": "^4.10",
"colymba/gridfield-bulk-editing-tools": "^3.0.0-beta4"
},
"suggest": {
"ezyang/htmlpurifier": "Standards compliant HTML filter written in PHP",
"silverstripe/cms": "The SilverStripe Content Management System"
},
"require-dev": {
"phpunit/PHPUnit": "~3.7@stable"
"phpunit/phpunit": "^9.5",
"squizlabs/php_codesniffer": "^3.0",
"ezyang/htmlpurifier": "^4.14"
},
"extra": [],
"license": "BSD-3-Clause"
"extra": {
"expose": [
"client/dist",
"client/lang",
"css"
]
},
"scripts": {
"lint": "vendor/bin/phpcs src/ tests/",
"fix": "vendor/bin/phpcbf src/ tests/"
},
"autoload": {
"psr-4": {
"SilverStripe\\Comments\\": "src/",
"SilverStripe\\Comments\\Tests\\": "tests/"
}
},
"license": "BSD-3-Clause",
"minimum-stability": "dev",
"prefer-stable": true
}

View File

@ -1,24 +0,0 @@
# Require any additional compass plugins here.
# Set this to the root of your project when deployed:
http_path = "/"
css_dir = "css"
sass_dir = "scss"
javascripts_dir = "javascript"
sourcemap = "true"
# You can select your preferred output style here (can be overridden via the command line):
# output_style = :expanded or :nested or :compact or :compressed
# To enable relative paths to assets via compass helper functions. Uncomment:
relative_assets = true
# To disable debugging comments that display the original location of your selectors. Uncomment:
line_comments = false
# If you prefer the indented syntax, you might want to regenerate this
# project again passing --syntax sass, or you can uncomment this:
# preferred_syntax = :sass
# and then run:
# sass-convert -R --from scss --to sass scss scss && rm -rf sass && mv scss sass

View File

@ -1,166 +1 @@
.comments-holder-container {
clear: both;
}
.comments-holder-container .field {
clear: left;
}
.comments-holder-container .num,
.comments-holder-container .author {
font-size: 1.3em;
}
.comments-holder-container .num {
color: #999;
margin-right: 5px;
}
.comments-holder-container .num-total {
line-height: 40px;
margin-bottom: 0;
}
.comments-holder-container #moderated {
border: solid #999 1px;
padding: 20px;
font-style: italic;
}
.comments-holder-container .comments-list {
margin: 0;
}
.comments-holder-container .comment-count {
margin: 15px 0;
}
.comments-holder-container .commenting-area {
margin-top: 50px;
}
.comments-holder-container .commenting-area label.left {
font-weight: normal;
}
.comments-holder-container .commenting-rss-feed {
margin-top: 4em;
text-align: right;
}
.comments-holder-container .commenting-rss-feed .action-links {
margin: 20px 0 10px;
}
.comments-holder-container .commenting-rss-feed .action-links li {
display: inline;
list-style-type: none;
margin-left: 20px;
}
.comments-holder-container .commenting-rss-feed .action-links li:first-child {
margin-left: 0;
}
.comments-holder-container .commenting-rss-feed .action-links li.comment-reply-action {
float: right;
}
.comments-holder-container .commenting-rss-feed .action-links a {
background-image: none;
}
.comments-holder-container .commenting-rss-feed .action-links a::first-letter {
text-transform: capitalize;
}
.comments-holder-container .no-comments-yet {
display: inline-block;
margin-top: 10px;
}
.comment {
clear: both;
list-style-type: none;
overflow: hidden;
padding: 20px 0 20px 0;
position: relative;
}
.comment.author-comment:after {
content: 'Author';
float: right;
position: absolute;
top: 1.5em;
right: 0.5em;
font-size: 1em;
font-weight: bold;
}
.comment.author-comment > .comment-text {
border: 1px solid blue;
}
.comment.spam .comment-text {
border: 1px dashed orange;
}
.comment img.gravatar {
float: left;
margin: 20px;
width: 90px;
height: 90px;
border: none;
}
.comment .comment-text {
background-color: #fff;
border: 1px solid #ddd;
box-shadow: none;
margin: 0;
padding: 0 20px 0 20px;
min-height: 130px;
white-space: pre;
white-space: pre-wrap;
white-space: pre-line;
word-wrap: break-word;
}
.comment .comment-text p:last-child {
margin-bottom: 0;
}
.comment .comment-text.hasGravatar {
padding: 0 20px 0 130px;
min-height: 130px;
}
.comment .date {
font-size: 16px;
}
.comment .date:before {
content: '\0000a0\0000a0\0000a0\0000a0';
}
.comment.unmoderated > .comment-text {
border: 1px solid yellow;
}
.comment .info {
margin-bottom: 10px;
}
.comment.spam .comment {
border: 1px dashed orange;
border-radius: 4px;
padding: 2.5em 1em 1em;
}
.comment .comment-replies-container {
clear: both;
padding-left: 10px;
margin: 80px 0 0 0;
border-left: 1px dashed #999;
}
.comment .comment-replies-container .comment-reply-form-holder {
padding: 0 10px;
}
.comment .comment-replies-container .comment-replies-holder {
padding: 0 0 0 10px;
}
.comments-list.root-level {
margin-left: 0;
}
.comment-reply-link {
float: right;
}
.comment-moderation-options {
float: left;
}
.comment-action-links {
margin: 20px 0 10px;
}
.comment-action-links a:not(:last-child) {
margin-right: 12px;
}
.commenting-rss-feed ul {
list-style: none;
}
/*# sourceMappingURL=comments.css.map */
/** Deprecated. Remove in 4.0 release. */

View File

@ -1,7 +0,0 @@
{
"version": 3,
"mappings": "AAAA,0BAA2B;EAC1B,KAAK,EAAE,IAAI;;AAEX,iCAAO;EACN,KAAK,EAAE,IAAI;;AAGZ;kCACQ;EACP,SAAS,EAAE,KAAK;;AAGjB,+BAAK;EACJ,KAAK,EAAE,IAAI;EACX,YAAY,EAAE,GAAG;;AAGlB,qCAAW;EACV,WAAW,EAAE,IAAI;EACjB,aAAa,EAAE,CAAC;;AAGd,qCAAW;EACP,MAAM,EAAE,cAAc;EACtB,OAAO,EAAE,IAAI;EACb,UAAU,EAAE,MAAM;;AAGzB,yCAAe;EACd,MAAM,EAAE,CAAC;;AAGV,yCAAe;EACd,MAAM,EAAE,MAAM;;AAIf,2CAAiB;EAChB,UAAU,EAAE,IAAI;;AAEhB,sDAAU;EACT,WAAW,EAAE,MAAM;;AAIrB,+CAAqB;EACpB,UAAU,EAAE,GAAG;EACf,UAAU,EAAE,KAAK;;AAEjB,6DAAc;EACb,MAAM,EAAE,WAAW;;AAEnB,gEAAG;EACF,OAAO,EAAE,MAAM;EACf,eAAe,EAAE,IAAI;EACrB,WAAW,EAAE,IAAI;;AAEjB,4EAAc;EACb,WAAW,EAAE,CAAC;;AAGf,qFAAuB;EACtB,KAAK,EAAE,KAAK;;AAId,+DAAE;EACD,gBAAgB,EAAE,IAAI;;AAEtB,6EAAgB;EACf,cAAc,EAAE,UAAU;;AAM9B,2CAAiB;EAChB,OAAO,EAAE,YAAY;EACrB,UAAU,EAAE,IAAI;;;AAKlB,QAAS;EACR,KAAK,EAAC,IAAI;EACV,eAAe,EAAE,IAAI;EACrB,QAAQ,EAAE,MAAM;EAChB,OAAO,EAAE,aAAa;EACtB,QAAQ,EAAE,QAAQ;;AAGjB,6BAAQ;EACP,OAAO,EAAE,QAAQ;EACjB,KAAK,EAAE,KAAK;EACZ,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,KAAK;EACV,KAAK,EAAE,KAAK;EACZ,SAAS,EAAE,GAAG;EACd,WAAW,EAAE,IAAI;;AAGlB,uCAAgB;EACf,MAAM,EAAE,cAAc;;AAMvB,2BAAc;EACb,MAAM,EAAE,iBAAiB;;AAIxB,qBAAa;EACT,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,MAAM,EAAE,IAAI;;AAGnB,sBAAc;EACb,gBAAgB,EAAE,IAAI;EACtB,MAAM,EAAE,cAAc;EACtB,UAAU,EAAE,IAAI;EAChB,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,aAAa;EAChB,UAAU,EAAE,KAAK;EACvB,WAAW,EAAE,GAAG;EAChB,WAAW,EAAE,QAAQ;EACrB,WAAW,EAAE,QAAQ;EACrB,SAAS,EAAE,UAAU;;AAErB,mCAAa;EACZ,aAAa,EAAE,CAAC;;AAIf,kCAA0B;EAEtB,OAAO,EAAE,cAAc;EAGvB,UAAU,EAAE,KAAK;;AAGxB,cAAM;EACL,SAAS,EAAE,IAAI;;AAEf,qBAAS;EACR,OAAO,EAAE,8BAA8B;;AAKxC,oCAAgB;EACf,MAAM,EAAE,gBAAgB;;AAI1B,cAAM;EACL,aAAa,EAAE,IAAI;;AAGpB,sBAAgB;EACf,MAAM,EAAE,iBAAiB;EACzB,aAAa,EAAE,GAAG;EAClB,OAAO,EAAE,aAAa;;AAGvB,mCAA2B;EAC1B,KAAK,EAAE,IAAI;EACX,YAAY,EAAE,IAAI;EAClB,MAAM,EAAE,UAAU;EAClB,WAAW,EAAE,eAAe;;AAE5B,8DAA2B;EAC1B,OAAO,EAAE,MAAM;;AAEhB,2DAAwB;EACvB,OAAO,EAAE,UAAU;;;AAKtB,yBAA0B;EACzB,WAAW,EAAE,CAAC;;;AAGf,mBAAoB;EACnB,KAAK,EAAE,KAAK;;;AAGb,2BAA4B;EAC3B,KAAK,EAAE,IAAI;;;AAGZ,qBAAsB;EACrB,MAAM,EAAE,WAAW;;AAEnB,wCAAmB;EAClB,YAAY,EAAE,IAAI;;;AAIpB,uBAAwB;EACvB,UAAU,EAAE,IAAI",
"sources": ["../scss/comments.scss"],
"names": [],
"file": "comments.css"
}

View File

@ -2,16 +2,16 @@
## Overview
The module provides a number of built in configuration settings below are the
The module provides a number of built in configuration settings below are the
default settings
In order to add commenting to your site, the minimum amount of work necessary is to add the `CommentsExtension` to
the base class for the object which holds comments.
```yaml
SiteTree:
SilverStripe\CMS\Model\SiteTree:
extensions:
- CommentsExtension
- SilverStripe\Comments\Extensions\CommentsExtension
```
## Configuration
@ -20,9 +20,9 @@ In order to configure options for any class you should assign the specific optio
config of the specified class.
```yaml
SiteTree:
SilverStripe\CMS\Model\SiteTree:
extensions:
- CommentsExtension
- SilverStripe\Comments\Extensions\CommentsExtension
comments:
enabled: true # Enables commenting to be disabled for a specific class (or subclass of a parent with commenting enabled)
enabled_cms: false # The 'enabled' option will be set via the CMS instead of config
@ -58,40 +58,44 @@ SiteTree:
Enabling any of the *_cms options will instead allow these options to be configured under the settings tab
of each page in the CMS.
If you want to customize any of the configuration options after you have added
If you want to customize any of the configuration options after you have added
the extension (or on the built-in SiteTree commenting) use `set_config_value`
```yaml
# Set the default option for pages to require login
SiteTree:
SilverStripe\CMS\Model\SiteTree:
comments:
require_login: true
```
```php
// Get the setting
$loginRequired = singleton('SiteTree')->getCommentsOption('require_login');
use SilverStripe\CMS\Model\SiteTree;
// [...]
// Get the setting
$loginRequired = singleton(SiteTree::class)->getCommentsOption('require_login');
```
## HTML Comments
Comments can be configured to contain a restricted set of HTML tags through the
`html_allowed` and `html_allowed_elements` settings. Raw HTML is hardly user
friendly, but combined with a rich-text editor of your own choosing it can
Comments can be configured to contain a restricted set of HTML tags through the
`html_allowed` and `html_allowed_elements` settings. Raw HTML is hardly user
friendly, but combined with a rich-text editor of your own choosing it can
allow rich comment formatting.
In order to use this feature, you need to install the
[HTMLPurifier](http://htmlpurifier.org/) library. The easiest way to do this is
[HTMLPurifier](http://htmlpurifier.org/) library. The easiest way to do this is
through [Composer](http://getcomposer.org).
{
"require": {"ezyang/htmlpurifier": "4.*"}
}
```json
{
"require": {"ezyang/htmlpurifier": "^4.8"}
}
```
**Important**: Rendering user-provided HTML on your website always risks
exposing your users to cross-site scripting (XSS) attacks, if the HTML isn't
**Important**: Rendering user-provided HTML on your website always risks
exposing your users to cross-site scripting (XSS) attacks, if the HTML isn't
properly sanitized. Don't allow tags like `<script>` or arbitrary attributes.
## Gravatars
@ -99,58 +103,58 @@ properly sanitized. Don't allow tags like `<script>` or arbitrary attributes.
Gravatars can be turned on by adding this to your mysite/_config/config.yml file
```yaml
SiteTree:
SilverStripe\CMS\Model\SiteTree:
comments:
use_gravatar: true
````
The default size is 80 pixels, as per the gravatar site if the 's' parameter is
The default size is 80 pixels, as per the gravatar site if the 's' parameter is
omitted. To change this add the following (again to mysite/_config/config.yml):
```yaml
SiteTree:
SilverStripe\CMS\Model\SiteTree:
comments:
gravatar_size: 40
```
If the email address used to comment does not have a gravatar, it is possible
to configure the default image shown. Valid values can be found at
http://gravatar.com/site/implement/images/, and at the time of writing are the
If the email address used to comment does not have a gravatar, it is possible
to configure the default image shown. Valid values can be found at
http://gravatar.com/site/implement/images/, and at the time of writing are the
following:
* 404: do not load any image if none is associated with the email hash, instead
* 404: do not load any image if none is associated with the email hash, instead
return an HTTP 404 (File Not Found) response.
* mm: (mystery-man) a simple, cartoon-style silhouetted outline of a person
* mm: (mystery-man) a simple, cartoon-style silhouetted outline of a person
(does not vary by email hash).
* identicon: a geometric pattern based on an email hash
* monsterid: a generated 'monster' with different colors, faces, etc
* wavatar: generated faces with differing features and backgrounds
* retro: awesome generated, 8-bit arcade-style pixelated faces
* blank: a transparent PNG image (border added to HTML below for demonstration
* blank: a transparent PNG image (border added to HTML below for demonstration
purposes)
To change the default image style, add the following to mysite/_config/config.yml
```yaml
SiteTree:
SilverStripe\CMS\Model\SiteTree:
comments:
gravatar_default: 'retro'
```
The rating of the image can be changed by adding a line similar to this to
The rating of the image can be changed by adding a line similar to this to
mysite/_config/config.yml
```yaml
SiteTree:
SilverStripe\CMS\Model\SiteTree:
comments:
gravatar_rating: 'r'
```
Vald values for rating are as follows:
Valid values for rating are as follows:
* g: suitable for display on all websites with any audience type.
* pg: may contain rude gestures, provocatively dressed individuals, the lesser
* pg: may contain rude gestures, provocatively dressed individuals, the lesser
swear words, or mild violence.
* r: may contain such things as harsh profanity, intense violence, nudity, or
* r: may contain such things as harsh profanity, intense violence, nudity, or
hard drug use.
* x: may contain hardcore sexual imagery or extremely disturbing violence.

View File

@ -1,37 +1,25 @@
# Installation
## Composer
Edit your project-wide composer.json file as follows; in the "require" block add:
"silverstripe/comments": "*"
Then in the root of your project run:
#> composer update silverstripe/comments
```sh
composer require silverstripe/comments`
```
## Web
To begin the installation first download the module online. You can find the version you require for your SilverStripe installation on the [silverstripe.org](http://www.silverstripe.org) website.
After you have finished downloading the file, extract the downloaded file to your site's root folder and ensure the name of the module is `comments`.
## All
Run a database rebuild by visiting *http://yoursite.com/dev/build*. This will add the required database columns and tables for the module to function.
If you previously had SilverStripe version 2.4 installed then you'll also need to run the migration script provided. More information on this is provided in the next section.
Then run a database rebuild by visiting `dev/build`. This will add the required database columns and tables for the module to function, and refresh the configuration manifest.
## Enabling Commenting
Out of the box the module adds commenting support to all pages on your site. This functionality can be turned on and off on a per page basis in the CMS under the `Behaviour` tab for a given page. Once the `Allow Comments` checkbox is ticked, republish and view the webpage.
Out of the box the module adds commenting support to all pages on your site. This functionality can be turned on and off on a per page basis in the CMS under the `Behaviour` tab for a given page. Once the `Allow comments` checkbox is ticked, republish and view the webpage.
For more configuration options see [Configuration](Configuration.md).
## Upgrading
## Displaying Comments
### Migrating from version 2.* SilverStripe installations
To display form and comments simply add
This module replaces the built-in commenting system available in versions up to SilverStripe 2.4. To migrate from that you'll need to run `dev/build` after installing the module.
```sh
{$CommentsForm}
```
You can do this via sake (`sake dev/build`) or via a web browser by visiting `http://yoursite.com/dev/build`
to your `.ss` file.

View File

@ -1,216 +0,0 @@
/**
* @package comments
*/
(function($) {
$.entwine( "ss.comments", function($) {
/**
* Enable form validation
*/
$('.comments-holder-container form').entwine({
onmatch: function() {
// @todo Reinstate preview-comment functionality
/**
* Validate
*/
$(this).validate({
/**
* Ignore hidden elements in this form
*/
ignore: ':hidden',
/**
* Use default 'required' for error labels
*/
errorClass: "required",
/**
* Use span instead of labels
*/
errorElement: "span",
/**
* On error, scroll to the invalid element
*/
invalidHandler : function(form, validator){
$('html, body').animate({
scrollTop: $(validator.errorList[0].element).offset().top - 30
}, 200);
},
/**
* Ensure any new error message has the correct class and placement
*/
errorPlacement: function(error, element) {
error
.addClass('message')
.insertAfter(element);
}
});
this._super();
},
onunmatch: function() {
this._super();
}
});
/**
* Comment reply form
*/
$( ".comment-replies-container .comment-reply-form-holder" ).entwine({
onmatch: function() {
// If and only if this is not the currently selected form, hide it on page load
var selectedHash = window.document.location.hash.substr(1),
form = $(this).children('.reply-form');
if( !selectedHash || selectedHash !== form.prop( 'id' ) ) {
this.hide();
}
this._super();
},
onunmatch: function() {
this._super();
}
});
/**
* Toggle on/off reply form
*/
$( ".comment-reply-link" ).entwine({
onclick: function( e ) {
var allForms = $( ".comment-reply-form-holder" ),
formID = $( this ).prop('href').replace(/^[^#]*#/, '#'),
form = $(formID).closest('.comment-reply-form-holder');
// Prevent focus
e.preventDefault();
if(form.is(':visible')) {
allForms.slideUp();
} else {
allForms.not(form).slideUp();
form.slideDown();
}
}
});
/**
* Preview comment by fetching it from the server via ajax.
*/
/* @todo Migrate to work with nested comments
$(':submit[name=action_doPreviewComment]', form).click(function(e) {
e.preventDefault();
if(!form.validate().valid()) {
return false;
}
previewEl.show().addClass('loading').find('.middleColumn').html(' ');
form.ajaxSubmit({
success: function(response) {
var responseEl = $(response);
if(responseEl.is('form')) {
// Validation failed, renders form instead of single comment
form.find(".data-fields").replaceWith(responseEl.find(".data-fields"));
} else {
// Default behaviour
previewEl.removeClass('loading').find('.middleColumn').html(responseEl);
}
},
data: {'action_doPreviewComment': 1}
});
});
*/
/**
* Hide outdated preview on form changes
*/
/*
$(':input', form).on('change keydown', function() {
previewEl.removeClass('loading').hide();
});*/
/**
* Clicking one of the metalinks performs the operation via ajax
* this inclues the spam and approve links
*/
$('.comments-holder .comments-list').on('click', 'div.comment-moderation-options a', function(e) {
var link = $(this);
if (link.hasClass('delete')) {
var confirmationMsg = ss.i18n._t('CommentsInterface_singlecomment_ss.DELETE_CONFIRMATION');
var confirmation = window.confirm(confirmationMsg);
if (!confirmation) {
e.preventDefault();
return false;
}
}
var comment = link.parents('.comment:first');
$.ajax({
url: $(this).attr('href'),
cache: false,
success: function(html){
if(link.hasClass('ham')) {
// comment has been marked as not spam
comment.html(html);
comment.removeClass('spam');
}
else if(link.hasClass('approve')) {
// comment has been approved
comment.html(html);
comment.removeClass('unmoderated');
}
else if(link.hasClass('delete')) {
comment.fadeOut(1000, function() {
comment.remove();
if(commentsList.children().length === 0) {
noCommentsYet.show();
}
});
}
else if(link.hasClass('spam')) {
comment.html(html).addClass('spam');
}
},
failure: function(html) {
var errorMsg = ss.i18n._t('CommentsInterface_singlecomment_ss.AJAX_ERROR');
alert(errorMsg);
}
});
e.preventDefault();
});
/**
* Ajax pagination
*/
/* @todo Migrate to work with nested comments
pagination.find('a').on('click', function(){
commentsList.addClass('loading');
$.ajax({
url: $(this).attr('href'),
cache: false,
success: function(html){
html = $(html);
commentsList.hide().html(html.find('.comments-list:first').html()).fadeIn();
pagination.hide().html(html.find('.comments-pagination:first').html()).fadeIn();
commentsList.removeClass('loading');
$('html, body').animate({
scrollTop: commentsList.offset().top - 30
}, 200);
},
failure: function(html) {
alert('Error loading comments');
}
});
return false;
});*/
});
})(jQuery);

22
lang/ar.yml Normal file
View File

@ -0,0 +1,22 @@
ar:
CommentInterface:
PREVIEW: معاينة
PREVIEWLABEL: معاينة
CommentsInterface_ss:
COMMENTS: التعليقات
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: التعليقات
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: التعليقات
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: التعليقات
COMMENTSTABSET: التعليقات
SilverStripe\Comments\Model\Comment:
COMMENT: تعليق
EMAIL: 'البريد الإلكتروني'
'ON': في
OPTIONS: الخيارات
PARENTTITLE: والد
PLURALNAME: التعليقات
SINGULARNAME: تعليق
URL: الرابط

18
lang/bg.yml Normal file
View File

@ -0,0 +1,18 @@
bg:
CommentInterface:
PREVIEW: Преглед
PREVIEWLABEL: Преглед
CommentsInterface_ss:
COMMENTS: Коментари
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Коментари
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Коментари
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Коментари
COMMENTSTABSET: Коментари
SilverStripe\Comments\Model\Comment:
EMAIL: Еmail
'ON': на
PLURALNAME: Коментари
URL: URL

19
lang/cs.yml Normal file
View File

@ -0,0 +1,19 @@
cs:
CommentInterface:
POST: Post
PREVIEW: Náhled
PREVIEWLABEL: Náhled
CommentsInterface_ss:
COMMENTS: Komentáře
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Komentáře
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Komentáře
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Komentáře
COMMENTSTABSET: Komentáře
SilverStripe\Comments\Model\Comment:
EMAIL: E-mail
'ON': v
PLURALNAME: Komentáře
URL: URL

26
lang/cs_CZ.yml Normal file
View File

@ -0,0 +1,26 @@
cs_CZ:
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Prosím vložte Váš komentář'
COMMENT_MESSAGE_URL: 'Prosím zadejte platnou URL adresu'
EMAILADDRESS_MESSAGE_EMAIL: 'Prosím zadejte platnou emailovou adresu'
EMAILADDRESS_MESSAGE_REQUIRED: 'Prosím zadejte Vaší emailovou adresu'
PREVIEW: Náhled
PREVIEWLABEL: Náhled
YOURNAME: 'Vaše jméno'
YOURNAME_MESSAGE_REQUIRED: 'Prosím zadejte Vaše jméno'
Comments:
COMMENTSREQUIRELOGIN: 'Vyžadováno přihlášení pro komentování'
CommentsAdmin:
NewComments: Nový
SpamComments: Spam
CommentsInterface_singlecomment_ss:
ISNTSPAM: 'Není spam'
SilverStripe\Comments\Admin\CommentAdmin:
NewComments: Nový
SpamComments: Spam
SilverStripe\Comments\Admin\CommentsGridFieldAction:
SPAM: Spam
SilverStripe\Comments\Admin\CommentsGridFieldConfig:
SPAM: Spam
SilverStripe\Comments\Admin\CommentsGridFieldSpamAction:
SPAM: Spam

18
lang/da.yml Normal file
View File

@ -0,0 +1,18 @@
da:
CommentInterface:
PREVIEW: Forhåndsvisning
PREVIEWLABEL: Forhåndsvisning
CommentsInterface_ss:
COMMENTS: Kommentarer
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Kommentarer
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Kommentarer
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Kommentarer
COMMENTSTABSET: Kommentarer
SilverStripe\Comments\Model\Comment:
EMAIL: Email
'ON': 'd. '
PLURALNAME: Kommentarer
URL: URL

View File

@ -1,27 +1,4 @@
de:
Comment:
ALLOWCOMMENTS: 'Kommentare Erlauben'
COMMENT: Kommentar
COMMENTBY: 'Kommentar von ''%s'''
CREATED: 'Datum geschrieben'
EMAIL: E-Mail
ISSPAM: 'Spam?'
MODERATED: 'Moderiert?'
NAME: 'Autor Name'
'ON': am
OPTIONS: Optionen
OPTION_DESCRIPTION: 'Unmoderierte und Spam-Kommentare werden nicht angezeigt, bis sie freigeschaltet sind'
PARENTTITLE: Parent
PLURALNAME: Kommentare
SINGULARNAME: Kommentar
URL: URL
CommentAdmin:
ADMIN_PERMISSION: 'Zugang zum Bereich ''Kommentare'''
MENUTITLE: Kommentare
Moderated: Moderiert
NeedsModeration: 'Benötigt Moderation'
NewComments: Neu
SpamComments: Spam
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Bitte geben Sie Ihren Kommentar ein'
COMMENT_MESSAGE_URL: 'Bitte geben Sie eine gültige URL ein'
@ -32,27 +9,16 @@ de:
PREVIEWLABEL: Vorschau
YOURNAME: Name
YOURNAME_MESSAGE_REQUIRED: 'Bitte geben Sie Ihren Namen ein'
CommentingController:
COMMENTS: Kommentare
EMAILADDRESS: 'E-Mail Adresse (wird nicht angezeigt)'
PERMISSIONFAILURE: 'Sie sind nicht berechtigt diese Seite zu kommentieren. Bitte stellen Sie sicher das Sie eingeloggt sind und die nötige Berechtigung besitzen.'
RSSTITLE: 'Kommentare RSS Feed'
WEBSITEURL: 'Website URL'
Comments:
COMMENTSREQUIRELOGIN: 'Einloggen, um zu kommentieren'
CommentsAdmin:
NeedsModeration: 'Benötigt Moderation'
Comments: Genehmigt
NewComments: Neu
SpamComments: Spam
CommentsExtension:
COMMENTOPTIONS: Kommentare
CommentsGridFieldAction:
SPAM: Spam
CommentsGridFieldConfig:
SPAM: Spam
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Ihr Kommentar wurde gespeichert und wird durch einen Moderator freigeschaltet.'
CommentsInterface_singlecomment_ss:
ISNTSPAM: 'kein Spam'
PBY: 'Geschrieben von'
REPLYTO: 'Antworten an'
CommentsInterface_ss:
AWAITINGMODERATION: 'Ihr Kommentar wurde gespeichert und wird durch einen Moderator freigeschaltet.'
COMMENTLOGINERROR: 'Sie können diese Seite nur kommentieren, wenn Sie eingeloggt sind'
@ -68,5 +34,55 @@ de:
PREV: zurück
RSSFEEDALLCOMMENTS: 'RSS Feed für alle Kommentare'
RSSFEEDCOMMENTS: 'RSS Feed für Kommentare auf dieser Seite'
PageCommentInterface:
DELETEALLCOMMENTS: 'Alle Kommentare auf dieser Seite entfernen'
SilverStripe\Comments\Admin\CommentAdmin:
ADMIN_PERMISSION: 'Zugang zum Bereich ''Kommentare'''
ApprovedComments: 'Gehnehmigt ({count})'
Comments: Genehmigt
MENUTITLE: Kommentare
NewComments: Neu
SpamComments: Spam
SilverStripe\Comments\Admin\CommentsGridFieldAction:
APPROVE: Genehmigen
COMMENTAPPROVED: 'Kommentar genehmigt.'
COMMENTMARKEDSPAM: 'Commentar als Spam markiert.'
SPAM: Spam
SilverStripe\Comments\Admin\CommentsGridFieldApproveAction:
APPROVE: Genehmigen
COMMENTAPPROVED: 'Kommentar genehmigt.'
SilverStripe\Comments\Admin\CommentsGridFieldConfig:
APPROVE: Genehmigen
SPAM: Spam
SilverStripe\Comments\Admin\CommentsGridFieldSpamAction:
COMMENTMARKEDSPAM: 'Commentar als Spam markiert.'
SPAM: Spam
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Kommentare
EMAILADDRESS: 'E-Mail Adresse (wird nicht angezeigt)'
PERMISSIONFAILURE: 'Sie sind nicht berechtigt diese Seite zu kommentieren. Bitte stellen Sie sicher das Sie eingeloggt sind und die nötige Berechtigung besitzen.'
RSSTITLE: 'Kommentare RSS Feed'
WEBSITEURL: 'Website URL'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTMODERATION: Kommentarmoderation
COMMENTOPTIONS: Kommentare
COMMENTSTABSET: Kommentare
MODERATIONREQUIRED_NONE: 'Keine Moderation benötigt'
MODERATIONREQUIRED_NONMEMBERSONLY: 'Nur Nicht-Mitglieder moderieren'
MODERATIONREQUIRED_REQUIRED: 'Alle Kommentare moderieren'
SilverStripe\Comments\Model\Comment:
COMMENT: Kommentar
COMMENTBY: 'Kommentar von ''%s'''
CREATED: 'Datum geschrieben'
EMAIL: E-Mail
ISSPAM: 'Spam?'
MODERATED: 'Moderiert?'
'ON': am
OPTIONS: Optionen
OPTION_DESCRIPTION: 'Unmoderierte und Spam-Kommentare werden nicht angezeigt, bis sie freigeschaltet sind'
PARENTTITLE: Parent
PLURALNAME: Kommentare
PLURALS:
one: 'Ein Kommentar'
other: '{count} Kommentare'
ParentComment_Title: 'Dieser Kommentar ist eine Antwort auf'
SINGULARNAME: Kommentar
URL: URL

17
lang/el.yml Normal file
View File

@ -0,0 +1,17 @@
el:
CommentInterface:
PREVIEW: Προεπισκόπιση
PREVIEWLABEL: Προεπισκόπιση
CommentsInterface_ss:
COMMENTS: Σχόλια
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Σχόλια
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Σχόλια
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Σχόλια
COMMENTSTABSET: Σχόλια
SilverStripe\Comments\Model\Comment:
EMAIL: Email
PLURALNAME: Σχόλια
URL: URL

View File

@ -1,30 +1,4 @@
en:
Comment:
ALLOWCOMMENTS: 'Allow Comments'
COMMENT: Comment
COMMENTBY: 'Comment by %s'
CREATED: 'Date posted'
EMAIL: Email
ISSPAM: 'Spam?'
MODERATED: 'Moderated?'
NAME: 'Author Name'
'ON': 'on'
OPTIONS: Options
OPTION_DESCRIPTION: 'Unmoderated and spam comments will not be displayed until approved'
PARENTTITLE: Parent
PLURALNAME: Comments
ParentComment_Title: 'This comment is a reply to the below'
SINGULARNAME: Comment
URL: URL
CommentAdmin:
ADMIN_PERMISSION: 'Access to ''Comments'' section'
ApprovedComments: Approved
Comments: Approved
MENUTITLE: Comments
Moderated: Moderated
NeedsModeration: 'Needs Moderation'
NewComments: New
SpamComments: Spam
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Please enter your comment'
COMMENT_MESSAGE_URL: 'Please enter a valid URL'
@ -35,46 +9,24 @@ en:
PREVIEWLABEL: Preview
YOURNAME: 'Your name'
YOURNAME_MESSAGE_REQUIRED: 'Please enter your name'
CommentingController:
COMMENTS: Comments
EMAILADDRESS: 'Your email address (will not be published)'
PERMISSIONFAILURE: 'You''re not able to post comments to this page. Please ensure you are logged in and have an appropriate permission level.'
RSSTITLE: 'Comments RSS Feed'
WEBSITEURL: 'Your website URL'
Comments:
COMMENTSREQUIRELOGIN: 'Require login to comment'
CommentsAdmin:
ApprovedComments: Approved
Comments: Approved
NeedsModeration: 'Needs Moderation'
NewComments: New
SpamComments: Spam
CommentsExtension:
COMMENTOPTIONS: Comments
MODERATIONREQUIRED_NONE: 'No moderation required'
MODERATIONREQUIRED_NONMEMBERSONLY: 'Only moderate non-members'
MODERATIONREQUIRED_REQUIRED: 'Moderate all comments'
CommentsGridFieldAction:
APPROVE: Approve
COMMENTAPPROVED: 'Comment approved.'
COMMENTMARKEDSPAM: 'Comment marked as spam.'
SPAM: Spam
CommentsGridFieldConfig:
APPROVE: Approve
SPAM: Spam
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Your comment has been submitted and is now awaiting moderation.'
CommentsInterface_singlecomment_ss:
APPROVE: 'approve it'
ISNTSPAM: 'not spam'
ISSPAM: 'spam it'
PBY: 'Posted by'
REMCOM: 'reject it'
APPROVE: 'Approve it'
ISNTSPAM: 'Not spam'
ISSPAM: 'Spam it'
REMCOM: 'Reject it'
REPLYTO: 'Reply to'
CommentsInterface_ss:
AWAITINGMODERATION: 'Your comment has been submitted and is now awaiting moderation.'
COMMENTLOGINERROR: 'You cannot post comments until you have logged in'
COMMENTPERMISSIONERROR: 'and that you have an appropriate permission level'
COMMENTPERMISSIONERROR: 'and have an appropriate permission level'
COMMENTPOSTLOGIN: 'Login Here'
COMMENTS: Comments
COMMENTSDISABLED: 'Posting comments has been disabled'
@ -86,5 +38,59 @@ en:
PREV: previous
RSSFEEDALLCOMMENTS: 'RSS feed for all comments'
RSSFEEDCOMMENTS: 'RSS feed for comments on this page'
PageCommentInterface:
DELETEALLCOMMENTS: 'Delete all comments on this page'
SilverStripe\Comments\Admin\CommentAdmin:
ADMIN_PERMISSION: 'Access to ''Comments'' section'
ApprovedComments: 'Approved ({count})'
Comments: Approved
MENUTITLE: Comments
NewComments: New
SpamComments: Spam
SilverStripe\Comments\Admin\CommentsGridFieldAction:
APPROVE: Approve
COMMENTAPPROVED: 'Comment approved.'
COMMENTMARKEDSPAM: 'Comment marked as spam.'
SPAM: Spam
SilverStripe\Comments\Admin\CommentsGridFieldApproveAction:
APPROVE: Approve
COMMENTAPPROVED: 'Comment approved.'
SilverStripe\Comments\Admin\CommentsGridFieldBulkAction\CommentHandler:
CHANGES_APPLIED: 'Changes applied'
SilverStripe\Comments\Admin\CommentsGridFieldConfig:
APPROVE: Approve
SPAM: Spam
SilverStripe\Comments\Admin\CommentsGridFieldSpamAction:
COMMENTMARKEDSPAM: 'Comment marked as spam.'
SPAM: Spam
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Comments
EMAILADDRESS: 'Your email address (will not be published)'
PERMISSIONFAILURE: 'You''re not able to post comments to this page. Please ensure you are logged in and have an appropriate permission level.'
RSSTITLE: 'Comments RSS Feed'
WEBSITEURL: 'Your website URL'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTMODERATION: 'Comment Moderation'
COMMENTOPTIONS: Comments
COMMENTSTABSET: Comments
MODERATIONREQUIRED_NONE: 'No moderation required'
MODERATIONREQUIRED_NONMEMBERSONLY: 'Only moderate non-members'
MODERATIONREQUIRED_REQUIRED: 'Moderate all comments'
SilverStripe\Comments\Model\Comment:
ALLOWCOMMENTS: 'Allow comments'
COMMENT: Comment
COMMENTBY: 'Comment by %s'
CREATED: 'Date posted'
EMAIL: Email
ISSPAM: 'Spam?'
MODERATED: 'Moderated?'
NAME: 'Author name'
'ON': 'on'
OPTIONS: Options
OPTION_DESCRIPTION: 'Unmoderated and spam comments will not be displayed until approved'
PARENTTITLE: Parent
PLURALNAME: Comments
PLURALS:
one: 'A Comment'
other: '{count} Comments'
ParentComment_Title: 'This comment is a reply to the below'
SINGULARNAME: Comment
URL: URL

15
lang/en_GB.yml Normal file
View File

@ -0,0 +1,15 @@
en_GB:
CommentsInterface_ss:
COMMENTS: Comments
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Comments
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Comments
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Comments
COMMENTSTABSET: Comments
SilverStripe\Comments\Model\Comment:
EMAIL: Email
'ON': 'on'
OPTIONS: Options
PLURALNAME: Comments

View File

@ -1,30 +1,4 @@
eo:
Comment:
ALLOWCOMMENTS: 'Ebligi komentojn'
COMMENT: Komento
COMMENTBY: 'Komento de %s'
CREATED: 'Dato de afiŝo'
EMAIL: Retpoŝto
ISSPAM: 'Ĉu spamo?'
MODERATED: 'Ĉu kontrolata?'
NAME: 'Nomo de aŭtoro'
'ON': en
OPTIONS: Agordoj
OPTION_DESCRIPTION: 'Ne vidigos nekontrolitajn aŭ spamajn komentojn antaŭ aprobo'
PARENTTITLE: Patra
PLURALNAME: Komentoj
ParentComment_Title: 'Tiu komento estas respondo al la suba'
SINGULARNAME: Komento
URL: URL
CommentAdmin:
ADMIN_PERMISSION: 'Aliro al sekcio ''Komentoj'''
ApprovedComments: Aprobita
Comments: Aprobita
MENUTITLE: Komentoj
Moderated: Kontrolata
NeedsModeration: 'Bezonas kontrolon'
NewComments: Nova
SpamComments: Spamo
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Bonvole enigu vian komenton'
COMMENT_MESSAGE_URL: 'Bonvole enigu validan URL-on'
@ -35,41 +9,20 @@ eo:
PREVIEWLABEL: Antaŭvido
YOURNAME: 'Via nomo'
YOURNAME_MESSAGE_REQUIRED: 'Bonvole enigu vian nomon'
CommentingController:
COMMENTS: Komentoj
EMAILADDRESS: 'Via retadreso (ne publikiĝos)'
PERMISSIONFAILURE: 'Vi ne povas afiŝi komentojn al ĉi tiu paĝo. Bonvole certigu ke vi jam ensalutis kaj havas taŭgan permeson.'
RSSTITLE: 'RSS-fluo de komentoj'
WEBSITEURL: 'Via reteja URL'
Comments:
COMMENTSREQUIRELOGIN: 'Necesas ensaluti por komenti'
CommentsAdmin:
ApprovedComments: Aprobita
Comments: Aprobita
NeedsModeration: 'Bezonas kontrolon'
NewComments: Nova
SpamComments: Spamo
CommentsExtension:
COMMENTOPTIONS: Komentoj
MODERATIONREQUIRED_NONE: 'Kontrolado ne bezonatas'
MODERATIONREQUIRED_NONMEMBERSONLY: 'Kontroli nur nemembrojn'
MODERATIONREQUIRED_REQUIRED: 'Kontroli ĉiujn komentojn'
CommentsGridFieldAction:
APPROVE: Aprobi
COMMENTAPPROVED: 'Komento aprobita.'
COMMENTMARKEDSPAM: 'Markis komenton kiel spamon'
SPAM: Spamo
CommentsGridFieldConfig:
APPROVE: Aprobi
SPAM: Spamo
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Via komento afiŝiĝis kaj nun atendas kontrolon.'
CommentsInterface_singlecomment_ss:
APPROVE: 'aprobi ĝin'
ISNTSPAM: 'ne spamo'
ISSPAM: 'spamigi ĝin'
PBY: 'Afiŝita de'
REMCOM: 'malakcepti ĝin'
APPROVE: 'Aprobi ĝin'
ISNTSPAM: 'Ne spamo'
ISSPAM: 'Trakti kiel spamon'
REMCOM: 'Malakcepti ĝin'
REPLYTO: 'Respondi al'
CommentsInterface_ss:
AWAITINGMODERATION: 'Via komento afiŝiĝis kaj nun atendas kontrolon.'
COMMENTLOGINERROR: 'Vi ne povas afiŝi komenton ĝis vi ensalutis'
@ -85,5 +38,59 @@ eo:
PREV: antaŭa
RSSFEEDALLCOMMENTS: 'RSS-fluo por ĉiuj komentoj'
RSSFEEDCOMMENTS: 'RSS-fluo por komentoj pri ĉi tiu paĝo'
PageCommentInterface:
DELETEALLCOMMENTS: 'Forigi ĉiujn komentojn pri ĉi tiu paĝo'
SilverStripe\Comments\Admin\CommentAdmin:
ADMIN_PERMISSION: 'Aliro al sekcio ''Komentoj'''
ApprovedComments: Aprobita
Comments: Aprobita
MENUTITLE: Komentoj
NewComments: Nova
SpamComments: Spamo
SilverStripe\Comments\Admin\CommentsGridFieldAction:
APPROVE: Aprobi
COMMENTAPPROVED: 'Komento aprobita.'
COMMENTMARKEDSPAM: 'Markis komenton kiel spamon'
SPAM: Spamo
SilverStripe\Comments\Admin\CommentsGridFieldApproveAction:
APPROVE: Aprobi
COMMENTAPPROVED: 'Komento aprobita.'
SilverStripe\Comments\Admin\CommentsGridFieldBulkAction\CommentHandler:
CHANGES_APPLIED: 'Aplikis la ŝanĝojn'
SilverStripe\Comments\Admin\CommentsGridFieldConfig:
APPROVE: Aprobi
SPAM: Spamo
SilverStripe\Comments\Admin\CommentsGridFieldSpamAction:
COMMENTMARKEDSPAM: 'Markis komenton kiel spamon'
SPAM: Spamo
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Komentoj
EMAILADDRESS: 'Via retadreso (ne publikiĝos)'
PERMISSIONFAILURE: 'Vi ne povas afiŝi komentojn al ĉi tiu paĝo. Bonvole certigu ke vi jam ensalutis kaj havas taŭgan permeson.'
RSSTITLE: 'RSS-fluo de komentoj'
WEBSITEURL: 'Via reteja URL'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTMODERATION: 'Kontroli komentojn'
COMMENTOPTIONS: Komentoj
COMMENTSTABSET: Komentoj
MODERATIONREQUIRED_NONE: 'Kontrolado ne bezonatas'
MODERATIONREQUIRED_NONMEMBERSONLY: 'Kontroli nur nemembrojn'
MODERATIONREQUIRED_REQUIRED: 'Kontroli ĉiujn komentojn'
SilverStripe\Comments\Model\Comment:
ALLOWCOMMENTS: 'Ebligi komentojn'
COMMENT: Komento
COMMENTBY: 'Komento de %s'
CREATED: 'Dato de afiŝo'
EMAIL: Retpoŝto
ISSPAM: 'Ĉu spamo?'
MODERATED: 'Ĉu kontrolata?'
NAME: 'Nomo de aŭtoro'
'ON': en
OPTIONS: Agordoj
OPTION_DESCRIPTION: 'Ne vidigos nekontrolitajn aŭ spamajn komentojn antaŭ aprobo'
PARENTTITLE: Patra
PLURALNAME: Komentoj
PLURALS:
one: 'Unu komento'
other: '{count} komentoj'
ParentComment_Title: 'Tiu komento estas respondo al la suba'
SINGULARNAME: Komento
URL: URL

View File

@ -1,22 +1,4 @@
es:
Comment:
ALLOWCOMMENTS: 'Permitir comentarios'
COMMENT: Comentario
COMMENTBY: 'Comentario por %s'
CREATED: 'Fecha de publicación'
EMAIL: Email
ISSPAM: '¿Spam?'
MODERATED: '¿Moderado?'
NAME: 'Nombre del autor'
PARENTTITLE: Padre
PLURALNAME: Comentarios
SINGULARNAME: Comentario
URL: URL
CommentAdmin:
ADMIN_PERMISSION: 'Acceder a la sección ''Comentarios'''
MENUTITLE: Comentarios
Moderated: Moderado
NeedsModeration: 'Necesita moderación'
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Por favor, ingres su comentario'
COMMENT_MESSAGE_URL: 'Por favor, ingrese una URL válida'
@ -27,17 +9,8 @@ es:
PREVIEWLABEL: 'Vista previa'
YOURNAME: 'Su nombre'
YOURNAME_MESSAGE_REQUIRED: 'Por favor, ingrese su nombre'
CommentingController:
COMMENTS: Comentarios
EMAILADDRESS: 'Su dirección de correo (no se publicará)'
PERMISSIONFAILURE: 'Ud no puede publicar comentarios en esta página. Por favor asegúrese que haya iniciado sesión y que tenga el adecuado nivel de permisos.'
WEBSITEURL: 'URL de su sitio Web'
CommentsAdmin:
NeedsModeration: 'Necesita moderación'
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Se envió su comentario y ahora está esperando la moderación.'
CommentsInterface_singlecomment_ss:
PBY: 'Publicado por'
CommentsInterface_ss:
AWAITINGMODERATION: 'Se envió su comentario y ahora está esperando la moderación.'
COMMENTLOGINERROR: 'Ud no puede comentar hasta que haya iniciado sesión'
@ -51,5 +24,26 @@ es:
NOCOMMENTSYET: 'Nadie comentó en esta página todavía.'
POSTCOM: 'Publicar su mensaje'
PREV: anterior
PageCommentInterface:
DELETEALLCOMMENTS: 'Eliminar todos los comentarios de esta página'
SilverStripe\Comments\Admin\CommentAdmin:
ADMIN_PERMISSION: 'Acceder a la sección ''Comentarios'''
MENUTITLE: Comentarios
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Comentarios
EMAILADDRESS: 'Su dirección de correo (no se publicará)'
PERMISSIONFAILURE: 'Ud no puede publicar comentarios en esta página. Por favor asegúrese que haya iniciado sesión y que tenga el adecuado nivel de permisos.'
WEBSITEURL: 'URL de su sitio Web'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Comentarios
COMMENTSTABSET: Comentarios
SilverStripe\Comments\Model\Comment:
COMMENT: Comentario
COMMENTBY: 'Comentario por %s'
CREATED: 'Fecha de publicación'
EMAIL: Email
ISSPAM: '¿Spam?'
MODERATED: '¿Moderado?'
'ON': en
PARENTTITLE: Padre
PLURALNAME: Comentarios
SINGULARNAME: Comentario
URL: URL

19
lang/es_MX.yml Normal file
View File

@ -0,0 +1,19 @@
es_MX:
CommentInterface:
PREVIEW: Previo
PREVIEWLABEL: Previo
CommentsInterface_ss:
COMMENTS: Comentarios
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Comentarios
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Comentarios
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Comentarios
COMMENTSTABSET: Comentarios
SilverStripe\Comments\Model\Comment:
EMAIL: Email
'ON': en
OPTIONS: Options
PLURALNAME: Comentarios
URL: URL

19
lang/et_EE.yml Normal file
View File

@ -0,0 +1,19 @@
et_EE:
CommentInterface:
PREVIEW: Eelvaade
PREVIEWLABEL: Eelvaade
CommentsInterface_ss:
COMMENTS: Komentaarid
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Komentaarid
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Komentaarid
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Komentaarid
COMMENTSTABSET: Komentaarid
SilverStripe\Comments\Model\Comment:
EMAIL: Email
'ON': '-'
OPTIONS: Options
PLURALNAME: Komentaarid
URL: URL

View File

@ -1,75 +1,24 @@
fa_IR:
Comment:
ALLOWCOMMENTS: 'اجازه نشر دیدگاه'
COMMENT: دیدگاه
COMMENTBY: 'دیدگاه توسط %s'
CREATED: 'تاریخ ارسال'
EMAIL: 'ایمیل'
ISSPAM: هرزنوشت؟
MODERATED: 'مدیریت شده؟'
NAME: 'نام نگارنده'
'ON': در
OPTIONS: گزینه‌ها
OPTION_DESCRIPTION: 'دیدگاه‌های مدیریت نشده و هرزنوشت‌ها تا زمان تایید به نمایش در نخواهند آمد'
PARENTTITLE: والد
PLURALNAME: دیدگاه‌ها
ParentComment_Title: 'این دیدگاه پاسخی است به زیر'
SINGULARNAME: دیدگاه
URL: 'نشانی اینترنتی'
CommentAdmin:
ADMIN_PERMISSION: 'دسترسی به بخش ''دیدگاه‌ها'''
ApprovedComments: 'تایید شده'
Comments: 'تایید شده'
MENUTITLE: دیدگاه‌ها
Moderated: 'مدیریت شده'
NeedsModeration: 'نیازمند مدیریت'
NewComments: تازه
SpamComments: هرزنوشت
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'لطفاً دیدگاه خود را وارد نمایید'
COMMENT_MESSAGE_URL: 'لطفاً نشانی اینترنتی معتبر وارد نمایید'
EMAILADDRESS_MESSAGE_EMAIL: 'لطفاً نشانی ایمیل معتبر وارد نمایید'
EMAILADDRESS_MESSAGE_REQUIRED: 'لطفاً نشانی ایمیل خود را وارد نمایید'
POST: ارسال
PREVIEW: 'پیش‌نمایش'
PREVIEWLABEL: 'پیش‌نمایش'
PREVIEW: پیش‌نمایش
PREVIEWLABEL: پیش‌نمایش
YOURNAME: 'نام شما'
YOURNAME_MESSAGE_REQUIRED: 'لطفاً نام خود را وارد نمایید'
CommentingController:
COMMENTS: دیدگاه‌ها
EMAILADDRESS: 'ایمیل شما (منتشر نخواهد شد)'
PERMISSIONFAILURE: 'شما نمی‌توانید در این صفحه دیدگاهی درج نمایید. لطفاً اطمینان حاصل نمایید که وارد سایت شده‌اید و از سطح دسترسی دسترسی مناسب برخوردار هستید.'
RSSTITLE: 'خوراک آراس‌اس دیدگاه‌ها'
WEBSITEURL: 'نشانی وب‌سایت شما'
Comments:
COMMENTSREQUIRELOGIN: 'درج دیدگاه نیازمند ورود شما به سایت است'
CommentsAdmin:
ApprovedComments: 'تایید شده'
Comments: 'تایید شده'
NeedsModeration: 'نیازمند مدیریت'
NewComments: تازه
SpamComments: هرزنوشت
CommentsExtension:
COMMENTOPTIONS: دیدگاه‌ها
MODERATIONREQUIRED_NONE: 'نیاز به مدیریت ندارد'
MODERATIONREQUIRED_NONMEMBERSONLY: 'تنها مدیریت کاربران غیر عضو'
MODERATIONREQUIRED_REQUIRED: 'مدیریت تمامی دیدگاه‌ها'
CommentsGridFieldAction:
APPROVE: تایید
COMMENTAPPROVED: 'دیدگاه تایید شد.'
COMMENTMARKEDSPAM: 'دیدگاه به عنوان هرزنوشت علامت‌گذاری شد.'
SPAM: هرزنوشت
CommentsGridFieldConfig:
APPROVE: تایید
SPAM: هرزنوشت
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'دیدگاه شما ارسال شده و هم‌اکنون در انتظار بررسی است.'
CommentsInterface_singlecomment_ss:
APPROVE: 'تایید کن'
ISNTSPAM: 'هرزنوشت نیست'
ISSPAM: هرزنوشته
PBY: 'ارسال شده توسط'
REMCOM: 'رد کردن'
REPLYTO: 'ارسال پاسخ به'
CommentsInterface_ss:
AWAITINGMODERATION: 'دیدگاه شما ارسال شده و هم‌اکنون در انتظار بررسی است.'
COMMENTLOGINERROR: 'تا زمانی‌که وارد سایت نشده‌اید نمی‌توانید دیدگاهی درج نمایید'
@ -85,5 +34,51 @@ fa_IR:
PREV: پیشین
RSSFEEDALLCOMMENTS: 'خوراک آر‌اس‌اس تمامی دیدگاه‌ها'
RSSFEEDCOMMENTS: 'خوراک آر‌اس‌اس دیدگاه‌های این صفحه'
PageCommentInterface:
DELETEALLCOMMENTS: 'حذف تمامی دیدگاه‌ها در این صفحه'
SilverStripe\Comments\Admin\CommentAdmin:
ADMIN_PERMISSION: 'دسترسی به بخش ''دیدگاه‌ها'''
ApprovedComments: 'تایید شده'
Comments: 'تایید شده'
MENUTITLE: دیدگاه‌ها
NewComments: تازه
SpamComments: هرزنوشت
SilverStripe\Comments\Admin\CommentsGridFieldAction:
APPROVE: تایید
COMMENTAPPROVED: 'دیدگاه تایید شد.'
COMMENTMARKEDSPAM: 'دیدگاه به عنوان هرزنوشت علامت‌گذاری شد.'
SPAM: هرزنوشت
SilverStripe\Comments\Admin\CommentsGridFieldApproveAction:
APPROVE: تایید
COMMENTAPPROVED: 'دیدگاه تایید شد.'
SilverStripe\Comments\Admin\CommentsGridFieldConfig:
APPROVE: تایید
SPAM: هرزنوشت
SilverStripe\Comments\Admin\CommentsGridFieldSpamAction:
COMMENTMARKEDSPAM: 'دیدگاه به عنوان هرزنوشت علامت‌گذاری شد.'
SPAM: هرزنوشت
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: دیدگاه‌ها
EMAILADDRESS: 'ایمیل شما (منتشر نخواهد شد)'
PERMISSIONFAILURE: 'شما نمی‌توانید در این صفحه دیدگاهی درج نمایید. لطفاً اطمینان حاصل نمایید که وارد سایت شده‌اید و از سطح دسترسی دسترسی مناسب برخوردار هستید.'
RSSTITLE: 'خوراک آراس‌اس دیدگاه‌ها'
WEBSITEURL: 'نشانی وب‌سایت شما'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: دیدگاه‌ها
COMMENTSTABSET: دیدگاه‌ها
MODERATIONREQUIRED_NONE: 'نیاز به مدیریت ندارد'
MODERATIONREQUIRED_NONMEMBERSONLY: 'تنها مدیریت کاربران غیر عضو'
MODERATIONREQUIRED_REQUIRED: 'مدیریت تمامی دیدگاه‌ها'
SilverStripe\Comments\Model\Comment:
COMMENT: دیدگاه
COMMENTBY: 'دیدگاه توسط %s'
CREATED: 'تاریخ ارسال'
EMAIL: ایمیل
ISSPAM: هرزنوشت؟
MODERATED: 'مدیریت شده؟'
'ON': در
OPTIONS: گزینه‌ها
OPTION_DESCRIPTION: 'دیدگاه‌های مدیریت نشده و هرزنوشت‌ها تا زمان تایید به نمایش در نخواهند آمد'
PARENTTITLE: والد
PLURALNAME: دیدگاه‌ها
ParentComment_Title: 'این دیدگاه پاسخی است به زیر'
SINGULARNAME: دیدگاه
URL: 'نشانی اینترنتی'

View File

@ -1,22 +1,4 @@
fi:
Comment:
ALLOWCOMMENTS: 'Salli kommentointi'
COMMENT: Komentti
COMMENTBY: 'Kommentoija: %s'
CREATED: Kirjoitettu
EMAIL: Sähköposti
ISSPAM: 'Spämmiä?'
MODERATED: 'Moderoitu?'
NAME: 'Kirjoittajan nimi'
'ON': pvm
PARENTTITLE: Isäntä
PLURALNAME: Kommentit
SINGULARNAME: Komentti
URL: URL-osoite
CommentAdmin:
MENUTITLE: Kommentit
Moderated: Moderoitu
NeedsModeration: 'Tarvitsee moderointia'
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Ole hyvä ja kommentoi'
COMMENT_MESSAGE_URL: 'URL-osoitteen on oltava kelvollinen'
@ -27,25 +9,24 @@ fi:
PREVIEWLABEL: Esikatselu
YOURNAME: Nimesi
YOURNAME_MESSAGE_REQUIRED: Nimesi
CommentingController:
COMMENTS: Kommentit
EMAILADDRESS: 'Sähköpostiosoitteesi (ei julkaista)'
PERMISSIONFAILURE: 'Et voi kommentoida tätä sivua. Varmista, että olet kirjatuneena ja että käyttöoikeutesi ovat riittävät.'
RSSTITLE: 'Kommenttien RSS-syöte'
WEBSITEURL: 'WWW-sivustosi osoite'
Comments:
COMMENTSREQUIRELOGIN: 'Vaadi kirjautuminen kommentointiin'
CommentsAdmin:
NeedsModeration: 'Tarvitsee moderointia'
Comments: Hyväksytty
NewComments: Uusi
SpamComments: Spämmiä
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Kommenttisi on lähetetty ja on moderoitavana.'
AWAITINGMODERATION: 'Kommenttisi on lähetetty ja odottaa moderointia.'
CommentsInterface_singlecomment_ss:
PBY: Lähettänyt
REPLYTO: Vastausosoite
CommentsInterface_ss:
AWAITINGMODERATION: 'Kommenttisi on lähetetty ja on moderoitavana.'
AWAITINGMODERATION: 'Kommenttisi on lähetetty ja odottaa moderointia.'
COMMENTLOGINERROR: 'Et voi kommentoida ennen kuin olet kirjautunut sisään'
COMMENTPERMISSIONERROR: 'ja käyttöoikeustasosi on oltava riittävä'
COMMENTPOSTLOGIN: 'Kirjaudu tästä'
COMMENTS: Comments
COMMENTSDISABLED: 'Kommentointi on lukittu'
DELETEALLCOMMENTS: 'Poista kaikki tämän sivun kommentit'
LOGINTOPOSTCOMMENT: 'Kirjaudu kommentoidaksesi'
NEXT: seuraava
NOCOMMENTSYET: 'Kukaan ei ole vielä kommentoinut tätä sivua.'
@ -53,5 +34,51 @@ fi:
PREV: edellinen
RSSFEEDALLCOMMENTS: 'RSS-syöte kaikista kommenteista'
RSSFEEDCOMMENTS: 'RSS-syöte tämän sivun kommenteista'
PageCommentInterface:
DELETEALLCOMMENTS: 'Poista kaikki tämän sivun kommentit'
SilverStripe\Comments\Admin\CommentAdmin:
ADMIN_PERMISSION: 'Pääsy Comments-osioon'
ApprovedComments: Hyväksytty
Comments: Hyväksytty
MENUTITLE: Kommentit
NewComments: Uusi
SpamComments: Spämmiä
SilverStripe\Comments\Admin\CommentsGridFieldAction:
APPROVE: Hyväksy
COMMENTAPPROVED: 'Kommentti hyväksytty'
COMMENTMARKEDSPAM: 'Kommentti merkitty spämmiksi.'
SPAM: Spämmiä
SilverStripe\Comments\Admin\CommentsGridFieldApproveAction:
APPROVE: Hyväksy
COMMENTAPPROVED: 'Kommentti hyväksytty'
SilverStripe\Comments\Admin\CommentsGridFieldConfig:
APPROVE: Hyväksy
SPAM: Spämmiä
SilverStripe\Comments\Admin\CommentsGridFieldSpamAction:
COMMENTMARKEDSPAM: 'Kommentti merkitty spämmiksi.'
SPAM: Spämmiä
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Kommentit
EMAILADDRESS: 'Sähköpostiosoitteesi (ei julkaista)'
PERMISSIONFAILURE: 'Et voi kommentoida tätä sivua. Varmista, että olet kirjatuneena ja että käyttöoikeutesi ovat riittävät.'
RSSTITLE: 'Kommenttien RSS-syöte'
WEBSITEURL: 'WWW-sivustosi osoite'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Kommentit
COMMENTSTABSET: Kommentit
MODERATIONREQUIRED_NONE: 'Moderointia ei tarvita'
MODERATIONREQUIRED_NONMEMBERSONLY: 'Moderoi vain ei-jäsenet'
MODERATIONREQUIRED_REQUIRED: 'Moderoi kaikki kommentit'
SilverStripe\Comments\Model\Comment:
COMMENT: Komentti
COMMENTBY: 'Kommentoija: %s'
CREATED: Kirjoitettu
EMAIL: Sähköposti
ISSPAM: 'Spämmiä?'
MODERATED: 'Moderoitu?'
'ON': pvm
OPTIONS: Asetukset
OPTION_DESCRIPTION: 'Moderoimattomat ja roskakommentit eivät näy ennen hyväksymistä'
PARENTTITLE: Isäntä
PLURALNAME: Kommentit
ParentComment_Title: 'Tämä kommentti on vastaus alla olevaan'
SINGULARNAME: Kommentti
URL: URL-osoite

15
lang/fi_FI.yml Normal file
View File

@ -0,0 +1,15 @@
fi_FI:
CommentsInterface_ss:
COMMENTS: Kommentit
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Kommentit
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Kommentit
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Kommentit
COMMENTSTABSET: Kommentit
SilverStripe\Comments\Model\Comment:
EMAIL: Sähköposti
OPTIONS: Valinnat
PLURALNAME: Kommentit
URL: URL-osoite

View File

@ -1,21 +1,4 @@
fr:
Comment:
ALLOWCOMMENTS: 'Autoriser Commentaires'
COMMENT: Commentaire
COMMENTBY: 'Commentaire par %s'
CREATED: 'Date de publication'
EMAIL: Email
ISSPAM: 'Spam?'
MODERATED: 'Modéré?'
NAME: 'Nom de l''Auteur'
PARENTTITLE: Parent
PLURALNAME: Commentaires
SINGULARNAME: Commentaire
URL: URL
CommentAdmin:
MENUTITLE: Commentaires
Moderated: Modéré
NeedsModeration: 'Besoin de modération'
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Saisissez votre commentaire'
COMMENT_MESSAGE_URL: 'Saisissez une URl valide'
@ -26,20 +9,8 @@ fr:
PREVIEWLABEL: Aperçu
YOURNAME: 'Votre Nom'
YOURNAME_MESSAGE_REQUIRED: 'Saisissez votre nom'
CommentingController:
COMMENTS: Commentaires
EMAILADDRESS: 'Votre adresse e-mail (ne sera pas publiée)'
PERMISSIONFAILURE: 'Vous n''avez pas l''autorisation de commenter cette page. Assurez vous d''être connecté et d''avoir le bon niveau de d''autorisation.'
RSSTITLE: 'Flux RSS de Commentaires'
WEBSITEURL: 'URl de votre site web'
CommentsAdmin:
NeedsModeration: 'Besoin de Modération'
CommentsExtension:
COMMENTOPTIONS: Commentaires
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Votre commentaire a été soumis à modération.'
CommentsInterface_singlecomment_ss:
PBY: 'Posté par'
CommentsInterface_ss:
AWAITINGMODERATION: 'Votre commentaire a été soumis à modération.'
COMMENTLOGINERROR: 'Vous ne pouvez pas poster de commentaires sans être connecté'
@ -47,6 +18,7 @@ fr:
COMMENTPOSTLOGIN: 'Se connecter'
COMMENTS: Commentaires
COMMENTSDISABLED: 'La publication de commentaires est désactivée'
DELETEALLCOMMENTS: 'Supprimer tout les commentaires de cette page'
LOGINTOPOSTCOMMENT: 'Connectez vous pour poster un commentaire'
NEXT: suivant
NOCOMMENTSYET: 'Il n''y a pas encore de commentaire.'
@ -54,5 +26,26 @@ fr:
PREV: précédent
RSSFEEDALLCOMMENTS: 'Flux RSS de tous les commentaires'
RSSFEEDCOMMENTS: 'Flux RSS de commentaires de cette page'
PageCommentInterface:
DELETEALLCOMMENTS: 'Supprimer tout les commentaires de cette page'
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Commentaires
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Commentaires
EMAILADDRESS: 'Votre adresse e-mail (ne sera pas publiée)'
PERMISSIONFAILURE: 'Vous n''avez pas l''autorisation de commenter cette page. Assurez vous d''être connecté et d''avoir le bon niveau de d''autorisation.'
RSSTITLE: 'Flux RSS de Commentaires'
WEBSITEURL: 'URl de votre site web'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Commentaires
COMMENTSTABSET: Commentaires
SilverStripe\Comments\Model\Comment:
COMMENT: Commentaire
COMMENTBY: 'Commentaire par %s'
CREATED: 'Date de publication'
EMAIL: Email
ISSPAM: 'Spam?'
MODERATED: 'Modéré?'
'ON': sur
PARENTTITLE: Parent
PLURALNAME: Commentaires
SINGULARNAME: Commentaire
URL: URL

16
lang/gl_ES.yml Normal file
View File

@ -0,0 +1,16 @@
gl_ES:
CommentInterface:
PREVIEW: Previsualizar
PREVIEWLABEL: Previsualizar
CommentsInterface_ss:
COMMENTS: Comentarios
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Comentarios
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Comentarios
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Comentarios
COMMENTSTABSET: Comentarios
SilverStripe\Comments\Model\Comment:
EMAIL: Correo-e
PLURALNAME: Comentarios

17
lang/he_IL.yml Normal file
View File

@ -0,0 +1,17 @@
he_IL:
CommentInterface:
PREVIEW: 'תצוגה מקדימה'
PREVIEWLABEL: 'תצוגה מקדימה'
CommentsInterface_ss:
COMMENTS: תגובות
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: תגובות
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: תגובות
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: תגובות
COMMENTSTABSET: תגובות
SilverStripe\Comments\Model\Comment:
EMAIL: 'דואר אלקטרוני'
PLURALNAME: תגובות
URL: 'כתובת הדף'

84
lang/hr.yml Normal file
View File

@ -0,0 +1,84 @@
hr:
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Molimo unesite vaš komentar'
COMMENT_MESSAGE_URL: 'Molimo unesite ispravan link'
EMAILADDRESS_MESSAGE_EMAIL: 'Molimo unesite ispravnu email adresu'
EMAILADDRESS_MESSAGE_REQUIRED: 'Molimo unesite email adresu'
POST: Objava
PREVIEW: Pregled
PREVIEWLABEL: Pregled
YOURNAME: 'Vaše ime'
YOURNAME_MESSAGE_REQUIRED: 'Molimo unesite vaše ime'
Comments:
COMMENTSREQUIRELOGIN: 'Zahtjeva prijavu za komentiranje'
CommentsAdmin:
Comments: Odobren
NewComments: Novo
SpamComments: Spam
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Vaš komentar je zaprimljen i čeka odobrenje.'
CommentsInterface_singlecomment_ss:
REPLYTO: 'Odgovori na'
CommentsInterface_ss:
AWAITINGMODERATION: 'Vaš komentar je zaprimljen i čeka odobrenje.'
COMMENTLOGINERROR: 'Ne možete objavljivati komentare dok se ne prijavite'
COMMENTPERMISSIONERROR: 'i da imate potrebna prava'
COMMENTPOSTLOGIN: 'Prijavi se ovdje'
COMMENTS: Komentari
COMMENTSDISABLED: 'Objavljivanje komentara je onemogućeno'
DELETEALLCOMMENTS: 'Obriši sve komentare na ovoj stranici'
LOGINTOPOSTCOMMENT: 'Prijavi se da objaviš komentar'
NEXT: sljedeći
NOCOMMENTSYET: 'Nitko nije komentirao na ovu stranicu.'
POSTCOM: 'Objavi svoj komentar'
PREV: prethodni
RSSFEEDALLCOMMENTS: 'RSS kanal za sve komentare'
RSSFEEDCOMMENTS: 'RSS kanal za sve komentare na ovoj stranici'
SilverStripe\Comments\Admin\CommentAdmin:
ADMIN_PERMISSION: 'Pristup ''Comments'' sekciji'
ApprovedComments: Odobren
Comments: Odobren
MENUTITLE: Komentari
NewComments: Novo
SpamComments: Spam
SilverStripe\Comments\Admin\CommentsGridFieldAction:
APPROVE: Odobri
COMMENTAPPROVED: 'Komentar odobren.'
COMMENTMARKEDSPAM: 'Komentar označen kao spam.'
SPAM: SPam
SilverStripe\Comments\Admin\CommentsGridFieldApproveAction:
APPROVE: Odobri
COMMENTAPPROVED: 'Komentar odobren.'
SilverStripe\Comments\Admin\CommentsGridFieldConfig:
APPROVE: Odobri
SPAM: Spam
SilverStripe\Comments\Admin\CommentsGridFieldSpamAction:
COMMENTMARKEDSPAM: 'Komentar označen kao spam.'
SPAM: Spam
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Komentari
EMAILADDRESS: 'Vaša email adresa (neće biti objavljena)'
PERMISSIONFAILURE: 'Ne možete objavljivati komentare na ovoj stranici. Molimo provjerite da li ste prijavljeni i imate potrebna prava.'
RSSTITLE: 'RSS kanal komentara'
WEBSITEURL: 'Vaša web adresa'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Komentari
COMMENTSTABSET: Komentari
MODERATIONREQUIRED_NONE: 'Nije potrebna moderacija'
MODERATIONREQUIRED_NONMEMBERSONLY: 'Samo moderiraj goste'
MODERATIONREQUIRED_REQUIRED: 'Moderiraj sve komentare'
SilverStripe\Comments\Model\Comment:
COMMENT: Komentar
COMMENTBY: 'Komentar od %s'
CREATED: 'Datum objave'
EMAIL: Email
ISSPAM: 'Spam?'
MODERATED: 'Moderirano?'
'ON': na
OPTIONS: Opcije
OPTION_DESCRIPTION: 'Nemoderirani i spam komentari neće biti objavljeni dok se ne odobre'
PARENTTITLE: Roditelj
PLURALNAME: Komentari
ParentComment_Title: 'Ovaj komentar je odgovor na dolje'
SINGULARNAME: Komentar
URL: Link

View File

@ -1,22 +1,4 @@
hu:
Comment:
ALLOWCOMMENTS: 'Hozzászólások engedélyezve'
COMMENT: Hozzászólás
COMMENTBY: 'Létrehozta %s'
CREATED: 'Létrehozás dátuma'
EMAIL: E-mail
ISSPAM: 'SPAM?'
MODERATED: 'Moderált?'
NAME: 'Hozzászóló neve'
PARENTTITLE: Szülő
PLURALNAME: Hozzászólások
SINGULARNAME: Hozzászólás
URL: Link
CommentAdmin:
ADMIN_PERMISSION: '''Hozzászólások'' mező elérése'
MENUTITLE: Hozzászólások
Moderated: Moderált
NeedsModeration: 'Moderálás szükséges'
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Szöveg megadása'
COMMENT_MESSAGE_URL: 'Kérjük adjon meg egy működő linket'
@ -27,18 +9,8 @@ hu:
PREVIEWLABEL: Előnézet
YOURNAME: 'Az Ön neve'
YOURNAME_MESSAGE_REQUIRED: 'Kérjük adja meg nevét'
CommentingController:
COMMENTS: 'A hosszászólás szövege'
EMAILADDRESS: 'Az Ön e-mail címe (nem látható)'
PERMISSIONFAILURE: 'Ön csak a bejelentkezést követően, és a megfelelő jogosultság birtokában hozhat létre hozzászólást.'
RSSTITLE: 'Hozzászólások RSS-ben'
WEBSITEURL: 'Az Ön webcíme'
CommentsAdmin:
NeedsModeration: 'Moderálás szükséges'
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Hozzászólását moderálásra továbbítottuk'
CommentsInterface_singlecomment_ss:
PBY: Feladó
CommentsInterface_ss:
AWAITINGMODERATION: 'Hozzászólását moderálásra továbbítottuk'
COMMENTLOGINERROR: 'A hozzászóláshoz be kell jelentkeznie'
@ -46,6 +18,7 @@ hu:
COMMENTPOSTLOGIN: Bejelentkezés
COMMENTS: Hozzászólások
COMMENTSDISABLED: 'A hozzászólások le vannak tiltva '
DELETEALLCOMMENTS: 'Oldal összes hozzászólásának törlése'
LOGINTOPOSTCOMMENT: 'A hozzászóláshoz jelentkezzen be '
NEXT: következő
NOCOMMENTSYET: 'Nem érkeztek hozzászólások'
@ -53,5 +26,26 @@ hu:
PREV: előző
RSSFEEDALLCOMMENTS: 'Összes hozzászólás RSS-ben'
RSSFEEDCOMMENTS: 'Oldal hozzászólásai RSS-ben'
PageCommentInterface:
DELETEALLCOMMENTS: 'Oldal összes hozzászólásának törlése'
SilverStripe\Comments\Admin\CommentAdmin:
ADMIN_PERMISSION: '''Hozzászólások'' mező elérése'
MENUTITLE: Hozzászólások
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: 'A hosszászólás szövege'
EMAILADDRESS: 'Az Ön e-mail címe (nem látható)'
PERMISSIONFAILURE: 'Ön csak a bejelentkezést követően, és a megfelelő jogosultság birtokában hozhat létre hozzászólást.'
RSSTITLE: 'Hozzászólások RSS-ben'
WEBSITEURL: 'Az Ön webcíme'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Hozzászólások
COMMENTSTABSET: Hozzászólások
SilverStripe\Comments\Model\Comment:
COMMENT: Hozzászólás
COMMENTBY: 'Létrehozta %s'
CREATED: 'Létrehozás dátuma'
EMAIL: E-mail
ISSPAM: 'SPAM?'
MODERATED: 'Moderált?'
PARENTTITLE: Szülő
PLURALNAME: Hozzászólások
SINGULARNAME: Hozzászólás
URL: Link

View File

@ -1,21 +1,4 @@
id:
Comment:
ALLOWCOMMENTS: 'Bolehkan Komentar'
COMMENT: Komentar
COMMENTBY: 'Komentar oleh %s'
CREATED: 'Tanggal kirim'
EMAIL: Email
ISSPAM: 'Spam?'
MODERATED: 'Moderasi?'
NAME: 'Nama Penulis'
PARENTTITLE: Induk
PLURALNAME: Komentar
SINGULARNAME: Komentar
URL: URL
CommentAdmin:
MENUTITLE: Komentar
Moderated: Dimoderasi
NeedsModeration: 'Perlu Moderasi'
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Ketikkan komentar Anda'
COMMENT_MESSAGE_URL: 'Isikan URL yang valid'
@ -26,18 +9,8 @@ id:
PREVIEWLABEL: Pratinjau
YOURNAME: 'Nama Anda'
YOURNAME_MESSAGE_REQUIRED: 'Isikan nama Anda'
CommentingController:
COMMENTS: Komentar
EMAILADDRESS: 'Alamat email Anda (tidak akan diterbitkan)'
PERMISSIONFAILURE: 'Anda tidak dapat mengomentari laman ini. Mohon pastikan Anda sudah login dan mendapatkan hak akses yang sesuai.'
RSSTITLE: 'Sindikasi RSS Komentar'
WEBSITEURL: 'URL situs Anda'
CommentsAdmin:
NeedsModeration: 'Perlu Moderasi'
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Komentar Anda sudah terkirim dan menunggu moderasi.'
CommentsInterface_singlecomment_ss:
PBY: 'Komentar oleh'
CommentsInterface_ss:
AWAITINGMODERATION: 'Komentar Anda sudah terkirim dan menunggu moderasi.'
COMMENTLOGINERROR: 'Anda tidak dapat mengomentari jika belum login'
@ -45,6 +18,7 @@ id:
COMMENTPOSTLOGIN: 'Login di Sini'
COMMENTS: Komentar
COMMENTSDISABLED: 'Komentar sedang dinonaktifkan'
DELETEALLCOMMENTS: 'Hapus semua komentar di laman ini'
LOGINTOPOSTCOMMENT: 'Login untuk berkomentar'
NEXT: selanjutnya
NOCOMMENTSYET: 'Belum ada yang berkomentar.'
@ -52,5 +26,25 @@ id:
PREV: sebelumnya
RSSFEEDALLCOMMENTS: 'Sindikasi RSS untuk semua komentar'
RSSFEEDCOMMENTS: 'Sindikasi RSS untuk komentar di laman ini'
PageCommentInterface:
DELETEALLCOMMENTS: 'Hapus semua komentar di laman ini'
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Komentar
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Komentar
EMAILADDRESS: 'Alamat email Anda (tidak akan diterbitkan)'
PERMISSIONFAILURE: 'Anda tidak dapat mengomentari laman ini. Mohon pastikan Anda sudah login dan mendapatkan hak akses yang sesuai.'
RSSTITLE: 'Sindikasi RSS Komentar'
WEBSITEURL: 'URL situs Anda'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Komentar
COMMENTSTABSET: Komentar
SilverStripe\Comments\Model\Comment:
COMMENT: Komentar
COMMENTBY: 'Komentar oleh %s'
CREATED: 'Tanggal kirim'
EMAIL: Email
ISSPAM: 'Spam?'
MODERATED: 'Moderasi?'
PARENTTITLE: Induk
PLURALNAME: Komentar
SINGULARNAME: Komentar
URL: URL

15
lang/is.yml Normal file
View File

@ -0,0 +1,15 @@
is:
CommentsInterface_ss:
COMMENTS: Athugasemdir
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Athugasemdir
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Athugasemdir
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Athugasemdir
COMMENTSTABSET: Athugasemdir
SilverStripe\Comments\Model\Comment:
EMAIL: Tölvupóstur
'ON': á
PLURALNAME: Athugasemdir
URL: 'Veffang (URL)'

22
lang/it.yml Normal file
View File

@ -0,0 +1,22 @@
it:
CommentInterface:
PREVIEW: Anteprima
PREVIEWLABEL: Anteprima
CommentsInterface_ss:
COMMENTS: Commenti
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Commenti
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Commenti
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Commenti
COMMENTSTABSET: Commenti
SilverStripe\Comments\Model\Comment:
COMMENT: Commento
EMAIL: E-mail
'ON': il
OPTIONS: Opzioni
PARENTTITLE: Parente
PLURALNAME: Commenti
SINGULARNAME: Commento
URL: URL

18
lang/ja.yml Normal file
View File

@ -0,0 +1,18 @@
ja:
CommentInterface:
PREVIEW: プレビュー
PREVIEWLABEL: プレビュー
CommentsInterface_ss:
COMMENTS: コメント
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: コメント
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: コメント
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: コメント
COMMENTSTABSET: コメント
SilverStripe\Comments\Model\Comment:
EMAIL: メール
OPTIONS: オプション
PLURALNAME: コメント
URL: URL

16
lang/ja_JP.yml Normal file
View File

@ -0,0 +1,16 @@
ja_JP:
CommentInterface:
PREVIEW: プレビュー
PREVIEWLABEL: プレビュー
CommentsInterface_ss:
COMMENTS: コメント
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: コメント
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: コメント
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: コメント
COMMENTSTABSET: コメント
SilverStripe\Comments\Model\Comment:
EMAIL: メールアドレス
PLURALNAME: コメント

17
lang/ko.yml Normal file
View File

@ -0,0 +1,17 @@
ko:
CommentInterface:
PREVIEW: 미리보기
PREVIEWLABEL: 미리보기
CommentsInterface_ss:
COMMENTS: 코멘트
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: 코멘트
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: 코멘트
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: 코멘트
COMMENTSTABSET: 코멘트
SilverStripe\Comments\Model\Comment:
EMAIL: 이메일
PLURALNAME: 코멘트
URL: URL

View File

@ -1,29 +1,4 @@
lt:
Comment:
ALLOWCOMMENTS: 'Leisti komentarus'
COMMENT: Komentaras
COMMENTBY: 'Komentarą parašė ''%s'''
CREATED: 'Paskelbimo data'
EMAIL: 'E. paštas'
ISSPAM: 'Šlamštas?'
MODERATED: 'Patvirtintas?'
NAME: 'Autoriaus Vardas'
'ON': į
OPTION_DESCRIPTION: 'Nepatvirtinti komentarai nebus rodomi, kol jie atskirai nebus patvirtinti'
PARENTTITLE: Priklauso
PLURALNAME: Komentarai
ParentComment_Title: 'Šis komentaras yra atsakymas į žemiau esantį'
SINGULARNAME: Komentaras
URL: 'URL adresas'
CommentAdmin:
ADMIN_PERMISSION: 'Patekti į ''Komentarų'' dalį'
ApprovedComments: Patvirtinti
Comments: Patvirtinti
MENUTITLE: Komentarai
Moderated: Patvirtinti
NeedsModeration: 'Laukia patvirtinimo'
NewComments: Nauji
SpamComments: 'Šlamštas'
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Prašome parašyti savo komentarą'
COMMENT_MESSAGE_URL: 'Prašome įvesti teisingą URL adresą'
@ -34,33 +9,14 @@ lt:
PREVIEWLABEL: Peržiūra
YOURNAME: 'Jūsų vardas'
YOURNAME_MESSAGE_REQUIRED: 'Prašome įvesti savo vardą'
CommentingController:
COMMENTS: Komentarai
EMAILADDRESS: 'Jūsų el.pašto adresas (nebus skelbiamas)'
PERMISSIONFAILURE: 'Jūs negalite skelbti komentarų šiame puslapyje. Įsitikinkite, kad esate prisijungęs ir turite atitinkamą teisių lygį.'
RSSTITLE: 'Komentarų RSS srautas'
WEBSITEURL: 'Jūsų svetainės nuoroda'
Comments:
COMMENTSREQUIRELOGIN: 'Būtina prisijungti komentavimui'
CommentsAdmin:
ApprovedComments: Patvirtinti
Comments: Patvirtinti
NeedsModeration: 'Laukia patvirtinimo'
NewComments: Nauji
SpamComments: 'Šlamštas'
CommentsExtension:
COMMENTOPTIONS: Komentarai
MODERATIONREQUIRED_NONE: 'Nereikalauja patvirtinimo'
MODERATIONREQUIRED_NONMEMBERSONLY: 'Tvirtinti tik neregistruotų vartotojų'
MODERATIONREQUIRED_REQUIRED: 'Tvirtinti visus komentarus'
SpamComments: Šlamštas
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Jūsų komentaras išsiųstas ir laukia patvirtinimo.'
CommentsInterface_singlecomment_ss:
APPROVE: patvirtinti
ISNTSPAM: 'ne šlamštas'
ISSPAM: šlamštas
PBY: Paskelbė
REMCOM: ištrinti
CommentsInterface_ss:
AWAITINGMODERATION: 'Jūsų komentaras išsiųstas ir laukia patvirtinimo.'
COMMENTLOGINERROR: 'Negalite rašyti komentarų, jeigu nesate prisijungę'
@ -76,5 +32,42 @@ lt:
PREV: ankstesni
RSSFEEDALLCOMMENTS: 'Visų komentarų RSS'
RSSFEEDCOMMENTS: 'Šio puslapio komentarų RSS'
PageCommentInterface:
DELETEALLCOMMENTS: 'Ištrinti visus komentarus šiame puslapyje'
SilverStripe\Comments\Admin\CommentAdmin:
ADMIN_PERMISSION: 'Patekti į ''Komentarų'' dalį'
ApprovedComments: Patvirtinti
Comments: Patvirtinti
MENUTITLE: Komentarai
NewComments: Nauji
SpamComments: Šlamštas
SilverStripe\Comments\Admin\CommentsGridFieldAction:
SPAM: Šlamštas
SilverStripe\Comments\Admin\CommentsGridFieldConfig:
SPAM: Šlamštas
SilverStripe\Comments\Admin\CommentsGridFieldSpamAction:
SPAM: Šlamštas
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Komentarai
EMAILADDRESS: 'Jūsų el.pašto adresas (nebus skelbiamas)'
PERMISSIONFAILURE: 'Jūs negalite skelbti komentarų šiame puslapyje. Įsitikinkite, kad esate prisijungęs ir turite atitinkamą teisių lygį.'
RSSTITLE: 'Komentarų RSS srautas'
WEBSITEURL: 'Jūsų svetainės nuoroda'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Komentarai
COMMENTSTABSET: Komentarai
MODERATIONREQUIRED_NONE: 'Nereikalauja patvirtinimo'
MODERATIONREQUIRED_NONMEMBERSONLY: 'Tvirtinti tik neregistruotų vartotojų'
MODERATIONREQUIRED_REQUIRED: 'Tvirtinti visus komentarus'
SilverStripe\Comments\Model\Comment:
COMMENT: Komentaras
COMMENTBY: 'Komentarą parašė ''%s'''
CREATED: 'Paskelbimo data'
EMAIL: 'E. paštas'
ISSPAM: 'Šlamštas?'
MODERATED: 'Patvirtintas?'
'ON': į
OPTION_DESCRIPTION: 'Nepatvirtinti komentarai nebus rodomi, kol jie atskirai nebus patvirtinti'
PARENTTITLE: Priklauso
PLURALNAME: Komentarai
ParentComment_Title: 'Šis komentaras yra atsakymas į žemiau esantį'
SINGULARNAME: Komentaras
URL: 'URL adresas'

21
lang/mi.yml Normal file
View File

@ -0,0 +1,21 @@
mi:
CommentInterface:
PREVIEW: Arokite
PREVIEWLABEL: Arokite
CommentsInterface_ss:
COMMENTS: 'Ngā Tākupu'
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: 'Ngā Tākupu'
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: 'Ngā Tākupu'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: 'Ngā Tākupu'
COMMENTSTABSET: 'Ngā Tākupu'
SilverStripe\Comments\Model\Comment:
COMMENT: Tākupu
EMAIL: Īmēra
OPTIONS: 'Ngā Kōwhiringa'
PARENTTITLE: Matua
PLURALNAME: 'Ngā Tākupu'
SINGULARNAME: Tākupu
URL: PRO

View File

@ -1,37 +1,20 @@
nb:
Comment:
ALLOWCOMMENTS: 'Tillat kommentarer'
COMMENT: Kommentar
ISSPAM: 'Spam?'
MODERATED: 'Moderert?'
NAME: Navn
PLURALNAME: Kommentarer
SINGULARNAME: Kommentar
CommentAdmin:
MENUTITLE: Kommentarer
Moderated: Moderert
NeedsModeration: 'Trenger moderering'
CommentInterface:
EMAILADDRESS_MESSAGE_REQUIRED: 'Vennligst fyll inn din e-postadresse'
POST: 'Legg ut'
PREVIEW: Forhåndsvisning
PREVIEWLABEL: Forhåndsvisning
YOURNAME: Navn
CommentingController:
COMMENTS: Kommentar
EMAILADDRESS: 'Epostadresse (blir ikke publisert)'
PERMISSIONFAILURE: 'Du kan ikke kommentere på denne siden. Vennligst sjekk at du er innlogget og har et passende tilgangsnivå.'
RSSTITLE: 'RSS-feed for kommentarer'
WEBSITEURL: Hjemmeside
CommentsAdmin:
NeedsModeration: 'Trenger moderering'
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Kommentaren din har blitt lagret og er lagt i kø for moderering.'
CommentsInterface_singlecomment_ss:
PBY: 'Skrevet av'
CommentsInterface_ss:
AWAITINGMODERATION: 'Kommentaren din har blitt lagret og er lagt i kø for moderering.'
COMMENTLOGINERROR: 'Du kan ikke skrive kommentarer før du har logget inn'
COMMENTPERMISSIONERROR: 'og at du har et passende tilgangsnivå'
COMMENTPOSTLOGIN: 'Logg inn her'
COMMENTS: Kommentarer
COMMENTSDISABLED: 'Kommentarskriving har blitt slått av'
DELETEALLCOMMENTS: 'Fjern alle kommentarer på denne siden'
LOGINTOPOSTCOMMENT: 'Logg inn for å skrive en kommentar'
NEXT: neste
NOCOMMENTSYET: 'Ingen har skrevet en kommentar ennå.'
@ -39,5 +22,22 @@ nb:
PREV: forrige
RSSFEEDALLCOMMENTS: 'RSS-feed for alle kommentarer'
RSSFEEDCOMMENTS: 'RSS-feed for kommentarer på denne siden'
PageCommentInterface:
DELETEALLCOMMENTS: 'Fjern alle kommentarer på denne siden'
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Kommentarer
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Kommentar
EMAILADDRESS: 'Epostadresse (blir ikke publisert)'
PERMISSIONFAILURE: 'Du kan ikke kommentere på denne siden. Vennligst sjekk at du er innlogget og har et passende tilgangsnivå.'
RSSTITLE: 'RSS-feed for kommentarer'
WEBSITEURL: Hjemmeside
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Kommentarer
COMMENTSTABSET: Kommentarer
SilverStripe\Comments\Model\Comment:
COMMENT: Kommentar
EMAIL: Epost
ISSPAM: 'Spam?'
MODERATED: 'Moderert?'
PLURALNAME: Kommentarer
SINGULARNAME: Kommentar
URL: Nettadresse

View File

@ -1,40 +1,30 @@
nl:
Comment:
ALLOWCOMMENTS: 'Reacties toestaan'
COMMENT: Reactie
ISSPAM: 'Spam?'
MODERATED: 'Gemodereerd?'
NAME: Auteur
'ON': op
PLURALNAME: Reacties
SINGULARNAME: Reactie
CommentAdmin:
MENUTITLE: Reacties
Moderated: Gemodereerd
NeedsModeration: 'Wacht op moderatie'
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Plaats een reactie'
COMMENT_MESSAGE_URL: 'Vul een geldige URL in'
EMAILADDRESS_MESSAGE_EMAIL: 'Gelieve een geldig email adres in te voeren'
EMAILADDRESS_MESSAGE_REQUIRED: 'Gelieve een email adres in te voeren.'
POST: 'Plaats reactie'
PREVIEW: Voorbeeld
PREVIEWLABEL: Voorbeeld
YOURNAME: Naam
CommentingController:
COMMENTS: Reacties
EMAILADDRESS: 'E-mail adres (wordt niet gepubliceerd)'
PERMISSIONFAILURE: 'Je mag geen reacties plaatsen op deze pagina. Log a.u.b. eerst in en controleer je gebruikersrechten.'
RSSTITLE: 'Reacties RSS feed'
WEBSITEURL: 'Website URL'
YOURNAME_MESSAGE_REQUIRED: 'Gelieve een naam in te voeren.'
Comments:
COMMENTSREQUIRELOGIN: 'Log in om een reactie te plaatsen'
CommentsAdmin:
NeedsModeration: 'Wacht op moderatie'
CommentsExtension:
COMMENTOPTIONS: Reacties
Comments: Goedgekeurd
NewComments: Nieuw
SpamComments: Spam
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Je reactie is verstuurd en is in afwachting van moderatie.'
CommentsInterface_singlecomment_ss:
PBY: 'Geplaatst door'
CommentsInterface_ss:
AWAITINGMODERATION: 'Je reactie is verstuurd en is in afwachting van moderatie.'
COMMENTLOGINERROR: 'Je moet ingelogd zijn om reacties te kunnen plaatsen'
COMMENTPERMISSIONERROR: 'en controleer je gebruikersrechten'
COMMENTPOSTLOGIN: Inloggen
COMMENTS: Reacties
COMMENTSDISABLED: 'Reacties plaatsen is uitgeschakeld'
DELETEALLCOMMENTS: 'Verwijder alle reacties op deze pagina'
LOGINTOPOSTCOMMENT: 'Log in om een reactie te plaatsen'
NEXT: volgende
NOCOMMENTSYET: 'Er zijn nog geen reacties.'
@ -42,5 +32,33 @@ nl:
PREV: vorige
RSSFEEDALLCOMMENTS: 'RSS feed voor alle reacties'
RSSFEEDCOMMENTS: 'RSS feed voor reacties op deze pagina'
PageCommentInterface:
DELETEALLCOMMENTS: 'Verwijder alle reacties op deze pagina'
SilverStripe\Comments\Admin\CommentAdmin:
Comments: Goedgekeurd
MENUTITLE: Reacties
NewComments: Nieuw
SpamComments: Spam
SilverStripe\Comments\Admin\CommentsGridFieldAction:
SPAM: Spam
SilverStripe\Comments\Admin\CommentsGridFieldConfig:
SPAM: Spam
SilverStripe\Comments\Admin\CommentsGridFieldSpamAction:
SPAM: Spam
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Reacties
EMAILADDRESS: 'E-mail adres (wordt niet gepubliceerd)'
PERMISSIONFAILURE: 'Je mag geen reacties plaatsen op deze pagina. Log a.u.b. eerst in en controleer je gebruikersrechten.'
RSSTITLE: 'Reacties RSS feed'
WEBSITEURL: 'Website URL'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Reacties
COMMENTSTABSET: Reacties
SilverStripe\Comments\Model\Comment:
COMMENT: Reactie
EMAIL: E-mail
ISSPAM: 'Spam?'
MODERATED: 'Gemodereerd?'
'ON': op
OPTIONS: Instellingen
PLURALNAME: Reacties
SINGULARNAME: Reactie
URL: URL

20
lang/pl.yml Normal file
View File

@ -0,0 +1,20 @@
pl:
CommentInterface:
EMAILADDRESS_MESSAGE_REQUIRED: 'Proszę podać adres email'
POST: Post
PREVIEW: Podgląd
PREVIEWLABEL: Podgląd
CommentsInterface_ss:
COMMENTS: Komentarze
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Komentarze
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Komentarze
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Komentarze
COMMENTSTABSET: Komentarze
SilverStripe\Comments\Model\Comment:
EMAIL: Email
'ON': Opublikowano
PLURALNAME: Komentarze
URL: 'Adres URL'

View File

@ -1,66 +1,22 @@
pl_PL:
Comment:
ALLOWCOMMENTS: 'Zezwól na komentarze'
COMMENT: Komentarz
COMMENTBY: 'Komentarz %s'
CREATED: 'Data opublikowania'
EMAIL: Email
ISSPAM: 'Spam?'
MODERATED: 'Moderowane?'
NAME: Autor
'ON': na
OPTION_DESCRIPTION: 'Niemoderowane i oznaczone jako spam komentarze nie będą wyświetlane do momentu zatwierdzenia'
PARENTTITLE: Rodzic
PLURALNAME: Komentarze
ParentComment_Title: 'Ten komentarz jest odpowiedzią na komentarz poniżej'
SINGULARNAME: Komentarz
URL: URL
CommentAdmin:
ADMIN_PERMISSION: 'Dostęp do sekcji "Komentarze"'
ApprovedComments: Zatwierdzone
Comments: Zatwierdzone
MENUTITLE: Komentarze
Moderated: Moderowane
NeedsModeration: 'Wymaga moderacji'
NewComments: Nowy
SpamComments: Spam
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Wprowadź swój komentarz'
COMMENT_MESSAGE_URL: 'Wprowadź poprawny adres URL'
EMAILADDRESS_MESSAGE_EMAIL: 'Wprowadź poprawny adres email'
EMAILADDRESS_MESSAGE_REQUIRED: 'Wprowadź swój adres email'
POST: Wyślij
PREVIEW: 'Podgląd'
PREVIEWLABEL: 'Podgląd'
PREVIEW: Podgląd
PREVIEWLABEL: Podgląd
YOURNAME: 'Twoja nazwa'
YOURNAME_MESSAGE_REQUIRED: 'Wprowadź swoje imie'
CommentingController:
COMMENTS: Komentarze
EMAILADDRESS: 'Twój adres email (nie będzie widoczny)'
PERMISSIONFAILURE: 'Nie można dodać komentarza na tej stronie. Upewnij się, że jesteś zalogowany i masz odpowednie uprawnienia.'
RSSTITLE: 'Komentarze z RSS'
WEBSITEURL: 'Adres Twojej strony'
Comments:
COMMENTSREQUIRELOGIN: 'Zaloguj się aby dodać komentarz'
CommentsAdmin:
ApprovedComments: Zatwierdzone
Comments: Zatwierdzone
NeedsModeration: 'Wymagają moderacji'
NewComments: Nowe
SpamComments: Spam
CommentsExtension:
COMMENTOPTIONS: Komentarze
MODERATIONREQUIRED_NONE: 'Komentarze nie wymagają moderacji'
MODERATIONREQUIRED_NONMEMBERSONLY: 'Moderuj tylko niezarejestrowanych użytkowników'
MODERATIONREQUIRED_REQUIRED: 'Moderuj wszystkie komentarze'
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Twój komentarz został wysłany i czeka na akceptację przez moderatora.'
CommentsInterface_singlecomment_ss:
APPROVE: zatwierdź
ISNTSPAM: 'nie spam'
ISSPAM: 'oznacz spam'
PBY: 'Dodany przez'
REMCOM: odrzuć
CommentsInterface_ss:
AWAITINGMODERATION: 'Twój komentarz został wysłany i czeka na akceptację przez moderatora.'
COMMENTLOGINERROR: 'Nie można dodać komentarza dopóki nie będziesz zalogowany'
@ -76,5 +32,43 @@ pl_PL:
PREV: poprzedni
RSSFEEDALLCOMMENTS: 'Kanał RSS dla wszystkich komentarzy'
RSSFEEDCOMMENTS: 'Kanał RSS dla komentarzy na tej stronie'
PageCommentInterface:
DELETEALLCOMMENTS: 'Usuń wszystkie komentarze na tej stronie'
SilverStripe\Comments\Admin\CommentAdmin:
ADMIN_PERMISSION: 'Dostęp do sekcji "Komentarze"'
ApprovedComments: Zatwierdzone
Comments: Zatwierdzone
MENUTITLE: Komentarze
NewComments: Nowy
SpamComments: Spam
SilverStripe\Comments\Admin\CommentsGridFieldAction:
SPAM: Spam
SilverStripe\Comments\Admin\CommentsGridFieldConfig:
SPAM: Spam
SilverStripe\Comments\Admin\CommentsGridFieldSpamAction:
SPAM: Spam
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Komentarze
EMAILADDRESS: 'Twój adres email (nie będzie widoczny)'
PERMISSIONFAILURE: 'Nie można dodać komentarza na tej stronie. Upewnij się, że jesteś zalogowany i masz odpowednie uprawnienia.'
RSSTITLE: 'Komentarze z RSS'
WEBSITEURL: 'Adres Twojej strony'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Komentarze
COMMENTSTABSET: Komentarze
MODERATIONREQUIRED_NONE: 'Komentarze nie wymagają moderacji'
MODERATIONREQUIRED_NONMEMBERSONLY: 'Moderuj tylko niezarejestrowanych użytkowników'
MODERATIONREQUIRED_REQUIRED: 'Moderuj wszystkie komentarze'
SilverStripe\Comments\Model\Comment:
COMMENT: Komentarz
COMMENTBY: 'Komentarz %s'
CREATED: 'Data opublikowania'
EMAIL: Email
ISSPAM: 'Spam?'
MODERATED: 'Moderowane?'
'ON': na
OPTIONS: Opcje
OPTION_DESCRIPTION: 'Niemoderowane i oznaczone jako spam komentarze nie będą wyświetlane do momentu zatwierdzenia'
PARENTTITLE: Rodzic
PLURALNAME: Komentarze
ParentComment_Title: 'Ten komentarz jest odpowiedzią na komentarz poniżej'
SINGULARNAME: Komentarz
URL: URL

16
lang/pt.yml Normal file
View File

@ -0,0 +1,16 @@
pt:
CommentInterface:
PREVIEW: Pré-visualização
PREVIEWLABEL: Pré-visualização
CommentsInterface_ss:
COMMENTS: Comentários
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Comentários
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Comentários
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Comentários
COMMENTSTABSET: Comentários
SilverStripe\Comments\Model\Comment:
'ON': em
PLURALNAME: Comentários

15
lang/pt_PT.yml Normal file
View File

@ -0,0 +1,15 @@
pt_PT:
CommentsInterface_ss:
COMMENTS: Comentários
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Comentários
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Comentários
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Comentários
COMMENTSTABSET: Comentários
SilverStripe\Comments\Model\Comment:
EMAIL: Email
'ON': em
OPTIONS: Options
PLURALNAME: Comentários

View File

@ -1,21 +1,4 @@
ro:
Comment:
ALLOWCOMMENTS: 'Acceptare comentarii'
COMMENT: Comentariu
COMMENTBY: 'Comentat de %s'
CREATED: 'Data publicării'
EMAIL: E-mail
ISSPAM: 'Spam?'
MODERATED: 'Moderare?'
NAME: 'Nume autor'
PARENTTITLE: Părinte
PLURALNAME: Comentarii
SINGULARNAME: Comentariu
URL: URL
CommentAdmin:
MENUTITLE: Commentarii
Moderated: Moderat
NeedsModeration: 'Necesită moderare'
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Vă rugăm să introduceți un comentariu'
COMMENT_MESSAGE_URL: 'Vă rugăm să introduceți un URL valid'
@ -26,18 +9,8 @@ ro:
PREVIEWLABEL: 'Vizualizare înaintea publicării'
YOURNAME: 'Numele dvs.'
YOURNAME_MESSAGE_REQUIRED: 'Vă rugăm să vă introduceți numele'
CommentingController:
COMMENTS: Commentarii
EMAILADDRESS: 'Adresa dvs. de e-mail (nu va fi publicată)'
PERMISSIONFAILURE: 'Nu puteţi publica comentarii pe această pagină. Vă rugăm să vă asiguaţi că sunteți autentificat și că aveşi nivelul de permisiune corespunzător.'
RSSTITLE: 'RSS feed pentru comentarii'
WEBSITEURL: 'URL Site web'
CommentsAdmin:
NeedsModeration: 'Necesită moderare'
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Comentariul dvs. a fost trimis și așteaptă să fie moderat.'
CommentsInterface_singlecomment_ss:
PBY: 'Publicat de'
CommentsInterface_ss:
AWAITINGMODERATION: 'Comentariul dvs. a fost trimis și așteaptă să fie moderat.'
COMMENTLOGINERROR: 'Publicarea de comentarii necesită autentificare pe site'
@ -45,6 +18,7 @@ ro:
COMMENTPOSTLOGIN: Autentificare
COMMENTS: Comentarii
COMMENTSDISABLED: 'Postarea de comentarii a fost dezactivată'
DELETEALLCOMMENTS: 'Ştergeţi toate comentariile de pe această pagină'
LOGINTOPOSTCOMMENT: 'Autentificaţi-vă pentru a publica un comentariu'
NEXT: următorul
NOCOMMENTSYET: 'Nimeni nu a comentat încă pe aceasta pagină.'
@ -52,5 +26,26 @@ ro:
PREV: anteriorul
RSSFEEDALLCOMMENTS: 'RSS pentru toate comentariile'
RSSFEEDCOMMENTS: 'RSS pentru comentariile de pe această pagină'
PageCommentInterface:
DELETEALLCOMMENTS: 'Ştergeţi toate comentariile de pe această pagină'
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Commentarii
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Commentarii
EMAILADDRESS: 'Adresa dvs. de e-mail (nu va fi publicată)'
PERMISSIONFAILURE: 'Nu puteţi publica comentarii pe această pagină. Vă rugăm să vă asiguaţi că sunteți autentificat și că aveşi nivelul de permisiune corespunzător.'
RSSTITLE: 'RSS feed pentru comentarii'
WEBSITEURL: 'URL Site web'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Comentarii
COMMENTSTABSET: Comentarii
SilverStripe\Comments\Model\Comment:
COMMENT: Comentariu
COMMENTBY: 'Comentat de %s'
CREATED: 'Data publicării'
EMAIL: E-mail
ISSPAM: 'Spam?'
MODERATED: 'Moderare?'
'ON': pe
PARENTTITLE: Părinte
PLURALNAME: Comentarii
SINGULARNAME: Comentariu
URL: URL

View File

@ -1,30 +1,4 @@
ru:
Comment:
ALLOWCOMMENTS: 'Разрешить комментарии'
COMMENT: Комментарий
COMMENTBY: 'Комментарий автора %s'
CREATED: 'Дата добавления'
EMAIL: Email
ISSPAM: 'Спам?'
MODERATED: 'Проверено?'
NAME: Автор
'ON': на
OPTIONS: Опции
OPTION_DESCRIPTION: 'Комментарии не будут отображаться пока не будут одобрены модератором'
PARENTTITLE: 'Родительская'
PLURALNAME: Комментарии
ParentComment_Title: 'Этот комментарий ответ на сообщение ниже'
SINGULARNAME: Комментарий
URL: URL
CommentAdmin:
ADMIN_PERMISSION: 'Доступ к разделу ''Комментарии'''
ApprovedComments: Одобренные
Comments: Одобрен
MENUTITLE: Комментарии
Moderated: Проверен
NeedsModeration: 'Необходима Проверка'
NewComments: Новый
SpamComments: Спам
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Введите ваш комментарий'
COMMENT_MESSAGE_URL: 'Пожалуйста, задайте действительный URL-адрес'
@ -35,41 +9,16 @@ ru:
PREVIEWLABEL: Просмотр
YOURNAME: Имя
YOURNAME_MESSAGE_REQUIRED: 'Пожалуйста, укажите своё имя'
CommentingController:
COMMENTS: Комментарии
EMAILADDRESS: 'Ваш электронный адрес (не будет опубликован)'
PERMISSIONFAILURE: 'Вы не можете отправлять комментарии на эту страницу. Убедитесь что вы вошли в систему и имеете необходимые права доступа.'
RSSTITLE: 'RSS-лента комментариев'
WEBSITEURL: 'Адрес вашего сайта'
Comments:
COMMENTSREQUIRELOGIN: 'Необходимо войти в систему для комментирования'
CommentsAdmin:
ApprovedComments: Одобренные
Comments: Одобрен
NeedsModeration: 'Необходима Проверка'
NewComments: Новые
SpamComments: Спам
CommentsExtension:
COMMENTOPTIONS: Комментарии
MODERATIONREQUIRED_NONE: 'Проверка не требуется'
MODERATIONREQUIRED_NONMEMBERSONLY: 'Проверка требуется только для незарегистрированных пользователей'
MODERATIONREQUIRED_REQUIRED: 'Проверка требуется для всех комментариев'
CommentsGridFieldAction:
APPROVE: Одобрить
COMMENTAPPROVED: 'Комментарий одобрен.'
COMMENTMARKEDSPAM: 'Комментарий помечен как спам.'
SPAM: Спам
CommentsGridFieldConfig:
APPROVE: Одобрить
SPAM: Спам
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Ваш комментарий отправлен и ожидает проверки.'
CommentsInterface_singlecomment_ss:
APPROVE: Одобрить
ISNTSPAM: 'не спам'
ISSPAM: 'это спам'
PBY: 'Автор:'
REMCOM: удалить
REPLYTO: Ответить
CommentsInterface_ss:
AWAITINGMODERATION: 'Ваш комментарий отправлен и ожидает проверки.'
COMMENTLOGINERROR: 'Вы не можете отправлять комментарии пока не войдёте в систему'
@ -85,5 +34,51 @@ ru:
PREV: предыдущие
RSSFEEDALLCOMMENTS: 'RSS лента для всех комментариев'
RSSFEEDCOMMENTS: 'RSS лента для комментариев на этой странице'
PageCommentInterface:
DELETEALLCOMMENTS: 'Удалить все комментарии на этой странице'
SilverStripe\Comments\Admin\CommentAdmin:
ADMIN_PERMISSION: 'Доступ к разделу ''Комментарии'''
ApprovedComments: Одобренные
Comments: Одобрен
MENUTITLE: Комментарии
NewComments: Новый
SpamComments: Спам
SilverStripe\Comments\Admin\CommentsGridFieldAction:
APPROVE: Одобрить
COMMENTAPPROVED: 'Комментарий одобрен.'
COMMENTMARKEDSPAM: 'Комментарий помечен как спам.'
SPAM: Спам
SilverStripe\Comments\Admin\CommentsGridFieldApproveAction:
APPROVE: Одобрить
COMMENTAPPROVED: 'Комментарий одобрен.'
SilverStripe\Comments\Admin\CommentsGridFieldConfig:
APPROVE: Одобрить
SPAM: Спам
SilverStripe\Comments\Admin\CommentsGridFieldSpamAction:
COMMENTMARKEDSPAM: 'Комментарий помечен как спам.'
SPAM: Спам
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Комментарии
EMAILADDRESS: 'Ваш электронный адрес (не будет опубликован)'
PERMISSIONFAILURE: 'Вы не можете отправлять комментарии на эту страницу. Убедитесь что вы вошли в систему и имеете необходимые права доступа.'
RSSTITLE: 'RSS-лента комментариев'
WEBSITEURL: 'Адрес вашего сайта'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Комментарии
COMMENTSTABSET: Комментарии
MODERATIONREQUIRED_NONE: 'Проверка не требуется'
MODERATIONREQUIRED_NONMEMBERSONLY: 'Проверка требуется только для незарегистрированных пользователей'
MODERATIONREQUIRED_REQUIRED: 'Проверка требуется для всех комментариев'
SilverStripe\Comments\Model\Comment:
COMMENT: Комментарий
COMMENTBY: 'Комментарий автора %s'
CREATED: 'Дата добавления'
EMAIL: Email
ISSPAM: 'Спам?'
MODERATED: 'Проверено?'
'ON': на
OPTIONS: Опции
OPTION_DESCRIPTION: 'Комментарии не будут отображаться пока не будут одобрены модератором'
PARENTTITLE: Родительская
PLURALNAME: Комментарии
ParentComment_Title: 'Этот комментарий ответ на сообщение ниже'
SINGULARNAME: Комментарий
URL: URL

84
lang/sk.yml Normal file
View File

@ -0,0 +1,84 @@
sk:
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Prosím vložte komentár'
COMMENT_MESSAGE_URL: 'Prosím zadajte platnú URL adresu'
EMAILADDRESS_MESSAGE_EMAIL: 'Prosím zadajte platnú e-mailovú adresu'
EMAILADDRESS_MESSAGE_REQUIRED: 'Prosím zadajte váš e-mail'
POST: Odoslať
PREVIEW: Náhľad
PREVIEWLABEL: Náhľad
YOURNAME: 'Vaše meno'
YOURNAME_MESSAGE_REQUIRED: 'Vložte vaše meno'
Comments:
COMMENTSREQUIRELOGIN: 'Vyžadovať prihlásenie na pridávanie komentárov'
CommentsAdmin:
Comments: Schválené
NewComments: Nové
SpamComments: Spam
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Váš komentár bol odoslaný a čaká na kontrolu.'
CommentsInterface_singlecomment_ss:
REPLYTO: Odpovedať
CommentsInterface_ss:
AWAITINGMODERATION: 'Váš komentár bol odoslaný a čaká na kontrolu.'
COMMENTLOGINERROR: 'Nemôžete pridávať komentáre pokiaľ nie ste prihlásený'
COMMENTPERMISSIONERROR: 'a nemáte dostatočné oprávnenia'
COMMENTPOSTLOGIN: 'Prihlásiť sa'
COMMENTS: Komentáre
COMMENTSDISABLED: 'Už nie je možné pridávať nové komentáre'
DELETEALLCOMMENTS: 'Odstrániť všetky komentáre na tejto stránke'
LOGINTOPOSTCOMMENT: 'Pre komentovanie sa prihláste'
NEXT: nasledujúce
NOCOMMENTSYET: 'Táto stránka ešte nebola komentovaná.'
POSTCOM: 'Napíšte komentárPridať komentár'
PREV: predchádzajúce
RSSFEEDALLCOMMENTS: 'RSS kanál pre všetky komentáre'
RSSFEEDCOMMENTS: 'RSS kanál pre komentáre na tejto stránke'
SilverStripe\Comments\Admin\CommentAdmin:
ADMIN_PERMISSION: 'Prístup k sekcii ''Komentáre'''
ApprovedComments: Schválené
Comments: Schválené
MENUTITLE: Komentáre
NewComments: Nové
SpamComments: Spam
SilverStripe\Comments\Admin\CommentsGridFieldAction:
APPROVE: Schváliť
COMMENTAPPROVED: 'Komentár schválený.'
COMMENTMARKEDSPAM: 'Komentár označený ako spam.'
SPAM: Spam
SilverStripe\Comments\Admin\CommentsGridFieldApproveAction:
APPROVE: Schváliť
COMMENTAPPROVED: 'Komentár schválený.'
SilverStripe\Comments\Admin\CommentsGridFieldConfig:
APPROVE: Schváliť
SPAM: Spam
SilverStripe\Comments\Admin\CommentsGridFieldSpamAction:
COMMENTMARKEDSPAM: 'Komentár označený ako spam.'
SPAM: Spam
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Komentáre
EMAILADDRESS: 'Váš e-mail (nebude zverejnený)'
PERMISSIONFAILURE: 'Nemôžete písať komentáre k tejto stránke. Prosím skontrolujte či ste prihlásený, a že máte dostatočné oprávnenia.'
RSSTITLE: 'RSS feed komentárov'
WEBSITEURL: 'Vaša web stránka'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Komentáre
COMMENTSTABSET: Komentáre
MODERATIONREQUIRED_NONE: 'Nevyžadovať odsúhlasenie'
MODERATIONREQUIRED_NONMEMBERSONLY: 'Vyžadovať odsúhlasenie len od neprihlásených užívateľov'
MODERATIONREQUIRED_REQUIRED: 'Odsúhlasiť všetky komentáre'
SilverStripe\Comments\Model\Comment:
COMMENT: Komentár
COMMENTBY: 'Komentáre od %s'
CREATED: 'Dátum odoslania'
EMAIL: E-mail
ISSPAM: 'Spam?'
MODERATED: 'Odsúhlasený?'
'ON': na
OPTIONS: Možnosti
OPTION_DESCRIPTION: 'Neodsúhlasené a spamové komentáre nebudú zobrazené'
PARENTTITLE: 'Komentovaný príspevok'
PLURALNAME: Komentáre
ParentComment_Title: 'Tento komentár je odpoveď na komentár zobrazený nižšie'
SINGULARNAME: Komentár
URL: 'Web adresa'

View File

@ -1,37 +1,84 @@
sk_SK:
Comment:
ALLOWCOMMENTS: 'Povoliť komentáre'
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Prosím vložte komentár'
COMMENT_MESSAGE_URL: 'Prosím zadajte platnú URL adresu'
EMAILADDRESS_MESSAGE_EMAIL: 'Prosím zadajte platnú e-mailovú adresu'
EMAILADDRESS_MESSAGE_REQUIRED: 'Prosím zadajte váš e-mail'
POST: Odoslať
PREVIEW: Náhľad
PREVIEWLABEL: Náhľad
YOURNAME: 'Vaše meno'
YOURNAME_MESSAGE_REQUIRED: 'Vložte vaše meno'
Comments:
COMMENTSREQUIRELOGIN: 'Vyžadovať prihlásenie na pridávanie komentárov'
CommentsAdmin:
Comments: Schválené
NewComments: Nové
SpamComments: Spam
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Váš komentár bol odoslaný a čaká na kontrolu.'
CommentsInterface_singlecomment_ss:
REPLYTO: Odpovedať
CommentsInterface_ss:
AWAITINGMODERATION: 'Váš komentár bol odoslaný a čaká na kontrolu.'
COMMENTLOGINERROR: 'Nemôžete pridávať komentáre pokiaľ nie ste prihlásený'
COMMENTPERMISSIONERROR: 'a nemáte dostatočné oprávnenia'
COMMENTPOSTLOGIN: 'Prihlásiť sa'
COMMENTS: Komentáre
COMMENTSDISABLED: 'Už nie je možné pridávať nové komentáre'
DELETEALLCOMMENTS: 'Odstrániť všetky komentáre na tejto stránke'
LOGINTOPOSTCOMMENT: 'Prihláste sa, aby ste mohli písať komentáre'
NEXT: nasledujúce
NOCOMMENTSYET: 'Táto stránka ešte nebola komentovaná.'
POSTCOM: 'Napíšte komentár'
PREV: predchádzajúce
RSSFEEDALLCOMMENTS: 'RSS kanál pre všetky komentáre'
RSSFEEDCOMMENTS: 'RSS kanál pre komentáre na tejto stránke'
SilverStripe\Comments\Admin\CommentAdmin:
ADMIN_PERMISSION: 'Prístup k sekcii ''Komentáre'''
ApprovedComments: Schválené
Comments: Schválené
MENUTITLE: Komentáre
NewComments: Nové
SpamComments: Spam
SilverStripe\Comments\Admin\CommentsGridFieldAction:
APPROVE: Schváliť
COMMENTAPPROVED: 'Komentár schválený.'
COMMENTMARKEDSPAM: 'Komentár označený ako spam.'
SPAM: Spam
SilverStripe\Comments\Admin\CommentsGridFieldApproveAction:
APPROVE: Schváliť
COMMENTAPPROVED: 'Komentár schválený.'
SilverStripe\Comments\Admin\CommentsGridFieldConfig:
APPROVE: Schváliť
SPAM: Spam
SilverStripe\Comments\Admin\CommentsGridFieldSpamAction:
COMMENTMARKEDSPAM: 'Komentár označený ako spam.'
SPAM: Spam
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Komentáre
EMAILADDRESS: 'Váš e-mail (nebude zverejnený)'
PERMISSIONFAILURE: 'Nemôžete písať komentáre k tejto stránke. Prosím skontrolujte či ste prihlásený, a že máte dostatočné oprávnenia.'
RSSTITLE: 'RSS feed komentárov'
WEBSITEURL: 'Vaša web stránka'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Komentáre
COMMENTSTABSET: Komentáre
MODERATIONREQUIRED_NONE: 'Nevyžadovať odsúhlasenie'
MODERATIONREQUIRED_NONMEMBERSONLY: 'Vyžadovať odsúhlasenie len od neprihlásených užívateľov'
MODERATIONREQUIRED_REQUIRED: 'Odsúhlasiť všetky komentáre'
SilverStripe\Comments\Model\Comment:
COMMENT: Komentár
COMMENTBY: 'Komentáre od %s'
CREATED: 'Dátum zverejnenia'
EMAIL: E-mail
ISSPAM: 'Spam?'
MODERATED: 'Odsúhlasený?'
NAME: 'Meno autora'
'ON': na
OPTIONS: Možnosti
OPTION_DESCRIPTION: 'Neodsúhlasené a spamové komentáre nebudú zobrazené'
PARENTTITLE: Rodič
PLURALNAME: Komentáre
ParentComment_Title: 'Tento komentár je odpoveď na komentár zobrazený nižšie'
SINGULARNAME: Komentár
URL: 'Web adresa'
CommentAdmin:
MENUTITLE: Komentáre
Moderated: Odsúhlasený
NeedsModeration: 'Vyžaduje odsúhlasenie'
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Pridaj scoj komentár'
COMMENT_MESSAGE_URL: 'Vlož platbú adresu URL'
POST: Odoslať
PREVIEW: Náhľad
PREVIEWLABEL: Náhľad
YOURNAME: 'Vaše meno'
YOURNAME_MESSAGE_REQUIRED: 'Vlož svoje meno'
CommentingController:
COMMENTS: Komentáre
EMAILADDRESS: 'Váš e-mail (nebude zverejnený)'
RSSTITLE: 'RSS feed komentárov'
WEBSITEURL: 'Vaša web stránka'
CommentsAdmin:
NeedsModeration: 'Vyžaduje schválenie'
CommentsInterface_ss:
COMMENTLOGINERROR: 'Komentáre môže pridávať len prihlásený užívateľ'
COMMENTS: Komentáre
COMMENTSDISABLED: 'Už nie je možné pridávať nové komentáre'

17
lang/sl.yml Normal file
View File

@ -0,0 +1,17 @@
sl:
CommentInterface:
PREVIEW: Predogled
PREVIEWLABEL: Predogled
CommentsInterface_ss:
COMMENTS: Komentarji
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Komentarji
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Komentarji
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Komentarji
COMMENTSTABSET: Komentarji
SilverStripe\Comments\Model\Comment:
EMAIL: E-pošta
PLURALNAME: Komentarji
URL: URL

18
lang/sr.yml Normal file
View File

@ -0,0 +1,18 @@
sr:
CommentInterface:
PREVIEW: 'Претходни преглед'
PREVIEWLABEL: 'Претходни преглед'
CommentsInterface_ss:
COMMENTS: Коментари
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Коментари
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Коментари
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Коментари
COMMENTSTABSET: Коментари
SilverStripe\Comments\Model\Comment:
EMAIL: Е-пошта
'ON': у
PLURALNAME: Коментари
URL: URL

View File

@ -1,21 +1,4 @@
sr@latin:
Comment:
ALLOWCOMMENTS: 'Dozvoli komentare'
COMMENT: Komentar
COMMENTBY: 'Autor komentara %s'
CREATED: 'Datum objavljivanja'
EMAIL: 'Elektronska pošta'
ISSPAM: 'Zlonameran?'
MODERATED: 'Uređen?'
NAME: 'Ime autora'
PARENTTITLE: Roditelj
PLURALNAME: Komentari
SINGULARNAME: Komentar
URL: URL
CommentAdmin:
MENUTITLE: Komentari
Moderated: Uređen
NeedsModeration: 'Potrebno uređivanje'
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Molimo unesite komentar'
COMMENT_MESSAGE_URL: 'Molimo Vas da unesete ispravan URL'
@ -26,18 +9,8 @@ sr@latin:
PREVIEWLABEL: Prikaz
YOURNAME: 'Vaše ime'
YOURNAME_MESSAGE_REQUIRED: 'Molimo Vas da unesete Vaše ime'
CommentingController:
COMMENTS: Komentari
EMAILADDRESS: 'Vaša adresa elektronske pošte (neće biti objavljeno)'
PERMISSIONFAILURE: 'Niste u mogućnosti da objavljujete komentare na ovoj strani. Molimo Vas da proverite da li ste prijavljeni i da li imate odgovarajući nivo ovlašćenja.'
RSSTITLE: 'RSS Feed komentara'
WEBSITEURL: 'URL Vašeg sajta'
CommentsAdmin:
NeedsModeration: 'Potrebno uređivanje'
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Vaš komentar je prosleđen i sada čeka uređivanje.'
CommentsInterface_singlecomment_ss:
PBY: Objavio
CommentsInterface_ss:
AWAITINGMODERATION: 'Vaš komentar je prosleđen i sada čeka uređivanje.'
COMMENTLOGINERROR: 'Ne možete objavljivati komentare dok se ne prijavite'
@ -45,6 +18,7 @@ sr@latin:
COMMENTPOSTLOGIN: 'Prijavite se ovde'
COMMENTS: Komentari
COMMENTSDISABLED: 'Objavljivanje komentara je onemogućeno'
DELETEALLCOMMENTS: 'Obriši sve komentare na ovoj strani'
LOGINTOPOSTCOMMENT: 'Prijavite se da biste objavili komentar'
NEXT: sledeći
NOCOMMENTSYET: 'Niko još uvek nije objavio komentar na ovoj strani'
@ -52,5 +26,25 @@ sr@latin:
PREV: prethodni
RSSFEEDALLCOMMENTS: 'RSS feed za sve komentare'
RSSFEEDCOMMENTS: 'RSS feed za komentare na ovoj strani'
PageCommentInterface:
DELETEALLCOMMENTS: 'Obriši sve komentare na ovoj strani'
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Komentari
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Komentari
EMAILADDRESS: 'Vaša adresa elektronske pošte (neće biti objavljeno)'
PERMISSIONFAILURE: 'Niste u mogućnosti da objavljujete komentare na ovoj strani. Molimo Vas da proverite da li ste prijavljeni i da li imate odgovarajući nivo ovlašćenja.'
RSSTITLE: 'RSS Feed komentara'
WEBSITEURL: 'URL Vašeg sajta'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Komentari
COMMENTSTABSET: Komentari
SilverStripe\Comments\Model\Comment:
COMMENT: Komentar
COMMENTBY: 'Autor komentara %s'
CREATED: 'Datum objavljivanja'
EMAIL: 'Elektronska pošta'
ISSPAM: 'Zlonameran?'
MODERATED: 'Uređen?'
PARENTTITLE: Roditelj
PLURALNAME: Komentari
SINGULARNAME: Komentar
URL: URL

17
lang/sr_RS@latin.yml Normal file
View File

@ -0,0 +1,17 @@
sr_RS@latin:
CommentInterface:
PREVIEW: 'Prethodni pregled'
PREVIEWLABEL: 'Prethodni pregled'
CommentsInterface_ss:
COMMENTS: Komentari
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Komentari
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Komentari
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Komentari
COMMENTSTABSET: Komentari
SilverStripe\Comments\Model\Comment:
EMAIL: E-pošta
PLURALNAME: Komentari
URL: URL

View File

@ -1,21 +1,4 @@
sv:
Comment:
ALLOWCOMMENTS: 'Tillåt kommentarer'
COMMENT: Kommentarer
COMMENTBY: 'Kommentar av %s'
CREATED: Datum
EMAIL: E-post
ISSPAM: 'Spam?'
MODERATED: 'Modererad?'
NAME: Författare
PARENTTITLE: 'Överordnad sida'
PLURALNAME: Kommentarer
SINGULARNAME: Kommentar
URL: URL
CommentAdmin:
MENUTITLE: Kommentarer
Moderated: Modererad
NeedsModeration: 'Kräver moderering'
CommentInterface:
COMMENT_MESSAGE_REQUIRED: 'Var vänlig och skriv in din kommentar'
COMMENT_MESSAGE_URL: 'Var vänlig och ange en korrekt URL'
@ -26,18 +9,8 @@ sv:
PREVIEWLABEL: Förhandsgranska
YOURNAME: 'Ditt namn'
YOURNAME_MESSAGE_REQUIRED: 'Var vänlig och skriv in ditt namn'
CommentingController:
COMMENTS: Kommentarer
EMAILADDRESS: 'Din e-postadress (kommer inte att publiceras)'
PERMISSIONFAILURE: 'Du kan inte skriva kommentarer på denna sida. Vänligen kontrollera att du är inloggad och har de användarrättigheter som krävs.'
RSSTITLE: 'RSS-flöde med kommentarer'
WEBSITEURL: 'Din hemsidas URL'
CommentsAdmin:
NeedsModeration: 'Kräver moderering'
CommentsInterface_pendingcomment_ss:
AWAITINGMODERATION: 'Din kommentar har skickats och väntar nu på moderering'
CommentsInterface_singlecomment_ss:
PBY: 'Skriven av'
CommentsInterface_ss:
AWAITINGMODERATION: 'Din kommentar har skickats och väntar nu på moderering'
COMMENTLOGINERROR: 'Du måste logga in för att kunna skriva kommentarer'
@ -45,6 +18,7 @@ sv:
COMMENTPOSTLOGIN: 'Logga in'
COMMENTS: Kommentarer
COMMENTSDISABLED: 'Möjligheten att skriva kommentarer har spärrats'
DELETEALLCOMMENTS: 'Radera alla kommenterar på den här sidan'
LOGINTOPOSTCOMMENT: 'Logga in för att skriva en kommentar'
NEXT: nästa
NOCOMMENTSYET: 'Inga har kommenterat på denna sida ännu'
@ -52,5 +26,27 @@ sv:
PREV: föregående
RSSFEEDALLCOMMENTS: 'RSS-flöde för samtliga kommentarer'
RSSFEEDCOMMENTS: 'RSS-flöde för kommentarer på denna sida'
PageCommentInterface:
DELETEALLCOMMENTS: 'Radera alla kommenterar på den här sidan'
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Kommentarer
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Kommentarer
EMAILADDRESS: 'Din e-postadress (kommer inte att publiceras)'
PERMISSIONFAILURE: 'Du kan inte skriva kommentarer på denna sida. Vänligen kontrollera att du är inloggad och har de användarrättigheter som krävs.'
RSSTITLE: 'RSS-flöde med kommentarer'
WEBSITEURL: 'Din hemsidas URL'
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Kommentarer
COMMENTSTABSET: Kommentarer
SilverStripe\Comments\Model\Comment:
COMMENT: Kommentarer
COMMENTBY: 'Kommentar av %s'
CREATED: Datum
EMAIL: E-post
ISSPAM: 'Spam?'
MODERATED: 'Modererad?'
'ON': den
OPTIONS: Alternativ
PARENTTITLE: 'Överordnad sida'
PLURALNAME: Kommentarer
SINGULARNAME: Kommentar
URL: URL

16
lang/th.yml Normal file
View File

@ -0,0 +1,16 @@
th:
CommentInterface:
PREVIEW: ดูตัวอย่าง
PREVIEWLABEL: ดูตัวอย่าง
CommentsInterface_ss:
COMMENTS: ความคิดเห็น
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: ความคิดเห็น
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: ความคิดเห็น
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: ความคิดเห็น
COMMENTSTABSET: ความคิดเห็น
SilverStripe\Comments\Model\Comment:
EMAIL: อีเมล
PLURALNAME: ความคิดเห็น

17
lang/tr.yml Normal file
View File

@ -0,0 +1,17 @@
tr:
CommentInterface:
PREVIEW: Önizleme
PREVIEWLABEL: Önizleme
CommentsInterface_ss:
COMMENTS: Yorumlar
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: Yorumlar
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: Yorumlar
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: Yorumlar
COMMENTSTABSET: Yorumlar
SilverStripe\Comments\Model\Comment:
EMAIL: Eposta
'ON': üzerinde
PLURALNAME: Yorumlar

21
lang/zh.yml Normal file
View File

@ -0,0 +1,21 @@
zh:
CommentInterface:
PREVIEW: 预览
PREVIEWLABEL: 预览
CommentsInterface_ss:
COMMENTS: 评论
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: 评论
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: 评论
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: 评论
COMMENTSTABSET: 评论
SilverStripe\Comments\Model\Comment:
COMMENT: 评论
EMAIL: 电子邮件
OPTIONS: 选项
PARENTTITLE:
PLURALNAME: 评论
SINGULARNAME: 评论
URL: 网址

14
lang/zh_TW.yml Normal file
View File

@ -0,0 +1,14 @@
zh_TW:
CommentsInterface_ss:
COMMENTS: 意見
SilverStripe\Comments\Admin\CommentAdmin:
MENUTITLE: 意見
SilverStripe\Comments\Controllers\CommentingController:
COMMENTS: 意見
SilverStripe\Comments\Extensions\CommentsExtension:
COMMENTOPTIONS: 意見
COMMENTSTABSET: 意見
SilverStripe\Comments\Model\Comment:
EMAIL: 電子郵件
PLURALNAME: 意見
URL: 網址

62
package.json Normal file
View File

@ -0,0 +1,62 @@
{
"name": "silverstripe-comments",
"version": "1.0.0",
"description": "SilverStripe campaign admin interface",
"directories": {
"test": "tests"
},
"engines": {
"node": "^10.x"
},
"scripts": {
"build": "yarn && NODE_ENV=production webpack -p --bail --progress",
"watch": "yarn && NODE_ENV=development webpack --watch --progress",
"css": "yarn && WEBPACK_CHILD=css webpack -p --bail --progress",
"test": "true",
"coverage": "jest --coverage",
"lint": "eslint client/src && sass-lint -v client/src"
},
"repository": {
"type": "git",
"url": "git://github.com/silverstripe/silverstripe-comments.git"
},
"keywords": [
"silverstripe",
"admin"
],
"author": "SilverStripe Ltd",
"license": "BSD-3-Clause",
"bugs": {
"url": "https://github.com/silverstripe/silverstripe-comments/issues"
},
"homepage": "https://github.com/silverstripe/silverstripe-comments",
"dependencies": {
"jquery": "^3.6.0",
"jquery-validation": "^1.19.3"
},
"devDependencies": {
"@silverstripe/eslint-config": "^0.0.6",
"@silverstripe/webpack-config": "^1.3",
"babel-jest": "^19.0.0",
"babel-preset-es2015": "^6.6.0",
"babel-preset-es2016": "^6.24.1",
"babel-preset-react": "^6.5.0",
"copy-webpack-plugin": "^4",
"jest-cli": "^19.0.2",
"node-dir": "^0.1.17",
"react-addons-test-utils": "^15.3.1",
"redux-logger": "^2.6.1",
"redux-mock-store": "^1.2.3",
"redux-thunk": "^2.2.0"
},
"babel": {
"presets": [
"react",
"es2015",
"es2016"
],
"plugins": [
"transform-object-rest-spread"
]
}
}

13
phpcs.xml.dist Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="SilverStripe">
<description>CodeSniffer ruleset for SilverStripe coding conventions.</description>
<file>src</file>
<file>tests</file>
<!-- base rules are PSR-2 -->
<rule ref="PSR2" >
<!-- Current exclusions -->
<exclude name="PSR1.Methods.CamelCapsMethodName" />
</rule>
</ruleset>

16
phpunit.xml.dist Normal file
View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/silverstripe/cms/tests/bootstrap.php" colors="true">
<testsuites>
<testsuite name="Default">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src/</directory>
<exclude>
<directory suffix=".php">tests/</directory>
</exclude>
</whitelist>
</filter>
</phpunit>

View File

@ -1,5 +1,16 @@
<?php
namespace SilverStripe\Comments\Admin;
use SilverStripe\Admin\LeftAndMain;
use SilverStripe\Comments\Model\Comment;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\Tab;
use SilverStripe\Forms\TabSet;
use SilverStripe\Security\PermissionProvider;
use SilverStripe\Security\Security;
/**
* Comment administration system within the CMS
*
@ -7,14 +18,15 @@
*/
class CommentAdmin extends LeftAndMain implements PermissionProvider
{
private static $url_segment = 'comments';
private static $url_rule = '/$Action';
private static $menu_title = 'Comments';
private static $allowed_actions = array(
private static $menu_icon_class = 'font-icon-comment';
private static $allowed_actions = [
'approvedmarked',
'deleteall',
'deletemarked',
@ -23,16 +35,18 @@ class CommentAdmin extends LeftAndMain implements PermissionProvider
'spammarked',
'EditForm',
'unmoderated'
);
];
private static $required_permission_codes = 'CMS_ACCESS_CommentAdmin';
public function providePermissions()
{
return array(
"CMS_ACCESS_CommentAdmin" => array(
'name' => _t('CommentAdmin.ADMIN_PERMISSION', "Access to 'Comments' section"),
'category' => _t('Permission.CMS_ACCESS_CATEGORY', 'CMS Access')
)
);
return [
'CMS_ACCESS_CommentAdmin' => [
'name' => _t(__CLASS__ . '.ADMIN_PERMISSION', "Access to 'Comments' section"),
'category' => _t('SilverStripe\\Security\\Permission.CMS_ACCESS_CATEGORY', 'CMS Access')
],
];
}
/**
@ -53,66 +67,78 @@ class CommentAdmin extends LeftAndMain implements PermissionProvider
$newComments = Comment::get()->filter('Moderated', 0);
$newGrid = new CommentsGridField(
$newGrid = CommentsGridField::create(
'NewComments',
_t('CommentsAdmin.NewComments', 'New'),
'',
$newComments,
CommentsGridFieldConfig::create()
);
$approvedComments = Comment::get()->filter('Moderated', 1)->filter('IsSpam', 0);
$approvedGrid = new CommentsGridField(
$approvedGrid = CommentsGridField::create(
'ApprovedComments',
_t('CommentsAdmin.ApprovedComments', 'Approved'),
'',
$approvedComments,
CommentsGridFieldConfig::create()
);
$spamComments = Comment::get()->filter('Moderated', 1)->filter('IsSpam', 1);
$spamGrid = new CommentsGridField(
$spamGrid = CommentsGridField::create(
'SpamComments',
_t('CommentsAdmin.SpamComments', 'Spam'),
'',
$spamComments,
CommentsGridFieldConfig::create()
);
$newCount = '(' . count($newComments) . ')';
$approvedCount = '(' . count($approvedComments) . ')';
$spamCount = '(' . count($spamComments) . ')';
$fields = new FieldList(
$root = new TabSet(
$fields = FieldList::create(
$root = TabSet::create(
'Root',
new Tab('NewComments', _t('CommentAdmin.NewComments', 'New') . ' ' . $newCount,
Tab::create(
'NewComments',
_t(
__CLASS__.'.NewComments',
'New ({count})',
['count' => count($newComments ?? [])]
),
$newGrid
),
new Tab('ApprovedComments', _t('CommentAdmin.ApprovedComments', 'Approved') . ' ' . $approvedCount,
Tab::create(
'ApprovedComments',
_t(
__CLASS__.'.ApprovedComments',
'Approved ({count})',
['count' => count($approvedComments ?? [])]
),
$approvedGrid
),
new Tab('SpamComments', _t('CommentAdmin.SpamComments', 'Spam') . ' ' . $spamCount,
Tab::create(
'SpamComments',
_t(
__CLASS__.'.SpamComments',
'Spam ({count})',
['count' => count($spamComments ?? [])]
),
$spamGrid
)
)
);
$root->setTemplate('CMSTabSet');
$actions = FieldList::create();
$actions = new FieldList();
$form = new Form(
$form = Form::create(
$this,
'EditForm',
$fields,
$actions
);
$form->addExtraClass('cms-edit-form');
$form->addExtraClass('cms-edit-form fill-height');
$form->setTemplate($this->getTemplatesWithSuffix('_EditForm'));
if ($form->Fields()->hasTabset()) {
$form->Fields()->findOrMakeTab('Root')->setTemplate('CMSTabSet');
$form->Fields()->findOrMakeTab('Root')->setTemplate('SilverStripe\\Forms\\CMSTabSet');
$form->addExtraClass('center ss-tabset cms-tabset ' . $this->BaseCSSClasses());
}

View File

@ -0,0 +1,44 @@
<?php
namespace SilverStripe\Comments\Admin;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig;
use SilverStripe\ORM\SS_List;
use SilverStripe\View\HTML;
class CommentsGridField extends GridField
{
/**
* @param string $name
* @param string $title
* @param SS_List $dataList
* @param GridFieldConfig $config
*/
public function __construct($name, $title = null, SS_List $dataList = null, GridFieldConfig $config = null)
{
parent::__construct($name, $title, $dataList, $config);
$this->addExtraClass('grid-field__filter-buttons');
}
/**
* {@inheritdoc}
*/
protected function newRow($total, $index, $record, $attributes, $content)
{
if (!isset($attributes['class'])) {
$attributes['class'] = '';
}
if ($record->IsSpam) {
$attributes['class'] .= ' spam';
}
return HTML::createTag(
'tr',
$attributes,
$content
);
}
}

View File

@ -1,13 +1,35 @@
<?php
namespace SilverStripe\Comments\Admin;
use SilverStripe\Dev\Deprecation;
use SilverStripe\Comments\Model\Comment;
use SilverStripe\Control\Controller;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridField_ActionProvider;
use SilverStripe\Forms\GridField\GridField_ColumnProvider;
use SilverStripe\Forms\GridField\GridField_FormAction;
/**
* @deprecated 3.2.0 Use CommentsGridFieldApproveAction CommentsGridFieldSpamAction instead
*/
class CommentsGridFieldAction implements GridField_ColumnProvider, GridField_ActionProvider
{
/**
* {@inheritdoc}
*/
public function __construct()
{
Deprecation::notice(
'3.2.0',
'Use CommentsGridFieldApproveAction CommentsGridFieldSpamAction instead',
Deprecation::SCOPE_CLASS
);
}
public function augmentColumns($gridField, &$columns)
{
if (!in_array('Actions', $columns)) {
if (!in_array('Actions', $columns ?? [])) {
$columns[] = 'Actions';
}
}
@ -17,7 +39,7 @@ class CommentsGridFieldAction implements GridField_ColumnProvider, GridField_Act
*/
public function getColumnAttributes($gridField, $record, $columnName)
{
return array('class' => 'col-buttons');
return ['class' => 'col-buttons'];
}
/**
@ -25,8 +47,8 @@ class CommentsGridFieldAction implements GridField_ColumnProvider, GridField_Act
*/
public function getColumnMetadata($gridField, $columnName)
{
if ($columnName == 'Actions') {
return array('title' => '');
if ($columnName === 'Actions') {
return ['title' => ''];
}
}
@ -35,7 +57,7 @@ class CommentsGridFieldAction implements GridField_ColumnProvider, GridField_Act
*/
public function getColumnsHandled($gridField)
{
return array('Actions');
return ['Actions'];
}
/**
@ -47,26 +69,30 @@ class CommentsGridFieldAction implements GridField_ColumnProvider, GridField_Act
return;
}
$field = "";
$field = '';
if (!$record->IsSpam || !$record->Moderated) {
$field .= GridField_FormAction::create(
$gridField,
'CustomAction' . $record->ID . 'Spam',
_t('CommentsGridFieldAction.SPAM', 'Spam'),
_t(__CLASS__ . '.SPAM', 'Spam'),
'spam',
array('RecordID' => $record->ID)
)->Field();
['RecordID' => $record->ID]
)
->addExtraClass('btn btn-secondary grid-field__icon-action')
->Field();
}
if ($record->IsSpam || !$record->Moderated) {
$field .= GridField_FormAction::create(
$gridField,
'CustomAction' . $record->ID . 'Approve',
_t('CommentsGridFieldAction.APPROVE', 'Approve'),
_t(__CLASS__ . '.APPROVE', 'Approve'),
'approve',
array('RecordID' => $record->ID)
)->Field();
['RecordID' => $record->ID]
)
->addExtraClass('btn btn-secondary grid-field__icon-action')
->Field();
}
return $field;
@ -77,7 +103,7 @@ class CommentsGridFieldAction implements GridField_ColumnProvider, GridField_Act
*/
public function getActions($gridField)
{
return array('spam', 'approve');
return ['spam', 'approve'];
}
/**
@ -85,25 +111,27 @@ class CommentsGridFieldAction implements GridField_ColumnProvider, GridField_Act
*/
public function handleAction(GridField $gridField, $actionName, $arguments, $data)
{
if ($actionName == 'spam') {
$comment = Comment::get()->byID($arguments["RecordID"]);
if ($actionName === 'spam') {
/** @var Comment $comment */
$comment = Comment::get()->byID($arguments['RecordID']);
$comment->markSpam();
// output a success message to the user
Controller::curr()->getResponse()->setStatusCode(
200,
_t('CommentsGridFieldAction.COMMENTMARKEDSPAM', 'Comment marked as spam.')
_t(__CLASS__ . '.COMMENTMARKEDSPAM', 'Comment marked as spam.')
);
}
if ($actionName == 'approve') {
$comment = Comment::get()->byID($arguments["RecordID"]);
if ($actionName === 'approve') {
/** @var Comment $comment */
$comment = Comment::get()->byID($arguments['RecordID']);
$comment->markApproved();
// output a success message to the user
Controller::curr()->getResponse()->setStatusCode(
200,
_t('CommentsGridFieldAction.COMMENTAPPROVED', 'Comment approved.')
_t(__CLASS__ . '.COMMENTAPPROVED', 'Comment approved.')
);
}
}

View File

@ -0,0 +1,140 @@
<?php
namespace SilverStripe\Comments\Admin;
use SilverStripe\Comments\Model\Comment;
use SilverStripe\Control\Controller;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridField_ActionMenuItem;
use SilverStripe\Forms\GridField\GridField_ActionProvider;
use SilverStripe\Forms\GridField\GridField_ColumnProvider;
use SilverStripe\Forms\GridField\GridField_FormAction;
class CommentsGridFieldApproveAction implements
GridField_ColumnProvider,
GridField_ActionProvider,
GridField_ActionMenuItem
{
/**
* {@inheritdoc}
*/
public function augmentColumns($gridField, &$columns)
{
if (!in_array('Actions', $columns ?? [])) {
$columns[] = 'Actions';
}
}
public function getTitle($gridField, $record, $columnName)
{
return _t(__CLASS__ . '.APPROVE', 'Approve');
}
public function getExtraData($gridField, $record, $columnName)
{
$field = $this->getApproveAction($gridField, $record, $columnName);
if ($field) {
return $field->getAttributes();
}
return null;
}
public function getGroup($gridField, $record, $columnName)
{
$field = $this->getApproveAction($gridField, $record, $columnName);
return $field ? GridField_ActionMenuItem::DEFAULT_GROUP: null;
}
/**
* {@inheritdoc}
*/
public function getColumnAttributes($gridField, $record, $columnName)
{
return ['class' => 'col-buttons grid-field__col-compact'];
}
/**
* {@inheritdoc}
*/
public function getColumnMetadata($gridField, $columnName)
{
if ($columnName === 'Actions') {
return ['title' => ''];
}
}
/**
* {@inheritdoc}
*/
public function getColumnsHandled($gridField)
{
return ['Actions'];
}
/**
* {@inheritdoc}
*/
public function getColumnContent($gridField, $record, $columnName)
{
if (!$record->canEdit()) {
return;
}
$field = $this->getApproveAction($gridField, $record, $columnName);
return $field ? $field->Field() : null;
}
/**
* Returns the FormAction object, used by other methods to get properties
*
* @return GridField_FormAction|null
*/
public function getApproveAction($gridField, $record, $columnName)
{
$field = GridField_FormAction::create(
$gridField,
'CustomAction' . $record->ID . 'Approve',
_t(__CLASS__ . '.APPROVE', 'Approve'),
'approve',
['RecordID' => $record->ID]
)
->addExtraClass(implode(' ', [
'btn',
'btn-secondary',
'grid-field__icon-action',
'action-menu--handled',
'font-icon-check-mark',
]))
->setAttribute('classNames', 'font-icon-check-mark');
return ($record->IsSpam || !$record->Moderated) ? $field : null;
}
/**
* {@inheritdoc}
*/
public function getActions($gridField)
{
return ['approve'];
}
/**
* {@inheritdoc}
*/
public function handleAction(GridField $gridField, $actionName, $arguments, $data)
{
/** @var Comment $comment */
$comment = Comment::get()->byID($arguments['RecordID']);
$comment->markApproved();
// output a success message to the user
Controller::curr()->getResponse()->setStatusCode(
200,
_t(__CLASS__ . '.COMMENTAPPROVED', 'Comment approved.')
);
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace SilverStripe\Comments\Admin\CommentsGridFieldBulkAction;
use SilverStripe\Comments\Model\Comment;
/**
* A {@link Handler} for bulk approving comments
*/
class ApproveHandler extends CommentHandler
{
private static $url_segment = 'approve';
protected $buttonClasses = 'font-icon-tick';
protected $label = 'Approve';
/**
* @param Comment $comment
*
* @return Comment
*/
public function updateComment($comment)
{
$comment->markApproved();
return $comment;
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace SilverStripe\Comments\Admin\CommentsGridFieldBulkAction;
use Colymba\BulkManager\BulkAction\Handler;
use Colymba\BulkTools\HTTPBulkToolsResponse;
use SilverStripe\Comments\Model\Comment;
use SilverStripe\Core\Convert;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse;
abstract class CommentHandler extends Handler
{
protected $xhr = true;
protected $destructive = false;
/**
* @param HTTPRequest $request
* @return HTTPResponse
*/
public function index(HTTPRequest $request)
{
$ids = [];
$response = new HTTPBulkToolsResponse(
true,
$this->gridField,
200
);
foreach ($this->getRecords() as $comment) {
array_push($ids, $comment->ID);
$this->updateComment($comment);
$response->addSuccessRecord($comment);
}
$response->setMessage(_t(__CLASS__ . '.CHANGES_APPLIED', 'Changes applied'));
return $response;
}
/**
* @param Comment $comment
*
* @return Comment
*/
abstract public function updateComment($comment);
}

View File

@ -1,20 +1,20 @@
<?php
/**
* @package comments
*/
class CommentsGridFieldBulkAction extends GridFieldBulkActionHandler
{
}
namespace SilverStripe\Comments\Admin\CommentsGridFieldBulkAction;
use SilverStripe\Dev\Deprecation;
use Colymba\BulkManager\BulkAction\Handler as GridFieldBulkActionHandler;
use SilverStripe\Core\Convert;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse;
/**
* A {@link GridFieldBulkActionHandler} for bulk marking comments as spam
*
* @package comments
* @deprecated 3.1.0 Use concrete Spam or Approve handlers instead
*/
class CommentsGridFieldBulkAction_Handlers extends CommentsGridFieldBulkAction
class Handler extends GridFieldBulkActionHandler
{
private static $allowed_actions = array(
'spam',
'approve',
@ -25,8 +25,16 @@ class CommentsGridFieldBulkAction_Handlers extends CommentsGridFieldBulkAction
'approve' => 'approve',
);
/**
* @param HTTPRequest $request
* @return HTTPResponse
*/
public function __construct()
{
Deprecation::notice('3.1.0', 'Use concrete Spam or Approve handlers instead', Deprecation::SCOPE_CLASS);
}
public function spam(SS_HTTPRequest $request)
public function spam(HTTPRequest $request)
{
$ids = array();
@ -35,7 +43,7 @@ class CommentsGridFieldBulkAction_Handlers extends CommentsGridFieldBulkAction
$record->markSpam();
}
$response = new SS_HTTPResponse(Convert::raw2json(array(
$response = new HTTPResponse(json_encode(array(
'done' => true,
'records' => $ids
)));
@ -45,8 +53,11 @@ class CommentsGridFieldBulkAction_Handlers extends CommentsGridFieldBulkAction
return $response;
}
public function approve(SS_HTTPRequest $request)
/**
* @param HTTPRequest $request
* @return HTTPResponse
*/
public function approve(HTTPRequest $request)
{
$ids = array();
@ -55,7 +66,7 @@ class CommentsGridFieldBulkAction_Handlers extends CommentsGridFieldBulkAction
$record->markApproved();
}
$response = new SS_HTTPResponse(Convert::raw2json(array(
$response = new HTTPResponse(json_encode(array(
'done' => true,
'records' => $ids
)));

View File

@ -0,0 +1,28 @@
<?php
namespace SilverStripe\Comments\Admin\CommentsGridFieldBulkAction;
use SilverStripe\Comments\Model\Comment;
/**
* A {@link Handler} for bulk marking comments as spam
*/
class SpamHandler extends CommentHandler
{
private static $url_segment = 'spam';
protected $buttonClasses = 'font-icon-cross-mark';
protected $label = 'Spam';
/**
* @param Comment $comment
*
* @return Comment
*/
public function updateComment($comment)
{
$comment->markSpam();
return $comment;
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace SilverStripe\Comments\Admin;
use Colymba\BulkManager\BulkManager;
use SilverStripe\Comments\Admin\CommentsGridFieldBulkAction\ApproveHandler;
use SilverStripe\Comments\Admin\CommentsGridFieldBulkAction\SpamHandler;
use SilverStripe\Core\Convert;
use SilverStripe\Forms\GridField\GridField_ActionMenu;
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
use SilverStripe\Forms\GridField\GridFieldDataColumns;
class CommentsGridFieldConfig extends GridFieldConfig_RecordEditor
{
public function __construct($itemsPerPage = 25)
{
parent::__construct($itemsPerPage);
// $this->addComponent(new GridFieldExportButton());
$this->addComponents([
new CommentsGridFieldSpamAction(),
new CommentsGridFieldApproveAction(),
]);
// Format column
/** @var GridFieldDataColumns $columns */
$columns = $this->getComponentByType(GridFieldDataColumns::class);
$columns->setFieldFormatting([
'Parent.Title' => function ($value, &$item) {
if ($link = $item->Link()) {
return sprintf(
'<a href="%s" class="cms-panel-link external-link action" target="_blank">%s</a>',
Convert::raw2att($link),
$item->obj('ParentTitle')->forTemplate()
);
} else {
return $item->obj('ParentTitle')->forTemplate();
}
}
]);
// Add bulk option
$manager = BulkManager::create(null, false);
$spamAction = SpamHandler::create()->setLabel(_t(__CLASS__ . '.SPAM', 'Spam'));
$approveAction = ApproveHandler::create()->setLabel(_t(__CLASS__ . '.APPROVE', 'Approve'));
$manager
->addBulkAction($spamAction)
->addBulkAction($approveAction);
$this->addComponent($manager);
}
}

View File

@ -0,0 +1,141 @@
<?php
namespace SilverStripe\Comments\Admin;
use SilverStripe\Comments\Model\Comment;
use SilverStripe\Control\Controller;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridField_ActionMenuItem;
use SilverStripe\Forms\GridField\GridField_ActionProvider;
use SilverStripe\Forms\GridField\GridField_ColumnProvider;
use SilverStripe\Forms\GridField\GridField_FormAction;
class CommentsGridFieldSpamAction implements
GridField_ColumnProvider,
GridField_ActionProvider,
GridField_ActionMenuItem
{
/**
* {@inheritdoc}
*/
public function augmentColumns($gridField, &$columns)
{
if (!in_array('Actions', $columns ?? [])) {
$columns[] = 'Actions';
}
}
public function getTitle($gridField, $record, $columnName)
{
return _t(__CLASS__ . '.SPAM', 'Spam');
}
public function getExtraData($gridField, $record, $columnName)
{
$field = $this->getSpamAction($gridField, $record, $columnName);
if ($field) {
return $field->getAttributes();
}
return null;
}
public function getGroup($gridField, $record, $columnName)
{
$field = $this->getSpamAction($gridField, $record, $columnName);
return $field ? GridField_ActionMenuItem::DEFAULT_GROUP: null;
}
/**
* {@inheritdoc}
*/
public function getColumnAttributes($gridField, $record, $columnName)
{
return ['class' => 'col-buttons grid-field__col-compact'];
}
/**
* {@inheritdoc}
*/
public function getColumnMetadata($gridField, $columnName)
{
if ($columnName === 'Actions') {
return ['title' => ''];
}
}
/**
* {@inheritdoc}
*/
public function getColumnsHandled($gridField)
{
return ['Actions'];
}
/**
* {@inheritdoc}
*/
public function getColumnContent($gridField, $record, $columnName)
{
if (!$record->canEdit()) {
return;
}
$field = $this->getSpamAction($gridField, $record, $columnName);
return $field ? $field->Field() : null;
}
/**
* Returns the FormAction object, used by other methods to get properties
*
* @return GridField_FormAction|null
*/
public function getSpamAction($gridField, $record, $columnName)
{
$field = GridField_FormAction::create(
$gridField,
'CustomAction' . $record->ID . 'Spam',
_t(__CLASS__ . '.SPAM', 'Spam'),
'spam',
['RecordID' => $record->ID]
)
->addExtraClass(implode(' ', [
'btn',
'btn-secondary',
'grid-field__icon-action',
'action-menu--handled',
'font-icon-cross-mark',
]))
->setAttribute('classNames', 'font-icon-cross-mark');
return (!$record->IsSpam || !$record->Moderated) ? $field : null;
}
/**
* {@inheritdoc}
*/
public function getActions($gridField)
{
return ['spam'];
}
/**
* {@inheritdoc}
*/
public function handleAction(GridField $gridField, $actionName, $arguments, $data)
{
/** @var Comment $comment */
$comment = Comment::get()->byID($arguments['RecordID']);
$comment->markSpam();
// output a success message to the user
Controller::curr()->getResponse()->setStatusCode(
200,
_t(__CLASS__ . '.COMMENTMARKEDSPAM', 'Comment marked as spam.')
);
}
}

View File

@ -0,0 +1,534 @@
<?php
namespace SilverStripe\Comments\Controllers;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Comments\Extensions\CommentsExtension;
use SilverStripe\Comments\Forms\CommentForm;
use SilverStripe\Comments\Model\Comment;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Director;
use SilverStripe\Control\HTTP;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse;
use SilverStripe\Control\HTTPResponse_Exception;
use SilverStripe\Control\RSS\RSSFeed;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forms\Form;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\FieldType\DBHTMLText;
use SilverStripe\ORM\PaginatedList;
use SilverStripe\Security\Security;
use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware;
/**
* @package comments
*/
class CommentingController extends Controller
{
/**
* {@inheritDoc}
*/
private static $allowed_actions = [
'delete',
'spam',
'ham',
'approve',
'rss',
'CommentsForm',
'reply',
'doPostComment',
'doPreviewComment',
];
/**
* {@inheritDoc}
*/
private static $url_handlers = [
'reply/$ParentCommentID//$ID/$OtherID' => 'reply',
];
/**
* Fields required for this form
*
* @var array
* @config
*/
private static $required_fields = [
'Name',
'Email',
'Comment',
];
/**
* Parent class this commenting form is for
*
* @var string
*/
private $parentClass = '';
/**
* The record this commenting form is for
*
* @var DataObject
*/
private $ownerRecord;
/**
* Parent controller record
*
* @var Controller
*/
private $ownerController;
/**
* Backup url to return to
*
* @var string
*/
protected $fallbackReturnURL;
/**
* Set the parent class name to use
*
* @param string $class
*/
public function setParentClass($class)
{
$this->parentClass = $this->encodeClassName($class);
}
/**
* Get the parent class name used
*
* @return string
*/
public function getParentClass()
{
return $this->decodeClassName($this->parentClass);
}
/**
* Encode a fully qualified class name to a URL-safe version
*
* @param string $input
* @return string
*/
public function encodeClassName($input)
{
return str_replace('\\', '-', $input ?? '');
}
/**
* Decode an "encoded" fully qualified class name back to its original
*
* @param string $input
* @return string
*/
public function decodeClassName($input)
{
return str_replace('-', '\\', $input ?? '');
}
/**
* Set the record this controller is working on
*
* @param DataObject $record
*/
public function setOwnerRecord($record)
{
$this->ownerRecord = $record;
}
/**
* Get the record
*
* @return DataObject
*/
public function getOwnerRecord()
{
return $this->ownerRecord;
}
/**
* Set the parent controller
*
* @param Controller $controller
*/
public function setOwnerController($controller)
{
$this->ownerController = $controller;
}
/**
* Get the parent controller
*
* @return Controller
*/
public function getOwnerController()
{
return $this->ownerController;
}
/**
* Get the commenting option for the current state
*
* @param string $key
* @return mixed Result if the setting is available, or null otherwise
*/
public function getOption($key)
{
// If possible use the current record
if ($record = $this->getOwnerRecord()) {
/** @var DataObject|CommentsExtension $record */
return $record->getCommentsOption($key);
}
// Otherwise a singleton of that record
if ($class = $this->getParentClass()) {
return singleton($class)->getCommentsOption($key);
}
// Otherwise just use the default options
return singleton(CommentsExtension::class)->getCommentsOption($key);
}
/**
* Returns all the commenting options for the current instance.
*
* @return array
*/
public function getOptions()
{
if ($record = $this->getOwnerRecord()) {
/** @var DataObject|CommentsExtension $record */
return $record->getCommentsOptions();
}
// Otherwise a singleton of that record
if ($class = $this->getParentClass()) {
return singleton($class)->getCommentsOptions();
}
// Otherwise just use the default options
return singleton(CommentsExtension::class)->getCommentsOptions();
}
/**
* Workaround for generating the link to this controller
*
* @param string $action
* @param int $id
* @param string $other
* @return string
*/
public function Link($action = '', $id = '', $other = '')
{
return Controller::join_links(Director::baseURL(), 'comments', $action, $id, $other);
}
/**
* Outputs the RSS feed of comments
*
* @return DBHTMLText
*/
public function rss()
{
return $this->getFeed($this->request)->outputToBrowser();
}
/**
* Return an RSSFeed of comments for a given set of comments or all
* comments on the website.
*
* @param HTTPRequest
*
* @return RSSFeed
*/
public function getFeed(HTTPRequest $request)
{
$link = $this->Link('rss');
$class = $this->decodeClassName($request->param('ID'));
$id = $request->param('OtherID');
// Support old pageid param
if (!$id && !$class && ($id = $request->getVar('pageid'))) {
$class = SiteTree::class;
}
$comments = Comment::get()->filter([
'Moderated' => 1,
'IsSpam' => 0,
]);
// Check if class filter
if ($class) {
if (!is_subclass_of($class, DataObject::class) || !$class::has_extension(CommentsExtension::class)) {
return $this->httpError(404);
}
$this->setParentClass($class);
$comments = $comments->filter('ParentClass', $class);
$link = Controller::join_links($link, $this->encodeClassName($class));
// Check if id filter
if ($id) {
$comments = $comments->filter('ParentID', $id);
$link = Controller::join_links($link, $id);
$this->setOwnerRecord(DataObject::get_by_id($class, $id));
}
}
$title = _t(__CLASS__ . '.RSSTITLE', "Comments RSS Feed");
$comments = PaginatedList::create($comments, $request);
$comments->setPageLength($this->getOption('comments_per_page'));
return RSSFeed::create(
$comments,
$link,
$title,
$link,
'Title',
'EscapedComment',
'AuthorName'
);
}
/**
* Deletes a given {@link Comment} via the URL.
*/
public function delete()
{
$comment = $this->getComment();
if (!$comment) {
return $this->httpError(404);
}
if (!$comment->canDelete()) {
return Security::permissionFailure($this, 'You do not have permission to delete this comment');
}
if (!$comment->getSecurityToken()->checkRequest($this->request)) {
return $this->httpError(400);
}
$comment->delete();
return $this->request->isAjax()
? true
: $this->redirectBack();
}
/**
* Marks a given {@link Comment} as spam. Removes the comment from display
*/
public function spam()
{
$comment = $this->getComment();
if (!$comment) {
return $this->httpError(404);
}
if (!$comment->canEdit()) {
return Security::permissionFailure($this, 'You do not have permission to edit this comment');
}
if (!$comment->getSecurityToken()->checkRequest($this->request)) {
return $this->httpError(400);
}
$comment->markSpam();
return $this->renderChangedCommentState($comment);
}
/**
* Marks a given {@link Comment} as ham (not spam).
*/
public function ham()
{
$comment = $this->getComment();
if (!$comment) {
return $this->httpError(404);
}
if (!$comment->canEdit()) {
return Security::permissionFailure($this, 'You do not have permission to edit this comment');
}
if (!$comment->getSecurityToken()->checkRequest($this->request)) {
return $this->httpError(400);
}
$comment->markApproved();
return $this->renderChangedCommentState($comment);
}
/**
* Marks a given {@link Comment} as approved.
*/
public function approve()
{
$comment = $this->getComment();
if (!$comment) {
return $this->httpError(404);
}
if (!$comment->canEdit()) {
return Security::permissionFailure($this, 'You do not have permission to approve this comment');
}
if (!$comment->getSecurityToken()->checkRequest($this->request)) {
return $this->httpError(400);
}
$comment->markApproved();
return $this->renderChangedCommentState($comment);
}
/**
* Redirect back to referer if available, ensuring that only site URLs
* are allowed to avoid phishing. If it's an AJAX request render the
* comment in it's new state
*
* @param Comment $comment
* @return DBHTMLText|HTTPResponse|false
*/
private function renderChangedCommentState($comment)
{
$referer = $this->request->getHeader('Referer');
// Render comment using AJAX
if ($this->request->isAjax()) {
return $comment->renderWith('Includes/CommentsInterface_singlecomment');
}
// Redirect to either the comment or start of the page
if (empty($referer)) {
return $this->redirectBack();
}
// Redirect to the comment, but check for phishing
$url = $referer . '#comment-' . $comment->ID;
// absolute redirection URLs not located on this site may cause phishing
if (Director::is_site_url($url)) {
return $this->redirect($url);
}
return false;
}
/**
* Returns the comment referenced in the URL (by ID). Permission checking
* should be done in the callee.
*
* @return Comment|false
*/
public function getComment()
{
$id = isset($this->urlParams['ID']) ? $this->urlParams['ID'] : false;
if ($id) {
/** @var Comment $comment */
$comment = Comment::get()->byId($id);
if ($comment) {
$this->fallbackReturnURL = $comment->Link();
return $comment;
}
}
return false;
}
/**
* Create a reply form for a specified comment
*
* @param Comment $comment
* @return Form
*/
public function ReplyForm($comment)
{
// Enables multiple forms with different names to use the same handler
$form = $this->CommentsForm();
$form->setName('ReplyForm_' . $comment->ID);
$form->setHTMLID(null);
$form->addExtraClass('reply-form');
// Load parent into reply form
$form->loadDataFrom([
'ParentCommentID' => $comment->ID
]);
// Customise action
$form->setFormAction($this->Link('reply', $comment->ID));
$this->extend('updateReplyForm', $form);
return $form;
}
/**
* Request handler for reply form.
*
* This method will disambiguate multiple reply forms in the same method
*
* @param HTTPRequest $request
* @throws HTTPResponse_Exception
*/
public function reply(HTTPRequest $request)
{
// Extract parent comment from reply and build this way
if ($parentID = $request->param('ParentCommentID')) {
/** @var Comment $comment */
$comment = DataObject::get_by_id(Comment::class, $parentID, true);
if ($comment) {
return $this->ReplyForm($comment);
}
}
return $this->httpError(404);
}
/**
* Post a comment form
*
* @return Form
*/
public function CommentsForm()
{
$form = Injector::inst()->create(CommentForm::class, __FUNCTION__, $this);
// hook to allow further extensions to alter the comments form
$this->extend('alterCommentForm', $form);
return $form;
}
/**
* @return HTTPResponse|false
*/
public function redirectBack()
{
// Don't cache the redirect back ever
HTTPCacheControlMiddleware::singleton()->setMaxAge(0);
$url = null;
// In edge-cases, this will be called outside of a handleRequest() context; in that case,
// redirect to the homepage - don't break into the global state at this stage because we'll
// be calling from a test context or something else where the global state is inappropraite
if ($this->request) {
if ($this->request->requestVar('BackURL')) {
$url = $this->request->requestVar('BackURL');
} elseif ($this->request->isAjax() && $this->request->getHeader('X-Backurl')) {
$url = $this->request->getHeader('X-Backurl');
} elseif ($this->request->getHeader('Referer')) {
$url = $this->request->getHeader('Referer');
}
}
if (!$url) {
$url = $this->fallbackReturnURL;
}
if (!$url) {
$url = Director::baseURL();
}
// absolute redirection URLs not located on this site may cause phishing
if (Director::is_site_url($url)) {
return $this->redirect($url);
}
return false;
}
}

View File

@ -1,5 +1,29 @@
<?php
namespace SilverStripe\Comments\Extensions;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Comments\Admin\CommentsGridField;
use SilverStripe\Comments\Admin\CommentsGridFieldConfig;
use SilverStripe\Comments\Controllers\CommentingController;
use SilverStripe\Comments\Model\Comment;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Director;
use SilverStripe\Core\Config\Config;
use SilverStripe\Forms\CheckboxField;
use SilverStripe\Forms\DropdownField;
use SilverStripe\Forms\FieldGroup;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Tab;
use SilverStripe\Forms\TabSet;
use SilverStripe\ORM\DataExtension;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\PaginatedList;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
use SilverStripe\View\Requirements;
/**
* Extension to {@link DataObject} to enable tracking comments.
*
@ -37,7 +61,7 @@ class CommentsExtension extends DataExtension
*
* @config
*/
private static $comments = array(
private static $comments = [
'enabled' => true,
'enabled_cms' => false,
'require_login' => false,
@ -60,20 +84,27 @@ class CommentsExtension extends DataExtension
'frontend_moderation' => false,
'frontend_spam' => false,
'html_allowed' => false,
'html_allowed_elements' => array('a', 'img', 'i', 'b'),
'html_allowed_elements' => ['a', 'img', 'i', 'b'],
'use_preview' => false,
'nested_comments' => false,
'nested_depth' => 2,
);
];
/**
* @var array
*/
private static $db = array(
private static $db = [
'ProvideComments' => 'Boolean',
'ModerationRequired' => 'Enum(\'None,Required,NonMembersOnly\',\'None\')',
'CommentsRequireLogin' => 'Boolean',
);
];
/**
* {@inheritDoc}
*/
private static $has_many = [
'Commments' => Comment::class . '.Parent'
];
/**
* CMS configurable options should default to the config values, but respect
@ -81,7 +112,7 @@ class CommentsExtension extends DataExtension
*/
public function populateDefaults()
{
$defaults = $this->owner->config()->defaults;
$defaults = $this->owner->config()->get('defaults');
// Set if comments should be enabled by default
if (isset($defaults['ProvideComments'])) {
@ -121,17 +152,20 @@ class CommentsExtension extends DataExtension
*/
public function updateSettingsFields(FieldList $fields)
{
$options = FieldGroup::create()->setTitle(_t('CommentsExtension.COMMENTOPTIONS', 'Comments'));
$options = FieldGroup::create()->setTitle(_t(__CLASS__ . '.COMMENTOPTIONS', 'Comments'));
// Check if enabled setting should be cms configurable
if ($this->owner->getCommentsOption('enabled_cms')) {
$options->push(new CheckboxField('ProvideComments', _t('Comment.ALLOWCOMMENTS', 'Allow Comments')));
$options->push(CheckboxField::create('ProvideComments', _t(
'SilverStripe\\Comments\\Model\\Comment.ALLOWCOMMENTS',
'Allow comments'
)));
}
// Check if we should require users to login to comment
if ($this->owner->getCommentsOption('require_login_cms')) {
$options->push(
new CheckboxField(
CheckboxField::create(
'CommentsRequireLogin',
_t('Comments.COMMENTSREQUIRELOGIN', 'Require login to comment')
)
@ -148,16 +182,23 @@ class CommentsExtension extends DataExtension
// Check if moderation should be enabled via cms configurable
if ($this->owner->getCommentsOption('require_moderation_cms')) {
$moderationField = new DropdownField('ModerationRequired', 'Comment Moderation', array(
'None' => _t('CommentsExtension.MODERATIONREQUIRED_NONE', 'No moderation required'),
'Required' => _t('CommentsExtension.MODERATIONREQUIRED_REQUIRED', 'Moderate all comments'),
'NonMembersOnly' => _t(
'CommentsExtension.MODERATIONREQUIRED_NONMEMBERSONLY',
'Only moderate non-members'
$moderationField = DropdownField::create(
'ModerationRequired',
_t(
__CLASS__ . '.COMMENTMODERATION',
'Comment Moderation'
),
));
[
'None' => _t(__CLASS__ . '.MODERATIONREQUIRED_NONE', 'No moderation required'),
'Required' => _t(__CLASS__ . '.MODERATIONREQUIRED_REQUIRED', 'Moderate all comments'),
'NonMembersOnly' => _t(
__CLASS__ . '.MODERATIONREQUIRED_NONMEMBERSONLY',
'Only moderate non-members'
),
]
);
if ($fields->hasTabSet()) {
$fields->addFieldsToTab('Root.Settings', $moderationField);
$fields->addFieldToTab('Root.Settings', $moderationField);
} else {
$fields->push($moderationField);
}
@ -177,13 +218,17 @@ class CommentsExtension extends DataExtension
{
if ($this->owner->getCommentsOption('require_moderation_cms')) {
return $this->owner->getField('ModerationRequired');
} elseif ($this->owner->getCommentsOption('require_moderation')) {
return 'Required';
} elseif ($this->owner->getCommentsOption('require_moderation_nonmembers')) {
return 'NonMembersOnly';
} else {
return 'None';
}
if ($this->owner->getCommentsOption('require_moderation')) {
return 'Required';
}
if ($this->owner->getCommentsOption('require_moderation_nonmembers')) {
return 'NonMembersOnly';
}
return 'None';
}
/**
@ -195,22 +240,24 @@ class CommentsExtension extends DataExtension
{
if ($this->owner->getCommentsOption('require_login_cms')) {
return (bool) $this->owner->getField('CommentsRequireLogin');
} else {
return (bool) $this->owner->getCommentsOption('require_login');
}
return (bool) $this->owner->getCommentsOption('require_login');
}
/**
* Returns the RelationList of all comments against this object. Can be used as a data source
* for a gridfield with write access.
*
* @return CommentList
* @return DataList
*/
public function AllComments()
{
$order = $this->owner->getCommentsOption('order_comments_by');
$comments = CommentList::create($this->ownerBaseClass)
->forForeignID($this->owner->ID)
$comments = Comment::get()
->filter([
'ParentID' => $this->owner->ID,
'ParentClass' => $this->owner->ClassName,
])
->sort($order);
$this->owner->extend('updateAllComments', $comments);
return $comments;
@ -219,7 +266,7 @@ class CommentsExtension extends DataExtension
/**
* Returns all comments against this object, with with spam and unmoderated items excluded, for use in the frontend
*
* @return CommentList
* @return DataList
*/
public function AllVisibleComments()
{
@ -227,6 +274,7 @@ class CommentsExtension extends DataExtension
// Filter spam comments for non-administrators if configured
$showSpam = $this->owner->getCommentsOption('frontend_spam') && $this->owner->canModerateComments();
if (!$showSpam) {
$list = $list->filter('IsSpam', 0);
}
@ -245,7 +293,7 @@ class CommentsExtension extends DataExtension
/**
* Returns the root level comments, with spam and unmoderated items excluded, for use in the frontend
*
* @return CommentList
* @return DataList
*/
public function Comments()
{
@ -271,7 +319,7 @@ class CommentsExtension extends DataExtension
$list = $this->Comments();
// Add pagination
$list = new PaginatedList($list, Controller::curr()->getRequest());
$list = PaginatedList::create($list, Controller::curr()->getRequest());
$list->setPaginationGetVar('commentsstart' . $this->owner->ID);
$list->setPageLength($this->owner->getCommentsOption('comments_per_page'));
@ -279,20 +327,6 @@ class CommentsExtension extends DataExtension
return $list;
}
/**
* Check if comments are configured for this page even if they are currently disabled.
* Do not include the comments on pages which don't have id's such as security pages
*
* @deprecated since version 2.0
*
* @return boolean
*/
public function getCommentsConfigured()
{
Deprecation::notice('2.0', 'getCommentsConfigured is deprecated. Use getCommentsEnabled instead');
return true; // by virtue of all classes with this extension being 'configured'
}
/**
* Determine if comments are enabled for this instance
*
@ -307,10 +341,10 @@ class CommentsExtension extends DataExtension
// Determine which flag should be used to determine if this is enabled
if ($this->owner->getCommentsOption('enabled_cms')) {
return $this->owner->ProvideComments;
} else {
return $this->owner->getCommentsOption('enabled');
return (bool) $this->owner->ProvideComments;
}
return (bool) $this->owner->getCommentsOption('enabled');
}
/**
@ -323,15 +357,6 @@ class CommentsExtension extends DataExtension
return $this->owner->getCommentsOption('comments_holder_id');
}
/**
* @deprecated since version 2.0
*/
public function getPostingRequiresPermission()
{
Deprecation::notice('2.0', 'Use getPostingRequiredPermission instead');
return $this->getPostingRequiredPermission();
}
/**
* Permission codes required in order to post (or empty if none required)
*
@ -342,12 +367,6 @@ class CommentsExtension extends DataExtension
return $this->owner->getCommentsOption('required_permission');
}
public function canPost()
{
Deprecation::notice('2.0', 'Use canPostComment instead');
return $this->canPostComment();
}
/**
* Determine if a user can post comments on this item
*
@ -362,6 +381,11 @@ class CommentsExtension extends DataExtension
return false;
}
if (!$this->owner->canView($member)) {
// deny if current user cannot view the underlying record.
return false;
}
// Check if member is required
$requireLogin = $this->owner->CommentsRequireLogin;
if (!$requireLogin) {
@ -369,7 +393,7 @@ class CommentsExtension extends DataExtension
}
// Check member is logged in
$member = $member ?: Member::currentUser();
$member = $member ?: Security::getCurrentUser();
if (!$member) {
return false;
}
@ -401,12 +425,6 @@ class CommentsExtension extends DataExtension
return $this->owner->canEdit($member);
}
public function getRssLink()
{
Deprecation::notice('2.0', 'Use getCommentRSSLink instead');
return $this->getCommentRSSLink();
}
/**
* Gets the RSS link to all comments
*
@ -414,13 +432,7 @@ class CommentsExtension extends DataExtension
*/
public function getCommentRSSLink()
{
return Controller::join_links(Director::baseURL(), 'CommentingController/rss');
}
public function getRssLinkPage()
{
Deprecation::notice('2.0', 'Use getCommentRSSLinkPage instead');
return $this->getCommentRSSLinkPage();
return Director::absoluteURL('comments/rss');
}
/**
@ -431,7 +443,9 @@ class CommentsExtension extends DataExtension
public function getCommentRSSLinkPage()
{
return Controller::join_links(
$this->getCommentRSSLink(), $this->ownerBaseClass, $this->owner->ID
$this->getCommentRSSLink(),
str_replace('\\', '-', get_class($this->owner)),
$this->owner->ID
);
}
@ -451,21 +465,21 @@ class CommentsExtension extends DataExtension
// Check if enabled
$enabled = $this->getCommentsEnabled();
if ($enabled && $this->owner->getCommentsOption('include_js')) {
Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js');
Requirements::javascript(THIRDPARTY_DIR . '/jquery-validate/lib/jquery.form.js');
Requirements::javascript(COMMENTS_THIRDPARTY . '/jquery-validate/jquery.validate.min.js');
Requirements::add_i18n_javascript('comments/javascript/lang');
Requirements::javascript('comments/javascript/CommentsInterface.js');
Requirements::javascript('silverstripe/comments:client/dist/js/jquery.min.js');
Requirements::javascript('silverstripe/comments:client/dist/js/jquery-validation/jquery.validate.min.js');
Requirements::javascript('silverstripe/admin:client/dist/js/i18n.js');
Requirements::add_i18n_javascript('silverstripe/comments:client/lang');
Requirements::javascript('silverstripe/comments:client/dist/js/CommentsInterface.js');
}
$controller = CommentingController::create();
$controller->setOwnerRecord($this->owner);
$controller->setBaseClass($this->ownerBaseClass);
$controller->setParentClass($this->owner->getClassName());
$controller->setOwnerController(Controller::curr());
$moderatedSubmitted = Session::get('CommentsModerated');
Session::clear('CommentsModerated');
$session = Controller::curr()->getRequest()->getSession();
$moderatedSubmitted = $session->get('CommentsModerated');
$session->clear('CommentsModerated');
$form = ($enabled) ? $controller->CommentsForm() : false;
@ -473,10 +487,10 @@ class CommentsExtension extends DataExtension
// return back the same variables as previously done in comments
return $this
->owner
->customise(array(
->customise([
'AddCommentForm' => $form,
'ModeratedSubmitted' => $moderatedSubmitted,
))
])
->renderWith('CommentsInterface');
}
@ -487,25 +501,16 @@ class CommentsExtension extends DataExtension
*/
public function attachedToSiteTree()
{
$class = $this->ownerBaseClass;
$class = $this->owner->baseClass();
return (is_subclass_of($class, 'SiteTree')) || ($class == 'SiteTree');
return (is_subclass_of($class, SiteTree::class)) || ($class == SiteTree::class);
}
/**
* @deprecated 1.0 Please use {@link CommentsExtension->CommentsForm()}
*/
public function PageComments()
{
// This method is very commonly used, don't throw a warning just yet
Deprecation::notice('1.0', '$PageComments is deprecated. Please use $CommentsForm');
return $this->CommentsForm();
}
/**
* Get the commenting option for this object
* Get the commenting option for this object.
*
* This can be overridden in any instance or extension to customise the option available
* This can be overridden in any instance or extension to customise the
* option available.
*
* @param string $key
*
@ -513,10 +518,9 @@ class CommentsExtension extends DataExtension
*/
public function getCommentsOption($key)
{
$settings = $this->owner // In case singleton is called on the extension directly
? $this->owner->config()->comments
: Config::inst()->get(__CLASS__, 'comments');
$settings = $this->getCommentsOptions();
$value = null;
if (isset($settings[$key])) {
$value = $settings[$key];
}
@ -525,9 +529,24 @@ class CommentsExtension extends DataExtension
if ($this->owner) {
$this->owner->extend('updateCommentsOption', $key, $value);
}
return $value;
}
/**
* @return array
*/
public function getCommentsOptions()
{
if ($this->owner) {
$settings = $this->owner->config()->get('comments');
} else {
$settings = Config::inst()->get(__CLASS__, 'comments');
}
return $settings;
}
/**
* Add moderation functions to the current fieldlist
*
@ -535,11 +554,11 @@ class CommentsExtension extends DataExtension
*/
protected function updateModerationFields(FieldList $fields)
{
Requirements::css(COMMENTS_DIR . '/css/cms.css');
Requirements::css('silverstripe/comments:client/dist/styles/cms.css');
$newComments = $this->owner->AllComments()->filter('Moderated', 0);
$newGrid = new CommentsGridField(
$newGrid = CommentsGridField::create(
'NewComments',
_t('CommentsAdmin.NewComments', 'New'),
$newComments,
@ -557,30 +576,38 @@ class CommentsExtension extends DataExtension
$spamComments = $this->owner->AllComments()->filter('Moderated', 1)->filter('IsSpam', 1);
$spamGrid = new CommentsGridField(
$spamGrid = CommentsGridField::create(
'SpamComments',
_t('CommentsAdmin.SpamComments', 'Spam'),
$spamComments,
CommentsGridFieldConfig::create()
);
$newCount = '(' . count($newComments) . ')';
$approvedCount = '(' . count($approvedComments) . ')';
$spamCount = '(' . count($spamComments) . ')';
$newCount = '(' . count($newComments ?? []) . ')';
$approvedCount = '(' . count($approvedComments ?? []) . ')';
$spamCount = '(' . count($spamComments ?? []) . ')';
if ($fields->hasTabSet()) {
$tabs = new TabSet(
$tabs = TabSet::create(
'Comments',
new Tab('CommentsNewCommentsTab', _t('CommentAdmin.NewComments', 'New') . ' ' . $newCount,
Tab::create(
'CommentsNewCommentsTab',
_t('SilverStripe\\Comments\\Admin\\CommentAdmin.NewComments', 'New') . ' ' . $newCount,
$newGrid
),
new Tab('CommentsCommentsTab', _t('CommentAdmin.Comments', 'Approved') . ' ' . $approvedCount,
Tab::create(
'CommentsCommentsTab',
_t('SilverStripe\\Comments\\Admin\\CommentAdmin.Comments', 'Approved') . ' ' . $approvedCount,
$approvedGrid
),
new Tab('CommentsSpamCommentsTab', _t('CommentAdmin.SpamComments', 'Spam') . ' ' . $spamCount,
Tab::create(
'CommentsSpamCommentsTab',
_t('SilverStripe\\Comments\\Admin\\CommentAdmin.SpamComments', 'Spam') . ' ' . $spamCount,
$spamGrid
)
);
$tabs->setTitle(_t(__CLASS__ . '.COMMENTSTABSET', 'Comments'));
$fields->addFieldToTab('Root', $tabs);
} else {
$fields->push($newGrid);

299
src/Forms/CommentForm.php Normal file
View File

@ -0,0 +1,299 @@
<?php
namespace SilverStripe\Comments\Forms;
use SilverStripe\Comments\Controllers\CommentingController;
use SilverStripe\Comments\Model\Comment;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPResponse;
use SilverStripe\Core\Convert;
use SilverStripe\Forms\CompositeField;
use SilverStripe\Forms\EmailField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\FormAction;
use SilverStripe\Forms\HiddenField;
use SilverStripe\Forms\ReadonlyField;
use SilverStripe\Forms\RequiredFields;
use SilverStripe\Forms\TextareaField;
use SilverStripe\Forms\TextField;
use SilverStripe\Security\Security;
class CommentForm extends Form
{
/**
* @param string $name
* @param CommentingController $controller
*/
public function __construct($name, CommentingController $controller)
{
$usePreview = $controller->getOption('use_preview');
$nameRequired = _t('CommentInterface.YOURNAME_MESSAGE_REQUIRED', 'Please enter your name');
$emailRequired = _t('CommentInterface.EMAILADDRESS_MESSAGE_REQUIRED', 'Please enter your email address');
$emailInvalid = _t('CommentInterface.EMAILADDRESS_MESSAGE_EMAIL', 'Please enter a valid email address');
$urlInvalid = _t('CommentInterface.COMMENT_MESSAGE_URL', 'Please enter a valid URL');
$commentRequired = _t('CommentInterface.COMMENT_MESSAGE_REQUIRED', 'Please enter your comment');
$fields = FieldList::create(
$dataFields = CompositeField::create(
// Name
$a = TextField::create('Name', _t('CommentInterface.YOURNAME', 'Your name'))
->setCustomValidationMessage($nameRequired)
->setAttribute('data-msg-required', $nameRequired),
// Email
EmailField::create(
'Email',
_t(
'SilverStripe\\Comments\\Controllers\\CommentingController.EMAILADDRESS',
'Your email address (will not be published)'
)
)
->setCustomValidationMessage($emailRequired)
->setAttribute('data-msg-required', $emailRequired)
->setAttribute('data-msg-email', $emailInvalid)
->setAttribute('data-rule-email', true),
// Url
TextField::create('URL', _t(
'SilverStripe\\Comments\\Controllers\\CommentingController.WEBSITEURL',
'Your website URL'
))
->setAttribute('data-msg-url', $urlInvalid)
->setAttribute('data-rule-url', true),
// Comment
TextareaField::create('Comment', _t(
'SilverStripe\\Comments\\Controllers\\CommentingController.COMMENTS',
'Comments'
))
->setCustomValidationMessage($commentRequired)
->setAttribute('data-msg-required', $commentRequired)
),
HiddenField::create('ParentID'),
HiddenField::create('ParentClassName'),
HiddenField::create('ReturnURL'),
HiddenField::create('ParentCommentID')
);
// Preview formatted comment. Makes most sense when shortcodes or
// limited HTML is allowed. Populated by JS/Ajax.
if ($usePreview) {
$fields->insertAfter(
'Comment',
ReadonlyField::create('PreviewComment', _t('CommentInterface.PREVIEWLABEL', 'Preview'))
->setAttribute('style', 'display: none') // enable through JS
);
}
$dataFields->addExtraClass('data-fields');
// save actions
$actions = FieldList::create(
$postAction = new FormAction('doPostComment', _t('CommentInterface.POST', 'Post'))
);
if ($usePreview) {
$actions->push(
FormAction::create('doPreviewComment', _t('CommentInterface.PREVIEW', 'Preview'))
->addExtraClass('action-minor')
->setAttribute('style', 'display: none') // enable through JS
);
}
$required = RequiredFields::create(
$controller->config()->required_fields
);
parent::__construct($controller, $name, $fields, $actions, $required);
// if the record exists load the extra required data
if ($record = $controller->getOwnerRecord()) {
// Load member data
$member = Security::getCurrentUser();
if (($record->CommentsRequireLogin || $record->PostingRequiredPermission) && $member) {
$fields = $this->Fields();
$fields->removeByName('Name');
$fields->removeByName('Email');
$fields->insertBefore(
ReadonlyField::create(
'NameView',
_t('CommentInterface.YOURNAME', 'Your name'),
$member->getName()
),
'URL'
);
$fields->push(HiddenField::create('Name', '', $member->getName()));
$fields->push(HiddenField::create('Email', '', $member->Email));
}
// we do not want to read a new URL when the form has already been submitted
// which in here, it hasn't been.
$this->loadDataFrom([
'ParentID' => $record->ID,
'ReturnURL' => $controller->getRequest()->getURL(),
'ParentClassName' => $controller->getParentClass()
]);
}
// Set it so the user gets redirected back down to the form upon form fail
$this->setRedirectToFormOnValidationError(true);
// load any data from the session
$data = $this->getSessionData();
if (!is_array($data)) {
return;
}
// load user data from previous form request back into form.
if (array_key_exists('UserData', $data ?? [])) {
$formData = json_decode($data['UserData'] ?? '', true);
$this->loadDataFrom([
'Name' => isset($formData['Name']) ? $formData['Name'] : '',
'URL' => isset($formData['URL']) ? $formData['URL'] : '',
'Email' => isset($formData['Email']) ? $formData['Email'] : ''
]);
}
// allow previous value to fill if comment
if (array_key_exists('Comment', $data ?? [])) {
$prevComment = $data['Comment'];
if ($prevComment && $prevComment != '') {
$this->loadDataFrom(['Comment' => $prevComment]);
}
}
}
/**
* @param array $data
* @param Form $form
* @return HTTPResponse
*/
public function doPreviewComment($data, $form)
{
$data['IsPreview'] = 1;
return $this->doPostComment($data, $form);
}
/**
* Process which creates a {@link Comment} once a user submits a comment from this form.
*
* @param array $data
* @param Form $form
* @return HTTPResponse
*/
public function doPostComment($data, $form)
{
// Load class and parent from data
if (isset($data['ParentClassName'])) {
$this->controller->setParentClass($data['ParentClassName']);
}
if (isset($data['ParentID']) && ($class = $this->controller->getParentClass())) {
$this->controller->setOwnerRecord($class::get()->byID($data['ParentID']));
}
if (!$this->controller->getOwnerRecord()) {
return $this->getRequestHandler()->httpError(404);
}
// cache users data
$form->setSessionData([
'UserData' => json_encode($data),
'Comment' => $data['Comment']
]);
// extend hook to allow extensions. Also see onAfterPostComment
$this->controller->extend('onBeforePostComment', $form);
// If commenting can only be done by logged in users, make sure the user is logged in
if (!$this->controller->getOwnerRecord()->canPostComment()) {
return Security::permissionFailure(
$this->controller,
_t(
'SilverStripe\\Comments\\Controllers\\CommentingController.PERMISSIONFAILURE',
"You're not able to post comments to this page. Please ensure you are logged in and have an "
. 'appropriate permission level.'
)
);
}
if ($member = Security::getCurrentUser()) {
$form->Fields()->push(HiddenField::create('AuthorID', 'Author ID', $member->ID));
}
// What kind of moderation is required?
switch ($this->controller->getOwnerRecord()->ModerationRequired) {
case 'Required':
$requireModeration = true;
break;
case 'NonMembersOnly':
$requireModeration = empty($member);
break;
case 'None':
default:
$requireModeration = false;
break;
}
$comment = Comment::create();
$form->saveInto($comment);
$comment->ParentID = $data['ParentID'];
$comment->ParentClass = $data['ParentClassName'];
$comment->AllowHtml = $this->controller->getOption('html_allowed');
$comment->Moderated = !$requireModeration;
// Save into DB, or call pre-save hooks to give accurate preview
$usePreview = $this->controller->getOption('use_preview');
$isPreview = $usePreview && !empty($data['IsPreview']);
if ($isPreview) {
$comment->extend('onBeforeWrite');
} else {
$comment->write();
// extend hook to allow extensions. Also see onBeforePostComment
$this->controller->extend('onAfterPostComment', $comment);
}
// we want to show a notification if comments are moderated
if ($requireModeration && !$comment->IsSpam) {
$this->getRequest()->getSession()->set('CommentsModerated', 1);
}
// clear the users comment since the comment was successful.
if ($comment->exists()) {
// Remove the comment data as it's been saved already.
unset($data['Comment']);
}
// cache users data (name, email, etc to prepopulate on other forms).
$form->setSessionData([
'UserData' => json_encode($data),
]);
// Find parent link
if (!empty($data['ReturnURL'])) {
$url = $data['ReturnURL'];
} elseif ($parent = $comment->Parent()) {
$url = $parent->Link();
} else {
return $this->controller->redirectBack();
}
// Given a redirect page exists, attempt to link to the correct anchor
if ($comment->IsSpam) {
// Link to the form with the error message contained
$hash = $form->FormName();
} elseif (!$comment->Moderated) {
// Display the "awaiting moderation" text
$hash = 'moderated';
} else {
// Link to the moderated, non-spam comment
$hash = $comment->Permalink();
}
return $this->controller->redirect(Controller::join_links($url, "#{$hash}"));
}
}

View File

@ -1,5 +1,35 @@
<?php
namespace SilverStripe\Comments\Model;
use SilverStripe\Dev\Deprecation;
use HTMLPurifier;
use HTMLPurifier_Config;
use SilverStripe\Comments\Controllers\CommentingController;
use SilverStripe\Comments\Extensions\CommentsExtension;
use SilverStripe\Comments\Model\Comment\SecurityToken;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Director;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Core\TempFolder;
use SilverStripe\Forms\CheckboxField;
use SilverStripe\Forms\EmailField;
use SilverStripe\Forms\FieldGroup;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\HeaderField;
use SilverStripe\Forms\HTMLEditor\HTMLEditorField;
use SilverStripe\Forms\TextareaField;
use SilverStripe\Forms\TextField;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\ORM\PaginatedList;
use SilverStripe\ORM\SS_List;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
/**
* Represents a single comment object.
*
@ -22,40 +52,53 @@
*/
class Comment extends DataObject
{
/**
* @var array
* {@inheritDoc}
*/
private static $db = array(
'Name' => 'Varchar(200)',
'Comment' => 'Text',
'Email' => 'Varchar(200)',
'URL' => 'Varchar(255)',
'BaseClass' => 'Varchar(200)',
'Moderated' => 'Boolean(0)',
'IsSpam' => 'Boolean(0)',
'ParentID' => 'Int',
'AllowHtml' => 'Boolean',
'SecretToken' => 'Varchar(255)',
'Depth' => 'Int',
'Depth' => 'Int'
);
/**
* {@inheritDoc}
*/
private static $has_one = array(
"Author" => "Member",
"ParentComment" => "Comment",
'Author' => Member::class,
'ParentComment' => self::class,
'Parent' => DataObject::class
);
/**
* {@inheritDoc}
*/
private static $has_many = array(
"ChildComments" => "Comment"
'ChildComments' => self::class
);
/**
* {@inheritDoc}
*/
private static $default_sort = '"Created" DESC';
/**
* {@inheritDoc}
*/
private static $defaults = array(
'Moderated' => 0,
'IsSpam' => 0,
);
/**
* {@inheritDoc}
*/
private static $casting = array(
'Title' => 'Varchar',
'ParentTitle' => 'Varchar',
@ -63,33 +106,50 @@ class Comment extends DataObject
'AuthorName' => 'Varchar',
'RSSName' => 'Varchar',
'DeleteLink' => 'Varchar',
'Date' => 'Datetime',
'SpamLink' => 'Varchar',
'HamLink' => 'Varchar',
'ApproveLink' => 'Varchar',
'Permalink' => 'Varchar',
'Permalink' => 'Varchar'
);
/**
* {@inheritDoc}
*/
private static $searchable_fields = array(
'Name',
'Email',
'Comment',
'Created',
'BaseClass',
'Created'
);
/**
* {@inheritDoc}
*/
private static $summary_fields = array(
'Name' => 'Submitted By',
'Email' => 'Email',
'getAuthorName' => 'Submitted By',
'getAuthorEmail' => 'Email',
'Comment.LimitWordCount' => 'Comment',
'Created' => 'Date Posted',
'ParentTitle' => 'Post',
'IsSpam' => 'Is Spam',
'Parent.Title' => 'Post',
'IsSpam' => 'Is Spam'
);
/**
* {@inheritDoc}
*/
private static $field_labels = array(
'Author' => 'Author Member',
'Author' => 'Author Member'
);
/**
* {@inheritDoc}
*/
private static $table_name = 'Comment';
/**
* {@inheritDoc}
*/
public function onBeforeWrite()
{
parent::onBeforeWrite();
@ -103,6 +163,9 @@ class Comment extends DataObject
$this->updateDepth();
}
/**
* {@inheritDoc}
*/
public function onBeforeDelete()
{
parent::onBeforeDelete();
@ -118,39 +181,7 @@ class Comment extends DataObject
*/
public function getSecurityToken()
{
return Injector::inst()->createWithArgs('Comment_SecurityToken', array($this));
}
/**
* Migrates the old {@link PageComment} objects to {@link Comment}
*/
public function requireDefaultRecords()
{
parent::requireDefaultRecords();
if (DB::getConn()->hasTable('PageComment')) {
$comments = DB::query('SELECT * FROM "PageComment"');
if ($comments) {
while ($pageComment = $comments->next()) {
// create a new comment from the older page comment
$comment = new Comment();
$comment->update($pageComment);
// set the variables which have changed
$comment->BaseClass = 'SiteTree';
$comment->URL = (isset($pageComment['CommenterURL'])) ? $pageComment['CommenterURL'] : '';
if ((int) $pageComment['NeedsModeration'] == 0) {
$comment->Moderated = true;
}
$comment->write();
}
}
DB::alteration_message('Migrated PageComment to Comment', 'changed');
DB::getConn()->dontRequireTable('PageComment');
}
return Injector::inst()->createWithArgs(SecurityToken::class, array($this));
}
/**
@ -162,7 +193,7 @@ class Comment extends DataObject
*/
public function Link($action = '')
{
if ($parent = $this->getParent()) {
if ($parent = $this->Parent()) {
return $parent->Link($action) . '#' . $this->Permalink();
}
}
@ -190,14 +221,14 @@ class Comment extends DataObject
{
$labels = parent::fieldLabels($includerelations);
$labels['Name'] = _t('Comment.NAME', 'Author Name');
$labels['Comment'] = _t('Comment.COMMENT', 'Comment');
$labels['Email'] = _t('Comment.EMAIL', 'Email');
$labels['URL'] = _t('Comment.URL', 'URL');
$labels['IsSpam'] = _t('Comment.ISSPAM', 'Spam?');
$labels['Moderated'] = _t('Comment.MODERATED', 'Moderated?');
$labels['ParentTitle'] = _t('Comment.PARENTTITLE', 'Parent');
$labels['Created'] = _t('Comment.CREATED', 'Date posted');
$labels['Name'] = _t(__CLASS__ . '.NAME', 'Author name');
$labels['Comment'] = _t(__CLASS__ . '.COMMENT', 'Comment');
$labels['Email'] = _t(__CLASS__ . '.EMAIL', 'Email');
$labels['URL'] = _t(__CLASS__ . '.URL', 'URL');
$labels['IsSpam'] = _t(__CLASS__ . '.ISSPAM', 'Spam?');
$labels['Moderated'] = _t(__CLASS__ . '.MODERATED', 'Moderated?');
$labels['ParentTitle'] = _t(__CLASS__ . '.PARENTTITLE', 'Parent');
$labels['Created'] = _t(__CLASS__ . '.CREATED', 'Date posted');
return $labels;
}
@ -212,26 +243,35 @@ class Comment extends DataObject
public function getOption($key)
{
// If possible use the current record
$record = $this->getParent();
$record = $this->Parent();
if (!$record && $this->BaseClass) {
if (!$record && $this->Parent()) {
// Otherwise a singleton of that record
$record = singleton($this->BaseClass);
$record = singleton($this->Parent()->dataClass());
} elseif (!$record) {
// Otherwise just use the default options
$record = singleton('CommentsExtension');
$record = singleton(CommentsExtension::class);
}
return ($record->hasMethod('getCommentsOption')) ? $record->getCommentsOption($key) : null;
return ($record instanceof CommentsExtension || $record->hasExtension(CommentsExtension::class))
? $record->getCommentsOption($key)
: null;
}
/**
* Returns the parent {@link DataObject} this comment is attached too
*
* @deprecated 4.0.0 Use $this->Parent() instead
* @return DataObject
*/
public function getParent()
{
// this is wrapped in withNoReplacement() because it's called by ViewableData::__get()
// which looks for a `"get$property"` method, which itself is called by
// AssetControllExtension::findAssets()
Deprecation::withNoReplacement(function () {
Deprecation::notice('4.0.0', 'Use $this->Parent() instead');
});
return $this->BaseClass && $this->ParentID
? DataObject::get_by_id($this->BaseClass, $this->ParentID, true)
: null;
@ -245,7 +285,7 @@ class Comment extends DataObject
*/
public function getParentTitle()
{
if ($parent = $this->getParent()) {
if ($parent = $this->Parent()) {
return $parent->Title ?: ($parent->ClassName . ' #' . $parent->ID);
}
}
@ -257,13 +297,16 @@ class Comment extends DataObject
*/
public function getParentClassName()
{
return $this->BaseClass;
return $this->Parent()->getClassName();
}
/**
* {@inheritDoc}
*/
public function castingHelper($field)
{
// Safely escape the comment
if ($field === 'EscapedComment') {
if (in_array($field, ['EscapedComment', 'Comment'], true)) {
return $this->AllowHtml ? 'HTMLText' : 'Text';
}
return parent::castingHelper($field);
@ -293,10 +336,10 @@ class Comment extends DataObject
* @todo needs to compare to the new {@link Commenting} configuration API
*
* @param Member $member
*
* @param array $context
* @return bool
*/
public function canCreate($member = null)
public function canCreate($member = null, $context = [])
{
return false;
}
@ -306,7 +349,6 @@ class Comment extends DataObject
* flag being set to true.
*
* @param Member $member
*
* @return Boolean
*/
public function canView($member = null)
@ -322,9 +364,9 @@ class Comment extends DataObject
return true;
}
if ($parent = $this->getParent()) {
if ($parent = $this->Parent()) {
return $parent->canView($member)
&& $parent->has_extension('CommentsExtension')
&& $parent->hasExtension(CommentsExtension::class)
&& $parent->CommentsEnabled;
}
@ -335,7 +377,6 @@ class Comment extends DataObject
* Checks if the comment can be edited.
*
* @param null|int|Member $member
*
* @return Boolean
*/
public function canEdit($member = null)
@ -355,7 +396,7 @@ class Comment extends DataObject
return true;
}
if ($parent = $this->getParent()) {
if ($parent = $this->Parent()) {
return $parent->canEdit($member);
}
@ -366,7 +407,6 @@ class Comment extends DataObject
* Checks if the comment can be deleted.
*
* @param null|int|Member $member
*
* @return Boolean
*/
public function canDelete($member = null)
@ -394,11 +434,11 @@ class Comment extends DataObject
protected function getMember($member = null)
{
if (!$member) {
$member = Member::currentUser();
$member = Security::getCurrentUser();
}
if (is_numeric($member)) {
$member = DataObject::get_by_id('Member', $member, true);
$member = DataObject::get_by_id(Member::class, $member, true);
}
return $member;
@ -418,6 +458,20 @@ class Comment extends DataObject
}
}
/**
* Return the comment authors email address
*
* @return string
*/
public function getAuthorEmail()
{
if ($this->Email) {
return $this->Email;
} elseif ($author = $this->Author()) {
return $author->Email;
}
}
/**
* Generate a secure admin-action link authorised for the specified member
*
@ -429,15 +483,23 @@ class Comment extends DataObject
protected function actionLink($action, $member = null)
{
if (!$member) {
$member = Member::currentUser();
$member = Security::getCurrentUser();
}
if (!$member) {
return false;
}
/**
* @todo: How do we handle "DataObject" instances that don't have a Link to reject/spam/delete?? This may
* we have to make CMS a hard dependency instead.
*/
// if (!$this->Parent()->hasMethod('Link')) {
// return false;
// }
$url = Controller::join_links(
Director::baseURL(),
'CommentingController',
'comments',
$action,
$this->ID
);
@ -554,11 +616,11 @@ class Comment extends DataObject
*/
public function getTitle()
{
$title = sprintf(_t('Comment.COMMENTBY', 'Comment by %s', 'Name'), $this->getAuthorName());
$title = sprintf(_t(__CLASS__ . '.COMMENTBY', 'Comment by %s', 'Name') ?? '', $this->getAuthorName());
if ($parent = $this->getParent()) {
if ($parent = $this->Parent()) {
if ($parent->Title) {
$title .= sprintf(' %s %s', _t('Comment.ON', 'on'), $parent->Title);
$title .= sprintf(' %s %s', _t(__CLASS__ . '.ON', 'on'), $parent->Title);
}
}
@ -570,7 +632,7 @@ class Comment extends DataObject
*/
public function getCMSFields()
{
$commentField = $this->AllowHtml ? 'HtmlEditorField' : 'TextareaField';
$commentField = $this->AllowHtml ? HTMLEditorField::class : TextareaField::class;
$fields = new FieldList(
$this
->obj('Created')
@ -584,9 +646,9 @@ class Comment extends DataObject
CheckboxField::create('Moderated', $this->fieldLabel('Moderated')),
CheckboxField::create('IsSpam', $this->fieldLabel('IsSpam')),
))
->setTitle(_t('Comment.OPTIONS', 'Options'))
->setTitle(_t(__CLASS__ . '.OPTIONS', 'Options'))
->setDescription(_t(
'Comment.OPTION_DESCRIPTION',
__CLASS__ . '.OPTION_DESCRIPTION',
'Unmoderated and spam comments will not be displayed until approved'
))
);
@ -594,9 +656,9 @@ class Comment extends DataObject
// Show member name if given
if (($author = $this->Author()) && $author->exists()) {
$fields->insertAfter(
'Name',
TextField::create('AuthorMember', $this->fieldLabel('Author'), $author->Title)
->performReadonlyTransformation(),
'Name'
->performReadonlyTransformation()
);
}
@ -604,14 +666,14 @@ class Comment extends DataObject
if (($parent = $this->ParentComment()) && $parent->exists()) {
$fields->push(new HeaderField(
'ParentComment_Title',
_t('Comment.ParentComment_Title', 'This comment is a reply to the below')
_t(__CLASS__ . '.ParentComment_Title', 'This comment is a reply to the below')
));
// Created date
// FIXME - the method setName in DatetimeField is not chainable, hence
// the lack of chaining here
$createdField = $parent
->obj('Created')
->scaffoldFormField($parent->fieldLabel('Created'));
->obj('Created')
->scaffoldFormField($parent->fieldLabel('Created'));
$createdField->setName('ParentComment_Created');
$createdField->setValue($parent->Created);
$createdField->performReadonlyTransformation();
@ -631,7 +693,7 @@ class Comment extends DataObject
$fields->push(
$parent
->obj('EscapedComment')
->scaffoldFormField($parent->fieldLabel('Comment'))
->scaffoldFormField($parent->fieldLabel(self::class))
->setName('ParentComment_EscapedComment')
->setValue($parent->Comment)
->performReadonlyTransformation()
@ -643,14 +705,17 @@ class Comment extends DataObject
}
/**
* @param String $dirtyHtml
* @param string $dirtyHtml
*
* @return String
* @return string
*/
public function purifyHtml($dirtyHtml)
{
$purifier = $this->getHtmlPurifierService();
return $purifier->purify($dirtyHtml);
if ($service = $this->getHtmlPurifierService()) {
return $service->purify($dirtyHtml);
}
return $dirtyHtml;
}
/**
@ -658,18 +723,24 @@ class Comment extends DataObject
*/
public function getHtmlPurifierService()
{
if (!class_exists(HTMLPurifier_Config::class)) {
return null;
}
$config = HTMLPurifier_Config::createDefault();
$allowedElements = $this->getOption('html_allowed_elements');
$config->set('HTML.AllowedElements', $allowedElements);
$allowedElements = (array) $this->getOption('html_allowed_elements');
if (!empty($allowedElements)) {
$config->set('HTML.AllowedElements', $allowedElements);
}
// This injector cannot be set unless the 'p' element is allowed
if (in_array('p', $allowedElements)) {
if (in_array('p', $allowedElements ?? [])) {
$config->set('AutoFormat.AutoParagraph', true);
}
$config->set('AutoFormat.Linkify', true);
$config->set('URI.DisableExternalResources', true);
$config->set('Cache.SerializerPath', getTempFolder());
$config->set('Cache.SerializerPath', TempFolder::getTempFolder(BASE_PATH));
return new HTMLPurifier($config);
}
@ -682,12 +753,17 @@ class Comment extends DataObject
{
$gravatar = '';
$use_gravatar = $this->getOption('use_gravatar');
if ($use_gravatar) {
$gravatar = 'http://www.gravatar.com/avatar/' . md5(strtolower(trim($this->Email)));
$gravatar = 'https://www.gravatar.com/avatar/' . md5(strtolower(trim($this->Email ?? '')));
$gravatarsize = $this->getOption('gravatar_size');
$gravatardefault = $this->getOption('gravatar_default');
$gravatarrating = $this->getOption('gravatar_rating');
$gravatar .= '?s=' . $gravatarsize . '&d=' . $gravatardefault . '&r=' . $gravatarrating;
$gravatar .= '?' . http_build_query(array(
's' => $gravatarsize,
'd' => $gravatardefault,
'r' => $gravatarrating,
));
}
return $gravatar;
@ -711,6 +787,20 @@ class Comment extends DataObject
return $notSpam && (!$maxLevel || $this->Depth < $maxLevel);
}
/**
* Proxy for checking whether the has permission to comment on the comment parent.
*
* @param Member $member Member to check
*
* @return boolean
*/
public function canPostComment($member = null)
{
return $this->Parent()
&& $this->Parent()->exists()
&& $this->Parent()->canPostComment($member);
}
/**
* Returns the list of all replies
*
@ -748,7 +838,7 @@ class Comment extends DataObject
$list = $this->AllReplies();
// Filter spam comments for non-administrators if configured
$parent = $this->getParent();
$parent = $this->Parent();
$showSpam = $this->getOption('frontend_spam') && $parent && $parent->canModerateComments();
if (!$showSpam) {
$list = $list->filter('IsSpam', 0);
@ -778,7 +868,7 @@ class Comment extends DataObject
// Add pagination
$list = new PaginatedList($list, Controller::curr()->getRequest());
$list->setPaginationGetVar('repliesstart'.$this->ID);
$list->setPaginationGetVar('repliesstart' . $this->ID);
$list->setPageLength($this->getOption('comments_per_page'));
$this->extend('updatePagedReplies', $list);
@ -798,7 +888,7 @@ class Comment extends DataObject
}
// Check parent is available
$parent = $this->getParent();
$parent = $this->Parent();
if (!$parent || !$parent->exists()) {
return null;
}
@ -806,12 +896,20 @@ class Comment extends DataObject
// Build reply controller
$controller = CommentingController::create();
$controller->setOwnerRecord($parent);
$controller->setBaseClass($parent->ClassName);
$controller->setParentClass($parent->ClassName);
$controller->setOwnerController(Controller::curr());
return $controller->ReplyForm($this);
}
/**
* @return string
*/
public function getDate()
{
return $this->Created;
}
/**
* Refresh of this comment in the hierarchy
*/
@ -826,115 +924,3 @@ class Comment extends DataObject
}
}
}
/**
* Provides the ability to generate cryptographically secure tokens for comment moderation
*/
class Comment_SecurityToken
{
private $secret = null;
/**
* @param Comment $comment Comment to generate this token for
*/
public function __construct($comment)
{
if (!$comment->SecretToken) {
$comment->SecretToken = $this->generate();
$comment->write();
}
$this->secret = $comment->SecretToken;
}
/**
* Generate the token for the given salt and current secret
*
* @param string $salt
*
* @return string
*/
protected function getToken($salt)
{
return hash_pbkdf2('sha256', $this->secret, $salt, 1000, 30);
}
/**
* Get the member-specific salt.
*
* The reason for making the salt specific to a user is that it cannot be "passed in" via a
* querystring, requiring the same user to be present at both the link generation and the
* controller action.
*
* @param string $salt Single use salt
* @param Member $member Member object
*
* @return string Generated salt specific to this member
*/
protected function memberSalt($salt, $member)
{
// Fallback to salting with ID in case the member has not one set
return $salt . ($member->Salt ?: $member->ID);
}
/**
* @param string $url Comment action URL
* @param Member $member Member to restrict access to this action to
*
* @return string
*/
public function addToUrl($url, $member)
{
$salt = $this->generate(15); // New random salt; Will be passed into url
// Generate salt specific to this member
$memberSalt = $this->memberSalt($salt, $member);
$token = $this->getToken($memberSalt);
return Controller::join_links(
$url,
sprintf(
'?t=%s&s=%s',
urlencode($token),
urlencode($salt)
)
);
}
/**
* @param SS_HTTPRequest $request
*
* @return boolean
*/
public function checkRequest($request)
{
$member = Member::currentUser();
if (!$member) {
return false;
}
$salt = $request->getVar('s');
$memberSalt = $this->memberSalt($salt, $member);
$token = $this->getToken($memberSalt);
// Ensure tokens match
return $token === $request->getVar('t');
}
/**
* Generates new random key
*
* @param integer $length
*
* @return string
*/
protected function generate($length = null)
{
$generator = new RandomGenerator();
$result = $generator->randomToken('sha256');
if ($length !== null) {
return substr($result, 0, $length);
}
return $result;
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace SilverStripe\Comments\Model\Comment;
use SilverStripe\Control\Controller;
use SilverStripe\Security\Member;
use SilverStripe\Security\RandomGenerator;
use SilverStripe\Security\Security;
/**
* Provides the ability to generate cryptographically secure tokens for comment moderation
*/
class SecurityToken
{
/**
* @var string
*/
private $secret = null;
/**
* @param Comment $comment Comment to generate this token for
*/
public function __construct($comment)
{
if (!$comment->SecretToken) {
$comment->SecretToken = $this->generate();
$comment->write();
}
$this->secret = $comment->SecretToken;
}
/**
* Generate the token for the given salt and current secret
*
* @param string $salt
*
* @return string
*/
protected function getToken($salt)
{
return hash_pbkdf2('sha256', $this->secret ?? '', $salt ?? '', 1000, 30);
}
/**
* Get the member-specific salt.
*
* The reason for making the salt specific to a user is that it cannot be "passed in" via a
* querystring, requiring the same user to be present at both the link generation and the
* controller action.
*
* @param string $salt Single use salt
* @param Member $member Member object
*
* @return string Generated salt specific to this member
*/
protected function memberSalt($salt, $member)
{
// Fallback to salting with ID in case the member has not one set
return $salt . ($member->Salt ?: $member->ID);
}
/**
* @param string $url Comment action URL
* @param Member $member Member to restrict access to this action to
*
* @return string
*/
public function addToUrl($url, $member)
{
$salt = $this->generate(15); // New random salt; Will be passed into url
// Generate salt specific to this member
$memberSalt = $this->memberSalt($salt, $member);
$token = $this->getToken($memberSalt);
return Controller::join_links(
$url,
sprintf(
'?t=%s&s=%s',
urlencode($token ?? ''),
urlencode($salt ?? '')
)
);
}
/**
* @param SS_HTTPRequest $request
*
* @return boolean
*/
public function checkRequest($request)
{
$member = Security::getCurrentUser();
if (!$member) {
return false;
}
$salt = $request->getVar('s');
$memberSalt = $this->memberSalt($salt, $member);
$token = $this->getToken($memberSalt);
// Ensure tokens match
return $token === $request->getVar('t');
}
/**
* Generates new random key
*
* @param integer $length
*
* @return string
*/
protected function generate($length = null)
{
$generator = new RandomGenerator();
$result = $generator->randomToken('sha256');
if ($length !== null) {
return substr($result ?? '', 0, $length);
}
return $result;
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace SilverStripe\Comments\Tasks;
use SilverStripe\Comments\Model\Comment;
use SilverStripe\Core\Config\Config;
use SilverStripe\Dev\BuildTask;
use SilverStripe\ORM\DB;
/**
* Migrates all 3.x comment's BaseClass fields to the new ParentClass fields
*
* @package comments
*/
class MigrateCommentParentsTask extends BuildTask
{
private static $segment = 'MigrateCommentParentsTask';
protected $title = 'Migrate Comment Parent classes from 3.x';
protected $description = 'Migrates all 3.x Comment BaseClass fields to the new ParentClass fields in 4.0';
/**
* @param HTTPRequest $request
*/
public function run($request)
{
// Check if anything needs to be done
$tableName = Comment::getSchema()->tableName(Comment::class);
if (!DB::get_schema()->hasField($tableName, 'BaseClass')) {
DB::alteration_message('"BaseClass" does not exist on "' . $tableName . '", nothing to upgrade.', 'notice');
return;
}
// Set the class names to fully qualified class names first
$remapping = Config::inst()->get('SilverStripe\\ORM\\DatabaseAdmin', 'classname_value_remapping');
$updateQuery = "UPDATE \"Comment\" SET \"BaseClass\" = ? WHERE \"BaseClass\" = ?";
foreach ($remapping as $old => $new) {
DB::prepared_query($updateQuery, [$new, $old]);
}
// Move these values to ParentClass (the 4.x column name)
DB::query('UPDATE "Comment" SET "ParentClass" = "BaseClass"');
DB::alteration_message('Finished updating any applicable Comment class columns', 'notice');
}
}

View File

@ -1,23 +0,0 @@
<% if $RepliesEnabled %>
<div class="comment-replies-container">
<div class="comment-reply-form-holder">
$ReplyForm
</div>
<div class="comment-replies-holder">
<% if $Replies %>
<ul class="comments-list level-{$Depth}">
<% loop $Replies %>
<li class="comment $EvenOdd<% if FirstLast %> $FirstLast <% end_if %> $SpamClass">
<% include CommentsInterface_singlecomment %>
</li>
<% end_loop %>
</ul>
<% with $Replies %>
<% include ReplyPagination %>
<% end_with %>
<% end_if %>
</div>
</div>
<% end_if %>

View File

@ -1,4 +1,4 @@
<% require themedCSS('comments', 'comments') %>
<% require themedCSS('client/dist/styles/comments', 'comments') %>
<% if $CommentsEnabled %>
<div id="$CommentHolderID" class="comments-holder-container">
@ -7,11 +7,11 @@
<% if $AddCommentForm %>
<% if $canPostComment %>
<% if $ModeratedSubmitted %>
<p id="moderated" class="message good"><% _t('CommentsInterface_ss.AWAITINGMODERATION', 'Your comment has been submitted and is now awaiting moderation.') %></p>
<p id="moderated" class="message good" tabindex="-1"><% _t('CommentsInterface_ss.AWAITINGMODERATION', 'Your comment has been submitted and is now awaiting moderation.') %></p>
<% end_if %>
$AddCommentForm
<% else %>
<p><% _t('CommentsInterface_ss.COMMENTLOGINERROR', 'You cannot post comments until you have logged in') %><% if $PostingRequiredPermission %>,<% _t('CommentsInterface_ss.COMMENTPERMISSIONERROR', 'and that you have an appropriate permission level') %><% end_if %>.
<p><% _t('CommentsInterface_ss.COMMENTLOGINERROR', 'You cannot post comments until you have logged in') %><% if $PostingRequiredPermission %>, <% _t('CommentsInterface_ss.COMMENTPERMISSIONERROR', 'and have an appropriate permission level') %><% end_if %>.
<a href="Security/login?BackURL={$Parent.Link}" title="<% _t('CommentsInterface_ss.LOGINTOPOSTCOMMENT', 'Login to post a comment') %>"><% _t('CommentsInterface_ss.COMMENTPOSTLOGIN', 'Login Here') %></a>.
</p>
<% end_if %>
@ -25,7 +25,7 @@
<% if $PagedComments %>
<ul class="comments-list root-level">
<% loop $PagedComments %>
<li class="comment $EvenOdd<% if FirstLast %> $FirstLast <% end_if %> $SpamClass">
<li class="comment $EvenOdd<% if $FirstLast %> $FirstLast <% end_if %> $SpamClass">
<% include CommentsInterface_singlecomment %>
</li>
<% end_loop %>

View File

@ -0,0 +1,25 @@
<% if $RepliesEnabled %>
<div class="comment-replies-container">
<% if $canPostComment %>
<div class="comment-reply-form-holder">
$ReplyForm
</div>
<% end_if %>
<div class="comment-replies-holder">
<% if $Replies %>
<ul class="comments-list level-{$Depth}">
<% loop $Replies %>
<li class="comment $EvenOdd<% if $FirstLast %> $FirstLast <% end_if %> $SpamClass">
<% include CommentsInterface_singlecomment %>
</li>
<% end_loop %>
</ul>
<% with $Replies %>
<% include ReplyPagination %>
<% end_with %>
<% end_if %>
</div>
</div>
<% end_if %>

View File

@ -11,7 +11,7 @@
<% if $Gravatar %>
<img class="gravatar" src="$Gravatar.ATT" alt="Gravatar for $Name.ATT" title="Gravatar for $Name.ATT" />
<% end_if %>
<div class="comment-text<% if $Gravatar %> hasGravatar<% end_if %>" id="<% if $isPreview %>comment-preview<% else %>$Permalink<% end_if %>">
<div class="comment-text<% if $Gravatar %> hasGravatar<% end_if %>" id="<% if $isPreview %>comment-preview<% else %>{$Permalink}-text<% end_if %>">
<p>$EscapedComment</p>
</div>
@ -20,20 +20,22 @@
<div class="comment-action-links">
<div class="comment-moderation-options">
<% if $ApproveLink %>
<a href="$ApproveLink.ATT" class="approve"><% _t('CommentsInterface_singlecomment_ss.APPROVE', 'approve it') %></a>
<a href="$ApproveLink.ATT" class="approve"><%t CommentsInterface_singlecomment_ss.APPROVE "Approve it" %></a>
<% end_if %>
<% if $SpamLink %>
<a href="$SpamLink.ATT" class="spam"><% _t('CommentsInterface_singlecomment_ss.ISSPAM','spam it') %></a>
<a href="$SpamLink.ATT" class="spam"><%t CommentsInterface_singlecomment_ss.ISSPAM "Spam it" %></a>
<% end_if %>
<% if $HamLink %>
<a href="$HamLink.ATT" class="ham"><% _t('CommentsInterface_singlecomment_ss.ISNTSPAM','not spam') %></a>
<a href="$HamLink.ATT" class="ham"><%t CommentsInterface_singlecomment_ss.ISNTSPAM "Not spam" %></a>
<% end_if %>
<% if $DeleteLink %>
<a href="$DeleteLink.ATT" class="delete"><% _t('CommentsInterface_singlecomment_ss.REMCOM','reject it') %></a>
<a href="$DeleteLink.ATT" class="delete"><%t CommentsInterface_singlecomment_ss.REMCOM "Reject it" %></a>
<% end_if %>
</div>
<% if $RepliesEnabled %>
<a class="comment-reply-link" href="#{$ReplyForm.FormName}"><% _t('CommentsInterface_singlecomment_ss.REPLYTO','Reply to') %> $AuthorName.XML</a>
<% if $RepliesEnabled && $canPostComment %>
<button class="comment-reply-link" type="button" aria-controls="$ReplyForm.FormName" aria-expanded="false">
<%t CommentsInterface_singlecomment_ss.REPLYTO "Reply to" %> $AuthorName.XML
</button>
<% end_if %>
</div>
<% end_if %>

View File

@ -1,59 +1,58 @@
<?php
namespace SilverStripe\Comments\Tests;
use SilverStripe\Comments\Admin\CommentAdmin;
use SilverStripe\Control\Session;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\i18n\i18n;
class CommentAdminTest extends SapphireTest
{
protected $usesDatabase = true;
public function testProvidePermissions()
{
$commentAdmin = new CommentAdmin();
$locale = i18n::get_locale();
$commentAdmin->getRequest()->setSession(new Session([]));
i18n::set_locale('fr');
$expected = array(
'CMS_ACCESS_CommentAdmin' => array(
# FIXME - this is a bug, missing from lang.yml files
'name' => 'Access to \'Comments\' section',
'category' => 'Accès au CMS'
)
$this->assertEquals(
'Accès au CMS',
$commentAdmin->providePermissions()['CMS_ACCESS_CommentAdmin']['category']
);
$this->assertEquals($expected, $commentAdmin->providePermissions());
i18n::set_locale($locale);
$expected = array(
'CMS_ACCESS_CommentAdmin' => array(
# FIXME - this is a bug, missing from lang.yml files
i18n::set_locale('en');
$expected = [
'CMS_ACCESS_CommentAdmin' => [
'name' => 'Access to \'Comments\' section',
'category' => 'CMS Access'
)
);
'category' => 'CMS Access',
]
];
$this->assertEquals($expected, $commentAdmin->providePermissions());
}
public function testGetEditForm()
{
$commentAdmin = new CommentAdmin();
$commentAdmin->getRequest()->setSession(new Session([]));
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
$form = $commentAdmin->getEditForm();
$names = $this->getFormFieldNames($form);
$expected = array(
$expected = [
'NewComments',
'ApprovedComments',
'SpamComments'
);
'SpamComments',
];
$this->assertEquals($expected, $names);
if ($member = Member::currentUser()) {
$member->logOut();
}
$form = $commentAdmin->getEditForm();
$this->logOut();
}
private function getFormFieldNames($form)
{
$result = array();
$result = [];
$fields = $form->Fields();
$tab = $fields->findOrMakeTab('Root');
$fields = $tab->FieldList();

View File

@ -1,145 +0,0 @@
<?php
class CommentListTest extends FunctionalTest
{
public static $fixture_file = 'comments/tests/CommentsTest.yml';
protected $extraDataObjects = array(
'CommentableItem',
'CommentableItemEnabled',
'CommentableItemDisabled'
);
public function setUp()
{
parent::setUp();
Config::nest();
// Set good default values
Config::inst()->update('CommentsExtension', 'comments', array(
'enabled' => true,
'enabled_cms' => false,
'require_login' => false,
'require_login_cms' => false,
'required_permission' => false,
'require_moderation_nonmembers' => false,
'require_moderation' => false,
'require_moderation_cms' => false,
'frontend_moderation' => false,
'frontend_spam' => false,
));
// Configure this dataobject
Config::inst()->update('CommentableItem', 'comments', array(
'enabled_cms' => true
));
}
public function tearDown()
{
Config::unnest();
parent::tearDown();
}
public function testGetForeignClass()
{
$item = $this->objFromFixture('CommentableItem', 'first');
// This is the class the Comments are related to
$this->assertEquals('CommentableItem',
$item->Comments()->getForeignClass());
}
public function testAddNonComment()
{
$item = $this->objFromFixture('CommentableItem', 'first');
$comments = $item->Comments();
$this->assertEquals(4, $comments->count());
$member = Member::get()->first();
try {
$comments->add($member);
$this->fail('Should not have been able to add member to comments');
} catch (InvalidArgumentException $e) {
$this->assertEquals(
'CommentList::add() expecting a Comment object, or ID value',
$e->getMessage()
);
}
}
public function testAddComment()
{
$item = $this->objFromFixture('CommentableItem', 'first');
$firstComment = $this->objFromFixture('Comment', 'firstComA');
$comments = $item->Comments();//->sort('Created');
foreach ($comments as $comment) {
error_log($comment->ID . ' ' . $comment->Created .' ' . $comment->Comment);
}
$this->assertEquals(4, $comments->count());
$newComment = new Comment();
$newComment->Name = 'Fred Bloggs';
$newComment->Comment = 'This is a test comment';
$newComment->write();
$comments->add($newComment);
// As a comment has been added, there should be 5 comments now
$this->assertEquals(5, $item->Comments()->count());
$newComment2 = new Comment();
$newComment2->Name = 'John Smith';
$newComment2->Comment = 'This is another test comment';
$newComment2->write();
// test adding the same comment by ID
$comments->add($newComment2->ID);
$this->assertEquals(6, $item->Comments()->count());
$this->setExpectedException(
'InvalidArgumentException',
"CommentList::add() can't be called until a single foreign ID is set"
);
$list = new CommentList('CommentableItem');
$list->add($newComment);
}
public function testRemoveComment()
{
// remove by comment
$item = $this->objFromFixture('CommentableItem', 'first');
$this->assertEquals(4, $item->Comments()->count());
$comments = $item->Comments();
$comment = $comments->first();
$comments->remove($comment);
// now remove by ID
$comments = $item->Comments();
$comment = $comments->first();
$comments->remove($comment->ID);
$this->assertEquals(2, $item->Comments()->count());
}
public function testRemoveNonComment()
{
$item = $this->objFromFixture('CommentableItem', 'first');
$this->assertEquals(4, $item->Comments()->count());
$comments = $item->Comments();
// try and remove a non comment
$member = Member::get()->first();
try {
$comments->remove($member);
$this->fail('Should not have been able to remove member from comments');
} catch (InvalidArgumentException $e) {
$this->assertEquals(
'CommentList::remove() expecting a Comment object, or ID',
$e->getMessage()
);
}
}
}

View File

@ -1,27 +1,28 @@
<?php
class CommentTestHelper
namespace SilverStripe\Comments\Tests;
use SilverStripe\Dev\TestOnly;
use SilverStripe\Forms\FieldGroup;
class CommentTestHelper implements TestOnly
{
/*
This only works if the last section is not a field group, e.g. a Comments
field group inside of a Root.Settings tab will not work
/**
* This only works if the last section is not a field group, e.g. a Comments
* field group inside of a Root.Settings tab will not work
*/
public static function assertFieldsForTab($context, $tabName, $expected, $fields)
{
$tab = $fields->findOrMakeTab($tabName);
$fields = $tab->FieldList();
CommentTestHelper::assertFieldNames($context, $expected, $fields);
self::assertFieldNames($context, $expected, $fields);
}
public static function assertFieldNames($context, $expected, $fields)
{
$actual = array();
foreach ($fields as $field) {
if (get_class($field) == 'FieldGroup') {
array_push($actual, $field->Name());
} else {
array_push($actual, $field->getName());
}
array_push($actual, $field->getName());
}
$context->assertEquals($expected, $actual);
}

View File

@ -1,57 +1,115 @@
<?php
/**
* @package comments
* @subpackage tests
*/
namespace SilverStripe\Comments\Tests;
use SilverStripe\Akismet\AkismetSpamProtector;
use SilverStripe\Comments\Controllers\CommentingController;
use SilverStripe\Comments\Model\Comment;
use SilverStripe\Comments\Model\Comment\SecurityToken as CommentSecurityToken;
use SilverStripe\Comments\Tests\Stubs\CommentableItem;
use SilverStripe\Control\Controller;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Dev\FunctionalTest;
use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
use SilverStripe\Security\SecurityToken;
use SilverStripe\Security\Security;
class CommentingControllerTest extends FunctionalTest
{
/**
* {@inheritDoc}
*/
protected static $fixture_file = 'CommentsTest.yml';
public static $fixture_file = 'CommentsTest.yml';
protected $extraDataObjects = array(
'CommentableItem'
);
/**
* {@inheritDoc}
*/
protected static $extra_dataobjects = [
CommentableItem::class
];
protected $securityEnabled;
public function tearDown()
protected function tearDown(): void
{
if ($this->securityEnabled) {
SecurityToken::enable();
SecurityToken::inst()->enable();
} else {
SecurityToken::disable();
SecurityToken::inst()->disable();
}
parent::tearDown();
}
public function setUp()
protected function setUp(): void
{
parent::setUp();
$this->securityEnabled = SecurityToken::is_enabled();
$this->securityEnabled = SecurityToken::inst()->is_enabled();
// We will assert against explicit responses, unless handed otherwise in a test for redirects
$this->autoFollowRedirection = false;
// Mock Akismet if it's installed
if (class_exists(AkismetSpamProtector::class)) {
$akismetMock = $this->createMock(AkismetSpamProtector::class);
Injector::inst()->registerService($akismetMock, AkismetSpamProtector::class);
}
}
public function testApprove()
public function testCommentsFormUsePreview()
{
SecurityToken::disable();
$parent = $this->objFromFixture(CommentableItem::class, 'first');
$commController = new CommentingController();
$commController->setOwnerRecord($parent);
$form = $commController->CommentsForm();
$commentsFields = $form->Fields()->first()->FieldList();
$expected = array('Name', 'Email', 'URL', 'Comment');
CommentTestHelper::assertFieldNames($this, $expected, $commentsFields);
// test with preview on
Config::modify()->merge(CommentableItem::class, 'comments', array(
'use_preview' => true
));
$parent = $this->objFromFixture(CommentableItem::class, 'first');
$commController = new CommentingController();
$commController->setOwnerRecord($parent);
$this->objFromFixture(Comment::class, 'firstComAChild1')->delete();
$this->objFromFixture(Comment::class, 'firstComAChild2')->delete();
$this->objFromFixture(Comment::class, 'firstComAChild3')->delete();
SecurityToken::inst()->disable();
$this->autoFollowRedirection = false;
$form = $commController->CommentsForm();
$commentsFields = $form->Fields()->first()->FieldList();
$expected = array('Name', 'Email', 'URL', 'Comment', 'PreviewComment');
CommentTestHelper::assertFieldNames($this, $expected, $commentsFields);
}
public function testApproveUnmoderatedComment()
{
SecurityToken::inst()->disable();
// mark a comment as spam then approve it
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment->markSpam();
$st = new Comment_SecurityToken($comment);
$url = 'CommentingController/approve/' . $comment->ID;
$url = $st->addToUrl($url, Member::currentUser());
$response = $this->get($url);
$this->assertEquals(200, $response->getStatusCode());
$comment = DataObject::get_by_id('Comment', $comment->ID);
$comment = $this->objFromFixture(Comment::class, 'testModeratedComment1');
$st = new CommentSecurityToken($comment);
$url = 'comments/approve/' . $comment->ID;
$url = $st->addToUrl($url, Security::getCurrentUser());
$response = $this->get($url, null, ['Referer' => '/']);
$this->assertEquals(302, $response->getStatusCode());
$comment = DataObject::get_by_id(Comment::class, $comment->ID);
// Need to use 0,1 here instead of false, true for SQLite
$this->assertEquals(0, $comment->IsSpam);
$this->assertEquals(1, $comment->Moderated);
// try and approve a non existent comment
$response = $this->get('CommentingController/approve/100000');
$response = $this->get('comments/approve/100000');
$this->assertEquals(404, $response->getStatusCode());
}
@ -66,25 +124,25 @@ class CommentingControllerTest extends FunctionalTest
public function testHam()
{
SecurityToken::disable();
SecurityToken::inst()->disable();
// mark a comment as spam then ham it
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$comment->markSpam();
$st = new Comment_SecurityToken($comment);
$url = 'CommentingController/ham/' . $comment->ID;
$url = $st->addToUrl($url, Member::currentUser());
$st = new CommentSecurityToken($comment);
$url = 'comments/ham/' . $comment->ID;
$url = $st->addToUrl($url, Security::getCurrentUser());
$response = $this->get($url);
$this->assertEquals(200, $response->getStatusCode());
$comment = DataObject::get_by_id('Comment', $comment->ID);
$this->assertEquals(302, $response->getStatusCode());
$comment = DataObject::get_by_id(Comment::class, $comment->ID);
// Need to use 0,1 here instead of false, true for SQLite
$this->assertEquals(0, $comment->IsSpam);
$this->assertEquals(1, $comment->Moderated);
// try and ham a non existent comment
$response = $this->get('CommentingController/ham/100000');
$response = $this->get('comments/ham/100000');
$this->assertEquals(404, $response->getStatusCode());
}
@ -92,55 +150,63 @@ class CommentingControllerTest extends FunctionalTest
{
// mark a comment as approved then spam it
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$comment->markApproved();
$st = new Comment_SecurityToken($comment);
$url = 'CommentingController/spam/' . $comment->ID;
$url = $st->addToUrl($url, Member::currentUser());
$st = new CommentSecurityToken($comment);
$url = 'comments/spam/' . $comment->ID;
$url = $st->addToUrl($url, Security::getCurrentUser());
$response = $this->get($url);
$this->assertEquals(200, $response->getStatusCode());
$comment = DataObject::get_by_id('Comment', $comment->ID);
$this->assertEquals(302, $response->getStatusCode());
$comment = DataObject::get_by_id(Comment::class, $comment->ID);
// Need to use 0,1 here instead of false, true for SQLite
$this->assertEquals(1, $comment->IsSpam);
$this->assertEquals(1, $comment->Moderated);
// try and spam a non existent comment
$response = $this->get('CommentingController/spam/100000');
$response = $this->get('comments/spam/100000');
$this->assertEquals(404, $response->getStatusCode());
}
public function testRSS()
{
// Delete the newly added children of firstComA so as not to have to recalculate values below
$this->objFromFixture('Comment', 'firstComAChild1')->delete();
$this->objFromFixture('Comment', 'firstComAChild2')->delete();
$this->objFromFixture('Comment', 'firstComAChild3')->delete();
$item = $this->objFromFixture('CommentableItem', 'first');
$this->objFromFixture(Comment::class, 'firstComAChild1')->delete();
$this->objFromFixture(Comment::class, 'firstComAChild2')->delete();
$this->objFromFixture(Comment::class, 'firstComAChild3')->delete();
$item = $this->objFromFixture(CommentableItem::class, 'first');
// comments sitewide
$response = $this->get('CommentingController/rss');
$this->assertEquals(10, substr_count($response->getBody(), "<item>"), "10 approved, non spam comments on page 1");
$response = $this->get('comments/rss');
$comment = "10 approved, non spam comments on page 1";
$this->assertEquals(10, substr_count($response->getBody() ?? '', "<item>"), $comment);
$response = $this->get('CommentingController/rss?start=10');
$this->assertEquals(4, substr_count($response->getBody(), "<item>"), "3 approved, non spam comments on page 2");
$response = $this->get('comments/rss?start=10');
$this->assertEquals(
4,
substr_count($response->getBody() ?? '', "<item>"),
"3 approved, non spam comments on page 2"
);
// all comments on a type
$response = $this->get('CommentingController/rss/CommentableItem');
$this->assertEquals(10, substr_count($response->getBody(), "<item>"));
$response = $this->get('comments/rss/SilverStripe-Comments-Tests-Stubs-CommentableItem');
$this->assertEquals(10, substr_count($response->getBody() ?? '', "<item>"));
$response = $this->get('CommentingController/rss/CommentableItem?start=10');
$this->assertEquals(4, substr_count($response->getBody(), "<item>"), "3 approved, non spam comments on page 2");
$response = $this->get('comments/rss/SilverStripe-Comments-Tests-Stubs-CommentableItem?start=10');
$this->assertEquals(
4,
substr_count($response->getBody() ?? '', "<item>"),
"3 approved, non spam comments on page 2"
);
// specific page
$response = $this->get('CommentingController/rss/CommentableItem/'.$item->ID);
$this->assertEquals(1, substr_count($response->getBody(), "<item>"));
$this->assertContains('<dc:creator>FA</dc:creator>', $response->getBody());
$response = $this->get('comments/rss/SilverStripe-Comments-Tests-Stubs-CommentableItem/'.$item->ID);
$this->assertEquals(1, substr_count($response->getBody() ?? '', "<item>"));
$this->assertStringContainsString('<dc:creator>FA</dc:creator>', $response->getBody());
// test accessing comments on a type that doesn't exist
$response = $this->get('CommentingController/rss/Fake');
$response = $this->get('comments/rss/Fake');
$this->assertEquals(404, $response->getStatusCode());
}
@ -151,8 +217,8 @@ class CommentingControllerTest extends FunctionalTest
$comment = $this->objFromFixture('Comment', 'firstComA');
$item = $this->objFromFixture('CommentableItem', 'first');
$st = new Comment_SecurityToken($comment);
$url = 'CommentingController/reply/' . $item->ID.'?ParentCommentID=' . $comment->ID;
$st = new CommentSecurityToken($comment);
$url = 'comments/reply/' . $item->ID.'?ParentCommentID=' . $comment->ID;
error_log($url);
$response = $this->get($url);
error_log(print_r($response,1));
@ -163,11 +229,11 @@ class CommentingControllerTest extends FunctionalTest
*/
/*
public function testCommentsFormLoadMemberData() {
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->set('CommentableItem', 'comments', array(
'use_preview' => false
));
$this->logInAs('visitor');
SecurityToken::disable();
SecurityToken::inst()->disable();
$parent = $this->objFromFixture('CommentableItem', 'first');
$parent->CommentsRequireLogin = true;
$parent->PostingRequiredPermission = true;
@ -182,98 +248,91 @@ class CommentingControllerTest extends FunctionalTest
}
*/
public function testCommentsFormUsePreview()
{
// test with preview on
Config::inst()->update('CommentableItem', 'comments', array(
'use_preview' => true
));
$this->objFromFixture('Comment', 'firstComAChild1')->delete();
$this->objFromFixture('Comment', 'firstComAChild2')->delete();
$this->objFromFixture('Comment', 'firstComAChild3')->delete();
SecurityToken::disable();
$this->autoFollowRedirection = false;
$parent = $this->objFromFixture('CommentableItem', 'first');
$commController = new CommentingController();
$commController->setOwnerRecord($parent);
$form = $commController->CommentsForm();
$commentsFields = $form->Fields()->first()->FieldList();
$expected = array('Name', 'Email', 'URL', 'Comment', 'PreviewComment');
CommentTestHelper::assertFieldNames($this, $expected, $commentsFields);
// Turn off preview. Assert lack of preview field
Config::inst()->update('CommentableItem', 'comments', array(
'use_preview' => false
));
$form = $commController->CommentsForm();
$commentsFields = $form->Fields()->first()->FieldList();
$expected = array('Name', 'Email', 'URL', 'Comment');
CommentTestHelper::assertFieldNames($this, $expected, $commentsFields);
}
public function testCommentsForm()
{
// Delete the newly added children of firstComA so as not to change this test
$this->objFromFixture('Comment', 'firstComAChild1')->delete();
$this->objFromFixture('Comment', 'firstComAChild2')->delete();
$this->objFromFixture('Comment', 'firstComAChild3')->delete();
$this->autoFollowRedirection = true;
SecurityToken::disable();
// Delete the newly added children of firstComA so as not to change this test
$this->objFromFixture(Comment::class, 'firstComAChild1')->delete();
$this->objFromFixture(Comment::class, 'firstComAChild2')->delete();
$this->objFromFixture(Comment::class, 'firstComAChild3')->delete();
SecurityToken::inst()->disable();
$this->autoFollowRedirection = false;
$parent = $this->objFromFixture('CommentableItem', 'first');
$parent = $this->objFromFixture(CommentableItem::class, 'first');
// Test posting to base comment
$response = $this->post('CommentingController/CommentsForm',
$response = $this->post(
'comments/CommentsForm',
array(
'Name' => 'Poster',
'Email' => 'guy@test.com',
'Comment' => 'My Comment',
'ParentID' => $parent->ID,
'BaseClass' => 'CommentableItem',
'ParentClassName' => CommentableItem::class,
'action_doPostComment' => 'Post'
)
);
$this->assertEquals(302, $response->getStatusCode());
$this->assertStringStartsWith('CommentableItem_Controller#comment-', $response->getHeader('Location'));
$this->assertDOSEquals(
array(array(
'Name' => 'Poster',
'Email' => 'guy@test.com',
'Comment' => 'My Comment',
'ParentID' => $parent->ID,
'BaseClass' => 'CommentableItem',
)),
// $this->assertStringStartsWith('CommentableItemController#comment-', $response->getHeader('Location'));
$this->assertListEquals(
array(
array(
'Name' => 'Poster',
'Email' => 'guy@test.com',
'Comment' => 'My Comment',
'ParentID' => $parent->ID,
'ParentClass' => CommentableItem::class,
)
),
Comment::get()->filter('Email', 'guy@test.com')
);
// Test posting to parent comment
$parentComment = $this->objFromFixture('Comment', 'firstComA');
$parentComment = $this->objFromFixture(Comment::class, 'firstComA');
$this->assertEquals(0, $parentComment->ChildComments()->count());
$response = $this->post(
'CommentingController/reply/'.$parentComment->ID,
'comments/reply/' . $parentComment->ID,
array(
'Name' => 'Test Author',
'Email' => 'test@test.com',
'Comment' => 'Making a reply to firstComA',
'ParentID' => $parent->ID,
'BaseClass' => 'CommentableItem',
'ParentClassName' => CommentableItem::class,
'ParentCommentID' => $parentComment->ID,
'action_doPostComment' => 'Post'
)
);
$this->assertEquals(302, $response->getStatusCode());
$this->assertStringStartsWith('CommentableItem_Controller#comment-', $response->getHeader('Location'));
$this->assertDOSEquals(array(array(
'Name' => 'Test Author',
'Email' => 'test@test.com',
'Comment' => 'Making a reply to firstComA',
'ParentID' => $parent->ID,
'BaseClass' => 'CommentableItem',
'ParentCommentID' => $parentComment->ID
)), $parentComment->ChildComments());
// $this->assertStringStartsWith('CommentableItemController#comment-', $response->getHeader('Location'));
$this->assertListEquals(
array(
array(
'Name' => 'Test Author',
'Email' => 'test@test.com',
'Comment' => 'Making a reply to firstComA',
'ParentID' => $parent->ID,
'ParentClass' => CommentableItem::class,
'ParentCommentID' => $parentComment->ID
)
),
$parentComment->ChildComments()
);
}
/**
* SS4 introduces namespaces. They don't work in URLs, so we encode and decode them here.
*/
public function testEncodeClassName()
{
$controller = new CommentingController;
$this->assertSame('SilverStripe-Comments-Model-Comment', $controller->encodeClassName(Comment::class));
}
public function testDecodeClassName()
{
$controller = new CommentingController;
$this->assertSame(Comment::class, $controller->decodeClassName('SilverStripe-Comments-Model-Comment'));
}
}

View File

@ -1,180 +0,0 @@
<?php
class CommentingTest extends SapphireTest
{
public function setUpOnce()
{
parent::setUpOnce();
}
public function testDeprecatedMethods()
{
$methods = array('add', 'remove', 'has_commenting');
foreach ($methods as $methodName) {
try {
Commenting::$methodName('Member');
} catch (PHPUnit_Framework_Error_Deprecated $e) {
$expected = 'Using Commenting:' . $methodName .' is deprecated.'
. ' Please use the config API instead';
$this->assertEquals($expected, $e->getMessage());
}
}
}
public function test_set_config_value()
{
// public static function set_config_value($class, $key, $value = false) {
Commenting::set_config_value(
'CommentableItem',
'comments_holder_id',
'commentable_item'
);
$config = Config::inst()->get(
'CommentableItem',
'comments'
);
$actual = $config['comments_holder_id'];
$this->assertEquals(
'commentable_item',
$actual
);
Commenting::set_config_value(
'all',
'comments_holder_id',
'all_items_actually_commentsextension'
);
$config = Config::inst()->get(
'CommentsExtension',
'comments'
);
$actual = $config['comments_holder_id'];
$this->assertEquals(
'all_items_actually_commentsextension',
$actual
);
}
public function test_get_config_value()
{
Config::inst()->update('CommentableItem', 'comments',
array(
'comments_holder_id' => 'commentable_item'
)
);
$this->assertEquals(
'commentable_item',
Commenting::get_config_value('CommentableItem', 'comments_holder_id')
);
Config::inst()->update('CommentsExtension', 'comments',
array(
'comments_holder_id' => 'comments_extension'
)
);
// if class is null, method uses the CommentsExtension property
$this->assertEquals(
'comments_extension',
Commenting::get_config_value(null, 'comments_holder_id')
);
$this->setExpectedException(
'InvalidArgumentException',
'Member does not have commenting enabled'
);
Commenting::get_config_value('Member', 'comments_holder_id');
}
public function test_config_value_equals()
{
Config::inst()->update('CommentableItem', 'comments',
array(
'comments_holder_id' => 'some_value'
)
);
$this->assertTrue(
Commenting::config_value_equals(
'CommentableItem',
'comments_holder_id',
'some_value'
)
);
$this->assertNull(
Commenting::config_value_equals(
'CommentableItem',
'comments_holder_id',
'not_some_value'
)
);
}
public function test_add()
{
Commenting::add('Member', array('comments_holder_id' => 'test_add_value'));
$config = Config::inst()->get(
'Member',
'comments'
);
$actual = $config['comments_holder_id'];
$this->assertEquals(
'test_add_value',
$actual
);
Commenting::add('Member');
$config = Config::inst()->get(
'Member',
'comments'
);
$actual = $config['comments_holder_id'];
// no settings updated
$this->assertEquals(
'test_add_value',
$actual
);
$this->setExpectedException('InvalidArgumentException', "\$settings needs to be an array or null");
Commenting::add('Member', 'illegal format, not an array');
}
public function test_can_member_post()
{
// logout
if ($member = Member::currentUser()) {
$member->logOut();
}
Config::inst()->update('CommentableItem', 'comments',
array(
'require_login' => false
)
);
$this->assertTrue(Commenting::can_member_post('CommentableItem'));
Config::inst()->update('CommentableItem', 'comments',
array(
'require_login' => true
)
);
$this->assertFalse(Commenting::can_member_post('CommentableItem'));
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
$this->assertTrue(Commenting::can_member_post('CommentableItem'));
Config::inst()->update('CommentableItem', 'comments',
array(
'require_login' => false
)
);
$this->assertTrue(Commenting::can_member_post('CommentableItem'));
}
}

View File

@ -1,23 +1,44 @@
<?php
class CommentsExtensionTest extends SapphireTest
namespace SilverStripe\Comments\Tests;
use SilverStripe\Comments\Extensions\CommentsExtension;
use SilverStripe\Comments\Model\Comment;
use SilverStripe\Comments\Tests\CommentTestHelper;
use SilverStripe\Comments\Tests\Stubs\CommentableItem;
use SilverStripe\Comments\Tests\Stubs\CommentableItemDisabled;
use SilverStripe\Comments\Tests\Stubs\CommentableItemEnabled;
use SilverStripe\Core\Config\Config;
use SilverStripe\Dev\FunctionalTest;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Security\Member;
use SilverStripe\View\Requirements;
use SilverStripe\Security\Security;
class CommentsExtensionTest extends FunctionalTest
{
protected static $fixture_file = 'CommentsTest.yml';
public static $fixture_file = 'comments/tests/CommentsTest.yml';
protected static $disable_themes = true;
protected $extraDataObjects = array(
'CommentableItem',
'CommentableItemEnabled',
'CommentableItemDisabled'
);
protected static $extra_dataobjects = [
CommentableItem::class,
CommentableItemEnabled::class,
CommentableItemDisabled::class,
];
public function setUp()
protected static $required_extensions = [
CommentableItem::class => [
CommentsExtension::class,
],
];
protected function setUp(): void
{
parent::setUp();
Config::nest();
// Set good default values
Config::inst()->update('CommentsExtension', 'comments', array(
Config::modify()->merge(CommentsExtension::class, 'comments', [
'enabled' => true,
'enabled_cms' => false,
'require_login' => false,
@ -28,22 +49,23 @@ class CommentsExtensionTest extends SapphireTest
'require_moderation_cms' => false,
'frontend_moderation' => false,
'Member' => false,
));
$this->requiredExtensions = array(
'CommentableItem' => 'CommentsExtension'
);
]);
// Configure this dataobject
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'enabled_cms' => true
));
]);
}
public function tearDown()
public function testGetCommentsOption()
{
Config::unnest();
parent::tearDown();
Config::modify()->merge(CommentableItem::class, 'comments', [
'comments_holder_id' => 'some-option'
]);
$item = $this->objFromFixture(CommentableItem::class, 'first');
$this->assertEquals('some-option', $item->getCommentsOption('comments_holder_id'));
}
public function testPopulateDefaults()
@ -60,7 +82,7 @@ class CommentsExtensionTest extends SapphireTest
{
// the 3 options take precedence in this order, executed if true
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', array(
'require_moderation_cms' => true,
'require_moderation' => true,
'require_moderation_nonmembers' => true
@ -68,29 +90,36 @@ class CommentsExtensionTest extends SapphireTest
// With require moderation CMS set to true, the value of the field
// 'ModerationRequired' is returned
$item = $this->objFromFixture('CommentableItem', 'first');
$item = $this->objFromFixture(CommentableItem::class, 'first');
$item->ModerationRequired = 'None';
$item->write();
$this->assertEquals('None', $item->getModerationRequired());
$item->ModerationRequired = 'Required';
$item->write();
$this->assertEquals('Required', $item->getModerationRequired());
$item->ModerationRequired = 'NonMembersOnly';
$item->write();
$this->assertEquals('NonMembersOnly', $item->getModerationRequired());
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', array(
'require_moderation_cms' => false,
'require_moderation' => true,
'require_moderation_nonmembers' => true
));
$this->assertEquals('Required', $item->getModerationRequired());
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', array(
'require_moderation_cms' => false,
'require_moderation' => false,
'require_moderation_nonmembers' => true
));
$this->assertEquals('NonMembersOnly', $item->getModerationRequired());
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', array(
'require_moderation_cms' => false,
'require_moderation' => false,
'require_moderation_nonmembers' => false
@ -100,24 +129,24 @@ class CommentsExtensionTest extends SapphireTest
public function testGetCommentsRequireLogin()
{
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', array(
'require_login_cms' => true
));
// With require moderation CMS set to true, the value of the field
// 'ModerationRequired' is returned
$item = $this->objFromFixture('CommentableItem', 'first');
$item = $this->objFromFixture(CommentableItem::class, 'first');
$item->CommentsRequireLogin = true;
$this->assertTrue($item->getCommentsRequireLogin());
$item->CommentsRequireLogin = false;
$this->assertFalse($item->getCommentsRequireLogin());
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', array(
'require_login_cms' => false,
'require_login' => false
));
$this->assertFalse($item->getCommentsRequireLogin());
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', array(
'require_login_cms' => false,
'require_login' => true
));
@ -126,33 +155,56 @@ class CommentsExtensionTest extends SapphireTest
public function testAllComments()
{
$this->markTestSkipped('TODO');
$item = $this->objFromFixture(CommentableItem::class, 'first');
$this->assertEquals(4, $item->AllComments()->count());
}
public function testAllVisibleComments()
{
$this->markTestSkipped('TODO');
$this->logOut();
$item = $this->objFromFixture(CommentableItem::class, 'second');
$this->assertEquals(2, $item->AllVisibleComments()->count());
}
public function testComments()
{
$this->markTestSkipped('TODO');
Config::modify()->merge(CommentableItem::class, 'comments', array(
'nested_comments' => false
));
$item = $this->objFromFixture(CommentableItem::class, 'first');
$this->assertEquals(4, $item->Comments()->count());
Config::modify()->merge(CommentableItem::class, 'comments', array(
'nested_comments' => true
));
$this->assertEquals(1, $item->Comments()->count());
}
public function testGetCommentsEnabled()
{
$this->markTestSkipped('TODO');
Config::modify()->merge(CommentableItem::class, 'comments', array(
'enabled_cms' => true
));
$item = $this->objFromFixture(CommentableItem::class, 'first');
$this->assertTrue($item->getCommentsEnabled());
$item->ProvideComments = 0;
$this->assertFalse($item->getCommentsEnabled());
}
public function testGetCommentHolderID()
{
$item = $this->objFromFixture('CommentableItem', 'first');
Config::inst()->update('CommentableItem', 'comments', array(
$item = $this->objFromFixture(CommentableItem::class, 'first');
Config::modify()->merge(CommentableItem::class, 'comments', array(
'comments_holder_id' => 'commentid_test1',
));
$this->assertEquals('commentid_test1', $item->getCommentHolderID());
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', array(
'comments_holder_id' => 'commtentid_test_another',
));
$this->assertEquals('commtentid_test_another', $item->getCommentHolderID());
@ -167,11 +219,11 @@ class CommentsExtensionTest extends SapphireTest
public function testCanModerateComments()
{
// ensure nobody logged in
if (Member::currentUser()) {
Member::currentUser()->logOut();
if (Security::getCurrentUser()) {
Security::getCurrentUser()->logOut();
}
$item = $this->objFromFixture('CommentableItem', 'first');
$item = $this->objFromFixture(CommentableItem::class, 'first');
$this->assertFalse($item->canModerateComments());
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
@ -180,98 +232,75 @@ class CommentsExtensionTest extends SapphireTest
public function testGetCommentRSSLink()
{
$item = $this->objFromFixture('CommentableItem', 'first');
$link = $item->getCommentRSSLink();
$this->assertEquals('/CommentingController/rss', $link);
}
Config::modify()->merge('SilverStripe\\Control\\Director', 'alternate_base_url', 'http://unittesting.local');
$item = $this->objFromFixture(CommentableItem::class, 'first');
$link = $item->getCommentRSSLink();
$this->assertEquals('http://unittesting.local/comments/rss', $link);
}
public function testGetCommentRSSLinkPage()
{
$item = $this->objFromFixture('CommentableItem', 'first');
Config::modify()->merge('SilverStripe\\Control\\Director', 'alternate_base_url', 'http://unittesting.local');
$item = $this->objFromFixture(CommentableItem::class, 'first');
$page = $item->getCommentRSSLinkPage();
$this->assertEquals(
'/CommentingController/rss/CommentableItem/' . $item->ID,
'http://unittesting.local/comments/rss/SilverStripe-Comments-Tests-Stubs-CommentableItem/' . $item->ID,
$page
);
}
public function testCommentsForm()
{
Config::inst()->update('CommentableItem', 'comments', array(
'include_js' => false
)
);
$item = $this->objFromFixture('CommentableItem', 'first');
$this->logInWithPermission('ADMIN');
Config::modify()->merge(CommentableItem::class, 'comments', array(
'include_js' => false,
'comments_holder_id' => 'comments-holder',
));
$item = $this->objFromFixture(CommentableItem::class, 'first');
// The comments form is HTML to do assertions by contains
$cf = $item->CommentsForm();
$expected = '<form id="Form_CommentsForm" action="/CommentingController'
. '/CommentsForm" method="post" enctype="application/x-www-form-urlenco'
. 'ded">';
$this->assertContains($expected, $cf);
$this->assertContains('<h4>Post your comment</h4>', $cf);
$cf = (string) $item->CommentsForm();
$expected = '/comments/CommentsForm/" method="POST" enctype="application/x-www-form-urlencoded">';
$this->assertStringContainsString($expected, $cf);
$this->assertStringContainsString('<h4>Post your comment</h4>', $cf);
// check the comments form exists
$expected = '<input type="text" name="Name" value="ADMIN User" class="text" id="Form_CommentsForm_Name" required="required"';
$this->assertContains($expected, $cf);
$expected = '<input type="text" name="Name"';
$this->assertStringContainsString($expected, $cf);
$expected = '<input type="email" name="Email" value="ADMIN@example.org" class="email text" id="Form_CommentsForm_Email"';
$this->assertContains($expected, $cf);
$expected = '<input type="email" name="Email"';
$this->assertStringContainsString($expected, $cf);
$expected = '<input type="text" name="URL" class="text" id="Form_CommentsForm_URL" data-msg-url="Please enter a valid URL"';
$this->assertContains($expected, $cf);
$expected = '<input type="text" name="URL"';
$this->assertStringContainsString($expected, $cf);
$expected = '<input type="hidden" name="ParentID" value="' . $item->ID . '" class="hidden" id="Form_CommentsForm_ParentID" />';
$this->assertContains($expected, $cf);
$expected = '<input type="hidden" name="ParentID"';
$this->assertStringContainsString($expected, $cf);
$expected = '<textarea name="Comment" class="textarea" id="Form_CommentsForm_Comment" required="required"';
$this->assertContains($expected, $cf);
$expected = '<textarea name="Comment"';
$this->assertStringContainsString($expected, $cf);
$expected = '<input type="submit" name="action_doPostComment" value="Post" class="action" id="Form_CommentsForm_action_doPostComment"';
$this->assertContains($expected, $cf);
$expected = '<input type="submit" name="action_doPostComment" value="Post" class="action"';
$this->assertStringContainsString($expected, $cf);
$expected = '<a href="/CommentingController/spam/';
$this->assertContains($expected, $cf);
$expected = '/comments/spam/';
$this->assertStringContainsString($expected, $cf);
$expected = '<p>Reply to firstComA 1</p>';
$this->assertContains($expected, $cf);
$this->assertStringContainsString($expected, $cf);
$expected = '<a href="/CommentingController/delete';
$this->assertContains($expected, $cf);
$expected = '/comments/delete';
$this->assertStringContainsString($expected, $cf);
$expected = '<p>Reply to firstComA 2</p>';
$this->assertContains($expected, $cf);
$this->assertStringContainsString($expected, $cf);
$expected = '<p>Reply to firstComA 3</p>';
$this->assertContains($expected, $cf);
// Check for JS inclusion
$backend = Requirements::backend();
$this->assertEquals(
array(),
$backend->get_javascript()
);
Config::inst()->update('CommentableItem', 'comments', array(
'include_js' => true
)
);
$cf = $item->CommentsForm();
$backend = Requirements::backend();
$this->assertEquals(
array(
'framework/thirdparty/jquery/jquery.js',
'framework/thirdparty/jquery-entwine/dist/jquery.entwine-dist.js',
'framework/thirdparty/jquery-validate/lib/jquery.form.js',
'comments/thirdparty/jquery-validate/jquery.validate.min.js',
'framework/javascript/i18n.js',
'comments/javascript/lang/en.js',
'comments/javascript/CommentsInterface.js'
),
$backend->get_javascript()
);
$this->assertStringContainsString($expected, $cf);
}
public function testAttachedToSiteTree()
@ -281,7 +310,7 @@ class CommentsExtensionTest extends SapphireTest
public function testPagedComments()
{
$item = $this->objFromFixture('CommentableItem', 'first');
$item = $this->objFromFixture(CommentableItem::class, 'first');
// Ensure Created times are set, as order not guaranteed if all set to 0
$comments = $item->PagedComments()->sort('ID');
$ctr = 0;
@ -299,28 +328,23 @@ class CommentsExtensionTest extends SapphireTest
}
$this->assertEquals(
$this->objFromFixture('Comment', 'firstComA')->Comment,
$this->objFromFixture(Comment::class, 'firstComA')->Comment,
$results[3]->Comment
);
$this->assertEquals(
$this->objFromFixture('Comment', 'firstComAChild1')->Comment,
$this->objFromFixture(Comment::class, 'firstComAChild1')->Comment,
$results[2]->Comment
);
$this->assertEquals(
$this->objFromFixture('Comment', 'firstComAChild2')->Comment,
$this->objFromFixture(Comment::class, 'firstComAChild2')->Comment,
$results[1]->Comment
);
$this->assertEquals(
$this->objFromFixture('Comment', 'firstComAChild3')->Comment,
$this->objFromFixture(Comment::class, 'firstComAChild3')->Comment,
$results[0]->Comment
);
$this->assertEquals(4, sizeof($results));
}
public function testGetCommentsOption()
{
$this->markTestSkipped('TODO');
$this->assertEquals(4, sizeof($results ?? []));
}
public function testUpdateModerationFields()
@ -330,37 +354,46 @@ class CommentsExtensionTest extends SapphireTest
public function testUpdateCMSFields()
{
Config::inst()->update('CommentableItem', 'comments', array(
'require_login_cms' => false
Config::modify()->merge(
CommentableItem::class,
'comments',
array(
'require_login_cms' => false
)
);
$this->logInWithPermission('ADMIN');
$item = $this->objFromFixture('CommentableItem', 'first');
$item = $this->objFromFixture(CommentableItem::class, 'first');
$item->ProvideComments = true;
$item->write();
$fields = $item->getCMSFields();
CommentTestHelper::assertFieldsForTab($this, 'Root.Comments',
array('CommentsNewCommentsTab', 'CommentsCommentsTab', 'CommentsSpamCommentsTab'),
$fields
);
// print_r($item->getCMSFields());
CommentTestHelper::assertFieldsForTab($this, 'Root.Comments.CommentsNewCommentsTab',
CommentTestHelper::assertFieldsForTab(
$this,
'Root.Comments.CommentsNewCommentsTab',
array('NewComments'),
$fields
);
CommentTestHelper::assertFieldsForTab($this, 'Root.Comments.CommentsCommentsTab',
CommentTestHelper::assertFieldsForTab(
$this,
'Root.Comments.CommentsCommentsTab',
array('ApprovedComments'),
$fields
);
CommentTestHelper::assertFieldsForTab($this, 'Root.Comments.CommentsSpamCommentsTab',
CommentTestHelper::assertFieldsForTab(
$this,
'Root.Comments.CommentsSpamCommentsTab',
array('SpamComments'),
$fields
);
Config::inst()->update('CommentableItem', 'comments', array(
'require_login_cms' => true
Config::modify()->merge(
CommentableItem::class,
'comments',
array(
'require_login_cms' => true
)
);
$fields = $item->getCMSFields();
@ -376,9 +409,12 @@ class CommentsExtensionTest extends SapphireTest
$fields
);
Config::inst()->update('CommentableItem', 'comments', array(
'require_login_cms' => true,
'require_moderation_cms' => true
Config::modify()->merge(
CommentableItem::class,
'comments',
array(
'require_login_cms' => true,
'require_moderation_cms' => true
)
);
@ -386,7 +422,8 @@ class CommentsExtensionTest extends SapphireTest
CommentTestHelper::assertFieldsForTab(
$this,
'Root.Settings',
array('Comments', 'ModerationRequired'), $fields
array('Comments', 'ModerationRequired'),
$fields
);
$settingsTab = $fields->findOrMakeTab('Root.Settings');
$settingsChildren = $settingsTab->getChildren();
@ -399,32 +436,4 @@ class CommentsExtensionTest extends SapphireTest
$fields
);
}
public function testDeprecatedMethods()
{
$item = $this->objFromFixture('CommentableItem', 'first');
$methodNames = array(
'getRssLinkPage',
'getRssLink',
'PageComments',
'getPostingRequiresPermission',
'canPost',
'getCommentsConfigured'
);
foreach ($methodNames as $methodName) {
try {
$item->$methodName();
$this->fail('Method ' . $methodName .' should be depracated');
} catch (PHPUnit_Framework_Error_Deprecated $e) {
$expected = 'CommentsExtension->' . $methodName . ' is '.
'deprecated.';
$this->assertStringStartsWith($expected, $e->getMessage());
}
}
// ooh, $this->setExpectedException('ExpectedException', 'Expected Message');
}
}

View File

@ -1,7 +1,33 @@
<?php
namespace SilverStripe\Comments\Tests;
use SilverStripe\Comments\Admin\CommentAdmin;
use SilverStripe\Comments\Admin\CommentsGridField;
use SilverStripe\Comments\Admin\CommentsGridFieldAction;
use SilverStripe\Comments\Admin\CommentsGridFieldConfig;
use SilverStripe\Comments\Model\Comment;
use SilverStripe\Comments\Tests\Stubs\CommentableItem;
use SilverStripe\Comments\Tests\Stubs\Team;
use SilverStripe\Control\Controller;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldDeleteAction;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject;
use SilverStripe\Dev\Deprecation;
class CommentsGridFieldActionTest extends SapphireTest
{
protected $usesDatabase = true;
protected static $extra_dataobjects = [
CommentableItem::class,
Team::class,
];
/** @var ArrayList */
protected $list;
@ -12,13 +38,16 @@ class CommentsGridFieldActionTest extends SapphireTest
/** @var Form */
protected $form;
public function setUp()
protected function setUp(): void
{
parent::setUp();
$this->list = new DataList('GridFieldAction_Delete_Team');
if (Deprecation::isEnabled()) {
$this->markTestSkipped('Test calls deprecated code');
}
$this->list = new DataList(Team::class);
$config = CommentsGridFieldConfig::create()->addComponent(new GridFieldDeleteAction());
$this->gridField = new CommentsGridField('testfield', 'testfield', $this->list, $config);
$this->form = new Form(new Controller(), 'mockform', new FieldList(array($this->gridField)), new FieldList());
$this->form = new Form(new CommentAdmin(), 'mockform', new FieldList(array($this->gridField)), new FieldList());
}
public function testAugmentColumns()
@ -41,7 +70,7 @@ class CommentsGridFieldActionTest extends SapphireTest
{
$action = new CommentsGridFieldAction();
$record = new Comment();
$attrs = $action->getColumnAttributes($this->gridField, $record, 'Comment');
$attrs = $action->getColumnAttributes($this->gridField, $record, Comment::class);
$this->assertEquals(array('class' => 'col-buttons'), $attrs);
}
@ -70,30 +99,28 @@ class CommentsGridFieldActionTest extends SapphireTest
$record->Comment = 'This is a comment';
$record->write();
$recordID = $record->ID;
$html = $action->getColumnContent($this->gridField, $record, 'Comment');
$this->assertContains('data-url="Controller/mockform/field/testfield',
$html);
$spamAction = 'value="Spam" class="action" id="action_CustomAction' .
$recordID . 'Spam"';
$this->assertContains($spamAction, $html);
$html = $action->getColumnContent($this->gridField, $record, Comment::class);
$this->assertStringContainsString('data-url="admin/comments/mockform/field/testfield', $html);
$approveAction = 'value="Approve" class="action" id="action_CustomAction' .
$recordID . 'Approve"';
$this->assertContains($approveAction, $html);
$this->assertStringContainsString('value="Spam"', $html);
$this->assertStringContainsString('id="action_CustomAction' . $recordID . 'Spam"', $html);
$this->assertStringContainsString('value="Approve"', $html);
$this->assertStringContainsString('id="action_CustomAction' . $recordID . 'Approve"', $html);
// If marked as spam, only the approve button should be available
$record->markSpam();
$record->write();
$html = $action->getColumnContent($this->gridField, $record, 'Comment');
$this->assertContains($approveAction, $html);
$this->assertNotContains($spamAction, $html);
$html = $action->getColumnContent($this->gridField, $record, Comment::class);
$this->assertStringContainsString('value="Approve"', $html);
$this->assertStringNotContainsString('value="Spam"', $html);
// If marked as spam, only the approve button should be available
$record->markApproved();
$record->write();
$html = $action->getColumnContent($this->gridField, $record, 'Comment');
$this->assertNotContains($approveAction, $html);
$this->assertContains($spamAction, $html);
$html = $action->getColumnContent($this->gridField, $record, Comment::class);
$this->assertStringNotContainsString('value="Approve"', $html);
$this->assertStringContainsString('value="Spam"', $html);
}
public function testGetActions()
@ -103,13 +130,18 @@ class CommentsGridFieldActionTest extends SapphireTest
$this->assertEquals(array('spam', 'approve'), $result);
}
public function testHandleAction()
{
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
$item = new CommentableItem;
$item->write();
$action = new CommentsGridFieldAction();
$record = new Comment();
$record->Name = 'Name of commeter';
$record->Name = 'Name of commenter';
$record->Comment = 'This is a comment';
$record->ParentID = $item->ID;
$record->ParentClass = $item->class;
$record->write();
$recordID = $record->ID;
$arguments = array('RecordID' => $recordID);
@ -120,11 +152,11 @@ class CommentsGridFieldActionTest extends SapphireTest
'Comment marked as spam.',
Controller::curr()->getResponse()->getStatusDescription()
);
$record = DataObject::get_by_id('Comment', $recordID);
$record = DataObject::get_by_id(Comment::class, $recordID);
$this->assertEquals(1, $record->Moderated);
$this->assertEquals(1, $record->IsSpam);
//getStatusDescription
//getStatusDescription
$result = $action->handleAction($this->gridField, 'approve', $arguments, $data);
$this->assertEquals(200, Controller::curr()->getResponse()->getStatusCode());
$this->assertEquals(
@ -132,10 +164,8 @@ class CommentsGridFieldActionTest extends SapphireTest
Controller::curr()->getResponse()->getStatusDescription()
);
$record = DataObject::get_by_id('Comment', $recordID);
$record = DataObject::get_by_id(Comment::class, $recordID);
$this->assertEquals(1, $record->Moderated);
$this->assertEquals(0, $record->IsSpam);
error_log(Controller::curr()->getResponse()->getStatusCode());
}
}

View File

@ -1,5 +1,9 @@
<?php
namespace SilverStripe\Comments\Tests;
use SilverStripe\Dev\SapphireTest;
class CommentsGridFieldBulkActionTest extends SapphireTest
{
public function testSpam()

View File

@ -1,10 +1,14 @@
<?php
namespace SilverStripe\Comments\Tests;
use SilverStripe\Dev\SapphireTest;
class CommentsGridFieldConfigTest extends SapphireTest
{
public function test__construct()
public function testConstruct()
{
$config = new CommentsGridFieldConfigTest();
// $config = new CommentsGridFieldConfigTest();
$this->markTestSkipped('TODO');
}
}

View File

@ -1,17 +1,24 @@
<?php
namespace SilverStripe\Comments\Tests;
use ReflectionClass;
use ReflectionException;
use SilverStripe\Comments\Model\Comment;
use SilverStripe\Comments\Admin\CommentsGridField;
use SilverStripe\Dev\SapphireTest;
class CommentsGridFieldTest extends SapphireTest
{
public function testNewRow()
{
$gridfield = new CommentsGridField('testfield', 'testfield');
// protected function newRow($total, $index, $record, $attributes, $content) {
$comment = new Comment();
// protected function newRow($total, $index, $record, $attributes, $content) {
$comment = new Comment();
$comment->Name = 'Fred Bloggs';
$comment->Comment = 'This is a comment';
$attr = array();
try {
$class = new ReflectionClass($gridfield);
$method = $class->getMethod('newRow');

View File

@ -1,107 +1,95 @@
<?php
/**
* @package comments
*/
namespace SilverStripe\Comments\Tests;
use HTMLPurifier;
use HTMLPurifier_Config;
use ReflectionClass;
use SilverStripe\Comments\Extensions\CommentsExtension;
use SilverStripe\Comments\Model\Comment;
use SilverStripe\Comments\Tests\Stubs\CommentableItem;
use SilverStripe\Comments\Tests\Stubs\CommentableItemDisabled;
use SilverStripe\Comments\Tests\Stubs\CommentableItemEnabled;
use SilverStripe\Core\Config\Config;
use SilverStripe\Dev\FunctionalTest;
use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
use SilverStripe\Security\Security;
class CommentsTest extends FunctionalTest
{
protected static $fixture_file = 'CommentsTest.yml';
public static $fixture_file = 'comments/tests/CommentsTest.yml';
protected static $extra_dataobjects = [
CommentableItem::class,
CommentableItemEnabled::class,
CommentableItemDisabled::class,
];
protected $extraDataObjects = array(
'CommentableItem',
'CommentableItemEnabled',
'CommentableItemDisabled'
);
public function setUp()
protected function setUp(): void
{
parent::setUp();
Config::nest();
// Set good default values
Config::inst()->update('CommentsExtension', 'comments', array(
Config::modify()->merge(CommentsExtension::class, 'comments', [
'enabled' => true,
'enabled_cms' => false,
'require_login' => false,
'require_login_cms' => false,
'required_permission' => false,
'require_moderation_nonmembers' => false,
'require_moderation' => false,
'require_moderation_cms' => false,
'frontend_moderation' => false,
'frontend_spam' => false,
));
// Configure this dataobject
Config::inst()->update('CommentableItem', 'comments', array(
'enabled_cms' => true
));
}
public function tearDown()
{
Config::unnest();
parent::tearDown();
'comment_permalink_prefix' => 'comment-',
]);
}
public function testCommentsList()
{
// comments don't require moderation so unmoderated comments can be
// shown but not spam posts
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'require_moderation_nonmembers' => false,
'require_moderation' => false,
'require_moderation_cms' => false,
));
]);
$item = $this->objFromFixture('CommentableItem', 'spammed');
$this->assertEquals('None', $item->ModerationRequired);
$item = $this->objFromFixture(CommentableItem::class, 'spammed');
$this->assertDOSEquals(array(
array('Name' => 'Comment 1'),
array('Name' => 'Comment 3')
), $item->Comments(), 'Only 2 non spam posts should be shown');
$this->assertListEquals([
['Name' => 'Comment 1'],
['Name' => 'Comment 3']
], $item->Comments(), 'Only 2 non spam posts should be shown');
// when moderated, only moderated, non spam posts should be shown.
Config::inst()->update('CommentableItem', 'comments', array('require_moderation_nonmembers' => true));
$this->assertEquals('NonMembersOnly', $item->ModerationRequired);
Config::modify()->merge(CommentableItem::class, 'comments', ['require_moderation_nonmembers' => true]);
// Check that require_moderation overrides this option
Config::inst()->update('CommentableItem', 'comments', array('require_moderation' => true));
$this->assertEquals('Required', $item->ModerationRequired);
Config::modify()->merge(CommentableItem::class, 'comments', ['require_moderation' => true]);
$this->assertDOSEquals(array(
$this->assertListEquals(array(
array('Name' => 'Comment 3')
), $item->Comments(), 'Only 1 non spam, moderated post should be shown');
$this->assertEquals(1, $item->Comments()->Count());
// require_moderation_nonmembers still filters out unmoderated comments
Config::inst()->update('CommentableItem', 'comments', array('require_moderation' => false));
Config::modify()->merge(CommentableItem::class, 'comments', ['require_moderation' => false]);
$this->assertEquals(1, $item->Comments()->Count());
Config::inst()->update('CommentableItem', 'comments', array('require_moderation_nonmembers' => false));
Config::modify()->merge(CommentableItem::class, 'comments', ['require_moderation_nonmembers' => false]);
$this->assertEquals(2, $item->Comments()->Count());
// With unmoderated comments set to display in frontend
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'require_moderation' => true,
'frontend_moderation' => true
));
'frontend_moderation' => true,
]);
$this->assertEquals(1, $item->Comments()->Count());
$this->logInWithPermission('ADMIN');
$this->assertEquals(2, $item->Comments()->Count());
// With spam comments set to display in frontend
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'require_moderation' => true,
'frontend_moderation' => false,
'frontend_spam' => true,
));
if ($member = Member::currentUser()) {
$member->logOut();
}
]);
$this->logOut();
$this->assertEquals(1, $item->Comments()->Count());
$this->logInWithPermission('ADMIN');
@ -109,14 +97,13 @@ class CommentsTest extends FunctionalTest
// With spam and unmoderated comments set to display in frontend
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'require_moderation' => true,
'frontend_moderation' => true,
'frontend_spam' => true,
));
if ($member = Member::currentUser()) {
$member->logOut();
}
]);
$this->logOut();
$this->assertEquals(1, $item->Comments()->Count());
$this->logInWithPermission('ADMIN');
@ -128,34 +115,34 @@ class CommentsTest extends FunctionalTest
*/
public function testCommentCMSModerationList()
{
// comments don't require moderation so unmoderated comments can be
// shown but not spam posts
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'require_moderation' => true,
'require_moderation_cms' => true,
));
]);
$item = $this->objFromFixture('CommentableItem', 'spammed');
$this->assertEquals('None', $item->ModerationRequired);
$item = $this->objFromFixture(CommentableItem::class, 'spammed');
$this->assertDOSEquals(array(
array('Name' => 'Comment 1'),
array('Name' => 'Comment 3')
), $item->Comments(), 'Only 2 non spam posts should be shown');
$this->assertEquals('None', $item->getModerationRequired());
$this->assertListEquals([
['Name' => 'Comment 1'],
['Name' => 'Comment 3']
], $item->Comments(), 'Only 2 non spam posts should be shown');
// when moderated, only moderated, non spam posts should be shown.
$item->ModerationRequired = 'NonMembersOnly';
$item->write();
$this->assertEquals('NonMembersOnly', $item->ModerationRequired);
$this->assertEquals('NonMembersOnly', $item->getModerationRequired());
// Check that require_moderation overrides this option
$item->ModerationRequired = 'Required';
$item->write();
$this->assertEquals('Required', $item->ModerationRequired);
$this->assertEquals('Required', $item->getModerationRequired());
$this->assertDOSEquals(array(
array('Name' => 'Comment 3')
), $item->Comments(), 'Only 1 non spam, moderated post should be shown');
$this->assertListEquals([
['Name' => 'Comment 3']
], $item->Comments(), 'Only 1 non spam, moderated post should be shown');
$this->assertEquals(1, $item->Comments()->Count());
// require_moderation_nonmembers still filters out unmoderated comments
@ -170,26 +157,26 @@ class CommentsTest extends FunctionalTest
public function testCanPostComment()
{
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'require_login' => false,
'require_login_cms' => false,
'required_permission' => false,
));
$item = $this->objFromFixture('CommentableItem', 'first');
$item2 = $this->objFromFixture('CommentableItem', 'second');
]);
/** @var CommentableItem&CommentsExtension $item */
$item = $this->objFromFixture(CommentableItem::class, 'first');
/** @var CommentableItem&CommentsExtension $item2 */
$item2 = $this->objFromFixture(CommentableItem::class, 'second');
// Test restriction free commenting
if ($member = Member::currentUser()) {
$member->logOut();
}
$this->logOut();
$this->assertFalse($item->CommentsRequireLogin);
$this->assertTrue($item->canPostComment());
// Test permission required to post
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'require_login' => true,
'required_permission' => 'POSTING_PERMISSION',
));
]);
$this->assertTrue($item->CommentsRequireLogin);
$this->assertFalse($item->canPostComment());
$this->logInWithPermission('WRONG_ONE');
@ -200,27 +187,25 @@ class CommentsTest extends FunctionalTest
$this->assertTrue($item->canPostComment());
// Test require login to post, but not any permissions
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'required_permission' => false,
));
]);
$this->assertTrue($item->CommentsRequireLogin);
if ($member = Member::currentUser()) {
$member->logOut();
}
$this->logOut();
$this->assertFalse($item->canPostComment());
$this->logInWithPermission('ANY_PERMISSION');
$this->assertTrue($item->canPostComment());
// Test options set via CMS
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'require_login' => true,
'require_login_cms' => true,
));
]);
$this->assertFalse($item->CommentsRequireLogin);
$this->assertTrue($item2->CommentsRequireLogin);
if ($member = Member::currentUser()) {
$member->logOut();
}
$this->logOut();
$this->assertTrue($item->canPostComment());
$this->assertFalse($item2->canPostComment());
@ -232,15 +217,13 @@ class CommentsTest extends FunctionalTest
public function testDeleteComment()
{
// Test anonymous user
if ($member = Member::currentUser()) {
$member->logOut();
}
$comment = $this->objFromFixture('Comment', 'firstComA');
$this->logOut();
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$commentID = $comment->ID;
$this->assertNull($comment->DeleteLink(), 'No permission to see delete link');
$delete = $this->get('CommentingController/delete/'.$comment->ID.'?ajax=1');
$delete = $this->get('comments/delete/' . $comment->ID . '?ajax=1');
$this->assertEquals(403, $delete->getStatusCode());
$check = DataObject::get_by_id('Comment', $commentID);
$check = DataObject::get_by_id(Comment::class, $commentID);
$this->assertTrue($check && $check->exists());
// Test non-authenticated user
@ -249,16 +232,16 @@ class CommentsTest extends FunctionalTest
// Test authenticated user
$this->logInAs('commentadmin');
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$commentID = $comment->ID;
$adminComment1Link = $comment->DeleteLink();
$this->assertContains('CommentingController/delete/'.$commentID.'?t=', $adminComment1Link);
$this->assertStringContainsString('comments/delete/' . $commentID . '?t=', $adminComment1Link);
// Test that this link can't be shared / XSS exploited
$this->logInAs('commentadmin2');
$delete = $this->get($adminComment1Link);
$this->assertEquals(400, $delete->getStatusCode());
$check = DataObject::get_by_id('Comment', $commentID);
$check = DataObject::get_by_id(Comment::class, $commentID);
$this->assertTrue($check && $check->exists());
// Test that this other admin can delete the comment with their own link
@ -267,22 +250,20 @@ class CommentsTest extends FunctionalTest
$this->autoFollowRedirection = false;
$delete = $this->get($adminComment2Link);
$this->assertEquals(302, $delete->getStatusCode());
$check = DataObject::get_by_id('Comment', $commentID);
$check = DataObject::get_by_id(Comment::class, $commentID);
$this->assertFalse($check && $check->exists());
}
public function testSpamComment()
{
// Test anonymous user
if ($member = Member::currentUser()) {
$member->logOut();
}
$comment = $this->objFromFixture('Comment', 'firstComA');
$this->logOut();
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$commentID = $comment->ID;
$this->assertNull($comment->SpamLink(), 'No permission to see mark as spam link');
$spam = $this->get('CommentingController/spam/'.$comment->ID.'?ajax=1');
$spam = $this->get('comments/spam/' . $comment->ID . '?ajax=1');
$this->assertEquals(403, $spam->getStatusCode());
$check = DataObject::get_by_id('Comment', $commentID);
$check = DataObject::get_by_id(Comment::class, $commentID);
$this->assertEquals(0, $check->IsSpam, 'No permission to mark as spam');
// Test non-authenticated user
@ -291,16 +272,16 @@ class CommentsTest extends FunctionalTest
// Test authenticated user
$this->logInAs('commentadmin');
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$commentID = $comment->ID;
$adminComment1Link = $comment->SpamLink();
$this->assertContains('CommentingController/spam/'.$commentID.'?t=', $adminComment1Link);
$this->assertStringContainsString('comments/spam/' . $commentID . '?t=', $adminComment1Link);
// Test that this link can't be shared / XSS exploited
$this->logInAs('commentadmin2');
$spam = $this->get($adminComment1Link);
$this->assertEquals(400, $spam->getStatusCode());
$check = DataObject::get_by_id('Comment', $comment->ID);
$check = DataObject::get_by_id(Comment::class, $comment->ID);
$this->assertEquals(0, $check->IsSpam, 'No permission to mark as spam');
// Test that this other admin can spam the comment with their own link
@ -309,7 +290,7 @@ class CommentsTest extends FunctionalTest
$this->autoFollowRedirection = false;
$spam = $this->get($adminComment2Link);
$this->assertEquals(302, $spam->getStatusCode());
$check = DataObject::get_by_id('Comment', $commentID);
$check = DataObject::get_by_id(Comment::class, $commentID);
$this->assertEquals(1, $check->IsSpam);
// Cannot re-spam spammed comment
@ -319,15 +300,13 @@ class CommentsTest extends FunctionalTest
public function testHamComment()
{
// Test anonymous user
if ($member = Member::currentUser()) {
$member->logOut();
}
$comment = $this->objFromFixture('Comment', 'secondComC');
$this->logOut();
$comment = $this->objFromFixture(Comment::class, 'secondComC');
$commentID = $comment->ID;
$this->assertNull($comment->HamLink(), 'No permission to see mark as ham link');
$ham = $this->get('CommentingController/ham/'.$comment->ID.'?ajax=1');
$ham = $this->get('comments/ham/' . $comment->ID . '?ajax=1');
$this->assertEquals(403, $ham->getStatusCode());
$check = DataObject::get_by_id('Comment', $commentID);
$check = DataObject::get_by_id(Comment::class, $commentID);
$this->assertEquals(1, $check->IsSpam, 'No permission to mark as ham');
// Test non-authenticated user
@ -336,16 +315,16 @@ class CommentsTest extends FunctionalTest
// Test authenticated user
$this->logInAs('commentadmin');
$comment = $this->objFromFixture('Comment', 'secondComC');
$comment = $this->objFromFixture(Comment::class, 'secondComC');
$commentID = $comment->ID;
$adminComment1Link = $comment->HamLink();
$this->assertContains('CommentingController/ham/'.$commentID.'?t=', $adminComment1Link);
$this->assertStringContainsString('comments/ham/' . $commentID . '?t=', $adminComment1Link);
// Test that this link can't be shared / XSS exploited
$this->logInAs('commentadmin2');
$ham = $this->get($adminComment1Link);
$this->assertEquals(400, $ham->getStatusCode());
$check = DataObject::get_by_id('Comment', $comment->ID);
$check = DataObject::get_by_id(Comment::class, $comment->ID);
$this->assertEquals(1, $check->IsSpam, 'No permission to mark as ham');
// Test that this other admin can ham the comment with their own link
@ -354,7 +333,7 @@ class CommentsTest extends FunctionalTest
$this->autoFollowRedirection = false;
$ham = $this->get($adminComment2Link);
$this->assertEquals(302, $ham->getStatusCode());
$check = DataObject::get_by_id('Comment', $commentID);
$check = DataObject::get_by_id(Comment::class, $commentID);
$this->assertEquals(0, $check->IsSpam);
// Cannot re-ham hammed comment
@ -364,15 +343,13 @@ class CommentsTest extends FunctionalTest
public function testApproveComment()
{
// Test anonymous user
if ($member = Member::currentUser()) {
$member->logOut();
}
$comment = $this->objFromFixture('Comment', 'secondComB');
$this->logOut();
$comment = $this->objFromFixture(Comment::class, 'secondComB');
$commentID = $comment->ID;
$this->assertNull($comment->ApproveLink(), 'No permission to see approve link');
$approve = $this->get('CommentingController/approve/'.$comment->ID.'?ajax=1');
$approve = $this->get('comments/approve/' . $comment->ID . '?ajax=1');
$this->assertEquals(403, $approve->getStatusCode());
$check = DataObject::get_by_id('Comment', $commentID);
$check = DataObject::get_by_id(Comment::class, $commentID);
$this->assertEquals(0, $check->Moderated, 'No permission to approve');
// Test non-authenticated user
@ -381,16 +358,16 @@ class CommentsTest extends FunctionalTest
// Test authenticated user
$this->logInAs('commentadmin');
$comment = $this->objFromFixture('Comment', 'secondComB');
$comment = $this->objFromFixture(Comment::class, 'secondComB');
$commentID = $comment->ID;
$adminComment1Link = $comment->ApproveLink();
$this->assertContains('CommentingController/approve/'.$commentID.'?t=', $adminComment1Link);
$this->assertStringContainsString('comments/approve/' . $commentID . '?t=', $adminComment1Link);
// Test that this link can't be shared / XSS exploited
$this->logInAs('commentadmin2');
$approve = $this->get($adminComment1Link);
$this->assertEquals(400, $approve->getStatusCode());
$check = DataObject::get_by_id('Comment', $comment->ID);
$check = DataObject::get_by_id(Comment::class, $comment->ID);
$this->assertEquals(0, $check->Moderated, 'No permission to approve');
// Test that this other admin can approve the comment with their own link
@ -399,7 +376,7 @@ class CommentsTest extends FunctionalTest
$this->autoFollowRedirection = false;
$approve = $this->get($adminComment2Link);
$this->assertEquals(302, $approve->getStatusCode());
$check = DataObject::get_by_id('Comment', $commentID);
$check = DataObject::get_by_id(Comment::class, $commentID);
$this->assertEquals(1, $check->Moderated);
// Cannot re-approve approved comment
@ -411,10 +388,10 @@ class CommentsTest extends FunctionalTest
$comment = new Comment();
// We only care about the CommenterURL, so only set that
// Check a http and https URL. Add more test urls here as needed.
$protocols = array(
$protocols = [
'Http',
'Https',
);
];
$url = '://example.com';
foreach ($protocols as $protocol) {
@ -427,21 +404,20 @@ class CommentsTest extends FunctionalTest
public function testSanitizesWithAllowHtml()
{
if (!class_exists('HTMLPurifier')) {
if (!class_exists('\\HTMLPurifier')) {
$this->markTestSkipped('HTMLPurifier class not found');
return;
}
// Add p for paragraph
// NOTE: The config method appears to append to the existing array
Config::inst()->update('CommentableItem', 'comments', array(
'html_allowed_elements' => array('p'),
));
Config::modify()->merge(CommentableItem::class, 'comments', [
'html_allowed_elements' => ['p'],
]);
// Without HTML allowed
$comment1 = new Comment();
$comment1->AllowHtml = false;
$comment1->BaseClass = 'CommentableItem';
$comment1->ParentClass = CommentableItem::class;
$comment1->Comment = '<p><script>alert("w00t")</script>my comment</p>';
$comment1->write();
$this->assertEquals(
@ -454,7 +430,7 @@ class CommentsTest extends FunctionalTest
// With HTML allowed
$comment2 = new Comment();
$comment2->AllowHtml = true;
$comment2->BaseClass = 'CommentableItem';
$comment2->ParentClass = CommentableItem::class;
$comment2->Comment = '<p><script>alert("w00t")</script>my comment</p>';
$comment2->write();
$this->assertEquals(
@ -466,13 +442,13 @@ class CommentsTest extends FunctionalTest
public function testDefaultTemplateRendersHtmlWithAllowHtml()
{
if (!class_exists('HTMLPurifier')) {
if (!class_exists('\\HTMLPurifier')) {
$this->markTestSkipped('HTMLPurifier class not found');
}
Config::inst()->update('CommentableItem', 'comments', array(
'html_allowed_elements' => array('p'),
));
Config::modify()->merge(CommentableItem::class, 'comments', [
'html_allowed_elements' => ['p'],
]);
$item = new CommentableItem();
$item->write();
@ -482,19 +458,19 @@ class CommentsTest extends FunctionalTest
$comment->Comment = '<p>my comment</p>';
$comment->AllowHtml = false;
$comment->ParentID = $item->ID;
$comment->BaseClass = 'CommentableItem';
$comment->ParentClass = CommentableItem::class;
$comment->write();
$html = $item->customise(array('CommentsEnabled' => true))->renderWith('CommentsInterface');
$this->assertContains(
$html = $item->customise(['CommentsEnabled' => true])->renderWith('CommentsInterface');
$this->assertStringContainsString(
'&lt;p&gt;my comment&lt;/p&gt;',
$html
);
$comment->AllowHtml = true;
$comment->write();
$html = $item->customise(array('CommentsEnabled' => true))->renderWith('CommentsInterface');
$this->assertContains(
$html = $item->customise(['CommentsEnabled' => true])->renderWith('CommentsInterface');
$this->assertStringContainsString(
'<p>my comment</p>',
$html
);
@ -506,12 +482,11 @@ class CommentsTest extends FunctionalTest
*/
public function testDefaultEnabled()
{
// Ensure values are set via cms (not via config)
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'enabled_cms' => true,
'require_moderation_cms' => true,
'require_login_cms' => true
));
'require_login_cms' => true,
]);
// With default = true
$obj = new CommentableItem();
@ -532,34 +507,35 @@ class CommentsTest extends FunctionalTest
// With default = false
// Because of config rules about falsey values, apply config to object directly
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'enabled' => false,
'require_login' => true,
'require_moderation' => true
));
'require_moderation' => true,
]);
$obj = new CommentableItem();
$this->assertFalse((bool)$obj->getCommentsOption('enabled'), "Default setting is disabled");
$this->assertFalse((bool)$obj->getCommentsOption('enabled'), 'Default setting is disabled');
$this->assertFalse((bool)$obj->ProvideComments);
$this->assertEquals('Required', $obj->ModerationRequired);
$this->assertTrue((bool)$obj->CommentsRequireLogin);
$obj = new CommentableItemEnabled();
$this->assertTrue((bool)$obj->ProvideComments);
$this->assertEquals('Required', $obj->ModerationRequired);
$this->assertTrue((bool)$obj->CommentsRequireLogin);
$obj = new CommentableItemDisabled();
$this->assertFalse((bool)$obj->ProvideComments);
$this->assertEquals('None', $obj->ModerationRequired);
$this->assertFalse((bool)$obj->CommentsRequireLogin);
}
/*
When a parent comment is deleted, remove the children
*/
public function testOnBeforeDelete()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$child = new Comment();
$child->Name = 'Fred Bloggs';
@ -574,8 +550,8 @@ class CommentsTest extends FunctionalTest
$comment->delete();
// assert that the new child been deleted
$this->assertFalse(DataObject::get_by_id('Comment', $commentID));
$this->assertFalse(DataObject::get_by_id('Comment', $childCommentID));
$this->assertNull(DataObject::get_by_id(Comment::class, $commentID));
$this->assertNull(DataObject::get_by_id(Comment::class, $childCommentID));
}
public function testRequireDefaultRecords()
@ -585,105 +561,77 @@ class CommentsTest extends FunctionalTest
public function testLink()
{
$comment = $this->objFromFixture('Comment', 'thirdComD');
$this->assertEquals('CommentableItem_Controller#comment-'.$comment->ID,
$comment->Link());
$comment = $this->objFromFixture(Comment::class, 'thirdComD');
$this->assertEquals(
'CommentableItemController#comment-' . $comment->ID,
$comment->Link()
);
$this->assertEquals($comment->ID, $comment->ID);
// An orphan comment has no link
$comment->ParentID = 0;
$comment->ParentClass = null;
$comment->write();
$this->assertEquals('', $comment->Link());
}
public function testPermalink()
{
$comment = $this->objFromFixture('Comment', 'thirdComD');
$comment = $this->objFromFixture(Comment::class, 'thirdComD');
$this->assertEquals('comment-' . $comment->ID, $comment->Permalink());
}
/*
Test field labels in 2 languages
/**
* Test field labels are defined
*/
public function testFieldLabels()
{
$locale = i18n::get_locale();
i18n::set_locale('fr');
$comment = $this->objFromFixture('Comment', 'firstComA');
$labels = $comment->FieldLabels();
$expected = array(
'Name' => 'Nom de l\'Auteur',
'Comment' => 'Commentaire',
'Email' => 'Email',
'URL' => 'URL',
'BaseClass' => 'Base Class',
'Moderated' => 'Modéré?',
'IsSpam' => 'Spam?',
'ParentID' => 'Parent ID',
'AllowHtml' => 'Allow Html',
'SecretToken' => 'Secret Token',
'Depth' => 'Depth',
'Author' => 'Author Member',
'ParentComment' => 'Parent Comment',
'ChildComments' => 'Child Comments',
'ParentTitle' => 'Parent',
'Created' => 'Date de publication'
);
i18n::set_locale($locale);
$this->assertEquals($expected, $labels);
$labels = $comment->FieldLabels();
$expected = array(
'Name' => 'Author Name',
'Comment' => 'Comment',
'Email' => 'Email',
'URL' => 'URL',
'BaseClass' => 'Base Class',
'Moderated' => 'Moderated?',
'IsSpam' => 'Spam?',
'ParentID' => 'Parent ID',
'AllowHtml' => 'Allow Html',
'SecretToken' => 'Secret Token',
'Depth' => 'Depth',
'Author' => 'Author Member',
'ParentComment' => 'Parent Comment',
'ChildComments' => 'Child Comments',
'ParentTitle' => 'Parent',
'Created' => 'Date posted'
/** @var Comment $comment */
$comment = $this->objFromFixture(Comment::class, 'firstComA');
);
$this->assertEquals($expected, $labels);
}
public function testGetOption()
{
$this->markTestSkipped('TODO');
$labels = $comment->FieldLabels();
$expected = [
'Name',
'Comment',
'Email',
'URL',
'IsSpam',
'Moderated',
'ParentTitle',
'Created',
];
foreach ($expected as $key) {
$this->assertArrayHasKey($key, $labels);
}
}
public function testGetParent()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$item = $this->objFromFixture('CommentableItem', 'first');
$parent = $comment->getParent();
$this->assertEquals($item, $parent);
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$item = $this->objFromFixture(CommentableItem::class, 'first');
$parent = $comment->Parent();
$this->assertSame($item->getClassName(), $parent->getClassName());
$this->assertSame($item->ID, $parent->ID);
}
public function testGetParentTitle()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$title = $comment->getParentTitle();
$this->assertEquals('First', $title);
// Title from a comment with no parent is blank
$comment->ParentID = 0;
$comment->ParentClass = null;
$comment->write();
$this->assertEquals('', $comment->getParentTitle());
}
public function testGetParentClassName()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$className = $comment->getParentClassName();
$this->assertEquals('CommentableItem', $className);
$this->assertEquals(CommentableItem::class, $className);
}
public function testCastingHelper()
@ -708,7 +656,7 @@ class CommentsTest extends FunctionalTest
public function testCanCreate()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
// admin can create - this is always false
$this->logInAs('commentadmin');
@ -721,7 +669,7 @@ class CommentsTest extends FunctionalTest
public function testCanView()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
// admin can view
$this->logInAs('commentadmin');
@ -738,7 +686,7 @@ class CommentsTest extends FunctionalTest
public function testCanEdit()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
// admin can edit
$this->logInAs('commentadmin');
@ -755,7 +703,7 @@ class CommentsTest extends FunctionalTest
public function testCanDelete()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
// admin can delete
$this->logInAs('commentadmin');
@ -773,26 +721,26 @@ class CommentsTest extends FunctionalTest
public function testGetMember()
{
$this->logInAs('visitor');
$current = Member::currentUser();
$comment = $this->objFromFixture('Comment', 'firstComA');
$current = Security::getCurrentUser();
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$method = $this->getMethod('getMember');
// null case
$member = $method->invokeArgs($comment, array());
$this->assertEquals($current, $member);
$this->assertEquals($current->ID, $member->ID);
// numeric ID case
$member = $method->invokeArgs($comment, array($current->ID));
$this->assertEquals($current, $member);
$this->assertEquals($current->ID, $member->ID);
// identity case
$member = $method->invokeArgs($comment, array($current));
$this->assertEquals($current, $member);
$this->assertEquals($current->ID, $member->ID);
}
public function testGetAuthorName()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$this->assertEquals(
'FA',
$comment->getAuthorName()
@ -804,7 +752,7 @@ class CommentsTest extends FunctionalTest
$comment->getAuthorName()
);
$author = $this->objFromFixture('Member', 'visitor');
$author = $this->objFromFixture(Member::class, 'visitor');
$comment->AuthorID = $author->ID;
$comment->write();
$this->assertEquals(
@ -821,44 +769,44 @@ class CommentsTest extends FunctionalTest
public function testLinks()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$this->logInAs('commentadmin');
$method = $this->getMethod('ActionLink');
// test with starts of strings and tokens and salts change each time
$this->assertStringStartsWith(
'/CommentingController/theaction/'.$comment->ID,
$this->assertStringContainsString(
'/comments/theaction/' . $comment->ID,
$method->invokeArgs($comment, array('theaction'))
);
$this->assertStringStartsWith(
'/CommentingController/delete/'.$comment->ID,
$this->assertStringContainsString(
'/comments/delete/' . $comment->ID,
$comment->DeleteLink()
);
$this->assertStringStartsWith(
'/CommentingController/spam/'.$comment->ID,
$this->assertStringContainsString(
'/comments/spam/' . $comment->ID,
$comment->SpamLink()
);
$comment->markSpam();
$this->assertStringStartsWith(
'/CommentingController/ham/'.$comment->ID,
$this->assertStringContainsString(
'/comments/ham/' . $comment->ID,
$comment->HamLink()
);
//markApproved
$comment->markUnapproved();
$this->assertStringStartsWith(
'/CommentingController/approve/'.$comment->ID,
$this->assertStringContainsString(
'/comments/approve/' . $comment->ID,
$comment->ApproveLink()
);
}
public function testMarkSpam()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$comment->markSpam();
$this->assertTrue($comment->Moderated);
$this->assertTrue($comment->IsSpam);
@ -866,7 +814,7 @@ class CommentsTest extends FunctionalTest
public function testMarkApproved()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$comment->markApproved();
$this->assertTrue($comment->Moderated);
$this->assertFalse($comment->IsSpam);
@ -874,14 +822,14 @@ class CommentsTest extends FunctionalTest
public function testMarkUnapproved()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$comment->markApproved();
$this->assertTrue($comment->Moderated);
}
public function testSpamClass()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$this->assertEquals('notspam', $comment->spamClass());
$comment->Moderated = false;
$this->assertEquals('unmoderated', $comment->spamClass());
@ -891,7 +839,7 @@ class CommentsTest extends FunctionalTest
public function testGetTitle()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$this->assertEquals(
'Comment by FA on First',
$comment->getTitle()
@ -900,50 +848,50 @@ class CommentsTest extends FunctionalTest
public function testGetCMSFields()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$fields = $comment->getCMSFields();
$names = array();
$names = [];
foreach ($fields as $field) {
$names[] = $field->getName();
}
$expected = array(
$expected = [
'Created',
'Name',
'Comment',
'Email',
'URL',
null #FIXME this is suspicious
);
'Options',
];
$this->assertEquals($expected, $names);
}
public function testGetCMSFieldsCommentHasAuthor()
{
$member = Member::get()->filter('FirstName', 'visitor')->first();
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$comment->AuthorID = $member->ID;
$comment->write();
$fields = $comment->getCMSFields();
$names = array();
$names = [];
foreach ($fields as $field) {
$names[] = $field->getName();
}
$expected = array(
$expected = [
'Created',
'Name',
'AuthorMember',
'Comment',
'Email',
'URL',
null #FIXME this is suspicious
);
'Options',
];
$this->assertEquals($expected, $names);
}
public function testGetCMSFieldsWithParentComment()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$child = new Comment();
$child->Name = 'John Smith';
@ -952,29 +900,32 @@ class CommentsTest extends FunctionalTest
$child->write();
$fields = $child->getCMSFields();
$names = array();
$names = [];
foreach ($fields as $field) {
$names[] = $field->getName();
}
$expected = array(
$expected = [
'Created',
'Name',
'Comment',
'Email',
'URL',
null, #FIXME this is suspicious
'Options',
'ParentComment_Title',
'ParentComment_Created',
'ParentComment_AuthorName',
'ParentComment_EscapedComment'
);
'ParentComment_EscapedComment',
];
$this->assertEquals($expected, $names);
}
public function testPurifyHtml()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
if (!class_exists(HTMLPurifier_Config::class)) {
$this->markTestSkipped('HTMLPurifier class not found');
}
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$dirtyHTML = '<p><script>alert("w00t")</script>my comment</p>';
$this->assertEquals(
@ -986,41 +937,48 @@ class CommentsTest extends FunctionalTest
public function testGravatar()
{
// Turn gravatars on
Config::inst()->update('CommentableItem', 'comments', array(
'use_gravatar' => true
));
$comment = $this->objFromFixture('Comment', 'firstComA');
Config::modify()->merge(CommentableItem::class, 'comments', [
'use_gravatar' => true,
'gravatar_size' => 80,
'gravatar_default' => 'identicon',
'gravatar_rating' => 'g',
]);
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$this->assertEquals(
'http://www.gravatar.com/avatar/d41d8cd98f00b204e9800998ecf8427e?s'.
'=80&d=identicon&r=g',
$comment->gravatar()
'https://www.gravatar.com/avatar/d41d8cd98f00b204e9800998ecf8427e?s'
. '=80&d=identicon&r=g',
$comment->Gravatar()
);
// Turn gravatars off
Config::inst()->update('CommentableItem', 'comments', array(
'use_gravatar' => false
));
$comment = $this->objFromFixture('Comment', 'firstComA');
Config::modify()->merge(CommentableItem::class, 'comments', [
'use_gravatar' => false,
]);
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$this->assertEquals(
'',
$comment->gravatar()
$comment->Gravatar()
);
}
public function testGetRepliesEnabled()
{
$comment = $this->objFromFixture('Comment', 'firstComA');
Config::inst()->update('CommentableItem', 'comments', array(
'nested_comments' => false
));
Config::modify()->merge(CommentableItem::class, 'comments', [
'nested_comments' => false,
]);
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$this->assertFalse($comment->getRepliesEnabled());
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'nested_comments' => true,
'nested_depth' => 4
));
'nested_depth' => 4,
]);
$this->assertTrue($comment->getRepliesEnabled());
$comment->Depth = 4;
@ -1028,15 +986,17 @@ class CommentsTest extends FunctionalTest
// 0 indicates no limit for nested_depth
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'nested_comments' => true,
'nested_depth' => 0
));
'nested_depth' => 0,
]);
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$comment->Depth = 234;
$this->assertTrue($comment->getRepliesEnabled());
$comment->markUnapproved();
$this->assertFalse($comment->getRepliesEnabled());
$comment->markSpam();
$this->assertFalse($comment->getRepliesEnabled());
@ -1046,15 +1006,18 @@ class CommentsTest extends FunctionalTest
public function testAllReplies()
{
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'nested_comments' => true,
'nested_depth' => 4
));
$comment = $this->objFromFixture('Comment', 'firstComA');
'nested_depth' => 4,
]);
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$this->assertEquals(
3,
$comment->allReplies()->count()
);
$child = new Comment();
$child->Name = 'Fred Smith';
$child->Comment = 'This is a child comment';
@ -1069,22 +1032,22 @@ class CommentsTest extends FunctionalTest
$comment->allReplies()->count()
);
Config::inst()->update('CommentableItem', 'comments', array(
'nested_comments' => false
));
Config::modify()->merge(CommentableItem::class, 'comments', [
'nested_comments' => false,
]);
$this->assertEquals(0, $comment->allReplies()->count());
}
public function testReplies()
{
CommentableItem::add_extension('CommentsExtension');
CommentableItem::add_extension(CommentsExtension::class);
$this->logInWithPermission('ADMIN');
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'nested_comments' => true,
'nested_depth' => 4
));
$comment = $this->objFromFixture('Comment', 'firstComA');
'nested_depth' => 4,
]);
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$this->assertEquals(
3,
$comment->Replies()->count()
@ -1114,17 +1077,17 @@ class CommentsTest extends FunctionalTest
// Test moderation required on the front end
$item = $this->objFromFixture('CommentableItem', 'first');
$item = $this->objFromFixture(CommentableItem::class, 'first');
$item->ModerationRequired = 'Required';
$item->write();
Config::inst()->update('CommentableItemDisabled', 'comments', array(
Config::modify()->merge(CommentableItemDisabled::class, 'comments', [
'nested_comments' => true,
'nested_depth' => 4,
'frontend_moderation' => true
));
'frontend_moderation' => true,
]);
$comment = DataObject::get_by_id('Comment', $comment->ID);
$comment = DataObject::get_by_id(Comment::class, $comment->ID);
$this->assertEquals(
2,
@ -1132,84 +1095,82 @@ class CommentsTest extends FunctionalTest
);
// Turn off nesting, empty array should be returned
Config::inst()->update('CommentableItem', 'comments', array(
'nested_comments' => false
));
Config::modify()->merge(CommentableItem::class, 'comments', [
'nested_comments' => false,
]);
$this->assertEquals(
0,
$comment->Replies()->count()
);
CommentableItem::remove_extension('CommentsExtension');
CommentableItem::remove_extension(CommentsExtension::class);
}
public function testPagedReplies()
{
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'nested_comments' => true,
'nested_depth' => 4,
'comments_per_page' => 2 #Force 2nd page for 3 items
));
'comments_per_page' => 2,
]);
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$pagedList = $comment->pagedReplies();
$this->assertEquals(
2,
$pagedList->TotalPages()
);
$this->assertEquals(
3,
$pagedList->getTotalItems()
);
//TODO - 2nd page requires controller
//
Config::inst()->update('CommentableItem', 'comments', array(
'nested_comments' => false
));
Config::modify()->merge(CommentableItem::class, 'comments', [
'nested_comments' => false,
]);
$this->assertEquals(0, $comment->PagedReplies()->count());
}
public function testReplyForm()
{
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'nested_comments' => false,
'nested_depth' => 4
));
'nested_depth' => 4,
]);
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
// No nesting, no reply form
$form = $comment->replyForm();
$this->assertNull($form);
// parent item so show form
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'nested_comments' => true,
'nested_depth' => 4
));
$form = $comment->replyForm();
'nested_depth' => 4,
]);
$form = $comment->ReplyForm();
$this->assertNotNull($form);
$names = [];
$names = array();
foreach ($form->Fields() as $field) {
array_push($names, $field->getName());
}
$this->assertEquals(
array(
null, #FIXME suspicious
'ParentID',
'ReturnURL',
'ParentCommentID',
'BaseClass'
),
$names
);
$this->assertContains('NameEmailURLComment', $names, 'The CompositeField name');
$this->assertContains('ParentID', $names);
$this->assertContains('ParentClassName', $names);
$this->assertContains('ReturnURL', $names);
$this->assertContains('ParentCommentID', $names);
// no parent, no reply form
$comment->ParentID = 0;
$comment->ParentClass = null;
$comment->write();
$form = $comment->replyForm();
$this->assertNull($form);
@ -1217,12 +1178,12 @@ class CommentsTest extends FunctionalTest
public function testUpdateDepth()
{
Config::inst()->update('CommentableItem', 'comments', array(
Config::modify()->merge(CommentableItem::class, 'comments', [
'nested_comments' => true,
'nested_depth' => 4
));
'nested_depth' => 4,
]);
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment = $this->objFromFixture(Comment::class, 'firstComA');
$children = $comment->allReplies()->toArray();
// Make the second child a child of the first
// Make the third child a child of the second
@ -1262,98 +1223,11 @@ class CommentsTest extends FunctionalTest
$this->markTestSkipped('TODO');
}
protected static function getMethod($name)
{
$class = new ReflectionClass('Comment');
$class = new ReflectionClass(Comment::class);
$method = $class->getMethod($name);
$method->setAccessible(true);
return $method;
}
}
/**
* @package comments
* @subpackage tests
*/
class CommentableItem extends DataObject implements TestOnly
{
private static $db = array(
'Title' => 'Varchar'
);
private static $extensions = array(
'CommentsExtension'
);
public function RelativeLink()
{
return "CommentableItem_Controller";
}
public function canView($member = null)
{
return true;
}
// This is needed for canModerateComments
public function canEdit($member = null)
{
if ($member instanceof Member) {
$memberID = $member->ID;
} elseif (is_numeric($member)) {
$memberID = $member;
} else {
$memberID = Member::currentUserID();
}
if ($memberID && Permission::checkMember($memberID, array("ADMIN", "CMS_ACCESS_CommentAdmin"))) {
return true;
}
return false;
}
public function Link()
{
return $this->RelativeLink();
}
public function AbsoluteLink()
{
return Director::absoluteURL($this->RelativeLink());
}
}
class CommentableItemEnabled extends CommentableItem
{
private static $defaults = array(
'ProvideComments' => true,
'ModerationRequired' => 'Required',
'CommentsRequireLogin' => true
);
}
class CommentableItemDisabled extends CommentableItem
{
private static $defaults = array(
'ProvideComments' => false,
'ModerationRequired' => 'None',
'CommentsRequireLogin' => false
);
}
/**
* @package comments
* @subpackage tests
*/
class CommentableItem_Controller extends Controller implements TestOnly
{
public function index()
{
return CommentableItem::get()->first()->CommentsForm();
}
}

View File

@ -1,4 +1,4 @@
Member:
SilverStripe\Security\Member:
commentadmin:
FirstName: admin
commentadmin2:
@ -6,17 +6,17 @@ Member:
visitor:
FirstName: visitor
Group:
SilverStripe\Security\Group:
commentadmins:
Title: Admin
Members: =>Member.commentadmin, =>Member.commentadmin2
Members: =>SilverStripe\Security\Member.commentadmin, =>SilverStripe\Security\Member.commentadmin2
Permission:
SilverStripe\Security\Permission:
admin:
Code: CMS_ACCESS_CommentAdmin
Group: =>Group.commentadmins
Group: =>SilverStripe\Security\Group.commentadmins
CommentableItem:
SilverStripe\Comments\Tests\Stubs\CommentableItem:
first:
Title: First
ProvideComments: 1
@ -35,166 +35,158 @@ CommentableItem:
ProvideComments: 1
Title: spammed
ModerationRequired: 'None'
moderated:
ProvideComments: 1
Title: Moderate everything
ModerationRequired: Required
CommentsRequireLogin: 0
Comment:
SilverStripe\Comments\Model\Comment:
firstComA:
ParentID: =>CommentableItem.first
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.first
Name: FA
Comment: textFA
BaseClass: CommentableItem
Moderated: 1
IsSpam:
Depth: 1
firstComAChild1:
ParentID: =>CommentableItem.first
ParentCommentID: =>Comment.firstComA
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.first
ParentComment: =>SilverStripe\Comments\Model\Comment.firstComA
Name: John Smith
Comment: Reply to firstComA 1
BaseClass: CommentableItem
Moderated: 1
IsSpam: 0
Depth: 2
firstComAChild2:
ParentID: =>CommentableItem.first
ParentCommentID: =>Comment.firstComA
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.first
ParentComment: =>SilverStripe\Comments\Model\Comment.firstComA
Name: John Smith
Comment: Reply to firstComA 2
BaseClass: CommentableItem
Moderated: 1
IsSpam: 0
Depth: 2
firstComAChild3:
ParentID: =>CommentableItem.first
ParentCommentID: =>Comment.firstComA
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.first
ParentComment: =>SilverStripe\Comments\Model\Comment.firstComA
Name: John Smith
Comment: Reply to firstComA 3
BaseClass: CommentableItem
Moderated: 1
IsSpam: 0
Depth: 2
secondComA:
ParentID: =>CommentableItem.second
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.second
Name: SA
Comment: textSA
Moderated: 1
IsSpam: 0
BaseClass: CommentableItem
secondComB:
ParentID: =>CommentableItem.second
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.second
Name: SB
Comment: textSB
Moderated: 0
IsSpam: 0
BaseClass: CommentableItem
secondComC:
ParentID: =>CommentableItem.second
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.second
Name: SB
Comment: textSB
Moderated: 1
IsSpam: 1
BaseClass: CommentableItem
thirdComA:
ParentID: =>CommentableItem.third
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.third
Name: TA
Comment: textTA
Moderated: 1
IsSpam: 0
BaseClass: CommentableItem
thirdComB:
ParentID: =>CommentableItem.third
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.third
Name: TB
Comment: textTB
Moderated: 1
IsSpam: 0
BaseClass: CommentableItem
thirdComC:
ParentID: =>CommentableItem.third
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.third
Name: TC
Comment: textTC
Moderated: 1
IsSpam: 0
BaseClass: CommentableItem
thirdComD:
ParentID: =>CommentableItem.third
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.third
Name: TC
Comment: textTC
Moderated: 1
BaseClass: CommentableItem
thirdComE:
ParentID: =>CommentableItem.third
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.third
Name: TC
Comment: textTC
Moderated: 1
BaseClass: CommentableItem
thirdComF:
ParentID: =>CommentableItem.third
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.third
Name: TC
Comment: textTC
Moderated: 1
IsSpam: 0
BaseClass: CommentableItem
thirdComG:
ParentID: =>CommentableItem.third
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.third
Name: TC
Comment: textTC
Moderated: 1
IsSpam: 0
BaseClass: CommentableItem
thirdComH:
ParentID: =>CommentableItem.third
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.third
Name: TC
Comment: textTC
Moderated: 1
IsSpam: 0
BaseClass: CommentableItem
thirdComI:
ParentID: =>CommentableItem.third
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.third
Name: TC
Comment: textTC
Moderated: 1
IsSpam: 0
BaseClass: CommentableItem
thirdComJ:
ParentID: =>CommentableItem.third
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.third
Name: TC
Comment: textTC
Moderated: 1
IsSpam: 0
BaseClass: CommentableItem
thirdComK:
ParentID: =>CommentableItem.third
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.third
Name: TC
Comment: textTC
Moderated: 1
IsSpam: 0
BaseClass: CommentableItem
disabledCom:
ParentID: =>CommentableItem.nocomments
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.nocomments
Name: Disabled
Moderated: 0
IsSpam: 1
BaseClass: CommentableItem
testCommentList1:
ParentID: =>CommentableItem.spammed
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.spammed
Name: Comment 1
Moderated: 0
IsSpam: 0
BaseClass: CommentableItem
testCommentList2:
ParentID: =>CommentableItem.spammed
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.spammed
Name: Comment 2
Moderated: 1
IsSpam: 1
BaseClass: CommentableItem
testCommentList3:
ParentID: =>CommentableItem.spammed
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.spammed
Name: Comment 3
Moderated: 1
IsSpam: 0
BaseClass: CommentableItem
testCommentList4:
ParentID: =>CommentableItem.spammed
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.spammed
Name: Comment 4
Moderated: 0
IsSpam: 1
BaseClass: CommentableItem
testModeratedComment1:
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.moderated
Name: Moderated comment 1
Moderated: 0
IsSpam: 0
testModeratedComment2:
Parent: =>SilverStripe\Comments\Tests\Stubs\CommentableItem.moderated
Name: Moderated comment 2
Moderated: 0
IsSpam: 1

View File

@ -0,0 +1,19 @@
<?php
namespace SilverStripe\Comments\Tests\Stubs;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
class Cheerleader extends DataObject implements TestOnly
{
private static $table_name = 'CommentsTest_Cheerleader';
private static $db = [
'Name' => 'Varchar',
];
private static $has_one = [
'Team' => Team::class,
];
}

View File

@ -0,0 +1,62 @@
<?php
namespace SilverStripe\Comments\Tests\Stubs;
use SilverStripe\Comments\Extensions\CommentsExtension;
use SilverStripe\Control\Director;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
class CommentableItem extends DataObject implements TestOnly
{
private static $db = array(
'Title' => 'Varchar'
);
private static $extensions = array(
CommentsExtension::class
);
private static $table_name = 'CommentableItem';
public function RelativeLink()
{
return 'CommentableItemController';
}
public function canView($member = null)
{
return true;
}
// This is needed for canModerateComments
public function canEdit($member = null)
{
if ($member instanceof Member) {
$memberID = $member->ID;
} elseif (is_numeric($member)) {
$memberID = $member;
} else {
$currentUser = Security::getCurrentUser();
$memberID = $currentUser ? $currentUser->ID : 0;
}
if ($memberID && Permission::checkMember($memberID, array('ADMIN', 'CMS_ACCESS_CommentAdmin'))) {
return true;
}
return false;
}
public function Link()
{
return $this->RelativeLink();
}
public function AbsoluteLink()
{
return Director::absoluteURL($this->RelativeLink());
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace SilverStripe\Comments\Tests\Stubs;
use SilverStripe\Control\Controller;
use SilverStripe\Dev\TestOnly;
/**
* @package comments
* @subpackage tests
*/
class CommentableItemController extends Controller implements TestOnly
{
public function index()
{
return CommentableItem::get()->first()->CommentsForm();
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace SilverStripe\Comments\Tests\Stubs;
class CommentableItemDisabled extends CommentableItem
{
private static $defaults = array(
'ProvideComments' => false,
'ModerationRequired' => 'None',
'CommentsRequireLogin' => false
);
private static $table_name = 'CommentableItemDisabled';
}

View File

@ -0,0 +1,14 @@
<?php
namespace SilverStripe\Comments\Tests\Stubs;
class CommentableItemEnabled extends CommentableItem
{
private static $defaults = array(
'ProvideComments' => true,
'ModerationRequired' => 'Required',
'CommentsRequireLogin' => true
);
private static $table_name = 'CommentableItemEnabled';
}

24
tests/Stubs/Player.php Normal file
View File

@ -0,0 +1,24 @@
<?php
namespace SilverStripe\Comments\Tests\Stubs;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\ManyManyList;
/**
* @method ManyManyList Teams()
*/
class Player extends DataObject implements TestOnly
{
private static $table_name = 'CommentsTest_Player';
private static $db = array(
'Name' => 'Varchar',
'Email' => 'Varchar',
);
private static $belongs_many_many = [
'Teams' => Team::class,
];
}

35
tests/Stubs/Team.php Normal file
View File

@ -0,0 +1,35 @@
<?php
namespace SilverStripe\Comments\Tests\Stubs;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
class Team extends DataObject implements TestOnly
{
private static $table_name = 'CommentsTest_Team';
private static $db = array(
'Name' => 'Varchar',
'City' => 'Varchar',
);
private static $many_many = [
'Players' => Player::class,
];
private static $has_many = [
'Cheerleaders' => Cheerleader::class,
];
private static $searchable_fields = [
'Name',
'City',
'Cheerleaders.Name',
];
public function canView($member = null)
{
return true;
}
}

View File

@ -1,940 +0,0 @@
/*!
* jQuery Validation Plugin v1.13.1
*
* http://jqueryvalidation.org/
*
* Copyright (c) 2015 Jörn Zaefferer
* Released under the MIT license
*/
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "./jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
(function() {
function stripHtml(value) {
// remove html tags and space chars
return value.replace(/<.[^<>]*?>/g, " ").replace(/&nbsp;|&#160;/gi, " ")
// remove punctuation
.replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g, "");
}
$.validator.addMethod("maxWords", function(value, element, params) {
return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length <= params;
}, $.validator.format("Please enter {0} words or less."));
$.validator.addMethod("minWords", function(value, element, params) {
return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length >= params;
}, $.validator.format("Please enter at least {0} words."));
$.validator.addMethod("rangeWords", function(value, element, params) {
var valueStripped = stripHtml(value),
regex = /\b\w+\b/g;
return this.optional(element) || valueStripped.match(regex).length >= params[0] && valueStripped.match(regex).length <= params[1];
}, $.validator.format("Please enter between {0} and {1} words."));
}());
// Accept a value from a file input based on a required mimetype
$.validator.addMethod("accept", function(value, element, param) {
// Split mime on commas in case we have multiple types we can accept
var typeParam = typeof param === "string" ? param.replace(/\s/g, "").replace(/,/g, "|") : "image/*",
optionalValue = this.optional(element),
i, file;
// Element is optional
if (optionalValue) {
return optionalValue;
}
if ($(element).attr("type") === "file") {
// If we are using a wildcard, make it regex friendly
typeParam = typeParam.replace(/\*/g, ".*");
// Check if the element has a FileList before checking each file
if (element.files && element.files.length) {
for (i = 0; i < element.files.length; i++) {
file = element.files[i];
// Grab the mimetype from the loaded file, verify it matches
if (!file.type.match(new RegExp( ".?(" + typeParam + ")$", "i"))) {
return false;
}
}
}
}
// Either return true because we've validated each file, or because the
// browser does not support element.files and the FileList feature
return true;
}, $.validator.format("Please enter a value with a valid mimetype."));
$.validator.addMethod("alphanumeric", function(value, element) {
return this.optional(element) || /^\w+$/i.test(value);
}, "Letters, numbers, and underscores only please");
/*
* Dutch bank account numbers (not 'giro' numbers) have 9 digits
* and pass the '11 check'.
* We accept the notation with spaces, as that is common.
* acceptable: 123456789 or 12 34 56 789
*/
$.validator.addMethod("bankaccountNL", function(value, element) {
if (this.optional(element)) {
return true;
}
if (!(/^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test(value))) {
return false;
}
// now '11 check'
var account = value.replace(/ /g, ""), // remove spaces
sum = 0,
len = account.length,
pos, factor, digit;
for ( pos = 0; pos < len; pos++ ) {
factor = len - pos;
digit = account.substring(pos, pos + 1);
sum = sum + factor * digit;
}
return sum % 11 === 0;
}, "Please specify a valid bank account number");
$.validator.addMethod("bankorgiroaccountNL", function(value, element) {
return this.optional(element) ||
($.validator.methods.bankaccountNL.call(this, value, element)) ||
($.validator.methods.giroaccountNL.call(this, value, element));
}, "Please specify a valid bank or giro account number");
/**
* BIC is the business identifier code (ISO 9362). This BIC check is not a guarantee for authenticity.
*
* BIC pattern: BBBBCCLLbbb (8 or 11 characters long; bbb is optional)
*
* BIC definition in detail:
* - First 4 characters - bank code (only letters)
* - Next 2 characters - ISO 3166-1 alpha-2 country code (only letters)
* - Next 2 characters - location code (letters and digits)
* a. shall not start with '0' or '1'
* b. second character must be a letter ('O' is not allowed) or one of the following digits ('0' for test (therefore not allowed), '1' for passive participant and '2' for active participant)
* - Last 3 characters - branch code, optional (shall not start with 'X' except in case of 'XXX' for primary office) (letters and digits)
*/
$.validator.addMethod("bic", function(value, element) {
return this.optional( element ) || /^([A-Z]{6}[A-Z2-9][A-NP-Z1-2])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test( value );
}, "Please specify a valid BIC code");
/*
* Código de identificación fiscal ( CIF ) is the tax identification code for Spanish legal entities
* Further rules can be found in Spanish on http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal
*/
$.validator.addMethod( "cifES", function( value ) {
"use strict";
var num = [],
controlDigit, sum, i, count, tmp, secondDigit;
value = value.toUpperCase();
// Quick format test
if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) {
return false;
}
for ( i = 0; i < 9; i++ ) {
num[ i ] = parseInt( value.charAt( i ), 10 );
}
// Algorithm for checking CIF codes
sum = num[ 2 ] + num[ 4 ] + num[ 6 ];
for ( count = 1; count < 8; count += 2 ) {
tmp = ( 2 * num[ count ] ).toString();
secondDigit = tmp.charAt( 1 );
sum += parseInt( tmp.charAt( 0 ), 10 ) + ( secondDigit === "" ? 0 : parseInt( secondDigit, 10 ) );
}
/* The first (position 1) is a letter following the following criteria:
* A. Corporations
* B. LLCs
* C. General partnerships
* D. Companies limited partnerships
* E. Communities of goods
* F. Cooperative Societies
* G. Associations
* H. Communities of homeowners in horizontal property regime
* J. Civil Societies
* K. Old format
* L. Old format
* M. Old format
* N. Nonresident entities
* P. Local authorities
* Q. Autonomous bodies, state or not, and the like, and congregations and religious institutions
* R. Congregations and religious institutions (since 2008 ORDER EHA/451/2008)
* S. Organs of State Administration and regions
* V. Agrarian Transformation
* W. Permanent establishments of non-resident in Spain
*/
if ( /^[ABCDEFGHJNPQRSUVW]{1}/.test( value ) ) {
sum += "";
controlDigit = 10 - parseInt( sum.charAt( sum.length - 1 ), 10 );
value += controlDigit;
return ( num[ 8 ].toString() === String.fromCharCode( 64 + controlDigit ) || num[ 8 ].toString() === value.charAt( value.length - 1 ) );
}
return false;
}, "Please specify a valid CIF number." );
/* NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator
* Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0
* Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings)
*/
$.validator.addMethod("creditcardtypes", function(value, element, param) {
if (/[^0-9\-]+/.test(value)) {
return false;
}
value = value.replace(/\D/g, "");
var validTypes = 0x0000;
if (param.mastercard) {
validTypes |= 0x0001;
}
if (param.visa) {
validTypes |= 0x0002;
}
if (param.amex) {
validTypes |= 0x0004;
}
if (param.dinersclub) {
validTypes |= 0x0008;
}
if (param.enroute) {
validTypes |= 0x0010;
}
if (param.discover) {
validTypes |= 0x0020;
}
if (param.jcb) {
validTypes |= 0x0040;
}
if (param.unknown) {
validTypes |= 0x0080;
}
if (param.all) {
validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;
}
if (validTypes & 0x0001 && /^(5[12345])/.test(value)) { //mastercard
return value.length === 16;
}
if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa
return value.length === 16;
}
if (validTypes & 0x0004 && /^(3[47])/.test(value)) { //amex
return value.length === 15;
}
if (validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test(value)) { //dinersclub
return value.length === 14;
}
if (validTypes & 0x0010 && /^(2(014|149))/.test(value)) { //enroute
return value.length === 15;
}
if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover
return value.length === 16;
}
if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb
return value.length === 16;
}
if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb
return value.length === 15;
}
if (validTypes & 0x0080) { //unknown
return true;
}
return false;
}, "Please enter a valid credit card number.");
/**
* Validates currencies with any given symbols by @jameslouiz
* Symbols can be optional or required. Symbols required by default
*
* Usage examples:
* currency: ["£", false] - Use false for soft currency validation
* currency: ["$", false]
* currency: ["RM", false] - also works with text based symbols such as "RM" - Malaysia Ringgit etc
*
* <input class="currencyInput" name="currencyInput">
*
* Soft symbol checking
* currencyInput: {
* currency: ["$", false]
* }
*
* Strict symbol checking (default)
* currencyInput: {
* currency: "$"
* //OR
* currency: ["$", true]
* }
*
* Multiple Symbols
* currencyInput: {
* currency: "$,£,¢"
* }
*/
$.validator.addMethod("currency", function(value, element, param) {
var isParamString = typeof param === "string",
symbol = isParamString ? param : param[0],
soft = isParamString ? true : param[1],
regex;
symbol = symbol.replace(/,/g, "");
symbol = soft ? symbol + "]" : symbol + "]?";
regex = "^[" + symbol + "([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$";
regex = new RegExp(regex);
return this.optional(element) || regex.test(value);
}, "Please specify a valid currency");
$.validator.addMethod("dateFA", function(value, element) {
return this.optional(element) || /^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(value);
}, "Please enter a correct date");
/**
* Return true, if the value is a valid date, also making this formal check dd/mm/yyyy.
*
* @example $.validator.methods.date("01/01/1900")
* @result true
*
* @example $.validator.methods.date("01/13/1990")
* @result false
*
* @example $.validator.methods.date("01.01.1900")
* @result false
*
* @example <input name="pippo" class="{dateITA:true}" />
* @desc Declares an optional input element whose value must be a valid date.
*
* @name $.validator.methods.dateITA
* @type Boolean
* @cat Plugins/Validate/Methods
*/
$.validator.addMethod("dateITA", function(value, element) {
var check = false,
re = /^\d{1,2}\/\d{1,2}\/\d{4}$/,
adata, gg, mm, aaaa, xdata;
if ( re.test(value)) {
adata = value.split("/");
gg = parseInt(adata[0], 10);
mm = parseInt(adata[1], 10);
aaaa = parseInt(adata[2], 10);
xdata = new Date(Date.UTC(aaaa, mm - 1, gg, 12, 0, 0, 0));
if ( ( xdata.getUTCFullYear() === aaaa ) && ( xdata.getUTCMonth () === mm - 1 ) && ( xdata.getUTCDate() === gg ) ) {
check = true;
} else {
check = false;
}
} else {
check = false;
}
return this.optional(element) || check;
}, "Please enter a correct date");
$.validator.addMethod("dateNL", function(value, element) {
return this.optional(element) || /^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(value);
}, "Please enter a correct date");
// Older "accept" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept
$.validator.addMethod("extension", function(value, element, param) {
param = typeof param === "string" ? param.replace(/,/g, "|") : "png|jpe?g|gif";
return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
}, $.validator.format("Please enter a value with a valid extension."));
/**
* Dutch giro account numbers (not bank numbers) have max 7 digits
*/
$.validator.addMethod("giroaccountNL", function(value, element) {
return this.optional(element) || /^[0-9]{1,7}$/.test(value);
}, "Please specify a valid giro account number");
/**
* IBAN is the international bank account number.
* It has a country - specific format, that is checked here too
*/
$.validator.addMethod("iban", function(value, element) {
// some quick simple tests to prevent needless work
if (this.optional(element)) {
return true;
}
// remove spaces and to upper case
var iban = value.replace(/ /g, "").toUpperCase(),
ibancheckdigits = "",
leadingZeroes = true,
cRest = "",
cOperator = "",
countrycode, ibancheck, charAt, cChar, bbanpattern, bbancountrypatterns, ibanregexp, i, p;
if (!(/^([a-zA-Z0-9]{4} ){2,8}[a-zA-Z0-9]{1,4}|[a-zA-Z0-9]{12,34}$/.test(iban))) {
return false;
}
// check the country code and find the country specific format
countrycode = iban.substring(0, 2);
bbancountrypatterns = {
"AL": "\\d{8}[\\dA-Z]{16}",
"AD": "\\d{8}[\\dA-Z]{12}",
"AT": "\\d{16}",
"AZ": "[\\dA-Z]{4}\\d{20}",
"BE": "\\d{12}",
"BH": "[A-Z]{4}[\\dA-Z]{14}",
"BA": "\\d{16}",
"BR": "\\d{23}[A-Z][\\dA-Z]",
"BG": "[A-Z]{4}\\d{6}[\\dA-Z]{8}",
"CR": "\\d{17}",
"HR": "\\d{17}",
"CY": "\\d{8}[\\dA-Z]{16}",
"CZ": "\\d{20}",
"DK": "\\d{14}",
"DO": "[A-Z]{4}\\d{20}",
"EE": "\\d{16}",
"FO": "\\d{14}",
"FI": "\\d{14}",
"FR": "\\d{10}[\\dA-Z]{11}\\d{2}",
"GE": "[\\dA-Z]{2}\\d{16}",
"DE": "\\d{18}",
"GI": "[A-Z]{4}[\\dA-Z]{15}",
"GR": "\\d{7}[\\dA-Z]{16}",
"GL": "\\d{14}",
"GT": "[\\dA-Z]{4}[\\dA-Z]{20}",
"HU": "\\d{24}",
"IS": "\\d{22}",
"IE": "[\\dA-Z]{4}\\d{14}",
"IL": "\\d{19}",
"IT": "[A-Z]\\d{10}[\\dA-Z]{12}",
"KZ": "\\d{3}[\\dA-Z]{13}",
"KW": "[A-Z]{4}[\\dA-Z]{22}",
"LV": "[A-Z]{4}[\\dA-Z]{13}",
"LB": "\\d{4}[\\dA-Z]{20}",
"LI": "\\d{5}[\\dA-Z]{12}",
"LT": "\\d{16}",
"LU": "\\d{3}[\\dA-Z]{13}",
"MK": "\\d{3}[\\dA-Z]{10}\\d{2}",
"MT": "[A-Z]{4}\\d{5}[\\dA-Z]{18}",
"MR": "\\d{23}",
"MU": "[A-Z]{4}\\d{19}[A-Z]{3}",
"MC": "\\d{10}[\\dA-Z]{11}\\d{2}",
"MD": "[\\dA-Z]{2}\\d{18}",
"ME": "\\d{18}",
"NL": "[A-Z]{4}\\d{10}",
"NO": "\\d{11}",
"PK": "[\\dA-Z]{4}\\d{16}",
"PS": "[\\dA-Z]{4}\\d{21}",
"PL": "\\d{24}",
"PT": "\\d{21}",
"RO": "[A-Z]{4}[\\dA-Z]{16}",
"SM": "[A-Z]\\d{10}[\\dA-Z]{12}",
"SA": "\\d{2}[\\dA-Z]{18}",
"RS": "\\d{18}",
"SK": "\\d{20}",
"SI": "\\d{15}",
"ES": "\\d{20}",
"SE": "\\d{20}",
"CH": "\\d{5}[\\dA-Z]{12}",
"TN": "\\d{20}",
"TR": "\\d{5}[\\dA-Z]{17}",
"AE": "\\d{3}\\d{16}",
"GB": "[A-Z]{4}\\d{14}",
"VG": "[\\dA-Z]{4}\\d{16}"
};
bbanpattern = bbancountrypatterns[countrycode];
// As new countries will start using IBAN in the
// future, we only check if the countrycode is known.
// This prevents false negatives, while almost all
// false positives introduced by this, will be caught
// by the checksum validation below anyway.
// Strict checking should return FALSE for unknown
// countries.
if (typeof bbanpattern !== "undefined") {
ibanregexp = new RegExp("^[A-Z]{2}\\d{2}" + bbanpattern + "$", "");
if (!(ibanregexp.test(iban))) {
return false; // invalid country specific format
}
}
// now check the checksum, first convert to digits
ibancheck = iban.substring(4, iban.length) + iban.substring(0, 4);
for (i = 0; i < ibancheck.length; i++) {
charAt = ibancheck.charAt(i);
if (charAt !== "0") {
leadingZeroes = false;
}
if (!leadingZeroes) {
ibancheckdigits += "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(charAt);
}
}
// calculate the result of: ibancheckdigits % 97
for (p = 0; p < ibancheckdigits.length; p++) {
cChar = ibancheckdigits.charAt(p);
cOperator = "" + cRest + "" + cChar;
cRest = cOperator % 97;
}
return cRest === 1;
}, "Please specify a valid IBAN");
$.validator.addMethod("integer", function(value, element) {
return this.optional(element) || /^-?\d+$/.test(value);
}, "A positive or negative non-decimal number please");
$.validator.addMethod("ipv4", function(value, element) {
return this.optional(element) || /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test(value);
}, "Please enter a valid IP v4 address.");
$.validator.addMethod("ipv6", function(value, element) {
return this.optional(element) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value);
}, "Please enter a valid IP v6 address.");
$.validator.addMethod("lettersonly", function(value, element) {
return this.optional(element) || /^[a-z]+$/i.test(value);
}, "Letters only please");
$.validator.addMethod("letterswithbasicpunc", function(value, element) {
return this.optional(element) || /^[a-z\-.,()'"\s]+$/i.test(value);
}, "Letters or punctuation only please");
$.validator.addMethod("mobileNL", function(value, element) {
return this.optional(element) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test(value);
}, "Please specify a valid mobile number");
/* For UK phone functions, do the following server side processing:
* Compare original input with this RegEx pattern:
* ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
* Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
* Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
* A number of very detailed GB telephone number RegEx patterns can also be found at:
* http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
*/
$.validator.addMethod("mobileUK", function(phone_number, element) {
phone_number = phone_number.replace(/\(|\)|\s+|-/g, "");
return this.optional(element) || phone_number.length > 9 &&
phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/);
}, "Please specify a valid mobile number");
/*
* The número de identidad de extranjero ( NIE )is a code used to identify the non-nationals in Spain
*/
$.validator.addMethod( "nieES", function( value ) {
"use strict";
value = value.toUpperCase();
// Basic format test
if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) {
return false;
}
// Test NIE
//T
if ( /^[T]{1}/.test( value ) ) {
return ( value[ 8 ] === /^[T]{1}[A-Z0-9]{8}$/.test( value ) );
}
//XYZ
if ( /^[XYZ]{1}/.test( value ) ) {
return (
value[ 8 ] === "TRWAGMYFPDXBNJZSQVHLCKE".charAt(
value.replace( "X", "0" )
.replace( "Y", "1" )
.replace( "Z", "2" )
.substring( 0, 8 ) % 23
)
);
}
return false;
}, "Please specify a valid NIE number." );
/*
* The Número de Identificación Fiscal ( NIF ) is the way tax identification used in Spain for individuals
*/
$.validator.addMethod( "nifES", function( value ) {
"use strict";
value = value.toUpperCase();
// Basic format test
if ( !value.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)") ) {
return false;
}
// Test NIF
if ( /^[0-9]{8}[A-Z]{1}$/.test( value ) ) {
return ( "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 0 ) % 23 ) === value.charAt( 8 ) );
}
// Test specials NIF (starts with K, L or M)
if ( /^[KLM]{1}/.test( value ) ) {
return ( value[ 8 ] === String.fromCharCode( 64 ) );
}
return false;
}, "Please specify a valid NIF number." );
$.validator.addMethod("nowhitespace", function(value, element) {
return this.optional(element) || /^\S+$/i.test(value);
}, "No white space please");
/**
* Return true if the field value matches the given format RegExp
*
* @example $.validator.methods.pattern("AR1004",element,/^AR\d{4}$/)
* @result true
*
* @example $.validator.methods.pattern("BR1004",element,/^AR\d{4}$/)
* @result false
*
* @name $.validator.methods.pattern
* @type Boolean
* @cat Plugins/Validate/Methods
*/
$.validator.addMethod("pattern", function(value, element, param) {
if (this.optional(element)) {
return true;
}
if (typeof param === "string") {
param = new RegExp("^(?:" + param + ")$");
}
return param.test(value);
}, "Invalid format.");
/**
* Dutch phone numbers have 10 digits (or 11 and start with +31).
*/
$.validator.addMethod("phoneNL", function(value, element) {
return this.optional(element) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(value);
}, "Please specify a valid phone number.");
/* For UK phone functions, do the following server side processing:
* Compare original input with this RegEx pattern:
* ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
* Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
* Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
* A number of very detailed GB telephone number RegEx patterns can also be found at:
* http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
*/
$.validator.addMethod("phoneUK", function(phone_number, element) {
phone_number = phone_number.replace(/\(|\)|\s+|-/g, "");
return this.optional(element) || phone_number.length > 9 &&
phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/);
}, "Please specify a valid phone number");
/**
* matches US phone number format
*
* where the area code may not start with 1 and the prefix may not start with 1
* allows '-' or ' ' as a separator and allows parens around area code
* some people may want to put a '1' in front of their number
*
* 1(212)-999-2345 or
* 212 999 2344 or
* 212-999-0983
*
* but not
* 111-123-5434
* and not
* 212 123 4567
*/
$.validator.addMethod("phoneUS", function(phone_number, element) {
phone_number = phone_number.replace(/\s+/g, "");
return this.optional(element) || phone_number.length > 9 &&
phone_number.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/);
}, "Please specify a valid phone number");
/* For UK phone functions, do the following server side processing:
* Compare original input with this RegEx pattern:
* ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
* Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
* Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
* A number of very detailed GB telephone number RegEx patterns can also be found at:
* http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
*/
//Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers
$.validator.addMethod("phonesUK", function(phone_number, element) {
phone_number = phone_number.replace(/\(|\)|\s+|-/g, "");
return this.optional(element) || phone_number.length > 9 &&
phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/);
}, "Please specify a valid uk phone number");
/**
* Matches a valid Canadian Postal Code
*
* @example jQuery.validator.methods.postalCodeCA( "H0H 0H0", element )
* @result true
*
* @example jQuery.validator.methods.postalCodeCA( "H0H0H0", element )
* @result false
*
* @name jQuery.validator.methods.postalCodeCA
* @type Boolean
* @cat Plugins/Validate/Methods
*/
$.validator.addMethod( "postalCodeCA", function( value, element ) {
return this.optional( element ) || /^[ABCEGHJKLMNPRSTVXY]\d[A-Z] \d[A-Z]\d$/.test( value );
}, "Please specify a valid postal code" );
/*
* Valida CEPs do brasileiros:
*
* Formatos aceitos:
* 99999-999
* 99.999-999
* 99999999
*/
$.validator.addMethod("postalcodeBR", function(cep_value, element) {
return this.optional(element) || /^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test( cep_value );
}, "Informe um CEP válido.");
/* Matches Italian postcode (CAP) */
$.validator.addMethod("postalcodeIT", function(value, element) {
return this.optional(element) || /^\d{5}$/.test(value);
}, "Please specify a valid postal code");
$.validator.addMethod("postalcodeNL", function(value, element) {
return this.optional(element) || /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(value);
}, "Please specify a valid postal code");
// Matches UK postcode. Does not match to UK Channel Islands that have their own postcodes (non standard UK)
$.validator.addMethod("postcodeUK", function(value, element) {
return this.optional(element) || /^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(value);
}, "Please specify a valid UK postcode");
/*
* Lets you say "at least X inputs that match selector Y must be filled."
*
* The end result is that neither of these inputs:
*
* <input class="productinfo" name="partnumber">
* <input class="productinfo" name="description">
*
* ...will validate unless at least one of them is filled.
*
* partnumber: {require_from_group: [1,".productinfo"]},
* description: {require_from_group: [1,".productinfo"]}
*
* options[0]: number of fields that must be filled in the group
* options[1]: CSS selector that defines the group of conditionally required fields
*/
$.validator.addMethod("require_from_group", function(value, element, options) {
var $fields = $(options[1], element.form),
$fieldsFirst = $fields.eq(0),
validator = $fieldsFirst.data("valid_req_grp") ? $fieldsFirst.data("valid_req_grp") : $.extend({}, this),
isValid = $fields.filter(function() {
return validator.elementValue(this);
}).length >= options[0];
// Store the cloned validator for future validation
$fieldsFirst.data("valid_req_grp", validator);
// If element isn't being validated, run each require_from_group field's validation rules
if (!$(element).data("being_validated")) {
$fields.data("being_validated", true);
$fields.each(function() {
validator.element(this);
});
$fields.data("being_validated", false);
}
return isValid;
}, $.validator.format("Please fill at least {0} of these fields."));
/*
* Lets you say "either at least X inputs that match selector Y must be filled,
* OR they must all be skipped (left blank)."
*
* The end result, is that none of these inputs:
*
* <input class="productinfo" name="partnumber">
* <input class="productinfo" name="description">
* <input class="productinfo" name="color">
*
* ...will validate unless either at least two of them are filled,
* OR none of them are.
*
* partnumber: {skip_or_fill_minimum: [2,".productinfo"]},
* description: {skip_or_fill_minimum: [2,".productinfo"]},
* color: {skip_or_fill_minimum: [2,".productinfo"]}
*
* options[0]: number of fields that must be filled in the group
* options[1]: CSS selector that defines the group of conditionally required fields
*
*/
$.validator.addMethod("skip_or_fill_minimum", function(value, element, options) {
var $fields = $(options[1], element.form),
$fieldsFirst = $fields.eq(0),
validator = $fieldsFirst.data("valid_skip") ? $fieldsFirst.data("valid_skip") : $.extend({}, this),
numberFilled = $fields.filter(function() {
return validator.elementValue(this);
}).length,
isValid = numberFilled === 0 || numberFilled >= options[0];
// Store the cloned validator for future validation
$fieldsFirst.data("valid_skip", validator);
// If element isn't being validated, run each skip_or_fill_minimum field's validation rules
if (!$(element).data("being_validated")) {
$fields.data("being_validated", true);
$fields.each(function() {
validator.element(this);
});
$fields.data("being_validated", false);
}
return isValid;
}, $.validator.format("Please either skip these fields or fill at least {0} of them."));
/* Validates US States and/or Territories by @jdforsythe
* Can be case insensitive or require capitalization - default is case insensitive
* Can include US Territories or not - default does not
* Can include US Military postal abbreviations (AA, AE, AP) - default does not
*
* Note: "States" always includes DC (District of Colombia)
*
* Usage examples:
*
* This is the default - case insensitive, no territories, no military zones
* stateInput: {
* caseSensitive: false,
* includeTerritories: false,
* includeMilitary: false
* }
*
* Only allow capital letters, no territories, no military zones
* stateInput: {
* caseSensitive: false
* }
*
* Case insensitive, include territories but not military zones
* stateInput: {
* includeTerritories: true
* }
*
* Only allow capital letters, include territories and military zones
* stateInput: {
* caseSensitive: true,
* includeTerritories: true,
* includeMilitary: true
* }
*
*
*
*/
jQuery.validator.addMethod("stateUS", function(value, element, options) {
var isDefault = typeof options === "undefined",
caseSensitive = ( isDefault || typeof options.caseSensitive === "undefined" ) ? false : options.caseSensitive,
includeTerritories = ( isDefault || typeof options.includeTerritories === "undefined" ) ? false : options.includeTerritories,
includeMilitary = ( isDefault || typeof options.includeMilitary === "undefined" ) ? false : options.includeMilitary,
regex;
if (!includeTerritories && !includeMilitary) {
regex = "^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$";
} else if (includeTerritories && includeMilitary) {
regex = "^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
} else if (includeTerritories) {
regex = "^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
} else {
regex = "^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$";
}
regex = caseSensitive ? new RegExp(regex) : new RegExp(regex, "i");
return this.optional(element) || regex.test(value);
},
"Please specify a valid state");
// TODO check if value starts with <, otherwise don't try stripping anything
$.validator.addMethod("strippedminlength", function(value, element, param) {
return $(value).text().length >= param;
}, $.validator.format("Please enter at least {0} characters"));
$.validator.addMethod("time", function(value, element) {
return this.optional(element) || /^([01]\d|2[0-3])(:[0-5]\d){1,2}$/.test(value);
}, "Please enter a valid time, between 00:00 and 23:59");
$.validator.addMethod("time12h", function(value, element) {
return this.optional(element) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(value);
}, "Please enter a valid time in 12-hour am/pm format");
// same as url, but TLD is optional
$.validator.addMethod("url2", function(value, element) {
return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
}, $.validator.messages.url);
/**
* Return true, if the value is a valid vehicle identification number (VIN).
*
* Works with all kind of text inputs.
*
* @example <input type="text" size="20" name="VehicleID" class="{required:true,vinUS:true}" />
* @desc Declares a required input element whose value must be a valid vehicle identification number.
*
* @name $.validator.methods.vinUS
* @type Boolean
* @cat Plugins/Validate/Methods
*/
$.validator.addMethod("vinUS", function(v) {
if (v.length !== 17) {
return false;
}
var LL = [ "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ],
VL = [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9 ],
FL = [ 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 ],
rs = 0,
i, n, d, f, cd, cdv;
for (i = 0; i < 17; i++) {
f = FL[i];
d = v.slice(i, i + 1);
if (i === 8) {
cdv = d;
}
if (!isNaN(d)) {
d *= f;
} else {
for (n = 0; n < LL.length; n++) {
if (d.toUpperCase() === LL[n]) {
d = VL[n];
d *= f;
if (isNaN(cdv) && n === 8) {
cdv = LL[n];
}
break;
}
}
}
rs += d;
}
cd = rs % 11;
if (cd === 10) {
cd = "X";
}
if (cd === cdv) {
return true;
}
return false;
}, "The specified vehicle identification number (VIN) is invalid.");
$.validator.addMethod("zipcodeUS", function(value, element) {
return this.optional(element) || /^\d{5}(-\d{4})?$/.test(value);
}, "The specified US ZIP Code is invalid");
$.validator.addMethod("ziprange", function(value, element) {
return this.optional(element) || /^90[2-5]\d\{2\}-\d{4}$/.test(value);
}, "Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx");
}));

View File

@ -1,4 +0,0 @@
/*! jQuery Validation Plugin - v1.13.1 - 10/14/2014
* http://jqueryvalidation.org/
* Copyright (c) 2014 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.validate.min"],a):a(jQuery)}(function(a){!function(){function b(a){return a.replace(/<.[^<>]*?>/g," ").replace(/&nbsp;|&#160;/gi," ").replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g,"")}a.validator.addMethod("maxWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length<=d},a.validator.format("Please enter {0} words or less.")),a.validator.addMethod("minWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length>=d},a.validator.format("Please enter at least {0} words.")),a.validator.addMethod("rangeWords",function(a,c,d){var e=b(a),f=/\b\w+\b/g;return this.optional(c)||e.match(f).length>=d[0]&&e.match(f).length<=d[1]},a.validator.format("Please enter between {0} and {1} words."))}(),a.validator.addMethod("accept",function(b,c,d){var e,f,g="string"==typeof d?d.replace(/\s/g,"").replace(/,/g,"|"):"image/*",h=this.optional(c);if(h)return h;if("file"===a(c).attr("type")&&(g=g.replace(/\*/g,".*"),c.files&&c.files.length))for(e=0;e<c.files.length;e++)if(f=c.files[e],!f.type.match(new RegExp(".?("+g+")$","i")))return!1;return!0},a.validator.format("Please enter a value with a valid mimetype.")),a.validator.addMethod("alphanumeric",function(a,b){return this.optional(b)||/^\w+$/i.test(a)},"Letters, numbers, and underscores only please"),a.validator.addMethod("bankaccountNL",function(a,b){if(this.optional(b))return!0;if(!/^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test(a))return!1;var c,d,e,f=a.replace(/ /g,""),g=0,h=f.length;for(c=0;h>c;c++)d=h-c,e=f.substring(c,c+1),g+=d*e;return g%11===0},"Please specify a valid bank account number"),a.validator.addMethod("bankorgiroaccountNL",function(b,c){return this.optional(c)||a.validator.methods.bankaccountNL.call(this,b,c)||a.validator.methods.giroaccountNL.call(this,b,c)},"Please specify a valid bank or giro account number"),a.validator.addMethod("bic",function(a,b){return this.optional(b)||/^([A-Z]{6}[A-Z2-9][A-NP-Z1-2])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test(a)},"Please specify a valid BIC code"),a.validator.addMethod("cifES",function(a){"use strict";var b,c,d,e,f,g,h=[];if(a=a.toUpperCase(),!a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)"))return!1;for(d=0;9>d;d++)h[d]=parseInt(a.charAt(d),10);for(c=h[2]+h[4]+h[6],e=1;8>e;e+=2)f=(2*h[e]).toString(),g=f.charAt(1),c+=parseInt(f.charAt(0),10)+(""===g?0:parseInt(g,10));return/^[ABCDEFGHJNPQRSUVW]{1}/.test(a)?(c+="",b=10-parseInt(c.charAt(c.length-1),10),a+=b,h[8].toString()===String.fromCharCode(64+b)||h[8].toString()===a.charAt(a.length-1)):!1},"Please specify a valid CIF number."),a.validator.addMethod("creditcardtypes",function(a,b,c){if(/[^0-9\-]+/.test(a))return!1;a=a.replace(/\D/g,"");var d=0;return c.mastercard&&(d|=1),c.visa&&(d|=2),c.amex&&(d|=4),c.dinersclub&&(d|=8),c.enroute&&(d|=16),c.discover&&(d|=32),c.jcb&&(d|=64),c.unknown&&(d|=128),c.all&&(d=255),1&d&&/^(5[12345])/.test(a)?16===a.length:2&d&&/^(4)/.test(a)?16===a.length:4&d&&/^(3[47])/.test(a)?15===a.length:8&d&&/^(3(0[012345]|[68]))/.test(a)?14===a.length:16&d&&/^(2(014|149))/.test(a)?15===a.length:32&d&&/^(6011)/.test(a)?16===a.length:64&d&&/^(3)/.test(a)?16===a.length:64&d&&/^(2131|1800)/.test(a)?15===a.length:128&d?!0:!1},"Please enter a valid credit card number."),a.validator.addMethod("currency",function(a,b,c){var d,e="string"==typeof c,f=e?c:c[0],g=e?!0:c[1];return f=f.replace(/,/g,""),f=g?f+"]":f+"]?",d="^["+f+"([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$",d=new RegExp(d),this.optional(b)||d.test(a)},"Please specify a valid currency"),a.validator.addMethod("dateFA",function(a,b){return this.optional(b)||/^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(a)},"Please enter a correct date"),a.validator.addMethod("dateITA",function(a,b){var c,d,e,f,g,h=!1,i=/^\d{1,2}\/\d{1,2}\/\d{4}$/;return i.test(a)?(c=a.split("/"),d=parseInt(c[0],10),e=parseInt(c[1],10),f=parseInt(c[2],10),g=new Date(f,e-1,d,12,0,0,0),h=g.getUTCFullYear()===f&&g.getUTCMonth()===e-1&&g.getUTCDate()===d?!0:!1):h=!1,this.optional(b)||h},"Please enter a correct date"),a.validator.addMethod("dateNL",function(a,b){return this.optional(b)||/^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(a)},"Please enter a correct date"),a.validator.addMethod("extension",function(a,b,c){return c="string"==typeof c?c.replace(/,/g,"|"):"png|jpe?g|gif",this.optional(b)||a.match(new RegExp(".("+c+")$","i"))},a.validator.format("Please enter a value with a valid extension.")),a.validator.addMethod("giroaccountNL",function(a,b){return this.optional(b)||/^[0-9]{1,7}$/.test(a)},"Please specify a valid giro account number"),a.validator.addMethod("iban",function(a,b){if(this.optional(b))return!0;var c,d,e,f,g,h,i,j,k,l=a.replace(/ /g,"").toUpperCase(),m="",n=!0,o="",p="";if(!/^([a-zA-Z0-9]{4} ){2,8}[a-zA-Z0-9]{1,4}|[a-zA-Z0-9]{12,34}$/.test(l))return!1;if(c=l.substring(0,2),h={AL:"\\d{8}[\\dA-Z]{16}",AD:"\\d{8}[\\dA-Z]{12}",AT:"\\d{16}",AZ:"[\\dA-Z]{4}\\d{20}",BE:"\\d{12}",BH:"[A-Z]{4}[\\dA-Z]{14}",BA:"\\d{16}",BR:"\\d{23}[A-Z][\\dA-Z]",BG:"[A-Z]{4}\\d{6}[\\dA-Z]{8}",CR:"\\d{17}",HR:"\\d{17}",CY:"\\d{8}[\\dA-Z]{16}",CZ:"\\d{20}",DK:"\\d{14}",DO:"[A-Z]{4}\\d{20}",EE:"\\d{16}",FO:"\\d{14}",FI:"\\d{14}",FR:"\\d{10}[\\dA-Z]{11}\\d{2}",GE:"[\\dA-Z]{2}\\d{16}",DE:"\\d{18}",GI:"[A-Z]{4}[\\dA-Z]{15}",GR:"\\d{7}[\\dA-Z]{16}",GL:"\\d{14}",GT:"[\\dA-Z]{4}[\\dA-Z]{20}",HU:"\\d{24}",IS:"\\d{22}",IE:"[\\dA-Z]{4}\\d{14}",IL:"\\d{19}",IT:"[A-Z]\\d{10}[\\dA-Z]{12}",KZ:"\\d{3}[\\dA-Z]{13}",KW:"[A-Z]{4}[\\dA-Z]{22}",LV:"[A-Z]{4}[\\dA-Z]{13}",LB:"\\d{4}[\\dA-Z]{20}",LI:"\\d{5}[\\dA-Z]{12}",LT:"\\d{16}",LU:"\\d{3}[\\dA-Z]{13}",MK:"\\d{3}[\\dA-Z]{10}\\d{2}",MT:"[A-Z]{4}\\d{5}[\\dA-Z]{18}",MR:"\\d{23}",MU:"[A-Z]{4}\\d{19}[A-Z]{3}",MC:"\\d{10}[\\dA-Z]{11}\\d{2}",MD:"[\\dA-Z]{2}\\d{18}",ME:"\\d{18}",NL:"[A-Z]{4}\\d{10}",NO:"\\d{11}",PK:"[\\dA-Z]{4}\\d{16}",PS:"[\\dA-Z]{4}\\d{21}",PL:"\\d{24}",PT:"\\d{21}",RO:"[A-Z]{4}[\\dA-Z]{16}",SM:"[A-Z]\\d{10}[\\dA-Z]{12}",SA:"\\d{2}[\\dA-Z]{18}",RS:"\\d{18}",SK:"\\d{20}",SI:"\\d{15}",ES:"\\d{20}",SE:"\\d{20}",CH:"\\d{5}[\\dA-Z]{12}",TN:"\\d{20}",TR:"\\d{5}[\\dA-Z]{17}",AE:"\\d{3}\\d{16}",GB:"[A-Z]{4}\\d{14}",VG:"[\\dA-Z]{4}\\d{16}"},g=h[c],"undefined"!=typeof g&&(i=new RegExp("^[A-Z]{2}\\d{2}"+g+"$",""),!i.test(l)))return!1;for(d=l.substring(4,l.length)+l.substring(0,4),j=0;j<d.length;j++)e=d.charAt(j),"0"!==e&&(n=!1),n||(m+="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(e));for(k=0;k<m.length;k++)f=m.charAt(k),p=""+o+f,o=p%97;return 1===o},"Please specify a valid IBAN"),a.validator.addMethod("integer",function(a,b){return this.optional(b)||/^-?\d+$/.test(a)},"A positive or negative non-decimal number please"),a.validator.addMethod("ipv4",function(a,b){return this.optional(b)||/^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test(a)},"Please enter a valid IP v4 address."),a.validator.addMethod("ipv6",function(a,b){return this.optional(b)||/^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(a)},"Please enter a valid IP v6 address."),a.validator.addMethod("lettersonly",function(a,b){return this.optional(b)||/^[a-z]+$/i.test(a)},"Letters only please"),a.validator.addMethod("letterswithbasicpunc",function(a,b){return this.optional(b)||/^[a-z\-.,()'"\s]+$/i.test(a)},"Letters or punctuation only please"),a.validator.addMethod("mobileNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid mobile number"),a.validator.addMethod("mobileUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/)},"Please specify a valid mobile number"),a.validator.addMethod("nieES",function(a){"use strict";return a=a.toUpperCase(),a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")?/^[T]{1}/.test(a)?a[8]===/^[T]{1}[A-Z0-9]{8}$/.test(a):/^[XYZ]{1}/.test(a)?a[8]==="TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.replace("X","0").replace("Y","1").replace("Z","2").substring(0,8)%23):!1:!1},"Please specify a valid NIE number."),a.validator.addMethod("nifES",function(a){"use strict";return a=a.toUpperCase(),a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")?/^[0-9]{8}[A-Z]{1}$/.test(a)?"TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,0)%23)===a.charAt(8):/^[KLM]{1}/.test(a)?a[8]===String.fromCharCode(64):!1:!1},"Please specify a valid NIF number."),a.validator.addMethod("nowhitespace",function(a,b){return this.optional(b)||/^\S+$/i.test(a)},"No white space please"),a.validator.addMethod("pattern",function(a,b,c){return this.optional(b)?!0:("string"==typeof c&&(c=new RegExp("^(?:"+c+")$")),c.test(a))},"Invalid format."),a.validator.addMethod("phoneNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid phone number."),a.validator.addMethod("phoneUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/)},"Please specify a valid phone number"),a.validator.addMethod("phoneUS",function(a,b){return a=a.replace(/\s+/g,""),this.optional(b)||a.length>9&&a.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/)},"Please specify a valid phone number"),a.validator.addMethod("phonesUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/)},"Please specify a valid uk phone number"),a.validator.addMethod("postalCodeCA",function(a,b){return this.optional(b)||/^[ABCEGHJKLMNPRSTVXY]\d[A-Z] \d[A-Z]\d$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeBR",function(a,b){return this.optional(b)||/^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test(a)},"Informe um CEP válido."),a.validator.addMethod("postalcodeIT",function(a,b){return this.optional(b)||/^\d{5}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeNL",function(a,b){return this.optional(b)||/^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postcodeUK",function(a,b){return this.optional(b)||/^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(a)},"Please specify a valid UK postcode"),a.validator.addMethod("require_from_group",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_req_grp")?f.data("valid_req_grp"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length>=d[0];return f.data("valid_req_grp",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),h},a.validator.format("Please fill at least {0} of these fields.")),a.validator.addMethod("skip_or_fill_minimum",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_skip")?f.data("valid_skip"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length,i=0===h||h>=d[0];return f.data("valid_skip",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),i},a.validator.format("Please either skip these fields or fill at least {0} of them.")),jQuery.validator.addMethod("stateUS",function(a,b,c){var d,e="undefined"==typeof c,f=e||"undefined"==typeof c.caseSensitive?!1:c.caseSensitive,g=e||"undefined"==typeof c.includeTerritories?!1:c.includeTerritories,h=e||"undefined"==typeof c.includeMilitary?!1:c.includeMilitary;return d=g||h?g&&h?"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":g?"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$":"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$",d=f?new RegExp(d):new RegExp(d,"i"),this.optional(b)||d.test(a)},"Please specify a valid state"),a.validator.addMethod("strippedminlength",function(b,c,d){return a(b).text().length>=d},a.validator.format("Please enter at least {0} characters")),a.validator.addMethod("time",function(a,b){return this.optional(b)||/^([01]\d|2[0-3])(:[0-5]\d){1,2}$/.test(a)},"Please enter a valid time, between 00:00 and 23:59"),a.validator.addMethod("time12h",function(a,b){return this.optional(b)||/^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(a)},"Please enter a valid time in 12-hour am/pm format"),a.validator.addMethod("url2",function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},a.validator.messages.url),a.validator.addMethod("vinUS",function(a){if(17!==a.length)return!1;var b,c,d,e,f,g,h=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"],i=[1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9],j=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2],k=0;for(b=0;17>b;b++){if(e=j[b],d=a.slice(b,b+1),8===b&&(g=d),isNaN(d)){for(c=0;c<h.length;c++)if(d.toUpperCase()===h[c]){d=i[c],d*=e,isNaN(g)&&8===c&&(g=h[c]);break}}else d*=e;k+=d}return f=k%11,10===f&&(f="X"),f===g?!0:!1},"The specified vehicle identification number (VIN) is invalid."),a.validator.addMethod("zipcodeUS",function(a,b){return this.optional(b)||/^\d{5}(-\d{4})?$/.test(a)},"The specified US ZIP Code is invalid"),a.validator.addMethod("ziprange",function(a,b){return this.optional(b)||/^90[2-5]\d\{2\}-\d{4}$/.test(a)},"Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx")});

View File

@ -1,1365 +0,0 @@
/*!
* jQuery Validation Plugin v1.13.1
*
* http://jqueryvalidation.org/
*
* Copyright (c) 2015 Jörn Zaefferer
* Released under the MIT license
*/
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
$.extend($.fn, {
// http://jqueryvalidation.org/validate/
validate: function( options ) {
// if nothing is selected, return nothing; can't chain anyway
if ( !this.length ) {
if ( options && options.debug && window.console ) {
console.warn( "Nothing selected, can't validate, returning nothing." );
}
return;
}
// check if a validator for this form was already created
var validator = $.data( this[ 0 ], "validator" );
if ( validator ) {
return validator;
}
// Add novalidate tag if HTML5.
this.attr( "novalidate", "novalidate" );
validator = new $.validator( options, this[ 0 ] );
$.data( this[ 0 ], "validator", validator );
if ( validator.settings.onsubmit ) {
this.validateDelegate( ":submit", "click", function( event ) {
if ( validator.settings.submitHandler ) {
validator.submitButton = event.target;
}
// allow suppressing validation by adding a cancel class to the submit button
if ( $( event.target ).hasClass( "cancel" ) ) {
validator.cancelSubmit = true;
}
// allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
if ( $( event.target ).attr( "formnovalidate" ) !== undefined ) {
validator.cancelSubmit = true;
}
});
// validate the form on submit
this.submit( function( event ) {
if ( validator.settings.debug ) {
// prevent form submit to be able to see console output
event.preventDefault();
}
function handle() {
var hidden, result;
if ( validator.settings.submitHandler ) {
if ( validator.submitButton ) {
// insert a hidden input as a replacement for the missing submit button
hidden = $( "<input type='hidden'/>" )
.attr( "name", validator.submitButton.name )
.val( $( validator.submitButton ).val() )
.appendTo( validator.currentForm );
}
result = validator.settings.submitHandler.call( validator, validator.currentForm, event );
if ( validator.submitButton ) {
// and clean up afterwards; thanks to no-block-scope, hidden can be referenced
hidden.remove();
}
if ( result !== undefined ) {
return result;
}
return false;
}
return true;
}
// prevent submit for invalid forms or custom submit handlers
if ( validator.cancelSubmit ) {
validator.cancelSubmit = false;
return handle();
}
if ( validator.form() ) {
if ( validator.pendingRequest ) {
validator.formSubmitted = true;
return false;
}
return handle();
} else {
validator.focusInvalid();
return false;
}
});
}
return validator;
},
// http://jqueryvalidation.org/valid/
valid: function() {
var valid, validator;
if ( $( this[ 0 ] ).is( "form" ) ) {
valid = this.validate().form();
} else {
valid = true;
validator = $( this[ 0 ].form ).validate();
this.each( function() {
valid = validator.element( this ) && valid;
});
}
return valid;
},
// attributes: space separated list of attributes to retrieve and remove
removeAttrs: function( attributes ) {
var result = {},
$element = this;
$.each( attributes.split( /\s/ ), function( index, value ) {
result[ value ] = $element.attr( value );
$element.removeAttr( value );
});
return result;
},
// http://jqueryvalidation.org/rules/
rules: function( command, argument ) {
var element = this[ 0 ],
settings, staticRules, existingRules, data, param, filtered;
if ( command ) {
settings = $.data( element.form, "validator" ).settings;
staticRules = settings.rules;
existingRules = $.validator.staticRules( element );
switch ( command ) {
case "add":
$.extend( existingRules, $.validator.normalizeRule( argument ) );
// remove messages from rules, but allow them to be set separately
delete existingRules.messages;
staticRules[ element.name ] = existingRules;
if ( argument.messages ) {
settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );
}
break;
case "remove":
if ( !argument ) {
delete staticRules[ element.name ];
return existingRules;
}
filtered = {};
$.each( argument.split( /\s/ ), function( index, method ) {
filtered[ method ] = existingRules[ method ];
delete existingRules[ method ];
if ( method === "required" ) {
$( element ).removeAttr( "aria-required" );
}
});
return filtered;
}
}
data = $.validator.normalizeRules(
$.extend(
{},
$.validator.classRules( element ),
$.validator.attributeRules( element ),
$.validator.dataRules( element ),
$.validator.staticRules( element )
), element );
// make sure required is at front
if ( data.required ) {
param = data.required;
delete data.required;
data = $.extend( { required: param }, data );
$( element ).attr( "aria-required", "true" );
}
// make sure remote is at back
if ( data.remote ) {
param = data.remote;
delete data.remote;
data = $.extend( data, { remote: param });
}
return data;
}
});
// Custom selectors
$.extend( $.expr[ ":" ], {
// http://jqueryvalidation.org/blank-selector/
blank: function( a ) {
return !$.trim( "" + $( a ).val() );
},
// http://jqueryvalidation.org/filled-selector/
filled: function( a ) {
return !!$.trim( "" + $( a ).val() );
},
// http://jqueryvalidation.org/unchecked-selector/
unchecked: function( a ) {
return !$( a ).prop( "checked" );
}
});
// constructor for validator
$.validator = function( options, form ) {
this.settings = $.extend( true, {}, $.validator.defaults, options );
this.currentForm = form;
this.init();
};
// http://jqueryvalidation.org/jQuery.validator.format/
$.validator.format = function( source, params ) {
if ( arguments.length === 1 ) {
return function() {
var args = $.makeArray( arguments );
args.unshift( source );
return $.validator.format.apply( this, args );
};
}
if ( arguments.length > 2 && params.constructor !== Array ) {
params = $.makeArray( arguments ).slice( 1 );
}
if ( params.constructor !== Array ) {
params = [ params ];
}
$.each( params, function( i, n ) {
source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() {
return n;
});
});
return source;
};
$.extend( $.validator, {
defaults: {
messages: {},
groups: {},
rules: {},
errorClass: "error",
validClass: "valid",
errorElement: "label",
focusCleanup: false,
focusInvalid: true,
errorContainer: $( [] ),
errorLabelContainer: $( [] ),
onsubmit: true,
ignore: ":hidden",
ignoreTitle: false,
onfocusin: function( element ) {
this.lastActive = element;
// Hide error label and remove error class on focus if enabled
if ( this.settings.focusCleanup ) {
if ( this.settings.unhighlight ) {
this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
}
this.hideThese( this.errorsFor( element ) );
}
},
onfocusout: function( element ) {
if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {
this.element( element );
}
},
onkeyup: function( element, event ) {
if ( event.which === 9 && this.elementValue( element ) === "" ) {
return;
} else if ( element.name in this.submitted || element === this.lastElement ) {
this.element( element );
}
},
onclick: function( element ) {
// click on selects, radiobuttons and checkboxes
if ( element.name in this.submitted ) {
this.element( element );
// or option elements, check parent select in that case
} else if ( element.parentNode.name in this.submitted ) {
this.element( element.parentNode );
}
},
highlight: function( element, errorClass, validClass ) {
if ( element.type === "radio" ) {
this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );
} else {
$( element ).addClass( errorClass ).removeClass( validClass );
}
},
unhighlight: function( element, errorClass, validClass ) {
if ( element.type === "radio" ) {
this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
} else {
$( element ).removeClass( errorClass ).addClass( validClass );
}
}
},
// http://jqueryvalidation.org/jQuery.validator.setDefaults/
setDefaults: function( settings ) {
$.extend( $.validator.defaults, settings );
},
messages: {
required: "This field is required.",
remote: "Please fix this field.",
email: "Please enter a valid email address.",
url: "Please enter a valid URL.",
date: "Please enter a valid date.",
dateISO: "Please enter a valid date ( ISO ).",
number: "Please enter a valid number.",
digits: "Please enter only digits.",
creditcard: "Please enter a valid credit card number.",
equalTo: "Please enter the same value again.",
maxlength: $.validator.format( "Please enter no more than {0} characters." ),
minlength: $.validator.format( "Please enter at least {0} characters." ),
rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ),
range: $.validator.format( "Please enter a value between {0} and {1}." ),
max: $.validator.format( "Please enter a value less than or equal to {0}." ),
min: $.validator.format( "Please enter a value greater than or equal to {0}." )
},
autoCreateRanges: false,
prototype: {
init: function() {
this.labelContainer = $( this.settings.errorLabelContainer );
this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );
this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );
this.submitted = {};
this.valueCache = {};
this.pendingRequest = 0;
this.pending = {};
this.invalid = {};
this.reset();
var groups = ( this.groups = {} ),
rules;
$.each( this.settings.groups, function( key, value ) {
if ( typeof value === "string" ) {
value = value.split( /\s/ );
}
$.each( value, function( index, name ) {
groups[ name ] = key;
});
});
rules = this.settings.rules;
$.each( rules, function( key, value ) {
rules[ key ] = $.validator.normalizeRule( value );
});
function delegate( event ) {
var validator = $.data( this[ 0 ].form, "validator" ),
eventType = "on" + event.type.replace( /^validate/, "" ),
settings = validator.settings;
if ( settings[ eventType ] && !this.is( settings.ignore ) ) {
settings[ eventType ].call( validator, this[ 0 ], event );
}
}
$( this.currentForm )
.validateDelegate( ":text, [type='password'], [type='file'], select, textarea, " +
"[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
"[type='email'], [type='datetime'], [type='date'], [type='month'], " +
"[type='week'], [type='time'], [type='datetime-local'], " +
"[type='range'], [type='color'], [type='radio'], [type='checkbox']",
"focusin focusout keyup", delegate)
// Support: Chrome, oldIE
// "select" is provided as event.target when clicking a option
.validateDelegate("select, option, [type='radio'], [type='checkbox']", "click", delegate);
if ( this.settings.invalidHandler ) {
$( this.currentForm ).bind( "invalid-form.validate", this.settings.invalidHandler );
}
// Add aria-required to any Static/Data/Class required fields before first validation
// Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html
$( this.currentForm ).find( "[required], [data-rule-required], .required" ).attr( "aria-required", "true" );
},
// http://jqueryvalidation.org/Validator.form/
form: function() {
this.checkForm();
$.extend( this.submitted, this.errorMap );
this.invalid = $.extend({}, this.errorMap );
if ( !this.valid() ) {
$( this.currentForm ).triggerHandler( "invalid-form", [ this ]);
}
this.showErrors();
return this.valid();
},
checkForm: function() {
this.prepareForm();
for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {
this.check( elements[ i ] );
}
return this.valid();
},
// http://jqueryvalidation.org/Validator.element/
element: function( element ) {
var cleanElement = this.clean( element ),
checkElement = this.validationTargetFor( cleanElement ),
result = true;
this.lastElement = checkElement;
if ( checkElement === undefined ) {
delete this.invalid[ cleanElement.name ];
} else {
this.prepareElement( checkElement );
this.currentElements = $( checkElement );
result = this.check( checkElement ) !== false;
if ( result ) {
delete this.invalid[ checkElement.name ];
} else {
this.invalid[ checkElement.name ] = true;
}
}
// Add aria-invalid status for screen readers
$( element ).attr( "aria-invalid", !result );
if ( !this.numberOfInvalids() ) {
// Hide error containers on last error
this.toHide = this.toHide.add( this.containers );
}
this.showErrors();
return result;
},
// http://jqueryvalidation.org/Validator.showErrors/
showErrors: function( errors ) {
if ( errors ) {
// add items to error list and map
$.extend( this.errorMap, errors );
this.errorList = [];
for ( var name in errors ) {
this.errorList.push({
message: errors[ name ],
element: this.findByName( name )[ 0 ]
});
}
// remove items from success list
this.successList = $.grep( this.successList, function( element ) {
return !( element.name in errors );
});
}
if ( this.settings.showErrors ) {
this.settings.showErrors.call( this, this.errorMap, this.errorList );
} else {
this.defaultShowErrors();
}
},
// http://jqueryvalidation.org/Validator.resetForm/
resetForm: function() {
if ( $.fn.resetForm ) {
$( this.currentForm ).resetForm();
}
this.submitted = {};
this.lastElement = null;
this.prepareForm();
this.hideErrors();
this.elements()
.removeClass( this.settings.errorClass )
.removeData( "previousValue" )
.removeAttr( "aria-invalid" );
},
numberOfInvalids: function() {
return this.objectLength( this.invalid );
},
objectLength: function( obj ) {
/* jshint unused: false */
var count = 0,
i;
for ( i in obj ) {
count++;
}
return count;
},
hideErrors: function() {
this.hideThese( this.toHide );
},
hideThese: function( errors ) {
errors.not( this.containers ).text( "" );
this.addWrapper( errors ).hide();
},
valid: function() {
return this.size() === 0;
},
size: function() {
return this.errorList.length;
},
focusInvalid: function() {
if ( this.settings.focusInvalid ) {
try {
$( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [])
.filter( ":visible" )
.focus()
// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
.trigger( "focusin" );
} catch ( e ) {
// ignore IE throwing errors when focusing hidden elements
}
}
},
findLastActive: function() {
var lastActive = this.lastActive;
return lastActive && $.grep( this.errorList, function( n ) {
return n.element.name === lastActive.name;
}).length === 1 && lastActive;
},
elements: function() {
var validator = this,
rulesCache = {};
// select all valid inputs inside the form (no submit or reset buttons)
return $( this.currentForm )
.find( "input, select, textarea" )
.not( ":submit, :reset, :image, [disabled], [readonly]" )
.not( this.settings.ignore )
.filter( function() {
if ( !this.name && validator.settings.debug && window.console ) {
console.error( "%o has no name assigned", this );
}
// select only the first element for each name, and only those with rules specified
if ( this.name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
return false;
}
rulesCache[ this.name ] = true;
return true;
});
},
clean: function( selector ) {
return $( selector )[ 0 ];
},
errors: function() {
var errorClass = this.settings.errorClass.split( " " ).join( "." );
return $( this.settings.errorElement + "." + errorClass, this.errorContext );
},
reset: function() {
this.successList = [];
this.errorList = [];
this.errorMap = {};
this.toShow = $( [] );
this.toHide = $( [] );
this.currentElements = $( [] );
},
prepareForm: function() {
this.reset();
this.toHide = this.errors().add( this.containers );
},
prepareElement: function( element ) {
this.reset();
this.toHide = this.errorsFor( element );
},
elementValue: function( element ) {
var val,
$element = $( element ),
type = element.type;
if ( type === "radio" || type === "checkbox" ) {
return $( "input[name='" + element.name + "']:checked" ).val();
} else if ( type === "number" && typeof element.validity !== "undefined" ) {
return element.validity.badInput ? false : $element.val();
}
val = $element.val();
if ( typeof val === "string" ) {
return val.replace(/\r/g, "" );
}
return val;
},
check: function( element ) {
element = this.validationTargetFor( this.clean( element ) );
var rules = $( element ).rules(),
rulesCount = $.map( rules, function( n, i ) {
return i;
}).length,
dependencyMismatch = false,
val = this.elementValue( element ),
result, method, rule;
for ( method in rules ) {
rule = { method: method, parameters: rules[ method ] };
try {
result = $.validator.methods[ method ].call( this, val, element, rule.parameters );
// if a method indicates that the field is optional and therefore valid,
// don't mark it as valid when there are no other rules
if ( result === "dependency-mismatch" && rulesCount === 1 ) {
dependencyMismatch = true;
continue;
}
dependencyMismatch = false;
if ( result === "pending" ) {
this.toHide = this.toHide.not( this.errorsFor( element ) );
return;
}
if ( !result ) {
this.formatAndAdd( element, rule );
return false;
}
} catch ( e ) {
if ( this.settings.debug && window.console ) {
console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
}
throw e;
}
}
if ( dependencyMismatch ) {
return;
}
if ( this.objectLength( rules ) ) {
this.successList.push( element );
}
return true;
},
// return the custom message for the given element and validation method
// specified in the element's HTML5 data attribute
// return the generic message if present and no method specific message is present
customDataMessage: function( element, method ) {
return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() +
method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" );
},
// return the custom message for the given element name and validation method
customMessage: function( name, method ) {
var m = this.settings.messages[ name ];
return m && ( m.constructor === String ? m : m[ method ]);
},
// return the first defined argument, allowing empty strings
findDefined: function() {
for ( var i = 0; i < arguments.length; i++) {
if ( arguments[ i ] !== undefined ) {
return arguments[ i ];
}
}
return undefined;
},
defaultMessage: function( element, method ) {
return this.findDefined(
this.customMessage( element.name, method ),
this.customDataMessage( element, method ),
// title is never undefined, so handle empty string as undefined
!this.settings.ignoreTitle && element.title || undefined,
$.validator.messages[ method ],
"<strong>Warning: No message defined for " + element.name + "</strong>"
);
},
formatAndAdd: function( element, rule ) {
var message = this.defaultMessage( element, rule.method ),
theregex = /\$?\{(\d+)\}/g;
if ( typeof message === "function" ) {
message = message.call( this, rule.parameters, element );
} else if ( theregex.test( message ) ) {
message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters );
}
this.errorList.push({
message: message,
element: element,
method: rule.method
});
this.errorMap[ element.name ] = message;
this.submitted[ element.name ] = message;
},
addWrapper: function( toToggle ) {
if ( this.settings.wrapper ) {
toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
}
return toToggle;
},
defaultShowErrors: function() {
var i, elements, error;
for ( i = 0; this.errorList[ i ]; i++ ) {
error = this.errorList[ i ];
if ( this.settings.highlight ) {
this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
}
this.showLabel( error.element, error.message );
}
if ( this.errorList.length ) {
this.toShow = this.toShow.add( this.containers );
}
if ( this.settings.success ) {
for ( i = 0; this.successList[ i ]; i++ ) {
this.showLabel( this.successList[ i ] );
}
}
if ( this.settings.unhighlight ) {
for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {
this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );
}
}
this.toHide = this.toHide.not( this.toShow );
this.hideErrors();
this.addWrapper( this.toShow ).show();
},
validElements: function() {
return this.currentElements.not( this.invalidElements() );
},
invalidElements: function() {
return $( this.errorList ).map(function() {
return this.element;
});
},
showLabel: function( element, message ) {
var place, group, errorID,
error = this.errorsFor( element ),
elementID = this.idOrName( element ),
describedBy = $( element ).attr( "aria-describedby" );
if ( error.length ) {
// refresh error/success class
error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
// replace message on existing label
error.html( message );
} else {
// create error element
error = $( "<" + this.settings.errorElement + ">" )
.attr( "id", elementID + "-error" )
.addClass( this.settings.errorClass )
.html( message || "" );
// Maintain reference to the element to be placed into the DOM
place = error;
if ( this.settings.wrapper ) {
// make sure the element is visible, even in IE
// actually showing the wrapped element is handled elsewhere
place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent();
}
if ( this.labelContainer.length ) {
this.labelContainer.append( place );
} else if ( this.settings.errorPlacement ) {
this.settings.errorPlacement( place, $( element ) );
} else {
place.insertAfter( element );
}
// Link error back to the element
if ( error.is( "label" ) ) {
// If the error is a label, then associate using 'for'
error.attr( "for", elementID );
} else if ( error.parents( "label[for='" + elementID + "']" ).length === 0 ) {
// If the element is not a child of an associated label, then it's necessary
// to explicitly apply aria-describedby
errorID = error.attr( "id" ).replace( /(:|\.|\[|\])/g, "\\$1");
// Respect existing non-error aria-describedby
if ( !describedBy ) {
describedBy = errorID;
} else if ( !describedBy.match( new RegExp( "\\b" + errorID + "\\b" ) ) ) {
// Add to end of list if not already present
describedBy += " " + errorID;
}
$( element ).attr( "aria-describedby", describedBy );
// If this element is grouped, then assign to all elements in the same group
group = this.groups[ element.name ];
if ( group ) {
$.each( this.groups, function( name, testgroup ) {
if ( testgroup === group ) {
$( "[name='" + name + "']", this.currentForm )
.attr( "aria-describedby", error.attr( "id" ) );
}
});
}
}
}
if ( !message && this.settings.success ) {
error.text( "" );
if ( typeof this.settings.success === "string" ) {
error.addClass( this.settings.success );
} else {
this.settings.success( error, element );
}
}
this.toShow = this.toShow.add( error );
},
errorsFor: function( element ) {
var name = this.idOrName( element ),
describer = $( element ).attr( "aria-describedby" ),
selector = "label[for='" + name + "'], label[for='" + name + "'] *";
// aria-describedby should directly reference the error element
if ( describer ) {
selector = selector + ", #" + describer.replace( /\s+/g, ", #" );
}
return this
.errors()
.filter( selector );
},
idOrName: function( element ) {
return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );
},
validationTargetFor: function( element ) {
// If radio/checkbox, validate first element in group instead
if ( this.checkable( element ) ) {
element = this.findByName( element.name );
}
// Always apply ignore filter
return $( element ).not( this.settings.ignore )[ 0 ];
},
checkable: function( element ) {
return ( /radio|checkbox/i ).test( element.type );
},
findByName: function( name ) {
return $( this.currentForm ).find( "[name='" + name + "']" );
},
getLength: function( value, element ) {
switch ( element.nodeName.toLowerCase() ) {
case "select":
return $( "option:selected", element ).length;
case "input":
if ( this.checkable( element ) ) {
return this.findByName( element.name ).filter( ":checked" ).length;
}
}
return value.length;
},
depend: function( param, element ) {
return this.dependTypes[typeof param] ? this.dependTypes[typeof param]( param, element ) : true;
},
dependTypes: {
"boolean": function( param ) {
return param;
},
"string": function( param, element ) {
return !!$( param, element.form ).length;
},
"function": function( param, element ) {
return param( element );
}
},
optional: function( element ) {
var val = this.elementValue( element );
return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch";
},
startRequest: function( element ) {
if ( !this.pending[ element.name ] ) {
this.pendingRequest++;
this.pending[ element.name ] = true;
}
},
stopRequest: function( element, valid ) {
this.pendingRequest--;
// sometimes synchronization fails, make sure pendingRequest is never < 0
if ( this.pendingRequest < 0 ) {
this.pendingRequest = 0;
}
delete this.pending[ element.name ];
if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
$( this.currentForm ).submit();
this.formSubmitted = false;
} else if (!valid && this.pendingRequest === 0 && this.formSubmitted ) {
$( this.currentForm ).triggerHandler( "invalid-form", [ this ]);
this.formSubmitted = false;
}
},
previousValue: function( element ) {
return $.data( element, "previousValue" ) || $.data( element, "previousValue", {
old: null,
valid: true,
message: this.defaultMessage( element, "remote" )
});
}
},
classRuleSettings: {
required: { required: true },
email: { email: true },
url: { url: true },
date: { date: true },
dateISO: { dateISO: true },
number: { number: true },
digits: { digits: true },
creditcard: { creditcard: true }
},
addClassRules: function( className, rules ) {
if ( className.constructor === String ) {
this.classRuleSettings[ className ] = rules;
} else {
$.extend( this.classRuleSettings, className );
}
},
classRules: function( element ) {
var rules = {},
classes = $( element ).attr( "class" );
if ( classes ) {
$.each( classes.split( " " ), function() {
if ( this in $.validator.classRuleSettings ) {
$.extend( rules, $.validator.classRuleSettings[ this ]);
}
});
}
return rules;
},
attributeRules: function( element ) {
var rules = {},
$element = $( element ),
type = element.getAttribute( "type" ),
method, value;
for ( method in $.validator.methods ) {
// support for <input required> in both html5 and older browsers
if ( method === "required" ) {
value = element.getAttribute( method );
// Some browsers return an empty string for the required attribute
// and non-HTML5 browsers might have required="" markup
if ( value === "" ) {
value = true;
}
// force non-HTML5 browsers to return bool
value = !!value;
} else {
value = $element.attr( method );
}
// convert the value to a number for number inputs, and for text for backwards compability
// allows type="date" and others to be compared as strings
if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
value = Number( value );
}
if ( value || value === 0 ) {
rules[ method ] = value;
} else if ( type === method && type !== "range" ) {
// exception: the jquery validate 'range' method
// does not test for the html5 'range' type
rules[ method ] = true;
}
}
// maxlength may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {
delete rules.maxlength;
}
return rules;
},
dataRules: function( element ) {
var method, value,
rules = {}, $element = $( element );
for ( method in $.validator.methods ) {
value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );
if ( value !== undefined ) {
rules[ method ] = value;
}
}
return rules;
},
staticRules: function( element ) {
var rules = {},
validator = $.data( element.form, "validator" );
if ( validator.settings.rules ) {
rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};
}
return rules;
},
normalizeRules: function( rules, element ) {
// handle dependency check
$.each( rules, function( prop, val ) {
// ignore rule when param is explicitly false, eg. required:false
if ( val === false ) {
delete rules[ prop ];
return;
}
if ( val.param || val.depends ) {
var keepRule = true;
switch ( typeof val.depends ) {
case "string":
keepRule = !!$( val.depends, element.form ).length;
break;
case "function":
keepRule = val.depends.call( element, element );
break;
}
if ( keepRule ) {
rules[ prop ] = val.param !== undefined ? val.param : true;
} else {
delete rules[ prop ];
}
}
});
// evaluate parameters
$.each( rules, function( rule, parameter ) {
rules[ rule ] = $.isFunction( parameter ) ? parameter( element ) : parameter;
});
// clean number parameters
$.each([ "minlength", "maxlength" ], function() {
if ( rules[ this ] ) {
rules[ this ] = Number( rules[ this ] );
}
});
$.each([ "rangelength", "range" ], function() {
var parts;
if ( rules[ this ] ) {
if ( $.isArray( rules[ this ] ) ) {
rules[ this ] = [ Number( rules[ this ][ 0 ]), Number( rules[ this ][ 1 ] ) ];
} else if ( typeof rules[ this ] === "string" ) {
parts = rules[ this ].replace(/[\[\]]/g, "" ).split( /[\s,]+/ );
rules[ this ] = [ Number( parts[ 0 ]), Number( parts[ 1 ] ) ];
}
}
});
if ( $.validator.autoCreateRanges ) {
// auto-create ranges
if ( rules.min != null && rules.max != null ) {
rules.range = [ rules.min, rules.max ];
delete rules.min;
delete rules.max;
}
if ( rules.minlength != null && rules.maxlength != null ) {
rules.rangelength = [ rules.minlength, rules.maxlength ];
delete rules.minlength;
delete rules.maxlength;
}
}
return rules;
},
// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
normalizeRule: function( data ) {
if ( typeof data === "string" ) {
var transformed = {};
$.each( data.split( /\s/ ), function() {
transformed[ this ] = true;
});
data = transformed;
}
return data;
},
// http://jqueryvalidation.org/jQuery.validator.addMethod/
addMethod: function( name, method, message ) {
$.validator.methods[ name ] = method;
$.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
if ( method.length < 3 ) {
$.validator.addClassRules( name, $.validator.normalizeRule( name ) );
}
},
methods: {
// http://jqueryvalidation.org/required-method/
required: function( value, element, param ) {
// check if dependency is met
if ( !this.depend( param, element ) ) {
return "dependency-mismatch";
}
if ( element.nodeName.toLowerCase() === "select" ) {
// could be an array for select-multiple or a string, both are fine this way
var val = $( element ).val();
return val && val.length > 0;
}
if ( this.checkable( element ) ) {
return this.getLength( value, element ) > 0;
}
return $.trim( value ).length > 0;
},
// http://jqueryvalidation.org/email-method/
email: function( value, element ) {
// From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29
// Retrieved 2014-01-14
// If you have a problem with this implementation, report a bug against the above spec
// Or use custom methods to implement your own email validation
return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );
},
// http://jqueryvalidation.org/url-method/
url: function( value, element ) {
// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
return this.optional( element ) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test( value );
},
// http://jqueryvalidation.org/date-method/
date: function( value, element ) {
return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );
},
// http://jqueryvalidation.org/dateISO-method/
dateISO: function( value, element ) {
return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );
},
// http://jqueryvalidation.org/number-method/
number: function( value, element ) {
return this.optional( element ) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
},
// http://jqueryvalidation.org/digits-method/
digits: function( value, element ) {
return this.optional( element ) || /^\d+$/.test( value );
},
// http://jqueryvalidation.org/creditcard-method/
// based on http://en.wikipedia.org/wiki/Luhn/
creditcard: function( value, element ) {
if ( this.optional( element ) ) {
return "dependency-mismatch";
}
// accept only spaces, digits and dashes
if ( /[^0-9 \-]+/.test( value ) ) {
return false;
}
var nCheck = 0,
nDigit = 0,
bEven = false,
n, cDigit;
value = value.replace( /\D/g, "" );
// Basing min and max length on
// http://developer.ean.com/general_info/Valid_Credit_Card_Types
if ( value.length < 13 || value.length > 19 ) {
return false;
}
for ( n = value.length - 1; n >= 0; n--) {
cDigit = value.charAt( n );
nDigit = parseInt( cDigit, 10 );
if ( bEven ) {
if ( ( nDigit *= 2 ) > 9 ) {
nDigit -= 9;
}
}
nCheck += nDigit;
bEven = !bEven;
}
return ( nCheck % 10 ) === 0;
},
// http://jqueryvalidation.org/minlength-method/
minlength: function( value, element, param ) {
var length = $.isArray( value ) ? value.length : this.getLength( value, element );
return this.optional( element ) || length >= param;
},
// http://jqueryvalidation.org/maxlength-method/
maxlength: function( value, element, param ) {
var length = $.isArray( value ) ? value.length : this.getLength( value, element );
return this.optional( element ) || length <= param;
},
// http://jqueryvalidation.org/rangelength-method/
rangelength: function( value, element, param ) {
var length = $.isArray( value ) ? value.length : this.getLength( value, element );
return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );
},
// http://jqueryvalidation.org/min-method/
min: function( value, element, param ) {
return this.optional( element ) || value >= param;
},
// http://jqueryvalidation.org/max-method/
max: function( value, element, param ) {
return this.optional( element ) || value <= param;
},
// http://jqueryvalidation.org/range-method/
range: function( value, element, param ) {
return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
},
// http://jqueryvalidation.org/equalTo-method/
equalTo: function( value, element, param ) {
// bind to the blur event of the target in order to revalidate whenever the target field is updated
// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
var target = $( param );
if ( this.settings.onfocusout ) {
target.unbind( ".validate-equalTo" ).bind( "blur.validate-equalTo", function() {
$( element ).valid();
});
}
return value === target.val();
},
// http://jqueryvalidation.org/remote-method/
remote: function( value, element, param ) {
if ( this.optional( element ) ) {
return "dependency-mismatch";
}
var previous = this.previousValue( element ),
validator, data;
if (!this.settings.messages[ element.name ] ) {
this.settings.messages[ element.name ] = {};
}
previous.originalMessage = this.settings.messages[ element.name ].remote;
this.settings.messages[ element.name ].remote = previous.message;
param = typeof param === "string" && { url: param } || param;
if ( previous.old === value ) {
return previous.valid;
}
previous.old = value;
validator = this;
this.startRequest( element );
data = {};
data[ element.name ] = value;
$.ajax( $.extend( true, {
url: param,
mode: "abort",
port: "validate" + element.name,
dataType: "json",
data: data,
context: validator.currentForm,
success: function( response ) {
var valid = response === true || response === "true",
errors, message, submitted;
validator.settings.messages[ element.name ].remote = previous.originalMessage;
if ( valid ) {
submitted = validator.formSubmitted;
validator.prepareElement( element );
validator.formSubmitted = submitted;
validator.successList.push( element );
delete validator.invalid[ element.name ];
validator.showErrors();
} else {
errors = {};
message = response || validator.defaultMessage( element, "remote" );
errors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message;
validator.invalid[ element.name ] = true;
validator.showErrors( errors );
}
previous.valid = valid;
validator.stopRequest( element, valid );
}
}, param ) );
return "pending";
}
}
});
$.format = function deprecated() {
throw "$.format has been deprecated. Please use $.validator.format instead.";
};
// ajax mode: abort
// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
var pendingRequests = {},
ajax;
// Use a prefilter if available (1.5+)
if ( $.ajaxPrefilter ) {
$.ajaxPrefilter(function( settings, _, xhr ) {
var port = settings.port;
if ( settings.mode === "abort" ) {
if ( pendingRequests[port] ) {
pendingRequests[port].abort();
}
pendingRequests[port] = xhr;
}
});
} else {
// Proxy ajax
ajax = $.ajax;
$.ajax = function( settings ) {
var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
port = ( "port" in settings ? settings : $.ajaxSettings ).port;
if ( mode === "abort" ) {
if ( pendingRequests[port] ) {
pendingRequests[port].abort();
}
pendingRequests[port] = ajax.apply(this, arguments);
return pendingRequests[port];
}
return ajax.apply(this, arguments);
};
}
// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
$.extend($.fn, {
validateDelegate: function( delegate, type, handler ) {
return this.bind(type, function( event ) {
var target = $(event.target);
if ( target.is(delegate) ) {
return handler.apply(target, arguments);
}
});
}
});
}));

View File

@ -1,4 +0,0 @@
/*! jQuery Validation Plugin - v1.13.1 - 10/14/2014
* http://jqueryvalidation.org/
* Copyright (c) 2014 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.validateDelegate(":submit","click",function(b){c.settings.submitHandler&&(c.submitButton=b.target),a(b.target).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(b.target).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.submit(function(b){function d(){var d,e;return c.settings.submitHandler?(c.submitButton&&(d=a("<input type='hidden'/>").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),e=c.settings.submitHandler.call(c,c.currentForm,b),c.submitButton&&d.remove(),void 0!==e?e:!1):!0}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c;return a(this[0]).is("form")?b=this.validate().form():(b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b})),b},removeAttrs:function(b){var c={},d=this;return a.each(b.split(/\s/),function(a,b){c[b]=d.attr(b),d.removeAttr(b)}),c},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(b,c){i[c]=f[c],delete f[c],"required"===c&&a(j).removeAttr("aria-required")}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g),a(j).attr("aria-required","true")),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}),a.extend(a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){return!!a.trim(""+a(b).val())},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(a,b){(9!==b.which||""!==this.elementValue(a))&&(a.name in this.submitted||a===this.lastElement)&&this.element(a)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date ( ISO ).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){var c=a.data(this[0].form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!this.is(e.ignore)&&e[d].call(c,this[0],b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).validateDelegate(":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'] ,[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox']","focusin focusout keyup",b).validateDelegate("select, option, [type='radio'], [type='checkbox']","click",b),this.settings.invalidHandler&&a(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler),a(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required","true")},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c=this.clean(b),d=this.validationTargetFor(c),e=!0;return this.lastElement=d,void 0===d?delete this.invalid[c.name]:(this.prepareElement(d),this.currentElements=a(d),e=this.check(d)!==!1,e?delete this.invalid[d.name]:this.invalid[d.name]=!0),a(b).attr("aria-invalid",!e),this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),e},showErrors:function(b){if(b){a.extend(this.errorMap,b),this.errorList=[];for(var c in b)this.errorList.push({message:b[c],element:this.findByName(c)[0]});this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors(),this.elements().removeClass(this.settings.errorClass).removeData("previousValue").removeAttr("aria-invalid")},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled], [readonly]").not(this.settings.ignore).filter(function(){return!this.name&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in c||!b.objectLength(a(this).rules())?!1:(c[this.name]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([]),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d=a(b),e=b.type;return"radio"===e||"checkbox"===e?a("input[name='"+b.name+"']:checked").val():"number"===e&&"undefined"!=typeof b.validity?b.validity.badInput?!1:d.val():(c=d.val(),"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f=a(b).rules(),g=a.map(f,function(a,b){return b}).length,h=!1,i=this.elementValue(b);for(d in f){e={method:d,parameters:f[d]};try{if(c=a.validator.methods[d].call(this,i,b,e.parameters),"dependency-mismatch"===c&&1===g){h=!0;continue}if(h=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(j){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",j),j}}if(!h)return this.objectLength(f)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(void 0!==arguments[a])return arguments[a];return void 0},defaultMessage:function(b,c){return this.findDefined(this.customMessage(b.name,c),this.customDataMessage(b,c),!this.settings.ignoreTitle&&b.title||void 0,a.validator.messages[c],"<strong>Warning: No message defined for "+b.name+"</strong>")},formatAndAdd:function(b,c){var d=this.defaultMessage(b,c.method),e=/\$?\{(\d+)\}/g;"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),this.errorList.push({message:d,element:b,method:c.method}),this.errorMap[b.name]=d,this.submitted[b.name]=d},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g=this.errorsFor(b),h=this.idOrName(b),i=a(b).attr("aria-describedby");g.length?(g.removeClass(this.settings.validClass).addClass(this.settings.errorClass),g.html(c)):(g=a("<"+this.settings.errorElement+">").attr("id",h+"-error").addClass(this.settings.errorClass).html(c||""),d=g,this.settings.wrapper&&(d=g.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement(d,a(b)):d.insertAfter(b),g.is("label")?g.attr("for",h):0===g.parents("label[for='"+h+"']").length&&(f=g.attr("id").replace(/(:|\.|\[|\])/g,"\\$1"),i?i.match(new RegExp("\\b"+f+"\\b"))||(i+=" "+f):i=f,a(b).attr("aria-describedby",i),e=this.groups[b.name],e&&a.each(this.groups,function(b,c){c===e&&a("[name='"+b+"']",this.currentForm).attr("aria-describedby",g.attr("id"))}))),!c&&this.settings.success&&(g.text(""),"string"==typeof this.settings.success?g.addClass(this.settings.success):this.settings.success(g,b)),this.toShow=this.toShow.add(g)},errorsFor:function(b){var c=this.idOrName(b),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+d.replace(/\s+/g,", #")),this.errors().filter(e)},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+b+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):!0},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(a){this.pending[a.name]||(this.pendingRequest++,this.pending[a.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b){return a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,"remote")})}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),/min|max/.test(c)&&(null===g||/number|range|text/.test(g))&&(d=Number(d)),d||0===d?e[c]=d:g===c&&"range"!==g&&(e[c]=!0);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b);for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),void 0!==d&&(e[c]=d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0!==e.param?e.param:!0:delete b[d]}}),a.each(b,function(d,e){b[d]=a.isFunction(e)?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:a.trim(b).length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||d>=e},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||c>=a},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d){if(this.optional(c))return"dependency-mismatch";var e,f,g=this.previousValue(c);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),g.originalMessage=this.settings.messages[c.name].remote,this.settings.messages[c.name].remote=g.message,d="string"==typeof d&&{url:d}||d,g.old===b?g.valid:(g.old=b,e=this,this.startRequest(c),f={},f[c.name]=b,a.ajax(a.extend(!0,{url:d,mode:"abort",port:"validate"+c.name,dataType:"json",data:f,context:e.currentForm,success:function(d){var f,h,i,j=d===!0||"true"===d;e.settings.messages[c.name].remote=g.originalMessage,j?(i=e.formSubmitted,e.prepareElement(c),e.formSubmitted=i,e.successList.push(c),delete e.invalid[c.name],e.showErrors()):(f={},h=d||e.defaultMessage(c,"remote"),f[c.name]=g.message=a.isFunction(h)?h(b):h,e.invalid[c.name]=!0,e.showErrors(f)),g.valid=j,e.stopRequest(c,j)}},d)),"pending")}}}),a.format=function(){throw"$.format has been deprecated. Please use $.validator.format instead."};var b,c={};a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)}),a.extend(a.fn,{validateDelegate:function(b,c,d){return this.bind(c,function(c){var e=a(c.target);return e.is(b)?d.apply(e,arguments):void 0})}})});

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: AR (Arabic; العربية)
*/
$.extend($.validator.messages, {
required: "هذا الحقل إلزامي",
remote: "يرجى تصحيح هذا الحقل للمتابعة",
email: "رجاء إدخال عنوان بريد إلكتروني صحيح",
url: "رجاء إدخال عنوان موقع إلكتروني صحيح",
date: "رجاء إدخال تاريخ صحيح",
dateISO: "رجاء إدخال تاريخ صحيح (ISO)",
number: "رجاء إدخال عدد بطريقة صحيحة",
digits: "رجاء إدخال أرقام فقط",
creditcard: "رجاء إدخال رقم بطاقة ائتمان صحيح",
equalTo: "رجاء إدخال نفس القيمة",
extension: "رجاء إدخال ملف بامتداد موافق عليه",
maxlength: $.validator.format("الحد الأقصى لعدد الحروف هو {0}"),
minlength: $.validator.format("الحد الأدنى لعدد الحروف هو {0}"),
rangelength: $.validator.format("عدد الحروف يجب أن يكون بين {0} و {1}"),
range: $.validator.format("رجاء إدخال عدد قيمته بين {0} و {1}"),
max: $.validator.format("رجاء إدخال عدد أقل من أو يساوي (0}"),
min: $.validator.format("رجاء إدخال عدد أكبر من أو يساوي (0}")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: BG (Bulgarian; български език)
*/
$.extend($.validator.messages, {
required: "Полето е задължително.",
remote: "Моля, въведете правилната стойност.",
email: "Моля, въведете валиден email.",
url: "Моля, въведете валидно URL.",
date: "Моля, въведете валидна дата.",
dateISO: "Моля, въведете валидна дата (ISO).",
number: "Моля, въведете валиден номер.",
digits: "Моля, въведете само цифри.",
creditcard: "Моля, въведете валиден номер на кредитна карта.",
equalTo: "Моля, въведете същата стойност отново.",
extension: "Моля, въведете стойност с валидно разширение.",
maxlength: $.validator.format("Моля, въведете повече от {0} символа."),
minlength: $.validator.format("Моля, въведете поне {0} символа."),
rangelength: $.validator.format("Моля, въведете стойност с дължина между {0} и {1} символа."),
range: $.validator.format("Моля, въведете стойност между {0} и {1}."),
max: $.validator.format("Моля, въведете стойност по-малка или равна на {0}."),
min: $.validator.format("Моля, въведете стойност по-голяма или равна на {0}.")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: bn_BD (Bengali, Bangladesh)
*/
$.extend($.validator.messages, {
required: "এই তথ্যটি আবশ্যক।",
remote: "এই তথ্যটি ঠিক করুন।",
email: "অনুগ্রহ করে একটি সঠিক মেইল ঠিকানা লিখুন।",
url: "অনুগ্রহ করে একটি সঠিক লিঙ্ক দিন।",
date: "তারিখ সঠিক নয়।",
dateISO: "অনুগ্রহ করে একটি সঠিক (ISO) তারিখ লিখুন।",
number: "অনুগ্রহ করে একটি সঠিক নম্বর লিখুন।",
digits: "এখানে শুধু সংখ্যা ব্যবহার করা যাবে।",
creditcard: "অনুগ্রহ করে একটি ক্রেডিট কার্ডের সঠিক নম্বর লিখুন।",
equalTo: "একই মান আবার লিখুন।",
extension: "সঠিক ধরনের ফাইল আপলোড করুন।",
maxlength: $.validator.format("{0}টির বেশি অক্ষর লেখা যাবে না।"),
minlength: $.validator.format("{0}টির কম অক্ষর লেখা যাবে না।"),
rangelength: $.validator.format("{0} থেকে {1} টি অক্ষর সম্বলিত মান লিখুন।"),
range: $.validator.format("{0} থেকে {1} এর মধ্যে একটি মান ব্যবহার করুন।"),
max: $.validator.format("অনুগ্রহ করে {0} বা তার চাইতে কম মান ব্যবহার করুন।"),
min: $.validator.format("অনুগ্রহ করে {0} বা তার চাইতে বেশি মান ব্যবহার করুন।")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: CA (Catalan; català)
*/
$.extend($.validator.messages, {
required: "Aquest camp és obligatori.",
remote: "Si us plau, omple aquest camp.",
email: "Si us plau, escriu una adreça de correu-e vàlida",
url: "Si us plau, escriu una URL vàlida.",
date: "Si us plau, escriu una data vàlida.",
dateISO: "Si us plau, escriu una data (ISO) vàlida.",
number: "Si us plau, escriu un número enter vàlid.",
digits: "Si us plau, escriu només dígits.",
creditcard: "Si us plau, escriu un número de tarjeta vàlid.",
equalTo: "Si us plau, escriu el maateix valor de nou.",
extension: "Si us plau, escriu un valor amb una extensió acceptada.",
maxlength: $.validator.format("Si us plau, no escriguis més de {0} caracters."),
minlength: $.validator.format("Si us plau, no escriguis menys de {0} caracters."),
rangelength: $.validator.format("Si us plau, escriu un valor entre {0} i {1} caracters."),
range: $.validator.format("Si us plau, escriu un valor entre {0} i {1}."),
max: $.validator.format("Si us plau, escriu un valor menor o igual a {0}."),
min: $.validator.format("Si us plau, escriu un valor major o igual a {0}.")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: CS (Czech; čeština, český jazyk)
*/
$.extend($.validator.messages, {
required: "Tento údaj je povinný.",
remote: "Prosím, opravte tento údaj.",
email: "Prosím, zadejte platný e-mail.",
url: "Prosím, zadejte platné URL.",
date: "Prosím, zadejte platné datum.",
dateISO: "Prosím, zadejte platné datum (ISO).",
number: "Prosím, zadejte číslo.",
digits: "Prosím, zadávejte pouze číslice.",
creditcard: "Prosím, zadejte číslo kreditní karty.",
equalTo: "Prosím, zadejte znovu stejnou hodnotu.",
extension: "Prosím, zadejte soubor se správnou příponou.",
maxlength: $.validator.format("Prosím, zadejte nejvíce {0} znaků."),
minlength: $.validator.format("Prosím, zadejte nejméně {0} znaků."),
rangelength: $.validator.format("Prosím, zadejte od {0} do {1} znaků."),
range: $.validator.format("Prosím, zadejte hodnotu od {0} do {1}."),
max: $.validator.format("Prosím, zadejte hodnotu menší nebo rovnu {0}."),
min: $.validator.format("Prosím, zadejte hodnotu větší nebo rovnu {0}.")
});
}));

View File

@ -1,30 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: DA (Danish; dansk)
*/
$.extend($.validator.messages, {
required: "Dette felt er påkrævet.",
maxlength: $.validator.format("Indtast højst {0} tegn."),
minlength: $.validator.format("Indtast mindst {0} tegn."),
rangelength: $.validator.format("Indtast mindst {0} og højst {1} tegn."),
email: "Indtast en gyldig email-adresse.",
url: "Indtast en gyldig URL.",
date: "Indtast en gyldig dato.",
number: "Indtast et tal.",
digits: "Indtast kun cifre.",
equalTo: "Indtast den samme værdi igen.",
range: $.validator.format("Angiv en værdi mellem {0} og {1}."),
max: $.validator.format("Angiv en værdi der højst er {0}."),
min: $.validator.format("Angiv en værdi der mindst er {0}."),
creditcard: "Indtast et gyldigt kreditkortnummer."
});
}));

View File

@ -1,30 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: DE (German, Deutsch)
*/
$.extend($.validator.messages, {
required: "Dieses Feld ist ein Pflichtfeld.",
maxlength: $.validator.format("Geben Sie bitte maximal {0} Zeichen ein."),
minlength: $.validator.format("Geben Sie bitte mindestens {0} Zeichen ein."),
rangelength: $.validator.format("Geben Sie bitte mindestens {0} und maximal {1} Zeichen ein."),
email: "Geben Sie bitte eine gültige E-Mail Adresse ein.",
url: "Geben Sie bitte eine gültige URL ein.",
date: "Bitte geben Sie ein gültiges Datum ein.",
number: "Geben Sie bitte eine Nummer ein.",
digits: "Geben Sie bitte nur Ziffern ein.",
equalTo: "Bitte denselben Wert wiederholen.",
range: $.validator.format("Geben Sie bitte einen Wert zwischen {0} und {1} ein."),
max: $.validator.format("Geben Sie bitte einen Wert kleiner oder gleich {0} ein."),
min: $.validator.format("Geben Sie bitte einen Wert größer oder gleich {0} ein."),
creditcard: "Geben Sie bitte eine gültige Kreditkarten-Nummer ein."
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: EL (Greek; ελληνικά)
*/
$.extend($.validator.messages, {
required: "Αυτό το πεδίο είναι υποχρεωτικό.",
remote: "Παρακαλώ διορθώστε αυτό το πεδίο.",
email: "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση email.",
url: "Παρακαλώ εισάγετε ένα έγκυρο URL.",
date: "Παρακαλώ εισάγετε μια έγκυρη ημερομηνία.",
dateISO: "Παρακαλώ εισάγετε μια έγκυρη ημερομηνία (ISO).",
number: "Παρακαλώ εισάγετε έναν έγκυρο αριθμό.",
digits: "Παρακαλώ εισάγετε μόνο αριθμητικά ψηφία.",
creditcard: "Παρακαλώ εισάγετε έναν έγκυρο αριθμό πιστωτικής κάρτας.",
equalTo: "Παρακαλώ εισάγετε την ίδια τιμή ξανά.",
extension: "Παρακαλώ εισάγετε μια τιμή με έγκυρη επέκταση αρχείου.",
maxlength: $.validator.format("Παρακαλώ εισάγετε μέχρι και {0} χαρακτήρες."),
minlength: $.validator.format("Παρακαλώ εισάγετε τουλάχιστον {0} χαρακτήρες."),
rangelength: $.validator.format("Παρακαλώ εισάγετε μια τιμή με μήκος μεταξύ {0} και {1} χαρακτήρων."),
range: $.validator.format("Παρακαλώ εισάγετε μια τιμή μεταξύ {0} και {1}."),
max: $.validator.format("Παρακαλώ εισάγετε μια τιμή μικρότερη ή ίση του {0}."),
min: $.validator.format("Παρακαλώ εισάγετε μια τιμή μεγαλύτερη ή ίση του {0}.")
});
}));

View File

@ -1,36 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: ES (Spanish; Español)
*/
$.extend($.validator.messages, {
required: "Este campo es obligatorio.",
remote: "Por favor, rellena este campo.",
email: "Por favor, escribe una dirección de correo válida.",
url: "Por favor, escribe una URL válida.",
date: "Por favor, escribe una fecha válida.",
dateISO: "Por favor, escribe una fecha (ISO) válida.",
number: "Por favor, escribe un número válido.",
digits: "Por favor, escribe sólo dígitos.",
creditcard: "Por favor, escribe un número de tarjeta válido.",
equalTo: "Por favor, escribe el mismo valor de nuevo.",
extension: "Por favor, escribe un valor con una extensión aceptada.",
maxlength: $.validator.format("Por favor, no escribas más de {0} caracteres."),
minlength: $.validator.format("Por favor, no escribas menos de {0} caracteres."),
rangelength: $.validator.format("Por favor, escribe un valor entre {0} y {1} caracteres."),
range: $.validator.format("Por favor, escribe un valor entre {0} y {1}."),
max: $.validator.format("Por favor, escribe un valor menor o igual a {0}."),
min: $.validator.format("Por favor, escribe un valor mayor o igual a {0}."),
nifES: "Por favor, escribe un NIF válido.",
nieES: "Por favor, escribe un NIE válido.",
cifES: "Por favor, escribe un CIF válido."
});
}));

View File

@ -1,37 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: ES (Spanish; Español)
* Region: AR (Argentina)
*/
$.extend($.validator.messages, {
required: "Este campo es obligatorio.",
remote: "Por favor, completá este campo.",
email: "Por favor, escribí una dirección de correo válida.",
url: "Por favor, escribí una URL válida.",
date: "Por favor, escribí una fecha válida.",
dateISO: "Por favor, escribí una fecha (ISO) válida.",
number: "Por favor, escribí un número entero válido.",
digits: "Por favor, escribí sólo dígitos.",
creditcard: "Por favor, escribí un número de tarjeta válido.",
equalTo: "Por favor, escribí el mismo valor de nuevo.",
extension: "Por favor, escribí un valor con una extensión aceptada.",
maxlength: $.validator.format("Por favor, no escribas más de {0} caracteres."),
minlength: $.validator.format("Por favor, no escribas menos de {0} caracteres."),
rangelength: $.validator.format("Por favor, escribí un valor entre {0} y {1} caracteres."),
range: $.validator.format("Por favor, escribí un valor entre {0} y {1}."),
max: $.validator.format("Por favor, escribí un valor menor o igual a {0}."),
min: $.validator.format("Por favor, escribí un valor mayor o igual a {0}."),
nifES: "Por favor, escribí un NIF válido.",
nieES: "Por favor, escribí un NIE válido.",
cifES: "Por favor, escribí un CIF válido."
});
}));

View File

@ -1,31 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: ET (Estonian; eesti, eesti keel)
*/
$.extend($.validator.messages, {
required: "See väli peab olema täidetud.",
maxlength: $.validator.format("Palun sisestage vähem kui {0} tähemärki."),
minlength: $.validator.format("Palun sisestage vähemalt {0} tähemärki."),
rangelength: $.validator.format("Palun sisestage väärtus vahemikus {0} kuni {1} tähemärki."),
email: "Palun sisestage korrektne e-maili aadress.",
url: "Palun sisestage korrektne URL.",
date: "Palun sisestage korrektne kuupäev.",
dateISO: "Palun sisestage korrektne kuupäev (YYYY-MM-DD).",
number: "Palun sisestage korrektne number.",
digits: "Palun sisestage ainult numbreid.",
equalTo: "Palun sisestage sama väärtus uuesti.",
range: $.validator.format("Palun sisestage väärtus vahemikus {0} kuni {1}."),
max: $.validator.format("Palun sisestage väärtus, mis on väiksem või võrdne arvuga {0}."),
min: $.validator.format("Palun sisestage väärtus, mis on suurem või võrdne arvuga {0}."),
creditcard: "Palun sisestage korrektne krediitkaardi number."
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: EU (Basque; euskara, euskera)
*/
$.extend($.validator.messages, {
required: "Eremu hau beharrezkoa da.",
remote: "Mesedez, bete eremu hau.",
email: "Mesedez, idatzi baliozko posta helbide bat.",
url: "Mesedez, idatzi baliozko URL bat.",
date: "Mesedez, idatzi baliozko data bat.",
dateISO: "Mesedez, idatzi baliozko (ISO) data bat.",
number: "Mesedez, idatzi baliozko zenbaki oso bat.",
digits: "Mesedez, idatzi digituak soilik.",
creditcard: "Mesedez, idatzi baliozko txartel zenbaki bat.",
equalTo: "Mesedez, idatzi berdina berriro ere.",
extension: "Mesedez, idatzi onartutako luzapena duen balio bat.",
maxlength: $.validator.format("Mesedez, ez idatzi {0} karaktere baino gehiago."),
minlength: $.validator.format("Mesedez, ez idatzi {0} karaktere baino gutxiago."),
rangelength: $.validator.format("Mesedez, idatzi {0} eta {1} karaktere arteko balio bat."),
range: $.validator.format("Mesedez, idatzi {0} eta {1} arteko balio bat."),
max: $.validator.format("Mesedez, idatzi {0} edo txikiagoa den balio bat."),
min: $.validator.format("Mesedez, idatzi {0} edo handiagoa den balio bat.")
});
}));

View File

@ -1,36 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: FA (Persian; فارسی)
*/
$.extend($.validator.messages, {
required: "تکمیل این فیلد اجباری است.",
remote: "لطفا این فیلد را تصحیح کنید.",
email: ".لطفا یک ایمیل صحیح وارد کنید",
url: "لطفا آدرس صحیح وارد کنید.",
date: "لطفا یک تاریخ صحیح وارد کنید",
dateFA: "لطفا یک تاریخ صحیح وارد کنید",
dateISO: "لطفا تاریخ صحیح وارد کنید (ISO).",
number: "لطفا عدد صحیح وارد کنید.",
digits: "لطفا تنها رقم وارد کنید",
creditcard: "لطفا کریدیت کارت صحیح وارد کنید.",
equalTo: "لطفا مقدار برابری وارد کنید",
extension: "لطفا مقداری وارد کنید که ",
maxlength: $.validator.format("لطفا بیشتر از {0} حرف وارد نکنید."),
minlength: $.validator.format("لطفا کمتر از {0} حرف وارد نکنید."),
rangelength: $.validator.format("لطفا مقداری بین {0} تا {1} حرف وارد کنید."),
range: $.validator.format("لطفا مقداری بین {0} تا {1} حرف وارد کنید."),
max: $.validator.format("لطفا مقداری کمتر از {0} حرف وارد کنید."),
min: $.validator.format("لطفا مقداری بیشتر از {0} حرف وارد کنید."),
minWords: $.validator.format("لطفا حداقل {0} کلمه وارد کنید."),
maxWords: $.validator.format("لطفا حداکثر {0} کلمه وارد کنید.")
});
}));

View File

@ -1,31 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: FI (Finnish; suomi, suomen kieli)
*/
$.extend($.validator.messages, {
required: "T&auml;m&auml; kentt&auml; on pakollinen.",
email: "Sy&ouml;t&auml; oikea s&auml;hk&ouml;postiosoite.",
url: "Sy&ouml;t&auml; oikea URL osoite.",
date: "Sy&ouml;t&auml; oike p&auml;iv&auml;m&auml;&auml;r&auml;.",
dateISO: "Sy&ouml;t&auml; oike p&auml;iv&auml;m&auml;&auml;r&auml; (VVVV-MM-DD).",
number: "Sy&ouml;t&auml; numero.",
creditcard: "Sy&ouml;t&auml; voimassa oleva luottokorttinumero.",
digits: "Sy&ouml;t&auml; pelk&auml;st&auml;&auml;n numeroita.",
equalTo: "Sy&ouml;t&auml; sama arvo uudestaan.",
maxlength: $.validator.format("Voit sy&ouml;tt&auml;&auml; enint&auml;&auml;n {0} merkki&auml;."),
minlength: $.validator.format("V&auml;hint&auml;&auml;n {0} merkki&auml;."),
rangelength: $.validator.format("Sy&ouml;t&auml; v&auml;hint&auml;&auml;n {0} ja enint&auml;&auml;n {1} merkki&auml;."),
range: $.validator.format("Sy&ouml;t&auml; arvo {0} ja {1} v&auml;lilt&auml;."),
max: $.validator.format("Sy&ouml;t&auml; arvo joka on pienempi tai yht&auml; suuri kuin {0}."),
min: $.validator.format("Sy&ouml;t&auml; arvo joka on yht&auml; suuri tai suurempi kuin {0}.")
});
}));

View File

@ -1,59 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: FR (French; français)
*/
$.extend($.validator.messages, {
required: "Ce champ est obligatoire.",
remote: "Veuillez corriger ce champ.",
email: "Veuillez fournir une adresse électronique valide.",
url: "Veuillez fournir une adresse URL valide.",
date: "Veuillez fournir une date valide.",
dateISO: "Veuillez fournir une date valide (ISO).",
number: "Veuillez fournir un numéro valide.",
digits: "Veuillez fournir seulement des chiffres.",
creditcard: "Veuillez fournir un numéro de carte de crédit valide.",
equalTo: "Veuillez fournir encore la même valeur.",
extension: "Veuillez fournir une valeur avec une extension valide.",
maxlength: $.validator.format("Veuillez fournir au plus {0} caractères."),
minlength: $.validator.format("Veuillez fournir au moins {0} caractères."),
rangelength: $.validator.format("Veuillez fournir une valeur qui contient entre {0} et {1} caractères."),
range: $.validator.format("Veuillez fournir une valeur entre {0} et {1}."),
max: $.validator.format("Veuillez fournir une valeur inférieure ou égale à {0}."),
min: $.validator.format("Veuillez fournir une valeur supérieure ou égale à {0}."),
maxWords: $.validator.format("Veuillez fournir au plus {0} mots."),
minWords: $.validator.format("Veuillez fournir au moins {0} mots."),
rangeWords: $.validator.format("Veuillez fournir entre {0} et {1} mots."),
letterswithbasicpunc: "Veuillez fournir seulement des lettres et des signes de ponctuation.",
alphanumeric: "Veuillez fournir seulement des lettres, nombres, espaces et soulignages.",
lettersonly: "Veuillez fournir seulement des lettres.",
nowhitespace: "Veuillez ne pas inscrire d'espaces blancs.",
ziprange: "Veuillez fournir un code postal entre 902xx-xxxx et 905-xx-xxxx.",
integer: "Veuillez fournir un nombre non décimal qui est positif ou négatif.",
vinUS: "Veuillez fournir un numéro d'identification du véhicule (VIN).",
dateITA: "Veuillez fournir une date valide.",
time: "Veuillez fournir une heure valide entre 00:00 et 23:59.",
phoneUS: "Veuillez fournir un numéro de téléphone valide.",
phoneUK: "Veuillez fournir un numéro de téléphone valide.",
mobileUK: "Veuillez fournir un numéro de téléphone mobile valide.",
strippedminlength: $.validator.format("Veuillez fournir au moins {0} caractères."),
email2: "Veuillez fournir une adresse électronique valide.",
url2: "Veuillez fournir une adresse URL valide.",
creditcardtypes: "Veuillez fournir un numéro de carte de crédit valide.",
ipv4: "Veuillez fournir une adresse IP v4 valide.",
ipv6: "Veuillez fournir une adresse IP v6 valide.",
require_from_group: "Veuillez fournir au moins {0} de ces champs.",
nifES: "Veuillez fournir un numéro NIF valide.",
nieES: "Veuillez fournir un numéro NIE valide.",
cifES: "Veuillez fournir un numéro CIF valide.",
postalCodeCA: "Veuillez fournir un code postal valide."
});
}));

View File

@ -1,38 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: GL (Galician; Galego)
*/
(function($) {
$.extend($.validator.messages, {
required: "Este campo é obrigatorio.",
remote: "Por favor, cubre este campo.",
email: "Por favor, escribe unha dirección de correo válida.",
url: "Por favor, escribe unha URL válida.",
date: "Por favor, escribe unha data válida.",
dateISO: "Por favor, escribe unha data (ISO) válida.",
number: "Por favor, escribe un número válido.",
digits: "Por favor, escribe só díxitos.",
creditcard: "Por favor, escribe un número de tarxeta válido.",
equalTo: "Por favor, escribe o mesmo valor de novo.",
extension: "Por favor, escribe un valor cunha extensión aceptada.",
maxlength: $.validator.format("Por favor, non escribas máis de {0} caracteres."),
minlength: $.validator.format("Por favor, non escribas menos de {0} caracteres."),
rangelength: $.validator.format("Por favor, escribe un valor entre {0} e {1} caracteres."),
range: $.validator.format("Por favor, escribe un valor entre {0} e {1}."),
max: $.validator.format("Por favor, escribe un valor menor ou igual a {0}."),
min: $.validator.format("Por favor, escribe un valor maior ou igual a {0}."),
nifES: "Por favor, escribe un NIF válido.",
nieES: "Por favor, escribe un NIE válido.",
cifES: "Por favor, escribe un CIF válido."
});
}(jQuery));
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: HE (Hebrew; עברית)
*/
$.extend($.validator.messages, {
required: "השדה הזה הינו שדה חובה",
remote: "נא לתקן שדה זה",
email: "נא למלא כתובת דוא\"ל חוקית",
url: "נא למלא כתובת אינטרנט חוקית",
date: "נא למלא תאריך חוקי",
dateISO: "נא למלא תאריך חוקי (ISO)",
number: "נא למלא מספר",
digits: "נא למלא רק מספרים",
creditcard: "נא למלא מספר כרטיס אשראי חוקי",
equalTo: "נא למלא את אותו ערך שוב",
extension: "נא למלא ערך עם סיומת חוקית",
maxlength: $.validator.format(".נא לא למלא יותר מ- {0} תווים"),
minlength: $.validator.format("נא למלא לפחות {0} תווים"),
rangelength: $.validator.format("נא למלא ערך בין {0} ל- {1} תווים"),
range: $.validator.format("נא למלא ערך בין {0} ל- {1}"),
max: $.validator.format("נא למלא ערך קטן או שווה ל- {0}"),
min: $.validator.format("נא למלא ערך גדול או שווה ל- {0}")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: HR (Croatia; hrvatski jezik)
*/
$.extend($.validator.messages, {
required: "Ovo polje je obavezno.",
remote: "Ovo polje treba popraviti.",
email: "Unesite ispravnu e-mail adresu.",
url: "Unesite ispravan URL.",
date: "Unesite ispravan datum.",
dateISO: "Unesite ispravan datum (ISO).",
number: "Unesite ispravan broj.",
digits: "Unesite samo brojeve.",
creditcard: "Unesite ispravan broj kreditne kartice.",
equalTo: "Unesite ponovo istu vrijednost.",
extension: "Unesite vrijednost sa ispravnom ekstenzijom.",
maxlength: $.validator.format("Maksimalni broj znakova je {0} ."),
minlength: $.validator.format("Minimalni broj znakova je {0} ."),
rangelength: $.validator.format("Unesite vrijednost između {0} i {1} znakova."),
range: $.validator.format("Unesite vrijednost između {0} i {1}."),
max: $.validator.format("Unesite vrijednost manju ili jednaku {0}."),
min: $.validator.format("Unesite vrijednost veću ili jednaku {0}.")
});
}));

View File

@ -1,32 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: HU (Hungarian; Magyar)
*/
$.extend($.validator.messages, {
required: "Kötelező megadni.",
maxlength: $.validator.format("Legfeljebb {0} karakter hosszú legyen."),
minlength: $.validator.format("Legalább {0} karakter hosszú legyen."),
rangelength: $.validator.format("Legalább {0} és legfeljebb {1} karakter hosszú legyen."),
email: "Érvényes e-mail címnek kell lennie.",
url: "Érvényes URL-nek kell lennie.",
date: "Dátumnak kell lennie.",
number: "Számnak kell lennie.",
digits: "Csak számjegyek lehetnek.",
equalTo: "Meg kell egyeznie a két értéknek.",
range: $.validator.format("{0} és {1} közé kell esnie."),
max: $.validator.format("Nem lehet nagyobb, mint {0}."),
min: $.validator.format("Nem lehet kisebb, mint {0}."),
creditcard: "Érvényes hitelkártyaszámnak kell lennie.",
remote: "Kérem javítsa ki ezt a mezőt.",
dateISO: "Kérem írjon be egy érvényes dátumot (ISO)."
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: HY_AM (Armenian; հայերեն լեզու)
*/
$.extend($.validator.messages, {
required: "Պարտադիր լրացման դաշտ",
remote: "Ներմուծեք ճիշտ արժեքը",
email: "Ներմուծեք վավեր էլեկտրոնային փոստի հասցե",
url: "Ներմուծեք վավեր URL",
date: "Ներմուծեք վավեր ամսաթիվ",
dateISO: "Ներմուծեք ISO ֆորմատով վավեր ամսաթիվ։",
number: "Ներմուծեք թիվ",
digits: "Ներմուծեք միայն թվեր",
creditcard: "Ներմուծեք ճիշտ բանկային քարտի համար",
equalTo: "Ներմուծեք միևնուն արժեքը ևս մեկ անգամ",
extension: "Ընտրեք ճիշտ ընդլանումով ֆայլ",
maxlength: $.validator.format("Ներմուծեք ոչ ավել քան {0} նիշ"),
minlength: $.validator.format("Ներմուծեք ոչ պակաս քան {0} նիշ"),
rangelength: $.validator.format("Ներմուծեք {0}֊ից {1} երկարությամբ արժեք"),
range: $.validator.format("Ներմուծեք թիվ {0}֊ից {1} միջակայքում"),
max: $.validator.format("Ներմուծեք թիվ, որը փոքր կամ հավասար է {0}֊ին"),
min: $.validator.format("Ներմուծեք թիվ, որը մեծ կամ հավասար է {0}֊ին")
});
}));

View File

@ -1,32 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: ID (Indonesia; Indonesian)
*/
$.extend($.validator.messages, {
required: "Kolom ini diperlukan.",
remote: "Harap benarkan kolom ini.",
email: "Silakan masukkan format email yang benar.",
url: "Silakan masukkan format URL yang benar.",
date: "Silakan masukkan format tanggal yang benar.",
dateISO: "Silakan masukkan format tanggal(ISO) yang benar.",
number: "Silakan masukkan angka yang benar.",
digits: "Harap masukan angka saja.",
creditcard: "Harap masukkan format kartu kredit yang benar.",
equalTo: "Harap masukkan nilai yg sama dengan sebelumnya.",
maxlength: $.validator.format("Input dibatasi hanya {0} karakter."),
minlength: $.validator.format("Input tidak kurang dari {0} karakter."),
rangelength: $.validator.format("Panjang karakter yg diizinkan antara {0} dan {1} karakter."),
range: $.validator.format("Harap masukkan nilai antara {0} dan {1}."),
max: $.validator.format("Harap masukkan nilai lebih kecil atau sama dengan {0}."),
min: $.validator.format("Harap masukkan nilai lebih besar atau sama dengan {0}.")
});
}));

View File

@ -1,31 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: IS (Icelandic; íslenska)
*/
$.extend($.validator.messages, {
required: "Þessi reitur er nauðsynlegur.",
remote: "Lagaðu þennan reit.",
maxlength: $.validator.format("Sláðu inn mest {0} stafi."),
minlength: $.validator.format("Sláðu inn minnst {0} stafi."),
rangelength: $.validator.format("Sláðu inn minnst {0} og mest {1} stafi."),
email: "Sláðu inn gilt netfang.",
url: "Sláðu inn gilda vefslóð.",
date: "Sláðu inn gilda dagsetningu.",
number: "Sláðu inn tölu.",
digits: "Sláðu inn tölustafi eingöngu.",
equalTo: "Sláðu sama gildi inn aftur.",
range: $.validator.format("Sláðu inn gildi milli {0} og {1}."),
max: $.validator.format("Sláðu inn gildi sem er minna en eða jafnt og {0}."),
min: $.validator.format("Sláðu inn gildi sem er stærra en eða jafnt og {0}."),
creditcard: "Sláðu inn gilt greiðslukortanúmer."
});
}));

View File

@ -1,36 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: IT (Italian; Italiano)
*/
$.extend($.validator.messages, {
required: "Campo obbligatorio.",
remote: "Controlla questo campo.",
email: "Inserisci un indirizzo email valido.",
url: "Inserisci un indirizzo web valido.",
date: "Inserisci una data valida.",
dateISO: "Inserisci una data valida (ISO).",
number: "Inserisci un numero valido.",
digits: "Inserisci solo numeri.",
creditcard: "Inserisci un numero di carta di credito valido.",
equalTo: "Il valore non corrisponde.",
extension: "Inserisci un valore con un&apos;estensione valida.",
maxlength: $.validator.format("Non inserire pi&ugrave; di {0} caratteri."),
minlength: $.validator.format("Inserisci almeno {0} caratteri."),
rangelength: $.validator.format("Inserisci un valore compreso tra {0} e {1} caratteri."),
range: $.validator.format("Inserisci un valore compreso tra {0} e {1}."),
max: $.validator.format("Inserisci un valore minore o uguale a {0}."),
min: $.validator.format("Inserisci un valore maggiore o uguale a {0}."),
nifES: "Inserisci un NIF valido.",
nieES: "Inserisci un NIE valido.",
cifES: "Inserisci un CIF valido."
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: JA (Japanese; 日本語)
*/
$.extend($.validator.messages, {
required: "このフィールドは必須です。",
remote: "このフィールドを修正してください。",
email: "有効なEメールアドレスを入力してください。",
url: "有効なURLを入力してください。",
date: "有効な日付を入力してください。",
dateISO: "有効な日付ISOを入力してください。",
number: "有効な数字を入力してください。",
digits: "数字のみを入力してください。",
creditcard: "有効なクレジットカード番号を入力してください。",
equalTo: "同じ値をもう一度入力してください。",
extension: "有効な拡張子を含む値を入力してください。",
maxlength: $.validator.format("{0} 文字以内で入力してください。"),
minlength: $.validator.format("{0} 文字以上で入力してください。"),
rangelength: $.validator.format("{0} 文字から {1} 文字までの値を入力してください。"),
range: $.validator.format("{0} から {1} までの値を入力してください。"),
max: $.validator.format("{0} 以下の値を入力してください。"),
min: $.validator.format("{0} 以上の値を入力してください。")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: KA (Georgian; ქართული)
*/
$.extend($.validator.messages, {
required: "ამ ველის შევსება აუცილებელია.",
remote: "გთხოვთ მიუთითოთ სწორი მნიშვნელობა.",
email: "გთხოვთ მიუთითოთ ელ-ფოსტის კორექტული მისამართი.",
url: "გთხოვთ მიუთითოთ კორექტული URL.",
date: "გთხოვთ მიუთითოთ კორექტული თარიღი.",
dateISO: "გთხოვთ მიუთითოთ კორექტული თარიღი ISO ფორმატში.",
number: "გთხოვთ მიუთითოთ ციფრი.",
digits: "გთხოვთ მიუთითოთ მხოლოდ ციფრები.",
creditcard: "გთხოვთ მიუთითოთ საკრედიტო ბარათის კორექტული ნომერი.",
equalTo: "გთხოვთ მიუთითოთ ასეთივე მნიშვნელობა კიდევ ერთხელ.",
extension: "გთხოვთ აირჩიოთ ფაილი კორექტული გაფართოებით.",
maxlength: $.validator.format("დასაშვებია არაუმეტეს {0} სიმბოლო."),
minlength: $.validator.format("აუცილებელია შეიყვანოთ მინიმუმ {0} სიმბოლო."),
rangelength: $.validator.format("ტექსტში სიმბოლოების რაოდენობა უნდა იყოს {0}-დან {1}-მდე."),
range: $.validator.format("გთხოვთ შეიყვანოთ ციფრი {0}-დან {1}-მდე."),
max: $.validator.format("გთხოვთ შეიყვანოთ ციფრი რომელიც ნაკლებია ან უდრის {0}-ს."),
min: $.validator.format("გთხოვთ შეიყვანოთ ციფრი რომელიც მეტია ან უდრის {0}-ს.")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: KK (Kazakh; қазақ тілі)
*/
$.extend($.validator.messages, {
required: "Бұл өрісті міндетті түрде толтырыңыз.",
remote: "Дұрыс мағына енгізуіңізді сұраймыз.",
email: "Нақты электронды поштаңызды енгізуіңізді сұраймыз.",
url: "Нақты URL-ды енгізуіңізді сұраймыз.",
date: "Нақты URL-ды енгізуіңізді сұраймыз.",
dateISO: "Нақты ISO форматымен сәйкес датасын енгізуіңізді сұраймыз.",
number: "Күнді енгізуіңізді сұраймыз.",
digits: "Тек қана сандарды енгізуіңізді сұраймыз.",
creditcard: "Несие картасының нөмірін дұрыс енгізуіңізді сұраймыз.",
equalTo: "Осы мәнді қайта енгізуіңізді сұраймыз.",
extension: "Файлдың кеңейтуін дұрыс таңдаңыз.",
maxlength: $.validator.format("Ұзындығы {0} символдан көр болмасын."),
minlength: $.validator.format("Ұзындығы {0} символдан аз болмасын."),
rangelength: $.validator.format("Ұзындығы {0}-{1} дейін мән енгізуіңізді сұраймыз."),
range: $.validator.format("Пожалуйста, введите число от {0} до {1}. - {0} - {1} санын енгізуіңізді сұраймыз."),
max: $.validator.format("{0} аз немесе тең санын енгізуіңіді сұраймыз."),
min: $.validator.format("{0} көп немесе тең санын енгізуіңізді сұраймыз.")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: KO (Korean; 한국어)
*/
$.extend($.validator.messages, {
required: "필수 항목입니다.",
remote: "항목을 수정하세요.",
email: "유효하지 않은 E-Mail주소입니다.",
url: "유효하지 않은 URL입니다.",
date: "올바른 날짜를 입력하세요.",
dateISO: "올바른 날짜(ISO)를 입력하세요.",
number: "유효한 숫자가 아닙니다.",
digits: "숫자만 입력 가능합니다.",
creditcard: "신용카드 번호가 바르지 않습니다.",
equalTo: "같은 값을 다시 입력하세요.",
extension: "올바른 확장자가 아닙니다.",
maxlength: $.validator.format("{0}자를 넘을 수 없습니다. "),
minlength: $.validator.format("{0}자 이상 입력하세요."),
rangelength: $.validator.format("문자 길이가 {0} 에서 {1} 사이의 값을 입력하세요."),
range: $.validator.format("{0} 에서 {1} 사이의 값을 입력하세요."),
max: $.validator.format("{0} 이하의 값을 입력하세요."),
min: $.validator.format("{0} 이상의 값을 입력하세요.")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: LT (Lithuanian; lietuvių kalba)
*/
$.extend($.validator.messages, {
required: "Šis laukas yra privalomas.",
remote: "Prašau pataisyti šį lauką.",
email: "Prašau įvesti teisingą elektroninio pašto adresą.",
url: "Prašau įvesti teisingą URL.",
date: "Prašau įvesti teisingą datą.",
dateISO: "Prašau įvesti teisingą datą (ISO).",
number: "Prašau įvesti teisingą skaičių.",
digits: "Prašau naudoti tik skaitmenis.",
creditcard: "Prašau įvesti teisingą kreditinės kortelės numerį.",
equalTo: "Prašau įvestį tą pačią reikšmę dar kartą.",
extension: "Prašau įvesti reikšmę su teisingu plėtiniu.",
maxlength: $.validator.format("Prašau įvesti ne daugiau kaip {0} simbolių."),
minlength: $.validator.format("Prašau įvesti bent {0} simbolius."),
rangelength: $.validator.format("Prašau įvesti reikšmes, kurių ilgis nuo {0} iki {1} simbolių."),
range: $.validator.format("Prašau įvesti reikšmę intervale nuo {0} iki {1}."),
max: $.validator.format("Prašau įvesti reikšmę mažesnę arba lygią {0}."),
min: $.validator.format("Prašau įvesti reikšmę didesnę arba lygią {0}.")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: LV (Latvian; latviešu valoda)
*/
$.extend($.validator.messages, {
required: "Šis lauks ir obligāts.",
remote: "Lūdzu, pārbaudiet šo lauku.",
email: "Lūdzu, ievadiet derīgu e-pasta adresi.",
url: "Lūdzu, ievadiet derīgu URL adresi.",
date: "Lūdzu, ievadiet derīgu datumu.",
dateISO: "Lūdzu, ievadiet derīgu datumu (ISO).",
number: "Lūdzu, ievadiet derīgu numuru.",
digits: "Lūdzu, ievadiet tikai ciparus.",
creditcard: "Lūdzu, ievadiet derīgu kredītkartes numuru.",
equalTo: "Lūdzu, ievadiet to pašu vēlreiz.",
extension: "Lūdzu, ievadiet vērtību ar derīgu paplašinājumu.",
maxlength: $.validator.format("Lūdzu, ievadiet ne vairāk kā {0} rakstzīmes."),
minlength: $.validator.format("Lūdzu, ievadiet vismaz {0} rakstzīmes."),
rangelength: $.validator.format("Lūdzu ievadiet {0} līdz {1} rakstzīmes."),
range: $.validator.format("Lūdzu, ievadiet skaitli no {0} līdz {1}."),
max: $.validator.format("Lūdzu, ievadiet skaitli, kurš ir mazāks vai vienāds ar {0}."),
min: $.validator.format("Lūdzu, ievadiet skaitli, kurš ir lielāks vai vienāds ar {0}.")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: MY (Malay; Melayu)
*/
$.extend($.validator.messages, {
required: "Medan ini diperlukan.",
remote: "Sila betulkan medan ini.",
email: "Sila masukkan alamat emel yang betul.",
url: "Sila masukkan URL yang betul.",
date: "Sila masukkan tarikh yang betul.",
dateISO: "Sila masukkan tarikh(ISO) yang betul.",
number: "Sila masukkan nombor yang betul.",
digits: "Sila masukkan nilai digit sahaja.",
creditcard: "Sila masukkan nombor kredit kad yang betul.",
equalTo: "Sila masukkan nilai yang sama semula.",
extension: "Sila masukkan nilai yang telah diterima.",
maxlength: $.validator.format("Sila masukkan nilai tidak lebih dari {0} aksara."),
minlength: $.validator.format("Sila masukkan nilai sekurang-kurangnya {0} aksara."),
rangelength: $.validator.format("Sila masukkan panjang nilai antara {0} dan {1} aksara."),
range: $.validator.format("Sila masukkan nilai antara {0} dan {1} aksara."),
max: $.validator.format("Sila masukkan nilai yang kurang atau sama dengan {0}."),
min: $.validator.format("Sila masukkan nilai yang lebih atau sama dengan {0}.")
});
}));

View File

@ -1,43 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: NL (Dutch; Nederlands, Vlaams)
*/
$.extend($.validator.messages, {
required: "Dit is een verplicht veld.",
remote: "Controleer dit veld.",
email: "Vul hier een geldig e-mailadres in.",
url: "Vul hier een geldige URL in.",
date: "Vul hier een geldige datum in.",
dateISO: "Vul hier een geldige datum in (ISO-formaat).",
number: "Vul hier een geldig getal in.",
digits: "Vul hier alleen getallen in.",
creditcard: "Vul hier een geldig creditcardnummer in.",
equalTo: "Vul hier dezelfde waarde in.",
extension: "Vul hier een waarde in met een geldige extensie.",
maxlength: $.validator.format("Vul hier maximaal {0} tekens in."),
minlength: $.validator.format("Vul hier minimaal {0} tekens in."),
rangelength: $.validator.format("Vul hier een waarde in van minimaal {0} en maximaal {1} tekens."),
range: $.validator.format("Vul hier een waarde in van minimaal {0} en maximaal {1}."),
max: $.validator.format("Vul hier een waarde in kleiner dan of gelijk aan {0}."),
min: $.validator.format("Vul hier een waarde in groter dan of gelijk aan {0}."),
// for validations in additional-methods.js
iban: "Vul hier een geldig IBAN in.",
dateNL: "Vul hier een geldige datum in.",
phoneNL: "Vul hier een geldig Nederlands telefoonnummer in.",
mobileNL: "Vul hier een geldig Nederlands mobiel telefoonnummer in.",
postalcodeNL: "Vul hier een geldige postcode in.",
bankaccountNL: "Vul hier een geldig bankrekeningnummer in.",
giroaccountNL: "Vul hier een geldig gironummer in.",
bankorgiroaccountNL: "Vul hier een geldig bank- of gironummer in."
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: NO (Norwegian; Norsk)
*/
$.extend($.validator.messages, {
required: "Dette feltet er obligatorisk.",
maxlength: $.validator.format("Maksimalt {0} tegn."),
minlength: $.validator.format("Minimum {0} tegn."),
rangelength: $.validator.format("Angi minimum {0} og maksimum {1} tegn."),
email: "Oppgi en gyldig epostadresse.",
url: "Angi en gyldig URL.",
date: "Angi en gyldig dato.",
dateISO: "Angi en gyldig dato (&ARING;&ARING;&ARING;&ARING;-MM-DD).",
dateSE: "Angi en gyldig dato.",
number: "Angi et gyldig nummer.",
numberSE: "Angi et gyldig nummer.",
digits: "Skriv kun tall.",
equalTo: "Skriv samme verdi igjen.",
range: $.validator.format("Angi en verdi mellom {0} og {1}."),
max: $.validator.format("Angi en verdi som er mindre eller lik {0}."),
min: $.validator.format("Angi en verdi som er st&oslash;rre eller lik {0}."),
creditcard: "Angi et gyldig kredittkortnummer."
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: PL (Polish; język polski, polszczyzna)
*/
$.extend($.validator.messages, {
required: "To pole jest wymagane.",
remote: "Proszę o wypełnienie tego pola.",
email: "Proszę o podanie prawidłowego adresu email.",
url: "Proszę o podanie prawidłowego URL.",
date: "Proszę o podanie prawidłowej daty.",
dateISO: "Proszę o podanie prawidłowej daty (ISO).",
number: "Proszę o podanie prawidłowej liczby.",
digits: "Proszę o podanie samych cyfr.",
creditcard: "Proszę o podanie prawidłowej karty kredytowej.",
equalTo: "Proszę o podanie tej samej wartości ponownie.",
extension: "Proszę o podanie wartości z prawidłowym rozszerzeniem.",
maxlength: $.validator.format("Proszę o podanie nie więcej niż {0} znaków."),
minlength: $.validator.format("Proszę o podanie przynajmniej {0} znaków."),
rangelength: $.validator.format("Proszę o podanie wartości o długości od {0} do {1} znaków."),
range: $.validator.format("Proszę o podanie wartości z przedziału od {0} do {1}."),
max: $.validator.format("Proszę o podanie wartości mniejszej bądź równej {0}."),
min: $.validator.format("Proszę o podanie wartości większej bądź równej {0}.")
});
}));

View File

@ -1,38 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: PT (Portuguese; português)
* Region: BR (Brazil)
*/
$.extend($.validator.messages, {
required: "Este campo &eacute; requerido.",
remote: "Por favor, corrija este campo.",
email: "Por favor, forne&ccedil;a um endere&ccedil;o de email v&aacute;lido.",
url: "Por favor, forne&ccedil;a uma URL v&aacute;lida.",
date: "Por favor, forne&ccedil;a uma data v&aacute;lida.",
dateISO: "Por favor, forne&ccedil;a uma data v&aacute;lida (ISO).",
number: "Por favor, forne&ccedil;a um n&uacute;mero v&aacute;lido.",
digits: "Por favor, forne&ccedil;a somente d&iacute;gitos.",
creditcard: "Por favor, forne&ccedil;a um cart&atilde;o de cr&eacute;dito v&aacute;lido.",
equalTo: "Por favor, forne&ccedil;a o mesmo valor novamente.",
extension: "Por favor, forne&ccedil;a um valor com uma extens&atilde;o v&aacute;lida.",
maxlength: $.validator.format("Por favor, forne&ccedil;a n&atilde;o mais que {0} caracteres."),
minlength: $.validator.format("Por favor, forne&ccedil;a ao menos {0} caracteres."),
rangelength: $.validator.format("Por favor, forne&ccedil;a um valor entre {0} e {1} caracteres de comprimento."),
range: $.validator.format("Por favor, forne&ccedil;a um valor entre {0} e {1}."),
max: $.validator.format("Por favor, forne&ccedil;a um valor menor ou igual a {0}."),
min: $.validator.format("Por favor, forne&ccedil;a um valor maior ou igual a {0}."),
nifES: "Por favor, forne&ccedil;a um NIF v&aacute;lido.",
nieES: "Por favor, forne&ccedil;a um NIE v&aacute;lido.",
cifEE: "Por favor, forne&ccedil;a um CIF v&aacute;lido.",
postalcodeBR: "Por favor, forne&ccedil;a um CEP v&aacute;lido."
});
}));

View File

@ -1,37 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: PT (Portuguese; português)
* Region: PT (Portugal)
*/
$.extend($.validator.messages, {
required: "Campo de preenchimento obrigat&oacute;rio.",
remote: "Por favor, corrija este campo.",
email: "Por favor, introduza um endere&ccedil;o eletr&oacute;nico v&aacute;lido.",
url: "Por favor, introduza um URL v&aacute;lido.",
date: "Por favor, introduza uma data v&aacute;lida.",
dateISO: "Por favor, introduza uma data v&aacute;lida (ISO).",
number: "Por favor, introduza um n&uacute;mero v&aacute;lido.",
digits: "Por favor, introduza apenas d&iacute;gitos.",
creditcard: "Por favor, introduza um n&uacute;mero de cart&atilde;o de cr&eacute;dito v&aacute;lido.",
equalTo: "Por favor, introduza de novo o mesmo valor.",
extension: "Por favor, introduza um ficheiro com uma extens&atilde;o v&aacute;lida.",
maxlength: $.validator.format("Por favor, n&atilde;o introduza mais do que {0} caracteres."),
minlength: $.validator.format("Por favor, introduza pelo menos {0} caracteres."),
rangelength: $.validator.format("Por favor, introduza entre {0} e {1} caracteres."),
range: $.validator.format("Por favor, introduza um valor entre {0} e {1}."),
max: $.validator.format("Por favor, introduza um valor menor ou igual a {0}."),
min: $.validator.format("Por favor, introduza um valor maior ou igual a {0}."),
nifES: "Por favor, introduza um NIF v&aacute;lido.",
nieES: "Por favor, introduza um NIE v&aacute;lido.",
cifES: "Por favor, introduza um CIF v&aacute;lido."
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: RO (Romanian, limba română)
*/
$.extend($.validator.messages, {
required: "Acest câmp este obligatoriu.",
remote: "Te rugăm să completezi acest câmp.",
email: "Te rugăm să introduci o adresă de email validă",
url: "Te rugăm sa introduci o adresă URL validă.",
date: "Te rugăm să introduci o dată corectă.",
dateISO: "Te rugăm să introduci o dată (ISO) corectă.",
number: "Te rugăm să introduci un număr întreg valid.",
digits: "Te rugăm să introduci doar cifre.",
creditcard: "Te rugăm să introduci un numar de carte de credit valid.",
equalTo: "Te rugăm să reintroduci valoarea.",
extension: "Te rugăm să introduci o valoare cu o extensie validă.",
maxlength: $.validator.format("Te rugăm să nu introduci mai mult de {0} caractere."),
minlength: $.validator.format("Te rugăm să introduci cel puțin {0} caractere."),
rangelength: $.validator.format("Te rugăm să introduci o valoare între {0} și {1} caractere."),
range: $.validator.format("Te rugăm să introduci o valoare între {0} și {1}."),
max: $.validator.format("Te rugăm să introduci o valoare egal sau mai mică decât {0}."),
min: $.validator.format("Te rugăm să introduci o valoare egal sau mai mare decât {0}.")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: RU (Russian; русский язык)
*/
$.extend($.validator.messages, {
required: "Это поле необходимо заполнить.",
remote: "Пожалуйста, введите правильное значение.",
email: "Пожалуйста, введите корректный адрес электронной почты.",
url: "Пожалуйста, введите корректный URL.",
date: "Пожалуйста, введите корректную дату.",
dateISO: "Пожалуйста, введите корректную дату в формате ISO.",
number: "Пожалуйста, введите число.",
digits: "Пожалуйста, вводите только цифры.",
creditcard: "Пожалуйста, введите правильный номер кредитной карты.",
equalTo: "Пожалуйста, введите такое же значение ещё раз.",
extension: "Пожалуйста, выберите файл с правильным расширением.",
maxlength: $.validator.format("Пожалуйста, введите не больше {0} символов."),
minlength: $.validator.format("Пожалуйста, введите не меньше {0} символов."),
rangelength: $.validator.format("Пожалуйста, введите значение длиной от {0} до {1} символов."),
range: $.validator.format("Пожалуйста, введите число от {0} до {1}."),
max: $.validator.format("Пожалуйста, введите число, меньшее или равное {0}."),
min: $.validator.format("Пожалуйста, введите число, большее или равное {0}.")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: SI (Slovenian)
*/
$.extend($.validator.messages, {
required: "To polje je obvezno.",
remote: "Vpis v tem polju ni v pravi obliki.",
email: "Prosimo, vnesite pravi email naslov.",
url: "Prosimo, vnesite pravi URL.",
date: "Prosimo, vnesite pravi datum.",
dateISO: "Prosimo, vnesite pravi datum (ISO).",
number: "Prosimo, vnesite pravo številko.",
digits: "Prosimo, vnesite samo številke.",
creditcard: "Prosimo, vnesite pravo številko kreditne kartice.",
equalTo: "Prosimo, ponovno vnesite enako vsebino.",
extension: "Prosimo, vnesite vsebino z pravo končnico.",
maxlength: $.validator.format("Prosimo, da ne vnašate več kot {0} znakov."),
minlength: $.validator.format("Prosimo, vnesite vsaj {0} znakov."),
rangelength: $.validator.format("Prosimo, vnesite od {0} do {1} znakov."),
range: $.validator.format("Prosimo, vnesite vrednost med {0} in {1}."),
max: $.validator.format("Prosimo, vnesite vrednost manjšo ali enako {0}."),
min: $.validator.format("Prosimo, vnesite vrednost večjo ali enako {0}.")
});
}));

View File

@ -1,30 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: SK (Slovak; slovenčina, slovenský jazyk)
*/
$.extend($.validator.messages, {
required: "Povinné zadať.",
maxlength: $.validator.format("Maximálne {0} znakov."),
minlength: $.validator.format("Minimálne {0} znakov."),
rangelength: $.validator.format("Minimálne {0} a Maximálne {1} znakov."),
email: "E-mailová adresa musí byť platná.",
url: "URL musí byť platný.",
date: "Musí byť dátum.",
number: "Musí byť číslo.",
digits: "Môže obsahovať iba číslice.",
equalTo: "Dva hodnoty sa musia rovnať.",
range: $.validator.format("Musí byť medzi {0} a {1}."),
max: $.validator.format("Nemôže byť viac ako{0}."),
min: $.validator.format("Nemôže byť menej ako{0}."),
creditcard: "Číslo platobnej karty musí byť platné."
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Language: SL (Slovenian; slovenski jezik)
*/
$.extend($.validator.messages, {
required: "To polje je obvezno.",
remote: "Prosimo popravite to polje.",
email: "Prosimo vnesite veljaven email naslov.",
url: "Prosimo vnesite veljaven URL naslov.",
date: "Prosimo vnesite veljaven datum.",
dateISO: "Prosimo vnesite veljaven ISO datum.",
number: "Prosimo vnesite veljavno število.",
digits: "Prosimo vnesite samo števila.",
creditcard: "Prosimo vnesite veljavno številko kreditne kartice.",
equalTo: "Prosimo ponovno vnesite vrednost.",
extension: "Prosimo vnesite vrednost z veljavno končnico.",
maxlength: $.validator.format("Prosimo vnesite največ {0} znakov."),
minlength: $.validator.format("Prosimo vnesite najmanj {0} znakov."),
rangelength: $.validator.format("Prosimo vnesite najmanj {0} in največ {1} znakov."),
range: $.validator.format("Prosimo vnesite vrednost med {0} in {1}."),
max: $.validator.format("Prosimo vnesite vrednost manjše ali enako {0}."),
min: $.validator.format("Prosimo vnesite vrednost večje ali enako {0}.")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: SR (Serbian; српски језик)
*/
$.extend($.validator.messages, {
required: "Поље је обавезно.",
remote: "Средите ово поље.",
email: "Унесите исправну и-мејл адресу.",
url: "Унесите исправан URL.",
date: "Унесите исправан датум.",
dateISO: "Унесите исправан датум (ISO).",
number: "Унесите исправан број.",
digits: "Унесите само цифе.",
creditcard: "Унесите исправан број кредитне картице.",
equalTo: "Унесите исту вредност поново.",
extension: "Унесите вредност са одговарајућом екстензијом.",
maxlength: $.validator.format("Унесите мање од {0} карактера."),
minlength: $.validator.format("Унесите барем {0} карактера."),
rangelength: $.validator.format("Унесите вредност дугачку између {0} и {1} карактера."),
range: $.validator.format("Унесите вредност између {0} и {1}."),
max: $.validator.format("Унесите вредност мању или једнаку {0}."),
min: $.validator.format("Унесите вредност већу или једнаку {0}.")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: SR (Serbian - Latin alphabet; srpski jezik - latinica)
*/
$.extend($.validator.messages, {
required: "Polje je obavezno.",
remote: "Sredite ovo polje.",
email: "Unesite ispravnu i-mejl adresu",
url: "Unesite ispravan URL.",
date: "Unesite ispravan datum.",
dateISO: "Unesite ispravan datum (ISO).",
number: "Unesite ispravan broj.",
digits: "Unesite samo cife.",
creditcard: "Unesite ispravan broj kreditne kartice.",
equalTo: "Unesite istu vrednost ponovo.",
extension: "Unesite vrednost sa odgovarajućom ekstenzijom.",
maxlength: $.validator.format("Unesite manje od {0} karaktera."),
minlength: $.validator.format("Unesite barem {0} karaktera."),
rangelength: $.validator.format("Unesite vrednost dugačku između {0} i {1} karaktera."),
range: $.validator.format("Unesite vrednost između {0} i {1}."),
max: $.validator.format("Unesite vrednost manju ili jednaku {0}."),
min: $.validator.format("Unesite vrednost veću ili jednaku {0}.")
});
}));

View File

@ -1,31 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: SV (Swedish; Svenska)
*/
$.extend($.validator.messages, {
required: "Detta f&auml;lt &auml;r obligatoriskt.",
maxlength: $.validator.format("Du f&aring;r ange h&ouml;gst {0} tecken."),
minlength: $.validator.format("Du m&aring;ste ange minst {0} tecken."),
rangelength: $.validator.format("Ange minst {0} och max {1} tecken."),
email: "Ange en korrekt e-postadress.",
url: "Ange en korrekt URL.",
date: "Ange ett korrekt datum.",
dateISO: "Ange ett korrekt datum (&Aring;&Aring;&Aring;&Aring;-MM-DD).",
number: "Ange ett korrekt nummer.",
digits: "Ange endast siffror.",
equalTo: "Ange samma v&auml;rde igen.",
range: $.validator.format("Ange ett v&auml;rde mellan {0} och {1}."),
max: $.validator.format("Ange ett v&auml;rde som &auml;r mindre eller lika med {0}."),
min: $.validator.format("Ange ett v&auml;rde som &auml;r st&ouml;rre eller lika med {0}."),
creditcard: "Ange ett korrekt kreditkortsnummer."
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: TH (Thai; ไทย)
*/
$.extend($.validator.messages, {
required: "โปรดระบุ",
remote: "โปรดแก้ไขให้ถูกต้อง",
email: "โปรดระบุที่อยู่อีเมล์ที่ถูกต้อง",
url: "โปรดระบุ URL ที่ถูกต้อง",
date: "โปรดระบุวันที่ ที่ถูกต้อง",
dateISO: "โปรดระบุวันที่ ที่ถูกต้อง (ระบบ ISO).",
number: "โปรดระบุทศนิยมที่ถูกต้อง",
digits: "โปรดระบุจำนวนเต็มที่ถูกต้อง",
creditcard: "โปรดระบุรหัสบัตรเครดิตที่ถูกต้อง",
equalTo: "โปรดระบุค่าเดิมอีกครั้ง",
extension: "โปรดระบุค่าที่มีส่วนขยายที่ถูกต้อง",
maxlength: $.validator.format("โปรดอย่าระบุค่าที่ยาวกว่า {0} อักขระ"),
minlength: $.validator.format("โปรดอย่าระบุค่าที่สั้นกว่า {0} อักขระ"),
rangelength: $.validator.format("โปรดอย่าระบุค่าความยาวระหว่าง {0} ถึง {1} อักขระ"),
range: $.validator.format("โปรดระบุค่าระหว่าง {0} และ {1}"),
max: $.validator.format("โปรดระบุค่าน้อยกว่าหรือเท่ากับ {0}"),
min: $.validator.format("โปรดระบุค่ามากกว่าหรือเท่ากับ {0}")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: TJ (Tajikistan; Забони тоҷикӣ)
*/
$.extend($.validator.messages, {
required: "Ворид кардани ин филд маҷбури аст.",
remote: "Илтимос, маълумоти саҳеҳ ворид кунед.",
email: "Илтимос, почтаи электронии саҳеҳ ворид кунед.",
url: "Илтимос, URL адреси саҳеҳ ворид кунед.",
date: "Илтимос, таърихи саҳеҳ ворид кунед.",
dateISO: "Илтимос, таърихи саҳеҳи (ISO)ӣ ворид кунед.",
number: "Илтимос, рақамҳои саҳеҳ ворид кунед.",
digits: "Илтимос, танҳо рақам ворид кунед.",
creditcard: "Илтимос, кредит карди саҳеҳ ворид кунед.",
equalTo: "Илтимос, миқдори баробар ворид кунед.",
extension: "Илтимос, қофияи файлро дуруст интихоб кунед",
maxlength: $.validator.format("Илтимос, бештар аз {0} рамз ворид накунед."),
minlength: $.validator.format("Илтимос, камтар аз {0} рамз ворид накунед."),
rangelength: $.validator.format("Илтимос, камтар аз {0} ва зиёда аз {1} рамз ворид кунед."),
range: $.validator.format("Илтимос, аз {0} то {1} рақам зиёд ворид кунед."),
max: $.validator.format("Илтимос, бештар аз {0} рақам ворид накунед."),
min: $.validator.format("Илтимос, камтар аз {0} рақам ворид накунед.")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: TR (Turkish; Türkçe)
*/
$.extend($.validator.messages, {
required: "Bu alanın doldurulması zorunludur.",
remote: "Lütfen bu alanı düzeltin.",
email: "Lütfen geçerli bir e-posta adresi giriniz.",
url: "Lütfen geçerli bir web adresi (URL) giriniz.",
date: "Lütfen geçerli bir tarih giriniz.",
dateISO: "Lütfen geçerli bir tarih giriniz(ISO formatında)",
number: "Lütfen geçerli bir sayı giriniz.",
digits: "Lütfen sadece sayısal karakterler giriniz.",
creditcard: "Lütfen geçerli bir kredi kartı giriniz.",
equalTo: "Lütfen aynı değeri tekrar giriniz.",
extension: "Lütfen geçerli uzantıya sahip bir değer giriniz.",
maxlength: $.validator.format("Lütfen en fazla {0} karakter uzunluğunda bir değer giriniz."),
minlength: $.validator.format("Lütfen en az {0} karakter uzunluğunda bir değer giriniz."),
rangelength: $.validator.format("Lütfen en az {0} ve en fazla {1} uzunluğunda bir değer giriniz."),
range: $.validator.format("Lütfen {0} ile {1} arasında bir değer giriniz."),
max: $.validator.format("Lütfen {0} değerine eşit ya da daha küçük bir değer giriniz."),
min: $.validator.format("Lütfen {0} değerine eşit ya da daha büyük bir değer giriniz.")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: UK (Ukrainian; українська мова)
*/
$.extend($.validator.messages, {
required: "Це поле необхідно заповнити.",
remote: "Будь ласка, введіть правильне значення.",
email: "Будь ласка, введіть коректну адресу електронної пошти.",
url: "Будь ласка, введіть коректний URL.",
date: "Будь ласка, введіть коректну дату.",
dateISO: "Будь ласка, введіть коректну дату у форматі ISO.",
number: "Будь ласка, введіть число.",
digits: "Вводите потрібно лише цифри.",
creditcard: "Будь ласка, введіть правильний номер кредитної карти.",
equalTo: "Будь ласка, введіть таке ж значення ще раз.",
extension: "Будь ласка, виберіть файл з правильним розширенням.",
maxlength: $.validator.format("Будь ласка, введіть не більше {0} символів."),
minlength: $.validator.format("Будь ласка, введіть не менше {0} символів."),
rangelength: $.validator.format("Будь ласка, введіть значення довжиною від {0} до {1} символів."),
range: $.validator.format("Будь ласка, введіть число від {0} до {1}."),
max: $.validator.format("Будь ласка, введіть число, менше або рівно {0}."),
min: $.validator.format("Будь ласка, введіть число, більше або рівно {0}.")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: VI (Vietnamese; Tiếng Việt)
*/
$.extend($.validator.messages, {
required: "Hãy nhập.",
remote: "Hãy sửa cho đúng.",
email: "Hãy nhập email.",
url: "Hãy nhập URL.",
date: "Hãy nhập ngày.",
dateISO: "Hãy nhập ngày (ISO).",
number: "Hãy nhập số.",
digits: "Hãy nhập chữ số.",
creditcard: "Hãy nhập số thẻ tín dụng.",
equalTo: "Hãy nhập thêm lần nữa.",
extension: "Phần mở rộng không đúng.",
maxlength: $.validator.format("Hãy nhập từ {0} kí tự trở xuống."),
minlength: $.validator.format("Hãy nhập từ {0} kí tự trở lên."),
rangelength: $.validator.format("Hãy nhập từ {0} đến {1} kí tự."),
range: $.validator.format("Hãy nhập từ {0} đến {1}."),
max: $.validator.format("Hãy nhập từ {0} trở xuống."),
min: $.validator.format("Hãy nhập từ {1} trở lên.")
});
}));

View File

@ -1,33 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: ZH (Chinese, 中文 (Zhōngwén), 汉语, 漢語)
*/
$.extend($.validator.messages, {
required: "必须填写",
remote: "请修正此栏位",
email: "请输入有效的电子邮件",
url: "请输入有效的网址",
date: "请输入有效的日期",
dateISO: "请输入有效的日期 (YYYY-MM-DD)",
number: "请输入正确的数字",
digits: "只可输入数字",
creditcard: "请输入有效的信用卡号码",
equalTo: "你的输入不相同",
extension: "请输入有效的后缀",
maxlength: $.validator.format("最多 {0} 个字"),
minlength: $.validator.format("最少 {0} 个字"),
rangelength: $.validator.format("请输入长度为 {0} 至 {1} 之間的字串"),
range: $.validator.format("请输入 {0} 至 {1} 之间的数值"),
max: $.validator.format("请输入不大于 {0} 的数值"),
min: $.validator.format("请输入不小于 {0} 的数值")
});
}));

View File

@ -1,34 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Translated default messages for the jQuery validation plugin.
* Locale: ZH (Chinese; 中文 (Zhōngwén), 汉语, 漢語)
* Region: TW (Taiwan)
*/
$.extend($.validator.messages, {
required: "必須填寫",
remote: "請修正此欄位",
email: "請輸入有效的電子郵件",
url: "請輸入有效的網址",
date: "請輸入有效的日期",
dateISO: "請輸入有效的日期 (YYYY-MM-DD)",
number: "請輸入正確的數值",
digits: "只可輸入數字",
creditcard: "請輸入有效的信用卡號碼",
equalTo: "請重複輸入一次",
extension: "請輸入有效的後綴",
maxlength: $.validator.format("最多 {0} 個字"),
minlength: $.validator.format("最少 {0} 個字"),
rangelength: $.validator.format("請輸入長度為 {0} 至 {1} 之間的字串"),
range: $.validator.format("請輸入 {0} 至 {1} 之間的數值"),
max: $.validator.format("請輸入不大於 {0} 的數值"),
min: $.validator.format("請輸入不小於 {0} 的數值")
});
}));

View File

@ -1,22 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Localized default methods for the jQuery validation plugin.
* Locale: DE
*/
$.extend($.validator.methods, {
date: function(value, element) {
return this.optional(element) || /^\d\d?\.\d\d?\.\d\d\d?\d?$/.test(value);
},
number: function(value, element) {
return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(value);
}
});
}));

View File

@ -1,22 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Localized default methods for the jQuery validation plugin.
* Locale: ES_CL
*/
$.extend($.validator.methods, {
date: function(value, element) {
return this.optional(element) || /^\d\d?\-\d\d?\-\d\d\d?\d?$/.test(value);
},
number: function(value, element) {
return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(value);
}
});
}));

View File

@ -1,22 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Localized default methods for the jQuery validation plugin.
* Locale: FI
*/
$.extend($.validator.methods, {
date: function(value, element) {
return this.optional(element) || /^\d{1,2}\.\d{1,2}\.\d{4}$/.test(value);
},
number: function(value, element) {
return this.optional(element) || /^-?(?:\d+)(?:,\d+)?$/.test(value);
}
});
}));

View File

@ -1,19 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Localized default methods for the jQuery validation plugin.
* Locale: NL
*/
$.extend($.validator.methods, {
date: function(value, element) {
return this.optional(element) || /^\d\d?[\.\/\-]\d\d?[\.\/\-]\d\d\d?\d?$/.test(value);
}
});
}));

View File

@ -1,19 +0,0 @@
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
define( ["jquery", "../jquery.validate"], factory );
} else {
factory( jQuery );
}
}(function( $ ) {
/*
* Localized default methods for the jQuery validation plugin.
* Locale: PT_BR
*/
$.extend($.validator.methods, {
date: function(value, element) {
return this.optional(element) || /^\d\d?\/\d\d?\/\d\d\d?\d?$/.test(value);
}
});
}));

93
webpack.config.js Normal file
View File

@ -0,0 +1,93 @@
const Path = require('path');
const dir = require('node-dir');
const webpackConfig = require('@silverstripe/webpack-config');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const {
resolveJS,
externalJS,
moduleJS,
pluginJS,
moduleCSS,
pluginCSS,
} = webpackConfig;
const ENV = process.env.NODE_ENV;
const PATHS = {
MODULES: 'node_modules',
MODULES_ABS: Path.resolve('node_modules'),
FILES_PATH: '../',
ROOT: Path.resolve(),
SRC: Path.resolve('client/src'),
DIST: Path.resolve('client/dist'),
DIST_JS: Path.resolve('client/dist/js'),
LEGACY_SRC: Path.resolve('client/src/legacy'),
};
const copyData = [
{
from: PATHS.MODULES + '/jquery/dist/jquery.min.js',
to: PATHS.DIST_JS
},
];
/**
* Builds a list of files matching the `*.min.js` pattern to copy from a source
* directory to a dist directory.
*/
const addMinFiles = (from, to) => {
const sourceDir = PATHS.MODULES_ABS + from;
dir.files(sourceDir, (err, files) => {
if (err) throw err;
files.forEach(file => {
filename = file.replace(sourceDir, '');
if (!filename.match(/\.min\.js$/)) {
return;
}
copyData.push({
from: PATHS.MODULES + from + filename,
to: PATHS.DIST_JS + to + filename
})
});
});
};
addMinFiles('/jquery-validation/dist', '/jquery-validation');
const config = [
{
name: 'js',
entry: {
CommentsInterface: `${PATHS.LEGACY_SRC}/CommentsInterface.js`,
},
output: {
path: PATHS.DIST,
filename: 'js/[name].js',
},
devtool: (ENV !== 'production') ? 'source-map' : '',
resolve: resolveJS(ENV, PATHS),
externals: externalJS(ENV, PATHS),
module: moduleJS(ENV, PATHS),
plugins: pluginJS(ENV, PATHS).concat([
new CopyWebpackPlugin(copyData)
])
},
{
name: 'css',
entry: {
comments: `${PATHS.SRC}/styles/comments.scss`,
cms: `${PATHS.SRC}/styles/cms.scss`,
},
output: {
path: PATHS.DIST,
filename: 'styles/[name].css',
},
devtool: (ENV !== 'production') ? 'source-map' : '',
module: moduleCSS(ENV, PATHS),
plugins: pluginCSS(ENV, PATHS),
},
];
// Use WEBPACK_CHILD=js or WEBPACK_CHILD=css env var to run a single config
module.exports = (process.env.WEBPACK_CHILD)
? config.find((entry) => entry.name === process.env.WEBPACK_CHILD)
: module.exports = config;

10054
yarn.lock Normal file

File diff suppressed because it is too large Load Diff