Merge pull request #1962 from wilr/api-links

Update @package, @subpackage labels
This commit is contained in:
Ingo Schommer 2013-05-21 03:27:22 -07:00
commit 30906c8b31
41 changed files with 707 additions and 257 deletions

View File

@ -6,8 +6,8 @@
* This is essentially an abstract class which should be subclassed.
* See {@link CMSMain} for a good example.
*
* @package cms
* @subpackage core
* @package framework
* @subpackage admin
*/
class LeftAndMain extends Controller implements PermissionProvider {
@ -1769,6 +1769,9 @@ class LeftAndMainMarkingFilter {
/**
* Allow overriding finished state for faux redirects.
*
* @package framework
* @subpackage admin
*/
class LeftAndMain_HTTPResponse extends SS_HTTPResponse {
@ -1788,7 +1791,10 @@ class LeftAndMain_HTTPResponse extends SS_HTTPResponse {
* Wrapper around objects being displayed in a tree.
* Caution: Volatile API.
*
* @todo Implement recursive tree node rendering
* @todo Implement recursive tree node rendering.
*
* @package framework
* @subpackage admin
*/
class LeftAndMain_TreeNode extends ViewableData {

View File

@ -2,8 +2,8 @@
/**
* Plug-ins for additional functionality in your LeftAndMain classes.
*
* @package cms
* @subpackage core
* @package framework
* @subpackage admin
*/
abstract class LeftAndMainExtension extends Extension {

View File

@ -26,8 +26,8 @@
*
* @uses SearchContext
*
* @package cms
* @subpackage core
* @package framework
* @subpackage admin
*/
abstract class ModelAdmin extends LeftAndMain {

View File

@ -1,14 +1,21 @@
<?php
/**
* Handle the X-Pjax header that AJAX responses may provide, returning the
* fragment, or, in the case of non-AJAX form submissions, redirecting back to the submitter.
* fragment, or, in the case of non-AJAX form submissions, redirecting back
* to the submitter.
*
* X-Pjax ensures that users won't end up seeing the unstyled form HTML in
* their browser.
*
* If a JS error prevents the Ajax overriding of form submissions from happening.
*
* X-Pjax ensures that users won't end up seeing the unstyled form HTML in their browser
* If a JS error prevents the Ajax overriding of form submissions from happening.
* It also provides better non-JS operation.
*
* Caution: This API is volatile, and might eventually be replaced by a generic
* action helper system for controllers.
*
* @package framework
* @subpackage control
*/
class PjaxResponseNegotiator {

View File

@ -1,10 +1,8 @@
<?php
/**
* Description of RequestProcessor
*
* @author marcus@silverstripe.com.au
* @license BSD License http://silverstripe.org/bsd-license/
* @package framework
* @subpackage control
*/
class RequestProcessor {

View File

@ -2,13 +2,10 @@
/**
* A class that proxies another, allowing various functionality to be
* injected
* injected.
*
* @author marcus@silverstripe.com.au
* @package framework
* @subpackage injector
*
* @license http://silverstripe.org/bsd-license/
*/
class AopProxyService {
public $beforeCall = array();

View File

@ -1,15 +1,13 @@
<?php
/**
* A BeforeCallAspect is run before a method is executed
* A BeforeCallAspect is run before a method is executed.
*
* This is a declared interface, but isn't actually required
* as PHP doesn't really care about types...
*
* @author Marcus Nyeholt <marcus@silverstripe.com.au>
* @package framework
* @subpackage injector
* @license BSD http://silverstripe.org/BSD-license
*/
interface BeforeCallAspect {

View File

@ -0,0 +1,26 @@
<?php
/**
* A class for creating new objects by the injector.
*
* @package framework
* @subpackage injector
*/
class InjectionCreator {
/**
* @param string $object
* A string representation of the class to create
* @param array $params
* An array of parameters to be passed to the constructor
*/
public function create($class, $params = array()) {
$reflector = new ReflectionClass($class);
if (count($params)) {
return $reflector->newInstanceArgs($params);
}
return $reflector->newInstance();
}
}

View File

@ -0,0 +1,15 @@
<?php
/**
* Used to locate configuration for a particular named service.
*
* If it isn't found, return null.
*
* @package framework
* @subpackage injector
*/
class ServiceConfigurationLocator {
public function locateConfigFor($name) {
}
}

View File

@ -0,0 +1,22 @@
<?php
/**
* @package framework
* @subpackage injector
*/
class SilverStripeInjectionCreator {
/**
*
* @param string $object
* A string representation of the class to create
* @param array $params
* An array of parameters to be passed to the constructor
*/
public function create($class, $params = array()) {
$class = Object::getCustomClass($class);
$reflector = new ReflectionClass($class);
return $reflector->newInstanceArgs($params);
}
}

View File

@ -0,0 +1,49 @@
<?php
/**
* Use the SilverStripe configuration system to lookup config for a
* particular service.
*
* @package framework
* @subpackage injector
*/
class SilverStripeServiceConfigurationLocator {
private $configs = array();
public function locateConfigFor($name) {
if (isset($this->configs[$name])) {
return $this->configs[$name];
}
$config = Config::inst()->get('Injector', $name);
if ($config) {
$this->configs[$name] = $config;
return $config;
}
// do parent lookup if it's a class
if (class_exists($name)) {
$parents = array_reverse(array_keys(ClassInfo::ancestry($name)));
array_shift($parents);
foreach ($parents as $parent) {
// have we already got for this?
if (isset($this->configs[$parent])) {
return $this->configs[$parent];
}
$config = Config::inst()->get('Injector', $parent);
if ($config) {
$this->configs[$name] = $config;
return $config;
} else {
$this->configs[$parent] = false;
}
}
// there is no parent config, so we'll record that as false so we don't do the expensive
// lookup through parents again
$this->configs[$name] = false;
}
}
}

View File

@ -10,166 +10,215 @@
* - An array
* - A non-array value
*
* If the value is an array, each value in the array may also be one of those three types
* If the value is an array, each value in the array may also be one of those
* three types.
*
* A property can have a value specified in multiple locations, each of which have a hardcoded or explicit priority.
* We combine all these values together into a "composite" value using rules that depend on the priority order of the
* locations to give the final value, using these rules:
* A property can have a value specified in multiple locations, each of which
* have a hard coded or explicit priority. We combine all these values together
* into a "composite" value using rules that depend on the priority order of
* the locations to give the final value, using these rules:
*
* - If the value is an array, each array is added to the _beginning_ of the composite array in ascending priority
* order. If a higher priority item has a non-integer key which is the same as a lower priority item, the value of
* those items is merged using these same rules, and the result of the merge is located in the same location the
* higher priority item would be if there was no key clash. Other than in this key-clash situation, within the
* particular array, order is preserved.
* - If the value is an array, each array is added to the _beginning_ of the
* composite array in ascending priority order. If a higher priority item has
* a non-integer key which is the same as a lower priority item, the value of
* those items is merged using these same rules, and the result of the merge
* is located in the same location the higher priority item would be if there
* was no key clash. Other than in this key-clash situation, within the
* particular array, order is preserved.
*
* - If the value is not an array, the highest priority value is used without any attempt to merge
* - If the value is not an array, the highest priority value is used without
* any attempt to merge.
*
* It is an error to have mixed types of the same named property in different locations (but an error will not
* necessarily be raised due to optimisations in the lookup code)
* It is an error to have mixed types of the same named property in different
* locations (but an error will not necessarily be raised due to optimizations
* in the lookup code).
*
* The exception to this is "false-ish" values - empty arrays, empty strings, etc. When merging a non-false-ish value
* with a false-ish value, the result will be the non-false-ish value regardless of priority. When merging two
* The exception to this is "false-ish" values - empty arrays, empty strings,
* etc. When merging a non-false-ish value with a false-ish value, the result
* will be the non-false-ish value regardless of priority. When merging two
* false-ish values the result will be the higher priority false-ish value.
*
* The locations that configuration values are taken from in highest -> lowest priority order
* The locations that configuration values are taken from in highest -> lowest
* priority order.
*
* - Any values set via a call to Config#update
* - Any values set via a call to Config#update.
*
* - The configuration values taken from the YAML files in _config directories (internally sorted in before / after
* order, where the item that is latest is highest priority)
* - The configuration values taken from the YAML files in _config directories
* (internally sorted in before / after order, where the item that is latest
* is highest priority).
*
* - Any static set on an "additional static source" class (such as an extension) named the same as the name of the
* property
* - Any static set on an "additional static source" class (such as an
* extension) named the same as the name of the property.
*
* - Any static set on the class named the same as the name of the property
* - Any static set on the class named the same as the name of the property.
*
* - The composite configuration value of the parent class of this class
* - The composite configuration value of the parent class of this class.
*
* At some of these levels you can also set masks. These remove values from the composite value at their priority
* point rather than add. They are much simpler. They consist of a list of key / value pairs. When applied against the
* current composite value:
* At some of these levels you can also set masks. These remove values from the
* composite value at their priority point rather than add. They are much
* simpler. They consist of a list of key / value pairs. When applied against
* the current composite value:
*
* - If the composite value is a sequential array, any member of that array that matches any value in the mask is
* removed
* - If the composite value is a sequential array, any member of that array
* that matches any value in the mask is removed.
*
* - If the composite value is an associative array, any member of that array that matches both the key and value of
* any pair in the mask is removed
* - If the composite value is an associative array, any member of that array
* that matches both the key and value of any pair in the mask is removed.
*
* - If the composite value is not an array, if that value matches any value in the mask it is removed
* - If the composite value is not an array, if that value matches any value
* in the mask it is removed.
*
* @package framework
* @subpackage core
*/
class Config {
/**
* [A marker instance for the "anything" singleton value. Don't access directly, even in-class, always use
* self::anything()
* A marker instance for the "anything" singleton value. Don't access
* directly, even in-class, always use self::anything()
*
* @var Object
*/
static private $_anything = null;
private static $_anything = null;
/**
* Get a marker class instance that is used to do a "remove anything with this key" by adding
* $key => Config::anything() to the suppress array
* Get a marker class instance that is used to do a "remove anything with
* this key" by adding $key => Config::anything() to the suppress array
*
* @todo Does this follow the SS coding conventions? Config::get_anything_marker_instance() is a lot less elegant.
* @return Object
*/
static public function anything() {
if (self::$_anything === null) self::$_anything = new stdClass();
public static function anything() {
if (self::$_anything === null) {
self::$_anything = new stdClass();
}
return self::$_anything;
}
// -- Source options bitmask --
/**
* source options bitmask value - merge all parent configuration in as lowest priority
* source options bitmask value - merge all parent configuration in as
* lowest priority.
*
* @const
*/
const INHERITED = 0;
/**
* source options bitmask value - only get configuration set for this specific class, not any of it's parents
* source options bitmask value - only get configuration set for this
* specific class, not any of it's parents.
*
* @const
*/
const UNINHERITED = 1;
/**
* source options bitmask value - inherit, but stop on the first class that actually provides a value (event an
* empty value)
* source options bitmask value - inherit, but stop on the first class
* that actually provides a value (event an empty value).
*
* @const
*/
const FIRST_SET = 2;
/** @const source options bitmask value - do not use additional statics sources (such as extension) */
/**
* @const source options bitmask value - do not use additional statics
* sources (such as extension)
*/
const EXCLUDE_EXTRA_SOURCES = 4;
// -- get_value_type response enum --
/**
* Return flag for get_value_type indicating value is a scalar (or really just not-an-array, at least ATM)
* Return flag for get_value_type indicating value is a scalar (or really
* just not-an-array, at least ATM)
*
* @const
*/
const ISNT_ARRAY = 1;
/**
* Return flag for get_value_type indicating value is an array
* Return flag for get_value_type indicating value is an array.
* @const
*/
const IS_ARRAY = 2;
/**
* Get whether the value is an array or not. Used to be more complicated, but still nice sugar to have an enum
* to compare and not just a true/false value
* Get whether the value is an array or not. Used to be more complicated,
* but still nice sugar to have an enum to compare and not just a true /
* false value.
*
* @param $val any - The value
*
* @return int - One of ISNT_ARRAY or IS_ARRAY
*/
static protected function get_value_type($val) {
if (is_array($val)) return self::IS_ARRAY;
protected static function get_value_type($val) {
if (is_array($val)) {
return self::IS_ARRAY;
}
return self::ISNT_ARRAY;
}
/**
* What to do if there's a type mismatch
* What to do if there's a type mismatch.
*
* @throws UnexpectedValueException
*/
static protected function type_mismatch() {
protected static function type_mismatch() {
throw new UnexpectedValueException('Type mismatch in configuration. All values for a particular property must'
. ' contain the same type (or no value at all).');
}
/* @todo If we can, replace next static & static methods with DI once that's in */
static protected $instance;
/**
* @todo If we can, replace next static & static methods with DI once that's in
*/
protected static $instance;
/**
* Get the current active Config instance.
*
* Configs should not normally be manually created.
* In general use you will use this method to obtain the current Config instance.
*
* In general use you will use this method to obtain the current Config
* instance.
*
* @return Config
*/
static public function inst() {
if (!self::$instance) self::$instance = new Config();
public static function inst() {
if (!self::$instance) {
self::$instance = new Config();
}
return self::$instance;
}
/**
* Set the current active Config instance.
* Set the current active {@link Config} instance.
*
* Configs should not normally be manually created.
* A use case for replacing the active configuration set would be for creating an isolated environment for
* unit tests
* {@link Config} objects should not normally be manually created.
*
* A use case for replacing the active configuration set would be for
* creating an isolated environment for unit tests.
*
* @return Config
*/
static public function set_instance($instance) {
public static function set_instance($instance) {
self::$instance = $instance;
global $_SINGLETONS;
$_SINGLETONS['Config'] = $instance;
}
/**
* Make the newly active Config be a copy of the current active Config instance.
* Make the newly active {@link Config} be a copy of the current active
* {@link Config} instance.
*
* You can then make changes to the configuration by calling update and remove on the new
* value returned by Config::inst(), and then discard those changes later by calling unnest
* You can then make changes to the configuration by calling update and
* remove on the new value returned by Config::inst(), and then discard
* those changes later by calling unnest.
*/
static public function nest() {
public static function nest() {
$current = self::$instance;
$new = clone $current;
@ -178,17 +227,21 @@ class Config {
}
/**
* Change the active Config back to the Config instance the current active Config object
* was copied from
* Change the active Config back to the Config instance the current active
* Config object was copied from.
*/
static public function unnest() {
public static function unnest() {
self::set_instance(self::$instance->nestedFrom);
}
/**
* @var array
*/
protected $cache;
/**
* Each copy of the Config object need's it's own cache, so changes don't leak through to other instances
* Each copy of the Config object need's it's own cache, so changes don't
* leak through to other instances.
*/
public function __construct() {
$this->cache = new Config_LRU();
@ -198,21 +251,37 @@ class Config {
$this->cache = clone $this->cache;
}
/** @var Config - The config instance this one was copied from when Config::nest() was called */
/**
* @var Config - The config instance this one was copied from when
* Config::nest() was called.
*/
protected $nestedFrom = null;
/** @var [array] - Array of arrays. Each member is an nested array keyed as $class => $name => $value,
* where value is a config value to treat as the highest priority item */
/**
* @var array - Array of arrays. Each member is an nested array keyed as
* $class => $name => $value, where value is a config value to treat as
* the highest priority item.
*/
protected $overrides = array();
/** @var [array] - Array of arrays. Each member is an nested array keyed as $class => $name => $value,
* where value is a config value suppress from any lower priority item */
/**
* @var array $suppresses Array of arrays. Each member is an nested array
* keyed as $class => $name => $value, where value is a config value suppress
* from any lower priority item.
*/
protected $suppresses = array();
/**
* @var array
*/
protected $staticManifests = array();
/**
* @param SS_ConfigStaticManifest
*/
public function pushConfigStaticManifest(SS_ConfigStaticManifest $manifest) {
array_unshift($this->staticManifests, $manifest);
$this->cache->clean();
}
@ -596,6 +665,10 @@ class Config {
}
/**
* @package framework
* @subpackage core
*/
class Config_LRU {
const SIZE = 1000;
@ -701,25 +774,54 @@ class Config_LRU {
}
}
/**
* @package framework
* @subpackage core
*/
class Config_ForClass {
/**
* @var string $class
*/
protected $class;
/**
* @param string $class
*/
public function __construct($class) {
$this->class = $class;
}
/**
* @param string $name
*/
public function __get($name) {
return Config::inst()->get($this->class, $name);
}
/**
* @param string $name
* @param mixed $val
*/
public function __set($name, $val) {
return Config::inst()->update($this->class, $name, $val);
}
/**
* @param string $name
* @param int $sourceOptions
*
* @return array|scalar
*/
public function get($name, $sourceOptions = 0) {
return Config::inst()->get($this->class, $name, $sourceOptions);
}
/**
* @param string
*
* @return Config_ForClass
*/
public function forClass($class) {
return Config::inst()->forClass($class);
}

View File

@ -16,7 +16,7 @@
* @see SS_List
*
* @package framework
* @subpackage fields-relational
* @subpackage fields-gridfield
*/
class GridField extends FormField {
@ -761,12 +761,11 @@ class GridField extends FormField {
/**
* This class is the base class when you want to have an action that alters the state of the gridfield,
* rendered as a button element.
* This class is the base class when you want to have an action that alters
* the state of the {@link GridField}, rendered as a button element.
*
* @package framework
* @subpackage forms
*
* @subpackage fields-gridfield
*/
class GridField_FormAction extends FormAction {

View File

@ -1,14 +1,25 @@
<?php
/**
* This class is is responsible for adding objects to another object's has_many and many_many relation,
* as defined by the {@link RelationList} passed to the GridField constructor.
* Objects can be searched through an input field (partially matching one or more fields).
* This class is is responsible for adding objects to another object's has_many
* and many_many relation, as defined by the {@link RelationList} passed to the
* {@link GridField} constructor.
*
* Objects can be searched through an input field (partially matching one or
* more fields).
*
* Selecting from the results will add the object to the relation.
* Often used alongside {@link GridFieldDeleteAction} for detaching existing records from a relatinship.
* For easier setup, have a look at a sample configuration in {@link GridFieldConfig_RelationEditor}.
*
* Often used alongside {@link GridFieldDeleteAction} for detaching existing
* records from a relationship.
*
* For easier setup, have a look at a sample configuration in
* {@link GridFieldConfig_RelationEditor}.
*
* @package framework
* @subpackage fields-gridfield
*/
class GridFieldAddExistingAutocompleter
implements GridField_HTMLProvider, GridField_ActionProvider, GridField_DataManipulator, GridField_URLHandler {
class GridFieldAddExistingAutocompleter
implements GridField_HTMLProvider, GridField_ActionProvider, GridField_DataManipulator, GridField_URLHandler {
/**
* Which template to use for rendering

View File

@ -1,10 +1,13 @@
<?php
/**
* This component provides a button for opening the add new form provided by {@link GridFieldDetailForm}.
* Only returns a button if {@link DataObject->canCreate()} for this record returns true.
* This component provides a button for opening the add new form provided by
* {@link GridFieldDetailForm}.
*
* Only returns a button if {@link DataObject->canCreate()} for this record
* returns true.
*
* @package framework
* @subpackage gridfield
* @subpackage fields-gridfield
*/
class GridFieldAddNewButton implements GridField_HTMLProvider {
@ -14,6 +17,7 @@ class GridFieldAddNewButton implements GridField_HTMLProvider {
public function setButtonName($name) {
$this->buttonName = $name;
return $this;
}
@ -23,7 +27,10 @@ class GridFieldAddNewButton implements GridField_HTMLProvider {
public function getHTMLFragments($gridField) {
$singleton = singleton($gridField->getModelClass());
if(!$singleton->canCreate()) return array();
if(!$singleton->canCreate()) {
return array();
}
if(!$this->buttonName) {
// provide a default button name, can be changed by calling {@link setButtonName()} on this component

View File

@ -1,14 +1,18 @@
<?php
/**
* Adding this class to a {@link GridFieldConfig} of a {@link GridField} adds a buttonrow to that field.
* Adding this class to a {@link GridFieldConfig} of a {@link GridField} adds
* a button row to that field.
*
* The button row provides a space for actions on this grid.
*
* This row provides two new HTML fragment spaces: 'toolbar-header-left' and 'toolbar-header-right'.
* This row provides two new HTML fragment spaces: 'toolbar-header-left' and
* 'toolbar-header-right'.
*
* @package framework
* @subpackage gridfield
* @subpackage fields-gridfield
*/
class GridFieldButtonRow implements GridField_HTMLProvider {
protected $targetFragment;
public function __construct($targetFragment = 'before') {
@ -20,6 +24,7 @@ class GridFieldButtonRow implements GridField_HTMLProvider {
"LeftFragment" => "\$DefineFragment(buttons-{$this->targetFragment}-left)",
"RightFragment" => "\$DefineFragment(buttons-{$this->targetFragment}-right)",
));
return array(
$this->targetFragment => $data->renderWith('GridFieldButtonRow')
);

View File

@ -1,42 +1,58 @@
<?php
/**
* Base interface for all components that can be added to GridField.
* Base interface for all components that can be added to GridField.
*
* @package framework
* @subpackage fields-gridfield
*/
interface GridFieldComponent {
}
/**
* A GridField manipulator that provides HTML for the header/footer rows, or for before/after the template
* A GridField manipulator that provides HTML for the header/footer rows, or f
* or before/after the template.
*
* @package framework
* @subpackage fields-gridfield
*/
interface GridField_HTMLProvider extends GridFieldComponent {
/**
* Returns a map where the keys are fragment names and the values are pieces of HTML to add to these fragments.
* Returns a map where the keys are fragment names and the values are
* pieces of HTML to add to these fragments.
*
* Here are 4 built-in fragments: 'header', 'footer', 'before', and 'after', but components may also specify
* fragments of their own.
* Here are 4 built-in fragments: 'header', 'footer', 'before', and
* 'after', but components may also specify fragments of their own.
*
* To specify a new fragment, specify a new fragment by including the text "$DefineFragment(fragmentname)" in the
* HTML that you return. Fragment names should only contain alphanumerics, -, and _.
* To specify a new fragment, specify a new fragment by including the
* text "$DefineFragment(fragmentname)" in the HTML that you return.
*
* If you attempt to return HTML for a fragment that doesn't exist, an exception will be thrown when the GridField
* is rendered.
* Fragment names should only contain alphanumerics, -, and _.
*
* @return Array
* If you attempt to return HTML for a fragment that doesn't exist, an
* exception will be thrown when the {@link GridField} is rendered.
*
* @return array
*/
public function getHTMLFragments($gridField);
}
/**
* Add a new column to the table display body, or modify existing columns.
*
* Used once per record/row.
*
* @package framework
* @subpackage fields-gridfield
*/
interface GridField_ColumnProvider extends GridFieldComponent {
/**
* Modify the list of columns displayed in the table.
* See {@link GridFieldDataColumns->getDisplayFields()} and {@link GridFieldDataColumns}.
*
* @see {@link GridFieldDataColumns->getDisplayFields()}
* @see {@link GridFieldDataColumns}.
*
* @param GridField $gridField
* @param array - List reference of all column names.
@ -83,16 +99,29 @@ interface GridField_ColumnProvider extends GridFieldComponent {
}
/**
* An action is defined by two things: an action name, and zero or more named arguments.
* An action is defined by two things: an action name, and zero or more named
* arguments.
*
* There is no built-in notion of a record-specific or column-specific action,
* but you may choose to define an argument such as ColumnName or RecordID in order to implement these.
* Does not provide interface elements to call those actions, see {@link GridField_FormAction}.
* but you may choose to define an argument such as ColumnName or RecordID in
* order to implement these.
*
* Does not provide interface elements to call those actions.
*
* @see {@link GridField_FormAction}.
*
* @package framework
* @subpackage fields-gridfield
*/
interface GridField_ActionProvider extends GridFieldComponent {
/**
* Return a list of the actions handled by this action provider.
* Used to identify the action later on through the $actionName parameter in {@link handleAction}.
* There is no namespacing on these actions, so you need to ensure that they don't conflict with other components.
*
* Used to identify the action later on through the $actionName parameter
* in {@link handleAction}.
*
* There is no namespacing on these actions, so you need to ensure that
* they don't conflict with other components.
*
* @param GridField
* @return Array with action identifier strings.
@ -100,9 +129,10 @@ interface GridField_ActionProvider extends GridFieldComponent {
public function getActions($gridField);
/**
* Handle an action on the given grid field.
* Calls ALL components for every action handled, so the component
* needs to ensure it only accepts actions it is actually supposed to handle.
* Handle an action on the given {@link GridField}.
*
* Calls ALL components for every action handled, so the component needs
* to ensure it only accepts actions it is actually supposed to handle.
*
* @param GridField
* @param String Action identifier, see {@link getActions()}.
@ -113,14 +143,21 @@ interface GridField_ActionProvider extends GridFieldComponent {
}
/**
* Can modify the data list.
* For example, a paginating component can apply a limit, or a sorting component can apply a sort.
* Generally, the data manipulator will make use of to `GridState` variables to decide
* how to modify the data list (see {@link GridState}).
* Can modify the data list.
*
* For example, a paginating component can apply a limit, or a sorting
* component can apply a sort.
*
* Generally, the data manipulator will make use of to {@link GridState}
* variables to decide how to modify the {@link DataList}.
*
* @package framework
* @subpackage fields-gridfield
*/
interface GridField_DataManipulator extends GridFieldComponent {
/**
* Manipulate the datalist as needed by this grid modifier.
* Manipulate the {@link DataList} as needed by this grid modifier.
*
* @param GridField
* @param SS_List
@ -130,21 +167,37 @@ interface GridField_DataManipulator extends GridFieldComponent {
}
/**
* Sometimes an action isn't enough: you need to provide additional support URLs for the grid.
* These URLs may return user-visible content, for example a pop-up form for editing a record's details,
* or they may be support URLs for front-end functionality.
* For example a URL that will return JSON-formatted data for a javascript grid control.
* Sometimes an action isn't enough: you need to provide additional support
* URLs for the {@link GridField}.
*
* These URLs may return user-visible content, for example a pop-up form for
* editing a record's details, or they may be support URLs for front-end
* functionality.
*
* For example a URL that will return JSON-formatted data for a javascript
* grid control.
*
* @package framework
* @subpackage fields-gridfield
*/
interface GridField_URLHandler extends GridFieldComponent {
/**
* Return URLs to be handled by this grid field, in an array the same form as $url_handlers.
* Handler methods will be called on the component, rather than the grid field.
* Return URLs to be handled by this grid field, in an array the same form
* as $url_handlers.
*
* Handler methods will be called on the component, rather than the
* {@link GridField}.
*/
public function getURLHandlers($gridField);
}
/**
* A component which is used to handle when a grid field is saved into a record.
* A component which is used to handle when a {@link GridField} is saved into
* a record.
*
* @package framework
* @subpackage fields-gridfield
*/
interface GridField_SaveHandler extends GridFieldComponent {

View File

@ -1,21 +1,27 @@
<?php
/**
* Encapsulates a collection of components following the {@link GridFieldComponent} interface.
* While the {@link GridField} itself has some configuration in the form of setters,
* most of the details are dealt with through components.
* Encapsulates a collection of components following the
* {@link GridFieldComponent} interface. While the {@link GridField} itself
* has some configuration in the form of setters, most of the details are
* dealt with through components.
*
* For example, you would add a {@link GridFieldPaginator} component to enable
* pagination on the listed records, and configure it through {@link GridFieldPaginator->setItemsPerPage()}.
* pagination on the listed records, and configure it through
* {@link GridFieldPaginator->setItemsPerPage()}.
*
* In order to reduce the amount of custom code required, the framework provides
* some default configurations for common use cases:
* In order to reduce the amount of custom code required, the framework
* provides some default configurations for common use cases:
*
* - {@link GridFieldConfig_Base} (added by default to GridField)
* - {@link GridFieldConfig_RecordEditor}
* - {@link GridFieldConfig_RelationEditor}
*
* @package framework
* @subpackage fields-gridfield
*/
class GridFieldConfig {
/**
*
* @var ArrayList
*/
protected $components = null;
@ -129,12 +135,15 @@ class GridFieldConfig {
}
/**
* A simple readonly, paginated view of records,
* with sortable and searchable headers.
* A simple readonly, paginated view of records, with sortable and searchable
* headers.
*
* @package framework
* @subpackage fields-gridfield
*/
class GridFieldConfig_Base extends GridFieldConfig {
/**
*
* @param int $itemsPerPage - How many items per page should show up
*/
public function __construct($itemsPerPage=null) {
@ -153,6 +162,9 @@ class GridFieldConfig_Base extends GridFieldConfig {
/**
* Allows viewing readonly details of individual records.
*
* @package framework
* @subpackage fields-gridfield
*/
class GridFieldConfig_RecordViewer extends GridFieldConfig_Base {
@ -166,7 +178,8 @@ class GridFieldConfig_RecordViewer extends GridFieldConfig_Base {
}
/**
*
* @package framework
* @subpackage fields-gridfield
*/
class GridFieldConfig_RecordEditor extends GridFieldConfig {
/**
@ -195,22 +208,28 @@ class GridFieldConfig_RecordEditor extends GridFieldConfig {
/**
* Similar to {@link GridFieldConfig_RecordEditor}, but adds features
* to work on has-many or many-many relationships.
* Allows to search for existing records to add to the relationship,
* detach listed records from the relationship (rather than removing them from the database),
* and automatically add newly created records to it.
* Similar to {@link GridFieldConfig_RecordEditor}, but adds features to work
* on has-many or many-many relationships.
*
* Allows to search for existing records to add to the relationship, detach
* listed records from the relationship (rather than removing them from the
* database), and automatically add newly created records to it.
*
* To further configure the field, use {@link getComponentByType()},
* for example to change the field to search.
* To further configure the field, use {@link getComponentByType()}, for
* example to change the field to search.
*
* <code>
* GridFieldConfig_RelationEditor::create()
* ->getComponentByType('GridFieldAddExistingAutocompleter')->setSearchFields('MyField');
* ->getComponentByType('GridFieldAddExistingAutocompleter')
* ->setSearchFields('MyField');
* </code>
*
* @package framework
* @subpackage fields-gridfield
*/
class GridFieldConfig_RelationEditor extends GridFieldConfig {
/**
*
* @param int $itemsPerPage - How many items per page should show up
*/
public function __construct($itemsPerPage=null) {

View File

@ -1,17 +1,20 @@
<?php
/**
*
* @see GridField
*
* @package framework
* @subpackage fields-relational
* @subpackage fields-gridfield
*/
class GridFieldDataColumns implements GridField_ColumnProvider {
/** @var array */
/**
* @var array
*/
public $fieldCasting = array();
/** @var array */
/**
* @var array
*/
public $fieldFormatting = array();
/**

View File

@ -1,24 +1,31 @@
<?php
/**
* This class is a {@link GridField} component that adds a delete action for objects.
* This class is a {@link GridField} component that adds a delete action for
* objects.
*
* This component also supports unlinking a relation instead of deleting the
* object.
*
* This component also supports unlinking a relation instead of deleting the object.
* Use the {@link $removeRelation} property set in the constructor.
*
* <code>
* $action = new GridFieldDeleteAction(); // delete objects permanently
* $action = new GridFieldDeleteAction(true); // removes the relation to object, instead of deleting
*
* // removes the relation to object instead of deleting
* $action = new GridFieldDeleteAction(true);
* </code>
*
* @package framework
* @subpackage gridfield
* @subpackage fields-gridfield
*/
class GridFieldDeleteAction implements GridField_ColumnProvider, GridField_ActionProvider {
/**
* If this is set to true, this actionprovider will remove the object from the list, instead of
* deleting. In the case of a has one, has many or many many list it will uncouple the item from
* the list.
* If this is set to true, this {@link GridField_ActionProvider} will
* remove the object from the list, instead of deleting.
*
* In the case of a has one, has many or many many list it will uncouple
* the item from the list.
*
* @var boolean
*/

View File

@ -1,14 +1,20 @@
<?php
/**
* Provides view and edit forms at GridField-specific URLs.
* Provides view and edit forms at GridField-specific URLs.
*
* These can be placed into pop-ups by an appropriate front-end.
* Usually added to a grid field alongside of {@link GridFieldEditButton}
* which takes care of linking the individual rows to their edit view.
*
* Usually added to a {@link GridField} alongside of a
* {@link GridFieldEditButton} which takes care of linking the
* individual rows to their edit view.
*
* The URLs provided will be off the following form:
* - <FormURL>/field/<GridFieldName>/item/<RecordID>
* - <FormURL>/field/<GridFieldName>/item/<RecordID>/edit
*
* @package framework
* @subpackage fields-gridfield
*/
class GridFieldDetailForm implements GridField_URLHandler {
@ -183,6 +189,10 @@ class GridFieldDetailForm implements GridField_URLHandler {
}
}
/**
* @package framework
* @subpackage fields-gridfield
*/
class GridFieldDetailForm_ItemRequest extends RequestHandler {
/**

View File

@ -1,10 +1,17 @@
<?php
/**
* Provides the entry point to editing a single record presented by the grid.
* Doesn't show an edit view on its own or modifies the record, but rather relies on routing conventions
* established in {@link getColumnContent()}. The default routing applies to
* the {@link GridFieldDetailForm} component, which has to be added separately
* to the grid field configuration.
* Provides the entry point to editing a single record presented by the
* {@link GridField}.
*
* Doesn't show an edit view on its own or modifies the record, but rather
* relies on routing conventions established in {@link getColumnContent()}.
*
* The default routing applies to the {@link GridFieldDetailForm} component,
* which has to be added separately to the {@link GridField} configuration.
*
* @package framework
* @subpackage fields-gridfield
*/
class GridFieldEditButton implements GridField_ColumnProvider {
@ -55,7 +62,7 @@ class GridFieldEditButton implements GridField_ColumnProvider {
}
/**
* Which GridField actions are this component handling
* Which GridField actions are this component handling.
*
* @param GridField $gridField
* @return array
@ -65,10 +72,10 @@ class GridFieldEditButton implements GridField_ColumnProvider {
}
/**
*
* @param GridField $gridField
* @param DataObject $record
* @param string $columnName
*
* @return string - the HTML for the column
*/
public function getColumnContent($gridField, $record, $columnName) {
@ -83,12 +90,13 @@ class GridFieldEditButton implements GridField_ColumnProvider {
}
/**
* Handle the actions and apply any changes to the GridField
* Handle the actions and apply any changes to the GridField.
*
* @param GridField $gridField
* @param string $actionName
* @param mixed $arguments
* @param array $data - form data
*
* @return void
*/
public function handleAction(GridField $gridField, $actionName, $arguments, $data) {

View File

@ -1,12 +1,12 @@
<?php
/**
* @package framework
* @subpackage gridfield
*/
/**
* Adds an "Export list" button to the bottom of a GridField.
* Adds an "Export list" button to the bottom of a {@link GridField}.
*
* @package framework
* @subpackage fields-gridfield
*/
class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler {
/**

View File

@ -1,11 +1,12 @@
<?php
/**
* GridFieldFilterHeader alters the gridfield with some filtering fields in the header of each column
* GridFieldFilterHeader alters the {@link GridField} with some filtering
* fields in the header of each column.
*
* @see GridField
*
* @package framework
* @subpackage fields-relational
* @subpackage fields-gridfield
*/
class GridFieldFilterHeader implements GridField_HTMLProvider, GridField_DataManipulator, GridField_ActionProvider {

View File

@ -1,13 +1,19 @@
<?php
/**
* Adding this class to a {@link GridFieldConfig} of a {@link GridField} adds a footer bar to that field.
* The footer looks just like the {@link GridFieldPaginator} control, except without the pagination controls.
* It only display the "Viewing 1-8 of 8" status text and (optionally) a configurable status message.
* Adding this class to a {@link GridFieldConfig} of a {@link GridField} adds
* a footer bar to that field.
*
* The purpose of this class is to have a footer that can round off GridField without having to use pagination.
* The footer looks just like the {@link GridFieldPaginator} control, except
* without the pagination controls.
*
* It only display the "Viewing 1-8 of 8" status text and (optionally) a
* configurable status message.
*
* The purpose of this class is to have a footer that can round off
* {@link GridField} without having to use pagination.
*
* @package framework
* @subpackage gridfield
* @subpackage fields-gridfield
*/
class GridFieldFooter implements GridField_HTMLProvider {
@ -21,7 +27,9 @@ class GridFieldFooter implements GridField_HTMLProvider {
* @param string $message - a message to display in the footer
*/
public function __construct($message = null) {
if($message) $this->message = $message;
if($message) {
$this->message = $message;
}
}
@ -36,7 +44,12 @@ class GridFieldFooter implements GridField_HTMLProvider {
));
return array(
'footer' => $forTemplate->renderWith('GridFieldFooter', array('Colspan'=>count($gridField->getColumns()))),
'footer' => $forTemplate->renderWith(
'GridFieldFooter',
array(
'Colspan' => count($gridField->getColumns())
)
)
);
}
}

View File

@ -1,10 +1,13 @@
<?php
/**
* Adds a "level up" link to a GridField table, which is useful
* when viewing hierarchical data. Requires the managed record
* to have a "getParent()" method or has_one relationship called "Parent".
* Adds a "level up" link to a GridField table, which is useful when viewing
* hierarchical data. Requires the managed record to have a "getParent()"
* method or has_one relationship called "Parent".
*
* @package framework
* @subpackage fields-gridfield
*/
class GridFieldLevelup extends Object implements GridField_HTMLProvider{
class GridFieldLevelup extends Object implements GridField_HTMLProvider {
/**
* @var integer - the record id of the level up to

View File

@ -4,10 +4,10 @@
* GridFieldPage displays a simple current page count summary.
* E.g. "View 1 - 15 of 32"
*
* Depends on GridFieldPaginator being added to the same gridfield
* Depends on {@link GridFieldPaginator} being added to the {@link GridField}.
*
* @package framework
* @subpackage fields-relational
* @subpackage fields-gridfield
*/
class GridFieldPageCount implements GridField_HTMLProvider {
/**

View File

@ -1,10 +1,10 @@
<?php
/**
* GridFieldPaginator paginates the gridfields list and adds controlls to the
* bottom of the gridfield.
* GridFieldPaginator paginates the {@link GridField} list and adds controls
* to the bottom of the {@link GridField}.
*
* @package framework
* @subpackage fields-relational
* @subpackage fields-gridfield
*/
class GridFieldPaginator implements GridField_HTMLProvider, GridField_DataManipulator, GridField_ActionProvider {

View File

@ -1,11 +1,11 @@
<?php
/**
* Adds an "Print" button to the bottom or top of a GridField.
*
* @package framework
* @subpackage gridfield
* @subpackage fields-gridfield
*/
class GridFieldPrintButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler {
/**

View File

@ -1,11 +1,13 @@
<?php
/**
* GridFieldSortableHeader adds column headers to a gridfield that can also sort the columns
* GridFieldSortableHeader adds column headers to a {@link GridField} that can
* also sort the columns.
*
* @see GridField
*
* @package framework
* @subpackage fields-relational
* @subpackage fields-gridfield
*/
class GridFieldSortableHeader implements GridField_HTMLProvider, GridField_DataManipulator, GridField_ActionProvider {
@ -14,7 +16,9 @@ class GridFieldSortableHeader implements GridField_HTMLProvider, GridField_DataM
*/
protected $throwExceptionOnBadDataType = true;
/** @var array */
/**
* @var array
*/
public $fieldSorting = array();
/**

View File

@ -1,12 +1,16 @@
<?php
/**
* Adding this class to a {@link GridFieldConfig} of a {@link GridField} adds a header title to that field.
* Adding this class to a {@link GridFieldConfig} of a {@link GridField} adds
* a header title to that field.
*
* The header serves to display the name of the data the GridField is showing.
*
* @package framework
* @subpackage gridfield
* @subpackage fields-gridfield
*/
class GridFieldToolbarHeader implements GridField_HTMLProvider {
public function getHTMLFragments( $gridField) {
return array(
'header' => $gridField->renderWith('GridFieldToolbarHeader')

View File

@ -1,9 +1,11 @@
<?php
/**
* A button that allows a user to view readonly details of a record. This is
* disabled by default and intended for use in readonly grid fields.
* disabled by default and intended for use in readonly {@link GridField}
* instances.
*
* @package framework
* @subpackage fields-gridfield
*/
class GridFieldViewButton implements GridField_ColumnProvider {
@ -31,5 +33,4 @@ class GridFieldViewButton implements GridField_ColumnProvider {
public function getColumnMetadata($gridField, $col) {
return array('title' => null);
}
}

View File

@ -1,13 +1,14 @@
<?php
/**
* This class is a snapshot of the current status of a {@link GridField}. It's
* designed to be inserted into a Form as a HiddenField and passed through to
* actions such as the {@link GridField_FormAction}
* This class is a snapshot of the current status of a {@link GridField}.
*
* It's designed to be inserted into a Form as a HiddenField and passed through
* to actions such as the {@link GridField_FormAction}.
*
* @see GridField
*
* @package framework
* @subpackage fields-relational
* @subpackage fields-gridfield
*/
class GridState extends HiddenField {
@ -115,12 +116,13 @@ class GridState extends HiddenField {
}
/**
* Simple set of data, similar to stdClass, but without the notice-level errors.
* Simple set of data, similar to stdClass, but without the notice-level
* errors.
*
* @see GridState
*
* @package framework
* @subpackage fields-relational
* @subpackage fields-gridfield
*/
class GridState_Data {
@ -174,7 +176,7 @@ class GridState_Data {
* @see GridState
*
* @package framework
* @subpackage fields-relational
* @subpackage fields-gridfield
*/
class GridState_Component implements GridField_HTMLProvider {

View File

@ -991,7 +991,10 @@ class DataList extends ViewableData implements SS_List, SS_Filterable, SS_Sortab
*/
public function removeByID($itemID) {
$item = $this->byID($itemID);
if($item) return $item->delete();
if($item) {
return $item->delete();
}
}
/**

View File

@ -1,45 +1,73 @@
<?php
/**
* Representation of a DataModel - a collection of DataLists for each different data type.
* Representation of a DataModel - a collection of DataLists for each different
* data type.
*
* Usage:
*
* <code>
* $model = new DataModel;
* $mainMenu = $model->SiteTree->where('"ParentID" = 0 AND "ShowInMenus" = 1');
* </code>
*
* @package framework
* @subpackage model
*/
class DataModel {
/**
* @var DataModel
*/
protected static $inst;
/**
* @var array $customDataLists
*/
protected $customDataLists = array();
/**
* Get the global DataModel.
*
* @return DataModel
*/
public static function inst() {
if(!self::$inst) self::$inst = new self;
if(!self::$inst) {
self::$inst = new self;
}
return self::$inst;
}
/**
* Set the global DataModel, used when data is requested from static methods.
* Set the global DataModel, used when data is requested from static
* methods.
*
* @return DataModel
*/
public static function set_inst(DataModel $inst) {
self::$inst = $inst;
}
////////////////////////////////////////////////////////////////////////
protected $customDataLists = array();
/**
* @param string
*
* @return DataList
*/
public function __get($class) {
if(isset($this->customDataLists[$class])) {
return clone $this->customDataLists[$class];
} else {
$list = DataList::create($class);
$list->setDataModel($this);
return $list;
}
}
/**
* @param string
* @param DataList
*/
public function __set($class, $item) {
$item = clone $item;
$item->setDataModel($this);

View File

@ -14,7 +14,7 @@
class DataQuery {
/**
* @var String
* @var string
*/
protected $dataClass;
@ -756,11 +756,16 @@ class DataQuery {
/**
* Represents a subgroup inside a WHERE clause in a {@link DataQuery}
*
* Stores the clauses for the subgroup inside a specific {@link SQLQuery} object.
* Stores the clauses for the subgroup inside a specific {@link SQLQuery}
* object.
*
* All non-where methods call their DataQuery versions, which uses the base
* query object.
*
* @package framework
*/
class DataQuery_SubGroup extends DataQuery {
protected $whereQuery;
public function __construct(DataQuery $base, $connective) {
@ -790,6 +795,7 @@ class DataQuery_SubGroup extends DataQuery {
if($filter) {
$this->whereQuery->addWhere($filter);
}
return $this;
}
@ -806,6 +812,7 @@ class DataQuery_SubGroup extends DataQuery {
if($filter) {
$this->whereQuery->addWhereAny($filter);
}
return $this;
}
@ -814,8 +821,14 @@ class DataQuery_SubGroup extends DataQuery {
// We always need to have something so we don't end up with something like '... AND () AND ...'
return '1=1';
}
$sql = DB::getConn()->sqlWhereToString($this->whereQuery->getWhere(), $this->whereQuery->getConnective());
$sql = DB::getConn()->sqlWhereToString(
$this->whereQuery->getWhere(),
$this->whereQuery->getConnective()
);
$sql = preg_replace('[^\s*WHERE\s*]', '', $sql);
return $sql;
}
}

View File

@ -1,9 +1,13 @@
<?php
/**
* Subclass of {@link DataList} representing a has_many relation
* Subclass of {@link DataList} representing a has_many relation.
*
* @package framework
* @subpackage model
*/
class HasManyList extends RelationList {
protected $foreignKey;
/**
@ -18,6 +22,7 @@ class HasManyList extends RelationList {
*/
public function __construct($dataClass, $foreignKey) {
parent::__construct($dataClass);
$this->foreignKey = $foreignKey;
}
@ -36,7 +41,9 @@ class HasManyList extends RelationList {
/**
* Adds the item to this relation.
*
* It does so by setting the relationFilters.
*
* @param $item The DataObject to be added, or its ID
*/
public function add($item) {
@ -66,11 +73,14 @@ class HasManyList extends RelationList {
/**
* Remove an item from this relation.
*
* Doesn't actually remove the item, it just clears the foreign key value.
* @param $itemID The ID of the item to be removed
*
* @param $itemID The ID of the item to be removed.
*/
public function removeByID($itemID) {
$item = $this->byID($itemID);
return $this->remove($item);
}

View File

@ -1,7 +1,10 @@
<?php
/**
* Subclass of {@link DataList} representing a many_many relation
* Subclass of {@link DataList} representing a many_many relation.
*
* @package framework
* @subpackage model
*/
class ManyManyList extends RelationList {

View File

@ -2,9 +2,11 @@
/**
* A DataList that represents a relation.
*
* Adds the notion of a foreign ID that can be optionally set.
*
* @todo Is this additional class really necessary?
* @package framework
* @subpackage model
*/
abstract class RelationList extends DataList {
@ -13,8 +15,10 @@ abstract class RelationList extends DataList {
}
/**
* Returns a copy of this list with the ManyMany relationship linked to the given foreign ID.
* @param $id An ID or an array of IDs.
* Returns a copy of this list with the ManyMany relationship linked to
* the given foreign ID.
*
* @param int|array $id An ID or an array of IDs.
*/
public function forForeignID($id) {
// Turn a 1-element array into a simple value
@ -43,7 +47,9 @@ abstract class RelationList extends DataList {
}
/**
* Returns a where clause that filters the members of this relationship to just the related items
* Returns a where clause that filters the members of this relationship to
* just the related items.
*
* @param $id (optional) An ID or an array of IDs - if not provided, will use the current ids as per getForeignID
*/
abstract protected function foreignIDFilter($id = null);

View File

@ -1,19 +1,23 @@
<?php
/**
* An ArrayList that represents an unsaved relation.
* An {@link ArrayList} that represents an unsaved relation.
*
* has_many and many_many relations cannot be saved until after the DataObject they're
* on has been written. This List pretends to be a RelationList and stores the related
* objects in memory.
* has_many and many_many relations cannot be saved until after the DataObject
* they're on has been written. This List pretends to be a RelationList and
* stores the related objects in memory.
*
* It can store both saved objects (as IDs) or unsaved objects (as instances of
* $dataClass). Unsaved objects are then written when the list is saved into an instance
* of RelationList.
* It can store both saved objects (as IDs) or unsaved objects (as instances
* of $dataClass). Unsaved objects are then written when the list is saved
* into an instance of {@link RelationList}.
*
* Most methods that alter the list of objects throw LogicExceptions.
*
* @package framework
* @subpackage model
*/
class UnsavedRelationList extends ArrayList {
/**
* The DataObject class name that this relation is on
*

View File

@ -1,15 +1,24 @@
<?php
/**
* Format of the Oembed config. Autodiscover allows discovery of all URLs.
* Endpoint set to true means autodiscovery for this specific provider is allowed
* (even if autodiscovery in general has been disabled).
*
* Endpoint set to true means autodiscovery for this specific provider is
* allowed (even if autodiscovery in general has been disabled).
*
* <code>
*
* name: Oembed
* ---
* Oembed:
* providers:
* {pattern}:
* {endpoint}/true
* 'http://*.youtube.com/watch*':
* 'http://www.youtube.com/oembed/'
* autodiscover:
* true/false
* true
* </code>
*
* @package framework
* @subpackage oembed
*/
class Oembed {
@ -178,6 +187,10 @@ class Oembed {
}
}
/**
* @package framework
* @subpackage oembed
*/
class Oembed_Result extends ViewableData {
/**
* JSON data fetched from the Oembed URL.