/** * xSaveAction * * @param string $ccId * @param string $projectId * @param string $name * @param string $description * @param string $billingCode * @param string $leadEmail * @param int $shared * @param int $accountId optional * @param bool $checkAccountAccessToCc optional * @param bool $grantAccountAccessToCc optional * @throws Scalr_Exception_InsufficientPermissions */ public function xSaveAction($ccId, $projectId, $name, $description, $billingCode, $leadEmail, $shared, $accountId = null, $checkAccountAccessToCc = true, $grantAccountAccessToCc = false) { $validator = new Validator(); $validator->validate($name, 'name', Validator::NOEMPTY); if ($projectId) { $project = $this->getContainer()->analytics->projects->get($projectId); if (!$project) { throw new Scalr_UI_Exception_NotFound(); } } else { $project = new ProjectEntity(); $project->createdById = $this->user->id; $project->createdByEmail = $this->user->getEmail(); $cc = $this->getContainer()->analytics->ccs->get($ccId); if (!$cc) { $validator->addError('ccId', 'Cost center ID should be set'); } $project->ccId = $ccId; } if ($shared == ProjectEntity::SHARED_WITHIN_ACCOUNT) { $project->shared = ProjectEntity::SHARED_WITHIN_ACCOUNT; $project->accountId = $accountId; } elseif ($shared == ProjectEntity::SHARED_WITHIN_CC) { $project->shared = ProjectEntity::SHARED_WITHIN_CC; $project->accountId = null; } else { throw new Scalr_UI_Exception_NotFound(); } if (!$validator->isValid($this->response)) { return; } if ($project->shared == ProjectEntity::SHARED_WITHIN_ACCOUNT) { if (!AccountCostCenterEntity::findOne([['accountId' => $project->accountId], ['ccId' => $ccId]])) { if ($checkAccountAccessToCc) { $this->response->data(['ccIsNotAllowedToAccount' => true]); $this->response->failure(); return; } elseif ($grantAccountAccessToCc) { //give account access to cc $accountCcEntity = new AccountCostCenterEntity($project->accountId, $ccId); $accountCcEntity->save(); } } } $project->name = $name; $this->db->BeginTrans(); try { $project->save(); //NOTE please take into account the presence of the usage->createHostedScalrAccountCostCenter() method $project->saveProperty(ProjectPropertyEntity::NAME_BILLING_CODE, $billingCode); $project->saveProperty(ProjectPropertyEntity::NAME_DESCRIPTION, $description); $project->saveProperty(ProjectPropertyEntity::NAME_LEAD_EMAIL, $leadEmail); $this->db->CommitTrans(); } catch (Exception $e) { $this->db->RollbackTrans(); throw $e; } $this->response->data(['project' => $this->getProjectData($project)]); $this->response->success('Project has been successfully saved'); }
public function xSaveAction() { if (!$this->user->isAdmin() && !$this->request->isAllowed(Acl::RESOURCE_ANALYTICS_PROJECTS)) { throw new Scalr_Exception_InsufficientPermissions(); } $this->request->defineParams(array('name' => array('type' => 'string', 'validator' => array(Scalr_Validator::NOEMPTY => true)), 'billingCode' => array('type' => 'string', 'validator' => array(Scalr_Validator::NOEMPTY => true, Scalr_Validator::ALPHANUM => true)), 'leadEmail' => array('type' => 'string', 'validator' => array(Scalr_Validator::NOEMPTY => true, Scalr_Validator::EMAIL => true)), 'shared' => array('type' => 'int'))); if ($this->user->isAdmin()) { if ($this->getParam('projectId')) { $project = $this->getContainer()->analytics->projects->get($this->getParam('projectId')); if (!$project) { throw new Scalr_UI_Exception_NotFound(); } } else { $project = new ProjectEntity(); } $cc = $this->getContainer()->analytics->ccs->get($this->getParam('ccId')); } else { $this->request->restrictAccess(Acl::RESOURCE_ANALYTICS_PROJECTS); $project = new ProjectEntity(); $cc = $this->getContainer()->analytics->ccs->get($this->getEnvironment()->getPlatformConfigValue(Scalr_Environment::SETTING_CC_ID)); $project->shared = $this->getParam('shared'); $project->envId = $this->getEnvironment()->id; $project->accountId = $this->user->getAccountId(); } $this->request->validate(); if (!$cc) { $this->request->addValidationErrors('ccId', 'Cost center ID should be set'); } if (!$this->request->isValid()) { $this->response->data($this->request->getValidationErrors()); $this->response->failure(); return; } //Checks whether billing code specified in the request is already used in another Project $criteria = [['name' => ProjectPropertyEntity::NAME_BILLING_CODE], ['value' => $this->getParam('billingCode')]]; if ($project->projectId !== null) { $criteria[] = ['projectId' => ['$ne' => $project->projectId]]; } else { //This is a new record. //Email and identifier of the user who creates this record must be set. $project->createdById = $this->user->id; $project->createdByEmail = $this->user->getEmail(); } $project->name = $this->getParam('name'); $project->ccId = $cc->ccId; $pp = new ProjectPropertyEntity(); $record = $this->db->GetRow("\n SELECT " . $project->fields('p') . "\n FROM " . $project->table('p') . "\n JOIN " . $pp->table('pp') . " ON pp.project_id = p.project_id\n WHERE " . $pp->_buildQuery($criteria, 'AND', 'pp')['where'] . "\n LIMIT 1\n "); if ($record) { $found = new ProjectEntity(); $found->load($record); } if (!empty($found)) { throw new AnalyticsException(sprintf('Billing code "%s" is already used in the Project "%s"', strip_tags($this->getParam('billingCode')), $found->name)); } $this->db->BeginTrans(); try { $project->save(); $project->saveProperty(ProjectPropertyEntity::NAME_BILLING_CODE, $this->getParam('billingCode')); $project->saveProperty(ProjectPropertyEntity::NAME_DESCRIPTION, $this->getParam('description')); $project->saveProperty(ProjectPropertyEntity::NAME_LEAD_EMAIL, $this->getParam('leadEmail')); $this->db->CommitTrans(); } catch (Exception $e) { $this->db->RollbackTrans(); throw $e; } $this->response->data(['project' => $this->getProjectData($project)]); $this->response->success('Project has been successfully saved'); }
/** * Creates default Cost Center for the Hosted Scalr new account * * @param Scalr_Account $account The account object * @param Scalr_Account_User $user optional The account owner user * @return CostCentreEntity Returns a new Cost Center */ public function createHostedScalrAccountCostCenter(Scalr_Account $account, Scalr_Account_User $user = null) { if (!$user instanceof Scalr_Account_User) { $user = $account->getOwner(); } //New Cost Center should be created in account share mode $cc = new CostCentreEntity(); $cc->ccId = \Scalr::GenerateUID(); $cc->accountId = $account->id; $cc->createdByEmail = $user->getEmail(); $cc->name = "Cost Center " . $account->name . " (" . $account->id . ")"; $cc->createdById = $user->id; $cc->save(); $cc->saveProperty(CostCentrePropertyEntity::NAME_BILLING_CODE, "CC-" . $account->name); $cc->saveProperty(CostCentrePropertyEntity::NAME_DESCRIPTION, "This Cost Center was added automatically."); $cc->saveProperty(CostCentrePropertyEntity::NAME_LEAD_EMAIL, $user->getEmail()); $cc->saveProperty(CostCentrePropertyEntity::NAME_LOCKED, false); //A new Project which corresponds to Cost Center (in account share mode as well) $project = new ProjectEntity(); $project->projectId = \Scalr::GenerateUID(); $project->ccId = $cc->ccId; $project->name = "Project " . $account->name . " (" . $account->id . ")"; $project->accountId = $account->id; $project->createdByEmail = $user->getEmail(); $project->shared = ProjectEntity::SHARED_WITHIN_ACCOUNT; $project->createdById = $user->id; $project->save(); $project->saveProperty(ProjectPropertyEntity::NAME_BILLING_CODE, "PR-" . $account->name); $project->saveProperty(ProjectPropertyEntity::NAME_DESCRIPTION, "This Project was added automatically."); $project->saveProperty(ProjectPropertyEntity::NAME_LEAD_EMAIL, $user->getEmail()); if (\Scalr::getContainer()->analytics->enabled) { \Scalr::getContainer()->analytics->tags->syncValue($account->id, TagEntity::TAG_ID_COST_CENTRE, $cc->ccId, $cc->name); \Scalr::getContainer()->analytics->tags->syncValue($account->id, TagEntity::TAG_ID_PROJECT, $project->projectId, $project->name); } return $cc; }
/** * xSaveAction * * @param string $projectId * @param string $name * @param string $description * @param string $billingCode * @param string $leadEmail * @param string $ccId optional * @throws \InvalidArgumentException * @throws Scalr_Exception_InsufficientPermissions * @throws Scalr_UI_Exception_NotFound */ public function xSaveAction($projectId, $name, $description, $billingCode, $leadEmail, $ccId = null) { $this->request->restrictAccess(Acl::RESOURCE_ANALYTICS_ACCOUNT, Acl::PERM_ANALYTICS_ACCOUNT_MANAGE_PROJECTS); $validator = new Validator(); $validator->validate($name, 'name', Validator::NOEMPTY); if (!$validator->isValid($this->response)) { return; } if ($projectId) { $project = $this->getContainer()->analytics->projects->get($projectId); if (!$project) { throw new Scalr_UI_Exception_NotFound(); } elseif ($project->shared != ProjectEntity::SHARED_WITHIN_ACCOUNT || $project->accountId != $this->user->getAccountId()) { throw new Scalr_Exception_InsufficientPermissions(); } } else { $project = new ProjectEntity(); if ($this->request->getScope() == 'environment') { $project->ccId = $this->getEnvironment()->getPlatformConfigValue(\Scalr_Environment::SETTING_CC_ID); } else { $project->ccId = $ccId; } $cc = $this->getContainer()->analytics->ccs->get($project->ccId); if (!empty($cc)) { if ($cc->getProperty(CostCentrePropertyEntity::NAME_LOCKED) == 1) { throw new Scalr_Exception_InsufficientPermissions(); } $email = $cc->getProperty(CostCentrePropertyEntity::NAME_LEAD_EMAIL); $emailData = ['projectName' => $name, 'ccName' => $cc->name]; } else { throw new Scalr_UI_Exception_NotFound(); } $project->shared = ProjectEntity::SHARED_WITHIN_ACCOUNT; $project->accountId = $this->user->getAccountId(); $project->createdById = $this->user->id; $project->createdByEmail = $this->user->getEmail(); } $project->name = $name; $this->db->BeginTrans(); try { $project->save(); //NOTE please take into account the presence of the usage->createHostedScalrAccountCostCenter() method $project->saveProperty(ProjectPropertyEntity::NAME_BILLING_CODE, $billingCode); $project->saveProperty(ProjectPropertyEntity::NAME_DESCRIPTION, $description); $project->saveProperty(ProjectPropertyEntity::NAME_LEAD_EMAIL, $leadEmail); $this->db->CommitTrans(); } catch (Exception $e) { $this->db->RollbackTrans(); throw $e; } if (!$projectId && !empty($email)) { \Scalr::getContainer()->mailer->sendTemplate(SCALR_TEMPLATES_PATH . '/emails/analytics_on_project_add.eml.php', $emailData, $email); } $this->response->data(['project' => $this->getProjectData($project)]); $this->response->success('Project has been successfully saved'); }
/** * Initializes default cost centres and projects according to fixtures * * @return void */ public function initDefault() { $fixture = $this->fixture(); foreach ($fixture as $i => $c) { $ccId = key($c); $cc = CostCentreEntity::findPk($ccId); if (!$cc) { $cc = new CostCentreEntity(); $cc->ccId = $ccId; $cc->name = sprintf('Cost center %02d', $i + 1); $cc->save(); $cc->saveProperty(CostCentrePropertyEntity::NAME_DESCRIPTION, 'This is the automatically added cost center'); $cc->saveProperty(CostCentrePropertyEntity::NAME_BILLING_CODE, sprintf('CC-%02d', $i)); $cc->saveProperty(CostCentrePropertyEntity::NAME_LEAD_EMAIL, ''); $this->cadb->Execute("\n INSERT IGNORE `account_tag_values` (`account_id`, `tag_id`, `value_id`, `value_name`)\n VALUES (0, ?, ?, ?)\n ", [TagEntity::TAG_ID_COST_CENTRE, $cc->ccId, $cc->name]); } foreach ($fixture[$i][$ccId] as $j => $projectId) { $pr = ProjectEntity::findPk($projectId); if (!$pr) { $pr = new ProjectEntity(); $pr->projectId = $projectId; $pr->ccId = $ccId; $pr->name = sprintf('Project %d%d', $i, $j + 1); $pr->save(); $pr->saveProperty(ProjectPropertyEntity::NAME_DESCRIPTION, 'This is the automatically generated project'); $pr->saveProperty(ProjectPropertyEntity::NAME_BILLING_CODE, sprintf('PR-%02d-%02d', $i, $j)); $pr->saveProperty(ProjectPropertyEntity::NAME_LEAD_EMAIL, ''); $this->cadb->Execute("\n INSERT IGNORE `account_tag_values` (`account_id`, `tag_id`, `value_id`, `value_name`)\n VALUES (0, ?, ?, ?)\n ", [TagEntity::TAG_ID_PROJECT, $pr->projectId, $pr->name]); } } } //Assigns cost centre to each environment $res = $this->db->Execute("SELECT id FROM client_environments"); while ($rec = $res->FetchRow()) { try { $environment = \Scalr_Environment::init()->loadById($rec['id']); } catch (Exception $e) { continue; } $environment->setPlatformConfig(array(\Scalr_Environment::SETTING_CC_ID => $this->autoCostCentre($environment->id))); } //Assigns project to each farm $res = $this->db->Execute("SELECT id, env_id, clientid FROM farms"); while ($rec = $res->FetchRow()) { try { $dbFarm = DBFarm::LoadByID($rec['id']); } catch (Exception $e) { continue; } $dbFarm->SetSetting(DBFarm::SETTING_PROJECT_ID, $this->autoProject($dbFarm->EnvID, $dbFarm->ID)); } //Initializes servers properties $res = $this->db->Execute("\n SELECT DISTINCT s.server_id, s.env_id, s.farm_id\n FROM servers s\n LEFT JOIN server_properties p ON p.server_id = s.server_id AND p.name = ?\n LEFT JOIN server_properties p2 ON p2.server_id = s.server_id AND p2.name = ?\n WHERE p.server_id IS NULL OR p.`value` IS NULL\n OR (s.farm_id IS NOT NULL AND (p2.server_id IS NULL OR p2.`value` IS NULL))\n ", [SERVER_PROPERTIES::ENV_CC_ID, SERVER_PROPERTIES::FARM_PROJECT_ID]); while ($rec = $res->FetchRow()) { $ccid = $this->autoCostCentre($rec['env_id']); $this->db->Execute("\n INSERT `server_properties` (`server_id`, `name`, `value`)\n VALUE (?, ?, ?)\n ON DUPLICATE KEY UPDATE `value` = IFNULL(`value`, ?)\n ", [$rec['server_id'], SERVER_PROPERTIES::ENV_CC_ID, $ccid, $ccid]); //Farm may not exist for bundle task servers if ($rec['farm_id']) { $projectid = $this->autoProject($rec['env_id'], $rec['farm_id']); $this->db->Execute("\n INSERT `server_properties` (`server_id`, `name`, `value`)\n VALUE (?, ?, ?)\n ON DUPLICATE KEY UPDATE `value` = IFNULL(`value`, ?)\n ", [$rec['server_id'], SERVER_PROPERTIES::FARM_PROJECT_ID, $projectid, $projectid]); } } }