function do_immutable() { $oForm = $this->form_main(); $res = $oForm->validate(); $data = $res['results']; if (!empty($res['errors'])) { return $oForm->handleError(); } $sReason = $data['reason']; $fFolderId = $this->oDocument->getFolderId(); $reason = KTUtil::arrayGet($_REQUEST['data'], 'reason'); $this->oDocument->setImmutable(true); $this->oDocument->update(); // create the document transaction record $oDocumentTransaction = new DocumentTransaction($this->oDocument, $reason, 'ktcore.transactions.immutable'); $oDocumentTransaction->create(); controllerRedirect('viewDocument', 'fDocumentId=' . $this->oDocument->getId()); exit(0); }
/** * Add a folder to the archive * * @param unknown_type $zip * @param unknown_type $folderId * @return unknown */ public function addFolder(&$zip, $folderId) { $oFolder = Folder::get($folderId); if (PEAR::isError($oFolder)) { $this->errors[] = _kt('Folder cannot be exported, an error occurred: ') . $oFolder->getMessage(); return $oFolder; } $sFolderDocs = $oFolder->getDocumentIDs($folderId); if (PEAR::isError($sFolderDocs)) { $default->log->error('Download Queue: get document ids for folder caused an error: ' . $sFolderDocs->getMessage()); $sFolderDocs = ''; } // Add folder to zip $zip->addFolderToZip($oFolder); $aDocuments = array(); if (!empty($sFolderDocs)) { $aDocuments = explode(',', $sFolderDocs); } // Get all the folders within the current folder $sWhereClause = "parent_folder_ids like '%,{$folderId}'\n OR parent_folder_ids like '%,{$folderId},%'\n OR parent_folder_ids like '{$folderId},%'\n OR parent_id = {$folderId}"; $aFolderList = $oFolder->getList($sWhereClause); $aLinkingFolders = $this->getLinkingEntities($aFolderList); $aFolderList = array_merge($aFolderList, $aLinkingFolders); $aFolderObjects = array(); $aFolderObjects[$folderId] = $oFolder; // Export the folder structure to ensure the export of empty directories if (!empty($aFolderList)) { foreach ($aFolderList as $k => $oFolderItem) { if ($oFolderItem->isSymbolicLink()) { $oFolderItem = $oFolderItem->getLinkedFolder(); } if (Permission::userHasFolderReadPermission($oFolderItem)) { // Get documents for each folder $sFolderItemId = $oFolderItem->getID(); $sFolderItemDocs = $oFolderItem->getDocumentIDs($sFolderItemId); if (!empty($sFolderItemDocs)) { $aFolderDocs = explode(',', $sFolderItemDocs); $aDocuments = array_merge($aDocuments, $aFolderDocs); } $zip->addFolderToZip($oFolderItem); $aFolderObjects[$oFolderItem->getId()] = $oFolderItem; } } } // Add all documents to the export if (!empty($aDocuments)) { foreach ($aDocuments as $sDocumentId) { $oDocument = Document::get($sDocumentId); if ($oDocument->isSymbolicLink()) { $oDocument->switchToLinkedCore(); } if (Permission::userHasDocumentReadPermission($oDocument)) { if (!KTWorkflowUtil::actionEnabledForDocument($oDocument, 'ktcore.actions.document.view')) { $this->errors[] = $oDocument->getName() . ': ' . _kt('Document cannot be exported as it is restricted by the workflow.'); continue; } $sDocFolderId = $oDocument->getFolderID(); $oFolder = isset($aFolderObjects[$sDocFolderId]) ? $aFolderObjects[$sDocFolderId] : Folder::get($sDocFolderId); if ($this->bNoisy) { $oDocumentTransaction = new DocumentTransaction($oDocument, "Document part of bulk export", 'ktstandard.transactions.bulk_export', array()); $oDocumentTransaction->create(); } // fire subscription alerts for the downloaded document if ($this->bNotifications) { $oSubscriptionEvent = new SubscriptionEvent(); $oSubscriptionEvent->DownloadDocument($oDocument, $oFolder); } $zip->addDocumentToZip($oDocument, $oFolder); } } } }
function do_finish_restore() { $selected_docs = KTUtil::arrayGet($_REQUEST, 'selected_docs', array()); $aDocuments = array(); foreach ($selected_docs as $doc_id) { $oDoc =& Document::get($doc_id); if (PEAR::isError($oDoc) || $oDoc === false) { $this->errorRedirectToMain(_kt('Invalid document id specified. Aborting restore')); } else { if ($oDoc->getStatusId() != DELETED) { $this->errorRedirectToMain(sprintf(_kt('%s is not a deleted document. Aborting restore'), $oDoc->getName())); } } $aDocuments[] = $oDoc; } $this->startTransaction(); $aErrorDocuments = array(); $aSuccessDocuments = array(); $oStorage =& KTStorageManagerUtil::getSingleton(); foreach ($aDocuments as $oDoc) { $oFolder = Folder::get($oDoc->getRestoreFolderId()); // move to root if parent no longer exists. if (PEAR::isError($oFolder)) { $oDoc->setFolderId(1); $oFolder = Folder::get(1); } else { $oDoc->setFolderId($oDoc->getRestoreFolderId()); } if ($oStorage->restore($oDoc)) { $oDoc = Document::get($oDoc->getId()); // storage path has changed for most recent object... $oDoc->setStatusId(LIVE); $oDoc->setPermissionObjectId($oFolder->getPermissionObjectId()); $res = $oDoc->update(); if (PEAR::isError($res) || $res == false) { $aErrorDocuments[] = $oDoc->getName(); continue; // skip transactions, etc. } $res = KTPermissionUtil::updatePermissionLookup($oDoc); if (PEAR::isError($res)) { $aErrorDocuments[] = $oDoc->getName(); continue; // skip transactions, etc. } // create a doc-transaction. // FIXME does this warrant a transaction-type? $oTransaction = new DocumentTransaction($oDoc, sprintf(_kt("Restored from deleted state by %s"), $this->oUser->getName()), 'ktcore.transactions.update'); if (!$oTransaction->create()) { // do nothing? the state of physicaldocumentmanager... } $aSuccessDocuments[] = $oDoc->getName(); } else { $aErrorDocuments[] = $oDoc->getName(); } } $this->commitTransaction(); $msg = sprintf(_kt('%d documents restored.'), count($aSuccessDocuments)); if (count($aErrorDocuments) != 0) { $msg .= _kt('Failed to restore') . ': ' . join(', ', $aErrorDocuments); } $this->successRedirectToMain($msg); }
/** * Performs a workflow transition on a document, changing it from * one workflow state to another, with potential side effects (user * scripts, and so forth). * * This function currently assumes that the user in question is * allowed to perform the transition and that all the guard * functionality on the transition has passed. */ function performTransitionOnDocument($oTransition, $oDocument, $oUser, $sComments) { $oWorkflow =& KTWorkflow::getByDocument($oDocument); if (empty($oWorkflow)) { return PEAR::raiseError(_kt("Document has no workflow")); } if (PEAR::isError($oWorkflow)) { return $oWorkflow; } $oSourceState =& KTWorkflowUtil::getWorkflowStateForDocument($oDocument); // walk the action triggers. $aActionTriggers = KTWorkflowUtil::getActionTriggersForTransition($oTransition); if (PEAR::isError($aActionTriggers)) { return $aActionTriggers; // error out? } foreach ($aActionTriggers as $oTrigger) { $res = $oTrigger->precheckTransition($oDocument, $oUser); if (PEAR::isError($res)) { return $res; } } $iPreviousMetadataVersion = $oDocument->getMetadataVersionId(); $oDocument->startNewMetadataVersion($oUser); KTDocumentUtil::copyMetadata($oDocument, $iPreviousMetadataVersion); $iStateId = $oTransition->getTargetStateId(); $oDocument->setWorkflowStateId($iStateId); $res = $oDocument->update(); if (PEAR::isError($res)) { return $res; } $oTargetState =& KTWorkflowState::get($iStateId); $sSourceState = $oSourceState->getName(); $sTargetState = $oTargetState->getName(); // create the document transaction record $sTransactionComments = sprintf(_kt("Workflow state changed from %s to %s"), $sSourceState, $sTargetState); if ($sComments) { $sTransactionComments .= _kt("; Reason given was: ") . $sComments; } $oDocumentTransaction = new DocumentTransaction($oDocument, $sTransactionComments, 'ktcore.transactions.workflow_state_transition'); $oDocumentTransaction->create(); // walk the action triggers. foreach ($aActionTriggers as $oTrigger) { $res = $oTrigger->performTransition($oDocument, $oUser); if (PEAR::isError($res)) { return $res; } } KTPermissionUtil::updatePermissionLookup($oDocument); KTWorkflowUtil::informUsersForState($oTargetState, KTWorkflowUtil::getInformedForState($oTargetState), $oDocument, $oUser, $sComments); return true; }
/** * Restores a deleted document * * @author KnowledgeTree Team * @access public */ function restore() { DBUtil::startTransaction(); $storage =& KTStorageManagerUtil::getSingleton(); $folder = Folder::get($this->document->getRestoreFolderId()); if (PEAR::isError($folder)) { $this->document->setFolderId(1); $folder = Folder::get(1); } else { $this->document->setFolderId($this->document->getRestoreFolderId()); } $storage->restore($this->document); $this->document->setStatusId(LIVE); $this->document->setPermissionObjectId($folder->getPermissionObjectId()); $res = $this->document->update(); $res = KTPermissionUtil::updatePermissionLookup($this->document); $user = $this->ktapi->get_user(); $oTransaction = new DocumentTransaction($this->document, 'Restored from deleted state by ' . $user->getName(), 'ktcore.transactions.update'); $oTransaction->create(); DBUtil::commit(); }
function sendEmailHyperlink($aDestEmailAddress, $iDocumentID, $sDocumentName, $sComment, &$aEmailErrors) { global $default; // Get the email list as a string for the logs $sDestEmails = implode(',', $aDestEmailAddress); $oSendingUser = User::get($_SESSION['userID']); $sMessage = '<font face="arial" size="2">'; /* if ($sDestUserName) { $sMessage .= $sDestUserName . ',<br><br>'; } */ $sMessage .= sprintf(_kt("Your colleague, %s, wishes you to view the document entitled '%s'."), $oSendingUser->getName(), $sDocumentName); $sMessage .= " \n"; $sMessage .= _kt('Click on the hyperlink below to view it.') . '<br>'; // add the link to the document to the mail $sMessage .= '<br>' . generateControllerLink('viewDocument', "fDocumentID={$iDocumentID}", $sDocumentName, true); // add optional comment if (strlen($sComment) > 0) { $sMessage .= '<br><br>' . _kt('Comments') . ':<br>' . $sComment; } $sMessage .= '</font>'; $sTitle = sprintf(_kt("Link (ID %s): %s from %s"), $iDocumentID, $sDocumentName, $oSendingUser->getName()); //email the hyperlink // $sEmail = null; $sEmailFrom = null; $oConfig =& KTConfig::getSingleton(); if (!$oConfig->get('email/sendAsSystem')) { $sEmail = $oSendingUser->getEmail(); $sEmailFrom = $oSendingUser->getName(); } $oEmail = new Email($sEmail, $sEmailFrom); $res = $oEmail->send($aDestEmailAddress, $sTitle, $sMessage); if (PEAR::isError($res)) { $default->log->error($res->getMessage()); $aEmailErrors[] = $res->getMessage(); return $res; } else { if ($res === false) { $default->log->error("Error sending email ({$sTitle}) to {$sDestEmails}"); $aEmailErrors[] = "Error sending email ({$sTitle}) to {$sDestEmails}"; return PEAR::raiseError(sprintf(_kt("Error sending email (%s) to %s"), $sTitle, $sDestEmails)); } else { $default->log->info("Send email ({$sTitle}) to {$sDestEmails}"); } } // emailed link transaction // need a document to do this. $oDocument =& Document::get($iDocumentID); $oDocumentTransaction = new DocumentTransaction($oDocument, sprintf(_kt("Document link emailed to %s. "), $sDestEmails) . $sComment, 'ktcore.transactions.email_link'); if ($oDocumentTransaction->create()) { $default->log->debug("emailBL.php created email link document transaction for document ID={$iDocumentID}"); } else { $default->log->error("emailBL.php couldn't create email link document transaction for document ID={$iDocumentID}"); } }
function perform_action($oEntity) { // checkout document $sReason = $this->sReason; if (is_a($oEntity, 'Document')) { if ($oEntity->getImmutable()) { return PEAR::raiseError($oEntity->getName() . ': ' . _kt('Document cannot be checked out as it is immutable')); } if ($oEntity->getIsCheckedOut()) { $checkedOutUser = $oEntity->getCheckedOutUserID(); $sUserId = $_SESSION['userID']; if ($checkedOutUser != $sUserId) { $oCheckedOutUser = User::get($checkedOutUser); return PEAR::raiseError($oEntity->getName() . ': ' . _kt('Document has already been checked out by ') . $oCheckedOutUser->getName()); } } else { $res = KTDocumentUtil::checkout($oEntity, $sReason, $this->oUser); if (PEAR::isError($res)) { return PEAR::raiseError($oEntity->getName() . ': ' . $res->getMessage()); } } if ($this->bDownload) { if ($this->bNoisy) { $oDocumentTransaction = new DocumentTransaction($oEntity, "Document part of bulk checkout", 'ktstandard.transactions.check_out', array()); $oDocumentTransaction->create(); } $oKTTriggerRegistry = KTTriggerRegistry::getSingleton(); $aTriggers = $oKTTriggerRegistry->getTriggers('checkoutDownload', 'postValidate'); foreach ($aTriggers as $aTrigger) { $sTrigger = $aTrigger[0]; $oTrigger = new $sTrigger(); $aInfo = array('document' => $oEntity); $oTrigger->setInfo($aInfo); $ret = $oTrigger->postValidate(); if (PEAR::isError($ret)) { return $ret; } } $this->oZip->addDocumentToZip($oEntity); } } else { if (is_a($oEntity, 'Folder')) { // get documents and subfolders $aDocuments = array(); $oFolder = $oEntity; if ($oFolder->isSymbolicLink()) { $oFolder = $oFolder->getLinkedFolder(); } $sFolderId = $oFolder->getId(); $sFolderDocs = $oFolder->getDocumentIDs($sFolderId); // get documents directly in the folder if (!empty($sFolderDocs)) { $aDocuments = explode(',', $sFolderDocs); } // Get all the folders within the current folder $sWhereClause = "parent_folder_ids = '{$sFolderId}' OR\n parent_folder_ids LIKE '{$sFolderId},%' OR\n parent_folder_ids LIKE '%,{$sFolderId},%' OR\n parent_folder_ids LIKE '%,{$sFolderId}'"; $aFolderList = $this->oFolder->getList($sWhereClause); $aLinkingFolders = $this->getLinkingEntities($aFolderList); $aFolderList = array_merge($aFolderList, $aLinkingFolders); $aFolderObjects = array(); $aFolderObjects[$sFolderId] = $oFolder; // Get the documents within the folder if (!empty($aFolderList)) { foreach ($aFolderList as $k => $oFolderItem) { if (Permission::userHasFolderReadPermission($oFolderItem)) { // Get documents for each folder if ($oFolderItem->isSymbolicLink()) { $oFolderItem = $oFolderItem->getLinkedFolder(); } $sFolderItemId = $oFolderItem->getID(); $sFolderItemDocs = $oFolderItem->getDocumentIDs($sFolderItemId); if (!empty($sFolderItemDocs)) { $aFolderDocs = explode(',', $sFolderItemDocs); $aDocuments = array_merge($aDocuments, $aFolderDocs); } // Add the folder to the zip file if ($this->bDownload) { $this->oZip->addFolderToZip($oFolderItem); $aFolderObjects[$oFolderItem->getId()] = $oFolderItem; } } } } // Checkout each document within the folder structure if (!empty($aDocuments)) { foreach ($aDocuments as $sDocId) { $oDocument = Document::get($sDocId); if (PEAR::isError($oDocument)) { // add message, skip document and continue $this->addErrorMessage($oDocument->getName() . ': ' . $oDocument->getMessage()); continue; } if ($oDocument->isSymbolicLink()) { $oDocument->switchToLinkedCore(); } if ($oDocument->getImmutable()) { $this->addErrorMessage($oDocument->getName() . ': ' . _kt('Document cannot be checked out as it is immutable')); continue; } // Check if the action is restricted by workflow on the document if (!KTWorkflowUtil::actionEnabledForDocument($oDocument, 'ktcore.actions.document.checkout')) { $this->addErrorMessage($oDocument->getName() . ': ' . _kt('Checkout is restricted by the workflow state.')); continue; } // Check if document is already checked out, check the owner. // If the current user is the owner, then include to the download, otherwise ignore. if ($oDocument->getIsCheckedOut()) { $checkedOutUser = $oDocument->getCheckedOutUserID(); $sUserId = $_SESSION['userID']; if ($checkedOutUser != $sUserId) { $oCheckedOutUser = User::get($checkedOutUser); $this->addErrorMessage($oDocument->getName() . ': ' . _kt('Document has already been checked out by ') . $oCheckedOutUser->getName()); continue; } } else { // Check out document $res = KTDocumentUtil::checkout($oDocument, $sReason, $this->oUser); if (PEAR::isError($res)) { $this->addErrorMessage($oDocument->getName() . ': ' . _kt('Document could not be checked out. ') . $res->getMessage()); continue; } } // Add document to the zip file if ($this->bDownload) { if ($this->bNoisy) { $oDocumentTransaction = new DocumentTransaction($oDocument, 'Document part of bulk checkout', 'ktstandard.transactions.check_out', array()); $oDocumentTransaction->create(); } $oKTTriggerRegistry = KTTriggerRegistry::getSingleton(); $aTriggers = $oKTTriggerRegistry->getTriggers('checkoutDownload', 'postValidate'); foreach ($aTriggers as $aTrigger) { $sTrigger = $aTrigger[0]; $oTrigger = new $sTrigger(); $aInfo = array('document' => $oDocument); $oTrigger->setInfo($aInfo); $ret = $oTrigger->postValidate(); if (PEAR::isError($ret)) { return $ret; } } $sDocFolderId = $oDocument->getFolderID(); $oFolder = isset($aFolderObjects[$sDocFolderId]) ? $aFolderObjects[$sDocFolderId] : Folder::get($sDocFolderId); $this->oZip->addDocumentToZip($oDocument, $oFolder); } } } } } return true; }
function do_changestate() { $aErrorOptions = array('redirect_to' => array('main', sprintf('fDocumentId=%d', $this->oDocument->getId()))); $iThreadId = KTUtil::arrayGet($_REQUEST, 'fThreadId'); $oThread = DiscussionThread::get($iThreadId); $this->oValidator->notError($oThread, $aErrorOptions); $aErrorOptions = array('redirect_to' => array('viewthread', sprintf('fDocumentId=%d&fThreadId=%d', $this->oDocument->getId(), $oThread->getId()))); $oPermission =& KTPermission::getByName('ktcore.permissions.workflow'); $sRedirectTo = implode('&', $aErrorOptions['redirect_to']); if (PEAR::isError($oPermission)) { $this->errorRedirectTo($sRedirectTo, _kt("Error getting permission")); exit(0); } if (!KTPermissionUtil::userHasPermissionOnItem($this->oUser, $oPermission, $this->oDocument)) { $this->errorRedirectTo($sRedirectTo, _kt("You do not have permission to close this thread")); exit(0); } $iStateId = KTUtil::arrayGet($_REQUEST, 'state'); if (!in_array($iStateId, $this->aTransitions[$oThread->getState()])) { $this->errorRedirectTo($sRedirectTo, _kt("Invalid transition")); exit(0); } $aErrorOptions['message'] = _kt("No reason provided"); $sReason = $this->oValidator->validateString(KTUtil::arrayGet($_REQUEST, 'reason'), $aErrorOptions); if ($iStateId > $oThread->getState()) { $sTransactionNamespace = 'ktcore.transactions.collaboration_step_approve'; } else { $sTransactionNamespace = 'ktcore.transactions.collaboration_step_rollback'; } // Start the transaction comment creation $this->startTransaction(); $oThread->setState($iStateId); if ($iStateId == DISCUSSION_CLOSED) { $oThread->setCloseMetadataVersion($this->oDocument->getMetadataVersion()); } else { if ($iStateId == DISCUSSION_CONCLUSION) { $oThread->setCloseReason($sReason); } } $oDocumentTransaction = new DocumentTransaction($this->oDocument, $sReason, $sTransactionNamespace); $oDocumentTransaction->create(); $res = $oThread->update(); $aErrorOptions['message'] = _kt("There was an error updating the thread with the new comment"); $this->oValidator->notError($res, $aErrorOptions); // Thread closed correctly, so commit $this->commitTransaction(); $this->successRedirectTo('viewThread', _kt("Thread state changed"), sprintf('fDocumentId=%d&fThreadId=%d', $this->oDocument->getId(), $oThread->getId())); exit(0); }
function move($oDocument, $oToFolder, $oUser = null, $sReason = null) { //make sure we move the symlink, and the document it's linking to if ($oDocument->isSymbolicLink()) { $oDocument->switchToRealCore(); } else { $oDocument->switchToLinkedCore(); } $oFolder = $oToFolder; // alias. $oOriginalFolder = Folder::get($oDocument->getFolderId()); $iOriginalFolderPermissionObjectId = $oOriginalFolder->getPermissionObjectId(); $iDocumentPermissionObjectId = $oDocument->getPermissionObjectId(); if ($iDocumentPermissionObjectId === $iOriginalFolderPermissionObjectId) { $oDocument->setPermissionObjectId($oFolder->getPermissionObjectId()); } //put the document in the new folder $oDocument->setFolderID($oFolder->getId()); $sName = $oDocument->getName(); $sFilename = $oDocument->getFileName(); $oDocument->setFileName(KTDocumentUtil::getUniqueFilename($oToFolder, $sFilename)); $oDocument->setName(KTDocumentUtil::getUniqueDocumentName($oToFolder, $sName)); $res = $oDocument->update(); if (PEAR::isError($res)) { return $res; } //move the document on the file system(not if it's a symlink) if (!$oDocument->isSymbolicLink()) { $oStorage =& KTStorageManagerUtil::getSingleton(); $res = $oStorage->moveDocument($oDocument, $oFolder, $oOriginalFolder); if (PEAR::isError($res) || $res === false) { $oDocument->setFolderID($oOriginalFolder->getId()); $res = $oDocument->update(); if (PEAR::isError($res)) { return $res; } return $res; // we failed, bail. } } $sMoveMessage = sprintf(_kt("Moved from %s/%s to %s/%s. %s"), $oOriginalFolder->getFullPath(), $oOriginalFolder->getName(), $oFolder->getFullPath(), $oFolder->getName(), $sReason); // create the document transaction record $oDocumentTransaction = new DocumentTransaction($oDocument, $sMoveMessage, 'ktcore.transactions.move'); $oDocumentTransaction->create(); $oKTTriggerRegistry = KTTriggerRegistry::getSingleton(); $aTriggers = $oKTTriggerRegistry->getTriggers('moveDocument', 'postValidate'); foreach ($aTriggers as $aTrigger) { $sTrigger = $aTrigger[0]; $oTrigger = new $sTrigger(); $aInfo = array('document' => $oDocument, 'old_folder' => $oOriginalFolder, 'new_folder' => $oFolder); $oTrigger->setInfo($aInfo); $ret = $oTrigger->postValidate(); if (PEAR::isError($ret)) { return $ret; } } // fire subscription alerts for the moved document $oSubscriptionEvent = new SubscriptionEvent(); $oSubscriptionEvent->MoveDocument($oDocument, $oFolder, $oOriginalFolder); return KTPermissionUtil::updatePermissionLookup($oDocument); }
function restore($iDocId) { // Get the document object $oDoc = Document::get($iDocId); if (PEAR::isError($oDoc) || $oDoc === false) { return $oDoc; } $this->startTransaction(); $iRestoreFolder = $oDoc->getRestoreFolderId(); $oFolder = Folder::get($iRestoreFolder); // move to root if parent no longer exists. if (PEAR::isError($oFolder)) { $oDoc->setFolderId(1); $oFolder = Folder::get(1); } else { $oDoc->setFolderId($iRestoreFolder); } $oStorage = KTStorageManagerUtil::getSingleton(); if ($oStorage->restore($oDoc)) { $oDoc = Document::get($iDocId); // storage path has changed for most recent object... $oDoc->setStatusId(LIVE); $oDoc->setPermissionObjectId($oFolder->getPermissionObjectId()); $res = $oDoc->update(); if (PEAR::isError($res) || $res == false) { return $res; } $res = KTPermissionUtil::updatePermissionLookup($oDoc); if (PEAR::isError($res)) { return $res; } // create a doc-transaction. $oTransaction = new DocumentTransaction($oDoc, sprintf(_kt("Restored from deleted state by %s"), $this->oUser->getName()), 'ktcore.transactions.update'); $oTransaction->create(); } $this->commitTransaction(); return true; }