Widget.php 6.4 KB

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