Merge remote-tracking branch 'origin/3.1.16' into 3.1

This commit is contained in:
Damian Mooyman 2015-11-16 16:30:24 +13:00
commit b943a0c6dd
29 changed files with 356 additions and 63 deletions

View File

@ -9,7 +9,7 @@ if(typeof(ss) == 'undefined' || typeof(ss.i18n) == 'undefined') {
"CMSMAIN.BATCH_PUBLISH_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich veröffentlichen?", "CMSMAIN.BATCH_PUBLISH_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich veröffentlichen?",
"CMSMAIN.BATCH_DELETE_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich löschen?", "CMSMAIN.BATCH_DELETE_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich löschen?",
"CMSMAIN.BATCH_ARCHIVE_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich archivieren?\n\nDiese Seiten und alle Unterseiten davon werden von der veröffentlichen Seite gelöscht und in das Archiv verschoben.", "CMSMAIN.BATCH_ARCHIVE_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich archivieren?\n\nDiese Seiten und alle Unterseiten davon werden von der veröffentlichen Seite gelöscht und in das Archiv verschoben.",
"CMSMAIN.BATCH_RESTORE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to restore to stage?\n\nChildren of archived pages will be restored to the root level, unless those pages are also being restored.", "CMSMAIN.BATCH_RESTORE_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\\n\\nWollen Sie diese wirklich wiederherstellen?\\n\\nUnterseiten von archivierten Seiten werden auf der Root-Ebene wiederhergestellt, es sei denn, diese Seiten werden ebenfalls wiederhergestellt.",
"CMSMAIN.BATCH_DELETELIVE_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich von der veröfffentlichten Seite löschen?", "CMSMAIN.BATCH_DELETELIVE_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich von der veröfffentlichten Seite löschen?",
"LeftAndMain.CONFIRMUNSAVED": "Sind Sie sicher, dass Sie die Seite verlassen möchten?\n\nWARNUNG: Ihre Änderungen werden nicht gespeichert.\n\nDrücken Sie \"OK\" um fortzufahren, oder \"Abbrechen\" um auf dieser Seite zu bleiben.", "LeftAndMain.CONFIRMUNSAVED": "Sind Sie sicher, dass Sie die Seite verlassen möchten?\n\nWARNUNG: Ihre Änderungen werden nicht gespeichert.\n\nDrücken Sie \"OK\" um fortzufahren, oder \"Abbrechen\" um auf dieser Seite zu bleiben.",
"LeftAndMain.CONFIRMUNSAVEDSHORT": "WARNUNG: Ihre Änderungen wurden nicht gespeichert.", "LeftAndMain.CONFIRMUNSAVEDSHORT": "WARNUNG: Ihre Änderungen wurden nicht gespeichert.",

View File

@ -4,13 +4,13 @@ if(typeof(ss) == 'undefined' || typeof(ss.i18n) == 'undefined') {
if(typeof(console) != 'undefined') console.error('Class ss.i18n not defined'); if(typeof(console) != 'undefined') console.error('Class ss.i18n not defined');
} else { } else {
ss.i18n.addDictionary('eo', { ss.i18n.addDictionary('eo', {
"CMSMAIN.SELECTONEPAGE": "Please select at least one page", "CMSMAIN.SELECTONEPAGE": "Bonvole elektu almenaŭ 1 paĝon.",
"CMSMAIN.BATCH_UNPUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to unpublish", "CMSMAIN.BATCH_UNPUBLISH_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈi vi vere volas malpublikigi?",
"CMSMAIN.BATCH_PUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to publish?", "CMSMAIN.BATCH_PUBLISH_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈi vi vere volas publikigi?",
"CMSMAIN.BATCH_DELETE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete?", "CMSMAIN.BATCH_DELETE_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈi vi vere volas forigi?",
"CMSMAIN.BATCH_ARCHIVE_PROMPT": "You have {num} page(s) selected.\n\nAre you sure you want to archive these pages?\n\nThese pages and all of their children pages will be unpublished and sent to the archive.", "CMSMAIN.BATCH_ARCHIVE_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈu vi vere volas enarĥivigi tiujn paĝojn?\n\nTiuj paĝoj kaj ĉiuj idaj paĝoj estos malpublikigitaj kaj senditaj al la arĥivo.",
"CMSMAIN.BATCH_RESTORE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to restore to stage?\n\nChildren of archived pages will be restored to the root level, unless those pages are also being restored.", "CMSMAIN.BATCH_RESTORE_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈu vi vere volas restaŭri al stadio?\n\nIdoj de enarĥivigitaj paĝoj estos restaŭritaj al la radika nivelo, escepte se tiuj paĝoj ankaŭ estos restaŭritaj.",
"CMSMAIN.BATCH_DELETELIVE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete these pages from live?", "CMSMAIN.BATCH_DELETELIVE_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈi vi vere volas forigi tiujn paĝojn el la publika stadio?",
"LeftAndMain.CONFIRMUNSAVED": "Ĉu vi vere volas navigi for de ĉi tiu paĝo?\n\nAVERTO: Viaj ŝanĝoj ne estas konservitaj.\n\nPremu je Akcepti por daŭrigi, aŭ Nuligi por resti ĉe la aktuala paĝo.", "LeftAndMain.CONFIRMUNSAVED": "Ĉu vi vere volas navigi for de ĉi tiu paĝo?\n\nAVERTO: Viaj ŝanĝoj ne estas konservitaj.\n\nPremu je Akcepti por daŭrigi, aŭ Nuligi por resti ĉe la aktuala paĝo.",
"LeftAndMain.CONFIRMUNSAVEDSHORT": "AVERTO: Viaj ŝanĝoj ne estas konservitaj.", "LeftAndMain.CONFIRMUNSAVEDSHORT": "AVERTO: Viaj ŝanĝoj ne estas konservitaj.",
"SecurityAdmin.BATCHACTIONSDELETECONFIRM": "Ĉu vi vere volas forigi %s grupojn?", "SecurityAdmin.BATCHACTIONSDELETECONFIRM": "Ĉu vi vere volas forigi %s grupojn?",

View File

@ -4,8 +4,8 @@ if(typeof(ss) == 'undefined' || typeof(ss.i18n) == 'undefined') {
if(typeof(console) != 'undefined') console.error('Class ss.i18n not defined'); if(typeof(console) != 'undefined') console.error('Class ss.i18n not defined');
} else { } else {
ss.i18n.addDictionary('ro', { ss.i18n.addDictionary('ro', {
"CMSMAIN.SELECTONEPAGE": "Please select at least one page", "CMSMAIN.SELECTONEPAGE": "Vă rugăm să selectaţi cel puțin o pagină.",
"CMSMAIN.BATCH_UNPUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to unpublish", "CMSMAIN.BATCH_UNPUBLISH_PROMPT": "Aveti {num} pagina(i) selectate.\n\nDoriti sa le nenublicati",
"CMSMAIN.BATCH_PUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to publish?", "CMSMAIN.BATCH_PUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to publish?",
"CMSMAIN.BATCH_DELETE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete?", "CMSMAIN.BATCH_DELETE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete?",
"CMSMAIN.BATCH_ARCHIVE_PROMPT": "You have {num} page(s) selected.\n\nAre you sure you want to archive these pages?\n\nThese pages and all of their children pages will be unpublished and sent to the archive.", "CMSMAIN.BATCH_ARCHIVE_PROMPT": "You have {num} page(s) selected.\n\nAre you sure you want to archive these pages?\n\nThese pages and all of their children pages will be unpublished and sent to the archive.",

View File

@ -4,7 +4,7 @@
"CMSMAIN.BATCH_PUBLISH_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich veröffentlichen?", "CMSMAIN.BATCH_PUBLISH_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich veröffentlichen?",
"CMSMAIN.BATCH_DELETE_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich löschen?", "CMSMAIN.BATCH_DELETE_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich löschen?",
"CMSMAIN.BATCH_ARCHIVE_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich archivieren?\n\nDiese Seiten und alle Unterseiten davon werden von der veröffentlichen Seite gelöscht und in das Archiv verschoben.", "CMSMAIN.BATCH_ARCHIVE_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich archivieren?\n\nDiese Seiten und alle Unterseiten davon werden von der veröffentlichen Seite gelöscht und in das Archiv verschoben.",
"CMSMAIN.BATCH_RESTORE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to restore to stage?\n\nChildren of archived pages will be restored to the root level, unless those pages are also being restored.", "CMSMAIN.BATCH_RESTORE_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\\n\\nWollen Sie diese wirklich wiederherstellen?\\n\\nUnterseiten von archivierten Seiten werden auf der Root-Ebene wiederhergestellt, es sei denn, diese Seiten werden ebenfalls wiederhergestellt.",
"CMSMAIN.BATCH_DELETELIVE_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich von der veröfffentlichten Seite löschen?", "CMSMAIN.BATCH_DELETELIVE_PROMPT": "Sie haben {num} Seite(n) ausgewählt.\n\nWollen Sie diese wirklich von der veröfffentlichten Seite löschen?",
"LeftAndMain.CONFIRMUNSAVED": "Sind Sie sicher, dass Sie die Seite verlassen möchten?\n\nWARNUNG: Ihre Änderungen werden nicht gespeichert.\n\nDrücken Sie \"OK\" um fortzufahren, oder \"Abbrechen\" um auf dieser Seite zu bleiben.", "LeftAndMain.CONFIRMUNSAVED": "Sind Sie sicher, dass Sie die Seite verlassen möchten?\n\nWARNUNG: Ihre Änderungen werden nicht gespeichert.\n\nDrücken Sie \"OK\" um fortzufahren, oder \"Abbrechen\" um auf dieser Seite zu bleiben.",
"LeftAndMain.CONFIRMUNSAVEDSHORT": "WARNUNG: Ihre Änderungen wurden nicht gespeichert.", "LeftAndMain.CONFIRMUNSAVEDSHORT": "WARNUNG: Ihre Änderungen wurden nicht gespeichert.",

View File

@ -1,11 +1,11 @@
{ {
"CMSMAIN.SELECTONEPAGE": "Please select at least one page", "CMSMAIN.SELECTONEPAGE": "Bonvole elektu almenaŭ 1 paĝon.",
"CMSMAIN.BATCH_UNPUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to unpublish", "CMSMAIN.BATCH_UNPUBLISH_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈi vi vere volas malpublikigi?",
"CMSMAIN.BATCH_PUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to publish?", "CMSMAIN.BATCH_PUBLISH_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈi vi vere volas publikigi?",
"CMSMAIN.BATCH_DELETE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete?", "CMSMAIN.BATCH_DELETE_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈi vi vere volas forigi?",
"CMSMAIN.BATCH_ARCHIVE_PROMPT": "You have {num} page(s) selected.\n\nAre you sure you want to archive these pages?\n\nThese pages and all of their children pages will be unpublished and sent to the archive.", "CMSMAIN.BATCH_ARCHIVE_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈu vi vere volas enarĥivigi tiujn paĝojn?\n\nTiuj paĝoj kaj ĉiuj idaj paĝoj estos malpublikigitaj kaj senditaj al la arĥivo.",
"CMSMAIN.BATCH_RESTORE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to restore to stage?\n\nChildren of archived pages will be restored to the root level, unless those pages are also being restored.", "CMSMAIN.BATCH_RESTORE_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈu vi vere volas restaŭri al stadio?\n\nIdoj de enarĥivigitaj paĝoj estos restaŭritaj al la radika nivelo, escepte se tiuj paĝoj ankaŭ estos restaŭritaj.",
"CMSMAIN.BATCH_DELETELIVE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete these pages from live?", "CMSMAIN.BATCH_DELETELIVE_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈi vi vere volas forigi tiujn paĝojn el la publika stadio?",
"LeftAndMain.CONFIRMUNSAVED": "Ĉu vi vere volas navigi for de ĉi tiu paĝo?\n\nAVERTO: Viaj ŝanĝoj ne estas konservitaj.\n\nPremu je Akcepti por daŭrigi, aŭ Nuligi por resti ĉe la aktuala paĝo.", "LeftAndMain.CONFIRMUNSAVED": "Ĉu vi vere volas navigi for de ĉi tiu paĝo?\n\nAVERTO: Viaj ŝanĝoj ne estas konservitaj.\n\nPremu je Akcepti por daŭrigi, aŭ Nuligi por resti ĉe la aktuala paĝo.",
"LeftAndMain.CONFIRMUNSAVEDSHORT": "AVERTO: Viaj ŝanĝoj ne estas konservitaj.", "LeftAndMain.CONFIRMUNSAVEDSHORT": "AVERTO: Viaj ŝanĝoj ne estas konservitaj.",
"SecurityAdmin.BATCHACTIONSDELETECONFIRM": "Ĉu vi vere volas forigi %s grupojn?", "SecurityAdmin.BATCHACTIONSDELETECONFIRM": "Ĉu vi vere volas forigi %s grupojn?",

View File

@ -1,6 +1,6 @@
{ {
"CMSMAIN.SELECTONEPAGE": "Please select at least one page", "CMSMAIN.SELECTONEPAGE": "Vă rugăm să selectaţi cel puțin o pagină.",
"CMSMAIN.BATCH_UNPUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to unpublish", "CMSMAIN.BATCH_UNPUBLISH_PROMPT": "Aveti {num} pagina(i) selectate.\n\nDoriti sa le nenublicati",
"CMSMAIN.BATCH_PUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to publish?", "CMSMAIN.BATCH_PUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to publish?",
"CMSMAIN.BATCH_DELETE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete?", "CMSMAIN.BATCH_DELETE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete?",
"CMSMAIN.BATCH_ARCHIVE_PROMPT": "You have {num} page(s) selected.\n\nAre you sure you want to archive these pages?\n\nThese pages and all of their children pages will be unpublished and sent to the archive.", "CMSMAIN.BATCH_ARCHIVE_PROMPT": "You have {num} page(s) selected.\n\nAre you sure you want to archive these pages?\n\nThese pages and all of their children pages will be unpublished and sent to the archive.",

View File

@ -1,8 +1,8 @@
{ {
"CMSMAIN.SELECTONEPAGE": "Please select at least one page", "CMSMAIN.SELECTONEPAGE": "请至少选择一个页面",
"CMSMAIN.BATCH_UNPUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to unpublish", "CMSMAIN.BATCH_UNPUBLISH_PROMPT": "您已选了{num}个页面。\n\n是否确定要取消发布",
"CMSMAIN.BATCH_PUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to publish?", "CMSMAIN.BATCH_PUBLISH_PROMPT": "您已选了{num}个页面。\n\n是否确定要发布",
"CMSMAIN.BATCH_DELETE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete?", "CMSMAIN.BATCH_DELETE_PROMPT": "您已选了{num}个页面。\n\n是否确定要删除",
"CMSMAIN.BATCH_ARCHIVE_PROMPT": "You have {num} page(s) selected.\n\nAre you sure you want to archive these pages?\n\nThese pages and all of their children pages will be unpublished and sent to the archive.", "CMSMAIN.BATCH_ARCHIVE_PROMPT": "You have {num} page(s) selected.\n\nAre you sure you want to archive these pages?\n\nThese pages and all of their children pages will be unpublished and sent to the archive.",
"CMSMAIN.BATCH_RESTORE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to restore to stage?\n\nChildren of archived pages will be restored to the root level, unless those pages are also being restored.", "CMSMAIN.BATCH_RESTORE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to restore to stage?\n\nChildren of archived pages will be restored to the root level, unless those pages are also being restored.",
"CMSMAIN.BATCH_DELETELIVE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete these pages from live?", "CMSMAIN.BATCH_DELETELIVE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete these pages from live?",

View File

@ -4,10 +4,10 @@ if(typeof(ss) == 'undefined' || typeof(ss.i18n) == 'undefined') {
if(typeof(console) != 'undefined') console.error('Class ss.i18n not defined'); if(typeof(console) != 'undefined') console.error('Class ss.i18n not defined');
} else { } else {
ss.i18n.addDictionary('zh', { ss.i18n.addDictionary('zh', {
"CMSMAIN.SELECTONEPAGE": "Please select at least one page", "CMSMAIN.SELECTONEPAGE": "请至少选择一个页面",
"CMSMAIN.BATCH_UNPUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to unpublish", "CMSMAIN.BATCH_UNPUBLISH_PROMPT": "您已选了{num}个页面。\n\n是否确定要取消发布",
"CMSMAIN.BATCH_PUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to publish?", "CMSMAIN.BATCH_PUBLISH_PROMPT": "您已选了{num}个页面。\n\n是否确定要发布",
"CMSMAIN.BATCH_DELETE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete?", "CMSMAIN.BATCH_DELETE_PROMPT": "您已选了{num}个页面。\n\n是否确定要删除",
"CMSMAIN.BATCH_ARCHIVE_PROMPT": "You have {num} page(s) selected.\n\nAre you sure you want to archive these pages?\n\nThese pages and all of their children pages will be unpublished and sent to the archive.", "CMSMAIN.BATCH_ARCHIVE_PROMPT": "You have {num} page(s) selected.\n\nAre you sure you want to archive these pages?\n\nThese pages and all of their children pages will be unpublished and sent to the archive.",
"CMSMAIN.BATCH_RESTORE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to restore to stage?\n\nChildren of archived pages will be restored to the root level, unless those pages are also being restored.", "CMSMAIN.BATCH_RESTORE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to restore to stage?\n\nChildren of archived pages will be restored to the root level, unless those pages are also being restored.",
"CMSMAIN.BATCH_DELETELIVE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete these pages from live?", "CMSMAIN.BATCH_DELETELIVE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete these pages from live?",

View File

@ -16,6 +16,7 @@ class RSSFeed extends ViewableData {
private static $casting = array( private static $casting = array(
"Title" => "Varchar", "Title" => "Varchar",
"Description" => "Varchar", "Description" => "Varchar",
"Link" => "Varchar",
); );
/** /**

View File

@ -188,14 +188,14 @@ class RequestHandler extends ViewableData {
user_error("Non-string method name: " . var_export($action, true), E_USER_ERROR); user_error("Non-string method name: " . var_export($action, true), E_USER_ERROR);
} }
$className = get_class($this); $classMessage = Director::isLive() ? 'on this handler' : 'on class '.get_class($this);
try { try {
if(!$this->hasAction($action)) { if(!$this->hasAction($action)) {
return $this->httpError(404, "Action '$action' isn't available on class $className."); return $this->httpError(404, "Action '$action' isn't available $classMessage.");
} }
if(!$this->checkAccessAction($action) || in_array(strtolower($action), array('run', 'init'))) { if(!$this->checkAccessAction($action) || in_array(strtolower($action), array('run', 'init'))) {
return $this->httpError(403, "Action '$action' isn't allowed on class $className."); return $this->httpError(403, "Action '$action' isn't allowed $classMessage.");
} }
$result = $this->handleAction($request, $action); $result = $this->handleAction($request, $action);
} }
@ -232,7 +232,7 @@ class RequestHandler extends ViewableData {
// But if we have more content on the URL and we don't know what to do with it, return an error. // But if we have more content on the URL and we don't know what to do with it, return an error.
} else { } else {
return $this->httpError(404, "I can't handle sub-URLs of a $this->class object."); return $this->httpError(404, "I can't handle sub-URLs $classMessage.");
} }
return $this; return $this;
@ -276,10 +276,10 @@ class RequestHandler extends ViewableData {
* @return SS_HTTPResponse * @return SS_HTTPResponse
*/ */
protected function handleAction($request, $action) { protected function handleAction($request, $action) {
$className = get_class($this); $classMessage = Director::isLive() ? 'on this handler' : 'on class '.get_class($this);
if(!$this->hasMethod($action)) { if(!$this->hasMethod($action)) {
return new SS_HTTPResponse("Action '$action' isn't available on class $className.", 404); return new SS_HTTPResponse("Action '$action' isn't available $classMessage.", 404);
} }
$res = $this->extend('beforeCallActionHandler', $request, $action); $res = $this->extend('beforeCallActionHandler', $request, $action);

View File

@ -0,0 +1,40 @@
# 3.1.16
## Upgrading
FormField validation messages generated by the `Validator` class will now be automatically XML
encoded before being rendered alongside an invalid field.
If a validation message in a custom `Validator` instance should be rendered as literal HTML,
then the $message parameter for `Validator::validationError` should be passed as an instance
of `HTMLText`
For example:
:::php
class MyCustomValidator extends Validator {
public function php($data) {
$this->validationError(
'EmailAddress',
DBField::create_field('HTMLText', "Invalid email. Please sign up at <a href='signup'>this page</a>")
);
}
}
<!--- Changes below this line will be automatically regenerated -->
## Change Log
### Security
* 2015-11-11 [245e0aa](https://github.com/silverstripe/silverstripe-framework/commit/245e0aae2f5f3eb0acba1d198ad8e196bb224462) Fix FormField error messages not being encoded safely (Damian Mooyman) - See [ss-2015-026](http://www.silverstripe.org/download/security-releases/ss-2015-026)
* 2015-11-09 [53b3bc7](https://github.com/silverstripe/silverstripe-framework/commit/53b3bc707bcccb8f5e5060f85ab1398a0975bba2) Dont expose class on error (Hamish Friedlander) - See [ss-2015-025](http://www.silverstripe.org/download/security-releases/ss-2015-025)
* 2015-11-01 [ac4342d](https://github.com/silverstripe/silverstripe-framework/commit/ac4342d81d19201bd8d3814f168240db1ac565fe) XML escape RSSFeed $link parameter (Ingo Schommer) - See [ss-2015-022](http://www.silverstripe.org/download/security-releases/ss-2015-022)
* 2015-10-28 [97f21fd](https://github.com/silverstripe/silverstripe-framework/commit/97f21fddb3c565052f19ee3b35366f48e1e9a36f) Fix rewrite hash links XSS (Damian Mooyman) - See [ss-2015-021](http://www.silverstripe.org/download/security-releases/ss-2015-021)
### Bugfixes
* 2015-10-20 [b857bdf](https://github.com/silverstripe/silverstripe-framework/commit/b857bdf209d79fc623724e68f6a660354cbd5f93) Fix duplicate files being included in case of flush (Damian Mooyman)
* 2015-10-08 [ff6c0a3](https://github.com/silverstripe/silverstripe-cms/commit/ff6c0a3160c5eb3ca624efea6585efb44399dc1c) (v3.1) for #1294 to workaround ErrorPage fatal errors (and undefined var) when publishing. (Patrick Nelson)

View File

@ -0,0 +1,19 @@
# 3.1.16-rc1
See [3.1.16](/changelogs/3.1.16) changelog for more information on what is new in 3.1.16
<!--- Changes below this line will be automatically regenerated -->
## Change Log
### Security
* 2015-11-11 [245e0aa](https://github.com/silverstripe/silverstripe-framework/commit/245e0aae2f5f3eb0acba1d198ad8e196bb224462) Fix FormField error messages not being encoded safely (Damian Mooyman) - See [ss-2015-026](http://www.silverstripe.org/download/security-releases/ss-2015-026)
* 2015-11-09 [53b3bc7](https://github.com/silverstripe/silverstripe-framework/commit/53b3bc707bcccb8f5e5060f85ab1398a0975bba2) Dont expose class on error (Hamish Friedlander) - See [ss-2015-025](http://www.silverstripe.org/download/security-releases/ss-2015-025)
* 2015-11-01 [ac4342d](https://github.com/silverstripe/silverstripe-framework/commit/ac4342d81d19201bd8d3814f168240db1ac565fe) XML escape RSSFeed $link parameter (Ingo Schommer) - See [ss-2015-022](http://www.silverstripe.org/download/security-releases/ss-2015-022)
* 2015-10-28 [97f21fd](https://github.com/silverstripe/silverstripe-framework/commit/97f21fddb3c565052f19ee3b35366f48e1e9a36f) Fix rewrite hash links XSS (Damian Mooyman) - See [ss-2015-021](http://www.silverstripe.org/download/security-releases/ss-2015-021)
### Bugfixes
* 2015-10-20 [b857bdf](https://github.com/silverstripe/silverstripe-framework/commit/b857bdf209d79fc623724e68f6a660354cbd5f93) Fix duplicate files being included in case of flush (Damian Mooyman)
* 2015-10-08 [ff6c0a3](https://github.com/silverstripe/silverstripe-cms/commit/ff6c0a3160c5eb3ca624efea6585efb44399dc1c) (v3.1) for #1294 to workaround ErrorPage fatal errors (and undefined var) when publishing. (Patrick Nelson)

View File

@ -1211,6 +1211,18 @@ class Form extends RequestHandler {
if($errors){ if($errors){
// Load errors into session and post back // Load errors into session and post back
$data = $this->getData(); $data = $this->getData();
// Encode validation messages as XML before saving into session state
// As per Form::addErrorMessage()
$errors = array_map(function($error) {
// Encode message as XML by default
if($error['message'] instanceof DBField) {
$error['message'] = $error['message']->forTemplate();;
} else {
$error['message'] = Convert::raw2xml($error['message']);
}
return $error;
}, $errors);
Session::set("FormInfo.{$this->FormName()}.errors", $errors); Session::set("FormInfo.{$this->FormName()}.errors", $errors);
Session::set("FormInfo.{$this->FormName()}.data", $data); Session::set("FormInfo.{$this->FormName()}.data", $data);
return false; return false;

View File

@ -292,8 +292,6 @@ cs:
FROMWEB: 'Z webu' FROMWEB: 'Z webu'
FindInFolder: 'Hledat ve složce' FindInFolder: 'Hledat ve složce'
IMAGEALT: 'Alternativní text (alt)' IMAGEALT: 'Alternativní text (alt)'
IMAGEALTTEXT: 'Alternativní text (alt) - ukáže se, když obrázek nemúže být zobrazen'
IMAGEALTTEXTDESC: 'Zobrazeno na obrazovce, anebo když obrázek nemůže být zobrazen'
IMAGEDIMENSIONS: Rozměry IMAGEDIMENSIONS: Rozměry
IMAGEHEIGHTPX: Výška IMAGEHEIGHTPX: Výška
IMAGETITLE: 'Titul text (tooltip) - další informace o obrázku' IMAGETITLE: 'Titul text (tooltip) - další informace o obrázku'
@ -328,11 +326,9 @@ cs:
DELETED: Smazáno. DELETED: Smazáno.
DropdownBatchActionsDefault: Akcie DropdownBatchActionsDefault: Akcie
HELP: Nápověda HELP: Nápověda
PAGETYPE: 'Typ stránky:'
PERMAGAIN: 'Byli jste odhlášeni z CMS. Pokud se chcete znovu přihlásit, zadejte níže své uživatelské jméno a heslo.' PERMAGAIN: 'Byli jste odhlášeni z CMS. Pokud se chcete znovu přihlásit, zadejte níže své uživatelské jméno a heslo.'
PERMALREADY: 'Omlouvám se, ale nemůžete vstoupit do této části CMS. Pokud se chcete přihlásit jako někdo jiný, udělejte tak níže.' PERMALREADY: 'Omlouvám se, ale nemůžete vstoupit do této části CMS. Pokud se chcete přihlásit jako někdo jiný, udělejte tak níže.'
PERMDEFAULT: 'Musíte být přihlášen/a k přístup do oblasti administrace, zadejte vaše přihlošovací údaje dole, prosím.' PERMDEFAULT: 'Musíte být přihlášen/a k přístup do oblasti administrace, zadejte vaše přihlošovací údaje dole, prosím.'
PLEASESAVE: 'Uložte stránku, prosím. Tato stránka nemůže být aktualizována, protože ještě nebyla uložena.'
PreviewButton: Náhled PreviewButton: Náhled
REORGANISATIONSUCCESSFUL: 'Strom webu reorganizován úspěšně.' REORGANISATIONSUCCESSFUL: 'Strom webu reorganizován úspěšně.'
SAVEDUP: Uloženo. SAVEDUP: Uloženo.

View File

@ -260,6 +260,7 @@ de:
many_many_Members: Mitglieder many_many_Members: Mitglieder
GroupImportForm: GroupImportForm:
Help1: '<p>Eine oder mehrere Gruppen im <em>CSV</em>-Format (kommaseparierte Werte) importieren. <small><a href="#" class="toggle-advanced">Erweiterte Nutzung</a></small></p>' Help1: '<p>Eine oder mehrere Gruppen im <em>CSV</em>-Format (kommaseparierte Werte) importieren. <small><a href="#" class="toggle-advanced">Erweiterte Nutzung</a></small></p>'
Help2: '<div class="advanced"><h4>Erweiterte Benutzung</h4><ul><li>Gültige Spalten: <em>%s</em></li><li>Bereits existierende Gruppen werden anhand ihres eindeutigen <em>Code</em> identifiziert und um neue Einträge aus der Importdatei erweitert.</li><li>Gruppenhierarchien können mittels der Spalte <em>ParentCode</em> erstellt werden.</li><li>Berechtigungen können in der Spalte <em>PermissionCode</em> hinzugefügt werden. Schon zugewiesene Berechtigungen werden nicht entfernt.</li></ul></div>'
ResultCreated: '{count} Gruppe(n) wurden erstellt' ResultCreated: '{count} Gruppe(n) wurden erstellt'
ResultDeleted: '%d Gruppe(n) gelöscht' ResultDeleted: '%d Gruppe(n) gelöscht'
ResultUpdated: '%d Gruppe(n) aktualisiert' ResultUpdated: '%d Gruppe(n) aktualisiert'
@ -291,6 +292,7 @@ de:
FROMWEB: 'Aus dem Web' FROMWEB: 'Aus dem Web'
FindInFolder: 'In Ordner suchen' FindInFolder: 'In Ordner suchen'
IMAGEALT: 'Alternativtext (alt)' IMAGEALT: 'Alternativtext (alt)'
IMAGEALTTEXT: 'Alternativtext (alt) - erscheint, falls das Bild nicht angezeigt werden kann.'
IMAGEDIMENSIONS: Dimensionen IMAGEDIMENSIONS: Dimensionen
IMAGEHEIGHTPX: Höhe (px) IMAGEHEIGHTPX: Höhe (px)
IMAGETITLE: 'Titeltext (Tooltip) - für zusätzliche Informationen über das Bild' IMAGETITLE: 'Titeltext (Tooltip) - für zusätzliche Informationen über das Bild'
@ -325,7 +327,11 @@ de:
DELETED: Gelöscht. DELETED: Gelöscht.
DropdownBatchActionsDefault: Aktionen DropdownBatchActionsDefault: Aktionen
HELP: Hilfe HELP: Hilfe
PAGETYPE: 'Seitentyp:'
PERMAGAIN: 'Sie wurden aus dem System ausgeloggt. Falls Sie sich wieder einloggen möchten, geben Sie bitte Benutzernamen und Passwort im untenstehenden Formular an.' PERMAGAIN: 'Sie wurden aus dem System ausgeloggt. Falls Sie sich wieder einloggen möchten, geben Sie bitte Benutzernamen und Passwort im untenstehenden Formular an.'
PERMALREADY: 'Leider dürfen Sie diesen Teil des CMS nicht aufrufen. Wenn Sie sich als jemand anderes einloggen wollen, benutzen Sie bitte das nachstehende Formular.'
PERMDEFAULT: 'Sie müssen angemeldet sein, um auf diesen Bereich zugreifen zu können. Bitte geben Sie Ihre Zugangsdaten ein.'
PLEASESAVE: 'Diese Seite konnte nicht aktualisiert werden weil sie noch nicht gespeichert wurde - bitte speichern.'
PreviewButton: Vorschau PreviewButton: Vorschau
REORGANISATIONSUCCESSFUL: 'Der Seitenbaum wurde erfolgreich sortiert.' REORGANISATIONSUCCESSFUL: 'Der Seitenbaum wurde erfolgreich sortiert.'
SAVEDUP: Gespeichert. SAVEDUP: Gespeichert.
@ -413,6 +419,7 @@ de:
Toggle: 'Hilfe zur Formatierung anzeigen' Toggle: 'Hilfe zur Formatierung anzeigen'
MemberImportForm: MemberImportForm:
Help1: '<p>Mitglieder im <em>CSV</em>-Format (kommaseparierte Werte) importieren. <small><a href="#" class="toggle-advanced">Erweiterte Nutzung</a></small></p>' Help1: '<p>Mitglieder im <em>CSV</em>-Format (kommaseparierte Werte) importieren. <small><a href="#" class="toggle-advanced">Erweiterte Nutzung</a></small></p>'
Help2: '<div class="advanced"><h4>Erweiterte Benutzung</h4><ul><li>Gültige Spalten: <em>%s</em></li><li>Bereits existierende Benutzer werden anhand ihres eindeutigen <em>Code</em> identifiziert und um neue Einträge aus der Importdatei erweitert.</li><li>Gruppen können in der Spalte <em>Gruppen</em> hinzugefügt werden. Gruppen werden anhand ihres <em>Code</em> erkannt. Mehrere Gruppen werden Komma-separiert eingetragen. Schon zugewiesene Gruppen werden nicht entfernt.</li></ul></div>'
ResultCreated: '{count} Mitglied(er) wurde(n) erstellt' ResultCreated: '{count} Mitglied(er) wurde(n) erstellt'
ResultDeleted: '%d Mitglied(er) gelöscht' ResultDeleted: '%d Mitglied(er) gelöscht'
ResultNone: 'Keine Änderungen' ResultNone: 'Keine Änderungen'

View File

@ -260,6 +260,7 @@ eo:
many_many_Members: Membroj many_many_Members: Membroj
GroupImportForm: GroupImportForm:
Help1: '<p>Importi unu aŭ pliaj grupojn en formato <em>CSV</em> (perkome disigitaj valoroj values). <small><a href="#" class="toggle-advanced">Vidigi spertulan uzadon</a></small></p>' Help1: '<p>Importi unu aŭ pliaj grupojn en formato <em>CSV</em> (perkome disigitaj valoroj values). <small><a href="#" class="toggle-advanced">Vidigi spertulan uzadon</a></small></p>'
Help2: '<div class="advanced"><h4>Speciala uzado </h4><ul><li>Eblaj kolumnoj: <em>%s</em></li><li>Ekzistantaj grupoj kongruiĝas laŭ la valoro de ilia unika <em>Kodo</em>, kaj ĝisdatiĝas per eventualaj valoroj el la importita dosiero</li><li>Eblas krei grupajn hierarĥiojn per la kolumno <em>ParentCode</em>.</li><li>Eblas agordi permeskodojn per la kolumno <em>PermissionCode</em>. Ekzistantaj permeskodoj ne vakiĝas.</li></ul></div>'
ResultCreated: 'Kreiĝis {count} grupoj' ResultCreated: 'Kreiĝis {count} grupoj'
ResultDeleted: 'Forigis %d grupojn' ResultDeleted: 'Forigis %d grupojn'
ResultUpdated: 'Aktualigis %d grupojn' ResultUpdated: 'Aktualigis %d grupojn'
@ -326,15 +327,20 @@ eo:
DropdownBatchActionsDefault: Agoj DropdownBatchActionsDefault: Agoj
HELP: Helpo HELP: Helpo
PERMAGAIN: 'Vin adiaŭis la CMS. Se vi volas denove saluti, enigu salutnomon kaj pasvorton malsupre.' PERMAGAIN: 'Vin adiaŭis la CMS. Se vi volas denove saluti, enigu salutnomon kaj pasvorton malsupre.'
PERMALREADY: 'Bedaŭrinde vi ne povas aliri tiun parton de la CMS. Se vi volas ensaluti kiel aliulo, faru tion sube.'
PERMDEFAULT: 'Necesas ensaluti por aliri la administran zonon; bonvolu enigi viajn akreditaĵoj sube.'
PreviewButton: Antaŭvido PreviewButton: Antaŭvido
REORGANISATIONSUCCESSFUL: 'Sukcese reorganizis la retejan arbon.' REORGANISATIONSUCCESSFUL: 'Sukcese reorganizis la retejan arbon.'
SAVEDUP: Konservita. SAVEDUP: Konservita.
ShowAsList: 'vidigi kiel liston' ShowAsList: 'vidigi kiel liston'
TooManyPages: 'Tro da paĝoj' TooManyPages: 'Tro da paĝoj'
ValidationError: 'Validiga eraro' ValidationError: 'Validiga eraro'
VersionUnknown: nekonata
LeftAndMain_Menu_ss: LeftAndMain_Menu_ss:
Hello: Saluton Hello: Saluton
LOGOUT: 'Elsaluti' LOGOUT: 'Elsaluti'
ListboxField:
SOURCE_VALIDATION: 'Bonvolu elekti valoron el la listo donita. %s ne estas valida agordo'
LoginAttempt: LoginAttempt:
Email: 'Retadreso' Email: 'Retadreso'
IP: 'IP-Adreso' IP: 'IP-Adreso'
@ -410,6 +416,7 @@ eo:
Toggle: 'Vidigi aranĝa helpo' Toggle: 'Vidigi aranĝa helpo'
MemberImportForm: MemberImportForm:
Help1: '<p>Importi membrojn en <em>CSV-formato</em> (diskomaj valoroj ). <small><a href="#" class="toggle-advanced">Vidigi spertulan uzadon</a></small></p>' Help1: '<p>Importi membrojn en <em>CSV-formato</em> (diskomaj valoroj ). <small><a href="#" class="toggle-advanced">Vidigi spertulan uzadon</a></small></p>'
Help2: '<div class="advanced"><h4>Speciala uzado </h4><ul><li>Eblaj kolumnoj: <em>%s</em></li><li>Ekzistantaj uzantoj kongruiĝas laŭ la valoro de sia unika atributo <em>Code</em>, kaj ĝisdatiĝas per eventualaj novaj valoroj el la importita dosiero. </li><li>Eblas agordi grupojn per la kolumno <em>Groups</em>. Grupoj estas identigeblaj per sia atributo <em>Code</em>, plurobla grupo estu apartigitaj per komo. Ekzistantaj grupaj membrecoj ne vakiĝas.</li></ul></div>'
ResultCreated: 'Krei {count} membrojn' ResultCreated: 'Krei {count} membrojn'
ResultDeleted: 'Forigis %d membrojn' ResultDeleted: 'Forigis %d membrojn'
ResultNone: 'Neniu ŝanĝo' ResultNone: 'Neniu ŝanĝo'
@ -539,6 +546,8 @@ eo:
Print: Presi Print: Presi
TableListField_PageControls_ss: TableListField_PageControls_ss:
OF: de OF: de
TextField:
VALIDATEMAXLENGTH: 'La longo de la valoro por {name} devas ne superi {maxLength} signojn'
TimeField: TimeField:
VALIDATEFORMAT: 'Bonvole enigu validan horan formaton ({format})' VALIDATEFORMAT: 'Bonvole enigu validan horan formaton ({format})'
ToggleField: ToggleField:

View File

@ -82,6 +82,7 @@ es:
CMSSecurity: CMSSecurity:
INVALIDUSER: '<p>Usuario inválido. <a target="_top" href="{link}">Por favor, vuelva a autenticar aquí</a> para continuar.</p>' INVALIDUSER: '<p>Usuario inválido. <a target="_top" href="{link}">Por favor, vuelva a autenticar aquí</a> para continuar.</p>'
LoginMessage: '<p>Si Ud tiene cualquier trabajo sin guardar puede volver donde lo dejó, iniciando sesión más abajo.</p>' LoginMessage: '<p>Si Ud tiene cualquier trabajo sin guardar puede volver donde lo dejó, iniciando sesión más abajo.</p>'
SUCCESS: Exito
SUCCESSCONTENT: '<p>Inicio de sesión exitoso. Si Ud no es automáticamente redireccionado, <a target="_top" href="{link}">haga clic aquí</a></p>' SUCCESSCONTENT: '<p>Inicio de sesión exitoso. Si Ud no es automáticamente redireccionado, <a target="_top" href="{link}">haga clic aquí</a></p>'
TimedOutTitleAnonymous: 'Expiró su sesión.' TimedOutTitleAnonymous: 'Expiró su sesión.'
TimedOutTitleMember: 'Eh {name}!<br />Tu sesión expiró.' TimedOutTitleMember: 'Eh {name}!<br />Tu sesión expiró.'
@ -259,6 +260,7 @@ es:
many_many_Members: Miembros many_many_Members: Miembros
GroupImportForm: GroupImportForm:
Help1: '<p>Importar uno o más grupos en formato <em>CSV</em> (valores separados por coma). <small><a href="#" class="toggle-advanced">Mostrar uso avanzado</a></small></p>' Help1: '<p>Importar uno o más grupos en formato <em>CSV</em> (valores separados por coma). <small><a href="#" class="toggle-advanced">Mostrar uso avanzado</a></small></p>'
Help2: '<div class="advanced"><h4>Uso avanzado</h4><ul><li>Columnas permitidas: <em>%s</em></li><li>Grupos existentes son relacionados con su <em>Código único</em> y actualizados con cualquier nuevo valor desde el archivo importado</li><li>Jerarquías de grupo pueden ser creadas utilizando la columna <em>ParentCode</em>.</li><li>Códigos de permiso pueden ser asignados por la columna <em>PermissionCode</em>. Códigos de permisos existentes no son eliminados.</li></ul></div>'
ResultCreated: 'Creados {count} grupos' ResultCreated: 'Creados {count} grupos'
ResultDeleted: 'Se eliminaron %d grupos' ResultDeleted: 'Se eliminaron %d grupos'
ResultUpdated: 'Actualizados grupos %d' ResultUpdated: 'Actualizados grupos %d'
@ -325,6 +327,8 @@ es:
DropdownBatchActionsDefault: Acciones DropdownBatchActionsDefault: Acciones
HELP: Ayuda HELP: Ayuda
PERMAGAIN: 'Ha sido desconectado del CMS. Si quiere volver a entrar, introduzca su nombre de usuario y contraseña a continuación.' PERMAGAIN: 'Ha sido desconectado del CMS. Si quiere volver a entrar, introduzca su nombre de usuario y contraseña a continuación.'
PERMALREADY: 'Lamentablemente no puede acceder a esta parte del CMS. Si quiere entrar como alguien distinto, hágalo a continuación'
PERMDEFAULT: 'Debes estar conectado para acceder al área de administración; por favor ingresa tus datos a continuación'
PreviewButton: Vista previa PreviewButton: Vista previa
REORGANISATIONSUCCESSFUL: 'Reorganizado el árbol del sitio con éxito.' REORGANISATIONSUCCESSFUL: 'Reorganizado el árbol del sitio con éxito.'
SAVEDUP: Guardado SAVEDUP: Guardado
@ -412,6 +416,7 @@ es:
Toggle: 'Cambiar' Toggle: 'Cambiar'
MemberImportForm: MemberImportForm:
Help1: '<p>Importar usuarios en <em>formato CSV</em> (valores separados por coma). <small><a href="#" class="toggle-advanced">Mostrar uso avanzado</a></small></p>' Help1: '<p>Importar usuarios en <em>formato CSV</em> (valores separados por coma). <small><a href="#" class="toggle-advanced">Mostrar uso avanzado</a></small></p>'
Help2: '<div class="advanced"><h4>Uso avanzado</h4><ul><li>Columnas permitidas: <em>%s</em></li><li>Usuarios existentes son relacionados con su <em>Código único</em>, y actualizados con cualquier nuevo valor desde el archivo importado.</li><li>Grupos pueden ser asignados por la columna <em>Groups</em>. Grupos son identificados por su propiedad <em>Code</em>, multiples grupos pueden ser separados por una coma. La pertenencia a grupos existentes no se borra.</li></ul></div>'
ResultCreated: 'Creados {count} miembros' ResultCreated: 'Creados {count} miembros'
ResultDeleted: 'Se eliminaron %d miembros' ResultDeleted: 'Se eliminaron %d miembros'
ResultNone: 'No hay cambios' ResultNone: 'No hay cambios'
@ -475,6 +480,7 @@ es:
SINGULARNAME: Regla SINGULARNAME: Regla
Title: Título Title: Título
PermissionRoleCode: PermissionRoleCode:
PLURALNAME: 'Códigos de permiso'
PermsError: 'No se puede asignar permisos privilegiados al código "% s" (requiere acceso de administrador)' PermsError: 'No se puede asignar permisos privilegiados al código "% s" (requiere acceso de administrador)'
SINGULARNAME: 'Códigos de las regla de permisos' SINGULARNAME: 'Códigos de las regla de permisos'
Permissions: Permissions:

View File

@ -4,12 +4,18 @@ fa_IR:
AssetTableField: AssetTableField:
DIM: ابعاد DIM: ابعاد
FILENAME: نام فايل FILENAME: نام فايل
FOLDER: پوشه
LASTEDIT: 'آخرین تغییرات' LASTEDIT: 'آخرین تغییرات'
OWNER: دارنده OWNER: دارنده
SIZE: 'حجم' SIZE: 'حجم'
TITLE: عنوان TITLE: عنوان
TYPE: 'نوع' TYPE: 'نوع'
URL: نشانی URL: نشانی
AssetUploadField:
EDITALL: 'ویرایش همه'
EDITINFO: 'ویرایش فایل‌ها'
FILES: فایل‌ها
TOTAL: مجموع
BBCodeParser: BBCodeParser:
ALIGNEMENT: جاگذاری ALIGNEMENT: جاگذاری
ALIGNEMENTEXAMPLE: 'به راست' ALIGNEMENTEXAMPLE: 'به راست'
@ -26,13 +32,29 @@ fa_IR:
UNDERLINEEXAMPLE: زیرخط UNDERLINEEXAMPLE: زیرخط
Boolean: Boolean:
ANY: هر ANY: هر
NOANSWER: 'خیر'
YESANSWER: 'بله'
CMSLoadingScreen_ss:
LOADING: بارگذاری...
CMSMain: CMSMain:
SAVE: نگاهداری SAVE: نگاهداری
CMSMemberLoginForm:
BUTTONFORGOTPASSWORD: 'رمز عبور را فراموش کرده‌اید؟'
BUTTONLOGOUT: 'خروج'
CMSPageHistoryController_versions_ss:
PREVIEW: 'پیش‌نمایش وب‌سایت'
CMSProfileController:
MENUTITLE: 'پروفایل من'
CMSSecurity:
SUCCESS: موفقیت
ChangePasswordEmail_ss: ChangePasswordEmail_ss:
CHANGEPASSWORDTEXT1: 'شما گذرواژه تان را دگرگون کردید برای' CHANGEPASSWORDTEXT1: 'شما گذرواژه تان را دگرگون کردید برای'
EMAIL: ايميل EMAIL: ايميل
HELLO: درود HELLO: درود
PASSWORD: كلمه عبور PASSWORD: كلمه عبور
CheckboxField:
NOANSWER: 'خیر'
YESANSWER: 'بله'
ConfirmedPasswordField: ConfirmedPasswordField:
SHOWONCLICKTITLE: 'تغيير كلمه عبور' SHOWONCLICKTITLE: 'تغيير كلمه عبور'
CreditCardField: CreditCardField:
@ -40,36 +62,76 @@ fa_IR:
FOURTH: چهارم FOURTH: چهارم
SECOND: دوم SECOND: دوم
THIRD: سوم THIRD: سوم
CurrencyField:
CURRENCYSYMBOL:
DataObject: DataObject:
PLURALNAME: 'داده های اشیاء' PLURALNAME: 'داده های اشیاء'
SINGULARNAME: 'داده اشیاء' SINGULARNAME: 'داده اشیاء'
Date:
DAY: روز
DAYS: روز
HOUR: ساعت
HOURS: ساعت
LessThanMinuteAgo: 'کمتر از یک دقیقه'
MIN: دقیقه
MINS: دقیقه
MONTH: ماه
MONTHS: ماه
SEC: ثانیه
SECS: ثانیه
TIMEDIFFAGO: '{difference} پیش'
TIMEDIFFIN: 'در {difference}'
YEAR: سال
YEARS: سال
DateField: DateField:
TODAY: امروز TODAY: امروز
DropdownField: DropdownField:
CHOOSE: (گزینش) CHOOSE: (گزینش)
Enum:
ANY: هر
File: File:
AviType: 'فایل ویدیو AVI'
Content: محتوا Content: محتوا
CssType: 'فایل CSS'
Filename: نام پرونده Filename: نام پرونده
HtlType: 'فایل HTML'
HtmlType: 'فایل HTML'
Name: نام Name: نام
PLURALNAME: فايل ها PLURALNAME: فايل ها
SINGULARNAME: فايل SINGULARNAME: فايل
Title: عنوان Title: عنوان
Folder:
PLURALNAME: پوشه‌ها
SINGULARNAME: پوشه
ForgotPasswordEmail_ss: ForgotPasswordEmail_ss:
HELLO: درود HELLO: درود
TEXT3: برای TEXT3: برای
Form: Form:
SubmitBtnLabel: برو
VALIDATIONPASSWORDSDONTMATCH: 'گذرواژه‌ها همانند هم نیستند' VALIDATIONPASSWORDSDONTMATCH: 'گذرواژه‌ها همانند هم نیستند'
VALIDATIONPASSWORDSNOTEMPTY: 'گذرواژه نباید تهی باشد' VALIDATIONPASSWORDSNOTEMPTY: 'گذرواژه نباید تهی باشد'
FormField: FormField:
NONE: هیچ کدام NONE: هیچ کدام
GridAction:
DELETE_DESCRIPTION: حذف
Delete: حذف
GridField:
Find: بگرد
ResetFilter: از نو
GridFieldEditButton_ss:
EDIT: ویرایش
GridFieldItemEditView:
Go_back: 'بازگشت'
Group: Group:
Code: 'كد گروه' Code: 'كد گروه'
DefaultGroupTitleAdministrators: مدیران کل DefaultGroupTitleAdministrators: مدیران کل
DefaultGroupTitleContentAuthors: 'نویسندگان مطالب' DefaultGroupTitleContentAuthors: 'نویسندگان مطالب'
Description: توضحیات Description: توضحیات
Locked: 'بسته شده است؟' Locked: 'بسته شده است؟'
PLURALNAME: گروه‌ها
Parent: 'گروه مادر' Parent: 'گروه مادر'
RolesAddEditLink: 'اضافه/ویرایش وظیفه' RolesAddEditLink: 'اضافه/ویرایش وظیفه'
SINGULARNAME: گروه
Sort: 'تربیت چیدن' Sort: 'تربیت چیدن'
has_many_Permissions: مجوز‌ها has_many_Permissions: مجوز‌ها
many_many_Members: اعضاء many_many_Members: اعضاء
@ -77,8 +139,11 @@ fa_IR:
ResultDeleted: 'گروه %d حذف شد' ResultDeleted: 'گروه %d حذف شد'
ResultUpdated: 'گروه %d بروز شد' ResultUpdated: 'گروه %d بروز شد'
HtmlEditorField: HtmlEditorField:
ADDURL: 'افزودن URL'
BUTTONINSERT: وارد کردن
BUTTONINSERTLINK: 'گذاشتن پیوند' BUTTONINSERTLINK: 'گذاشتن پیوند'
BUTTONREMOVELINK: 'برداشتن پیوند' BUTTONREMOVELINK: 'برداشتن پیوند'
BUTTONUpdate: به روزرسانی
CSSCLASS: 'جاگیری / الگو' CSSCLASS: 'جاگیری / الگو'
EMAIL: 'پست الکترونیک' EMAIL: 'پست الکترونیک'
FILE: پرونده FILE: پرونده
@ -94,11 +159,25 @@ fa_IR:
LINKTO: 'پیوند به' LINKTO: 'پیوند به'
PAGE: برگ PAGE: برگ
URL: نشانی URL: نشانی
Image:
PLURALNAME: فایل‌ها
SINGULARNAME: فايل
Image_Cached:
PLURALNAME: فایل‌ها
SINGULARNAME: فايل
LeftAndMain: LeftAndMain:
DELETED: حذف شده
HELP: کمک HELP: کمک
PERMAGAIN: 'شما از سیستم مدیریت محتوا خارج شده اید.اگر میخواهید دوباره وارد شوید نام کاربری و رمز عبور خود را در قسمت زیر وارد کنید' PERMAGAIN: 'شما از سیستم مدیریت محتوا خارج شده اید.اگر میخواهید دوباره وارد شوید نام کاربری و رمز عبور خود را در قسمت زیر وارد کنید'
PreviewButton: پیش‌نمایش
SAVEDUP: ذخیره شده
LeftAndMain_Menu_ss:
Hello: درود
LOGOUT: 'خروج'
LoginAttempt: LoginAttempt:
Email: 'آدرس های ایمیل' Email: 'نشانی ای‌میل'
IP: 'نشانی IP'
Status: وضعیت
Member: Member:
BUTTONCHANGEPASSWORD: 'تغییر رمز عبور' BUTTONCHANGEPASSWORD: 'تغییر رمز عبور'
BUTTONLOGIN: 'ورود' BUTTONLOGIN: 'ورود'
@ -116,20 +195,41 @@ fa_IR:
SUBJECTPASSWORDCHANGED: 'گذرواژه شما دگرگون شد' SUBJECTPASSWORDCHANGED: 'گذرواژه شما دگرگون شد'
SUBJECTPASSWORDRESET: 'پیوند ازنوسازی گذرواژه شما' SUBJECTPASSWORDRESET: 'پیوند ازنوسازی گذرواژه شما'
SURNAME: نام خانوادگی SURNAME: نام خانوادگی
TIMEFORMAT: 'قالب زمان'
YOUROLDPASSWORD: 'رمز عبور قدیمی' YOUROLDPASSWORD: 'رمز عبور قدیمی'
belongs_many_many_Groups: گروه‌ها belongs_many_many_Groups: گروه‌ها
db_LockedOutUntil: 'بسته شده تا ' db_LockedOutUntil: 'بسته شده تا '
db_Password: رمز عبور
db_PasswordExpiry: 'تاریخ از میان رفتن گذرواژه' db_PasswordExpiry: 'تاریخ از میان رفتن گذرواژه'
MemberDatetimeOptionsetField:
Preview: پیش‌نمایش
MemberImportForm: MemberImportForm:
ResultDeleted: 'کاربر %d حذف شد' ResultDeleted: 'کاربر %d حذف شد'
ResultNone: 'تغییری ایجاد نشد' ResultNone: 'تغییری ایجاد نشد'
ModelAdmin: ModelAdmin:
DELETE: حذف DELETE: حذف
ModelAdmin_Tools_ss:
FILTER: پالایش
IMPORT: وارد کردن
ModelSidebar_ss:
IMPORT_TAB_HEADER: وارد کردن
SEARCHLISTINGS: جستجو
MoneyField:
FIELDLABELAMOUNT: مقدار
FIELDLABELCURRENCY: واحد پول
NullableField: NullableField:
IsNullLabel: 'خالی است' IsNullLabel: 'خالی است'
Pagination:
Page: صفحه
View: نمایش
Permission: Permission:
AdminGroup: مدیر کل AdminGroup: مدیر کل
CMS_ACCESS_CATEGORY: 'دسترسی CMS'
FULLADMINRIGHTS: 'توانایی‌های کامل مدیریتی:' FULLADMINRIGHTS: 'توانایی‌های کامل مدیریتی:'
PermissionRole:
PLURALNAME: وظایف
SINGULARNAME: وظیفه
Title: عنوان
Permissions: Permissions:
PERMISSIONS_CATEGORY: 'مجوز دسترسی ها و وظایف' PERMISSIONS_CATEGORY: 'مجوز دسترسی ها و وظایف'
PhoneNumberField: PhoneNumberField:
@ -142,14 +242,29 @@ fa_IR:
SecurityAdmin: SecurityAdmin:
APPLY_ROLES: 'اعمال وظایف به گروه' APPLY_ROLES: 'اعمال وظایف به گروه'
MEMBERS: کاربران MEMBERS: کاربران
MENUTITLE: امنیت
NEWGROUP: 'گروه تازه' NEWGROUP: 'گروه تازه'
ROLES: وظایف ROLES: وظایف
TABROLES: وظایف TABROLES: وظایف
Users: کاربران
SecurityAdmin_MemberImportForm: SecurityAdmin_MemberImportForm:
BtnImport: 'وارد کردن' BtnImport: 'وارد کردن'
SilverStripeNavigator:
Edit: ویرایش
Mobile: موبایل
Tablet: تبلت
Width: پهنا
SiteTree: SiteTree:
TABMAIN: اصلی TABMAIN: اصلی
TableListField:
Print: چاپ
ToggleField: ToggleField:
MORE: بیشتر MORE: بیشتر
UploadField:
DOEDIT: ذخیره
Dimensions: ابعاد
EDIT: ویرایش
REMOVE: حذف
Saved: ذخیره شده
Versioned: Versioned:
has_many_Versions: نسخه ها has_many_Versions: نسخه ها

View File

@ -251,9 +251,9 @@ fr:
CAPTIONTEXT: 'Légende' CAPTIONTEXT: 'Légende'
CSSCLASS: 'Alignement / Style' CSSCLASS: 'Alignement / Style'
CSSCLASSCENTER: 'Centré' CSSCLASSCENTER: 'Centré'
CSSCLASSLEFT: 'A gauche, avec texte à la ligne.' CSSCLASSLEFT: 'À gauche, avec texte autour.'
CSSCLASSLEFTALONE: 'Sur la gauche seulement' CSSCLASSLEFTALONE: 'Sur la gauche seulement'
CSSCLASSRIGHT: 'a droite, avec texte à la ligne.' CSSCLASSRIGHT: 'À droite, avec texte autour.'
DETAILS: Détails DETAILS: Détails
EMAIL: 'Adresse email' EMAIL: 'Adresse email'
FILE: Fichier FILE: Fichier

View File

@ -326,6 +326,8 @@ it:
DropdownBatchActionsDefault: Azioni DropdownBatchActionsDefault: Azioni
HELP: Aiuto HELP: Aiuto
PERMAGAIN: 'Sei stato disconnesso dal CMS. Se desideri autenticarti nuovamente, inserisci qui sotto nome utente e password.' PERMAGAIN: 'Sei stato disconnesso dal CMS. Se desideri autenticarti nuovamente, inserisci qui sotto nome utente e password.'
PERMALREADY: 'Siamo spiacenti, ma non puoi accedere a questa sezione del CMS. Se desideri autenticarti come qualcun altro, fallo qui sotto.'
PERMDEFAULT: 'Devi essere autenticato per accedere all''area amministrativa; Per favore inserisci le tue credenziali qui sotto'
PreviewButton: Anteprima PreviewButton: Anteprima
REORGANISATIONSUCCESSFUL: 'Albero del sito riorganizzato con successo.' REORGANISATIONSUCCESSFUL: 'Albero del sito riorganizzato con successo.'
SAVEDUP: Salvato. SAVEDUP: Salvato.

View File

@ -292,8 +292,6 @@ sk:
FROMWEB: 'Z webu' FROMWEB: 'Z webu'
FindInFolder: 'Vyhľadať v priečinku' FindInFolder: 'Vyhľadať v priečinku'
IMAGEALT: 'Atlernatívny text (alt)' IMAGEALT: 'Atlernatívny text (alt)'
IMAGEALTTEXT: 'Atlernatívny text (alt) - zobrazí sa ak obrázok nemože byť zobrazený '
IMAGEALTTEXTDESC: 'Zobrazí sa na obrazovke, ak obrázok nemôže byť zobrazený'
IMAGEDIMENSIONS: Rozmery IMAGEDIMENSIONS: Rozmery
IMAGEHEIGHTPX: Výška IMAGEHEIGHTPX: Výška
IMAGETITLE: 'Text titulky (tooltip) - pre doplňujúce informácie o obrázku' IMAGETITLE: 'Text titulky (tooltip) - pre doplňujúce informácie o obrázku'
@ -328,11 +326,9 @@ sk:
DELETED: Zmazané. DELETED: Zmazané.
DropdownBatchActionsDefault: Akcie DropdownBatchActionsDefault: Akcie
HELP: Pomoc HELP: Pomoc
PAGETYPE: 'Typ stránky:'
PERMAGAIN: 'Boli ste odhlásený' PERMAGAIN: 'Boli ste odhlásený'
PERMALREADY: 'Je mi ľúto, ale nemáte prístup k tejto časti CMS. Ak sa chcete prihlásiť ako niekto iný, urobte tak nižšie' PERMALREADY: 'Je mi ľúto, ale nemáte prístup k tejto časti CMS. Ak sa chcete prihlásiť ako niekto iný, urobte tak nižšie'
PERMDEFAULT: 'Musíte byť prihlásený/á k prístupu do oblasti administrácie, zadajte vaše prihlasovacie údaje dole, prosím.' PERMDEFAULT: 'Musíte byť prihlásený/á k prístupu do oblasti administrácie, zadajte vaše prihlasovacie údaje dole, prosím.'
PLEASESAVE: 'Uložte stránku, prosím. Táto stránka nemôže byť aktualizovaná, pretože eště nebola uložená.'
PreviewButton: Náhľad PreviewButton: Náhľad
REORGANISATIONSUCCESSFUL: 'Strom webu bol reorganizovaný úspešne.' REORGANISATIONSUCCESSFUL: 'Strom webu bol reorganizovaný úspešne.'
SAVEDUP: Uložené. SAVEDUP: Uložené.

View File

@ -47,6 +47,8 @@ tr:
ERRORNOTREC: 'Kullanıcı adı / şifre hatalı' ERRORNOTREC: 'Kullanıcı adı / şifre hatalı'
Boolean: Boolean:
ANY: Herhangi ANY: Herhangi
NOANSWER: 'Hayır'
YESANSWER: 'Evet'
CMSMain: CMSMain:
ACCESSALLINTERFACES: 'Tüm İYS arayüzlerine erişim' ACCESSALLINTERFACES: 'Tüm İYS arayüzlerine erişim'
SAVE: Kaydet SAVE: Kaydet
@ -56,6 +58,9 @@ tr:
EMAIL: E-Posta EMAIL: E-Posta
HELLO: Merhaba HELLO: Merhaba
PASSWORD: Parola PASSWORD: Parola
CheckboxField:
NOANSWER: 'Hayır'
YESANSWER: 'Evet'
ConfirmedPasswordField: ConfirmedPasswordField:
SHOWONCLICKTITLE: 'Parola Değiştir' SHOWONCLICKTITLE: 'Parola Değiştir'
CreditCardField: CreditCardField:
@ -87,6 +92,7 @@ tr:
TEXT2: 'şifre sıfırlama linki' TEXT2: 'şifre sıfırlama linki'
TEXT3: için TEXT3: için
Form: Form:
SubmitBtnLabel: Başla
VALIDATIONNOTUNIQUE: 'Girilen değer benzersiz olmalıdır' VALIDATIONNOTUNIQUE: 'Girilen değer benzersiz olmalıdır'
VALIDATIONPASSWORDSDONTMATCH: 'Şifre tekrarı hatalı' VALIDATIONPASSWORDSDONTMATCH: 'Şifre tekrarı hatalı'
VALIDATIONPASSWORDSNOTEMPTY: 'Şifreler boş geçilemez' VALIDATIONPASSWORDSNOTEMPTY: 'Şifreler boş geçilemez'

View File

@ -60,6 +60,8 @@ zh:
ERRORNOTREC: '那个用户名 / 密码无法被辨认' ERRORNOTREC: '那个用户名 / 密码无法被辨认'
Boolean: Boolean:
ANY: 任何 ANY: 任何
NOANSWER: '不是'
YESANSWER: '是'
CMSLoadingScreen_ss: CMSLoadingScreen_ss:
LOADING: 正在载入…… LOADING: 正在载入……
REQUIREJS: 'CMS 要求您启用 JavaScript。' REQUIREJS: 'CMS 要求您启用 JavaScript。'
@ -68,16 +70,35 @@ zh:
ACCESSALLINTERFACES: '对所有 CMS 部分的访问' ACCESSALLINTERFACES: '对所有 CMS 部分的访问'
ACCESSALLINTERFACESHELP: '支配更多的特殊访问设置' ACCESSALLINTERFACESHELP: '支配更多的特殊访问设置'
SAVE: 保存 SAVE: 保存
CMSMemberLoginForm:
BUTTONFORGOTPASSWORD: '忘记密码?'
BUTTONLOGIN: '重新登录'
BUTTONLOGOUT: '登出'
PASSWORDEXPIRED: '<p>您的密码已过期。 <a target="_top" href="{link}">请选择一个新的。</a></ P>'
CMSPageHistoryController_versions_ss: CMSPageHistoryController_versions_ss:
PREVIEW: '网站预览' PREVIEW: '网站预览'
CMSProfileController: CMSProfileController:
MENUTITLE: '我的个人资料' MENUTITLE: '我的个人资料'
CMSSecurity:
INVALIDUSER: '<p>用户已无效。 <a target="_top" href="{link}">请在此继续重新进行身份验证</a>。</ p>'
LoginMessage: '<p>如果您有任何未保存的工作,你可以重新登录以回到你未保存的地方。</p>'
SUCCESS: 成功
SUCCESSCONTENT: '<p>登录成功。如果您没有自动重定向<a target="_top" href="{link}">点击此处</a></p>'
TimedOutTitleAnonymous: '你的登陆超时已过期。'
TimedOutTitleMember: '你好{name}!<br />你的登陆超时已过期。'
ChangePasswordEmail_ss: ChangePasswordEmail_ss:
CHANGEPASSWORDTEXT1: '您的密码已更改为:' CHANGEPASSWORDTEXT1: '您的密码已更改为:'
CHANGEPASSWORDTEXT2: '现在,您可以使用下列证书来登录了:' CHANGEPASSWORDTEXT2: '现在,您可以使用下列证书来登录了:'
EMAIL: 电子邮件 EMAIL: 电子邮件
HELLO: 您好 HELLO: 您好
PASSWORD: 密码 PASSWORD: 密码
CheckboxField:
NOANSWER: '不是'
YESANSWER: '是'
CheckboxFieldSetField:
SOURCE_VALIDATION: '请选择列表内提供的选项。{value}不是一个有效的选项'
CheckboxSetField:
SOURCE_VALIDATION: '请选择列表内提供的选项。''{value}''不是一个有效的选项'
ConfirmedPasswordField: ConfirmedPasswordField:
ATLEAST: '密码长度必须至少 {min} 个字符。' ATLEAST: '密码长度必须至少 {min} 个字符。'
BETWEEN: '密码长度必须含 {min} 到 {max} 个字符。' BETWEEN: '密码长度必须含 {min} 到 {max} 个字符。'
@ -124,6 +145,7 @@ zh:
DropdownField: DropdownField:
CHOOSE: (选择) CHOOSE: (选择)
CHOOSESEARCH: '(选择或搜索)' CHOOSESEARCH: '(选择或搜索)'
SOURCE_VALIDATION: '请选择列表内提供的选项。{value}不是一个有效的选项'
EmailField: EmailField:
VALIDATION: '请输入一个电子邮件地址' VALIDATION: '请输入一个电子邮件地址'
Enum: Enum:
@ -171,6 +193,7 @@ zh:
TEXT2: '密码重设链接' TEXT2: '密码重设链接'
TEXT3: TEXT3:
Form: Form:
CSRF_FAILED_MESSAGE: '似乎是一个技术问题。请点击返回按钮,刷新浏览器,然后再试一次。'
FIELDISREQUIRED: '{name} 为必填' FIELDISREQUIRED: '{name} 为必填'
SubmitBtnLabel: 前往 SubmitBtnLabel: 前往
VALIDATIONCREDITNUMBER: '请确保您输入了正确的 {number} 信用卡号码' VALIDATIONCREDITNUMBER: '请确保您输入了正确的 {number} 信用卡号码'
@ -244,6 +267,8 @@ zh:
HtmlEditorField: HtmlEditorField:
ADDURL: '添加网址' ADDURL: '添加网址'
ADJUSTDETAILSDIMENSIONS: '详情 &amp;amp; 体积' ADJUSTDETAILSDIMENSIONS: '详情 &amp;amp; 体积'
ANCHORSCANNOTACCESSPAGE: '您不允许访问该页面的内容。'
ANCHORSPAGENOTFOUND: '无法找到该页面。'
ANCHORVALUE: 固定 ANCHORVALUE: 固定
BUTTONADDURL: '添加网址' BUTTONADDURL: '添加网址'
BUTTONINSERT: 插入 BUTTONINSERT: 插入
@ -282,6 +307,7 @@ zh:
LINKOPENNEWWIN: '在新窗口中打开链接?' LINKOPENNEWWIN: '在新窗口中打开链接?'
LINKTO: '链接到' LINKTO: '链接到'
PAGE: 页面 PAGE: 页面
SUBJECT: '电子邮件标题'
URL: 网址 URL: 网址
URLNOTANOEMBEDRESOURCE: '''{url}'' 该网址无法转换成媒体来源。' URLNOTANOEMBEDRESOURCE: '''{url}'' 该网址无法转换成媒体来源。'
UpdateMEDIA: '更新媒体' UpdateMEDIA: '更新媒体'
@ -299,15 +325,19 @@ zh:
DropdownBatchActionsDefault: 动作 DropdownBatchActionsDefault: 动作
HELP: 帮助 HELP: 帮助
PERMAGAIN: '您已经退出 CMS。如果您想再次登录请在下面输入用户名和密码。' PERMAGAIN: '您已经退出 CMS。如果您想再次登录请在下面输入用户名和密码。'
PERMALREADY: '抱歉,您不能访问这一部分的后台管理。如果您想以不同的身份登录,请在下面进行操作。'
PreviewButton: 预览 PreviewButton: 预览
REORGANISATIONSUCCESSFUL: '重新组织网站地图已成功' REORGANISATIONSUCCESSFUL: '重新组织网站地图已成功'
SAVEDUP: 已保存。 SAVEDUP: 已保存。
ShowAsList: '以列表方式展示' ShowAsList: '以列表方式展示'
TooManyPages: '页面数目过多' TooManyPages: '页面数目过多'
ValidationError: '验证错误' ValidationError: '验证错误'
VersionUnknown: 未知
LeftAndMain_Menu_ss: LeftAndMain_Menu_ss:
Hello: 您好 Hello: 您好
LOGOUT: '退出' LOGOUT: '退出'
ListboxField:
SOURCE_VALIDATION: '请选择列表内提供的选项。%s不是一个有效的选项'
LoginAttempt: LoginAttempt:
Email: '电子邮件地址' Email: '电子邮件地址'
IP: 'IP 地址' IP: 'IP 地址'
@ -340,6 +370,7 @@ zh:
NEWPASSWORD: '新密码' NEWPASSWORD: '新密码'
NoPassword: '该成员无密码' NoPassword: '该成员无密码'
PASSWORD: 密码 PASSWORD: 密码
PASSWORDEXPIRED: '您的密码已过期。 请选择一个新的。'
PLURALNAME: 成员 PLURALNAME: 成员
REMEMBERME: '下次记住我?' REMEMBERME: '下次记住我?'
SINGULARNAME: 成员 SINGULARNAME: 成员
@ -445,6 +476,7 @@ zh:
SINGULARNAME: 角色 SINGULARNAME: 角色
Title: 标题 Title: 标题
PermissionRoleCode: PermissionRoleCode:
PLURALNAME: '权限角色代码'
PermsError: '无法为代码 "%s"分配特权权限(要求具备 ADMIN 访问)' PermsError: '无法为代码 "%s"分配特权权限(要求具备 ADMIN 访问)'
SINGULARNAME: '权限角色代码' SINGULARNAME: '权限角色代码'
Permissions: Permissions:
@ -510,6 +542,8 @@ zh:
Print: 打印 Print: 打印
TableListField_PageControls_ss: TableListField_PageControls_ss:
OF: OF:
TextField:
VALIDATEMAXLENGTH: '{name} 的长度必须至多{maxLength} 个字符。'
TimeField: TimeField:
VALIDATEFORMAT: '请输入有效的时间格式 ({format})' VALIDATEFORMAT: '请输入有效的时间格式 ({format})'
ToggleField: ToggleField:

View File

@ -43,6 +43,13 @@ class RSSFeedTest extends SapphireTest {
$this->assertContains('<description>ItemC AltContent</description>', $content); $this->assertContains('<description>ItemC AltContent</description>', $content);
} }
public function testLinkEncoding() {
$list = new ArrayList();
$rssFeed = new RSSFeed($list, "http://www.example.com/?param1=true&param2=true", "Test RSS Feed");
$content = $rssFeed->outputToBrowser();
$this->assertContains('<link>http://www.example.com/?param1=true&amp;param2=true', $content);
}
public function testRSSFeedWithShortcode() { public function testRSSFeedWithShortcode() {
$list = new ArrayList(); $list = new ArrayList();
$list->push(new RSSFeedTest_ItemD()); $list->push(new RSSFeedTest_ItemD());

View File

@ -226,6 +226,7 @@ class FormTest extends FunctionalTest {
'FormTest_Controller/Form', 'FormTest_Controller/Form',
array( array(
'Email' => 'invalid', 'Email' => 'invalid',
'Number' => '<a href="http://mysite.com">link</a>' // XSS attempt
// leaving out "Required" field // leaving out "Required" field
) )
); );
@ -244,6 +245,16 @@ class FormTest extends FunctionalTest {
'Required fields show a notification on field when left blank' 'Required fields show a notification on field when left blank'
); );
$this->assertContains(
'&#039;&lt;a href=&quot;http://mysite.com&quot;&gt;link&lt;/a&gt;&#039; is not a number, only numbers can be accepted for this field',
$response->getBody(),
"Validation messages are safely XML encoded"
);
$this->assertNotContains(
'<a href="http://mysite.com">link</a>',
$response->getBody(),
"Unsafe content is not emitted directly inside the response body"
);
} }
public function testSessionSuccessMessage() { public function testSessionSuccessMessage() {
@ -630,7 +641,8 @@ class FormTest_Controller extends Controller implements TestOnly {
new FieldList( new FieldList(
new EmailField('Email'), new EmailField('Email'),
new TextField('SomeRequiredField'), new TextField('SomeRequiredField'),
new CheckboxSetField('Boxes', null, array('1'=>'one','2'=>'two')) new CheckboxSetField('Boxes', null, array('1'=>'one','2'=>'two')),
new NumericField('Number')
), ),
new FieldList( new FieldList(
new FormAction('doSubmit') new FormAction('doSubmit')

View File

@ -1,9 +1,28 @@
<?php <?php
class SSViewerTest extends SapphireTest { class SSViewerTest extends SapphireTest {
/**
* Backup of $_SERVER global
*
* @var array
*/
protected $oldServer = array();
protected $extraDataObjects = array(
'SSViewerTest_Object',
);
public function setUp() { public function setUp() {
parent::setUp(); parent::setUp();
Config::inst()->update('SSViewer', 'source_file_comments', false); Config::inst()->update('SSViewer', 'source_file_comments', false);
Config::inst()->update('SSViewer_FromString', 'cache_template', false);
$this->oldServer = $_SERVER;
}
public function tearDown() {
$_SERVER = $this->oldServer;
parent::tearDown();
} }
/** /**
@ -1160,10 +1179,13 @@ after')
$orig = Config::inst()->get('SSViewer', 'rewrite_hash_links'); $orig = Config::inst()->get('SSViewer', 'rewrite_hash_links');
Config::inst()->update('SSViewer', 'rewrite_hash_links', true); Config::inst()->update('SSViewer', 'rewrite_hash_links', true);
$_SERVER['REQUEST_URI'] = 'http://path/to/file?foo"onclick="alert(\'xss\')""'; $_SERVER['HTTP_HOST'] = 'www.mysite.com';
$_SERVER['REQUEST_URI'] = '//file.com?foo"onclick="alert(\'xss\')""';
// Emulate SSViewer::process() // Emulate SSViewer::process()
$base = Convert::raw2att($_SERVER['REQUEST_URI']); // Note that leading double slashes have been rewritten to prevent these being mis-interepreted
// as protocol-less absolute urls
$base = Convert::raw2att('/file.com?foo"onclick="alert(\'xss\')""');
$tmplFile = TEMP_FOLDER . '/SSViewerTest_testRewriteHashlinks_' . sha1(rand()) . '.ss'; $tmplFile = TEMP_FOLDER . '/SSViewerTest_testRewriteHashlinks_' . sha1(rand()) . '.ss';
@ -1231,10 +1253,11 @@ after')
$obj = new ViewableData(); $obj = new ViewableData();
$obj->InsertedLink = '<a class="inserted" href="#anchor">InsertedLink</a>'; $obj->InsertedLink = '<a class="inserted" href="#anchor">InsertedLink</a>';
$result = $tmpl->process($obj); $result = $tmpl->process($obj);
$this->assertContains(
'<a class="inserted" href="<?php echo Convert::raw2att(', $code = <<<'EOC'
$result <a class="inserted" href="<?php echo Convert::raw2att(preg_replace("/^(\/)+/", "/", $_SERVER['REQUEST_URI'])); ?>#anchor">InsertedLink</a>
); EOC;
$this->assertContains($code, $result);
// TODO Fix inline links in PHP mode // TODO Fix inline links in PHP mode
// $this->assertContains( // $this->assertContains(
// '<a class="inline" href="<?php echo str_replace(', // '<a class="inline" href="<?php echo str_replace(',

View File

@ -4681,11 +4681,15 @@ class SSTemplateParser extends Parser implements TemplateParser {
// TODO: This is pretty ugly & gets applied on all files not just html. I wonder if we can make this // TODO: This is pretty ugly & gets applied on all files not just html. I wonder if we can make this
// non-dynamically calculated // non-dynamically calculated
$code = <<<'EOC'
(\Config::inst()->get('SSViewer', 'rewrite_hash_links')
? \Convert::raw2att( preg_replace("/^(\\/)+/", "/", $_SERVER['REQUEST_URI'] ) )
: "")
EOC;
// Because preg_replace replacement requires escaped slashes, addcslashes here
$text = preg_replace( $text = preg_replace(
'/(<a[^>]+href *= *)"#/i', '/(<a[^>]+href *= *)"#/i',
'\\1"\' . (Config::inst()->get(\'SSViewer\', \'rewrite_hash_links\') ?' . '\\1"\' . ' . addcslashes($code, '\\') . ' . \'#',
' Convert::raw2att( $_SERVER[\'REQUEST_URI\'] ) : "") .
\'#',
$text $text
); );

View File

@ -1135,11 +1135,15 @@ class SSTemplateParser extends Parser implements TemplateParser {
// TODO: This is pretty ugly & gets applied on all files not just html. I wonder if we can make this // TODO: This is pretty ugly & gets applied on all files not just html. I wonder if we can make this
// non-dynamically calculated // non-dynamically calculated
$code = <<<'EOC'
(\Config::inst()->get('SSViewer', 'rewrite_hash_links')
? \Convert::raw2att( preg_replace("/^(\\/)+/", "/", $_SERVER['REQUEST_URI'] ) )
: "")
EOC;
// Because preg_replace replacement requires escaped slashes, addcslashes here
$text = preg_replace( $text = preg_replace(
'/(<a[^>]+href *= *)"#/i', '/(<a[^>]+href *= *)"#/i',
'\\1"\' . (Config::inst()->get(\'SSViewer\', \'rewrite_hash_links\') ?' . '\\1"\' . ' . addcslashes($code, '\\') . ' . \'#',
' Convert::raw2att( $_SERVER[\'REQUEST_URI\'] ) : "") .
\'#',
$text $text
); );

View File

@ -1111,9 +1111,9 @@ class SSViewer implements Flushable {
if($this->rewriteHashlinks && $rewrite) { if($this->rewriteHashlinks && $rewrite) {
if(strpos($output, '<base') !== false) { if(strpos($output, '<base') !== false) {
if($rewrite === 'php') { if($rewrite === 'php') {
$thisURLRelativeToBase = "<?php echo Convert::raw2att(\$_SERVER['REQUEST_URI']); ?>"; $thisURLRelativeToBase = "<?php echo Convert::raw2att(preg_replace(\"/^(\\\\/)+/\", \"/\", \$_SERVER['REQUEST_URI'])); ?>";
} else { } else {
$thisURLRelativeToBase = Convert::raw2att($_SERVER['REQUEST_URI']); $thisURLRelativeToBase = Convert::raw2att(preg_replace("/^(\\/)+/", "/", $_SERVER['REQUEST_URI']));
} }
$output = preg_replace('/(<a[^>]+href *= *)"#/i', '\\1"' . $thisURLRelativeToBase . '#', $output); $output = preg_replace('/(<a[^>]+href *= *)"#/i', '\\1"' . $thisURLRelativeToBase . '#', $output);