config = $config; $this->configWriter = $configWriter; } /** * Job for checking a new version of EspoCRM. */ public function jobCheckNewVersion() { $config = $this->config; if (!$config->get('adminNotifications') || !$config->get('adminNotificationsNewVersion')) { return true; } $latestRelease = $this->getLatestRelease(); if (empty($latestRelease['version'])) { $this->configWriter->set('latestVersion', $latestRelease['version']); $this->configWriter->save(); return true; } if ($config->get('latestVersion') != $latestRelease['version']) { $this->configWriter->set('latestVersion', $latestRelease['version']); if (!empty($latestRelease['notes'])) { // @todo Create a notification. } $this->configWriter->save(); return true; } if (!empty($latestRelease['notes'])) { // @todo Find and modify notification. } return true; } /** * Job for checking a new version of installed extensions. */ public function jobCheckNewExtensionVersion() { $config = $this->config; if (!$config->get('adminNotifications') || !$config->get('adminNotificationsNewExtensionVersion')) { return true; } $query = $this->entityManager->getQueryBuilder() ->select() ->from('Extension') ->select(['id', 'name', 'version', 'checkVersionUrl']) ->where([ 'deleted' => false, 'isInstalled' => true, ]) ->order(['createdAt']) ->build(); $sth = $this->entityManager->getQueryExecutor()->execute($query); $latestReleases = []; while ($row = $sth->fetch()) { $url = !empty($row['checkVersionUrl']) ? $row['checkVersionUrl'] : null; $extensionName = $row['name']; $latestRelease = $this->getLatestRelease($url, [ 'name' => $extensionName, ]); if (!empty($latestRelease) && !isset($latestRelease['error'])) { $latestReleases[$extensionName] = $latestRelease; } } $latestExtensionVersions = $config->get('latestExtensionVersions', []); $save = false; foreach ($latestReleases as $extensionName => $extensionData) { if (empty($latestExtensionVersions[$extensionName])) { $latestExtensionVersions[$extensionName] = $extensionData['version']; $save = true; continue; } if ($latestExtensionVersions[$extensionName] != $extensionData['version']) { $latestExtensionVersions[$extensionName] = $extensionData['version']; if (!empty($extensionData['notes'])) { //todo: create notification } $save = true; continue; } if (!empty($extensionData['notes'])) { //todo: find and modify notification } } if ($save) { $this->configWriter->set('latestExtensionVersions', $latestExtensionVersions); $this->configWriter->save(); } return true; } protected function getLatestRelease( ?string $url = null, array $requestData = [], string $urlPath = 'release/latest' ): ?array { if (!function_exists('curl_version')) { return null; } $ch = curl_init(); $requestUrl = $url ? trim($url) : base64_decode('aHR0cHM6Ly9zLmVzcG9jcm0uY29tLw=='); $requestUrl = (substr($requestUrl, -1) == '/') ? $requestUrl : $requestUrl . '/'; $requestUrl .= empty($requestData) ? $urlPath . '/' : $urlPath . '/?' . http_build_query($requestData); curl_setopt($ch, CURLOPT_URL, $requestUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); $result = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200) { return null; } $data = json_decode($result, true); if (!is_array($data)) { return null; } return $data; } }