Update @package, @subpackage labels

Cleanup of framework's use of @package and @subpackage labels and additional of labels for classes missing packages.

Moved all GridField related components to the one name.

Countless spelling fixes, grammar for other comments.

Link ClassName references in file headers.
This commit is contained in:
Will Rossiter 2013-05-20 22:18:07 +12:00
parent 13e632d053
commit ddcfcf7bed
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. * This is essentially an abstract class which should be subclassed.
* See {@link CMSMain} for a good example. * See {@link CMSMain} for a good example.
* *
* @package cms * @package framework
* @subpackage core * @subpackage admin
*/ */
class LeftAndMain extends Controller implements PermissionProvider { class LeftAndMain extends Controller implements PermissionProvider {
@ -1769,6 +1769,9 @@ class LeftAndMainMarkingFilter {
/** /**
* Allow overriding finished state for faux redirects. * Allow overriding finished state for faux redirects.
*
* @package framework
* @subpackage admin
*/ */
class LeftAndMain_HTTPResponse extends SS_HTTPResponse { class LeftAndMain_HTTPResponse extends SS_HTTPResponse {
@ -1788,7 +1791,10 @@ class LeftAndMain_HTTPResponse extends SS_HTTPResponse {
* Wrapper around objects being displayed in a tree. * Wrapper around objects being displayed in a tree.
* Caution: Volatile API. * Caution: Volatile API.
* *
* @todo Implement recursive tree node rendering * @todo Implement recursive tree node rendering.
*
* @package framework
* @subpackage admin
*/ */
class LeftAndMain_TreeNode extends ViewableData { class LeftAndMain_TreeNode extends ViewableData {

View File

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

View File

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

View File

@ -1,14 +1,21 @@
<?php <?php
/** /**
* Handle the X-Pjax header that AJAX responses may provide, returning the * 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. * It also provides better non-JS operation.
* *
* Caution: This API is volatile, and might eventually be replaced by a generic * Caution: This API is volatile, and might eventually be replaced by a generic
* action helper system for controllers. * action helper system for controllers.
*
* @package framework
* @subpackage control
*/ */
class PjaxResponseNegotiator { class PjaxResponseNegotiator {

View File

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

View File

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

View File

@ -1,15 +1,13 @@
<?php <?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 * This is a declared interface, but isn't actually required
* as PHP doesn't really care about types... * as PHP doesn't really care about types...
* *
* @author Marcus Nyeholt <marcus@silverstripe.com.au>
* @package framework * @package framework
* @subpackage injector * @subpackage injector
* @license BSD http://silverstripe.org/BSD-license
*/ */
interface BeforeCallAspect { 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 * - An array
* - A non-array value * - 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. * A property can have a value specified in multiple locations, each of which
* We combine all these values together into a "composite" value using rules that depend on the priority order of the * have a hard coded or explicit priority. We combine all these values together
* locations to give the final value, using these rules: * 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 * - If the value is an array, each array is added to the _beginning_ of the
* order. If a higher priority item has a non-integer key which is the same as a lower priority item, the value of * composite array in ascending priority order. If a higher priority item has
* those items is merged using these same rules, and the result of the merge is located in the same location the * a non-integer key which is the same as a lower priority item, the value of
* higher priority item would be if there was no key clash. Other than in this key-clash situation, within the * those items is merged using these same rules, and the result of the merge
* particular array, order is preserved. * 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 * It is an error to have mixed types of the same named property in different
* necessarily be raised due to optimisations in the lookup code) * 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 * The exception to this is "false-ish" values - empty arrays, empty strings,
* with a false-ish value, the result will be the non-false-ish value regardless of priority. When merging two * 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. * 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 * - The configuration values taken from the YAML files in _config directories
* order, where the item that is latest is highest priority) * (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 * - Any static set on an "additional static source" class (such as an
* property * 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 * At some of these levels you can also set masks. These remove values from the
* point rather than add. They are much simpler. They consist of a list of key / value pairs. When applied against the * composite value at their priority point rather than add. They are much
* current composite value: * 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 * - If the composite value is a sequential array, any member of that array
* removed * 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 * - If the composite value is an associative array, any member of that array
* any pair in the mask is removed * 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 { class Config {
/** /**
* [A marker instance for the "anything" singleton value. Don't access directly, even in-class, always use * A marker instance for the "anything" singleton value. Don't access
* self::anything() * directly, even in-class, always use self::anything()
*
* @var Object * @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 * Get a marker class instance that is used to do a "remove anything with
* $key => Config::anything() to the suppress array * 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 * @return Object
*/ */
static public function anything() { public static function anything() {
if (self::$_anything === null) self::$_anything = new stdClass(); if (self::$_anything === null) {
self::$_anything = new stdClass();
}
return self::$_anything; return self::$_anything;
} }
// -- Source options bitmask -- // -- 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
*/ */
const INHERITED = 0; 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
*/ */
const UNINHERITED = 1; const UNINHERITED = 1;
/** /**
* source options bitmask value - inherit, but stop on the first class that actually provides a value (event an * source options bitmask value - inherit, but stop on the first class
* empty value) * that actually provides a value (event an empty value).
*
* @const * @const
*/ */
const FIRST_SET = 2; 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; const EXCLUDE_EXTRA_SOURCES = 4;
// -- get_value_type response enum -- // -- 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
*/ */
const ISNT_ARRAY = 1; 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
*/ */
const IS_ARRAY = 2; 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 * Get whether the value is an array or not. Used to be more complicated,
* to compare and not just a true/false value * but still nice sugar to have an enum to compare and not just a true /
* false value.
*
* @param $val any - The value * @param $val any - The value
*
* @return int - One of ISNT_ARRAY or IS_ARRAY * @return int - One of ISNT_ARRAY or IS_ARRAY
*/ */
static protected function get_value_type($val) { protected static function get_value_type($val) {
if (is_array($val)) return self::IS_ARRAY; if (is_array($val)) {
return self::IS_ARRAY;
}
return self::ISNT_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 * @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' throw new UnexpectedValueException('Type mismatch in configuration. All values for a particular property must'
. ' contain the same type (or no value at all).'); . ' 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. * Get the current active Config instance.
* *
* Configs should not normally be manually created. * 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 * @return Config
*/ */
static public function inst() { public static function inst() {
if (!self::$instance) self::$instance = new Config(); if (!self::$instance) {
self::$instance = new Config();
}
return self::$instance; return self::$instance;
} }
/** /**
* Set the current active Config instance. * Set the current active {@link Config} instance.
* *
* Configs should not normally be manually created. * {@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 * A use case for replacing the active configuration set would be for
* creating an isolated environment for unit tests.
* *
* @return Config * @return Config
*/ */
static public function set_instance($instance) { public static function set_instance($instance) {
self::$instance = $instance; self::$instance = $instance;
global $_SINGLETONS; global $_SINGLETONS;
$_SINGLETONS['Config'] = $instance; $_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 * You can then make changes to the configuration by calling update and
* value returned by Config::inst(), and then discard those changes later by calling unnest * 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; $current = self::$instance;
$new = clone $current; $new = clone $current;
@ -178,17 +227,21 @@ class Config {
} }
/** /**
* Change the active Config back to the Config instance the current active Config object * Change the active Config back to the Config instance the current active
* was copied from * Config object was copied from.
*/ */
static public function unnest() { public static function unnest() {
self::set_instance(self::$instance->nestedFrom); self::set_instance(self::$instance->nestedFrom);
} }
/**
* @var array
*/
protected $cache; 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() { public function __construct() {
$this->cache = new Config_LRU(); $this->cache = new Config_LRU();
@ -198,21 +251,37 @@ class Config {
$this->cache = clone $this->cache; $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; 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(); 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(); protected $suppresses = array();
/**
* @var array
*/
protected $staticManifests = array(); protected $staticManifests = array();
/**
* @param SS_ConfigStaticManifest
*/
public function pushConfigStaticManifest(SS_ConfigStaticManifest $manifest) { public function pushConfigStaticManifest(SS_ConfigStaticManifest $manifest) {
array_unshift($this->staticManifests, $manifest); array_unshift($this->staticManifests, $manifest);
$this->cache->clean(); $this->cache->clean();
} }
@ -596,6 +665,10 @@ class Config {
} }
/**
* @package framework
* @subpackage core
*/
class Config_LRU { class Config_LRU {
const SIZE = 1000; const SIZE = 1000;
@ -701,25 +774,54 @@ class Config_LRU {
} }
} }
/**
* @package framework
* @subpackage core
*/
class Config_ForClass { class Config_ForClass {
/**
* @var string $class
*/
protected $class; protected $class;
/**
* @param string $class
*/
public function __construct($class) { public function __construct($class) {
$this->class = $class; $this->class = $class;
} }
/**
* @param string $name
*/
public function __get($name) { public function __get($name) {
return Config::inst()->get($this->class, $name); return Config::inst()->get($this->class, $name);
} }
/**
* @param string $name
* @param mixed $val
*/
public function __set($name, $val) { public function __set($name, $val) {
return Config::inst()->update($this->class, $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) { public function get($name, $sourceOptions = 0) {
return Config::inst()->get($this->class, $name, $sourceOptions); return Config::inst()->get($this->class, $name, $sourceOptions);
} }
/**
* @param string
*
* @return Config_ForClass
*/
public function forClass($class) { public function forClass($class) {
return Config::inst()->forClass($class); return Config::inst()->forClass($class);
} }

View File

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

View File

@ -1,14 +1,25 @@
<?php <?php
/** /**
* This class is is responsible for adding objects to another object's has_many and many_many relation, * This class is is responsible for adding objects to another object's has_many
* as defined by the {@link RelationList} passed to the GridField constructor. * and many_many relation, as defined by the {@link RelationList} passed to the
* Objects can be searched through an input field (partially matching one or more fields). * {@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. * 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 class GridFieldAddExistingAutocompleter
implements GridField_HTMLProvider, GridField_ActionProvider, GridField_DataManipulator, GridField_URLHandler { implements GridField_HTMLProvider, GridField_ActionProvider, GridField_DataManipulator, GridField_URLHandler {
/** /**
* Which template to use for rendering * Which template to use for rendering

View File

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

View File

@ -1,14 +1,18 @@
<?php <?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. * 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 * @package framework
* @subpackage gridfield * @subpackage fields-gridfield
*/ */
class GridFieldButtonRow implements GridField_HTMLProvider { class GridFieldButtonRow implements GridField_HTMLProvider {
protected $targetFragment; protected $targetFragment;
public function __construct($targetFragment = 'before') { public function __construct($targetFragment = 'before') {
@ -20,6 +24,7 @@ class GridFieldButtonRow implements GridField_HTMLProvider {
"LeftFragment" => "\$DefineFragment(buttons-{$this->targetFragment}-left)", "LeftFragment" => "\$DefineFragment(buttons-{$this->targetFragment}-left)",
"RightFragment" => "\$DefineFragment(buttons-{$this->targetFragment}-right)", "RightFragment" => "\$DefineFragment(buttons-{$this->targetFragment}-right)",
)); ));
return array( return array(
$this->targetFragment => $data->renderWith('GridFieldButtonRow') $this->targetFragment => $data->renderWith('GridFieldButtonRow')
); );

View File

@ -1,42 +1,58 @@
<?php <?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 { 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 { 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 * Here are 4 built-in fragments: 'header', 'footer', 'before', and
* fragments of their own. * '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 * To specify a new fragment, specify a new fragment by including the
* HTML that you return. Fragment names should only contain alphanumerics, -, and _. * 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 * Fragment names should only contain alphanumerics, -, and _.
* is rendered.
* *
* @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); public function getHTMLFragments($gridField);
} }
/** /**
* Add a new column to the table display body, or modify existing columns. * Add a new column to the table display body, or modify existing columns.
*
* Used once per record/row. * Used once per record/row.
*
* @package framework
* @subpackage fields-gridfield
*/ */
interface GridField_ColumnProvider extends GridFieldComponent { interface GridField_ColumnProvider extends GridFieldComponent {
/** /**
* Modify the list of columns displayed in the table. * 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 GridField $gridField
* @param array - List reference of all column names. * @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, * 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. * but you may choose to define an argument such as ColumnName or RecordID in
* Does not provide interface elements to call those actions, see {@link GridField_FormAction}. * 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 { interface GridField_ActionProvider extends GridFieldComponent {
/** /**
* Return a list of the actions handled by this action provider. * 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 * @param GridField
* @return Array with action identifier strings. * @return Array with action identifier strings.
@ -100,9 +129,10 @@ interface GridField_ActionProvider extends GridFieldComponent {
public function getActions($gridField); public function getActions($gridField);
/** /**
* Handle an action on the given grid field. * 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. * 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 GridField
* @param String Action identifier, see {@link getActions()}. * @param String Action identifier, see {@link getActions()}.
@ -113,14 +143,21 @@ interface GridField_ActionProvider extends GridFieldComponent {
} }
/** /**
* Can modify the data list. * 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 * For example, a paginating component can apply a limit, or a sorting
* how to modify the data list (see {@link GridState}). * 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 { 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 GridField
* @param SS_List * @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. * Sometimes an action isn't enough: you need to provide additional support
* These URLs may return user-visible content, for example a pop-up form for editing a record's details, * URLs for the {@link GridField}.
* 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. * 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 { interface GridField_URLHandler extends GridFieldComponent {
/** /**
* Return URLs to be handled by this grid field, in an array the same form as $url_handlers. * Return URLs to be handled by this grid field, in an array the same form
* Handler methods will be called on the component, rather than the grid field. * as $url_handlers.
*
* Handler methods will be called on the component, rather than the
* {@link GridField}.
*/ */
public function getURLHandlers($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 { interface GridField_SaveHandler extends GridFieldComponent {

View File

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

View File

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

View File

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

View File

@ -1,14 +1,20 @@
<?php <?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. * 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: * The URLs provided will be off the following form:
* - <FormURL>/field/<GridFieldName>/item/<RecordID> * - <FormURL>/field/<GridFieldName>/item/<RecordID>
* - <FormURL>/field/<GridFieldName>/item/<RecordID>/edit * - <FormURL>/field/<GridFieldName>/item/<RecordID>/edit
*
* @package framework
* @subpackage fields-gridfield
*/ */
class GridFieldDetailForm implements GridField_URLHandler { class GridFieldDetailForm implements GridField_URLHandler {
@ -183,6 +189,10 @@ class GridFieldDetailForm implements GridField_URLHandler {
} }
} }
/**
* @package framework
* @subpackage fields-gridfield
*/
class GridFieldDetailForm_ItemRequest extends RequestHandler { class GridFieldDetailForm_ItemRequest extends RequestHandler {
/** /**

View File

@ -1,10 +1,17 @@
<?php <?php
/** /**
* Provides the entry point to editing a single record presented by the grid. * Provides the entry point to editing a single record presented by the
* Doesn't show an edit view on its own or modifies the record, but rather relies on routing conventions * {@link GridField}.
* established in {@link getColumnContent()}. The default routing applies to *
* the {@link GridFieldDetailForm} component, which has to be added separately * Doesn't show an edit view on its own or modifies the record, but rather
* to the grid field configuration. * 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 { 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 * @param GridField $gridField
* @return array * @return array
@ -65,10 +72,10 @@ class GridFieldEditButton implements GridField_ColumnProvider {
} }
/** /**
*
* @param GridField $gridField * @param GridField $gridField
* @param DataObject $record * @param DataObject $record
* @param string $columnName * @param string $columnName
*
* @return string - the HTML for the column * @return string - the HTML for the column
*/ */
public function getColumnContent($gridField, $record, $columnName) { 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 GridField $gridField
* @param string $actionName * @param string $actionName
* @param mixed $arguments * @param mixed $arguments
* @param array $data - form data * @param array $data - form data
*
* @return void * @return void
*/ */
public function handleAction(GridField $gridField, $actionName, $arguments, $data) { public function handleAction(GridField $gridField, $actionName, $arguments, $data) {

View File

@ -1,12 +1,12 @@
<?php <?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 { class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler {
/** /**

View File

@ -1,11 +1,12 @@
<?php <?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 * @see GridField
* *
* @package framework * @package framework
* @subpackage fields-relational * @subpackage fields-gridfield
*/ */
class GridFieldFilterHeader implements GridField_HTMLProvider, GridField_DataManipulator, GridField_ActionProvider { class GridFieldFilterHeader implements GridField_HTMLProvider, GridField_DataManipulator, GridField_ActionProvider {

View File

@ -1,13 +1,19 @@
<?php <?php
/** /**
* Adding this class to a {@link GridFieldConfig} of a {@link GridField} adds a footer bar to that field. * Adding this class to a {@link GridFieldConfig} of a {@link GridField} adds
* The footer looks just like the {@link GridFieldPaginator} control, except without the pagination controls. * a footer bar to that field.
* 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 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 * @package framework
* @subpackage gridfield * @subpackage fields-gridfield
*/ */
class GridFieldFooter implements GridField_HTMLProvider { class GridFieldFooter implements GridField_HTMLProvider {
@ -21,7 +27,9 @@ class GridFieldFooter implements GridField_HTMLProvider {
* @param string $message - a message to display in the footer * @param string $message - a message to display in the footer
*/ */
public function __construct($message = null) { 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( 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 <?php
/** /**
* Adds a "level up" link to a GridField table, which is useful * Adds a "level up" link to a GridField table, which is useful when viewing
* when viewing hierarchical data. Requires the managed record * hierarchical data. Requires the managed record to have a "getParent()"
* to have a "getParent()" method or has_one relationship called "Parent". * 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 * @var integer - the record id of the level up to

View File

@ -4,10 +4,10 @@
* GridFieldPage displays a simple current page count summary. * GridFieldPage displays a simple current page count summary.
* E.g. "View 1 - 15 of 32" * 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 * @package framework
* @subpackage fields-relational * @subpackage fields-gridfield
*/ */
class GridFieldPageCount implements GridField_HTMLProvider { class GridFieldPageCount implements GridField_HTMLProvider {
/** /**

View File

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

View File

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

View File

@ -1,11 +1,13 @@
<?php <?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 * @see GridField
* *
* @package framework * @package framework
* @subpackage fields-relational * @subpackage fields-gridfield
*/ */
class GridFieldSortableHeader implements GridField_HTMLProvider, GridField_DataManipulator, GridField_ActionProvider { class GridFieldSortableHeader implements GridField_HTMLProvider, GridField_DataManipulator, GridField_ActionProvider {
@ -14,7 +16,9 @@ class GridFieldSortableHeader implements GridField_HTMLProvider, GridField_DataM
*/ */
protected $throwExceptionOnBadDataType = true; protected $throwExceptionOnBadDataType = true;
/** @var array */ /**
* @var array
*/
public $fieldSorting = array(); public $fieldSorting = array();
/** /**

View File

@ -1,12 +1,16 @@
<?php <?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. * The header serves to display the name of the data the GridField is showing.
* *
* @package framework * @package framework
* @subpackage gridfield * @subpackage fields-gridfield
*/ */
class GridFieldToolbarHeader implements GridField_HTMLProvider { class GridFieldToolbarHeader implements GridField_HTMLProvider {
public function getHTMLFragments( $gridField) { public function getHTMLFragments( $gridField) {
return array( return array(
'header' => $gridField->renderWith('GridFieldToolbarHeader') 'header' => $gridField->renderWith('GridFieldToolbarHeader')

View File

@ -1,9 +1,11 @@
<?php <?php
/** /**
* A button that allows a user to view readonly details of a record. This is * 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 * @package framework
* @subpackage fields-gridfield
*/ */
class GridFieldViewButton implements GridField_ColumnProvider { class GridFieldViewButton implements GridField_ColumnProvider {
@ -31,5 +33,4 @@ class GridFieldViewButton implements GridField_ColumnProvider {
public function getColumnMetadata($gridField, $col) { public function getColumnMetadata($gridField, $col) {
return array('title' => null); return array('title' => null);
} }
} }

View File

@ -1,13 +1,14 @@
<?php <?php
/** /**
* This class is a snapshot of the current status of a {@link GridField}. It's * This class is a snapshot of the current status of a {@link GridField}.
* designed to be inserted into a Form as a HiddenField and passed through to *
* actions such as the {@link GridField_FormAction} * 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 * @see GridField
* *
* @package framework * @package framework
* @subpackage fields-relational * @subpackage fields-gridfield
*/ */
class GridState extends HiddenField { 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 * @see GridState
* *
* @package framework * @package framework
* @subpackage fields-relational * @subpackage fields-gridfield
*/ */
class GridState_Data { class GridState_Data {
@ -174,7 +176,7 @@ class GridState_Data {
* @see GridState * @see GridState
* *
* @package framework * @package framework
* @subpackage fields-relational * @subpackage fields-gridfield
*/ */
class GridState_Component implements GridField_HTMLProvider { 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) { public function removeByID($itemID) {
$item = $this->byID($itemID); $item = $this->byID($itemID);
if($item) return $item->delete();
if($item) {
return $item->delete();
}
} }
/** /**

View File

@ -1,45 +1,73 @@
<?php <?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: * Usage:
* * <code>
* $model = new DataModel; * $model = new DataModel;
* $mainMenu = $model->SiteTree->where('"ParentID" = 0 AND "ShowInMenus" = 1'); * $mainMenu = $model->SiteTree->where('"ParentID" = 0 AND "ShowInMenus" = 1');
* </code>
*
* @package framework
* @subpackage model
*/ */
class DataModel { class DataModel {
/**
* @var DataModel
*/
protected static $inst; protected static $inst;
/**
* @var array $customDataLists
*/
protected $customDataLists = array();
/** /**
* Get the global DataModel. * Get the global DataModel.
*
* @return DataModel
*/ */
public static function inst() { public static function inst() {
if(!self::$inst) self::$inst = new self; if(!self::$inst) {
self::$inst = new self;
}
return self::$inst; 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) { public static function set_inst(DataModel $inst) {
self::$inst = $inst; self::$inst = $inst;
} }
//////////////////////////////////////////////////////////////////////// /**
* @param string
protected $customDataLists = array(); *
* @return DataList
*/
public function __get($class) { public function __get($class) {
if(isset($this->customDataLists[$class])) { if(isset($this->customDataLists[$class])) {
return clone $this->customDataLists[$class]; return clone $this->customDataLists[$class];
} else { } else {
$list = DataList::create($class); $list = DataList::create($class);
$list->setDataModel($this); $list->setDataModel($this);
return $list; return $list;
} }
} }
/**
* @param string
* @param DataList
*/
public function __set($class, $item) { public function __set($class, $item) {
$item = clone $item; $item = clone $item;
$item->setDataModel($this); $item->setDataModel($this);

View File

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

View File

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

View File

@ -1,7 +1,10 @@
<?php <?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 { class ManyManyList extends RelationList {

View File

@ -2,9 +2,11 @@
/** /**
* A DataList that represents a relation. * A DataList that represents a relation.
*
* Adds the notion of a foreign ID that can be optionally set. * 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 { 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. * Returns a copy of this list with the ManyMany relationship linked to
* @param $id An ID or an array of IDs. * the given foreign ID.
*
* @param int|array $id An ID or an array of IDs.
*/ */
public function forForeignID($id) { public function forForeignID($id) {
// Turn a 1-element array into a simple value // 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 * @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); abstract protected function foreignIDFilter($id = null);

View File

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

View File

@ -1,15 +1,24 @@
<?php <?php
/** /**
* Format of the Oembed config. Autodiscover allows discovery of all URLs. * 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: * Oembed:
* providers: * providers:
* {pattern}: * 'http://*.youtube.com/watch*':
* {endpoint}/true * 'http://www.youtube.com/oembed/'
* autodiscover: * autodiscover:
* true/false * true
* </code>
*
* @package framework
* @subpackage oembed
*/ */
class Oembed { class Oembed {
@ -178,6 +187,10 @@ class Oembed {
} }
} }
/**
* @package framework
* @subpackage oembed
*/
class Oembed_Result extends ViewableData { class Oembed_Result extends ViewableData {
/** /**
* JSON data fetched from the Oembed URL. * JSON data fetched from the Oembed URL.