Chris@13: getLatest(), '>='); Chris@13: } Chris@13: Chris@13: /** Chris@13: * @return string Chris@13: */ Chris@13: public function getLatest() Chris@13: { Chris@13: if (!isset($this->latest)) { Chris@13: $this->setLatest($this->getVersionFromTag()); Chris@13: } Chris@13: Chris@13: return $this->latest; Chris@13: } Chris@13: Chris@13: /** Chris@13: * @param string $version Chris@13: */ Chris@13: public function setLatest($version) Chris@13: { Chris@13: $this->latest = $version; Chris@13: } Chris@13: Chris@13: /** Chris@13: * @return string|null Chris@13: */ Chris@13: private function getVersionFromTag() Chris@13: { Chris@13: $contents = $this->fetchLatestRelease(); Chris@13: if (!$contents || !isset($contents->tag_name)) { Chris@13: throw new \InvalidArgumentException('Unable to check for updates'); Chris@13: } Chris@13: $this->setLatest($contents->tag_name); Chris@13: Chris@13: return $this->getLatest(); Chris@13: } Chris@13: Chris@13: /** Chris@13: * Set to public to make testing easier. Chris@13: * Chris@13: * @return mixed Chris@13: */ Chris@13: public function fetchLatestRelease() Chris@13: { Chris@17: $context = \stream_context_create([ Chris@13: 'http' => [ Chris@13: 'user_agent' => 'PsySH/' . Shell::VERSION, Chris@13: 'timeout' => 3, Chris@13: ], Chris@13: ]); Chris@13: Chris@17: \set_error_handler(function () { Chris@13: // Just ignore all errors with this. The checker will throw an exception Chris@13: // if it doesn't work :) Chris@13: }); Chris@13: Chris@17: $result = @\file_get_contents(self::URL, false, $context); Chris@13: Chris@17: \restore_error_handler(); Chris@13: Chris@17: return \json_decode($result); Chris@13: } Chris@13: }