00001 <?php
00021 class SMWParseData {
00022
00029 static public function stripMagicWords( &$text, Parser $parser ) {
00030 $words = array();
00031 $mw = MagicWord::get( 'SMW_NOFACTBOX' );
00032
00033 if ( $mw->matchAndRemove( $text ) ) {
00034 $words[] = 'SMW_NOFACTBOX';
00035 }
00036
00037 $mw = MagicWord::get( 'SMW_SHOWFACTBOX' );
00038
00039 if ( $mw->matchAndRemove( $text ) ) {
00040 $words[] = 'SMW_SHOWFACTBOX';
00041 }
00042
00043 $output = $parser->getOutput();
00044 $output->mSMWMagicWords = $words;
00045
00046 return $words;
00047 }
00048
00055 static public function getSMWdata( $parser ) {
00056 $output = $parser->getOutput();
00057 $title = $parser->getTitle();
00058
00059
00060 if ( !isset( $output ) || !isset( $title ) ) {
00061 return null;
00062 }
00063
00064
00065 if ( !isset( $output->mSMWData ) ) {
00066 $output->mSMWData = new SMWSemanticData( new SMWDIWikiPage( $title->getDBkey(), $title->getNamespace(), $title->getInterwiki() ) );
00067 }
00068
00069 return $output->mSMWData;
00070 }
00071
00077 static public function clearStorage( Parser $parser ) {
00078 $output = $parser->getOutput();
00079 $title = $parser->getTitle();
00080
00081 if ( !isset( $output ) || !isset( $title ) ) {
00082 return;
00083 }
00084
00085 $output->mSMWData = new SMWSemanticData( new SMWDIWikiPage( $title->getDBkey(), $title->getNamespace(), $title->getInterwiki() ) );
00086 }
00087
00102 static public function addProperty( $propertyName, $value, $caption, Parser $parser, $storeAnnotation = true ) {
00103 wfProfileIn( 'SMWParseData::addProperty (SMW)' );
00104
00105
00106 $propertyDv = SMWPropertyValue::makeUserProperty( $propertyName );
00107
00108 if ( !$propertyDv->isValid() ) {
00109 return $propertyDv;
00110 }
00111
00112 $propertyDi = $propertyDv->getDataItem();
00113
00114
00115 if ( $propertyDi instanceof SMWDIError ) {
00116 return $propertyDv;
00117 }
00118
00119 $semandticData = self::getSMWData( $parser );
00120
00121 $result = SMWDataValueFactory::newPropertyObjectValue(
00122 $propertyDi,
00123 $value,
00124 $caption,
00125 $semandticData->getSubject()
00126 );
00127
00128 if ( $propertyDi->isInverse() ) {
00129 $result->addError( wfMsgForContent( 'smw_noinvannot' ) );
00130 } elseif ( $storeAnnotation && !is_null( self::getSMWData( $parser ) ) ) {
00131 $semandticData->addPropertyObjectValue( $propertyDi, $result->getDataItem() );
00132
00133
00134 if ( !$result->isValid() ) {
00135 $semandticData->addPropertyObjectValue(
00136 new SMWDIProperty( '_ERRP' ),
00137 $propertyDi->getDiWikiPage()
00138 );
00139 }
00140 }
00141
00142 wfProfileOut( 'SMWParseData::addProperty (SMW)' );
00143
00144 return $result;
00145 }
00146
00167 static public function storeData( $parseroutput, Title $title, $makejobs = true ) {
00168 global $smwgEnableUpdateJobs, $smwgDeclarationProperties, $smwgPageSpecialProperties;
00169
00170 $semdata = $parseroutput->mSMWData;
00171 $namespace = $title->getNamespace();
00172 $processSemantics = smwfIsSemanticsProcessed( $namespace );
00173
00174 if ( !isset( $semdata ) ) {
00175 $semdata = new SMWSemanticData( SMWDIWikiPage::newFromTitle( $title ) );
00176 }
00177
00178 if ( $processSemantics ) {
00179 $props = array();
00180
00181 foreach ( $smwgPageSpecialProperties as $propId ) {
00182
00183 if ( array_key_exists( $propId, $props ) ) {
00184 continue;
00185 }
00186
00187
00188 $props[ $propId ] = true;
00189 $prop = new SMWDIProperty( $propId );
00190
00191 if ( count( $semdata->getPropertyValues( $prop ) ) > 0 ) {
00192 continue;
00193 }
00194
00195
00196 $value = null;
00197
00198 switch ( $propId ) {
00199 case '_MDAT' :
00200 $timestamp = Revision::getTimeStampFromID( $title, $title->getLatestRevID() );
00201 $value = self::getDataItemFromMWTimestamp( $timestamp );
00202 break;
00203 case '_CDAT' :
00204 $timestamp = $title->getFirstRevision()->getTimestamp();
00205 $value = self::getDataItemFromMWTimestamp( $timestamp );
00206 break;
00207 case '_NEWP' :
00208 $value = new SMWDIBoolean( $title->isNewPage() );
00209 break;
00210 case '_LEDT' :
00211 $revision = Revision::newFromId( $title->getLatestRevID() );
00212 $user = User::newFromId( $revision->getUser() );
00213 $value = SMWDIWikiPage::newFromTitle( $user->getUserPage() );
00214 break;
00215 }
00216
00217 if ( !is_null( $value ) ) {
00218 $semdata->addPropertyObjectValue( $prop, $value );
00219 }
00220
00221 }
00222 } else {
00223 $semdata = new SMWSemanticData( $semdata->getSubject() );
00224 }
00225
00226
00227
00228
00229
00230 $updatejobflag = false;
00231 $jobs = array();
00232
00233 if ( $makejobs && $smwgEnableUpdateJobs && ( $namespace == SMW_NS_PROPERTY ) ) {
00234
00235 $ptype = new SMWDIProperty( '_TYPE' );
00236 $oldtype = smwfGetStore()->getPropertyValues( $semdata->getSubject(), $ptype );
00237 $newtype = $semdata->getPropertyValues( $ptype );
00238
00239 if ( !self::equalDatavalues( $oldtype, $newtype ) ) {
00240 $updatejobflag = true;
00241 } else {
00242 foreach ( $smwgDeclarationProperties as $prop ) {
00243 $pv = new SMWDIProperty( $prop );
00244 $oldvalues = smwfGetStore()->getPropertyValues( $semdata->getSubject(), $pv );
00245 $newvalues = $semdata->getPropertyValues( $pv );
00246 $updatejobflag = !self::equalDatavalues( $oldvalues, $newvalues );
00247 }
00248 }
00249
00250 if ( $updatejobflag ) {
00251 $prop = new SMWDIProperty( $title->getDBkey() );
00252 $subjects = smwfGetStore()->getAllPropertySubjects( $prop );
00253
00254 foreach ( $subjects as $subject ) {
00255 $subjectTitle = $subject->getTitle();
00256 if ( !is_null( $subjectTitle ) ) {
00257 $jobs[] = new SMWUpdateJob( $subjectTitle );
00258 }
00259 }
00260 wfRunHooks( 'smwUpdatePropertySubjects', array( &$jobs ) );
00261
00262 $subjects = smwfGetStore()->getPropertySubjects( new SMWDIProperty( '_ERRP' ), $semdata->getSubject() );
00263
00264 foreach ( $subjects as $subject ) {
00265 $subjectTitle = $subject->getTitle();
00266
00267 if ( !is_null( $subjectTitle ) ) {
00268 $jobs[] = new SMWUpdateJob( $subjectTitle );
00269 }
00270 }
00271 }
00272 } elseif ( $makejobs && $smwgEnableUpdateJobs && ( $namespace == SMW_NS_TYPE ) ) {
00273
00274 $pconv = new SMWDIProperty( '_CONV' );
00275 $ptype = new SMWDIProperty( '_TYPE' );
00276
00277 $oldfactors = smwfGetStore()->getPropertyValues( $semdata->getSubject(), $pconv );
00278 $newfactors = $semdata->getPropertyValues( $pconv );
00279 $updatejobflag = !self::equalDatavalues( $oldfactors, $newfactors );
00280
00281 if ( $updatejobflag ) {
00282 $store = smwfGetStore();
00283
00285 $dv = SMWDataValueFactory::newTypeIdValue( '__typ', $title->getDBkey() );
00286 $proppages = $store->getPropertySubjects( $ptype, $dv );
00287
00288 foreach ( $proppages as $proppage ) {
00289 $propertyTitle = $proppage->getTitle();
00290
00291 if ( !is_null( $propertyTitle ) ) {
00292 $jobs[] = new SMWUpdateJob( $propertyTitle );
00293 }
00294
00295 $prop = new SMWDIProperty( $proppage->getDBkey() );
00296 $subjects = $store->getAllPropertySubjects( $prop );
00297
00298 foreach ( $subjects as $subject ) {
00299 $subjectTitle = $subject->getTitle();
00300
00301 if ( !is_null( $subjectTitle ) ) {
00302 $jobs[] = new SMWUpdateJob( $subjectTitle );
00303 }
00304 }
00305
00306 $subjects = smwfGetStore()->getPropertySubjects(
00307 new SMWDIProperty( '_ERRP' ),
00308 $prop->getWikiPageValue()
00309 );
00310
00311 foreach ( $subjects as $subject ) {
00312 $subjectTitle = $subject->getTitle();
00313
00314 if ( !is_null( $subjectTitle ) ) {
00315 $jobs[] = new SMWUpdateJob( $subject->getTitle() );
00316 }
00317 }
00318 }
00319 }
00320 }
00321
00322
00323 if ( $processSemantics ) {
00324 smwfGetStore()->updateData( $semdata );
00325 } else {
00326 smwfGetStore()->clearData( $semdata->getSubject() );
00327 }
00328
00329
00330 if ( $updatejobflag ) {
00331 Job::batchInsert( $jobs );
00332 }
00333
00334 return true;
00335 }
00336
00342 static public function equalDatavalues( $dv1, $dv2 ) {
00343
00344
00345
00346 $values = array();
00347 foreach ( $dv1 as $v ) {
00348 $values[] = $v->getHash();
00349 }
00350
00351 sort( $values );
00352 $dv1hash = implode( '___', $values );
00353
00354 $values = array();
00355 foreach ( $dv2 as $v ) {
00356 $values[] = $v->getHash();
00357 }
00358
00359 sort( $values );
00360 $dv2hash = implode( '___', $values );
00361
00362 return ( $dv1hash == $dv2hash );
00363 }
00364
00370 static public function onParserAfterTidy( &$parser, &$text ) {
00371 global $smwgUseCategoryHierarchy, $smwgCategoriesAsInstances;
00372
00373 if ( is_null( self::getSMWData( $parser ) ) ) {
00374 return true;
00375 }
00376
00377 $categories = $parser->mOutput->getCategoryLinks();
00378 foreach ( $categories as $catname ) {
00379 if ( $smwgCategoriesAsInstances && ( self::getSMWData( $parser )->getSubject()->getNamespace() != NS_CATEGORY ) ) {
00380 $pinst = new SMWDIProperty( '_INST' );
00381 $categoryDi = new SMWDIWikiPage( $catname, NS_CATEGORY, '' );
00382 self::getSMWData( $parser )->addPropertyObjectValue( $pinst, $categoryDi );
00383 }
00384
00385 if ( $smwgUseCategoryHierarchy && ( self::getSMWData( $parser )->getSubject()->getNamespace() == NS_CATEGORY ) ) {
00386 $psubc = new SMWDIProperty( '_SUBC' );
00387 $categoryDi = new SMWDIWikiPage( $catname, NS_CATEGORY, '' );
00388 self::getSMWData( $parser )->addPropertyObjectValue( $psubc, $categoryDi );
00389 }
00390 }
00391
00392 $sortkey = $parser->mDefaultSort ? $parser->mDefaultSort :
00393 str_replace( '_', ' ', self::getSMWData( $parser )->getSubject()->getDBkey() );
00394 $pskey = new SMWDIProperty( '_SKEY' );
00395 try {
00396 $sortkeyDi = new SMWDIString( $sortkey );
00397 } catch (SMWStringLengthException $e) {
00398 $sortkey = substr( $sortkey, 0, $e->getMaxLength() );
00399 $sortkeyDi = new SMWDIString( $sortkey );
00400 }
00401 self::getSMWData( $parser )->addPropertyObjectValue( $pskey, $sortkeyDi );
00402
00403 return true;
00404 }
00405
00424 static public function onNewRevisionFromEditComplete( $article, Revision $rev, $baseID, User $user ) {
00425 global $smwgPageSpecialProperties;
00426
00427 if ( ( $article->mPreparedEdit ) && ( $article->mPreparedEdit->output instanceof ParserOutput ) ) {
00428 $output = $article->mPreparedEdit->output;
00429 $title = $article->getTitle();
00430
00431 if ( !isset( $title ) ) {
00432 return true;
00433 }
00434 if ( !isset( $output->mSMWData ) ) {
00435 $output->mSMWData = new SMWSemanticData( new SMWDIWikiPage( $title->getDBkey(), $title->getNamespace(), $title->getInterwiki() ) );
00436 }
00437
00438 $semdata = $output->mSMWData;
00439 } else {
00440 return true;
00441 }
00442
00443 if ( in_array( '_MDAT', $smwgPageSpecialProperties ) ) {
00444 $timestamp = $article->getTimestamp();
00445 $di = self::getDataItemFromMWTimestamp( $timestamp );
00446
00447 if ( !is_null( $di ) ) {
00448 $semdata->addPropertyObjectValue( new SMWDIProperty( '_MDAT' ), $di );
00449 }
00450 }
00451
00452 if ( in_array( '_LEDT', $smwgPageSpecialProperties ) ) {
00453 $di = SMWDIWikiPage::newFromTitle( $user->getUserPage() );
00454
00455 if ( !is_null( $di ) ) {
00456 $semdata->addPropertyObjectValue( new SMWDIProperty( '_LEDT' ), $di );
00457 }
00458 }
00459
00460 if ( in_array( '_NEWP', $smwgPageSpecialProperties ) ) {
00461 $semdata->addPropertyObjectValue(
00462 new SMWDIProperty( '_NEWP' ),
00463 new SMWDIBoolean( is_null( $rev->getParentId() ) )
00464 );
00465 }
00466
00467 return true;
00468 }
00469
00474 static public function onLinksUpdateConstructed( $links_update ) {
00475 self::storeData( $links_update->mParserOutput, $links_update->mTitle, true );
00476 return true;
00477 }
00478
00483 static public function onArticleDelete( &$article, &$user, &$reason ) {
00484 smwfGetStore()->deleteSubject( $article->getTitle() );
00485 return true;
00486 }
00487
00492 static public function onTitleMoveComplete( &$old_title, &$new_title, &$user, $pageid, $redirid ) {
00493 smwfGetStore()->changeTitle( $old_title, $new_title, $pageid, $redirid );
00494 return true;
00495 }
00496
00504 static protected function getDataItemFromMWTimestamp( $timestamp ) {
00505 $year = intval( substr( $timestamp, 0, 4 ) );
00506 $month = intval( substr( $timestamp, 4, 2 ) );
00507 $day = intval( substr( $timestamp, 6, 2 ) );
00508 $hour = intval( substr( $timestamp, 8, 2 ) );
00509 $min = intval( substr( $timestamp, 10, 2 ) );
00510 $sec = intval( substr( $timestamp, 12, 2 ) );
00511 try {
00512 return new SMWDITime( SMWDITime::CM_GREGORIAN, $year, $month, $day, $hour, $min, $sec );
00513 } catch ( SMWDataItemException $e ) {
00514
00515
00516 trigger_error( $e->getMessage(), E_USER_NOTICE );
00517 return null;
00518 }
00519 }
00520
00521 }