-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathLocalSettings.php
More file actions
334 lines (273 loc) · 12.4 KB
/
LocalSettings.php
File metadata and controls
334 lines (273 loc) · 12.4 KB
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
<?php
/**
* PickiPedia - Traditional Music Knowledge Base
*
* This file is tracked in version control.
* Secrets are loaded from LocalSettings.local.php (not tracked).
*/
# Suppress deprecation warnings early to prevent them from corrupting
# ResourceLoader JS output (EmbedVideo extension has compatibility issues)
error_reporting( E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED );
# Protect against web entry
if ( !defined( 'MEDIAWIKI' ) ) {
exit;
}
## Load secrets from local config
require_once __DIR__ . '/LocalSettings.local.php';
## Error tracking with Sentry/GlitchTip
# DSN is set in LocalSettings.local.php as $wgSentryDsn
if ( !empty( $wgSentryDsn ) ) {
\Sentry\init([
'dsn' => $wgSentryDsn,
'environment' => getenv('WIKI_DEV_MODE') === 'true' ? 'development' : 'production',
'release' => $wgPickipediaBuildInfo['commit'] ?? 'unknown',
]);
// Use MediaWiki's LogException hook to capture ALL exceptions, including
// those caught internally by MediaWiki (like DBQueryError)
$wgHooks['LogException'][] = function ( Throwable $e, bool $suppressed ) {
\Sentry\captureException( $e );
};
// Also keep shutdown handler for fatal errors that bypass exception handling
register_shutdown_function( function () {
$error = error_get_last();
if ( $error !== null && in_array( $error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR] ) ) {
\Sentry\captureException( new \ErrorException(
$error['message'], 0, $error['type'], $error['file'], $error['line']
) );
}
});
}
## Site identity
$wgSitename = getenv('WIKI_NAME') ?: "PickiPedia";
$wgMetaNamespace = "PickiPedia";
## Custom namespaces
# Cryptograss namespace for infrastructure and project documentation
define( "NS_CRYPTOGRASS", 3000 );
define( "NS_CRYPTOGRASS_TALK", 3001 );
$wgExtraNamespaces[NS_CRYPTOGRASS] = "Cryptograss";
$wgExtraNamespaces[NS_CRYPTOGRASS_TALK] = "Cryptograss_talk";
# BlueRailroad namespace for NFT token pages
define( "NS_BLUERAILROAD", 3002 );
define( "NS_BLUERAILROAD_TALK", 3003 );
$wgExtraNamespaces[NS_BLUERAILROAD] = "BlueRailroad";
$wgExtraNamespaces[NS_BLUERAILROAD_TALK] = "BlueRailroad_talk";
# Make Cryptograss namespace searchable by default
$wgNamespacesToBeSearchedDefault[NS_CRYPTOGRASS] = true;
$wgNamespacesToBeSearchedDefault[NS_BLUERAILROAD] = true;
## URLs
$wgServer = getenv('WIKI_URL') ?: "https://pickipedia.xyz";
$wgScriptPath = "";
$wgArticlePath = "/wiki/$1";
$wgUsePathInfo = true;
## Database settings (from LocalSettings.local.php)
# $wgDBtype, $wgDBserver, $wgDBname, $wgDBuser, $wgDBpassword
# are set in LocalSettings.local.php
$wgDBprefix = "";
$wgDBTableOptions = "ENGINE=InnoDB, DEFAULT CHARSET=binary";
## Shared memory / caching
$wgMainCacheType = CACHE_ACCEL;
$wgMemCachedServers = [];
## File uploads
$wgEnableUploads = true;
$wgUploadPath = "$wgScriptPath/images";
$wgUploadDirectory = "$IP/images";
$wgUseImageMagick = false;
# GD library is used for thumbnails instead
$wgMaxImageArea = 50e6; # 50 megapixels (default is 12.5MP)
# Allow uploads from URLs (e.g., Instagram, external sources)
$wgAllowCopyUploads = true;
$wgCopyUploadsFromSpecialUpload = true;
$wgGroupPermissions['user']['upload_by_url'] = true;
# Allow video uploads (HTML5 playback, no transcoding)
$wgFileExtensions = array_merge( $wgFileExtensions, ['mp4', 'webm', 'mov', 'ogv'] );
# Disable strict MIME verification for iPhone HEVC videos (mov containers)
$wgVerifyMimeType = false;
## InstantCommons allows wiki to use images from commons.wikimedia.org
$wgUseInstantCommons = true;
## Logos
$wgLogos = [
'1x' => "$wgResourceBasePath/assets/logo.png",
];
$wgFavicon = "$wgResourceBasePath/assets/favicon.ico";
## Skins
wfLoadSkin( 'MonoBook' );
wfLoadSkin( 'Vector' );
$wgDefaultSkin = "monobook";
## Rights
$wgRightsPage = "";
$wgRightsUrl = "";
$wgRightsText = "";
$wgRightsIcon = "";
## Permissions
# Account creation requires an invite code (handled by PickiPediaInvitations extension)
$wgGroupPermissions['*']['createaccount'] = true;
# Anonymous users can read but not edit
$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['*']['read'] = true;
# All logged-in users can edit (restored after disabling for anonymous above)
$wgGroupPermissions['user']['edit'] = true;
# Allow sysops to merge/delete users (for bot cleanup)
$wgGroupPermissions['sysop']['usermerge'] = true;
# Restrict Release namespace to users in the 'release' group
# NS_RELEASE (3004) is defined by the PickiPediaReleases extension
$wgNamespaceProtection[3004] = ['release-edit'];
$wgGroupPermissions['release']['release-edit'] = true;
# ReleaseDraft namespace (3006) is readable/editable by all logged-in users.
# Finalization is gated by HMAC tokens (only generated for finalize-release users).
# No namespace protection needed — anonymous editing is already disabled wiki-wide.
# Make release-edit available as a BotPasswords grant
$wgGrantPermissions['release-edit']['release-edit'] = true;
$wgGrantPermissionGroups['release-edit'] = 'other';
## Extensions
# Semantic MediaWiki (installed via Composer)
wfLoadExtension( 'SemanticMediaWiki' );
enableSemantics( parse_url($wgServer, PHP_URL_HOST) );
# Enable SMW semantic links for Cryptograss namespace
$smwgNamespacesWithSemanticLinks[NS_CRYPTOGRASS] = true;
# Enable semantic links for Release namespace (after PickiPediaReleases is loaded)
# Note: NS_RELEASE (3004) and NS_RELEASEDRAFT (3006) are defined by PickiPediaReleases
$smwgNamespacesWithSemanticLinks[3004] = true;
$smwgNamespacesWithSemanticLinks[3006] = true;
# Page Forms - create forms for SMW data entry (installed via Composer)
wfLoadExtension( 'PageForms' );
# YouTube - for embedding YouTube videos
wfLoadExtension( 'YouTube' );
# Scribunto - Lua scripting for templates (Module: namespace)
wfLoadExtension( 'Scribunto' );
$wgScribuntoDefaultEngine = 'luastandalone';
# ParserFunctions - {{#if:}}, {{#switch:}}, etc. for templates (bundled with MediaWiki)
wfLoadExtension( 'ParserFunctions' );
$wgPFEnableStringFunctions = true; # Enable #explode, #sub, #len, etc. for parsing
# WikiEditor - enhanced editing toolbar (bundled with MediaWiki)
wfLoadExtension( 'WikiEditor' );
# LinkSuggest - autocomplete when typing [[ or {{ in standard editor
wfLoadExtension( 'LinkSuggest' );
# VisualEditor - rich editing experience (available, but source editing is default)
wfLoadExtension( 'VisualEditor' );
$wgVisualEditorParsoidAutoConfig = true; # Parsoid runs in-process (MW 1.35+)
$wgDefaultUserOptions['visualeditor-enable'] = 1; # VE available
$wgDefaultUserOptions['visualeditor-newwikitext'] = 0; # Use classic WikiEditor for source, not 2017 wikitext
$wgDefaultUserOptions['visualeditor-editor'] = 'wikitext'; # Default to source editing
$wgDefaultUserOptions['usebetatoolbar'] = 0; # Disable WikiEditor toolbar
$wgVisualEditorUseSingleEditTab = false; # Show both "Edit" and "Edit source" tabs
$wgVisualEditorAvailableNamespaces = [
NS_MAIN => true,
NS_USER => true,
NS_PROJECT => true,
NS_TEMPLATE => true,
NS_HELP => true,
NS_CATEGORY => true,
NS_CRYPTOGRASS => true,
NS_BLUERAILROAD => true,
];
# CodeMirror - syntax highlighting in the editor
# DISABLED in test environment (not in Docker image)
# wfLoadExtension( 'CodeMirror' );
# $wgDefaultUserOptions['usecodemirror'] = 1; # Enable by default for all users
# MultimediaViewer - modern lightbox for images (bundled with MediaWiki)
wfLoadExtension( 'MultimediaViewer' );
# MsUpload - drag-and-drop multiple file upload in edit page
wfLoadExtension( 'MsUpload' );
$wgMSU_useDragDrop = true;
$wgMSU_showAutoCat = true;
# MediaUploader - step-by-step multi-file upload wizard
wfLoadExtension( 'MediaUploader' );
$wgMediaUploaderConfig = [
'tutorial' => [ 'enabled' => false ],
];
$wgUploadNavigationUrl = '/wiki/Special:MediaUploader';
$wgMSU_checkAutoCat = true;
$wgMSU_imgParams = '400px';
$wgMSU_uploadsize = '1024mb';
$wgMaxUploadSize = 1024 * 1024 * 1024; // 1GB in bytes - bigger things can go to delivery-kid
$wgMediaUploaderConfig['licensing']['enabled'] = false;
# TimedMediaHandler - video/audio playback with transcoding
wfLoadExtension( 'TimedMediaHandler' );
$wgFFmpegLocation = '/usr/local/bin/ffmpeg';
# HitCounters - page view statistics (installed via Composer)
wfLoadExtension( 'HitCounters' );
# RSS - embed RSS feeds in wiki pages
wfLoadExtension( 'RSS' );
$wgRSSUrlWhitelist = array( "*" );
# Gadgets - user-customizable JavaScript/CSS tools
wfLoadExtension( 'Gadgets' );
# PickiPediaVerification - enforce verification workflow for bot edits
# Also provides Special:VerifyBotEdits for bulk verification
wfLoadExtension( 'PickiPediaVerification' );
# Exempt trusted bots from verification requirement
# Add bot accounts to this group via Special:UserRights
$wgGroupPermissions['exempt-from-verification']['read'] = true;
$wgPickiPediaVerificationExemptGroups = ['exempt-from-verification'];
# RambutanMode - adds "Rambutan" as a middle name/alias to person and band articles
# Users can toggle via sidebar; auto-disables at midnight Florida time
wfLoadExtension( 'RambutanMode' );
# PickiPediaInvitations - gate account creation behind invite codes
# Creates an accountability chain via EntityAttestation pages
wfLoadExtension( 'PickiPediaInvitations' );
# EmbedVideo - embed external video files (MP4, etc.)
wfLoadExtension( 'EmbedVideo' );
# PickiPediaReleases - Release namespace with YAML content model
# Stores IPFS CIDs and BitTorrent infohashes for pinning service sync
wfLoadExtension( 'PickiPediaReleases' );
$wgDeliveryKidUrl = getenv('DELIVERY_KID_URL') ?: 'https://delivery-kid.cryptograss.live';
if ( getenv('DELIVERY_KID_API_KEY') ) {
$wgDeliveryKidApiKey = getenv('DELIVERY_KID_API_KEY');
}
# Echo - notifications for talk page messages, mentions, watchlist changes
wfLoadExtension( 'Echo' );
# Thanks - thank editors for contributions
wfLoadExtension( 'Thanks' );
# UserMerge - merge and delete user accounts (for bot cleanup)
# DISABLED: Not in Docker image
# wfLoadExtension( 'UserMerge' );
# WikiSEO - social sharing cards and SEO meta tags (installed via Composer)
# DISABLED in test environment (not in Docker image)
# wfLoadExtension( 'WikiSEO' );
# $wgWikiSeoDefaultImage = "$wgServer/w/images/pickipedia-card.png";
# $wgTwitterSiteHandle = "@cryptograss";
# Add custom 'videolink' service for direct video URLs (MP4 or IPFS gateway)
$wgHooks['SetupAfterCache'][] = function() {
\EmbedVideo\VideoService::addService('videolink', [
'embed' => '<video width="%2$d" controls><source src="%1$s" type="video/mp4">Your browser does not support video.</video>',
'default_width' => 320,
'default_ratio' => 1.77777777777778,
'https_enabled' => true,
'url_regex' => ['#^(https?://.+)$#is'],
'id_regex' => ['#^(https?://.+)$#is']
]);
};
## Email (disabled by default)
$wgEnableEmail = false;
$wgEnableUserEmail = false;
## Debugging (disable in production)
$wgShowExceptionDetails = false;
$wgShowDBErrorBacktrace = false;
$wgShowSQLErrors = false;
$wgDevelopmentWarnings = (getenv('WIKI_DEV_MODE') === 'true');
# Note: Deprecation warnings are suppressed at the top of this file to prevent
# them from corrupting ResourceLoader JS output (EmbedVideo has compatibility issues)
## Allow embedding in iframes (for rabbithole integration)
$wgEditPageFrameOptions = false;
## Build info footer (generated at build time)
if ( file_exists( __DIR__ . '/build-info.php' ) ) {
require_once __DIR__ . '/build-info.php';
if ( isset( $wgPickipediaBuildInfo ) && $wgPickipediaBuildInfo['blockheight'] > 0 ) {
$blockheight = number_format( $wgPickipediaBuildInfo['blockheight'] );
$commit = $wgPickipediaBuildInfo['commit'];
$wgFooterIcons['poweredby']['pickipedia-build'] = [
'src' => '',
'url' => "https://etherscan.io/block/{$wgPickipediaBuildInfo['blockheight']}",
'alt' => "Built at block {$blockheight}",
'height' => false,
'width' => false,
];
// Also add to site notice / footer text
$wgHooks['SkinAfterContent'][] = function ( &$data, $skin ) use ( $blockheight, $commit ) {
$data .= "<div style='text-align: center; font-size: 0.8em; color: #666; padding: 5px;'>"
. "Built at Ethereum block <a href='https://etherscan.io/block/{$GLOBALS['wgPickipediaBuildInfo']['blockheight']}'>{$blockheight}</a>"
. " | commit {$commit}"
. "</div>";
return true;
};
}
}