PluginServiceProvider.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * Author: 芸众商城 www.yunzshop.com
  5. * Date: 01/03/2017
  6. * Time: 21:33
  7. */
  8. namespace app\common\providers;
  9. use app\common\helpers\Cache;
  10. use app\common\services\Plugin;
  11. use app\common\events;
  12. use Illuminate\Support\Str;
  13. use app\common\services\PluginManager;
  14. use Illuminate\Support\ServiceProvider;
  15. class PluginServiceProvider extends ServiceProvider
  16. {
  17. /**
  18. * Bootstrap any application services.
  19. *
  20. * @return void
  21. */
  22. public function boot()
  23. {
  24. /**
  25. * @var PluginManager $plugins
  26. */
  27. if (strpos(request()->path(), 'install')) {
  28. return;
  29. }
  30. // store paths of class files of plugins
  31. $srcPaths = [];
  32. $loader = $this->app->make('translation.loader');
  33. // make view instead of view.finder since the finder is defined as not a singleton
  34. $finder = $this->app->make('view');
  35. $this->registerPluginCallbackListener();
  36. $plugins = app('plugins')->getEnabledPlugins();
  37. foreach ($plugins as $plugin) {
  38. // always add paths of translation files for namespace hints
  39. $loader->addNamespace($plugin->getNameSpace(), $plugin->getPath() . "/lang");
  40. $srcPaths[$plugin->getNameSpace()] = $plugin->getPath() . "/src";
  41. // add paths of views
  42. $finder->addNamespace($plugin->getNameSpace(), $plugin->getPath() . "/views");
  43. }
  44. $this->registerClassAutoloader($srcPaths);
  45. foreach ($plugins as $plugin) {
  46. $plugin->app()->init();
  47. }
  48. }
  49. protected function registerPluginCallbackListener()
  50. {
  51. \Event::listen([
  52. events\PluginWasEnabled::class,
  53. events\PluginWasDeleted::class,
  54. events\PluginWasDisabled::class,
  55. ], function ($event) {
  56. // call callback functions of plugin
  57. if (file_exists($filename = $event->plugin->getPath() . "/callbacks.php")) {
  58. $callbacks = require $filename;
  59. $callback = array_get($callbacks, get_class($event));
  60. return $callback ? app()->call($callback, ['plugins'=>$event->plugin]) : null;
  61. }
  62. });
  63. }
  64. /**
  65. * Register any application services.
  66. *
  67. * @return void
  68. */
  69. public function register()
  70. {
  71. $this->app->singleton('plugins', PluginManager::class);
  72. }
  73. /**
  74. * Register class autoloader for plugins.
  75. *
  76. * @return void
  77. */
  78. protected function registerClassAutoloader($paths)
  79. {
  80. spl_autoload_register(function ($class) use ($paths) {
  81. if (!(mb_strpos($class, 'Yunshop') === 0)) {
  82. return false;
  83. }
  84. // traverse in registered plugin paths
  85. foreach ((array)array_keys($paths) as $namespace) {
  86. if ($namespace != '' && mb_strpos($class, $namespace) === 0) {
  87. // parse real file path
  88. $path = $paths[$namespace] . Str::replaceFirst($namespace, '', $class) . ".php";
  89. $path = str_replace('\\', '/', $path);
  90. if (file_exists($path)) {
  91. // include class file if it exists
  92. include $path;
  93. return true;
  94. }
  95. }
  96. }
  97. return false;
  98. });
  99. }
  100. }