r77756 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r77755‎ | r77756 | r77757 >
Date:02:53, 5 December 2010
Author:jeroendedauw
Status:deferred
Tags:
Comment:
Follow up to r77755
Modified paths:
  • /trunk/extensions/DSMW/CHANGELOG (modified) (history)
  • /trunk/extensions/DSMW/DSMW.hooks.php (added) (history)
  • /trunk/extensions/DSMW/DSMW.php (modified) (history)
  • /trunk/extensions/DSMW/includes/DSMW_GlobalFunctions.php (modified) (history)

Diff [purge]

Index: trunk/extensions/DSMW/DSMW.hooks.php
@@ -0,0 +1,703 @@
 2+<?php
 3+
 4+/**
 5+ * Static class for hooks handled by the DSMW extension.
 6+ *
 7+ * @since 1.1
 8+ *
 9+ * @file DSMW.hooks.php
 10+ * @ingroup DSMW
 11+ *
 12+ * @author jean-philippe muller
 13+ * @author Morel Émile
 14+ * @author Jeroen De Dauw
 15+ */
 16+final class DSMWHooks {
 17+
 18+ /**
 19+ * @since 1.1
 20+ *
 21+ * @param EditPage $editor
 22+ * @param OutputPage &$out
 23+ *
 24+ * @return true
 25+ */
 26+ public function onEditConflict( EditPage &$editor, OutputPage &$out ) {
 27+ $conctext = $editor->textbox1;
 28+ $actualtext = $editor->textbox2;
 29+ $initialtext = $editor->getBaseRevision()->mText;
 30+
 31+ // TODO: WTF?!
 32+ $editor->mArticle->updateArticle(
 33+ $actualtext,
 34+ $editor->summary,
 35+ $editor->minoredit,
 36+ $editor->watchthis,
 37+ $bot = false,
 38+ $sectionanchor = ''
 39+ );
 40+
 41+ return true;
 42+ }
 43+
 44+ /**
 45+ * MW Hook used to redirect to page creation (pushfeed, pullfeed, changeset),
 46+ * to forms or to push/pull action testing the action param
 47+ *
 48+ * @since 1.1
 49+ *
 50+ * @param string $action
 51+ * @param Article $article
 52+ *
 53+ * @return true
 54+ */
 55+ public function onUnknownAction( $action, Article $article ) {
 56+ global $wgOut, $wgServerName, $wgScriptPath, $wgUser, $wgScriptExtension, $wgDSMWIP;
 57+
 58+ $urlServer = 'http://' . $wgServerName . $wgScriptPath . "/index{$wgScriptExtension}";
 59+ $urlAjax = 'http://' . $wgServerName . $wgScriptPath;
 60+
 61+ ////////// pull form page////////
 62+ if ( isset( $_GET['action'] ) && $_GET['action'] == 'addpullpage' ) {
 63+ wfDebugLog( 'p2p', 'addPullPage ' );
 64+ $newtext = "Add a new site:
 65+ <div id='dsmw' style=\"color:green;\"></div>
 66+
 67+ {{#form:action=" . $urlServer . "?action=pullpage|method=POST|
 68+ PushFeed Url: {{#input:type=button|value=Url test|onClick=
 69+ var url = document.getElementsByName('url')[0].value;
 70+ if(url.indexOf('PushFeed')==-1){
 71+ alert('No valid PushFeed syntax, see example.');
 72+ }else{
 73+ var urlTmp = url.substring(0,url.indexOf('PushFeed'));
 74+ //alert(urlTmp);
 75+
 76+ var pos1 = urlTmp.indexOf('index.php');
 77+ //alert(pos1);
 78+ var pushUrl='';
 79+ if(pos1!=-1){
 80+ pushUrl = urlTmp.substring(0,pos1);
 81+ //alert('if');
 82+ }else{
 83+ pushUrl = urlTmp;
 84+ //alert('else');
 85+ }
 86+ //alert(pushUrl);
 87+
 88+ //alert(pushUrl+'api.php?action=query&meta=patch&papatchId=1&format=xml');
 89+ var xhr_object = null;
 90+
 91+ if(window.XMLHttpRequest) // Firefox
 92+ xhr_object = new XMLHttpRequest();
 93+ else if(window.ActiveXObject) // Internet Explorer
 94+ xhr_object = new ActiveXObject('Microsoft.XMLHTTP');
 95+ else {
 96+ alert('Votre navigateur ne supporte pas les objets XMLHTTPRequest...');
 97+ return;
 98+ }
 99+ try{ xhr_object.open('GET', '" . $urlAjax . "/extensions/DSMW/files/ajax.php?url='+escape(pushUrl+'api.php?action=query&meta=patch&papatchId=1&format=xml'), true);}
 100+ catch(e){
 101+ //alert('There is no DSMW Server responding at this URL');
 102+ document.getElementById('dsmw').innerHTML = 'There is no DSMW Server responding at this URL!';
 103+ document.getElementById('dsmw').style.color = 'red';
 104+ }
 105+ xhr_object.onreadystatechange = function() {
 106+
 107+ if(xhr_object.readyState == 4) {
 108+ if(xhr_object.statusText=='OK'){
 109+ if(xhr_object.responseText == 'true'){ //alert('URL valid, there is a DSMW Server responding');
 110+ document.getElementById('dsmw').innerHTML = 'URL valid, there is a DSMW Server responding!';
 111+ document.getElementById('dsmw').style.color = 'green';
 112+ }
 113+ else{ //alert('There is no DSMW Server responding at this URL');
 114+ document.getElementById('dsmw').innerHTML = 'There is no DSMW Server responding at this URL!';
 115+ document.getElementById('dsmw').style.color = 'red';
 116+ }
 117+ }
 118+ else{
 119+ //alert('There is no DSMW Server responding at this URL');
 120+ document.getElementById('dsmw').innerHTML = 'There is no DSMW Server responding at this URL!';
 121+ document.getElementById('dsmw').style.color = 'red';
 122+ }
 123+ }
 124+ }
 125+
 126+ xhr_object.send(null);
 127+ }
 128+ }}<br> {{#input:type=text|name=url|size=50}} <b>e.g. http://server/path/index.php?title=PushFeed:PushName</b><br>
 129+ PullFeed Name: <br> {{#input:type=text|name=pullname}}<br>
 130+ {{#input:type=submit|value=ADD}}
 131+ }}";
 132+
 133+ // if article doesn't exist insertNewArticle
 134+ if ( $article->mTitle->exists() ) {
 135+ $article->updateArticle( $newtext, $summary = "", false, false );
 136+ } else {
 137+ $article->insertNewArticle( $newtext, $summary = "", false, false );
 138+ }
 139+ $article->doRedirect();
 140+
 141+ return false;
 142+ }
 143+
 144+
 145+ ///////// push form page////////
 146+ elseif ( isset( $_GET['action'] ) && $_GET['action'] == 'addpushpage' ) {
 147+ wfDebugLog( 'p2p', 'addPushPage' );
 148+ $specialAsk = $urlServer . '?title=Special:Ask';
 149+ $newtext = "Add a new pushfeed:
 150+
 151+ {{#form:action=" . $urlServer . "?action=pushpage|method=POST|
 152+ PushFeed Name: <br> {{#input:class=test|name=name|type=text|onKeyUp=test('$urlServer');}}<div style=\"display:inline; \" id=\"state\" ></div><br />
 153+ Request: {{#input:type=button|value=Test your query|title=click here to test your query results|onClick=
 154+ var query = document.getElementsByName('keyword')[0].value;
 155+ var query1 = encodeURI(query);
 156+ window.open('" . $specialAsk . "&q='+query1+'&eq=yes&p%5Bformat%5D=broadtable','querywindow','menubar=no, status=no, scrollbars=yes, menubar=no, width=1000, height=900');}}
 157+ <br>{{#input:type=textarea|cols=30 | style=width:auto |rows=2|name=keyword}} <b>e.g. [[Category:city]][[locatedIn::France]]</b><br>
 158+ {{#input:type=submit|value=ADD}}
 159+ }}";
 160+
 161+ $article->doEdit( $newtext, $summary = "" );
 162+ $article->doRedirect();
 163+ return false;
 164+ }
 165+
 166+
 167+ /////// PushFeed page////////
 168+ elseif ( isset( $_GET['action'] ) && $_GET['action'] == 'pushpage' ) {
 169+ // $url = $_POST['url'];//pas url mais changesetId
 170+ wfDebugLog( 'p2p', 'Create new push ' . $_POST['name'] . ' with ' . $_POST['keyword'] );
 171+ $name = $_POST['name'];
 172+ $request = $_POST['keyword'];
 173+ $stringReq = utils::encodeRequest( $request ); // avoid "semantic injection" :))
 174+ // addPushSite($url, $name, $request);
 175+
 176+
 177+ $newtext = "
 178+ [[Special:ArticleAdminPage|DSMW Admin functions]]
 179+
 180+ ==Features==
 181+ [[name::PushFeed:" . $name . "| ]]
 182+ '''Semantic query:''' [[hasSemanticQuery::" . $stringReq . "| ]]<nowiki>" . $request . "</nowiki>
 183+
 184+ '''Pages concerned:'''
 185+ {{#ask: " . $request . "}}
 186+ [[deleted::false| ]]
 187+
 188+ ==Actions==
 189+
 190+ {{#input:type=ajax|value=PUSH|onClick=pushpull('" . $urlServer . "','PushFeed:" . $name . "', 'onpush');}}
 191+ The \"PUSH\" action publishes the (unpublished) modifications of the articles listed above.
 192+
 193+ == PUSH Progress : ==
 194+ <div id=\"state\" ></div><br />
 195+ ";
 196+
 197+ wfDebugLog( 'p2p', ' -> push page contains : ' . $newtext );
 198+ $title = Title::newFromText( $_POST['name'], PUSHFEED );
 199+
 200+ $article = new Article( $title );
 201+ $edit = $article->doEdit( $newtext, $summary = "" );
 202+ $article->doRedirect();
 203+ return false;
 204+ }
 205+ /////// ChangeSet page////////
 206+ elseif ( isset( $_POST['action'] ) && $_POST['action'] == 'onpush' ) {
 207+
 208+ /* In case we push directly from an article page */
 209+ if ( isset( $_POST['page'] ) && isset( $_POST['request'] ) ) {
 210+ $articlename = Title::newFromText( $_POST['name'] );
 211+
 212+ if ( !$articlename->exists() ) {
 213+ $result = utils::createPushFeed( $_POST['name'], $_POST['request'] );
 214+ utils::writeAndFlush( "Create push <A HREF=" . 'http://' . $wgServerName . $wgScriptPath . "/index.php?title=" . $_POST['name'] . ">" . $_POST['name'] . "</a>" );
 215+ if ( $result == false ) {
 216+ throw new MWException(
 217+ __METHOD__ . ': no Pushfeed created in utils:: createPushFeed:
 218+ name: ' . $_POST['name'] . ' request' . $_POST['request'] );
 219+ }
 220+ }
 221+ }
 222+
 223+ wfDebugLog( 'p2p', 'push on ' );
 224+ $patches = array();
 225+ $tmpPatches = array();
 226+
 227+ if ( isset( $_POST['name'] ) ) {
 228+ $name1 = $_POST['name'];
 229+ if ( !is_array( $name1 ) )
 230+ $name1 = array( $name1 );
 231+ foreach ( $name1 as $push ) {
 232+ wfDebugLog( 'p2p', ' - ' . $push );
 233+ }
 234+ }
 235+ else {
 236+ $name1 = '';
 237+ }
 238+
 239+ if ( $name1 == '' ) {
 240+ utils::writeAndFlush( '<p><b>No pushfeed selected!</b></p>' );
 241+
 242+ $title = Title::newFromText( 'Special:ArticleAdminPage' );
 243+ $article = new Article( $title );
 244+ $article->doRedirect();
 245+
 246+ return false;
 247+ }
 248+
 249+ // $name = $name1[0];
 250+ utils::writeAndFlush( '<p><b>Start push </b></p>' );
 251+ foreach ( $name1 as $name ) {
 252+ utils::writeAndFlush( "<span style=\"margin-left:30px;\">begin push: <A HREF=" . 'http://' . $wgServerName . $wgScriptPath . "/index.php?title=$name>" . $name . "</a></span> <br/>" );
 253+ $patches = array(); /// / for each pushfeed name==> push
 254+ wfDebugLog( 'p2p', ' -> pushname ' . $name );
 255+ // $name = $_GET['name'];//PushFeed name
 256+ $request = getPushFeedRequest( $name );
 257+ // $previousCSID = getPreviousCSID($name);
 258+ $previousCSID = getHasPushHead( $name );
 259+ if ( $previousCSID == false ) {
 260+ $previousCSID = "none";
 261+ // $CSID = $name."_0";
 262+ }// else{
 263+ // $count = explode(" ", $previousCSID);
 264+ // $cnt = $count[1] + 1;
 265+ // $CSID = $name."_".$cnt;
 266+ // }
 267+ wfDebugLog( 'p2p', ' ->pushrequest ' . $request );
 268+ wfDebugLog( 'p2p', ' ->pushHead : ' . $previousCSID );
 269+ $CSID = utils::generateID(); // changesetID
 270+ if ( $request == false ) {
 271+ $outtext = '<p><b>No semantic request found!</b></p> <a href="' . $_SERVER['HTTP_REFERER'] . '">back</a>';
 272+ $wgOut->addHTML( $outtext );
 273+ return false;
 274+ }
 275+
 276+ $pages = getRequestedPages( $request ); // ce sont des pages et non des patches
 277+ foreach ( $pages as $page ) {
 278+ wfDebugLog( 'p2p', ' ->requested page ' . $page );
 279+ $page = str_replace( '"', '', $page );
 280+ $request1 = '[[Patch:+]][[onPage::' . $page . ']]';
 281+ $tmpPatches = utils::orderPatchByPrevious( $page );
 282+ if ( !is_array( $tmpPatches ) )
 283+ throw new MWException( __METHOD__ . ': $tmpPatches is not an array' );
 284+ $patches = array_merge( $patches, $tmpPatches );
 285+ wfDebugLog( 'p2p', ' -> ' . count( $tmpPatches ) . 'patchs were found for the page ' . $page );
 286+ }
 287+ wfDebugLog( 'p2p', ' -> ' . count( $patches ) . ' patchs were found for the pushfeed ' . $name );
 288+ $published = getPublishedPatches( $name );
 289+ $unpublished = array_diff( $patches, $published ); /* unpublished = patches-published */
 290+ wfDebugLog( 'p2p', ' -> ' . count( $published ) . ' patchs were published for the pushfeed ' . $name . ' and ' . count( $unpublished ) . ' unpublished patchs' );
 291+ if ( empty( $unpublished ) ) {
 292+ wfDebugLog( 'p2p', ' -> no unpublished patch' );
 293+ utils::writeAndFlush( "<span style=\"margin-left:60px;\">no unpublished patch</span><br/>" );
 294+ // return false; //If there is no unpublished patch
 295+ } else {
 296+ utils::writeAndFlush( "<span style=\"margin-left:60px;\">" . count( $unpublished ) . " unpublished patch</span><br/>" );
 297+ $pos = strrpos( $CSID, ":" ); // NS removing
 298+ if ( $pos === false ) {
 299+ // not found...
 300+ $articleName = $CSID;
 301+ $CSID = "ChangeSet:" . $articleName;
 302+ } else {
 303+ $articleName = substr( $CSID, 0, $pos + 1 );
 304+ $CSID = "ChangeSet:" . $articleName;
 305+ }
 306+ $newtext = "
 307+ [[Special:ArticleAdminPage|DSMW Admin functions]]
 308+
 309+ ==Features==
 310+ [[changeSetID::" . $CSID . "| ]]
 311+
 312+ '''Date:''' " . date( DATE_RFC822 ) . "
 313+
 314+ '''User:''' " . $wgUser->getName() . "
 315+
 316+ This ChangeSet is in : [[inPushFeed::" . $name . "]]<br>
 317+ ==Published patches==
 318+
 319+ {| class=\"wikitable\" border=\"1\" style=\"text-align:left; width:30%;\"
 320+ |-
 321+ !bgcolor=#c0e8f0 scope=col | Patch
 322+ |-
 323+ ";
 324+ // wfDebugLog('p2p',' -> count unpublished patch '.count($unpublished));
 325+ foreach ( $unpublished as $patch ) {
 326+ wfDebugLog( 'p2p', ' -> unpublished patch ' . $patch );
 327+ $newtext .= "|[[hasPatch::" . $patch . "]]
 328+ |-
 329+ ";
 330+ }
 331+ $newtext .= "
 332+ |}";
 333+ $newtext .= "
 334+ ==Previous ChangeSet==
 335+ [[previousChangeSet::" . $previousCSID . "]]
 336+ ";
 337+
 338+ $update = updatePushFeed( $name, $CSID );
 339+ if ( $update == true ) {// update the "hasPushHead" value successful
 340+ $title = Title::newFromText( $articleName, CHANGESET );
 341+ $article = new Article( $title );
 342+ $article->doEdit( $newtext, $summary = "" );
 343+ } else {
 344+ $outtext = '<p><b>PushFeed has not been updated!</b></p>';
 345+ $wgOut->addHTML( $outtext );
 346+ }
 347+ }
 348+ }// end foreach pushfeed list
 349+ utils::writeAndFlush( '<p><b>End push</b></p>' );
 350+ $title = Title::newFromText( 'Special:ArticleAdminPage' );
 351+ $article = new Article( $title );
 352+ $article->doRedirect();
 353+ return false;
 354+ }
 355+
 356+
 357+ ////////// PullFeed page////////
 358+ elseif ( isset( $_GET['action'] ) && $_GET['action'] == 'pullpage' ) {
 359+ // wfDebugLog('p2p','Create pull '.$_POST['pullname'].' with pushName '.$_POST['pushname'].' on '.$_POST['url']);
 360+ // $url = rtrim($_POST['url'], "/"); //removes the final "/" if there is one
 361+ $urlTmp = $_POST['url'];
 362+ if ( utils::isValidURL( $urlTmp ) == false )
 363+ throw new MWException( __METHOD__ . ': ' . $urlTmp . ' seems not to be an url' ); // throws an exception if $url is invalid
 364+
 365+ $res = utils::parsePushURL( $urlTmp );
 366+ if ( $res === false || empty( $res ) )
 367+ throw new MWException( __METHOD__ . ': URL format problem' );
 368+ $pushname = $res[0];
 369+ $url = $res[1];
 370+
 371+ // $pushname = $_POST['pushname'];
 372+ $pullname = $_POST['pullname'];
 373+
 374+ $newtext = "
 375+ [[Special:ArticleAdminPage|DSMW Admin functions]]
 376+
 377+ ==Features==
 378+
 379+ [[name::PullFeed:" . $pullname . "| ]]
 380+ '''URL of the DSMW PushServer:''' [[pushFeedServer::" . $url . "]]<br>
 381+ '''PushFeed name:''' [[pushFeedName::PushFeed:" . $pushname . "]]
 382+ [[deleted::false| ]]
 383+
 384+ ==Actions==
 385+
 386+ {{#input:type=ajax|value=PULL|onClick=pushpull('" . $urlServer . "','PullFeed:" . $pullname . "','onpull');}}
 387+
 388+ The \"PULL\" action gets the modifications published in the PushFeed of the PushFeedServer above.
 389+
 390+ == PULL Progress : ==
 391+ <div id=\"state\" ></div><br />
 392+ ";
 393+
 394+ $title = Title::newFromText( $pullname, PULLFEED );
 395+ $article = new Article( $title );
 396+ $article->doEdit( $newtext, $summary = "" );
 397+ $article->doRedirect();
 398+
 399+ return false;
 400+ }
 401+
 402+ ////////// OnPull/////////////
 403+ elseif ( isset( $_POST['action'] ) && $_POST['action'] == 'onpull' ) {
 404+ if ( isset( $_POST['name'] ) ) {
 405+ $name1 = $_POST['name'];
 406+ wfDebugLog( 'p2p', 'pull on ' );
 407+ if ( !is_array( $name1 ) )
 408+ $name1 = array( $name1 );
 409+ }
 410+ else {
 411+ $name1 = '';
 412+ }
 413+
 414+ if ( $name1 == '' ) {
 415+ utils::writeAndFlush( '<p><b>No pullfeed selected!</b></p> ' );
 416+ $title = Title::newFromText( 'Special:ArticleAdminPage' );
 417+ $article = new Article( $title );
 418+ $article->doEdit( '', $summary = "" );
 419+ $article->doRedirect();
 420+ return false;
 421+ }
 422+
 423+ // $name = $name1[0];//with NS
 424+ utils::writeAndFlush( '<p><b>Start pull</b></p>' );
 425+ foreach ( $name1 as $name ) {// for each pullfeed name==> pull
 426+ utils::writeAndFlush( "<span style=\"margin-left:30px;\">begin pull: <A HREF=" . 'http://' . $wgServerName . $wgScriptPath . "/index.php?title=$name>" . $name . "</a></span> <br/>" );
 427+ wfDebugLog( 'p2p', ' -> pull : ' . $name );
 428+
 429+ // $previousCSID = getPreviousPulledCSID($name);
 430+ // if($previousCSID==false) {
 431+ // $previousCSID = "none";
 432+ // }
 433+ $previousCSID = getHasPullHead( $name );
 434+ if ( $previousCSID == false ) {
 435+ $previousCSID = "none";
 436+ }
 437+
 438+ wfDebugLog( 'p2p', ' -> pullHead : ' . $previousCSID );
 439+
 440+ $relatedPushServer = getPushURL( $name );
 441+ if ( is_null( $relatedPushServer ) ) {
 442+ throw new MWException( __METHOD__ . ': no relatedPushServer url' );
 443+ }
 444+
 445+ $namePush = getPushName( $name );
 446+ $namePush = str_replace( ' ', '_', $namePush );
 447+
 448+ wfDebugLog( 'p2p', ' -> pushServer : ' . $relatedPushServer );
 449+ wfDebugLog( 'p2p', ' -> pushName : ' . $namePush );
 450+
 451+ if ( is_null( $namePush ) ) {
 452+ throw new MWException( __METHOD__ . ': no PushName' );
 453+ }
 454+
 455+ // split NS and name
 456+ preg_match( "/^(.+?)_*:_*(.*)$/S", $namePush, $m );
 457+ $nameWithoutNS = $m[2];
 458+
 459+ // $url = $relatedPushServer.'/api.php?action=query&meta=changeSet&cspushName='.$nameWithoutNS.'&cschangeSet='.$previousCSID.'&format=xml';
 460+ // $url = $relatedPushServer."/api{$wgScriptExtension}?action=query&meta=changeSet&cspushName=".$nameWithoutNS.'&cschangeSet='.$previousCSID.'&format=xml';
 461+ wfDebugLog( 'testlog', ' -> request ChangeSet : ' . $relatedPushServer . '/api.php?action=query&meta=changeSet&cspushName=' . $nameWithoutNS . '&cschangeSet=' . $previousCSID . '&format=xml' );
 462+ $cs = utils::file_get_contents_curl( utils::lcfirst( $relatedPushServer ) . "/api.php?action=query&meta=changeSet&cspushName=" . $nameWithoutNS . '&cschangeSet=' . $previousCSID . '&format=xml' );
 463+
 464+ /* test if it is a xml file. If not, the server is not reachable via the url
 465+ * Then we try to reach it with the .php5 extension
 466+ */
 467+ if ( strpos( $cs, "<?xml version=\"1.0\"?>" ) === false ) {
 468+ $cs = utils::file_get_contents_curl( utils::lcfirst( $relatedPushServer ) . "/api.php5?action=query&meta=changeSet&cspushName=" . $nameWithoutNS . '&cschangeSet=' . $previousCSID . '&format=xml' );
 469+ }
 470+ if ( strpos( $cs, "<?xml version=\"1.0\"?>" ) === false ) {
 471+ $cs = false;
 472+ }
 473+
 474+ if ( $cs === false )
 475+ throw new MWException( __METHOD__ . ': Cannot connect to Push Server (ChangeSet API)' );
 476+ $cs = trim( $cs );
 477+ $dom = new DOMDocument();
 478+ $dom->loadXML( $cs );
 479+
 480+ $changeSet = $dom->getElementsByTagName( 'changeSet' );
 481+ $CSID = null;
 482+
 483+ foreach ( $changeSet as $cs ) {
 484+ if ( $cs->hasAttribute( "id" ) ) {
 485+ $CSID = $cs->getAttribute( 'id' );
 486+ $csName = $CSID;
 487+ }
 488+ }
 489+
 490+ wfDebugLog( 'p2p', ' -> changeSet found ' . $CSID );
 491+
 492+ while ( $CSID != null ) {
 493+ // if(!utils::pageExist($CSID)) {
 494+ $listPatch = null;
 495+ $patchs = $dom->getElementsByTagName( 'patch' );
 496+ foreach ( $patchs as $p ) {
 497+ wfDebugLog( 'p2p', ' -> patch ' . $p->firstChild->nodeValue );
 498+ $listPatch[] = $p->firstChild->nodeValue;
 499+ }
 500+
 501+ // $CSID = substr($CSID,strlen('changeSet:'));
 502+ utils::createChangeSetPull( $CSID, $name, $previousCSID, $listPatch );
 503+
 504+ integrate( $CSID, $listPatch, $relatedPushServer, $csName );
 505+ updatePullFeed( $name, $CSID );
 506+
 507+ // }
 508+
 509+ $previousCSID = $CSID;
 510+ wfDebugLog( 'p2p', ' -> request ChangeSet : ' . $relatedPushServer . '/api.php?action=query&meta=changeSet&cspushName=' . $nameWithoutNS . '&cschangeSet=' . $previousCSID . '&format=xml' );
 511+ $cs = utils::file_get_contents_curl( utils::lcfirst( $relatedPushServer ) . "/api.php?action=query&meta=changeSet&cspushName=" . $nameWithoutNS . '&cschangeSet=' . $previousCSID . '&format=xml' );
 512+
 513+ /* test if it is a xml file. If not, the server is not reachable via the url
 514+ * Then we try to reach it with the .php5 extension
 515+ */
 516+ if ( strpos( $cs, "<?xml version=\"1.0\"?>" ) === false ) {
 517+ $cs = utils::file_get_contents_curl( utils::lcfirst( $relatedPushServer ) . "/api.php5?action=query&meta=changeSet&cspushName=" . $nameWithoutNS . '&cschangeSet=' . $previousCSID . '&format=xml' );
 518+ }
 519+ if ( strpos( $cs, "<?xml version=\"1.0\"?>" ) === false )
 520+ $cs = false;
 521+
 522+ if ( $cs === false )
 523+ throw new MWException( __METHOD__ . ': Cannot connect to Push Server (ChangeSet API)' );
 524+ $cs = trim( $cs );
 525+
 526+ $dom = new DOMDocument();
 527+ $dom->loadXML( $cs );
 528+
 529+ $changeSet = $dom->getElementsByTagName( 'changeSet' );
 530+ $CSID = null;
 531+ foreach ( $changeSet as $cs ) {
 532+ if ( $cs->hasAttribute( "id" ) ) {
 533+ $CSID = $cs->getAttribute( 'id' );
 534+ }
 535+ }
 536+ wfDebugLog( 'p2p', ' -> changeSet found ' . $CSID );
 537+ }
 538+ if ( is_null( $csName ) ) {
 539+ wfDebugLog( 'p2p', ' - redirect to Special:ArticleAdminPage' );
 540+ utils::writeAndFlush( "<span style=\"margin-left:60px;\">no new patch</span><br/>" );
 541+ } else {
 542+ wfDebugLog( 'p2p', ' - redirect to ChangeSet:' . $csName );
 543+ }
 544+ }// end foreach list pullfeed
 545+
 546+ utils::writeAndFlush( '<p><b>End pull</b></p>' );
 547+ $title = Title::newFromText( 'Special:ArticleAdminPage' );
 548+ $article = new Article( $title );
 549+ $article->doRedirect();
 550+
 551+ return false;
 552+ } else {
 553+ return true;
 554+ }
 555+ }
 556+
 557+ /* * *************************************************************************** */
 558+ /*
 559+ V0 : initial revision
 560+ / \
 561+ /
 562+ P1 / \P2
 563+ /
 564+ / \
 565+ V1 V2:2nd edit of the same article
 566+ 1st Edit
 567+ */
 568+ /* * *************************************************************************** */
 569+
 570+ /**
 571+ * @since 1.1
 572+ *
 573+ * @param EditPage $editpage
 574+ *
 575+ * @return true
 576+ */
 577+ public function onAttemptSave( EditPage $editpage ) {
 578+ global $wgServerName, $wgScriptPath;
 579+
 580+ $urlServer = 'http://' . $wgServerName . $wgScriptPath;
 581+
 582+ $ns = $editpage->mTitle->getNamespace();
 583+ if ( ( $ns == PATCH ) || ( $ns == PUSHFEED ) || ( $ns == PULLFEED ) || ( $ns == CHANGESET ) ) {
 584+ return true;
 585+ }
 586+
 587+ $actualtext = $editpage->textbox1; // V2
 588+
 589+ $dbr = wfGetDB( DB_SLAVE );
 590+ $lastRevision = Revision::loadFromTitle( $dbr, $editpage->mTitle );
 591+
 592+ if ( is_null( $lastRevision ) ) {
 593+ $conctext = "";
 594+ $rev_id = 0;
 595+ } elseif ( ( $ns == NS_FILE || $ns == NS_IMAGE || $ns == NS_MEDIA ) && $lastRevision->getRawText() == "" ) {
 596+ $rev_id = 0;
 597+ $conctext = $lastRevision->getText();
 598+ } else {
 599+ $conctext = $lastRevision->getText(); // V1 conc
 600+ $rev_id = $lastRevision->getId();
 601+ }
 602+
 603+ // if there is no modification on the text
 604+ if ( $actualtext == $conctext ) {
 605+ return true;
 606+ }
 607+
 608+ $model = manager::loadModel( $rev_id );
 609+ $logoot = new logootEngine( $model );
 610+
 611+ // get the revision with the edittime==>V0
 612+ $rev = Revision::loadFromTimestamp( $dbr, $editpage->mTitle, $editpage->edittime );
 613+ if ( is_null( $rev ) ) {
 614+ $text = "";
 615+ $rev_id1 = 0;
 616+ } else {
 617+ $text = $rev->getText(); // VO
 618+ $rev_id1 = $rev->getId();
 619+ }
 620+
 621+ if ( $conctext != $text ) {// if last revision is not V0, there is editing conflict
 622+ // wfDebugLog('testlog',' -> CONCURRENCE: ');
 623+ // wfDebugLog('testlog',' -> +'.$conctext.'+('.$rev_id.') ts '.$lastRevision->getTimestamp());
 624+ // wfDebugLog('testlog',' -> +'.$text.'+('.$rev_id1.') ts '.$editpage->edittime.' '.$rev->getTimestamp());
 625+ $model1 = manager::loadModel( $rev_id1 );
 626+ $logoot1 = new logootEngine( $model1 );
 627+ $listOp1 = $logoot1->generate( $text, $actualtext );
 628+ // creation Patch P2
 629+ $tmp = serialize( $listOp1 );
 630+ $patch = new Patch( false, false, $listOp1, $urlServer, $rev_id1 );
 631+
 632+ if ( $editpage->mTitle->getNamespace() == 0 ) {
 633+ $title = $editpage->mTitle->getText();
 634+ }
 635+ else {
 636+ $title = $editpage->mTitle->getNsText() . ':' . $editpage->mTitle->getText();
 637+ }
 638+
 639+ // integration: diffs between VO and V2 into V1
 640+
 641+ $modelAfterIntegrate = $logoot->integrate( $listOp1 );
 642+ } else {// no edition conflict
 643+ $listOp = $logoot->generate( $conctext, $actualtext );
 644+ $modelAfterIntegrate = $logoot->getModel();
 645+ $tmp = serialize( $listOp );
 646+ $patch = new Patch( false, false, $listOp, $urlServer, $rev_id1 );
 647+
 648+ if ( $editpage->mTitle->getNamespace() == 0 )
 649+ $title = $editpage->mTitle->getText();
 650+ else
 651+ $title = $editpage->mTitle->getNsText() . ':' . $editpage->mTitle->getText();
 652+ }
 653+
 654+ $revId = utils::getNewArticleRevId();
 655+ wfDebugLog( 'p2p', ' -> store model rev : ' . $revId . ' session ' . session_id() . ' model ' . $modelAfterIntegrate->getText() );
 656+ manager::storeModel( $revId + 1, $sessionId = session_id(), $modelAfterIntegrate, $blobCB = 0 );
 657+
 658+ $patch->storePage( $title, $revId + 1 ); // stores the patch in a wikipage
 659+ $editpage->textbox1 = $modelAfterIntegrate->getText();
 660+ return true;
 661+ }
 662+
 663+ /**
 664+ * @since 1.1
 665+ *
 666+ * @param UploadForm $image
 667+ *
 668+ * @return true
 669+ */
 670+ public function onUploadComplete( UploadForm $image ) {
 671+ global $wgServerName, $wgScriptPath, $wgServer, $wgVersion;
 672+ $urlServer = 'http://' . $wgServerName . $wgScriptPath;
 673+
 674+ // $classe = get_class($image);
 675+ if ( compareMWVersion( $wgVersion, '1.16.0' ) == -1 ) {
 676+ $localfile = $image->mLocalFile;
 677+ } else {
 678+ $localfile = $image->getLocalFile();
 679+ }
 680+
 681+ $path = utils::prepareString( $localfile->mime, $localfile->size, $wgServer . urldecode( $localfile->url ) );
 682+
 683+ if ( !file_exists( $path ) ) {
 684+ $dbr = wfGetDB( DB_SLAVE );
 685+ $lastRevision = Revision::loadFromTitle( $dbr, $localfile->getTitle() );
 686+
 687+ if ( $lastRevision->getPrevious() == null ) {
 688+ $rev_id = 0;
 689+ } else {
 690+ $rev_id = $lastRevision->getPrevious()->getId();
 691+ }
 692+
 693+ $revID = $lastRevision->getId();
 694+ $model = manager::loadModel( $rev_id );
 695+ $patch = new Patch( false, true, null, $urlServer, $rev_id, null, null, null, $localfile->mime, $localfile->size, urldecode( $localfile->url ), null );
 696+ $patch->storePage( $localfile->getTitle(), $revID ); // stores the patch in a wikipage
 697+ manager::storeModel( $revID, $sessionId = session_id(), $model, $blobCB = 0 );
 698+ }
 699+
 700+ return true;
 701+ }
 702+
 703+
 704+}
\ No newline at end of file
Property changes on: trunk/extensions/DSMW/DSMW.hooks.php
___________________________________________________________________
Added: svn:eol-style
1705 + native
Index: trunk/extensions/DSMW/CHANGELOG
@@ -2,6 +2,7 @@
33
44 == DSMW 1.1 ==
55
 6+* Compatibility with MediaWiki 1.17.
67 * Stylized all files using the stylize.php script.
78
89 == DSMW 1.0 ==
Index: trunk/extensions/DSMW/DSMW.php
@@ -46,13 +46,11 @@
4747
4848 $wgExtensionMessagesFiles['DSMW'] = dirname( __FILE__ ) . '/DSMW.i18n.php';
4949
50 -$wgHooks['UnknownAction'][] = 'onUnknownAction';
51 -// $wgHooks['MediaWikiPerformAction'][] = 'performAction';
 50+$wgHooks['UnknownAction'][] = 'DSMWHooks::onUnknownAction';
 51+$wgHooks['EditPage::attemptSave'][] = 'DSMWHooks::onAttemptSave';
 52+$wgHooks['EditPageBeforeConflictDiff'][] = 'DSMWHooks::onEditConflict';
 53+$wgHooks['UploadComplete'][] = 'DSMWHooks::onUploadComplete';
5254
53 -$wgHooks['EditPage::attemptSave'][] = 'attemptSave';
54 -$wgHooks['EditPageBeforeConflictDiff'][] = 'conflict';
55 -$wgHooks['UploadComplete'][] = 'uploadComplete';
56 -
5755 $wgAutoloadClasses['logootEngine'] = "$wgDSMWIP/logootComponent/logootEngine.php";
5856 $wgAutoloadClasses['logoot'] = "$wgDSMWIP/logootComponent/logoot.php";
5957 $wgAutoloadClasses['LogootId'] = "$wgDSMWIP/logootComponent/LogootId.php";
Index: trunk/extensions/DSMW/includes/DSMW_GlobalFunctions.php
@@ -13,539 +13,8 @@
1414 die( 'Not a valid entry point.' );
1515 }
1616
17 -define( 'INT_MAX', '1000000000000000000000' ); // 22
18 -define( 'INT_MIN', '0' );
19 -
20 -function conflict( &$editor, &$out ) {
21 - $conctext = $editor->textbox1;
22 - $actualtext = $editor->textbox2;
23 - $initialtext = $editor->getBaseRevision()->mText;
24 -
25 - // TODO: WTF?!
26 - $editor->mArticle->updateArticle(
27 - $actualtext,
28 - $editor->summary,
29 - $editor->minoredit,
30 - $editor->watchthis,
31 - $bot = false,
32 - $sectionanchor = ''
33 - );
34 -
35 - return true;
36 -}
37 -
3817 /**
39 - * MW Hook used to redirect to page creation (pushfeed, pullfeed, changeset),
40 - * to forms or to push/pull action testing the action param
4118 *
42 - *
43 - * @global <Object> $wgOut
44 - * @param <Object> $action
45 - * @param <Object> $article
46 - * @return <boolean>
47 - */
48 -function onUnknownAction( $action, $article ) {
49 - global $wgOut, $wgServerName, $wgScriptPath, $wgUser, $wgScriptExtension, $wgDSMWIP;
50 - $urlServer = 'http://' . $wgServerName . $wgScriptPath . "/index{$wgScriptExtension}";
51 - $urlAjax = 'http://' . $wgServerName . $wgScriptPath;
52 - ////////// pull form page////////
53 - if ( isset( $_GET['action'] ) && $_GET['action'] == 'addpullpage' ) {
54 - wfDebugLog( 'p2p', 'addPullPage ' );
55 - $newtext = "Add a new site:
56 -<div id='dsmw' style=\"color:green;\"></div>
57 -
58 -{{#form:action=" . $urlServer . "?action=pullpage|method=POST|
59 -PushFeed Url: {{#input:type=button|value=Url test|onClick=
60 -var url = document.getElementsByName('url')[0].value;
61 -if(url.indexOf('PushFeed')==-1){
62 -alert('No valid PushFeed syntax, see example.');
63 -}else{
64 -var urlTmp = url.substring(0,url.indexOf('PushFeed'));
65 -//alert(urlTmp);
66 -
67 -var pos1 = urlTmp.indexOf('index.php');
68 -//alert(pos1);
69 -var pushUrl='';
70 -if(pos1!=-1){
71 -pushUrl = urlTmp.substring(0,pos1);
72 -//alert('if');
73 -}else{
74 -pushUrl = urlTmp;
75 -//alert('else');
76 -}
77 -//alert(pushUrl);
78 -
79 -//alert(pushUrl+'api.php?action=query&meta=patch&papatchId=1&format=xml');
80 -var xhr_object = null;
81 -
82 - if(window.XMLHttpRequest) // Firefox
83 - xhr_object = new XMLHttpRequest();
84 - else if(window.ActiveXObject) // Internet Explorer
85 - xhr_object = new ActiveXObject('Microsoft.XMLHTTP');
86 - else {
87 - alert('Votre navigateur ne supporte pas les objets XMLHTTPRequest...');
88 - return;
89 - }
90 - try{ xhr_object.open('GET', '" . $urlAjax . "/extensions/DSMW/files/ajax.php?url='+escape(pushUrl+'api.php?action=query&meta=patch&papatchId=1&format=xml'), true);}
91 - catch(e){
92 - //alert('There is no DSMW Server responding at this URL');
93 - document.getElementById('dsmw').innerHTML = 'There is no DSMW Server responding at this URL!';
94 - document.getElementById('dsmw').style.color = 'red';
95 - }
96 - xhr_object.onreadystatechange = function() {
97 -
98 -if(xhr_object.readyState == 4) {
99 - if(xhr_object.statusText=='OK'){
100 - if(xhr_object.responseText == 'true'){ //alert('URL valid, there is a DSMW Server responding');
101 - document.getElementById('dsmw').innerHTML = 'URL valid, there is a DSMW Server responding!';
102 - document.getElementById('dsmw').style.color = 'green';
103 - }
104 - else{ //alert('There is no DSMW Server responding at this URL');
105 - document.getElementById('dsmw').innerHTML = 'There is no DSMW Server responding at this URL!';
106 - document.getElementById('dsmw').style.color = 'red';
107 - }
108 - }
109 - else{
110 - //alert('There is no DSMW Server responding at this URL');
111 - document.getElementById('dsmw').innerHTML = 'There is no DSMW Server responding at this URL!';
112 - document.getElementById('dsmw').style.color = 'red';
113 -}
114 - }
115 - }
116 -
117 - xhr_object.send(null);
118 -}
119 -}}<br> {{#input:type=text|name=url|size=50}} <b>e.g. http://server/path/index.php?title=PushFeed:PushName</b><br>
120 -PullFeed Name: <br> {{#input:type=text|name=pullname}}<br>
121 -{{#input:type=submit|value=ADD}}
122 -}}";
123 -
124 - // if article doesn't exist insertNewArticle
125 - if ( $article->mTitle->exists() ) {
126 - $article->updateArticle( $newtext, $summary = "", false, false );
127 - } else {
128 - $article->insertNewArticle( $newtext, $summary = "", false, false );
129 - }
130 - $article->doRedirect();
131 -
132 - return false;
133 - }
134 -
135 -
136 - ///////// push form page////////
137 - elseif ( isset( $_GET['action'] ) && $_GET['action'] == 'addpushpage' ) {
138 - wfDebugLog( 'p2p', 'addPushPage' );
139 - $specialAsk = $urlServer . '?title=Special:Ask';
140 - $newtext = "Add a new pushfeed:
141 -
142 -{{#form:action=" . $urlServer . "?action=pushpage|method=POST|
143 -PushFeed Name: <br> {{#input:class=test|name=name|type=text|onKeyUp=test('$urlServer');}}<div style=\"display:inline; \" id=\"state\" ></div><br />
144 -Request: {{#input:type=button|value=Test your query|title=click here to test your query results|onClick=
145 -var query = document.getElementsByName('keyword')[0].value;
146 -var query1 = encodeURI(query);
147 -window.open('" . $specialAsk . "&q='+query1+'&eq=yes&p%5Bformat%5D=broadtable','querywindow','menubar=no, status=no, scrollbars=yes, menubar=no, width=1000, height=900');}}
148 - <br>{{#input:type=textarea|cols=30 | style=width:auto |rows=2|name=keyword}} <b>e.g. [[Category:city]][[locatedIn::France]]</b><br>
149 -{{#input:type=submit|value=ADD}}
150 -}}";
151 -
152 - $article->doEdit( $newtext, $summary = "" );
153 - $article->doRedirect();
154 - return false;
155 - }
156 -
157 -
158 - /////// PushFeed page////////
159 - elseif ( isset( $_GET['action'] ) && $_GET['action'] == 'pushpage' ) {
160 - // $url = $_POST['url'];//pas url mais changesetId
161 - wfDebugLog( 'p2p', 'Create new push ' . $_POST['name'] . ' with ' . $_POST['keyword'] );
162 - $name = $_POST['name'];
163 - $request = $_POST['keyword'];
164 - $stringReq = utils::encodeRequest( $request ); // avoid "semantic injection" :))
165 - // addPushSite($url, $name, $request);
166 -
167 -
168 - $newtext = "
169 -[[Special:ArticleAdminPage|DSMW Admin functions]]
170 -
171 -==Features==
172 -[[name::PushFeed:" . $name . "| ]]
173 -'''Semantic query:''' [[hasSemanticQuery::" . $stringReq . "| ]]<nowiki>" . $request . "</nowiki>
174 -
175 -'''Pages concerned:'''
176 -{{#ask: " . $request . "}}
177 -[[deleted::false| ]]
178 -
179 -==Actions==
180 -
181 -{{#input:type=ajax|value=PUSH|onClick=pushpull('" . $urlServer . "','PushFeed:" . $name . "', 'onpush');}}
182 -The \"PUSH\" action publishes the (unpublished) modifications of the articles listed above.
183 -
184 -== PUSH Progress : ==
185 -<div id=\"state\" ></div><br />
186 -";
187 -
188 - wfDebugLog( 'p2p', ' -> push page contains : ' . $newtext );
189 - $title = Title::newFromText( $_POST['name'], PUSHFEED );
190 -
191 - $article = new Article( $title );
192 - $edit = $article->doEdit( $newtext, $summary = "" );
193 - $article->doRedirect();
194 - return false;
195 - }
196 - /////// ChangeSet page////////
197 - elseif ( isset( $_POST['action'] ) && $_POST['action'] == 'onpush' ) {
198 -
199 - /* In case we push directly from an article page */
200 - if ( isset( $_POST['page'] ) && isset( $_POST['request'] ) ) {
201 - $articlename = Title::newFromText( $_POST['name'] );
202 -
203 - if ( !$articlename->exists() ) {
204 - $result = utils::createPushFeed( $_POST['name'], $_POST['request'] );
205 - utils::writeAndFlush( "Create push <A HREF=" . 'http://' . $wgServerName . $wgScriptPath . "/index.php?title=" . $_POST['name'] . ">" . $_POST['name'] . "</a>" );
206 - if ( $result == false ) {
207 - throw new MWException(
208 - __METHOD__ . ': no Pushfeed created in utils:: createPushFeed:
209 - name: ' . $_POST['name'] . ' request' . $_POST['request'] );
210 - }
211 - }
212 - }
213 -
214 - wfDebugLog( 'p2p', 'push on ' );
215 - $patches = array();
216 - $tmpPatches = array();
217 -
218 - if ( isset( $_POST['name'] ) ) {
219 - $name1 = $_POST['name'];
220 - if ( !is_array( $name1 ) )
221 - $name1 = array( $name1 );
222 - foreach ( $name1 as $push ) {
223 - wfDebugLog( 'p2p', ' - ' . $push );
224 - }
225 - }
226 - else {
227 - $name1 = '';
228 - }
229 -
230 - if ( $name1 == '' ) {
231 - utils::writeAndFlush( '<p><b>No pushfeed selected!</b></p>' );
232 -
233 - $title = Title::newFromText( 'Special:ArticleAdminPage' );
234 - $article = new Article( $title );
235 - $article->doRedirect();
236 -
237 - return false;
238 - }
239 -
240 - // $name = $name1[0];
241 - utils::writeAndFlush( '<p><b>Start push </b></p>' );
242 - foreach ( $name1 as $name ) {
243 - utils::writeAndFlush( "<span style=\"margin-left:30px;\">begin push: <A HREF=" . 'http://' . $wgServerName . $wgScriptPath . "/index.php?title=$name>" . $name . "</a></span> <br/>" );
244 - $patches = array(); /// / for each pushfeed name==> push
245 - wfDebugLog( 'p2p', ' -> pushname ' . $name );
246 - // $name = $_GET['name'];//PushFeed name
247 - $request = getPushFeedRequest( $name );
248 - // $previousCSID = getPreviousCSID($name);
249 - $previousCSID = getHasPushHead( $name );
250 - if ( $previousCSID == false ) {
251 - $previousCSID = "none";
252 - // $CSID = $name."_0";
253 - }// else{
254 - // $count = explode(" ", $previousCSID);
255 - // $cnt = $count[1] + 1;
256 - // $CSID = $name."_".$cnt;
257 - // }
258 - wfDebugLog( 'p2p', ' ->pushrequest ' . $request );
259 - wfDebugLog( 'p2p', ' ->pushHead : ' . $previousCSID );
260 - $CSID = utils::generateID(); // changesetID
261 - if ( $request == false ) {
262 - $outtext = '<p><b>No semantic request found!</b></p> <a href="' . $_SERVER['HTTP_REFERER'] . '">back</a>';
263 - $wgOut->addHTML( $outtext );
264 - return false;
265 - }
266 -
267 - $pages = getRequestedPages( $request ); // ce sont des pages et non des patches
268 - foreach ( $pages as $page ) {
269 - wfDebugLog( 'p2p', ' ->requested page ' . $page );
270 - $page = str_replace( '"', '', $page );
271 - $request1 = '[[Patch:+]][[onPage::' . $page . ']]';
272 - $tmpPatches = utils::orderPatchByPrevious( $page );
273 - if ( !is_array( $tmpPatches ) )
274 - throw new MWException( __METHOD__ . ': $tmpPatches is not an array' );
275 - $patches = array_merge( $patches, $tmpPatches );
276 - wfDebugLog( 'p2p', ' -> ' . count( $tmpPatches ) . 'patchs were found for the page ' . $page );
277 - }
278 - wfDebugLog( 'p2p', ' -> ' . count( $patches ) . ' patchs were found for the pushfeed ' . $name );
279 - $published = getPublishedPatches( $name );
280 - $unpublished = array_diff( $patches, $published ); /* unpublished = patches-published */
281 - wfDebugLog( 'p2p', ' -> ' . count( $published ) . ' patchs were published for the pushfeed ' . $name . ' and ' . count( $unpublished ) . ' unpublished patchs' );
282 - if ( empty( $unpublished ) ) {
283 - wfDebugLog( 'p2p', ' -> no unpublished patch' );
284 - utils::writeAndFlush( "<span style=\"margin-left:60px;\">no unpublished patch</span><br/>" );
285 - // return false; //If there is no unpublished patch
286 - } else {
287 - utils::writeAndFlush( "<span style=\"margin-left:60px;\">" . count( $unpublished ) . " unpublished patch</span><br/>" );
288 - $pos = strrpos( $CSID, ":" ); // NS removing
289 - if ( $pos === false ) {
290 - // not found...
291 - $articleName = $CSID;
292 - $CSID = "ChangeSet:" . $articleName;
293 - } else {
294 - $articleName = substr( $CSID, 0, $pos + 1 );
295 - $CSID = "ChangeSet:" . $articleName;
296 - }
297 - $newtext = "
298 -[[Special:ArticleAdminPage|DSMW Admin functions]]
299 -
300 -==Features==
301 -[[changeSetID::" . $CSID . "| ]]
302 -
303 -'''Date:''' " . date( DATE_RFC822 ) . "
304 -
305 -'''User:''' " . $wgUser->getName() . "
306 -
307 -This ChangeSet is in : [[inPushFeed::" . $name . "]]<br>
308 -==Published patches==
309 -
310 -{| class=\"wikitable\" border=\"1\" style=\"text-align:left; width:30%;\"
311 -|-
312 -!bgcolor=#c0e8f0 scope=col | Patch
313 -|-
314 -";
315 - // wfDebugLog('p2p',' -> count unpublished patch '.count($unpublished));
316 - foreach ( $unpublished as $patch ) {
317 - wfDebugLog( 'p2p', ' -> unpublished patch ' . $patch );
318 - $newtext .= "|[[hasPatch::" . $patch . "]]
319 -|-
320 -";
321 - }
322 - $newtext .= "
323 -|}";
324 - $newtext .= "
325 -==Previous ChangeSet==
326 -[[previousChangeSet::" . $previousCSID . "]]
327 -";
328 -
329 - $update = updatePushFeed( $name, $CSID );
330 - if ( $update == true ) {// update the "hasPushHead" value successful
331 - $title = Title::newFromText( $articleName, CHANGESET );
332 - $article = new Article( $title );
333 - $article->doEdit( $newtext, $summary = "" );
334 - } else {
335 - $outtext = '<p><b>PushFeed has not been updated!</b></p>';
336 - $wgOut->addHTML( $outtext );
337 - }
338 - }
339 - }// end foreach pushfeed list
340 - utils::writeAndFlush( '<p><b>End push</b></p>' );
341 - $title = Title::newFromText( 'Special:ArticleAdminPage' );
342 - $article = new Article( $title );
343 - $article->doRedirect();
344 - return false;
345 - }
346 -
347 -
348 - ////////// PullFeed page////////
349 - elseif ( isset( $_GET['action'] ) && $_GET['action'] == 'pullpage' ) {
350 - // wfDebugLog('p2p','Create pull '.$_POST['pullname'].' with pushName '.$_POST['pushname'].' on '.$_POST['url']);
351 - // $url = rtrim($_POST['url'], "/"); //removes the final "/" if there is one
352 - $urlTmp = $_POST['url'];
353 - if ( utils::isValidURL( $urlTmp ) == false )
354 - throw new MWException( __METHOD__ . ': ' . $urlTmp . ' seems not to be an url' ); // throws an exception if $url is invalid
355 -
356 - $res = utils::parsePushURL( $urlTmp );
357 - if ( $res === false || empty( $res ) )
358 - throw new MWException( __METHOD__ . ': URL format problem' );
359 - $pushname = $res[0];
360 - $url = $res[1];
361 -
362 - // $pushname = $_POST['pushname'];
363 - $pullname = $_POST['pullname'];
364 -
365 - $newtext = "
366 -[[Special:ArticleAdminPage|DSMW Admin functions]]
367 -
368 -==Features==
369 -
370 -[[name::PullFeed:" . $pullname . "| ]]
371 -'''URL of the DSMW PushServer:''' [[pushFeedServer::" . $url . "]]<br>
372 -'''PushFeed name:''' [[pushFeedName::PushFeed:" . $pushname . "]]
373 -[[deleted::false| ]]
374 -
375 -==Actions==
376 -
377 -{{#input:type=ajax|value=PULL|onClick=pushpull('" . $urlServer . "','PullFeed:" . $pullname . "','onpull');}}
378 -
379 -The \"PULL\" action gets the modifications published in the PushFeed of the PushFeedServer above.
380 -
381 -== PULL Progress : ==
382 -<div id=\"state\" ></div><br />
383 -";
384 -
385 - $title = Title::newFromText( $pullname, PULLFEED );
386 - $article = new Article( $title );
387 - $article->doEdit( $newtext, $summary = "" );
388 - $article->doRedirect();
389 -
390 - return false;
391 - }
392 -
393 - ////////// OnPull/////////////
394 - elseif ( isset( $_POST['action'] ) && $_POST['action'] == 'onpull' ) {
395 - if ( isset( $_POST['name'] ) ) {
396 - $name1 = $_POST['name'];
397 - wfDebugLog( 'p2p', 'pull on ' );
398 - if ( !is_array( $name1 ) )
399 - $name1 = array( $name1 );
400 - }
401 - else {
402 - $name1 = '';
403 - }
404 -
405 - if ( $name1 == '' ) {
406 - utils::writeAndFlush( '<p><b>No pullfeed selected!</b></p> ' );
407 - $title = Title::newFromText( 'Special:ArticleAdminPage' );
408 - $article = new Article( $title );
409 - $article->doEdit( '', $summary = "" );
410 - $article->doRedirect();
411 - return false;
412 - }
413 -
414 - // $name = $name1[0];//with NS
415 - utils::writeAndFlush( '<p><b>Start pull</b></p>' );
416 - foreach ( $name1 as $name ) {// for each pullfeed name==> pull
417 - utils::writeAndFlush( "<span style=\"margin-left:30px;\">begin pull: <A HREF=" . 'http://' . $wgServerName . $wgScriptPath . "/index.php?title=$name>" . $name . "</a></span> <br/>" );
418 - wfDebugLog( 'p2p', ' -> pull : ' . $name );
419 -
420 - // $previousCSID = getPreviousPulledCSID($name);
421 - // if($previousCSID==false) {
422 - // $previousCSID = "none";
423 - // }
424 - $previousCSID = getHasPullHead( $name );
425 - if ( $previousCSID == false ) {
426 - $previousCSID = "none";
427 - }
428 -
429 - wfDebugLog( 'p2p', ' -> pullHead : ' . $previousCSID );
430 -
431 - $relatedPushServer = getPushURL( $name );
432 - if ( is_null( $relatedPushServer ) ) {
433 - throw new MWException( __METHOD__ . ': no relatedPushServer url' );
434 - }
435 -
436 - $namePush = getPushName( $name );
437 - $namePush = str_replace( ' ', '_', $namePush );
438 -
439 - wfDebugLog( 'p2p', ' -> pushServer : ' . $relatedPushServer );
440 - wfDebugLog( 'p2p', ' -> pushName : ' . $namePush );
441 -
442 - if ( is_null( $namePush ) ) {
443 - throw new MWException( __METHOD__ . ': no PushName' );
444 - }
445 -
446 - // split NS and name
447 - preg_match( "/^(.+?)_*:_*(.*)$/S", $namePush, $m );
448 - $nameWithoutNS = $m[2];
449 -
450 - // $url = $relatedPushServer.'/api.php?action=query&meta=changeSet&cspushName='.$nameWithoutNS.'&cschangeSet='.$previousCSID.'&format=xml';
451 - // $url = $relatedPushServer."/api{$wgScriptExtension}?action=query&meta=changeSet&cspushName=".$nameWithoutNS.'&cschangeSet='.$previousCSID.'&format=xml';
452 - wfDebugLog( 'testlog', ' -> request ChangeSet : ' . $relatedPushServer . '/api.php?action=query&meta=changeSet&cspushName=' . $nameWithoutNS . '&cschangeSet=' . $previousCSID . '&format=xml' );
453 - $cs = utils::file_get_contents_curl( utils::lcfirst( $relatedPushServer ) . "/api.php?action=query&meta=changeSet&cspushName=" . $nameWithoutNS . '&cschangeSet=' . $previousCSID . '&format=xml' );
454 -
455 - /* test if it is a xml file. If not, the server is not reachable via the url
456 - * Then we try to reach it with the .php5 extension
457 - */
458 - if ( strpos( $cs, "<?xml version=\"1.0\"?>" ) === false ) {
459 - $cs = utils::file_get_contents_curl( utils::lcfirst( $relatedPushServer ) . "/api.php5?action=query&meta=changeSet&cspushName=" . $nameWithoutNS . '&cschangeSet=' . $previousCSID . '&format=xml' );
460 - }
461 - if ( strpos( $cs, "<?xml version=\"1.0\"?>" ) === false ) {
462 - $cs = false;
463 - }
464 -
465 - if ( $cs === false )
466 - throw new MWException( __METHOD__ . ': Cannot connect to Push Server (ChangeSet API)' );
467 - $cs = trim( $cs );
468 - $dom = new DOMDocument();
469 - $dom->loadXML( $cs );
470 -
471 - $changeSet = $dom->getElementsByTagName( 'changeSet' );
472 - $CSID = null;
473 -
474 - foreach ( $changeSet as $cs ) {
475 - if ( $cs->hasAttribute( "id" ) ) {
476 - $CSID = $cs->getAttribute( 'id' );
477 - $csName = $CSID;
478 - }
479 - }
480 -
481 - wfDebugLog( 'p2p', ' -> changeSet found ' . $CSID );
482 -
483 - while ( $CSID != null ) {
484 - // if(!utils::pageExist($CSID)) {
485 - $listPatch = null;
486 - $patchs = $dom->getElementsByTagName( 'patch' );
487 - foreach ( $patchs as $p ) {
488 - wfDebugLog( 'p2p', ' -> patch ' . $p->firstChild->nodeValue );
489 - $listPatch[] = $p->firstChild->nodeValue;
490 - }
491 -
492 - // $CSID = substr($CSID,strlen('changeSet:'));
493 - utils::createChangeSetPull( $CSID, $name, $previousCSID, $listPatch );
494 -
495 - integrate( $CSID, $listPatch, $relatedPushServer, $csName );
496 - updatePullFeed( $name, $CSID );
497 -
498 - // }
499 -
500 - $previousCSID = $CSID;
501 - wfDebugLog( 'p2p', ' -> request ChangeSet : ' . $relatedPushServer . '/api.php?action=query&meta=changeSet&cspushName=' . $nameWithoutNS . '&cschangeSet=' . $previousCSID . '&format=xml' );
502 - $cs = utils::file_get_contents_curl( utils::lcfirst( $relatedPushServer ) . "/api.php?action=query&meta=changeSet&cspushName=" . $nameWithoutNS . '&cschangeSet=' . $previousCSID . '&format=xml' );
503 -
504 - /* test if it is a xml file. If not, the server is not reachable via the url
505 - * Then we try to reach it with the .php5 extension
506 - */
507 - if ( strpos( $cs, "<?xml version=\"1.0\"?>" ) === false ) {
508 - $cs = utils::file_get_contents_curl( utils::lcfirst( $relatedPushServer ) . "/api.php5?action=query&meta=changeSet&cspushName=" . $nameWithoutNS . '&cschangeSet=' . $previousCSID . '&format=xml' );
509 - }
510 - if ( strpos( $cs, "<?xml version=\"1.0\"?>" ) === false )
511 - $cs = false;
512 -
513 - if ( $cs === false )
514 - throw new MWException( __METHOD__ . ': Cannot connect to Push Server (ChangeSet API)' );
515 - $cs = trim( $cs );
516 -
517 - $dom = new DOMDocument();
518 - $dom->loadXML( $cs );
519 -
520 - $changeSet = $dom->getElementsByTagName( 'changeSet' );
521 - $CSID = null;
522 - foreach ( $changeSet as $cs ) {
523 - if ( $cs->hasAttribute( "id" ) ) {
524 - $CSID = $cs->getAttribute( 'id' );
525 - }
526 - }
527 - wfDebugLog( 'p2p', ' -> changeSet found ' . $CSID );
528 - }
529 - if ( is_null( $csName ) ) {
530 - wfDebugLog( 'p2p', ' - redirect to Special:ArticleAdminPage' );
531 - utils::writeAndFlush( "<span style=\"margin-left:60px;\">no new patch</span><br/>" );
532 - } else {
533 - wfDebugLog( 'p2p', ' - redirect to ChangeSet:' . $csName );
534 - }
535 - }// end foreach list pullfeed
536 -
537 - utils::writeAndFlush( '<p><b>End pull</b></p>' );
538 - $title = Title::newFromText( 'Special:ArticleAdminPage' );
539 - $article = new Article( $title );
540 - $article->doRedirect();
541 -
542 - return false;
543 - } else {
544 - return true;
545 - }
546 -}
547 -
548 -/**
549 - *
55019 * @param <String> $version1
55120 * @param <String> $version2='1.14.0'
55221 * @return <integer>
@@ -570,129 +39,6 @@
57140 return 0;
57241 }
57342
574 -/* * *************************************************************************** */
575 -/*
576 - V0 : initial revision
577 - / \
578 - /
579 - P1 / \P2
580 - /
581 - / \
582 - V1 V2:2nd edit of the same article
583 - 1st Edit
584 - */
585 -/* * *************************************************************************** */
 43+define( 'INT_MAX', '1000000000000000000000' ); // 22
 44+define( 'INT_MIN', '0' );
58645
587 -function attemptSave( $editpage ) {
588 - global $wgServerName, $wgScriptPath;
589 - $urlServer = 'http://' . $wgServerName . $wgScriptPath;
590 -
591 - $ns = $editpage->mTitle->getNamespace();
592 - if ( ( $ns == PATCH ) || ( $ns == PUSHFEED ) || ( $ns == PULLFEED ) || ( $ns == CHANGESET ) ) {
593 - return true;
594 - }
595 -
596 - $actualtext = $editpage->textbox1; // V2
597 -
598 - $dbr = wfGetDB( DB_SLAVE );
599 - $lastRevision = Revision::loadFromTitle( $dbr, $editpage->mTitle );
600 -
601 - if ( is_null( $lastRevision ) ) {
602 - $conctext = "";
603 - $rev_id = 0;
604 - } elseif ( ( $ns == NS_FILE || $ns == NS_IMAGE || $ns == NS_MEDIA ) && $lastRevision->getRawText() == "" ) {
605 - $rev_id = 0;
606 - $conctext = $lastRevision->getText();
607 - } else {
608 - $conctext = $lastRevision->getText(); // V1 conc
609 - $rev_id = $lastRevision->getId();
610 - }
611 -
612 - // if there is no modification on the text
613 - if ( $actualtext == $conctext ) {
614 - return true;
615 - }
616 -
617 - $model = manager::loadModel( $rev_id );
618 - $logoot = new logootEngine( $model );
619 -
620 - // get the revision with the edittime==>V0
621 - $rev = Revision::loadFromTimestamp( $dbr, $editpage->mTitle, $editpage->edittime );
622 - if ( is_null( $rev ) ) {
623 - $text = "";
624 - $rev_id1 = 0;
625 - } else {
626 - $text = $rev->getText(); // VO
627 - $rev_id1 = $rev->getId();
628 - }
629 -
630 - if ( $conctext != $text ) {// if last revision is not V0, there is editing conflict
631 -// wfDebugLog('testlog',' -> CONCURRENCE: ');
632 -// wfDebugLog('testlog',' -> +'.$conctext.'+('.$rev_id.') ts '.$lastRevision->getTimestamp());
633 -// wfDebugLog('testlog',' -> +'.$text.'+('.$rev_id1.') ts '.$editpage->edittime.' '.$rev->getTimestamp());
634 - $model1 = manager::loadModel( $rev_id1 );
635 - $logoot1 = new logootEngine( $model1 );
636 - $listOp1 = $logoot1->generate( $text, $actualtext );
637 - // creation Patch P2
638 - $tmp = serialize( $listOp1 );
639 - $patch = new Patch( false, false, $listOp1, $urlServer, $rev_id1 );
640 -
641 - if ( $editpage->mTitle->getNamespace() == 0 ) {
642 - $title = $editpage->mTitle->getText();
643 - }
644 - else {
645 - $title = $editpage->mTitle->getNsText() . ':' . $editpage->mTitle->getText();
646 - }
647 -
648 - // integration: diffs between VO and V2 into V1
649 -
650 - $modelAfterIntegrate = $logoot->integrate( $listOp1 );
651 - } else {// no edition conflict
652 - $listOp = $logoot->generate( $conctext, $actualtext );
653 - $modelAfterIntegrate = $logoot->getModel();
654 - $tmp = serialize( $listOp );
655 - $patch = new Patch( false, false, $listOp, $urlServer, $rev_id1 );
656 -
657 - if ( $editpage->mTitle->getNamespace() == 0 )
658 - $title = $editpage->mTitle->getText();
659 - else
660 - $title = $editpage->mTitle->getNsText() . ':' . $editpage->mTitle->getText();
661 - }
662 -
663 - $revId = utils::getNewArticleRevId();
664 - wfDebugLog( 'p2p', ' -> store model rev : ' . $revId . ' session ' . session_id() . ' model ' . $modelAfterIntegrate->getText() );
665 - manager::storeModel( $revId + 1, $sessionId = session_id(), $modelAfterIntegrate, $blobCB = 0 );
666 -
667 - $patch->storePage( $title, $revId + 1 ); // stores the patch in a wikipage
668 - $editpage->textbox1 = $modelAfterIntegrate->getText();
669 - return true;
670 -}
671 -
672 -function uploadComplete( $image ) {
673 - global $wgServerName, $wgScriptPath, $wgServer, $wgVersion;
674 - $urlServer = 'http://' . $wgServerName . $wgScriptPath;
675 -
676 - // $classe = get_class($image);
677 - if ( compareMWVersion( $wgVersion, '1.16.0' ) == -1 ) {
678 - $localfile = $image->mLocalFile;
679 - } else {
680 -
681 - $localfile = $image->getLocalFile();
682 - }
683 - $path = utils::prepareString( $localfile->mime, $localfile->size, $wgServer . urldecode( $localfile->url ) );
684 - if ( !file_exists( $path ) ) {
685 - $dbr = wfGetDB( DB_SLAVE );
686 - $lastRevision = Revision::loadFromTitle( $dbr, $localfile->getTitle() );
687 - if ( $lastRevision->getPrevious() == null ) {
688 - $rev_id = 0;
689 - } else {
690 - $rev_id = $lastRevision->getPrevious()->getId();
691 - }
692 - $revID = $lastRevision->getId();
693 - $model = manager::loadModel( $rev_id );
694 - $patch = new Patch( false, true, null, $urlServer, $rev_id, null, null, null, $localfile->mime, $localfile->size, urldecode( $localfile->url ), null );
695 - $patch->storePage( $localfile->getTitle(), $revID ); // stores the patch in a wikipage
696 - manager::storeModel( $revID, $sessionId = session_id(), $model, $blobCB = 0 );
697 - }
698 - return true;
699 -}

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r77755Follow up to r77754jeroendedauw02:38, 5 December 2010

Status & tagging log