|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* This file contains only the TopEdits class. |
|
4
|
|
|
*/ |
|
5
|
|
|
|
|
6
|
|
|
namespace Xtools; |
|
7
|
|
|
|
|
8
|
|
|
use Symfony\Component\DependencyInjection\Container; |
|
9
|
|
|
use DateTime; |
|
10
|
|
|
|
|
11
|
|
|
/** |
|
12
|
|
|
* TopEdits returns the top-edited pages by a user. There is not a separate |
|
13
|
|
|
* repository because there is only one query :) |
|
14
|
|
|
*/ |
|
15
|
|
|
class TopEdits extends Model |
|
16
|
|
|
{ |
|
17
|
|
|
/** @var Project The project. */ |
|
18
|
|
|
protected $project; |
|
19
|
|
|
|
|
20
|
|
|
/** @var User The user. */ |
|
21
|
|
|
protected $user; |
|
22
|
|
|
|
|
23
|
|
|
/** @var string[] Top edits object for quick caching, keyed by namespace ID. */ |
|
24
|
|
|
protected $topEdits = []; |
|
25
|
|
|
|
|
26
|
|
|
/** @var int Number of rows to fetch. */ |
|
27
|
|
|
protected $limit; |
|
28
|
|
|
|
|
29
|
|
|
/** @var int Which namespace we are querying for. */ |
|
30
|
|
|
protected $namespace; |
|
31
|
|
|
|
|
32
|
|
|
const DEFAULT_LIMIT_SINGLE_NAMESPACE = 100; |
|
33
|
|
|
const DEFAULT_LIMIT_ALL_NAMESPACES = 20; |
|
34
|
|
|
|
|
35
|
|
|
/** |
|
36
|
|
|
* TopEdits constructor. |
|
37
|
|
|
* @param Project $project |
|
38
|
|
|
* @param User $user |
|
39
|
|
|
* @param string|int Namespace ID or 'all'. |
|
40
|
|
|
* @param int $limit Number of rows to fetch. This defaults to |
|
41
|
|
|
* DEFAULT_LIMIT_SINGLE_NAMESPACE if $this->namespace is a single namespace (int), |
|
42
|
|
|
* and DEFAULT_LIMIT_ALL_NAMESPACES if $this->namespace is 'all'. |
|
43
|
|
|
*/ |
|
44
|
|
|
public function __construct(Project $project, User $user, $namespace = 0, $limit = null) |
|
45
|
|
|
{ |
|
46
|
|
|
$this->project = $project; |
|
47
|
|
|
$this->user = $user; |
|
48
|
|
|
$this->namespace = $namespace === 'all' ? 'all' : (int)$namespace; |
|
|
|
|
|
|
49
|
|
|
|
|
50
|
|
|
if ($limit) { |
|
|
|
|
|
|
51
|
|
|
$this->limit = $limit; |
|
52
|
|
|
} else { |
|
53
|
|
|
$this->limit = $this->namespace === 'all' |
|
54
|
|
|
? self::DEFAULT_LIMIT_ALL_NAMESPACES |
|
55
|
|
|
: self::DEFAULT_LIMIT_SINGLE_NAMESPACE; |
|
56
|
|
|
} |
|
57
|
|
|
} |
|
58
|
|
|
|
|
59
|
|
|
/** |
|
60
|
|
|
* Get the limit set on number of rows to fetch. |
|
61
|
|
|
* @return int |
|
62
|
|
|
*/ |
|
63
|
|
|
public function getLimit() |
|
64
|
|
|
{ |
|
65
|
|
|
return $this->limit; |
|
66
|
|
|
} |
|
67
|
|
|
|
|
68
|
|
|
/** |
|
69
|
|
|
* Get the namespace set on the instance. |
|
70
|
|
|
* @return int|string Namespace ID or 'all'. |
|
71
|
|
|
*/ |
|
72
|
|
|
public function getNamespace() |
|
73
|
|
|
{ |
|
74
|
|
|
return $this->namespace; |
|
75
|
|
|
} |
|
76
|
|
|
|
|
77
|
|
|
/** |
|
78
|
|
|
* Get the top edits by a user in the given namespace, or 'all' namespaces. |
|
79
|
|
|
* This is the public function that should be used. |
|
80
|
|
|
* @return string[] Results of self::getTopEditsByNamespace(), keyed by namespace. |
|
81
|
|
|
*/ |
|
82
|
|
|
public function getTopEdits() |
|
83
|
|
|
{ |
|
84
|
|
|
if (count($this->topEdits) > 0) { |
|
85
|
|
|
return $this->topEdits; |
|
86
|
|
|
} |
|
87
|
|
|
|
|
88
|
|
|
if ($this->namespace === 'all') { |
|
|
|
|
|
|
89
|
|
|
$pages = $this->getRepository()->getTopEditsAllNamespaces( |
|
|
|
|
|
|
90
|
|
|
$this->project, |
|
91
|
|
|
$this->user, |
|
92
|
|
|
$this->limit |
|
93
|
|
|
); |
|
94
|
|
|
} else { |
|
95
|
|
|
$pages = $this->getRepository()->getTopEditsNamespace( |
|
96
|
|
|
$this->project, |
|
97
|
|
|
$this->user, |
|
98
|
|
|
$this->namespace, |
|
99
|
|
|
$this->limit |
|
100
|
|
|
); |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
$this->topEdits = $this->formatTopPages($pages); |
|
104
|
|
|
return $this->topEdits; |
|
105
|
|
|
} |
|
106
|
|
|
|
|
107
|
|
|
/** |
|
108
|
|
|
* [formatTopPages description] |
|
109
|
|
|
* @param string[] $pages As returned by TopEditsRepository::getTopEditsNamespace |
|
110
|
|
|
* or TopEditsRepository::getTopEditsAllNamespaces. |
|
111
|
|
|
* @return string[] Same as input but with 'displaytitle', and 'page_title_ns'. |
|
112
|
|
|
*/ |
|
113
|
|
|
private function formatTopPages($pages) |
|
114
|
|
|
{ |
|
115
|
|
|
/** @var string[] The top edited pages, keyed by namespace ID. */ |
|
116
|
|
|
$topEditedPages = []; |
|
117
|
|
|
|
|
118
|
|
|
/** @var string[] Display titles of the pages, which need to be fetched ahead of time. */ |
|
119
|
|
|
$displayTitles = $this->getDisplayTitles($pages); |
|
120
|
|
|
|
|
121
|
|
|
foreach ($pages as $page) { |
|
122
|
|
|
$nsId = (int) $page['page_namespace']; |
|
123
|
|
|
$nsTitle = $nsId > 0 ? $this->project->getNamespaces()[$page['page_namespace']] . ':' : ''; |
|
124
|
|
|
$pageTitle = $nsTitle . $page['page_title']; |
|
125
|
|
|
$page['displaytitle'] = $displayTitles[$pageTitle]; |
|
126
|
|
|
|
|
127
|
|
|
// $page['page_title'] is retained without the namespace |
|
128
|
|
|
// so we can link to TopEdits for that page. |
|
129
|
|
|
$page['page_title_ns'] = $pageTitle; |
|
130
|
|
|
|
|
131
|
|
|
if (isset($topEditedPages[$nsId])) { |
|
132
|
|
|
$topEditedPages[$nsId][] = $page; |
|
133
|
|
|
} else { |
|
134
|
|
|
$topEditedPages[$nsId] = [$page]; |
|
135
|
|
|
} |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
return $topEditedPages; |
|
139
|
|
|
} |
|
140
|
|
|
|
|
141
|
|
|
/** |
|
142
|
|
|
* Get the display titles of the given pages. |
|
143
|
|
|
* @param string[] $topPages As returned by $this->getRepository()->getTopEdits() |
|
144
|
|
|
* @return string[] Keys are the original supplied titles, and values are the display titles. |
|
145
|
|
|
*/ |
|
146
|
|
|
private function getDisplayTitles($topPages) |
|
147
|
|
|
{ |
|
148
|
|
|
$namespaces = $this->project->getNamespaces(); |
|
149
|
|
|
|
|
150
|
|
|
// First extract page titles including namespace. |
|
151
|
|
|
$pageTitles = array_map(function ($page) use ($namespaces) { |
|
152
|
|
|
// If non-mainspace, prepend namespace to the titles. |
|
153
|
|
|
$ns = $page['page_namespace']; |
|
154
|
|
|
$nsTitle = $ns > 0 ? $namespaces[$page['page_namespace']] . ':' : ''; |
|
155
|
|
|
return $nsTitle . $page['page_title']; |
|
156
|
|
|
}, $topPages); |
|
157
|
|
|
|
|
158
|
|
|
return $this->getRepository()->getDisplayTitles($this->project, $pageTitles); |
|
|
|
|
|
|
159
|
|
|
} |
|
160
|
|
|
} |
|
161
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountIdthat can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theidproperty of an instance of theAccountclass. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.