-
Notifications
You must be signed in to change notification settings - Fork 2
/
TPCPatchMap.php
155 lines (136 loc) · 4.75 KB
/
TPCPatchMap.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
<?php
/**
* Database-powered page->patch mapping.
*
* @file
* @author Nmlgc
*/
use MediaWiki\MediaWikiServices;
class TPCPatchMap {
protected static function mergePatch( &$map, &$patch ) {
// If we already have a mapping, update only if necessary
if ( !$map or in_array( $patch, $map->pm_patch ) ) {
return $patch;
} else {
$map->pm_patch[] = $patch;
return implode( "\n", $map->pm_patch );
}
}
// -------------------------
// Database access functions
// -------------------------
/**
* @return ?string Source language of the given page, if it is part of `tpc_tl_source_pages`.
*/
public static function getTLPageSourceLanguage( int $namespace, string $title ): ?string {
$dbr = MediaWikiServices::getInstance()->getDBLoadBalancer()->getConnection( DB_REPLICA );
$row = $dbr->selectRow( 'tpc_tl_source_pages', 'tlsp_code', array(
'tlsp_namespace' => $namespace,
'tlsp_title' => $title
));
return ( $row->tlsp_code ?? null );
}
/**
* @return array Mapping information for this page.
* See tpc_patch_map.sql for the format.
*/
public static function buildTLMapping( string $game, string $lang ) {
$dbr = MediaWikiServices::getInstance()->getDBLoadBalancer()->getConnection( DB_REPLICA );
$tl = $dbr->selectRow( 'tpc_tl_patches', 'tl_patch', array( 'tl_code' => $lang ) );
if ( $tl === false ) {
return null;
}
return ( object )array(
'pm_patch' => array( $tl->tl_patch ),
'pm_game' => $game,
'pm_target' => null, // Important for TPCState::from()
);
}
protected static function getMapping( Title &$title ) {
$dbr = MediaWikiServices::getInstance()->getDBLoadBalancer()->getConnection( DB_REPLICA );
// Get old value
$map = $dbr->selectRow( 'tpc_patch_map', '*', array(
'pm_namespace' => $title->getNamespace(),
'pm_title' => $title->getText(),
) );
if ( $map ) {
$map->pm_patch = explode( "\n", $map->pm_patch );
}
return $map;
}
public static function update( $title, $patch, $game = null, $target = null ) {
$map = self::get( $title );
$patches = self::mergePatch( $map, $patch );
// If we already have a mapping, update only if necessary
if (
( $map ) and
( in_array( $patch, $map->pm_patch ) ) and
( $map->pm_game == $game ) and
( $map->pm_target == $target )
) {
return;
}
$dbw = MediaWikiServices::getInstance()->getDBLoadBalancer()->getConnection( DB_PRIMARY );
$inserts = array(
'pm_namespace' => $title->getNamespace(),
'pm_title' => $title->getText(),
'pm_patch' => $patch,
'pm_game' => $game,
'pm_target' => $target
);
$dbw->replace( 'tpc_patch_map', 'pm_title', $inserts );
}
// -------------------------
/**
* @return array Mapping information for this page.
* See tpc_patch_map.sql for the format.
*/
public static function get( $title ) {
$namespace = $title->getNamespace();
$ret = self::getMapping( $title );
if ( $ret or $namespace == NS_FILE ) {
return $ret;
}
// Auto-generate the mapping from the page title. This has to work for the following cases:
//
// | Case | $title | tl_source_page | Mapped game / patch |
// |----------------------------+----------------+----------------+---------------------|
// | Multi-game, source page | Game titles | Game titles | "", "lang_ja" |
// | Multi-game, translated | Game titles/en | Game titles | "", "lang_en" |
// | Specific game, source page | Th06/Images | Th06/Images | "th06", "lang_ja" |
// | Specific game, translated | Th06/Images/en | Th06/Images | "th06", "lang_en" |
$root = $title->getRootText(); // Might indicate a game
// Source page?
if ( $code = self::getTLPageSourceLanguage( $namespace, $title->getText() ) ) {
$game = $title->isSubpage() ? lcfirst( $root ) : "";
return self::buildTLMapping( $game, $code );
}
// If $title is a translated page, getBaseText() gives us the source page…
$base = $title->getBaseText();
// … which we can check against the same database table to check if this is a translated
// page of a registered source page.
if ( self::getTLPageSourceLanguage( $namespace, $base ) ) {
$game = ( $root != $base ) ? lcfirst( $root ) : "";
return self::buildTLMapping( $game, $title->getSubpageText() );
}
return null;
}
/**
* @param Title $title Title object
* @return bool
*/
public static function isPatchRootPage( $title ) {
return ( $title->getNamespace() === NS_PATCH and !$title->isSubpage() );
}
public static function getPatchRootPages() {
$dbr = MediaWikiServices::getInstance()->getDBLoadBalancer()->getConnection( DB_REPLICA );
return $dbr->select(
'page',
array( 'page_namespace', 'page_title'),
array(
'page_namespace' => NS_PATCH,
"page_title NOT LIKE '%/%'"
)
);
}
}