waitMultiple() public static method

A progress bar tracks the state of each activity. The activity log is only displayed at the end, if an activity failed.
public static waitMultiple ( array $activities, Symfony\Component\Console\Output\OutputInterface $output, Platformsh\Client\Model\Project $project ) : boolean
$activities array
$output Symfony\Component\Console\Output\OutputInterface
$project Platformsh\Client\Model\Project
return boolean True if all activities succeed, false otherwise.
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $this->validateInput($input);
     if (!$this->validateDomainInput($input)) {
         return 1;
     }
     $project = $this->getSelectedProject();
     try {
         $this->stdErr->writeln("Adding the domain <info>{$this->domainName}</info>");
         $result = $project->addDomain($this->domainName, $this->sslOptions);
     } catch (ClientException $e) {
         // Catch 409 Conflict errors.
         $response = $e->getResponse();
         if ($response && $response->getStatusCode() === 409) {
             $this->stdErr->writeln("The domain <error>{$this->domainName}</error> already exists on the project.");
             $this->stdErr->writeln("Use <info>domain:delete</info> to delete an existing domain");
         } else {
             $this->handleApiException($e, $project);
         }
         return 1;
     }
     if (!$input->getOption('no-wait')) {
         ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr);
     }
     return 0;
 }
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $this->validateInput($input);
     if (!$this->validateDomainInput($input)) {
         return 1;
     }
     $project = $this->getSelectedProject();
     $domain = $project->getDomain($this->domainName);
     if (!$domain) {
         $this->stdErr->writeln('Domain not found: <error>' . $this->domainName . '</error>');
         return 1;
     }
     $needsUpdate = false;
     foreach (['key' => '', 'certificate' => '', 'chain' => []] as $option => $default) {
         if (empty($this->sslOptions[$option])) {
             $this->sslOptions[$option] = $domain->ssl[$option] ?: $default;
         } elseif ($this->sslOptions[$option] != $domain->ssl[$option]) {
             $needsUpdate = true;
         }
     }
     if (!$needsUpdate) {
         $this->stdErr->writeln('There is nothing to update.');
         return 0;
     }
     $this->stdErr->writeln('Updating the domain <info>' . $this->domainName . '</info>');
     $result = $domain->update(['ssl' => $this->sslOptions]);
     if (!$input->getOption('no-wait')) {
         ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr, $project);
     }
     return 0;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $this->validateInput($input);
     $variableName = $input->getArgument('name');
     $variable = $this->getSelectedEnvironment()->getVariable($variableName);
     if (!$variable) {
         $this->stdErr->writeln("Variable not found: <error>{$variableName}</error>");
         return 1;
     }
     if (!$variable->operationAvailable('delete')) {
         if ($variable->inherited) {
             $this->stdErr->writeln("The variable <error>{$variableName}</error> is inherited," . " so it cannot be deleted from this environment." . "\nYou could override it with the <comment>variable:set</comment> command.");
         } else {
             $this->stdErr->writeln("The variable <error>{$variableName}</error> cannot be deleted");
         }
         return 1;
     }
     $environmentId = $this->getSelectedEnvironment()->id;
     $confirm = $this->getHelper('question')->confirm("Delete the variable <info>{$variableName}</info> from the environment <info>{$environmentId}</info>?", false);
     if (!$confirm) {
         return 1;
     }
     $result = $variable->delete();
     $this->stdErr->writeln("Deleted variable <info>{$variableName}</info>");
     $success = true;
     if (!$result->countActivities()) {
         $this->rebuildWarning();
     } elseif (!$input->getOption('no-wait')) {
         $success = ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr, $this->getSelectedProject());
     }
     return $success ? 0 : 1;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $this->validateInput($input);
     $variableName = $input->getArgument('name');
     $variableValue = $input->getArgument('value');
     $json = $input->getOption('json');
     if ($json && !$this->validateJson($variableValue)) {
         throw new \Exception("Invalid JSON: <error>{$variableValue}</error>");
     }
     // Check whether the variable already exists. If there is no change,
     // quit early.
     $existing = $this->getSelectedEnvironment()->getVariable($variableName);
     if ($existing && $existing->getProperty('value') === $variableValue && $existing->getProperty('is_json') == $json) {
         $this->stdErr->writeln("Variable <info>{$variableName}</info> already set as: {$variableValue}");
         return 0;
     }
     // Set the variable to a new value.
     $result = $this->getSelectedEnvironment()->setVariable($variableName, $variableValue, $json);
     $this->stdErr->writeln("Variable <info>{$variableName}</info> set to: {$variableValue}");
     $success = true;
     if (!$result->countActivities()) {
         $this->rebuildWarning();
     } elseif (!$input->getOption('no-wait')) {
         $success = ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr, $this->getSelectedProject());
     }
     return $success ? 0 : 1;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $this->validateInput($input);
     $project = $this->getSelectedProject();
     $email = $input->getArgument('email');
     $selectedUser = $this->api()->loadProjectAccessByEmail($project, $email);
     if (empty($selectedUser)) {
         $this->stdErr->writeln("User not found: <error>{$email}</error>");
         return 1;
     }
     if ($project->owner === $selectedUser->id) {
         $this->stdErr->writeln(sprintf('The user <error>%s</error> is the owner of the project %s.', $email, $this->api()->getProjectLabel($project, 'error')));
         $this->stdErr->writeln("The project's owner cannot be deleted.");
         return 1;
     }
     /** @var \Platformsh\Cli\Helper\QuestionHelper $questionHelper */
     $questionHelper = $this->getHelper('question');
     if (!$questionHelper->confirm("Are you sure you want to delete the user <info>{$email}</info>?")) {
         return 1;
     }
     $result = $selectedUser->delete();
     $this->stdErr->writeln("User <info>{$email}</info> deleted");
     if (!$input->getOption('no-wait')) {
         ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr, $project);
     }
     // If the user was deleting themselves from the project, then invalidate
     // the projects cache.
     $myUuid = $this->api()->getMyAccount()['uuid'];
     if ($myUuid === $selectedUser->id) {
         $this->api()->clearProjectsCache();
     }
     return 0;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $this->validateInput($input);
     $values = $this->getForm()->resolveOptions($input, $this->stdErr, $this->getHelper('question'));
     $result = $this->getSelectedProject()->addIntegration($values['type'], $values);
     /** @var Integration $integration */
     $integration = $result->getEntity();
     $this->stdErr->writeln("Created integration <info>{$integration->id}</info> (type: {$values['type']})");
     $success = true;
     if (!$input->getOption('no-wait')) {
         $success = ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr);
     }
     $output->writeln($this->formatIntegrationData($integration));
     return $success ? 0 : 1;
 }
 /**
  * @param Environment[]   $environments
  * @param InputInterface  $input
  * @param OutputInterface $output
  *
  * @return bool
  */
 protected function activateMultiple(array $environments, InputInterface $input, OutputInterface $output)
 {
     $count = count($environments);
     $processed = 0;
     // Confirm which environments the user wishes to be activated.
     $process = [];
     $questionHelper = $this->getHelper('question');
     foreach ($environments as $environment) {
         $environmentId = $environment->id;
         if ($environment->isActive()) {
             $output->writeln("The environment <info>{$environmentId}</info> is already active.");
             $count--;
             continue;
         }
         if (!$environment->operationAvailable('activate')) {
             $output->writeln("Operation not available: The environment <error>{$environmentId}</error> can't be activated.");
             continue;
         }
         $question = "Are you sure you want to activate the environment <info>{$environmentId}</info>?";
         if (!$questionHelper->confirm($question, $input, $output)) {
             continue;
         }
         $process[$environmentId] = $environment;
     }
     $activities = [];
     /** @var Environment $environment */
     foreach ($process as $environmentId => $environment) {
         try {
             $activities[] = $environment->activate();
             $processed++;
             $output->writeln("Activating environment <info>{$environmentId}</info>");
         } catch (\Exception $e) {
             $output->writeln($e->getMessage());
         }
     }
     $success = true;
     if ($processed) {
         if (!$input->getOption('no-wait')) {
             $success = ActivityUtil::waitMultiple($activities, $output);
         }
         $this->clearEnvironmentsCache();
     }
     return $processed >= $count && $success;
 }
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $this->validateInput($input);
     $name = $input->getArgument('name');
     $project = $this->getSelectedProject();
     $domain = $project->getDomain($name);
     if (!$domain) {
         $this->stdErr->writeln("Domain not found: <error>{$name}</error>");
         return 1;
     }
     if (!$this->getHelper('question')->confirm("Are you sure you want to delete the domain <info>{$name}</info>?")) {
         return 1;
     }
     $result = $domain->delete();
     $this->stdErr->writeln("The domain <info>{$name}</info> has been deleted.");
     if (!$input->getOption('no-wait')) {
         ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr, $project);
     }
     return 0;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $this->validateInput($input);
     $id = $input->getArgument('id');
     $integration = $this->getSelectedProject()->getIntegration($id);
     if (!$integration) {
         $this->stdErr->writeln("Integration not found: <error>{$id}</error>");
         return 1;
     }
     $type = $integration->getProperty('type');
     $confirmText = "Delete the integration <info>{$id}</info> (type: {$type})?";
     if (!$this->getHelper('question')->confirm($confirmText)) {
         return 1;
     }
     $result = $integration->delete();
     $this->stdErr->writeln("Deleted integration <info>{$id}</info>");
     if (!$input->getOption('no-wait')) {
         ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr, $this->getSelectedProject());
     }
     return 0;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $this->validateInput($input);
     $id = $input->getArgument('id');
     $integration = $this->getSelectedProject()->getIntegration($id);
     if (!$integration) {
         $this->stdErr->writeln("Integration not found: <error>{$id}</error>");
         return 1;
     }
     $values = [];
     $form = $this->getForm();
     $currentValues = $integration->getProperties();
     foreach ($form->getFields() as $key => $field) {
         $value = $field->getValueFromInput($input);
         if ($value !== null && $currentValues[$key] !== $value) {
             $values[$key] = $value;
         }
     }
     if (!$values) {
         $this->stdErr->writeln("No changed values were provided to update");
         return 1;
     }
     // Complete the PATCH request with the current values. This is a
     // workaround: at the moment a PATCH with only the changed values will
     // cause a 500 error.
     foreach ($currentValues as $key => $currentValue) {
         if ($key !== 'id' && !array_key_exists($key, $values)) {
             $values[$key] = $currentValue;
         }
     }
     $result = $integration->update($values);
     $this->stdErr->writeln("Integration <info>{$id}</info> (<info>{$integration->type}</info>) updated");
     $this->displayIntegration($integration, $input, $this->stdErr);
     if (!$input->getOption('no-wait')) {
         ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr, $this->getSelectedProject());
     }
     return 0;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $this->validateInput($input);
     $project = $this->getSelectedProject();
     $email = $input->getArgument('email');
     foreach ($project->getUsers() as $user) {
         if ($this->getAccount($user)['email'] === $email) {
             $selectedUser = $user;
             break;
         }
     }
     if (empty($selectedUser)) {
         $this->stdErr->writeln("User not found: <error>{$email}</error>");
         return 1;
     }
     if ($project->owner === $selectedUser->id) {
         $this->stdErr->writeln("The user <error>{$email}</error> is the owner of the project <error>{$project->title}</error>.");
         $this->stdErr->writeln("The project's owner cannot be deleted.");
         return 1;
     }
     /** @var \Platformsh\Cli\Helper\PlatformQuestionHelper $questionHelper */
     $questionHelper = $this->getHelper('question');
     if (!$questionHelper->confirm("Are you sure you want to delete the user <info>{$email}</info>?", $input, $this->stdErr)) {
         return 1;
     }
     $result = $selectedUser->delete();
     $this->stdErr->writeln("User <info>{$email}</info> deleted");
     if (!$input->getOption('no-wait')) {
         ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr);
     }
     // If the user was deleting themselves from the project, then invalidate
     // the projects cache.
     $account = $this->getClient()->getAccountInfo();
     if ($account['uuid'] === $selectedUser->id) {
         $this->clearProjectsCache();
     }
     return 0;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $level = $input->getOption('level');
     $validLevels = ['project', 'environment'];
     if (!in_array($level, $validLevels)) {
         $this->stdErr->writeln("Invalid level: <error>{$level}</error>");
         return 1;
     }
     $this->validateInput($input, true);
     $project = $this->getSelectedProject();
     $email = $input->getArgument('email');
     foreach ($project->getUsers() as $user) {
         $account = $this->getAccount($user);
         if ($account['email'] === $email) {
             $selectedUser = $user;
             break;
         }
     }
     if (empty($selectedUser)) {
         $this->stdErr->writeln("User not found: <error>{$email}</error>");
         return 1;
     }
     $currentRole = false;
     $environmentAccess = false;
     $validRoles = ProjectAccess::$roles;
     if ($level == 'project') {
         $currentRole = $selectedUser['role'];
     } elseif ($level == 'environment') {
         if (!$this->hasSelectedEnvironment()) {
             $this->stdErr->writeln('You must specify an environment');
             return 1;
         }
         $environment = $this->getSelectedEnvironment();
         $environmentAccesses = $environment->getUsers();
         foreach ($environmentAccesses as $candidate) {
             if ($candidate->user === $selectedUser->id) {
                 $environmentAccess = $candidate;
                 $currentRole = $environmentAccess->role;
                 break;
             }
         }
         $validRoles = EnvironmentAccess::$roles;
     }
     $role = $input->getOption('role');
     if ($role && $role !== 'none' && !in_array($role, $validRoles)) {
         $this->stdErr->writeln("Invalid role: {$role}");
         return 1;
     }
     if ($role && $project->owner === $selectedUser->id) {
         $this->stdErr->writeln("The user <error>{$email}</error> is the owner of the project <error>{$project->title}</error>.");
         $this->stdErr->writeln("You cannot change the role of the project's owner.");
         return 1;
     }
     if ($role === $currentRole || $role === 'none' && $currentRole === false) {
         $this->stdErr->writeln("There is nothing to change");
     } elseif ($role && $level == 'project') {
         $result = $selectedUser->update(['role' => $role]);
         $this->stdErr->writeln("User <info>{$email}</info> updated");
     } elseif ($role && $level == 'environment') {
         $environment = $this->getSelectedEnvironment();
         if ($role == 'none') {
             if ($environmentAccess) {
                 $result = $environmentAccess->delete();
             }
         } elseif ($environmentAccess) {
             $result = $environmentAccess->update(['role' => $role]);
         } else {
             $result = $environment->addUser($selectedUser->id, $role);
         }
         $this->stdErr->writeln("User <info>{$email}</info> updated");
     }
     if (isset($result) && !$input->getOption('no-wait')) {
         ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr);
     }
     if ($input->getOption('pipe')) {
         if ($level == 'project') {
             $output->writeln($selectedUser->role);
         } elseif ($level == 'environment') {
             $environment = $this->getSelectedEnvironment();
             $output->writeln($selectedUser->getEnvironmentRole($environment) ?: 'none');
         }
         return 0;
     }
     $output->writeln("Project role: <info>{$selectedUser->role}</info>");
     if ($this->hasSelectedEnvironment()) {
         $environment = $this->getSelectedEnvironment();
         $environmentAccesses = $environment->getUsers();
         $currentEnvironmentRole = 'none';
         foreach ($environmentAccesses as $environmentAccess) {
             if ($selectedUser->id === $environmentAccess->user) {
                 $currentEnvironmentRole = $environmentAccess->role;
             }
         }
         $output->writeln("Role for environment {$environment->title}: <info>{$currentEnvironmentRole}</info>");
     }
     return 0;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $this->validateInput($input);
     /** @var \Platformsh\Cli\Helper\QuestionHelper $questionHelper */
     $questionHelper = $this->getHelper('question');
     $email = $input->getArgument('email');
     if ($email && !$this->validateEmail($email)) {
         return 1;
     } elseif (!$email) {
         $question = new Question('Email address: ');
         $question->setValidator([$this, 'validateEmail']);
         $question->setMaxAttempts(5);
         $email = $questionHelper->ask($input, $this->stdErr, $question);
     }
     $project = $this->getSelectedProject();
     if ($this->api()->loadProjectAccessByEmail($project, $email)) {
         $this->stdErr->writeln("The user already exists: <comment>{$email}</comment>");
         return 1;
     }
     $projectRole = $input->getOption('role');
     if ($projectRole && !in_array($projectRole, ProjectAccess::$roles)) {
         $this->stdErr->writeln("Valid project-level roles are 'admin' or 'viewer'");
         return 1;
     } elseif (!$projectRole) {
         if (!$input->isInteractive()) {
             $this->stdErr->writeln('You must specify a project role for the user.');
             return 1;
         }
         $this->stdErr->writeln("The user's project role can be 'viewer' ('v') or 'admin' ('a').");
         $question = new Question('Project role <question>[V/a]</question>: ', 'viewer');
         $question->setValidator([$this, 'validateRole']);
         $question->setMaxAttempts(5);
         $projectRole = $this->standardizeRole($questionHelper->ask($input, $this->stdErr, $question));
     }
     $environmentRoles = [];
     $environments = [];
     if ($projectRole !== 'admin') {
         $environments = $this->api()->getEnvironments($project);
         if ($input->isInteractive()) {
             $this->stdErr->writeln("The user's environment-level roles can be 'viewer', 'contributor', 'admin', or 'none'.");
         }
         foreach ($environments as $environment) {
             $question = new Question('<info>' . $environment->id . '</info> environment role <question>[v/c/a/N]</question>: ', 'none');
             $question->setValidator([$this, 'validateRole']);
             $question->setMaxAttempts(5);
             $environmentRoles[$environment->id] = $this->standardizeRole($questionHelper->ask($input, $this->stdErr, $question));
         }
     }
     $summaryFields = ['Email address' => $email, 'Project role' => $projectRole];
     if (!empty($environmentRoles)) {
         foreach ($environments as $environment) {
             if (isset($environmentRoles[$environment->id])) {
                 $summaryFields[$environment->title] = $environmentRoles[$environment->id];
             }
         }
     }
     $this->stdErr->writeln('Summary:');
     foreach ($summaryFields as $field => $value) {
         $this->stdErr->writeln("    {$field}: <info>{$value}</info>");
     }
     $this->stdErr->writeln("<comment>Adding users can result in additional charges.</comment>");
     if ($input->isInteractive()) {
         if (!$questionHelper->confirm("Are you sure you want to add this user?")) {
             return 1;
         }
     }
     $this->stdErr->writeln("Adding the user to the project");
     $result = $project->addUser($email, $projectRole);
     $activities = $result->getActivities();
     $this->stdErr->writeln("User <info>{$email}</info> created");
     $success = true;
     if (!empty($environmentRoles)) {
         /** @var ProjectAccess $projectAccess */
         $projectAccess = $result->getEntity();
         $uuid = $projectAccess->id;
         $this->stdErr->writeln("Setting environment role(s)");
         foreach ($environmentRoles as $environmentId => $role) {
             if (!isset($environments[$environmentId])) {
                 $this->stdErr->writeln("<error>Environment not found: {$environmentId}</error>");
                 $success = false;
                 continue;
             }
             if ($role == 'none') {
                 continue;
             }
             $access = $environments[$environmentId]->getUser($uuid);
             if ($access) {
                 $this->stdErr->writeln("Modifying the user's role on the environment: <info>{$environmentId}</info>");
                 $result = $access->update(['role' => $role]);
             } else {
                 $this->stdErr->writeln("Adding the user to the environment: <info>{$environmentId}</info>");
                 $result = $environments[$environmentId]->addUser($uuid, $role);
             }
             $activities = array_merge($activities, $result->getActivities());
         }
     }
     if (!$input->getOption('no-wait')) {
         if (!ActivityUtil::waitMultiple($activities, $this->stdErr, $project)) {
             $success = false;
         }
     }
     return $success ? 0 : 1;
 }
 /**
  * @param Environment[]   $environments
  * @param InputInterface  $input
  * @param OutputInterface $output
  *
  * @return bool
  */
 protected function deleteMultiple(array $environments, InputInterface $input, OutputInterface $output)
 {
     // Confirm which environments the user wishes to be deleted.
     $delete = array();
     $deactivate = array();
     $questionHelper = $this->getHelper('question');
     foreach ($environments as $environment) {
         $environmentId = $environment['id'];
         if ($environmentId == 'master') {
             $output->writeln("The <error>master</error> environment cannot be deleted.");
             continue;
         }
         // Check that the environment does not have children.
         // @todo remove this check when Platform's behavior is fixed
         foreach ($this->getEnvironments() as $potentialChild) {
             if ($potentialChild['parent'] == $environment['id']) {
                 $output->writeln("The environment <error>{$environmentId}</error> has children and therefore can't be deleted.");
                 $output->writeln("Please delete the environment's children first.");
                 continue 2;
             }
         }
         if ($environment->status === 'dirty') {
             $environment->refresh();
         }
         if ($environment->isActive()) {
             $output->writeln("The environment <comment>{$environmentId}</comment> is currently active: deleting it will delete all associated data.");
             $question = "Are you sure you want to delete the environment <comment>{$environmentId}</comment>?";
             if ($questionHelper->confirm($question, $input, $output)) {
                 $deactivate[$environmentId] = $environment;
                 $question = "Delete the remote Git branch too?";
                 if ($questionHelper->confirm($question, $input, $output)) {
                     $delete[$environmentId] = $environment;
                 }
             }
         } elseif ($environment->status === 'inactive') {
             $question = "Are you sure you want to delete the remote Git branch <comment>{$environmentId}</comment>?";
             if ($questionHelper->confirm($question, $input, $output)) {
                 $delete[$environmentId] = $environment;
             }
         } elseif ($environment->status === 'dirty') {
             $output->writeln("The environment <error>{$environmentId}</error> is currently building, and therefore can't be deleted. Please wait");
             continue;
         }
     }
     $deactivateActivities = array();
     $deactivated = 0;
     /** @var Environment $environment */
     foreach ($deactivate as $environmentId => $environment) {
         try {
             $output->writeln("Deleting environment <info>{$environmentId}</info>");
             $deactivateActivities[] = $environment->deactivate();
             $deactivated++;
         } catch (\Exception $e) {
             $output->writeln($e->getMessage());
         }
     }
     ActivityUtil::waitMultiple($deactivateActivities, $output);
     $deleted = 0;
     foreach ($delete as $environmentId => $environment) {
         try {
             if ($environment->status !== 'inactive') {
                 $environment->refresh();
                 if ($environment->status !== 'inactive') {
                     $output->writeln("Cannot delete environment <error>{$environmentId}</error>: it is not (yet) inactive.");
                     continue;
                 }
             }
             $environment->delete();
             $output->writeln("Deleted remote Git branch <info>{$environmentId}</info>");
             $deleted++;
         } catch (\Exception $e) {
             $output->writeln($e->getMessage());
         }
     }
     if ($deleted || $deactivated) {
         $this->getEnvironments(null, true);
     }
     return $deleted >= count($delete) && $deactivated >= count($deactivate);
 }
 /**
  * @param Environment[]   $environments
  * @param InputInterface  $input
  * @param OutputInterface $output
  *
  * @return bool
  */
 protected function deleteMultiple(array $environments, InputInterface $input, OutputInterface $output)
 {
     // Confirm which environments the user wishes to be deleted.
     $delete = [];
     $deactivate = [];
     $error = false;
     $questionHelper = $this->getHelper('question');
     foreach ($environments as $environment) {
         $environmentId = $environment->id;
         if ($environmentId == 'master') {
             $output->writeln("The <error>master</error> environment cannot be deleted.");
             $error = true;
             continue;
         }
         // Check that the environment does not have children.
         // @todo remove this check when Platform's behavior is fixed
         foreach ($this->api()->getEnvironments($this->getSelectedProject()) as $potentialChild) {
             if ($potentialChild->parent == $environment->id) {
                 $output->writeln("The environment <error>{$environmentId}</error> has children and therefore can't be deleted.");
                 $output->writeln("Please delete the environment's children first.");
                 $error = true;
                 continue 2;
             }
         }
         if ($environment->isActive()) {
             $output->writeln("The environment <comment>{$environmentId}</comment> is currently active: deleting it will delete all associated data.");
             if ($questionHelper->confirm("Are you sure you want to delete the environment <comment>{$environmentId}</comment>?")) {
                 $deactivate[$environmentId] = $environment;
                 if (!$input->getOption('no-delete-branch')) {
                     if ($input->getOption('delete-branch') || $input->isInteractive() && $questionHelper->confirm("Delete the remote Git branch too?")) {
                         $delete[$environmentId] = $environment;
                     }
                 }
             }
         } elseif ($environment->status === 'inactive') {
             if ($questionHelper->confirm("Are you sure you want to delete the remote Git branch <comment>{$environmentId}</comment>?")) {
                 $delete[$environmentId] = $environment;
             }
         } elseif ($environment->status === 'dirty') {
             $output->writeln("The environment <error>{$environmentId}</error> is currently building, and therefore can't be deleted. Please wait.");
             $error = true;
             continue;
         }
     }
     $deactivateActivities = [];
     $deactivated = 0;
     /** @var Environment $environment */
     foreach ($deactivate as $environmentId => $environment) {
         try {
             $output->writeln("Deleting environment <info>{$environmentId}</info>");
             $deactivateActivities[] = $environment->deactivate();
             $deactivated++;
         } catch (\Exception $e) {
             $output->writeln($e->getMessage());
         }
     }
     if (!$input->getOption('no-wait')) {
         if (!ActivityUtil::waitMultiple($deactivateActivities, $output, $this->getSelectedProject())) {
             $error = true;
         }
     }
     $deleted = 0;
     foreach ($delete as $environmentId => $environment) {
         try {
             if ($environment->status !== 'inactive') {
                 $environment->refresh();
                 if ($environment->status !== 'inactive') {
                     $output->writeln("Cannot delete branch <error>{$environmentId}</error>: it is not (yet) inactive.");
                     continue;
                 }
             }
             $environment->delete();
             $output->writeln("Deleted remote Git branch <info>{$environmentId}</info>");
             $deleted++;
         } catch (\Exception $e) {
             $output->writeln($e->getMessage());
         }
     }
     if ($deleted < count($delete) || $deactivated < count($deactivate)) {
         $error = true;
     }
     if (($deleted || $deactivated || $error) && isset($environment)) {
         $this->api()->clearEnvironmentsCache($environment->project);
     }
     return !$error;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $level = $input->getOption('level');
     $role = $input->getOption('role');
     $validLevels = ['project', 'environment', null];
     if (!in_array($level, $validLevels)) {
         $this->stdErr->writeln("Invalid level: <error>{$level}</error>");
         return 1;
     }
     $this->validateInput($input, $level !== 'environment');
     $project = $this->getSelectedProject();
     if ($level === null && $role && $this->hasSelectedEnvironment() && $input->isInteractive()) {
         $environment = $this->getSelectedEnvironment();
         /** @var \Platformsh\Cli\Helper\QuestionHelper $questionHelper */
         $questionHelper = $this->getHelper('question');
         $question = new ChoiceQuestion('For which access level do you want to set the role?', ['project' => 'The project', 'environment' => sprintf('The environment (%s)', $environment->id)]);
         $level = $questionHelper->ask($input, $output, $question);
     } elseif ($level === null && $role) {
         $level = 'project';
     }
     // Validate the --role option, according to the level.
     $validRoles = $level !== 'environment' ? ProjectAccess::$roles : array_merge(EnvironmentAccess::$roles, ['none']);
     if ($role && !in_array($role, $validRoles)) {
         $this->stdErr->writeln('Invalid ' . $level . ' role: ' . $role);
         return 1;
     }
     // Load the user.
     $email = $input->getArgument('email');
     $selectedUser = $this->api()->loadProjectAccessByEmail($project, $email);
     if (!$selectedUser) {
         $this->stdErr->writeln("User not found: <error>{$email}</error>");
         return 1;
     }
     // Get the current role.
     if ($level !== 'environment') {
         $currentRole = $selectedUser->role;
         $environmentAccess = false;
     } else {
         $environmentAccess = $this->getSelectedEnvironment()->getUser($selectedUser->id);
         $currentRole = $environmentAccess === false ? 'none' : $environmentAccess->role;
     }
     if ($role === $currentRole) {
         $this->stdErr->writeln("There is nothing to change");
     } elseif ($role && $project->owner === $selectedUser->id) {
         $this->stdErr->writeln(sprintf('The user <error>%s</error> is the owner of the project %s.', $email, $this->api()->getProjectLabel($project, 'error')));
         $this->stdErr->writeln("You cannot change the role of the project's owner.");
         return 1;
     } elseif ($role && $level === 'environment' && $selectedUser->role === ProjectAccess::ROLE_ADMIN) {
         $this->stdErr->writeln(sprintf('The user <error>%s</error> is an admin on the project %s.', $email, $this->api()->getProjectLabel($project, 'error')));
         $this->stdErr->writeln('You cannot change the environment-level role of a project admin.');
         return 1;
     } elseif ($role && $level !== 'environment') {
         $result = $selectedUser->update(['role' => $role]);
         $this->stdErr->writeln("User <info>{$email}</info> updated");
     } elseif ($role && $level === 'environment') {
         $environment = $this->getSelectedEnvironment();
         if ($role === 'none') {
             if ($environmentAccess instanceof EnvironmentAccess) {
                 $result = $environmentAccess->delete();
             }
         } elseif ($environmentAccess instanceof EnvironmentAccess) {
             $result = $environmentAccess->update(['role' => $role]);
         } else {
             $result = $environment->addUser($selectedUser->id, $role);
         }
         $this->stdErr->writeln("User <info>{$email}</info> updated");
     }
     if (isset($result) && !$input->getOption('no-wait')) {
         ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr, $project);
     }
     if ($input->getOption('pipe')) {
         if ($level !== 'environment') {
             $output->writeln($selectedUser->role);
         } else {
             $access = $this->getSelectedEnvironment()->getUser($selectedUser->id);
             $output->writeln($access ? $access->role : 'none');
         }
         return 0;
     }
     if ($level !== 'environment') {
         $output->writeln("Project role: <info>{$selectedUser->role}</info>");
     }
     $environments = [];
     if ($level === 'environment') {
         $environments = [$this->getSelectedEnvironment()];
     } elseif ($level === null && $selectedUser->role !== ProjectAccess::ROLE_ADMIN) {
         $environments = $this->api()->getEnvironments($project);
         $this->api()->sortResources($environments, 'id');
         if ($this->hasSelectedEnvironment()) {
             $environment = $this->getSelectedEnvironment();
             unset($environments[$environment->id]);
             array_splice($environments, 0, 0, [$environment->id => $environment]);
         }
     }
     foreach ($environments as $environment) {
         $access = $environment->getUser($selectedUser->id);
         $output->writeln(sprintf('Role for environment %s: <info>%s</info>', $environment->id, $access ? $access->role : 'none'));
     }
     return 0;
 }
 /**
  * @param string      $property
  * @param string      $value
  * @param Environment $environment
  * @param bool        $noWait
  *
  * @return int
  */
 protected function setProperty($property, $value, Environment $environment, $noWait)
 {
     if (!$this->validateValue($property, $value)) {
         return 1;
     }
     $type = $this->getType($property);
     if ($type === 'boolean' && $value === 'false') {
         $value = false;
     }
     settype($value, $type);
     $currentValue = $environment->getProperty($property, false);
     if ($currentValue === $value) {
         $this->stdErr->writeln("Property <info>{$property}</info> already set as: " . $this->formatter->format($environment->getProperty($property, false), $property));
         return 0;
     }
     $result = $environment->update([$property => $value]);
     $this->stdErr->writeln("Property <info>{$property}</info> set to: " . $this->formatter->format($environment->{$property}, $property));
     $this->api()->clearEnvironmentsCache($environment->project);
     $rebuildProperties = ['enable_smtp', 'restrict_robots'];
     $success = true;
     if ($result->countActivities() && !$noWait) {
         $success = ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr, $this->getSelectedProject());
     } elseif (!$result->countActivities() && in_array($property, $rebuildProperties)) {
         $this->rebuildWarning();
     }
     return $success ? 0 : 1;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $this->validateInput($input);
     $auth = $input->getOption('auth');
     $access = $input->getOption('access');
     $accessOpts = [];
     $enabled = $input->getOption('enabled');
     if ($enabled !== null) {
         $accessOpts['is_enabled'] = !in_array($enabled, ['0', 'false']);
     }
     if ($access) {
         $accessOpts['addresses'] = [];
         foreach (array_filter($access) as $access) {
             $accessOpts["addresses"][] = $this->parseAccess($access);
         }
     }
     if ($auth) {
         $accessOpts['basic_auth'] = [];
         foreach (array_filter($auth) as $auth) {
             $parsed = $this->parseAuth($auth);
             $accessOpts["basic_auth"][$parsed["username"]] = $parsed["password"];
         }
     }
     // Ensure the environment is refreshed.
     $selectedEnvironment = $this->getSelectedEnvironment();
     $selectedEnvironment->ensureFull();
     $environmentId = $selectedEnvironment->id;
     $formatter = new PropertyFormatter();
     if (!empty($accessOpts)) {
         $current = (array) $selectedEnvironment->getProperty('http_access');
         // Merge existing settings. Not using a reference here, as that
         // would affect the comparison with $current later.
         foreach ($current as $key => $value) {
             if (!isset($accessOpts[$key])) {
                 $accessOpts[$key] = $value;
             }
         }
         if ($current != $accessOpts) {
             // The API only accepts {} for an empty "basic_auth" value,
             // rather than [].
             if (isset($accessOpts['basic_auth']) && $accessOpts['basic_auth'] === []) {
                 $accessOpts['basic_auth'] = (object) [];
             }
             // Patch the environment with the changes.
             $result = $selectedEnvironment->update(['http_access' => $accessOpts]);
             $this->clearEnvironmentsCache();
             $this->stdErr->writeln("Updated HTTP access settings for the environment <info>{$environmentId}</info>:");
             $output->writeln($formatter->format($selectedEnvironment->getProperty('http_access'), 'http_access'));
             $success = true;
             if (!$result->countActivities()) {
                 $this->rebuildWarning();
             } elseif (!$input->getOption('no-wait')) {
                 $success = ActivityUtil::waitMultiple($result->getActivities(), $this->stdErr);
             }
             return $success ? 0 : 1;
         }
     }
     $this->stdErr->writeln("HTTP access settings for the environment <info>{$environmentId}</info>:");
     $output->writeln($formatter->format($selectedEnvironment->getProperty('http_access'), 'http_access'));
     return 0;
 }
 /**
  * @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;
 }