Filter.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. <?php
  2. namespace Dcat\Admin\Grid\Column;
  3. use Dcat\Admin\Grid\Column;
  4. use Dcat\Admin\Grid\Model;
  5. use Dcat\Admin\Support\Helper;
  6. use Dcat\Laravel\Database\WhereHasInServiceProvider;
  7. use Illuminate\Contracts\Support\Renderable;
  8. use Illuminate\Support\Arr;
  9. use Illuminate\Support\Str;
  10. abstract class Filter implements Renderable
  11. {
  12. /**
  13. * @var string|array
  14. */
  15. protected $class;
  16. /**
  17. * @var Column
  18. */
  19. protected $parent;
  20. /**
  21. * @var string
  22. */
  23. protected $columnName;
  24. /**
  25. * @var \Closure[]
  26. */
  27. protected $resolvings = [];
  28. /**
  29. * @var bool
  30. */
  31. protected $display = true;
  32. /**
  33. * @param Column $column
  34. */
  35. public function setParent(Column $column)
  36. {
  37. $this->parent = $column;
  38. $this->parent->grid()->fetching(function () {
  39. $this->addResetButton();
  40. $this->parent->grid()->model()->treeUrlWithoutQuery(
  41. $this->getQueryName()
  42. );
  43. });
  44. foreach ($this->resolvings as $closure) {
  45. $closure($this);
  46. }
  47. }
  48. /**
  49. * @return Column
  50. */
  51. public function parent()
  52. {
  53. return $this->parent;
  54. }
  55. /**
  56. * @param \Closure $callback
  57. *
  58. * @return $this
  59. */
  60. public function resolving(\Closure $callback)
  61. {
  62. $this->resolvings[] = $callback;
  63. return $this;
  64. }
  65. /**
  66. * @param string $name
  67. *
  68. * @return $this
  69. */
  70. public function setColumnName(string $name)
  71. {
  72. $this->columnName = $name;
  73. return $this;
  74. }
  75. /**
  76. * Get column name.
  77. *
  78. * @return string
  79. */
  80. public function getColumnName()
  81. {
  82. return str_replace(['.', '->'], '_', $this->getOriginalColumnName());
  83. }
  84. /**
  85. * @return mixed
  86. */
  87. public function getOriginalColumnName()
  88. {
  89. return $this->columnName ?: $this->parent->getName();
  90. }
  91. /**
  92. * @return string
  93. */
  94. public function getQueryName()
  95. {
  96. return $this->parent->grid()->getName().
  97. '_filter_'.
  98. $this->getColumnName();
  99. }
  100. /**
  101. * Get filter value of this column.
  102. *
  103. * @param string $default
  104. *
  105. * @return array|\Illuminate\Http\Request|string
  106. */
  107. public function value($default = '')
  108. {
  109. return request($this->getQueryName(), $default);
  110. }
  111. /**
  112. * @param mixed $model
  113. * @param string $query
  114. * @param mixed array $params
  115. *
  116. * @return void
  117. */
  118. protected function withQuery($model, string $query, array $params)
  119. {
  120. $column = $this->getOriginalColumnName();
  121. if (! Str::contains($column, '.')) {
  122. $model->$query($column, ...$params);
  123. return;
  124. }
  125. $this->withRelationQuery($model, $query, $params);
  126. }
  127. /**
  128. * @param mixed $model
  129. * @param string $query
  130. * @param mixed ...$params
  131. *
  132. * @return void
  133. */
  134. protected function withRelationQuery($model, string $query, array $params)
  135. {
  136. $column = $this->getOriginalColumnName();
  137. $relation = substr($column, 0, strrpos($column, '.'));
  138. array_unshift($params, Arr::last(explode('.', $column)));
  139. // 增加对whereHasIn的支持
  140. $method = class_exists(WhereHasInServiceProvider::class) ? 'whereHasIn' : 'whereHas';
  141. $model->$method($relation, function ($relation) use ($params, $query) {
  142. $relation->$query(...$params);
  143. });
  144. }
  145. /**
  146. * Add reset button.
  147. */
  148. protected function addResetButton()
  149. {
  150. $value = $this->value();
  151. if ($value === '' || $value === null) {
  152. return;
  153. }
  154. $style = $this->shouldDisplay() ? 'style=\'margin:3px 14px\'' : '';
  155. return $this->parent->addHeader(
  156. "&nbsp;<a class='feather icon-rotate-ccw' href='{$this->urlWithoutFilter()}' {$style}></a>"
  157. );
  158. }
  159. /**
  160. * Get form action url.
  161. *
  162. * @return string
  163. */
  164. public function formAction()
  165. {
  166. return Helper::fullUrlWithoutQuery([
  167. $this->getQueryName(),
  168. $this->getColumnName(),
  169. $this->parent->grid()->model()->getPageName(),
  170. '_pjax',
  171. ]);
  172. }
  173. /**
  174. * @return string
  175. */
  176. protected function urlWithoutFilter()
  177. {
  178. return Helper::fullUrlWithoutQuery([
  179. $this->getQueryName(),
  180. ]);
  181. }
  182. /**
  183. * @param string $key
  184. *
  185. * @return array|null|string
  186. */
  187. protected function trans($key)
  188. {
  189. return __("admin.{$key}");
  190. }
  191. /**
  192. * @param bool $value
  193. *
  194. * @return $this
  195. */
  196. public function display(bool $value)
  197. {
  198. $this->display = $value;
  199. return $this;
  200. }
  201. /**
  202. * @return $this
  203. */
  204. public function hide()
  205. {
  206. return $this->display(false);
  207. }
  208. /**
  209. * @return bool
  210. */
  211. public function shouldDisplay()
  212. {
  213. return $this->display;
  214. }
  215. /**
  216. * Add a query binding.
  217. *
  218. * @param mixed $value
  219. * @param Model $model
  220. */
  221. public function addBinding($value, Model $model)
  222. {
  223. //
  224. }
  225. /**
  226. * {@inheritdoc}
  227. */
  228. public function render()
  229. {
  230. //
  231. }
  232. /**
  233. * @param array ...$params
  234. *
  235. * @return static
  236. */
  237. public static function make(...$params)
  238. {
  239. return new static(...$params);
  240. }
  241. }