/forms/gridfield/GridFieldConfig.php

https://github.com/sminnee/silverstripe-framework · PHP · 235 lines · 122 code · 22 blank · 91 comment · 8 complexity · 170707b9fa84eb38172f5df04b369174 MD5 · raw file

  1. <?php
  2. /**
  3. * Encapsulates a collection of components following the {@link GridFieldComponent} interface.
  4. * While the {@link GridField} itself has some configuration in the form of setters,
  5. * most of the details are dealt with through components.
  6. *
  7. * For example, you would add a {@link GridFieldPaginator} component to enable
  8. * pagination on the listed records, and configure it through {@link GridFieldPaginator->setItemsPerPage()}.
  9. *
  10. * In order to reduce the amount of custom code required, the framework provides
  11. * some default configurations for common use cases:
  12. * - {@link GridFieldConfig_Base} (added by default to GridField)
  13. * - {@link GridFieldConfig_RecordEditor}
  14. * - {@link GridFieldConfig_RelationEditor}
  15. */
  16. class GridFieldConfig {
  17. /**
  18. *
  19. * @var ArrayList
  20. */
  21. protected $components = null;
  22. /**
  23. * @param mixed $arguments,... arguments to pass to the constructor
  24. * @return GridFieldConfig
  25. */
  26. public static function create() {
  27. return call_user_func_array('Object::create', array_merge(
  28. array(get_called_class()),
  29. func_get_args()
  30. ));
  31. }
  32. /**
  33. *
  34. */
  35. public function __construct() {
  36. $this->components = new ArrayList();
  37. }
  38. /**
  39. * @param GridFieldComponent $component
  40. * @param string $insertBefore The class of the component to insert this one before
  41. */
  42. public function addComponent(GridFieldComponent $component, $insertBefore = null) {
  43. if($insertBefore) {
  44. $existingItems = $this->getComponents();
  45. $this->components = new ArrayList;
  46. $inserted = false;
  47. foreach($existingItems as $existingItem) {
  48. if(!$inserted && $existingItem instanceof $insertBefore) {
  49. $this->components->push($component);
  50. $inserted = true;
  51. }
  52. $this->components->push($existingItem);
  53. }
  54. if(!$inserted) $this->components->push($component);
  55. } else {
  56. $this->getComponents()->push($component);
  57. }
  58. return $this;
  59. }
  60. /**
  61. * @param GridFieldComponent One or more components
  62. */
  63. public function addComponents() {
  64. $components = func_get_args();
  65. foreach($components as $component) $this->addComponent($component);
  66. return $this;
  67. }
  68. /**
  69. * @param GridFieldComponent $component
  70. * @return GridFieldConfig $this
  71. */
  72. public function removeComponent(GridFieldComponent $component) {
  73. $this->getComponents()->remove($component);
  74. return $this;
  75. }
  76. /**
  77. * @param String Class name or interface
  78. * @return GridFieldConfig $this
  79. */
  80. public function removeComponentsByType($type) {
  81. $components = $this->getComponentsByType($type);
  82. foreach($components as $component) {
  83. $this->removeComponent($component);
  84. }
  85. return $this;
  86. }
  87. /**
  88. * @return ArrayList Of GridFieldComponent
  89. */
  90. public function getComponents() {
  91. if(!$this->components) {
  92. $this->components = new ArrayList();
  93. }
  94. return $this->components;
  95. }
  96. /**
  97. * Returns all components extending a certain class, or implementing a certain interface.
  98. *
  99. * @param String Class name or interface
  100. * @return ArrayList Of GridFieldComponent
  101. */
  102. public function getComponentsByType($type) {
  103. $components = new ArrayList();
  104. foreach($this->components as $component) {
  105. if($component instanceof $type) $components->push($component);
  106. }
  107. return $components;
  108. }
  109. /**
  110. * Returns the first available component with the given class or interface.
  111. *
  112. * @param String ClassName
  113. * @return GridFieldComponent
  114. */
  115. public function getComponentByType($type) {
  116. foreach($this->components as $component) {
  117. if($component instanceof $type) return $component;
  118. }
  119. }
  120. }
  121. /**
  122. * A simple readonly, paginated view of records,
  123. * with sortable and searchable headers.
  124. */
  125. class GridFieldConfig_Base extends GridFieldConfig {
  126. /**
  127. *
  128. * @param int $itemsPerPage - How many items per page should show up
  129. */
  130. public function __construct($itemsPerPage=null) {
  131. $this->addComponent(new GridFieldToolbarHeader());
  132. $this->addComponent($sort = new GridFieldSortableHeader());
  133. $this->addComponent($filter = new GridFieldFilterHeader());
  134. $this->addComponent(new GridFieldDataColumns());
  135. $this->addComponent(new GridFieldPageCount('toolbar-header-right'));
  136. $this->addComponent($pagination = new GridFieldPaginator($itemsPerPage));
  137. $sort->setThrowExceptionOnBadDataType(false);
  138. $filter->setThrowExceptionOnBadDataType(false);
  139. $pagination->setThrowExceptionOnBadDataType(false);
  140. }
  141. }
  142. /**
  143. * Allows viewing readonly details of individual records.
  144. */
  145. class GridFieldConfig_RecordViewer extends GridFieldConfig_Base {
  146. public function __construct($itemsPerPage = null) {
  147. parent::__construct($itemsPerPage);
  148. $this->addComponent(new GridFieldViewButton());
  149. $this->addComponent(new GridFieldDetailForm());
  150. }
  151. }
  152. /**
  153. *
  154. */
  155. class GridFieldConfig_RecordEditor extends GridFieldConfig {
  156. /**
  157. *
  158. * @param int $itemsPerPage - How many items per page should show up
  159. */
  160. public function __construct($itemsPerPage=null) {
  161. $this->addComponent(new GridFieldButtonRow('before'));
  162. $this->addComponent(new GridFieldAddNewButton('buttons-before-left'));
  163. $this->addComponent(new GridFieldToolbarHeader());
  164. $this->addComponent($sort = new GridFieldSortableHeader());
  165. $this->addComponent($filter = new GridFieldFilterHeader());
  166. $this->addComponent(new GridFieldDataColumns());
  167. $this->addComponent(new GridFieldEditButton());
  168. $this->addComponent(new GridFieldDeleteAction());
  169. $this->addComponent(new GridFieldPageCount('toolbar-header-right'));
  170. $this->addComponent($pagination = new GridFieldPaginator($itemsPerPage));
  171. $this->addComponent(new GridFieldDetailForm());
  172. $sort->setThrowExceptionOnBadDataType(false);
  173. $filter->setThrowExceptionOnBadDataType(false);
  174. $pagination->setThrowExceptionOnBadDataType(false);
  175. }
  176. }
  177. /**
  178. * Similar to {@link GridFieldConfig_RecordEditor}, but adds features
  179. * to work on has-many or many-many relationships.
  180. * Allows to search for existing records to add to the relationship,
  181. * detach listed records from the relationship (rather than removing them from the database),
  182. * and automatically add newly created records to it.
  183. *
  184. * To further configure the field, use {@link getComponentByType()},
  185. * for example to change the field to search.
  186. * <code>
  187. * GridFieldConfig_RelationEditor::create()
  188. * ->getComponentByType('GridFieldAddExistingAutocompleter')->setSearchFields('MyField');
  189. * </code>
  190. */
  191. class GridFieldConfig_RelationEditor extends GridFieldConfig {
  192. /**
  193. *
  194. * @param int $itemsPerPage - How many items per page should show up
  195. */
  196. public function __construct($itemsPerPage=null) {
  197. $this->addComponent(new GridFieldButtonRow('before'));
  198. $this->addComponent(new GridFieldAddNewButton('buttons-before-left'));
  199. $this->addComponent(new GridFieldAddExistingAutocompleter('buttons-before-left'));
  200. $this->addComponent(new GridFieldToolbarHeader());
  201. $this->addComponent($sort = new GridFieldSortableHeader());
  202. $this->addComponent($filter = new GridFieldFilterHeader());
  203. $this->addComponent(new GridFieldDataColumns());
  204. $this->addComponent(new GridFieldEditButton());
  205. $this->addComponent(new GridFieldDeleteAction(true));
  206. $this->addComponent(new GridFieldPageCount('toolbar-header-right'));
  207. $this->addComponent($pagination = new GridFieldPaginator($itemsPerPage));
  208. $this->addComponent(new GridFieldDetailForm());
  209. $sort->setThrowExceptionOnBadDataType(false);
  210. $filter->setThrowExceptionOnBadDataType(false);
  211. $pagination->setThrowExceptionOnBadDataType(false);
  212. }
  213. }