/** * Propagate data in xml property to other articles if necessary * @param string $oldText contains text being replaced * @param String $text which we never touch when propagating places * @param bool $textChanged which we never touch when propagating places * @return bool true if propagation was successful */ protected function propagateEditData($oldText, &$text, &$textChanged) { $result = true; // determine current parents and type and lat and lng list($alsoLocatedIn, $type, $lat, $lng, $fromYear, $toYear) = Place::getPropagatedData($this->xml); // determine original parents by retrieving current version list($origAlsoLocatedIn, $origType, $origLat, $origLng, $origFromYear, $origToYear) = array(array(), null, null, null, null, null); if ($oldText) { $origXml = StructuredData::getXml('place', $oldText); if (isset($origXml)) { list($origAlsoLocatedIn, $origType, $origLat, $origLng, $origFromYear, $origToYear) = Place::getPropagatedData($origXml); // maintain place_abbrevs if (!isset($this->xml) || Place::placeAbbrevsChanged($origXml, $this->xml)) { Place::placeAbbrevsDelete($this->titleString); if (isset($this->xml)) { Place::placeAbbrevsAdd($this->titleString, $this->xml); } } } else { // new place comes here or below // add to place_abbrevs Place::placeAbbrevsDelete($this->titleString); Place::placeAbbrevsAdd($this->titleString, $this->xml); } } else { // add to place_abbrevs Place::placeAbbrevsDelete($this->titleString); Place::placeAbbrevsAdd($this->titleString, $this->xml); } // $delAlsoLocatedIn = StructuredData::mapDiff($origAlsoLocatedIn, $alsoLocatedIn, 'place'); // don't remove from X if this place is locatedIn X // if ($this->locatedIn) { // $key = StructuredData::mapSearch($this->locatedIn, $delAlsoLocatedIn, 'place'); // if ($key!==false) { // array_splice($delAlsoLocatedIn, $key, 1); // } // } // if ($type != $origType || $lat != $origLat || $lng != $origLng) { // $updAlsoLocatedIn = $alsoLocatedIn; // } // else { // $updAlsoLocatedIn = array_diff($alsoLocatedIn, $origAlsoLocatedIn); // } // remove from original parent if necessary (don't remove from X if this place is now prevLocatedIn X) // if ($origLocatedIn && $origLocatedIn != $locatedIn && array_search($origLocatedIn, $alsoLocatedIn)===false) { // $parentArticle = StructuredData::getArticle(Title::newFromText((string)$origLocatedIn, NS_PLACE), true); // if ($parentArticle) { // $content =& $parentArticle->fetchContent(); // $updatedContent =& $this->updateContainedPlace(null, null, null, null, $content); // if ($updatedContent) { // $updateResult = $parentArticle->doEdit($updatedContent, self::PROPAGATE_MESSAGE, PROPAGATE_EDIT_FLAGS); // $result = $result && $updateResult; // } // } // } $isRedirect = StructuredData::isRedirect($text); if ($isRedirect) { // add alt name to redirect target list($prefName, $locatedIn) = Place::getPrefNameLocatedIn($this->titleString); $prefName = StructuredData::mb_str_replace($prefName, '_', ' '); // convert _'s back to spaces $newTitle = Title::newFromRedirect($text); $targetArticle = StructuredData::getArticle($newTitle, true); $targetContent =& $targetArticle->fetchContent(); $targetXml = StructuredData::getXml('place', $targetContent); $found = false; foreach ($targetXml->alternate_name as $an) { $altName = (string) $an['name']; if ($altName == $prefName) { $found = true; break; } } if (!$found) { $altName = '<alternate_name name="' . StructuredData::escapeXml($prefName) . '" source="from redirect"/>'; $targetContent = StructuredData::mb_str_replace($targetContent, "<place>", "<place>\n" . $altName); $targetArticle->doEdit($targetContent, 'Add alternate name from redirect', PROPAGATE_EDIT_FLAGS); } // edit wlh pages to point to the target title $job = new PlaceRedirectJob(array('old_title' => $this->titleString, 'new_title' => $newTitle->getText())); $job->insert(); } // update type, lat, or lng if changed, or this place has been redirected or this place is new if ($this->locatedIn && ($isRedirect || !isset($origXml) || $type != $origType || $lat != $origLat || $lng != $origLng || $fromYear != $origFromYear || $toYear != $origToYear)) { $parentArticle = StructuredData::getArticle(Title::newFromText($this->locatedIn, NS_PLACE), true); if ($parentArticle) { $content =& $parentArticle->fetchContent(); if ($isRedirect) { // remove from parent $updatedContent =& $this->updateContainedPlace(null, null, null, null, null, null, $content); } else { $updatedContent =& $this->updateContainedPlace($this->titleString, $type, $lat, $lng, $fromYear, $toYear, $content); } if ($updatedContent) { $updateResult = $parentArticle->doEdit($updatedContent, self::PROPAGATE_MESSAGE . ' [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS); $result = $result && $updateResult; } } } // remove from deleted previous parents foreach ($origAlsoLocatedIn as $pli) { if ($this->locatedIn != (string) $pli['place'] && StructuredData::mapArraySearch((string) $pli['place'], $alsoLocatedIn, 'place') === false) { $parentArticle = StructuredData::getArticle(Title::newFromText((string) $pli['place'], NS_PLACE), true); if ($parentArticle) { $content =& $parentArticle->fetchContent(); $updatedContent =& $this->updateContainedPlace(null, null, null, null, null, null, $content); if ($updatedContent) { $updateResult = $parentArticle->doEdit($updatedContent, self::PROPAGATE_MESSAGE . ' [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS); $result = $result && $updateResult; } } } } // add to new previous parents or update type, lat, lng on same previous-parents foreach ($alsoLocatedIn as $pli) { $origKey = StructuredData::mapArraySearch((string) $pli['place'], $origAlsoLocatedIn, 'place'); if ($origKey !== false) { $origPli = $origAlsoLocatedIn[$origKey]; } if ($this->locatedIn != (string) $pli['place'] && ($origKey === false || $type != $origType || $lat != $origLat || $lng != $origLng || (string) $pli['from_year'] != (string) $origPli['from_year'] || (string) $pli['to_year'] != (string) $origPli['to_year'])) { $parentArticle = StructuredData::getArticle(Title::newFromText((string) $pli['place'], NS_PLACE), true); if ($parentArticle) { $content =& $parentArticle->fetchContent(); $updatedContent =& $this->updateContainedPlace($this->titleString, $type, $lat, $lng, (string) $pli['from_year'], (string) $pli['to_year'], $content); if ($updatedContent) { $updateResult = $parentArticle->doEdit($updatedContent, self::PROPAGATE_MESSAGE . ' [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS); $result = $result && $updateResult; } } } } if (!$result) { error_log("ERROR! Place edit/rollback not propagated: {$this->titleString}\n"); } return $result; }