MINOR Moved class-specific documentation from doc.silverstripe.org back into class-level PHPDoc (from r107725)

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@112608 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2010-10-15 03:55:22 +00:00
parent eed13a7384
commit a0dd4ff8f0
25 changed files with 740 additions and 15 deletions

View File

@ -29,7 +29,8 @@
* }
* </code>
*
* Supported operations:
* <b>Supported operations</b>
*
* - GET /api/v1/(ClassName)/(ID) - gets a database record
* - GET /api/v1/(ClassName)/(ID)/(Relation) - get all of the records linked to this database record by the given reatlion
* - GET /api/v1/(ClassName)?(Field)=(Val)&(Field)=(Val) - searches for matching database records
@ -43,17 +44,22 @@
*
* - POST /api/v1/(ClassName)/(ID)/(MethodName) - executes a method on the given object (e.g, publish)
*
* <b>Search</b>
*
* You can trigger searches based on the fields specified on {@link DataObject::searchable_fields} and passed
* through {@link DataObject::getDefaultSearchContext()}. Just add a key-value pair with the search-term
* to the url, e.g. /api/v1/(ClassName)/?Title=mytitle.
*
* Other url-modifiers:
* <b>Other url-modifiers</b>
*
* - &limit=<numeric>: Limit the result set
* - &relationdepth=<numeric>: Displays links to existing has-one and has-many relationships to a certain depth (Default: 1)
* - &fields=<string>: Comma-separated list of fields on the output object (defaults to all database-columns).
* Handy to limit output for bandwidth and performance reasons.
* - &sort=<myfield>&dir=<asc|desc>
* - &add_fields=<string>: Comma-separated list of additional fields, for example dynamic getters.
*
* <b>Access control</b>
*
* Access control is implemented through the usual Member system with Basicauth authentication only.
* By default, you have to bear the ADMIN permission to retrieve or send any data.

View File

@ -17,6 +17,14 @@ if(!defined('MANIFEST_FILE')) define("MANIFEST_FILE", TEMP_FOLDER . "/manifest-"
* This information is cached so that it need not be regenerated on every
* pageview.
*
* <b>Autoloading</b>
*
* Sapphire class autoloader. Requires the ManifestBuilder to work.
* $_CLASS_MANIFEST must have been loaded up by ManifestBuilder for this to successfully load classes.
* Classes will be loaded from any PHP file within the application. If your class contains an underscore,
* for example, Page_Controller, then the filename is expected to be the stuff before the underscore.
* In this case, Page.php.
*
* @see main.php, __autoload(), SSViewer, Requirements::themedCSS()
* @package sapphire
* @subpackage core

View File

@ -10,7 +10,69 @@
* each with their own session.
*
* The instance object is basically just a way of manipulating a set of nested maps, and isn't specific to session data.
* This class is currently really basic and could do with a more well-thought-out implementation
*
* <b>Saving Data</b>
*
* You can write a value to a users session from your PHP code using the static function {@link Session::set()}. You can add this line in any function or file you wish to save the value.
*
* <code>
* Session::set('MyValue', 6);
* </code>
*
* Saves the value of "6" to the MyValue session data. You can also save arrays or serialized objects in session (but note there may be size restrictions as to how much you can save)
*
* <code>
* // save a variable
* $var = 1;
* Session::set('MyVar', $var);
*
* // saves an array
* Session::set('MyArrayOfValues', array('1','2','3'));
*
* // saves an object (you'll have to unserialize it back)
* $object = new Object();
*
* Session::set('MyObject', serialize($object));
* </code>
*
* <b>Accessing Data</b>
*
* Once you have saved a value to the Session you can access it by using the {@link Session::get()} function.
* Like the {@link Session::set()} function you can use this anywhere in your PHP files.
*
* The values in the comments are the values stored from the previous example.
*
* <code>
* function bar() {
* $value = Session::get('MyValue'); // $value = 6
* $var = Session::get('MyVar'); // $var = 1
* $array = Session::get('MyArrayOfValues'); // $array = array(1,2,3)
* $object = Session::get('MyObject', unserialize($object)); // $object = Object()
* }
* </code>
*
* You can also get all the values in the session at once. This is useful for debugging.
*
* <code>
* Session::getAll(); // returns an array of all the session values.
* </code>
*
* <b>Clearing Data</b>
*
* 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. To clear a value you can either delete 1 session value by the name that you saved it
*
* <code>
* Session::clear('MyValue'); // myvalue is no longer 6.
* </code>
*
* 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.
*
* <code>
* Session::clearAll();
* </code>
*
* @see Cookie
* @todo This class is currently really basic and could do with a more well-thought-out implementation.
*
* @package sapphire
* @subpackage control

View File

@ -2,7 +2,47 @@
/**
* A migration task is a build task that is reversible.
*
* Up and Down methods must be implemented.
* <b>Creating Migration Tasks</b>
*
* To create your own migration task all you need to do is define your own subclass of MigrationTask and define the following functions
*
* <i>mysite/code/MyMigrationTask.php</i>
*
* <code>
* class MyMigrationTask extends BuildTask {
*
* protected $title = "My Database Migrations"; // title of the script
* protected $description = "Description"; // description of what it does
*
* function run($request) {
* if ($request->param('Direction') == 'down') {
* $this->down();
* } else {
* $this->up();
* }
* }
*
* function up() {
* // do something when going from old -> new
* }
*
* function down() {
* // do something when going from new -> old
* }
* }
* </code>
*
* <b>Running Migration Tasks</b>
* To run any tasks you can find them under the dev/ namespace. To run the above script you would need to run
* the following and note - Either the site has to be in [devmode](debugging) or you need to add ?isDev=1 to the URL
*
* <code>
* // url to visit if in dev mode.
* http://www.yoursite.com/dev/tasks/MyMigrationTask
*
* // url if you are in live mode but need to run this
* http://www.yoursite.com/dev/tasks/MyMigrationTask?isDev=1
* </code>
*
* @package sapphire
* @subpackage dev

View File

@ -1,6 +1,67 @@
<?php
/**
* Specify special required fields to be executed as part of form validation
* CustomRequiredFields allow you to create your own validation on forms, while still having the ability to have required fields (as used in [RequiredFields](http://api.silverstripe.org/current/sapphire/form/RequiredFields.html)).
*
* The constructor of CustomRequiredFields takes an array. Each array element is one of two things - either the name of a field that is required, or an array containing two items, 'js' and 'php'. These items are functions called to validate in javascript or php respectively.
*
* Some useful javascript:
* 1. _CURRENT_FORM is the current form
* 2. _CURRENT_FORM.elements is an array of the fields
* 3. validationError(element, message, type) will create a validation error
* 4. clearErrorMessage(element) will clear the validation error
* 5. require('FieldName') create a required field ($this->requireField('FieldName') is the php equivalent)
*
* An example for creating required fields only if payment type is CreditCard:
*
* <code>
* new CustomRequiredFields(
* array(
* "PaymentMethod",
* array(
* "js" => "
* for( var i = 0; i <= this.elements.PaymentMethod.length -1; i++){
* if(this.elements.PaymentMethod[i].value == 'CC' && this.elements.PaymentMethod[i].checked == true){
* require('CardHolderName');
* require('CreditCardNumber');
* require('DateExpiry');
* }
* }
*
* ",
* "php" => 'if($data[PaymentMethod] == "CC") {
* $this->requireField($field,"$field is required","required");
* $this->requireField("CardHolderName", $data);
* $this->requireField("CreditCardNumber", $data);
* $this->requireField("DateExpiry", $data);
* }',
* )
* )
* );
* </code>
*
* And example for confirming mobile number and email address:
*
* <code>
* $js = <<<JS
* if(_CURRENT_FORM.elements["MobileNumberConfirm"].value == _CURRENT_FORM.elements["MobileNumber"].value) {
* clearErrorMessage(_CURRENT_FORM.elements["MobileNumberConfirm"].parentNode);
* } else {
* validationError(_CURRENT_FORM.elements["MobileNumberConfirm"], "Mobile numbers do not match", "validation");
* }
* JS;
*
* $js2 = <<<JS2
* if(_CURRENT_FORM.elements["EmailConfirm"].value == _CURRENT_FORM.elements["Email"].value) {
* clearErrorMessage(_CURRENT_FORM.elements["EmailConfirm"].parentNode);
* } else {
* validationError(_CURRENT_FORM.elements["EmailConfirm"], "Email addresses do not match", "validation");
* }
* JS2;
*
* //create validator
* $validator=new CustomRequiredFields(array('FirstName', 'Surname', 'Email', 'MobileNumber', array('js' => $js, 'php' => 'return true;'), array('js' => $js2, 'php'=>'return true;')));
* </code>
*
* @package forms
* @subpackage validators
*/

View File

@ -1,6 +1,73 @@
<?php
/**
* Dropdown field, created from a <select> tag.
*
* <b>Setting a $has_one relation</b>
*
* Using here an example of an art gallery, with Exhibition pages,
* each of which has a Gallery they belong to. The Gallery class is also user-defined.
* <code>
* static $has_one = array(
* 'Gallery' => 'Gallery',
* );
*
* public function getCMSFields() {
* $fields = parent::getCMSFields();
* $galleries = DataObject::get('Gallery');
* if ($galleries) {
* $galleries = $galleries->toDropdownMap('ID', 'Title', '(Select one)', true);
* }
* $fields->addFieldToTab('Root.Content.Main', new DropdownField('GalleryID', 'Gallery', $galleries), 'Content');
* </code>
*
* As you see, you need to put "GalleryID", rather than "Gallery" here.
*
* <b>Populate with Array</b>
*
* Example model defintion:
* <code>
* class MyObject extends DataObject {
* static $db = array(
* 'Country' => "Varchar(100)"
* );
* }
* </code>
*
* Exampe instantiation:
* <code>
* new DropdownField(
* 'Country',
* 'Country',
* array(
* 'NZ' => 'New Zealand',
* 'US' => 'United States'
* 'GEM'=> 'Germany'
* )
* );
* </code>
*
* <b>Populate with Enum-Values</b>
*
* You can automatically create a map of possible values from an {@link Enum} database column.
*
* Example model definition:
* <code>
* class MyObject extends DataObject {
* static $db = array(
* 'Country' => "Enum('New Zealand,United States,Germany','New Zealand')"
* );
* }
* </code>
*
* Field construction:
* <code>
* new DropdownField(
* 'Country',
* 'Country',
* singleton('MyObject')->dbObject('Country')->enumValues()
* );
* </code>
*
* @package forms
* @subpackage fields-basic
*/

View File

@ -5,6 +5,42 @@
*
* Note: the child fields within a field group aren't rendered using FieldHolder(). Instead,
* SmallFieldHolder() is called, which just prefixes $Field with a <label> tag, if the Title is set.
*
* <b>Usage</b>
*
* <code>
* new FieldGroup(
* new FieldGroup(
* new HeaderField('FieldGroup 1'),
* new TextField('Firstname')
* ),
* new FieldGroup(
* new HeaderField('FieldGroup 2'),
* new TextField('Surname')
* )
* )
* </code>
*
* <b>Adding to existing FieldGroup instances</b>
*
* <code>
* function getCMSFields() {
* $fields = parent::getCMSFields();
*
* $fields->addFieldToTab(
* 'Root.Content.Main',
* new FieldGroup(
* new TimeField("StartTime","What's the start time?"),
* new TimeField("EndTime","What's the end time?")
* ),
* 'Content'
* );
*
* return $fields;
*
* }
* </code>
*
* @package forms
* @subpackage fields-structural
*/

View File

@ -9,6 +9,34 @@
*
* CAUTION: Doesn't work in the CMS due to ajax submission, please use {@link FileIFrameField} instead.
*
* <b>Usage</p>
*
* If you want to implement a FileField into a form element, you need to pass it an array of source data.
*
* <code>
* class ExampleForm_Controller extends Page_Controller {
*
* public function Form() {
* $fields = new FieldSet(
* new TextField('MyName'),
* new FileField('MyFile')
* );
* $actions = new FieldSet(
* new FormAction('doUpload', 'Upload file')
* );
* $validator = new RequiredFields(array('MyName', 'MyFile'));
*
* return new Form($this, 'Form', $fields, $actions, $validator);
* }
*
* function doUpload($data, $form) {
* $file = $data['MyFile'];
* $content = file_get_contents($file['tmp_name']);
* // ... process content
* }
* }
* </code>
*
* @package forms
* @subpackage fields-files
*/

View File

@ -2,6 +2,23 @@
/**
* Single action button.
* The action buttons are <input type="submit"> tags.
*
* <b>Usage</b>
*
* Upon clicking the button below will redirect the user to doAction under the current controller.
*
* <code>
* new FormAction (
* // doAction has to be a defined controller member
* $action = "doAction",
* $title = "Submit button"
* )
* </code>
*
* <b>Labels</b>
*
* By default, FormAction will use the title as the label for the left margin. This can look redundant on the form. If you'd rather have just the button alone with as pictured above try using {@link FormAction_WithoutLabel} instead.
*
* @package forms
* @subpackage actions
*/

View File

@ -9,6 +9,31 @@
* Returns a <select> tag containing all the appropriate <option> tags, with
* <optgroup> tags around the <option> tags as required.
*
* <b>Usage</b>
*
* <code>
* new GroupedDropdownField(
* $name = "dropdown",
* $title = "Simple Grouped Dropdown",
* $source = array(
* "numbers" => array(
* "1" => "1",
* "2" => "2",
* "3" => "3",
* "4" => "4"
* ),
* "letters" => array(
* "1" => "A",
* "2" => "B",
* "3" => "C",
* "4" => "D",
* "5" => "E",
* "6" => "F"
* )
* )
* )
* </code>
*
* @package forms
* @subpackage fields-basic
*/

View File

@ -1,6 +1,32 @@
<?php
/**
* ComplexTableField designed to edit a has_many join.
*
* This field allows you to show a 1-to-many relation with a group of DataObjects as a (readonly) tabular list. Its most useful when you want to manage the relationship itself thanks the **check boxes** present on each line of the table.
*
* Moreover, you can not do any mistake anymore in the relation by checking a DataObject already linked with another of the parent class.
*
* See {@link ComplexTableField} for more documentation on the base-class.
*
* <b>Usage</b>
*
* <code>
* $tablefield = new HasManyComplexTableField(
* $this,
* 'MyFruits',
* 'Fruit',
* array(
* 'Name' => 'Name',
* 'Color' => 'Color'
* ),
* 'getCMSFields_forPopup'
* );
* </code>
*
* Notice: You still have different ways to customize the popup window as in the parent-class {@link ComplexTableField}.
*
* @see http://doc.silverstripe.org/tutorial/5-dataobject-relationship-management
*
* @package forms
* @subpackage fields-relational
*/

View File

@ -1,6 +1,35 @@
<?php
/**
* ComplexTableField with a radio button column, designed to edit a has_one join.
*
* This [RelationTable](RelationTable) allows you to show a **1-to-1** or **1-to-many** relation with a group of DataObjects as a (readonly) tabular list (similiar to [ComplexTableField](ComplexTableField)). Its most useful when you want to manage the relationship itself thanks the **radio buttons** present on each line of the table.
*
* Moreover, you have the possibility to uncheck a radio button in order to make the relation as null.
*
* <b>Usage</b>
*
* <code>
* $tablefield = new HasOneComplexTableField(
* $this,
* 'MyOnlyFruit',
* 'Fruit',
* array(
* 'Name' => 'Name',
* 'Color' => 'Color'
* ),
* 'getCMSFields_forPopup'
* );
* </code>
*
* **Notice** : You still have different ways to customize the popup window as in the parent-class [ComplexTableField](ComplexTableField).
*
* This field is made to manage a **has_one** relation. In the SilverStripe relation between DataObjects, you can use this relation for **1-to-1** and **1-to-many** relations.
* By default, a HasOneComplexTableField manages a **1-to-many** relation. If you want to specify that the relation that you manage is a **1-to-1** relation, add this code :
*
* <code>
* $tablefield->setOneToOne();
* </code>
*
* @package forms
* @subpackage fields-relational
*/

View File

@ -2,6 +2,21 @@
/**
* A field that allows you to attach an image to a record from within a iframe - designed for use in AJAX forms where it
* is not possible to use {@link SimpleImageField}.
*
* <b>Usage</b>
*
* If you want to upload all assets from this field to a given folder you can define the folder in 2 ways. Either in the constructor or as a method on the field
*
* <code>
* $myField = new ImageField("myName", "Upload image below", null, null, null, "myFolder");
* </code>
*
* Will upload images into the assets/myFolder folder. If that folder does not exist it will create it for you. You can also define it as a method
*
* <code>
* $myField = new ImageField("myName");
* $myField->setFolderName('myFolder');
* </code>
*
* @package forms
* @subpackage fields-files

View File

@ -1,6 +1,22 @@
<?php
/**
* Multi-line listbox field, created from a <select> tag.
*
* <b>Usage</b>
*
* <code>
* new ListboxField(
* $name = "pickanumber",
* $title = "Pick a number",
* $source = array(
* "1" => "one",
* "2" => "two",
* "3" => "three"
* ),
* $value = 1
* )
* </code>
*
* @package forms
* @subpackage fields-basic
*/

View File

@ -2,6 +2,15 @@
/**
* This field lets you put an arbitrary piece of HTML into your forms.
*
* <b>Usage</b>
*
* <code>
* new LiteralField (
* $name = "literalfield",
* $content = '<b>some bold text</b> and <a href="http://silverstripe.com">a link</a>'
* )
* </code>
*
* @package forms
* @subpackage fields-dataless
*/

View File

@ -1,6 +1,35 @@
<?php
/**
* Special ComplexTableField for editing a many_many relation.
*
* This field allows you to show a **many-to-many** relation with a group of
* DataObjects as a (readonly) tabular list (similiar to {@link ComplexTableField}).
* Its most useful when you want to manage the relationship itself
* thanks to the check boxes present on each line of the table.
*
* See {@link ComplexTableField} for more documentation on the base-class.
* See {@link HasManyComplexTableField} for more documentation on the relation table base-class.
*
* Note: This class relies on the fact that both sides of the relation have database tables.
* If you are only creating a class as a logical extension (that is, it doesn't have any database fields),
* then you will need to create a dummy static $db array because SilverStripe won't create a database
* table unless needed.
*
* <b>Usage</b>
*
* <code>
* $tablefield = new ManyManyComplexTableField(
* $this,
* 'MyFruits',
* 'Fruit',
* array(
* 'Name' => 'Name',
* 'Color' => 'Color'
* ),
* 'getCMSFields_forPopup'
* );
* </code>
*
* @package forms
* @subpackage fields-relational
*/

View File

@ -2,6 +2,51 @@
/**
* Set of radio buttons designed to emulate a dropdown.
* It even uses the same constructor as a dropdown field.
*
* This field allows you to ensure that a form element is submitted is not optional and is part of a fixed set of
* data. This field uses the input type of radio. It's a direct subclass of {@link DropdownField},
* so the constructor and arguments are in the same format.
*
* <b>Usage</b>
*
* <code>
* new OptionsetField(
* $name = "Foobar",
* $title = "FooBar's optionset",
* $source = array(
* "1" => "Option 1",
* "2" => "Option 2",
* "3" => "Option 3",
* "4" => "Option 4",
* "5" => "Option 5"
* ),
* $value = "1"
* );
* </code>
*
* You can use the helper functions on data object set to create the source array. eg:
*
* <code>
* //Database request for the object
* $myDoSet = DataObject::get("FooBars","");
* if($myDoSet){
* // This returns an array of ID => Title
* $map = $myDoSet->toDropDownMap();
*
* // Instantiate the OptionsetField
* $fieldset = new Fieldset(
* new OptionsetField(
* $name = "Foobar",
* $title = "FooBar's optionset",
* $source = $map,
* $value = $map[0]
* )
* );
* }
*
* // Pass the fields to the form constructor. etc
* </code>
*
* @package forms
* @subpackage fields-basic
*/

View File

@ -7,7 +7,8 @@
* Restricts the upload size to 2MB by default, and only allows upload
* of files with the extension 'jpg', 'gif' or 'png'.
*
* Example Usage:
* <b>Usage</b>
*
* <code>
* class Article extends DataObject {
* static $has_one = array('MyImage' => 'Image');
@ -16,6 +17,48 @@
* $myField = new SimpleImageField('MyImage');
* </code>
*
* <b>Usage within a controller</b>
*
* First add your $has_one relationship:
*
* <code>
* static $has_one = array(
* 'FileName' => 'FileType'
* );
* </code>
* (i.e. Image for a FileType)
*
* Then add your Field into your form:
*
* <code>
* function Form() {
* return new Form($this, "Form", new FieldSet(
* new SimpleImageField (
* $name = "FileTypeID",
* $title = "Upload your FileType"
* )
* ), new FieldSet(
*
* // List the action buttons here - doform executes the function 'doform' below
* new FormAction("doform", "Submit")
*
* // List the required fields here
* ), new RequiredFields(
* "FileTypeID"
* ));
* }
* // Then make sure that the file is saved into the assets area:
* function doform($data, $form) {
* $file = new File();
* $file->loadUploaded($_FILES['FileTypeID']);
*
* // Redirect to a page thanking people for registering
* Director::redirect('thanks-for-your-submission/');
* }
* </code>
*
* Your file should be now in the uploads directory
*
* @package forms
* @subpackage fields-files
*/

View File

@ -1,6 +1,18 @@
<?php
/**
* Implements a single tab in a {@link TabSet}.
*
* Here is a simple implementation of a Tab. Obviously, you can include as much fields
* inside as you want. A tab can contain other tabs as well.
*
* <code>
* new Tab(
* $title='Tab one',
* new HeaderField("A header"),
* new LiteralField("Lipsum","Lorem ipsum dolor sit amet enim.")
* )
* </code>
*
* @package forms
* @subpackage fields-structural
*/

View File

@ -1,8 +1,27 @@
<?php
/**
* Defines a set of tabs in a form.
* The tabs are build with our standard tabstrip javascript library. By default, the HTML is
* generated using FieldHolder.
* The tabs are build with our standard tabstrip javascript library.
* By default, the HTML is generated using FieldHolder.
*
* <b>Usage</b>
*
* <code>
* new TabSet(
* $name = "TheTabSetName",
* new Tab(
* $title='Tab one',
* new HeaderField("A header"),
* new LiteralField("Lipsum","Lorem ipsum dolor sit amet enim.")
* ),
* new Tab(
* $title='Tab two',
* new HeaderField("A second header"),
* new LiteralField("Lipsum","Ipsum dolor sit amet enim.")
* )
* )
* </code>
*
* @package forms
* @subpackage fields-structural
*/

View File

@ -5,6 +5,18 @@
* text field. It creates the <textarea> tag in the
* form HTML.
*
* <b>Usage</b>
*
* <code>
* new TextareaField(
* $name = "description",
* $title = "Description",
* $rows = 8,
* $cols = 3,
* $value = "This is the default description"
* );
* </code>
*
* @package forms
* @subpackage fields-basic
*/

View File

@ -1,6 +1,28 @@
<?php
/**
* Dropdown-like field that allows you to select an item from a hierachical AJAX-expandable tree
* Dropdown-like field that allows you to select an item from a hierachical AJAX-expandable tree.
*
* Creates a field which opens a dropdown (actually a div via javascript included for you) which contains a tree with the ability to select a singular item for the value of the field. This field has the ability to store one-to-one joins related to hierarchy or a hierarchy based filter.
*
* **Note:** your source object must use an implementation of hierarchy for this field to generate the tree correctly, e.g. groups, sitetree etc.
*
* All operations are carried out through behaviour and javascript.
*
* <b>Usage</b>.
*
* treedropdownfield is used on {@link VirtualPage} a class which creates another instance of a page, with exactly the same fields that can be represented on another part of the site. The code below is taken from an example of this.
*
* <code>
* // Put this at the top of the class that defines your model (e.g. the class that extends DataObject).
* static $has_one = array(
* 'RightContent' => 'SiteTree'
* );
*
* // Setup the linking to the original page. (Put this in your getCMSFields() method or similar)
* $treedropdownfield = new TreeDropdownField("RightContentID", "Choose a page to show on the right:", "SiteTree");
* </code>
*
* This will generate a tree allowing the user to expand and contract subsections to find the appropriate page to save to the field.
*
* @package forms
* @subpackage fields-relational

View File

@ -1,7 +1,34 @@
<?php
/**
* This formfield represents many-many joins using a tree selector shown in a dropdown styled element
* which can be added to any form usually in the CMS.
* which can be added to any form usually in the CMS.
*
* This form class allows you to represent Many-Many Joins in a handy single field. The field has javascript which generates a AJAX tree of the site structure allowing you to save selected options to a component set on a given {@link DataObject}.
*
* <b>Saving</b>
*
* This field saves a {@link ComponentSet} object which is present on the {@link DataObject} passed by the form, returned by calling a function with the same name as the field. The Join is updated by running setByIDList on the {@link ComponentSet}
*
* <b>Customizing Save Behaviour</b>
*
* Before the data is saved, you can modify the ID list sent to the {@link ComponentSet} by specifying a function on the {@link DataObject} called "onChange[fieldname](&items)". This will be passed by reference the IDlist (an array of ID's) from the Treefield to be saved to the component set.
* Returning false on this method will prevent treemultiselect from saving to the {@link ComponentSet} of the given {@link DataObject}
*
* <code>
* // Called when we try and set the Parents() component set
* // by Tree Multiselect Field in the administration.
* function onChangeParents(&$items) {
* // This ensures this DataObject can never be a parent of itself
* if($items){
* foreach($items as $k => $id){
* if($id == $this->ID){
* unset($items[$k]);
* }
* }
* }
* return true;
* }
* </code>
*
* @package forms
* @subpackage fields-relational

View File

@ -2,11 +2,51 @@
/**
* A simple parser that allows you to map BBCode-like "shortcodes" to an arbitrary callback.
*
* Shortcodes can take the form:
* * The Shortcode API (new in 2.4) is a simple regex based parser that allows you to replace simple bbcode-like tags within a HTMLText or HTMLVarchar field when rendered into a template. It is inspired by and very similar to the [Wordpress implementation](http://codex.wordpress.org/Shortcode_API) of shortcodes. Examples of shortcode tags are:
*
* <code>
* [shortcode]
* [shortcode attributes="example" /]
* [shortcode]enclosed content[/shortcode]
* [shortcode]
* [shortcode /]
* [shortcode parameter="value"]
* [shortcode parameter="value"]Enclosed Content[/shortcode]
* </code>
*
* <b>Defining Custom Shortcodes</b>
*
* All you need to do to define a shortcode is to register a callback with the parser that will be called whenever a shortcode is encountered. This callback will return a string to replace the shortcode with.
*
* To register a shortcode you call:
*
* <code>
* ShortcodeParser::get('default')->register('shortcode_tag_name', 'callback');
* </code>
*
* These parameters are passed to the callback:
* * Any parameters attached to the shortcode as an associative array (keys are lower-case).
* * Any content enclosed within the shortcode (if it is an enclosing shortcode). Note that any content within this will not have been parsed, and can optionally be fed back into the parser.
* * The ShortcodeParser instance used to parse the content.
* * The shortcode tag name that was matched within the parsed content.
*
* <b>Inbuilt Shortcodes</b>
*
* From 2.4 onwards links inserted via the CMS into a content field are in the form ''<a href="[sitetree_link id=n]">''. At runtime this is replaced by a plain link to the page with the ID in question.
*
* <b>Limitations</b>
*
* Since the shortcode parser is based on a simple regular expression it cannot properly handle nested shortcodes. For example the below code will not work as expected:
*
* <code>
* [shortcode]
* [shortcode][/shortcode]
* [/shortcode]
* </code>
*
* The parser will recognise this as:
*
* <code>
* [shortcode]
* [shortcode]
* [/shortcode]
* </code>
*
* @package sapphire

View File

@ -1,11 +1,42 @@
<?php
/**
* Abstract task representing scheudled tasks.
*
* Scheduled tasks are tasks that are run at a certain time or set interval. For example, notify a page owner that
* their page is about to expire. Scheduled tasks are implemented as singleton instances and a single
* instance is responsibly directly or indirectly for executing all tasks that should be run at that time.
*
* You can use the different subclasses {@link HourlyTask}, {@link DailyTask},
* {@link WeeklyTask} to determine when a task should be run,
* and use automation tools such as unix cron to trigger them.
*
* Example Cron:
* <b>Usage</b>
*
* Implement a daily task by extending DailyTask and implementing process().
*
* <code>
* class MyTask extends DailyTask {
* function process() {
* // implement your task here
* }
* }
* </code>
*
* You can also implement the index() method to overwrite which singleton classes are instantiated and processed.
* By default, all subclasses of the task are instantiated and used. For the DailyTask class, this means
* that an instance of each subclass of DailyTask will be created.
*
* You can test your task from the command line by running the following command
* (replace <MyTask> is the classname of your task):
*
* <code>sapphire/cli-script.php /<MyTask></code>
*
* To perform all Daily tasks, run from the command line:
*
* <code>cli-script.php /DailyTask</code>
*
* <b>Example Cron Definition</b>
*
* <code>
* # Quarter-hourly task (every hour at 25 minutes past) (remove space between first * and /15)
* * /15 * * * * www-data /my/webroot/sapphire/cli-script.php /QuarterlyHourlyTask > /var/log/silverstripe_quarterhourlytask.log