mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Yay, clean arrays
This commit is contained in:
parent
eb1695c03d
commit
2414eaeafd
@ -103,7 +103,6 @@ Save it as `check.php` into your webroot, and run it as `php check.php` (or open
|
||||
After using the script (and fixing errors afterwards), please remember to remove it again.
|
||||
|
||||
```php
|
||||
<?php
|
||||
// Check for whitespace around PHP brackets which show in output,
|
||||
// and hence can break HTML rendering and HTTP operations.
|
||||
$path = dirname(__FILE__);
|
||||
|
@ -350,8 +350,6 @@ types right now, we will go into much more detail in the [next tutorial](/tutori
|
||||
Create a new file *HomePage.php* in *mysite/code*. Copy the following code into it:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Page;
|
||||
use PageController;
|
||||
|
||||
|
@ -68,8 +68,7 @@ We'll start with the *ArticlePage* page type. First we create the model, a class
|
||||
**mysite/code/ArticlePage.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Page;
|
||||
use Page;
|
||||
|
||||
class ArticlePage extends Page
|
||||
{
|
||||
@ -78,8 +77,7 @@ We'll start with the *ArticlePage* page type. First we create the model, a class
|
||||
```
|
||||
**mysite/code/ArticlePageController.php**
|
||||
```php
|
||||
<?php
|
||||
use PageController;
|
||||
use PageController;
|
||||
|
||||
class ArticlePageController extends PageController
|
||||
{
|
||||
@ -97,8 +95,7 @@ Let's create the *ArticleHolder* page type.
|
||||
**mysite/code/ArticleHolder.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Page;
|
||||
use Page;
|
||||
|
||||
class ArticleHolder extends Page
|
||||
{
|
||||
@ -107,8 +104,7 @@ Let's create the *ArticleHolder* page type.
|
||||
```
|
||||
**mysite/code/ArticleHolderController.php**
|
||||
```php
|
||||
<?php
|
||||
use PageController;
|
||||
use PageController;
|
||||
|
||||
class ArticleHolderController extends PageController
|
||||
{
|
||||
@ -136,8 +132,7 @@ the $db array to add extra fields to the database. It would be nice to know when
|
||||
it. Add a *$db* property definition in the *ArticlePage* class:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Page;
|
||||
use Page;
|
||||
|
||||
class ArticlePage extends Page
|
||||
{
|
||||
@ -162,8 +157,7 @@ When we rebuild the database, we will see that the *ArticlePage* table has been
|
||||
To add our new fields to the CMS we have to override the *getCMSFields()* method, which is called by the CMS when it creates the form to edit a page. Add the method to the *ArticlePage* class.
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Page;
|
||||
use Page;
|
||||
|
||||
class ArticlePage extends Page
|
||||
{
|
||||
@ -233,8 +227,7 @@ To make the date field a bit more user friendly, you can add a dropdown calendar
|
||||
the date field will have the date format defined by your locale.
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Page;
|
||||
use Page;
|
||||
|
||||
class ArticlePage extends Page
|
||||
{
|
||||
@ -488,8 +481,7 @@ Now that we have a complete news section, let's take a look at the staff section
|
||||
**mysite/code/StaffHolder.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Page;
|
||||
use Page;
|
||||
|
||||
class StaffHolder extends Page
|
||||
{
|
||||
@ -502,8 +494,7 @@ Now that we have a complete news section, let's take a look at the staff section
|
||||
**mysite/code/StaffHolderController.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
use PageController;
|
||||
use PageController;
|
||||
|
||||
class StaffHolderController extends PageController
|
||||
{
|
||||
@ -516,8 +507,7 @@ Nothing here should be new. The *StaffPage* page type is more interesting though
|
||||
**mysite/code/StaffPage.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
use SilverStripe\AssetAdmin\Forms\UploadField;
|
||||
use SilverStripe\AssetAdmin\Forms\UploadField;
|
||||
use SilverStripe\Assets\Image;
|
||||
|
||||
class StaffPage extends Page
|
||||
@ -542,8 +532,7 @@ Nothing here should be new. The *StaffPage* page type is more interesting though
|
||||
**mysite/code/StaffPageController.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
use PageController;
|
||||
use PageController;
|
||||
|
||||
class StaffPageController extends PageController
|
||||
{
|
||||
|
@ -32,7 +32,7 @@ use SilverStripe\Forms\TextField;
|
||||
|
||||
class HomePageController extends PageController
|
||||
{
|
||||
private static $allowed_actions = array('BrowserPollForm');
|
||||
private static $allowed_actions = ['BrowserPollForm'];
|
||||
|
||||
// ...
|
||||
|
||||
@ -41,14 +41,14 @@ class HomePageController extends PageController
|
||||
// Create fields
|
||||
$fields = new FieldList(
|
||||
new TextField('Name'),
|
||||
new OptionsetField('Browser', 'Your Favourite Browser', array(
|
||||
new OptionsetField('Browser', 'Your Favourite Browser', [
|
||||
'Firefox' => 'Firefox',
|
||||
'Chrome' => 'Chrome',
|
||||
'Internet Explorer' => 'Internet Explorer',
|
||||
'Safari' => 'Safari',
|
||||
'Opera' => 'Opera',
|
||||
'Lynx' => 'Lynx'
|
||||
))
|
||||
])
|
||||
);
|
||||
|
||||
// Create actions
|
||||
@ -62,6 +62,7 @@ class HomePageController extends PageController
|
||||
// ...
|
||||
}
|
||||
// ...
|
||||
|
||||
```
|
||||
|
||||
Let's step through this code.
|
||||
@ -70,15 +71,16 @@ Let's step through this code.
|
||||
// Create fields
|
||||
$fields = new FieldList(
|
||||
new TextField('Name'),
|
||||
new OptionsetField('Browser', 'Your Favourite Browser', array(
|
||||
new OptionsetField('Browser', 'Your Favourite Browser', [
|
||||
'Firefox' => 'Firefox',
|
||||
'Chrome' => 'Chrome',
|
||||
'Internet Explorer' => 'Internet Explorer',
|
||||
'Safari' => 'Safari',
|
||||
'Opera' => 'Opera',
|
||||
'Lynx' => 'Lynx'
|
||||
))
|
||||
])
|
||||
);
|
||||
|
||||
```
|
||||
|
||||
First we create our form fields.
|
||||
@ -192,17 +194,16 @@ If you recall, in the [second tutorial](/tutorials/extending_a_basic_site) we sa
|
||||
**mysite/code/BrowserPollSubmission.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use SilverStripe\ORM\DataObject;
|
||||
|
||||
class BrowserPollSubmission extends DataObject
|
||||
{
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Name' => 'Text',
|
||||
'Browser' => 'Text'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
If we then rebuild the database ([http://localhost/your_site_name/dev/build](http://localhost/your_site_name/dev/build)), we will see that the *BrowserPollSubmission* table is created. Now we just need to define 'doBrowserPoll' on *HomePageController*:
|
||||
|
||||
@ -324,13 +325,14 @@ public function BrowserPollResults()
|
||||
$list = new ArrayList();
|
||||
foreach($submissions->groupBy('Browser') as $browserName => $browserSubmissions) {
|
||||
$percentage = (int) ($browserSubmissions->Count() / $total * 100);
|
||||
$list->push(new ArrayData(array(
|
||||
$list->push(new ArrayData([
|
||||
'Browser' => $browserName,
|
||||
'Percentage' => $percentage
|
||||
)));
|
||||
]));
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
```
|
||||
This code introduces a few new concepts, so let's step through it.
|
||||
|
||||
@ -349,11 +351,12 @@ We get the total number of submissions, which is needed to calculate the percent
|
||||
$list = new ArrayList();
|
||||
foreach ($submissions->groupBy('Browser') as $browserName => $browserSubmissions) {
|
||||
$percentage = (int) ($browserSubmissions->Count() / $total * 100);
|
||||
$list->push(new ArrayData(array(
|
||||
$list->push(new ArrayData([
|
||||
'Browser' => $browserName,
|
||||
'Percentage' => $percentage
|
||||
)));
|
||||
]));
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Now we create an empty [ArrayList](api:SilverStripe\ORM\ArrayList) to hold the data we'll pass to the template. Its similar to [DataList](api:SilverStripe\ORM\DataList), but can hold arbitrary objects rather than just DataObject` instances. Then we iterate over the 'Browser' submissions field.
|
||||
|
@ -64,14 +64,15 @@ is applied via `FulltextSearchable::enable()`
|
||||
|
||||
public function results($data, $form, $request)
|
||||
{
|
||||
$data = array(
|
||||
$data = [
|
||||
'Results' => $form->getResults(),
|
||||
'Query' => $form->getSearchQuery(),
|
||||
'Title' => _t('SearchForm.SearchResults', 'Search Results')
|
||||
);
|
||||
return $this->owner->customise($data)->renderWith(array('Page_results', 'Page'));
|
||||
];
|
||||
return $this->owner->customise($data)->renderWith(['Page_results', 'Page']);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The code populates an array with the data we wish to pass to the template - the search results, query and title of the page. The final line is a little more complicated.
|
||||
|
@ -39,41 +39,38 @@ Let's create the `Student` and `Project` objects.
|
||||
**mysite/code/Student.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use SilverStripe\ORM\DataObject;
|
||||
|
||||
class Student extends DataObject
|
||||
{
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Name' => 'Varchar',
|
||||
'University' => 'Varchar',
|
||||
);
|
||||
private static $has_one = array(
|
||||
];
|
||||
private static $has_one = [
|
||||
'Project' => 'Project'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
**mysite/code/Project.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Page;
|
||||
|
||||
class Project extends Page
|
||||
{
|
||||
private static $has_many = array(
|
||||
private static $has_many = [
|
||||
'Students' => 'Student'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
**mysite/code/ProjectController.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
use PageController;
|
||||
|
||||
class ProjectController extends PageController
|
||||
@ -116,22 +113,19 @@ The restriction is enforced through the `$allowed_children` directive.
|
||||
**mysite/code/ProjectsHolder.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Page;
|
||||
|
||||
class ProjectsHolder extends Page {
|
||||
private static $allowed_children = array(
|
||||
private static $allowed_children = [
|
||||
'Project'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
**mysite/code/ProjectsHolderController.php
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use PageController;
|
||||
|
||||
class ProjectsHolderController extends PageController
|
||||
@ -164,8 +158,6 @@ All customization to fields for a page type are managed through a method called
|
||||
**mysite/code/Project.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Page;
|
||||
use SilverStripe\Forms\GridField;
|
||||
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;
|
||||
@ -182,10 +174,10 @@ class Project extends Page
|
||||
// Set the names and data for our gridfield columns
|
||||
$config
|
||||
->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldDataColumns')
|
||||
->setDisplayFields(array(
|
||||
->setDisplayFields([
|
||||
'Name' => 'Name',
|
||||
'Project.Title'=> 'Project' // Retrieve from a has-one relationship
|
||||
));
|
||||
]);
|
||||
// Create a gridfield to hold the student relationship
|
||||
$studentsField = new GridField(
|
||||
'Students', // Field name
|
||||
@ -198,6 +190,7 @@ class Project extends Page
|
||||
return $fields;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
This creates a tabular field, which lists related student records, one row at a time.
|
||||
@ -246,35 +239,33 @@ The first step is to create the `Mentor` object and set the relation with the `P
|
||||
**mysite/code/Mentor.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use SilverStripe\ORM\DataObject;
|
||||
|
||||
class Mentor extends DataObject
|
||||
{
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Name' => 'Varchar',
|
||||
);
|
||||
private static $belongs_many_many = array(
|
||||
];
|
||||
private static $belongs_many_many = [
|
||||
'Projects' => 'Project'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
**mysite/code/Project.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Page;
|
||||
|
||||
class Project extends Page
|
||||
{
|
||||
// ...
|
||||
private static $many_many = array(
|
||||
private static $many_many = [
|
||||
'Mentors' => 'Mentor'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
This code will create a relationship between the `Project` table and the `Mentor` table by storing the ids of the respective `Project` and `Mentor` in a another table named "Project_Mentors"
|
||||
@ -288,8 +279,6 @@ to configure it a bit differently.
|
||||
**mysite/code/Project.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Page;
|
||||
use SilverStripe\Forms\GridField;
|
||||
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;
|
||||
|
@ -20,18 +20,17 @@ Let's look at a simple example:
|
||||
**mysite/code/Player.php**
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Player extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'PlayerNumber' => 'Int',
|
||||
'FirstName' => 'Varchar(255)',
|
||||
'LastName' => 'Text',
|
||||
'Birthday' => 'Date'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
This `Player` class definition will create a database table `Player` with columns for `PlayerNumber`, `FirstName` and
|
||||
@ -78,18 +77,17 @@ system. Instead, it will generate a new `ID` by adding 1 to the current maximum
|
||||
**mysite/code/Player.php**
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Player extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'PlayerNumber' => 'Int',
|
||||
'FirstName' => 'Varchar(255)',
|
||||
'LastName' => 'Text',
|
||||
'Birthday' => 'Date'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Generates the following `SQL`.
|
||||
@ -113,14 +111,12 @@ Generates the following `SQL`.
|
||||
A new instance of a [DataObject](api:SilverStripe\ORM\DataObject) can be created using the `new` syntax.
|
||||
|
||||
```php
|
||||
|
||||
$player = new Player();
|
||||
```
|
||||
|
||||
Or, a better way is to use the `create` method.
|
||||
|
||||
```php
|
||||
|
||||
$player = Player::create();
|
||||
```
|
||||
|
||||
@ -133,7 +129,6 @@ Database columns and properties can be set as class properties on the object. Th
|
||||
of the values through a custom `__set()` method.
|
||||
|
||||
```php
|
||||
|
||||
$player->FirstName = "Sam";
|
||||
$player->PlayerNumber = 07;
|
||||
```
|
||||
@ -142,14 +137,12 @@ To save the `DataObject` to the database, use the `write()` method. The first ti
|
||||
set.
|
||||
|
||||
```php
|
||||
|
||||
$player->write();
|
||||
```
|
||||
|
||||
For convenience, the `write()` method returns the record's ID. This is particularly useful when creating new records.
|
||||
|
||||
```php
|
||||
|
||||
$player = Player::create();
|
||||
$id = $player->write();
|
||||
```
|
||||
@ -160,7 +153,6 @@ With the `Player` class defined we can query our data using the `ORM` or Object-
|
||||
shortcuts and methods for fetching, sorting and filtering data from our database.
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get();
|
||||
// returns a `DataList` containing all the `Player` objects.
|
||||
|
||||
@ -178,12 +170,12 @@ The `ORM` uses a "fluent" syntax, where you specify a query by chaining together
|
||||
are `filter()` and `sort()`:
|
||||
|
||||
```php
|
||||
|
||||
$members = Player::get()->filter(array(
|
||||
$members = Player::get()->filter([
|
||||
'FirstName' => 'Sam'
|
||||
))->sort('Surname');
|
||||
])->sort('Surname');
|
||||
|
||||
// returns a `DataList` containing all the `Player` records that have the `FirstName` of 'Sam'
|
||||
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
@ -198,28 +190,28 @@ It's smart enough to generate a single efficient query at the last moment in tim
|
||||
result set in PHP. In `MySQL` the query generated by the ORM may look something like this
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->filter(array(
|
||||
$players = Player::get()->filter([
|
||||
'FirstName' => 'Sam'
|
||||
));
|
||||
]);
|
||||
|
||||
$players = $players->sort('Surname');
|
||||
|
||||
// executes the following single query
|
||||
// SELECT * FROM Player WHERE FirstName = 'Sam' ORDER BY Surname
|
||||
|
||||
```
|
||||
|
||||
This also means that getting the count of a list of objects will be done with a single, efficient query.
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->filter(array(
|
||||
$players = Player::get()->filter([
|
||||
'FirstName' => 'Sam'
|
||||
))->sort('Surname');
|
||||
])->sort('Surname');
|
||||
|
||||
// This will create an single SELECT COUNT query
|
||||
// SELECT COUNT(*) FROM Player WHERE FirstName = 'Sam'
|
||||
echo $players->Count();
|
||||
|
||||
```
|
||||
|
||||
## Looping over a list of objects
|
||||
@ -227,7 +219,6 @@ This also means that getting the count of a list of objects will be done with a
|
||||
`get()` returns a `DataList` instance. You can loop over `DataList` instances in both PHP and templates.
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get();
|
||||
|
||||
foreach($players as $player) {
|
||||
@ -238,7 +229,6 @@ This also means that getting the count of a list of objects will be done with a
|
||||
Notice that we can step into the loop safely without having to check if `$players` exists. The `get()` call is robust, and will at worst return an empty `DataList` object. If you do want to check if the query returned any records, you can use the `exists()` method, e.g.
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get();
|
||||
|
||||
if($players->exists()) {
|
||||
@ -254,14 +244,12 @@ There are a couple of ways of getting a single DataObject from the ORM. If you k
|
||||
can use `byID($id)`:
|
||||
|
||||
```php
|
||||
|
||||
$player = Player::get()->byID(5);
|
||||
```
|
||||
|
||||
`get()` returns a [DataList](api:SilverStripe\ORM\DataList) instance. You can use operations on that to get back a single record.
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get();
|
||||
|
||||
$first = $players->first();
|
||||
@ -273,7 +261,6 @@ can use `byID($id)`:
|
||||
If would like to sort the list by `FirstName` in a ascending way (from A to Z).
|
||||
|
||||
```php
|
||||
|
||||
// Sort can either be Ascending (ASC) or Descending (DESC)
|
||||
$players = Player::get()->sort('FirstName', 'ASC');
|
||||
|
||||
@ -284,7 +271,6 @@ If would like to sort the list by `FirstName` in a ascending way (from A to Z).
|
||||
To reverse the sort
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->sort('FirstName', 'DESC');
|
||||
|
||||
// or..
|
||||
@ -295,17 +281,16 @@ However you might have several entries with the same `FirstName` and would like
|
||||
`LastName`
|
||||
|
||||
```php
|
||||
|
||||
$players = Players::get()->sort(array(
|
||||
$players = Players::get()->sort([
|
||||
'FirstName' => 'ASC',
|
||||
'LastName'=>'ASC'
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
You can also sort randomly. Using the `DB` class, you can get the random sort method per database type.
|
||||
|
||||
```php
|
||||
|
||||
$random = DB::get_conn()->random();
|
||||
$players = Player::get()->sort($random)
|
||||
```
|
||||
@ -315,10 +300,10 @@ You can also sort randomly. Using the `DB` class, you can get the random sort me
|
||||
The `filter()` method filters the list of objects that gets returned.
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->filter(array(
|
||||
$players = Player::get()->filter([
|
||||
'FirstName' => 'Sam'
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
Each element of the array specifies a filter. You can specify as many filters as you like, and they **all** must be
|
||||
@ -330,42 +315,41 @@ value that you want to filter to.
|
||||
So, this would return only those players called "Sam Minnée".
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->filter(array(
|
||||
$players = Player::get()->filter([
|
||||
'FirstName' => 'Sam',
|
||||
'LastName' => 'Minnée',
|
||||
));
|
||||
]);
|
||||
|
||||
// SELECT * FROM Player WHERE FirstName = 'Sam' AND LastName = 'Minnée'
|
||||
|
||||
```
|
||||
|
||||
There is also a shorthand way of getting Players with the FirstName of Sam.
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->filter('FirstName', 'Sam');
|
||||
```
|
||||
|
||||
Or if you want to find both Sam and Sig.
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->filter(
|
||||
'FirstName', array('Sam', 'Sig')
|
||||
'FirstName', ['Sam', 'Sig']
|
||||
);
|
||||
|
||||
// SELECT * FROM Player WHERE FirstName IN ('Sam', 'Sig')
|
||||
|
||||
```
|
||||
|
||||
You can use [SearchFilters](searchfilters) to add additional behavior to your `filter` command rather than an
|
||||
exact match.
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->filter(array(
|
||||
$players = Player::get()->filter([
|
||||
'FirstName:StartsWith' => 'S'
|
||||
'PlayerNumber:GreaterThan' => '10'
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
### filterAny
|
||||
@ -373,38 +357,38 @@ exact match.
|
||||
Use the `filterAny()` method to match multiple criteria non-exclusively (with an "OR" disjunctive),
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->filterAny(array(
|
||||
$players = Player::get()->filterAny([
|
||||
'FirstName' => 'Sam',
|
||||
'Age' => 17,
|
||||
));
|
||||
]);
|
||||
|
||||
// SELECT * FROM Player WHERE ("FirstName" = 'Sam' OR "Age" = '17')
|
||||
|
||||
```
|
||||
|
||||
You can combine both conjunctive ("AND") and disjunctive ("OR") statements.
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()
|
||||
->filter(array(
|
||||
->filter([
|
||||
'LastName' => 'Minnée'
|
||||
))
|
||||
->filterAny(array(
|
||||
])
|
||||
->filterAny([
|
||||
'FirstName' => 'Sam',
|
||||
'Age' => 17,
|
||||
));
|
||||
]);
|
||||
// SELECT * FROM Player WHERE ("LastName" = 'Minnée' AND ("FirstName" = 'Sam' OR "Age" = '17'))
|
||||
|
||||
```
|
||||
|
||||
You can use [SearchFilters](searchfilters) to add additional behavior to your `filterAny` command.
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->filterAny(array(
|
||||
$players = Player::get()->filterAny([
|
||||
'FirstName:StartsWith' => 'S'
|
||||
'PlayerNumber:GreaterThan' => '10'
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
### Filtering by null values
|
||||
@ -418,7 +402,6 @@ For instance, the below code will select only values that do not match the given
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->filter('FirstName:not', 'Sam');
|
||||
// ... WHERE "FirstName" != 'Sam' OR "FirstName" IS NULL
|
||||
// Returns rows with any value (even null) other than Sam
|
||||
@ -428,21 +411,21 @@ If null values should be excluded, include the null in your check.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->filter('FirstName:not', array('Sam', null));
|
||||
$players = Player::get()->filter('FirstName:not', ['Sam', null]);
|
||||
// ... WHERE "FirstName" != 'Sam' AND "FirstName" IS NOT NULL
|
||||
// Only returns non-null values for "FirstName" that aren't Sam.
|
||||
// Strictly the IS NOT NULL isn't necessary, but is included for explicitness
|
||||
|
||||
```
|
||||
|
||||
It is also often useful to filter by all rows with either empty or null for a given field.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->filter('FirstName', array(null, ''));
|
||||
$players = Player::get()->filter('FirstName', [null, '']);
|
||||
// ... WHERE "FirstName" == '' OR "FirstName" IS NULL
|
||||
// Returns rows with FirstName which is either empty or null
|
||||
|
||||
```
|
||||
|
||||
### Filtering by aggregates
|
||||
@ -480,7 +463,6 @@ for each record, if the callback returns true, this record will be added to the
|
||||
The below example will get all `Players` aged over 10.
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->filterByCallback(function($item, $list) {
|
||||
return ($item->Age() > 10);
|
||||
});
|
||||
@ -491,7 +473,6 @@ The below example will get all `Players` aged over 10.
|
||||
The `exclude()` method is the opposite to the filter in that it removes entries from a list.
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->exclude('FirstName', 'Sam');
|
||||
|
||||
// SELECT * FROM Player WHERE FirstName != 'Sam'
|
||||
@ -500,42 +481,42 @@ The `exclude()` method is the opposite to the filter in that it removes entries
|
||||
Remove both Sam and Sig..
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->exclude(
|
||||
'FirstName', array('Sam','Sig')
|
||||
'FirstName', ['Sam','Sig']
|
||||
);
|
||||
|
||||
```
|
||||
|
||||
`Exclude` follows the same pattern as filter, so for removing only Sam Minnée from the list:
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->exclude(array(
|
||||
$players = Player::get()->exclude([
|
||||
'FirstName' => 'Sam',
|
||||
'Surname' => 'Minnée',
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
And removing Sig and Sam with that are either age 17 or 43.
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->exclude(array(
|
||||
'FirstName' => array('Sam', 'Sig'),
|
||||
'Age' => array(17, 43)
|
||||
));
|
||||
$players = Player::get()->exclude([
|
||||
'FirstName' => ['Sam', 'Sig'],
|
||||
'Age' => [17, 43]
|
||||
]);
|
||||
|
||||
// SELECT * FROM Player WHERE ("FirstName" NOT IN ('Sam','Sig) OR "Age" NOT IN ('17', '43'));
|
||||
|
||||
```
|
||||
|
||||
You can use [SearchFilters](searchfilters) to add additional behavior to your `exclude` command.
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->exclude(array(
|
||||
$players = Player::get()->exclude([
|
||||
'FirstName:EndsWith' => 'S'
|
||||
'PlayerNumber:LessThanOrEqual' => '10'
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
### Subtract
|
||||
@ -543,7 +524,6 @@ You can use [SearchFilters](searchfilters) to add additional behavior to your `e
|
||||
You can subtract entries from a [DataList](api:SilverStripe\ORM\DataList) by passing in another DataList to `subtract()`
|
||||
|
||||
```php
|
||||
|
||||
$sam = Player::get()->filter('FirstName', 'Sam');
|
||||
$players = Player::get();
|
||||
|
||||
@ -554,7 +534,6 @@ Though for the above example it would probably be easier to use `filter()` and `
|
||||
when you want to find all the members that does not exist in a Group.
|
||||
|
||||
```php
|
||||
|
||||
// ... Finding all members that does not belong to $group.
|
||||
$otherMembers = Member::get()->subtract($group->Members());
|
||||
```
|
||||
@ -564,7 +543,6 @@ when you want to find all the members that does not exist in a Group.
|
||||
You can limit the amount of records returned in a DataList by using the `limit()` method.
|
||||
|
||||
```php
|
||||
|
||||
$members = Member::get()->limit(5);
|
||||
```
|
||||
|
||||
@ -573,7 +551,6 @@ parameter to specify the offset, which allows you to tell the system where to st
|
||||
offset, if not provided as an argument, will default to 0.
|
||||
|
||||
```php
|
||||
|
||||
// Return 10 members with an offset of 4 (starting from the 5th result).
|
||||
$members = Member::get()->sort('Surname')->limit(10, 4);
|
||||
```
|
||||
@ -592,7 +569,6 @@ For instance, the below model will be stored in the table name `BannerImage`
|
||||
|
||||
|
||||
```php
|
||||
|
||||
namespace SilverStripe\BannerManager;
|
||||
class BannerImage extends \DataObject {
|
||||
private static $table_name = 'BannerImage';
|
||||
@ -627,7 +603,6 @@ table and column.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function countDuplicates($model, $fieldToCheck) {
|
||||
$table = DataObject::getSchema()->tableForField($model, $field);
|
||||
$query = new SQLSelect();
|
||||
@ -654,7 +629,6 @@ you need it to, you may also consider extending the ORM with new data types or f
|
||||
You can specify a WHERE clause fragment (that will be combined with other filters using AND) with the `where()` method:
|
||||
|
||||
```php
|
||||
|
||||
$members = Member::get()->where("\"FirstName\" = 'Sam'")
|
||||
```
|
||||
|
||||
@ -667,7 +641,6 @@ You can specify a join with the `innerJoin` and `leftJoin` methods. Both of the
|
||||
* An optional alias.
|
||||
|
||||
```php
|
||||
|
||||
// Without an alias
|
||||
$members = Member::get()
|
||||
->leftJoin("Group_Members", "\"Group_Members\".\"MemberID\" = \"Member\".\"ID\"");
|
||||
@ -687,15 +660,14 @@ Define the default values for all the `$db` fields. This example sets the "Statu
|
||||
whenever a new object is created.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Player extends DataObject {
|
||||
|
||||
private static $defaults = array(
|
||||
private static $defaults = [
|
||||
"Status" => 'Active',
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
@ -713,19 +685,18 @@ time.
|
||||
For example, suppose we have the following set of classes:
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Page extends SiteTree {
|
||||
|
||||
}
|
||||
|
||||
class NewsPage extends Page {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Summary' => 'Text'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The data for the following classes would be stored across the following tables:
|
||||
@ -747,7 +718,6 @@ The data for the following classes would be stored across the following tables:
|
||||
Accessing the data is transparent to the developer.
|
||||
|
||||
```php
|
||||
|
||||
$news = NewsPage::get();
|
||||
|
||||
foreach($news as $article) {
|
||||
|
@ -16,26 +16,25 @@ A 1-to-1 relation creates a database-column called "`<relationship-name>`ID", in
|
||||
"TeamID" on the "Player"-table.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Team extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Title' => 'Varchar'
|
||||
);
|
||||
];
|
||||
|
||||
private static $has_many = array(
|
||||
private static $has_many = [
|
||||
'Players' => 'Player'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
class Player extends DataObject {
|
||||
|
||||
private static $has_one = array(
|
||||
private static $has_one = [
|
||||
"Team" => "Team",
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
This defines a relationship called `Team` which links to a `Team` class. The `ORM` handles navigating the relationship
|
||||
@ -44,7 +43,6 @@ and provides a short syntax for accessing the related object.
|
||||
At the database level, the `has_one` creates a `TeamID` field on `Player`. A `has_many` field does not impose any database changes. It merely injects a new method into the class to access the related records (in this case, `Players()`)
|
||||
|
||||
```php
|
||||
|
||||
$player = Player::get()->byId(1);
|
||||
|
||||
$team = $player->Team();
|
||||
@ -77,28 +75,27 @@ To specify that a has_one relation is polymorphic set the type to 'DataObject'.
|
||||
Ideally, the associated has_many (or belongs_to) should be specified with dot notation.
|
||||
|
||||
```php
|
||||
|
||||
|
||||
class Player extends DataObject {
|
||||
private static $has_many = array(
|
||||
private static $has_many = [
|
||||
"Fans" => "Fan.FanOf"
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
class Team extends DataObject {
|
||||
private static $has_many = array(
|
||||
private static $has_many = [
|
||||
"Fans" => "Fan.FanOf"
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
// Type of object returned by $fan->FanOf() will vary
|
||||
class Fan extends DataObject {
|
||||
|
||||
// Generates columns FanOfID and FanOfClass
|
||||
private static $has_one = array(
|
||||
private static $has_one = [
|
||||
"FanOf" => "DataObject"
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<div class="warning" markdown='1'>
|
||||
@ -119,33 +116,31 @@ available on both ends.
|
||||
</div>
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Team extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Title' => 'Varchar'
|
||||
);
|
||||
];
|
||||
|
||||
private static $has_many = array(
|
||||
private static $has_many = [
|
||||
'Players' => 'Player'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
class Player extends DataObject {
|
||||
|
||||
private static $has_one = array(
|
||||
private static $has_one = [
|
||||
"Team" => "Team",
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Much like the `has_one` relationship, `has_many` can be navigated through the `ORM` as well. The only difference being
|
||||
you will get an instance of [HasManyList](api:SilverStripe\ORM\HasManyList) rather than the object.
|
||||
|
||||
```php
|
||||
|
||||
$team = Team::get()->first();
|
||||
|
||||
echo $team->Players();
|
||||
@ -162,24 +157,23 @@ you will get an instance of [HasManyList](api:SilverStripe\ORM\HasManyList) rath
|
||||
To specify multiple `$has_many` to the same object you can use dot notation to distinguish them like below:
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Person extends DataObject {
|
||||
|
||||
private static $has_many = array(
|
||||
private static $has_many = [
|
||||
"Managing" => "Company.Manager",
|
||||
"Cleaning" => "Company.Cleaner",
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
class Company extends DataObject {
|
||||
|
||||
private static $has_one = array(
|
||||
private static $has_one = [
|
||||
"Manager" => "Person",
|
||||
"Cleaner" => "Person"
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Multiple `$has_one` relationships are okay if they aren't linking to the same object type. Otherwise, they have to be
|
||||
@ -207,22 +201,21 @@ Similarly with `$has_many`, dot notation can be used to explicitly specify the `
|
||||
This is not mandatory unless the relationship would be otherwise ambiguous.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Team extends DataObject {
|
||||
|
||||
private static $has_one = array(
|
||||
private static $has_one = [
|
||||
'Coach' => 'Coach'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
class Coach extends DataObject {
|
||||
|
||||
private static $belongs_to = array(
|
||||
private static $belongs_to = [
|
||||
'Team' => 'Team.Coach'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## many_many
|
||||
@ -241,7 +234,6 @@ The only difference being you will get an instance of [ManyManyList](api:SilverS
|
||||
[ManyManyThroughList](api:SilverStripe\ORM\ManyManyThroughList) rather than the object.
|
||||
|
||||
```php
|
||||
|
||||
$team = Team::get()->byId(1);
|
||||
|
||||
$supporters = $team->Supporters();
|
||||
@ -259,9 +251,7 @@ config to add extra columns.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Team extends DataObject {
|
||||
private static $many_many = [
|
||||
"Supporters" => "Supporter",
|
||||
@ -304,9 +294,7 @@ or child record.
|
||||
The syntax for `belongs_many_many` is unchanged.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Team extends DataObject {
|
||||
private static $many_many = [
|
||||
"Supporters" => [
|
||||
@ -340,7 +328,6 @@ for any sql conditions.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$team = Team::get()->byId(1);
|
||||
$supporters = $team->Supporters()->where(['"TeamSupporter"."Ranking"' => 1]);
|
||||
```
|
||||
@ -376,24 +363,23 @@ distinguish them like below:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Category extends DataObject {
|
||||
|
||||
private static $many_many = array(
|
||||
private static $many_many = [
|
||||
'Products' => 'Product',
|
||||
'FeaturedProducts' => 'Product'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
class Product extends DataObject {
|
||||
|
||||
private static $belongs_many_many = array(
|
||||
private static $belongs_many_many = [
|
||||
'Categories' => 'Category.Products',
|
||||
'FeaturedInCategories' => 'Category.FeaturedProducts'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
If you're unsure about whether an object should take on `many_many` or `belongs_many_many`,
|
||||
@ -409,7 +395,6 @@ encapsulated by [HasManyList](api:SilverStripe\ORM\HasManyList) and [ManyManyLis
|
||||
and `remove()` method.
|
||||
|
||||
```php
|
||||
|
||||
$team = Team::get()->byId(1);
|
||||
|
||||
// create a new supporter
|
||||
@ -429,19 +414,18 @@ You can use the ORM to get a filtered result list without writing any SQL. For e
|
||||
See [DataObject::$has_many](api:SilverStripe\ORM\DataObject::$has_many) for more info on the described relations.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Team extends DataObject {
|
||||
|
||||
private static $has_many = array(
|
||||
private static $has_many = [
|
||||
"Players" => "Player"
|
||||
);
|
||||
];
|
||||
|
||||
public function ActivePlayers() {
|
||||
return $this->Players()->filter('Status', 'Active');
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
|
@ -12,7 +12,6 @@ modify.
|
||||
[SS_List](api:SilverStripe\ORM\SS_List) implements `IteratorAggregate`, allowing you to loop over the instance.
|
||||
|
||||
```php
|
||||
|
||||
$members = Member::get();
|
||||
|
||||
foreach($members as $member) {
|
||||
@ -32,7 +31,6 @@ Or in the template engine:
|
||||
## Finding an item by value.
|
||||
|
||||
```php
|
||||
|
||||
// $list->find($key, $value);
|
||||
|
||||
//
|
||||
@ -47,7 +45,6 @@ Or in the template engine:
|
||||
A map is an array where the array indexes contain data as well as the values. You can build a map from any list
|
||||
|
||||
```php
|
||||
|
||||
$members = Member::get()->map('ID', 'FirstName');
|
||||
|
||||
// $members = array(
|
||||
@ -55,12 +52,12 @@ A map is an array where the array indexes contain data as well as the values. Yo
|
||||
// 2 => 'Sig'
|
||||
// 3 => 'Will'
|
||||
// );
|
||||
|
||||
```
|
||||
|
||||
This functionality is provided by the [Map](api:SilverStripe\ORM\Map) class, which can be used to build a map around any `SS_List`.
|
||||
|
||||
```php
|
||||
|
||||
$members = Member::get();
|
||||
$map = new Map($members, 'ID', 'FirstName');
|
||||
```
|
||||
@ -68,7 +65,6 @@ This functionality is provided by the [Map](api:SilverStripe\ORM\Map) class, whi
|
||||
## Column
|
||||
|
||||
```php
|
||||
|
||||
$members = Member::get();
|
||||
|
||||
echo $members->column('Email');
|
||||
@ -78,6 +74,7 @@ This functionality is provided by the [Map](api:SilverStripe\ORM\Map) class, whi
|
||||
// 'sig@silverstripe.com',
|
||||
// 'will@silverstripe.com'
|
||||
// );
|
||||
|
||||
```
|
||||
|
||||
## ArrayList
|
||||
@ -85,7 +82,6 @@ This functionality is provided by the [Map](api:SilverStripe\ORM\Map) class, whi
|
||||
[ArrayList](api:SilverStripe\ORM\ArrayList) exists to wrap a standard PHP array in the same API as a database backed list.
|
||||
|
||||
```php
|
||||
|
||||
$sam = Member::get()->byId(5);
|
||||
$sig = Member::get()->byId(6);
|
||||
|
||||
@ -95,6 +91,7 @@ This functionality is provided by the [Map](api:SilverStripe\ORM\Map) class, whi
|
||||
|
||||
echo $list->Count();
|
||||
// returns '2'
|
||||
|
||||
```
|
||||
|
||||
## API Documentation
|
||||
|
@ -14,18 +14,17 @@ In the `Player` example, we have four database columns each with a different dat
|
||||
**mysite/code/Player.php**
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Player extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'PlayerNumber' => 'Int',
|
||||
'FirstName' => 'Varchar(255)',
|
||||
'LastName' => 'Text',
|
||||
'Birthday' => 'Date'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Available Types
|
||||
@ -54,21 +53,20 @@ For complex default values for newly instantiated objects see [Dynamic Default V
|
||||
For simple values you can make use of the `$defaults` array. For example:
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Car extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Wheels' => 'Int',
|
||||
'Condition' => 'Enum(array("New","Fair","Junk"))'
|
||||
);
|
||||
];
|
||||
|
||||
private static $defaults = array(
|
||||
private static $defaults = [
|
||||
'Wheels' => 4,
|
||||
'Condition' => 'New'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Default values for new database columns
|
||||
@ -86,17 +84,16 @@ For enum values, it's the second parameter.
|
||||
For example:
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Car extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Wheels' => 'Int(4)',
|
||||
'Condition' => 'Enum(array("New","Fair","Junk"), "New")',
|
||||
'Make' => 'Varchar(["default" => "Honda"]),
|
||||
);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Formatting Output
|
||||
@ -110,9 +107,7 @@ object we can control the formatting and it allows us to call methods defined fr
|
||||
**mysite/code/Player.php**
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Player extends DataObject {
|
||||
|
||||
..
|
||||
@ -126,7 +121,6 @@ object we can control the formatting and it allows us to call methods defined fr
|
||||
Then we can refer to a new `Name` column on our `Player` instances. In templates we don't need to use the `get` prefix.
|
||||
|
||||
```php
|
||||
|
||||
$player = Player::get()->byId(1);
|
||||
|
||||
echo $player->Name;
|
||||
@ -144,19 +138,18 @@ Then we can refer to a new `Name` column on our `Player` instances. In templates
|
||||
Rather than manually returning objects from your custom functions. You can use the `$casting` property.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Player extends DataObject {
|
||||
|
||||
private static $casting = array(
|
||||
private static $casting = [
|
||||
"Name" => 'Varchar',
|
||||
);
|
||||
];
|
||||
|
||||
public function getName() {
|
||||
return $this->FirstName . ' '. $this->LastName;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The properties on any SilverStripe object can be type casted automatically, by transforming its scalar value into an
|
||||
@ -167,7 +160,6 @@ On the most basic level, the class can be used as simple conversion class from o
|
||||
number.
|
||||
|
||||
```php
|
||||
|
||||
DBField::create_field('Double', 1.23456)->Round(2); // results in 1.23
|
||||
```
|
||||
|
||||
@ -175,7 +167,6 @@ Of course that's much more verbose than the equivalent PHP call. The power of [D
|
||||
sophisticated helpers, like showing the time difference to the current date:
|
||||
|
||||
```php
|
||||
|
||||
DBField::create_field('Date', '1982-01-01')->TimeDiff(); // shows "30 years ago"
|
||||
```
|
||||
|
||||
@ -185,14 +176,12 @@ Most objects in SilverStripe extend from [ViewableData](api:SilverStripe\View\Vi
|
||||
context. Through a `$casting` array, arbitrary properties and getters can be casted:
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyObject extends ViewableData {
|
||||
|
||||
private static $casting = array(
|
||||
private static $casting = [
|
||||
'MyDate' => 'Date'
|
||||
);
|
||||
];
|
||||
|
||||
public function getMyDate() {
|
||||
return '1982-01-01';
|
||||
@ -204,6 +193,7 @@ context. Through a `$casting` array, arbitrary properties and getters can be cas
|
||||
$obj->MyDate; // returns string
|
||||
$obj->obj('MyDate'); // returns object
|
||||
$obj->obj('MyDate')->InPast(); // returns boolean
|
||||
|
||||
```
|
||||
|
||||
## Casting HTML Text
|
||||
@ -225,18 +215,17 @@ The following example will use the result of `getStatus` instead of the 'Status'
|
||||
database column using `dbObject`.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Player extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
"Status" => "Enum(array('Active', 'Injured', 'Retired'))"
|
||||
);
|
||||
];
|
||||
|
||||
public function getStatus() {
|
||||
return (!$this->obj("Birthday")->InPast()) ? "Unborn" : $this->dbObject('Status')->Value();
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## API Documentation
|
||||
|
@ -19,14 +19,12 @@ a `ModelAdmin` record.
|
||||
Example: Disallow creation of new players if the currently logged-in player is not a team-manager.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Player extends DataObject {
|
||||
|
||||
private static $has_many = array(
|
||||
private static $has_many = [
|
||||
"Teams"=>"Team"
|
||||
);
|
||||
];
|
||||
|
||||
public function onBeforeWrite() {
|
||||
// check on first write action, aka "database row creation" (ID-property is not set)
|
||||
@ -50,6 +48,7 @@ Example: Disallow creation of new players if the currently logged-in player is n
|
||||
parent::onBeforeWrite();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## onBeforeDelete
|
||||
@ -60,14 +59,12 @@ Example: Checking for a specific [permission](permissions) to delete this type o
|
||||
member is logged in who belongs to a group containing the permission "PLAYER_DELETE".
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Player extends DataObject {
|
||||
|
||||
private static $has_many = array(
|
||||
private static $has_many = [
|
||||
"Teams" => "Team"
|
||||
);
|
||||
];
|
||||
|
||||
public function onBeforeDelete() {
|
||||
if(!Permission::check('PLAYER_DELETE')) {
|
||||
@ -78,6 +75,7 @@ member is logged in who belongs to a group containing the permission "PLAYER_DEL
|
||||
parent::onBeforeDelete();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown='1'>
|
||||
|
@ -17,18 +17,18 @@ you can put on field names to change this behavior. These are represented as `Se
|
||||
An example of a `SearchFilter` in use:
|
||||
|
||||
```php
|
||||
|
||||
// fetch any player that starts with a S
|
||||
$players = Player::get()->filter(array(
|
||||
$players = Player::get()->filter([
|
||||
'FirstName:StartsWith' => 'S',
|
||||
'PlayerNumber:GreaterThan' => '10'
|
||||
));
|
||||
]);
|
||||
|
||||
// to fetch any player that's name contains the letter 'z'
|
||||
$players = Player::get()->filterAny(array(
|
||||
$players = Player::get()->filterAny([
|
||||
'FirstName:PartialMatch' => 'z',
|
||||
'LastName:PartialMatch' => 'z'
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
Developers can define their own [SearchFilter](api:SilverStripe\ORM\Filters\SearchFilter) if needing to extend the ORM filter and exclude behaviors.
|
||||
@ -53,15 +53,15 @@ config:
|
||||
The following is a query which will return everyone whose first name starts with "S", either lowercase or uppercase:
|
||||
|
||||
```php
|
||||
|
||||
$players = Player::get()->filter(array(
|
||||
$players = Player::get()->filter([
|
||||
'FirstName:StartsWith:nocase' => 'S'
|
||||
));
|
||||
]);
|
||||
|
||||
// use :not to perform a converse operation to filter anything but a 'W'
|
||||
$players = Player::get()->filter(array(
|
||||
$players = Player::get()->filter([
|
||||
'FirstName:StartsWith:not' => 'W'
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
## API Documentation
|
||||
|
@ -17,9 +17,7 @@ code.
|
||||
</div>
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyDataObject extends DataObject {
|
||||
|
||||
public function canView($member = null) {
|
||||
|
@ -19,7 +19,6 @@ For example, if you want to run a simple `COUNT` SQL statement,
|
||||
the following three statements are functionally equivalent:
|
||||
|
||||
```php
|
||||
|
||||
// Through raw SQL.
|
||||
$count = DB::query('SELECT COUNT(*) FROM "Member"')->value();
|
||||
|
||||
@ -59,15 +58,13 @@ conditional filters, grouping, limiting, and sorting.
|
||||
E.g.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
$sqlQuery = new SQLSelect();
|
||||
$sqlQuery->setFrom('Player');
|
||||
$sqlQuery->selectField('FieldName', 'Name');
|
||||
$sqlQuery->selectField('YEAR("Birthday")', 'Birthyear');
|
||||
$sqlQuery->addLeftJoin('Team','"Player"."TeamID" = "Team"."ID"');
|
||||
$sqlQuery->addWhere(array('YEAR("Birthday") = ?' => 1982));
|
||||
$sqlQuery->addWhere(['YEAR("Birthday") = ?' => 1982]);
|
||||
// $sqlQuery->setOrderBy(...);
|
||||
// $sqlQuery->setGroupBy(...);
|
||||
// $sqlQuery->setHaving(...);
|
||||
@ -84,6 +81,7 @@ E.g.
|
||||
foreach($result as $row) {
|
||||
echo $row['BirthYear'];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The result of `SQLSelect::execute()` is an array lightly wrapped in a database-specific subclass of [Query](api:SilverStripe\ORM\Connect\Query).
|
||||
@ -98,35 +96,32 @@ object instead.
|
||||
For example, creating a `SQLDelete` object
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
$query = SQLDelete::create()
|
||||
->setFrom('"SiteTree"')
|
||||
->setWhere(array('"SiteTree"."ShowInMenus"' => 0));
|
||||
->setWhere(['"SiteTree"."ShowInMenus"' => 0]);
|
||||
$query->execute();
|
||||
|
||||
```
|
||||
|
||||
Alternatively, turning an existing `SQLQuery` into a delete
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
$query = SQLQuery::create()
|
||||
->setFrom('"SiteTree"')
|
||||
->setWhere(array('"SiteTree"."ShowInMenus"' => 0))
|
||||
->setWhere(['"SiteTree"."ShowInMenus"' => 0])
|
||||
->toDelete();
|
||||
$query->execute();
|
||||
|
||||
```
|
||||
|
||||
Directly querying the database
|
||||
|
||||
```php
|
||||
|
||||
DB::prepared_query('DELETE FROM "SiteTree" WHERE "SiteTree"."ShowInMenus" = ?', [0]);
|
||||
|
||||
<?php
|
||||
|
||||
DB::prepared_query('DELETE FROM "SiteTree" WHERE "SiteTree"."ShowInMenus" = ?', array(0));
|
||||
```
|
||||
|
||||
### INSERT/UPDATE
|
||||
@ -174,31 +169,30 @@ SQLInsert also includes the following api methods:
|
||||
E.g.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
$update = SQLUpdate::create('"SiteTree"')->addWhere(array('ID' => 3));
|
||||
$update = SQLUpdate::create('"SiteTree"')->addWhere(['ID' => 3]);
|
||||
|
||||
// assigning a list of items
|
||||
$update->addAssignments(array(
|
||||
$update->addAssignments([
|
||||
'"Title"' => 'Our Products',
|
||||
'"MenuTitle"' => 'Products'
|
||||
));
|
||||
]);
|
||||
|
||||
// Assigning a single value
|
||||
$update->assign('"MenuTitle"', 'Products');
|
||||
|
||||
// Assigning a value using parameterised expression
|
||||
$title = 'Products';
|
||||
$update->assign('"MenuTitle"', array(
|
||||
$update->assign('"MenuTitle"', [
|
||||
'CASE WHEN LENGTH("MenuTitle") > LENGTH(?) THEN "MenuTitle" ELSE ? END' =>
|
||||
array($title, $title)
|
||||
));
|
||||
[$title, $title]
|
||||
]);
|
||||
|
||||
// Assigning a value using a pure SQL expression
|
||||
$update->assignSQL('"Date"', 'NOW()');
|
||||
|
||||
// Perform the update
|
||||
$update->execute();
|
||||
|
||||
```
|
||||
|
||||
In addition to assigning values, the SQLInsert object also supports multi-row
|
||||
@ -208,27 +202,26 @@ these are translated internally as multiple single row inserts.
|
||||
For example,
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
$insert = SQLInsert::create('"SiteTree"');
|
||||
$insert = SQLInsert::create('"SiteTree"');
|
||||
|
||||
// Add multiple rows in a single call. Note that column names do not need
|
||||
// to be symmetric
|
||||
$insert->addRows(array(
|
||||
array('"Title"' => 'Home', '"Content"' => '<p>This is our home page</p>'),
|
||||
array('"Title"' => 'About Us', '"ClassName"' => 'AboutPage')
|
||||
));
|
||||
$insert->addRows([
|
||||
['"Title"' => 'Home', '"Content"' => '<p>This is our home page</p>'],
|
||||
['"Title"' => 'About Us', '"ClassName"' => 'AboutPage']
|
||||
]);
|
||||
|
||||
// Adjust an assignment on the last row
|
||||
$insert->assign('"Content"', '<p>This is about us</p>');
|
||||
|
||||
// Add another row
|
||||
$insert->addRow(array('"Title"' => 'Contact Us'));
|
||||
$insert->addRow(['"Title"' => 'Contact Us']);
|
||||
|
||||
$columns = $insert->getColumns();
|
||||
// $columns will be array('"Title"', '"Content"', '"ClassName"');
|
||||
|
||||
$insert->execute();
|
||||
|
||||
```
|
||||
|
||||
### Value Checks
|
||||
@ -239,19 +232,18 @@ e.g. when you want a single column rather than a full-blown object representatio
|
||||
Example: Get the count from a relationship.
|
||||
|
||||
```php
|
||||
|
||||
$sqlQuery = new SQLSelect();
|
||||
$sqlQuery->setFrom('Player');
|
||||
$sqlQuery->addSelect('COUNT("Player"."ID")');
|
||||
$sqlQuery->addWhere(array('"Team"."ID"' => 99));
|
||||
$sqlQuery->addWhere(['"Team"."ID"' => 99]);
|
||||
$sqlQuery->addLeftJoin('Team', '"Team"."ID" = "Player"."TeamID"');
|
||||
$count = $sqlQuery->execute()->value();
|
||||
|
||||
```
|
||||
|
||||
Note that in the ORM, this call would be executed in an efficient manner as well:
|
||||
|
||||
```php
|
||||
|
||||
$count = $myTeam->Players()->count();
|
||||
```
|
||||
|
||||
@ -263,7 +255,6 @@ This can be useful for creating dropdowns.
|
||||
Example: Show player names with their birth year, but set their birth dates as values.
|
||||
|
||||
```php
|
||||
|
||||
$sqlQuery = new SQLSelect();
|
||||
$sqlQuery->setFrom('Player');
|
||||
$sqlQuery->setSelect('Birthdate');
|
||||
@ -277,18 +268,18 @@ because of the custom SQL value transformation (`YEAR()`).
|
||||
An alternative approach would be a custom getter in the object definition.
|
||||
|
||||
```php
|
||||
|
||||
class Player extends DataObject {
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Name' => 'Varchar',
|
||||
'Birthdate' => 'Date'
|
||||
);
|
||||
];
|
||||
function getNameWithBirthyear() {
|
||||
return date('y', $this->Birthdate);
|
||||
}
|
||||
}
|
||||
$players = Player::get();
|
||||
$map = $players->map('Name', 'NameWithBirthyear');
|
||||
|
||||
```
|
||||
|
||||
## Related
|
||||
|
@ -22,15 +22,13 @@ write, and respond appropriately if it isn't.
|
||||
The return value of `validate()` is a [ValidationResult](api:SilverStripe\ORM\ValidationResult) object.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyObject extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Country' => 'Varchar',
|
||||
'Postcode' => 'Varchar'
|
||||
);
|
||||
];
|
||||
|
||||
public function validate() {
|
||||
$result = parent::validate();
|
||||
@ -42,6 +40,7 @@ The return value of `validate()` is a [ValidationResult](api:SilverStripe\ORM\Va
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## API Documentation
|
||||
|
@ -21,7 +21,6 @@ also track versioned history.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyStagedModel extends DataObject {
|
||||
private static $extensions = [
|
||||
Versioned::class
|
||||
@ -34,7 +33,6 @@ can be specified by setting the constructor argument to "Versioned"
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class VersionedModel extends DataObject {
|
||||
private static $extensions = [
|
||||
"SilverStripe\\ORM\\Versioning\\Versioned('Versioned')"
|
||||
@ -82,7 +80,6 @@ By default, all records are retrieved from the "Draft" stage (so the `MyRecord`
|
||||
explicitly request a certain stage through various getters on the `Versioned` class.
|
||||
|
||||
```php
|
||||
|
||||
// Fetching multiple records
|
||||
$stageRecords = Versioned::get_by_stage('MyRecord', Versioned::DRAFT);
|
||||
$liveRecords = Versioned::get_by_stage('MyRecord', Versioned::LIVE);
|
||||
@ -98,7 +95,6 @@ The above commands will just retrieve the latest version of its respective stage
|
||||
in the `<class>_versions` tables.
|
||||
|
||||
```php
|
||||
|
||||
$historicalRecord = Versioned::get_version('MyRecord', <record-id>, <version-id>);
|
||||
```
|
||||
|
||||
@ -112,7 +108,6 @@ objects, which expose the same database information as a `DataObject`, but also
|
||||
a record was published.
|
||||
|
||||
```php
|
||||
|
||||
$record = MyRecord::get()->byID(99); // stage doesn't matter here
|
||||
$versions = $record->allVersions();
|
||||
echo $versions->First()->Version; // instance of Versioned_Version
|
||||
@ -139,7 +134,6 @@ done via one of several ways:
|
||||
See "DataObject ownership" for reference on dependant objects.
|
||||
|
||||
```php
|
||||
|
||||
$record = Versioned::get_by_stage('MyRecord', Versioned::DRAFT)->byID(99);
|
||||
$record->MyField = 'changed';
|
||||
// will update `MyRecord` table (assuming Versioned::current_stage() == 'Stage'),
|
||||
@ -152,7 +146,6 @@ done via one of several ways:
|
||||
Similarly, an "unpublish" operation does the reverse, and removes a record from a specific stage.
|
||||
|
||||
```php
|
||||
|
||||
$record = MyRecord::get()->byID(99); // stage doesn't matter here
|
||||
// will remove the row from the `MyRecord_Live` table
|
||||
$record->deleteFromStage(Versioned::LIVE);
|
||||
@ -164,7 +157,6 @@ The current stage is stored as global state on the object. It is usually modifie
|
||||
is initialized. But it can also be set and reset temporarily to force a specific operation to run on a certain stage.
|
||||
|
||||
```php
|
||||
|
||||
$origMode = Versioned::get_reading_mode(); // save current mode
|
||||
$obj = MyRecord::getComplexObjectRetrieval(); // returns 'Live' records
|
||||
Versioned::set_reading_mode(Versioned::DRAFT); // temporarily overwrite mode
|
||||
@ -192,28 +184,28 @@ without requiring any custom code.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyPage extends Page {
|
||||
private static $has_many = array(
|
||||
private static $has_many = [
|
||||
'Banners' => Banner::class
|
||||
);
|
||||
private static $owns = array(
|
||||
];
|
||||
private static $owns = [
|
||||
'Banners'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
class Banner extends Page {
|
||||
private static $extensions = array(
|
||||
private static $extensions = [
|
||||
Versioned::class
|
||||
);
|
||||
private static $has_one = array(
|
||||
];
|
||||
private static $has_one = [
|
||||
'Parent' => MyPage::class,
|
||||
'Image' => Image::class,
|
||||
);
|
||||
private static $owns = array(
|
||||
];
|
||||
private static $owns = [
|
||||
'Image'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Note that ownership cannot be used with polymorphic relations. E.g. has_one to non-type specific `DataObject`.
|
||||
@ -232,29 +224,29 @@ that can be used to traverse between each, and then by ensuring you configure bo
|
||||
E.g.
|
||||
|
||||
```php
|
||||
|
||||
class MyParent extends DataObject {
|
||||
private static $extensions = array(
|
||||
private static $extensions = [
|
||||
Versioned::class
|
||||
);
|
||||
private static $owns = array(
|
||||
];
|
||||
private static $owns = [
|
||||
'ChildObjects'
|
||||
);
|
||||
];
|
||||
public function ChildObjects() {
|
||||
return MyChild::get();
|
||||
}
|
||||
}
|
||||
class MyChild extends DataObject {
|
||||
private static $extensions = array(
|
||||
private static $extensions = [
|
||||
Versioned::class
|
||||
);
|
||||
private static $owned_by = array(
|
||||
];
|
||||
private static $owned_by = [
|
||||
'Parent'
|
||||
);
|
||||
];
|
||||
public function Parent() {
|
||||
return MyParent::get()->first();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### DataObject Ownership in HTML Content
|
||||
@ -275,7 +267,6 @@ smaller modifications of the generated `DataList` objects.
|
||||
Example: Get the first 10 live records, filtered by creation date:
|
||||
|
||||
```php
|
||||
|
||||
$records = Versioned::get_by_stage('MyRecord', Versioned::LIVE)->limit(10)->sort('Created', 'ASC');
|
||||
```
|
||||
|
||||
@ -300,11 +291,10 @@ Versioned object visibility can be customised in one of the following ways by ed
|
||||
E.g.
|
||||
|
||||
```php
|
||||
|
||||
class MyObject extends DataObject {
|
||||
private static $extensions = array(
|
||||
private static $extensions = [
|
||||
Versioned::class,
|
||||
);
|
||||
];
|
||||
|
||||
public function canViewVersioned($member = null) {
|
||||
// Check if site is live
|
||||
@ -318,6 +308,7 @@ E.g.
|
||||
return Permission::checkMember($member, 'ADMIN');
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
If you want to control permissions of an object in an extension, you can also use
|
||||
@ -332,7 +323,6 @@ only be invoked if the object is in a non-published state.
|
||||
E.g.
|
||||
|
||||
```php
|
||||
|
||||
class MyObjectExtension extends DataExtension {
|
||||
public function canViewNonLive($member = null) {
|
||||
return Permission::check($member, 'DRAFT_STATUS');
|
||||
@ -346,13 +336,13 @@ permissions in the `TargetObject.non_live_permissions` config.
|
||||
E.g.
|
||||
|
||||
```php
|
||||
|
||||
class MyObject extends DataObject {
|
||||
private static $extensions = array(
|
||||
private static $extensions = [
|
||||
Versioned::class,
|
||||
);
|
||||
private static $non_live_permissions = array('ADMIN');
|
||||
];
|
||||
private static $non_live_permissions = ['ADMIN'];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Versioned applies no additional permissions to `canEdit` or `canCreate`, and such
|
||||
@ -371,7 +361,6 @@ to force a specific stage, we recommend the `Controller->init()` method for this
|
||||
|
||||
**mysite/code/MyController.php**
|
||||
```php
|
||||
|
||||
public function init() {
|
||||
parent::init();
|
||||
Versioned::set_stage(Versioned::DRAFT);
|
||||
|
@ -13,16 +13,14 @@ customise those fields as required.
|
||||
An example is `DataObject`, SilverStripe will automatically create your CMS interface so you can modify what you need.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyDataObject extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'IsActive' => 'Boolean',
|
||||
'Title' => 'Varchar',
|
||||
'Content' => 'Text'
|
||||
);
|
||||
];
|
||||
|
||||
public function getCMSFields() {
|
||||
// parent::getCMSFields() does all the hard work and creates the fields for Title, IsActive and Content.
|
||||
@ -32,14 +30,13 @@ An example is `DataObject`, SilverStripe will automatically create your CMS inte
|
||||
return $fields;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
To fully customise your form fields, start with an empty FieldList.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
public function getCMSFields() {
|
||||
$fields = FieldList::create(
|
||||
TabSet::create("Root.Main",
|
||||
@ -63,16 +60,15 @@ The `$searchable_fields` property uses a mixed array format that can be used to
|
||||
system. The default is a set of array values listing the fields.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyDataObject extends DataObject {
|
||||
|
||||
private static $searchable_fields = array(
|
||||
private static $searchable_fields = [
|
||||
'Name',
|
||||
'ProductCode'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Searchable fields will be appear in the search interface with a default form field (usually a [TextField](api:SilverStripe\Forms\TextField)) and a
|
||||
@ -80,74 +76,71 @@ default search filter assigned (usually an [ExactMatchFilter](api:SilverStripe\O
|
||||
additional information on `$searchable_fields`:
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyDataObject extends DataObject {
|
||||
|
||||
private static $searchable_fields = array(
|
||||
private static $searchable_fields = [
|
||||
'Name' => 'PartialMatchFilter',
|
||||
'ProductCode' => 'NumericField'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
If you assign a single string value, you can set it to be either a [FormField](api:SilverStripe\Forms\FormField) or [SearchFilter](api:SilverStripe\ORM\Filters\SearchFilter). To specify
|
||||
both, you can assign an array:
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyDataObject extends DataObject {
|
||||
|
||||
private static $searchable_fields = array(
|
||||
'Name' => array(
|
||||
private static $searchable_fields = [
|
||||
'Name' => [
|
||||
'field' => 'TextField',
|
||||
'filter' => 'PartialMatchFilter',
|
||||
),
|
||||
'ProductCode' => array(
|
||||
],
|
||||
'ProductCode' => [
|
||||
'title' => 'Product code #',
|
||||
'field' => 'NumericField',
|
||||
'filter' => 'PartialMatchFilter',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
To include relations (`$has_one`, `$has_many` and `$many_many`) in your search, you can use a dot-notation.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Team extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Title' => 'Varchar'
|
||||
);
|
||||
];
|
||||
|
||||
private static $many_many = array(
|
||||
private static $many_many = [
|
||||
'Players' => 'Player'
|
||||
);
|
||||
];
|
||||
|
||||
private static $searchable_fields = array(
|
||||
private static $searchable_fields = [
|
||||
'Title',
|
||||
'Players.Name',
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
class Player extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Name' => 'Varchar',
|
||||
'Birthday' => 'Date'
|
||||
);
|
||||
];
|
||||
|
||||
private static $belongs_many_many = array(
|
||||
private static $belongs_many_many = [
|
||||
'Teams' => 'Team'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Summary Fields
|
||||
@ -156,77 +149,74 @@ Summary fields can be used to show a quick overview of the data for a specific [
|
||||
is their display as table columns, e.g. in the search results of a [ModelAdmin](api:SilverStripe\Admin\ModelAdmin) CMS interface.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyDataObject extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Name' => 'Text',
|
||||
'OtherProperty' => 'Text',
|
||||
'ProductCode' => 'Int',
|
||||
);
|
||||
];
|
||||
|
||||
private static $summary_fields = array(
|
||||
private static $summary_fields = [
|
||||
'Name',
|
||||
'ProductCode'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
To include relations or field manipulations in your summaries, you can use a dot-notation.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class OtherObject extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Title' => 'Varchar'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
class MyDataObject extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Name' => 'Text',
|
||||
'Description' => 'HTMLText'
|
||||
);
|
||||
];
|
||||
|
||||
private static $has_one = array(
|
||||
private static $has_one = [
|
||||
'OtherObject' => 'OtherObject'
|
||||
);
|
||||
];
|
||||
|
||||
private static $summary_fields = array(
|
||||
private static $summary_fields = [
|
||||
'Name' => 'Name',
|
||||
'Description.Summary' => 'Description (summary)',
|
||||
'OtherObject.Title' => 'Other Object Title'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Non-textual elements (such as images and their manipulations) can also be used in summaries.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyDataObject extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Name' => 'Text'
|
||||
);
|
||||
];
|
||||
|
||||
private static $has_one = array(
|
||||
private static $has_one = [
|
||||
'HeroImage' => 'Image'
|
||||
);
|
||||
];
|
||||
|
||||
private static $summary_fields = array(
|
||||
private static $summary_fields = [
|
||||
'Name' => 'Name',
|
||||
'HeroImage.CMSThumbnail' => 'Hero Image'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
@ -25,9 +25,7 @@ Indexes are represented on a `DataObject` through the `DataObject::$indexes` arr
|
||||
descriptor. There are several supported notations:
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyObject extends DataObject {
|
||||
|
||||
private static $indexes = [
|
||||
@ -55,9 +53,7 @@ support the following:
|
||||
**mysite/code/MyTestObject.php**
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyTestObject extends DataObject {
|
||||
|
||||
private static $db = [
|
||||
|
@ -39,9 +39,9 @@ will be used both for grouping and for the title in the template.
|
||||
|
||||
class Module extends DataObject
|
||||
{
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Title' => 'Text'
|
||||
);
|
||||
];
|
||||
|
||||
/**
|
||||
* Returns the first letter of the module title, used for grouping.
|
||||
@ -52,6 +52,7 @@ will be used both for grouping and for the title in the template.
|
||||
return $this->Title[0];
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The next step is to create a method or variable that will contain/return all the objects,
|
||||
|
@ -104,7 +104,6 @@ Variables can come from your database fields, or custom methods you define on yo
|
||||
**mysite/code/Page.php**
|
||||
|
||||
```php
|
||||
|
||||
public function UsersIpAddress()
|
||||
{
|
||||
return $this->getRequest()->getIP();
|
||||
|
@ -32,8 +32,6 @@ It is common practice to include most Requirements either in the *init()*-method
|
||||
as close to rendering as possible (e.g. in [FormField](api:SilverStripe\Forms\FormField)).
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use SilverStripe\Control\Director;
|
||||
use SilverStripe\View\Requirements;
|
||||
|
||||
|
@ -22,14 +22,15 @@ instance with a template name or an array of templates to render.
|
||||
**mysite/code/Page.php**
|
||||
|
||||
```php
|
||||
$arrayData = new SilverStripe/View/ArrayData(array(
|
||||
$arrayData = new SilverStripe/View/ArrayData([
|
||||
'Name' => 'John',
|
||||
'Role' => 'Head Coach'
|
||||
));
|
||||
]);
|
||||
|
||||
echo $arrayData->renderWith('Coach_Message');
|
||||
|
||||
// returns "<strong>John</strong> is the Head Coach on our team."
|
||||
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
@ -38,22 +39,21 @@ includes [Controller](api:SilverStripe\Control\Controller), [FormField](api:Silv
|
||||
</div>
|
||||
|
||||
```php
|
||||
$controller->renderWith(array('MyController', 'MyBaseController'));
|
||||
$controller->renderWith(['MyController', 'MyBaseController']);
|
||||
|
||||
SilverStripe\Security\Security::getCurrentUser()->renderWith('Member_Profile');
|
||||
|
||||
```
|
||||
|
||||
`renderWith` can be used to override the default template process. For instance, to provide an ajax version of a
|
||||
template.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use SilverStripe\CMS\Controllers\ContentController;
|
||||
|
||||
class PageController extends ContentController
|
||||
{
|
||||
private static $allowed_actions = array('iwantmyajax');
|
||||
private static $allowed_actions = ['iwantmyajax'];
|
||||
|
||||
public function iwantmyajax()
|
||||
{
|
||||
@ -64,13 +64,13 @@ class PageController extends ContentController
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Any data you want to render into the template that does not extend `ViewableData` should be wrapped in an object that
|
||||
does, such as `ArrayData` or `ArrayList`.
|
||||
|
||||
```php
|
||||
<?php
|
||||
use SilverStripe\View\ArrayData;
|
||||
use SilverStripe\ORM\ArrayList;
|
||||
use SilverStripe\Control\Director;
|
||||
@ -83,18 +83,19 @@ class PageController extends ContentController
|
||||
{
|
||||
if (Director::is_ajax()) {
|
||||
$experience = new ArrayList();
|
||||
$experience->push(new ArrayData(array(
|
||||
$experience->push(new ArrayData([
|
||||
'Title' => 'First Job'
|
||||
)));
|
||||
]));
|
||||
|
||||
return $this->customise(new ArrayData(array(
|
||||
return $this->customise(new ArrayData([
|
||||
'Name' => 'John',
|
||||
'Role' => 'Head Coach',
|
||||
'Experience' => $experience
|
||||
)))->renderWith('AjaxTemplate');
|
||||
]))->renderWith('AjaxTemplate');
|
||||
} else {
|
||||
return $this->httpError(404);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
@ -9,7 +9,6 @@ All functions that provide data to templates must have no side effects, as the v
|
||||
example, this controller method will not behave as you might imagine.
|
||||
|
||||
```php
|
||||
|
||||
private $counter = 0;
|
||||
|
||||
public function Counter() {
|
||||
|
@ -48,9 +48,7 @@ provide default template for an object.
|
||||
|
||||
**mysite/code/Page.php**
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Page extends SiteTree {
|
||||
|
||||
public function forTemplate() {
|
||||
@ -73,19 +71,18 @@ content that method sends back, or, provide a type in the `$casting` array for t
|
||||
to a template, SilverStripe will ensure that the object is wrapped in the correct type and values are safely escaped.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Page extends SiteTree {
|
||||
|
||||
private static $casting = array(
|
||||
private static $casting = [
|
||||
'MyCustomMethod' => 'HTMLText'
|
||||
);
|
||||
];
|
||||
|
||||
public function MyCustomMethod() {
|
||||
return "<h1>This is my header</h1>";
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
When calling `$MyCustomMethod` SilverStripe now has the context that this method will contain HTML and escape the data
|
||||
|
@ -9,15 +9,13 @@ subclass the base `Controller` class.
|
||||
**mysite/code/controllers/TeamController.php**
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class TeamController extends Controller {
|
||||
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'players',
|
||||
'index'
|
||||
);
|
||||
];
|
||||
|
||||
public function index(HTTPRequest $request) {
|
||||
// ..
|
||||
@ -27,6 +25,7 @@ subclass the base `Controller` class.
|
||||
print_r($request->allParams());
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Routing
|
||||
@ -78,15 +77,14 @@ Action methods can return one of four main things:
|
||||
**mysite/code/controllers/TeamController.php**
|
||||
|
||||
```php
|
||||
|
||||
/**
|
||||
* Return some additional data to the current response that is waiting to go out, this makes $Title set to
|
||||
* 'MyTeamName' and continues on with generating the response.
|
||||
*/
|
||||
public function index(HTTPRequest $request) {
|
||||
return array(
|
||||
return [
|
||||
'Title' => 'My Team Name'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,23 +111,24 @@ Action methods can return one of four main things:
|
||||
* We can render HTML and leave SilverStripe to set the response code and body.
|
||||
*/
|
||||
public function htmlaction() {
|
||||
return $this->customise(new ArrayData(array(
|
||||
return $this->customise(new ArrayData([
|
||||
'Title' => 'HTML Action'
|
||||
)))->renderWith('MyCustomTemplate');
|
||||
]))->renderWith('MyCustomTemplate');
|
||||
}
|
||||
|
||||
/**
|
||||
* We can send stuff to the browser which isn't HTML
|
||||
*/
|
||||
public function ajaxaction() {
|
||||
$this->getResponse()->setBody(json_encode(array(
|
||||
$this->getResponse()->setBody(json_encode([
|
||||
'json' => true
|
||||
)));
|
||||
]));
|
||||
|
||||
$this->getResponse()->addHeader("Content-type", "application/json");
|
||||
|
||||
return $this->getResponse().
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
For more information on how a URL gets mapped to an action see the [Routing](routing) documentation.
|
||||
@ -159,7 +158,6 @@ Each controller should define a `Link()` method. This should be used to avoid ha
|
||||
**mysite/code/controllers/TeamController.php**
|
||||
|
||||
```php
|
||||
|
||||
public function Link($action = null) {
|
||||
return Controller::join_links('teams', $action);
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ print_r($this->getRequest()->params());
|
||||
// [ID] => 1
|
||||
// [Name] => null
|
||||
// )
|
||||
|
||||
```
|
||||
|
||||
You can also fetch one parameter at a time.
|
||||
@ -158,20 +159,19 @@ This is useful when you want to provide custom actions for the mapping of `teams
|
||||
**mysite/code/controllers/TeamController.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use SilverStripe\Control\Controller;
|
||||
|
||||
class TeamController extends Controller
|
||||
{
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'payroll'
|
||||
);
|
||||
];
|
||||
|
||||
private static $url_handlers = array(
|
||||
private static $url_handlers = [
|
||||
'staff/$ID/$Name' => 'payroll',
|
||||
'coach/$ID/$Name' => 'payroll'
|
||||
);
|
||||
];
|
||||
|
||||
```
|
||||
|
||||
The syntax for the `$url_handlers` array users the same pattern matches as the `YAML` configuration rules.
|
||||
@ -188,10 +188,10 @@ use SilverStripe\CMS\Controllers\ContentController;
|
||||
|
||||
class FeedController extends ContentController
|
||||
{
|
||||
private static $allowed_actions = array('go');
|
||||
private static $url_handlers = array(
|
||||
private static $allowed_actions = ['go'];
|
||||
private static $url_handlers = [
|
||||
'go/$UserName/$AuthToken/$Timestamp/$OutputType/$DeleteMode' => 'go'
|
||||
);
|
||||
];
|
||||
|
||||
public function go()
|
||||
{
|
||||
@ -206,6 +206,7 @@ class FeedController extends ContentController
|
||||
The YAML rule, in contrast, is simple. It needs to provide only enough
|
||||
information for the framework to choose the desired controller.
|
||||
|
||||
|
||||
```yml
|
||||
Director:
|
||||
rules:
|
||||
|
@ -12,12 +12,10 @@ Any action you define on a controller must be defined in a `$allowed_actions` st
|
||||
directly calling methods that they shouldn't.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyController extends Controller {
|
||||
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
// someaction can be accessed by anyone, any time
|
||||
'someaction',
|
||||
|
||||
@ -35,8 +33,9 @@ directly calling methods that they shouldn't.
|
||||
|
||||
// complexactioncheck can only be accessed if $this->canComplexAction("MyRestrictedAction", false, 42) is true.
|
||||
'complexactioncheck' => '->canComplexAction("MyRestrictedAction", false, 42)',
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<div class="info">
|
||||
@ -47,7 +46,6 @@ An action named "index" is white listed by default, unless `allowed_actions` is
|
||||
is specifically restricted.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
class MyController extends Controller {
|
||||
@ -61,29 +59,26 @@ is specifically restricted.
|
||||
`$allowed_actions` can be defined on `Extension` classes applying to the controller.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyExtension extends Extension {
|
||||
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'mycustomaction'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Only public methods can be made accessible.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyController extends Controller {
|
||||
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'secure',
|
||||
// secureaction won't work as it's private.
|
||||
);
|
||||
];
|
||||
|
||||
public function secure() {
|
||||
// ..
|
||||
@ -93,18 +88,17 @@ Only public methods can be made accessible.
|
||||
// ..
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
If a method on a parent class is overwritten, access control for it has to be redefined as well.
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyController extends Controller {
|
||||
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'action',
|
||||
);
|
||||
];
|
||||
|
||||
public function action() {
|
||||
// ..
|
||||
@ -113,14 +107,15 @@ If a method on a parent class is overwritten, access control for it has to be re
|
||||
|
||||
class MyChildController extends MyController {
|
||||
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'action', // required as we are redefining action
|
||||
);
|
||||
];
|
||||
|
||||
public function action() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
@ -132,14 +127,12 @@ Access checks on parent classes need to be overwritten via the [Configuration AP
|
||||
Form action methods should **not** be included in `$allowed_actions`. However, the form method **should** be included
|
||||
as an `allowed_action`.
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyController extends Controller {
|
||||
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'ContactForm' // use the Form method, not the action
|
||||
);
|
||||
];
|
||||
|
||||
public function ContactForm() {
|
||||
return new Form(..);
|
||||
@ -149,6 +142,7 @@ as an `allowed_action`.
|
||||
// ..
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Action Level Checks
|
||||
@ -157,14 +151,12 @@ Each method responding to a URL can also implement custom permission checks, e.g
|
||||
the passed request data.
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyController extends Controller {
|
||||
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'myaction'
|
||||
);
|
||||
];
|
||||
|
||||
public function myaction($request) {
|
||||
if(!$request->getVar('apikey')) {
|
||||
@ -174,6 +166,7 @@ the passed request data.
|
||||
return 'valid';
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
@ -191,12 +184,10 @@ execution. This behavior can be used to implement permission checks.
|
||||
`init` is called for any possible action on the controller and before any specific method such as `index`.
|
||||
</div>
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyController extends Controller {
|
||||
|
||||
private static $allowed_actions = array();
|
||||
private static $allowed_actions = [];
|
||||
|
||||
public function init() {
|
||||
parent::init();
|
||||
@ -206,6 +197,7 @@ execution. This behavior can be used to implement permission checks.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
@ -10,7 +10,6 @@ HTTP header.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$this->redirect('goherenow');
|
||||
// redirect to Page::goherenow(), i.e on the contact-us page this will redirect to /contact-us/goherenow/
|
||||
|
||||
@ -29,7 +28,6 @@ HTTP header.
|
||||
The `redirect()` method takes an optional HTTP status code, either `301` for permanent redirects, or `302` for
|
||||
temporary redirects (default).
|
||||
```php
|
||||
|
||||
$this->redirect('/', 302);
|
||||
// go back to the homepage, don't cache that this page has moved
|
||||
```
|
||||
@ -41,10 +39,10 @@ operator.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
private static $url_handlers = array(
|
||||
private static $url_handlers = [
|
||||
'players/john' => '~>coach'
|
||||
);
|
||||
];
|
||||
|
||||
```
|
||||
|
||||
For more information on `$url_handlers` see the [Routing](routing) documenation.
|
||||
|
@ -19,8 +19,6 @@ will deliberately return a different response, e.g. an error response or a redir
|
||||
**mysite/code/CustomMiddleware.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use SilverStripe\Control\Middleware\HTTPMiddleware
|
||||
use SilverStripe\Control\HTTPRequest;
|
||||
|
||||
|
@ -16,7 +16,6 @@ Creating a [Form](api:SilverStripe\Forms\Form) has the following signature.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$form = new Form(
|
||||
$controller, // the Controller to render this form on
|
||||
$name, // name of the method that returns this form on the controller
|
||||
@ -31,8 +30,6 @@ In practice, this looks like:
|
||||
**mysite/code/Page.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use SilverStripe\CMS\Controllers\ContentController;
|
||||
use SilverStripe\Forms\FieldList;
|
||||
use SilverStripe\Forms\Form;
|
||||
@ -42,9 +39,9 @@ use SilverStripe\Forms\TextField;
|
||||
|
||||
class PageController extends ContentController
|
||||
{
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'HelloForm'
|
||||
);
|
||||
];
|
||||
|
||||
public function HelloForm()
|
||||
{
|
||||
@ -70,6 +67,7 @@ class PageController extends ContentController
|
||||
return $this->redirectBack();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
**mysite/templates/Page.ss**
|
||||
@ -94,9 +92,10 @@ Because the `HelloForm()` method will be the location the user is taken to, it n
|
||||
controller action. To grant it access through URLs, we add it to the `$allowed_actions` array.
|
||||
|
||||
```php
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'HelloForm'
|
||||
);
|
||||
];
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
@ -279,8 +278,6 @@ The `$action` method takes two arguments:
|
||||
* `$form` the submitted [Form](api:SilverStripe\Forms\Form) instance.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use SilverStripe\CMS\Controllers\ContentController;
|
||||
use SilverStripe\Forms\EmailField;
|
||||
use SilverStripe\Forms\FieldList;
|
||||
@ -290,9 +287,9 @@ use SilverStripe\Forms\TextField;
|
||||
|
||||
class PageController extends ContentController
|
||||
{
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'MyForm'
|
||||
);
|
||||
];
|
||||
|
||||
public function MyForm()
|
||||
{
|
||||
@ -326,6 +323,7 @@ class PageController extends ContentController
|
||||
return $this->redirectBack();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Validation
|
||||
@ -337,12 +335,13 @@ validating its' own data value.
|
||||
For more information, see the [Form Validation](validation) documentation.
|
||||
|
||||
```php
|
||||
$validator = new SilverStripe\Forms\RequiredFields(array(
|
||||
$validator = new SilverStripe\Forms\RequiredFields([
|
||||
'Name',
|
||||
'Email'
|
||||
));
|
||||
]);
|
||||
|
||||
$form = new Form($this, 'MyForm', $fields, $actions, $validator);
|
||||
|
||||
```
|
||||
|
||||
## API Documentation
|
||||
|
@ -8,8 +8,6 @@ SilverStripe provides server-side form validation out of the box through the [Va
|
||||
the [Form](api:SilverStripe\Forms\Form) constructor or through the function `setValidator`.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use SilverStripe\CMS\Controllers\ContentController;
|
||||
use SilverStripe\Forms\EmailField;
|
||||
use SilverStripe\Forms\Form;
|
||||
@ -19,9 +17,9 @@ use SilverStripe\Forms\RequiredFields;
|
||||
|
||||
class PageController extends ContentController
|
||||
{
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'MyForm'
|
||||
);
|
||||
];
|
||||
|
||||
public function MyForm()
|
||||
{
|
||||
@ -35,9 +33,9 @@ class PageController extends ContentController
|
||||
);
|
||||
|
||||
// the fields 'Name' and 'Email' are required.
|
||||
$required = new RequiredFields(array(
|
||||
$required = new RequiredFields([
|
||||
'Name', 'Email'
|
||||
));
|
||||
]);
|
||||
|
||||
// $required can be set as an argument
|
||||
$form = new Form($controller, 'MyForm', $fields, $actions, $required);
|
||||
@ -53,6 +51,7 @@ class PageController extends ContentController
|
||||
//..
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
In this example we will be required to input a value for `Name` and a valid email address for `Email` before the
|
||||
@ -96,8 +95,6 @@ the same validation logic applied to it throughout.
|
||||
**mysite/code/CustomNumberField.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use SilverStripe\Forms\TextField;
|
||||
|
||||
class CustomNumberField extends TextField
|
||||
@ -128,8 +125,6 @@ reusable and would not be possible within the `CMS` or other automated `UI` but
|
||||
`FormField` classes.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use SilverStripe\CMS\Controllers\ContentController;
|
||||
use SilverStripe\Forms\EmailField;
|
||||
use SilverStripe\Forms\FieldList;
|
||||
@ -140,9 +135,9 @@ use SilverStripe\Security\Member;
|
||||
|
||||
class Page_Controller extends ContentController
|
||||
{
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'MyForm'
|
||||
);
|
||||
];
|
||||
|
||||
public function MyForm()
|
||||
{
|
||||
@ -179,6 +174,7 @@ class Page_Controller extends ContentController
|
||||
return $this->redirectBack();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Exempt validation actions
|
||||
@ -283,17 +279,15 @@ Again, custom error messages can be provided through the `FormField`
|
||||
</div>
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use SilverStripe\CMS\Model\SiteTree;
|
||||
use SilverStripe\Forms\TextField;
|
||||
use SilverStripe\Forms\RequiredFields;
|
||||
|
||||
class Page extends SiteTree
|
||||
{
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'MyRequiredField' => 'Text'
|
||||
);
|
||||
];
|
||||
|
||||
public function getCMSFields()
|
||||
{
|
||||
@ -306,11 +300,12 @@ class Page extends SiteTree
|
||||
|
||||
public function getCMSValidator()
|
||||
{
|
||||
return new RequiredFields(array(
|
||||
return new RequiredFields([
|
||||
'MyRequiredField'
|
||||
));
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## API Documentation
|
||||
|
@ -8,8 +8,6 @@ can be rendered out using custom templates using `setTemplate`.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
|
||||
$form = new Form(..);
|
||||
$form->setTemplate('MyCustomFormTemplate');
|
||||
|
||||
@ -39,7 +37,6 @@ For [FormField](api:SilverStripe\Forms\FormField) instances, there are several o
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$field = new TextField();
|
||||
|
||||
$field->setTemplate('CustomTextField');
|
||||
|
@ -22,7 +22,6 @@ The `SecurityToken` automatically added looks something like:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$form = new Form(..);
|
||||
echo $form->getSecurityToken()->getValue();
|
||||
|
||||
@ -42,7 +41,6 @@ normally require a security token).
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$form = new Form(..);
|
||||
$form->disableSecurityToken();
|
||||
```
|
||||
@ -60,7 +58,6 @@ application errors or edge cases. If you need to disable this setting follow the
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$form = new Form(..);
|
||||
|
||||
$form->setFormMethod('POST');
|
||||
|
@ -11,7 +11,6 @@ To make an entire [Form](api:SilverStripe\Forms\Form) read-only.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$form = new Form(..);
|
||||
$form->makeReadonly();
|
||||
```
|
||||
@ -20,7 +19,6 @@ To make all the fields within a [FieldList](api:SilverStripe\Forms\FieldList) re
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$fields = new FieldList(..);
|
||||
$fields = $fields->makeReadonly();
|
||||
```
|
||||
@ -29,7 +27,6 @@ To make a [FormField](api:SilverStripe\Forms\FormField) read-only you need to kn
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$field = new TextField(..);
|
||||
$field = $field->performReadonlyTransformation();
|
||||
|
||||
|
@ -23,7 +23,6 @@ display up to two levels of tabs in the interface. If you want to group data fur
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$fields->addFieldToTab('Root.Main', new TextField(..));
|
||||
```
|
||||
|
||||
@ -31,7 +30,6 @@ display up to two levels of tabs in the interface. If you want to group data fur
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$fields->removeFieldFromTab('Root.Main', 'Content');
|
||||
```
|
||||
|
||||
@ -39,7 +37,6 @@ display up to two levels of tabs in the interface. If you want to group data fur
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$fields->addFieldToTab('Root.MyNewTab', new TextField(..));
|
||||
```
|
||||
|
||||
@ -47,7 +44,6 @@ display up to two levels of tabs in the interface. If you want to group data fur
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$content = $fields->dataFieldByName('Content');
|
||||
|
||||
$fields->removeFieldFromTab('Root.Main', 'Content');
|
||||
@ -58,11 +54,11 @@ display up to two levels of tabs in the interface. If you want to group data fur
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$fields->addFieldsToTab('Root.Content', array(
|
||||
$fields->addFieldsToTab('Root.Content', [
|
||||
TextField::create('Name'),
|
||||
TextField::create('Email')
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
## API Documentation
|
||||
|
@ -16,14 +16,12 @@ The following example will add a simple DateField to your Page, allowing you to
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Page extends SiteTree {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'MyDate' => 'Date',
|
||||
);
|
||||
];
|
||||
|
||||
public function getCMSFields() {
|
||||
$fields = parent::getCMSFields();
|
||||
@ -36,6 +34,7 @@ The following example will add a simple DateField to your Page, allowing you to
|
||||
return $fields;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Custom Date Format
|
||||
@ -45,7 +44,6 @@ This is only necessary if you want to opt-out of the built-in browser localisati
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// will display a date in the following format: 31/06/2012
|
||||
DateField::create('MyDate')
|
||||
->setHTML5(false)
|
||||
@ -64,7 +62,6 @@ Sets the minimum and maximum allowed date values using the `min` and `max` confi
|
||||
|
||||
|
||||
```php
|
||||
|
||||
DateField::create('MyDate')
|
||||
->setMinDate('-7 days')
|
||||
->setMaxDate('2012-12-31')
|
||||
@ -78,7 +75,6 @@ field description as an example.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$dateField = DateField::create('MyDate');
|
||||
|
||||
// Show long format as text below the field
|
||||
|
@ -17,14 +17,12 @@ functionality. It is usually added through the [DataObject::getCMSFields()](api:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyObject extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Content' => 'HTMLText'
|
||||
);
|
||||
];
|
||||
|
||||
public function getCMSFields() {
|
||||
return new FieldList(
|
||||
@ -32,6 +30,7 @@ functionality. It is usually added through the [DataObject::getCMSFields()](api:
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Specify which configuration to use
|
||||
@ -47,20 +46,20 @@ This is particularly useful if you need different configurations for multiple [H
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyObject extends DataObject {
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Content' => 'HTMLText',
|
||||
'OtherContent' => 'HTMLText'
|
||||
);
|
||||
];
|
||||
|
||||
public function getCMSFields() {
|
||||
return new FieldList(array(
|
||||
return new FieldList([
|
||||
new HTMLEditorField('Content'),
|
||||
new HTMLEditorField('OtherContent', 'Other content', $this->OtherContent, 'myConfig')
|
||||
));
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
In the above example, the 'Content' field will use the default 'cms' config while 'OtherContent' will be using 'myConfig'.
|
||||
@ -93,7 +92,6 @@ transparently generate the relevant underlying TinyMCE code.
|
||||
**mysite/_config.php**
|
||||
|
||||
```php
|
||||
|
||||
HtmlEditorConfig::get('cms')->enablePlugins('media');
|
||||
```
|
||||
|
||||
@ -109,7 +107,6 @@ configuration. Here is an example of adding a `ssmacron` button after the `charm
|
||||
**mysite/_config.php**
|
||||
|
||||
```php
|
||||
|
||||
HtmlEditorConfig::get('cms')->insertButtonsAfter('charmap', 'ssmacron');
|
||||
```
|
||||
|
||||
@ -118,7 +115,6 @@ Buttons can also be removed:
|
||||
**mysite/_config.php**
|
||||
|
||||
```php
|
||||
|
||||
HtmlEditorConfig::get('cms')->removeButtons('tablecontrols', 'blockquote', 'hr');
|
||||
```
|
||||
|
||||
@ -140,7 +136,6 @@ from the HTML source by the editor.
|
||||
**mysite/_config.php**
|
||||
|
||||
```php
|
||||
|
||||
// Add start and type attributes for <ol>, add <object> and <embed> with all attributes.
|
||||
HtmlEditorConfig::get('cms')->setOption(
|
||||
'extended_valid_elements',
|
||||
@ -168,8 +163,8 @@ You can enable them through [HtmlEditorConfig::enablePlugins()](api:SilverStripe
|
||||
**mysite/_config.php**
|
||||
|
||||
```php
|
||||
HtmlEditorConfig::get('cms')->enablePlugins(['myplugin' => '../../../mysite/javascript/myplugin/editor_plugin.js']);
|
||||
|
||||
HtmlEditorConfig::get('cms')->enablePlugins(array('myplugin' => '../../../mysite/javascript/myplugin/editor_plugin.js'));
|
||||
```
|
||||
|
||||
You can learn how to [create a plugin](http://www.tinymce.com/wiki.php/Creating_a_plugin) from the TinyMCE documentation.
|
||||
@ -223,7 +218,6 @@ In case you want to adhere to HTML4 instead, use the following configuration:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
HtmlEditorConfig::get('cms')->setOption('element_format', 'html');
|
||||
```
|
||||
|
||||
@ -249,7 +243,6 @@ Example: Remove field for "image captions"
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// File: mysite/code/MyToolbarExtension.php
|
||||
class MyToolbarExtension extends Extension {
|
||||
public function updateFieldsForImage(&$fields, $url, $file) {
|
||||
@ -261,7 +254,6 @@ Example: Remove field for "image captions"
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// File: mysite/_config.php
|
||||
ModalController::add_extension('MyToolbarExtension');
|
||||
```
|
||||
@ -291,7 +283,6 @@ of the CMS you have to take care of instantiate yourself:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// File: mysite/code/MyController.php
|
||||
class MyObjectController extends Controller {
|
||||
public function Modals() {
|
||||
@ -305,7 +296,6 @@ so this is considered advanced usage of the field.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// File: mysite/_config.php
|
||||
HtmlEditorConfig::get('cms')->disablePlugins('ssbuttons');
|
||||
HtmlEditorConfig::get('cms')->removeButtons('sslink', 'ssmedia');
|
||||
@ -332,7 +322,6 @@ Assuming you have the module installed, here's how you enable its use in `mysite
|
||||
|
||||
|
||||
```php
|
||||
|
||||
HtmlEditorConfig::get('cms')->enablePlugins('spellchecker', 'contextmenu');
|
||||
HtmlEditorConfig::get('cms')->addButtonsToLine(2, 'spellchecker');
|
||||
HtmlEditorConfig::get('cms')->setOption(
|
||||
@ -346,7 +335,6 @@ Now change the default spellchecker in `framework/thirdparty/tinymce-spellchecke
|
||||
|
||||
|
||||
```php
|
||||
|
||||
|
||||
// ...
|
||||
$config['general.engine'] = 'PSpell';
|
||||
|
@ -8,7 +8,6 @@ tabular data in a format that is easy to view and modify. It can be thought of a
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$field = new GridField($name, $title, $list);
|
||||
```
|
||||
|
||||
@ -30,9 +29,7 @@ actions such as deleting records.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Page extends SiteTree {
|
||||
|
||||
public function getCMSFields() {
|
||||
@ -64,9 +61,7 @@ the `getConfig()` method on `GridField`.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Page extends SiteTree {
|
||||
|
||||
public function getCMSFields() {
|
||||
@ -86,20 +81,20 @@ the `getConfig()` method on `GridField`.
|
||||
//
|
||||
$dataColumns = $config->getComponentByType('GridFieldDataColumns');
|
||||
|
||||
$dataColumns->setDisplayFields(array(
|
||||
$dataColumns->setDisplayFields([
|
||||
'Title' => 'Title',
|
||||
'Link'=> 'URL',
|
||||
'LastEdited' => 'Changed'
|
||||
));
|
||||
]);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
With the `GridFieldConfig` instance, we can modify the behavior of the `GridField`.
|
||||
```php
|
||||
|
||||
// `GridFieldConfig::create()` will create an empty configuration (no components).
|
||||
$config = GridFieldConfig::create();
|
||||
|
||||
@ -113,7 +108,6 @@ With the `GridFieldConfig` instance, we can modify the behavior of the `GridFiel
|
||||
`GridFieldConfig` provides a number of methods to make setting the configuration easier. We can insert a component
|
||||
before another component by passing the second parameter.
|
||||
```php
|
||||
|
||||
$config->addComponent(new GridFieldFilterHeader(), 'GridFieldDataColumns');
|
||||
```
|
||||
|
||||
@ -121,7 +115,6 @@ We can add multiple components in one call.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$config->addComponents(
|
||||
new GridFieldDataColumns(),
|
||||
new GridFieldToolbarHeader()
|
||||
@ -132,7 +125,6 @@ Or, remove a component.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$config->removeComponentsByType('GridFieldDeleteAction');
|
||||
```
|
||||
|
||||
@ -140,7 +132,6 @@ Fetch a component to modify it later on.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$component = $config->getComponentByType('GridFieldFilterHeader')
|
||||
```
|
||||
|
||||
@ -170,7 +161,6 @@ A simple read-only and paginated view of records with sortable and searchable he
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$config = GridFieldConfig_Base::create();
|
||||
|
||||
$gridField->setConfig($config);
|
||||
@ -201,7 +191,6 @@ this record.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$config = GridFieldConfig_RecordViewer::create();
|
||||
|
||||
$gridField->setConfig($config);
|
||||
@ -227,7 +216,6 @@ Permission control for editing and deleting the record uses the `canEdit()` and
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$config = GridFieldConfig_RecordEditor::create();
|
||||
|
||||
$gridField->setConfig($config);
|
||||
@ -243,7 +231,6 @@ Permission control for editing and deleting the record uses the `canEdit()` and
|
||||
Similar to `GridFieldConfig_RecordEditor`, but adds features to work on a record's has-many or many-many relationships.
|
||||
As such, it expects the list used with the `GridField` to be a instance of `RelationList`.
|
||||
```php
|
||||
|
||||
$config = GridFieldConfig_RelationEditor::create();
|
||||
|
||||
$gridField->setConfig($config);
|
||||
@ -263,7 +250,6 @@ The `GridFieldDetailForm` component drives the record viewing and editing form.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$form = $gridField->getConfig()->getComponentByType('GridFieldDetailForm');
|
||||
$form->setFields(new FieldList(
|
||||
new TextField('Title')
|
||||
@ -283,35 +269,33 @@ The namespace notation is `ManyMany[<extradata-field-name>]`, so for example `Ma
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Team extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Name' => 'Text'
|
||||
);
|
||||
];
|
||||
|
||||
public static $many_many = array(
|
||||
public static $many_many = [
|
||||
'Players' => 'Player'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
class Player extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Name' => 'Text'
|
||||
);
|
||||
];
|
||||
|
||||
public static $many_many = array(
|
||||
public static $many_many = [
|
||||
'Teams' => 'Team'
|
||||
);
|
||||
];
|
||||
|
||||
public static $many_many_extraFields = array(
|
||||
'Teams' => array(
|
||||
public static $many_many_extraFields = [
|
||||
'Teams' => [
|
||||
'Position' => 'Text'
|
||||
)
|
||||
);
|
||||
]
|
||||
];
|
||||
|
||||
public function getCMSFields() {
|
||||
$fields = parent::getCMSFields();
|
||||
@ -334,6 +318,7 @@ The namespace notation is `ManyMany[<extradata-field-name>]`, so for example `Ma
|
||||
return $fields;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Flexible Area Assignment through Fragments
|
||||
@ -355,7 +340,6 @@ bottom right of the table.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$config->addComponent(new GridFieldButtonRow('after'));
|
||||
$config->addComponent(new GridFieldPrintButton('buttons-after-right'));
|
||||
```
|
||||
@ -368,17 +352,16 @@ create an area rendered before the table wrapped in a simple `<div>`.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyAreaComponent implements GridField_HTMLProvider {
|
||||
|
||||
public function getHTMLFragments( $gridField) {
|
||||
return array(
|
||||
return [
|
||||
'before' => '<div class="my-area">$DefineFragment(my-area)</div>'
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
@ -391,24 +374,22 @@ Now you can add other components into this area by returning them as an array fr
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyShareLinkComponent implements GridField_HTMLProvider {
|
||||
|
||||
public function getHTMLFragments( $gridField) {
|
||||
return array(
|
||||
return [
|
||||
'my-area' => '<a href>...</a>'
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Your new area can also be used by existing components, e.g. the [GridFieldPrintButton](api:SilverStripe\Forms\GridField\GridFieldPrintButton)
|
||||
|
||||
|
||||
```php
|
||||
|
||||
new GridFieldPrintButton('my-component-area');
|
||||
```
|
||||
|
||||
|
@ -11,30 +11,28 @@ code for a `Form` is to create it as a subclass to `Form`. Let's look at a examp
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class PageController extends ContentController {
|
||||
|
||||
public function SearchForm() {
|
||||
$fields = new FieldList(
|
||||
HeaderField::create('Header', 'Step 1. Basics'),
|
||||
OptionsetField::create('Type', '', array(
|
||||
OptionsetField::create('Type', '', [
|
||||
'foo' => 'Search Foo',
|
||||
'bar' => 'Search Bar',
|
||||
'baz' => 'Search Baz'
|
||||
)),
|
||||
]),
|
||||
|
||||
CompositeField::create(
|
||||
HeaderField::create('Header2', 'Step 2. Advanced '),
|
||||
CheckboxSetField::create('Foo', 'Select Option', array(
|
||||
CheckboxSetField::create('Foo', 'Select Option', [
|
||||
'qux' => 'Search Qux'
|
||||
)),
|
||||
]),
|
||||
|
||||
CheckboxSetField::create('Category', 'Category', array(
|
||||
CheckboxSetField::create('Category', 'Category', [
|
||||
'Foo' => 'Foo',
|
||||
'Bar' => 'Bar'
|
||||
)),
|
||||
]),
|
||||
|
||||
NumericField::create('Minimum', 'Minimum'),
|
||||
NumericField::create('Maximum', 'Maximum')
|
||||
@ -45,9 +43,9 @@ code for a `Form` is to create it as a subclass to `Form`. Let's look at a examp
|
||||
FormAction::create('doSearchForm', 'Search')
|
||||
);
|
||||
|
||||
$required = new RequiredFields(array(
|
||||
$required = new RequiredFields([
|
||||
'Type'
|
||||
));
|
||||
]);
|
||||
|
||||
$form = new Form($this, 'SearchForm', $fields, $actions, $required);
|
||||
$form->setFormMethod('GET');
|
||||
@ -61,6 +59,7 @@ code for a `Form` is to create it as a subclass to `Form`. Let's look at a examp
|
||||
|
||||
..
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Now that is a bit of code to include on our controller and generally makes the file look much more complex than it
|
||||
@ -70,9 +69,7 @@ should be. Good practice would be to move this to a subclass and create a new in
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class SearchForm extends Form {
|
||||
|
||||
/**
|
||||
@ -83,22 +80,22 @@ should be. Good practice would be to move this to a subclass and create a new in
|
||||
public function __construct($controller, $name) {
|
||||
$fields = new FieldList(
|
||||
HeaderField::create('Header', 'Step 1. Basics'),
|
||||
OptionsetField::create('Type', '', array(
|
||||
OptionsetField::create('Type', '', [
|
||||
'foo' => 'Search Foo',
|
||||
'bar' => 'Search Bar',
|
||||
'baz' => 'Search Baz'
|
||||
)),
|
||||
]),
|
||||
|
||||
CompositeField::create(
|
||||
HeaderField::create('Header2', 'Step 2. Advanced '),
|
||||
CheckboxSetField::create('Foo', 'Select Option', array(
|
||||
CheckboxSetField::create('Foo', 'Select Option', [
|
||||
'qux' => 'Search Qux'
|
||||
)),
|
||||
]),
|
||||
|
||||
CheckboxSetField::create('Category', 'Category', array(
|
||||
CheckboxSetField::create('Category', 'Category', [
|
||||
'Foo' => 'Foo',
|
||||
'Bar' => 'Bar'
|
||||
)),
|
||||
]),
|
||||
|
||||
NumericField::create('Minimum', 'Minimum'),
|
||||
NumericField::create('Maximum', 'Maximum')
|
||||
@ -109,9 +106,9 @@ should be. Good practice would be to move this to a subclass and create a new in
|
||||
FormAction::create('doSearchForm', 'Search')
|
||||
);
|
||||
|
||||
$required = new RequiredFields(array(
|
||||
$required = new RequiredFields([
|
||||
'Type'
|
||||
));
|
||||
]);
|
||||
|
||||
// now we create the actual form with our fields and actions defined
|
||||
// within this class
|
||||
@ -125,6 +122,7 @@ should be. Good practice would be to move this to a subclass and create a new in
|
||||
$this->loadDataFrom($_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Our controller will now just have to create a new instance of this form object. Keeping the file light and easy to read.
|
||||
@ -133,19 +131,18 @@ Our controller will now just have to create a new instance of this form object.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class PageController extends ContentController {
|
||||
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'SearchForm',
|
||||
);
|
||||
];
|
||||
|
||||
public function SearchForm() {
|
||||
return new SearchForm($this, 'SearchForm');
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Form actions can also be defined within your `Form` subclass to keep the entire form logic encapsulated.
|
||||
|
@ -13,9 +13,7 @@ totally custom template to meet our needs. To do this, we'll provide the class w
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
public function SearchForm() {
|
||||
$fields = new FieldList(
|
||||
TextField::create('q')
|
||||
|
@ -19,9 +19,7 @@ below:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class GridFieldCustomAction implements GridField_ColumnProvider, GridField_ActionProvider {
|
||||
|
||||
public function augmentColumns($gridField, &$columns) {
|
||||
@ -31,17 +29,17 @@ below:
|
||||
}
|
||||
|
||||
public function getColumnAttributes($gridField, $record, $columnName) {
|
||||
return array('class' => 'grid-field__col-compact');
|
||||
return ['class' => 'grid-field__col-compact'];
|
||||
}
|
||||
|
||||
public function getColumnMetadata($gridField, $columnName) {
|
||||
if($columnName == 'Actions') {
|
||||
return array('title' => '');
|
||||
return ['title' => ''];
|
||||
}
|
||||
}
|
||||
|
||||
public function getColumnsHandled($gridField) {
|
||||
return array('Actions');
|
||||
return ['Actions'];
|
||||
}
|
||||
|
||||
public function getColumnContent($gridField, $record, $columnName) {
|
||||
@ -52,14 +50,14 @@ below:
|
||||
'CustomAction'.$record->ID,
|
||||
'Do Action',
|
||||
"docustomaction",
|
||||
array('RecordID' => $record->ID)
|
||||
['RecordID' => $record->ID]
|
||||
);
|
||||
|
||||
return $field->Field();
|
||||
}
|
||||
|
||||
public function getActions($gridField) {
|
||||
return array('docustomaction');
|
||||
return ['docustomaction'];
|
||||
}
|
||||
|
||||
public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
|
||||
@ -74,6 +72,7 @@ below:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Add the GridFieldCustomAction to the current `GridFieldConfig`
|
||||
@ -85,7 +84,6 @@ manipulating the `GridFieldConfig` instance if required.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// option 1: creating a new GridField with the CustomAction
|
||||
$config = GridFieldConfig::create();
|
||||
$config->addComponent(new GridFieldCustomAction());
|
||||
|
@ -6,12 +6,10 @@ Let's start by defining a new `ContactPage` page type:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
class ContactPage extends Page {
|
||||
class ContactPage extends Page {
|
||||
}
|
||||
class ContactPageController extends PageController {
|
||||
private static $allowed_actions = array('Form');
|
||||
private static $allowed_actions = ['Form'];
|
||||
public function Form() {
|
||||
$fields = new FieldList(
|
||||
new TextField('Name'),
|
||||
@ -24,6 +22,7 @@ Let's start by defining a new `ContactPage` page type:
|
||||
return new Form($this, 'Form', $fields, $actions);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
To create a form, we instanciate a `Form` object on a function on our page controller. We'll call this function `Form()`. You're free to choose this name, but it's standard practice to name the function `Form()` if there's only a single form on the page.
|
||||
@ -32,7 +31,6 @@ There's quite a bit in this function, so we'll step through one piece at a time.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$fields = new FieldList(
|
||||
new TextField('Name'),
|
||||
new EmailField('Email'),
|
||||
@ -44,7 +42,6 @@ First we create all the fields we want in the contact form, and put them inside
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$actions = FieldList(
|
||||
new FormAction('submit', 'Submit')
|
||||
);
|
||||
@ -54,7 +51,6 @@ We then create a [FieldList](api:SilverStripe\Forms\FieldList) of the form actio
|
||||
|
||||
|
||||
```php
|
||||
|
||||
return new Form($this, 'Form', $fields, $actions);
|
||||
```
|
||||
|
||||
@ -74,9 +70,8 @@ Now that we have a contact form, we need some way of collecting the data submitt
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class ContactPageController extends PageController {
|
||||
private static $allowed_actions = array('Form');
|
||||
private static $allowed_actions = ['Form'];
|
||||
public function Form() {
|
||||
// ...
|
||||
}
|
||||
@ -93,12 +88,13 @@ Now that we have a contact form, we need some way of collecting the data submitt
|
||||
";
|
||||
$email->setBody($messageBody);
|
||||
$email->send();
|
||||
return array(
|
||||
return [
|
||||
'Content' => '<p>Thank you for your feedback.</p>',
|
||||
'Form' => ''
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<div class="hint" markdown="1">
|
||||
@ -123,7 +119,6 @@ The framework comes with a predefined validator called [RequiredFields](api:Silv
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function Form() {
|
||||
// ...
|
||||
$validator = new RequiredFields('Name', 'Message');
|
||||
|
@ -29,9 +29,7 @@ be marked `private static` and follow the `lower_case_with_underscores` structur
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyClass extends Page {
|
||||
|
||||
/**
|
||||
@ -42,10 +40,11 @@ be marked `private static` and follow the `lower_case_with_underscores` structur
|
||||
/**
|
||||
* @config
|
||||
*/
|
||||
private static $option_two = array();
|
||||
private static $option_two = [];
|
||||
|
||||
// ..
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Accessing and Setting Configuration Properties
|
||||
@ -54,7 +53,6 @@ This can be done by calling the static method [Config::inst()](api:SilverStripe\
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$config = Config::inst()->get('MyClass', 'property');
|
||||
```
|
||||
|
||||
@ -99,7 +97,6 @@ To use those variables in your application code:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$me = new MyClass();
|
||||
|
||||
echo $me->config()->option_one;
|
||||
@ -120,12 +117,13 @@ To use those variables in your application code:
|
||||
// returns true
|
||||
|
||||
// You can also use the static version
|
||||
MyClass::config()->option_two = array(
|
||||
MyClass::config()->option_two = [
|
||||
'Qux'
|
||||
);
|
||||
];
|
||||
|
||||
echo implode(', ', MyClass::config()->option_one);
|
||||
// returns 'Qux'
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
|
@ -25,7 +25,6 @@ To access variables in the PHP:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$config = SiteConfig::current_site_config();
|
||||
|
||||
echo $config->Title;
|
||||
@ -41,14 +40,12 @@ To extend the options available in the panel, define your own fields via a [Data
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class CustomSiteConfig extends DataExtension {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'FooterContent' => 'HTMLText'
|
||||
);
|
||||
];
|
||||
|
||||
public function updateCMSFields(FieldList $fields) {
|
||||
$fields->addFieldToTab("Root.Main",
|
||||
@ -56,6 +53,7 @@ To extend the options available in the panel, define your own fields via a [Data
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Then activate the extension.
|
||||
|
@ -19,20 +19,19 @@ and `RequestHandler`. You can still apply extensions to descendants of these cla
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyMemberExtension extends DataExtension {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'DateOfBirth' => 'SS_Datetime'
|
||||
);
|
||||
];
|
||||
|
||||
public function SayHi() {
|
||||
// $this->owner refers to the original instance. In this case a `Member`.
|
||||
return "Hi " . $this->owner->Name;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<div class="info" markdown="1">
|
||||
@ -56,7 +55,6 @@ Alternatively, we can add extensions through PHP code (in the `_config.php` file
|
||||
|
||||
|
||||
```php
|
||||
|
||||
Member::add_extension('MyMemberExtension');
|
||||
```
|
||||
|
||||
@ -81,24 +79,23 @@ $has_one etc.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyMemberExtension extends DataExtension {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Position' => 'Varchar',
|
||||
);
|
||||
];
|
||||
|
||||
private static $has_one = array(
|
||||
private static $has_one = [
|
||||
'Image' => 'Image',
|
||||
);
|
||||
];
|
||||
|
||||
public function SayHi() {
|
||||
// $this->owner refers to the original instance. In this case a `Member`.
|
||||
return "Hi " . $this->owner->Name;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
**mysite/templates/Page.ss**
|
||||
@ -127,7 +124,6 @@ we added a `SayHi` method which is unique to our extension.
|
||||
**mysite/code/Page.php**
|
||||
|
||||
```php
|
||||
|
||||
$member = Security::getCurrentUser();
|
||||
echo $member->SayHi;
|
||||
|
||||
@ -144,7 +140,6 @@ through the [Object::extend()](api:Object::extend()) method.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function getValidator() {
|
||||
// ..
|
||||
|
||||
@ -163,9 +158,7 @@ validator by defining the `updateValidator` method.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyMemberExtension extends DataExtension {
|
||||
|
||||
// ..
|
||||
@ -186,18 +179,16 @@ extension. The `CMS` provides a `updateCMSFields` Extension Hook to tie into.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyMemberExtension extends DataExtension {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Position' => 'Varchar',
|
||||
);
|
||||
];
|
||||
|
||||
private static $has_one = array(
|
||||
private static $has_one = [
|
||||
'Image' => 'Image',
|
||||
);
|
||||
];
|
||||
|
||||
public function updateCMSFields(FieldList $fields) {
|
||||
$fields->push(new TextField('Position'));
|
||||
@ -205,6 +196,7 @@ extension. The `CMS` provides a `updateCMSFields` Extension Hook to tie into.
|
||||
$upload->setAllowedFileCategories('image/supported');
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
@ -214,7 +206,6 @@ which allows an Extension to modify the results.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function Foo() {
|
||||
$foo = // ..
|
||||
|
||||
@ -234,9 +225,7 @@ In your [Extension](api:SilverStripe\Core\Extension) class you can only refer to
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyMemberExtension extends DataExtension {
|
||||
|
||||
public function updateFoo($foo) {
|
||||
@ -251,7 +240,6 @@ In your [Extension](api:SilverStripe\Core\Extension) class you can only refer to
|
||||
To see what extensions are currently enabled on an object, use [Object::getExtensionInstances()](api:Object::getExtensionInstances()) and
|
||||
[Object::hasExtension()](api:Object::hasExtension())
|
||||
```php
|
||||
|
||||
$member = Security::getCurrentUser();
|
||||
|
||||
print_r($member->getExtensionInstances());
|
||||
@ -279,7 +267,6 @@ if not specified in `self::$defaults`, but before extensions have been called:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
function __construct() {
|
||||
$self = $this;
|
||||
|
||||
@ -301,7 +288,6 @@ This method is preferred to disabling, enabling, and calling field extensions ma
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function getCMSFields() {
|
||||
|
||||
$this->beforeUpdateCMSFields(function($fields) {
|
||||
|
@ -12,7 +12,6 @@ in their WYSIWYG editor. Shortcodes are a semi-technical solution for this. A go
|
||||
viewer or a Google Map at a certain location.
|
||||
|
||||
```php
|
||||
|
||||
$text = "<h1>My Map</h1>[map]"
|
||||
|
||||
// Will output
|
||||
@ -22,7 +21,6 @@ viewer or a Google Map at a certain location.
|
||||
Here's some syntax variations:
|
||||
|
||||
```php
|
||||
|
||||
[my_shortcode]
|
||||
#
|
||||
[my_shortcode /]
|
||||
@ -40,7 +38,6 @@ Other fields can be manually parsed with shortcodes through the `parse` method.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$text = "My awesome [my_shortcode] is here.";
|
||||
ShortcodeParser::get_active()->parse($text);
|
||||
```
|
||||
@ -53,19 +50,18 @@ First we need to define a callback for the shortcode.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Page extends SiteTree {
|
||||
|
||||
private static $casting = array(
|
||||
private static $casting = [
|
||||
'MyShortCodeMethod' => 'HTMLText'
|
||||
);
|
||||
];
|
||||
|
||||
public static function MyShortCodeMethod($arguments, $content = null, $parser = null, $tagName) {
|
||||
return "<em>" . $tagName . "</em> " . $content . "; " . count($arguments) . " arguments.";
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
These parameters are passed to the `MyShortCodeMethod` callback:
|
||||
@ -86,10 +82,10 @@ To register a shortcode you call the following.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// ShortcodeParser::get('default')->register($shortcode, $callback);
|
||||
|
||||
ShortcodeParser::get('default')->register('my_shortcode', array('Page', 'MyShortCodeMethod'));
|
||||
ShortcodeParser::get('default')->register('my_shortcode', ['Page', 'MyShortCodeMethod']);
|
||||
|
||||
```
|
||||
|
||||
## Built-in Shortcodes
|
||||
@ -104,7 +100,6 @@ shortcode, which takes an `id` parameter.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<a href="[sitetree_link,id=99]">
|
||||
```
|
||||
|
||||
@ -112,7 +107,6 @@ Links to internal `File` database records work exactly the same, but with the `[
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<a href="[file_link,id=99]">
|
||||
```
|
||||
|
||||
@ -203,30 +197,30 @@ When the location attribute is "leftAlone" or "center" then the DOM is split aro
|
||||
|
||||
Here is a summary of the callback parameter values based on some example shortcodes.
|
||||
```php
|
||||
|
||||
public function MyCustomShortCode($arguments, $content = null, $parser = null, $tagName) {
|
||||
// ..
|
||||
}
|
||||
|
||||
[my_shortcode]
|
||||
$attributes => array();
|
||||
$attributes => [];
|
||||
$content => null;
|
||||
$parser => ShortcodeParser instance,
|
||||
$tagName => 'my_shortcode')
|
||||
|
||||
[my_shortcode,attribute="foo",other="bar"]
|
||||
|
||||
$attributes => array ('attribute' => 'foo', 'other' => 'bar')
|
||||
$attributes => ['attribute' => 'foo', 'other' => 'bar']
|
||||
$enclosedContent => null
|
||||
$parser => ShortcodeParser instance
|
||||
$tagName => 'my_shortcode'
|
||||
|
||||
[my_shortcode,attribute="foo"]content[/my_shortcode]
|
||||
|
||||
$attributes => array('attribute' => 'foo')
|
||||
$attributes => ['attribute' => 'foo']
|
||||
$enclosedContent => 'content'
|
||||
$parser => ShortcodeParser instance
|
||||
$tagName => 'my_shortcode'
|
||||
|
||||
```
|
||||
|
||||
## Limitations
|
||||
|
@ -20,7 +20,6 @@ The following sums up the simplest usage of the `Injector` it creates a new obje
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$object = Injector::inst()->create('MyClassName');
|
||||
```
|
||||
|
||||
@ -40,7 +39,6 @@ Repeated calls to `create()` create a new object each time.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$object = Injector::inst()->create('MyClassName');
|
||||
$object2 = Injector::inst()->create('MyClassName');
|
||||
|
||||
@ -56,7 +54,6 @@ object instance as the first call.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// sets up MyClassName as a singleton
|
||||
$object = Injector::inst()->get('MyClassName');
|
||||
$object2 = Injector::inst()->get('MyClassName');
|
||||
@ -73,8 +70,7 @@ The `Injector` API can be used to define the types of `$dependencies` that an ob
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyController extends Controller {
|
||||
|
||||
// both of these properties will be automatically
|
||||
@ -84,18 +80,18 @@ The `Injector` API can be used to define the types of `$dependencies` that an ob
|
||||
|
||||
// we declare the types for each of the properties on the object. Anything we pass in via the Injector API must
|
||||
// match these data types.
|
||||
static $dependencies = array(
|
||||
static $dependencies = [
|
||||
'textProperty' => 'a string value',
|
||||
'permissions' => '%$PermissionService',
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
When creating a new instance of `MyController` the dependencies on that class will be met.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$object = Injector::inst()->get('MyController');
|
||||
|
||||
echo ($object->permissions instanceof PermissionService);
|
||||
@ -123,7 +119,6 @@ Now the dependencies will be replaced with our configuration.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$object = Injector::inst()->get('MyController');
|
||||
|
||||
echo ($object->permissions instanceof MyCustomPermissionService);
|
||||
@ -182,18 +177,17 @@ An example using the `MyFactory` service to create instances of the `MyService`
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyFactory implements SilverStripe\Core\Injector\Factory {
|
||||
|
||||
public function create($service, array $params = array()) {
|
||||
public function create($service, array $params = []) {
|
||||
return new MyServiceImplementation();
|
||||
}
|
||||
}
|
||||
|
||||
// Will use MyFactoryImplementation::create() to create the service instance.
|
||||
$instance = Injector::inst()->get('MyService');
|
||||
|
||||
```
|
||||
|
||||
## Dependency overrides
|
||||
@ -219,9 +213,7 @@ Assuming a class structure such as
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class RestrictivePermissionService {
|
||||
private $database;
|
||||
|
||||
@ -266,7 +258,6 @@ Calling..
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// sets up ClassName as a singleton
|
||||
$controller = Injector::inst()->get('MyController');
|
||||
```
|
||||
@ -324,7 +315,6 @@ This is useful when writing test cases, as certain services may be necessary to
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// Setup default service
|
||||
Injector::inst()->registerService(new LiveService(), 'ServiceName');
|
||||
|
||||
|
@ -47,9 +47,7 @@ used.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MySQLWriteDbAspect implements BeforeCallAspect {
|
||||
|
||||
/**
|
||||
@ -57,9 +55,9 @@ used.
|
||||
*/
|
||||
public $writeDb;
|
||||
|
||||
public $writeQueries = array(
|
||||
public $writeQueries = [
|
||||
'insert','update','delete','replace'
|
||||
);
|
||||
];
|
||||
|
||||
public function beforeCall($proxied, $method, $args, &$alternateReturn) {
|
||||
if (isset($args[0])) {
|
||||
@ -73,6 +71,7 @@ used.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
To actually make use of this class, a few different objects need to be configured. First up, define the `writeDb`
|
||||
@ -184,7 +183,6 @@ One major feature of an `Aspect` is the ability to modify what is returned from
|
||||
As seen in the above example, the `beforeCall` method modifies the `&$alternateReturn` variable, and returns `false`
|
||||
after doing so.
|
||||
```php
|
||||
|
||||
$alternateReturn = $this->writeDb->query($sql, $code);
|
||||
|
||||
return false;
|
||||
|
@ -7,7 +7,6 @@ address. We want our CMS authors to be able to embed the map using the following
|
||||
|
||||
|
||||
```php
|
||||
|
||||
[googlemap,width=500,height=300]97-99 Courtenay Place, Wellington, New Zealand[/googlemap]
|
||||
```
|
||||
|
||||
|
@ -11,13 +11,11 @@ explicitly logging in or by invoking the "remember me" functionality.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
class MyMemberExtension extends DataExtension {
|
||||
private static $db = array(
|
||||
class MyMemberExtension extends DataExtension {
|
||||
private static $db = [
|
||||
'LastVisited' => 'Datetime',
|
||||
'NumVisit' => 'Int',
|
||||
);
|
||||
];
|
||||
|
||||
public function memberLoggedIn() {
|
||||
$this->logVisit();
|
||||
@ -28,10 +26,10 @@ explicitly logging in or by invoking the "remember me" functionality.
|
||||
}
|
||||
|
||||
public function updateCMSFields(FieldList $fields) {
|
||||
$fields->addFieldsToTab('Root.Main', array(
|
||||
$fields->addFieldsToTab('Root.Main', [
|
||||
ReadonlyField::create('LastVisited', 'Last visited'),
|
||||
ReadonlyField::create('NumVisit', 'Number of visits')
|
||||
));
|
||||
]);
|
||||
}
|
||||
|
||||
protected function logVisit() {
|
||||
@ -44,6 +42,7 @@ explicitly logging in or by invoking the "remember me" functionality.
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Now you just need to apply this extension through your config:
|
||||
|
@ -10,9 +10,7 @@ to ensure that it works as it should. A simple example would be to test the resu
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
use SilverStripe\CMS\Model\SiteTree;
|
||||
|
||||
class Page extends SiteTree
|
||||
@ -28,9 +26,7 @@ to ensure that it works as it should. A simple example would be to test the resu
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
use Page;
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
|
||||
@ -120,9 +116,7 @@ end of each test.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
|
||||
@ -134,7 +128,7 @@ end of each test.
|
||||
|
||||
// create 100 pages
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$page = new Page(array('Title' => "Page $i"));
|
||||
$page = new Page(['Title' => "Page $i"]);
|
||||
$page->write();
|
||||
$page->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
|
||||
}
|
||||
@ -153,6 +147,7 @@ end of each test.
|
||||
// ..
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
`tearDownAfterClass` and `setUpBeforeClass` can be used to run code just once for the file rather than before and after
|
||||
@ -161,9 +156,7 @@ takes place.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
|
||||
class PageTest extends SapphireTest
|
||||
@ -196,7 +189,6 @@ It's important to remember that the `parent::setUp();` functions will need to be
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
|
@ -9,7 +9,6 @@ creating [HTTPRequest](api:SilverStripe\Control\HTTPRequest), receiving [HTTPRes
|
||||
|
||||
## Get
|
||||
```php
|
||||
|
||||
$page = $this->get($url);
|
||||
```
|
||||
|
||||
@ -18,7 +17,6 @@ of the response.
|
||||
|
||||
## Post
|
||||
```php
|
||||
|
||||
$page = $this->post($url);
|
||||
```
|
||||
|
||||
@ -29,8 +27,8 @@ of the response.
|
||||
|
||||
|
||||
```php
|
||||
$submit = $this->submitForm($formID, $button = null, $data = []);
|
||||
|
||||
$submit = $this->submitForm($formID, $button = null, $data = array());
|
||||
```
|
||||
|
||||
Submits the given form (`#ContactForm`) on the current page and returns the [HTTPResponse](api:SilverStripe\Control\HTTPResponse).
|
||||
@ -39,7 +37,6 @@ Submits the given form (`#ContactForm`) on the current page and returns the [HTT
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$this->logInAs($member);
|
||||
```
|
||||
|
||||
@ -47,7 +44,6 @@ Logs a given user in, sets the current session. To log all users out pass `null`
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$this->logInAs(null);
|
||||
```
|
||||
|
||||
@ -59,10 +55,10 @@ The `FunctionalTest` class also provides additional asserts to validate your tes
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$this->assertPartialMatchBySelector('p.good',array(
|
||||
$this->assertPartialMatchBySelector('p.good',[
|
||||
'Test save was successful'
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
Asserts that the most recently queried page contains a number of content tags specified by a CSS selector. The given CSS
|
||||
@ -74,10 +70,10 @@ assertion fails if one of the expectedMatches fails to appear.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$this->assertExactMatchBySelector("#MyForm_ID p.error", array(
|
||||
$this->assertExactMatchBySelector("#MyForm_ID p.error", [
|
||||
"That email address is invalid."
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
Asserts that the most recently queried page contains a number of content tags specified by a CSS selector. The given CSS
|
||||
@ -86,10 +82,10 @@ assertion fails if one of the expectedMatches fails to appear.
|
||||
|
||||
### assertPartialHTMLMatchBySelector
|
||||
```php
|
||||
|
||||
$this->assertPartialHTMLMatchBySelector("#MyForm_ID p.error", array(
|
||||
$this->assertPartialHTMLMatchBySelector("#MyForm_ID p.error", [
|
||||
"That email address is invalid."
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
Assert that the most recently queried page contains a number of content tags specified by a CSS selector. The given CSS
|
||||
@ -102,10 +98,10 @@ assertion fails if one of the expectedMatches fails to appear.
|
||||
|
||||
### assertExactHTMLMatchBySelector
|
||||
```php
|
||||
|
||||
$this->assertExactHTMLMatchBySelector("#MyForm_ID p.error", array(
|
||||
$this->assertExactHTMLMatchBySelector("#MyForm_ID p.error", [
|
||||
"That email address is invalid."
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
Assert that the most recently queried page contains a number of content tags specified by a CSS selector. The given CSS
|
||||
|
@ -16,9 +16,7 @@ To include your fixture file in your tests, you should define it as your `$fixtu
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyNewTest extends SapphireTest {
|
||||
|
||||
protected static $fixture_file = 'fixtures.yml';
|
||||
@ -33,17 +31,16 @@ You can also use an array of fixture files, if you want to use parts of multiple
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyNewTest extends SapphireTest {
|
||||
|
||||
protected static $fixture_file = array(
|
||||
protected static $fixture_file = [
|
||||
'fixtures.yml',
|
||||
'otherfixtures.yml'
|
||||
);
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Typically, you'd have a separate fixture file for each class you are testing - although overlap between tests is common.
|
||||
@ -53,33 +50,32 @@ ideal for fixture generation. Say we have the following two DataObjects:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
use SilverStripe\ORM\DataObject;
|
||||
|
||||
class Player extends DataObject
|
||||
{
|
||||
private static $db = array (
|
||||
private static $db = [
|
||||
'Name' => 'Varchar(255)'
|
||||
);
|
||||
];
|
||||
|
||||
private static $has_one = array(
|
||||
private static $has_one = [
|
||||
'Team' => 'Team'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
class Team extends DataObject
|
||||
{
|
||||
private static $db = array (
|
||||
private static $db = [
|
||||
'Name' => 'Varchar(255)',
|
||||
'Origin' => 'Varchar(255)'
|
||||
);
|
||||
];
|
||||
|
||||
private static $has_many = array(
|
||||
private static $has_many = [
|
||||
'Players' => 'Player'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
We can represent multiple instances of them in `YAML` as follows:
|
||||
@ -116,7 +112,6 @@ represents a new object and can be referenced in the PHP using `objFromFixture`
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$player = $this->objFromFixture('Player', 'jack');
|
||||
```
|
||||
|
||||
@ -173,15 +168,15 @@ writing:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$team = new Team(array(
|
||||
$team = new Team([
|
||||
'Name' => 'Hurricanes',
|
||||
'Origin' => 'Wellington'
|
||||
));
|
||||
]);
|
||||
|
||||
$team->write();
|
||||
|
||||
$team->Players()->add($john);
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
@ -218,36 +213,36 @@ declare the role each player has in the team.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
use SilverStripe\ORM\DataObject;
|
||||
|
||||
class Player extends DataObject
|
||||
{
|
||||
private static $db = array (
|
||||
private static $db = [
|
||||
'Name' => 'Varchar(255)'
|
||||
);
|
||||
];
|
||||
|
||||
private static $belongs_many_many = array(
|
||||
private static $belongs_many_many = [
|
||||
'Teams' => 'Team'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
class Team extends DataObject
|
||||
{
|
||||
private static $db = array (
|
||||
private static $db = [
|
||||
'Name' => 'Varchar(255)'
|
||||
);
|
||||
];
|
||||
|
||||
private static $many_many = array(
|
||||
private static $many_many = [
|
||||
'Players' => 'Player'
|
||||
);
|
||||
];
|
||||
|
||||
private static $many_many_extraFields = array(
|
||||
'Players' => array(
|
||||
private static $many_many_extraFields = [
|
||||
'Players' => [
|
||||
'Role' => "Varchar"
|
||||
)
|
||||
);
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
To provide the value for the `many_many_extraField` use the YAML list syntax.
|
||||
@ -298,7 +293,6 @@ using them.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$factory = Injector::inst()->create('FixtureFactory');
|
||||
|
||||
$obj = $factory->createObject('Team', 'hurricanes');
|
||||
@ -308,10 +302,10 @@ In order to create an object with certain properties, just add a third argument:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$obj = $factory->createObject('Team', 'hurricanes', array(
|
||||
$obj = $factory->createObject('Team', 'hurricanes', [
|
||||
'Name' => 'My Value'
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
<div class="warning" markdown="1">
|
||||
@ -323,7 +317,6 @@ After we've created this object in the factory, `getId` is used to retrieve it b
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$databaseId = $factory->getId('Team', 'hurricanes');
|
||||
```
|
||||
|
||||
@ -334,10 +327,10 @@ name, we can set the default to be `Unknown Team`.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$factory->define('Team', array(
|
||||
$factory->define('Team', [
|
||||
'Name' => 'Unknown Team'
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
### Dependent Properties
|
||||
@ -347,8 +340,7 @@ values based on other fixture data.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$factory->define('Member', array(
|
||||
$factory->define('Member', [
|
||||
'Email' => function($obj, $data, $fixtures) {
|
||||
if(isset($data['FirstName']) {
|
||||
$obj->Email = strtolower($data['FirstName']) . '@example.org';
|
||||
@ -357,7 +349,8 @@ values based on other fixture data.
|
||||
'Score' => function($obj, $data, $fixtures) {
|
||||
$obj->Score = rand(0,10);
|
||||
}
|
||||
));
|
||||
)];
|
||||
|
||||
```
|
||||
|
||||
### Relations
|
||||
@ -367,10 +360,10 @@ Model relations can be expressed through the same notation as in the YAML fixtur
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$obj = $factory->createObject('Team', 'hurricanes', array(
|
||||
$obj = $factory->createObject('Team', 'hurricanes', [
|
||||
'MyHasManyRelation' => '=>Player.john,=>Player.joe'
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
#### Callbacks
|
||||
@ -380,7 +373,6 @@ publish a page, which requires a method call.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$blueprint = Injector::inst()->create('FixtureBlueprint', 'Member');
|
||||
|
||||
$blueprint->addCallback('afterCreate', function($obj, $identifier, $data, $fixtures) {
|
||||
@ -403,7 +395,6 @@ equal the class names they manage.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$memberBlueprint = Injector::inst()->create('FixtureBlueprint', 'Member', 'Member');
|
||||
|
||||
$adminBlueprint = Injector::inst()->create('FixtureBlueprint', 'AdminMember', 'Member');
|
||||
|
@ -9,9 +9,7 @@ how you can load default records into the test database.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
|
||||
class PageTest extends SapphireTest
|
||||
@ -32,12 +30,12 @@ how you can load default records into the test database.
|
||||
*/
|
||||
public function testURLGeneration()
|
||||
{
|
||||
$expectedURLs = array(
|
||||
$expectedURLs = [
|
||||
'home' => 'home',
|
||||
'staff' => 'my-staff',
|
||||
'about' => 'about-us',
|
||||
'staffduplicate' => 'my-staff-2'
|
||||
);
|
||||
];
|
||||
|
||||
foreach($expectedURLs as $fixture => $urlSegment) {
|
||||
$obj = $this->objFromFixture('Page', $fixture);
|
||||
@ -46,6 +44,7 @@ how you can load default records into the test database.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Firstly we define a static `$fixture_file`, this should point to a file that represents the data we want to test,
|
||||
|
@ -11,9 +11,7 @@ response and modify the session within a test.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class HomePageTest extends FunctionalTest {
|
||||
|
||||
/**
|
||||
@ -26,15 +24,15 @@ response and modify the session within a test.
|
||||
$this->assertEquals(200, $page->getStatusCode());
|
||||
|
||||
// We should see a login form
|
||||
$login = $this->submitForm("LoginFormID", null, array(
|
||||
$login = $this->submitForm("LoginFormID", null, [
|
||||
'Email' => 'test@test.com',
|
||||
'Password' => 'wrongpassword'
|
||||
));
|
||||
]);
|
||||
|
||||
// wrong details, should now see an error message
|
||||
$this->assertExactHTMLMatchBySelector("#LoginForm p.error", array(
|
||||
$this->assertExactHTMLMatchBySelector("#LoginForm p.error", [
|
||||
"That email address is invalid."
|
||||
));
|
||||
]);
|
||||
|
||||
// If we login as a user we should see a welcome message
|
||||
$me = Member::get()->first();
|
||||
@ -42,11 +40,12 @@ response and modify the session within a test.
|
||||
$this->logInAs($me);
|
||||
$page = $this->get('home/');
|
||||
|
||||
$this->assertExactHTMLMatchBySelector("#Welcome", array(
|
||||
$this->assertExactHTMLMatchBySelector("#Welcome", [
|
||||
'Welcome Back'
|
||||
));
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
@ -10,7 +10,6 @@ with information that we need.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyObjectTest extends SapphireTest {
|
||||
|
||||
protected $factory;
|
||||
@ -21,9 +20,9 @@ with information that we need.
|
||||
$factory = Injector::inst()->create('FixtureFactory');
|
||||
|
||||
// Defines a "blueprint" for new objects
|
||||
$factory->define('MyObject', array(
|
||||
$factory->define('MyObject', [
|
||||
'MyProperty' => 'My Default Value'
|
||||
));
|
||||
]);
|
||||
|
||||
$this->factory = $factory;
|
||||
}
|
||||
@ -31,7 +30,7 @@ with information that we need.
|
||||
function testSomething() {
|
||||
$MyObjectObj = $this->factory->createObject(
|
||||
'MyObject',
|
||||
array('MyOtherProperty' => 'My Custom Value')
|
||||
['MyOtherProperty' => 'My Custom Value']
|
||||
);
|
||||
|
||||
echo $MyObjectObj->MyProperty;
|
||||
@ -41,6 +40,7 @@ with information that we need.
|
||||
// returns "My Custom Value"
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
@ -8,7 +8,6 @@ email was sent using this method.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function MyMethod() {
|
||||
$e = new Email();
|
||||
$e->To = "someone@example.com";
|
||||
@ -22,7 +21,6 @@ To test that `MyMethod` sends the correct email, use the [SapphireTest::assertEm
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$this->assertEmailSent($to, $from, $subject, $body);
|
||||
|
||||
// to assert that the email is sent to the correct person
|
||||
|
@ -83,7 +83,6 @@ You can check for the current environment type in [config files](../configuratio
|
||||
Checking for what environment you're running in can also be done in PHP. Your application code may disable or enable
|
||||
certain functionality depending on the environment type.
|
||||
```php
|
||||
|
||||
if (Director::isLive()) {
|
||||
// is in live
|
||||
} elseif (Director::isTest()) {
|
||||
|
@ -98,18 +98,17 @@ For example, a block that shows a collection of rotating slides needs to update
|
||||
|
||||
|
||||
```php
|
||||
|
||||
|
||||
public function SliderCacheKey() {
|
||||
$fragments = array(
|
||||
$fragments = [
|
||||
'Page-Slides',
|
||||
$this->ID,
|
||||
// identify which objects are in the list and their sort order
|
||||
implode('-', $this->Slides()->Column('ID')),
|
||||
$this->Slides()->max('LastEdited')
|
||||
);
|
||||
];
|
||||
return implode('-_-', $fragments);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Then reference that function in the cache key:
|
||||
@ -147,7 +146,6 @@ configurable only on a site-wide basis), you could add a special function to you
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function BlogStatisticsCounter() {
|
||||
return (int)(time() / 60 / 5); // Returns a new number every five minutes
|
||||
}
|
||||
@ -308,7 +306,6 @@ logic is sound, you could increase the expiry dramatically.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// Set partial cache expiry to 7 days
|
||||
SS_Cache::set_cache_lifetime('cacheblock', 60 * 60 * 24 * 7);
|
||||
```
|
||||
|
@ -47,7 +47,6 @@ This factory allows us you to globally define an adapter for all cache instances
|
||||
|
||||
|
||||
```php
|
||||
|
||||
use Psr\SimpleCache\CacheInterface
|
||||
$cache = Injector::inst()->get(CacheInterface::class . '.myCache');
|
||||
```
|
||||
@ -67,7 +66,6 @@ Cache objects follow the [PSR-16](http://www.php-fig.org/psr/psr-16/) class inte
|
||||
|
||||
|
||||
```php
|
||||
|
||||
use Psr\SimpleCache\CacheInterface
|
||||
$cache = Injector::inst()->get(CacheInterface::class . '.myCache');
|
||||
|
||||
@ -92,7 +90,6 @@ this will only affect a subset of cache keys ("myCache" in this example):
|
||||
|
||||
|
||||
```php
|
||||
|
||||
use Psr\SimpleCache\CacheInterface
|
||||
$cache = Injector::inst()->get(CacheInterface::class . '.myCache');
|
||||
|
||||
@ -105,7 +102,6 @@ You can also delete a single item based on it's cache key:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
use Psr\SimpleCache\CacheInterface
|
||||
$cache = Injector::inst()->get(CacheInterface::class . '.myCache');
|
||||
|
||||
@ -117,7 +113,6 @@ Individual cache items can define a lifetime, after which the cached value is ma
|
||||
|
||||
|
||||
```php
|
||||
|
||||
use Psr\SimpleCache\CacheInterface
|
||||
$cache = Injector::inst()->get(CacheInterface::class . '.myCache');
|
||||
|
||||
@ -150,7 +145,6 @@ old cache keys will be garbage collected as the cache fills up.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
use Psr\SimpleCache\CacheInterface
|
||||
$cache = Injector::inst()->get(CacheInterface::class . '.myCache');
|
||||
|
||||
|
@ -18,7 +18,6 @@ headers:
|
||||
|
||||
### HTTP::set_cache_age
|
||||
```php
|
||||
|
||||
HTTP::set_cache_age(0);
|
||||
```
|
||||
|
||||
@ -29,7 +28,6 @@ clause in `Cache-Control` and `Pragma` will be included.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
HTTP::register_modification_date('2014-10-10');
|
||||
```
|
||||
|
||||
|
@ -17,7 +17,6 @@ next method for testing if you just need to test.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// Is a member logged in?
|
||||
if( Member::currentUserID() ) {
|
||||
// Yes!
|
||||
@ -32,7 +31,6 @@ Returns the full *Member* Object for the current user, returns *null* if user is
|
||||
|
||||
|
||||
```php
|
||||
|
||||
if( $member = Security::getCurrentUser() ) {
|
||||
// Work with $member
|
||||
} else {
|
||||
@ -51,13 +49,13 @@ You can define subclasses of [Member](api:SilverStripe\Security\Member) to add e
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyMember extends Member {
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
"Age" => "Int",
|
||||
"Address" => "Text",
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
To ensure that all new members are created using this class, put a call to [Object::useCustomClass()](api:Object::useCustomClass()) in
|
||||
@ -65,7 +63,6 @@ To ensure that all new members are created using this class, put a call to [Obje
|
||||
|
||||
|
||||
```php
|
||||
|
||||
Object::useCustomClass("Member", "MyMember");
|
||||
```
|
||||
|
||||
@ -79,7 +76,6 @@ parent::getCMSFields() and manipulate the [FieldList](api:SilverStripe\Forms\Fie
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function getCMSFields() {
|
||||
$fields = parent::getCMSFields();
|
||||
$fields->insertBefore("HTMLEmail", new TextField("Age"));
|
||||
@ -118,7 +114,6 @@ things, you should add appropriate [Permission::checkMember()](api:SilverStripe\
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyMemberExtension extends DataExtension {
|
||||
/**
|
||||
|
||||
@ -132,16 +127,17 @@ things, you should add appropriate [Permission::checkMember()](api:SilverStripe\
|
||||
}
|
||||
|
||||
// define additional properties
|
||||
private static $db = array();
|
||||
private static $has_one = array();
|
||||
private static $has_many = array();
|
||||
private static $many_many = array();
|
||||
private static $belongs_many_many = array();
|
||||
private static $db = [];
|
||||
private static $has_one = [];
|
||||
private static $has_many = [];
|
||||
private static $many_many = [];
|
||||
private static $belongs_many_many = [];
|
||||
|
||||
public function somethingElse() {
|
||||
// You can add any other methods you like, which you can call directly on the member object.
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Saved User Logins ##
|
||||
@ -172,7 +168,6 @@ E.g.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class CleanRecordsTask extends BuildTask
|
||||
{
|
||||
public function run($request)
|
||||
|
@ -38,11 +38,12 @@ class PageController implements PermissionProvider
|
||||
|
||||
public function providePermissions()
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
'VIEW_SITE' => 'Access the site'
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
@ -26,35 +26,35 @@ come from user input.
|
||||
|
||||
Example:
|
||||
```php
|
||||
|
||||
$records = DB::prepared_query('SELECT * FROM "MyClass" WHERE "ID" = ?', array(3));
|
||||
$records = MyClass::get()->where(array('"ID" = ?' => 3));
|
||||
$records = MyClass::get()->where(array('"ID"' => 3));
|
||||
$records = DB::prepared_query('SELECT * FROM "MyClass" WHERE "ID" = ?', [3]);
|
||||
$records = MyClass::get()->where(['"ID" = ?' => 3]);
|
||||
$records = MyClass::get()->where(['"ID"' => 3]);
|
||||
$records = DataObject::get_by_id('MyClass', 3);
|
||||
$records = DataObject::get_one('MyClass', array('"ID" = ?' => 3));
|
||||
$records = DataObject::get_one('MyClass', ['"ID" = ?' => 3]);
|
||||
$records = MyClass::get()->byID(3);
|
||||
$records = SQLSelect::create()->addWhere(array('"ID"' => 3))->execute();
|
||||
$records = SQLSelect::create()->addWhere(['"ID"' => 3])->execute();
|
||||
|
||||
```
|
||||
|
||||
Parameterised updates and inserts are also supported, but the syntax is a little different
|
||||
|
||||
|
||||
```php
|
||||
|
||||
SQLInsert::create('"MyClass"')
|
||||
->assign('"Name"', 'Daniel')
|
||||
->addAssignments(array(
|
||||
->addAssignments([
|
||||
'"Position"' => 'Accountant',
|
||||
'"Age"' => array(
|
||||
'GREATEST(0,?,?)' => array(24, 28)
|
||||
)
|
||||
))
|
||||
'"Age"' => [
|
||||
'GREATEST(0,?,?)' => [24, 28]
|
||||
]
|
||||
])
|
||||
->assignSQL('"Created"', 'NOW()')
|
||||
->execute();
|
||||
DB::prepared_query(
|
||||
'INSERT INTO "MyClass" ("Name", "Position", "Age", "Created") VALUES(?, ?, GREATEST(0,?,?), NOW())'
|
||||
array('Daniel', 'Accountant', 24, 28)
|
||||
['Daniel', 'Accountant', 24, 28]
|
||||
);
|
||||
|
||||
```
|
||||
|
||||
### Automatic escaping
|
||||
@ -80,15 +80,15 @@ handled via prepared statements.
|
||||
|
||||
Example:
|
||||
```php
|
||||
|
||||
// automatically escaped/quoted
|
||||
$members = Member::get()->filter('Name', $_GET['name']);
|
||||
// automatically escaped/quoted
|
||||
$members = Member::get()->filter(array('Name' => $_GET['name']));
|
||||
$members = Member::get()->filter(['Name' => $_GET['name']]);
|
||||
// parameterised condition
|
||||
$members = Member::get()->where(array('"Name" = ?' => $_GET['name']));
|
||||
$members = Member::get()->where(['"Name" = ?' => $_GET['name']]);
|
||||
// needs to be escaped and quoted manually (note raw2sql called with the $quote parameter set to true)
|
||||
$members = Member::get()->where(sprintf('"Name" = %s', Convert::raw2sql($_GET['name'], true)));
|
||||
|
||||
```
|
||||
|
||||
<div class="warning" markdown='1'>
|
||||
@ -114,7 +114,6 @@ Example:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyForm extends Form {
|
||||
public function save($RAW_data, $form) {
|
||||
// Pass true as the second parameter of raw2sql to quote the value safely
|
||||
@ -123,6 +122,7 @@ Example:
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
* `FormField->Value()`
|
||||
@ -132,9 +132,8 @@ Example:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyController extends Controller {
|
||||
private static $allowed_actions = array('myurlaction');
|
||||
private static $allowed_actions = ['myurlaction'];
|
||||
public function myurlaction($RAW_urlParams) {
|
||||
// Pass true as the second parameter of raw2sql to quote the value safely
|
||||
$SQL_urlParams = Convert::raw2sql($RAW_urlParams, true); // works recursively on an array
|
||||
@ -142,6 +141,7 @@ Example:
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
As a rule of thumb, you should escape your data **as close to querying as possible**
|
||||
@ -150,7 +150,6 @@ passing data through, escaping should happen at the end of the chain.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyController extends Controller {
|
||||
/**
|
||||
* @param array $RAW_data All names in an indexed array (not SQL-safe)
|
||||
@ -165,6 +164,7 @@ passing data through, escaping should happen at the end of the chain.
|
||||
DB::query("UPDATE Player SET Name = {$SQL_name}");
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
This might not be applicable in all cases - especially if you are building an API thats likely to be customised. If
|
||||
@ -231,20 +231,19 @@ PHP:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyObject extends DataObject {
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'MyEscapedValue' => 'Text', // Example value: <b>not bold</b>
|
||||
'MyUnescapedValue' => 'HTMLText' // Example value: <b>bold</b>
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Template:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<ul>
|
||||
<li>$MyEscapedValue</li> // output: <b>not bold<b>
|
||||
<li>$MyUnescapedValue</li> // output: <b>bold</b>
|
||||
@ -263,7 +262,6 @@ Template (see above):
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<ul>
|
||||
// output: <a href="#" title="foo & &#quot;bar"">foo & "bar"</a>
|
||||
<li><a href="#" title="$Title.ATT">$Title</a></li>
|
||||
@ -282,27 +280,26 @@ PHP:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyObject extends DataObject {
|
||||
public $Title = '<b>not bold</b>'; // will be escaped due to Text casting
|
||||
|
||||
$casting = array(
|
||||
$casting = [
|
||||
"Title" => "Text", // forcing a casting
|
||||
'TitleWithHTMLSuffix' => 'HTMLText' // optional, as HTMLText is the default casting
|
||||
);
|
||||
];
|
||||
|
||||
public function TitleWithHTMLSuffix($suffix) {
|
||||
// $this->Title is not casted in PHP
|
||||
return $this->Title . '<small>(' . $suffix. ')</small>';
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Template:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<ul>
|
||||
<li>$Title</li> // output: <b>not bold<b>
|
||||
<li>$Title.RAW</li> // output: <b>not bold</b>
|
||||
@ -325,24 +322,23 @@ PHP:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyController extends Controller {
|
||||
private static $allowed_actions = array('search');
|
||||
private static $allowed_actions = ['search'];
|
||||
public function search($request) {
|
||||
$htmlTitle = '<p>Your results for:' . Convert::raw2xml($request->getVar('Query')) . '</p>';
|
||||
return $this->customise(array(
|
||||
return $this->customise([
|
||||
'Query' => Text::create($request->getVar('Query')),
|
||||
'HTMLTitle' => HTMLText::create($htmlTitle)
|
||||
));
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Template:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<h2 title="Searching for $Query.ATT">$HTMLTitle</h2>
|
||||
```
|
||||
|
||||
@ -359,24 +355,23 @@ PHP:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyController extends Controller {
|
||||
private static $allowed_actions = array('search');
|
||||
private static $allowed_actions = ['search'];
|
||||
public function search($request) {
|
||||
$rssRelativeLink = "/rss?Query=" . urlencode($_REQUEST['query']) . "&sortOrder=asc";
|
||||
$rssLink = Controller::join_links($this->Link(), $rssRelativeLink);
|
||||
return $this->customise(array(
|
||||
return $this->customise([
|
||||
"RSSLink" => Text::create($rssLink),
|
||||
));
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Template:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<a href="$RSSLink.ATT">RSS feed</a>
|
||||
```
|
||||
|
||||
@ -426,7 +421,6 @@ Below is an example with different ways you would use this casting technique:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function CaseStudies() {
|
||||
|
||||
// cast an ID from URL parameters e.g. (mysite.com/home/action/ID)
|
||||
@ -524,12 +518,12 @@ a [PasswordValidator](api:SilverStripe\Security\PasswordValidator):
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$validator = new PasswordValidator();
|
||||
$validator->minLength(7);
|
||||
$validator->checkHistoricalPasswords(6);
|
||||
$validator->characterStrength(3, array("lowercase", "uppercase", "digits", "punctuation"));
|
||||
$validator->characterStrength(3, ["lowercase", "uppercase", "digits", "punctuation"]);
|
||||
Member::set_password_validator($validator);
|
||||
|
||||
```
|
||||
|
||||
In addition, you can tighten password security with the following configuration settings:
|
||||
@ -554,7 +548,6 @@ controller's `init()` method:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyController extends Controller {
|
||||
public function init() {
|
||||
parent::init();
|
||||
@ -638,8 +631,6 @@ variable will be no longer necessary, thus it will be necessary to always set
|
||||
SilverStripe recommends the use of TLS(HTTPS) for your application, and you can easily force the use through the
|
||||
director function `forceSSL()`
|
||||
```php
|
||||
|
||||
|
||||
if (!Director::isDev()) {
|
||||
Director::forceSSL();
|
||||
}
|
||||
@ -668,7 +659,6 @@ clear text and can be intercepted and stolen by an attacker who is listening on
|
||||
code. It is best practice to set this flag unless the application is known to use JavaScript to access these cookies
|
||||
as this prevents an attacker who achieves cross-site scripting from accessing these cookies.
|
||||
```php
|
||||
|
||||
|
||||
Cookie::set('cookie-name', 'chocolate-chip', $expiry = 30, $path = null, $domain = null, $secure = true,
|
||||
$httpOnly = false
|
||||
@ -697,8 +687,6 @@ and `Date: <current date>` will ensure that sensitive content is not stored loca
|
||||
unauthorised local persons. SilverStripe adds the current date for every request, and we can add the other cache
|
||||
headers to the request for our secure controllers:
|
||||
```php
|
||||
|
||||
|
||||
class MySecureController extends Controller {
|
||||
|
||||
public function init() {
|
||||
|
@ -24,7 +24,6 @@ SilverStripe\Core\Injector\Injector:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$email = new Email($from, $to, $subject, $body);
|
||||
$email->sendPlain();
|
||||
```
|
||||
@ -37,7 +36,6 @@ to `*text*`).
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$email = new Email($from, $to, $subject, $body);
|
||||
$email->send();
|
||||
```
|
||||
@ -68,10 +66,10 @@ The PHP Logic..
|
||||
```php
|
||||
$email = SilverStripe\Control\Email\Email::create()
|
||||
->setHTMLTemplate('Email\\MyCustomEmail')
|
||||
->setData(array(
|
||||
->setData([
|
||||
'Member' => Security::getCurrentUser(),
|
||||
'Link'=> $link,
|
||||
))
|
||||
])
|
||||
->setFrom($from)
|
||||
->setTo($to)
|
||||
->setSubject($subject);
|
||||
@ -81,6 +79,7 @@ if ($email->send()) {
|
||||
} else {
|
||||
// there may have been 1 or more failures
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
@ -136,7 +135,6 @@ Configuration of those properties looks like the following:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
if(Director::isLive()) {
|
||||
Config::inst()->update('Email', 'bcc_all_emails_to', "client@example.com");
|
||||
} else {
|
||||
@ -151,7 +149,6 @@ email, do the following. This is encouraged especially when the domain responsib
|
||||
necessarily the same which should be used for return correspondence and should help prevent your message from being
|
||||
marked as spam.
|
||||
```php
|
||||
|
||||
$email = new Email(..);
|
||||
$email->setReplyTo('me@address.com');
|
||||
```
|
||||
@ -163,7 +160,6 @@ For email headers which do not have getters or setters (like setTo(), setFrom())
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$email = new Email(...);
|
||||
$email->getSwiftMessage()->getHeaders()->addTextHeader('HeaderName', 'HeaderValue');
|
||||
..
|
||||
|
@ -36,7 +36,6 @@ The loader would be triggered through the `load()` method:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$loader = new CsvBulkLoader('Member');
|
||||
$result = $loader->load('<my-file-path>');
|
||||
```
|
||||
@ -50,18 +49,17 @@ The simplest way to use [CsvBulkLoader](api:SilverStripe\Dev\CsvBulkLoader) is t
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
class PlayerAdmin extends ModelAdmin {
|
||||
private static $managed_models = array(
|
||||
class PlayerAdmin extends ModelAdmin {
|
||||
private static $managed_models = [
|
||||
'Player'
|
||||
);
|
||||
private static $model_importers = array(
|
||||
];
|
||||
private static $model_importers = [
|
||||
'Player' => 'CsvBulkLoader',
|
||||
);
|
||||
];
|
||||
private static $url_segment = 'players';
|
||||
}
|
||||
?>
|
||||
|
||||
```
|
||||
|
||||
The new admin interface will be available under `http://localhost/admin/players`, the import form is located
|
||||
@ -76,11 +74,9 @@ You'll need to add a route to your controller to make it accessible via URL
|
||||
|
||||
|
||||
```php
|
||||
class MyController extends Controller {
|
||||
|
||||
<?php
|
||||
class MyController extends Controller {
|
||||
|
||||
private static $allowed_actions = array('Form');
|
||||
private static $allowed_actions = ['Form'];
|
||||
|
||||
protected $template = "BlankPage";
|
||||
|
||||
@ -106,7 +102,7 @@ You'll need to add a route to your controller to make it accessible via URL
|
||||
public function doUpload($data, $form) {
|
||||
$loader = new CsvBulkLoader('MyDataObject');
|
||||
$results = $loader->load($_FILES['CsvFile']['tmp_name']);
|
||||
$messages = array();
|
||||
$messages = [];
|
||||
if($results->CreatedCount()) $messages[] = sprintf('Imported %d items', $results->CreatedCount());
|
||||
if($results->UpdatedCount()) $messages[] = sprintf('Updated %d items', $results->UpdatedCount());
|
||||
if($results->DeletedCount()) $messages[] = sprintf('Deleted %d items', $results->DeletedCount());
|
||||
@ -116,6 +112,7 @@ You'll need to add a route to your controller to make it accessible via URL
|
||||
return $this->redirectBack();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Note: This interface is not secured, consider using [Permission::check()](api:SilverStripe\Security\Permission::check()) to limit the controller to users
|
||||
@ -137,37 +134,35 @@ Datamodel for Player
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
class Player extends DataObject {
|
||||
private static $db = array(
|
||||
class Player extends DataObject {
|
||||
private static $db = [
|
||||
'PlayerNumber' => 'Int',
|
||||
'FirstName' => 'Text',
|
||||
'LastName' => 'Text',
|
||||
'Birthday' => 'Date',
|
||||
);
|
||||
private static $has_one = array(
|
||||
];
|
||||
private static $has_one = [
|
||||
'Team' => 'FootballTeam'
|
||||
);
|
||||
];
|
||||
}
|
||||
?>
|
||||
|
||||
```
|
||||
|
||||
Datamodel for FootballTeam:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
class FootballTeam extends DataObject {
|
||||
private static $db = array(
|
||||
class FootballTeam extends DataObject {
|
||||
private static $db = [
|
||||
'Title' => 'Text',
|
||||
);
|
||||
private static $has_many = array(
|
||||
];
|
||||
private static $has_many = [
|
||||
'Players' => 'Player'
|
||||
);
|
||||
];
|
||||
}
|
||||
?>
|
||||
|
||||
```
|
||||
|
||||
Sample implementation of a custom loader. Assumes a CSV-file in a certain format (see below).
|
||||
@ -177,24 +172,22 @@ Sample implementation of a custom loader. Assumes a CSV-file in a certain format
|
||||
* Avoids duplicate imports by a custom `$duplicateChecks` definition
|
||||
* Creates `Team` relations automatically based on the `Gruppe` column in the CSV data
|
||||
```php
|
||||
|
||||
<?php
|
||||
class PlayerCsvBulkLoader extends CsvBulkLoader {
|
||||
public $columnMap = array(
|
||||
class PlayerCsvBulkLoader extends CsvBulkLoader {
|
||||
public $columnMap = [
|
||||
'Number' => 'PlayerNumber',
|
||||
'Name' => '->importFirstAndLastName',
|
||||
'Birthday' => 'Birthday',
|
||||
'Team' => 'Team.Title',
|
||||
);
|
||||
public $duplicateChecks = array(
|
||||
];
|
||||
public $duplicateChecks = [
|
||||
'Number' => 'PlayerNumber'
|
||||
);
|
||||
public $relationCallbacks = array(
|
||||
'Team.Title' => array(
|
||||
];
|
||||
public $relationCallbacks = [
|
||||
'Team.Title' => [
|
||||
'relationname' => 'Team',
|
||||
'callback' => 'getTeamByTitle'
|
||||
)
|
||||
);
|
||||
]
|
||||
];
|
||||
public static function importFirstAndLastName(&$obj, $val, $record) {
|
||||
$parts = explode(' ', $val);
|
||||
if(count($parts) != 2) return false;
|
||||
@ -206,24 +199,24 @@ Sample implementation of a custom loader. Assumes a CSV-file in a certain format
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
```
|
||||
|
||||
Building off of the ModelAdmin example up top, use a custom loader instead of the default loader by adding it to `$model_importers`. In this example, `CsvBulkLoader` is replaced with `PlayerCsvBulkLoader`.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
class PlayerAdmin extends ModelAdmin {
|
||||
private static $managed_models = array(
|
||||
class PlayerAdmin extends ModelAdmin {
|
||||
private static $managed_models = [
|
||||
'Player'
|
||||
);
|
||||
private static $model_importers = array(
|
||||
];
|
||||
private static $model_importers = [
|
||||
'Player' => 'PlayerCsvBulkLoader',
|
||||
);
|
||||
];
|
||||
private static $url_segment = 'players';
|
||||
}
|
||||
?>
|
||||
|
||||
```
|
||||
|
||||
## Related
|
||||
|
@ -21,15 +21,14 @@ in the template.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function getWellingtonWeather() {
|
||||
$fetch = new RestfulService(
|
||||
'https://query.yahooapis.com/v1/public/yql'
|
||||
);
|
||||
|
||||
$fetch->setQueryString(array(
|
||||
$fetch->setQueryString([
|
||||
'q' => 'select * from weather.forecast where woeid in (select woeid from geo.places(1) where text="Wellington, NZ")'
|
||||
));
|
||||
]);
|
||||
|
||||
// perform the query
|
||||
$conn = $fetch->request();
|
||||
@ -42,14 +41,15 @@ in the template.
|
||||
|
||||
if($msgs) {
|
||||
foreach($msgs as $msg) {
|
||||
$output->push(new ArrayData(array(
|
||||
$output->push(new ArrayData([
|
||||
'Description' => Convert::xml2raw($msg->channel_item_description)
|
||||
)));
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Features
|
||||
@ -58,7 +58,6 @@ in the template.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$service = new RestfulService("http://example.harvestapp.com");
|
||||
$service->basicAuth('username', 'password');
|
||||
```
|
||||
@ -67,7 +66,6 @@ in the template.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$service = new RestfulService("http://example.harvestapp.com");
|
||||
|
||||
$peopleXML = $service->request('/people');
|
||||
@ -85,7 +83,6 @@ To set the cache interval you can pass it as the 2nd argument to constructor.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$expiry = 60 * 60; // 1 hour;
|
||||
|
||||
$request = new RestfulService("http://example.harvestapp.com", $expiry );
|
||||
@ -111,20 +108,20 @@ To extract the id attributes of the entries use:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$this->getAttributes($xml, "entries", "entry");
|
||||
|
||||
// array(array('id' => 12), array('id' => '15'), ..)
|
||||
|
||||
```
|
||||
|
||||
To extract the values (the names) of the entries use:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$this->getValues($xml, "entries", "entry");
|
||||
|
||||
// array('Sally', 'Ted', 'Matt', 'John')
|
||||
|
||||
```
|
||||
|
||||
### Searching for Values & Attributes
|
||||
@ -147,10 +144,10 @@ To get the value of entry node with the namespace media, use:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$this->searchValue($response, "//media:guide/media:entry");
|
||||
|
||||
// array('video');
|
||||
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
@ -163,9 +160,7 @@ If the web service returned an error (for example, API key not available or inad
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyRestfulService extends RestfulService {
|
||||
|
||||
public function errorCatch($response) {
|
||||
@ -184,9 +179,7 @@ If you want to bypass error handling, define `checkErrors` in the constructor fo
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyRestfulService extends RestfulService {
|
||||
|
||||
public function __construct($expiry = NULL) {
|
||||
@ -216,10 +209,11 @@ To set global cURL settings you can update the `RestfulService` config via the C
|
||||
Here is an example to increase the HTTP Timeout globally. Insert this in your `_config.php` file:
|
||||
|
||||
```php
|
||||
SilverStripe\Core\Config\Config::inst()->update('RestfulService', 'default_curl_options', array(
|
||||
SilverStripe\Core\Config\Config::inst()->update('RestfulService', 'default_curl_options', [
|
||||
CURLOPT_DNS_CACHE_TIMEOUT => 3600,
|
||||
CURLOPT_CONNECTTIMEOUT => 10,
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
|
||||
@ -231,15 +225,15 @@ parameter in `RestfulService::request()`.
|
||||
For example:
|
||||
|
||||
```php
|
||||
|
||||
//cURL options
|
||||
$curlOptions = array(
|
||||
$curlOptions = [
|
||||
CURLOPT_UNRESTRICTED_AUTH => true,
|
||||
);
|
||||
];
|
||||
|
||||
$service = new RestfulService('http://example.com/');
|
||||
$service->request('service.json', 'GET', null, null, $curlOptions);
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
@ -24,7 +24,6 @@ An outline of step one looks like:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$feed = new RSSFeed(
|
||||
$list,
|
||||
$link,
|
||||
@ -43,7 +42,6 @@ An outline of step one looks like:
|
||||
To achieve step two include the following code where ever you want to include the `<link>` tag to the RSS Feed. This
|
||||
will normally go in your `Controllers` `init` method.
|
||||
```php
|
||||
|
||||
RSSFeed::linkToFeed($link, $title);
|
||||
```
|
||||
|
||||
@ -58,16 +56,14 @@ You can use [RSSFeed](api:SilverStripe\Control\RSS\RSSFeed) to easily create a f
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
..
|
||||
|
||||
class PageController extends ContentController {
|
||||
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'rss'
|
||||
);
|
||||
];
|
||||
|
||||
public function init() {
|
||||
parent::init();
|
||||
@ -90,6 +86,7 @@ You can use [RSSFeed](api:SilverStripe\Control\RSS\RSSFeed) to easily create a f
|
||||
return Page::get()->sort("LastEdited", "DESC")->limit(10);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Rendering DataObjects in a RSSFeed
|
||||
@ -106,9 +103,7 @@ method is defined and returns a string to the full website URL.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Player extends DataObject {
|
||||
|
||||
public function AbsoluteLink() {
|
||||
@ -127,14 +122,12 @@ Then in our controller, we add a new action which returns a the XML list of `Pla
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class PageController extends ContentController {
|
||||
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'players'
|
||||
);
|
||||
];
|
||||
|
||||
public function init() {
|
||||
parent::init();
|
||||
@ -152,6 +145,7 @@ Then in our controller, we add a new action which returns a the XML list of `Pla
|
||||
return $rss->outputToBrowser();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Customizing the RSS Feed template
|
||||
@ -190,8 +184,6 @@ Say from that last example we want to include the Players Team in the XML feed w
|
||||
|
||||
|
||||
```php
|
||||
|
||||
|
||||
public function players() {
|
||||
$rss = new RSSFeed(
|
||||
Player::get(),
|
||||
|
@ -8,14 +8,12 @@ form (which is used for `MyDataObject` instances). You can access it through
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyController extends Controller {
|
||||
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'Form'
|
||||
);
|
||||
];
|
||||
|
||||
protected $template = "BlankPage";
|
||||
|
||||
@ -41,7 +39,7 @@ form (which is used for `MyDataObject` instances). You can access it through
|
||||
public function doUpload($data, $form) {
|
||||
$loader = new CsvBulkLoader('MyDataObject');
|
||||
$results = $loader->load($_FILES['CsvFile']['tmp_name']);
|
||||
$messages = array();
|
||||
$messages = [];
|
||||
|
||||
if($results->CreatedCount()) {
|
||||
$messages[] = sprintf('Imported %d items', $results->CreatedCount());
|
||||
@ -64,6 +62,7 @@ form (which is used for `MyDataObject` instances). You can access it through
|
||||
return $this->redirectBack();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
|
@ -17,41 +17,39 @@ information about the individual player and a relation set up for managing the `
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Player extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'PlayerNumber' => 'Int',
|
||||
'FirstName' => 'Text',
|
||||
'LastName' => 'Text',
|
||||
'Birthday' => 'Date'
|
||||
);
|
||||
];
|
||||
|
||||
private static $has_one = array(
|
||||
private static $has_one = [
|
||||
'Team' => 'FootballTeam'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
**mysite/code/FootballTeam.php**
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class FootballTeam extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Title' => 'Text'
|
||||
);
|
||||
];
|
||||
|
||||
private static $has_many = array(
|
||||
private static $has_many = [
|
||||
'Players' => 'Player'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Now going back to look at the CSV, we can see that what we're provided with does not match what our data model looks
|
||||
@ -70,28 +68,26 @@ Our final import looks like this.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class PlayerCsvBulkLoader extends CsvBulkLoader {
|
||||
|
||||
public $columnMap = array(
|
||||
public $columnMap = [
|
||||
'Number' => 'PlayerNumber',
|
||||
'Name' => '->importFirstAndLastName',
|
||||
'Geburtsdatum' => 'Birthday',
|
||||
'Gruppe' => 'Team.Title',
|
||||
);
|
||||
];
|
||||
|
||||
public $duplicateChecks = array(
|
||||
public $duplicateChecks = [
|
||||
'SpielerNummer' => 'PlayerNumber'
|
||||
);
|
||||
];
|
||||
|
||||
public $relationCallbacks = array(
|
||||
'Team.Title' => array(
|
||||
public $relationCallbacks = [
|
||||
'Team.Title' => [
|
||||
'relationname' => 'Team',
|
||||
'callback' => 'getTeamByTitle'
|
||||
)
|
||||
);
|
||||
]
|
||||
];
|
||||
|
||||
public static function importFirstAndLastName(&$obj, $val, $record) {
|
||||
$parts = explode(' ', $val);
|
||||
@ -104,6 +100,7 @@ Our final import looks like this.
|
||||
return FootballTeam::get()->filter('Title', $val)->First();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Related
|
||||
|
@ -11,15 +11,14 @@ First, we write the code to query the API feed.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function getWellingtonWeather() {
|
||||
$fetch = new RestfulService(
|
||||
'https://query.yahooapis.com/v1/public/yql'
|
||||
);
|
||||
|
||||
$fetch->setQueryString(array(
|
||||
$fetch->setQueryString([
|
||||
'q' => 'select * from weather.forecast where woeid in (select woeid from geo.places(1) where text="Wellington, NZ")'
|
||||
));
|
||||
]);
|
||||
|
||||
// perform the query
|
||||
$conn = $fetch->request();
|
||||
@ -32,14 +31,15 @@ First, we write the code to query the API feed.
|
||||
|
||||
if($msgs) {
|
||||
foreach($msgs as $msg) {
|
||||
$output->push(new ArrayData(array(
|
||||
$output->push(new ArrayData([
|
||||
'Description' => Convert::xml2raw($msg->channel_item_description)
|
||||
)));
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
This will provide our `Page` template with a new `WellingtonWeather` variable (an [ArrayList](api:SilverStripe\ORM\ArrayList)). Each item has a
|
||||
|
@ -20,16 +20,15 @@ Defining search-able fields on your DataObject.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyDataObject extends DataObject {
|
||||
|
||||
private static $searchable_fields = array(
|
||||
private static $searchable_fields = [
|
||||
'Name',
|
||||
'ProductCode'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Customizing fields and filters
|
||||
@ -40,26 +39,24 @@ and `MyDate`. The attribute `HiddenProperty` should not be searchable, and `MyDa
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyDataObject extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'PublicProperty' => 'Text'
|
||||
'HiddenProperty' => 'Text',
|
||||
'MyDate' => 'Date'
|
||||
);
|
||||
];
|
||||
|
||||
public function getDefaultSearchContext() {
|
||||
$fields = $this->scaffoldSearchFields(array(
|
||||
'restrictFields' => array('PublicProperty','MyDate')
|
||||
));
|
||||
$fields = $this->scaffoldSearchFields([
|
||||
'restrictFields' => ['PublicProperty','MyDate']
|
||||
]);
|
||||
|
||||
$filters = array(
|
||||
$filters = [
|
||||
'PublicProperty' => new PartialMatchFilter('PublicProperty'),
|
||||
'MyDate' => new GreaterThanFilter('MyDate')
|
||||
);
|
||||
];
|
||||
|
||||
return new SearchContext(
|
||||
$this->class,
|
||||
@ -68,6 +65,7 @@ and `MyDate`. The attribute `HiddenProperty` should not be searchable, and `MyDa
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
@ -84,9 +82,7 @@ the `$fields` constructor parameter.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
// ..
|
||||
|
||||
class PageController extends ContentController {
|
||||
@ -109,11 +105,12 @@ the `$fields` constructor parameter.
|
||||
$context = singleton('MyDataObject')->getCustomSearchContext();
|
||||
$results = $context->getResults($data);
|
||||
|
||||
return $this->customise(array(
|
||||
return $this->customise([
|
||||
'Results' => $results
|
||||
))->renderWith('Page_results');
|
||||
])->renderWith('Page_results');
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Pagination
|
||||
@ -125,14 +122,13 @@ in order to read page limit information. It is also passed the current
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function getResults($searchCriteria = array()) {
|
||||
public function getResults($searchCriteria = []) {
|
||||
$start = ($this->getRequest()->getVar('start')) ? (int)$this->getRequest()->getVar('start') : 0;
|
||||
$limit = 10;
|
||||
|
||||
$context = singleton('MyDataObject')->getCustomSearchContext();
|
||||
$query = $context->getQuery($searchCriteria, null, array('start'=>$start,'limit'=>$limit));
|
||||
$records = $context->getResults($searchCriteria, null, array('start'=>$start,'limit'=>$limit));
|
||||
$query = $context->getQuery($searchCriteria, null, ['start'=>$start,'limit'=>$limit]);
|
||||
$records = $context->getResults($searchCriteria, null, ['start'=>$start,'limit'=>$limit]);
|
||||
|
||||
if($records) {
|
||||
$records = new PaginatedList($records, $this->getRequest());
|
||||
@ -143,20 +139,21 @@ in order to read page limit information. It is also passed the current
|
||||
|
||||
return $records;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
notice that if you want to use this getResults function, you need to change the function doSearch for this one:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function doSearch($data, $form) {
|
||||
$context = singleton('MyDataObject')->getCustomSearchContext();
|
||||
$results = $this->getResults($data);
|
||||
return $this->customise(array(
|
||||
return $this->customise([
|
||||
'Results' => $results
|
||||
))->renderWith(array('Catalogo_results', 'Page'));
|
||||
])->renderWith(['Catalogo_results', 'Page']);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The change is in **$results = $this->getResults($data);**, because you are using a custom getResults function.
|
||||
|
@ -23,15 +23,14 @@ You can do so by adding this static variable to your class definition:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyDataObject extends DataObject {
|
||||
|
||||
private static $create_table_options = array(
|
||||
private static $create_table_options = [
|
||||
'MySQLDatabase' => 'ENGINE=MyISAM'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The [FulltextSearchable](api:SilverStripe\ORM\Search\FulltextSearchable) extension will add the correct `Fulltext` indexes to the data model.
|
||||
@ -51,33 +50,32 @@ Example DataObject:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class SearchableDataObject extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
"Title" => "Varchar(255)",
|
||||
"Content" => "HTMLText",
|
||||
);
|
||||
];
|
||||
|
||||
private static $indexes = array(
|
||||
'SearchFields' => array(
|
||||
private static $indexes = [
|
||||
'SearchFields' => [
|
||||
'type' => 'fulltext',
|
||||
'columns' => ['Title', 'Content'],
|
||||
)
|
||||
);
|
||||
]
|
||||
];
|
||||
|
||||
private static $create_table_options = array(
|
||||
private static $create_table_options = [
|
||||
'MySQLDatabase' => 'ENGINE=MyISAM'
|
||||
);
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Performing the search:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
SearchableDataObject::get()->filter('SearchFields:Fulltext', 'search term');
|
||||
```
|
||||
|
||||
|
@ -29,7 +29,6 @@ you want to set.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// mysite/_config.php
|
||||
i18n::set_locale('de_DE'); // Setting the locale to German (Germany)
|
||||
i18n::set_locale('ca_AD'); // Setting to Catalan (Andorra)
|
||||
@ -83,7 +82,6 @@ You can use these settings for your own view logic.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
Config::inst()->update('i18n', 'date_format', 'dd.MM.yyyy');
|
||||
Config::inst()->update('i18n', 'time_format', 'HH:mm');
|
||||
```
|
||||
@ -157,7 +155,6 @@ followed by `setLocale()` or `setDateFormat()`/`setTimeFormat()`.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$field = new DateField();
|
||||
$field->setLocale('de_AT'); // set Austrian/German locale, defaulting format to dd.MM.y
|
||||
$field->setDateFormat('d.M.y'); // set a more specific date format (single digit day/month)
|
||||
@ -170,7 +167,6 @@ language-dependent and use a translator function call instead.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// without i18n
|
||||
echo "This is a string";
|
||||
// with i18n
|
||||
@ -215,7 +211,6 @@ For instance, this is an example of how to correctly declare pluralisations for
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyObject extends DataObject, implements i18nEntityProvider
|
||||
{
|
||||
public function provideI18nEntities()
|
||||
@ -255,19 +250,18 @@ Please ensure that any required plurals are exposed via provideI18nEntities.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
|
||||
// Simple string translation
|
||||
_t('LeftAndMain.FILESIMAGES','Files & Images');
|
||||
|
||||
// Using injection to add variables into the translated strings.
|
||||
_t('CMSMain.RESTORED',
|
||||
"Restored {value} successfully",
|
||||
array('value' => $itemRestored)
|
||||
['value' => $itemRestored]
|
||||
);
|
||||
|
||||
// Plurals are invoked via a `|` pipe-delimeter with a {count} argument
|
||||
_t('MyObject.PLURALS', 'An object|{count} objects', [ 'count' => '$count ]);
|
||||
|
||||
```
|
||||
|
||||
#### Usage in Template Files
|
||||
@ -404,7 +398,6 @@ Just point it to a directory instead of a file, and the class will figure out th
|
||||
|
||||
|
||||
```php
|
||||
|
||||
Requirements::add_i18n_javascript('<my-module-dir>/javascript/lang');
|
||||
```
|
||||
|
||||
|
@ -52,17 +52,17 @@ within the assets folder).
|
||||
|
||||
For example, to load a temporary file into a DataObject you could use the below:
|
||||
```php
|
||||
|
||||
<?
|
||||
class Banner extends DataObject {
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Image' => 'DBFile'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
// Image could be assigned in other parts of the code using the below
|
||||
$banner = new Banner();
|
||||
$banner->Image->setFromLocalFile($tempfile['path'], 'uploads/banner-file.jpg');
|
||||
|
||||
```
|
||||
|
||||
When uploading a file it's normally necessary to give the file a useful name and directory, otherwise the
|
||||
|
@ -88,7 +88,6 @@ png images.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$Image.Pad(80, 80, FFFFFF, 50) // white padding with 50% transparency
|
||||
$Image.Pad(80, 80, FFFFFF, 100) // white padding with 100% transparency
|
||||
$Image.Pad(80, 80, FFFFFF) // white padding with no transparency
|
||||
@ -108,7 +107,6 @@ You can also create your own functions by decorating the `Image` class.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class ImageExtension extends \SilverStripe\Core\Extension
|
||||
{
|
||||
|
||||
|
@ -20,11 +20,11 @@ config option:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$store = singleton(AssetStore::class);
|
||||
$store->setFromString('My protected content', 'Documents/Mydocument.txt', null, null, array(
|
||||
$store->setFromString('My protected content', 'Documents/Mydocument.txt', null, null, [
|
||||
'visibility' => AssetStore::VISIBILITY_PROTECTED
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
## User access control
|
||||
@ -65,7 +65,6 @@ authorised users, the following should be considered:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class PageController extends ContentController {
|
||||
public function init() {
|
||||
parent::init();
|
||||
@ -97,7 +96,6 @@ authorised users, the following should be considered:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class PageController extends ContentController {
|
||||
public function init() {
|
||||
parent::init();
|
||||
@ -130,10 +128,10 @@ E.g.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$object->MyFile->setFromLocalFile($tmpFile['Path'], $filename, null, null, array(
|
||||
$object->MyFile->setFromLocalFile($tmpFile['Path'], $filename, null, null, [
|
||||
'visibility' => AssetStore::VISIBILITY_PROTECTED
|
||||
));
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
You can also adjust the visibility of any existing file to either public or protected.
|
||||
@ -141,7 +139,6 @@ You can also adjust the visibility of any existing file to either public or prot
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// This will make the file available only when a user calls `->grant()`
|
||||
$object->SecretFile->protectFile();
|
||||
|
||||
@ -197,7 +194,6 @@ the web server, bypassing the need for additional PHP requests.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$store = singleton(AssetStore::class);
|
||||
$store->publish('NewCompanyLogo.gif', 'a870de278b475cb75f5d9f451439b2d378e13af1');
|
||||
```
|
||||
@ -313,13 +309,13 @@ the `Versioned` extension.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyVersiondObject extends DataObject {
|
||||
/** Ensure assets are archived along with the DataObject */
|
||||
private static $keep_archived_assets = true;
|
||||
/** Versioned */
|
||||
private static $extensions = array('Versioned');
|
||||
private static $extensions = ['Versioned'];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The extension can also be globally disabled by removing it at the root level:
|
||||
|
@ -21,40 +21,38 @@ a category.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Product extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Name' => 'Varchar',
|
||||
'ProductCode' => 'Varchar',
|
||||
'Price' => 'Currency'
|
||||
);
|
||||
];
|
||||
|
||||
private static $has_one = array(
|
||||
private static $has_one = [
|
||||
'Category' => 'Category'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
**mysite/code/Category.php**
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Category extends DataObject {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'Title' => 'Text'
|
||||
);
|
||||
];
|
||||
|
||||
private static $has_many = array(
|
||||
private static $has_many = [
|
||||
'Products' => 'Product'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
To create your own `ModelAdmin`, simply extend the base class, and edit the `$managed_models` property with the list of
|
||||
@ -66,20 +64,19 @@ We'll name it `MyAdmin`, but the class name can be anything you want.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyAdmin extends ModelAdmin {
|
||||
|
||||
private static $managed_models = array(
|
||||
private static $managed_models = [
|
||||
'Product',
|
||||
'Category'
|
||||
);
|
||||
];
|
||||
|
||||
private static $url_segment = 'products';
|
||||
|
||||
private static $menu_title = 'My Product Admin';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
This will automatically add a new menu entry to the SilverStripe Admin UI entitled `My Product Admin` and logged in
|
||||
@ -107,9 +104,7 @@ permissions by default. For most cases, less restrictive checks make sense, e.g.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Category extends DataObject {
|
||||
// ...
|
||||
public function canView($member = null) {
|
||||
@ -143,16 +138,15 @@ class (see [SearchContext](../search/searchcontext) docs for details).
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Product extends DataObject {
|
||||
|
||||
private static $searchable_fields = array(
|
||||
private static $searchable_fields = [
|
||||
'Name',
|
||||
'ProductCode'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<div class="hint" markdown="1">
|
||||
@ -169,20 +163,19 @@ model class, where you can add or remove columns. To change the title, use [Data
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class Product extends DataObject {
|
||||
|
||||
private static $field_labels = array(
|
||||
private static $field_labels = [
|
||||
'Price' => 'Cost' // renames the column to "Cost"
|
||||
);
|
||||
];
|
||||
|
||||
private static $summary_fields = array(
|
||||
private static $summary_fields = [
|
||||
'Name',
|
||||
'Price'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The results list are retrieved from [SearchContext::getResults()](api:SilverStripe\ORM\Search\SearchContext::getResults()), based on the parameters passed through the search
|
||||
@ -195,9 +188,7 @@ For example, we might want to exclude all products without prices in our sample
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyAdmin extends ModelAdmin {
|
||||
|
||||
public function getList() {
|
||||
@ -220,9 +211,7 @@ checkbox which limits search results to expensive products (over $100).
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyAdmin extends ModelAdmin {
|
||||
|
||||
public function getSearchContext() {
|
||||
@ -256,15 +245,13 @@ example, to add a new component.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyAdmin extends ModelAdmin {
|
||||
|
||||
private static $managed_models = array(
|
||||
private static $managed_models = [
|
||||
'Product',
|
||||
'Category'
|
||||
);
|
||||
];
|
||||
|
||||
// ...
|
||||
public function getEditForm($id = null, $fields = null) {
|
||||
@ -282,6 +269,7 @@ example, to add a new component.
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The above example will add the component to all `GridField`s (of all managed models). Alternatively we can also add it
|
||||
@ -291,15 +279,13 @@ to only one specific `GridField`:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyAdmin extends ModelAdmin {
|
||||
|
||||
private static $managed_models = array(
|
||||
private static $managed_models = [
|
||||
'Product',
|
||||
'Category'
|
||||
);
|
||||
];
|
||||
|
||||
public function getEditForm($id = null, $fields = null) {
|
||||
$form = parent::getEditForm($id, $fields);
|
||||
@ -314,6 +300,7 @@ to only one specific `GridField`:
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Data Import
|
||||
@ -334,20 +321,19 @@ To customize the exported columns, create a new method called `getExportFields`
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyAdmin extends ModelAdmin {
|
||||
// ...
|
||||
|
||||
public function getExportFields() {
|
||||
return array(
|
||||
return [
|
||||
'Name' => 'Name',
|
||||
'ProductCode' => 'Product Code',
|
||||
'Category.Title' => 'Category'
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
@ -75,7 +75,6 @@ In PHP you should use:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
AdminRootController::admin_url()
|
||||
```
|
||||
|
||||
@ -163,7 +162,6 @@ Basic example form in a CMS controller subclass:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyAdmin extends LeftAndMain {
|
||||
function getEditForm() {
|
||||
return CMSForm::create(
|
||||
@ -296,12 +294,12 @@ Firstly, `reactRouter` must be passed as a boolean flag to indicate that this se
|
||||
controlled by the react section, and thus should suppress registration of a page.js route
|
||||
for this section.
|
||||
```php
|
||||
|
||||
public function getClientConfig() {
|
||||
return array_merge(parent::getClientConfig(), [
|
||||
'reactRouter' => true
|
||||
]);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Secondly, you should ensure that your react CMS section triggers route registration on the client side
|
||||
@ -363,7 +361,6 @@ in a single Ajax request.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// mysite/code/MyAdmin.php
|
||||
class MyAdmin extends LeftAndMain {
|
||||
private static $url_segment = 'myadmin';
|
||||
@ -489,7 +486,6 @@ without affecting the response body.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyController extends LeftAndMain {
|
||||
class myaction() {
|
||||
// ...
|
||||
@ -550,7 +546,6 @@ which is picked up by the menu:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function mycontrollermethod() {
|
||||
// .. logic here
|
||||
$this->getResponse()->addHeader('X-Controller', 'AssetAdmin');
|
||||
|
@ -8,7 +8,6 @@ SilverStripe lets you customise the style of content in the CMS. This is done by
|
||||
|
||||
|
||||
```php
|
||||
|
||||
HtmlEditorConfig::get('cms')->setOption('content_css', project() . '/css/editor.css');
|
||||
```
|
||||
|
||||
@ -18,7 +17,6 @@ If using this config option in `mysite/_config.php`, you will have to instead ca
|
||||
|
||||
|
||||
```php
|
||||
|
||||
HtmlEditorConfig::get('cms')->setOption('content_css', project() . '/css/editor.css');
|
||||
```
|
||||
|
||||
|
@ -421,7 +421,6 @@ PHP:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyController {
|
||||
public function autocomplete($request) {
|
||||
$results = Page::get()->filter("Title", $request->getVar('title'));
|
||||
@ -432,11 +431,12 @@ PHP:
|
||||
|
||||
// render all results with a custom template
|
||||
$vd = new ViewableData();
|
||||
return $vd->customise(array(
|
||||
return $vd->customise([
|
||||
"Results" => $results
|
||||
))->renderWith('AutoComplete');
|
||||
])->renderWith('AutoComplete');
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
HTML
|
||||
|
@ -28,7 +28,6 @@ Here is the configuration code for the button:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function getCMSActions() {
|
||||
$fields = parent::getCMSActions();
|
||||
|
||||
@ -55,7 +54,6 @@ Here we initialise the button based on the backend check, and assume that the bu
|
||||
|
||||
|
||||
```php
|
||||
|
||||
public function getCMSActions() {
|
||||
// ...
|
||||
if ($this->needsCleaning()) {
|
||||
|
@ -11,7 +11,6 @@ at the last position within the field, and expects unescaped HTML content.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
TextField::create('MyText', 'My Text Label')
|
||||
->setDescription('More <strong>detailed</strong> help');
|
||||
```
|
||||
@ -21,7 +20,6 @@ add a `.cms-description-tooltip` class.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
TextField::create('MyText', 'My Text Label')
|
||||
->setDescription('More <strong>detailed</strong> help')
|
||||
->addExtraClass('cms-description-tooltip');
|
||||
@ -42,7 +40,6 @@ by clicking the 'info' icon displayed alongside the field.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
TextField::create('MyText', 'My Text Label')
|
||||
->setDescription('More <strong>detailed</strong> help')
|
||||
->addExtraClass('cms-description-toggle');
|
||||
@ -53,7 +50,6 @@ by setting an additional `RightTitle`.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
TextField::create('MyText', 'My Text Label')
|
||||
->setDescription('More <strong>detailed</strong> help')
|
||||
->addExtraClass('cms-description-toggle')
|
||||
|
@ -22,7 +22,6 @@ black-and-transparent PNG graphics. In this case we'll place the icon in
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class ProductAdmin extends ModelAdmin {
|
||||
// ...
|
||||
private static $menu_icon = 'mysite/images/product-icon.png';
|
||||
@ -37,7 +36,6 @@ controller, removing the "Admin" bit at the end.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class ProductAdmin extends ModelAdmin {
|
||||
// ...
|
||||
private static $menu_title = 'My Custom Admin';
|
||||
@ -62,9 +60,7 @@ button configuration.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class CustomLeftAndMain extends LeftAndMainExtension {
|
||||
|
||||
public function init() {
|
||||
@ -83,13 +79,14 @@ button configuration.
|
||||
|
||||
// Add your own attributes onto the link. In our case, we want to
|
||||
// open the link in a new window (not the original)
|
||||
$attributes = array(
|
||||
$attributes = [
|
||||
'target' => '_blank'
|
||||
);
|
||||
];
|
||||
|
||||
CMSMenu::add_link($id, $title, $link, $priority, $attributes);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
To have the link appear, make sure you add the extension to the `LeftAndMain`
|
||||
@ -98,7 +95,6 @@ class. For more information about configuring extensions see the
|
||||
|
||||
|
||||
```php
|
||||
|
||||
LeftAndMain::add_extension('CustomLeftAndMain')
|
||||
```
|
||||
|
||||
|
@ -19,18 +19,18 @@ hypothetical `NewsPageHolder` type, which contains `NewsPage` children.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// mysite/code/NewsPageHolder.php
|
||||
class NewsPageHolder extends Page {
|
||||
private static $allowed_children = array('NewsPage');
|
||||
private static $allowed_children = ['NewsPage'];
|
||||
}
|
||||
|
||||
// mysite/code/NewsPage.php
|
||||
class NewsPage extends Page {
|
||||
private static $has_one = array(
|
||||
private static $has_one = [
|
||||
'Author' => 'Member',
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
We'll now add an `Extension` subclass to `LeftAndMain`, which is the main CMS controller.
|
||||
@ -41,7 +41,6 @@ or across page types with common characteristics.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// mysite/code/NewsPageHolderCMSMainExtension.php
|
||||
class NewsPageHolderCMSMainExtension extends Extension {
|
||||
function updateListView($listView) {
|
||||
|
@ -66,7 +66,6 @@ __Example: using a subclass__
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class Page extends SiteTree {
|
||||
public function getScheduledToPublish(){
|
||||
// return either true or false
|
||||
|
@ -34,7 +34,6 @@ The following example will create a report to list every page on the current sit
|
||||
|
||||
###CustomSideReport.php
|
||||
```php
|
||||
|
||||
class CustomSideReport_NameOfReport extends SS_Report {
|
||||
|
||||
// the name of the report
|
||||
@ -49,13 +48,14 @@ The following example will create a report to list every page on the current sit
|
||||
|
||||
// which fields on that object we want to show
|
||||
public function columns() {
|
||||
$fields = array(
|
||||
$fields = [
|
||||
'Title' => 'Title'
|
||||
);
|
||||
];
|
||||
|
||||
return $fields;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
More useful reports can be created by changing the `DataList` returned in the `sourceRecords` function.
|
||||
|
@ -80,14 +80,12 @@ and insert the following code.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class BookmarkedPageExtension extends DataExtension {
|
||||
|
||||
private static $db = array(
|
||||
private static $db = [
|
||||
'IsBookmarked' => 'Boolean'
|
||||
);
|
||||
];
|
||||
|
||||
public function updateCMSFields(FieldList $fields) {
|
||||
$fields->addFieldToTab('Root.Main',
|
||||
@ -95,6 +93,7 @@ and insert the following code.
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Enable the extension in your [configuration file](../../configuration)
|
||||
@ -121,9 +120,7 @@ Add the following code to a new file `mysite/code/BookmarkedLeftAndMainExtension
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class BookmarkedPagesLeftAndMainExtension extends LeftAndMainExtension {
|
||||
|
||||
public function BookmarkedPages() {
|
||||
@ -191,7 +188,6 @@ button group (`CompositeField`) in a similar fashion.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$fields->unshift(FormAction::create('normal', 'Normal button'));
|
||||
```
|
||||
|
||||
@ -200,7 +196,6 @@ already present in the `FieldList`.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$fields->fieldByName('MajorActions')->push(FormAction::create('grouped', 'New group button'));
|
||||
```
|
||||
|
||||
@ -209,7 +204,6 @@ infrequently used minor actions.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$fields->addFieldToTab('ActionMenus.MoreOptions', FormAction::create('minor', 'Minor action'));
|
||||
```
|
||||
|
||||
@ -218,7 +212,6 @@ We can also easily create new drop-up menus by defining new tabs within the
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$fields->addFieldToTab('ActionMenus.MyDropUp', FormAction::create('minor', 'Minor action in a new drop-up'));
|
||||
```
|
||||
|
||||
@ -243,12 +236,11 @@ applicable controller actions to it:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class CustomActionsExtension extends LeftAndMainExtension {
|
||||
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'sampleAction'
|
||||
);
|
||||
];
|
||||
|
||||
public function sampleAction()
|
||||
{
|
||||
@ -256,6 +248,7 @@ applicable controller actions to it:
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The extension then needs to be registered:
|
||||
@ -272,7 +265,6 @@ You can now use these handlers with your buttons:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$fields->push(FormAction::create('sampleAction', 'Perform Sample Action'));
|
||||
```
|
||||
|
||||
|
@ -5,7 +5,6 @@ also another tool at your disposal: The [Extension](api:SilverStripe\Core\Extens
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyAdminExtension extends Extension {
|
||||
// ...
|
||||
public function updateEditForm(&$form) {
|
||||
|
@ -20,9 +20,7 @@ This example uses [Cache](api:Cache) in some custom code, and the same cache is
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
class MyClass extends DataObject implements Flushable {
|
||||
class MyClass extends DataObject implements Flushable {
|
||||
|
||||
public static function flush() {
|
||||
Cache::factory('mycache')->clean(Zend_Cache::CLEANING_MODE_ALL);
|
||||
@ -48,8 +46,7 @@ useful in an example like `GD` or `Imagick` generating resampled images, but we
|
||||
flush so they are re-created on demand.
|
||||
|
||||
```php
|
||||
<?php
|
||||
class MyClass extends DataObject implements Flushable {
|
||||
class MyClass extends DataObject implements Flushable {
|
||||
|
||||
public static function flush() {
|
||||
foreach(glob(ASSETS_PATH . '/_tempfiles/*.jpg') as $file) {
|
||||
|
@ -10,7 +10,6 @@ This can be accessed in user code via Injector
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$kernel = Injector::inst()->get(Kernel::class);
|
||||
echo "Current environment: " . $kernel->getEnvironment();
|
||||
```
|
||||
@ -40,7 +39,6 @@ you should call `->activate()` on the kernel instance you would like to unnest t
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$oldKernel = Injector::inst()->get(Kernel::class);
|
||||
try {
|
||||
// Injector::inst() / Config::inst() are automatically updated to the new kernel
|
||||
@ -71,9 +69,7 @@ This class provides basic support for HTTP Middleware, such as [ErrorControlChai
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
use SilverStripe\Control\HTTPApplication;
|
||||
use SilverStripe\Control\HTTPRequestBuilder;
|
||||
use SilverStripe\Core\CoreKernel;
|
||||
@ -136,7 +132,6 @@ routing.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$request = CLIRequestBuilder::createFromEnvironment();
|
||||
$kernel = new TestKernel(BASE_PATH);
|
||||
$app = new HTTPApplication($kernel);
|
||||
|
@ -93,14 +93,12 @@ This code provides a good template:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
class MyProcess extends Controller {
|
||||
|
||||
private static $allowed_actions = array(
|
||||
private static $allowed_actions = [
|
||||
'index'
|
||||
);
|
||||
];
|
||||
|
||||
function index() {
|
||||
set_time_limit(0);
|
||||
@ -115,6 +113,7 @@ This code provides a good template:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Then the process can be managed through `sake`
|
||||
|
@ -15,7 +15,6 @@ Sets the value of cookie with configuration.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
Cookie::set($name, $value, $expiry = 90, $path = null, $domain = null, $secure = false, $httpOnly = false);
|
||||
|
||||
// Cookie::set('MyApplicationPreference', 'Yes');
|
||||
@ -27,7 +26,6 @@ Returns the value of cookie.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
Cookie::get($name);
|
||||
|
||||
// Cookie::get('MyApplicationPreference');
|
||||
@ -40,7 +38,6 @@ Clears a given cookie.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
Cookie::force_expiry($name, $path = null, $domain = null);
|
||||
|
||||
// Cookie::force_expiry('MyApplicationPreference')
|
||||
@ -57,16 +54,16 @@ from the browser.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
$myCookies = array(
|
||||
$myCookies = [
|
||||
'cookie1' => 'value1',
|
||||
);
|
||||
];
|
||||
|
||||
$newBackend = new CookieJar($myCookies);
|
||||
|
||||
Injector::inst()->registerService($newBackend, 'Cookie_Backend');
|
||||
|
||||
Cookie::get('cookie1');
|
||||
|
||||
```
|
||||
|
||||
### Resetting the Cookie_Backend state
|
||||
@ -77,7 +74,6 @@ create a new service for you using the `$_COOKIE` superglobal.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
Injector::inst()->unregisterNamedObject('Cookie_Backend');
|
||||
|
||||
Cookie::get('cookiename'); // will return $_COOKIE['cookiename'] if set
|
||||
@ -88,7 +84,6 @@ the current `CookieJar` service to tell you what it was like when it was registe
|
||||
|
||||
|
||||
```php
|
||||
|
||||
//store the cookies that were loaded into the `CookieJar`
|
||||
$recievedCookie = Cookie::get_inst()->getAll(false);
|
||||
|
||||
@ -125,7 +120,6 @@ Using the `Cookie_Backend` we can do this like such:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
Cookie::set('CookieName', 'CookieVal');
|
||||
|
||||
Cookie::get('CookieName'); //gets the cookie as we set it
|
||||
@ -140,7 +134,6 @@ One can also access all of the cookies in one go using the `Cookie_Backend`
|
||||
|
||||
|
||||
```php
|
||||
|
||||
Cookie::get_inst()->getAll(); //returns all the cookies including ones set during the current process
|
||||
|
||||
Cookie::get_inst()->getAll(false); //returns all the cookies in the request
|
||||
|
@ -14,7 +14,6 @@ unit-testing, you can create multiple Controllers, each with their own session.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
Session::set('MyValue', 6);
|
||||
```
|
||||
|
||||
@ -23,13 +22,13 @@ size restrictions as to how much you can save).
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// saves an array
|
||||
Session::set('MyArrayOfValues', array('1','2','3'));
|
||||
Session::set('MyArrayOfValues', ['1','2','3']);
|
||||
|
||||
// saves an object (you'll have to unserialize it back)
|
||||
$object = new Object();
|
||||
Session::set('MyObject', serialize($object));
|
||||
|
||||
```
|
||||
|
||||
|
||||
@ -40,7 +39,6 @@ can use this anywhere in your PHP files.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
echo Session::get('MyValue');
|
||||
// returns 6
|
||||
|
||||
@ -49,15 +47,16 @@ can use this anywhere in your PHP files.
|
||||
|
||||
$object = unserialize(Session::get('MyObject', $object));
|
||||
// $object = Object()
|
||||
|
||||
```
|
||||
|
||||
## get_all
|
||||
|
||||
You can also get all the values in the session at once. This is useful for debugging.
|
||||
```php
|
||||
|
||||
Session::get_all();
|
||||
// returns an array of all the session values.
|
||||
|
||||
```
|
||||
|
||||
## clear
|
||||
@ -65,14 +64,12 @@ You can also get all the values in the session at once. This is useful for debug
|
||||
Once you have accessed a value from the Session it doesn't automatically wipe the value from the Session, you have
|
||||
to specifically remove it.
|
||||
```php
|
||||
|
||||
Session::clear('MyValue');
|
||||
```
|
||||
|
||||
Or you can clear every single value in the session at once. Note SilverStripe stores some of its own session data
|
||||
including form and page comment information. None of this is vital but `clear_all` will clear everything.
|
||||
```php
|
||||
|
||||
Session::clear_all();
|
||||
```
|
||||
|
||||
|
@ -377,7 +377,6 @@ For example, if you have the below `_ss_environment.php` file, your `.env` would
|
||||
|
||||
|
||||
```php
|
||||
<?php
|
||||
// Environment
|
||||
define('SS_ENVIRONMENT_TYPE', 'dev');
|
||||
define('SS_DEFAULT_ADMIN_USERNAME', 'admin');
|
||||
@ -1031,7 +1030,6 @@ that handled saving of content into composite fields can be removed, as it is no
|
||||
The below describes the minimum amount of effort required to implement a composite DB field.
|
||||
|
||||
```php
|
||||
<?php
|
||||
use SilverStripe\ORM\FieldType\DBComposite;
|
||||
|
||||
class MyAddressField extends DBComposite
|
||||
|
@ -63,7 +63,6 @@ Here's an example for replacing `Director::isDev()` with a (theoretical) `Env::i
|
||||
|
||||
|
||||
```php
|
||||
|
||||
/**
|
||||
* Returns true if your are in development mode
|
||||
* @deprecated 4.0 Use {@link Env::is_dev()} instead.
|
||||
@ -87,7 +86,6 @@ notices are always disabled on both live and test.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
Deprecation::set_enabled(false);
|
||||
```
|
||||
|
||||
|
@ -27,7 +27,6 @@ As opposed to other variables, these should be declared as lower case with under
|
||||
|
||||
|
||||
```php
|
||||
|
||||
class MyClass
|
||||
{
|
||||
private static $my_config_variable = 'foo';
|
||||
@ -41,7 +40,6 @@ Read more in the PHP documentation for [comparison operators](http://php.net/man
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// good - only need to cast to (int) if $a might not already be an int
|
||||
if ((int)$a === 100) {
|
||||
doThis();
|
||||
@ -59,7 +57,6 @@ Try to avoid using PHP's ability to mix HTML into the code.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// PHP code
|
||||
public function getTitle() {
|
||||
return "<h2>Bad Example</h2>";
|
||||
@ -73,7 +70,6 @@ Better: Keep HTML in template files:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
// PHP code
|
||||
public function getTitle() {
|
||||
return "Better Example";
|
||||
@ -99,7 +95,6 @@ Example:
|
||||
|
||||
|
||||
```php
|
||||
|
||||
/**
|
||||
* My short description for this class.
|
||||
* My longer description with
|
||||
@ -151,8 +146,8 @@ with the column or table name escaped with double quotes as below.
|
||||
|
||||
|
||||
```php
|
||||
MyClass::get()->where(["\"Score\" > ?" => 50]);
|
||||
|
||||
MyClass::get()->where(array("\"Score\" > ?" => 50));
|
||||
```
|
||||
|
||||
It is preferable to use parameterised queries whenever necessary to provide conditions
|
||||
@ -162,7 +157,6 @@ are single quoted.
|
||||
|
||||
|
||||
```php
|
||||
|
||||
MyClass::get()->where("\"Title\" = 'my title'");
|
||||
```
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user