Merge remote-tracking branch 'origin/3'

Conflicts:
	control/Director.php
	filesystem/File.php
	filesystem/GD.php
	filesystem/ImagickBackend.php
	forms/HtmlEditorField.php
	javascript/UploadField_uploadtemplate.js
	model/Image.php
	model/Image_Backend.php
	model/fieldtypes/Enum.php
	templates/AssetUploadField.ss
	tests/model/ImageTest.php
	tests/search/FulltextFilterTest.php
This commit is contained in:
Damian Mooyman 2015-11-03 14:23:16 +13:00
commit 1e1a7a345c
69 changed files with 852 additions and 137 deletions

View File

@ -29,6 +29,8 @@ matrix:
env: DB=MYSQL BEHAT_TEST=1
before_script:
# Until http://pecl.php.net/package/imagick is working again
# - printf "\n" | pecl install imagick
- composer self-update || true
- phpenv rehash
- git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support

View File

@ -15,6 +15,7 @@ After:
Director:
rules:
'Security//$Action/$ID/$OtherID': 'Security'
'CMSSecurity//$Action/$ID/$OtherID': 'CMSSecurity'
'dev': 'DevelopmentAdmin'
'interactive': 'SapphireREPL'
'InstallerTest//$Action/$ID/$OtherID': 'InstallerTest'

View File

@ -212,7 +212,7 @@ abstract class ModelAdmin extends LeftAndMain {
$params = $this->getRequest()->requestVar('q');
if(is_array($params)) {
$params = array_map('trim', $params);
$params = ArrayLib::array_map_recursive('trim', $params);
}
$list = $context->getResults($params);

View File

@ -28,7 +28,7 @@
// Remove all bound events.
// This guards against an edge case where the click handlers are not unbound
// because the panel is still open when the ajax edit form reloads.
var frame = $('.cms').find('iframe');
var frame = $('.cms-container').find('iframe');
frame.each(function(index, iframe){
$(iframe).contents().off('click.ss-ui-action-tabset');
});
@ -58,7 +58,7 @@
* Note: Should be called by a click event attached to 'this'
*/
attachCloseHandler: function(event, ui) {
var that = this, frame = $('.cms').find('iframe'), closeHandler;
var that = this, frame = $('.cms-container').find('iframe'), closeHandler;
// Create a handler for the click event so we can close tabs
// and easily remove the event once done
@ -74,7 +74,7 @@
that.tabs('option', 'active', false); // close tabs
// remove click event from objects it is bound to (iframe's and document)
frame = $('.cms').find('iframe');
frame = $('.cms-container').find('iframe');
frame.each(function(index, iframe){
$(iframe).contents().off('click.ss-ui-action-tabset', closeHandler);
});

View File

@ -278,21 +278,23 @@
sessionData = hasSessionStorage ? window.sessionStorage.getItem(this.attr('id')) : null,
sessionStates = sessionData ? JSON.parse(sessionData) : false,
elementID,
tabbed = this.find('.ss-tabset'),
tabbed = (this.find('.ss-tabset').length !== 0),
activeTab,
elementTab,
toggleComposite,
scrollY;
if(hasSessionStorage && sessionStates.length > 0){
$.each(sessionStates, function(i, sessionState) {
if(self.is('#' + sessionState.id)){
elementID = $('#' + sessionState.selected);
}
});
// If the element IDs saved in session states don't match up to anything in this particular form
// that probably means we haven't encountered this form yet, so focus on the first input
if($(elementID).length < 1){
this.focusFirstInput();
return;
}
@ -330,14 +332,18 @@
}
} else {
// If there is no focus data attribute set, focus input on first form element. Exclude elements which
// specifically opt-out of this behaviour via "data-skip-autofocus".
// This opt-out is useful if the first visible field is shown far down a scrollable area,
// for example for the pagination input field after a long GridField listing.
// Skip if an element in the form is already focused.
this.find(':input:not(:submit)[data-skip-autofocus!="true"]').filter(':visible:first').focus();
// If session storage is not supported or there is nothing stored yet, focus on the first input
this.focusFirstInput();
}
},
/**
* Skip if an element in the form is already focused. Exclude elements which specifically
* opt-out of this behaviour via "data-skip-autofocus". This opt-out is useful if the
* first visible field is shown far down a scrollable area, for example for the pagination
* input field after a long GridField listing.
*/
focusFirstInput: function() {
this.find(':input:not(:submit)[data-skip-autofocus!="true"]').filter(':visible:first').focus();
}
});

View File

@ -105,7 +105,10 @@
SiblingIDs: siblingIDs
},
success: function() {
$('.cms-edit-form :input[name=ParentID]').val(newParentID);
// We only need to update the ParentID if the current page we're on is the page being moved
if ($('.cms-edit-form :input[name=ID]').val() == nodeID) {
$('.cms-edit-form :input[name=ParentID]').val(newParentID);
}
self.updateNodesFromServer([nodeID]);
},
statusCode: {

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');
} else {
ss.i18n.addDictionary('eo', {
"CMSMAIN.SELECTONEPAGE": "Please select at least one page",
"CMSMAIN.BATCH_UNPUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to unpublish",
"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_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_DELETELIVE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete these pages from live?",
"CMSMAIN.SELECTONEPAGE": "Bonvole elektu almenaŭ 1 paĝon.",
"CMSMAIN.BATCH_UNPUBLISH_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈi vi vere volas malpublikigi?",
"CMSMAIN.BATCH_PUBLISH_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈi vi vere volas publikigi?",
"CMSMAIN.BATCH_DELETE_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈi vi vere volas forigi?",
"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": "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": "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.CONFIRMUNSAVEDSHORT": "AVERTO: Viaj ŝanĝoj ne estas konservitaj.",
"SecurityAdmin.BATCHACTIONSDELETECONFIRM": "Ĉu vi vere volas forigi %s grupojn?",

View File

@ -1,11 +1,11 @@
{
"CMSMAIN.SELECTONEPAGE": "Please select at least one page",
"CMSMAIN.BATCH_UNPUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to unpublish",
"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_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_DELETELIVE_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to delete these pages from live?",
"CMSMAIN.SELECTONEPAGE": "Bonvole elektu almenaŭ 1 paĝon.",
"CMSMAIN.BATCH_UNPUBLISH_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈi vi vere volas malpublikigi?",
"CMSMAIN.BATCH_PUBLISH_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈi vi vere volas publikigi?",
"CMSMAIN.BATCH_DELETE_PROMPT": "Vi elektis {num} paĝo(j)n.\n\nĈi vi vere volas forigi?",
"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": "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": "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.CONFIRMUNSAVEDSHORT": "AVERTO: Viaj ŝanĝoj ne estas konservitaj.",
"SecurityAdmin.BATCHACTIONSDELETECONFIRM": "Ĉu vi vere volas forigi %s grupojn?",

View File

@ -1,8 +1,8 @@
{
"CMSMAIN.SELECTONEPAGE": "Please select at least one page",
"CMSMAIN.BATCH_UNPUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to unpublish",
"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.SELECTONEPAGE": "请至少选择一个页面",
"CMSMAIN.BATCH_UNPUBLISH_PROMPT": "您已选了{num}个页面。\n\n是否确定要取消发布",
"CMSMAIN.BATCH_PUBLISH_PROMPT": "您已选了{num}个页面。\n\n是否确定要发布",
"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_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?",

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');
} else {
ss.i18n.addDictionary('zh', {
"CMSMAIN.SELECTONEPAGE": "Please select at least one page",
"CMSMAIN.BATCH_UNPUBLISH_PROMPT": "You have {num} page(s) selected.\n\nDo you really want to unpublish",
"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.SELECTONEPAGE": "请至少选择一个页面",
"CMSMAIN.BATCH_UNPUBLISH_PROMPT": "您已选了{num}个页面。\n\n是否确定要取消发布",
"CMSMAIN.BATCH_PUBLISH_PROMPT": "您已选了{num}个页面。\n\n是否确定要发布",
"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_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?",

View File

@ -119,6 +119,7 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
$this->pushCurrent();
$this->urlParams = $request->allParams();
$this->setRequest($request);
$this->getResponse();
$this->setDataModel($model);
$this->extend('onBeforeInit');
@ -394,7 +395,7 @@ class Controller extends RequestHandler implements TemplateGlobalProvider {
/**
* Returns the current controller
* @returns Controller
* @return Controller
*/
public static function curr() {
if(Controller::$controller_stack) {

View File

@ -448,8 +448,14 @@ class HTTP {
// Now that we've generated them, either output them or attach them to the SS_HTTPResponse as appropriate
foreach($responseHeaders as $k => $v) {
if($body) $body->addHeader($k, $v);
else if(!headers_sent()) header("$k: $v");
if($body) {
// Set the header now if it's not already set.
if ($body->getHeader($k) === null) {
$body->addHeader($k, $v);
}
} elseif(!headers_sent()) {
header("$k: $v");
}
}
}

View File

@ -163,6 +163,23 @@ class ArrayLib {
return false;
}
/**
* Similar to array_map, but recurses when arrays are encountered.
*
* Actually only one array argument is supported.
*
* @param $f callback to apply
* @param $array array
* @return array
*/
public static function array_map_recursive($f, $array) {
$applyOrRecurse = function($v) use($f) {
return is_array($v) ? ArrayLib::array_map_recursive($f, $v) : call_user_func($f, $v);
};
return array_map($applyOrRecurse, $array);
}
/**
* Recursively merges two or more arrays.
*

View File

@ -301,22 +301,30 @@ class ClassInfo {
* @return string
*/
public static function table_for_object_field($candidateClass, $fieldName) {
if(!$candidateClass || !$fieldName || !is_subclass_of($candidateClass, 'DataObject')) {
if(!$candidateClass
|| !$fieldName
|| !class_exists($candidateClass)
|| !is_subclass_of($candidateClass, 'DataObject')
) {
return null;
}
//normalise class name
$candidateClass = self::class_name($candidateClass);
$exists = self::exists($candidateClass);
while($candidateClass && $candidateClass != 'DataObject' && $exists) {
if(DataObject::has_own_table($candidateClass)) {
$inst = singleton($candidateClass);
// Short circuit for fixed fields
$fixed = DataObject::config()->fixed_fields;
if($exists && isset($fixed[$fieldName])) {
return self::baseDataClass($candidateClass);
}
if($inst->hasOwnTableDatabaseField($fieldName)) {
break;
}
// Find regular field
while($candidateClass && $candidateClass != 'DataObject' && $exists) {
if( DataObject::has_own_table($candidateClass)
&& DataObject::has_own_table_database_field($candidateClass, $fieldName)
) {
break;
}
$candidateClass = get_parent_class($candidateClass);

View File

@ -457,13 +457,17 @@ abstract class Object {
}
$extensionClass = $matches[1];
if(!class_exists($extensionClass)) {
user_error(sprintf('Object::add_extension() - Can\'t find extension class for "%s"', $extensionClass),
E_USER_ERROR);
user_error(
sprintf('Object::add_extension() - Can\'t find extension class for "%s"', $extensionClass),
E_USER_ERROR
);
}
if(!is_subclass_of($extensionClass, 'Extension')) {
user_error(sprintf('Object::add_extension() - Extension "%s" is not a subclass of Extension',
$extensionClass), E_USER_ERROR);
user_error(
sprintf('Object::add_extension() - Extension "%s" is not a subclass of Extension', $extensionClass),
E_USER_ERROR
);
}
// unset some caches

View File

@ -434,6 +434,13 @@ class PaginatedList extends SS_ListDecorator {
}
}
/**
* Returns the total number of items in the list
*/
public function TotalItems() {
return $this->getTotalItems();
}
/**
* Set the request object for this list
*

View File

@ -69,7 +69,8 @@ This is my `_ss_environment.php` file. I have it placed in `/var`, as each of th
:::php
<?php
// These three defines set the database connection details.
// These four define set the database connection details.
define('SS_DATABASE_CLASS', 'MySQLPDODatabase');
define('SS_DATABASE_SERVER', 'localhost');
define('SS_DATABASE_USERNAME', 'root');
define('SS_DATABASE_PASSWORD', '<password>');
@ -106,7 +107,7 @@ This is my `_ss_environment.php` file. I have it placed in `/var`, as each of th
| Name | Description |
| ---- | ----------- |
| `TEMP_FOLDER` | Absolute file path to store temporary files such as cached templates or the class manifest. Needs to be writeable by the webserver user. Defaults to *silverstripe-cache* in the webroot, and falls back to *sys_get_temp_dir()*. See *getTempFolder()* in *framework/core/TempPath.php*.|
| `SS_DATABASE_CLASS` | The database class to use, MySQLDatabase, MSSQLDatabase, etc. defaults to MySQLDatabase.|
| `SS_DATABASE_CLASS` | The database class to use, MySQLPDODatabase, MySQLDatabase, MSSQLDatabase, etc. defaults to MySQLDatabase.|
| `SS_DATABASE_SERVER`| The database server to use, defaulting to localhost.|
| `SS_DATABASE_USERNAME`| The database username (mandatory).|
| `SS_DATABASE_PASSWORD`| The database password (mandatory).|

View File

@ -3,7 +3,7 @@ summary: Modify the data model without using subclasses.
# Extending DataObjects
You can add properties and methods to existing [api:DataObjects]s like [api:Member] without hacking core code or sub
You can add properties and methods to existing [api:DataObject]s like [api:Member] without hacking core code or sub
classing by using [api:DataExtension]. See the [Extending SilverStripe](../extending) guide for more information on
[api:DataExtension].

View File

@ -1,4 +1,4 @@
title: Formating, Modifying and Casting Variables
title: Formatting, Modifying and Casting Variables
summary: Information on casting, security, modifying data before it's displayed to the user and how to format data within the template.
# Formatting and Casting

View File

@ -17,11 +17,11 @@ top level menu with a nested second level using the `Menu` loop and a `Children`
<% if $LinkOrSection == section %>
<% if $Children %>
<li><ul class="secondary">
<ul class="secondary">
<% loop $Children %>
<li class="$LinkingMode"><a href="$Link">$MenuTitle</a></li>
<% end_loop %>
</ul></li>
</ul>
<% end_if %>
<% end_if %>
</li>
@ -31,4 +31,4 @@ top level menu with a nested second level using the `Menu` loop and a `Children`
## Related
* [Template Syntax](../syntax)
* [Common Variables](../common_variables)
* [Common Variables](../common_variables)

View File

@ -67,7 +67,7 @@ the `getConfig()` method on `GridField`.
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Pages',
$grid = GridField('Pages', 'All pages', SiteTree::get())
$grid = new GridField('Pages', 'All pages', SiteTree::get())
);
// GridField configuration

View File

@ -101,6 +101,51 @@ operate in other structures, paths to static files such as CSS or JavaScript won
See the [How to Publish a SilverStripe Module](how_tos/publish_a_module) for details on how to publish your SilverStripe
modules with the community
## Module Standard
The SilverStripe module standard defines a set of conventions that high-quality SilverStripe modules should follow. Its a bit like PSR for SilverStripe CMS. Suggested improvements can be raised as pull requests.
### Coding Guidelines
* Declaration of level of support is provided for each module (either via README.md or composer) including the below.
* Level of support provided.
* Supporting user(s) and/or organisation(s).
* Complies to a well defined module directory structure and coding standards:
* templates (for ss templates)
* code (for php files)
* tests (for php test files) and
* _config (for yml config)
* The module is a Composer package.
* All Composer dependencies are bound to a single major release (e.g. ^3.1 not >=3.1).
* There is a level of test coverage.
* A clear public API documented in the docblock tags.
* Recommend the use of [PSR-1](http://www.php-fig.org/psr/psr-1/) and [PSR-2](http://www.php-fig.org/psr/psr-2/).
* .gitattributes will be used to exclude non-essential files from the distribution. At a minimum tests, docs, and IDE/dev-tool config should be excluded.
### Documentation Guidelines
Documentation will use the following format:
* README.md provides:
* Links or badges to CI and code quality tools.
* A short summary of the module, end-user.
* Installation instructions
* Testing/development instructions and a link to contrib instructions.
* How to report security vulnerabilities. Note that PSR-9 / PSR-10 may be recommended once released.
* Security, license, links to more detailed docs.
* CONTRIBUTING.md explaining terms of contribution.
* A changelog CHANGELOG.md (may link to other more detailed docs or GitHub releases if you want).
* Has a licence (LICENSE.md file) - for SilverStripe supported this needs to be BSD.
* Detailed documentation in /docs/en as a nested set of GitHub-compatible Markdown files.
* Links and image references are relative, and are able to be followed in viewers such as GitHub.
* Markdown may include non-visible comments or meta-data.
Documentation will cover:
* Installation
* Configuration
* Usage guides for key features; screenshots are recommended.
* A committers guide, covering PR-merging and release guidelines.
## Related

View File

@ -23,7 +23,7 @@ the [api:Extension] class for non DataObject subclasses (such as [api:Controller
public function SayHi() {
// $this->owner refers to the original instance. In this case a `Member`.
return "Hi ". $this->owner->Name;
return "Hi " . $this->owner->Name;
}
}
@ -80,7 +80,7 @@ $has_one etc.
public function SayHi() {
// $this->owner refers to the original instance. In this case a `Member`.
return "Hi ". $this->owner->Name;
return "Hi " . $this->owner->Name;
}
}

View File

@ -7,7 +7,7 @@ SilverStripe lets you customize the style of content in the CMS. This is done by
`editor.css` in either your theme or in your `mysite` folder. This is set through
:::php
HtmlEditorConfig::get('cms')->setOption('ContentCSS', project() . '/css/editor.css');
HtmlEditorConfig::get('cms')->setOption('content_css', project() . '/css/editor.css');
Will load the `mysite/css/editor.css` file.

View File

@ -250,7 +250,7 @@ Ready](http://docs.jquery.com/How_jQuery_Works#Launching_Code_on_Document_Ready)
jQuery supports automatically reapplying event handlers when new DOM elements get inserted, mostly through Ajax calls.
This "binding" saves you from reapplying this step manually.
Caution: Only applies to certain events, see the [jQuery.on() documentation](http://api.jquery.com/on/).
Caution: Only applies to certain events, see the [jQuery.on() documentation](http://api.jquery.com/on/#direct-and-delegated-events).
Example: Add a 'loading' classname to all pressed buttons
@ -261,14 +261,11 @@ Example: Add a 'loading' classname to all pressed buttons
});
// binding, applies to any inserted elements as well
$('input[[type=submit]]').on(function() {
$('.cms-container').on('click', 'input[[type=submit]]', function() {
$(this).addClass('loading');
});
See [jQuery FAQ: Why do my events stop working after an AJAX
request](http://docs.jquery.com/Frequently_Asked_Questions#Why_do_my_events_stop_working_after_an_AJAX_request.3F).
### Assume Element Collections
jQuery is based around collections of DOM elements, the library functions typically handle multiple elements (where it

View File

@ -0,0 +1,13 @@
# 3.1.15
This release resolves issues with compatibility with PHP 5.3.3 introduced in 3.1.14
<!--- Changes below this line will be automatically regenerated -->
## Change Log
### Bugfixes
* 2015-09-17 [e64d73c](https://github.com/silverstripe/silverstripe-framework/commit/e64d73c1f741399412b6015f6602ed707b2e9778) Fix ClassInfo::table_for_object_field (Damian Mooyman)
* 2015-09-09 [06cc185](https://github.com/silverstripe/silverstripe-framework/commit/06cc18526a1f63b8bb16809e23f2eb17ade7a85e) UploadField error when attempting to attach non-existent file IDs (Loz Calver)
* 2015-09-07 [96d20bc](https://github.com/silverstripe/silverstripe-framework/commit/96d20bc1809c731e3e78b7c5248282c8771f3097) Fix missing framework/admin/tests (Damian Mooyman)

View File

@ -3,8 +3,8 @@
## Contents
* [Major Changes](#major-changes)
* [Removed API](#deprecated-classesmethods-removed)
* [New API](#new-and-changed-api)
* [Deprecated classes/methods](#deprecated-classesmethods-removed)
* [New and changed API](#new-and-changed-api)
* [Bugfixes](#bugfixes)
* [Upgrading Notes](#upgrading-notes)
@ -183,6 +183,32 @@ The following functionality deprecated in 3.0 has been removed:
## Upgrading Notes
### Enable PDO
Although this is not a mandatory upgrade step, the new `[api:PDOConnector]` class offers improved database
performance and security, and should be integrated into any project using 3.2.
In order to update your connector you can do so in one of two ways, depending on whether or not
your project is using `_ss_environment.php` to configure your database, or via `mysite/_config.php`
If using `_ss_environment.php`:
:::php
define('SS_DATABASE_CLASS', 'MySQLPDODatabase');
If using `mysite/_config.php`:
:::php
global $databaseConfig;
$databaseConfig = array(
"type" => "MySQLPDODatabase"
// other config settings
);
### Disable `LastVisited` and `NumVisits` counter
These fields were deprecated in 3.1 due to performance concerns, and should be disabled unless required by
@ -788,3 +814,163 @@ In order to remove the new "archive" action and restore the old "delete" action
enabled_legacy_actions:
- CMSBatchAction_Delete
<!--- Changes below this line will be automatically regenerated -->
## Change Log
### API Changes
* 2015-08-03 [f2c39aa](https://github.com/silverstripe/silverstripe-framework/commit/f2c39aac200f50157d9163b825ea7a7dd1f7aa18) batch restore action (Damian Mooyman)
* 2015-08-03 [e22b653](https://github.com/silverstripe/silverstripe-cms/commit/e22b653e06207bfdc0b36ac7a9e6be250e10bde8) batch restore action (Damian Mooyman)
* 2015-07-10 [a6677b1](https://github.com/silverstripe/silverstripe-cms/commit/a6677b1653cf338d66b8b6d1e4d5b14d66250c0e) respect custom attributes on OptionsetField and CheckboxSetField (Damian Mooyman)
* 2015-07-10 [560f9a6](https://github.com/silverstripe/silverstripe-framework/commit/560f9a6e39df4f09dfe4bed5978f6dcddc0bb299) respect custom attributes on OptionsetField and CheckboxSetField (Damian Mooyman)
* 2015-06-15 [f3e1472](https://github.com/silverstripe/silverstripe-cms/commit/f3e1472493b15758c67bb2c8814bc28765eac401) Revert DataObject::validate to 3.1 method signature (protected) (Damian Mooyman)
* 2015-06-15 [58cc3da](https://github.com/silverstripe/silverstripe-framework/commit/58cc3da8d8005d6a367d88fb7c5d41c96dd8946f) Revert DataObject::validate to 3.1 method signature (protected) (Damian Mooyman)
* 2015-06-13 [e766658](https://github.com/silverstripe/silverstripe-framework/commit/e766658ee3b9e70988b79d99d75124857f2a7ccc) Allow HTTP Cache Headers to be customized (Jeremy Shipman)
* 2015-06-12 [8389260](https://github.com/silverstripe/silverstripe-framework/commit/838926085cac00ec65ee5aecb67e6102ea8b6f20) and renamed image functions (Jonathon Menz)
* 2015-06-09 [914d734](https://github.com/silverstripe/silverstripe-framework/commit/914d734df004947eb869de2abb6fb2fc463be574) Disable deprecation notices by default (Damian Mooyman)
* 2015-06-09 [a8ace75](https://github.com/silverstripe/silverstripe-framework/commit/a8ace7534194b5e1a636c96eca4607d08726dfeb) Support for multiple HTMLEditorConfig per page (Damian Mooyman)
* 2015-05-14 [b169823](https://github.com/silverstripe/silverstripe-cms/commit/b169823a00fed190bcd55054339baa3bc818cd75) Deprecate delete in favour of archive (Damian Mooyman)
* 2015-05-14 [a72bd16](https://github.com/silverstripe/silverstripe-framework/commit/a72bd16f420915d4ef2301ee1bec3dcfe2ed2305) Deprecate delete in favour of archive (Damian Mooyman)
* 2015-04-30 [c5e0c8f](https://github.com/silverstripe/silverstripe-cms/commit/c5e0c8f007c814e82f2c7f84b1fb4eacbcf5ab4d) Enable tree filter highlighting (Damian Mooyman)
* 2015-04-30 [8863797](https://github.com/silverstripe/silverstripe-framework/commit/8863797b76fd1f81d9e9f4900fc6c387966554da) Enable tree filter highlighting (Damian Mooyman)
* 2015-04-29 [e8d6f15](https://github.com/silverstripe/silverstripe-framework/commit/e8d6f15f2883b765bf17bb7027013ebd2a79cf9c) Use mysql buffered statements (Damian Mooyman)
* 2015-04-09 [e91606e](https://github.com/silverstripe/silverstripe-framework/commit/e91606e4943a1725d51f5c0f7bf80165995bc814) Introduce $FromEnd variable for iterators (Damian Mooyman)
* 2015-03-31 [95c162e](https://github.com/silverstripe/silverstripe-framework/commit/95c162ef0d645a2af9ad355ef195ab426a881fd4) Security better respects BackURL on login (Damian Mooyman)
* 2015-03-04 [9367fd2](https://github.com/silverstripe/silverstripe-framework/commit/9367fd2456a1f3f535f55249f9d6d5a2d7399af9) enable PaginatedList to be disabled by setting page length to 0 (Damian Mooyman)
* 2015-01-14 [5d4c2c4](https://github.com/silverstripe/silverstripe-framework/commit/5d4c2c4b34e1a0d544ce1b39a8d6fd74420025d4) Adding default_classes to FormField (Daniel Hensby)
* 2015-01-14 [6d00027](https://github.com/silverstripe/silverstripe-framework/commit/6d0002780dc89af91354979cba4d09d2cf8946da) Adding default_classes to Form (Daniel Hensby)
* 2014-09-25 [e478009](https://github.com/silverstripe/silverstripe-framework/commit/e47800917a5482b1dce455f4fbcb564ff73d7576) Mailer can be configured to use different encoding mechanisms, and added support for unicode quoted-string encoding (Damian Mooyman)
* 2014-09-25 [29e3347](https://github.com/silverstripe/silverstripe-framework/commit/29e33475621fd9e4be20ecdea45d017bbd4f65f8) Convert::html2raw no longer wraps text automatically (Damian Mooyman)
* 2014-09-24 [5631553](https://github.com/silverstripe/silverstripe-framework/commit/563155391f02dca5017dfc2a967eb1e93f0f1014) Cookies set via Cookie::set() are now HTTP only by default (Sean Harvey)
* 2014-09-15 [062ad8e](https://github.com/silverstripe/silverstripe-framework/commit/062ad8e6850efa4a1b8895bd361cb93079685cfa) Allow parameterised joins / subselects (Damian Mooyman)
* 2014-08-15 [2ba1c46](https://github.com/silverstripe/silverstripe-cms/commit/2ba1c46bc86b3c8fdea723e6b936ede4806314be) broken link hihglighting to write to database. (Mateusz Uzdowski)
* 2014-08-13 [784e292](https://github.com/silverstripe/silverstripe-framework/commit/784e292d4e57b82c372f3db2edbbc6e0e067d4d3) Add a getter for customisedObject property. (Mateusz Uzdowski)
* 2014-08-09 [18d6c53](https://github.com/silverstripe/silverstripe-cms/commit/18d6c538a7d8865dca44f4e37d88b54dc30c20e6) Extract siteconfig out to an external module. (Will Rossiter)
* 2014-08-04 [1759d5d](https://github.com/silverstripe/silverstripe-framework/commit/1759d5d017068693b20f82ac7009004fd0163375) Use "number" HTML5 type for NumericField by default (Sean Harvey)
* 2014-07-29 [26a0e91](https://github.com/silverstripe/silverstripe-framework/commit/26a0e915536f067c5c5429ffa5224f3cff37b886) SS_Filterable, SS_Limitable and SS_Sortable now explicitly extend SS_List (Damian Mooyman)
* 2014-04-22 [d16db2d](https://github.com/silverstripe/silverstripe-framework/commit/d16db2d4f4b2fbd65722f40305fbc075edf72eb1) tinymce editor no longer transforms paragraphs with margin-left into blockquotes (Damian Mooyman)
* 2014-04-16 [5f7ebd3](https://github.com/silverstripe/silverstripe-framework/commit/5f7ebd3c235d663b5ad5c0fbcd3d393d2e893306) UploadField: move replaceFile to the front end config (Devlin)
* 2014-04-10 [5b55361](https://github.com/silverstripe/silverstripe-framework/commit/5b553616dc2438b3ad7803e2765bd37b0d1d8736) DateTime.Ago better infers significance of date units. (Damian Mooyman)
* 2014-04-09 [2e73dcb](https://github.com/silverstripe/silverstripe-framework/commit/2e73dcb8912223abb88354e09b13aafa902af8af) Remove swf,html,htm,xhtml,xml as default allowed upload able file types (Damian Mooyman)
* 2014-04-04 [bf4e9eb](https://github.com/silverstripe/silverstripe-framework/commit/bf4e9eb0443c00e1e8a06d0db5636edd627d55eb) Singleton method allowing type inference (Damian Mooyman)
* 2014-02-11 [6906c9b](https://github.com/silverstripe/silverstripe-framework/commit/6906c9bd1a5535e6e2674c26446f4fd6d81e8490) Removed auto-detection for i18n date/time formats (Ingo Schommer)
* 2014-01-17 [973b967](https://github.com/silverstripe/silverstripe-framework/commit/973b967e6b9ce68e0e03b97ae49f28a155a28c6e) Adding chaining to i18nTextCollector::write() (Daniel Hensby)
* 2014-01-02 [791ee71](https://github.com/silverstripe/silverstripe-framework/commit/791ee7171b20ffd66f2d6d0c18589adfc22b6680) Prevent large images from repeatedly crashing PHP on resize (Loz Calver)
* 2013-12-23 [5fff5af](https://github.com/silverstripe/silverstripe-framework/commit/5fff5afb478381a23e6b8b5b9079ae1fe5724fdd) moved useTestTheme to base Sapphire test class so that it can be used elsewhere (eg CMS test) (micmania1)
* 2013-12-19 [6fc9db6](https://github.com/silverstripe/silverstripe-framework/commit/6fc9db6f0e87fe935ccb46daff880158453ad04b) DataObject::validate() visibility changed to public (issue #1659) (Sean Harvey)
* 2013-11-26 [b88a095](https://github.com/silverstripe/silverstripe-framework/commit/b88a0955a5b314cc57573ec573f9839ec9d17f7a) Support string descriptors for unique indexes in Versioned (Fred Condo)
* 2013-10-17 [fee54c7](https://github.com/silverstripe/silverstripe-framework/commit/fee54c75f05d7bbc2b7c221c3150d201e1fffb59) Change DropdownField::getSource() to not return the emptyString value. (Nathan J. Brauer)
* 2013-10-17 [1c983bc](https://github.com/silverstripe/silverstripe-framework/commit/1c983bc16d7479c2c9bac3984e36545dc4a301e8) LookupField::Field now returns an HTMLText instance. (Will Rossiter)
* 2013-10-16 [52f6581](https://github.com/silverstripe/silverstripe-framework/commit/52f6581ecf1d09f8c368e2de15e4a64e69ff4a40) Better declaration of DataObject field change levels. (Damian Mooyman)
* 2013-10-10 [b6b3cd9](https://github.com/silverstripe/silverstripe-framework/commit/b6b3cd98891e0f6134c77225e76147d8721d0129) GridState_Data values can have default values specified during retrieval. (Damian Mooyman)
* 2013-10-09 [b367dd6](https://github.com/silverstripe/silverstripe-framework/commit/b367dd6237e56cc88744befa98e6c8f2cdd503f2) Removed Member.LastVisited and Member.NumVisits (Ingo Schommer)
* 2013-09-27 [c7f656c](https://github.com/silverstripe/silverstripe-framework/commit/c7f656cd0051a051bca2e60011c52ff812596d8a) Removed "PastMember" cookie and template getter (Ingo Schommer)
* 2013-08-08 [4385264](https://github.com/silverstripe/silverstripe-framework/commit/4385264aa9da453d3a9fcf28d92c61ef31d928f2) Make GridFieldConfig objects decoratable (unclecheese)
* 2013-07-10 [7c60c73](https://github.com/silverstripe/silverstripe-framework/commit/7c60c73dbb2559cc5950eb40efa640e04bde2d17) Polymorphic has_one behaviour (Damian Mooyman)
* 2013-06-30 [47147eb](https://github.com/silverstripe/silverstripe-framework/commit/47147eb3dfc39a13da9ff9b9644c0ce0375bd669) delete simplepie from framework thirdparty (carlos barberis)
* 2013-06-20 [a395c53](https://github.com/silverstripe/silverstripe-cms/commit/a395c5322fc1965b775be50149a38cdff36cca59) Move of codebase to parameterised query database abstraction layer (Damian Mooyman)
* 2013-06-20 [d8e9af8](https://github.com/silverstripe/silverstripe-framework/commit/d8e9af8af8d59b3ee16f404f2f2b0a528d503022) Database abstraction layer. Ticket #7429 (Damian Mooyman)
* 2013-05-31 [0c4ec47](https://github.com/silverstripe/silverstripe-framework/commit/0c4ec4708bcbb8fb09a1bb9acf75639077cbaaa9) Using $HolderID for form field container templates (Ingo Schommer)
* 2013-05-25 [ca87b8b](https://github.com/silverstripe/silverstripe-framework/commit/ca87b8b79496a78454d63c225f1f4f38fa55a150) Form Field ID attribute should follow HTML specification (Will Rossiter)
* 2013-05-22 [cb1f95e](https://github.com/silverstripe/silverstripe-framework/commit/cb1f95e51eff1ce762456e0fa6b7eca38ccc3198) Remove AjaxUniqueTextField, since its operation is very limited (#1947) (Ingo Schommer)
* 2013-01-29 [957469d](https://github.com/silverstripe/silverstripe-framework/commit/957469d770c555d5461ea476906fbaa64ac2bc02) Removed auto-routing of controller name (Ingo Schommer)
* 2013-01-17 [56346a5](https://github.com/silverstripe/silverstripe-cms/commit/56346a50bf161a2a840517cf8bf5d38cf8174103) moved reports API to separate module (Will Rossiter)
### Features and Enhancements
* 2015-06-02 [a9d22f1](https://github.com/silverstripe/silverstripe-framework/commit/a9d22f1fbf6e499ac0cc7f12e3f389015a07834d) Files can be uploaded directly in the 'Insert Link' form (scott1702)
* 2015-05-29 [44b1ff1](https://github.com/silverstripe/silverstripe-framework/commit/44b1ff193106e55aa754f64ddab28146f8857290) Configurable file version prefix (Jonathon Menz)
* 2015-05-11 [ce5a8f2](https://github.com/silverstripe/silverstripe-framework/commit/ce5a8f2b415d4c4f0680f5adece2686f0a490f48) Cookie names with dots are now handled more gracefully (Daniel Hensby)
* 2015-03-31 [ae8dbe3](https://github.com/silverstripe/silverstripe-framework/commit/ae8dbe309b797a20a91088351d70486cf3dfea79) - Added maximum upload file size by type (Turnerj)
* 2015-03-24 [16f0e7b](https://github.com/silverstripe/silverstripe-framework/commit/16f0e7b0d3f1b25af325c224ea4111303b50785b) ViewableData_Debugger implements __toString (Daniel Hensby)
* 2015-03-03 [835ee69](https://github.com/silverstripe/silverstripe-framework/commit/835ee69339fbfca0c477c3717cc12c1c1e7737e0) Only validate DataObject model definitions during a build (Loz Calver)
* 2015-02-24 [8ee9130](https://github.com/silverstripe/silverstripe-framework/commit/8ee9130bcf10339c3eed54e10aa55f297ec89efd) CMS site tree status icons (Jonathon Menz)
* 2015-02-08 [5f31983](https://github.com/silverstripe/silverstripe-framework/commit/5f31983ded7a7a08586a74a9b5ff594d84a8a11c) updateAttributes hook in FormField (Ingo Schommer)
* 2015-01-23 [3f1805b](https://github.com/silverstripe/silverstripe-framework/commit/3f1805bfd2934bdf2a489fdd00b5c21308cf9837) Support multiple many_manys between the same classes (closes #1377) (Josh)
* 2014-12-15 [6ad8f7c](https://github.com/silverstripe/silverstripe-framework/commit/6ad8f7c3dd1d4b18d9982ac33e709dac6436a664) Subject line for email links in HtmlEditorField (Loz Calver)
* 2014-11-12 [41ea83b](https://github.com/silverstripe/silverstripe-framework/commit/41ea83b3374d026da9575f5256a02bdcfbb82059) add validation to form field subclasses (Stevie Mayhew)
* 2014-10-17 [dc7bc46](https://github.com/silverstripe/silverstripe-framework/commit/dc7bc4673e6860938519bb7cb9fba9e3835fd5de) Text - Limit characters to closest word (Anton Smith)
* 2014-10-03 [23fc498](https://github.com/silverstripe/silverstripe-framework/commit/23fc498c275db92ba182be3bf13e672b20866ba3) Allow 'null' limit for database queries (closes #3487) (Loz Calver)
* 2014-05-04 [3b9056f](https://github.com/silverstripe/silverstripe-framework/commit/3b9056fc014d1a9432aa1142174904ac6c1f8e08) Cookie_Backend for managing cookie state (Daniel Hensby)
* 2013-10-17 [e8287cd](https://github.com/silverstripe/silverstripe-framework/commit/e8287cd2f56952345be65e98fb732476b8c0b481) Hook for `Member::registerFailedLogin` (Thomas Speak)
* 2013-08-23 [7d7c754](https://github.com/silverstripe/silverstripe-cms/commit/7d7c75414c338bfd906f7e63eccaccff913951ef) Track broken anchors (Russell Michell)
* 2013-06-05 [60333f6](https://github.com/silverstripe/silverstripe-framework/commit/60333f68ee3557ce9ecef1984c988a08c2fe6b51) UploadField lists all files, shows path info (Ingo Schommer)
* 2013-06-03 [2a91d27](https://github.com/silverstripe/silverstripe-framework/commit/2a91d27ccb15ea4bb2e8501b7735f977a206d83b) use Injector pattern to create ValidationResult in validate (Will Morgan)
* 2013-05-25 [736bde8](https://github.com/silverstripe/silverstripe-framework/commit/736bde8fe578a8702e72e801996b9cc2c989b9c2) Add Convert::raw2htmlid() (Will Rossiter)
* 2013-03-26 [64349fe](https://github.com/silverstripe/silverstripe-framework/commit/64349fefb5fdc2c8a189a49d72e6a68a6c95afbc) Allow setting of ASSETS_DIR in _ss_environment.php (Loz Calver)
### Bugfixes
* 2015-10-06 [df805af](https://github.com/silverstripe/silverstripe-framework/commit/df805af67bda15888d17f49817903bf136561773) Imagick tests compare image dimensions rather than image hashes (Damian Mooyman)
* 2015-10-05 [ad42f80](https://github.com/silverstripe/silverstripe-framework/commit/ad42f802c4a621916a352c3a7c5d4f849b896c3e) Fix duplicate HolderID on TreeDropdownField (Damian Mooyman)
* 2015-10-05 [6c117cd](https://github.com/silverstripe/silverstripe-framework/commit/6c117cd62960670239c5a6f6b3832c819e21332a) fix imagick interface and add to travis (Damian Mooyman)
* 2015-09-30 [cb55a0a](https://github.com/silverstripe/silverstripe-framework/commit/cb55a0a621494873a04c697ecd326bb7a4d02173) GridFieldSortableHeader incorrectly reporting fields as sortable (Loz Calver)
* 2015-09-29 [666ce26](https://github.com/silverstripe/silverstripe-framework/commit/666ce269292521288eef8aeac4af30378f775576) Permission::checkMember() use of undefined variable $codes (Manuel Teuber)
* 2015-09-23 [8f0f647](https://github.com/silverstripe/silverstripe-framework/commit/8f0f6475daa6cb32a33089ef60f18d5f4f8735ed) Issues with field focus in edit forms (fixes #4621) (Loz Calver)
* 2015-09-23 [052aba1](https://github.com/silverstripe/silverstripe-cms/commit/052aba17acee51a276e42bcc0bd5a26b4cc2ae58) Incorrect field IDs breaking SiteTree settings toggles (fixes #1280) (Loz Calver)
* 2015-09-22 [0d89a13](https://github.com/silverstripe/silverstripe-framework/commit/0d89a13c2d02dc08d8ff14884b12f22b2f1cf4f2) GridFieldDetailForm failing to save many_many relations (Loz Calver)
* 2015-09-14 [81ca74b](https://github.com/silverstripe/silverstripe-framework/commit/81ca74bc30cb8f128c48672fd9807943c924145d) #103 (David Alexander)
* 2015-09-10 [6056e9c](https://github.com/silverstripe/silverstripe-framework/commit/6056e9cb1bc4f8073aef07b83f7417edbe7f2ac4) Editing existing file links in HtmlEditorField was broken (Loz Calver)
* 2015-08-31 [e86b45b](https://github.com/silverstripe/silverstripe-framework/commit/e86b45bf5db663b03e006a132e04afba37ee4bf3) Remove html5 number field due to insufficient localisation support (Damian Mooyman)
* 2015-08-24 [f7c1983](https://github.com/silverstripe/silverstripe-framework/commit/f7c19830d663ee05d81f7fa504b1ef043b8361fe) Fix JS error on clicking collapsed panel (Damian Mooyman)
* 2015-08-24 [6c17397](https://github.com/silverstripe/silverstripe-cms/commit/6c173973229acc198cb467ee369bab5af96b7f13) block adding children from archived pages (Damian Mooyman)
* 2015-08-21 [0f81d5e](https://github.com/silverstripe/silverstripe-framework/commit/0f81d5ece57a50c0daaf0d86c2faa977f323663b) Fix bulk actions making sitetree unclickable (Damian Mooyman)
* 2015-08-09 [cf9d2d1](https://github.com/silverstripe/silverstripe-framework/commit/cf9d2d12ac7fc6a2509ee70f8e6f304b3b232019) Fix duplicate primary key crash on duplicate (Damian Mooyman)
* 2015-08-07 [1f0602d](https://github.com/silverstripe/silverstripe-framework/commit/1f0602d42fd9e1c0a4268f3a51aa7f483100a935) Fixed regression from ClassInfo case-sensitivity fix. (Sam Minnee)
* 2015-07-30 [66ca540](https://github.com/silverstripe/silverstripe-framework/commit/66ca5405d0cb8116e5cdf5f886b96d321b20477c) Fix change detection on browser back button (Damian Mooyman)
* 2015-07-30 [97b226a](https://github.com/silverstripe/silverstripe-framework/commit/97b226abe023bbc059633cd944ff04c281a675a8) Fix semver violation in create_table_options (Damian Mooyman)
* 2015-07-27 [aa286ef](https://github.com/silverstripe/silverstripe-framework/commit/aa286ef7d77d78cde1aaedb2eca5b3c07803366b) Missing thumbnails and inconsistencies (Jonathon Menz)
* 2015-07-23 [10b2fdc](https://github.com/silverstripe/silverstripe-cms/commit/10b2fdc3181310ec3ca75361852deca57ccbbe4c) ContentController::getViewer() not returning all found templates (fixes #1244) (Loz Calver)
* 2015-07-22 [b7480b9](https://github.com/silverstripe/silverstripe-framework/commit/b7480b92a9c734058135a3259a1c4432c6bb474d) Hide 'Logged Passwords' tab in member CMS fields (fixes #4422) (Loz Calver)
* 2015-07-05 [a5b3083](https://github.com/silverstripe/silverstripe-framework/commit/a5b3083dccaedf6a78a5bfd5ecfc5d12ca7cdfba) memory exhaustion in MySQLStatement-&gt;bind() (micmania1)
* 2015-07-01 [3b90fef](https://github.com/silverstripe/silverstripe-cms/commit/3b90fef04f914aa6d4a43322771ea1d6b3329af2) fix behat tests (Damian Mooyman)
* 2015-06-24 [3507ddb](https://github.com/silverstripe/silverstripe-framework/commit/3507ddb0e8f85cb2a2cb20595590b1c89cc27c67) MemberPassword history removed with with Members (Daniel Hensby)
* 2015-06-19 [a58e595](https://github.com/silverstripe/silverstripe-framework/commit/a58e59565b7b092451b084643d58ddb6ccfbee31) docs not included in composer package installs (through export-ignore git attribute) (Sam Minnee)
* 2015-06-16 [ce3b5a5](https://github.com/silverstripe/silverstripe-framework/commit/ce3b5a5ace556f65a23348ed6e7bd50dd639f9e0) Fix major segfault on PDOConnector after any DDL (Damian Mooyman)
* 2015-06-09 [24a268a](https://github.com/silverstripe/silverstripe-framework/commit/24a268a12b5ade6e513694e6e7d826f5f0759ee2) Image test cleanup (Jonathon Menz)
* 2015-06-09 [07c21e2](https://github.com/silverstripe/silverstripe-framework/commit/07c21e28805236807387b984e988f62043728620) Fix deletion of orphaned versioned records when a parent _versions table has been deleted (Damian Mooyman)
* 2015-06-08 [acf19b7](https://github.com/silverstripe/silverstripe-framework/commit/acf19b72e2a6fb52527a788b1ed87f552e57f314) Fix false values for many_many_ExtraFields not being saved (Damian Mooyman)
* 2015-06-04 [a819bcf](https://github.com/silverstripe/silverstripe-cms/commit/a819bcfc97a6594787cea738bda2596787ab673f) explicitly call get functions for site tree checks (Stevie Mayhew)
* 2015-05-22 [68d8df4](https://github.com/silverstripe/silverstripe-framework/commit/68d8df4e04556b3f9ad63a6d8cff84e63f972d66) DropdownField didn't consider disabled items (Loz Calver)
* 2015-05-11 [9e8a5c9](https://github.com/silverstripe/silverstripe-framework/commit/9e8a5c9ba557298eed319744d3cc5689483063ab) remove validation type constraint from form fields for 3.2 release (Stevie Mayhew)
* 2015-04-02 [dd0e2dc](https://github.com/silverstripe/silverstripe-framework/commit/dd0e2dc36200e3931923693c2b9dc978aea99825) Image_Cached exists method doesnt check for positive ID (Daniel Hensby)
* 2015-02-14 [bee642a](https://github.com/silverstripe/silverstripe-framework/commit/bee642a6b9de946f507b73f07412d4ee2127fe45) make class loader classExists check interface_exists as per docs (Daniel Hensby)
* 2015-02-13 [66391ab](https://github.com/silverstripe/silverstripe-framework/commit/66391ab57ad49c2a40bad59fc1fc9e1f12e39d97) Imported namespaces now correctly used to determine class inheritance (Daniel Hensby)
* 2015-02-08 [6212b4b](https://github.com/silverstripe/silverstripe-framework/commit/6212b4bd4bd9adcc79042ffffe88144796239b57) Versioned not ignoring obsolete fields (Benjamin R. White)
* 2015-01-30 [e724d6f](https://github.com/silverstripe/silverstripe-framework/commit/e724d6f578af8878226665f189c596276e4b1536) notice level error when value is not set on CreditCardField (Will Rossiter)
* 2015-01-07 [cee7adc](https://github.com/silverstripe/silverstripe-framework/commit/cee7adc12c9a05f14e956f8ff23f06c43e337b5f) . Placeholder isn't completely translated (Elvinas L)
* 2014-12-15 [c358ac6](https://github.com/silverstripe/silverstripe-framework/commit/c358ac6496a837e86e5b0ab97fcc56ae8a78a250) How to folder on forms (Cam Findlay)
* 2014-12-08 [bdb3b7f](https://github.com/silverstripe/silverstripe-framework/commit/bdb3b7f085d9ddc1152a98cc93418bcfd10d63d5) Feedback to name the fields section to "field types" to make it clearer what the section is about. (Cam Findlay)
* 2014-12-08 [aba9667](https://github.com/silverstripe/silverstripe-framework/commit/aba966729ac7570435fc33227e3ca88f4e4d955f) use GFMD code blocks to fix code formatting consistency. (Cam Findlay)
* 2014-11-03 [51337ac](https://github.com/silverstripe/silverstripe-framework/commit/51337acda91a68d0d353c521fb4541531dfa82bc) Image backend ignoring config. (Michael Strong)
* 2014-10-26 [ec0c259](https://github.com/silverstripe/silverstripe-framework/commit/ec0c259c17cd3b1df6235378692ed8b6a7630dfc) Reinstate tab and form focus states (fixes CMS #732 and #817) (Naomi Guyer)
* 2014-09-26 [db0cad4](https://github.com/silverstripe/silverstripe-framework/commit/db0cad461670a11f9ba27f979812be4d70ab37c9) ErrorControlChain now supports exception handling (Damian Mooyman)
* 2014-09-01 [c140459](https://github.com/silverstripe/silverstripe-framework/commit/c140459ac624738630ac8bec6a665fa3040e2e54) Fix versioned (Damian Mooyman)
* 2014-09-01 [3644110](https://github.com/silverstripe/silverstripe-framework/commit/364411034947b78d9077caf91ad215ae79d2afba) Ensure that columns are unique within a gridfield (Will Rossiter)
* 2014-08-01 [b0239f4](https://github.com/silverstripe/silverstripe-framework/commit/b0239f43302110f250d6121a518c5119a76d1fca) Fix PDOConnector issues (Damian Mooyman)
* 2014-07-25 [81c0a34](https://github.com/silverstripe/silverstripe-framework/commit/81c0a3499bea4aa4191011616e2cbaf9ed075748) Remove caching of statements due to risk of instability (Damian Mooyman)
* 2014-07-14 [0433ba1](https://github.com/silverstripe/silverstripe-framework/commit/0433ba1642efdd32c5667c12cc3ef7f2f5e7db04) Revert some changes to ManyManyList (Damian Mooyman)
* 2014-05-22 [3213630](https://github.com/silverstripe/silverstripe-framework/commit/32136305be887fe3118f078c3f73df569c86ca53) fix listview not working with IE9 (Igor)
* 2014-05-09 [8335de4](https://github.com/silverstripe/silverstripe-framework/commit/8335de49b3dacd614819af5f7ce12157bb38d6b9) remove redundant DB name switch in TestRunner (Will Morgan)
* 2014-05-02 [9cbfd14](https://github.com/silverstripe/silverstripe-framework/commit/9cbfd14d9d75628bdfd97a31ab571b5ad597b5eb) TemplateManifest prevent cache collision (Will Morgan)
* 2014-04-29 [5dd0583](https://github.com/silverstripe/silverstripe-cms/commit/5dd058338af08dd3ee5956e7a7c66c30160f6cd4) Fix encoding of SearchForm::getSearchQuery (Damian Mooyman)
* 2014-04-08 [438fe02](https://github.com/silverstripe/silverstripe-framework/commit/438fe02116365569893f3370d08c4b1f20f0b19e) change action variable source to getViewer (Will Morgan)
* 2014-03-27 [cf5d524](https://github.com/silverstripe/silverstripe-framework/commit/cf5d524235b82c3f13a0643333ffcd140788da14) Fix regressions from #2206 in hasValue and dbObject (Damian Mooyman)
* 2014-03-25 [4b87b2e](https://github.com/silverstripe/silverstripe-cms/commit/4b87b2e2e6ab1aac546d707f79ce00dc17ca07f8) Fix ContentControllerTest (Damian Mooyman)
* 2014-02-28 [ab52b67](https://github.com/silverstripe/silverstripe-framework/commit/ab52b677aac5caae974928642aee42cc76f54f65) Log out current member when forgotten password (Daniel Hensby)
* 2014-02-20 [f6b72a2](https://github.com/silverstripe/silverstripe-framework/commit/f6b72a20919c77615d222f28adaa735ff0f0a49b) Fixed regression in ContentController template selection. (Sam Minnee)
* 2014-02-14 [d0a4fc2](https://github.com/silverstripe/silverstripe-cms/commit/d0a4fc206542242362a753414bd28366c9c1a84e) Fix failover to index template in ContentController::getViewer() (Sam Minnee)
* 2014-02-03 [cd213ab](https://github.com/silverstripe/silverstripe-framework/commit/cd213ab4884958d45cccaaf75cde15c0c525584b) Fixed handing of false values in GridState_Data (Damian Mooyman)
* 2014-01-31 [6df276c](https://github.com/silverstripe/silverstripe-framework/commit/6df276c843621ca07da3ace5be681cef82dc1ae3) GridState_Data doesn't hold falsey values (Daniel Hensby)
* 2013-10-30 [4102cc6](https://github.com/silverstripe/silverstripe-framework/commit/4102cc64a07992639ea8e9fa91ad55f3c771e430) Issues with CMSForm not consistently respecting new form naming scheme. (Damian Mooyman)
* 2013-10-22 [8534982](https://github.com/silverstripe/silverstripe-framework/commit/85349820e4da838236064681d72405737850b438) Debug error handler breaks error_get_last (Damian Mooyman)
* 2013-10-19 [ab10c2e](https://github.com/silverstripe/silverstripe-framework/commit/ab10c2ecdc8522d11becb59fe7020ab0526d59e9) An enum field in the search panel model admin misses an option to not filter on that field (Nico Haase)
* 2013-10-17 [d22ca62](https://github.com/silverstripe/silverstripe-framework/commit/d22ca62c6f324548b7c494c84b39a4197e7a5f35) FailedLoginCount reset (Thomas Speak)
* 2013-10-02 [fb5bb64](https://github.com/silverstripe/silverstripe-framework/commit/fb5bb646fe2734464ef3fd500765146cdd63dbeb) Fixed cross-platform issues with test cases and file utilities (Damian Mooyman)
* 2013-05-30 [c7468ca](https://github.com/silverstripe/silverstripe-framework/commit/c7468caeb67ad680ef748621348b0d82e2fed992) Generate Form::FormName() through (Will Rossiter)
* 2013-05-25 [831a507](https://github.com/silverstripe/silverstripe-framework/commit/831a507c90b8a4560742e86ecb5defd6fe1e259d) Update references to ID values from 79c9433 (Will Rossiter)
* 2013-05-17 [3728907](https://github.com/silverstripe/silverstripe-framework/commit/372890703ca96abfa8695277c1851c0b8ca52428) allow children to be accessed via template (Will Morgan)
* 2013-01-23 [60c4d99](https://github.com/silverstripe/silverstripe-framework/commit/60c4d999d8a5892132ef3e29d47d8ced410c7061) PHPUnit latest not working with composer installed builds (Hamish Friedlander)
* 2012-12-13 [31255fc](https://github.com/silverstripe/silverstripe-framework/commit/31255fc8f0b03cd70ef3dc50c206c943b07c4c01) Set visibility on login form methods to public. (Justin Martin)
* 2012-12-11 [379b561](https://github.com/silverstripe/silverstripe-framework/commit/379b561cdbd599134196cd7801087f725d8fa993) RSSFeed now sets the Content-Type on the current HTTPResponse (Simon Welsh)

View File

@ -0,0 +1,33 @@
# 3.2.0-rc2
See [3.2.0](/changelogs/3.2.0) changelog for more information on what is new in 3.2
<!--- Changes below this line will be automatically regenerated -->
## Change Log
### Security
* 2015-09-07 [d8fd64c](https://github.com/silverstripe/silverstripe-framework/commit/d8fd64c3e25dbf500615ecbbe9580e234e1730d4) Fix XSS in install.php (Damian Mooyman) - See [ss-2015-016](http://www.silverstripe.org/software/download/security-releases/ss-2015-016)
* 2015-09-07 [7192932](https://github.com/silverstripe/silverstripe-framework/commit/7192932022510d830d1fc2373a9edb80fee24f48) Fix insecure returnURL in DatabaseAdmin (Damian Mooyman) - See [ss-2015-015](http://www.silverstripe.org/software/download/security-releases/ss-2015-015)
* 2015-09-07 [7367cf5](https://github.com/silverstripe/silverstripe-framework/commit/7367cf54c4069a8e296fafb511fb28e27a8efd7e) Prevent possible Privilege escalation (Damian Mooyman) - See [ss-2015-020](http://www.silverstripe.org/software/download/security-releases/ss-2015-020)
### Bugfixes
* 2015-10-06 [df805af](https://github.com/silverstripe/silverstripe-framework/commit/df805af67bda15888d17f49817903bf136561773) Imagick tests compare image dimensions rather than image hashes (Damian Mooyman)
* 2015-10-05 [ad42f80](https://github.com/silverstripe/silverstripe-framework/commit/ad42f802c4a621916a352c3a7c5d4f849b896c3e) Fix duplicate HolderID on TreeDropdownField (Damian Mooyman)
* 2015-10-05 [6c117cd](https://github.com/silverstripe/silverstripe-framework/commit/6c117cd62960670239c5a6f6b3832c819e21332a) fix imagick interface and add to travis (Damian Mooyman)
* 2015-09-30 [cb55a0a](https://github.com/silverstripe/silverstripe-framework/commit/cb55a0a621494873a04c697ecd326bb7a4d02173) GridFieldSortableHeader incorrectly reporting fields as sortable (Loz Calver)
* 2015-09-23 [8f0f647](https://github.com/silverstripe/silverstripe-framework/commit/8f0f6475daa6cb32a33089ef60f18d5f4f8735ed) Issues with field focus in edit forms (fixes #4621) (Loz Calver)
* 2015-09-23 [052aba1](https://github.com/silverstripe/silverstripe-cms/commit/052aba17acee51a276e42bcc0bd5a26b4cc2ae58) Incorrect field IDs breaking SiteTree settings toggles (fixes #1280) (Loz Calver)
* 2015-09-22 [0d89a13](https://github.com/silverstripe/silverstripe-framework/commit/0d89a13c2d02dc08d8ff14884b12f22b2f1cf4f2) GridFieldDetailForm failing to save many_many relations (Loz Calver)
* 2015-09-14 [81ca74b](https://github.com/silverstripe/silverstripe-framework/commit/81ca74bc30cb8f128c48672fd9807943c924145d) #103 (David Alexander)
* 2015-09-10 [6056e9c](https://github.com/silverstripe/silverstripe-framework/commit/6056e9cb1bc4f8073aef07b83f7417edbe7f2ac4) Editing existing file links in HtmlEditorField was broken (Loz Calver)
* 2015-09-09 [06cc185](https://github.com/silverstripe/silverstripe-framework/commit/06cc18526a1f63b8bb16809e23f2eb17ade7a85e) UploadField error when attempting to attach non-existent file IDs (Loz Calver)
* 2015-09-07 [45b22c7](https://github.com/silverstripe/silverstripe-framework/commit/45b22c788eeb5d7501844ceb19395cc4e15e61b6) Fix missing framework/admin/tests (Damian Mooyman)
* 2015-09-07 [96d20bc](https://github.com/silverstripe/silverstripe-framework/commit/96d20bc1809c731e3e78b7c5248282c8771f3097) Fix missing framework/admin/tests (Damian Mooyman)
* 2015-08-31 [e86b45b](https://github.com/silverstripe/silverstripe-framework/commit/e86b45bf5db663b03e006a132e04afba37ee4bf3) Remove html5 number field due to insufficient localisation support (Damian Mooyman)
* 2015-08-27 [899eb0b](https://github.com/silverstripe/silverstripe-framework/commit/899eb0b235859c843890c790e99c03f4fd4b825c) Use complete fieldlist for extracting data (Daniel Hensby)
* 2015-08-26 [2d4b743](https://github.com/silverstripe/silverstripe-framework/commit/2d4b743090935e7c10bd95e00398df7bfb5763af) Members can access their own profiles in CMS (Daniel Hensby)
* 2015-08-26 [0943b3b](https://github.com/silverstripe/silverstripe-framework/commit/0943b3b1a06e6c9130500532fd979c720b65c761) Recursion errors when sorting objects with circular dependencies (fixes #4464) (Loz Calver)
* 2015-08-20 [fc212e0](https://github.com/silverstripe/silverstripe-framework/commit/fc212e030c474d966ffb1821423ddcb3ae361b72) Fix illegalExtensions breaking tests. (Damian Mooyman)

View File

@ -1,7 +1,7 @@
title: Contributing Code
summary: Fix bugs and add new features to help make SilverStripe better.
# Contributing Code - Submiting Bugfixes and Enhancements
# Contributing Code - Submitting Bugfixes and Enhancements
SilverStripe will never be finished, and we need your help to keep making it better. If you're a developer a great way to get involved is to contribute patches to our modules and core codebase, fixing bugs or adding features.

View File

@ -6,6 +6,7 @@ The core committers team is reviewed approximately annually, new members are add
* [Daniel Hensby](https://github.com/dhensby)
* [Hamish Friedlander](https://github.com/hafriedlander)
* [Ingo Schommer](https://github.com/chillu)
* [Jono Menz](https://github.com/jonom)
* [Loz Calver](https://github.com/kinglozzer)
* [Sam Minnée](https://github.com/sminnee)
* [Sean Harvey](https://github.com/halkyon/)

View File

@ -222,6 +222,9 @@ class CompositeField extends FormField {
return $ret;
}
/**
* @uses FieldList->insertAfter()
*/
public function insertAfter($insertAfter, $field) {
$ret = $this->children->insertAfter($insertAfter, $field);
$this->sequentialSet = null;

View File

@ -348,7 +348,9 @@ class DropdownField extends FormField {
*/
public function castedCopy($classOrCopy) {
$field = parent::castedCopy($classOrCopy);
$field->setHasEmptyDefault($this->getHasEmptyDefault());
if($field->hasMethod('setHasEmptyDefault')) {
$field->setHasEmptyDefault($this->getHasEmptyDefault());
}
return $field;
}
}

View File

@ -312,7 +312,7 @@ class FieldList extends ArrayList {
* Returns a named field.
* You can use dot syntax to get fields from child composite fields
*
* @todo Implement similiarly to dataFieldByName() to support nested sets - or merge with dataFields()
* @todo Implement similarly to dataFieldByName() to support nested sets - or merge with dataFields()
*/
public function fieldByName($name) {
$name = $this->rewriteTabPath($name);
@ -356,6 +356,7 @@ class FieldList extends ArrayList {
*
* @param string $name Name of the field to insert before
* @param FormField $item The form field to insert
* @return FormField|false
*/
public function insertBefore($name, $item) {
// Backwards compatibility for order of arguments
@ -385,6 +386,7 @@ class FieldList extends ArrayList {
*
* @param string $name Name of the field to insert after
* @param FormField $item The form field to insert
* @return FormField|false
*/
public function insertAfter($name, $item) {
// Backwards compatibility for order of arguments

View File

@ -315,7 +315,7 @@ class HtmlEditorField_Toolbar extends RequestHandler {
$description = new LiteralField('URLDescription', '<div class="url-description">' . $URLDescription . '</div>'),
$remoteURL = new TextField('RemoteURL', 'http://'),
new LiteralField('addURLImage',
'<button class="action ui-action-constructive ui-button field font-icon-plus add-url">' .
'<button type="button" class="action ui-action-constructive ui-button field font-icon-plus add-url">' .
_t('HtmlEditorField.BUTTONADDURL', 'Add url').'</button>')
);

View File

@ -20,7 +20,7 @@ class InlineFormAction extends FormField {
*/
public function __construct($action, $title = "", $extraClass = '') {
$this->extraClass = ' '.$extraClass;
parent::__construct($action, $title, null, null);
parent::__construct($action, $title);
}
public function performReadonlyTransformation() {
@ -39,7 +39,8 @@ class InlineFormAction extends FormField {
return DBField::create_field(
'HTMLText',
FormField::create('input', array(
FormField::create_tag('input', array(
'type' => 'submit',
'name' => sprintf('action_%s', $this->getName()),
'value' => $this->title,
'id' => $this->ID(),

View File

@ -114,7 +114,10 @@ class TabSet extends CompositeField {
}
/**
* Returns the named tab
* Returns a named field.
*
* @param string $name Name of the field you want to find. Allows for dot notation.
* @return FormField|null
*/
public function fieldByName($name) {
if(strpos($name,'.') !== false) list($name, $remainder) = explode('.',$name,2);
@ -135,6 +138,8 @@ class TabSet extends CompositeField {
}
}
}
return null;
}
/**
@ -148,22 +153,24 @@ class TabSet extends CompositeField {
/**
* Inserts a field before a particular field in a FieldList.
*
* @param FormField $item The form field to insert
* @param string $name Name of the field to insert before
* @param string $insertBefore Name of the field to insert before
* @param FormField $field The form field to insert
* @return FormField|null
*/
public function insertBefore($insertBefore, $field) {
parent::insertBefore($insertBefore, $field);
if($field instanceof Tab) $field->setTabSet($this);
$this->sequentialSet = null;
return parent::insertBefore($insertBefore, $field);
}
/**
* Inserts a field after a particular field in a FieldList.
*
* @param string $insertAfter Name of the field to insert after
* @param FormField $field The form field to insert
* @return FormField|null
*/
public function insertAfter($insertAfter, $field) {
parent::insertAfter($insertAfter, $field);
if($field instanceof Tab) $field->setTabSet($this);
$this->sequentialSet = null;
}
public function removeByName( $tabName, $dataFieldOnly = false ) {
parent::removeByName( $tabName, $dataFieldOnly );
return parent::insertAfter($insertAfter, $field);
}
}

View File

@ -149,7 +149,7 @@ class GridField extends FormField {
return $this->modelClassName;
}
if($this->list && method_exists($this->list, 'dataClass')) {
if($this->list && $this->list->hasMethod('dataClass')) {
$class = $this->list->dataClass();
if($class) {

View File

@ -114,8 +114,8 @@ class GridFieldSortableHeader implements GridField_HTMLProvider, GridField_DataM
} elseif(method_exists($tmpItem, 'hasMethod') && $tmpItem->hasMethod($methodName)) {
// The part is a relation name, so get the object/list from it
$tmpItem = $tmpItem->$methodName();
} elseif($tmpItem instanceof DataObject && $tmpItem->hasField($methodName)) {
// Else, if we've found a field at the end of the chain, we can sort on it.
} elseif($tmpItem instanceof DataObject && $tmpItem->hasDatabaseField($methodName)) {
// Else, if we've found a database field at the end of the chain, we can sort on it.
// If a method is applied further to this field (E.g. 'Cost.Currency') then don't try to sort.
$allowSort = $idx === sizeof($parts) - 1;
break;
@ -150,7 +150,7 @@ class GridFieldSortableHeader implements GridField_HTMLProvider, GridField_DataM
&& $gridField->getConfig()->getComponentByType('GridFieldFilterHeader')){
$field = new LiteralField($fieldName,
'<button name="showFilter" class="ss-gridfield-button-filter trigger"></button>');
'<button type="button" name="showFilter" class="ss-gridfield-button-filter trigger"></button>');
} else {
$field = new LiteralField($fieldName, '<span class="non-sortable">' . $title . '</span>');
}

View File

@ -55,7 +55,7 @@
content = '<span class="non-sortable"></span>';
self.addClass('show-filter').find('.filter-header').show();
} else {
content = '<button name="showFilter" class="ss-gridfield-button-filter trigger"></button>';
content = '<button type="button" name="showFilter" class="ss-gridfield-button-filter trigger"></button>';
self.removeClass('show-filter').find('.filter-header').hide();
}

View File

@ -845,9 +845,11 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
} else if(el.is(':radio')) {
el.val([selected]).change();
} else if(fieldName == 'file') {
// Can't rely on fieldName, ad UploadFields have different naming convention
el = $('#' + fieldName);
// UploadField inputs have a slightly different naming convention
el = this.find(':input[name="' + fieldName + '[Uploads][]"]');
// We need the UploadField "field", not just the input
el = el.parents('.ss-uploadfield');
// We have to wait for the UploadField to initialise
(function attach(el, selected) {
if( ! el.getConfig()) {

View File

@ -27,7 +27,7 @@ window.tmpl.cache['ss-uploadfield-downloadtemplate'] = tmpl(
'</label>' +
'{% if (file.error) { %}' +
'<div class="ss-uploadfield-item-actions">' +
'<div class="ss-uploadfield-item-cancel ss-uploadfield-item-cancelfailed delete"><button class="icon icon-16" data-icon="delete" title="' + ss.i18n._t('UploadField.CANCELREMOVE', 'Cancel/Remove') + '">' + ss.i18n._t('UploadField.CANCELREMOVE', 'Cancel/Remove') + '</button></div>' +
'<div class="ss-uploadfield-item-cancel ss-uploadfield-item-cancelfailed delete"><button type="button" class="icon icon-16" data-icon="delete" title="' + ss.i18n._t('UploadField.CANCELREMOVE', 'Cancel/Remove') + '">' + ss.i18n._t('UploadField.CANCELREMOVE', 'Cancel/Remove') + '</button></div>' +
'</div>' +
'{% } else { %}' +
'<div class="ss-uploadfield-item-actions">{% print(file.buttons, true); %}</div>' +

View File

@ -17,14 +17,14 @@ window.tmpl.cache['ss-uploadfield-uploadtemplate'] = tmpl(
'{% if (!file.error) { %}' +
'<div class="ss-uploadfield-item-progress"><div class="ss-uploadfield-item-progressbar"><div class="ss-uploadfield-item-progressbarvalue"></div></div></div>' +
'{% if (!o.options.autoUpload) { %}' +
'<div class="ss-uploadfield-item-start start"><button class="icon icon-16" data-icon="navigation">' + ss.i18n._t('UploadField.START', 'Start') + '</button></div>' +
'<div class="ss-uploadfield-item-start start"><button type="button" class="icon icon-16" data-icon="navigation">' + ss.i18n._t('UploadField.START', 'Start') + '</button></div>' +
'{% } %}' +
'{% } %}' +
'<div class="ss-uploadfield-item-cancel cancel">' +
'<button class="icon icon-16" data-icon="minus-circle" title="' + ss.i18n._t('UploadField.CANCELREMOVE', 'Cancel/Remove') + '">' + ss.i18n._t('UploadField.CANCELREMOVE', 'Cancel/Remove') + '</button>' +
'<button type="button" class="icon icon-16" data-icon="minus-circle" title="' + ss.i18n._t('UploadField.CANCELREMOVE', 'Cancel/Remove') + '">' + ss.i18n._t('UploadField.CANCELREMOVE', 'Cancel/Remove') + '</button>' +
'</div>' +
'<div class="ss-uploadfield-item-overwrite hide ">' +
'<button data-icon="drive-upload" class="ss-uploadfield-item-overwrite-warning" title="' + ss.i18n._t('UploadField.OVERWRITE', 'Overwrite') + '">' + ss.i18n._t('UploadField.OVERWRITE', 'Overwrite') + '</button>' +
'<button type="button" data-icon="drive-upload" class="ss-uploadfield-item-overwrite-warning" title="' + ss.i18n._t('UploadField.OVERWRITE', 'Overwrite') + '">' + ss.i18n._t('UploadField.OVERWRITE', 'Overwrite') + '</button>' +
'</div>' +
'</div>' +
'</div>' +

View File

@ -260,6 +260,7 @@ cs:
many_many_Members: Členové
GroupImportForm:
Help1: '<p>Import jedné nebo více skupin v <em>CSV</em> formátu (čárkou-oddělené hodnoty). <small><a href="#" class="toggle-advanced">Zobrazit rozšířené použití</a></small></p>'
Help2: '<div class="advanced"> <h4>Pokročilé použití</h4> <ul> <li>Povolené sloupce: <em>%s</em></li> <li>Existující skupiny jsou porovnány jejich unikátním <em>Code</em> hodnotou, a aktualizovány s novými hodnotami z importovaného souboru</li> <li>Hierarchie skupin může být tvořena použitím <em>ParentCode</em> sloupce.<li> <li>Kódy oprávnění mohou být přiřazeny <em>PermissionCode</em> sloupcem. Existující oprávnění nejsou smazána.</li> </ul> </div>'
ResultCreated: 'Vytvořeno {count} skupin'
ResultDeleted: 'Smazáno %d skupin'
ResultUpdated: 'Aktualizováno %d skupin'
@ -291,6 +292,8 @@ cs:
FROMWEB: 'Z webu'
FindInFolder: 'Hledat ve složce'
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
IMAGEHEIGHTPX: Výška
IMAGETITLE: 'Titul text (tooltip) - další informace o obrázku'
@ -325,7 +328,11 @@ cs:
DELETED: Smazáno.
DropdownBatchActionsDefault: Akcie
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.'
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.'
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
REORGANISATIONSUCCESSFUL: 'Strom webu reorganizován úspěšně.'
SAVEDUP: Uloženo.
@ -413,6 +420,7 @@ cs:
Toggle: 'Ukázat nápovědu formátování'
MemberImportForm:
Help1: '<p>Import členů v <em>CSV formátu</em> (čárkou-oddělené hodnoty). <small><a href="#" class="toggle-advanced">Zobrazit rozšířené použití</a></small></p>'
Help2: '<div class="advanced"> <h4>Pokročilé použití</h4> <ul> <li>Povolené sloupce: <em>%s</em></li> <li>Existující uživatelé jsou porovnáni jejich unikátní vlastností <em>Code</em>, a aktualizováni s novými hodnotami z importovaného souboru.</li> <li>Skupiny mohou být přiřazeny sloupcem <em>Groups</em>. Skupiny jsou identifikovány svojí vlastností <em>Code</em>, více skupin může být odděleno čárkou. Existující členství ve skupině nejsou smazána.</li> </ul> </div>'
ResultCreated: 'Vytvořeno {count} členů'
ResultDeleted: 'Smazáno %d členů'
ResultNone: 'Žádné změny'

View File

@ -292,8 +292,8 @@ en:
FROMWEB: 'From the web'
FindInFolder: 'Find in Folder'
IMAGEALT: 'Alternative text (alt)'
IMAGEALTTEXT: 'Alternative text (alt) - shown if image cannot be displayed'
IMAGEALTTEXTDESC: 'Shown to screen readers or if image can not be displayed'
IMAGEALTTEXT: 'Alternative text (alt) - shown if image can''t be displayed'
IMAGEALTTEXTDESC: 'Shown to screen readers or if image can''t be displayed'
IMAGEDIMENSIONS: Dimensions
IMAGEHEIGHTPX: Height
IMAGETITLE: 'Title text (tooltip) - for additional information about the image'
@ -328,11 +328,11 @@ en:
DELETED: Deleted.
DropdownBatchActionsDefault: Actions
HELP: Help
PAGETYPE: 'Page type: '
PAGETYPE: 'Page type'
PERMAGAIN: 'You have been logged out of the CMS. If you would like to log in again, enter a username and password below.'
PERMALREADY: 'I''m sorry, but you can''t access that part of the CMS. If you want to log in as someone else, do so below.'
PERMDEFAULT: 'You must be logged in to access the administration area; please enter your credentials below.'
PLEASESAVE: 'Please Save Page: This page could not be upated because it hasn''t been saved yet.'
PLEASESAVE: 'Please Save Page: This page could not be updated because it hasn''t been saved yet.'
PreviewButton: Preview
REORGANISATIONSUCCESSFUL: 'Reorganised the site tree successfully.'
SAVEDUP: Saved.

View File

@ -260,6 +260,7 @@ eo:
many_many_Members: Membroj
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>'
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'
ResultDeleted: 'Forigis %d grupojn'
ResultUpdated: 'Aktualigis %d grupojn'
@ -326,15 +327,20 @@ eo:
DropdownBatchActionsDefault: Agoj
HELP: Helpo
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
REORGANISATIONSUCCESSFUL: 'Sukcese reorganizis la retejan arbon.'
SAVEDUP: Konservita.
ShowAsList: 'vidigi kiel liston'
TooManyPages: 'Tro da paĝoj'
ValidationError: 'Validiga eraro'
VersionUnknown: nekonata
LeftAndMain_Menu_ss:
Hello: Saluton
LOGOUT: 'Elsaluti'
ListboxField:
SOURCE_VALIDATION: 'Bonvolu elekti valoron el la listo donita. %s ne estas valida agordo'
LoginAttempt:
Email: 'Retadreso'
IP: 'IP-Adreso'
@ -410,6 +416,7 @@ eo:
Toggle: 'Vidigi aranĝa helpo'
MemberImportForm:
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'
ResultDeleted: 'Forigis %d membrojn'
ResultNone: 'Neniu ŝanĝo'
@ -539,6 +546,8 @@ eo:
Print: Presi
TableListField_PageControls_ss:
OF: de
TextField:
VALIDATEMAXLENGTH: 'La longo de la valoro por {name} devas ne superi {maxLength} signojn'
TimeField:
VALIDATEFORMAT: 'Bonvole enigu validan horan formaton ({format})'
ToggleField:

View File

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

View File

@ -260,6 +260,7 @@ lt:
many_many_Members: Vartotojai
GroupImportForm:
Help1: '<p>Importuoti vieną ar kelias grupes <em>CSV</em> formatu (kableliu atskirtos reikšmės). <small><a href="#" class="toggle-advanced">Rodyti detalesnį aprašymą</a></small></p>'
Help2: '<div class="advanced"><h4>Detalesnis aprašymas</h4><ul><li>Galimi stulpeliai: <em>%s</em>.</li><li>Esamos grupės yra surandamos su jų unikalia <em>Code</em> reikšme ir atnaujinamos duomenimis iš importuojamos bylos.</li><li>Grupių hierarchija gali būti sukurta naudojant <em>ParentCode</em> stulpelį.</li><li>Leidimų kodai gali būti priskirti naudojant <em>PermissionCode</em> stulpelį. Esami leidimai nebus pakeisti.</li></ul></div>'
ResultCreated: 'Sukurta {count} grupių'
ResultDeleted: 'Ištrinta %d grupių'
ResultUpdated: 'Atnaujinta %d grupių'
@ -291,6 +292,8 @@ lt:
FROMWEB: 'Iš interneto'
FindInFolder: 'Rasti kataloge'
IMAGEALT: 'Alternatyvus tekstas (alt)'
IMAGEALTTEXT: 'Alternatyvus tekstas (alt) - rodomas, jeigu nepavyko parodyti paveikslėlio'
IMAGEALTTEXTDESC: 'Rodomas, jeigu nepavyko parodyti paveikslėlio'
IMAGEDIMENSIONS: Matmenys
IMAGEHEIGHTPX: Aukštis
IMAGETITLE: 'Pavadinimo tekstas (tooltip) - papildomai informacijai apie paveikslėlį'
@ -325,9 +328,11 @@ lt:
DELETED: Ištrinta.
DropdownBatchActionsDefault: Veiksmai
HELP: Pagalba
PAGETYPE: 'Puslapio tipas:'
PERMAGAIN: 'Jūs atsijungėte. Norėdami vėl prisijungti, įveskite savo duomenis į žemiau esančius laukelius.'
PERMALREADY: 'Deja, bet Jūs negalite patekti į šią TVS dalį. Jeigu norite prisijungti kitu vartotoju, tai atlikite žemiau.'
PERMDEFAULT: 'Jūs turite būti prisijungę, norėdami pasiekti administravimo zoną; prašome suvesti prisijungimo duomenis į žemiau esančius laukelius.'
PLEASESAVE: 'Prašome išsaugoti puslapį: Šis puslapis negali būti atnaujintas, nes jis dar nėra išsaugotas.'
PreviewButton: Peržiūra
REORGANISATIONSUCCESSFUL: 'Puslapių medis pertvarkytas sėkmingai.'
SAVEDUP: Išsaugota.
@ -415,6 +420,7 @@ lt:
Toggle: 'Rodyti formatavimo aprašymą'
MemberImportForm:
Help1: '<p>Importuoti vartotojus <em>CSV</em> formatu (kableliu atskirtos reikšmės). <small><a href="#" class="toggle-advanced">Rodyti detalesnį aprašymą</a></small></p>'
Help2: '<div class="advanced"><h4>Detalesnis aprašymas</h4><ul><li>Galimi stulpeliai: <em>%s</em>.</li><li>Esami vartotojai yra surandami su jų unikalia <em>Code</em> reikšme ir atnaujinami duomenimis iš importuojamos bylos.</li><li>Grupės gali būti priskirtos naudojant <em>Groups</em> column. stulpelį. Grupės yra atpažįstamos pagal <em>Code</em> stulpelį, kelios grupės nurodomos per kablelį. Jau priskirtos vartotojui grupės nebus pakeistos.</li></ul></div>'
ResultCreated: 'Sukurta {count} vartotojų'
ResultDeleted: 'Ištrinta %d vartotojų'
ResultNone: 'Nėra jokių pakeitimų'

View File

@ -260,6 +260,7 @@ sk:
many_many_Members: Členovia
GroupImportForm:
Help1: 'Importovať jednu alebo viac skupín v CSV formáte (čiarkov oddelené hodnoty). Zobraziť pokročilé použitie'
Help2: '<div class="advanced"> <h4>Pokročilé použitie</h4> <ul> <li>Povolené stĺpce: <em>%s</em></li> <li>Existujúce skupiny sú porovnávané s ich unikátnou <em>Code</em>; hodnotou, a aktualizované s novými hodnotami z importovaného súbory&lt;/li> <li>Skupina hierarchií môže byť tvorená použitím <em>ParentCode</em>; stĺpce.&lt;/li> <li>Kódy oprávnení môžu byť priradené <em>PermissionCode</em>; stĺpcom. Existujúce oprávnenia nie sú smazáné.</li> </ul> </div>'
ResultCreated: 'Vytvorených {count} skupín'
ResultDeleted: 'Zmazané %d skupiny'
ResultUpdated: 'Aktualizované %d skupiny'
@ -291,6 +292,8 @@ sk:
FROMWEB: 'Z webu'
FindInFolder: 'Vyhľadať v priečinku'
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
IMAGEHEIGHTPX: Výška
IMAGETITLE: 'Text titulky (tooltip) - pre doplňujúce informácie o obrázku'
@ -325,7 +328,11 @@ sk:
DELETED: Zmazané.
DropdownBatchActionsDefault: Akcie
HELP: Pomoc
PAGETYPE: 'Typ stránky:'
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'
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
REORGANISATIONSUCCESSFUL: 'Strom webu bol reorganizovaný úspešne.'
SAVEDUP: Uložené.
@ -413,6 +420,7 @@ sk:
Toggle: 'Ukázať nápovedu formátovania'
MemberImportForm:
Help1: 'Importovať členov v <em>CSV formáte</em> (čiarkov oddelené hodnoty). Zobraziť pokročile použitie'
Help2: '<div class="advanced"> <h4>Pokročilé použitie</h4> <ul> <li>Povolené stĺpce: <em>%s</em></li> <li>Existujúci užívatelia sú porovnávaní ich unikátnou vlastnosťou <em>Code</em>, a aktualizovaní s novými hodnotami z importovaného súboru.</li> <li>Skupiny môžu byťt priradené stĺpcom <em>Groups</em>. Skupiny sú identifikované ich vlastnosťou <em>Code</em>, viacero skupín môže byť oddelené čiarkou. Existujúce členstvá skupiny nie sú smazané.</li> </ul> </div>'
ResultCreated: 'Vytvorených {count} členov'
ResultDeleted: 'Zmazaných %d členov'
ResultNone: 'Žiadne zmeny'

View File

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

View File

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

View File

@ -1763,10 +1763,8 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
return $this->unsavedRelations[$componentName];
}
$result = ManyManyList::create(
$componentClass, $table, $componentField, $parentField,
$this->manyManyExtraFieldsForComponent($componentName)
);
$extraFields = $this->manyManyExtraFieldsForComponent($componentName) ?: array();
$result = ManyManyList::create($componentClass, $table, $componentField, $parentField, $extraFields);
if($this->model) $result->setDataModel($this->model);

View File

@ -125,9 +125,16 @@ class MySQLSchemaManager extends DBSchemaManager {
}
public function checkAndRepairTable($tableName) {
// Flag to ensure we only send the warning about PDO + native mode once
static $pdo_warning_sent = false;
// If running PDO and not in emulated mode, check table will fail
if($this->database->getConnector() instanceof PDOConnector && !PDOConnector::is_emulate_prepare()) {
$this->alterationMessage('CHECK TABLE command disabled for PDO in native mode', 'notice');
if (!$pdo_warning_sent) {
$this->alterationMessage('CHECK TABLE command disabled for PDO in native mode', 'notice');
$pdo_warning_sent = true;
}
return true;
}

View File

@ -163,7 +163,7 @@ class Enum extends StringField {
*/
public function setEnum($enum) {
if(!is_array($enum)) {
$enum = preg_split("/ *, */", trim($enum));
$enum = preg_split("/\s*,\s*/", trim($enum, ", \t\n\r\0\x0B"));
}
$this->enum = $enum;
return $this;

View File

@ -58,12 +58,12 @@ class FulltextFilter extends SearchFilter {
if(is_array($indexes) && array_key_exists($this->getName(), $indexes)) {
$index = $indexes[$this->getName()];
if(is_array($index) && array_key_exists("value", $index)) {
return $index['value'];
return $this->prepareColumns($index['value']);
} else {
// Parse a fulltext string (eg. fulltext ("ColumnA", "ColumnB")) to figure out which columns
// we need to search.
if(preg_match('/^fulltext\s+\((.+)\)$/i', $index, $matches)) {
return $matches[1];
return $this->prepareColumns($matches[1]);
} else {
throw new Exception("Invalid fulltext index format for '" . $this->getName()
. "' on '" . $this->model . "'");
@ -74,4 +74,19 @@ class FulltextFilter extends SearchFilter {
return parent::getDbName();
}
/**
* Adds table identifier to the every column.
* Columns must have table identifier to prevent duplicate column name error.
*
* @return string
*/
protected function prepareColumns($columns) {
$cols = preg_split('/"?\s*,\s*"?/', trim($columns, '(") '));
$class = ClassInfo::table_for_object_field($this->model, current($cols));
$cols = array_map(function($col) use ($class) {
return sprintf('"%s"."%s"', $class, $col);
}, $cols);
return implode(',', $cols);
}
}

View File

@ -199,7 +199,7 @@ class Permission extends DataObject implements TemplateGlobalProvider {
// Code filters
$codeParams = is_array($code) ? $code : array($code);
$codeClause = DB::placeholders($codes);
$codeClause = DB::placeholders($codeParams);
$adminParams = (self::$admin_implies_all) ? array('ADMIN') : array();
$adminClause = (self::$admin_implies_all) ? ", ?" : '';

View File

@ -21,7 +21,7 @@
<div class="ss-uploadfield-editandorganize">
<div class="ss-uploadfield-item-actions edit-all">
<button class="ss-uploadfield-item-edit-all ss-ui-button ui-corner-all" title="<%t AssetUploadField.EDITINFO 'Edit files' %>" style="display:none;">
<button type="button" class="ss-uploadfield-item-edit-all ss-ui-button ui-corner-all" title="<%t AssetUploadField.EDITINFO 'Edit files' %>" style="display:none;">
<%t AssetUploadField.EDITALL 'Edit all' %>
<span class="toggle-details-icon"></span>
</button>
@ -39,4 +39,4 @@
</div>
</div>
</div>
</div>

View File

@ -23,12 +23,12 @@
<div class="clear"><!-- --></div>
</label>
<div class="ss-uploadfield-item-actions">
<button data-icon="deleteLight" class="ss-uploadfield-item-cancel ss-uploadfield-item-remove" title="<%t UploadField.REMOVE 'Remove' %>">
<button type="button" data-icon="deleteLight" class="ss-uploadfield-item-cancel ss-uploadfield-item-remove" title="<%t UploadField.REMOVE 'Remove' %>">
<%t UploadField.REMOVE 'Remove' %>
</button>
<div class="ss-uploadfield-item-edit edit">
<button class="ss-uploadfield-item-edit ss-ui-button ui-corner-all" title="<%t UploadField.EDITINFO 'Edit this file' %>" data-icon="pencil">
<button type="button" class="ss-uploadfield-item-edit ss-ui-button ui-corner-all" title="<%t UploadField.EDITINFO 'Edit this file' %>" data-icon="pencil">
<%t UploadField.EDIT 'Edit' %>
<span class="toggle-details">
<span class="toggle-details-icon"></span>

View File

@ -1,17 +1,17 @@
<% if $canEdit %>
<button class="ss-uploadfield-item-edit ss-ui-button ui-corner-all" title="<%t UploadField.EDITINFO 'Edit this file' %>" data-icon="pencil">
<button type="button" class="ss-uploadfield-item-edit ss-ui-button ui-corner-all" title="<%t UploadField.EDITINFO 'Edit this file' %>" data-icon="pencil">
<%t UploadField.EDIT 'Edit' %>
<span class="toggle-details">
<span class="toggle-details-icon"></span>
</span>
</button>
<% end_if %>
<button class="ss-uploadfield-item-remove ss-ui-button ui-corner-all" title="<%t UploadField.REMOVEINFO 'Remove this file from here, but do not delete it from the file store' %>" data-icon="plug-disconnect-prohibition">
<button type="button" class="ss-uploadfield-item-remove ss-ui-button ui-corner-all" title="<%t UploadField.REMOVEINFO 'Remove this file from here, but do not delete it from the file store' %>" data-icon="plug-disconnect-prohibition">
<%t UploadField.REMOVE 'Remove' %></button>
<% if $canDelete %>
<button data-href="$UploadFieldDeleteLink" class="ss-uploadfield-item-delete ss-ui-button ui-corner-all" title="<%t UploadField.DELETEINFO 'Permanently delete this file from the file store' %>" data-icon="minus-circle"><%t UploadField.DELETE 'Delete from files' %></button>
<button type="button" data-href="$UploadFieldDeleteLink" class="ss-uploadfield-item-delete ss-ui-button ui-corner-all" title="<%t UploadField.DELETEINFO 'Permanently delete this file from the file store' %>" data-icon="minus-circle"><%t UploadField.DELETE 'Delete from files' %></button>
<% end_if %>
<% if $UploadField.canAttachExisting %>
<button class="ss-uploadfield-item-choose-another ss-uploadfield-fromfiles ss-ui-button ui-corner-all" title="<%t UploadField.CHOOSEANOTHERINFO 'Replace this file with another one from the file store' %>" data-icon="network-cloud">
<button type="button" class="ss-uploadfield-item-choose-another ss-uploadfield-fromfiles ss-ui-button ui-corner-all" title="<%t UploadField.CHOOSEANOTHERINFO 'Replace this file with another one from the file store' %>" data-icon="network-cloud">
<%t UploadField.CHOOSEANOTHERFILE 'Choose another file' %></button>
<% end_if %>

View File

@ -57,11 +57,11 @@
<% end_if %>
<% if $canAttachExisting %>
<button class="ss-uploadfield-fromfiles ss-ui-button ui-corner-all" title="<%t UploadField.FROMCOMPUTERINFO 'Select from files' %>" data-icon="network-cloud"><%t UploadField.FROMFILES 'From files' %></button>
<button type="button" class="ss-uploadfield-fromfiles ss-ui-button ui-corner-all" title="<%t UploadField.FROMCOMPUTERINFO 'Select from files' %>" data-icon="network-cloud"><%t UploadField.FROMFILES 'From files' %></button>
<% end_if %>
<% if $canUpload %>
<% if not $autoUpload %>
<button class="ss-uploadfield-startall ss-ui-button ui-corner-all" data-icon="navigation"><%t UploadField.STARTALL 'Start all' %></button>
<button type="button" class="ss-uploadfield-startall ss-ui-button ui-corner-all" data-icon="navigation"><%t UploadField.STARTALL 'Start all' %></button>
<% end_if %>
<% end_if %>
<div class="clear"><!-- --></div>

View File

@ -1,5 +1,4 @@
<div id="$HolderID"
class="TreeDropdownField <% if $extraClass %> $extraClass<% end_if %><% if $ShowSearch %> searchable<% end_if %>"
<div class="TreeDropdownField <% if $extraClass %> $extraClass<% end_if %><% if $ShowSearch %> searchable<% end_if %>"
data-url-tree="$Link('tree')"
data-title="$Title.ATT"
data-empty-title="$EmptyTitle.ATT"

View File

@ -13,18 +13,37 @@ class HTTPTest extends FunctionalTest {
$this->assertEmpty($response->getHeader('Cache-Control'));
HTTP::set_cache_age(30);
HTTP::add_cache_headers($response);
HTTP::add_cache_headers($response);
$this->assertNotEmpty($response->getHeader('Cache-Control'));
// Ensure max-age is zero for development.
Config::inst()->update('Director', 'environment_type', 'dev');
$response = new SS_HTTPResponse($body, 200);
HTTP::add_cache_headers($response);
$this->assertContains('max-age=0', $response->getHeader('Cache-Control'));
// Ensure max-age setting is respected in production.
Config::inst()->update('Director', 'environment_type', 'live');
$response = new SS_HTTPResponse($body, 200);
HTTP::add_cache_headers($response);
$this->assertContains('max-age=30', explode(', ', $response->getHeader('Cache-Control')));
$this->assertNotContains('max-age=0', $response->getHeader('Cache-Control'));
// Still "live": Ensure header's aren't overridden if already set (using purposefully different values).
$headers = array(
'Vary' => '*',
'Pragma' => 'no-cache',
'Cache-Control' => 'max-age=0, no-cache, no-store',
);
$response = new SS_HTTPResponse($body, 200);
foreach($headers as $name => $value) {
$response->addHeader($name, $value);
}
HTTP::add_cache_headers($response);
foreach($headers as $name => $value) {
$this->assertEquals($value, $response->getHeader($name));
}
}
/**

View File

@ -48,6 +48,29 @@ class ArrayLibTest extends SapphireTest {
);
}
public function testArrayMapRecursive() {
$array = array(
'a ',
array(' b', 'c'),
);
$strtoupper = array(
'A ',
array(' B', 'C'),
);
$trim = array(
'a',
array('b', 'c'),
);
$this->assertEquals(
$strtoupper,
ArrayLib::array_map_recursive('strtoupper', $array)
);
$this->assertEquals(
$trim,
ArrayLib::array_map_recursive('trim', $array)
);
}
public function testArrayMergeRecursive() {
$first = array(
'first' => 'a',

View File

@ -197,6 +197,16 @@ class ClassInfoTest extends SapphireTest {
$this->assertNull(
ClassInfo::table_for_object_field(null, null)
);
// Test fixed fields
$this->assertEquals(
'ClassInfoTest_BaseDataClass',
ClassInfo::table_for_object_field('ClassInfoTest_HasFields', 'ID')
);
$this->assertEquals(
'ClassInfoTest_BaseDataClass',
ClassInfo::table_for_object_field('ClassInfoTest_NoFields', 'Created')
);
}
}

View File

@ -16,4 +16,26 @@ class EnumFieldTest extends SapphireTest {
$this->assertEquals(true, $searchField->getHasEmptyDefault());
$this->assertEquals($anyText, $searchField->getEmptyString());
}
public function testEnumParsing() {
$enum = new Enum('testField', "
Item1,
Item2,
Item 3,
Item-4,
item 5
still 5,
trailing comma,
");
$this->assertEquals(ArrayLib::valuekey(array(
'Item1',
'Item2',
'Item 3',
'Item-4',
'item 5
still 5',
'trailing comma'
)), $enum->enumValues());
}
}

View File

@ -19,6 +19,9 @@ class FormTest extends FunctionalTest {
Config::inst()->update('Director', 'rules', array(
'FormTest_Controller' => 'FormTest_Controller'
));
// Suppress themes
Config::inst()->remove('SSViewer', 'theme');
}
public function testLoadDataFromRequest() {

View File

@ -0,0 +1,18 @@
<?php
/**
* Tests {@see InlineFormAction}
*/
class InlineFormActionTest extends SapphireTest {
public function testField() {
$action = new InlineFormAction('dothing', 'My Title', 'ss-action');
$html = (string)$action->Field();
$this->assertContains('<input', $html);
$this->assertContains('type="submit"', $html);
$this->assertContains('name="action_dothing"', $html);
$this->assertContains('value="My Title"', $html);
$this->assertContains('id="dothing"', $html);
$this->assertContains('class="action ss-action"', $html);
}
}

View File

@ -153,6 +153,38 @@ class GridFieldDetailFormTest extends FunctionalTest {
$this->assertDOSContains(array(array('Surname' => 'Baggins')), $group->People());
}
public function testEditFormWithManyMany() {
$this->logInWithPermission('ADMIN');
// Edit the first person
$response = $this->get('GridFieldDetailFormTest_CategoryController');
// Find the link to add a new favourite group
$parser = new CSSContentParser($response->getBody());
$addLink = $parser->getBySelector('#Form_Form_testgroupsfield .new-link');
$addLink = (string) $addLink[0]['href'];
// Add a new favourite group
$response = $this->get($addLink);
$parser = new CSSContentParser($response->getBody());
$addform = $parser->getBySelector('#Form_ItemEditForm');
$addformurl = (string) $addform[0]['action'];
$response = $this->post(
$addformurl,
array(
'Name' => 'My Favourite Group',
'ajax' => 1,
'action_doSave' => 1
)
);
$this->assertFalse($response->isError());
$person = GridFieldDetailFormTest_Person::get()->sort('FirstName')->First();
$favouriteGroup = $person->FavouriteGroups()->first();
$this->assertInstanceOf('GridFieldDetailFormTest_PeopleGroup', $favouriteGroup);
}
public function testEditFormWithManyManyExtraData() {
$this->logInWithPermission('ADMIN');
@ -341,7 +373,8 @@ class GridFieldDetailFormTest_Person extends DataObject implements TestOnly {
);
private static $many_many = array(
'Categories' => 'GridFieldDetailFormTest_Category'
'Categories' => 'GridFieldDetailFormTest_Category',
'FavouriteGroups' => 'GridFieldDetailFormTest_PeopleGroup'
);
private static $many_many_extraFields = array(
@ -362,6 +395,12 @@ class GridFieldDetailFormTest_Person extends DataObject implements TestOnly {
GridFieldConfig_RelationEditor::create()
)
);
$fields->replaceField('FavouriteGroups',
GridField::create('FavouriteGroups', 'Favourite Groups',
$this->FavouriteGroups(),
GridFieldConfig_RelationEditor::create()
)
);
return $fields;
}
@ -386,6 +425,10 @@ class GridFieldDetailFormTest_PeopleGroup extends DataObject implements TestOnly
'People' => 'GridFieldDetailFormTest_Person'
);
private static $belongs_many_many = array(
'People' => 'GridFieldDetailFormTest_Person'
);
private static $default_sort = '"Name"';
public function getCMSFields() {
@ -499,13 +542,22 @@ class GridFieldDetailFormTest_CategoryController extends Controller implements T
new CheckboxField('ManyMany[IsPublished]'),
new TextField('ManyMany[PublishedBy]'))
);
$field = new GridField('testfield', 'testfield', $person->Categories());
$field->getConfig()->addComponent($gridFieldForm = new GridFieldDetailForm($this, 'Form'));
$categoriesField = new GridField('testfield', 'testfield', $person->Categories());
$categoriesField->getConfig()->addComponent($gridFieldForm = new GridFieldDetailForm($this, 'Form'));
$gridFieldForm->setFields($detailFields);
$field->getConfig()->addComponent(new GridFieldToolbarHeader());
$field->getConfig()->addComponent(new GridFieldAddNewButton('toolbar-header-right'));
$field->getConfig()->addComponent(new GridFieldEditButton());
return new Form($this, 'Form', new FieldList($field), new FieldList());
$categoriesField->getConfig()->addComponent(new GridFieldToolbarHeader());
$categoriesField->getConfig()->addComponent(new GridFieldAddNewButton('toolbar-header-right'));
$categoriesField->getConfig()->addComponent(new GridFieldEditButton());
$favGroupsField = new GridField('testgroupsfield', 'testgroupsfield', $person->FavouriteGroups());
$favGroupsField->getConfig()->addComponent(new GridFieldDetailForm($this, 'Form'));
$favGroupsField->getConfig()->addComponent(new GridFieldToolbarHeader());
$favGroupsField->getConfig()->addComponent(new GridFieldAddNewButton('toolbar-header-right'));
$favGroupsField->getConfig()->addComponent(new GridFieldEditButton());
$fields = new FieldList($categoriesField, $favGroupsField);
return new Form($this, 'Form', $fields, new FieldList());
}
}

View File

@ -400,6 +400,11 @@ class DataListTest extends SapphireTest {
// byID() returns a DataObject, rather than a DataList
$this->assertInstanceOf('DataObjectTest_Team', $team);
$this->assertEquals('Team 2', $team->Title);
// Assert that filtering on ID searches by the base table, not the child table field
$query = DataObjectTest_SubTeam::get()->filter('ID', 4)->sql($parameters);
$this->assertContains('WHERE ("DataObjectTest_Team"."ID" = ?)', $query);
$this->assertNotContains('WHERE ("DataObjectTest_SubTeam"."ID" = ?)', $query);
}
/**

View File

@ -40,29 +40,39 @@ class FulltextFilterTest extends SapphireTest {
}
public function testGenerateQuery() {
// Test if columns have table identifier
$filter1 = new FulltextFilter('SearchFields', 'SilverStripe');
$filter1->setModel('FulltextFilterTest_DataObject');
$query1 = FulltextFilterTest_DataObject::get()->dataQuery();
$filter1->apply($query1);
$this->assertNotEquals('"ColumnA","ColumnB"', $filter1->getDbName());
$this->assertNotEquals(
array("MATCH (\"ColumnA\",\"ColumnB\") AGAINST ('SilverStripe')"),
$query1->query()->getWhere()
);
// Test SearchFields
$filter1 = new FulltextFilter('SearchFields', 'SilverStripe');
$filter1->setModel('FulltextFilterTest_DataObject');
$query1 = FulltextFilterTest_DataObject::get()->dataQuery();
$filter1->apply($query1);
$this->assertEquals('"ColumnA", "ColumnB"', $filter1->getDbName());
$this->assertEquals('"FulltextFilterTest_DataObject"."ColumnA","FulltextFilterTest_DataObject"."ColumnB"', $filter1->getDbName());
$this->assertEquals(
array(array(
"MATCH (\"ColumnA\", \"ColumnB\") AGAINST (?)" => array('SilverStripe')
"MATCH (\"FulltextFilterTest_DataObject\".\"ColumnA\",\"FulltextFilterTest_DataObject\".\"ColumnB\") AGAINST (?)" => array('SilverStripe')
)),
$query1->query()->getWhere()
);
// Test Other searchfields
$filter2 = new FulltextFilter('OtherSearchFields', 'SilverStripe');
$filter2->setModel('FulltextFilterTest_DataObject');
$query2 = FulltextFilterTest_DataObject::get()->dataQuery();
$filter2->apply($query2);
$this->assertEquals('"ColumnC", "ColumnD"', $filter2->getDbName());
$this->assertEquals('"FulltextFilterTest_DataObject"."ColumnC","FulltextFilterTest_DataObject"."ColumnD"', $filter2->getDbName());
$this->assertEquals(
array(array(
"MATCH (\"ColumnC\", \"ColumnD\") AGAINST (?)" => array('SilverStripe')
"MATCH (\"FulltextFilterTest_DataObject\".\"ColumnC\",\"FulltextFilterTest_DataObject\".\"ColumnD\") AGAINST (?)" => array('SilverStripe')
)),
$query2->query()->getWhere()
);