/** * @Method("GET|POST") * @Route("extension.update", name="api-project.update") * @ParamConverter("site", class="Model:Site", options={"request_path":"site", "query_path":"site", "repository_method":"findOneByUid"}) * @Api("Undine\Form\Type\Api\ExtensionUpdateType") */ public function downloadUpdateFromUrlAction(Site $site, ExtensionUpdateCommand $command) { $updates = $site->getSiteState()->getSiteUpdates(); if (!isset($updates[$command->getExtension()])) { throw $this->createNotFoundException('The extension could not be found.'); } $extension = $command->getExtension(); $url = $updates[$command->getExtension()]->getRecommendedDownloadLink(); $reaction = $this->oxygenClient->sendAsync($site, new ExtensionDownloadUpdateFromUrlAction($extension, $url))->then(function (ExtensionDownloadUpdateFromUrlReaction $reaction) use($site, $extension) { return $this->oxygenClient->sendAsync($site, new ExtensionUpdateAction($extension)); })->then(function (ExtensionUpdateReaction $reaction) use($site) { return $this->oxygenClient->sendAsync($site, new DatabaseListMigrationsAction()); })->then(function (DatabaseListMigrationsReaction $reaction) use($site) { $migrationGenerator = function () use($site, $reaction) { foreach ($reaction->getMigrations() as $migration) { (yield $this->oxygenClient->sendAsync($site, new DatabaseRunMigrationAction($migration['module'], $migration['number'], $migration['dependencyMap']))); } }; return \GuzzleHttp\Promise\each_limit_all($migrationGenerator(), 1); })->wait(); return new ExtensionUpdateResult(); }
public function testEachLimitAllRejectsOnFailure() { $p = [new FulfilledPromise('a'), new RejectedPromise('b')]; $aggregate = \GuzzleHttp\Promise\each_limit_all($p, 2); P\queue()->run(); $this->assertEquals(P\PromiseInterface::REJECTED, $aggregate->getState()); $result = \GuzzleHttp\Promise\inspect($aggregate); $this->assertEquals('b', $result['reason']); }
/** * @param UriInterface $url * @param string $extensionUrl * @param Session $session * * @return Promise * * @rejects RequestException * @rejects FtpCredentialsRequiredException * @rejects FtpCredentialsErrorException */ public function installExtensionFromUrlAsync(UriInterface $url, $extensionUrl, Session $session) { return $this->client->getAsync($url->withQuery(\GuzzleHttp\Psr7\build_query(['q' => 'admin/modules/install'])), [RequestOptions::COOKIES => $session->getCookieJar(), RequestOptions::AUTH => $session->getAuthData()])->then(function (ResponseInterface $response) use($url, $extensionUrl, $session) { $crawler = new Crawler((string) $response->getBody(), (string) $url); try { $form = $crawler->filter('form#update-manager-install-form')->form(['project_url' => $extensionUrl]); } catch (\Exception $e) { throw new InstallExtensionException(InstallExtensionException::FORM_NOT_FOUND); } return $this->client->requestAsync($form->getMethod(), $form->getUri(), [RequestOptions::COOKIES => $session->getCookieJar(), RequestOptions::AUTH => $session->getAuthData(), RequestOptions::HEADERS => ['referer' => $form->getUri()], RequestOptions::FORM_PARAMS => $form->getPhpValues(), ClientOptions::FTP_CREDENTIALS => $session->getFtpCredentials()]); })->then(function (ResponseInterface $response) use($session) { // Drupal uses batch processing when installing extensions, so follow the regular user steps. // Example: <meta http-equiv="Refresh" content="(\d+); URL=http://drupal-1.dev.localhost/authorize.php?batch=1&id=3&op=do_nojs" /> // Send requests while we're getting HTTP-EQUIV refresh. $generateRequest = function (ResponseInterface $response) use($session) { if (!preg_match('<meta http-equiv="Refresh" content="(\\d+); URL=([^"]+)"\\s*/?>', (string) $response->getBody(), $matches)) { return new FulfilledPromise(null); } return $this->client->getAsync(html_entity_decode($matches[2]), [RequestOptions::COOKIES => $session->getCookieJar(), RequestOptions::AUTH => $session->getAuthData(), RequestOptions::DELAY => (int) $matches[1] * 1000]); }; // Dynamic iterator that allows us to push requests as responses are received. $promises = new \ArrayIterator([$generateRequest($response)]); return \GuzzleHttp\Promise\each_limit_all($promises, 1, function (ResponseInterface $response = null) use($promises, $generateRequest) { if ($response !== null) { $promises->append($generateRequest($response)); } // Resolve to null when there are no more responses generated, or more specifically, we get FulfilledPromise(null) from above. }); }); }