/** * @param Workflow $workflow * @param IContextSource $context * @param AbstractBlock[] $blocks * @param string $action * @param array $parameters * @return AbstractBlock[] * @throws InvalidActionException * @throws InvalidDataException */ public function handleSubmit(Workflow $workflow, IContextSource $context, array $blocks, $action, array $parameters) { // since this is a submit force dbFactory to always return master $this->dbFactory->forceMaster(); /** @var Block[] $interestedBlocks */ $interestedBlocks = array(); foreach ($blocks as $block) { // This is just a check whether the block understands the action, // Doesn't consider permissions if ($block->canSubmit($action)) { $block->init($context, $action); $interestedBlocks[] = $block; } } if (!$interestedBlocks) { if (!$blocks) { throw new InvalidDataException('No Blocks?!?', 'fail-load-data'); } $type = array(); foreach ($blocks as $block) { $type[] = get_class($block); } // All blocks returned null, nothing knows how to handle this action throw new InvalidActionException("No block accepted the '{$action}' action: " . implode(',', array_unique($type)), 'invalid-action'); } // Check mediawiki core permissions for title protection, blocked // status, etc. if (!$workflow->userCan('edit', $context->getUser())) { reset($interestedBlocks)->addError('block', wfMessage('blockedtitle')); return array(); } $success = true; foreach ($interestedBlocks as $block) { $name = $block->getName(); $data = isset($parameters[$name]) ? $parameters[$name] : array(); $success &= $block->onSubmit($data); } return $success ? $interestedBlocks : array(); }
/** * Collects the workflow and header (if it exists) and puts them into the database. Does * not commit yet. It is intended for prepareMove to be called from the TitleMove hook, * and committed from TitleMoveComplete hook. This ensures that if some error prevents the * core transaction from committing this transaction is also not committed. * * @param int $oldPageId Page ID before move/change * @param Title $newPage Page after move/change */ public function prepareMove($oldPageId, Title $newPage) { if ($this->dbw !== null) { throw new FlowException("Already prepared for move from {$oldPageId} to {$newPage->getArticleID()}"); } // All reads must go through master to help ensure consistency $this->dbFactory->forceMaster(); // Open a transaction, this will be closed from self::commit. $this->dbw = $this->dbFactory->getDB(DB_MASTER); $this->dbw->begin(); $this->cache->begin(); // @todo this loads every topic workflow this board has ever seen, // would prefer to update db directly but that won't work due to // the caching layer not getting updated. After dropping Flow\Data\Index\* // revisit this. $found = $this->storage->find('Workflow', array('workflow_wiki' => wfWikiId(), 'workflow_page_id' => $oldPageId)); if (!$found) { throw new FlowException("Could not locate workflow for {$oldPageId}"); } $discussionWorkflow = null; foreach ($found as $workflow) { if ($workflow->getType() === 'discussion') { $discussionWorkflow = $workflow; } $workflow->updateFromPageId($oldPageId, $newPage); $this->storage->put($workflow, array()); } if ($discussionWorkflow === null) { throw new FlowException("Main discussion workflow for {$oldPageId} not found"); } $found = $this->storage->find('Header', array('rev_type_id' => $discussionWorkflow->getId()), array('sort' => 'rev_id', 'order' => 'DESC', 'limit' => 1)); if ($found) { $this->header = reset($found); $nextHeader = $this->header->newNextRevision($this->nullEditUser, $this->header->getContentRaw(), $this->header->getContentFormat(), 'edit-header', $newPage); $this->storage->put($nextHeader, array('workflow' => $discussionWorkflow)); } }