Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
86.67% |
39 / 45 |
|
77.78% |
7 / 9 |
CRAP | |
0.00% |
0 / 1 |
FilePagination | |
86.67% |
39 / 45 |
|
77.78% |
7 / 9 |
24.25 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
getPageNumber | |
100.00% |
15 / 15 |
|
100.00% |
1 / 1 |
6 | |||
getDisplayedPageNumber | |
40.00% |
2 / 5 |
|
0.00% |
0 / 1 |
2.86 | |||
getNumberOfPages | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getPageTitle | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
3 | |||
buildPageTitle | |
57.14% |
4 / 7 |
|
0.00% |
0 / 1 |
5.26 | |||
buildPageTitleFromPageNumber | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
pageNumberExists | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
isValidInterval | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | |
3 | namespace ProofreadPage\Pagination; |
4 | |
5 | use MediaWiki\Title\Title; |
6 | use OutOfBoundsException; |
7 | |
8 | /** |
9 | * @license GPL-2.0-or-later |
10 | * |
11 | * Pagination of a book based on a multipage file |
12 | */ |
13 | class FilePagination extends Pagination { |
14 | |
15 | /** @var Title */ |
16 | private $indexTitle; |
17 | |
18 | /** |
19 | * @var PageList representation of the <pagelist> tag |
20 | */ |
21 | private $pageList; |
22 | |
23 | /** @var int */ |
24 | private $numberOfPages; |
25 | |
26 | /** |
27 | * @var Title[] cache of build pages of the pagination as $pageNumber => $page array |
28 | */ |
29 | private $pages = []; |
30 | |
31 | /** @var int */ |
32 | private $pageNamespaceId; |
33 | |
34 | /** |
35 | * @param Title $indexTitle |
36 | * @param PageList $pageList representation of the <pagelist> tag that configure page numbers |
37 | * @param int $numberOfPages |
38 | * @param int $pageNamespaceId |
39 | */ |
40 | public function __construct( |
41 | Title $indexTitle, PageList $pageList, int $numberOfPages, int $pageNamespaceId |
42 | ) { |
43 | $this->indexTitle = $indexTitle; |
44 | $this->pageList = $pageList; |
45 | $this->numberOfPages = $numberOfPages; |
46 | $this->pageNamespaceId = $pageNamespaceId; |
47 | } |
48 | |
49 | /** |
50 | * @inheritDoc |
51 | */ |
52 | public function getPageNumber( Title $pageTitle ): int { |
53 | $parts = explode( '/', $pageTitle->getText() ); |
54 | if ( count( $parts ) !== 2 ) { |
55 | throw new PageNotInPaginationException( |
56 | $pageTitle->getFullText() . ' does not have page numbers' |
57 | ); |
58 | } |
59 | if ( $parts[0] !== $this->indexTitle->getText() ) { |
60 | throw new PageNotInPaginationException( |
61 | $pageTitle->getFullText() . ' does not belong to the pagination' |
62 | ); |
63 | } |
64 | $number = $pageTitle->getPageLanguage()->parseFormattedNumber( $parts[1] ); |
65 | if ( ctype_digit( $number ) && $number > 0 && $number < PHP_INT_MAX ) { |
66 | // Valid page numbers are integer > 0. |
67 | return (int)$number; |
68 | } else { |
69 | throw new PageNotInPaginationException( |
70 | $pageTitle->getFullText() . ' provides invalid page number ' . $number |
71 | ); |
72 | } |
73 | } |
74 | |
75 | /** |
76 | * @inheritDoc |
77 | */ |
78 | public function getDisplayedPageNumber( int $pageNumber ): PageNumber { |
79 | if ( !$this->pageNumberExists( $pageNumber ) ) { |
80 | throw new OutOfBoundsException( |
81 | 'There is no page number ' . $pageNumber . ' in the pagination.' |
82 | ); |
83 | } |
84 | return $this->pageList->getNumber( $pageNumber ); |
85 | } |
86 | |
87 | /** |
88 | * @inheritDoc |
89 | */ |
90 | public function getNumberOfPages(): int { |
91 | return $this->numberOfPages; |
92 | } |
93 | |
94 | /** |
95 | * @inheritDoc |
96 | */ |
97 | public function getPageTitle( int $pageNumber ): Title { |
98 | if ( !$this->pageNumberExists( $pageNumber ) ) { |
99 | throw new OutOfBoundsException( |
100 | 'There is no page number ' . $pageNumber . ' in the pagination.' |
101 | ); |
102 | } |
103 | |
104 | if ( !array_key_exists( $pageNumber, $this->pages ) ) { |
105 | $this->pages[$pageNumber] = $this->buildPageTitle( $pageNumber ); |
106 | } |
107 | |
108 | return $this->pages[$pageNumber]; |
109 | } |
110 | |
111 | /** |
112 | * @param int $pageNumber |
113 | * @return Title |
114 | */ |
115 | private function buildPageTitle( int $pageNumber ): Title { |
116 | $i18nNumber = $this->indexTitle->getPageLanguage()->formatNumNoSeparators( $pageNumber ); |
117 | $title = $this->buildPageTitleFromPageNumber( $i18nNumber ); |
118 | |
119 | // fallback to arabic number |
120 | if ( $i18nNumber !== (string)$pageNumber && !$title->exists() ) { |
121 | $arabicTitle = $this->buildPageTitleFromPageNumber( (string)$pageNumber ); |
122 | if ( $arabicTitle->exists() ) { |
123 | return $arabicTitle; |
124 | } |
125 | } |
126 | |
127 | return $title; |
128 | } |
129 | |
130 | /** |
131 | * @param string $pageNumber |
132 | * @return Title |
133 | */ |
134 | private function buildPageTitleFromPageNumber( string $pageNumber ): Title { |
135 | return Title::makeTitle( |
136 | $this->pageNamespaceId, |
137 | $this->indexTitle->getText() . '/' . $pageNumber |
138 | ); |
139 | } |
140 | |
141 | /** |
142 | * @inheritDoc |
143 | */ |
144 | protected function pageNumberExists( int $pageNumber ): bool { |
145 | return $pageNumber >= 1 && $pageNumber <= $this->numberOfPages; |
146 | } |
147 | |
148 | /** |
149 | * @param int $from |
150 | * @param int $to |
151 | * @param int $count |
152 | * @return bool |
153 | */ |
154 | public static function isValidInterval( int $from, int $to, int $count ): bool { |
155 | return $from >= 1 && $from <= $to && $to <= $count; |
156 | } |
157 | |
158 | } |