Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
66.67% covered (warning)
66.67%
20 / 30
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
StaticTaskSuggester
66.67% covered (warning)
66.67%
20 / 30
50.00% covered (danger)
50.00%
2 / 4
17.33
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 suggest
82.35% covered (warning)
82.35%
14 / 17
0.00% covered (danger)
0.00%
0 / 1
9.45
 filter
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 getTopicIds
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace GrowthExperiments\NewcomerTasks\TaskSuggester;
4
5use GrowthExperiments\NewcomerTasks\Task\Task;
6use GrowthExperiments\NewcomerTasks\Task\TaskSet;
7use GrowthExperiments\NewcomerTasks\Task\TaskSetFilters;
8use GrowthExperiments\NewcomerTasks\Topic\Topic;
9use MediaWiki\Title\TitleFactory;
10use MediaWiki\User\UserIdentity;
11use Wikimedia\Assert\Assert;
12
13/**
14 * A TaskSuggester which always starts with the same preconfigured set of tasks, and applies
15 * filter/limit/offset to them. Intended for testing and local frontend development.
16 */
17class StaticTaskSuggester implements TaskSuggester {
18
19    /** @var Task[] */
20    private $tasks;
21    /**
22     * @var TitleFactory|null
23     */
24    private $titleFactory;
25
26    /**
27     * @param Task[] $tasks
28     * @param TitleFactory|null $titleFactory
29     */
30    public function __construct( array $tasks, ?TitleFactory $titleFactory = null ) {
31        Assert::parameterElementType( Task::class, $tasks, '$suggestions' );
32        $this->tasks = $tasks;
33        $this->titleFactory = $titleFactory;
34    }
35
36    /** @inheritDoc */
37    public function suggest(
38        UserIdentity $user,
39        TaskSetFilters $taskSetFilters,
40        ?int $limit = null,
41        ?int $offset = null,
42        array $options = []
43    ) {
44        $filteredTasks = array_filter( $this->tasks,
45            function ( Task $task ) use ( $taskSetFilters, $options ) {
46                if ( isset( $options['excludePageIds'] ) && $this->titleFactory instanceof TitleFactory ) {
47                    $title = $this->titleFactory->castFromLinkTarget( $task->getTitle() );
48                    if ( in_array( $title->getArticleID(), $options['excludePageIds'] ) ) {
49                        return false;
50                    }
51                }
52                $taskTypeFilter = $taskSetFilters->getTaskTypeFilters();
53                $topicFilter = $taskSetFilters->getTopicFilters();
54                if ( $taskTypeFilter && !in_array( $task->getTaskType()->getId(), $taskTypeFilter, true ) ) {
55                    return false;
56                } elseif ( $topicFilter && !array_intersect( $this->getTopicIds( $task ), $topicFilter ) ) {
57                    return false;
58                }
59                return true;
60            }
61        );
62        return new TaskSet( array_slice( $filteredTasks, $offset ?? 0, $limit ),
63            count( $filteredTasks ), $offset ?: 0, new TaskSetFilters() );
64    }
65
66    /** @inheritDoc */
67    public function filter( UserIdentity $user, TaskSet $taskSet ) {
68        $tasks = array_filter( iterator_to_array( $taskSet ), function ( Task $task ) {
69            return in_array( $task, $this->tasks, true );
70        } );
71        $newTaskSet = new TaskSet( $tasks, $taskSet->getTotalCount(), $taskSet->getOffset(),
72            $taskSet->getFilters() );
73        $newTaskSet->setDebugData( $taskSet->getDebugData() );
74        return $newTaskSet;
75    }
76
77    /**
78     * @param Task $task
79     * @return string[]
80     */
81    private function getTopicIds( Task $task ) {
82        return array_map( static function ( Topic $topic ) {
83            return $topic->getId();
84        }, $task->getTopics() );
85    }
86
87}