public function changeParent(Request\ChangeParent $request) { $result = new Response\ChangeParent(); $customerId = $request->getCustomerId(); $newParentId = $request->getNewParentId(); $formatted = $request->getDate(); $this->_logger->info("Set up new parent #{$newParentId} for customer #{$customerId}."); $def = $this->_manTrans->begin(); try { /* get customer's downline data */ $data = $this->_repoCustomer->getById($customerId); $currParentId = $data->getParentId(); $currDepth = $data->getDepth(); $currPath = $data->getPath(); if ($currParentId == $newParentId) { /* nothing to change */ $result->markSucceed(); $this->_manTrans->commit($def); $this->_logger->notice("Current parent is the same as new one. Nothing to do."); } else { if ($customerId == $newParentId) { /* change to root node */ $newCustomerDepth = Cfg::INIT_DEPTH; $newCustomerPath = Cfg::DTPS; } else { /* get new parent data */ $newParentData = $this->_repoCustomer->getById($newParentId); $newParentDepth = $newParentData->getDepth(); $newParentPath = $newParentData->getPath(); $newCustomerDepth = $newParentDepth + 1; $newCustomerPath = $newParentPath . $newParentId . Cfg::DTPS; } /* update customer with new data */ $bind = [Customer::ATTR_PARENT_ID => $newParentId, Customer::ATTR_DEPTH => $newCustomerDepth, Customer::ATTR_PATH => $newCustomerPath]; $updateRows = $this->_repoCustomer->updateById($customerId, $bind); if ($updateRows == 1) { /* update depths and paths in downline */ $deltaDepth = $newCustomerDepth - $currDepth; $pathKey = $currPath . $customerId . Cfg::DTPS; $pathReplace = $newCustomerPath . $customerId . Cfg::DTPS; $rowsUpdated = $this->_repoCustomer->updateChildrenPath($pathKey, $pathReplace, $deltaDepth); $this->_logger->info("Total '{$rowsUpdated}' customers in downline were updated."); /* save new record into change log */ $bind = [Change::ATTR_CUSTOMER_ID => $customerId, Change::ATTR_PARENT_ID => $newParentId, Change::ATTR_DATE_CHANGED => $formatted]; $insertedId = $this->_repoChange->create($bind); if ($insertedId) { $this->_logger->info("New change log record #{$insertedId} is inserted (customer: {$customerId}, parent: {$newParentId}, date: {$formatted})."); $this->_manTrans->commit($def); $result->markSucceed(); $this->_logger->info("New parent #{$newParentId} for customer #{$customerId} is set."); } } } } finally { $this->_manTrans->end($def); } return $result; }