WpCliCheckTrigger.php 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. <?php
  2. namespace YahnisElsts\PluginUpdateChecker\v5p1;
  3. use WP_CLI;
  4. /**
  5. * Triggers an update check when relevant WP-CLI commands are executed.
  6. *
  7. * When WP-CLI runs certain commands like "wp plugin status" or "wp theme list", it calls
  8. * wp_update_plugins() and wp_update_themes() to refresh update information. This class hooks into
  9. * the same commands and triggers an update check when they are executed.
  10. *
  11. * Note that wp_update_plugins() and wp_update_themes() do not perform an update check *every* time
  12. * they are called. They use a context-dependent delay between update checks. Similarly, this class
  13. * calls Scheduler::maybeCheckForUpdates(), which also dynamically decides whether to actually
  14. * run a check. If you want to force an update check, call UpdateChecker::checkForUpdates() instead.
  15. */
  16. class WpCliCheckTrigger {
  17. /**
  18. * @var Scheduler
  19. */
  20. private $scheduler;
  21. /**
  22. * @var string 'plugin' or 'theme'
  23. */
  24. private $componentType;
  25. /**
  26. * @var bool Whether an update check was already triggered during the current request
  27. * or script execution.
  28. */
  29. private $wasCheckTriggered = false;
  30. public function __construct($componentType, Scheduler $scheduler) {
  31. if ( !in_array($componentType, ['plugin', 'theme']) ) {
  32. throw new \InvalidArgumentException('Invalid component type. Must be "plugin" or "theme".');
  33. }
  34. $this->componentType = $componentType;
  35. $this->scheduler = $scheduler;
  36. if ( !defined('WP_CLI') || !class_exists(WP_CLI::class, false) ) {
  37. return; //Nothing to do if WP-CLI is not available.
  38. }
  39. /*
  40. * We can't hook directly into wp_update_plugins(), but we can hook into the WP-CLI
  41. * commands that call it. We'll use the "before_invoke:xyz" hook to trigger update checks.
  42. */
  43. foreach ($this->getRelevantCommands() as $command) {
  44. WP_CLI::add_hook('before_invoke:' . $command, [$this, 'triggerUpdateCheckOnce']);
  45. }
  46. }
  47. private function getRelevantCommands() {
  48. $result = [];
  49. foreach (['status', 'list', 'update'] as $subcommand) {
  50. $result[] = $this->componentType . ' ' . $subcommand;
  51. }
  52. return $result;
  53. }
  54. /**
  55. * Trigger a potential update check once.
  56. *
  57. * @param mixed $input
  58. * @return mixed The input value, unchanged.
  59. * @internal This method is public so that it can be used as a WP-CLI hook callback.
  60. * It should not be called directly.
  61. *
  62. */
  63. public function triggerUpdateCheckOnce($input = null) {
  64. if ( $this->wasCheckTriggered ) {
  65. return $input;
  66. }
  67. $this->wasCheckTriggered = true;
  68. $this->scheduler->maybeCheckForUpdates();
  69. return $input;
  70. }
  71. }