Widget.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. <?php
  2. namespace Dcat\Admin\Widgets;
  3. use Dcat\Admin\Admin;
  4. use Dcat\Admin\Contracts\LazyRenderable;
  5. use Dcat\Admin\Grid\LazyRenderable as LazyGrid;
  6. use Dcat\Admin\Layout\Content;
  7. use Dcat\Admin\Support\Helper;
  8. use Dcat\Admin\Traits\HasHtmlAttributes;
  9. use Dcat\Admin\Traits\HasVariables;
  10. use Illuminate\Contracts\Support\Arrayable;
  11. use Illuminate\Contracts\Support\Renderable;
  12. use Illuminate\Support\Arr;
  13. /**
  14. * @method $this class(array|string $class, bool $append = false)
  15. * @method $this style(string $style, bool $append = true)
  16. * @method $this id(string $id = null)
  17. */
  18. abstract class Widget implements Renderable
  19. {
  20. use HasHtmlAttributes;
  21. use HasVariables;
  22. /**
  23. * @var array
  24. */
  25. public static $css = [];
  26. /**
  27. * @var array
  28. */
  29. public static $js = [];
  30. /**
  31. * @var string
  32. */
  33. protected $view;
  34. /**
  35. * @var string
  36. */
  37. protected $script = '';
  38. /**
  39. * @var array
  40. */
  41. protected $options = [];
  42. /**
  43. * @var string
  44. */
  45. protected $elementClass;
  46. /**
  47. * @var bool
  48. */
  49. protected $runScript = true;
  50. /**
  51. * @param mixed ...$params
  52. *
  53. * @return static
  54. */
  55. public static function make(...$params)
  56. {
  57. return new static(...$params);
  58. }
  59. /**
  60. * 符合条件则执行.
  61. *
  62. * @param mixed $value
  63. * @param callable $callback
  64. *
  65. * @return $this|mixed
  66. */
  67. public function when($value, $callback)
  68. {
  69. if ($value) {
  70. return $callback($this, $value) ?: $this;
  71. }
  72. return $this;
  73. }
  74. /**
  75. * 批量设置选项.
  76. *
  77. * @param array $options
  78. *
  79. * @return $this
  80. */
  81. public function options($options = [])
  82. {
  83. if ($options instanceof Arrayable) {
  84. $options = $options->toArray();
  85. }
  86. $this->options = array_merge($this->options, $options);
  87. return $this;
  88. }
  89. /**
  90. * 设置或获取配置选项.
  91. *
  92. * @param string $key
  93. * @param mixed $value
  94. *
  95. * @return $this
  96. */
  97. public function option($key, $value = null)
  98. {
  99. if ($value === null) {
  100. return Arr::get($this->options, $key);
  101. }
  102. Arr::set($this->options, $key, $value);
  103. return $this;
  104. }
  105. /**
  106. * 获取所有选项.
  107. *
  108. * @return array
  109. */
  110. public function getOptions()
  111. {
  112. return $this->options;
  113. }
  114. /**
  115. * 获取视图变量.
  116. *
  117. * @return array
  118. */
  119. public function defaultVariables()
  120. {
  121. return [
  122. 'attributes' => $this->formatHtmlAttributes(),
  123. 'options' => $this->options,
  124. 'class' => $this->getElementClass(),
  125. 'selector' => $this->getElementSelector(),
  126. ];
  127. }
  128. /**
  129. * 收集静态资源.
  130. */
  131. public static function requireAssets()
  132. {
  133. static::$js && Admin::js(static::$js);
  134. static::$css && Admin::css(static::$css);
  135. }
  136. /**
  137. * 运行JS.
  138. */
  139. protected function withScript()
  140. {
  141. if ($this->runScript && $this->script) {
  142. Admin::script($this->script);
  143. }
  144. }
  145. /**
  146. * @param $value
  147. *
  148. * @return string
  149. */
  150. protected function toString($value)
  151. {
  152. return Helper::render($value);
  153. }
  154. /**
  155. * @return string
  156. */
  157. public function render()
  158. {
  159. static::requireAssets();
  160. $this->class($this->getElementClass(), true);
  161. $html = $this->html();
  162. $this->withScript();
  163. return $html;
  164. }
  165. /**
  166. * 获取元素选择器.
  167. *
  168. * @return string
  169. */
  170. public function getElementSelector()
  171. {
  172. return '.'.$this->getElementClass();
  173. }
  174. /**
  175. * @param string $elementClass
  176. *
  177. * @return $this
  178. */
  179. public function setElementClass(string $elementClass)
  180. {
  181. $this->elementClass = $elementClass;
  182. return $this;
  183. }
  184. /**
  185. * @return mixed
  186. */
  187. public function getElementClass()
  188. {
  189. return $this->elementClass ?: str_replace('\\', '_', static::class);
  190. }
  191. /**
  192. * 渲染HTML.
  193. *
  194. * @return string
  195. */
  196. public function html()
  197. {
  198. if (! $this->view) {
  199. return;
  200. }
  201. $result = Admin::resolveHtml(view($this->view, $this->variables()), ['runScript' => $this->runScript]);
  202. $this->script .= $result['script'];
  203. return $result['html'];
  204. }
  205. /**
  206. * 自动调用render方法.
  207. *
  208. * @return void
  209. */
  210. protected function autoRender()
  211. {
  212. Content::composed(function () {
  213. if ($results = Helper::render($this->render())) {
  214. Admin::html($results);
  215. }
  216. });
  217. }
  218. /**
  219. * 设置模板.
  220. *
  221. * @param string $view
  222. */
  223. public function view($view)
  224. {
  225. $this->view = $view;
  226. }
  227. /**
  228. * 设置是否执行JS代码.
  229. *
  230. * @param bool $run
  231. *
  232. * @return $this
  233. */
  234. public function runScript(bool $run = true)
  235. {
  236. $this->runScript = $run;
  237. return $this;
  238. }
  239. /**
  240. * @return string
  241. */
  242. public function getScript()
  243. {
  244. return $this->script;
  245. }
  246. /**
  247. * @param mixed $content
  248. *
  249. * @return Lazy|LazyTable|mixed
  250. */
  251. protected function formatRenderable($content)
  252. {
  253. if ($content instanceof LazyGrid) {
  254. return LazyTable::make($content);
  255. }
  256. if ($content instanceof LazyRenderable) {
  257. return Lazy::make($content);
  258. }
  259. return $content;
  260. }
  261. /**
  262. * @param $method
  263. * @param $parameters
  264. *
  265. * @return $this
  266. */
  267. public function __call($method, $parameters)
  268. {
  269. if ($method === 'style' || $method === 'class') {
  270. $value = $parameters[0] ?? null;
  271. $append = $parameters[1] ?? ($method === 'class' ? false : true);
  272. if (is_array($value)) {
  273. $value = implode(' ', $value);
  274. }
  275. if ($append) {
  276. $original = $this->htmlAttributes[$method] ?? '';
  277. $de = $method === 'style' ? ';' : ' ';
  278. $value = $original.$de.$value;
  279. }
  280. return $this->setHtmlAttribute($method, $value);
  281. }
  282. // 获取属性
  283. if (count($parameters) === 0 || $parameters[0] === null) {
  284. return $this->getHtmlAttribute($method);
  285. }
  286. // 设置属性
  287. $this->setHtmlAttribute($method, $parameters[0]);
  288. return $this;
  289. }
  290. /**
  291. * @param string $key
  292. *
  293. * @return mixed
  294. */
  295. public function __get($key)
  296. {
  297. return $this->htmlAttributes[$key] ?? null;
  298. }
  299. /**
  300. * @param string $key
  301. * @param mixed $value
  302. *
  303. * @return void
  304. */
  305. public function __set($key, $value)
  306. {
  307. $this->htmlAttributes[$key] = $value;
  308. }
  309. /**
  310. * @return mixed
  311. */
  312. public function __toString()
  313. {
  314. return $this->render();
  315. }
  316. }