/** * @param FormatterRow $row * @return array * @throws FlowException */ public function buildActions(FormatterRow $row) { $user = $this->permissions->getUser(); $workflow = $row->workflow; $title = $workflow->getArticleTitle(); // If a user is blocked from performing actions on this page return // an empty array of actions. // // We only check actual users and not anon's because the anonymous // version can be cached and served to many different ip addresses // which will not all be blocked. if (!$user->isAnon() && ($user->isBlockedFrom($title, true) || !$title->quickUserCan('edit', $user))) { return array(); } $revision = $row->revision; $action = $revision->getChangeType(); $workflowId = $workflow->getId(); $revId = $revision->getRevisionId(); $postId = method_exists($revision, 'getPostId') ? $revision->getPostId() : null; $actionTypes = $this->permissions->getActions()->getValue($action, 'actions'); if ($actionTypes === null) { wfDebugLog('Flow', __METHOD__ . ": No actions defined for action: {$action}"); return array(); } // actions primarily vary by revision type... $links = array(); foreach ($actionTypes as $type) { if (!$this->permissions->isAllowed($revision, $type)) { continue; } switch ($type) { case 'thank': if (class_exists('ThanksHooks') && !$user->isAnon() && $revision instanceof PostRevision && $revision->getCreatorId() > 0 && $user->getId() !== $revision->getCreatorId()) { $links['thank'] = $this->urlGenerator->thankAction($postId); } break; case 'reply': if (!$postId) { throw new FlowException("{$type} called without \$postId"); } elseif (!$revision instanceof PostRevision) { throw new FlowException("{$type} called without PostRevision object"); } /* * If the post being replied to is the most recent post * of its depth, the reply link should point to parent */ $replyToId = $postId; $replyToRevision = $revision; if ($row->isLastReply) { $replyToId = $replyToRevision->getReplyToId(); $replyToRevision = PostCollection::newFromId($replyToId)->getLastRevision(); } /* * If the post being replied to is at or exceeds the max * threading depth, the reply link should point to parent. */ while ($replyToRevision->getDepth() >= $this->maxThreadingDepth) { $replyToId = $replyToRevision->getReplyToId(); $replyToRevision = PostCollection::newFromId($replyToId)->getLastRevision(); } $links['reply'] = $this->urlGenerator->replyAction($title, $workflowId, $replyToId, $revision->isTopicTitle()); break; case 'edit-header': $links['edit'] = $this->urlGenerator->editHeaderAction($title, $workflowId, $revId); break; case 'edit-title': if (!$postId) { throw new FlowException("{$type} called without \$postId"); } $links['edit'] = $this->urlGenerator->editTitleAction($title, $workflowId, $postId, $revId); break; case 'edit-post': if (!$postId) { throw new FlowException("{$type} called without \$postId"); } $links['edit'] = $this->urlGenerator->editPostAction($title, $workflowId, $postId, $revId); break; case 'undo-edit-header': case 'undo-edit-post': case 'undo-edit-topic-summary': if (!$revision->isFirstRevision()) { $links['undo'] = $this->urlGenerator->undoAction($revision, $title, $workflowId); } break; case 'hide-post': if (!$postId) { throw new FlowException("{$type} called without \$postId"); } $links['hide'] = $this->urlGenerator->hidePostAction($title, $workflowId, $postId); break; case 'delete-topic': $links['delete'] = $this->urlGenerator->deleteTopicAction($title, $workflowId); break; case 'delete-post': if (!$postId) { throw new FlowException("{$type} called without \$postId"); } $links['delete'] = $this->urlGenerator->deletePostAction($title, $workflowId, $postId); break; case 'suppress-topic': $links['suppress'] = $this->urlGenerator->suppressTopicAction($title, $workflowId); break; case 'suppress-post': if (!$postId) { throw new FlowException("{$type} called without \$postId"); } $links['suppress'] = $this->urlGenerator->suppressPostAction($title, $workflowId, $postId); break; case 'lock-topic': // lock topic link is only available to topics if (!$revision instanceof PostRevision || !$revision->isTopicTitle()) { continue; } $links['lock'] = $this->urlGenerator->lockTopicAction($title, $workflowId); break; case 'restore-topic': $moderateAction = $flowAction = null; switch ($revision->getModerationState()) { case AbstractRevision::MODERATED_LOCKED: $moderateAction = 'unlock'; $flowAction = 'lock-topic'; break; case AbstractRevision::MODERATED_HIDDEN: case AbstractRevision::MODERATED_DELETED: case AbstractRevision::MODERATED_SUPPRESSED: $moderateAction = 'un' . $revision->getModerationState(); $flowAction = 'moderate-topic'; break; } if (isset($moderateAction) && $moderateAction) { $links[$moderateAction] = $this->urlGenerator->restoreTopicAction($title, $workflowId, $moderateAction, $flowAction); } break; case 'restore-post': if (!$postId) { throw new FlowException("{$type} called without \$postId"); } $moderateAction = $flowAction = null; switch ($revision->getModerationState()) { case AbstractRevision::MODERATED_HIDDEN: case AbstractRevision::MODERATED_DELETED: case AbstractRevision::MODERATED_SUPPRESSED: $moderateAction = 'un' . $revision->getModerationState(); $flowAction = 'moderate-post'; break; } if ($moderateAction) { $links[$moderateAction] = $this->urlGenerator->restorePostAction($title, $workflowId, $postId, $moderateAction, $flowAction); } break; case 'hide-topic': $links['hide'] = $this->urlGenerator->hideTopicAction($title, $workflowId); break; // Need to use 'edit-topic-summary' to match FlowActions // Need to use 'edit-topic-summary' to match FlowActions case 'edit-topic-summary': // summarize link is only available to topic workflow if (!in_array($workflow->getType(), array('topic', 'topicsummary'))) { continue; } $links['summarize'] = $this->urlGenerator->editTopicSummaryAction($title, $workflowId); break; default: wfDebugLog('Flow', __METHOD__ . ': unkown action link type: ' . $type); break; } } return $links; }
/** * @var IContextSource $context * @var string $action */ public function init(IContextSource $context, $action) { $this->context = $context; $this->action = $action; $this->permissions = Container::get('permissions'); if (!$context->getUser()->equals($this->permissions->getUser())) { throw new PermissionException('Formatting for wrong user: '******' instead of ' . $this->permissions->getUser()->getName()); } }