×
Create a new article
Write your page title here:
We currently have 0 articles on Grand Theft Auto. Type your article name above or click on one of the titles below and start writing!



    License for SkywikiMagic

    SkywikiMagic/README.md0000644000000000000000000000014214723367061013434 0ustar  rootroot# WikiOasisMagic
    
    Forked from [miraheze/MirahezeMagic](https://github.com/miraheze/MirahezeMagic)
    SkywikiMagic/extension.json0000644000000000000000000000451214727376305015076 0ustar  rootroot{
    	"name": "SkywikiMagic",
    	"author": [
    		"Agent Isai",
    		"John Lewis",
    		"Labster",
    		"MacFan4000",
    		"Reception123",
    		"Revi",
    		"Paladox",
    		"Southparkfan",
    		"Universal Omega",
    		"Waki285"
    	],
    	"descriptionmsg": "skywikimagic-description",
    	"namemsg": "skywikimagic-extensionname",
    	"license-name": "GPL-3.0-or-later",
    	"type": "other",
    	"requires": {
    		"MediaWiki": ">= 1.42.0",
    		"platform": {
    			"php": ">= 8.0"
    		}
    	},
    	"MessagesDirs": {
    		"WikiOasisMagic": [
    			"i18n/wikioasis"
    		]
    	},
    	"AutoloadNamespaces": {
    		"WikiOasis\\WikiOasisMagic\\": "includes/"
    	},
    	"SpecialPages": {
    		"CreateNewWiki": {
    			"class": "WikiOasis\\WikiOasisMagic\\SpecialCreateNewWiki",
    			"services": [
    				"CreateWikiDatabaseUtils",
    				"WikiManagerFactory"
    			]
    		},
                    "ChangeDomain": {
                            "class": "WikiOasis\\WikiOasisMagic\\SpecialChangeDomain",
                            "services": [
                                    "CreateWikiDatabaseUtils",
                                    "RemoteWikiFactory"
                            ]
                    }
    	},
    	"AvailableRights": [
    		"createnewwiki"
    	],
    	"Hooks": {
    		"AbuseFilterShouldFilterAction": {
    			"handler": "Main"
    		},
    		"ContributionsToolLinks": {
    			"handler": "Main"
    		},
    		"CreateWikiStatePrivate": {
    			"handler": "Main"
    		},
    		"CreateWikiTables": {
    			"handler": "Main"
    		},
    		"GetLocalURL::Internal": {
    			"handler": "Main"
    		},
    		"GlobalUserPageWikis": {
    			"handler": "Main"
    		},
            "ImportDumpJobGetFile": {
    			"handler": "Main"
    		},
    		"MessageCacheFetchOverrides": {
    			"handler": "Main"
    		},
    		"MimeMagicInit": {
    			"handler": "Main"
    		},
    		"SiteNoticeAfter": {
    			"handler": "Main"
    		},
    		"SkinAddFooterLinks": {
    			"handler": "Main"
    		},
    		"TitleReadWhitelist": {
    			"handler": "Main"
    		}
    	},
    	"HookHandlers": {
    		"Main": {
    			"class": "WikiOasis\\WikiOasisMagic\\HookHandlers\\Main",
    			"factory": "WikiOasis\\WikiOasisMagic\\HookHandlers\\Main::factory",
    			"services": [
    				"MainConfig",
    				"CommentStore",
    				"DBLoadBalancerFactory",
    				"HttpRequestFactory"
    			]
    		}
    	},
    	"config": {
    		"WikiOasisMagicMemcachedServers": {
    			"description": "Array. Memcached servers to use for clearing memcached keys when a wiki is deleted or renamed.",
    			"value": []
    		}
    	},
    	"ConfigRegistry": {
    		"WikiOasisMagic": "MediaWiki\\Config\\GlobalVarConfig::newInstance"
    	},
    	"manifest_version": 2
    }
    SkywikiMagic/i18n/0000755000000000000000000000000014723367061012737 5ustar  rootrootSkywikiMagic/i18n/wikioasis/0000755000000000000000000000000014727377257014755 5ustar  rootrootSkywikiMagic/i18n/wikioasis/en.json0000644000000000000000000001401314727377257016251 0ustar  rootroot{
    	"@metadata": {
    		"authors": [
    			"Agent Isai",
    			"John Lewis",
    			"AlvaroMolina",
    			"MacFan4000",
    			"Universal Omega",
    			"Waki285"
    		]
    	},
        "skywikimagic-extensionname": "SkywikiMagic",
        "skywikimagic-description": "SkyWiki dedicated extension",
    	"extensions-antispam": "Spam prevention",
    	"extensions-api": "API",
    	"extensions-editors": "Editors",
    	"extensions-mediahandlers": "Media handlers",
    	"extensions-parserhooks": "Parser hooks",
    	"extensions-skins": "Skins",
    	"extensions-specialpages": "Special pages",
    	"extensions-variable": "Variables",
    	"grant-usedatadumpapi": "Create, view, and delete dumps",
    	"group-autopatrolled-member": "{{GENDER:$1|autopatrolled}}",
    	"group-autopatrolled": "Autopatrolled users",
    	"group-confirmed-member": "{{GENDER:$1|confirmed user}}",
    	"group-confirmed": "Confirmed users",
    	"group-electionadmin": "Election administrators",
    	"group-electionadmin-member": "{{GENDER:$1|election administrator}}",
    	"group-flood-member": "{{GENDER:$1|flooder}}",
    	"group-flood": "Flooders",
    	"group-founder": "Founders",
    	"group-founder-member": "{{GENDER:$1|founder}}",
    	"group-global-admin-member": "{{GENDER:$1|global administrator}}",
    	"group-global-admin": "Global Administrators",
    	"group-global-flood-member": "{{GENDER:$1|global flooder}}",
    	"group-global-flood": "Global flooders",
    	"group-global-ipblock-exempt-member": "{{GENDER:$1|global IP block exempt}}",
    	"group-global-ipblock-exempt": "Global IP block exemption",
    	"group-global-patroller-member": "{{GENDER:$1|global patroller}}",
    	"group-global-patroller": "Global patrollers",
    	"group-global-renamer-member": "{{GENDER:$1|global renamer}}",
    	"group-global-renamer": "Global renamers",
    	"group-global-rollbacker-member": "{{GENDER:$1|global rollbacker}}",
    	"group-global-rollbacker": "Global rollbackers",
    	"group-ipblock-exempt-member": "{{GENDER:$1|IP block exempt}}",
    	"group-ipblock-exempt": "IP block exemption",
    	"group-member": "Members",
    	"group-member-member": "{{GENDER:$1|member}}",
    	"group-patroller-member": "{{GENDER:$1|patroller}}",
    	"group-patroller": "Patrollers",
    	"group-rollbacker-member": "{{GENDER:$1|rollbacker}}",
    	"group-rollbacker": "Rollbackers",
    	"group-steward-member": "{{GENDER:$1|steward}}",
    	"group-steward": "Stewards",
        "group-sysadmin-member": "{{GENDER:$1|system administrator}}",
        "group-sysadmin": "System administrators",
    	"group-translator-member": "{{GENDER:$1|translator}}",
    	"group-translator": "Translators",
    	"group-trustandsafety-member": "{{GENDER:$1|Trust and Safety member}}",
    	"group-trustandsafety": "Trust and Safety",
    	"group-wiki-creator-member": "{{GENDER:$1|wiki creator}}",
    	"group-wiki-creator": "Wiki creators",
    	"grouppage-autopatrolled": "wom:Special:MyLanguage/User groups#{{int:Group-autopatrolled}}",
    	"grouppage-confirmed": "wom:Special:MyLanguage/User groups#{{int:Group-autoconfirmed}}",
    	"grouppage-electionadmin": "wom:Special:MyLanguage/Meta:Election administrators",
    	"grouppage-flood": "wom:Special:MyLanguage/User groups#{{int:Group-flood}}",
    	"grouppage-founder": "wom:Special:MyLanguage/User groups#{{int:Group-founder}}",
    	"grouppage-global-admin": "wom:Special:MyLanguage/Global Administrators",
    	"grouppage-global-flood": "wom:Special:MyLanguage/Global flooders",
    	"grouppage-global-ipblock-exempt": "wom:Special:MyLanguage/Global IP block exemption",
    	"grouppage-global-patroller": "wom:Special:MyLanguage/Global Patrollers",
    	"grouppage-global-renamer": "wom:Special:MyLanguage/Global renamers",
    	"grouppage-global-rollbacker": "wom:Special:MyLanguage/Global rollbackers",
    	"grouppage-ipblock-exempt": "wom:Special:MyLanguage/User groups#{{int:Group-ipblock-exempt}}",
    	"grouppage-member": "wom:Special:MyLanguage/User groups#{{int:Group-member}}",
    	"grouppage-patroller": "wom:Special:MyLanguage/User groups#{{int:Group-patroller}}",
    	"grouppage-rollbacker": "wom:Special:MyLanguage/User groups#{{int:Group-rollbacker}}",
    	"grouppage-steward": "wom:Special:MyLanguage/Stewards",
        "grouppage-sysadmin": "wom:Special:MyLanguage/System administrators",
    	"grouppage-trustandsafety": "wom:Special:MyLanguage/Trust and Safety",
    	"grouppage-wiki-creator": "wom:Special:MyLanguage/Meta:Wiki creators",
    	"settings-anti-spam": "Anti Spam",
    	"settings-beta": "Beta",
    	"settings-categories": "Categories",
    	"settings-discussion": "Discussion",
    	"settings-editing": "Editing",
    	"settings-links": "Links",
    	"settings-localisation": "Localisation",
    	"settings-maps": "Maps",
    	"settings-media": "Media",
    	"settings-notifications": "Notifications",
    	"settings-parserfunctions": "Parser Functions",
    	"settings-permissions": "Permissions",
    	"settings-preferences": "Preferences",
    	"settings-recentchanges": "Recent changes",
    	"settings-restricted": "Restricted",
    	"settings-seo": "SEO",
    	"settings-socialtools": "Social tools",
    	"settings-styling": "Styling",
    	"settings-wikibase": "Wikibase",
        "specialpages-group-wikimanage": "Wiki management",
    	"miraheze-label-managewiki-article-path": "Article path",
    	"miraheze-label-managewiki-article-path-root": "Don't use /wiki/ for articles (use the root path)",
    	"miraheze-label-managewiki-article-path-wiki": "Use /wiki/ for articles",
    	"miraheze-label-managewiki-mainpage-is-domain-root": "Make the main page of this wiki use the domain root?",
    	"miraheze-label-managewiki-mediawiki-version": "MediaWiki version",
    	"miraheze-label-managewiki-primary-domain": "Primary domain",
        "createnewwiki": "Start your own community",
        "createnewwiki-description": "Every wiki, whether big or small, needs an address and a name. Please note that the subdomain can only contain alphanumeric characters.",
            "action-createnewwiki": "create a new wiki through CreateNewWiki",
            "right-createnewwiki": "Create a new wiki through CreateNewWiki",
            "createnewwiki-label-subdomain": "Subdomain:",
            "createnewwiki-placeholder-subdomain": "Give your community a subdomain",
            "createnewwiki-placeholder-sitename": "Name your wiki",
            "changedomain": "Change domain",
    	"changedomain-info": "Insert the database name of the wiki you wish to change the domain for.",
    	"changedomain-label-domain": "Domain"
    }
    SkywikiMagic/includes/0000755000000000000000000000000014727411650013764 5ustar  rootrootSkywikiMagic/includes/SpecialCreateNewWiki.php0000644000000000000000000001105314727376352020510 0ustar  rootroot<?php
    
    namespace WikiOasis\WikiOasisMagic;
    
    use ErrorPageError;
    use MediaWiki\Html\Html;
    use MediaWiki\Message\Message;
    use MediaWiki\SpecialPage\FormSpecialPage;
    use Miraheze\CreateWiki\ConfigNames;
    use Miraheze\CreateWiki\Services\CreateWikiDatabaseUtils;
    use Miraheze\CreateWiki\Services\WikiManagerFactory;
    use OOUI;
    
    class SpecialCreateNewWiki extends FormSpecialPage {
    
    	private CreateWikiDatabaseUtils $databaseUtils;
    	private WikiManagerFactory $wikiManagerFactory;
    
    	public function __construct(
    		CreateWikiDatabaseUtils $databaseUtils,
    		WikiManagerFactory $wikiManagerFactory
    	) {
    		parent::__construct( 'CreateNewWiki', 'createnewwiki' );
    
    		$this->databaseUtils = $databaseUtils;
    		$this->wikiManagerFactory = $wikiManagerFactory;
    	}
    
    	/**
    	 * @param ?string $par
    	 */
    	public function execute( $par ): void {
    		if ( !$this->databaseUtils->isCurrentWikiCentral() ) {
    			throw new ErrorPageError( 'errorpagetitle', 'createwiki-wikinotcentralwiki' );
    		}
    
    		if ( !$this->getUser()->isEmailConfirmed() ) {
    			throw new ErrorPageError( 'requestwiki', 'requestwiki-error-emailnotconfirmed' );
    		}
    
    		parent::execute( $par );
    	}
    
    	/**
    	 * @inheritDoc
    	 */
    	protected function getFormFields(): array {
    		$formDescriptor = [
    			'dbname' => [
    				#'label-message' => 'createnewwiki-label-subdomain',
    				'label' => "." . $this->getConfig()->get( 'CreateWikiSubdomain' ),
    				'cssclass' => 'subdomain',
    				'placeholder-message' => 'createnewwiki-placeholder-subdomain',
    				'type' => 'text',
    				'required' => true,
    				'validation-callback' => [ $this, 'isValidDatabase' ],
    			],
    			'sitename' => [
    				'label-message' => 'createwiki-label-sitename',
    				'placeholder-message' => 'createnewwiki-placeholder-sitename',
    				'type' => 'text',
    				'size' => 20,
    			],
    			'language' => [
    				'type' => 'language',
    				'label-message' => 'createwiki-label-language',
    				'default' => 'en',
    			],
    		];
    
    		if ( $this->getConfig()->get( ConfigNames::UsePrivateWikis ) ) {
    			$formDescriptor['private'] = [
    				'type' => 'check',
    				'label-message' => 'createwiki-label-private',
    			];
    		}
    
    		if ( $this->getConfig()->get( ConfigNames::Categories ) ) {
    			$formDescriptor['category'] = [
    				'type' => 'select',
    				'label-message' => 'createwiki-label-category',
    				'options' => $this->getConfig()->get( ConfigNames::Categories ),
    				'default' => 'uncategorised',
    			];
    		}
    
    		$formDescriptor['reason'] = [
    			'type' => 'textarea',
    			'rows' => 10,
    			'label-message' => 'createwiki-label-reason',
    			'help-message' => 'createwiki-help-reason',
    			'required' => true,
    			'useeditfont' => true,
    		];
    
    		return $formDescriptor;
    	}
    
    	/**
    	 * @inheritDoc
    	 */
    	public function onSubmit( array $formData ): bool {
    		if ( $this->getConfig()->get( ConfigNames::UsePrivateWikis ) ) {
    			$private = $formData['private'];
    		} else {
    			$private = 0;
    		}
    
    		if ( $this->getConfig()->get( ConfigNames::Categories ) ) {
    			$category = $formData['category'];
    		} else {
    			$category = 'uncategorised';
    		}
    
    		$wikiManager = $this->wikiManagerFactory->newInstance( $formData['dbname'] . 'wiki' );
    		$wikiManager->create(
    			sitename: $formData['sitename'],
    			language: $formData['language'],
    			private: $private,
    			category: $category,
    			requester: $this->getContext()->getUser()->getName(),
    			actor: $this->getContext()->getUser()->getName(),
    			reason: $formData['reason'],
    			extra: []
    		);
    
    		$this->getOutput()->redirect( "http://" . $formData['dbname'] . "." . $this->getConfig()->get( 'CreateWikiSubdomain' ) ); 
    
    		return true;
    	}
    
    	public function isValidDatabase( ?string $dbname ): bool|string|Message {
    		if ( !$dbname || ctype_space( $dbname ) ) {
    			return $this->msg( 'htmlform-required' );
    		}
    
    		$wikiManager = $this->wikiManagerFactory->newInstance( $dbname . 'wiki' );
    		$check = $wikiManager->checkDatabaseName( $dbname . 'wiki', forRename: false );
    
    		if ( $check ) {
    			// Will return a string — the error it received
    			return $check;
    		}
    
    		return true;
    	}
    
    	/**
    	 * @inheritDoc
    	 */
    	protected function getDisplayFormat(): string {
    		return 'ooui';
    	}
    
    	/**
    	 * @inheritDoc
    	 */
    	protected function getGroupName(): string {
    		return 'wikimanage';
    	}
    
    	/**
    	 * @inheritDoc
    	 */
    	protected function preHtml(): string {
    		return $this->msg( 'createnewwiki-description' ) . "
    			<style>
    				.subdomain .oo-ui-fieldLayout-body {
    					display: flex;
    					flex-direction: row-reverse;
    					justify-content: flex-end;
    				}
    				.subdomain .oo-ui-fieldLayout-field {
    					flex: 1;
    					max-width: 50em;
    					margin-right: 1rem;
    				}
    				.oo-ui-fieldLayout-body .oo-ui-iconElement-icon {
    					margin-right: .25rem;
    				}
    			</style>
    		";
    	}
    }
    SkywikiMagic/includes/HookHandlers/0000755000000000000000000000000014727360362016350 5ustar  rootrootSkywikiMagic/includes/HookHandlers/Main.php0000644000000000000000000004016214727234344017750 0ustar  rootroot<?php
    
    namespace WikiOasis\WikiOasisMagic\HookHandlers;
    
    use MediaWiki\Cache\Hook\MessageCacheFetchOverridesHook;
    use MediaWiki\CommentStore\CommentStore;
    use MediaWiki\Config\Config;
    use MediaWiki\Config\GlobalVarConfig;
    use MediaWiki\Config\ServiceOptions;
    use MediaWiki\Context\RequestContext;
    use MediaWiki\Extension\AbuseFilter\AbuseFilterServices;
    use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterShouldFilterActionHook;
    use MediaWiki\Extension\AbuseFilter\Variables\VariableHolder;
    use MediaWiki\Extension\CentralAuth\User\CentralAuthUser;
    use MediaWiki\Hook\ContributionsToolLinksHook;
    use MediaWiki\Hook\GetLocalURL__InternalHook;
    use MediaWiki\Hook\MimeMagicInitHook;
    use MediaWiki\Hook\SiteNoticeAfterHook;
    use MediaWiki\Hook\SkinAddFooterLinksHook;
    use MediaWiki\Html\Html;
    use MediaWiki\Http\HttpRequestFactory;
    use MediaWiki\Linker\Linker;
    use MediaWiki\MainConfigNames;
    use MediaWiki\MediaWikiServices;
    use MediaWiki\Permissions\Hook\TitleReadWhitelistHook;
    use MediaWiki\Shell\Shell;
    use MediaWiki\SpecialPage\SpecialPage;
    use MediaWiki\Title\Title;
    use MediaWiki\User\User;
    use MediaWiki\WikiMap\WikiMap;
    use Memcached;
    use MessageCache;
    use Miraheze\CreateWiki\Hooks\CreateWikiStatePrivateHook;
    use Miraheze\CreateWiki\Hooks\CreateWikiTablesHook;
    use Miraheze\ManageWiki\Helpers\ManageWikiExtensions;
    use Miraheze\ManageWiki\Helpers\ManageWikiSettings;
    use Miraheze\ImportDump\Hooks\ImportDumpJobGetFileHook;
    use Redis;
    use Skin;
    use Throwable;
    use Wikimedia\IPUtils;
    use Wikimedia\Rdbms\DBConnRef;
    use Wikimedia\Rdbms\ILBFactory;
    
    class Main implements
    	AbuseFilterShouldFilterActionHook,
    	ContributionsToolLinksHook,
    	CreateWikiStatePrivateHook,
    	CreateWikiTablesHook,
    	GetLocalURL__InternalHook,
        ImportDumpJobGetFileHook,
    	MessageCacheFetchOverridesHook,
    	MimeMagicInitHook,
    	SiteNoticeAfterHook,
    	SkinAddFooterLinksHook,
    	TitleReadWhitelistHook
    {
    
    	/** @var ServiceOptions */
    	private $options;
    
    	/** @var CommentStore */
    	private $commentStore;
    
    	/** @var ILBFactory */
    	private $dbLoadBalancerFactory;
    
    	/** @var HttpRequestFactory */
    	private $httpRequestFactory;
    
    	/**
    	 * @param ServiceOptions $options
    	 * @param CommentStore $commentStore
    	 * @param ILBFactory $dbLoadBalancerFactory
    	 * @param HttpRequestFactory $httpRequestFactory
    	 */
    	public function __construct(
    		ServiceOptions $options,
    		CommentStore $commentStore,
    		ILBFactory $dbLoadBalancerFactory,
    		HttpRequestFactory $httpRequestFactory
    	) {
    		$this->options = $options;
    		$this->commentStore = $commentStore;
    		$this->dbLoadBalancerFactory = $dbLoadBalancerFactory;
    		$this->httpRequestFactory = $httpRequestFactory;
    	}
    
    	/**
    	 * @param Config $mainConfig
    	 * @param CommentStore $commentStore
    	 * @param ILBFactory $dbLoadBalancerFactory
    	 * @param HttpRequestFactory $httpRequestFactory
    	 *
    	 * @return self
    	 */
    	public static function factory(
    		Config $mainConfig,
    		CommentStore $commentStore,
    		ILBFactory $dbLoadBalancerFactory,
    		HttpRequestFactory $httpRequestFactory
    	): self {
    		return new self(
    			new ServiceOptions(
    				[
    					'ArticlePath',
    					'CreateWikiCacheDirectory',
    					'CreateWikiGlobalWiki',
    					'EchoSharedTrackingDB',
    					'JobTypeConf',
    					'LanguageCode',
    					'LocalDatabases',
    					'ManageWikiSettings',
    					'WikiOasisMagicMemcachedServers',
    					'Script',
    				],
    				$mainConfig
    			),
    			$commentStore,
    			$dbLoadBalancerFactory,
    			$httpRequestFactory
    		);
    	}
    
    	/**
    	 * Avoid filtering automatic account creation
    	 *
    	 * @param VariableHolder $vars
    	 * @param Title $title
    	 * @param User $user
    	 * @param array &$skipReasons
    	 * @return bool|void
    	 */
    	public function onAbuseFilterShouldFilterAction(
    		VariableHolder $vars,
    		Title $title,
    		User $user,
    		array &$skipReasons
    	) {
    		if ( defined( 'MW_PHPUNIT_TEST' ) ) {
    			return;
    		}
    
    		$varManager = AbuseFilterServices::getVariablesManager();
    
    		$action = $varManager->getVar( $vars, 'action', 1 )->toString();
    		if ( $action === 'autocreateaccount' ) {
    			$skipReasons[] = 'Blocking automatic account creation is not allowed';
    
    			return false;
    		}
    	}
    
    	public function onCreateWikiStatePrivate( string $dbname ): void {
    		/*$localRepo = MediaWikiServices::getInstance()->getRepoGroup()->getLocalRepo();
    		$sitemaps = $localRepo->getBackend()->getTopFileList( [
    			'dir' => $localRepo->getZonePath( 'public' ) . '/sitemaps',
    			'adviseStat' => false,
    		] );
    
    		foreach ( $sitemaps as $sitemap ) {
    			$status = $localRepo->getBackend()->quickDelete( [
    				'src' => $localRepo->getZonePath( 'public' ) . '/sitemaps/' . $sitemap,
    			] );
    
    			if ( !$status->isOK() ) {
    				$statusFormatter = MediaWikiServices::getInstance()->getFormatterFactory()
    					->getStatusFormatter( RequestContext::getMain() );
    
    				$statusMessage = $statusFormatter->getWikiText( $status );
    				wfDebugLog( 'WikiOasisMagic', "Sitemap \"{$sitemap}\" failed to delete: {$statusMessage}" );
    			}
    		}
    
    		$localRepo->getBackend()->clean( [ 'dir' => $localRepo->getZonePath( 'public' ) . '/sitemaps' ] );*/
    	}
    
    	public function onCreateWikiTables( array &$cTables ): void {
    		$cTables['localnames'] = 'ln_wiki';
    		$cTables['localuser'] = 'lu_wiki';
    	}
    
        public function onImportDumpJobGetFile( &$filePath, $importDumpRequestManager ): void {
            wfDebugLog( 'WikiOasisMagic', "Importing dump from {$filePath}" );
            $originalFilePath = $importDumpRequestManager->getSplitFilePath();
    
            if ( $originalFilePath === null ) {
                return;
            }
    
            wfDebugLog( 'WikiOasisMagic', "Importing dump from {$originalFilePath} to {$filePath}" );
    
            // copy $originalFilePath to $filePath file
            if (!copy('/var/www/mediawiki/images/metawiki/'.$originalFilePath, $filePath)) {
                throw new RuntimeException("Failed to copy $originalFilePath to $filePath");
            }
    
            wfDebugLog( 'WikiOasisMagic', "Importing dump from {$originalFilePath} to {$filePath} done" );
    	}
    
    	/**
    	 * From WikimediaMessages
    	 * When core requests certain messages, change the key to a Miraheze version.
    	 *
    	 * @see https://www.mediawiki.org/wiki/Manual:Hooks/MessageCacheFetchOverrides
    	 * @param string[] &$keys
    	 */
    	public function onMessageCacheFetchOverrides( array &$keys ): void {
    		static $keysToOverride = [
    			/*'centralauth-groupname',
    			'centralauth-login-error-locked',
    			'createwiki-close-email-body',
    			'createwiki-close-email-sender',
    			'createwiki-close-email-subject',
    			'createwiki-defaultmainpage',
    			'createwiki-defaultmainpage-summary',
    			'createwiki-email-body',
    			'createwiki-email-subject',
    			'createwiki-error-subdomaintaken',
    			'createwiki-help-bio',
    			'createwiki-help-category',
    			'createwiki-help-reason',
    			'createwiki-help-subdomain',
    			'createwiki-label-reason',
    			'dberr-again',
    			'dberr-problems',
    			'globalblocking-ipblocked-range',
    			'globalblocking-ipblocked-xff',
    			'globalblocking-ipblocked',*/
    			'grouppage-autoconfirmed',
    			'grouppage-automoderated',
    			'grouppage-autoreview',
    			'grouppage-blockedfromchat',
    			'grouppage-bot',
    			'grouppage-bureaucrat',
    			'grouppage-chatmod',
    			'grouppage-checkuser',
    			'grouppage-commentadmin',
    			'grouppage-csmoderator',
    			'grouppage-editor',
    			'grouppage-flow-bot',
    			'grouppage-interface-admin',
    			'grouppage-moderator',
    			'grouppage-no-ipinfo',
    			'grouppage-reviewer',
    			'grouppage-suppress',
    			'grouppage-sysop',
    			'grouppage-upwizcampeditors',
    			'grouppage-user',
    			/*'importdump-help-reason',
    			'importdump-help-target',
    			'importdump-help-upload-file',
    			'importdump-import-failed-comment',
    			'importtext',
    			'interwiki_intro',
    			'newsignuppage-loginform-tos',
    			'newsignuppage-must-accept-tos',
    			'oathauth-step1',
    			'prefs-help-realname',
    			'privacypage',
    			'requestwiki-error-invalidcomment',
    			'requestwiki-info-guidance',
    			'requestwiki-info-guidance-post',
    			'requestwiki-label-agreement',
    			'requestwiki-success',
    			'restriction-delete',
    			'restriction-protect',
    			'skinname-snapwikiskin',
    			'snapwikiskin',
    			'uploadtext',
    			'webauthn-module-description',
    			'wikibase-sitelinks-miraheze',*/
    		];
    
    		$languageCode = $this->options->get( MainConfigNames::LanguageCode );
    
    		$transformationCallback = static function ( string $key, MessageCache $cache ) use ( $languageCode ): string {
    			$transformedKey = "wikioasis-$key";
    
    			// MessageCache uses ucfirst if ord( key ) is < 128, which is true of all
    			// of the above.  Revisit if non-ASCII keys are used.
    			$ucKey = ucfirst( $key );
    
    			if (
    				/*
    				 * Override order:
    				 * 1. If the MediaWiki:$ucKey page exists, use the key unprefixed
    				 * (in all languages) with normal fallback order.  Specific
    				 * language pages (MediaWiki:$ucKey/xy) are not checked when
    				 * deciding which key to use, but are still used if applicable
    				 * after the key is decided.
    				 *
    				 * 2. Otherwise, use the prefixed key with normal fallback order
    				 * (including MediaWiki pages if they exist).
    				 */
    				$cache->getMsgFromNamespace( $ucKey, $languageCode ) === false
    			) {
    				return $transformedKey;
    			}
    
    			return $key;
    		};
    
    		foreach ( $keysToOverride as $key ) {
    			$keys[$key] = $transformationCallback;
    		}
    	}
    
    	public function onTitleReadWhitelist( $title, $user, &$whitelisted ) {
    		if ( $title->equals( Title::newMainPage() ) ) {
    			$whitelisted = true;
    			return;
    		}
    
    		$specialsArray = [
    			'CentralAutoLogin',
    			'CentralLogin',
    			'ConfirmEmail',
    			'CreateAccount',
    			'Notifications',
    			'OAuth',
    			'ResetPassword'
    		];
    
    		if ( $user->isAllowed( 'interwiki' ) ) {
    			$specialsArray[] = 'Interwiki';
    		}
    
    		if ( $title->isSpecialPage() ) {
    			$rootName = strtok( $title->getText(), '/' );
    			$rootTitle = Title::makeTitle( $title->getNamespace(), $rootName );
    
    			foreach ( $specialsArray as $page ) {
    				if ( $rootTitle->equals( SpecialPage::getTitleFor( $page ) ) ) {
    					$whitelisted = true;
    					return;
    				}
    			}
    		}
    	}
    
    	public function onGlobalUserPageWikis( array &$list ): bool {
    		$cwCacheDir = $this->options->get( 'CreateWikiCacheDirectory' );
    
    		if ( file_exists( "{$cwCacheDir}/databases.php" ) ) {
    			$databasesArray = include "{$cwCacheDir}/databases.php";
    
    			$dbList = array_keys( $databasesArray['databases'] ?? [] );
    
    			// Filter out those databases that don't have GlobalUserPage enabled
    			$list = array_filter( $dbList, static function ( $dbname ) {
    				$extensions = new ManageWikiExtensions( $dbname );
    				return in_array( 'globaluserpage', $extensions->list() );
    			} );
    
    			return false;
    		}
    
    		return true;
    	}
    
    	public function onMimeMagicInit( $mimeMagic ) {
    		$mimeMagic->addExtraTypes( 'text/plain txt off' );
    	}
    
    	public function onSkinAddFooterLinks( Skin $skin, string $key, array &$footerItems ) {
    		/*if ( $key === 'places' ) {
    			$footerItems['termsofservice'] = $this->addFooterLink( $skin, 'termsofservice', 'termsofservicepage' );
    			$footerItems['donate'] = $this->addFooterLink( $skin, 'miraheze-donate', 'miraheze-donatepage' );
    		}*/
    	}
    
    	public function onSiteNoticeAfter( &$siteNotice, $skin ) {
    		/*$cwConfig = new GlobalVarConfig( 'cw' );
    
    		if ( $cwConfig->get( 'Closed' ) ) {
    			if ( $cwConfig->get( 'Private' ) ) {
    				$siteNotice .= '<div class="wikitable" style="text-align: center; width: 90%; margin-left: auto; margin-right:auto; padding: 15px; border: 4px solid black; background-color: #EEE;"> <span class="plainlinks"> <img src="https://static.miraheze.org/metawiki/0/02/Wiki_lock.png" align="left" style="width:80px;height:90px;">' . $skin->msg( 'miraheze-sitenotice-closed-private' )->parse() . '</span></div>';
    			} elseif ( $cwConfig->get( 'Locked' ) ) {
    				$siteNotice .= '<div class="wikitable" style="text-align: center; width: 90%; margin-left: auto; margin-right:auto; padding: 15px; border: 4px solid black; background-color: #EEE;"> <span class="plainlinks"> <img src="https://static.miraheze.org/metawiki/5/5f/Out_of_date_clock_icon.png" align="left" style="width:80px;height:90px;">' . $skin->msg( 'miraheze-sitenotice-closed-locked' )->parse() . '</span></div>';
    			} else {
    				$siteNotice .= '<div class="wikitable" style="text-align: center; width: 90%; margin-left: auto; margin-right:auto; padding: 15px; border: 4px solid black; background-color: #EEE;"> <span class="plainlinks"> <img src="https://static.miraheze.org/metawiki/0/02/Wiki_lock.png" align="left" style="width:80px;height:90px;">' . $skin->msg( 'miraheze-sitenotice-closed' )->parse() . '</span></div>';
    			}
    		} elseif ( $cwConfig->get( 'Inactive' ) && $cwConfig->get( 'Inactive' ) !== 'exempt' ) {
    			if ( $cwConfig->get( 'Private' ) ) {
    				$siteNotice .= '<div class="wikitable" style="text-align: center; width: 90%; margin-left: auto; margin-right:auto; padding: 15px; border: 4px solid black; background-color: #EEE;"> <span class="plainlinks"> <img src="https://static.miraheze.org/metawiki/5/5f/Out_of_date_clock_icon.png" align="left" style="width:80px;height:90px;">' . $skin->msg( 'miraheze-sitenotice-inactive-private' )->parse() . '</span></div>';
    			} else {
    				$siteNotice .= '<div class="wikitable" style="text-align: center; width: 90%; margin-left: auto; margin-right:auto; padding: 15px; border: 4px solid black; background-color: #EEE;"> <span class="plainlinks"> <img src="https://static.miraheze.org/metawiki/5/5f/Out_of_date_clock_icon.png" align="left" style="width:80px;height:90px;">' . $skin->msg( 'miraheze-sitenotice-inactive' )->parse() . '</span></div>';
    			}
    		}*/
    	}
    
    	public function onContributionsToolLinks( $id, Title $title, array &$tools, SpecialPage $specialPage ) {
    		$username = $title->getText();
    
    		if ( !IPUtils::isIPAddress( $username ) ) {
    			$globalUserGroups = CentralAuthUser::getInstanceByName( $username )->getGlobalGroups();
    
    			if (
    				!in_array( 'steward', $globalUserGroups ) &&
    				!in_array( 'global-sysop', $globalUserGroups ) &&
    				!$specialPage->getUser()->isAllowed( 'centralauth-lock' )
    			) {
    				return;
    			}
    
    			$tools['centralauth'] = Linker::makeExternalLink(
    				'https://meta.wikioasis.org/wiki/Special:CentralAuth/' . $username,
    				strtolower( $specialPage->msg( 'centralauth' )->text() )
    			);
    		}
    	}
    
    	/**
    	 * phpcs:disable MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName
    	 *
    	 * @param Title $title
    	 * @param string &$url
    	 * @param string $query
    	 */
    	public function onGetLocalURL__Internal( $title, &$url, $query ) {
    		// phpcs:enable
    
    		if ( defined( 'MW_PHPUNIT_TEST' ) ) {
    			return;
    		}
    
    		// If the URL contains wgScript, rewrite it to use wgArticlePath
    		if ( str_contains( $url, $this->options->get( MainConfigNames::Script ) ) ) {
    			$dbkey = wfUrlencode( $title->getPrefixedDBkey() );
    			$url = str_replace( '$1', $dbkey, $this->options->get( MainConfigNames::ArticlePath ) );
    			if ( $query !== '' ) {
    				$url = wfAppendQuery( $url, $query );
    			}
    		}
    	}
    
    	private function addFooterLink( $skin, $desc, $page ) {
    		if ( $skin->msg( $desc )->inContentLanguage()->isDisabled() ) {
    			$title = null;
    		} else {
    			$title = Title::newFromText( $skin->msg( $page )->inContentLanguage()->text() );
    		}
    
    		if ( !$title ) {
    			return '';
    		}
    
    		return Html::element( 'a',
    			[ 'href' => $title->fixSpecialName()->getLinkURL() ],
    			$skin->msg( $desc )->text()
    		);
    	}
    
    	/** Removes redis keys for jobrunner */
    	private function removeRedisKey( string $key ) {
    		$jobTypeConf = $this->options->get( MainConfigNames::JobTypeConf );
    		if ( !isset( $jobTypeConf['default']['redisServer'] ) || !$jobTypeConf['default']['redisServer'] ) {
    			return;
    		}
    
    		$hostAndPort = IPUtils::splitHostAndPort( $jobTypeConf['default']['redisServer'] );
    
    		if ( $hostAndPort ) {
    			try {
    				$redis = new Redis();
    				$redis->connect( $hostAndPort[0], $hostAndPort[1] );
    				$redis->auth( $jobTypeConf['default']['redisConfig']['password'] );
    				$redis->del( $redis->keys( $key ) );
    			} catch ( Throwable $ex ) {
    				// empty
    			}
    		}
    	}
    
    	/** Remove memcached keys */
    	private function removeMemcachedKey( string $key ) {
    		$memcachedServers = $this->options->get( 'WikiOasisMemcachedServers' );
    
    		try {
    			foreach ( $memcachedServers as $memcachedServer ) {
    				$memcached = new Memcached();
    
    				$memcached->addServer( $memcachedServer[0], (string)$memcachedServer[1] );
    
    				// Fetch all keys
    				$keys = $memcached->getAllKeys();
    				if ( !is_array( $keys ) ) {
    					return;
    				}
    
    				foreach ( $keys as $item ) {
    					// Decide which keys to delete
    					if ( preg_match( "/{$key}/", $item ) ) {
    						$memcached->delete( $item );
    					} else {
    						continue;
    					}
    				}
    			}
    		} catch ( Throwable $ex ) {
    			// empty
    		}
    	}
    }
    SkywikiMagic/includes/SpecialChangeDomain.php0000644000000000000000000001212114727411650020310 0ustar  rootroot<?php
    
    namespace WikiOasis\WikiOasisMagic;
    
    use ErrorPageError;
    use MediaWiki\Html\Html;
    use MediaWiki\Message\Message;
    use MediaWiki\HTMLForm\HTMLForm;
    use MediaWiki\SpecialPage\SpecialPage;
    use Miraheze\CreateWiki\ConfigNames;
    use Miraheze\CreateWiki\Services\CreateWikiDatabaseUtils;
    use Miraheze\CreateWiki\Services\RemoteWikiFactory;
    use ManualLogEntry;
    
    class SpecialChangeDomain extends SpecialPage {
    
    	private CreateWikiDatabaseUtils $databaseUtils;
    	private RemoteWikiFactory $remoteWikiFactory;
    
    	public function __construct(
    		CreateWikiDatabaseUtils $databaseUtils,
    		RemoteWikiFactory $remoteWikiFactory
    	) {
    		parent::__construct( 'ChangeDomain', 'managewiki-restricted' );
    
    		$this->databaseUtils = $databaseUtils;
    		$this->remoteWikiFactory = $remoteWikiFactory;
    	}
    
    	/**
    	 * @param ?string $par
    	 */
    	public function execute( $par ): void {
    		if ( !$this->databaseUtils->isCurrentWikiCentral() ) {
    			throw new ErrorPageError( 'errorpagetitle', 'createwiki-wikinotcentralwiki' );
    		}
    		$par = explode( '/', $par ?? '', 3 );
    
    		$this->getOutput()->setPageTitle( 'Change domain' );
    		if ( $par[0] == '' ) {
    			$this->showInputBox();
    		} else {
    			$this->showWikiForm( $par[0] );
    		}
    	}
    
    
    	public function showInputBox() {
    		$formDescriptor = [
    			'info' => [
    				'default' => $this->msg( 'changedomain-info' )->text(),
    				'type' => 'info',
    			],
    			'dbname' => [
    				'label-message' => 'managewiki-label-dbname',
    				'type' => 'text',
    				'size' => 20,
    				'required' => true
    			]
    		];
    
    		if ( !$this->getContext()->getUser()->isAllowed( 'managewiki-restricted' ) ) {
                            $this->getOutput()->addHTML(
                                    Html::errorBox( $this->msg( 'managewiki-error-nopermission' )->escaped() )
                            );
    		}
    
    		$htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext(), 'searchForm' );
    		$htmlForm->setWrapperLegendMsg( 'managewiki-core-header' );
    		$htmlForm->setMethod( 'post' )
    			->setSubmitCallback( [ $this, 'onSubmitRedirectToWikiForm' ] )
    			->prepareForm()
    			->show();
    
    		return true;
    	}
    
    
    	public function onSubmitRedirectToWikiForm( array $params ) {
    		if ( $params['dbname'] !== '' ) {
    			header( 'Location: ' . SpecialPage::getTitleFor( 'ChangeDomain' )->getFullURL() . '/' . $params['dbname'] );
    		} else {
    			return 'Invalid url.';
    		}
    
    		return true;
    	}
    
    
    	public function showWikiForm( $wiki ) {
    		$out = $this->getOutput();
    
    		$out->addModules( [ 'ext.managewiki.oouiform' ] );
    
    		$out->addModuleStyles( [
    			'ext.managewiki.oouiform.styles',
    			'mediawiki.widgets.TagMultiselectWidget.styles',
    		] );
    
    		$out->addModuleStyles( [ 'oojs-ui-widgets.styles' ] );
    		$out->addModules( [ 'mediawiki.special.userrights' ] );
    
    		$remoteWiki = $this->remoteWikiFactory->newInstance( $wiki );
    
    		if ( $remoteWiki->isLocked() ) {
    			$out->addHTML( Html::errorBox( $this->msg( 'managewiki-mwlocked' )->escaped() ) );
    		}
    
    		$options = [];
    
                    $formDescriptor = [
    			'wiki' => [
    			        'type' => 'hidden',
    			        'name' => 'wiki',
    			        'default' => $wiki,
        			],
                            'subdomain' => [
                                    'default' => $remoteWiki->getServerName(),
                                    'label-message' => 'changedomain-label-domain',
                                    'type' => 'text',
                                    'size' => 20
    			]
    		];
    
    		$htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext(), 'changesubdomain' );
    
    		$htmlForm->setSubmitTextMsg( 'managewiki-save' );
    
                    $htmlForm->setSubmitCallback( [ $this, 'submitForm' ] );
    
    		if ( !$this->getContext()->getUser()->isAllowed( 'managewiki-restricted' ) ) {
    			$out->addHTML(
    				Html::errorBox( $this->msg( 'managewiki-error-nopermission' )->escaped() )
    			);
    		}
    
    		$htmlForm->show();
    	}
    
            public function submitForm( array $params ) {
                    $out = $this->getOutput();
    
                    $remoteWiki = $this->remoteWikiFactory->newInstance( $params['wiki'] );
    
                    if ( $remoteWiki->isLocked() ) {
    			$out->addHTML( Html::errorBox( $this->msg( 'managewiki-mwlocked' )->escaped() ) );
    			return;
    		}
    
    		if ( !$this->getContext()->getUser()->isAllowed( 'managewiki-restricted' ) ) {
    			$out->addHTML(
    				Html::errorBox( $this->msg( 'managewiki-error-nopermission' )->escaped() )
    			);
    			return;
    		}
    
    		$remoteWiki->setServerName( $params['subdomain'] );
    		$remoteWiki->commit();
                    $logEntry = new ManualLogEntry( 'managewiki', 'settings' );
                    $logEntry->setPerformer( $this->getUser() );
                    $logEntry->setTarget( SpecialPage::getTitleValueFor( 'ChangeDomain', (string)$params['wiki'] ) );
                    $logEntry->setParameters( [ '4::wiki' => $params['wiki'], '5::changes' => 'servername' ] );
                    $logID = $logEntry->insert();
                    $logEntry->publish( $logID );
    		$out->addHTML(
    			Html::successBox(
    				Html::element(
    					'p',
    					[],
    					wfMessage( 'managewiki-success' )->plain()
    				),
    				'mw-notify-success'
    			)
    		);
    
                    return true;
            }
    
    	/**
    	 * @inheritDoc
    	 */
    	protected function getGroupName(): string {
    		return 'wikimanage';
    	}
    }