PageRenderTime 51ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/forms/gridfield/GridFieldDataColumns.php

http://github.com/silverstripe/sapphire
PHP | 288 lines | 123 code | 29 blank | 136 comment | 22 complexity | c1b08b6bf11be4a3716a7cdc58fdea46 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT, CC-BY-3.0, GPL-2.0, AGPL-1.0, LGPL-2.1
  1. <?php
  2. /**
  3. * @see GridField
  4. *
  5. * @package forms
  6. * @subpackage fields-gridfield
  7. */
  8. class GridFieldDataColumns implements GridField_ColumnProvider {
  9. /**
  10. * @var array
  11. */
  12. public $fieldCasting = array();
  13. /**
  14. * @var array
  15. */
  16. public $fieldFormatting = array();
  17. /**
  18. * This is the columns that will be visible
  19. *
  20. * @var array
  21. */
  22. protected $displayFields = array();
  23. /**
  24. * Modify the list of columns displayed in the table.
  25. * See {@link GridFieldDataColumns->getDisplayFields()} and {@link GridFieldDataColumns}.
  26. *
  27. * @param GridField $gridField
  28. * @param array - List reference of all column names.
  29. */
  30. public function augmentColumns($gridField, &$columns) {
  31. $baseColumns = array_keys($this->getDisplayFields($gridField));
  32. foreach($baseColumns as $col) {
  33. $columns[] = $col;
  34. }
  35. $columns = array_unique($columns);
  36. }
  37. /**
  38. * Names of all columns which are affected by this component.
  39. *
  40. * @param GridField $gridField
  41. * @return array
  42. */
  43. public function getColumnsHandled($gridField) {
  44. return array_keys($this->getDisplayFields($gridField));
  45. }
  46. /**
  47. * Override the default behaviour of showing the models summaryFields with
  48. * these fields instead
  49. * Example: array( 'Name' => 'Members name', 'Email' => 'Email address')
  50. *
  51. * @param array $fields
  52. */
  53. public function setDisplayFields($fields) {
  54. if(!is_array($fields)) {
  55. throw new InvalidArgumentException('
  56. Arguments passed to GridFieldDataColumns::setDisplayFields() must be an array');
  57. }
  58. $this->displayFields = $fields;
  59. return $this;
  60. }
  61. /**
  62. * Get the DisplayFields
  63. *
  64. * @return array
  65. * @see GridFieldDataColumns::setDisplayFields
  66. */
  67. public function getDisplayFields($gridField) {
  68. if(!$this->displayFields) {
  69. return singleton($gridField->getModelClass())->summaryFields();
  70. }
  71. return $this->displayFields;
  72. }
  73. /**
  74. * Specify castings with fieldname as the key, and the desired casting as value.
  75. * Example: array("MyCustomDate"=>"Date","MyShortText"=>"Text->FirstSentence")
  76. *
  77. * @param array $casting
  78. */
  79. public function setFieldCasting($casting) {
  80. $this->fieldCasting = $casting;
  81. return $this;
  82. }
  83. /**
  84. * @return array
  85. */
  86. public function getFieldCasting() {
  87. return $this->fieldCasting;
  88. }
  89. /**
  90. * Specify custom formatting for fields, e.g. to render a link instead of pure text.
  91. *
  92. * Caution: Make sure to escape special php-characters like in a normal php-statement.
  93. * Example: "myFieldName" => '<a href=\"custom-admin/$ID\">$ID</a>'.
  94. *
  95. * Alternatively, pass a anonymous function, which takes two parameters:
  96. * The value and the original list item.
  97. *
  98. * Formatting is applied after field casting, so if you're modifying the string
  99. * to include further data through custom formatting, ensure it's correctly escaped.
  100. *
  101. * @param array $formatting
  102. */
  103. public function setFieldFormatting($formatting) {
  104. $this->fieldFormatting = $formatting;
  105. return $this;
  106. }
  107. /**
  108. * @return array
  109. */
  110. public function getFieldFormatting() {
  111. return $this->fieldFormatting;
  112. }
  113. /**
  114. * HTML for the column, content of the <td> element.
  115. *
  116. * @param GridField
  117. * @param DataObject - Record displayed in this row
  118. * @param string
  119. * @return string HTML for the column. Return NULL to skip.
  120. */
  121. public function getColumnContent($gridField, $record, $columnName) {
  122. // Find the data column for the given named column
  123. $columns = $this->getDisplayFields($gridField);
  124. $columnInfo = $columns[$columnName];
  125. // Allow callbacks
  126. if(is_array($columnInfo) && isset($columnInfo['callback'])) {
  127. $method = $columnInfo['callback'];
  128. $value = $method($record);
  129. // This supports simple FieldName syntax
  130. } else {
  131. $value = $gridField->getDataFieldValue($record, $columnName);
  132. }
  133. // Turn $value, whatever it is, into a HTML embeddable string
  134. $value = $this->castValue($gridField, $columnName, $value);
  135. // Make any formatting tweaks
  136. $value = $this->formatValue($gridField, $record, $columnName, $value);
  137. // Do any final escaping
  138. $value = $this->escapeValue($gridField, $value);
  139. return $value;
  140. }
  141. /**
  142. * Attributes for the element containing the content returned by {@link getColumnContent()}.
  143. *
  144. * @param GridField $gridField
  145. * @param DataObject $record displayed in this row
  146. * @param string $columnName
  147. * @return array
  148. */
  149. public function getColumnAttributes($gridField, $record, $columnName) {
  150. return array('class' => 'col-' . preg_replace('/[^\w]/', '-', $columnName));
  151. }
  152. /**
  153. * Additional metadata about the column which can be used by other components,
  154. * e.g. to set a title for a search column header.
  155. *
  156. * @param GridField $gridField
  157. * @param string $columnName
  158. * @return array - Map of arbitrary metadata identifiers to their values.
  159. */
  160. public function getColumnMetadata($gridField, $column) {
  161. $columns = $this->getDisplayFields($gridField);
  162. $title = null;
  163. if(is_string($columns[$column])) {
  164. $title = $columns[$column];
  165. } else if(is_array($columns[$column]) && isset($columns[$column]['title'])) {
  166. $title = $columns[$column]['title'];
  167. }
  168. return array(
  169. 'title' => $title,
  170. );
  171. }
  172. /**
  173. * Translate a Object.RelationName.ColumnName $columnName into the value that ColumnName returns
  174. *
  175. * @param DataObject $record
  176. * @param string $columnName
  177. * @return string|null - returns null if it could not found a value
  178. */
  179. protected function getValueFromRelation($record, $columnName) {
  180. $fieldNameParts = explode('.', $columnName);
  181. $tmpItem = clone($record);
  182. for($idx = 0; $idx < sizeof($fieldNameParts); $idx++) {
  183. $methodName = $fieldNameParts[$idx];
  184. // Last mmethod call from $columnName return what that method is returning
  185. if($idx == sizeof($fieldNameParts) - 1) {
  186. return $tmpItem->XML_val($methodName);
  187. }
  188. // else get the object from this $methodName
  189. $tmpItem = $tmpItem->$methodName();
  190. }
  191. return null;
  192. }
  193. /**
  194. * Casts a field to a string which is safe to insert into HTML
  195. *
  196. * @param GridField $gridField
  197. * @param string $fieldName
  198. * @param string $value
  199. * @return string
  200. */
  201. protected function castValue($gridField, $fieldName, $value) {
  202. // If a fieldCasting is specified, we assume the result is safe
  203. if(array_key_exists($fieldName, $this->fieldCasting)) {
  204. $value = $gridField->getCastedValue($value, $this->fieldCasting[$fieldName]);
  205. } else if(is_object($value)) {
  206. // If the value is an object, we do one of two things
  207. if (method_exists($value, 'Nice')) {
  208. // If it has a "Nice" method, call that & make sure the result is safe
  209. $value = Convert::raw2xml($value->Nice());
  210. } else {
  211. // Otherwise call forTemplate - the result of this should already be safe
  212. $value = $value->forTemplate();
  213. }
  214. } else {
  215. // Otherwise, just treat as a text string & make sure the result is safe
  216. $value = Convert::raw2xml($value);
  217. }
  218. return $value;
  219. }
  220. /**
  221. *
  222. * @param GridField $gridField
  223. * @param DataObject $item
  224. * @param string $fieldName
  225. * @param string $value
  226. * @return string
  227. */
  228. protected function formatValue($gridField, $item, $fieldName, $value) {
  229. if(!array_key_exists($fieldName, $this->fieldFormatting)) {
  230. return $value;
  231. }
  232. $spec = $this->fieldFormatting[$fieldName];
  233. if(is_callable($spec)) {
  234. return $spec($value, $item);
  235. } else {
  236. $format = str_replace('$value', "__VAL__", $spec);
  237. $format = preg_replace('/\$([A-Za-z0-9-_]+)/', '$item->$1', $format);
  238. $format = str_replace('__VAL__', '$value', $format);
  239. eval('$value = "' . $format . '";');
  240. return $value;
  241. }
  242. }
  243. /**
  244. * Remove values from a value using FieldEscape setter
  245. *
  246. * @param GridField $gridField
  247. * @param string $value
  248. * @return string
  249. */
  250. protected function escapeValue($gridField, $value) {
  251. if(!$escape = $gridField->FieldEscape) {
  252. return $value;
  253. }
  254. foreach($escape as $search => $replace) {
  255. $value = str_replace($search, $replace, $value);
  256. }
  257. return $value;
  258. }
  259. }