Yeah psr2 functions

This commit is contained in:
Aaron Carlino 2017-08-03 16:25:49 +12:00
parent 4c7a068b28
commit 84feab5a68
67 changed files with 398 additions and 199 deletions

View File

@ -216,7 +216,8 @@ use PageController;
class HomePageController extends PageController class HomePageController extends PageController
{ {
// ... // ...
public function doBrowserPoll($data, $form) { public function doBrowserPoll($data, $form)
{
$submission = new BrowserPollSubmission(); $submission = new BrowserPollSubmission();
$form->saveInto($submission); $form->saveInto($submission);
$submission->write(); $submission->write();

View File

@ -604,7 +604,8 @@ table and column.
```php ```php
public function countDuplicates($model, $fieldToCheck) { public function countDuplicates($model, $fieldToCheck)
{
$table = DataObject::getSchema()->tableForField($model, $field); $table = DataObject::getSchema()->tableForField($model, $field);
$query = new SQLSelect(); $query = new SQLSelect();
$query->setFrom("\"{$table}\""); $query->setFrom("\"{$table}\"");

View File

@ -423,7 +423,8 @@ See [DataObject::$has_many](api:SilverStripe\ORM\DataObject::$has_many) for more
"Players" => "Player" "Players" => "Player"
]; ];
public function ActivePlayers() { public function ActivePlayers()
{
return $this->Players()->filter('Status', 'Active'); return $this->Players()->filter('Status', 'Active');
} }
} }

View File

@ -112,7 +112,8 @@ object we can control the formatting and it allows us to call methods defined fr
.. ..
public function getName() { public function getName()
{
return DBField::create_field('Varchar', $this->FirstName . ' '. $this->LastName); return DBField::create_field('Varchar', $this->FirstName . ' '. $this->LastName);
} }
} }
@ -145,7 +146,8 @@ Rather than manually returning objects from your custom functions. You can use t
"Name" => 'Varchar', "Name" => 'Varchar',
]; ];
public function getName() { public function getName()
{
return $this->FirstName . ' '. $this->LastName; return $this->FirstName . ' '. $this->LastName;
} }
} }
@ -183,7 +185,8 @@ context. Through a `$casting` array, arbitrary properties and getters can be cas
'MyDate' => 'Date' 'MyDate' => 'Date'
]; ];
public function getMyDate() { public function getMyDate()
{
return '1982-01-01'; return '1982-01-01';
} }
} }
@ -222,7 +225,8 @@ database column using `dbObject`.
"Status" => "Enum(array('Active', 'Injured', 'Retired'))" "Status" => "Enum(array('Active', 'Injured', 'Retired'))"
]; ];
public function getStatus() { public function getStatus()
{
return (!$this->obj("Birthday")->InPast()) ? "Unborn" : $this->dbObject('Status')->Value(); return (!$this->obj("Birthday")->InPast()) ? "Unborn" : $this->dbObject('Status')->Value();
} }

View File

@ -26,7 +26,8 @@ Example: Disallow creation of new players if the currently logged-in player is n
"Teams"=>"Team" "Teams"=>"Team"
]; ];
public function onBeforeWrite() { public function onBeforeWrite()
{
// check on first write action, aka "database row creation" (ID-property is not set) // check on first write action, aka "database row creation" (ID-property is not set)
if(!$this->isInDb()) { if(!$this->isInDb()) {
$currentPlayer = Security::getCurrentUser(); $currentPlayer = Security::getCurrentUser();
@ -66,7 +67,8 @@ member is logged in who belongs to a group containing the permission "PLAYER_DEL
"Teams" => "Team" "Teams" => "Team"
]; ];
public function onBeforeDelete() { public function onBeforeDelete()
{
if(!Permission::check('PLAYER_DELETE')) { if(!Permission::check('PLAYER_DELETE')) {
Security::permissionFailure($this); Security::permissionFailure($this);
exit(); exit();

View File

@ -20,19 +20,23 @@ code.
class MyDataObject extends DataObject class MyDataObject extends DataObject
{ {
public function canView($member = null) { public function canView($member = null)
{
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member); return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
} }
public function canEdit($member = null) { public function canEdit($member = null)
{
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member); return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
} }
public function canDelete($member = null) { public function canDelete($member = null)
{
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member); return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
} }
public function canCreate($member = null) { public function canCreate($member = null)
{
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member); return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
} }
} }

View File

@ -30,7 +30,8 @@ The return value of `validate()` is a [ValidationResult](api:SilverStripe\ORM\Va
'Postcode' => 'Varchar' 'Postcode' => 'Varchar'
]; ];
public function validate() { public function validate()
{
$result = parent::validate(); $result = parent::validate();
if($this->Country == 'DE' && $this->Postcode && strlen($this->Postcode) != 5) { if($this->Country == 'DE' && $this->Postcode && strlen($this->Postcode) != 5) {

View File

@ -235,7 +235,8 @@ E.g.
private static $owns = [ private static $owns = [
'ChildObjects' 'ChildObjects'
]; ];
public function ChildObjects() { public function ChildObjects()
{
return MyChild::get(); return MyChild::get();
} }
} }
@ -247,7 +248,8 @@ E.g.
private static $owned_by = [ private static $owned_by = [
'Parent' 'Parent'
]; ];
public function Parent() { public function Parent()
{
return MyParent::get()->first(); return MyParent::get()->first();
} }
} }
@ -302,7 +304,8 @@ E.g.
Versioned::class, Versioned::class,
]; ];
public function canViewVersioned($member = null) { public function canViewVersioned($member = null)
{
// Check if site is live // Check if site is live
$mode = $this->getSourceQueryParam("Versioned.mode"); $mode = $this->getSourceQueryParam("Versioned.mode");
$stage = $this->getSourceQueryParam("Versioned.stage"); $stage = $this->getSourceQueryParam("Versioned.stage");
@ -331,7 +334,8 @@ E.g.
```php ```php
class MyObjectExtension extends DataExtension class MyObjectExtension extends DataExtension
{ {
public function canViewNonLive($member = null) { public function canViewNonLive($member = null)
{
return Permission::check($member, 'DRAFT_STATUS'); return Permission::check($member, 'DRAFT_STATUS');
} }
} }
@ -369,7 +373,8 @@ to force a specific stage, we recommend the `Controller->init()` method for this
**mysite/code/MyController.php** **mysite/code/MyController.php**
```php ```php
public function init() { public function init()
{
parent::init(); parent::init();
Versioned::set_stage(Versioned::DRAFT); Versioned::set_stage(Versioned::DRAFT);
} }

View File

@ -22,7 +22,8 @@ An example is `DataObject`, SilverStripe will automatically create your CMS inte
'Content' => 'Text' 'Content' => 'Text'
]; ];
public function getCMSFields() { public function getCMSFields()
{
// parent::getCMSFields() does all the hard work and creates the fields for Title, IsActive and Content. // parent::getCMSFields() does all the hard work and creates the fields for Title, IsActive and Content.
$fields = parent::getCMSFields(); $fields = parent::getCMSFields();
$fields->dataFieldByName('IsActive')->setTitle('Is active?'); $fields->dataFieldByName('IsActive')->setTitle('Is active?');
@ -37,7 +38,8 @@ To fully customise your form fields, start with an empty FieldList.
```php ```php
public function getCMSFields() { public function getCMSFields()
{
$fields = FieldList::create( $fields = FieldList::create(
TabSet::create("Root.Main", TabSet::create("Root.Main",
CheckboxSetField::create('IsActive','Is active?'), CheckboxSetField::create('IsActive','Is active?'),

View File

@ -11,7 +11,8 @@ example, this controller method will not behave as you might imagine.
```php ```php
private $counter = 0; private $counter = 0;
public function Counter() { public function Counter()
{
$this->counter += 1; $this->counter += 1;
return $this->counter; return $this->counter;

View File

@ -51,7 +51,8 @@ provide default template for an object.
class Page extends SiteTree class Page extends SiteTree
{ {
public function forTemplate() { public function forTemplate()
{
return "Page: ". $this->Title; return "Page: ". $this->Title;
} }
} }
@ -78,7 +79,8 @@ to a template, SilverStripe will ensure that the object is wrapped in the correc
'MyCustomMethod' => 'HTMLText' 'MyCustomMethod' => 'HTMLText'
]; ];
public function MyCustomMethod() { public function MyCustomMethod()
{
return "<h1>This is my header</h1>"; return "<h1>This is my header</h1>";
} }
} }

View File

@ -14,7 +14,8 @@ The `PaginatedList` will automatically set up query limits and read the request
/** /**
* Returns a paginated list of all pages in the site. * Returns a paginated list of all pages in the site.
*/ */
public function PaginatedPages() { public function PaginatedPages()
{
$list = Page::get(); $list = Page::get();
return new PaginatedList($list, $this->getRequest()); return new PaginatedList($list, $this->getRequest());

View File

@ -37,7 +37,8 @@ SSViewer:
Or, a better way is to call this just for the rendering phase of this particular file: Or, a better way is to call this just for the rendering phase of this particular file:
:::php :::php
public function RenderCustomTemplate() { public function RenderCustomTemplate()
{
Config::inst()->update('SSViewer', 'rewrite_hash_links', false); Config::inst()->update('SSViewer', 'rewrite_hash_links', false);
$html = $this->renderWith('MyCustomTemplate'); $html = $this->renderWith('MyCustomTemplate');
Config::inst()->update('SSViewer', 'rewrite_hash_links', true); Config::inst()->update('SSViewer', 'rewrite_hash_links', true);

View File

@ -17,11 +17,13 @@ subclass the base `Controller` class.
'index' 'index'
]; ];
public function index(HTTPRequest $request) { public function index(HTTPRequest $request)
{
// .. // ..
} }
public function players(HTTPRequest $request) { public function players(HTTPRequest $request)
{
print_r($request->allParams()); print_r($request->allParams());
} }
} }
@ -81,7 +83,8 @@ Action methods can return one of four main things:
* Return some additional data to the current response that is waiting to go out, this makes $Title set to * 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. * 'MyTeamName' and continues on with generating the response.
*/ */
public function index(HTTPRequest $request) { public function index(HTTPRequest $request)
{
return [ return [
'Title' => 'My Team Name' 'Title' => 'My Team Name'
]; ];
@ -90,7 +93,8 @@ Action methods can return one of four main things:
/** /**
* We can manually create a response and return that to ignore any previous data. * We can manually create a response and return that to ignore any previous data.
*/ */
public function someaction(HTTPRequest $request) { public function someaction(HTTPRequest $request)
{
$this->setResponse(new HTTPResponse()); $this->setResponse(new HTTPResponse());
$this->getResponse()->setStatusCode(400); $this->getResponse()->setStatusCode(400);
$this->getResponse()->setBody('invalid'); $this->getResponse()->setBody('invalid');
@ -101,7 +105,8 @@ Action methods can return one of four main things:
/** /**
* Or, we can modify the response that is waiting to go out. * Or, we can modify the response that is waiting to go out.
*/ */
public function anotheraction(HTTPRequest $request) { public function anotheraction(HTTPRequest $request)
{
$this->getResponse()->setStatusCode(400); $this->getResponse()->setStatusCode(400);
return $this->getResponse(); return $this->getResponse();
@ -110,7 +115,8 @@ Action methods can return one of four main things:
/** /**
* We can render HTML and leave SilverStripe to set the response code and body. * We can render HTML and leave SilverStripe to set the response code and body.
*/ */
public function htmlaction() { public function htmlaction()
{
return $this->customise(new ArrayData([ return $this->customise(new ArrayData([
'Title' => 'HTML Action' 'Title' => 'HTML Action'
]))->renderWith('MyCustomTemplate'); ]))->renderWith('MyCustomTemplate');
@ -119,7 +125,8 @@ Action methods can return one of four main things:
/** /**
* We can send stuff to the browser which isn't HTML * We can send stuff to the browser which isn't HTML
*/ */
public function ajaxaction() { public function ajaxaction()
{
$this->getResponse()->setBody(json_encode([ $this->getResponse()->setBody(json_encode([
'json' => true 'json' => true
])); ]));
@ -158,7 +165,8 @@ Each controller should define a `Link()` method. This should be used to avoid ha
**mysite/code/controllers/TeamController.php** **mysite/code/controllers/TeamController.php**
```php ```php
public function Link($action = null) { public function Link($action = null)
{
return Controller::join_links('teams', $action); return Controller::join_links('teams', $action);
} }
``` ```

View File

@ -50,7 +50,8 @@ is specifically restricted.
class MyController extends Controller class MyController extends Controller
{ {
public function index() { public function index()
{
// allowed without an $allowed_action defined // allowed without an $allowed_action defined
} }
} }
@ -80,11 +81,13 @@ Only public methods can be made accessible.
// secureaction won't work as it's private. // secureaction won't work as it's private.
]; ];
public function secure() { public function secure()
{
// .. // ..
} }
private function secureaction() { private function secureaction()
{
// .. // ..
} }
} }
@ -100,7 +103,8 @@ If a method on a parent class is overwritten, access control for it has to be re
'action', 'action',
]; ];
public function action() { public function action()
{
// .. // ..
} }
} }
@ -111,7 +115,8 @@ If a method on a parent class is overwritten, access control for it has to be re
'action', // required as we are redefining action 'action', // required as we are redefining action
]; ];
public function action() { public function action()
{
} }
} }
@ -134,11 +139,13 @@ as an `allowed_action`.
'ContactForm' // use the Form method, not the action 'ContactForm' // use the Form method, not the action
]; ];
public function ContactForm() { public function ContactForm()
{
return new Form(..); return new Form(..);
} }
public function doContactForm($data, $form) { public function doContactForm($data, $form)
{
// .. // ..
} }
} }
@ -158,7 +165,8 @@ the passed request data.
'myaction' 'myaction'
]; ];
public function myaction($request) { public function myaction($request)
{
if(!$request->getVar('apikey')) { if(!$request->getVar('apikey')) {
return $this->httpError(403, 'No API key provided'); return $this->httpError(403, 'No API key provided');
} }
@ -189,7 +197,8 @@ execution. This behavior can be used to implement permission checks.
private static $allowed_actions = []; private static $allowed_actions = [];
public function init() { public function init()
{
parent::init(); parent::init();
if(!Permission::check('ADMIN')) { if(!Permission::check('ADMIN')) {

View File

@ -23,7 +23,8 @@ The following example will add a simple DateField to your Page, allowing you to
'MyDate' => 'Date', 'MyDate' => 'Date',
]; ];
public function getCMSFields() { public function getCMSFields()
{
$fields = parent::getCMSFields(); $fields = parent::getCMSFields();
$fields->addFieldToTab( $fields->addFieldToTab(

View File

@ -24,7 +24,8 @@ functionality. It is usually added through the [DataObject::getCMSFields()](api:
'Content' => 'HTMLText' 'Content' => 'HTMLText'
]; ];
public function getCMSFields() { public function getCMSFields()
{
return new FieldList( return new FieldList(
new HTMLEditorField('Content') new HTMLEditorField('Content')
); );
@ -53,7 +54,8 @@ This is particularly useful if you need different configurations for multiple [H
'OtherContent' => 'HTMLText' 'OtherContent' => 'HTMLText'
]; ];
public function getCMSFields() { public function getCMSFields()
{
return new FieldList([ return new FieldList([
new HTMLEditorField('Content'), new HTMLEditorField('Content'),
new HTMLEditorField('OtherContent', 'Other content', $this->OtherContent, 'myConfig') new HTMLEditorField('OtherContent', 'Other content', $this->OtherContent, 'myConfig')
@ -247,7 +249,8 @@ Example: Remove field for "image captions"
// File: mysite/code/MyToolbarExtension.php // File: mysite/code/MyToolbarExtension.php
class MyToolbarExtension extends Extension class MyToolbarExtension extends Extension
{ {
public function updateFieldsForImage(&$fields, $url, $file) { public function updateFieldsForImage(&$fields, $url, $file)
{
$fields->removeByName('CaptionText'); $fields->removeByName('CaptionText');
} }
} }
@ -288,7 +291,8 @@ of the CMS you have to take care of instantiate yourself:
// File: mysite/code/MyController.php // File: mysite/code/MyController.php
class MyObjectController extends Controller class MyObjectController extends Controller
{ {
public function Modals() { public function Modals()
{
return ModalController::create($this, "Modals"); return ModalController::create($this, "Modals");
} }
} }

View File

@ -32,7 +32,8 @@ actions such as deleting records.
class Page extends SiteTree class Page extends SiteTree
{ {
public function getCMSFields() { public function getCMSFields()
{
$fields = parent::getCMSFields(); $fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Pages', $fields->addFieldToTab('Root.Pages',
@ -64,7 +65,8 @@ the `getConfig()` method on `GridField`.
class Page extends SiteTree class Page extends SiteTree
{ {
public function getCMSFields() { public function getCMSFields()
{
$fields = parent::getCMSFields(); $fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Pages', $fields->addFieldToTab('Root.Pages',
@ -297,7 +299,8 @@ The namespace notation is `ManyMany[<extradata-field-name>]`, so for example `Ma
] ]
]; ];
public function getCMSFields() { public function getCMSFields()
{
$fields = parent::getCMSFields(); $fields = parent::getCMSFields();
if($this->ID) { if($this->ID) {
@ -355,7 +358,8 @@ create an area rendered before the table wrapped in a simple `<div>`.
class MyAreaComponent implements GridField_HTMLProvider class MyAreaComponent implements GridField_HTMLProvider
{ {
public function getHTMLFragments( $gridField) { public function getHTMLFragments( $gridField)
{
return [ return [
'before' => '<div class="my-area">$DefineFragment(my-area)</div>' 'before' => '<div class="my-area">$DefineFragment(my-area)</div>'
]; ];
@ -377,7 +381,8 @@ Now you can add other components into this area by returning them as an array fr
class MyShareLinkComponent implements GridField_HTMLProvider class MyShareLinkComponent implements GridField_HTMLProvider
{ {
public function getHTMLFragments( $gridField) { public function getHTMLFragments( $gridField)
{
return [ return [
'my-area' => '<a href>...</a>' 'my-area' => '<a href>...</a>'
]; ];

View File

@ -14,7 +14,8 @@ code for a `Form` is to create it as a subclass to `Form`. Let's look at a examp
class PageController extends ContentController class PageController extends ContentController
{ {
public function SearchForm() { public function SearchForm()
{
$fields = new FieldList( $fields = new FieldList(
HeaderField::create('Header', 'Step 1. Basics'), HeaderField::create('Header', 'Step 1. Basics'),
OptionsetField::create('Type', '', [ OptionsetField::create('Type', '', [
@ -77,7 +78,8 @@ should be. Good practice would be to move this to a subclass and create a new in
* method. We'll create the fields and actions in here. * method. We'll create the fields and actions in here.
* *
*/ */
public function __construct($controller, $name) { public function __construct($controller, $name)
{
$fields = new FieldList( $fields = new FieldList(
HeaderField::create('Header', 'Step 1. Basics'), HeaderField::create('Header', 'Step 1. Basics'),
OptionsetField::create('Type', '', [ OptionsetField::create('Type', '', [
@ -138,7 +140,8 @@ Our controller will now just have to create a new instance of this form object.
'SearchForm', 'SearchForm',
]; ];
public function SearchForm() { public function SearchForm()
{
return new SearchForm($this, 'SearchForm'); return new SearchForm($this, 'SearchForm');
} }
} }

View File

@ -14,7 +14,8 @@ totally custom template to meet our needs. To do this, we'll provide the class w
```php ```php
public function SearchForm() { public function SearchForm()
{
$fields = new FieldList( $fields = new FieldList(
TextField::create('q') TextField::create('q')
); );

View File

@ -22,27 +22,32 @@ below:
class GridFieldCustomAction implements GridField_ColumnProvider, GridField_ActionProvider class GridFieldCustomAction implements GridField_ColumnProvider, GridField_ActionProvider
{ {
public function augmentColumns($gridField, &$columns) { public function augmentColumns($gridField, &$columns)
{
if(!in_array('Actions', $columns)) { if(!in_array('Actions', $columns)) {
$columns[] = 'Actions'; $columns[] = 'Actions';
} }
} }
public function getColumnAttributes($gridField, $record, $columnName) { public function getColumnAttributes($gridField, $record, $columnName)
{
return ['class' => 'grid-field__col-compact']; return ['class' => 'grid-field__col-compact'];
} }
public function getColumnMetadata($gridField, $columnName) { public function getColumnMetadata($gridField, $columnName)
{
if($columnName == 'Actions') { if($columnName == 'Actions') {
return ['title' => '']; return ['title' => ''];
} }
} }
public function getColumnsHandled($gridField) { public function getColumnsHandled($gridField)
{
return ['Actions']; return ['Actions'];
} }
public function getColumnContent($gridField, $record, $columnName) { public function getColumnContent($gridField, $record, $columnName)
{
if(!$record->canEdit()) return; if(!$record->canEdit()) return;
$field = GridField_FormAction::create( $field = GridField_FormAction::create(
@ -56,11 +61,13 @@ below:
return $field->Field(); return $field->Field();
} }
public function getActions($gridField) { public function getActions($gridField)
{
return ['docustomaction']; return ['docustomaction'];
} }
public function handleAction(GridField $gridField, $actionName, $arguments, $data) { public function handleAction(GridField $gridField, $actionName, $arguments, $data)
{
if($actionName == 'docustomaction') { if($actionName == 'docustomaction') {
// perform your action here // perform your action here

View File

@ -12,7 +12,8 @@ Let's start by defining a new `ContactPage` page type:
class ContactPageController extends PageController class ContactPageController extends PageController
{ {
private static $allowed_actions = ['Form']; private static $allowed_actions = ['Form'];
public function Form() { public function Form()
{
$fields = new FieldList( $fields = new FieldList(
new TextField('Name'), new TextField('Name'),
new EmailField('Email'), new EmailField('Email'),
@ -75,10 +76,12 @@ Now that we have a contact form, we need some way of collecting the data submitt
class ContactPageController extends PageController class ContactPageController extends PageController
{ {
private static $allowed_actions = ['Form']; private static $allowed_actions = ['Form'];
public function Form() { public function Form()
{
// ... // ...
} }
public function submit($data, $form) { public function submit($data, $form)
{
$email = new Email(); $email = new Email();
$email->setTo('siteowner@mysite.com'); $email->setTo('siteowner@mysite.com');
@ -122,7 +125,8 @@ The framework comes with a predefined validator called [RequiredFields](api:Silv
```php ```php
public function Form() { public function Form()
{
// ... // ...
$validator = new RequiredFields('Name', 'Message'); $validator = new RequiredFields('Name', 'Message');
return new Form($this, 'Form', $fields, $actions, $validator); return new Form($this, 'Form', $fields, $actions, $validator);

View File

@ -47,7 +47,8 @@ To extend the options available in the panel, define your own fields via a [Data
'FooterContent' => 'HTMLText' 'FooterContent' => 'HTMLText'
]; ];
public function updateCMSFields(FieldList $fields) { public function updateCMSFields(FieldList $fields)
{
$fields->addFieldToTab("Root.Main", $fields->addFieldToTab("Root.Main",
new HTMLEditorField("FooterContent", "Footer Content") new HTMLEditorField("FooterContent", "Footer Content")
); );

View File

@ -26,7 +26,8 @@ and `RequestHandler`. You can still apply extensions to descendants of these cla
'DateOfBirth' => 'SS_Datetime' 'DateOfBirth' => 'SS_Datetime'
]; ];
public function SayHi() { public function SayHi()
{
// $this->owner refers to the original instance. In this case a `Member`. // $this->owner refers to the original instance. In this case a `Member`.
return "Hi " . $this->owner->Name; return "Hi " . $this->owner->Name;
} }
@ -90,7 +91,8 @@ $has_one etc.
'Image' => 'Image', 'Image' => 'Image',
]; ];
public function SayHi() { public function SayHi()
{
// $this->owner refers to the original instance. In this case a `Member`. // $this->owner refers to the original instance. In this case a `Member`.
return "Hi " . $this->owner->Name; return "Hi " . $this->owner->Name;
} }
@ -140,7 +142,8 @@ through the [Object::extend()](api:Object::extend()) method.
```php ```php
public function getValidator() { public function getValidator()
{
// .. // ..
$this->extend('updateValidator', $validator); $this->extend('updateValidator', $validator);
@ -163,7 +166,8 @@ validator by defining the `updateValidator` method.
// .. // ..
public function updateValidator($validator) { public function updateValidator($validator)
{
// we want to make date of birth required for each member // we want to make date of birth required for each member
$validator->addRequiredField('DateOfBirth'); $validator->addRequiredField('DateOfBirth');
} }
@ -190,7 +194,8 @@ extension. The `CMS` provides a `updateCMSFields` Extension Hook to tie into.
'Image' => 'Image', 'Image' => 'Image',
]; ];
public function updateCMSFields(FieldList $fields) { public function updateCMSFields(FieldList $fields)
{
$fields->push(new TextField('Position')); $fields->push(new TextField('Position'));
$fields->push($upload = new UploadField('Image', 'Profile Image')); $fields->push($upload = new UploadField('Image', 'Profile Image'));
$upload->setAllowedFileCategories('image/supported'); $upload->setAllowedFileCategories('image/supported');
@ -206,7 +211,8 @@ which allows an Extension to modify the results.
```php ```php
public function Foo() { public function Foo()
{
$foo = // .. $foo = // ..
$this->extend('updateFoo', $foo); $this->extend('updateFoo', $foo);
@ -228,7 +234,8 @@ In your [Extension](api:SilverStripe\Core\Extension) class you can only refer to
class MyMemberExtension extends DataExtension class MyMemberExtension extends DataExtension
{ {
public function updateFoo($foo) { public function updateFoo($foo)
{
// outputs the original class // outputs the original class
var_dump($this->owner); var_dump($this->owner);
} }
@ -288,7 +295,8 @@ This method is preferred to disabling, enabling, and calling field extensions ma
```php ```php
public function getCMSFields() { public function getCMSFields()
{
$this->beforeUpdateCMSFields(function($fields) { $this->beforeUpdateCMSFields(function($fields) {
// Include field which must be present when updateCMSFields is called on extensions // Include field which must be present when updateCMSFields is called on extensions

View File

@ -57,7 +57,8 @@ First we need to define a callback for the shortcode.
'MyShortCodeMethod' => 'HTMLText' 'MyShortCodeMethod' => 'HTMLText'
]; ];
public static function MyShortCodeMethod($arguments, $content = null, $parser = null, $tagName) { public static function MyShortCodeMethod($arguments, $content = null, $parser = null, $tagName)
{
return "<em>" . $tagName . "</em> " . $content . "; " . count($arguments) . " arguments."; return "<em>" . $tagName . "</em> " . $content . "; " . count($arguments) . " arguments.";
} }
} }
@ -197,7 +198,8 @@ 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. Here is a summary of the callback parameter values based on some example shortcodes.
```php ```php
public function MyCustomShortCode($arguments, $content = null, $parser = null, $tagName) { public function MyCustomShortCode($arguments, $content = null, $parser = null, $tagName)
{
// .. // ..
} }

View File

@ -179,7 +179,8 @@ An example using the `MyFactory` service to create instances of the `MyService`
class MyFactory implements SilverStripe\Core\Injector\Factory class MyFactory implements SilverStripe\Core\Injector\Factory
{ {
public function create($service, array $params = []) { public function create($service, array $params = [])
{
return new MyServiceImplementation(); return new MyServiceImplementation();
} }
} }
@ -216,7 +217,8 @@ Assuming a class structure such as
{ {
private $database; private $database;
public function setDatabase($d) { public function setDatabase($d)
{
$this->database = $d; $this->database = $d;
} }
} }
@ -225,7 +227,8 @@ Assuming a class structure such as
private $username; private $username;
private $password; private $password;
public function __construct($username, $password) { public function __construct($username, $password)
{
$this->username = $username; $this->username = $username;
$this->password = $password; $this->password = $password;
} }

View File

@ -59,7 +59,8 @@ used.
'insert','update','delete','replace' 'insert','update','delete','replace'
]; ];
public function beforeCall($proxied, $method, $args, &$alternateReturn) { public function beforeCall($proxied, $method, $args, &$alternateReturn)
{
if (isset($args[0])) { if (isset($args[0])) {
$sql = $args[0]; $sql = $args[0];
$code = isset($args[1]) ? $args[1] : E_USER_ERROR; $code = isset($args[1]) ? $args[1] : E_USER_ERROR;

View File

@ -18,22 +18,26 @@ explicitly logging in or by invoking the "remember me" functionality.
'NumVisit' => 'Int', 'NumVisit' => 'Int',
]; ];
public function memberLoggedIn() { public function memberLoggedIn()
{
$this->logVisit(); $this->logVisit();
} }
public function memberAutoLoggedIn() { public function memberAutoLoggedIn()
{
$this->logVisit(); $this->logVisit();
} }
public function updateCMSFields(FieldList $fields) { public function updateCMSFields(FieldList $fields)
{
$fields->addFieldsToTab('Root.Main', [ $fields->addFieldsToTab('Root.Main', [
ReadonlyField::create('LastVisited', 'Last visited'), ReadonlyField::create('LastVisited', 'Last visited'),
ReadonlyField::create('NumVisit', 'Number of visits') ReadonlyField::create('NumVisit', 'Number of visits')
]); ]);
} }
protected function logVisit() { protected function logVisit()
{
if(!Security::database_is_ready()) return; if(!Security::database_is_ready()) return;
DB::query(sprintf( DB::query(sprintf(

View File

@ -17,7 +17,8 @@ response and modify the session within a test.
/** /**
* Test generation of the view * Test generation of the view
*/ */
public function testViewHomePage() { public function testViewHomePage()
{
$page = $this->get('home/'); $page = $this->get('home/');
// Home page should load.. // Home page should load..

View File

@ -8,7 +8,8 @@ email was sent using this method.
```php ```php
public function MyMethod() { public function MyMethod()
{
$e = new Email(); $e = new Email();
$e->To = "someone@example.com"; $e->To = "someone@example.com";
$e->Subject = "Hi there"; $e->Subject = "Hi there";

View File

@ -98,7 +98,8 @@ For example, a block that shows a collection of rotating slides needs to update
```php ```php
public function SliderCacheKey() { public function SliderCacheKey()
{
$fragments = [ $fragments = [
'Page-Slides', 'Page-Slides',
$this->ID, $this->ID,
@ -146,7 +147,8 @@ configurable only on a site-wide basis), you could add a special function to you
```php ```php
public function BlogStatisticsCounter() { public function BlogStatisticsCounter()
{
return (int)(time() / 60 / 5); // Returns a new number every five minutes return (int)(time() / 60 / 5); // Returns a new number every five minutes
} }
``` ```

View File

@ -24,7 +24,8 @@ SilverStripe can request more resources through `Environment::increaseMemoryLimi
</div> </div>
```php ```php
public function myBigFunction() { public function myBigFunction()
{
Environment::increaseTimeLimitTo(400); Environment::increaseTimeLimitTo(400);
} }
``` ```

View File

@ -77,7 +77,8 @@ parent::getCMSFields() and manipulate the [FieldList](api:SilverStripe\Forms\Fie
```php ```php
public function getCMSFields() { public function getCMSFields()
{
$fields = parent::getCMSFields(); $fields = parent::getCMSFields();
$fields->insertBefore("HTMLEmail", new TextField("Age")); $fields->insertBefore("HTMLEmail", new TextField("Age"));
$fields->removeByName("JobTitle"); $fields->removeByName("JobTitle");
@ -121,7 +122,8 @@ things, you should add appropriate [Permission::checkMember()](api:SilverStripe\
* Modify the field set to be displayed in the CMS detail pop-up * Modify the field set to be displayed in the CMS detail pop-up
*/ */
public function updateCMSFields(FieldList $currentFields) { public function updateCMSFields(FieldList $currentFields)
{
// Only show the additional fields on an appropriate kind of use // Only show the additional fields on an appropriate kind of use
if(Permission::checkMember($this->owner->ID, "VIEW_FORUM")) { if(Permission::checkMember($this->owner->ID, "VIEW_FORUM")) {
// Edit the FieldList passed, adding or removing fields as necessary // Edit the FieldList passed, adding or removing fields as necessary
@ -135,7 +137,8 @@ things, you should add appropriate [Permission::checkMember()](api:SilverStripe\
private static $many_many = []; private static $many_many = [];
private static $belongs_many_many = []; private static $belongs_many_many = [];
public function somethingElse() { public function somethingElse()
{
// You can add any other methods you like, which you can call directly on the member object. // You can add any other methods you like, which you can call directly on the member object.
} }
} }

View File

@ -116,7 +116,8 @@ Example:
```php ```php
class MyForm extends Form class MyForm extends Form
{ {
public function save($RAW_data, $form) { public function save($RAW_data, $form)
{
// Pass true as the second parameter of raw2sql to quote the value safely // Pass true as the second parameter of raw2sql to quote the value safely
$SQL_data = Convert::raw2sql($RAW_data, true); // works recursively on an array $SQL_data = Convert::raw2sql($RAW_data, true); // works recursively on an array
$objs = Player::get()->where("Name = " . $SQL_data['name']); $objs = Player::get()->where("Name = " . $SQL_data['name']);
@ -136,7 +137,8 @@ Example:
class MyController extends Controller class MyController extends Controller
{ {
private static $allowed_actions = ['myurlaction']; private static $allowed_actions = ['myurlaction'];
public function myurlaction($RAW_urlParams) { public function myurlaction($RAW_urlParams)
{
// Pass true as the second parameter of raw2sql to quote the value safely // 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 $SQL_urlParams = Convert::raw2sql($RAW_urlParams, true); // works recursively on an array
$objs = Player::get()->where("Name = " . $SQL_data['OtherID']); $objs = Player::get()->where("Name = " . $SQL_data['OtherID']);
@ -157,12 +159,14 @@ passing data through, escaping should happen at the end of the chain.
/** /**
* @param array $RAW_data All names in an indexed array (not SQL-safe) * @param array $RAW_data All names in an indexed array (not SQL-safe)
*/ */
public function saveAllNames($RAW_data) { public function saveAllNames($RAW_data)
{
// $SQL_data = Convert::raw2sql($RAW_data); // premature escaping // $SQL_data = Convert::raw2sql($RAW_data); // premature escaping
foreach($RAW_data as $item) $this->saveName($item); foreach($RAW_data as $item) $this->saveName($item);
} }
public function saveName($RAW_name) { public function saveName($RAW_name)
{
$SQL_name = Convert::raw2sql($RAW_name, true); $SQL_name = Convert::raw2sql($RAW_name, true);
DB::query("UPDATE Player SET Name = {$SQL_name}"); DB::query("UPDATE Player SET Name = {$SQL_name}");
} }
@ -293,7 +297,8 @@ PHP:
'TitleWithHTMLSuffix' => 'HTMLText' // optional, as HTMLText is the default casting 'TitleWithHTMLSuffix' => 'HTMLText' // optional, as HTMLText is the default casting
]; ];
public function TitleWithHTMLSuffix($suffix) { public function TitleWithHTMLSuffix($suffix)
{
// $this->Title is not casted in PHP // $this->Title is not casted in PHP
return $this->Title . '<small>(' . $suffix. ')</small>'; return $this->Title . '<small>(' . $suffix. ')</small>';
} }
@ -330,7 +335,8 @@ PHP:
class MyController extends Controller class MyController extends Controller
{ {
private static $allowed_actions = ['search']; private static $allowed_actions = ['search'];
public function search($request) { public function search($request)
{
$htmlTitle = '<p>Your results for:' . Convert::raw2xml($request->getVar('Query')) . '</p>'; $htmlTitle = '<p>Your results for:' . Convert::raw2xml($request->getVar('Query')) . '</p>';
return $this->customise([ return $this->customise([
'Query' => Text::create($request->getVar('Query')), 'Query' => Text::create($request->getVar('Query')),
@ -364,7 +370,8 @@ PHP:
class MyController extends Controller class MyController extends Controller
{ {
private static $allowed_actions = ['search']; private static $allowed_actions = ['search'];
public function search($request) { public function search($request)
{
$rssRelativeLink = "/rss?Query=" . urlencode($_REQUEST['query']) . "&sortOrder=asc"; $rssRelativeLink = "/rss?Query=" . urlencode($_REQUEST['query']) . "&sortOrder=asc";
$rssLink = Controller::join_links($this->Link(), $rssRelativeLink); $rssLink = Controller::join_links($this->Link(), $rssRelativeLink);
return $this->customise([ return $this->customise([
@ -428,7 +435,8 @@ Below is an example with different ways you would use this casting technique:
```php ```php
public function CaseStudies() { public function CaseStudies()
{
// cast an ID from URL parameters e.g. (mysite.com/home/action/ID) // cast an ID from URL parameters e.g. (mysite.com/home/action/ID)
$anotherID = (int)Director::urlParam['ID']; $anotherID = (int)Director::urlParam['ID'];
@ -557,7 +565,8 @@ controller's `init()` method:
```php ```php
class MyController extends Controller class MyController extends Controller
{ {
public function init() { public function init()
{
parent::init(); parent::init();
$this->getResponse()->addHeader('X-Frame-Options', 'SAMEORIGIN'); $this->getResponse()->addHeader('X-Frame-Options', 'SAMEORIGIN');
} }
@ -698,7 +707,8 @@ unauthorised local persons. SilverStripe adds the current date for every request
class MySecureController extends Controller class MySecureController extends Controller
{ {
public function init() { public function init()
{
parent::init(); parent::init();
// Add cache headers to ensure sensitive content isn't cached. // Add cache headers to ensure sensitive content isn't cached.

View File

@ -82,11 +82,13 @@ You'll need to add a route to your controller to make it accessible via URL
protected $template = "BlankPage"; protected $template = "BlankPage";
public function Link($action = null) { public function Link($action = null)
{
return Controller::join_links('MyController', $action); return Controller::join_links('MyController', $action);
} }
public function Form() { public function Form()
{
$form = new Form( $form = new Form(
$this, $this,
'Form', 'Form',
@ -101,7 +103,8 @@ You'll need to add a route to your controller to make it accessible via URL
return $form; return $form;
} }
public function doUpload($data, $form) { public function doUpload($data, $form)
{
$loader = new CsvBulkLoader('MyDataObject'); $loader = new CsvBulkLoader('MyDataObject');
$results = $loader->load($_FILES['CsvFile']['tmp_name']); $results = $loader->load($_FILES['CsvFile']['tmp_name']);
$messages = []; $messages = [];
@ -193,13 +196,15 @@ Sample implementation of a custom loader. Assumes a CSV-file in a certain format
'callback' => 'getTeamByTitle' 'callback' => 'getTeamByTitle'
] ]
]; ];
public static function importFirstAndLastName(&$obj, $val, $record) { public static function importFirstAndLastName(&$obj, $val, $record)
{
$parts = explode(' ', $val); $parts = explode(' ', $val);
if(count($parts) != 2) return false; if(count($parts) != 2) return false;
$obj->FirstName = $parts[0]; $obj->FirstName = $parts[0];
$obj->LastName = $parts[1]; $obj->LastName = $parts[1];
} }
public static function getTeamByTitle(&$obj, $val, $record) { public static function getTeamByTitle(&$obj, $val, $record)
{
return FootballTeam::get()->filter('Title', $val)->First(); return FootballTeam::get()->filter('Title', $val)->First();
} }
} }

View File

@ -21,7 +21,8 @@ in the template.
```php ```php
public function getWellingtonWeather() { public function getWellingtonWeather()
{
$fetch = new RestfulService( $fetch = new RestfulService(
'https://query.yahooapis.com/v1/public/yql' 'https://query.yahooapis.com/v1/public/yql'
); );
@ -163,7 +164,8 @@ If the web service returned an error (for example, API key not available or inad
class MyRestfulService extends RestfulService class MyRestfulService extends RestfulService
{ {
public function errorCatch($response) { public function errorCatch($response)
{
$err_msg = $response; $err_msg = $response;
if(strpos($err_msg, '<') === false) { if(strpos($err_msg, '<') === false) {
@ -182,7 +184,8 @@ If you want to bypass error handling, define `checkErrors` in the constructor fo
class MyRestfulService extends RestfulService class MyRestfulService extends RestfulService
{ {
public function __construct($expiry = NULL) { public function __construct($expiry = NULL)
{
parent::__construct('http://www.flickr.com/services/rest/', $expiry); parent::__construct('http://www.flickr.com/services/rest/', $expiry);
$this->checkErrors = false; $this->checkErrors = false;

View File

@ -65,13 +65,15 @@ You can use [RSSFeed](api:SilverStripe\Control\RSS\RSSFeed) to easily create a f
'rss' 'rss'
]; ];
public function init() { public function init()
{
parent::init(); parent::init();
RSSFeed::linkToFeed($this->Link() . "rss", "10 Most Recently Updated Pages"); RSSFeed::linkToFeed($this->Link() . "rss", "10 Most Recently Updated Pages");
} }
public function rss() { public function rss()
{
$rss = new RSSFeed( $rss = new RSSFeed(
$this->LatestUpdates(), $this->LatestUpdates(),
$this->Link(), $this->Link(),
@ -82,7 +84,8 @@ You can use [RSSFeed](api:SilverStripe\Control\RSS\RSSFeed) to easily create a f
return $rss->outputToBrowser(); return $rss->outputToBrowser();
} }
public function LatestUpdates() { public function LatestUpdates()
{
return Page::get()->sort("LastEdited", "DESC")->limit(10); return Page::get()->sort("LastEdited", "DESC")->limit(10);
} }
} }
@ -106,7 +109,8 @@ method is defined and returns a string to the full website URL.
class Player extends DataObject class Player extends DataObject
{ {
public function AbsoluteLink() { public function AbsoluteLink()
{
// assumes players can be accessed at yoursite.com/players/2 // assumes players can be accessed at yoursite.com/players/2
return Controller::join_links( return Controller::join_links(
@ -129,13 +133,15 @@ Then in our controller, we add a new action which returns a the XML list of `Pla
'players' 'players'
]; ];
public function init() { public function init()
{
parent::init(); parent::init();
RSSFeed::linkToFeed($this->Link("players"), "Players"); RSSFeed::linkToFeed($this->Link("players"), "Players");
} }
public function players() { public function players()
{
$rss = new RSSFeed( $rss = new RSSFeed(
Player::get(), Player::get(),
$this->Link("players"), $this->Link("players"),
@ -184,7 +190,8 @@ Say from that last example we want to include the Players Team in the XML feed w
```php ```php
public function players() { public function players()
{
$rss = new RSSFeed( $rss = new RSSFeed(
Player::get(), Player::get(),
$this->Link("players"), $this->Link("players"),

View File

@ -17,11 +17,13 @@ form (which is used for `MyDataObject` instances). You can access it through
protected $template = "BlankPage"; protected $template = "BlankPage";
public function Link($action = null) { public function Link($action = null)
{
return Controller::join_links('MyController', $action); return Controller::join_links('MyController', $action);
} }
public function Form() { public function Form()
{
$form = new Form( $form = new Form(
$this, $this,
'Form', 'Form',
@ -36,7 +38,8 @@ form (which is used for `MyDataObject` instances). You can access it through
return $form; return $form;
} }
public function doUpload($data, $form) { public function doUpload($data, $form)
{
$loader = new CsvBulkLoader('MyDataObject'); $loader = new CsvBulkLoader('MyDataObject');
$results = $loader->load($_FILES['CsvFile']['tmp_name']); $results = $loader->load($_FILES['CsvFile']['tmp_name']);
$messages = []; $messages = [];

View File

@ -89,14 +89,16 @@ Our final import looks like this.
] ]
]; ];
public static function importFirstAndLastName(&$obj, $val, $record) { public static function importFirstAndLastName(&$obj, $val, $record)
{
$parts = explode(' ', $val); $parts = explode(' ', $val);
if(count($parts) != 2) return false; if(count($parts) != 2) return false;
$obj->FirstName = $parts[0]; $obj->FirstName = $parts[0];
$obj->LastName = $parts[1]; $obj->LastName = $parts[1];
} }
public static function getTeamByTitle(&$obj, $val, $record) { public static function getTeamByTitle(&$obj, $val, $record)
{
return FootballTeam::get()->filter('Title', $val)->First(); return FootballTeam::get()->filter('Title', $val)->First();
} }
} }

View File

@ -11,7 +11,8 @@ First, we write the code to query the API feed.
```php ```php
public function getWellingtonWeather() { public function getWellingtonWeather()
{
$fetch = new RestfulService( $fetch = new RestfulService(
'https://query.yahooapis.com/v1/public/yql' 'https://query.yahooapis.com/v1/public/yql'
); );

View File

@ -48,7 +48,8 @@ and `MyDate`. The attribute `HiddenProperty` should not be searchable, and `MyDa
'MyDate' => 'Date' 'MyDate' => 'Date'
]; ];
public function getDefaultSearchContext() { public function getDefaultSearchContext()
{
$fields = $this->scaffoldSearchFields([ $fields = $this->scaffoldSearchFields([
'restrictFields' => ['PublicProperty','MyDate'] 'restrictFields' => ['PublicProperty','MyDate']
]); ]);
@ -87,7 +88,8 @@ the `$fields` constructor parameter.
class PageController extends ContentController class PageController extends ContentController
{ {
public function SearchForm() { public function SearchForm()
{
$context = singleton('MyDataObject')->getCustomSearchContext(); $context = singleton('MyDataObject')->getCustomSearchContext();
$fields = $context->getSearchFields(); $fields = $context->getSearchFields();
@ -101,7 +103,8 @@ the `$fields` constructor parameter.
return $form; return $form;
} }
public function doSearch($data, $form) { public function doSearch($data, $form)
{
$context = singleton('MyDataObject')->getCustomSearchContext(); $context = singleton('MyDataObject')->getCustomSearchContext();
$results = $context->getResults($data); $results = $context->getResults($data);
@ -122,7 +125,8 @@ in order to read page limit information. It is also passed the current
```php ```php
public function getResults($searchCriteria = []) { public function getResults($searchCriteria = [])
{
$start = ($this->getRequest()->getVar('start')) ? (int)$this->getRequest()->getVar('start') : 0; $start = ($this->getRequest()->getVar('start')) ? (int)$this->getRequest()->getVar('start') : 0;
$limit = 10; $limit = 10;
@ -146,7 +150,8 @@ notice that if you want to use this getResults function, you need to change the
```php ```php
public function doSearch($data, $form) { public function doSearch($data, $form)
{
$context = singleton('MyDataObject')->getCustomSearchContext(); $context = singleton('MyDataObject')->getCustomSearchContext();
$results = $this->getResults($data); $results = $this->getResults($data);
return $this->customise([ return $this->customise([

View File

@ -67,7 +67,8 @@ authorised users, the following should be considered:
```php ```php
class PageController extends ContentController class PageController extends ContentController
{ {
public function init() { public function init()
{
parent::init(); parent::init();
// Whitelist any protected files on this page for the current user // Whitelist any protected files on this page for the current user
foreach($this->Files() as $file) { foreach($this->Files() as $file) {
@ -99,7 +100,8 @@ authorised users, the following should be considered:
```php ```php
class PageController extends ContentController class PageController extends ContentController
{ {
public function init() { public function init()
{
parent::init(); parent::init();
// Whitelist any protected files on this page for the current user // Whitelist any protected files on this page for the current user
foreach($this->Files() as $file) { foreach($this->Files() as $file) {

View File

@ -107,19 +107,23 @@ permissions by default. For most cases, less restrictive checks make sense, e.g.
class Category extends DataObject class Category extends DataObject
{ {
// ... // ...
public function canView($member = null) { public function canView($member = null)
{
return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member); return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member);
} }
public function canEdit($member = null) { public function canEdit($member = null)
{
return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member); return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member);
} }
public function canDelete($member = null) { public function canDelete($member = null)
{
return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member); return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member);
} }
public function canCreate($member = null) { public function canCreate($member = null)
{
return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member); return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member);
} }
``` ```
@ -191,7 +195,8 @@ For example, we might want to exclude all products without prices in our sample
class MyAdmin extends ModelAdmin class MyAdmin extends ModelAdmin
{ {
public function getList() { public function getList()
{
$list = parent::getList(); $list = parent::getList();
// Always limit by model class, in case you're managing multiple // Always limit by model class, in case you're managing multiple
@ -214,7 +219,8 @@ checkbox which limits search results to expensive products (over $100).
class MyAdmin extends ModelAdmin class MyAdmin extends ModelAdmin
{ {
public function getSearchContext() { public function getSearchContext()
{
$context = parent::getSearchContext(); $context = parent::getSearchContext();
if($this->modelClass == 'Product') { if($this->modelClass == 'Product') {
@ -224,7 +230,8 @@ checkbox which limits search results to expensive products (over $100).
return $context; return $context;
} }
public function getList() { public function getList()
{
$list = parent::getList(); $list = parent::getList();
$params = $this->getRequest()->requestVar('q'); // use this to access search parameters $params = $this->getRequest()->requestVar('q'); // use this to access search parameters
@ -254,7 +261,8 @@ example, to add a new component.
]; ];
// ... // ...
public function getEditForm($id = null, $fields = null) { public function getEditForm($id = null, $fields = null)
{
$form = parent::getEditForm($id, $fields); $form = parent::getEditForm($id, $fields);
// $gridFieldName is generated from the ModelClass, eg if the Class 'Product' // $gridFieldName is generated from the ModelClass, eg if the Class 'Product'
@ -287,7 +295,8 @@ to only one specific `GridField`:
'Category' 'Category'
]; ];
public function getEditForm($id = null, $fields = null) { public function getEditForm($id = null, $fields = null)
{
$form = parent::getEditForm($id, $fields); $form = parent::getEditForm($id, $fields);
$gridFieldName = 'Product'; $gridFieldName = 'Product';
@ -325,7 +334,8 @@ To customize the exported columns, create a new method called `getExportFields`
{ {
// ... // ...
public function getExportFields() { public function getExportFields()
{
return [ return [
'Name' => 'Name', 'Name' => 'Name',
'ProductCode' => 'Product Code', 'ProductCode' => 'Product Code',

View File

@ -295,7 +295,8 @@ 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 controlled by the react section, and thus should suppress registration of a page.js route
for this section. for this section.
```php ```php
public function getClientConfig() { public function getClientConfig()
{
return array_merge(parent::getClientConfig(), [ return array_merge(parent::getClientConfig(), [
'reactRouter' => true 'reactRouter' => true
]); ]);
@ -366,7 +367,8 @@ in a single Ajax request.
class MyAdmin extends LeftAndMain class MyAdmin extends LeftAndMain
{ {
private static $url_segment = 'myadmin'; private static $url_segment = 'myadmin';
public function getResponseNegotiator() { public function getResponseNegotiator()
{
$negotiator = parent::getResponseNegotiator(); $negotiator = parent::getResponseNegotiator();
$controller = $this; $controller = $this;
// Register a new callback // Register a new callback
@ -375,7 +377,8 @@ in a single Ajax request.
}); });
return $negotiator; return $negotiator;
} }
public function MyRecordInfo() { public function MyRecordInfo()
{
return $this->renderWith('MyRecordInfo'); return $this->renderWith('MyRecordInfo');
} }
} }
@ -550,7 +553,8 @@ which is picked up by the menu:
```php ```php
public function mycontrollermethod() { public function mycontrollermethod()
{
// .. logic here // .. logic here
$this->getResponse()->addHeader('X-Controller', 'AssetAdmin'); $this->getResponse()->addHeader('X-Controller', 'AssetAdmin');
return 'my response'; return 'my response';

View File

@ -423,7 +423,8 @@ PHP:
```php ```php
class MyController class MyController
{ {
public function autocomplete($request) { public function autocomplete($request)
{
$results = Page::get()->filter("Title", $request->getVar('title')); $results = Page::get()->filter("Title", $request->getVar('title'));
if(!$results) return new HTTPResponse("Not found", 404); if(!$results) return new HTTPResponse("Not found", 404);

View File

@ -28,7 +28,8 @@ Here is the configuration code for the button:
```php ```php
public function getCMSActions() { public function getCMSActions()
{
$fields = parent::getCMSActions(); $fields = parent::getCMSActions();
$fields->fieldByName('MajorActions')->push( $fields->fieldByName('MajorActions')->push(
@ -54,7 +55,8 @@ Here we initialise the button based on the backend check, and assume that the bu
```php ```php
public function getCMSActions() { public function getCMSActions()
{
// ... // ...
if ($this->needsCleaning()) { if ($this->needsCleaning()) {
// Will initialise the button into alternate state. // Will initialise the button into alternate state.

View File

@ -65,7 +65,8 @@ button configuration.
class CustomLeftAndMain extends LeftAndMainExtension class CustomLeftAndMain extends LeftAndMainExtension
{ {
public function init() { public function init()
{
// unique identifier for this item. Will have an ID of Menu-$ID // unique identifier for this item. Will have an ID of Menu-$ID
$id = 'LinkToGoogle'; $id = 'LinkToGoogle';

View File

@ -68,11 +68,13 @@ __Example: using a subclass__
```php ```php
class Page extends SiteTree class Page extends SiteTree
{ {
public function getScheduledToPublish(){ public function getScheduledToPublish()
{
// return either true or false // return either true or false
} }
public function getStatusFlags($cached = true) { public function getStatusFlags($cached = true)
{
$flags = parent::getStatusFlags($cached); $flags = parent::getStatusFlags($cached);
$flags['scheduledtopublish'] = "Scheduled To Publish"; $flags['scheduledtopublish'] = "Scheduled To Publish";
return $flags; return $flags;

View File

@ -38,17 +38,20 @@ The following example will create a report to list every page on the current sit
{ {
// the name of the report // the name of the report
public function title() { public function title()
{
return 'All Pages'; return 'All Pages';
} }
// what we want the report to return // what we want the report to return
public function sourceRecords($params = null) { public function sourceRecords($params = null)
{
return Page::get()->sort('Title'); return Page::get()->sort('Title');
} }
// which fields on that object we want to show // which fields on that object we want to show
public function columns() { public function columns()
{
$fields = [ $fields = [
'Title' => 'Title' 'Title' => 'Title'
]; ];

View File

@ -87,7 +87,8 @@ and insert the following code.
'IsBookmarked' => 'Boolean' 'IsBookmarked' => 'Boolean'
]; ];
public function updateCMSFields(FieldList $fields) { public function updateCMSFields(FieldList $fields)
{
$fields->addFieldToTab('Root.Main', $fields->addFieldToTab('Root.Main',
new CheckboxField('IsBookmarked', "Show in CMS bookmarks?") new CheckboxField('IsBookmarked', "Show in CMS bookmarks?")
); );
@ -123,7 +124,8 @@ Add the following code to a new file `mysite/code/BookmarkedLeftAndMainExtension
class BookmarkedPagesLeftAndMainExtension extends LeftAndMainExtension class BookmarkedPagesLeftAndMainExtension extends LeftAndMainExtension
{ {
public function BookmarkedPages() { public function BookmarkedPages()
{
return Page::get()->filter("IsBookmarked", 1); return Page::get()->filter("IsBookmarked", 1);
} }
} }

View File

@ -8,7 +8,8 @@ also another tool at your disposal: The [Extension](api:SilverStripe\Core\Extens
class MyAdminExtension extends Extension class MyAdminExtension extends Extension
{ {
// ... // ...
public function updateEditForm(&$form) { public function updateEditForm(&$form)
{
$form->Fields()->push(/* ... */) $form->Fields()->push(/* ... */)
} }
} }

View File

@ -23,11 +23,13 @@ This example uses [Cache](api:Cache) in some custom code, and the same cache is
class MyClass extends DataObject implements Flushable class MyClass extends DataObject implements Flushable
{ {
public static function flush() { public static function flush()
{
Cache::factory('mycache')->clean(Zend_Cache::CLEANING_MODE_ALL); Cache::factory('mycache')->clean(Zend_Cache::CLEANING_MODE_ALL);
} }
public function MyCachedContent() { public function MyCachedContent()
{
$cache = Cache::factory('mycache') $cache = Cache::factory('mycache')
$something = $cache->load('mykey'); $something = $cache->load('mykey');
if(!$something) { if(!$something) {
@ -50,7 +52,8 @@ flush so they are re-created on demand.
class MyClass extends DataObject implements Flushable class MyClass extends DataObject implements Flushable
{ {
public static function flush() { public static function flush()
{
foreach(glob(ASSETS_PATH . '/_tempfiles/*.jpg') as $file) { foreach(glob(ASSETS_PATH . '/_tempfiles/*.jpg') as $file) {
unlink($file); unlink($file);
} }

View File

@ -163,7 +163,8 @@ you can use `add_to_class()` as a replacement to `extraStatics()`.
); );
// advanced syntax // advanced syntax
static function add_to_class($class, $extensionClass, $args = null) { static function add_to_class($class, $extensionClass, $args = null)
{
if($class == 'MyClass') { if($class == 'MyClass') {
Config::inst()->update($class, 'db', array( Config::inst()->update($class, 'db', array(
'Title' => 'Varchar' 'Title' => 'Varchar'

View File

@ -24,7 +24,8 @@ please use `DataObject->canView()` to determine permissions.
class MyController extends Controller class MyController extends Controller
{ {
private static $allowed_actions = array('showpage'); private static $allowed_actions = array('showpage');
public function showpage($request) { public function showpage($request)
{
$page = Page::get()->byID($request->param('ID')); $page = Page::get()->byID($request->param('ID'));
if(!$page->canView()) return $this->httpError(401); if(!$page->canView()) return $this->httpError(401);
// continue with authenticated logic... // continue with authenticated logic...

View File

@ -250,7 +250,8 @@ on your own `Controller` subclasses if they contain any actions accessible throu
class MyController extends Controller class MyController extends Controller
{ {
// This action is now denied because no $allowed_actions are specified // This action is now denied because no $allowed_actions are specified
public function myaction($request) {} public function myaction($request)
{}
} }
You can overwrite the default behaviour on undefined `$allowed_actions` to allow all actions, You can overwrite the default behaviour on undefined `$allowed_actions` to allow all actions,
@ -273,9 +274,11 @@ you'll need to specificy each accessible action individually.
{ {
public static $allowed_actions = array('*' => 'ADMIN'); public static $allowed_actions = array('*' => 'ADMIN');
// Always denied because not explicitly listed in $allowed_actions // Always denied because not explicitly listed in $allowed_actions
public function myaction($request) {} public function myaction($request)
{}
// Always denied because not explicitly listed in $allowed_actions // Always denied because not explicitly listed in $allowed_actions
public function myotheraction($request) {} public function myotheraction($request)
{}
} }
Please review all rules governing allowed actions in the Please review all rules governing allowed actions in the
@ -291,7 +294,8 @@ Overriding inherited access definitions is no longer possible.
class MyController extends Controller class MyController extends Controller
{ {
public static $allowed_actions = array('myaction' => 'ADMIN'); public static $allowed_actions = array('myaction' => 'ADMIN');
public function myaction($request) {} public function myaction($request)
{}
} }
class MySubController extends MyController class MySubController extends MyController
{ {
@ -309,7 +313,8 @@ New approach with the [Config API](/developer_guides/configuration/configuration
:::php :::php
class MySubController extends MyController class MySubController extends MyController
{ {
public function init() { public function init()
{
parent::init(); parent::init();
Config::inst()->update('MyController', 'allowed_actions', Config::inst()->update('MyController', 'allowed_actions',
@ -376,16 +381,20 @@ Since `GridField` is used in `ModelAdmin`, this change will affect both classes.
:::php :::php
class MyModel extends DataObject class MyModel extends DataObject
{ {
public function canView($member = null) { public function canView($member = null)
{
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member); return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
} }
public function canEdit($member = null) { public function canEdit($member = null)
{
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member); return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
} }
public function canDelete($member = null) { public function canDelete($member = null)
{
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member); return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
} }
public function canCreate($member = null) { public function canCreate($member = null)
{
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member); return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
} }

View File

@ -35,7 +35,8 @@ E.g.
<?php <?php
class SingletonPage extends Page class SingletonPage extends Page
{ {
public function canCreate($member) { public function canCreate($member)
{
if(static::get()->count()) return false; if(static::get()->count()) return false;
$context = func_num_args() > 1 ? func_get_arg(1) : array(); $context = func_num_args() > 1 ? func_get_arg(1) : array();

View File

@ -15,7 +15,8 @@ For example:
:::php :::php
class MyCustomValidator extends Validator class MyCustomValidator extends Validator
{ {
public function php($data) { public function php($data)
{
$this->validationError( $this->validationError(
'EmailAddress', 'EmailAddress',
DBField::create_field('HTMLText', "Invalid email. Please sign up at <a href='signup'>this page</a>") DBField::create_field('HTMLText', "Invalid email. Please sign up at <a href='signup'>this page</a>")

View File

@ -34,7 +34,8 @@ please use `DataObject->canView()` to determine permissions.
class MyController extends Controller class MyController extends Controller
{ {
private static $allowed_actions = array('showpage'); private static $allowed_actions = array('showpage');
public function showpage($request) { public function showpage($request)
{
$page = Page::get()->byID($request->param('ID')); $page = Page::get()->byID($request->param('ID'));
if(!$page->canView()) return $this->httpError(401); if(!$page->canView()) return $this->httpError(401);
// continue with authenticated logic... // continue with authenticated logic...

View File

@ -17,7 +17,8 @@ E.g.
<?php <?php
class FileSecurityExtension extends DataExtension class FileSecurityExtension extends DataExtension
{ {
public function canEdit($member) { public function canEdit($member)
{
return Permission::checkMember($member, 'MyCustomPermission'); return Permission::checkMember($member, 'MyCustomPermission');
} }
} }

View File

@ -311,7 +311,8 @@ simply use the provided page URLs.
class MyController extends Controller class MyController extends Controller
{ {
static $allowed_actions = array('myaction'); static $allowed_actions = array('myaction');
public function myaction($request) { public function myaction($request)
{
// ... // ...
} }
} }
@ -501,7 +502,8 @@ of strings. This format is inherently unsafe, and should be avoided where possib
:::php :::php
<?php <?php
public function augmentSQL(SQLQuery &$query) { public function augmentSQL(SQLQuery &$query)
{
$query->getWhere(); // Will be flattened (unsafe 3.1 compatible format) $query->getWhere(); // Will be flattened (unsafe 3.1 compatible format)
$expression = $query->toAppropriateExpression(); // Either SQLSelect or SQLDelete $expression = $query->toAppropriateExpression(); // Either SQLSelect or SQLDelete
$expression->getWhere(); // Will be parameterised (preferred 3.2 compatible format) $expression->getWhere(); // Will be parameterised (preferred 3.2 compatible format)
@ -732,7 +734,8 @@ Before:
:::php :::php
public function filtersOnColumn($query, $column) { public function filtersOnColumn($query, $column)
{
$regexp = '/^(.*\.)?("|`)?' . $column . ' ("|`)?\s?=/'; $regexp = '/^(.*\.)?("|`)?' . $column . ' ("|`)?\s?=/';
foreach($this->getWhere() as $predicate) { foreach($this->getWhere() as $predicate) {
if(preg_match($regexp, $predicate)) return true; if(preg_match($regexp, $predicate)) return true;
@ -745,7 +748,8 @@ After:
:::php :::php
public function filtersOnColumn($query, $column) { public function filtersOnColumn($query, $column)
{
$regexp = '/^(.*\.)?("|`)?' . $column . ' ("|`)?\s?=/'; $regexp = '/^(.*\.)?("|`)?' . $column . ' ("|`)?\s?=/';
foreach($this->getWhereParameterised($parameters) as $predicate) { foreach($this->getWhereParameterised($parameters) as $predicate) {
if(preg_match($regexp, $predicate)) return true; if(preg_match($regexp, $predicate)) return true;

View File

@ -15,7 +15,8 @@ For example:
:::php :::php
class MyCustomValidator extends Validator class MyCustomValidator extends Validator
{ {
public function php($data) { public function php($data)
{
$this->validationError( $this->validationError(
'EmailAddress', 'EmailAddress',
DBField::create_field('HTMLText', "Invalid email. Please sign up at <a href='signup'>this page</a>") DBField::create_field('HTMLText', "Invalid email. Please sign up at <a href='signup'>this page</a>")

View File

@ -1001,7 +1001,8 @@ class MyShortcodeUser extends Object
private $content; private $content;
public function Content($arguments, $parser, $shortcode) { public function Content($arguments, $parser, $shortcode)
{
return File::handle_shortcode($arguments, $this->content, $parser, $shortcode); return File::handle_shortcode($arguments, $this->content, $parser, $shortcode);
} }
} }
@ -1020,7 +1021,8 @@ class MyShortcodeUser extends Object
private $content; private $content;
public function Content($arguments, $parser, $shortcode) { public function Content($arguments, $parser, $shortcode)
{
return FileShortcodeProvider::handle_shortcode($arguments, $this->content, $parser, $shortcode); return FileShortcodeProvider::handle_shortcode($arguments, $this->content, $parser, $shortcode);
} }
} }

View File

@ -454,10 +454,12 @@ Before:
// in MyImageExtension.php // in MyImageExtension.php
class MyImageExtension extends DataExtension class MyImageExtension extends DataExtension
{ {
public function GalleryThumbnail($height) { public function GalleryThumbnail($height)
{
return $this->getFormattedImage('GalleryThumbnail', $height); return $this->getFormattedImage('GalleryThumbnail', $height);
} }
public function generateGalleryThumbnail(Image_Backend $backend, $height) { public function generateGalleryThumbnail(Image_Backend $backend, $height)
{
return $backend->paddedResize(300, $height); return $backend->paddedResize(300, $height);
} }
} }
@ -475,7 +477,8 @@ After:
// in MyImageExtension.php // in MyImageExtension.php
class MyImageExtension extends Extension class MyImageExtension extends Extension
{ {
public function GalleryThumbnail($height) { public function GalleryThumbnail($height)
{
// Generates the manipulation key // Generates the manipulation key
$variant = $this->owner->variantName(__FUNCTION__, $height); $variant = $this->owner->variantName(__FUNCTION__, $height);
@ -522,7 +525,8 @@ The below describes the minimum amount of effort required to implement a composi
'Country' => 'Varchar(100)' 'Country' => 'Varchar(100)'
); );
public function scaffoldFormField($title = null) { public function scaffoldFormField($title = null)
{
new AddressFormField($this->getName(), $title); new AddressFormField($this->getName(), $title);
} }
} }
@ -613,7 +617,8 @@ E.g.
:::php :::php
class MyErrorPageExtension extends SiteTreeExtension class MyErrorPageExtension extends SiteTreeExtension
{ {
public function updateErrorFilename(&$name, &$statuscode) { public function updateErrorFilename(&$name, &$statuscode)
{
if($this->owner->exists()) { if($this->owner->exists()) {
$locale = $this->Locale; $locale = $this->Locale;
} else { } else {
@ -801,7 +806,8 @@ For example:
* @param Int $val * @param Int $val
* @return Varchar * @return Varchar
*/ */
public function TextNumber() { public function TextNumber()
{
return new Varchar('TextNumber', 'Number is ' . $this->Number); return new Varchar('TextNumber', 'Number is ' . $this->Number);
} }
} }
@ -820,7 +826,8 @@ Will become:
* @param Int $val * @param Int $val
* @return Varchar * @return Varchar
*/ */
public function TextNumber() { public function TextNumber()
{
return new DBVarchar('TextNumber', 'Number is ' . $this->Number); return new DBVarchar('TextNumber', 'Number is ' . $this->Number);
} }
} }

View File

@ -279,7 +279,8 @@ simply use the provided page URLs.
class MyController extends Controller class MyController extends Controller
{ {
static $allowed_actions = array('myaction'); static $allowed_actions = array('myaction');
public function myaction($request) { public function myaction($request)
{
// ... // ...
} }
} }
@ -469,7 +470,8 @@ of strings. This format is inherently unsafe, and should be avoided where possib
:::php :::php
<?php <?php
public function augmentSQL(SQLQuery &$query) { public function augmentSQL(SQLQuery &$query)
{
$query->getWhere(); // Will be flattened (unsafe 3.1 compatible format) $query->getWhere(); // Will be flattened (unsafe 3.1 compatible format)
$expression = $query->toAppropriateExpression(); // Either SQLSelect or SQLDelete $expression = $query->toAppropriateExpression(); // Either SQLSelect or SQLDelete
$expression->getWhere(); // Will be parameterised (preferred 3.2 compatible format) $expression->getWhere(); // Will be parameterised (preferred 3.2 compatible format)
@ -700,7 +702,8 @@ Before:
:::php :::php
public function filtersOnColumn($query, $column) { public function filtersOnColumn($query, $column)
{
$regexp = '/^(.*\.)?("|`)?' . $column . ' ("|`)?\s?=/'; $regexp = '/^(.*\.)?("|`)?' . $column . ' ("|`)?\s?=/';
foreach($this->getWhere() as $predicate) { foreach($this->getWhere() as $predicate) {
if(preg_match($regexp, $predicate)) return true; if(preg_match($regexp, $predicate)) return true;
@ -713,7 +716,8 @@ After:
:::php :::php
public function filtersOnColumn($query, $column) { public function filtersOnColumn($query, $column)
{
$regexp = '/^(.*\.)?("|`)?' . $column . ' ("|`)?\s?=/'; $regexp = '/^(.*\.)?("|`)?' . $column . ' ("|`)?\s?=/';
foreach($this->getWhereParameterised($parameters) as $predicate) { foreach($this->getWhereParameterised($parameters) as $predicate) {
if(preg_match($regexp, $predicate)) return true; if(preg_match($regexp, $predicate)) return true;

View File

@ -34,7 +34,8 @@ please use `DataObject->canView()` to determine permissions.
class MyController extends Controller class MyController extends Controller
{ {
private static $allowed_actions = array('showpage'); private static $allowed_actions = array('showpage');
public function showpage($request) { public function showpage($request)
{
$page = Page::get()->byID($request->param('ID')); $page = Page::get()->byID($request->param('ID'));
if(!$page->canView()) return $this->httpError(401); if(!$page->canView()) return $this->httpError(401);
// continue with authenticated logic... // continue with authenticated logic...

View File

@ -67,7 +67,8 @@ Here's an example for replacing `Director::isDev()` with a (theoretical) `Env::i
* Returns true if your are in development mode * Returns true if your are in development mode
* @deprecated 4.0 Use {@link Env::is_dev()} instead. * @deprecated 4.0 Use {@link Env::is_dev()} instead.
*/ */
public function isDev() { public function isDev()
{
Deprecation::notice('4.0', 'Use Env::is_dev() instead'); Deprecation::notice('4.0', 'Use Env::is_dev() instead');
return Env::is_dev(); return Env::is_dev();
} }

View File

@ -58,7 +58,8 @@ Try to avoid using PHP's ability to mix HTML into the code.
```php ```php
// PHP code // PHP code
public function getTitle() { public function getTitle()
{
return "<h2>Bad Example</h2>"; return "<h2>Bad Example</h2>";
} }
@ -71,7 +72,8 @@ Better: Keep HTML in template files:
```php ```php
// PHP code // PHP code
public function getTitle() { public function getTitle()
{
return "Better Example"; return "Better Example";
} }