GatheringCrontabEventHook.php 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. <?php
  2. declare(strict_types=1);
  3. namespace SixShop\System\Hook;
  4. use ReflectionClass;
  5. use ReflectionMethod;
  6. use SixShop\Core\Attribute\Cron;
  7. use SixShop\Core\Attribute\Hook;
  8. use SixShop\Core\Helper;
  9. use SixShop\System\Event\CrontabWorkerStartEvent;
  10. use SixShop\System\Event\GetCronJobsEvent;
  11. use SixShop\System\ExtensionManager;
  12. use think\App;
  13. use Workerman\Crontab\Crontab;
  14. use function SixShop\Core\extension_name_list;
  15. class GatheringCrontabEventHook
  16. {
  17. public function __construct(private App $app)
  18. {
  19. }
  20. /**
  21. * @throws \ReflectionException
  22. */
  23. #[Hook(CrontabWorkerStartEvent::class)]
  24. public function onWorkerStart(): void
  25. {
  26. $extensionManager = $this->app->make(ExtensionManager::class);
  27. $event = new GetCronJobsEvent();
  28. foreach (extension_name_list() as $extensionName) {
  29. $extension = $extensionManager->getExtension($extensionName);
  30. if ($extension->available()) {
  31. $cronJobs = $extension->getCronJobs();
  32. foreach ($cronJobs as $cronJobClass) {
  33. $event->push($cronJobClass);
  34. }
  35. }
  36. }
  37. $this->app->event->trigger($event);
  38. foreach ($event as $cronJobClass) {
  39. $ref = new ReflectionClass($cronJobClass);
  40. foreach ($ref->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
  41. $attributes = $method->getAttributes(Cron::class);
  42. foreach ($attributes as $attribute) {
  43. $cronInstance = $attribute->newInstance();
  44. $name = $cronInstance->name ?: $cronJobClass . '@' . $method->getName();
  45. new Crontab($cronInstance->rule, [$this->app->make($cronJobClass), $method->getName()], $name);
  46. }
  47. }
  48. }
  49. }
  50. }