/** * Updates instance types in a database * * @param string $platform A cloud platform * @param string $url A cloud endpoint url * @param string $cloudLocation A cloud location * @param array $instanceTypes Array of the instance types looks like [instanceTypeId => [prop => value]] */ public static function updateInstanceTypes($platform, $url, $cloudLocation, array $instanceTypes) { //One representation for platforms which does not support different cloud locations if (empty($cloudLocation)) { $cloudLocation = ''; } //Normalizes url to use in queries $url = static::normalizeUrl($url); //Search for cloud location record $cl = static::findOne([['platform' => $platform], ['url' => $url], ['cloudLocation' => $cloudLocation]]); if (!$cl instanceof CloudLocation) { $isNew = true; //There are no records yet $cl = static::init($platform, $cloudLocation, $url); } //Starts database transaction $cl->db()->BeginTrans(); try { if (!empty($isNew)) { //We have to create a parent table record in order to foreign key does not bark $cl->save(); } //Existing instance types $updatedIds = []; //Updates instance types which were known before foreach ($cl->getInstanceTypes() as $cit) { /* @var $cit \Scalr\Model\Entity\CloudInstanceType */ $changes = 0; if (!empty($instanceTypes[$cit->instanceTypeId]) && is_array($instanceTypes[$cit->instanceTypeId])) { //Updates status $changes = $cit->updateProperties(array_merge($instanceTypes[$cit->instanceTypeId], ['status' => $cit::STATUS_ACTIVE])); //Remembers which instances have been handled $updatedIds[] = $cit->instanceTypeId; } else { //Deactivates this instance type as it does not exist for now $cit->status = $cit::STATUS_INACTIVE; $changes++; } //Updates a record only if real changes happen if ($changes) { $cit->save(); } } //New instance types which were not known before foreach (array_diff_key($instanceTypes, array_flip($updatedIds)) as $instanceTypeId => $array) { if (empty($array) || !is_array($array)) { continue; } $cit = new CloudInstanceType($cl->cloudLocationId, $instanceTypeId); $cit->updateProperties($array); $cit->status = $cit::STATUS_ACTIVE; $cit->save(); } //Checks whether we need to refresh an update time if (empty($isNew)) { $cl->updated = new DateTime('now'); $cl->save(); } } catch (Exception $e) { $cl->db()->RollbackTrans(); throw $e; } $cl->db()->CommitTrans(); }