From 19e087d2262f5971ce11dd713eb2aabd7a1216b3 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Thu, 28 Jun 2012 11:43:56 +0200 Subject: [PATCH] Fixed references to deprecated APIs in docs --- docs/en/changelogs/3.0.0.md | 2 +- docs/en/howto/dynamic-default-fields.md | 4 +- docs/en/howto/extend-cms-interface.md | 5 +- docs/en/reference/complextablefield.md | 25 +-- docs/en/reference/dataextension.md | 46 ++--- docs/en/reference/dataobject.md | 2 +- docs/en/reference/director.md | 18 -- docs/en/reference/form-field-types.md | 2 - docs/en/reference/image.md | 4 +- docs/en/reference/member.md | 9 +- docs/en/reference/searchcontext.md | 4 +- docs/en/reference/siteconfig.md | 10 +- docs/en/reference/sqlquery.md | 102 +++++------ docs/en/reference/tablelistfield.md | 4 + .../en/reference/templates-upgrading-guide.md | 2 +- docs/en/reference/urlvariabletools.md | 12 +- docs/en/topics/configuration.md | 5 - docs/en/topics/controller.md | 14 ++ docs/en/topics/files.md | 2 +- docs/en/topics/forms.md | 172 +++++++----------- docs/en/topics/grid-field.md | 2 +- docs/en/topics/i18n.md | 18 +- docs/en/topics/page-types.md | 6 +- docs/en/topics/rich-text-editing.md | 2 +- docs/en/topics/search.md | 4 +- docs/en/topics/theme-development.md | 1 - docs/en/tutorials/3-forms.md | 119 ++++++------ docs/en/tutorials/4-site-search.md | 2 +- .../5-dataobject-relationship-management.md | 2 +- 29 files changed, 243 insertions(+), 357 deletions(-) diff --git a/docs/en/changelogs/3.0.0.md b/docs/en/changelogs/3.0.0.md index b0f824e3311..8f3751c0372 100644 --- a/docs/en/changelogs/3.0.0.md +++ b/docs/en/changelogs/3.0.0.md @@ -625,7 +625,7 @@ Note that its just necessary if SilverStripe is used in a language other than th The SS_Report::register() method is deprecated. You no longer need to explicitly register reports. The CMS now automatically picks up and adds all Report classes to the list of reports in ReportAdmin. You can choose to exclude certain reports by using the SS_Report::add_excluded_reports() method. -fe + ### Removed the ability use a SQLQuery object in a SS_Report You can no longer create reports that using the deprecated DataObject->buildSQL and DataObject->extendedSQL diff --git a/docs/en/howto/dynamic-default-fields.md b/docs/en/howto/dynamic-default-fields.md index 66ee9af54a7..5e03d7e8ea8 100644 --- a/docs/en/howto/dynamic-default-fields.md +++ b/docs/en/howto/dynamic-default-fields.md @@ -2,7 +2,7 @@ The [api:DataObject::$defaults] array allows you to specify simple static values to be the default value for when a record is created, but in many situations default values needs to be dynamically calculated. In order to do this, the -[api:DataObjectSet->populateDefaults()] method will need to be overloaded. +`[api:DataObject->populateDefaults()]` method will need to be overloaded. This method is called whenever a new record is instantiated, and you must be sure to call the method on the parent object! @@ -13,7 +13,6 @@ A simple example is to set a field to the current date and time: /** * Sets the Date field to the current date. */ - public function populateDefaults() { $this->Date = date('Y-m-d'); parent::populateDefaults(); @@ -27,7 +26,6 @@ methods. For example: * This method combines the Title of the parent object with the Title of this * object in the FullTitle field. */ - public function populateDefaults() { if($parent = $this->Parent()) { $this->FullTitle = $parent->Title . ': ' . $this->Title; diff --git a/docs/en/howto/extend-cms-interface.md b/docs/en/howto/extend-cms-interface.md index ff49bdd69b4..17303586823 100644 --- a/docs/en/howto/extend-cms-interface.md +++ b/docs/en/howto/extend-cms-interface.md @@ -85,9 +85,8 @@ Create a new file called `zzz_admin/code/BookmarkedPageExtension.php` and insert :::php array('IsBookmarked' => 'Boolean')); - } + static $db = array('IsBookmarked' => 'Boolean'); + public function updateCMSFields(&$fields) { $fields->addFieldToTab('Root.Main', new CheckboxField('IsBookmarked', "Show in CMS bookmarks?") diff --git a/docs/en/reference/complextablefield.md b/docs/en/reference/complextablefield.md index fdf98d93b5f..3ed5900c9f7 100644 --- a/docs/en/reference/complextablefield.md +++ b/docs/en/reference/complextablefield.md @@ -2,6 +2,10 @@ ## Introduction +
+ This field is deprecated in favour of the new [GridField](/topics/grid-field) API. +
+ Shows a group of DataObjects as a (readonly) tabular list (similiar to `[api:TableListField]`.) You can specify limits and filters for the resultset by customizing query-settings (mostly the ID-field on the other @@ -128,23 +132,4 @@ Most of the time, you need to override the following methods: * ComplexTableField->sourceItems() - querying * ComplexTableField->DetailForm() - form output -* ComplexTableField_Popup->saveComplexTableField() - saving - -### Examples - -* `[api:AssetTableField]` -* `[api:MemberTableField]` - -## API Documentation - -`[api:ComplexTableField]` - -## Todo - -* Find a less fragile solution for accessing this field through the main controller and ReferencedField, e.g. build a -seperate CTF-instance (doesn't necessarly have to be connected to the original by ReferencedField) -* Control width/height of popup by constructor (hardcoded at the moment) -* Integrate search from MemberTableField.php directly on `[api:ComplexTableField]` -* Less performance-hungry implementation of detail-view paging (don't return all items on a single view) -* Use automatic has-many and many-many functions to return a ComponentSet rather than building the join manually -* Javascript/Ajax-Sorting (see [http://www.activewidgets.com/grid/](http://www.activewidgets.com/grid/) and [http://openrico.org/rico/livegrid.page](http://openrico.org/rico/livegrid.page)) +* ComplexTableField_Popup->saveComplexTableField() - saving \ No newline at end of file diff --git a/docs/en/reference/dataextension.md b/docs/en/reference/dataextension.md index 70f47ec56d2..ace00e9aa75 100644 --- a/docs/en/reference/dataextension.md +++ b/docs/en/reference/dataextension.md @@ -45,56 +45,42 @@ For example above we want to override Member with a Custom Member so we would wr ### Adding extra database fields -Extra database fields can be added with a extension by defining an **extraStatics()** method. These will be added to the table of the base object - the extension will actually edit the $db, $has_one, etc static variables on load. +Extra database fields can be added with a extension in the same manner as if they +were placed on the `DataObject` class they're applied to. These will be added to the table of the base object - the extension will actually edit the $db, $has_one, etc static variables on load. The function should return a map where the keys are the names of the static variables to update: :::php class CustomMember extends DataExtension { - - public function extraStatics() { - return array( - 'db' => array( - 'AvatarURL' => 'Varchar', - ), - 'has_one' => array( - 'RelatedMember' => 'Member', - ), - ); - } + static $db = array( + 'AvatarURL' => 'Varchar', + ); + static $has_one = array( + 'RelatedMember' => 'Member', + ); } - -*NOTE* -If you want to add has_one or db items to a particular class, then that class **must** have that static variable -explicitly defined, even if it's just a blank array. For example, the extension method above wouldn't work if you added -to a class that didn't have static $has_one explicitly declared on the object. This is because of PHP's crappy support -for statics. - - ### Modifying CMS Fields -The member class demonstrates an extension that allows you to update the default CMS fields for an object in a -extension: +The member class demonstrates an extension that allows you to update the default CMS fields for an +object in an extension: :::php public function getCMSFields() { - ... - $this->extend('updateCMSFields', $fields); - return $fields; + // ... + $this->extend('updateCMSFields', $fields); + return $fields; } -The $fields parameter is passed by reference, as it is an object. +The `$`fields parameter is passed by reference, as it is an object. :::php public function updateCMSFields(FieldList $fields) { - $fields->push(new TextField('Position', 'Position Title')); - $fields->push(new UploadField('Image', 'Profile Image')); + $fields->push(new TextField('Position', 'Position Title')); + $fields->push(new UploadField('Image', 'Profile Image')); } - - ### Custom database generation Some extensions are designed to transparently add more sophisticated data-collection capabilities to your data object. diff --git a/docs/en/reference/dataobject.md b/docs/en/reference/dataobject.md index fbde2b59f87..5aea366f367 100644 --- a/docs/en/reference/dataobject.md +++ b/docs/en/reference/dataobject.md @@ -31,7 +31,7 @@ by adding, removing or configuring fields. 'IsActive' => 'Boolean' ); public function getCMSFields() { - return new FieldSet( + return new FieldList( new CheckboxField('IsActive') ); } diff --git a/docs/en/reference/director.md b/docs/en/reference/director.md index 1ee1bcd3a02..7cc9542245f 100644 --- a/docs/en/reference/director.md +++ b/docs/en/reference/director.md @@ -10,24 +10,6 @@ the viewer and/or perform processing steps. * Checking for an Ajax-Request: Use Director::is_ajax() instead of checking for $_REQUEST['ajax']. -## Redirection - -The `[api:Director]` class has a number of methods to facilitate 301 and 302 HTTP redirection. - -* **Director::redirect("action-name")**: If there's no slash in the URL passed to redirect, then it is assumed that you -want to go to a different action on the current controller. -* **Director::redirect("relative/url")**: If there is a slash in the URL, it's taken to be a normal URL. Relative URLs -will are assumed to be relative to the site-root; so Director::redirect("home/") will work no matter what the current -URL is. -* **Director::redirect("http://www.absoluteurl.com")**: Of course, you can pass redirect() absolute URL s too. -* **Director::redirectPerm("any-url")**: redirectPerm takes the same arguments as redirect, but it will send a 301 -(permanent) instead of a 302 (temporary) header. It improves search rankings, so this should be used whenever the -following two conditions are true: - * Nothing happens server-side prior to the redirection - * The redirection will always occur -* **Director::redirectBack()**: This will return you to the previous page. There's no permanent version of -redirectBack(). - ## Request processing diff --git a/docs/en/reference/form-field-types.md b/docs/en/reference/form-field-types.md index 73a9e5fcb47..cc9ef2b3637 100644 --- a/docs/en/reference/form-field-types.md +++ b/docs/en/reference/form-field-types.md @@ -34,8 +34,6 @@ This is a highlevel overview of available `[api:apiFormField]` subclasses. An au * `[api:NumericField]`: Text input field with validation for numeric values. * `[api:OptionsetField]`: Set of radio buttons designed to emulate a dropdown. * `[api:PhoneNumberField]`: Field for displaying phone numbers. It separates the number, the area code and optionally the country code and extension. - * `[api:UniqueRestrictedTextField]`: Text field that automatically checks that the value entered is unique for the given set of fields in a given set of tables - * `[api:SelectionGroup]`: SelectionGroup represents a number of fields which are selectable by a radio button that appears at the beginning of each item. * `[api:TimeField]`: Input field with time-specific, localized validation. diff --git a/docs/en/reference/image.md b/docs/en/reference/image.md index 48caca19243..53d7245aa05 100644 --- a/docs/en/reference/image.md +++ b/docs/en/reference/image.md @@ -72,10 +72,10 @@ You can also create your own functions by extending the image class, for example public function Exif(){ //http://www.v-nessa.net/2010/08/02/using-php-to-extract-image-exif-data $image = $this->AbsoluteURL; - $d=new DataObjectSet(); + $d=new ArrayList(); $exif = exif_read_data($image, 0, true); foreach ($exif as $key => $section) { - $a=new DataObjectSet(); + $a=new ArrayList(); foreach ($section as $name => $val) $a->push(new ArrayData(array("Title"=>$name,"Content"=>$val))); $d->push(new ArrayData(array("Title"=>strtolower($key),"Content"=>$a))); diff --git a/docs/en/reference/member.md b/docs/en/reference/member.md index d8846a01a79..a3a25447b53 100644 --- a/docs/en/reference/member.md +++ b/docs/en/reference/member.md @@ -113,9 +113,12 @@ things, you should add appropriate `[api:Permission::checkMember()]` calls to th } } - public function extraStatics() { - // Return an array containing keys 'db', 'has_one', 'many_many', 'belongs_many_many', - } + // define additional properties + static $db = array(); + static $has_one = array(); + static $has_many = array(); + static $many_many = array(); + static $belongs_many_many = array(); public function somethingElse() { // You can add any other methods you like, which you can call directly on the member object. diff --git a/docs/en/reference/searchcontext.md b/docs/en/reference/searchcontext.md index 4bb215fc97c..22e3d4a335d 100644 --- a/docs/en/reference/searchcontext.md +++ b/docs/en/reference/searchcontext.md @@ -12,7 +12,7 @@ The default output of a `[api:SearchContext]` is either a `[api:SQLQuery]` objec In case you need multiple contexts, consider namespacing your request parameters by using `FieldList->namespace()` on the $fields constructor parameter. -`[api:SearchContext]` is mainly used by `[api:ModelAdmin]`, our generic data administration interface. Another +`[api:SearchContext]` is mainly used by `[ModelAdmin](/reference/modeladmin)`, our generic data administration interface. Another implementation can be found in generic frontend search forms through the [genericviews](http://silverstripe.org/generic-views-module) module. ## Usage @@ -187,6 +187,6 @@ See `[api:SearchFilter]` API Documentation ## Related -* `[api:ModelAdmin]` +* [ModelAdmin](/reference/modeladmin) * [RestfulServer module](https://github.com/silverstripe/silverstripe-restfulserver) * [Tutorial: Site Search](/tutorials/4-site-search) diff --git a/docs/en/reference/siteconfig.md b/docs/en/reference/siteconfig.md index 8eb79c1ae1f..b46cb34bce8 100644 --- a/docs/en/reference/siteconfig.md +++ b/docs/en/reference/siteconfig.md @@ -39,13 +39,9 @@ Create a mysite/code/CustomSiteConfig.php file. class CustomSiteConfig extends DataExtension { - public function extraStatics() { - return array( - 'db' => array( - 'FooterContent' => 'HTMLText' - ) - ); - } + static $db = array( + 'FooterContent' => 'HTMLText' + ); public function updateCMSFields(FieldList $fields) { $fields->addFieldToTab("Root.Main", new HTMLEditorField("FooterContent", "Footer Content")); diff --git a/docs/en/reference/sqlquery.md b/docs/en/reference/sqlquery.md index 2527454e6f2..0e1b7936047 100644 --- a/docs/en/reference/sqlquery.md +++ b/docs/en/reference/sqlquery.md @@ -2,45 +2,40 @@ ## Introduction -An object representing a SQL query. It is easier to deal with object-wrappers than string-parsing a raw SQL-query. This -object is used by `[api:DataObject]`, though... +An object representing a SQL query. It is easier to deal with object-wrappers than string-parsing a raw SQL-query. This object is used by the SilverStripe ORM internally. +Dealing with low-level SQL is not encouraged, since the ORM provides +powerful abstraction APIs (see [datamodel](/topics/datamodel). -A word of caution: Dealing with low-level SQL is not encouraged in the SilverStripe [datamodel](/topics/datamodel) for various -reasons. You'll break the behaviour of: +You'll run the risk of breaking various assumptions the ORM and code based on it have: -* Custom getters/setters -* DataObject::onBeforeWrite/onBeforeDelete +* Custom getters/setters (object property can differ from database column) +* DataObject hooks like onBeforeWrite() and onBeforeDelete() * Automatic casting -* Default-setting through object-model -* `[api:DataObject]` +* Default values set through objects * Database abstraction -We'll explain some ways to use *SELECT* with the full power of SQL, but still maintain a connection to the SilverStripe -[datamodel](/topics/datamodel). +We'll explain some ways to use *SELECT* with the full power of SQL, +but still maintain a connection to the ORM where possible. ## Usage - ### SELECT :::php $sqlQuery = new SQLQuery(); - $sqlQuery->select = array( - 'Firstname AS Name', - 'YEAR(Birthday) AS BirthYear' + $sqlQuery->setFrom('Player'); + $sqlQuery->selectField('FieldName', 'Name'); + $sqlQuery->selectField('YEAR("Birthday")', 'BirthYear'); + $sqlQuery->addLeftJoin( + 'Team', + '"Player"."TeamID" = "Team"."ID"' ); - $sqlQuery->from = " - Player - LEFT JOIN Team ON Player.TeamID = Team.ID - "; - $sqlQuery->where = " - YEAR(Birthday) = 1982 - "; - // $sqlQuery->orderby = ""; - // $sqlQuery->groupby = ""; - // $sqlQuery->having = ""; - // $sqlQuery->limit = ""; - // $sqlQuery->distinct = true; + $sqlQuery->addWhere('YEAR("Birthday") = 1982'); + // $sqlQuery->setOrderBy(...); + // $sqlQuery->setGroupBy(...); + // $sqlQuery->setHaving(...); + // $sqlQuery->setLimit(...); + // $sqlQuery->setDistinct(true); // get the raw SQL $rawSQL = $sqlQuery->sql(); @@ -53,7 +48,7 @@ We'll explain some ways to use *SELECT* with the full power of SQL, but still ma :::php // ... - $sqlQuery->delete = true; + $sqlQuery->setDelete(true); ### INSERT/UPDATE @@ -80,10 +75,10 @@ Raw SQL is handy for performance-optimized calls. :::php class Team extends DataObject { public function getPlayerCount() { - $sqlQuery = new SQLQuery( - "COUNT(Player.ID)", - "Team LEFT JOIN Player ON Team.ID = Player.TeamID" - ); + $sqlQuery = new SQLQuery(); + $sqlQuery->setFrom('Player'); + $sqlQuery->addSelect('COUNT("Player"."ID")'); + $sqlQuery->addLeftJoin('Team', '"Team"."ID" = "Player"."TeamID"'); return $sqlQuery->execute()->value(); } @@ -99,10 +94,9 @@ Way faster than dealing with `[api:DataObject]`s, but watch out for premature op Useful for creating dropdowns. :::php - $sqlQuery = new SQLQuery( - array('YEAR(Birthdate)', 'Birthdate'), - 'Player' - ); + $sqlQuery = new SQLQuery(); + $sqlQuery->setFrom('Player'); + $sqlQuery->selectField('YEAR("Birthdate")', 'Birthdate'); $map = $sqlQuery->execute()->map(); $field = new DropdownField('Birthdates', 'Birthdates', $map); @@ -112,8 +106,11 @@ Useful for creating dropdowns. This is not recommended for most cases, but you can also use the SilverStripe database-layer to fire off a raw query: :::php - DB::query("UPDATE Player SET Status='Active'"); + DB::query('UPDATE "Player" SET "Status"=\'Active\''); +<<<<<<< Updated upstream +### Transforming a result to `[api:ArrayList]` +======= One example for using a raw DB::query is when you are wanting to order twice in the database: :::php @@ -130,46 +127,41 @@ You can gain some ground on the datamodel-side when involving the selected class need to call *buildSQL* from a specific object-instance, a *singleton* will do just fine. :::php - $sqlQuery = singleton('Player')->buildSQL( - 'YEAR(Birthdate) = 1982' - ); + $sqlQuery = singleton('Player')->buildSQL('YEAR("Birthdate") = 1982'); This form of building a query has the following advantages: * Respects DataObject::$default_sort -* Automatically LEFT JOIN on all base-tables (see [database-structure](database-structure)) +* Automatically `LEFT JOIN` on all base-tables (see [database-structure](database-structure)) * Selection of *ID*, *ClassName*, *RecordClassName*, which are necessary to use *buildDataObjectSet* later on * Filtering records for correct *ClassName* ### Transforming a result to `[api:DataObjectSet]` +>>>>>>> Stashed changes This is a commonly used technique inside SilverStripe: Use raw SQL, but transfer the resulting rows back into `[api:DataObject]`s. :::php $sqlQuery = new SQLQuery(); - $sqlQuery->select = array( - 'Firstname AS Name', - 'YEAR(Birthday) AS BirthYear', + $sqlQuery->setSelect(array( + '"Firstname" AS "Name"', + 'YEAR("Birthday") AS "BirthYear"', // IMPORTANT: Needs to be set after other selects to avoid overlays - 'Player.ClassName AS ClassName', - 'Player.ClassName AS RecordClassName', - 'Player.ID AS ID' - ); - $sqlQuery->from = array( - "Player", - "LEFT JOIN Team ON Player.TeamID = Team.ID" - ); - $sqlQuery->where = array( - "YEAR(Player.Birthday) = 1982" - ); + '"Player"."ClassName" AS "ClassName"', + '"Player"."ClassName" AS "RecordClassName"', + '"Player"."ID" AS "ID"' + )); + $sqlQuery->setFrom('Player'); + $sqlQuery->addLeftJoin('Team', '"Player"."TeamID" = "Team"."ID"'); + $sqlQuery->addWhere("YEAR("Player"."Birthday") = 1982"); $result = $sqlQuery->execute(); var_dump($result->first()); // array // let Silverstripe work the magic - $myDataObjectSet = singleton('Player')->buildDataObjectSet($result); + $myList = singleton('Player')->buildDataObjectSet($result); var_dump($myDataObjectSet->First()); // DataObject // this is where it gets tricky diff --git a/docs/en/reference/tablelistfield.md b/docs/en/reference/tablelistfield.md index c756475e49f..515600d2a26 100644 --- a/docs/en/reference/tablelistfield.md +++ b/docs/en/reference/tablelistfield.md @@ -2,6 +2,10 @@ ## Introduction +
+ This field is deprecated in favour of the new [GridField](/topics/grid-field) API. +
+ Form field that embeds a list of `[api:DataObject]`s into a form, such as a member list or a file list. Provides customizeable columns, record-deletion by ajax, paging, sorting, CSV-export, printing, input by `[api:DataObject]` or raw SQL. diff --git a/docs/en/reference/templates-upgrading-guide.md b/docs/en/reference/templates-upgrading-guide.md index 443c8773c53..30add91e2d7 100644 --- a/docs/en/reference/templates-upgrading-guide.md +++ b/docs/en/reference/templates-upgrading-guide.md @@ -4,7 +4,7 @@ These are the main changes to the SiverStripe 3 template language. ## Control blocks: Loops vs. Scope -The `<% control var %>...<% end_control %>` in SilverStripe prior to version 3 has two different meanings. Firstly, if the control variable is a collection (e.g. DataObjectSet), then `<% control %>` iterates over that set. If it's a non-iteratable object, however, `<% control %>` introduces a new scope, which is used to render the inner template code. This dual-use is confusing to some people, and doesn't allow a collection of objects to be used as a scope. +The `<% control var %>...<% end_control %>` in SilverStripe prior to version 3 has two different meanings. Firstly, if the control variable is a collection (e.g. DataList), then `<% control %>` iterates over that set. If it's a non-iteratable object, however, `<% control %>` introduces a new scope, which is used to render the inner template code. This dual-use is confusing to some people, and doesn't allow a collection of objects to be used as a scope. In SilverStripe 3, the first usage (iteration) is replaced by `<% loop var %>`. The second usage (scoping) is replaced by `<% with var %>` diff --git a/docs/en/reference/urlvariabletools.md b/docs/en/reference/urlvariabletools.md index 74e70d2b12b..7816cdfcfda 100644 --- a/docs/en/reference/urlvariabletools.md +++ b/docs/en/reference/urlvariabletools.md @@ -49,20 +49,10 @@ Append the option and corresponding value to your URL in your browser's address | URL Variable | | Values | | Description | | ------------ | | ------ | | ----------- | + | debug_memory | | 1 | | Output the number of bytes of memory used for this | debug_memory | | 1 | | Output the number of bytes of memory used for this request | | debug_profile | | 1 | | Enable the [profiler](/topics/debugging) for the duration of the request | | profile_trace | | 1 | | Includes full stack traces, must be used with **debug_profile** | - | debug_behaviour | | 1 | | Get profiling of [Behaviour.js](http://bennolan.com/behaviour) performance (Firebug recommended) | - | debug_javascript | | 1 | | Force debug-output on live-sites | - -## Misc - - | URL Variable | | Values | | Description | - | ------------ | | ------ | | ----------- | - | forceFormat | | xhtml,html | | Force the content negotiator to deliver HTML or XHTML is allowed | - | showspam | | 1 | | Show comments marked as spam when viewing Comments on a Page (Saving spam to the database must be enabled) | - | ajax | | 1 | | Force request to process as AJAX request, useful for debugging from a browser | - | force_ajax | | 1 | | Similar to **ajax** | ## Security Redirects diff --git a/docs/en/topics/configuration.md b/docs/en/topics/configuration.md index 4625b8a2444..b6e134a43db 100644 --- a/docs/en/topics/configuration.md +++ b/docs/en/topics/configuration.md @@ -36,9 +36,6 @@ incomplete - please add to it** *Try to keep it in alphabetical order too! :)* | Authenticator::register_authenticator($authenticator);| | Enable an authentication method (for more details see [security](/topics/security)). | | Authenticator::set_default_authenticator($authenticator); | | Modify tab-order on login-form.| | BBCodeParser::disable_autolink_urls(); | | Disables plain hyperlinks from being turned into links when bbcode is parsed. | - | BlogEntry::allow_wysiwyg_editing(); | | Enable rich text editing for blog posts. | - | ContentNegotiator::set_encoding(string $encoding) | | The encoding charset to use - UTF-8 by default | - | ContentNegotiator::disable() | | Disables the negotiation of content type -usually used to stop it from rewriting the DOCTYPE of the document | DataObject::$create_table_options['MySQLDatabase'] = 'ENGINE=MyISAM';| | Set the default database engine to MyISAM (versions 2.4 and below already default to MyISAM) | | Debug::send_errors_to(string $email) | | Send live errors on your site to this address (site has to be in 'live' mode using Director::set_environment_type(live) for this to occur | | Director::set_environment_type(string dev,test,live) | | Sets the environment type (e.g. dev site will show errors, live site hides them and displays a 500 error instead) | @@ -48,8 +45,6 @@ incomplete - please add to it** *Try to keep it in alphabetical order too! :)* | Email::send_all_emails_to(string $email) | | Sends all emails to this address. Useful for debugging your email sending functions | | Email::cc_all_emails_to(string $email) | | Useful for CC'ing all emails to someone checking correspondence | | Email::bcc_all_emails_to(string $email) | | BCC all emails to this address, similar to CC'ing emails (above) | - | MathSpamProtection::setEnabled() | | Adds a math spam question to all page comment forms | - | PageComment::enableModeration(); | | Enables comment moderation | | Requirements::set_suffix_requirements(false); | | Disable appending the current date to included files | | Security::encrypt_passwords($encrypt_passwords); | | Specify if you want store your passwords in clear text or encrypted (for more details see [security](/topics/security)) | | Security::set_password_encryption_algorithm($algorithm, $use_salt);| | If you choose to encrypt your passwords, you can choose which algorithm is used to and if a salt should be used to increase the security level even more (for more details see [security](/topics/security)). | diff --git a/docs/en/topics/controller.md b/docs/en/topics/controller.md index 94bcae9a67b..1b1edf45f12 100644 --- a/docs/en/topics/controller.md +++ b/docs/en/topics/controller.md @@ -88,6 +88,20 @@ after it. If the URLSegment is **order** then `/order/tag/34` and `/order/tag/a You can use the `debug_request=1` switch from the [urlvariabletools](/reference/urlvariabletools) to see these in action. +## Redirection + +Controllers facilitate HTTP redirection. +Note: These methods have been formerly located on the `[api:Director]` class. + +* `redirect("action-name")`: If there's no slash in the URL passed to redirect, then it is assumed that you want to go to a different action on the current controller. +* `redirect("relative/url")`: If there is a slash in the URL, it's taken to be a normal URL. Relative URLs +will are assumed to be relative to the site-root. +* `redirect("http://www.absoluteurl.com")`: Of course, you can pass `redirect()` absolute URLs too. +* `redirectBack()`: This will return you to the previous page. + +The `redirect()` method takes an optional HTTP status code, +either `301` for permanent redirects, or `302` for temporary redirects (default). + ## API Documentation `[api:Controller]` diff --git a/docs/en/topics/files.md b/docs/en/topics/files.md index 15aeac73789..a406b9721df 100644 --- a/docs/en/topics/files.md +++ b/docs/en/topics/files.md @@ -10,7 +10,7 @@ TODO Screenshot of admin interface ## Upload -TODO Link to Upload and FileIframeField classes +TODO Link to UploadField and FileField classes ## Image Resizing diff --git a/docs/en/topics/forms.md b/docs/en/topics/forms.md index 6d71850823d..1880a5e1b06 100644 --- a/docs/en/topics/forms.md +++ b/docs/en/topics/forms.md @@ -60,78 +60,42 @@ The real difference, however, is that you can then define your controller method ## Form Field Types -There are many classes extending `[api:FormField]`. Some examples: - -* `[api:TextField]` -* `[api:EmailField]` -* `[api:NumericField]` -* `[api:DateField]` -* `[api:CheckboxField]` -* `[api:DropdownField]` -* `[api:OptionsetField]` -* `[api:CheckboxSetField]` - -Full overview at [form-field-types](/reference/form-field-types) +There are many classes extending `[api:FormField]`, +there's a full overview at [form-field-types](/reference/form-field-types) ### Using Form Fields -To get these fields automatically rendered into a form element, all you need to do is create a new instance of the +To get these fields automatically rendered into a form element, +all you need to do is create a new instance of the class, and add it to the fieldlist of the form. :::php $form = new Form( - $controller = $this, - $name = "SignupForm", - $fields = new FieldList( - new TextField( - $name = "FirstName", - $title = "First name" - ), - new TextField("Surname"), - new EmailField("Email", "Email address"), - ), - $actions = new FieldList( - // List the action buttons here - new FormAction("signup", "Sign up") - ), - $requiredFields = new RequiredFields( - // List the required fields here: "Email", "FirstName" - ) - ); - - -You'll note some of the fields are optional. - -Implementing the more complex fields requires extra arguments. - - :::php - $form = new Form( - $controller = $this, - $name = "SignupForm", - $fields = new FieldList( - // List the your fields here - new TextField( - $name = "FirstName", - $title = "First name" - ), - new TextField("Surname"), - new EmailField("Email", "Email address") - new DropdownField( - $name = "Country", - $title = "Country (if outside nz)", - $source = Geoip::getCountryDropDown(), - $value = Geoip::visitor_country() - ) - ), new FieldList( - // List the action buttons here - new FormAction("signup", "Sign up") - - ), new RequiredFields( - // List the required fields here: "Email", "FirstName" - ) + $this, // controller + "SignupForm", // form name + new FieldList( // fields + TextField::create("FirstName") + ->setTitle('First name') + TextField::create("Surname") + ->setTitle('Last name') + ->setMaxLength(50), + EmailField::create("Email") + ->setTitle("Email address") + ->setAttribute('type', 'email') + ), + new FieldList( // actions + FormAction::create("signup")->setTitle("Sign up") + ), + new RequiredFields( // validation + "Email", "FirstName" + ) ); +You'll notice that we've used a new notation for creating form fields, +using `create()` instead of the `new` operator. These are functionally equivalent, +but allows PHP to chain operations like `setTitle()` without assigning +the field instance to a temporary variable. ## Readonly @@ -144,7 +108,7 @@ Readonly on a Form Readonly on a FieldList :::php - $myFieldSet->makeReadonly(); + $myFieldList->makeReadonly(); Readonly on a FormField @@ -167,29 +131,29 @@ First of all, you need to create your form on it's own class, that way you can d :::php class MyForm extends Form { - public function __construct($controller, $name) { - $fields = new FieldList( - new TextField('FirstName', 'First name'), - new EmailField('Email', 'Email address') - ); + public function __construct($controller, $name) { + $fields = new FieldList( + new TextField('FirstName', 'First name'), + new EmailField('Email', 'Email address') + ); - $actions = new FieldList( - new FormAction('submit', 'Submit') - ); + $actions = new FieldList( + new FormAction('submit', 'Submit') + ); - parent::__construct($controller, $name, $fields, $actions); - } + parent::__construct($controller, $name, $fields, $actions); + } - public function forTemplate() { - return $this->renderWith(array( - $this->class, - 'Form' - )); - } + public function forTemplate() { + return $this->renderWith(array( + $this->class, + 'Form' + )); + } - public function submit($data, $form) { - // do stuff here - } + public function submit($data, $form) { + // do stuff here + } } @@ -201,31 +165,31 @@ basic customisation: :::ss
- <% if Message %> -

$Message

- <% else %> - - <% end_if %> - -
-
- - $dataFieldByName(FirstName) -
+ <% if Message %> +

$Message

+ <% else %> + + <% end_if %> + +
+
+ + $dataFieldByName(FirstName) +
- + - $dataFieldByName(SecurityID) -
+ $dataFieldByName(SecurityID) +
- <% if Actions %> -
- <% loop Actions %>$Field<% end_loop %> -
- <% end_if %> + <% if Actions %> +
+ <% loop Actions %>$Field<% end_loop %> +
+ <% end_if %>
`$dataFieldByName(FirstName)` will return the form control contents of `Field()` for the particular field object, in diff --git a/docs/en/topics/grid-field.md b/docs/en/topics/grid-field.md index e049ce961ae..f1369c8e3c9 100644 --- a/docs/en/topics/grid-field.md +++ b/docs/en/topics/grid-field.md @@ -14,7 +14,7 @@ This example might come from a Controller designed to manage the members of a gr */ public function MemberForm() { $field = new GridField("Members", "Members of this group", $this->group->Members()); - return new Form("MemberForm", $this, new FieldSet($field), new FieldSet()); + return new Form("MemberForm", $this, new FieldList($field), new FieldList()); } Note that the only way to specify the data that is listed in a grid field is with `SS_List` argument. If you want to customise the data displayed, you can do so by customising this object. diff --git a/docs/en/topics/i18n.md b/docs/en/topics/i18n.md index fd61ff13450..91c26ee98ea 100644 --- a/docs/en/topics/i18n.md +++ b/docs/en/topics/i18n.md @@ -70,9 +70,9 @@ to write your own logic for any frontend output. i18n::set_date_format('dd.MM.YYYY'); i18n::set_time_format('HH:mm'); -Most localization routines in SilverStripe use the [http://framework.zend.com/manual/en/zend.date.html](Zend_Date API). +Most localization routines in SilverStripe use the [Zend_Date API](http://framework.zend.com/manual/en/zend.date.html). This means all formats are defined in -[http://framework.zend.com/manual/en/zend.date.constants.html#zend.date.constants.selfdefinedformats](ISO date format), +[ISO date format](http://framework.zend.com/manual/en/zend.date.constants.html#zend.date.constants.selfdefinedformats), not PHP's built-in [date()](http://nz.php.net/manual/en/function.date.php). ### i18n in URLs @@ -227,22 +227,20 @@ which supports different translation adapters, dealing with different storage fo By default, SilverStripe 3.x uses a YAML format (through the [Zend_Translate_RailsYAML adapter](https://github.com/chillu/zend_translate_railsyaml)). -Example: sapphire/lang/en.yml (extract) +Example: framework/lang/en.yml (extract) - :::yml en: ImageUploader: Attach: 'Attach %s' - FileIFrameField: + UploadField: NOTEADDFILES: 'You can add files once you have saved for the first time.' -Translation table: sapphire/lang/de.yml (extract) +Translation table: framework/lang/de.yml (extract) - :::yml de: ImageUploader: ATTACH: '%s anhängen' - FileIframeField: + UploadField: NOTEADDFILES: 'Sie können Dateien hinzufügen sobald Sie das erste mal gespeichert haben' Note that translations are cached across requests. @@ -262,7 +260,7 @@ Example: framework/lang/en_US.php (extract) 'Attach %s', 'Attach image/file' ); - $lang['en_US']['FileIFrameField']['NOTEADDFILES'] = 'You can add files once you have saved for the first time.'; + $lang['en_US']['UploadField']['NOTEADDFILES'] = 'You can add files once you have saved for the first time.'; // ... @@ -270,7 +268,7 @@ Translation table: framework/lang/de_DE.php (extract) :::php $lang['de_DE']['ImageUploader']['ATTACH'] = '%s anhängen'; - $lang['de_DE']['FileIframeField']['NOTEADDFILES'] = 'Sie können Dateien hinzufügen sobald Sie das erste mal gespeichert haben'; + $lang['de_DE']['UploadField']['NOTEADDFILES'] = 'Sie können Dateien hinzufügen sobald Sie das erste mal gespeichert haben'; In order to enable usage of PHP language definitions in 3.x, you need to register a legacy adapter in your `mysite/_config.php`: diff --git a/docs/en/topics/page-types.md b/docs/en/topics/page-types.md index 22b5a83b59a..7123671bf0d 100644 --- a/docs/en/topics/page-types.md +++ b/docs/en/topics/page-types.md @@ -52,14 +52,11 @@ especially useful if you know how long your source data needs to be. :::php class StaffPage extends Page { - static $db = array( 'Author' => 'Varchar(50)' ); - } class StaffPage_Controller extends Page_Controller { - } @@ -68,7 +65,8 @@ model works. ## Adding Form Fields and Tabs -See [form](/topics/forms) and [tutorial:2-extending-a-basic-site](/tutorials/2-extending-a-basic-site) +See [form](/topics/forms) and [tutorial:2-extending-a-basic-site](/tutorials/2-extending-a-basic-site). +Note: To modify fields in the "Settings" tab, you need to use `updateSettingsFields()` instead. ## Removing inherited form fields and tabs diff --git a/docs/en/topics/rich-text-editing.md b/docs/en/topics/rich-text-editing.md index dea4cb1f5f7..51527c5bab1 100644 --- a/docs/en/topics/rich-text-editing.md +++ b/docs/en/topics/rich-text-editing.md @@ -17,7 +17,7 @@ It is usually added through the `[api:DataObject->getCMSFields()]` method: static $db = array('Content' => 'HTMLText'); public function getCMSFields() { - return new FieldSet(new HTMLEditorField('Content')); + return new FieldList(new HTMLEditorField('Content')); } } diff --git a/docs/en/topics/search.md b/docs/en/topics/search.md index a5f6a44ad76..d828189f01a 100644 --- a/docs/en/topics/search.md +++ b/docs/en/topics/search.md @@ -8,7 +8,7 @@ See [Tutorial: Site Search](/tutorials/4-site-search) for details. ## Searching for DataObjects The `[api:SearchContext]` class provides a good base implementation that you can hook into your own controllers. -A working implementation of searchable DataObjects can be seen in the `[api:ModelAdmin]` class. +A working implementation of searchable DataObjects can be seen in the `[ModelAdmin](/reference/modeladmin)` class. [SearchContext](/reference/searchcontext) goes into more detail about setting up a default search form for `[api:DataObject]`s. @@ -33,7 +33,7 @@ dedicated search service like the [sphinx module](http://silverstripe.org/sphinx ## Related -* `[api:ModelAdmin]` +* [ModelAdmin](/reference/modeladmin) * [RestfulServer module](https://github.com/silverstripe/silverstripe-restfulserver) * [Tutorial: Site Search](/tutorials/4-site-search) * [SearchContext](/reference/searchcontext) diff --git a/docs/en/topics/theme-development.md b/docs/en/topics/theme-development.md index 5c4896cde24..4eeb7bd223b 100644 --- a/docs/en/topics/theme-development.md +++ b/docs/en/topics/theme-development.md @@ -99,7 +99,6 @@ our theme in action. The code for mine is below.

$Title

$Content $Form - $PageComments All you have to do now is tell your site to use your new theme - This is defined in the **mysite/_config.php** file diff --git a/docs/en/tutorials/3-forms.md b/docs/en/tutorials/3-forms.md index afce41f3d54..cb9ca3394e1 100644 --- a/docs/en/tutorials/3-forms.md +++ b/docs/en/tutorials/3-forms.md @@ -207,7 +207,7 @@ that the *BrowserPollSubmission* table is created. Now we just need to define 'd $submission = new BrowserPollSubmission(); $form->saveInto($submission); $submission->write(); - Director::redirectBack(); + return $this->redirectBack(); } } @@ -218,7 +218,7 @@ A function that processes a form submission takes two arguments - the first is t In our function we create a new *BrowserPollSubmission* object. Since the name of our form fields and the name of the database fields are the same we can save the form directly into the data object. -We call the 'write' method to write our data to the database, and 'Director::redirectBack()' will redirect the user back +We call the 'write' method to write our data to the database, and 'redirectBack()' will redirect the user back to the home page. @@ -237,11 +237,8 @@ Change the end of the 'BrowserPollForm' function so it looks like this: :::php public function BrowserPollForm() { - ... - - // Create validator + // ... $validator = new RequiredFields('Name', 'Browser'); - return new Form($this, 'BrowserPollForm', $fields, $actions, $validator); } @@ -266,22 +263,16 @@ First modify the 'doBrowserPoll' to set the session variable 'BrowserPollVoted' *mysite/code/HomePage.php* :::php - ... - - HomePage_Controller extends Page_Controller { - ... - + // ... + class HomePage_Controller extends Page_Controller { + // ... public function doBrowserPoll($data, $form) { $submission = new BrowserPollSubmission(); $form->saveInto($submission); $submission->write(); - Session::set('BrowserPollVoted', true); - - Director::redirectBack(); + return $this->redirectBack(); } - - ... } @@ -293,59 +284,55 @@ it is. if(Session::get('BrowserPollVoted')) { return false; } - - ... - + // ... + } -If you visit the home page now you will see you can only vote once per session; after that the form won't be shown. You -can start a new session by closing and reopening your browser (or if you're using Firefox and have installed the [Web -Developer](http://chrispederick.com/work/web-developer/) extension, you can use its Clear Session Cookies command). -Although the form is not shown, you'll still see the 'Browser Poll' heading. We'll leave this for now: after we've built -the bar graph of the results, we'll modify the template to show the graph instead of the form if the user has already -voted. +If you visit the home page now you will see you can only vote once per session; +after that the form won't be shown. +You can start a new session by closing and reopening your browser. -We now need some way of getting the data from the database into the template. +Now that we're collecting data, it would be nice to show the results +on the website as well. We could simply output every vote, but that's boring. +Let's group the results by browser, through the SilverStripe data model. -In the second tutorial we got the latest news articles for the home page by using the 'DataObject::get' function. We -can't use the 'DataObject::get' function here directly as we wish to count the total number of votes for each browser. -By looking at the documentation for 'DataObject::get', we can see that it returns a `[api:DataObjectSet]` -object. In fact, all data that can be iterated over in a template with a page control is contained in a DataObjectSet. +In the [second tutorial](/tutorials/2-extending-a-basic-site), +we got a collection of news articles for the home page by +using the 'ArticleHolder::get()' function, which returns a `[api:DataList]`. +We can get all submissions in the same fashion, through `BrowserPollSubmission::get()`. +This list will be the starting point for our result aggregation. -A `[api:DataObjectSet]` is a set of not just DataObjects, but of ViewableData, which the majority of -SilverStripe's classes (including DataObject) inherit from. We can create a DataObjectSet, fill it with our data, and -then create our graph using a page control in the template. Create the function 'BrowserPollResults' on the -*HomePage_Controller* class. +Create the function 'BrowserPollResults' on the *HomePage_Controller* class. ** mysite/code/HomePage.php ** :::php public function BrowserPollResults() { - $submissions = BrowserPollSubmission::get(); + $submissions = new GroupedList(BrowserPollSubmission::get()); $total = $submissions->Count(); - $doSet = new DataObjectSet(); - foreach($submissions->groupBy('Browser') as $browser => $data) { + $list = new ArrayList(); + foreach($submissions->groupBy('Browser') as $browserName => $browserSubmissions) { $percentage = (int) ($data->Count() / $total * 100); - $record = array( - 'Browser' => $browser, + $list->push(new ArrayData(array( + 'Browser' => $browserName, 'Percentage' => $percentage - ); - $doSet->push(new ArrayData($record)); + ))); } - - return $doSet; + return $list; } - -This introduces a few new concepts, so let's step through it. +This code introduces a few new concepts, so let's step through it. :::php - $submissions = BrowserPollSubmission::get(); + $submissions = new GroupedList(BrowserPollSubmission::get()); -First we get all of the *BrowserPollSubmission*s from the database. This returns the submissions as a -DataObjectSet, which contains the submissions as *BrowserPollSubmission* objects. +First we get all of the `BrowserPollSubmission` records from the database. +This returns the submissions as a `[api:DataList]`. +Then we wrap it inside a `[api:GroupedList]`, which adds the ability +to group those records. The resulting object will behave just like +the original `DataList`, though (with the addition of a `groupBy()` method). :::php $total = $submissions->Count(); @@ -354,29 +341,24 @@ DataObjectSet, which contains the submissions as *BrowserPollSubmission* objects We get the total number of submissions, which is needed to calculate the percentages. :::php - $doSet = new DataObjectSet(); - foreach($submissions->groupBy('Browser') as $browser => $data) { - $percentage = (int) ($data->Count() / $total * 100); - $record = array( - 'Browser' => $browser, + $list = new ArrayList(); + foreach($submissions->groupBy('Browser') as $browserName => $browserSubmissions) { + $percentage = (int) ($browserSubmissions->Count() / $total * 100); + $list->push(new ArrayData(array( + 'Browser' => $browserName, 'Percentage' => $percentage - ); - $doSet->push(new ArrayData($record)); + ))); } -Now we create an empty DataObjectSet to hold our data and then iterate over the 'Browser' submissions field. The 'groupBy' -method of DataObjectSet splits our DataObjectSet by the 'Browser' field passed to it. The percentage of submissions for each -browser is calculated using the size of the DataObjectSet. It puts these new DataObjectSets into an array indexed -by the value of the field. The `[api:ArrayData]` class wraps an array into a ViewableData object, so we finally create a new -ArrayData object, which we can add to our *$doSet* DataObjectSet of results. - - :::php - return $doSet; - - -After we have iterated through all the browsers, the DataObjectSet contains all the results, which is then -returned. +Now we create an empty `[api:ArrayList]` to hold the data we'll pass to the template. +Its similar to `[api:DataList]`, but can hold arbitrary objects rather than just `DataObject` instances. +Then iterate over the 'Browser' submissions field. +The `groupBy()` method splits our list by the 'Browser' field passed to it, +creating new lists with submissions just for a specific browser. +Each of those lists is keyed by the browser name. +The aggregated result is then contained in an `[api:ArrayData]` object, +which behaves much like a standard PHP array, but allows us to use it in SilverStripe templates. The final step is to create the template to display our data. Change the 'BrowserPoll' div in *themes/tutorial/templates/Layout/HomePage.ss* to the below. @@ -408,6 +390,9 @@ a complete poll. ![](_images/pollresults.jpg) +
+While the ORM is +
## Summary diff --git a/docs/en/tutorials/4-site-search.md b/docs/en/tutorials/4-site-search.md index f3ded671b32..af2a903b043 100644 --- a/docs/en/tutorials/4-site-search.md +++ b/docs/en/tutorials/4-site-search.md @@ -98,7 +98,7 @@ function, and then attempt to render it with *Page_results.ss*, falling back to ## Creating the template Lastly we need the template for the search page. This template uses all the same techniques used in previous -tutorials. It also uses a number of pagination variables, which are provided by the `[api:DataObjectSet]` +tutorials. It also uses a number of pagination variables, which are provided by the `[api:PaginatedList]` class. *themes/simple/templates/Layout/Page_results.ss* diff --git a/docs/en/tutorials/5-dataobject-relationship-management.md b/docs/en/tutorials/5-dataobject-relationship-management.md index 2166ebc12d4..d101f902bbe 100644 --- a/docs/en/tutorials/5-dataobject-relationship-management.md +++ b/docs/en/tutorials/5-dataobject-relationship-management.md @@ -214,7 +214,7 @@ To use your *HasOneComplexTableField* table for a **1-to-1** relation, make this $tablefield->setOneToOne(); - $fields->addFieldToTab( 'Root.Content.Student', $tablefield ); + $fields->addFieldToTab( 'Root.Student', $tablefield ); return $fields; }