Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
LinkRecommendation
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 9
110
0.00% covered (danger)
0.00%
0 / 1
 getLinksFromArray
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
6
 getMetadataFromArray
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 __construct
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 getTitle
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getPageId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getRevisionId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getLinks
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getMetadata
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 toArray
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace GrowthExperiments\NewcomerTasks\AddLink;
4
5use GrowthExperiments\NewcomerTasks\Recommendation;
6use MediaWiki\Linker\LinkTarget;
7
8/**
9 * Value object for machine-generated link recommendations. A link recommendation is a set of
10 * suggested LinkRecommendationLinks for a given wiki page.
11 */
12class LinkRecommendation implements Recommendation {
13
14    /**
15     * Fallback timestamp for tasks which have been stored before the code was updated to
16     * record a timestamp. It is 2000-01-01 (chosen arbitrarily as an "old" value).
17     * @internal Exposed for tests, should be treated as private.
18     */
19    public const FALLBACK_TASK_TIMESTAMP = 946713600;
20
21    /** @var LinkTarget */
22    private $title;
23
24    /** @var int */
25    private $pageId;
26
27    /** @var int */
28    private $revisionId;
29
30    /** @var LinkRecommendationLink[] */
31    private $links;
32
33    /** @var LinkRecommendationMetadata */
34    private $metadata;
35
36    /**
37     * Parse a JSON array into a LinkRecommendationLink array. This is more or less the inverse of
38     * toArray(), except it only returns a link list, not a LinkRecommendation.
39     * @param array $array
40     * @return LinkRecommendationLink[]
41     */
42    public static function getLinksFromArray( array $array ): array {
43        // FIXME this should probably live in some de/serializer class, with proper error handling.
44        $links = [];
45        foreach ( $array as $item ) {
46            $links[] = new LinkRecommendationLink(
47                $item['link_text'],
48                $item['link_target'],
49                $item['match_index'],
50                $item['wikitext_offset'],
51                $item['score'],
52                $item['context_before'],
53                $item['context_after'],
54                $item['link_index']
55            );
56        }
57        return $links;
58    }
59
60    /**
61     * Construct a LinkRecommendationMetadata value object with metadata included by the service for a
62     * link recommendation.
63     *
64     * Includes backward compatibility as this method is called when retrieving stored link recommendations
65     * in the cache, which may not have the meta field stored.
66     *
67     * @param array $meta
68     * @return LinkRecommendationMetadata
69     */
70    public static function getMetadataFromArray( array $meta ): LinkRecommendationMetadata {
71        return new LinkRecommendationMetadata(
72            $meta['application_version'] ?? '',
73            $meta['format_version'] ?? 1,
74            $meta['dataset_checksums'] ?? [],
75            $meta['task_timestamp'] ?? self::FALLBACK_TASK_TIMESTAMP
76        );
77    }
78
79    /**
80     * @param LinkTarget $title Page for which the recommendations were generated.
81     * @param int $pageId Page for which the recommendations were generated.
82     * @param int $revisionId Revision ID for which the recommendations were generated.
83     * @param LinkRecommendationLink[] $links List of the recommended links
84     * @param LinkRecommendationMetadata $metadata Metadata associated with the links.
85     */
86    public function __construct(
87        LinkTarget $title,
88        int $pageId,
89        int $revisionId,
90        array $links,
91        LinkRecommendationMetadata $metadata
92    ) {
93        $this->title = $title;
94        $this->pageId = $pageId;
95        $this->revisionId = $revisionId;
96        $this->links = array_values( $links );
97        $this->metadata = $metadata;
98    }
99
100    /** @inheritDoc */
101    public function getTitle(): LinkTarget {
102        return $this->title;
103    }
104
105    /**
106     * Get the ID of the page for which the recommendations were generated.
107     * @return int
108     */
109    public function getPageId(): int {
110        return $this->pageId;
111    }
112
113    /**
114     * Get the revision ID for which the recommendations were generated.
115     * @return int
116     */
117    public function getRevisionId(): int {
118        return $this->revisionId;
119    }
120
121    /**
122     * Get the links recommended for the article.
123     * @return LinkRecommendationLink[]
124     */
125    public function getLinks(): array {
126        return $this->links;
127    }
128
129    /** @return LinkRecommendationMetadata */
130    public function getMetadata(): LinkRecommendationMetadata {
131        return $this->metadata;
132    }
133
134    /**
135     * JSON-ifiable data that represents the state of the object except the page identity and
136     * revision.
137     * @return array[]
138     */
139    public function toArray(): array {
140        return [ 'links' => array_map( static function ( LinkRecommendationLink $linkRecommendationItem ) {
141            return $linkRecommendationItem->toArray();
142        }, $this->links ), 'meta' => $this->metadata->toArray() ];
143    }
144
145}