private function newPage() { global $wgOut, $wgUser; if ($this->name) { if (mb_strpos($this->name, $wgUser->getName() . "/") !== 0 && mb_strpos($this->name, "User:"******"/") !== 0) { $this->name = $wgUser->getName() . "/" . $this->name; } $t = Title::newFromText($this->name, NS_USER); $wgOut->redirect($t->getFullURL('action=edit')); // purge user page StructuredData::purgeTitle($wgUser->getUserPage()); } else { $wgOut->setPagetitle('Create a new user page'); $wgOut->setArticleRelated(false); $wgOut->setRobotpolicy('noindex,nofollow'); $titleObj = Title::makeTitle(NS_SPECIAL, 'MyRelate'); $action = $titleObj->escapeLocalURL(); $wgOut->addHTML(<<<END <form method='post' action="{$action}"> <input type="hidden" name="action" value="{$this->action}"/> Page title: <input type="text" name="name"/> <input type='submit' name="add"" value="Add"/> </form> END ); } }
/** * Add a jTip * * @param unknown_type $tipId must be unique * @param unknown_type $tipTitle title of the tip * @param unknown_type $tipText text of the tip * @param unknown_type $tipPageTitle title of the page to link to in URL form * @param unknown_type $linkText * @param unknown_type $width not used * @return unknown */ public function addTip($tipId, $tipTitle, $tipText, $tipPagePrefixedURL, $linkText, $width = 250) { global $wgScript; $tipId = str_replace(array('"', "'", '<', '>', '&'), '', $tipId); $tipTextId = $tipId . 'TipText'; $this->tips[$tipTextId] = $tipText; $tipTitle = StructuredData::escapeXml($tipTitle); return "<a class=\"jTip\" title=\"{$tipTitle}\" rel=\"#{$tipTextId}\" href=\"#\">{$linkText}</a>"; }
public function expandValue(StructuredData $structuredData, $elementDepth) { $value = $this->value; if (is_object($value) && isset($value->id)) { $value = array($value); } if (is_array($value)) { foreach ($value as $v) { if (isset($v->id)) { try { $SDElement = $structuredData->getSDElementById($v->id, $elementDepth + 1); $v->object = $SDElement; } catch (WikiaException $e) { $v->object = null; } } } } }
function getPageHeader() { global $wgScript; $t = Title::makeTitle(NS_SPECIAL, $this->getName()); $submitbutton = '<input type="submit" value="' . wfMsgHtml('allpagessubmit') . "\" />\n"; $out = "<div class='namespacesettings'><form method='get' action='{$wgScript}'>\n"; $out .= '<input type="hidden" name="title" value="' . $t->getPrefixedText() . '" />'; $out .= '<label for="user">User name:</label> <input type="text" name="user" size="15" value="' . htmlspecialchars($this->userName) . '" />'; $out .= ' <label for="tree">Tree name:</label>' . StructuredData::addSelectToHtml(0, 'tree', $this->allTrees, $this->treeName, '', true); if ($this->selectNamespace()) { $namespaceselect = StructuredData::addSelectToHtml(0, 'namespace', self::$NAMESPACE_OPTIONS, $this->namespace, '', false); $out .= " <label for='namespace'> " . wfMsgHtml('namespace') . "</label> {$namespaceselect} {$submitbutton}"; } $out .= '</form></div><br>'; return $out; }
public function getObject() { // force json format $this->getResponse()->setFormat('json'); $id = $this->request->getVal('id', false); $url = $this->request->getVal('url', false); $object = null; if (!empty($id)) { $object = $this->structuredData->getSDElementById($id); } else { if (!empty($url)) { $object = $this->structuredData->getSDElementByURL($url); } } if (is_object($object)) { $this->response->setBody((string) $object); } }
function wfSpecialAddSubpage($par) { global $wgOut, $wgRequest, $wgUser; $super = $wgRequest->getVal('super'); $sub = $wgRequest->getVal('sub'); $found = false; if ($super && $sub && $wgUser->isLoggedIn()) { $sub = mb_strtoupper(mb_substr($sub, 0, 1)) . mb_substr($sub, 1); $subTitle = Title::newFromText("{$super}/{$sub}"); if ($subTitle) { // add the page to the super page if it has a listsubpages tag $superTitle = Title::newFromText($super); if ($superTitle) { $r = Revision::newFromTitle($superTitle); if ($r) { $text =& $r->getText(); if ($subTitle->exists()) { $dbr =& wfGetDB(DB_SLAVE); $timestamp = $dbr->selectField(array('page', 'revision'), 'rev_timestamp', array('page_namespace' => $subTitle->getNamespace(), 'page_title' => $subTitle->getDBkey(), 'page_id = rev_page'), 'wfSpecialAddSubpage', array('order by rev_timestamp')); $d = new DateTime(substr($timestamp, 0, 8)); $date = $d->format('j M Y'); } else { $date = date('j M Y'); } $cnt = 0; $text = preg_replace('#(<listsubpages[^>]*>.*?)(</listsubpages>)#s', '${1}' . StructuredData::protectRegexReplace("{$sub}|{$date}") . "\n" . '${2}', $text, 1, $cnt); if ($cnt) { $a = StructuredData::getArticle($superTitle); $a->doEdit($text, 'Added ' . $sub, EDIT_UPDATE); } } } $wgOut->redirect($subTitle->getFullURL('action=edit')); $found = true; } } if (!$found) { $super = htmlspecialchars($super); $sub = htmlspecialchars($sub); $wgOut->addHTML("<p><font color=red>Cannot create page: {$super}/{$sub}</font></p>"); } }
/** * Run a refreshLinks job * @return boolean success */ function run() { global $wgUser, $wgTitle; $status = FTE_SUCCESS; $user = $this->params['user']; $wgUser = User::newFromName($user); $treeId = $this->params['tree_id']; $wgTitle = $this->title; // FakeTitle (the default) generates errors when accessed, and sometimes I log wgTitle, so set it to something else $dbw =& wfGetDB(DB_MASTER); $dbw->begin(); $dbw->ignoreErrors(true); $rows = $dbw->select('familytree_page', array('fp_namespace', 'fp_title'), array('fp_tree_id' => $treeId)); $errno = $dbw->lastErrno(); if ($errno > 0) { $status = FTE_DB_ERROR; } else { if ($rows !== false) { while ($row = $dbw->fetchObject($rows)) { $title = Title::makeTitle($row->fp_namespace, $row->fp_title); if ($title) { // watch article StructuredData::addWatch($wgUser, new Article($title, 0)); } } $dbw->freeResult($rows); } } if ($errno == 0) { $dbw->commit(); return true; } else { $dbw->rollback(); $this->error = "Error watching pages; db_errno={$errno}\n"; return false; } }
public static function updateImageLink($tag, $oldTitle, $newTitle, $caption, &$text, &$textChanged) { // TODO if you allow renaming images you must find a way to preserve caption and primary attributes here $old = "<image id=\"I(\\d+)\" filename=\"" . StructuredData::protectRegexSearch(StructuredData::escapeXml($oldTitle)) . "\".*?/>\n"; $matches = array(); $id = 0; $oldFound = false; if (preg_match('$' . $old . '$', $text, $matches)) { $id = (int) $matches[1]; $oldFound = true; } else { $old = "</{$tag}>"; } if ($newTitle) { $newTitle = StructuredData::escapeXml($newTitle); // get the last image number in the text if ($id == 0) { $id = ESINHandler::getLastImageId($text) + 1; } if ($caption) { $caption = " caption=\"{$caption}\""; } $new = "<image id=\"I{$id}\" filename=\"{$newTitle}\"{$caption}/>\n"; } else { $new = ''; } if (!$oldFound) { $new .= $old; } $result = preg_replace('$' . $old . '$', StructuredData::protectRegexReplace($new), $text); if ($result != $text) { $text = $result; $textChanged = true; } }
private function getMapData($n, &$result) { $family = @$this->families[$n]; // calculate color index numbers list($familyNumber, $husbandNumber, $wifeNumber, $selfNumber, $spouseNumber) = ShowPedigree::getColorIndexes($n); if (@$family['exists']) { $endpoints = array(); // get marriage $this->addEvent($family, 'marriage', $husbandNumber, $result); $this->addEndpoint($family, 'marriage', $endpoints); // get childbirths if (isset($family['children'])) { foreach ($family['children'] as $child) { // get birth for children $this->addEvent($child, 'birth', $familyNumber, $result); $this->addEndpoint($child, 'birth', $endpoints); } } // calculate which spouse dies first $husbandDeath = StructuredData::getDateKey(@$family['husband']['deathdate']); $wifeDeath = StructuredData::getDateKey(@$family['wife']['deathdate']); if ($husbandDeath && $wifeDeath) { if ($husbandDeath < $wifeDeath) { $firstDeathTag = 'husband'; $secondDeathTag = 'wife'; $secondDeathNumber = $wifeNumber; } else { $firstDeathTag = 'wife'; $secondDeathTag = 'husband'; $secondDeathNumber = $husbandNumber; } } else { if ($n >= ShowPedigree::SPOUSE_FAMILY_BASE && $n < ShowPedigree::SPOUSE_FAMILY_BASE + $this->numSpouseFamilies - 1) { $firstDeathTag = $this->spouseTag; $secondDeathTag = $this->selfTag; $secondDeathNumber = $selfNumber; } else { $firstDeathTag = 'husband'; $secondDeathTag = 'wife'; $secondDeathNumber = $wifeNumber; } } // include endpoint of first spouse to die in family endpoints $this->addEndpoint(@$family[$firstDeathTag], 'death', $endpoints); // generate edges from endpoints sort($endpoints, SORT_STRING); $firstFamilyEndpoint = count($endpoints) > 0 ? $endpoints[0] : null; $lastFamilyEndpoint = count($endpoints) > 0 ? $endpoints[count($endpoints) - 1] : null; $result .= $this->generateEdges($endpoints, $husbandNumber, $wifeNumber); // get death edge for last spouse to die (self's death on last spouse-family only) if ($lastFamilyEndpoint && ($secondDeathTag != $this->selfTag || $n <= ShowPedigree::MAX_FAMILIES || $n == ShowPedigree::SPOUSE_FAMILY_BASE + $this->numSpouseFamilies - 1)) { $endpoints = array($lastFamilyEndpoint); $this->addEndpoint(@$family[$secondDeathTag], 'death', $endpoints); $result .= $this->generateEdges($endpoints, $secondDeathNumber); } // get death info (self's death on last spouse-family only) if ($n >= ShowPedigree::SPOUSE_FAMILY_BASE) { $this->addEvent(@$family[$this->spouseTag], 'death', $spouseNumber, $result); if ($n == ShowPedigree::SPOUSE_FAMILY_BASE + $this->numSpouseFamilies - 1) { // last spouse family $this->addEvent(@$family[$this->selfTag], 'death', $selfNumber, $result); } } else { $this->addEvent(@$family['husband'], 'death', $husbandNumber, $result); $this->addEvent(@$family['wife'], 'death', $wifeNumber, $result); } // get birth for self-spouses and anyone who doesn't appear in a parent-family if ($n >= ShowPedigree::SPOUSE_FAMILY_BASE) { $this->addEvent(@$family[$this->spouseTag], 'birth', $spouseNumber, $result); if ($n == ShowPedigree::SPOUSE_FAMILY_BASE && @(!$this->families[1]['exists'])) { // first family, and parent family doesn't exist $this->addEvent(@$family[$this->selfTag], 'birth', $selfNumber, $result); } // add edges from spouse and self to first family event (but don't do this for self for 2nd and later families) if ($firstFamilyEndpoint) { $endpoints = array($firstFamilyEndpoint); $this->addEndpoint(@$family[$this->spouseTag], 'birth', $endpoints); $result .= $this->generateEdges($endpoints, $spouseNumber); if ($n == ShowPedigree::SPOUSE_FAMILY_BASE) { // first family for self $endpoints = array($firstFamilyEndpoint); $this->addEndpoint(@$family[$this->selfTag], 'birth', $endpoints); $result .= $this->generateEdges($endpoints, $selfNumber); } else { if ($this->prevLastFamilyEndpoint) { // second or later family for self $endpoints = array($this->prevLastFamilyEndpoint, $firstFamilyEndpoint); $result .= $this->generateEdges($endpoints, $selfNumber); } } } } else { if (@(!$this->families[$n * 2]['exists'])) { $this->addEvent(@$family['husband'], 'birth', $husbandNumber, $result); } if (@(!$this->families[$n * 2 + 1]['exists'])) { $this->addEvent(@$family['wife'], 'birth', $wifeNumber, $result); } if ($firstFamilyEndpoint) { $endpoints = array($firstFamilyEndpoint); $this->addEndpoint(@$family['husband'], 'birth', $endpoints); $result .= $this->generateEdges($endpoints, $husbandNumber); $endpoints = array($firstFamilyEndpoint); $this->addEndpoint(@$family['wife'], 'birth', $endpoints); $result .= $this->generateEdges($endpoints, $wifeNumber); } } $this->prevLastFamilyEndpoint = $lastFamilyEndpoint; } // just in case there are no spouse-families and we're not doing a pedigree for a family, we still need to get info on self if ($this->numSpouseFamilies == 0 && $n == 1 && $this->selfTag) { $endpoints = array(); if (@(!$this->families[1]['exists'])) { $this->addEvent(@$this->families[ShowPedigree::SPOUSE_FAMILY_BASE][$this->selfTag], 'birth', $selfNumber, $result); } $this->addEndpoint(@$this->families[ShowPedigree::SPOUSE_FAMILY_BASE][$this->selfTag], 'birth', $endpoints); $this->addEvent(@$this->families[ShowPedigree::SPOUSE_FAMILY_BASE][$this->selfTag], 'death', $selfNumber, $result); $this->addEndpoint(@$this->families[ShowPedigree::SPOUSE_FAMILY_BASE][$this->selfTag], 'death', $endpoints); $result .= $this->generateEdges($endpoints, $selfNumber); } }
private function cleanDate($str) { return StructuredData::getDateKey($str); // if($str == 'UNKNOWN') // return ''; // $str = preg_replace('/abt\.?\s*/i', '', $str); // $date = date_create($str); // function new in PHP 5.2 // return @date_format($date, DATE_ISO8601); // $matches = array(); // $pattern = '/abt\.?\s+([0-9]{4})'; // preg_match($pattern, $str, $matches); // if(isset($matches[1])) // return $matches[1]; // $pattern = '([0-9]{1,2}\s+(\w+)\s+' }
function wfShowWatchers($args) { $title = Title::newFromText($args); $watchers = StructuredData::getWatchers($title); return '<ol>' . join('', $watchers) . '</ol>'; }
/** * constructor */ function wfSpecialShowPedigree() { global $wgOut, $wgRequest, $wgScriptPath, $wgGoogleMapKey, $wrHostName, $wrSidebarHtml; $wgOut->setArticleRelated(false); $wgOut->setRobotpolicy('noindex,nofollow'); $titleText = $wgRequest->getVal('pagetitle'); $error = ''; if ($titleText) { $title = Title::newFromText($titleText); if (!$title->exists() && !StructuredData::endsWith($titleText, ')')) { $title = Title::newFromText($titleText . ')'); } if (is_null($title) || $title->getNamespace() != NS_PERSON && $title->getNamespace() != NS_FAMILY || !$title->exists()) { $error = 'Please enter the title of a person or family page (include the "Person:" or "Family:")'; } else { $wgOut->setPageTitle('Pedigree for ' . $title->getText()); $wgOut->addLink(array('href' => $wgScriptPath . '/index.php?action=ajax&rs=wfGetPedigreeData&rsargs=' . $title->getPrefixedURL(), 'type' => 'application/json', 'rel' => 'exhibit/data')); $wgOut->addScript("<script type=\"text/javascript\" src=\"{$wgScriptPath}/exhibit/src/webapp/api/exhibit-api.2.js\"></script>"); $wgOut->addScript("<script type=\"text/javascript\" src=\"{$wgScriptPath}/exhibit/src/webapp/extensions/time/time-extension.1.js\"></script>"); $wgOut->addScript("<script type=\"text/javascript\" src=\"{$wgScriptPath}/exhibit/src/webapp/extensions/map/map-extension.1.js?gmapkey={$wgGoogleMapKey}\"></script>"); $wgOut->addScript("<script type=\"text/javascript\" src=\"{$wgScriptPath}/exhibit.6.js\"></script>"); $wrSidebarHtml = <<<END <div id="wr-pedigreemap-sidebar"> <div ex:role="facet" ex:facetClass="TextSearch"></div> <div ex:role="facet" ex:height="165px" ex:expression=".Line" ex:facetLabel="Line"></div> <div ex:role="facet" ex:height="150px" ex:expression=".Generation" ex:facetLabel="Generation"></div> <div ex:role="facet" ex:height="75px" ex:facetClass="NumericRange" ex:expression=".BirthYear" ex:interval="10" ex:facetLabel="Birth Year"></div> <div ex:role="facet" ex:height="75px" ex:facetClass="NumericRange" ex:expression=".DeathYear" ex:interval="10" ex:facetLabel="Death Year"></div> </div> END; $wgOut->addHtml(<<<END <div ex:role="viewPanel"> <table ex:role="lens" ex:itemTypes="Person" class="exhibit-lens"> <tr> <td><span ex:if-exists=".ImageURL"><img ex:src-content=".ImageURL" /></span></td> <td> <div> <span ex:if=".FullName <> ''"> <span ex:content=".FullName" class="exhibit-name"></span> <span ex:content=".label" class="exhibit-name"></span> </span> </div> <div> <span ex:if=".Parents <> ''"> <span ex:content=".Parents"> <span ex:content="value" ex:formats="item { title: expression('Birth') }"></span> </span> <span>Birth</span> </span>: <span ex:content=".BirthDate"></span><span ex:if-exists=".BirthPlaceText">,</span> <span ex:if=".BirthPlace <> ''"> <span><a ex:href-subcontent="http://{$wrHostName}/wiki/{{.BirthPlace}}"><span ex:content=".BirthPlaceText" class="exhibit-place"></span></a></span> <span ex:content=".BirthPlaceText" class="exhibit-place"></span> </span> </div> <span ex:content=".Spouse"> <div> <span ex:content="value" ex:formats="item { title: expression('Marriage') }"></span>: <span ex:content=".MarriageDate"></span><span ex:if-exists=".MarriagePlaceText">,</span> <span ex:if=".MarriagePlace <> ''"> <span><a ex:href-subcontent="http://{$wrHostName}/wiki/{{.MarriagePlace}}"><span ex:content=".MarriagePlaceText" class="exhibit-place"></span></a></span> <span ex:content=".MarriagePlaceText" class="exhibit-place"></span> </span> </div> </span> <div>Death: <span ex:content=".DeathDate"></span><span ex:if-exists=".DeathPlaceText">,</span> <span ex:if=".DeathPlace <> ''"> <span><a ex:href-subcontent="http://{$wrHostName}/wiki/{{.DeathPlace}}"><span ex:content=".DeathPlaceText" class="exhibit-place"></span></a></span> <span ex:content=".DeathPlaceText" class="exhibit-place"></span> </span> </div> <span ex:content=".OtherEvents"> <div> <span ex:content=".EventType"></span>: <span ex:content=".Date"></span><span ex:if-exists=".PlaceText">,</span> <span ex:if=".Place <> ''"> <span><a ex:href-subcontent="http://{$wrHostName}/wiki/{{.Place}}"><span ex:content=".PlaceText" class="exhibit-place"></span></a></span> <span ex:content=".PlaceText" class="exhibit-place"></span> </span> </div> </span> <div class="exhibit-more"> ( <a ex:href-subcontent="http://{$wrHostName}/wiki/{{.label}}">more...</a> ) </div> </td> </tr> </table> <table ex:role="lens" ex:itemtypes="Family" class="exhibit-lens"> <tr> <td><span ex:if-exists=".ImageURL"><img ex:src-content=".ImageURL" /></span></td> <td> <span ex:content=".Husband"> <div>Husband: <span ex:if=".FullName <> ''"> <span ex:content="value" ex:formats="item { title: expression(.FullName) }"></span> <span ex:content="value"></span> </span> </div> </span> <span ex:content=".Wife"> <div>Wife: <span ex:if=".FullName <> ''"> <span ex:content="value" ex:formats="item { title: expression(.FullName) }"></span> <span ex:content="value"></span> </span> </div> </span> <div>Marriage: <span ex:content=".MarriageDate"></span><span ex:if-exists=".MarriagePlaceText">,</span> <span ex:if=".MarriagePlace <> ''"> <span><a ex:href-subcontent="http://{$wrHostName}/wiki/{{.MarriagePlace}}"><span ex:content=".MarriagePlaceText" class="exhibit-place"></span></a></span> <span ex:content=".MarriagePlaceText" class="exhibit-place"></span> </span> </div> <span ex:content=".OtherEvents"> <div> <span ex:content=".EventType"></span>: <span ex:content=".Date"></span><span ex:if-exists=".PlaceText">,</span> <span ex:if=".Place <> ''"> <span><a ex:href-subcontent="http://{$wrHostName}/wiki/{{.Place}}"><span ex:content=".PlaceText" class="exhibit-place"></span></a></span> <span ex:content=".PlaceText" class="exhibit-place"></span> </span> </div> </span> <span ex:if-exists=".Child"> <div>Children: <ol class="exhibit-children"> <span ex:content=".Child"> <li> <span ex:if=".FullName <> ''"> <span ex:content="value" ex:formats="item { title: expression(.FullName) }"></span> <span ex:content="value" ex:formats="item { title: expression(.label) }"></span> </span> </li> </span> </ol> </div> </span> <div class="exhibit-more"> ( <a ex:href-subcontent="http://{$wrHostName}/wiki/{{.label}}">more...</a> ) </div> </td> </tr> </table> <table ex:role="lens" ex:itemtypes="External" class="exhibit-lens"> <tr> <td> <div> <span ex:if=".FullName <> ''"> <span ex:content=".FullName" class="exhibit-name"></span> <span ex:content=".label"></span> </span> </div> <div class="exhibit-more"> ( <a ex:href-subcontent="http://{$wrHostName}/wiki/{{.label}}">more...</a> ) </div> </td> </tr> </table> <div ex:role="view" ex:viewClass="Template" ex:label="Pedigree" ex:title="View pedigree" ex:template="exhibitPersonPedigreeTemplate" ex:lenses="exhibitLenses" ex:slotIDPrefix="exhibit-pedigree-" ex:slotKey="Position" ex:slotClass="exhibit-pedigree-box" ex:showSummary="false" ex:showToolbox="false"> </div> <div ex:role="view" ex:viewClass="Map" ex:label="Birth Places" ex:title="View birth places on a map" ex:latlng=".addressLatLng" ex:maxAutoZoom='9' ex:mapHeight='435' ex:proxy=".BirthPlace" ex:icon=".IconURL" ex:colorKey=".Surname" ex:colorMarkerGenerator="wrExhibitColorMarkerGenerator" ex:makeIcon="wrExhibitMakeIcon" ex:showSummary="false" ex:showToolbox="false"> </div> <div ex:role="view" ex:viewClass="Map" ex:label="Death Places" ex:title="View death places on a map" ex:latlng=".addressLatLng" ex:maxAutoZoom='9' ex:mapHeight='435' ex:proxy=".DeathPlace" ex:icon=".IconURL" ex:colorKey=".Surname" ex:colorMarkerGenerator="wrExhibitColorMarkerGenerator" ex:makeIcon="wrExhibitMakeIcon" ex:showSummary="false" ex:showToolbox="false"> </div> <div ex:role="view" ex:viewClass="Map" ex:label="All Places" ex:title="View all event places on a map" ex:latlng=".addressLatLng" ex:maxAutoZoom='9' ex:mapHeight='435' ex:proxy=".AllPlaces" ex:icon=".IconURL" ex:colorKey=".Surname" ex:addOverlaysCallback="wrExhibitMapAddOverlays" ex:colorMarkerGenerator="wrExhibitColorMarkerGenerator" ex:makeIcon="wrExhibitMakeIcon" ex:showSummary="false" ex:showToolbox="false"> </div> <div ex:role="view" ex:viewClass="Timeline" ex:label="Timeline" ex:title="View people as timeline" ex:timelineHeight='435' ex:topBandHeight='86' ex:bottomBandHeight='14' ex:start=".BirthYear" ex:end=".DeathYear" ex:eventLabel=".FullName" ex:topBandUnit="decade" ex:topBandPixelsPerUnit="55" ex:bottomBandUnit="century" ex:bottomBandPixelsPerUnit="135" ex:colorKey=".Surname" ex:showSummary="false" ex:showToolbox="false"> </div> <div ex:role="view" ex:viewClass="Thumbnail" ex:label="Thumbnails" ex:title="View people as thumbnails" ex:orders=".Surname" ex:possibleOrders=".Surname, .Givenname, .Generation, .BirthYear, .DeathYear" ex:grouped="true" ex:showSummary="false" ex:showToolbox="false"> <table ex:role="lens" class="exhibit-thumbnail" style="display:none;"><tr><td> <div class="center"><span ex:if-exists=".ImageURL"><img ex:src-content=".ImageURL"/></span></div> <div><span ex:content="value" ex:formats="item { title: expression(.FullName) }"></span></div> <div>b. <span ex:content=".BirthDate"></span></div> <div>d. <span ex:content=".DeathDate"></span></div> </td></tr></table> </div> <div ex:role="view" ex:viewClass="Tile" ex:label="Details" ex:title="View details" ex:orders=".Surname, .Givenname" ex:possibleOrders=".Surname, .Givenname, .Generation, .BirthYear, .DeathYear" ex:grouped="false" ex:showSummary="false" ex:showToolbox="false"> </div> </div> <div ex:role="collection" ex:itemTypes="Person" style="display:none"></div> END ); return; } } $wgOut->setPageTitle('Show Pedigree'); if ($error) { $wgOut->addHTML("<p><font color=red>{$error}</font></p>"); } $queryBoxStyle = 'width:100%;text-align:center;'; $form = <<<END <form name="search" action="/wiki/Special:ShowPedigree" method="get"> <div id="searchFormDiv" style="{$queryBoxStyle}"> Person or Family page title: <input type="text" name="pagetitle" size="24" maxlength="100" value="{$titleText}" onfocus="select()" /> <input type="submit" value="Go" /> </div> </form> END; $wgOut->addHTML($form); }
public function getFormHtml() { global $wgLang, $wgUser; $target = $this->target; if (!$target) { $target = 'AddPage'; } $buttonValue = 'Next'; $nsText = $wgLang->getFormattedNsText($this->namespace); if ($this->namespace == NS_PERSON) { $givenname = htmlspecialchars($this->givenname); $surname = htmlspecialchars($this->surname); $birthSelect = StructuredData::addSelectToHtml(1, 'bt', AddPageForm::$BIRTH_TYPE_OPTIONS, $this->birthType); $birthdate = htmlspecialchars($this->birthdate); $birthplace = htmlspecialchars($this->birthplace); $deathSelect = StructuredData::addSelectToHtml(1, 'dt', AddPageForm::$DEATH_TYPE_OPTIONS, $this->deathType); $deathdate = htmlspecialchars($this->deathdate); $deathplace = htmlspecialchars($this->deathplace); $genderSelect = StructuredData::addSelectToHtml(1, 'gnd', Person::$GENDER_OPTIONS, $this->gender); $parentFamily = htmlspecialchars($this->parentFamily); $spouseFamily = htmlspecialchars($this->spouseFamily); $wifegivenname = htmlspecialchars($this->wifeGivenname); // if we're adding a father we need to remember the mother's name $wifesurname = htmlspecialchars($this->wifeSurname); $result = <<<END <form name="search" action="/wiki/Special:Search" method="get"> <input type="hidden" name="target" value="{$target}"/> <input type="hidden" id="ns" name="ns" value="{$nsText}"/> <input type="hidden" id="input_pf" name="pf" value="{$parentFamily}"/> <input type="hidden" id="input_sf" name="sf" value="{$spouseFamily}"/> <input type="hidden" id="input_wg" name="wg" value="{$wifegivenname}"/> <input type="hidden" id="input_ws" name="ws" value="{$wifesurname}"/> <table class="searchform"> <tr><td align="right">Given name: </td><td><input type="text" id="givenname_input" name="g" size=15 maxlength="50" value="{$givenname}" tabindex="1"/></td> <td align="right">Surname: </td><td><input type="text" name="s" size=35 maxlength="50" value="{$surname}" tabindex="1"/></td></tr> <tr><td align="right">Gender: </td><td>{$genderSelect}</td></tr> <tr><td align="right">{$birthSelect} date: </td><td><input type="text" name="bd" size=15 maxlength="25" value="{$birthdate}" tabindex="1" /></td> <td align="right">Place: </td><td><input class="place_input" type="text" name="bp" size=35 maxlength="130" value="{$birthplace}" tabindex="1" /></td></tr> <tr><td align="right">{$deathSelect} date: </td><td><input type="text" name="dd" size=15 maxlength="25" value="{$deathdate}" tabindex="1" /></td> <td align="right">Place: </td><td><input class="place_input" type="text" name="dp" size=35 maxlength="130" value="{$deathplace}" tabindex="1" /></td></tr> <tr><td colspan=4 align="right"><input type="submit" name="add" value="{$buttonValue}" tabindex="1"/></td></tr></table> </form> END; } else { if ($this->namespace == NS_FAMILY) { $gender = htmlspecialchars($this->gender); $husbandgivenname = htmlspecialchars($this->husbandGivenname); $husbandsurname = htmlspecialchars($this->husbandSurname); $wifegivenname = htmlspecialchars($this->wifeGivenname); $wifesurname = htmlspecialchars($this->wifeSurname); $marriagedate = htmlspecialchars($this->marriagedate); $marriageplace = htmlspecialchars($this->marriageplace); $husbandTitle = htmlspecialchars($this->husbandTitle); $wifeTitle = htmlspecialchars($this->wifeTitle); $childTitle = htmlspecialchars($this->childTitle); $result = <<<END <form name="search" action="/wiki/Special:Search" method="get"> <input type="hidden" name="target" value="{$target}"/> <input type="hidden" id = "ns" name="ns" value="{$nsText}"/> <input type="hidden" id="input_gnd" name="gnd" value="{$gender}"/> <input type="hidden" id="input_ht" name="ht" value="{$husbandTitle}"/> <input type="hidden" id="input_wt" name="wt" value="{$wifeTitle}"/> <input type="hidden" id="input_ct" name="ct" value="{$childTitle}"/> <table class="searchform"> <tr id="husband_row"><td align="right">Husband given name: </td><td><input type="text" name="hg" size=15 maxlength="50" value="{$husbandgivenname}" tabindex="1" /></td> <td align="right">Surname: </td><td><input type="text" name="hs" size=25 maxlength="50" value="{$husbandsurname}" tabindex="1" /></td></tr> <tr><td align="right">Wife given name: </td><td><input type="text" name="wg" size=15 maxlength="50" value="{$wifegivenname}" tabindex="1" /></td> <td align="right">Maiden name: </td><td><input type="text" name="ws" size=25 maxlength="50" value="{$wifesurname}" tabindex="1" /></td></tr> <tr><td align="right">Marriage date: </td><td><input type="text" name="md" size=15 maxlength="25" value="{$marriagedate}" tabindex="1" /></td> <td align="right">Place: </td><td><input class="place_input" type="text" name="mp" size=25 maxlength="130" value="{$marriageplace}" tabindex="1" /></td></tr> <tr><td colspan=4 align="right"><input type="submit" name="add" value="{$buttonValue}" tabindex="1" /></td></tr></table> </form> END; } else { if ($this->namespace == NS_SOURCE) { $title = htmlspecialchars($this->sourceTitle); $author = htmlspecialchars($this->author); $place = htmlspecialchars($this->place); $placeIssued = htmlspecialchars($this->placeIssued); $publisher = htmlspecialchars($this->publisher); $select = StructuredData::addSelectToHtml(1, 'sty', Source::$ADD_SOURCE_TYPE_OPTIONS, $this->sourceType); $result = <<<END <form name="search" action="/wiki/Special:Search" method="get"> <input type="hidden" name="target" value="{$target}"/> <input type="hidden" id = "ns" name="ns" value="{$nsText}"/> <table class="searchform"> <tr><td align="right">Source type:</td><td align="left">{$select}</td><td></td></tr> <tr id="author_row"><td align="right">Author:</td><td align="left"><input type="text" name="a" size="35" value="{$author}" tabindex="1" /></td><td> <i>surname, given name(s) of first author</i></td></tr> <tr><td align="right">Title:</td><td align="left"><input type="text" name="st" size="35" value="{$title}" tabindex="1" /></td><td> <i>title only, no subtitle</i></td></tr> <tr><td align="right">Place covered:</td><td align="left"><input class="place_input" type="text" name="p" size="35" value="{$place}" tabindex="1" /></td><td> <i>for government/church records</i></td></tr> <tr><td align="right">Publisher:</td><td align="left"><input type="text" name="pu" size="35" value="{$publisher}" tabindex="1" /></td><td></td></tr> <tr><td align="right">Place issued:</td><td align="left"><input type="text" name="pi" size="35" value="{$placeIssued}" tabindex="1" /></td><td></td></tr> <tr><td colspan=3 align="right"><input type="submit" name="add" value="{$buttonValue}" tabindex="1" /></td></tr> </table></form> END; } else { if ($this->namespace == NS_MYSOURCE) { $author = htmlspecialchars($this->author); $title = htmlspecialchars($this->titleText); $result = <<<END <form name="search" action="/wiki/Special:Search" method="get"> <input type="hidden" name="target" value="{$target}"/> <input type="hidden" id = "ns" name="ns" value="{$nsText}"/> <table class="searchform"> <tr><td align="right">Title:</td><td align="left"><input type="text" name="t" size="35" value="{$title}" tabindex="1" /></td></tr> <tr><td colspan=2 align="right"><input type="submit" name="add" value="{$buttonValue}" tabindex="1" /></td></tr> </table></form> END; } else { if ($this->namespace == NS_PLACE) { $placeName = htmlspecialchars($this->placeName); $locatedIn = htmlspecialchars($this->locatedIn); $result = <<<END <form name="search" action="/wiki/Special:Search" method="get"> <input type="hidden" name="target" value="{$target}"/> <input type="hidden" id = "ns" name="ns" value="{$nsText}"/> <table class="searchform"> <tr id="placename_row"><td align="right">Place name:</td><td align="left"><input type="text" name="pn" size="20" value="{$placeName}" tabindex="1" /></td><td>Name of the place to add</td></tr> <tr><td align="right">Located in:</td><td align="left"><input class="place_input" type="text" name="li" size="35" value="{$locatedIn}" tabindex="1" /></td><td>County, District, or State in which the place is located</td></tr> <tr><td colspan=3 align="right"><input type="submit" name="add" value="{$buttonValue}" tabindex="1" /></td></tr> </table></form> END; } else { $title = htmlspecialchars($this->titleText); if (strlen($this->namespace) == 0) { $hiddenField = ''; $namespaceselect = "<tr><td align=\"right\">Namespace:</td><td align=\"left\">" . HTMLnamespaceselector('', null) . "</tr>"; } else { $hiddenField = "<input type=\"hidden\" name=\"namespace\" value=\"{$this->namespace}\"/>"; $namespaceselect = ''; } $result = <<<END <form name="search" action="/wiki/Special:AddPage" method="get"> <input type="hidden" name="confirm" value="true"/> {$hiddenField} <table class="searchform"> {$namespaceselect}<tr id="title_row"><td align="right">Title:</td><td align="left"><input id="titleinput" type="text" name="t" size="40" maxlength="160" value="{$title}" /> </td><td><input type="submit" name="add" value="{$buttonValue}"/> </td></tr></table></form> END; } } } } } // $treeCheckboxes = ''; // if ($this->namespace == NS_PERSON || $this->namespace == NS_FAMILY) { // $treeCheckboxes = '<p>'.FamilyTreeUtil::generateTreeCheckboxes($wgUser, null, true).'</p>'; // } $addPageCache = $this->namespace == NS_SOURCE || $this->namespace == NS_MYSOURCE || $this->namespace == NS_PERSON || $this->namespace == NS_FAMILY ? '<div id="addpage_cache" style="display:none"></div>' : ''; // was $treeCheckboxes inside div return '<center>' . $result . '</center>' . $addPageCache; }
/** * Propagate an article rollback * Sets xml property and calls the abstract function propagateRollbackData($title) * @param Article $article contains text being replaced * @return bool true if propagate succeeded */ public function propagateRollback($article) { global $wgUser, $wrBotUserID; $result = true; // we do propagate bot edits // if ($wgUser->getID() != $wrBotUserID) { $title = $article->getTitle(); $oldText =& $article->fetchContent(); // $article contains the text being replaced; $rollbackRevision contains the new text $rollbackRevision = StructuredData::getRevision($title, false, true); $text =& $rollbackRevision->getText(); $this->xml = StructuredData::getXml($this->tagName, $text); $textChanged = false; $result = $this->propagateEditData($oldText, $text, $textChanged); if ($result && $textChanged) { PropagationManager::enablePropagation(false); $result = $article->doEdit($text, self::PROPAGATE_MESSAGE, PROPAGATE_EDIT_FLAGS); PropagationManager::enablePropagation(true); } // } return $result; }
/** * Propagate move, delete, or undelete to other articles if necessary * * @param String $newTitleString null in case of delete; same as this title string in case of undelete * @param String $text text of article * @param bool $textChanged set to true if we change the text * @return bool true if success */ protected function propagateMoveDeleteUndelete($newTitleString, $newNs, &$text, &$textChanged) { global $wgESINHandler; $result = true; $newTitle = $newTitleString ? Title::newFromText($newTitleString, NS_PERSON) : null; // if we're undeleting, add additional families from WLH if ($this->titleString == $newTitleString) { $wlh = simplexml_load_string($this->getPageTextFromWLH(false)); // get text for all families $familyText = $this->getFamilyData($wlh->child_of_family, $this->xml->child_of_family, 'child_of_family') . $this->getFamilyData($wlh->spouse_of_family, $this->xml->spouse_of_family, 'spouse_of_family') . $wgESINHandler->getImageData($wlh->image, $this->xml->image); // update text: replace old family information with new $text = preg_replace("\$<((child|spouse)_of_family|image) [^>]*>\n\$", '', $text); $text = preg_replace('$</person>$', StructuredData::protectRegexReplace($familyText . '</person>'), $text, 1); $this->xml = StructuredData::getXml($this->tagName, $text); $textChanged = true; } // get data to propagate $propagatedData = Person::getPropagatedData($this->xml); foreach ($propagatedData['parentFamilies'] as $f) { $familyTitle = Title::newFromText((string) $f, NS_FAMILY); PropagationManager::addPropagatedAction($this->title, 'delchild_of_family', $familyTitle); if ($newTitle) { PropagationManager::addPropagatedAction($newTitle, 'addchild_of_family', $familyTitle); } // don't need to check propagated action before calling updateFamily, because propagateMoveDeleteUndelete is never part of a loop $result = $result && $this->updateFamily($familyTitle, 'child_of_family', 'child', $newTitleString, $propagatedData, $text, $textChanged); } $spouseTag = $propagatedData['gender'] == 'F' ? 'wife' : 'husband'; foreach ($propagatedData['spouseFamilies'] as $f) { $familyTitle = Title::newFromText((string) $f, NS_FAMILY); PropagationManager::addPropagatedAction($this->title, 'delspouse_of_family', $familyTitle); if ($newTitle) { PropagationManager::addPropagatedAction($newTitle, 'addspouse_of_family', $familyTitle); } // don't need to check propagated action before calling updateFamily, because propagateMoveDeleteUndelete is never part of a loop $result = $result && $this->updateFamily($familyTitle, 'spouse_of_family', $spouseTag, $newTitleString, $propagatedData, $text, $textChanged); } if (StructuredData::removeDuplicateLinks('child_of_family|spouse_of_family', $text)) { $textChanged = true; } $result = $result && $wgESINHandler->propagateSINMoveDeleteUndelete($this->title, 'person', $this->titleString, $newTitleString, $propagatedData, $text, $textChanged); if (!$result) { error_log("ERROR! Person move/delete/undelete not propagated: {$this->titleString} -> " . ($newTitleString ? $newTitleString : "[delete]") . "\n"); } return $result; }
public function doMerge() { global $wgOut, $wgUser; $skin =& $wgUser->getSkin(); if ($this->isGedcom()) { $editFlags = EDIT_UPDATE; $mergeText = 'updated'; } else { // create a mergelog record $mergeScore = $this->getMergeScore(); $isTrustedUser = CompareForm::isTrustedMerger($wgUser, false); $isTrustedMerge = MergeForm::isTrustedMerge($mergeScore, $isTrustedUser); $mergeLogId = $this->logMerge($mergeScore, $isTrustedMerge); wfDebug("MERGESCORE mergeLogId={$mergeLogId} total score={$mergeScore}\n"); if (!$isTrustedUser && $mergeScore < self::$LOW_MATCH_THRESHOLD) { error_log("WARNING suspect merge: id={$mergeLogId} user={$wgUser->getName()} score={$mergeScore}"); } $editFlags = EDIT_UPDATE | EDIT_FORCE_BOT; $mergeText = 'merged'; } // get merging people and families // add merging people and families to blacklist so propagation doesn't also try to update them $mergingPeople = array(); $mergingFamilies = array(); for ($m = 0; $m < count($this->data); $m++) { for ($p = 0; $p < count($this->data[$m]); $p++) { $titleString = $this->data[$m][$p]['title']; if ($this->namespace == 'Family' && $m == 0) { if ($p > 0) { $mergingFamilies[$titleString] = $this->data[$m][0]['title']; } $ns = NS_FAMILY; } else { if ($p > 0) { $mergingPeople[$titleString] = $this->data[$m][0]['title']; } $ns = NS_PERSON; } if (!GedcomUtil::isGedcomTitle($titleString)) { $title = Title::newFromText($titleString, $ns); PropagationManager::addBlacklistPage($title); } } } $output = "<H2>Pages {$mergeText} successfully</H2>"; $output .= $this->getWarnings(); $output .= '<ul>'; $outputRows = array(); $emptyRequest = new FauxRequest(array(), true); $mergeCmtSuffix = $this->isGedcom() ? '' : " - [[Special:ReviewMerge/{$mergeLogId}|review/undo]]"; if ($this->namespace == 'Family' && !$this->isGedcom()) { $t = Title::newFromText($this->data[0][0]['title'], NS_FAMILY); $mergeCmtFamily = $this->namespace == 'Family' ? " in merge of [[{$t->getPrefixedText()}]]" : ''; } else { $mergeCmtFamily = ''; } // backwards, because you must merge family last, so that propagated person data in family xml is correct // and so that mergeCmtFamily can be cleared at the end and mergeSummary and mergeTargetTitle are correct after the for loop for ($m = count($this->data) - 1; $m >= 0; $m--) { $requestData = array(); $contents = ''; $talkContents = ''; $outputRow = ''; $mainOutput = ''; $talkOutput = ''; $nameCount = $eventCount = $sourceCount = $imageCount = $noteCount = $husbandCount = $wifeCount = $childrenCount = $parentFamilyCount = $spouseFamilyCount = 0; $primaryNameFound = $primaryImageFound = $birthFound = $christeningFound = $deathFound = $burialFound = $marriageFound = false; if ($this->namespace == 'Family' && $m == 0) { $mergeTargetNs = NS_FAMILY; $mergeTargetTalkNs = NS_FAMILY_TALK; $mergeCmtFamily = ''; } else { $mergeTargetNs = NS_PERSON; $mergeTargetTalkNs = NS_PERSON_TALK; } $mergeTargetTitle = Title::newFromText($this->data[$m][0]['title'], $mergeTargetNs); if ($mergeTargetTitle->getNamespace() != $mergeTargetNs) { error_log("Merge glitch:{$mergeTargetNs}:{$this->data[$m][0]['title']}:{$mergeTargetTitle->getNamespace()}:"); } $mergeTargetTalkTitle = Title::newFromText($this->data[$m][0]['title'], $mergeTargetTalkNs); $mergeSummary = ''; $talkMergeSummary = ''; $keepKeys = $this->generateKeepKeys($this->data[$m], $this->add[$m], $this->key[$m]); $notesMap = array(); $noteAdoptions = array(); $this->generateMapAdoptions('notes', 'N', $mergeTargetNs, $this->data[$m], $this->add[$m], $this->key[$m], $keepKeys, $notesMap, $noteAdoptions); $sourcesMap = array(); $sourceAdoptions = array(); $this->generateMapAdoptions('sources', 'S', $mergeTargetNs, $this->data[$m], $this->add[$m], $this->key[$m], $keepKeys, $sourcesMap, $sourceAdoptions); $imagesMap = array(); $imageAdoptions = array(); $this->generateMapAdoptions('images', 'I', $mergeTargetNs, $this->data[$m], $this->add[$m], $this->key[$m], $keepKeys, $imagesMap, $imageAdoptions); // get request data for merge target for ($p = 0; $p < count($this->data[$m]); $p++) { if ($this->isMergeable($this->data[$m][$p])) { $this->addNotesToRequestData($requestData, $keepKeys[$p], $noteCount, $notesMap[$p], $this->data[$m][$p]['notes']); $this->addImagesToRequestData($requestData, $keepKeys[$p], $imageCount, $imagesMap[$p], $primaryImageFound, $this->data[$m][$p]['images']); $this->addSourcesToRequestData($requestData, $keepKeys[$p], $sourceCount, $sourcesMap[$p], $notesMap[$p], $imagesMap[$p], $this->data[$m][$p]['sources'], $noteAdoptions, $imageAdoptions); $this->addEventsToRequestData($requestData, $keepKeys[$p], $eventCount, $mergeTargetNs == NS_PERSON ? Person::$STD_EVENT_TYPES : Family::$STD_EVENT_TYPES, $birthFound, $christeningFound, $deathFound, $burialFound, $marriageFound, $notesMap[$p], $imagesMap[$p], $sourcesMap[$p], $this->data[$m][$p]['events'], $noteAdoptions, $sourceAdoptions, $imageAdoptions); if ($mergeTargetNs == NS_PERSON) { $this->addNamesToRequestData($requestData, $keepKeys[$p], $nameCount, $primaryNameFound, $notesMap[$p], $sourcesMap[$p], $this->data[$m][$p]['names'], $noteAdoptions, $sourceAdoptions); $this->addFamilyToRequestData($requestData, $mergingFamilies, 'child_of_family', $parentFamilyCount, $this->data[$m][$p]['child_of_families']); $this->addFamilyToRequestData($requestData, $mergingFamilies, 'spouse_of_family', $spouseFamilyCount, $this->data[$m][$p]['spouse_of_families']); } else { $this->addFamilyMembersToRequestData($requestData, $mergingPeople, 'husband', $husbandCount, $this->data[$m][$p]['husbands']); $this->addFamilyMembersToRequestData($requestData, $mergingPeople, 'wife', $wifeCount, $this->data[$m][$p]['wives']); $this->addFamilyMembersToRequestData($requestData, $mergingPeople, 'child', $childrenCount, $this->data[$m][$p]['children']); } $pageContents = $this->mapContents($sourcesMap[$p], $imagesMap[$p], $notesMap[$p], $this->data[$m][$p]['contents']); $this->addContents($contents, $keepKeys[$p], $pageContents); if ($p > 0) { if ($mergeSummary) { $mergeSummary .= ', '; } if ($mainOutput) { $mainOutput .= ', '; } if ($this->data[$m][$p]['gedcom']) { $mergeSummary .= 'gedcom'; $mainOutput .= htmlspecialchars(($mergeTargetNs == NS_FAMILY ? 'Family:' : 'Person:') . $this->data[$m][$p]['title']); } else { $title = Title::newFromText($this->data[$m][$p]['title'], $mergeTargetNs); $mergeSummary .= "[[" . $title->getPrefixedText() . "]]"; $mainOutput .= $skin->makeKnownLinkObj($title, htmlspecialchars($title->getPrefixedText()), 'redirect=no'); } } } } // redirect other pages to merge target $redir = "#REDIRECT [[" . $mergeTargetTitle->getPrefixedText() . "]]"; $talkRedir = "#REDIRECT [[" . $mergeTargetTalkTitle->getPrefixedText() . "]]"; for ($p = 1; $p < count($this->data[$m]); $p++) { if (!$this->data[$m][$p]['gedcom']) { $obj = $this->data[$m][$p]['object']; $comment = $this->makeComment($this->userComment, "merge into [[" . $mergeTargetTitle->getPrefixedText() . "]]" . $mergeCmtFamily, $mergeCmtSuffix); $obj->editPage($emptyRequest, $redir, $comment, $editFlags, false); // redir talk page as well if ($this->data[$m][$p]['talkrevid']) { // if talk page exists $talkTitle = Title::newFromText($this->data[$m][$p]['title'], $mergeTargetTalkNs); $article = new Article($talkTitle, 0); if ($article) { $this->addTalkContents($talkContents, $talkTitle, $article->fetchContent()); if ($talkMergeSummary) { $talkMergeSummary .= ', '; } if ($talkOutput) { $talkOutput .= ', '; } $talkMergeSummary .= "[[" . $talkTitle->getPrefixedText() . "]]"; $talkOutput .= $skin->makeKnownLinkObj($talkTitle, htmlspecialchars($talkTitle->getPrefixedText()), 'redirect=no'); $comment = $this->makeComment($this->userComment, "merge into [[" . $mergeTargetTalkTitle->getPrefixedText() . "]]" . $mergeCmtFamily, $mergeCmtSuffix); $article->doEdit($talkRedir, $comment, $editFlags); } } } } // update merge target talk if ($talkContents) { $article = new Article($mergeTargetTalkTitle, 0); if ($article) { $mergeTargetTalkContents = $article->fetchContent(); if ($mergeTargetTalkContents) { $mergeTargetTalkContents = rtrim($mergeTargetTalkContents) . "\n\n"; } $comment = $this->makeComment($this->userComment, 'merged with ' . $talkMergeSummary . $mergeCmtFamily, $mergeCmtSuffix); $article->doEdit($mergeTargetTalkContents . $talkContents, $comment, $editFlags); if ($this->addWatches) { StructuredData::addWatch($wgUser, $article, true); } } $outputRow .= '<li>Merged ' . $talkOutput . ' into ' . $skin->makeKnownLinkObj($mergeTargetTalkTitle, htmlspecialchars($mergeTargetTalkTitle->getPrefixedText())) . "</li>"; } $obj = $this->data[$m][0]['object']; if ($mergeTargetNs == NS_PERSON) { Person::addGenderToRequestData($requestData, $this->data[$m][0]['gender']); } else { // family $obj->isMerging(true); // to read propagated data from person pages, not from prev family revision } // update merge target $req = new FauxRequest($requestData, true); $comment = $this->makeComment($this->userComment, ($mergeSummary == 'gedcom' ? 'Add data from gedcom' : 'merged with ' . $mergeSummary) . $mergeCmtFamily, $mergeCmtSuffix); $obj->editPage($req, $contents, $comment, $editFlags, $this->addWatches); $outputRow .= '<li>Merged ' . $mainOutput . ' into ' . $skin->makeKnownLinkObj($mergeTargetTitle, htmlspecialchars($mergeTargetTitle->getPrefixedText())) . "</li>"; $outputRows[] = $outputRow; } // add log and recent changes if (!$this->isGedcom()) { if (!$mergeSummary) { $mergeSummary = 'members of other families'; } $mergeComment = 'Merge [[' . $mergeTargetTitle->getPrefixedText() . ']] and ' . $mergeSummary; $log = new LogPage('merge', false); $t = Title::makeTitle(NS_SPECIAL, "ReviewMerge/{$mergeLogId}"); $log->addEntry('merge', $t, $mergeComment); RecentChange::notifyLog(wfTimestampNow(), $t, $wgUser, $mergeComment, '', 'merge', 'merge', $t->getPrefixedText(), $mergeComment, '', $isTrustedMerge, 0); } $nonmergedPages = $this->getNonmergedPages(); $output .= join("\n", array_reverse($outputRows)) . '</ul>' . ($nonmergedPages ? '<p>In addition to the people listed above, the following have also been included in the target family' . ($this->isGedcom() ? '<br/>(GEDCOM people listed will be added when the GEDCOM is imported)' : '') . $nonmergedPages . "</p>\n" : '') . ($this->isGedcom() ? '' : '<p>' . $skin->makeKnownLinkObj(Title::makeTitle(NS_SPECIAL, 'ReviewMerge/' . $mergeLogId), htmlspecialchars("Review/undo merge")) . '<br>' . $skin->makeKnownLinkObj(Title::makeTitle(NS_SPECIAL, 'ShowDuplicates'), htmlspecialchars("Show more duplicates")) . '</p>'); return $output; }
private function getEventData($xml, $eventTypes) { $eventTypeIndex = 0; foreach ($eventTypes as $type) { foreach ($xml->event_fact as $event_fact) { if ((string) $event_fact['type'] == $type) { $eventDate = (string) $event_fact['date']; $eventYear = substr(StructuredData::getDateKey($eventDate), 0, 4); $eventPlace = ''; // $eventPlaceUrl = ''; $place = (string) $event_fact['place']; if ($place) { $pos = mb_strpos($place, '|'); if ($pos !== false) { $eventPlace = mb_substr($place, $pos + 1); // $placeTitle = mb_substr($place, 0, $pos); } else { $eventPlace = $place; // $placeTitle = $place; } // $t = Title::newFromText($placeTitle, NS_PLACE); // if ($t) { // $eventPlaceUrl = $t->getFullURL(); // } } return array($eventYear, $eventDate, $eventPlace, $eventTypeIndex); } } $eventTypeIndex++; } return array('', '', '', -1); }
public function getFormHtml() { $name = htmlspecialchars($this->name); $nameTypeSelect = StructuredData::addSelectToHtml(0, "type", self::$TYPE_OPTIONS, $this->type, '', false); $namesend = preg_replace('#</?p>#', '', wfMsgWikiHtml('namesend')); $result = <<<END <form id="names_form" action="/wiki/Special:Names" method="get"> <table id="namesform" class="namesform"><tr> <td align=right>{$nameTypeSelect}</td> <td><input id="input_name" class="input_name" type="text" name="name" maxlength=100 value="{$name}" onfocus="select()"/></td> <td><input type="submit" value="Go"/></td> <td style="padding-left:15px">{$namesend}</td> </tr></table></form> END; return $result; }
/** * Returns an error message in case of error * * @param unknown_type $treeId * @param unknown_type $filename * @return unknown */ public function exportGedcom($treeId, $filename) { $this->treeId = $treeId; $dbr =& wfGetDB(DB_SLAVE); $dbr->ignoreErrors(true); // read tree $row = $dbr->selectRow('familytree', array('ft_user', 'ft_name', 'ft_primary_namespace', 'ft_primary_title'), array('ft_tree_id' => $this->treeId)); $this->userName = $row->ft_user; $this->treeName = $row->ft_name; $this->primary = ''; $primaryId = ''; $title = Title::makeTitle($row->ft_primary_namespace, $row->ft_primary_title); if ($title) { $title = StructuredData::getRedirectToTitle($title); } if ($title && $title->getNamespace() == NS_PERSON) { $this->primary = $title->getFullText(); $primaryId = $this->generateId(NS_PERSON); } // read pages in the tree $rows = $dbr->select('familytree_page', array('fp_namespace', 'fp_title'), array('fp_tree_id' => $this->treeId), 'GedcomExport::select'); if ($dbr->lastErrno() > 0) { return "Error reading tree {$treeId}"; } else { if ($rows !== false) { while ($row = $dbr->fetchObject($rows)) { $title = Title::makeTitle($row->fp_namespace, $row->fp_title); if (!$title) { echo "Bad title: ns={$row->fp_namespace} title={$row->fp_title} treeId={$this->treeId}\n"; } else { $title = StructuredData::getRedirectToTitle($title); $ns = $title->getNamespace(); $fullTitle = $title->getFullText(); if (!@$this->titleMap[$fullTitle]) { // don't add this page if it's been added already (can happen in the case of redirects) $id = $this->primary && $this->primary == $fullTitle ? $primaryId : $this->generateId($ns); if ($id) { // pages without an id don't go into the GEDCOM $this->titleMap[$fullTitle] = $id; $this->titleList[] = $fullTitle; } } } } $dbr->freeResult($rows); } } // create the file $this->fh = fopen($filename, "w"); if (!$this->fh || !is_writable($filename)) { return "Unable to create gedcom file for {$treeId}"; } // write the header $this->writeHeader(); // write the primary page if ($this->primary) { $this->writePage($this->primary); } // read and write each page for ($i = 0; $i < count($this->titleList); $i++) { if ($this->primary != $this->titleList[$i]) { $this->writePage($this->titleList[$i]); } } foreach ($this->titleOnlySources as $title => $id) { $this->writeTitleOnlySource($id, $title); } foreach ($this->repositories as $key => $id) { list($repoName, $repoAddr) = explode("^|^", $key, 2); $this->writeRepository($id, $repoName, $repoAddr); } $this->writeWeRelateSource(); // write the trailer $this->writeTrailer(); // close the file fclose($this->fh); return ''; }
/** * Return true if xml property is valid */ protected function validateData() { if (isset($this->xml)) { return StructuredData::isValidYear((string) $this->xml->from_year) && StructuredData::isValidYear((string) $this->xml->to_year) && StructuredData::isValidUrl((string) $this->xml->url); } return true; }
/** * constructor */ function wfSpecialGotoPageOld() { global $wgOut, $wgRequest, $wgUser; $error = ''; $titleList = ''; $addPersonFamily = false; $title = null; $namespace = $wgRequest->getVal('namespace'); $titleText = $wgRequest->getVal('pagetitle'); if ($namespace == 'person') { $addPersonFamily = true; $titleText = wrConstructName($wgRequest->getVal('personGiven'), $wgRequest->getVal('personSurname')); if ($titleText) { $title = Title::newFromText($titleText, NS_PERSON); } } else { if ($namespace == 'family') { $addPersonFamily = true; $husbandText = wrConstructName($wgRequest->getVal('husbandGiven'), $wgRequest->getVal('husbandSurname')); $wifeText = wrConstructName($wgRequest->getVal('wifeGiven'), $wgRequest->getVal('wifeSurname')); $titleText = ''; if ($husbandText && $wifeText) { $titleText = $husbandText . ' and ' . $wifeText; } else { if ($husbandText) { $titleText = $husbandText . ' and Unknown'; } else { if ($wifeText) { $titleText = 'Unknown and ' . $wifeText; } } } if ($titleText) { $title = Title::newFromText($titleText, NS_FAMILY); } } else { if ($titleText) { $title = Title::newFromText($titleText, $namespace); if (is_null($title)) { $error = wfmsg('invalidtitle'); } else { if ($wgRequest->getVal('add') && ($title->getNamespace() == NS_USER || $title->getNamespace() == NS_USER_TALK)) { // user must exist if we're adding a page for them $pos = strpos($title->getText(), '/'); if ($pos !== false) { $userName = substr($title->getText(), 0, $pos); } else { $userName = $title->getText(); } if (!User::isIP($userName) && User::idFromName($userName) == 0) { $error = 'User does not exist. Is the name spelled correctly?'; $title = null; } } } } } } if ($title) { if ($wgRequest->getVal('goto')) { if ($title->getNamespace() == NS_SPECIAL || $title->exists()) { $wgOut->redirect($title->getFullURL()); return; } else { $error = 'Title not found.'; $skin = $wgUser->getSkin(); $n = 0; $moreLink = false; $dbr =& wfGetDB(DB_SLAVE); $res = $dbr->select('page', array('page_title', 'page_namespace', 'page_is_redirect'), 'page_namespace=' . $title->getNamespace() . ' and page_title like "' . $title->getDBkey() . '%"', 'wfSpecialGotoPageOld', array('LIMIT' => 31, 'ORDER BY' => 'page_title')); while ($row = $dbr->fetchObject($res)) { if ($n == 30) { $moreLink = true; break; } if (!$titleList) { $titleList = '<h2>Titles starting with ' . $titleText . '</h2><table style="background: inherit;" border="0" width="100%">'; } $t = Title::makeTitle($row->page_namespace, $row->page_title); if ($t) { $link = ($row->page_is_redirect ? '<div class="allpagesredirect">' : '') . $skin->makeKnownLinkObj($t, htmlspecialchars($t->getPrefixedText())) . ($row->page_is_redirect ? '</div>' : ''); } else { $link = '[[' . htmlspecialchars($row->page_title) . ']]'; } if ($n % 3 == 0) { $titleList .= '<tr>'; } $titleList .= "<td>{$link}</td>"; $n++; if ($n % 3 == 0) { $titleList .= '</tr>'; } } $dbr->freeResult($res); if ($n % 3 != 0) { $titleList .= '</tr>'; } if ($titleList) { $titleList .= '</table>'; $error .= " All pages starting with {$titleText} are listed below."; } if ($moreLink) { $t = Title::makeTitle(NS_SPECIAL, 'Allpages'); $titleList .= '<p>More not shown (' . $skin->makeKnownLinkObj($t, 'show all', "from={$title->getText()}&namespace={$title->getNamespace()}") . ')</p>'; } } } else { if ($wgRequest->getVal('add')) { // PERSON and FAMILY pages must have a unique id if (($title->getNamespace() == NS_PERSON || $title->getNamespace() == NS_FAMILY) && !StructuredData::titleStringHasId($title->getText())) { // standardize name case and append a unique id $title = StructuredData::appendUniqueId(Title::newFromText((string) StructuredData::standardizeNameCase($title->getText()), $title->getNamespace())); } if ($title != null) { $wgOut->redirect($title->getFullURL('action=edit')); } return; } } } // set up page $wgOut->setPagetitle('Go to / Add page'); $wgOut->setArticleRelated(false); $wgOut->setRobotpolicy('noindex,nofollow'); if ($error) { $wgOut->addHTML("<p><font color=red>{$error}</font></p>"); } $wgOut->addHTML("<center>" . getGotoPageForm($namespace, $titleText) . "</center>"); if (!$addPersonFamily) { if ($titleList) { $wgOut->addHTML($titleList); } else { $wgOut->addWikiText("\n\n" . wfmsg('gotopageend')); } } }
public static function updateGedcomMatch($dbw, $treeId, $gedcomId, $key, $matchTitle, $merged, $gedcomUser) { $newTitle = $matchTitle == '#nomatch#' ? null : Title::newFromText($matchTitle); $oldTitle = null; // read old match_namespace and title $row = $dbw->selectRow('familytree_gedcom_data', array('fgd_match_namespace', 'fgd_match_title'), array('fgd_gedcom_id' => $gedcomId, 'fgd_gedcom_key' => $key)); if ($row && $row->fgd_match_namespace > 0) { $oldTitle = Title::makeTitle($row->fgd_match_namespace, $row->fgd_match_title); if ($oldTitle && ($oldTitle->getNamespace() == NS_PERSON || $oldTitle->getNamespace() == NS_FAMILY || $oldTitle->getNamespace() == NS_MYSOURCE) && (!$newTitle || $oldTitle->getPrefixedText() != $newTitle->getPrefixedText())) { // remove match title from tree if (!FamilyTreeUtil::removePage($dbw, $treeId, $oldTitle)) { return false; } // unwatch match title if no other trees contain it if (!$dbw->selectField('familytree_page', 'fp_tree_id', array('fp_namespace' => $row->fgd_match_namespace, 'fp_title' => $row->fgd_match_title, 'fp_user_id' => $gedcomUser->getID()))) { $article = new Article($oldTitle, 0); StructuredData::removeWatch($gedcomUser, $article); } } } if ($newTitle) { $matchTitle = $newTitle->getDBkey(); $matchNamespace = $newTitle->getNamespace(); $potentialMatchesAttr = ''; $potentialMatchesValue = ''; $potentialMatchesUpdate = ''; if (($newTitle->getNamespace() == NS_PERSON || $newTitle->getNamespace() == NS_FAMILY || $newTitle->getNamespace() == NS_MYSOURCE) && (!$oldTitle || $oldTitle->getPrefixedText() != $newTitle->getPrefixedText())) { // add match title to tree if (!FamilyTreeUtil::addPage($dbw, $gedcomUser, $treeId, $newTitle, 0, 0)) { return false; } // watch match title $article = new Article($newTitle, 0); StructuredData::addWatch($gedcomUser, $article); } } else { $matchTitle = ''; $matchNamespace = -1; $merged = 0; $potentialMatchesAttr = ', fgd_potential_matches'; // reset potential matches to what's in the gedcom $potentialMatchesValue = ", ''"; $potentialMatchesUpdate = ", fgd_potential_matches=''"; } $matchTitle = $dbw->addQuotes($matchTitle); $sql = "INSERT INTO familytree_gedcom_data (fgd_gedcom_id, fgd_gedcom_key, fgd_match_namespace, fgd_match_title, fgd_merged{$potentialMatchesAttr})" . " VALUES({$gedcomId}," . $dbw->addQuotes($key) . ",{$matchNamespace},{$matchTitle},{$merged}{$potentialMatchesValue})" . " ON DUPLICATE KEY UPDATE fgd_match_namespace={$matchNamespace}, fgd_match_title={$matchTitle}, fgd_merged={$merged}{$potentialMatchesUpdate}"; $dbw->query($sql); return $dbw->lastErrno() == 0; }
/** * Propagate move, delete, or undelete to other articles if necessary * * @param String $newTitleString null in case of delete; same as this title string in case of undelete * @param String $text text of article * @param bool $textChanged set to true if we change the text * @return bool true if success */ protected function propagateMoveDeleteUndelete($newTitleString, $newNs, &$text, &$textChanged) { global $wgESINHandler; $result = true; $newTitle = $newTitleString ? Title::newFromText($newTitleString, NS_FAMILY) : null; // if we're undeleting, add additional people from WLH, getting updated person data if ($this->titleString == $newTitleString) { $wlh = simplexml_load_string($this->getPageTextFromWLH(false)); // get text for all people // TODO is propagateEditData called after Undelete? if so, then we could get updated person attributes there $personText = $this->getPersonData($wlh->husband, $this->xml->husband, 'husband') . $this->getPersonData($wlh->wife, $this->xml->wife, 'wife') . $this->getPersonData($wlh->child, $this->xml->child, 'child') . $wgESINHandler->getImageData($wlh->image, $this->xml->image); // update text: replace old family information with new $text = preg_replace("\$<(husband|wife|child|image) [^>]*>\n\$", '', $text); $text = preg_replace('$</family>$', StructuredData::protectRegexReplace($personText . '</family>'), $text, 1); $this->xml = StructuredData::getXml($this->tagName, $text); $textChanged = true; } // get data to propagate $propagatedData = Family::getPropagatedData($this->xml); foreach ($propagatedData['husbands'] as $p) { $personTitle = Title::newFromText((string) $p, NS_PERSON); PropagationManager::addPropagatedAction($this->title, 'delspouse', $personTitle); if ($newTitle) { PropagationManager::addPropagatedAction($newTitle, 'addspouse', $personTitle); } // don't need to check propagated action before calling updatePerson, because propagateMoveDeleteUndelete is never part of a loop $result = $result && $this->updatePerson($personTitle, 'husband', 'spouse_of_family', $newTitleString, $text, $textChanged); } foreach ($propagatedData['wives'] as $p) { $personTitle = Title::newFromText((string) $p, NS_PERSON); PropagationManager::addPropagatedAction($this->title, 'delspouse', $personTitle); if ($newTitle) { PropagationManager::addPropagatedAction($newTitle, 'addspouse', $personTitle); } // don't need to check propagated action before calling updatePerson, because propagateMoveDeleteUndelete is never part of a loop $result = $result && $this->updatePerson($personTitle, 'wife', 'spouse_of_family', $newTitleString, $text, $textChanged); } foreach ($propagatedData['children'] as $p) { $personTitle = Title::newFromText((string) $p, NS_PERSON); PropagationManager::addPropagatedAction($this->title, 'delchild', $personTitle); if ($newTitle) { PropagationManager::addPropagatedAction($newTitle, 'addchild', $personTitle); } // don't need to check propagated action before calling updatePerson, because propagateMoveDeleteUndelete is never part of a loop $result = $result && $this->updatePerson($personTitle, 'child', 'child_of_family', $newTitleString, $text, $textChanged); } if (StructuredData::removeDuplicateLinks('husband|wife|child', $text)) { $textChanged = true; } $result = $result && $wgESINHandler->propagateSINMoveDeleteUndelete($this->title, 'family', $this->titleString, $newTitleString, $propagatedData, $text, $textChanged); if (!$result) { error_log("ERROR! Family move/delete/undelete not propagated: {$this->titleString} -> " . ($newTitleString ? $newTitleString : "[delete]") . "\n"); } return $result; }
/** * Generate the Microdata or RDFa semantics * * @param array $params The params used to setup the StructuredData library * * @return string */ protected function display($params) { $html = ''; $setType = $params['setType']; // Specialized fallbacks $sFallbacks = $params['fallbacks']['specialized']; // Global fallbacks $gFallbacks = $params['fallbacks']['global']; // Set the current Type if available if ($setType) { $this->handler->setType($setType); } // If no properties available and there is a 'setType', return and display the scope if ($setType && !$sFallbacks && !$gFallbacks) { return $this->handler->displayScope(); } // Get the current Type $currentType = $this->handler->getType(); // Check if there is an available 'specialized' fallback property for the current Type if ($sFallbacks && array_key_exists($currentType, $sFallbacks)) { $property = key($sFallbacks[$currentType]); $expectedType = $sFallbacks[$currentType][$property]; $html .= $this->handler->property($property)->display('inline'); // Check if an expected Type is available and it is valid if ($expectedType && in_array($expectedType, StructuredData::getExpectedTypes($currentType, $property))) { // Update the current Type $this->handler->setType($expectedType); // Display the scope $html .= ' ' . $this->handler->displayScope(); } return $html; } // Check if there is an available 'global' fallback property for the current Type if ($gFallbacks) { foreach ($gFallbacks as $property => $expectedType) { // Check if the property is available in the current Type if (StructuredData::isPropertyInType($currentType, $property)) { $html .= $this->handler->property($property)->display('inline'); // Check if an expected Type is available if ($expectedType && in_array($expectedType, StructuredData::getExpectedTypes($currentType, $property))) { // Update the current Type $this->handler->setType($expectedType); // Display the scope $html .= ' ' . $this->handler->displayScope(); } return $html; } } } return $html; }
/** * Return true if xml property is valid */ protected function validateData(&$textbox1) { if (!StructuredData::isRedirect($textbox1)) { return StructuredData::isValidUrl((string) $this->xml->url); } return true; }
/** * Displays the main upload form, optionally with a highlighted * error message up at the top. * * @param string $msg as HTML * @access private */ function mainUploadForm($msg = '') { global $wgOut, $wgUser; global $wgUseCopyrightUpload; // set up page $wgOut->setPagetitle('Import GEDCOM'); $wgOut->setArticleRelated(false); $wgOut->setRobotpolicy('noindex,nofollow'); if ('' != $msg) { $sub = 'Import Error'; $wgOut->addHTML("<h2>{$sub}</h2>\n" . "<span class='error'>{$msg}</span>\n"); } $wgOut->addScript(<<<END <script type='text/javascript'>/*<![CDATA[*/ function hideNewTreeName() { \tsel = document.getElementById('wrTreeName'); \ttreeName = sel.options[sel.selectedIndex].value; \$('span.wrNewTreeName').css('display',treeName == '[new]' ? 'inline' : 'none'); } /*]]>*/</script> END ); $sk = $wgUser->getSkin(); $country = $this->mDefaultCountry ? $this->mDefaultCountry : 'United States'; $defaultCountryControl = StructuredData::addSelectToHtml(0, 'wrDefaultCountry', GedcomImport::$DEFAULT_COUNTRIES, $country, '', false); $treeFound = false; $trees = FamilyTreeUtil::getFamilyTrees($wgUser->getName(), false); $treeList = '<select name="wrTreeName" id="wrTreeName" onchange="hideNewTreeName()">'; for ($i = 0; $i < count($trees); $i++) { $encTreeName = htmlspecialchars($trees[$i]['name']); if ($trees[$i]['name'] == $this->mTreeName) { $treeFound = true; $selected = ' selected="selected"'; } else { $selected = ''; } $treeList .= "<option value=\"{$encTreeName}\"{$selected}>{$encTreeName}</option>"; } if ($treeFound || strlen($this->mTreeName) == 0 && count($trees) > 0) { $selected = ''; $display = 'none'; $encNewTreeName = ''; } else { $selected = ' selected="selected"'; $display = 'inline'; $encNewTreeName = htmlspecialchars($this->mNewTreeName); } $treeList .= "<option value=\"[new]\"{$selected}><New tree></option>"; $treeList .= '</select>'; $sourcefilename = 'GEDCOM filename'; $importIntoTree = 'Import into tree'; $newTreeName = 'Tree name'; $importGedcom = 'Import GEDCOM'; $titleObj = Title::makeTitle(NS_SPECIAL, 'ImportGedcom'); $action = $titleObj->escapeLocalURL(); $wgOut->addHTML(<<<END <form id='import' method='post' enctype='multipart/form-data' action="{$action}"> <table border='0'> <tr> <td align='right'><label for='wrUploadFile'>{$sourcefilename}:</label></td> <td align='left'><input type='file' name='wrUploadFile' id='wrUploadFile' size='30' /></td> </tr> <tr> <td align="right"><label for="wrDefaultCountry">Default country:</label></td> <td align="left" style="font-size: 11px; line-height:2em">{$defaultCountryControl} if places in your GEDCOM don't have countries, this country will be assumed</td> </tr> <tr> <td align='right'><label for='wrTreeName'>{$importIntoTree}</label></td> <td align='left'>{$treeList} \t<span class='wrNewTreeName' style='display:{$display}'><label for='wrNewTreeName'>{$newTreeName}</label></span> <span class='wrNewTreeName' style='display:{$display}'><input type='text' name='wrNewTreeName' size='29' value="{$encNewTreeName}"/></span> <input type='submit' id='wrImport' name='wrImport' value="{$importGedcom}" /></td> </tr> </table> </form> END ); $wgOut->addWikiText(wfMsg('importgedcomtext')); }
/** * Return true if xml property is valid */ protected function validateData(&$textbox1) { $source = (string) $this->xml->source; return !$source || StructuredData::titleExists(NS_SOURCE, $source); }
public function getFormHtml() { global $wgUser; $target = htmlspecialchars($this->target); $givenname = htmlspecialchars($this->givenname); $surname = htmlspecialchars($this->surname); $place = htmlspecialchars($this->place); $birthdate = htmlspecialchars($this->birthdate); $birthplace = htmlspecialchars($this->birthplace); $deathdate = htmlspecialchars($this->deathdate); $deathplace = htmlspecialchars($this->deathplace); $fathergivenname = htmlspecialchars($this->fatherGivenname); $fathersurname = htmlspecialchars($this->fatherSurname); $mothergivenname = htmlspecialchars($this->motherGivenname); $mothersurname = htmlspecialchars($this->motherSurname); $spousegivenname = htmlspecialchars($this->spouseGivenname); $spousesurname = htmlspecialchars($this->spouseSurname); $husbandgivenname = htmlspecialchars($this->husbandGivenname); $husbandsurname = htmlspecialchars($this->husbandSurname); $wifegivenname = htmlspecialchars($this->wifeGivenname); $wifesurname = htmlspecialchars($this->wifeSurname); $marriagedate = htmlspecialchars($this->marriagedate); $marriageplace = htmlspecialchars($this->marriageplace); $placename = htmlspecialchars($this->placename); $locatedinplace = htmlspecialchars($this->locatedinplace); $title = htmlspecialchars($this->title); $author = htmlspecialchars($this->author); $sourcetitle = htmlspecialchars($this->sourceTitle); $keywords = htmlspecialchars($this->keywords); // generate form if ($wgUser->isLoggedIn()) { $watchSelectExtra = ''; } else { $watchSelectExtra = 'disabled'; } $watchSelect = StructuredData::addSelectToHtml(0, "watch", self::$WATCH_OPTIONS, $this->watch, $watchSelectExtra, false); $hiddenFields = ''; if ($target || $this->match) { if ($target) { $hiddenFields .= '<input type="hidden" name="target" value="' . $target . '"/>'; } else { $hiddenFields .= '<input type="hidden" name="match" value="true"/><input type="hidden" name="pagetitle" value="' . htmlspecialchars($this->pagetitle) . '"/>'; } $hiddenFields .= '<input id="ns" type="hidden" name="ns" value="' . htmlspecialchars($this->namespace) . '"/>'; $nsSelectField = 'dummy'; // disabled fields don't get passed back $nsSelectExtra = 'disabled'; } else { $nsSelectField = 'ns'; $nsSelectExtra = 'onChange="showSearchFields()"'; } $hiddenFields .= $this->addHiddenInput('gnd', $this->personGender); $hiddenFields .= $this->addHiddenInput('bt', $this->birthType); $hiddenFields .= $this->addHiddenInput('dt', $this->deathType); $hiddenFields .= $this->addHiddenInput('sty', $this->sourceType); $hiddenFields .= $this->addHiddenInput('pi', $this->placeIssued); $hiddenFields .= $this->addHiddenInput('pu', $this->publisher); $hiddenFields .= $this->addHiddenInput('ct', $this->childTitle); $hiddenFields .= $this->addHiddenInput('ht', $this->husbandTitle); $hiddenFields .= $this->addHiddenInput('wt', $this->wifeTitle); $hiddenFields .= $this->addHiddenInput('pf', $this->parentFamily); $hiddenFields .= $this->addHiddenInput('sf', $this->spouseFamily); $nsSelect = StructuredData::addSelectToHtml(0, $nsSelectField, self::$NAMESPACE_OPTIONS, $this->namespace, $nsSelectExtra, false); if ($this->ecp == 'p') { $this->sort = 'score'; } $sortSelect = StructuredData::addSelectToHtml(0, "sort", self::$SORT_OPTIONS, $this->sort, '', false); // TODO //$talkSpan = '<span id="talk_input"><input type="checkbox" name="talk"'.($this->talk ? ' checked' : '').'/>Include talk</span>'; $talkSpan = ''; $subChecked = $this->sub ? ' checked' : ''; $supChecked = $this->sup ? ' checked' : ''; $birthRangeSelect = StructuredData::addSelectToHtml(0, 'br', self::$DATE_RANGE_OPTIONS, $this->birthrange, '', false); $deathRangeSelect = StructuredData::addSelectToHtml(0, 'dr', self::$DATE_RANGE_OPTIONS, $this->deathrange, '', false); $marriageRangeSelect = StructuredData::addSelectToHtml(0, 'mr', self::$DATE_RANGE_OPTIONS, $this->marriagerange, '', false); $sourceSubjectSelect = StructuredData::addSelectToHtml(0, 'su', Source::$SOURCE_SUBJECT_OPTIONS, $this->sourceSubject); $sourceAvailabilitySelect = StructuredData::addSelectToHtml(0, 'sa', Source::$SOURCE_AVAILABILITY_OPTIONS, $this->sourceAvailability); $rowsSelector = StructuredData::addSelectToHtml(0, 'rows', self::$ROWS_OPTIONS, $this->rows, '', false); $ecpSelector = StructuredData::addSelectToHtml(0, 'ecp', self::$ECP_OPTIONS, $this->ecp, '', false); $heading = $this->target && $this->namespace != 'Image' ? '<h2 style="padding-bottom:4px">Review possible matches. Select a match or click Add Page</h2>' : ''; $condensedChecked = $this->condensedView ? ' checked="checked"' : ''; if ($this->target) { $relativeRows = ''; } else { $relativeRows = <<<END <tr id="father_row"> <td align=right>Father given: </td><td colspan=2><input id="input_fg" class="input_medium" type="text" name="fg" maxlength=50 value="{$fathergivenname}" onfocus="select()"/></td> <td align=right>Surname: </td><td colspan=2><input id="input_fs" class="input_wider" type="text" name="fs" maxlength=50 value="{$fathersurname}" onfocus="select()"/></td> </tr><tr id="mother_row"> <td align=right>Mother given: </td><td colspan=2><input id="input_mg" class="input_medium" type="text" name="mg" maxlength=50 value="{$mothergivenname}" onfocus="select()"/></td> <td align=right>Surname: </td><td colspan=2><input id="input_ms" class="input_wider" type="text" name="ms" maxlength=50 value="{$mothersurname}" onfocus="select()"/></td> </tr><tr id="spouse_row"> <td align=right>Spouse given: </td><td colspan=2><input id="input_sg" class="input_medium" type="text" name="sg" maxlength=50 value="{$spousegivenname}" onfocus="select()"/></td> <td align=right>Surname: </td><td colspan=2><input id="input_ss" class="input_wider" type="text" name="ss" maxlength=50 value="{$spousesurname}" onfocus="select()"/></td> </tr> END; } $result = <<<END {$heading} <form id="search_form" name="search" action="/wiki/Special:Search" method="get"> {$hiddenFields} <table id="searchform" class="searchform"><tr> <td colspan=6 align=right><span class="sort_label">Sort by</span>{$sortSelect}</td> </tr><tr> <td align=right>Namespace: </td><td>{$nsSelect}</td><td>{$talkSpan}</td> <td colspan=3 align=right>{$watchSelect}</td> </tr><tr id="author_row"> <td align=right>Author: </td><td colspan=5><input id="input_a" class="input_long" type="text" name="a" maxlength=100 value="{$author}" onfocus="select()"/></td> </tr><tr id="source_title_row"> <td align=right>Title: </td><td colspan=5><input id="input_st" class="input_long" type="text" name="st" maxlength=100 value="{$sourcetitle}" onfocus="select()"/></td> </tr><tr id="coverage_row"> <td align=right></td><td colspan=5>Covers:</td> </tr><tr id="name_row"> <td id="givenname_cell1" align=right>Given name: </td><td id="givenname_cell2" colspan=2><input id="input_g" class="input_medium" type="text" name="g" maxlength=50 value="{$givenname}" onfocus="select()"/></td> <td align=right>Surname: </td><td colspan=2><input id="input_s" class="input_wider" type="text" name="s" maxlength=50 value="{$surname}" onfocus="select()"/></td> </tr><tr id="place_row"> <td align=right>Place: </td><td colspan=5><input id="input_p" class="input_long place_input" type="text" name="p" maxlength=130 value="{$place}" onfocus="select()"/></td> </tr><tr id="source_place_row"> <td align=right></td><td colspan=5> Include sources for <input type="checkbox" name="sub"{$subChecked}/>subordinate places <input type="checkbox" name="sup"{$supChecked}/>superior places</td> </tr><tr id="birth_row"> <td align=right>Birth/Chr date: </td><td colspan=2><input id="input_bd" class="input_short" type="text" name="bd" size=14 maxlength=25 value="{$birthdate}" onfocus="select()"/> {$birthRangeSelect}</td> <td align=right>Place: </td><td colspan=2><input id="input_bp" class="input_wider place_input" type="text" name="bp" maxlength=130 value="{$birthplace}" onfocus="select()"/></td> </tr><tr id="death_row"> <td align=right>Death/Bur date: </td><td colspan=2><input id="input_dd" class="input_short" type="text" name="dd" size=14 maxlength=25 value="{$deathdate}" onfocus="select()"/> {$deathRangeSelect}</td> <td align=right>Place: </td><td colspan=2><input id="input_dp" class="input_wider place_input" type="text" name="dp" maxlength=130 value="{$deathplace}" onfocus="select()"/></td> </tr> {$relativeRows} <tr id="husband_row"> <td align=right>Husband given: </td><td colspan=2><input id="input_hg" class="input_medium" type="text" name="hg" maxlength=50 value="{$husbandgivenname}" onfocus="select()"/></td> <td align=right>Surname: </td><td colspan=2><input id="input_hs" class="input_wider" type="text" name="hs" maxlength=50 value="{$husbandsurname}" onfocus="select()"/></td> </tr><tr id="wife_row"> <td align=right>Wife given: </td><td colspan=2><input id="input_wg" class="input_medium" type="text" name="wg" maxlength=50 value="{$wifegivenname}" onfocus="select()"/></td> <td align=right>Surname: </td><td colspan=2><input id="input_ws" class="input_wider" type="text" name="ws" maxlength=50 value="{$wifesurname}" onfocus="select()"/></td> </tr><tr id="marriage_row"> <td align=right>Marriage date: </td><td colspan=2><input id="input_md" class="input_short" type="text" name="md" size=14 maxlength=25 value="{$marriagedate}" onfocus="select()"/> {$marriageRangeSelect}</td> <td align=right>Place: </td><td colspan=2><input id="input_mp" class="input_wider place_input" type="text" name="mp" maxlength=130 value="{$marriageplace}" onfocus="select()"/></td> </tr><tr id="placename_row"> <td align=right>Place name: </td><td colspan=2><input id="input_pn" class="input_medium" type="text" name="pn" maxlength=50 value="{$placename}" onfocus="select()"/></td> <td align=right>Located in: </td><td colspan=2><input id="input_li" class="input_wider place_input" type="text" name="li" maxlength=130 value="{$locatedinplace}" onfocus="select()"/></td> </tr><tr id="subject_row"> <td align=right>Subject: </td><td colspan=2>{$sourceSubjectSelect}</td> <td align=right>Availability: </td><td colspan=2>{$sourceAvailabilitySelect}</td> </tr><tr id="title_row"> <td align=right>Page title: </td><td colspan=5><input id="input_t" class="input_long" type="text" name="t" maxlength=100 value="{$title}" onfocus="select()"/></td> </tr><tr> <td align=right>Keywords: </td><td colspan=5><input id="input_k" class="input_long" type="text" name="k" maxlength=100 value="{$keywords}" onfocus="select()"/></td> </tr><tr> <td colspan=2>{$rowsSelector} results per page <input type="checkbox" name="cv"{$condensedChecked}>condensed</td><td align="right" colspan=4>{$ecpSelector} <input type="submit" value="Search"/></td> </tr></table></form> END; return $result; }
/** * Return HTML for displaying search results * @return string HTML */ public function getCompareResults() { global $wgUser; $this->setMergeTargets(); list($compareData, $compareChildren, $maxChildren) = $this->readCompareData(); $dataLabels = $this->getDataLabels(); list($compareClass, $husbandScores, $wifeScores, $totalScores) = $this->scoreCompareData($dataLabels, $compareData); $output = ''; $semiProtected = false; $isLoggedIn = $wgUser->isLoggedIn(); if (!$isLoggedIn) { $output .= '<p><font color=red>You need to sign in to match and merge pages</font></p>'; } $gedcomExtra = $this->gedcomDataString ? '?gedcomtab=' . htmlspecialchars($this->gedcomTab) . '&gedcomkey=' . htmlspecialchars($this->gedcomKey) : ''; $output .= "<form id=\"compare\" name=\"compare\" action=\"/wiki/Special:Merge{$gedcomExtra}\" method=\"post\">" . "<input type=\"hidden\" id=\"ns\" name=\"ns\" value=\"{$this->namespace}\">" . "<input type=\"hidden\" id=\"maxpages\" name=\"maxpages\" value=\"" . count($this->compareTitles) . "\">" . ($this->namespace == 'Family' ? "<input id=\"maxchildren\" type=\"hidden\" name=\"maxchildren\" value=\"{$maxChildren}\">" : '') . '<table border="0" cellspacing="0" cellpadding="4">'; foreach ($dataLabels as $label) { $labelClass = CompareForm::getLabelClass($label); if ($labelClass == self::$COMPARE_ULC_CLASS) { $output .= CompareForm::insertEmptyRow(count($this->compareTitles) + 1); } $found = !in_array($label, self::$OPTIONAL_LABELS); if (!$found) { foreach ($this->compareTitles as $t) { if (is_array(@$compareData[$t][$label]) && count($compareData[$t][$label]) > 0) { $found = true; break; } } } if ($found) { $output .= "<tr><td class=\"{$labelClass}\">" . CompareForm::formatLabel($label) . "</td>"; // show target left if gedcom; right otherwise $i = $this->gedcomDataString ? 0 : count($this->compareTitles) - 1; while ($this->gedcomDataString && $i < count($this->compareTitles) || !$this->gedcomDataString && $i >= 0) { $t = $this->compareTitles[$i]; $class = $compareClass[$label][$i]; $output .= "<td class=\"{$class}\">"; $first = true; if (is_array(@$compareData[$t][$label])) { foreach ($compareData[$t][$label] as $value) { if (!$first) { $output .= '<br>'; } $output .= CompareForm::formatValue($label, $value); $first = false; } } if ($first) { $output .= ' '; } if ($class == self::$COMPARE_PAGE_CLASS) { $titlesCnt = count(@$compareData[$t][$label]); $baseTitlesCnt = count(@$compareData[$this->compareTitles[0]][$label]); if ($titlesCnt > 0) { $value = htmlspecialchars($compareData[$t][$label][0]); if ($label == 'husbandTitle') { $relative = 'husband'; $relativeAbbrev = 'h'; $score = $husbandScores[$i]; } else { if ($label == 'wifeTitle') { $relative = 'wife'; $relativeAbbrev = 'w'; $score = $wifeScores[$i]; } else { $relative = ''; $relativeAbbrev = ''; $score = 0; } } if (!$compareData[$t]['Exists']) { // base person/family not found if (!$relative) { $output .= '<br>Not found'; } } else { if ($compareData[$t]['Redirect']) { // base person/family has been merged if (!$relative) { $output .= '<br>Already merged'; } } else { if ($compareData[$t][$relative . 'Redirect']) { // husband/wife has been merged $output .= '<br>Already merged'; } else { if ($i == 0 && $this->gedcomDataString) { if (@$compareData[$t][$relative . 'GedcomMatchTitle']) { $skin =& $wgUser->getSkin(); $gedcomMatchTitle = $compareData[$t][$relative . 'GedcomMatchTitle']; $temp = Title::newFromText($gedcomMatchTitle, StructuredData::endsWith($label, 'familyTitle', true) ? NS_FAMILY : NS_PERSON); $title = $skin->makeLinkObj($temp, htmlspecialchars($gedcomMatchTitle)); $output .= "<br>Matched with {$title}"; } $output .= "<input type=\"hidden\" id=\"m{$relativeAbbrev}_{$i}\" name=\"m{$relativeAbbrev}_{$i}\" value=\"{$value}\">"; } else { if ($titlesCnt == 1 && $baseTitlesCnt <= 1) { // if ($i == 0 || $baseTitlesCnt == 0 || $compareData[$this->compareTitles[0]][$label][0] != $compareData[$t][$label][0]) { // don't allow merge if same title if ($i == 0) { $extra = " checked"; } else { if ($relative) { // always check spouses $extra = 'disabled checked'; //if ($score > self::$SPOUSE_MATCH_THRESHOLD) $extra .= ' checked'; } else { $extra = ''; } } if ($this->namespace == 'Family' && !$relative) { $extra .= " onClick=\"compareClick({$i})\""; } $output .= "<br><input id=\"m{$relativeAbbrev}_{$i}\" type=\"checkbox\" name=\"m{$relativeAbbrev}_{$i}\" value=\"{$value}\" {$extra}> Match"; // } } else { $output .= "<br>Multiple spouses - merge after merging family"; } } } } } $nomergeTitles = $this->getNomergeTitleMatches($compareData, $t, -1, $relative, '<br>'); if ($nomergeTitles) { $output .= '<br><b>Do not merge with</b><br>' . $nomergeTitles; } if ((!$this->gedcomDataString || $i > 0) && !$compareData[$t][$relative . 'Updatable']) { $output .= "<br><font color=\"red\">Semi-protected</font> (see below)"; $semiProtected = true; } } } $output .= '</td>'; $i += $this->gedcomDataString ? 1 : -1; } $output .= '</tr>'; } } if ($this->namespace == 'Family') { for ($c = 0; $c < $maxChildren; $c++) { foreach (CompareForm::$CHILD_COMPARE_LABELS as $label) { $labelClass = CompareForm::getLabelClass($label); if ($labelClass == self::$COMPARE_ULC_CLASS) { $output .= CompareForm::insertEmptyRow(count($this->compareTitles) + 1); } $found = !in_array($label, self::$OPTIONAL_LABELS); if (!$found) { foreach ($this->compareTitles as $t) { if (is_array(@$compareChildren[$t][$c][$label]) && count($compareChildren[$t][$c][$label]) > 0) { $found = true; break; } } } if ($found) { $output .= "<tr><td class=\"{$labelClass}\">" . CompareForm::formatLabel($label, $c + 1) . "</td>"; $baseStdValues =& CompareForm::standardizeValues($label, @$compareChildren[$this->compareTitles[0]][$c][$label]); $i = $this->gedcomDataString ? 0 : count($this->compareTitles) - 1; while ($this->gedcomDataString && $i < count($this->compareTitles) || !$this->gedcomDataString && $i >= 0) { $t = $this->compareTitles[$i]; if ($i == 0) { $stdValues = $baseStdValues; } else { $stdValues =& CompareForm::standardizeValues($label, @$compareChildren[$t][$c][$label]); } list($score, $class) = CompareForm::getCompareScoreClass($i == 0, $label, $baseStdValues, $stdValues); $output .= "<td class=\"{$class}\">"; $children =& $compareChildren[$t]; $first = true; if (count($children) > $c) { if (is_array(@$children[$c][$label])) { foreach ($children[$c][$label] as $value) { if (!$first) { $output .= '<br>'; } $output .= CompareForm::formatValue($label, $value); $first = false; } } } if ($first) { $output .= ' '; } if ($class == self::$COMPARE_PAGE_CLASS) { if (count(@$compareChildren[$t][$c][$label]) == 1) { $value = htmlspecialchars($compareChildren[$t][$c][$label][0]); $output .= "<input type=\"hidden\" id=\"mc_{$i}_{$c}\" name=\"mc_{$i}_{$c}\" value=\"{$value}\">"; if ($compareData[$t]['Redirect']) { // family has already been merged } else { if ($compareChildren[$t][$c]['childRedirect']) { // child has already been merged $output .= '<br>Already merged'; } else { if ($i == 0 && $this->gedcomDataString) { if (@$compareChildren[$t][$c]['childGedcomMatchTitle']) { $skin =& $wgUser->getSkin(); $gedcomMatchTitle = $compareChildren[$t][$c]['childGedcomMatchTitle']; $temp = Title::newFromText($gedcomMatchTitle, StructuredData::endsWith($label, 'familyTitle', true) ? NS_FAMILY : NS_PERSON); $title = $skin->makeLinkObj($temp, htmlspecialchars($gedcomMatchTitle)); $output .= "<br>Matched with {$title}"; } $c1 = $c + 1; $output .= "<input type=\"hidden\" id=\"mcr_0_{$c}\" name=\"mcr_0_{$c}\" value=\"{$c1}\">"; } else { // else if (@$compareChildren[$this->compareTitles[0]][$c][$label][0] != $compareChildren[$t][$c][$label][0]) { // don't allow merge if same title // $mergeChild = (count(@$compareChildren[$this->compareTitles[0]][$c][$label]) == 1 ? $c+1 : 0); $mergeChild = $c + 1; $extra = $i == 0 ? '' : 'disabled'; $mergeChildSelectOptions = $this->getMergeChildSelectOptions($c, $maxChildren); $output .= '<br>' . StructuredData::addSelectToHtml(0, "mcr_{$i}_{$c}", $mergeChildSelectOptions, $mergeChild, $extra, false); } } } $nomergeTitles = $this->getNomergeTitleMatches($compareChildren, $t, $c, 'child', '<br>'); if ($nomergeTitles) { $output .= '<br><b>Do not merge with</b><br>' . $nomergeTitles; } if ((!$this->gedcomDataString || $i > 0) && !$compareChildren[$t][$c]['childUpdatable']) { $output .= "<br><font color=\"red\">Semi-protected</font> (see below)"; $semiProtected = true; } } } $output .= '</td>'; $i += $this->gedcomDataString ? 1 : -1; } $output .= '</tr>'; } } } } if ($this->gedcomDataString) { $mergeLabel = 'Prepare to update'; $mergeFunction = 'doGedcomPrepareToMerge()'; $notMatchFunction = 'doGedcomNotMatch()'; $notMatchTitle = 'GEDCOM family does not match any of the families shown'; } else { $mergeLabel = 'Prepare to merge'; $mergeFunction = 'doPrepareToMerge()'; $notMatchFunction = 'doNotMatch()'; $notMatchTitle = 'Notify others not to merge the selected ' . ($this->namespace == 'Family' ? 'families' : 'people'); } $mergeTitle = 'Prepare to combine the selected ' . ($this->namespace == 'Family' ? 'families' : 'people'); $output .= '<tr><td align=right colspan="' . (count($this->compareTitles) + 1) . '"><input type="hidden" name="formAction">' . ($this->gedcomDataString ? '<input type="button" title="Match people in your GEDCOM to people in the selected family" value="Match" onClick="doGedcomMatch()"/> ' : '') . ($this->gedcomDataString ? '' : "<input type=\"button\" title=\"{$mergeTitle}\" value=\"{$mergeLabel}\" onClick=\"{$mergeFunction}\"/> ") . "<input type=\"button\" title=\"{$notMatchTitle}\" value=\"Not a match\" onClick=\"{$notMatchFunction}\"/>"; '</td></tr></table></form>'; if ($semiProtected) { $output .= CompareForm::getSemiprotectedMessage(CompareForm::isTrustedMerger($wgUser, $this->gedcomDataString)); } return $output; }
/** * Show a namespace selection form for filtering * * @return string */ function getPageHeader() { $thisTitle = Title::makeTitle(NS_SPECIAL, $this->getName()); $form = wfOpenElement('form', array('method' => 'get', 'action' => $thisTitle->getLocalUrl())); $form .= wfElement('label', array('for' => 'status'), 'Status') . ' '; $form .= StructuredData::addSelectToHtml(0, 'status', self::$STATUS_OPTIONS, $this->status, '', false); # Preserve the offset and limit $form .= wfElement('input', array('type' => 'hidden', 'name' => 'offset', 'value' => $this->offset)); $form .= wfElement('input', array('type' => 'hidden', 'name' => 'limit', 'value' => $this->limit)); $form .= wfElement('input', array('type' => 'submit', 'name' => 'submit', 'id' => 'submit', 'value' => wfMsg('allpagessubmit'))); $form .= wfCloseElement('form'); return $form; }