/** * @param string $property * @param string $value * @param Project $project * @param bool $noWait * * @return int */ protected function setProperty($property, $value, Project $project, $noWait) { if (!$this->validateValue($property, $value)) { return 1; } $type = $this->getType($property); if ($type === 'boolean' && $value === 'false') { $value = false; } settype($value, $type); $currentValue = $project->getProperty($property); if ($currentValue === $value) { $this->stdErr->writeln("Property <info>{$property}</info> already set as: " . $this->formatter->format($value, $property)); return 0; } $project->ensureFull(); $result = $project->update([$property => $value]); $this->stdErr->writeln("Property <info>{$property}</info> set to: " . $this->formatter->format($value, $property)); $this->api()->clearProjectsCache(); $success = true; if (!$noWait) { $success = ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr, $project); } return $success ? 0 : 1; }
/** * @param string $property * @param string $value * @param Project $project * @param OutputInterface $output * * @return int */ protected function setProperty($property, $value, Project $project, OutputInterface $output) { if (!$this->validateValue($property, $value, $output)) { return 1; } $type = $this->getType($property); if ($type === 'boolean' && $value === 'false') { $value = false; } settype($value, $type); $currentValue = $project->getProperty($property, false); if ($currentValue === $value) { $output->writeln("Property <info>{$property}</info> already set as: " . $project->getProperty($property, false)); return 0; } $project->update(array($property => $value)); $output->writeln("Property <info>{$property}</info> set to: " . $project[$property]); return 0; }
/** * @param string $property * @param string $value * @param Project $project * * @return int */ protected function setProperty($property, $value, Project $project) { if (!$this->validateValue($property, $value)) { return 1; } $type = $this->getType($property); if ($type === 'boolean' && $value === 'false') { $value = false; } settype($value, $type); $currentValue = $project->getProperty($property); if ($currentValue === $value) { $this->stdErr->writeln("Property <info>{$property}</info> already set as: " . $this->formatter->format($value, $property)); return 0; } $project->ensureFull(); $project->update(array($property => $value)); $this->stdErr->writeln("Property <info>{$property}</info> set to: " . $this->formatter->format($value, $property)); $this->getProjects(true); return 0; }
/** * Get the project associated with this subscription. * * @return Project|false */ public function getProject() { if (!$this->hasLink('project') && !$this->isActive()) { throw new \BadMethodCallException('Inactive subscriptions do not have projects.'); } $url = $this->getLink('project'); return Project::get($url, null, $this->client); }
/** * Get a single project at a known location. * * @param string $id The project ID. * @param string $hostname The hostname of the Platform.sh regional API, * e.g. 'eu.platform.sh' or 'us.platform.sh'. * @param bool $https Whether to use HTTPS (default: true). * * @return Project|false */ public function getProjectDirect($id, $hostname, $https = true) { $scheme = $https ? 'https' : 'http'; $collection = "{$scheme}://{$hostname}/api/projects"; return Project::get($id, $collection, $this->connector->getClient()); }
/** * Output a clear explanation for domains API errors. * * @param ClientException $e * @param Project $project * * @throws ClientException If it can't be explained. */ protected function handleApiException(ClientException $e, Project $project) { $response = $e->getResponse(); if ($response !== null && $response->getStatusCode() === 403) { $project->ensureFull(); $data = $project->getData(); if (!$project->hasLink('#manage-domains') && !empty($data['subscription']['plan']) && $data['subscription']['plan'] === 'development') { $this->stdErr->writeln('This project is on a Development plan. Upgrade the plan to add domains.'); } } else { throw $e; } }
/** * Return the user's projects. * * @param boolean $refresh Whether to refresh the list of projects. * * @return Project[] The user's projects. */ public function getProjects($refresh = false) { $this->loadCache(); $cached = isset(self::$cache['projects']); $stale = isset(self::$cache['projectsRefreshed']) && time() - self::$cache['projectsRefreshed'] > $this->projectsTtl; if ($refresh || !$cached || $stale) { $projects = $this->getClient()->getProjects(); foreach ($projects as $id => $project) { self::$cache['projects'][$id] = $project->getData(); self::$cache['projects'][$id]['_endpoint'] = $project->getUri(true); } self::$cache['projectsRefreshed'] = time(); } else { $projects = array(); $connector = $this->getClient(false)->getConnector(); $client = $connector->getClient(); foreach (self::$cache['projects'] as $id => $data) { $projects[$id] = Project::wrap($data, $data['_endpoint'], $client); } } return $projects; }
/** * Return the user's projects. * * @param boolean $refresh Whether to refresh the list of projects. * * @return Project[] The user's projects, keyed by project ID. */ public function getProjects($refresh = false) { $cacheKey = 'projects'; /** @var Project[] $projects */ $projects = array(); if ($refresh || !self::$cache->contains($cacheKey)) { foreach ($this->getClient()->getProjects() as $project) { $projects[$project->id] = $project; } $cachedProjects = array(); foreach ($projects as $id => $project) { $cachedProjects[$id] = $project->getData(); $cachedProjects[$id]['_endpoint'] = $project->getUri(true); $cachedProjects[$id]['git'] = $project->getGitUrl(); } self::$cache->save($cacheKey, $cachedProjects, $this->projectsTtl); } else { $connector = $this->getClient(false)->getConnector(); $client = $connector->getClient(); foreach ((array) self::$cache->fetch($cacheKey) as $id => $data) { $projects[$id] = Project::wrap($data, $data['_endpoint'], $client); } } return $projects; }
/** * Wait for multiple activities to complete. * * A progress bar tracks the state of each activity. The activity log is * only displayed at the end, if an activity failed. * * @param Activity[] $activities * @param OutputInterface $output * @param Project $project * * @return bool * True if all activities succeed, false otherwise. */ public static function waitMultiple(array $activities, OutputInterface $output, Project $project) { $count = count($activities); if ($count == 0) { return true; } elseif ($count === 1) { return self::waitAndLog(reset($activities), $output); } $output->writeln("Waiting for {$count} activities..."); // Initialize a progress bar which will show elapsed time and all of the // activities' states. $bar = new ProgressBar($output); $states = []; foreach ($activities as $activity) { $state = $activity->state; $states[$state] = isset($states[$state]) ? $states[$state] + 1 : 1; } $bar->setPlaceholderFormatterDefinition('states', function () use(&$states) { $format = ''; foreach ($states as $state => $count) { $format .= $count . ' ' . self::formatState($state) . ', '; } return rtrim($format, ', '); }); $bar->setFormat(" [%bar%] %elapsed:6s% (%states%)"); $bar->start(); // Get the most recent created date of each of the activities, as a Unix // timestamp, so that they can be more efficiently refreshed. $mostRecentTimestamp = 0; foreach ($activities as $activity) { $created = strtotime($activity->created_at); $mostRecentTimestamp = $created > $mostRecentTimestamp ? $created : $mostRecentTimestamp; } // Wait for the activities to complete, polling (refreshing) all of them // with a 1 second delay. $complete = 0; while ($complete < $count) { sleep(1); $states = []; $complete = 0; // Get a list of activities on the project. Any of our activities // which are not contained in this list must be refreshed // individually. $projectActivities = $project->getActivities(0, null, $mostRecentTimestamp ?: null); foreach ($activities as $activity) { $refreshed = false; foreach ($projectActivities as $projectActivity) { if ($projectActivity->id === $activity->id) { $activity = $projectActivity; $refreshed = true; break; } } if (!$refreshed && !$activity->isComplete()) { $activity->refresh(); } if ($activity->isComplete()) { $complete++; } $state = $activity->state; $states[$state] = isset($states[$state]) ? $states[$state] + 1 : 1; } $bar->advance(); } $bar->finish(); $output->writeln(''); // Display success or failure messages for each activity. $success = true; foreach ($activities as $activity) { $description = $activity->getDescription(); switch ($activity['result']) { case Activity::RESULT_SUCCESS: $output->writeln("Activity <info>{$activity->id}</info> succeeded: {$description}"); break; case Activity::RESULT_FAILURE: $success = false; $output->writeln("Activity <error>{$activity->id}</error> failed"); // If the activity failed, show the complete log. $output->writeln(" Description: {$description}"); $output->writeln(" Log:"); $output->writeln(preg_replace('/^/m', ' ', $activity->log)); break; } } return $success; }
/** * Load a project user ("project access" record) by email address. * * @param Project $project * @param string $email * * @return ProjectAccess|false */ public function loadProjectAccessByEmail(Project $project, $email) { foreach ($project->getUsers() as $user) { $account = $this->getAccount($user); if ($account['email'] === $email) { return $user; } } return false; }