Widget.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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(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. $html = $this->html();
  161. $this->withScript();
  162. return $html;
  163. }
  164. /**
  165. * 获取元素选择器.
  166. *
  167. * @return string
  168. */
  169. public function getElementSelector()
  170. {
  171. return '.'.$this->getElementClass();
  172. }
  173. /**
  174. * @param string $elementClass
  175. *
  176. * @return $this
  177. */
  178. public function setElementClass(string $elementClass)
  179. {
  180. $this->elementClass = $elementClass;
  181. return $this;
  182. }
  183. /**
  184. * @return mixed
  185. */
  186. public function getElementClass()
  187. {
  188. return $this->elementClass ?: str_replace('\\', '_', static::class);
  189. }
  190. /**
  191. * 渲染HTML.
  192. *
  193. * @return string
  194. */
  195. public function html()
  196. {
  197. if (! $this->view) {
  198. return;
  199. }
  200. $result = Admin::resolveHtml(view($this->view, $this->variables()), ['runScript' => $this->runScript]);
  201. $this->script .= $result['script'];
  202. return $result['html'];
  203. }
  204. /**
  205. * 自动调用render方法.
  206. *
  207. * @return void
  208. */
  209. protected function autoRender()
  210. {
  211. Content::composed(function () {
  212. if ($results = Helper::render($this->render())) {
  213. Admin::html($results);
  214. }
  215. });
  216. }
  217. /**
  218. * 设置模板.
  219. *
  220. * @param string $view
  221. */
  222. public function view($view)
  223. {
  224. $this->view = $view;
  225. }
  226. /**
  227. * 设置是否执行JS代码.
  228. *
  229. * @param bool $run
  230. *
  231. * @return $this
  232. */
  233. public function runScript(bool $run = true)
  234. {
  235. $this->runScript = $run;
  236. return $this;
  237. }
  238. /**
  239. * @return string
  240. */
  241. public function getScript()
  242. {
  243. return $this->script;
  244. }
  245. /**
  246. * @param mixed $content
  247. *
  248. * @return Lazy|LazyTable|mixed
  249. */
  250. protected function formatRenderable($content)
  251. {
  252. if ($content instanceof LazyGrid) {
  253. return LazyTable::make($content);
  254. }
  255. if ($content instanceof LazyRenderable) {
  256. return Lazy::make($content);
  257. }
  258. return $content;
  259. }
  260. /**
  261. * @param $method
  262. * @param $parameters
  263. *
  264. * @return $this
  265. */
  266. public function __call($method, $parameters)
  267. {
  268. if ($method === 'style' || $method === 'class') {
  269. $value = $parameters[0] ?? null;
  270. $append = $parameters[1] ?? ($method === 'class' ? false : true);
  271. if ($append) {
  272. $original = $this->htmlAttributes[$method] ?? '';
  273. $de = $method === 'style' ? ';' : ' ';
  274. $value = $original.$de.$value;
  275. }
  276. return $this->setHtmlAttribute($method, $value);
  277. }
  278. // 获取属性
  279. if (count($parameters) === 0 || $parameters[0] === null) {
  280. return $this->getHtmlAttribute($method);
  281. }
  282. // 设置属性
  283. $this->setHtmlAttribute($method, $parameters[0]);
  284. return $this;
  285. }
  286. /**
  287. * @param string $key
  288. *
  289. * @return mixed
  290. */
  291. public function __get($key)
  292. {
  293. return $this->htmlAttributes[$key] ?? null;
  294. }
  295. /**
  296. * @param string $key
  297. * @param mixed $value
  298. *
  299. * @return void
  300. */
  301. public function __set($key, $value)
  302. {
  303. $this->htmlAttributes[$key] = $value;
  304. }
  305. /**
  306. * @return mixed
  307. */
  308. public function __toString()
  309. {
  310. return $this->render();
  311. }
  312. }