PluginManager.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. <?php
  2. namespace app\common\services;
  3. use app\common\events;
  4. use app\common\helpers\Cache;
  5. use Illuminate\Support\Arr;
  6. use Illuminate\Support\Collection;
  7. use Illuminate\Filesystem\Filesystem;
  8. use Illuminate\Contracts\Events\Dispatcher;
  9. use app\common\repositories\OptionRepository;
  10. use Illuminate\Contracts\Foundation\Application;
  11. use Illuminate\Support\Facades\DB;
  12. class PluginManager
  13. {
  14. /**
  15. * @var Application
  16. */
  17. protected $app;
  18. /**
  19. * @var OptionRepository
  20. */
  21. protected $option;
  22. /**
  23. * @var Dispatcher
  24. */
  25. protected $dispatcher;
  26. /**
  27. * @var Filesystem
  28. */
  29. protected $filesystem;
  30. /**
  31. * @var Collection|null
  32. */
  33. protected $plugins;
  34. public function __construct(
  35. Application $app,
  36. OptionRepository $option,
  37. Dispatcher $dispatcher,
  38. Filesystem $filesystem
  39. )
  40. {
  41. $this->app = $app;
  42. $this->option = $option;
  43. $this->dispatcher = $dispatcher;
  44. $this->filesystem = $filesystem;
  45. }
  46. /**
  47. * @return Collection
  48. */
  49. public function getPlugins()
  50. {
  51. if (is_null($this->plugins)) {
  52. $this->plugins = Cache::get('plugins_list');
  53. if (!is_null($this->plugins)) {
  54. return $this->plugins;
  55. }
  56. $plugins = new Collection();
  57. $pluginDirs = $this->filesystem->directories(base_path('plugins'));
  58. if (\YunShop::app()->uniacid || \Setting::$uniqueAccountId) {
  59. foreach ($pluginDirs as $pluginDir) {
  60. if (file_exists($pluginDir . "/package.json")) {
  61. // Instantiates an Plugin object using the package path and package.json file.
  62. $plugin = new Plugin($pluginDir);
  63. // Per default all plugins are installed if they are registered in composer.
  64. $plugin->setInstalled(true);
  65. $plugin->setEnabled($this->isOptionEnable($plugin->name));
  66. $plugins->put($plugin->name, $plugin);
  67. }
  68. }
  69. }else {
  70. foreach ($pluginDirs as $pluginDir) {
  71. if (file_exists($pluginDir . "/package.json")) {
  72. $plugin = new Plugin($pluginDir);
  73. $plugins->put($plugin->name, $plugin);
  74. }
  75. }
  76. }
  77. $this->plugins = $plugins->sortBy(function ($plugin, $name) {
  78. return $plugin->name;
  79. });
  80. Cache::put('plugins_list',$this->plugins,5);
  81. }
  82. return $this->plugins;
  83. }
  84. /**
  85. * Loads an Plugin with all information.
  86. *
  87. * @param string $name
  88. * @return Plugin|null
  89. */
  90. public function getPlugin($name)
  91. {
  92. return $this->getPlugins()->get($name);
  93. }
  94. public function getEnablePlugin($name)
  95. {
  96. return $this->getEnabledPlugins()->get($name);
  97. }
  98. public function getPluginId($name)
  99. {
  100. $pluginIdConfig = array_first(\app\common\modules\shop\ShopConfig::current()->get('plugin'), function ($item) use ($name) {
  101. return $item['name'] == $name;
  102. }, []);
  103. return $pluginIdConfig['id'];
  104. }
  105. public function findPlugin($id)
  106. {
  107. return $this->getPlugins()->first(function (Plugin $plugin) use ($id) {
  108. if ('' === $plugin->getId()) {
  109. return false;
  110. }
  111. return $plugin->getId() == $id;
  112. });
  113. }
  114. /**
  115. * Enables the plugin.
  116. *
  117. * @param string $name
  118. */
  119. public function enable($name)
  120. {
  121. if (!$this->isOptionEnable($name)) {
  122. DB::transaction(function () use ($name) {
  123. $plugin = $this->getPlugin($name);
  124. $enabled = $this->getEnabled();
  125. // $enabled[] = $name;
  126. $this->setEnabled($enabled[$name]['id'], 1, $name);
  127. $plugin->app()->init();
  128. $this->dispatcher->dispatch(new events\PluginWasEnabled($plugin));
  129. });
  130. }
  131. }
  132. /**
  133. * Disables an plugin.
  134. *
  135. * @param string $name
  136. */
  137. public function disable($name)
  138. {
  139. $enabled = $this->getEnabled();
  140. $plugin = $this->getPlugin($name);
  141. $this->option->editDisable($enabled[$name]['id']);
  142. $this->dispatcher->dispatch(new events\PluginWasEnabled($plugin));
  143. }
  144. /**
  145. * 启动插件套餐.
  146. *
  147. * @param string $name
  148. */
  149. public function enableMeal($name)
  150. {
  151. \Log::error("sss5".$name);
  152. DB::transaction(function () use ($name) {
  153. $plugin = $this->getPlugin($name);
  154. $enabled = $this->getEnabled();
  155. $this->setEnabled($enabled[$name]['id'], 1, $name);
  156. $plugin->app()->init();
  157. $this->dispatcher->dispatch(new events\PluginWasEnabled($plugin));
  158. });
  159. }
  160. public function disableMeal($uniacid)
  161. {
  162. DB::table('yz_options')->where('uniacid', $uniacid)->delete();
  163. \app\common\modules\option\OptionRepository::flush();
  164. app('supervisor')->restart();
  165. }
  166. //发放关闭所有套餐后的事件
  167. public function dispatchEvent($name)
  168. {
  169. $plugin = $this->getPlugin($name);
  170. $this->dispatcher->dispatch(new events\PluginWasEnabled($plugin));
  171. }
  172. /**
  173. * Uninstalls an plugin.
  174. *
  175. * @param string $name
  176. */
  177. public function uninstall($name)
  178. {
  179. $plugin = $this->getPlugin($name);
  180. $this->disable($name);
  181. // fire event before deleeting plugin files
  182. // $this->dispatcher->fire(new events\PluginWasDeleted($plugin));
  183. $find = storage_path('/logs/plugin_uninstall.log');
  184. if(!file_exists($find)){
  185. fopen($find,'a');
  186. }
  187. file_put_contents($find, date('Y-m-d H:i:s').'操作员:'. \Auth::guard('admin')->user()->uid.'卸载了插件'.$name.PHP_EOL, FILE_APPEND);
  188. $this->filesystem->deleteDirectory($plugin->getPath());
  189. // refresh plugin list
  190. $this->plugins = null;
  191. }
  192. /**
  193. * Get only enabled plugins.
  194. *
  195. * @return Collection
  196. */
  197. public function getEnabledPlugins($uniacid = null)
  198. {
  199. $only = [];
  200. foreach ($this->getEnabled($uniacid) as $key => $plugin) {
  201. if ($plugin['enabled']) {
  202. $only[] = $key;
  203. }
  204. }
  205. return $this->getPlugins()->only($only);
  206. }
  207. public function getEnableApp($name)
  208. {
  209. return $this->getEnablePlugin($name)->app();
  210. }
  211. /**
  212. * The id's of the enabled plugins.
  213. *
  214. * @return array
  215. */
  216. public function getEnabled($uniacid = null)
  217. {
  218. if ($uniacid == '*') {
  219. return (array)$this->option->all();
  220. }
  221. \YunShop::app()->uniacid = \YunShop::app()->uniacid ?:\Setting::$uniqueAccountId;
  222. $uniacid = $uniacid ?: \YunShop::app()->uniacid;
  223. return (array)$this->option->uniacid($uniacid);
  224. }
  225. /**
  226. * Persist the currently enabled plugins.
  227. *
  228. * @param array $enabled
  229. */
  230. protected function setEnabled($id, $enabled, $name = null)
  231. {
  232. $pluginData = [
  233. 'uniacid' => \YunShop::app()->uniacid,
  234. 'option_name' => $name,
  235. 'option_value' => 'true',
  236. 'enabled' => $enabled,
  237. ];
  238. return $this->option->insertPlugin($pluginData);
  239. }
  240. /**
  241. * Whether the plugin is enabled.
  242. *
  243. * @param $plugin
  244. * @return bool
  245. */
  246. public function isEnabled($pluginName)
  247. {
  248. $plugin = $this->getPlugin($pluginName);
  249. if (!$plugin) {
  250. return false;
  251. }
  252. return $this->isOptionEnable($pluginName);
  253. }
  254. private function isOptionEnable($plugin)
  255. {
  256. $plugins = $this->getEnabled();
  257. return $plugins[$plugin]['enabled'] ?: false;
  258. // return in_array($plugin, $this->getEnabled());
  259. }
  260. /**
  261. * The plugins path.
  262. *
  263. * @return string
  264. */
  265. protected function getPluginsDir()
  266. {
  267. return $this->app->basePath() . '/plugins';
  268. }
  269. public function enTopShow($name, $enable)
  270. {
  271. if (!$this->getPlugin($name)) {
  272. $name = str_replace("_", "-", $name);
  273. }
  274. $enabled = $this->getEnabled();
  275. $this->setTopShow($enabled[$name]['id'], $enable);
  276. }
  277. public function setTopShow($id, $enabled, $name = null)
  278. {
  279. if ($id) {
  280. return $this->option->editTopShowById($id, $enabled);
  281. } else {
  282. $pluginData = [
  283. 'uniacid' => \YunShop::app()->uniacid,
  284. 'option_name' => $name,
  285. 'option_value' => 'true',
  286. 'top_show' => $enabled
  287. ];
  288. return $this->option->insertPlugin($pluginData);
  289. }
  290. }
  291. public function isTopShow($name)
  292. {
  293. $plugins = (array)$this->option->uniacid(\YunShop::app()->uniacid);
  294. if (!$this->getPlugin($name)) {
  295. $name = str_replace("_", "-", $name);
  296. }
  297. return $plugins = $plugins[$name]['top_show'];
  298. }
  299. }