Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Admin/Controller/Forum.php
<?php

namespace XF\Admin\Controller;

use
XF\Mvc\FormAction;
use
XF\Mvc\ParameterBag;

use function
in_array;

class
Forum extends AbstractNode
{
    protected function
preDispatchController($action, ParameterBag $params)
    {
        switch (
strtolower($action))
        {
            case
'index':
                break;

            default:
               
parent::preDispatchController($action, $params);
        }
    }

    public function
actionIndex()
    {
       
$this->setSectionContext('forums');

        return
$this->plugin('XF:AdminSection')->actionView('forums');
    }

    protected function
getNodeTypeId()
    {
        return
'Forum';
    }

    protected function
getDataParamName()
    {
        return
'forum';
    }

    protected function
getTemplatePrefix()
    {
        return
'forum';
    }

    protected function
getViewClassPrefix()
    {
        return
'XF:Forum';
    }

    protected function
nodeAddEdit(\XF\Entity\Node $node)
    {
       
$forumType = $this->getForumTypeHandlerForAddEdit($node);
        if (!
$forumType)
        {
            if (
$node->exists())
            {
                return
$this->error(\XF::phrase('forum_type_handler_not_found'));
            }
            else
            {
               
$params = [
                   
'node_type_id' => 'Forum',
                   
'parent_node_id' => $node->parent_node_id
               
];
                return
$this->redirect($this->buildLink('nodes/add', null, $params));
            }
        }

        if (!
$node->exists() && !$forumType->canManuallyCreateForum())
        {
            return
$this->error(\XF::phrase('forums_of_this_type_cannot_be_manually_created'));
        }

       
$reply = parent::nodeAddEdit($node);

        if (
$reply instanceof \XF\Mvc\Reply\View)
        {
           
/** @var \XF\Repository\ThreadField $fieldRepo */
           
$fieldRepo = $this->repository('XF:ThreadField');
           
$availableFields = $fieldRepo->findFieldsForList()->fetch();

           
/** @var \XF\Repository\ThreadPrefix $prefixRepo */
           
$prefixRepo = $this->repository('XF:ThreadPrefix');
           
$availablePrefixes = $prefixRepo->findPrefixesForList()->fetch()->pluckNamed('title', 'prefix_id');
           
$prefixListData = $prefixRepo->getPrefixListData();

           
/** @var \XF\Repository\ThreadPrompt $promptRepo */
           
$promptRepo = $this->repository('XF:ThreadPrompt');
           
$availablePrompts = $promptRepo->findPromptsForList()->fetch()->pluckNamed('title', 'prompt_id');
           
$promptListData = $promptRepo->getPromptListData();

           
/** @var \XF\Entity\Forum $forum */
           
$forum = $node->getDataRelationOrDefault(false);
            if (!
$forum->exists())
            {
               
$forum->forum_type_id = $forumType->getTypeId();
            }

           
$reply->setParams([
               
'availableFields' => $availableFields,

               
'availablePrefixes' => $availablePrefixes,

               
'availablePrompts' => $availablePrompts,

               
'prefixGroups' => $prefixListData['prefixGroups'],
               
'prefixesGrouped' => $prefixListData['prefixesGrouped'],

               
'promptGroups' => $promptListData['promptGroups'],
               
'promptsGrouped' => $promptListData['promptsGrouped'],

               
'sortOptions' => $forumType->getThreadListSortOptions($forum, true),

               
'forumType' => $forumType,
               
'forumTypeId' => $forumType->getTypeId(),
               
'forumTypeTitle' => $forumType->getTypeTitle(),
               
'forumTypeDesc' => $forumType->getTypeDescription(),
               
'canChangeForumType' => $forumType->canChangeForumType($forum)
            ]);

           
$typeConfig = $forum->type_config;
           
$typeConfigTemplate = $forumType->setupTypeConfigEdit($reply, $node, $forum, $typeConfig);

           
$reply->setParam('typeConfig', $typeConfig);
            if (
$typeConfigTemplate)
            {
               
$reply->setParam('typeConfigTemplate', $typeConfigTemplate);
            }
        }

        return
$reply;
    }

    protected function
saveTypeData(FormAction $form, \XF\Entity\Node $node, \XF\Entity\AbstractNode $data)
    {
       
$forumType = $this->getForumTypeHandlerForAddEdit($node);
        if (!
$forumType)
        {
           
$form->logError(\XF::phrase('forum_type_handler_not_found'), 'forum_type_id');
            return;
        }

       
$forumInput = $this->filter([
           
'allow_posting' => 'bool',
           
'moderate_threads' => 'bool',
           
'moderate_replies' => 'bool',
           
'count_messages' => 'bool',
           
'find_new' => 'bool',
           
'allowed_watch_notifications' => 'str',
           
'default_sort_order' => 'str',
           
'default_sort_direction' => 'str',
           
'list_date_limit_days' => 'uint',
           
'default_prefix_id' => 'uint',
           
'require_prefix' => 'bool',
           
'min_tags' => 'uint',
           
'allow_index' => 'str'
       
]);

       
$forumInput['index_criteria'] = $this->filterIndexCriteria();

       
/** @var \XF\Entity\Forum $data */
       
$data->bulkSet($forumInput);
       
$data->forum_type_id = $forumType->getTypeId();

       
$typeConfig = $forumType->setupTypeConfigSave($form, $node, $data, $this->request);
        if (
$typeConfig instanceof \XF\Mvc\Entity\ArrayValidator)
        {
            if (
$typeConfig->hasErrors())
            {
               
$form->logErrors($typeConfig->getErrors());
            }
           
$typeConfig = $typeConfig->getValuesForced();
        }

       
$data->type_config = $typeConfig;

       
$prefixIds = $this->filter('available_prefixes', 'array-uint');
       
$form->complete(function() use($data, $prefixIds)
        {
           
/** @var \XF\Repository\ForumPrefix $repo */
           
$repo = $this->repository('XF:ForumPrefix');
           
$repo->updateContentAssociations($data->node_id, $prefixIds);
        });

        if (!
in_array($data->default_prefix_id, $prefixIds))
        {
           
$data->default_prefix_id = 0;
        }

       
$fieldIds = $this->filter('available_fields', 'array-str');
       
$form->complete(function () use ($data, $fieldIds)
        {
           
/** @var \XF\Repository\ForumField $repo */
           
$repo = $this->repository('XF:ForumField');
           
$repo->updateContentAssociations($data->node_id, $fieldIds);
        });

       
$promptIds = $this->filter('available_prompts', 'array-uint');
       
$form->complete(function() use($data, $promptIds)
        {
           
/** @var \XF\Repository\ForumPrompt $repo */
           
$repo = $this->repository('XF:ForumPrompt');
           
$repo->updateContentAssociations($data->node_id, $promptIds);
        });
    }

   
/**
     * @return array
     */
   
protected function filterIndexCriteria()
    {
       
$criteria = [];

       
$input = $this->filterArray(
           
$this->filter('index_criteria', 'array'),
            [
               
'max_days_post' => [
                   
'enabled' => 'bool',
                   
'value' => 'posint'
               
],
               
'max_days_last_post' => [
                   
'enabled' => 'bool',
                   
'value' => 'posint'
               
],
               
'min_replies' => [
                   
'enabled' => 'bool',
                   
'value' => 'posint'
               
],
               
'min_reaction_score' => [
                   
'enabled' => 'bool',
                   
'value' => 'int'
               
]
            ]
        );

        foreach (
$input AS $rule => $criterion)
        {
            if (!
$criterion['enabled'])
            {
                continue;
            }

           
$criteria[$rule] = $criterion['value'];
        }

        return
$criteria;
    }

   
/**
     * @param \XF\Entity\Node $node
     *
     * @return \XF\ForumType\AbstractHandler|null
     */
   
protected function getForumTypeHandlerForAddEdit(\XF\Entity\Node $node)
    {
       
/** @var \XF\Entity\Forum $forum */
       
$forum = $node->getDataRelationOrDefault(false);

        if (!
$node->exists())
        {
           
$forumTypeId = $this->filter('forum_type_id', 'str');
            return
$this->app->forumType($forumTypeId, false);
        }
        else
        {
            return
$forum->TypeHandler;
        }
    }

    public function
actionPrefixes(ParameterBag $params)
    {
       
$this->assertPostOnly();

       
$viewParams = [];

       
$nodeId = $this->filter('val', 'uint');
        if (
$nodeId)
        {
           
/** @var \XF\Entity\Forum $forum */
           
$node = $this->assertNodeExists($nodeId);
           
$forum = $node->getDataRelationOrDefault(false);

           
$viewParams['forum'] = $forum;
           
$viewParams['prefixes'] = $forum->getPrefixesGrouped();
        }

        return
$this->view('XF:Forum\Prefixes', 'public:forum_prefixes', $viewParams);
    }

    public function
actionChangeType(ParameterBag $params)
    {
       
$node = $this->assertNodeExists($params->node_id);

       
/** @var \XF\Entity\Forum $forum */
       
$forum = $node->Data;

       
$newForumTypeId = $this->filter('new_forum_type_id', 'str');
       
$newForumType = $newForumTypeId ? $this->app->forumType($newForumTypeId, false) : null;

       
$currentForumType = $forum->TypeHandler;

        if (!
$currentForumType->canChangeForumType($forum))
        {
            return
$this->error(\XF::phrase('this_forums_type_cannot_be_changed'));
        }

        if (
$newForumType && $newForumType->getTypeId() == $currentForumType->getTypeId())
        {
            return
$this->error(\XF::phrase('forum_is_already_that_type'));
        }

        if (
$newForumType && !$newForumType->canManuallyCreateForum())
        {
            return
$this->error(\XF::phrase('forums_of_this_type_cannot_be_manually_created'));
        }

       
$viewParams = [
           
'node' => $node,
           
'forum' => $forum,

           
'currentForumTypeId' => $currentForumType->getTypeId(),
           
'currentForumTypeTitle' => $currentForumType->getTypeTitle(),
           
'currentForumTypeDesc' => $currentForumType->getTypeDescription()
        ];

        if (
$newForumType && $this->isPost() && $this->filter('confirm', 'bool'))
        {
           
// actually change the type
           
$currentDefaultThreadType = $currentForumType->getDefaultThreadType($forum);

           
$form = $this->formAction();

           
$typeConfig = $newForumType->setupTypeConfigSave($form, $node, $forum, $this->request);
            if (
$typeConfig instanceof \XF\Mvc\Entity\ArrayValidator)
            {
                if (
$typeConfig->hasErrors())
                {
                   
$form->logErrors($typeConfig->getErrors());
                }
               
$typeConfig = $typeConfig->getValuesForced();
            }

           
$form->basicEntitySave($forum, [
               
'forum_type_id' => $newForumType->getTypeId(),
               
'type_config' => $typeConfig
           
]);
           
$form->run();

           
$this->app->jobManager()->enqueueUnique(
               
"changeForumType{$forum->node_id}{$newForumTypeId}",
               
'XF:ForumChangeThreadTypes',
                [
                   
'node_id' => $forum->node_id,
                   
'old_default_type' => $currentDefaultThreadType
               
]
            );

            return
$this->redirect($this->buildLink('nodes') . $this->buildLinkHash($node->node_id));
        }
        else if (
$newForumType)
        {
           
// display the type config form
           
$viewParams += [
               
'isTypeChange' => true,
               
'newForumTypeId' => $newForumType->getTypeId(),
               
'newForumTypeTitle' => $newForumType->getTypeTitle(),
               
'newForumTypeDesc' => $newForumType->getTypeDescription()
            ];
           
$reply = $this->view('XF:Forum\ChangeType', 'forum_change_type', $viewParams);

           
$typeConfig = $newForumType->getDefaultTypeConfig();
           
$typeConfigTemplate = $newForumType->setupTypeConfigEdit($reply, $node, $forum, $typeConfig);

           
$reply->setParam('typeConfig', $typeConfig);
            if (
$typeConfigTemplate)
            {
               
$reply->setParam('typeConfigTemplate', $typeConfigTemplate);
            }

            return
$reply;
        }
        else
        {
           
// display the type selection
           
$viewParams['forumTypesInfo'] = $this->repository('XF:ForumType')->getForumTypesList(
                \
XF\Repository\ForumType::FILTER_MANUAL_CREATE
           
);

            return
$this->view('XF:Forum\ChangeType', 'forum_change_type', $viewParams);
        }
    }

    public function
actionSuggestionConvertReactions(ParameterBag $params)
    {
       
$node = $this->assertNodeExists($params->node_id);

       
/** @var \XF\Entity\Forum $forum */
       
$forum = $node->Data;

        if (!(
$forum->TypeHandler instanceof \XF\ForumType\Suggestion))
        {
            return
$this->notFound();
        }

        if (
$this->isPost())
        {
           
$this->app->jobManager()->enqueueUnique(
               
"suggestionConvertReactions{$node->node_id}",
               
'XF:SuggestionConvertReactions',
                [
'node_id' => $node->node_id]
            );

            return
$this->redirect($this->buildLink('nodes') . $this->buildLinkHash($node->node_id));
        }
        else
        {
           
$viewParams = [
               
'node' => $node,
               
'forum' => $forum,
            ];
            return
$this->view(
               
'XF:Forum\SuggestionConvertReactions', 'forum_suggestion_convert_reactions', $viewParams
           
);
        }
    }
}