/src/Terranet/Administrator/Traits/Module/HasColumns.php

https://gitlab.com/indritqoku/laravel-aministrator · PHP · 244 lines · 156 code · 35 blank · 53 comment · 13 complexity · 044d42435c0e4ed76d39f646ad4cbc7f MD5 · raw file

  1. <?php
  2. namespace Terranet\Administrator\Traits\Module;
  3. use Codesleeve\Stapler\ORM\StaplerableInterface;
  4. use Terranet\Translatable\Translatable;
  5. trait HasColumns
  6. {
  7. /**
  8. * Fetch scaffold columns
  9. *
  10. * @return array
  11. */
  12. public function columns()
  13. {
  14. return $this->scaffoldColumns();
  15. }
  16. /**
  17. * Scaffold columns
  18. *
  19. * @return array
  20. */
  21. protected function scaffoldColumns()
  22. {
  23. return $this->decorateAttachments($model = $this->model(), $this->collectColumns($model));
  24. }
  25. /**
  26. * @param $model
  27. * @param $columns
  28. * @return mixed
  29. */
  30. protected function decorateAttachments($model, $columns)
  31. {
  32. if ($model instanceof StaplerableInterface) {
  33. $attachments = $model->getAttachedFiles();
  34. foreach ($columns as $column => $attributes) {
  35. if (array_key_exists($column, $attachments)) {
  36. $columns[$column] = array_merge((array)$attributes, [
  37. 'output' => function ($row) use ($column) {
  38. if (($attachment = $row->$column) && $attachment->originalFilename()) {
  39. if (count($styles = $attachment->getConfig()->styles) > 1) {
  40. $firstStyle = head($styles)->name;
  41. $origStyle = last($styles)->name;
  42. return '<a href="' . url($attachment->url($origStyle)) . '">' .
  43. \admin\output\image($attachment->url($firstStyle), ['width' => 100]) .
  44. '</a>';
  45. }
  46. return link_to($attachment->url(), basename($attachment->url()));
  47. }
  48. return null;
  49. },
  50. ]);
  51. }
  52. }
  53. }
  54. return $columns;
  55. }
  56. /**
  57. * @param $model
  58. * @return array
  59. */
  60. protected function collectColumns($model)
  61. {
  62. $fillable = $model->getFillable();
  63. $columns = array_merge([$model->getKeyName()], $fillable);
  64. $columns = array_flip($columns);
  65. $columns = $this->filterHiddenColumns($model, $columns);
  66. $columns = $this->decorateOutput($columns);
  67. if ($translatable = $this->scaffoldTranslatableColumns($model)) {
  68. $columns = array_merge($columns, $translatable);
  69. }
  70. if ($this->includeDateColumns && ($dates = $model->getDates())) {
  71. $columns = array_merge($columns, [
  72. 'Dates' => ['elements' => $this->decorateOutput(array_flip(
  73. array_diff($dates, array_keys($columns))
  74. ))],
  75. ]);
  76. }
  77. return $columns;
  78. }
  79. /**
  80. * @param $model
  81. * @param $columns
  82. * @return array
  83. */
  84. protected function filterHiddenColumns($model, $columns)
  85. {
  86. $hidden = $model->getHidden();
  87. if (property_exists($this, 'hideColumns')) {
  88. $hidden = array_merge($hidden, (array)$this->hideColumns);
  89. }
  90. return array_unique(array_filter($columns, function ($index, $column) use ($hidden) {
  91. return ! in_array($column, $hidden);
  92. }, ARRAY_FILTER_USE_BOTH));
  93. }
  94. /**
  95. * @param $columns
  96. * @return array
  97. */
  98. protected function decorateOutput($columns)
  99. {
  100. $tableColumns = $this->fetchTableColumns($this->model()->getTable());
  101. foreach ($columns as $column => &$index) {
  102. $index = $this->realColum($column, $tableColumns)
  103. ? $this->decorateByType($tableColumns, $column)
  104. : $this->defaultDecorator($column);
  105. }
  106. return $columns;
  107. }
  108. protected function fetchTableColumns($table)
  109. {
  110. return app('scaffold.schema')->columns($table);
  111. }
  112. /**
  113. * @param $column
  114. * @return array
  115. */
  116. protected function booleanDecorator($column)
  117. {
  118. return
  119. [
  120. 'output' => function ($row) use ($column) {
  121. return \admin\output\boolean($row->{$column});
  122. }
  123. ];
  124. }
  125. /**
  126. * @param $className
  127. * @param $column
  128. * @return array
  129. */
  130. protected function dateTimeDecorator($className, $column)
  131. {
  132. $method = "to" . str_replace('Type', '', $className) . "String";
  133. return
  134. [
  135. 'output' => function ($row) use ($column, $method) {
  136. $callable = [$this->presentValue($row, $column), $method];
  137. return is_callable($callable) ? call_user_func($callable) : $this->presentValue($row, $column);
  138. }
  139. ];
  140. }
  141. protected function defaultDecorator($column)
  142. {
  143. return
  144. [
  145. 'output' => function ($row) use ($column) {
  146. if ($value = $row->$column) {
  147. return $this->presentValue($row, $column);
  148. }
  149. return null;
  150. }
  151. ];
  152. }
  153. /**
  154. * Collect translatable columns
  155. *
  156. * @param $model
  157. * @return array
  158. */
  159. protected function scaffoldTranslatableColumns($model)
  160. {
  161. if ($model instanceof Translatable) {
  162. return array_build($model->getTranslatedAttributes(), function ($index, $column) {
  163. return [
  164. $column,
  165. [
  166. 'output' => function ($row) use ($column) {
  167. if ($value = $row->$column) {
  168. return $this->presentValue($row, $column);
  169. }
  170. return null;
  171. },
  172. ],
  173. ];
  174. });
  175. }
  176. return [];
  177. }
  178. /**
  179. * @param $column
  180. * @param $tableColumns
  181. * @return bool
  182. */
  183. protected function realColum($column, $tableColumns)
  184. {
  185. return array_key_exists($column, $tableColumns);
  186. }
  187. /**
  188. * @param $tableColumns
  189. * @param $column
  190. * @return array
  191. */
  192. protected function decorateByType($tableColumns, $column)
  193. {
  194. $columnInfo = $tableColumns[$column];
  195. switch ($className = class_basename($columnInfo->getType())) {
  196. case 'BooleanType':
  197. return $this->booleanDecorator($column);
  198. case 'TimeType':
  199. case 'DateType':
  200. case 'DateTimeType':
  201. return $this->dateTimeDecorator($className, $column);
  202. }
  203. return $this->defaultDecorator($column);
  204. }
  205. protected function presentValue($row, $column)
  206. {
  207. return \admin\helpers\eloquent_attribute($row, $column);
  208. }
  209. }