2016-01-11 17:45:24 +00:00
< ? php
$IP = getenv ( 'MW_INSTALL_PATH' );
if ( $IP === false ) {
$IP = __DIR__ . '/../../..' ;
}
require_once ( " $IP /maintenance/Maintenance.php " );
/**
* A maintenance script that generates sample notifications for testing purposes .
*/
class GenerateSampleNotifications extends Maintenance {
2016-03-02 20:04:56 +00:00
private $supportedNotificationTypes = array (
'welcome' ,
'edit-user-talk' ,
'mention' ,
'page-linked' ,
'reverted' ,
'email' ,
'user-rights' ,
'cx' ,
'osm' ,
2016-07-29 12:20:42 +00:00
'edit-thanks' ,
'edu' ,
2016-08-04 15:19:20 +00:00
'page-connection' ,
2016-03-02 20:04:56 +00:00
);
2016-01-11 17:45:24 +00:00
public function __construct () {
parent :: __construct ();
$this -> mDescription = " Generate sample notifications " ;
$this -> addOption (
2016-03-02 20:04:56 +00:00
'force' ,
'Bypass confirmation' ,
false , false , 'f' );
$allTypes = implode ( ',' , $this -> supportedNotificationTypes );
$this -> addOption (
'types' ,
" Comma-separated list of notification types to generate ( $allTypes ) " ,
false , true , 't' );
2016-01-11 17:45:24 +00:00
$this -> addOption (
2016-03-02 20:04:56 +00:00
'user' ,
'Name of the user receiving the notifications' ,
true , true , 'u' );
2016-01-11 17:45:24 +00:00
$this -> addOption (
2016-03-02 20:04:56 +00:00
'agent' ,
'Name of the user creating the notifications' ,
true , true , 'a' );
$this -> addOption (
'other' ,
'Name of another user involved with the notifications' ,
true , true , 'o' );
2016-01-11 17:45:24 +00:00
}
public function execute () {
if ( ! class_exists ( 'EchoHooks' ) ) {
$this -> error ( " Echo isn't enabled on this wiki \n " , 1 );
}
$user = $this -> getOptionUser ( 'user' );
$agent = $this -> getOptionUser ( 'agent' );
$otherUser = $this -> getOptionUser ( 'other' );
2016-02-17 17:27:49 +00:00
$title = Title :: newFromText ( 'This is a pretty long page title lets see if it is going to be truncated' );
2016-01-11 17:45:24 +00:00
2016-03-02 20:04:56 +00:00
$types = $this -> getOption ( 'types' );
if ( $types ) {
$types = explode ( ',' , $types );
} else {
$types = $this -> supportedNotificationTypes ;
}
2016-01-11 17:45:24 +00:00
$this -> confirm ();
$this -> output ( " Started processing... \n " );
2016-03-02 20:04:56 +00:00
if ( $this -> shouldGenerate ( 'welcome' , $types ) ) {
$this -> generateWelcome ( $user );
}
if ( $this -> shouldGenerate ( 'edit-user-talk' , $types ) ) {
$this -> generateEditUserTalk ( $user , $agent );
}
if ( $this -> shouldGenerate ( 'mention' , $types ) ) {
$this -> generateMention ( $user , $agent , $otherUser , $title );
}
if ( $this -> shouldGenerate ( 'page-linked' , $types ) ) {
$this -> generatePageLink ( $user , $agent );
}
if ( $this -> shouldGenerate ( 'reverted' , $types ) ) {
$this -> generateReverted ( $user , $agent );
}
if ( $this -> shouldGenerate ( 'email' , $types ) ) {
$this -> generateEmail ( $user , $agent );
}
if ( $this -> shouldGenerate ( 'user-rights' , $types ) ) {
$this -> generateUserRights ( $user , $agent );
}
if ( $this -> shouldGenerate ( 'cx' , $types ) ) {
$this -> generateContentTranslation ( $user );
}
if ( $this -> shouldGenerate ( 'osm' , $types ) ) {
$this -> generateOpenStackManager ( $user , $agent );
}
2016-01-11 17:45:24 +00:00
2016-06-16 16:04:24 +00:00
if ( $this -> shouldGenerate ( 'edit-thanks' , $types ) ) {
$this -> generateEditThanks ( $user , $agent , $otherUser );
}
2016-07-29 12:20:42 +00:00
if ( $this -> shouldGenerate ( 'edu' , $types ) ) {
$this -> generateEducationProgram ( $user , $agent );
}
2016-08-04 15:19:20 +00:00
if ( $this -> shouldGenerate ( 'page-connection' , $types ) ) {
$this -> generateWikibase ( $user , $agent );
}
2016-01-11 17:45:24 +00:00
$this -> output ( " Completed \n " );
}
private function generateEditUserTalk ( User $user , User $agent ) {
$this -> output ( " { $agent -> getName () } is writing on { $user -> getName () } 's user talk page \n " );
$editId = $this -> generateRandomString ();
$section = " == section $editId == \n \n this is the text $editId\n\n ~~~~ \n \n " ;
$this -> addToUserTalk ( $user , $agent , $section );
}
private function getOptionUser ( $optionName ) {
$username = $this -> getOption ( $optionName );
$user = User :: newFromName ( $username );
if ( $user -> isAnon () ) {
$this -> error ( " User $username does not seem to exist in this wiki " , 1 );
}
return $user ;
}
private function generateRandomString ( $length = 10 ) {
return substr ( str_shuffle ( " 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ " ), 0 , $length );
}
protected function confirm () {
2016-03-02 20:04:56 +00:00
if ( $this -> getOption ( 'force' , false ) ) {
return ;
}
2016-01-11 17:45:24 +00:00
$this -> output ( " === WARNING === \n " );
$this -> output ( " This script modifies the content of several pages, \n " );
$this -> output ( " including user's talk pages. \n " );
$this -> output ( " ONLY RUN ON TEST WIKIS \n " );
$this -> output ( " Enter 'yes' if you wish to continue or any other key to exit \n " );
$confirm = $this -> readconsole ();
if ( $confirm !== 'yes' ) {
$this -> error ( 'Safe decision' , 1 );
}
}
private function addToUserTalk ( User $user , User $agent , $contentText ) {
$this -> addToPageContent ( $user -> getTalkPage (), $agent , $contentText );
}
private function addToPageContent ( Title $title , User $agent , $contentText ) {
$page = WikiPage :: factory ( $title );
$previousContent = " " ;
$page -> loadPageData ( 'fromdbmaster' );
$revision = $page -> getRevision ();
if ( $revision ) {
$content = $revision -> getContent ( Revision :: FOR_PUBLIC );
if ( $content instanceof WikitextContent ) {
$previousContent = $content -> getNativeData ();
}
}
$status = $page -> doEditContent (
new WikitextContent ( $contentText . $previousContent ),
'generating sample notifications' ,
0 ,
false ,
$agent
);
if ( ! $status -> isGood () ) {
$this -> error ( " Failed to edit { $title -> getPrefixedText () } : { $status -> getMessage () } " );
}
2016-06-16 16:04:24 +00:00
return $status -> getValue ()[ 'revision' ];
2016-01-11 17:45:24 +00:00
}
2016-02-17 17:27:49 +00:00
private function generateMention ( User $user , User $agent , User $otherUser , Title $title ) {
2016-01-11 17:45:24 +00:00
$mention = " == section { $this -> generateRandomString () } == \n Hello [[User: { $user -> getName () } ]] \n ~~~~ \n " ;
// article talk
2016-02-17 17:27:49 +00:00
$this -> output ( " { $agent -> getName () } is mentioning { $user -> getName () } on { $title -> getTalkPage () -> getPrefixedText () } \n " );
$this -> addToPageContent ( $title -> getTalkPage (), $agent , $mention );
2016-01-11 17:45:24 +00:00
// agent tak
$this -> output ( " { $agent -> getName () } is mentioning { $user -> getName () } on { $agent -> getTalkPage () -> getPrefixedText () } \n " );
$this -> addToPageContent ( $agent -> getTalkPage (), $agent , $mention );
// user talk
$this -> output ( " { $agent -> getName () } is mentioning { $user -> getName () } on { $otherUser -> getTalkPage () -> getPrefixedText () } \n " );
$this -> addToPageContent ( $otherUser -> getTalkPage (), $agent , $mention );
// any other page
2016-02-17 17:27:49 +00:00
$this -> output ( " { $agent -> getName () } is mentioning { $user -> getName () } on { $title -> getPrefixedText () } \n " );
$this -> addToPageContent ( $title , $agent , $mention );
2016-01-11 17:45:24 +00:00
}
private function generatePageLink ( User $user , User $agent ) {
2016-02-03 17:34:01 +00:00
$this -> generateOnePageLink ( $user , $agent );
$this -> generateMultiplePageLinks ( $user , $agent );
2016-01-11 17:45:24 +00:00
}
private function generateNewPageTitle () {
return Title :: newFromText ( $this -> generateRandomString () );
}
private function generateReverted ( User $user , User $agent ) {
global $wgRequest ;
$agent -> addGroup ( 'sysop' );
// revert (undo)
$moai = Title :: newFromText ( 'Moai' );
$page = WikiPage :: factory ( $moai );
$this -> output ( " { $agent -> getName () } is reverting { $user -> getName () } 's edit on { $moai -> getPrefixedText () } \n " );
$this -> addToPageContent ( $moai , $agent , " \n creating a good revision here \n " );
$this -> addToPageContent ( $moai , $user , " \n adding a line here \n " );
2016-10-06 16:22:28 +00:00
// hack: EchoHooks::onPageContentSaveComplete depends on the request to know which revision is being reverted
2016-01-11 17:45:24 +00:00
$wgRequest -> setVal ( 'wpUndidRevision' , $page -> getRevision () -> getId () );
$content = $page -> getUndoContent ( $page -> getRevision (), $page -> getRevision () -> getPrevious () );
$status = $page -> doEditContent ( $content , 'undo' , 0 , false , $agent );
if ( ! $status -> isGood () ) {
$this -> error ( " Failed to undo { $moai -> getPrefixedText () } : { $status -> getMessage () } " );
}
// rollback
$moai2 = Title :: newFromText ( 'Moai2' );
$page = WikiPage :: factory ( $moai2 );
$this -> output ( " { $agent -> getName () } is rolling back { $user -> getName () } 's edits on { $moai2 -> getPrefixedText () } \n " );
$this -> addToPageContent ( $moai2 , $agent , " \n creating a good revision here \n " );
$this -> addToPageContent ( $moai2 , $user , " \n adding a line here \n " );
$this -> addToPageContent ( $moai2 , $user , " \n adding a line here \n " );
$details = array ();
2016-07-12 13:20:58 +00:00
$token = $agent -> getEditToken ( 'rollback' , null );
2016-01-11 17:45:24 +00:00
$errors = $page -> doRollback ( $user -> getName (), 'generating reverted notification' , $token , false , $details , $agent );
if ( $errors ) {
2016-07-12 13:20:58 +00:00
$this -> error ( serialize ( $errors ) );
2016-01-11 17:45:24 +00:00
}
}
private function generateWelcome ( User $user ) {
$this -> output ( " Welcoming { $user -> getName () } \n " );
EchoEvent :: create ( array (
'type' => 'welcome' ,
'agent' => $user ,
'extra' => array (
'notifyAgent' => true
)
) );
}
private function generateEmail ( User $user , User $agent ) {
$this -> output ( " { $agent -> getName () } is emailing { $user -> getName () } \n " );
EchoEvent :: create ( array (
'type' => 'emailuser' ,
'extra' => array (
'to-user-id' => $user -> getId (),
2016-02-10 17:34:26 +00:00
'subject' => 'Long time no see' ,
2016-01-11 17:45:24 +00:00
),
'agent' => $agent ,
) );
}
private function generateUserRights ( User $user , User $agent ) {
$this -> output ( " { $agent -> getName () } is changing { $user -> getName () } 's rights \n " );
$this -> createUserRightsNotification ( $user , $agent , array ( 'OnlyAdd-1' ), null );
$this -> createUserRightsNotification ( $user , $agent , null , array ( 'JustRemove-1' , 'JustRemove-2' ) );
$this -> createUserRightsNotification ( $user , $agent , array ( 'Add-1' , 'Add-2' ), array ( 'Remove-1' , 'Remove-2' ) );
}
private function createUserRightsNotification ( User $user , User $agent , $add , $remove ) {
EchoEvent :: create (
array (
'type' => 'user-rights' ,
'extra' => array (
'user' => $user -> getID (),
'add' => $add ,
'remove' => $remove ,
2016-07-28 15:46:58 +00:00
'reason' => 'This is the reason for changing your user rights.' ,
2016-01-11 17:45:24 +00:00
),
'agent' => $agent ,
)
);
}
2016-02-08 15:37:49 +00:00
private function generateContentTranslation ( User $user ) {
if ( ! class_exists ( 'ContentTranslationHooks' ) ) {
return ;
}
$this -> output ( " Generating CX notifications \n " );
foreach ( array ( 'cx-first-translation' , 'cx-tenth-translation' , 'cx-hundredth-translation' ) as $eventType ) {
EchoEvent :: create (
array (
'type' => $eventType ,
'extra' => array (
'recipient' => $user -> getId (),
),
)
);
}
EchoEvent :: create (
array (
'type' => 'cx-suggestions-available' ,
'extra' => array (
'recipient' => $user -> getId (),
'lastTranslationTitle' => 'History of the People\'s Republic of China'
),
)
);
2016-02-03 17:34:01 +00:00
}
private function generateOnePageLink ( User $user , User $agent ) {
$pageBeingLinked = $this -> generateNewPageTitle ();
$this -> addToPageContent ( $pageBeingLinked , $user , " this is a new page " );
$pageLinking = $this -> generateNewPageTitle ();
$content = " checkout [[ { $pageBeingLinked -> getPrefixedText () } ]]! " ;
$this -> output ( " { $agent -> getName () } is linking to { $pageBeingLinked -> getPrefixedText () } from { $pageLinking -> getPrefixedText () } \n " );
$this -> addToPageContent ( $pageLinking , $agent , $content );
}
private function generateMultiplePageLinks ( User $user , User $agent ) {
$pageBeingLinked = $this -> generateNewPageTitle ();
$this -> addToPageContent ( $pageBeingLinked , $user , " this is a new page " );
2016-02-08 15:37:49 +00:00
2016-02-03 17:34:01 +00:00
$content = " checkout [[ { $pageBeingLinked -> getPrefixedText () } ]]! " ;
$this -> output ( " { $agent -> getName () } is linking to { $pageBeingLinked -> getPrefixedText () } from multiple pages \n " );
$this -> addToPageContent ( $this -> generateNewPageTitle (), $agent , $content );
$this -> addToPageContent ( $this -> generateNewPageTitle (), $agent , $content );
$this -> addToPageContent ( $this -> generateNewPageTitle (), $agent , $content );
2016-02-08 15:37:49 +00:00
}
2016-02-15 19:54:35 +00:00
private function generateOpenStackManager ( User $user , User $agent ) {
if ( ! class_exists ( 'OpenStackManagerHooks' ) ) {
return ;
}
$this -> output ( " Generating OpenStackManager notifications \n " );
foreach ( array ( 'build-completed' , 'reboot-completed' , 'deleted' ) as $action ) {
EchoEvent :: create ( array (
'type' => " osm-instance- $action " ,
'title' => Title :: newFromText ( " Moai " ),
'agent' => $user ,
'extra' => array (
'instanceName' => 'instance1' ,
'projectName' => 'TheProject' ,
'notifyAgent' => true ,
)
) );
}
EchoEvent :: create ( array (
'type' => 'osm-projectmembers-add' ,
'title' => Title :: newFromText ( " Moai " ),
'agent' => $agent ,
'extra' => array ( 'userAdded' => $user -> getId () ),
) );
}
2016-03-02 20:04:56 +00:00
private function shouldGenerate ( $type , $types ) {
return array_search ( $type , $types ) !== false ;
}
2016-06-16 16:04:24 +00:00
private function generateEditThanks ( User $user , User $agent , User $otherUser ) {
$this -> generateOneEditThanks ( $user , $agent );
$this -> generateMultipleEditThanks ( $user , $agent , $otherUser );
}
private function generateOneEditThanks ( User $user , User $agent ) {
if ( ! class_exists ( 'ThanksHooks' ) ) {
return ;
}
// make an edit, thank it once
$title = $this -> generateNewPageTitle ();
$revision = $this -> addToPageContent ( $title , $user , " an awesome edit! ~~~~ " );
EchoEvent :: create ( [
'type' => 'edit-thank' ,
'title' => $title ,
'extra' => [
'revid' => $revision -> getId (),
'thanked-user-id' => $user -> getId (),
'source' => 'generateSampleNotifications.php' ,
],
'agent' => $agent ,
] );
$this -> output ( " { $agent -> getName () } is thanking { $user -> getName () } for edit { $revision -> getId () } on { $title -> getPrefixedText () } \n " );
}
private function generateMultipleEditThanks ( User $user , User $agent , User $otherUser ) {
if ( ! class_exists ( 'ThanksHooks' ) ) {
return ;
}
// make an edit, thank it twice
$title = $this -> generateNewPageTitle ();
$revision = $this -> addToPageContent ( $title , $user , " an even better edit! ~~~~ " );
EchoEvent :: create ( [
'type' => 'edit-thank' ,
'title' => $title ,
'extra' => [
'revid' => $revision -> getId (),
'thanked-user-id' => $user -> getId (),
'source' => 'generateSampleNotifications.php' ,
],
'agent' => $agent ,
] );
EchoEvent :: create ( [
'type' => 'edit-thank' ,
'title' => $title ,
'extra' => [
'revid' => $revision -> getId (),
'thanked-user-id' => $user -> getId (),
'source' => 'generateSampleNotifications.php' ,
],
'agent' => $otherUser ,
] );
$this -> output ( " { $agent -> getName () } and { $otherUser -> getName () } are thanking { $user -> getName () } for edit { $revision -> getId () } on { $title -> getPrefixedText () } \n " );
}
2016-07-29 12:20:42 +00:00
private function generateEducationProgram ( User $user , User $agent ) {
if ( ! class_exists ( 'EducationProgram\Extension' ) ) {
$this -> output ( 'class EducationProgram\Extension not found' );
return ;
}
$chem101 = Title :: newFromText ( 'School/Chemistry101' );
if ( ! $chem101 -> exists () ) {
$this -> addToPageContent ( $chem101 , $agent , " \n This is the main page for the Chemistry 101 course \n " );
}
$notificationManager = EducationProgram\Extension :: globalInstance () -> getNotificationsManager ();
$this -> output ( " { $agent -> getName () } is adding { $user -> getName () } to { $chem101 -> getPrefixedText () } as instructor, student, campus volunteer and online volunteer. \n " );
$types = array (
'ep-instructor-add-notification' ,
'ep-online-add-notification' ,
'ep-campus-add-notification' ,
'ep-student-add-notification' ,
);
foreach ( $types as $type ) {
$notificationManager -> trigger (
$type ,
array (
'role-add-title' => $chem101 ,
'agent' => $agent ,
'users' => array ( $user -> getId () ),
)
);
}
// NOTE: Not generating 'ep-course-talk-notification' for now
// as it requires a full setup to actually work (institution, course, instructors, students).
}
2016-08-04 15:19:20 +00:00
private function generateWikibase ( User $user , User $agent ) {
if ( ! class_exists ( 'Wikibase\Client\Hooks\EchoNotificationsHandlers' ) ) {
$this -> output ( 'class Wikibase\Client\Hooks\EchoNotificationsHandlers not found' );
return ;
}
$title = $this -> generateNewPageTitle ();
$this -> addToPageContent ( $title , $user , " this is a new page " );
$helpPage = Title :: newFromText ( 'Project:Wikidata' );
$this -> addToPageContent ( $helpPage , $user , " this is the help page " );
$this -> output ( " { $agent -> getName () } is connecting { $user -> getName () } 's page { $title -> getPrefixedText () } to an item \n " );
EchoEvent :: create ( [
'type' => Wikibase\Client\Hooks\EchoNotificationsHandlers :: NOTIFICATION_TYPE ,
'title' => $title ,
'extra' => [
'url' => Title :: newFromText ( 'Item:Q1' ) -> getFullURL (),
'repoSiteName' => 'Wikidata'
],
'agent' => $agent ,
] );
}
2016-01-11 17:45:24 +00:00
}
$maintClass = " GenerateSampleNotifications " ;
require_once ( DO_MAINTENANCE );