示例#1
0
 private function getPersonData($wlhPeople, $thisPeople, $tag)
 {
     $people = array();
     foreach ($wlhPeople as $p) {
         $people[] = (string) $p['title'];
     }
     foreach ($thisPeople as $p) {
         $personTitle = (string) $p['title'];
         $t = Title::newFromText($personTitle, NS_PERSON);
         $t = StructuredData::getRedirectToTitle($t, true);
         $personTitle = $t->getText();
         if (!in_array($personTitle, $people)) {
             $people[] = $personTitle;
         }
     }
     $peopleText = '';
     foreach ($people as $p) {
         $peopleText .= Family::formatFamilyMemberElement($tag, $p);
     }
     return $peopleText;
 }
示例#2
0
 private function getSourceCitationText($sourceCitation)
 {
     $citation = '';
     $recordName = (string) $sourceCitation['record_name'];
     $citation .= $recordName;
     $title = (string) $sourceCitation['title'];
     $titleLower = mb_strtolower($title);
     if ($recordName && $title) {
         $citation = StructuredData::chomp($citation, ',') . ', in ';
     }
     $srcTitle = '';
     $altTitle = '';
     if (mb_strpos($titleLower, 'source:') === 0 || mb_strpos($titleLower, 'mysource:') === 0) {
         $fields = explode('|', $title);
         if (count($fields) > 1) {
             $altTitle = $fields[1];
         }
         $t = Title::newFromText($fields[0]);
         if ($t) {
             $srcTitle = StructuredData::getRedirectToTitle($t);
         }
     }
     if ($srcTitle) {
         if ($altTitle) {
             $citation .= "[[" . $srcTitle->getPrefixedText() . "|{$altTitle}]]";
         } else {
             if ($srcTitle->getNamespace() == NS_SOURCE) {
                 $source = new Source($srcTitle->getText());
             } else {
                 $source = new MySource($srcTitle->getText());
             }
             $source->loadPage();
             $citation .= $source->getCitationText(true);
         }
     } else {
         $citation .= $title;
     }
     $page = (string) $sourceCitation['page'];
     if ($page) {
         $citation = StructuredData::chomp($citation, ',') . ", {$page}";
     }
     $date = (string) $sourceCitation['date'];
     if ($date) {
         $citation = StructuredData::chomp($citation, ',') . ", {$date}";
     }
     $quality = (string) $sourceCitation['quality'];
     if (strlen($quality) > 0) {
         $qualName = array_search($quality, self::$QUALITY_OPTIONS);
         if (!$qualName && @self::$QUALITY_OPTIONS[$quality]) {
             $qualName = $quality;
         }
         // allow old alpha form
         if ($qualName) {
             $citation = StructuredData::chomp($citation, ',') . ", {$qualName} quality";
         }
     }
     return $citation;
 }
示例#3
0
function wfGetTreeData($rsargs = null)
{
    global $wgAjaxCachePolicy, $wgRequest;
    $callback = $wgRequest->getVal('callback');
    $orn = $wgRequest->getVal('orn');
    $titleText = $wgRequest->getVal('id');
    $setRoot = $wgRequest->getBool('setRoot');
    $numDescLevels = $wgRequest->getVal('descLevels');
    if ($numDescLevels > 10) {
        $numDescLevels = 10;
    }
    $numAncLevels = $wgRequest->getVal('ancLevels');
    if ($numAncLevels > 20) {
        $numAncLevels = 20;
    }
    // set cache policy
    $wgAjaxCachePolicy->setPolicy(0);
    // set content type
    $wgAjaxCachePolicy->setContentType($callback ? 'application/javascript' : 'application/json');
    $data = null;
    $treeData = new TreeData();
    if ($titleText) {
        $title = Title::newFromText($titleText);
        if ($title) {
            if ($setRoot) {
                // we can get a person initially and when someone sets a new root
                if ($orn == 'left') {
                    $numDescLevels = 0;
                    if (!$numAncLevels) {
                        $numAncLevels = $title->getNamespace() == NS_PERSON ? 7 : 6;
                    }
                } else {
                    if (!$numDescLevels) {
                        $numDescLevels = $title->getNamespace() == NS_PERSON ? 1 : 2;
                    }
                    $numAncLevels = 0;
                }
            } else {
                if ($orn == 'left') {
                    $numDescLevels = 0;
                    if (!$numAncLevels) {
                        $numAncLevels = 2;
                    }
                } else {
                    if ($orn == 'right') {
                        if (!$numDescLevels) {
                            $numDescLevels = 2;
                        }
                        $numAncLevels = 0;
                    } else {
                        // make sure we have the final redirect
                        $title = StructuredData::getRedirectToTitle($title);
                        $orn = 'center';
                        if ($title->getNamespace() == NS_PERSON) {
                            if (!$numDescLevels) {
                                $numDescLevels = 1;
                            }
                            if (!$numAncLevels) {
                                $numAncLevels = 7;
                            }
                        } else {
                            if (!$numDescLevels) {
                                $numDescLevels = 2;
                            }
                            if (!$numAncLevels) {
                                $numAncLevels = 6;
                            }
                        }
                    }
                }
            }
            if ($title->getNamespace() == NS_PERSON) {
                $data = $treeData->getPersonData($title->getText(), $orn, $numDescLevels, $numAncLevels);
            } else {
                if ($title->getNamespace() == NS_FAMILY) {
                    $data = $treeData->getFamilyData($title->getText(), $orn, $numDescLevels, $numAncLevels);
                }
            }
        }
    }
    if (!$data) {
        $data = array('error' => 'invalid title');
    }
    $json = StructuredData::json_encode($data);
    if ($callback) {
        $json = $callback . '(' . $json . ');';
    }
    return $json;
}
示例#4
0
 /**
  * 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 '';
 }
示例#5
0
 private function getFamilyData($wlhFamilies, $thisFamilies, $tag)
 {
     $families = array();
     foreach ($wlhFamilies as $f) {
         $families[] = (string) $f['title'];
     }
     foreach ($thisFamilies as $f) {
         $familyTitle = (string) $f['title'];
         $t = Title::newFromText($familyTitle, NS_FAMILY);
         $t = StructuredData::getRedirectToTitle($t, true);
         $familyTitle = $t->getText();
         if (!in_array($familyTitle, $families)) {
             $families[] = $familyTitle;
         }
     }
     $familyText = '';
     foreach ($families as $f) {
         $familyText .= $this->formatFamilyElement($tag, $f);
     }
     return $familyText;
 }
示例#6
0
 public static function addCategories($surnames, $places, $addPlaceCategories = true, $titleString = '', $ns = NS_MAIN, $displayCats = false)
 {
     global $wrStdSurnames, $wrStdPlaces, $wgParser;
     // TODO figure out how to not disable caching
     // disable caching because we're passing wrStdSurnames and wrStdPlaces as globals
     $wgParser->disableCache();
     $result = '';
     $titleString = mb_strtolower($titleString);
     $wrStdSurnames = array();
     $wrStdPlaces = array();
     $hlPlaces = array();
     // standardize names and make them unique
     foreach ($surnames as $surname) {
         $s = (string) $surname;
         if ($s) {
             // add an entry for the entire surname as well as separate entries for each piece
             $wrStdSurnames[] = StructuredData::standardizeNameCase($s);
             $surnamePieces = StructuredData::parseSurnamePieces($s);
             foreach ($surnamePieces as $surnamePiece) {
                 $wrStdSurnames[] = StructuredData::standardizeNameCase($surnamePiece);
             }
         }
     }
     $wrStdSurnames = array_unique($wrStdSurnames);
     // standardize places and make them unique
     foreach ($places as $place) {
         $p = (string) $place;
         if ($p) {
             // if you change the transformation for titleText, change it also in UserPage.formatResearchLinks
             $fields = explode('|', $p);
             $titleText = trim($fields[0]);
             $t = Title::newFromText($titleText, NS_PLACE);
             if ($t) {
                 $t = StructuredData::getRedirectToTitle($t);
                 $titleText = $t->getText();
             }
             $wrStdPlaces[] = $titleText;
             $fields = explode(',', $titleText);
             $hlPlace = trim($fields[count($fields) - 1]);
             if (count($fields) > 1 && strcasecmp($hlPlace, 'united states') == 0) {
                 $hlPlace = trim($fields[count($fields) - 2]);
             }
             $hlPlaces[] = $hlPlace;
         }
     }
     $wrStdPlaces = array_unique($wrStdPlaces);
     $hlPlaces = array_unique($hlPlaces);
     // write out categories
     $colon = $displayCats ? ':' : '';
     //	   foreach ($stdSurnames as $surname) {
     //	      if ($result && $displayCats) {
     //	         $result .= ', ';
     //	      }
     //		   $result .= "[[{$colon}Category:$surname surname" . ($displayCats ? "|$surname surname" : '') ."]]";
     //		}
     if ($addPlaceCategories) {
         foreach ($wrStdPlaces as $place) {
             if ($result && $displayCats) {
                 $result .= ', ';
             }
             $result .= "[[{$colon}Category:{$place}" . ($displayCats ? "|{$place}" : '') . "]]";
         }
     }
     //		foreach ($hlPlaces as $place) {
     //		   foreach ($stdSurnames as $surname) {
     //		      $catName = "$surname in $place";
     //		      if (!$displayCats && $titleString && $ns == NS_MAIN && mb_strtolower($catName) == $titleString) { // main Surname in Place article
     //		         $catName .= "|*";
     //		      }
     //   	      if ($result && $displayCats) {
     //   	         $result .= ', ';
     //   	      }
     //		      $result .= "[[{$colon}Category:$catName" . ($displayCats ? "|$catName" : '') ."]]";
     //		   }
     //		}
     return $result;
 }
示例#7
0
<?php

require_once "commandLine.inc";
require_once "{$IP}/extensions/structuredNamespaces/StructuredData.php";
require_once "{$IP}/extensions/familytree/FamilyTreePropagator.php";
require_once "{$IP}/includes/Title.php";
$db =& wfGetDB(DB_MASTER);
$rows = $db->query("select page_namespace, page_title from page where page_is_redirect > 0 and (page_namespace = 108 or page_namespace = 110)");
while ($row = $db->fetchObject($rows)) {
    $title = Title::makeTitle($row->page_namespace, $row->page_title);
    $newTitle = StructuredData::getRedirectToTitle($title);
    if ($title->getPrefixedText() != $newTitle->getPrefixedText()) {
        //		print "title=" . $title->getPrefixedText() . " newTitle=" . $newTitle->getPrefixedText() . "\n";
        // from wrArticleSave
        WatchedItem::duplicateEntries($title, $newTitle);
    }
}
$db->freeResult($rows);
示例#8
0
 public function propagateEdit($article, $request, &$text)
 {
     global $wgUser, $wgArticle;
     if ($this->needsPropagation()) {
         //wfDebug("propagateEdit {$article->getTitle()->getNamespace()} {$article->getTitle()->getDBkey()} {$article->mRevIdEdited}/{$article->getRevIdFetched()}\n");
         //wfDebug(" -> {$wgArticle->getTitle()->getPrefixedText()}\n");
         $this->begin();
         $res = $this->propagateEditMoveRollback($article->mRevIdEdited, $this->title->getNamespace(), $this->title->getDBkey());
         if ($res && ($wgArticle->getTitle()->getPrefixedText() == $article->getTitle()->getPrefixedText() || $wgArticle->getTitle()->getNamespace() == NS_SPECIAL && $wgArticle->getTitle()->getText() == 'Merge')) {
             // do this also for merges
             $newTitle = Title::newFromRedirect($text);
             // can't use $article->content or SD:getRedirectToTitle because they return the wrong results
             //wfDebug("propagateEdit title=".$this->title->getPrefixedText()." newTitle=" . ($newTitle == null ? '' : $newTitle->getPrefixedText()) . "\n");
             if ($newTitle != null && $newTitle->getPrefixedText() != $this->title->getPrefixedText()) {
                 // if this article is a redirect, add the new page to the users' tree(s)
                 $newTitle = StructuredData::getRedirectToTitle($newTitle, true);
                 // get final redirect; unreliable on the current title for some reason
                 $res = $this->handleRedirect($newTitle);
             }
         }
         // only update trees for the article being edited (no propagation but allow image uploads) and if it's a primary namespace
         if ($res && FamilyTreeUtil::isTreePage($article->getTitle()->getNamespace(), $article->getTitle()->getDBkey()) && ($wgArticle->getTitle()->getNamespace() == NS_SPECIAL && $wgArticle->getTitle()->getText() == 'Upload' || $wgArticle->getTitle()->getPrefixedText() == $article->getTitle()->getPrefixedText())) {
             $res = $this->updateTrees($wgUser, $article->getTitle(), $article->mRevIdEdited, $request);
         }
         //wfDebug("propagateEdit result $res\n");
         $this->end($res);
     }
 }
示例#9
0
文件: Place.php 项目: k-hasan-19/wiki
 /**
  * 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 we never change the text, so this is never set to true
  * @return bool true if success
  */
 protected function propagateMoveDeleteUndelete($newTitleString, $newNs, &$text, &$textChanged)
 {
     $result = true;
     // move: maintain place abbrevs and add place redirect job
     if ($newTitleString && $newTitleString != $this->titleString) {
         Place::placeAbbrevsDelete($this->titleString);
         Place::placeAbbrevsDelete($newTitleString);
         Place::placeAbbrevsAdd($newTitleString, $this->xml);
         // edit wlh pages to point to the target title
         $newTitle = Title::newFromText($newTitleString, NS_PLACE);
         $job = new PlaceRedirectJob(array('old_title' => $this->titleString, 'new_title' => $newTitle->getText()));
         $job->insert();
     } else {
         if (!$newTitleString) {
             Place::placeAbbrevsDelete($this->titleString);
         }
     }
     // determine parents and type and lat and lng
     list($alsoLocatedIn, $type, $lat, $lng, $fromYear, $toYear) = Place::getPropagatedData($this->xml);
     // get new name pieces
     $newName = Place::getPrefNameLocatedIn($newTitleString);
     // follow redirects
     $t = (string) $this->locatedIn ? Title::newFromText((string) $this->locatedIn, NS_PLACE) : null;
     if ($t) {
         $t = StructuredData::getRedirectToTitle($t);
     }
     $oldLocatedIn = $t ? $t->getText() : (string) $this->locatedIn;
     $t = $newName[1] ? Title::newFromText($newName[1], NS_PLACE) : null;
     if ($t) {
         $t = StructuredData::getRedirectToTitle($t);
     }
     $newLocatedIn = $t ? $t->getText() : $newName[1];
     foreach ($alsoLocatedIn as $ali) {
         $t = $ali['place'] ? Title::newFromText($ali['place'], NS_PLACE) : null;
         if ($t) {
             $t = StructuredData::getRedirectToTitle($t);
         }
         if ($t) {
             $ali['place'] = $t->getText();
         }
     }
     // if current located-in place is not also an also-located-in place
     if (StructuredData::mapArraySearch($oldLocatedIn, $alsoLocatedIn, 'place') === false) {
         if ($oldLocatedIn == $newLocatedIn) {
             // update title in located-in place
             $article = StructuredData::getArticle(Title::newFromText($oldLocatedIn, NS_PLACE), true);
             if ($article) {
                 $content =& $article->fetchContent();
                 $updatedContent =& $this->updateContainedPlace($newTitleString, $type, $lat, $lng, $fromYear, $toYear, $content);
                 if ($updatedContent) {
                     $updateResult = $article->doEdit($updatedContent, self::PROPAGATE_MESSAGE . ' [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS);
                     $result = $result && $updateResult;
                 }
             }
         } else {
             // remove from current parent
             $parentArticle = StructuredData::getArticle(Title::newFromText($oldLocatedIn, 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 parent if necessary
     if ($oldLocatedIn != $newLocatedIn && StructuredData::mapArraySearch($newLocatedIn, $alsoLocatedIn, 'place') === false) {
         $article = StructuredData::getArticle(Title::newFromText($newLocatedIn, NS_PLACE), true);
         if ($article) {
             $content =& $article->fetchContent();
             $updatedContent =& $this->updateContainedPlace($newTitleString, $type, $lat, $lng, $fromYear, $toYear, $content);
             if ($updatedContent) {
                 $updateResult = $article->doEdit($updatedContent, self::PROPAGATE_MESSAGE . ' [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS);
                 $result = $result && $updateResult;
             }
         }
     }
     // update title in also-located-in places
     foreach ($alsoLocatedIn as $pli) {
         $article = StructuredData::getArticle(Title::newFromText((string) $pli['place'], NS_PLACE), true);
         if ($article) {
             $content =& $article->fetchContent();
             $updatedContent =& $this->updateContainedPlace($newTitleString, $type, $lat, $lng, (string) $pli['from_year'], (string) $pli['to_year'], $content);
             if ($updatedContent) {
                 $updateResult = $article->doEdit($updatedContent, self::PROPAGATE_MESSAGE . ' [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS);
                 $result = $result && $updateResult;
             }
         }
     }
     if (!$result) {
         error_log("ERROR! Place move/delete/undelete not propagated: {$this->titleString} -> " . ($newTitleString ? $newTitleString : "[delete]") . "\n");
     }
     return $result;
 }
示例#10
0
 private function formatPageElement($tag, $titleString, $ns)
 {
     $title = Title::newFromText($titleString, $ns);
     if (!$title) {
         return '';
     }
     $title = StructuredData::getRedirectToTitle($title);
     // ok to read from slave here; mistakes will get corrected in propagate
     if ($ns == NS_PERSON) {
         if (isset($this->prevPeople[$title->getText()])) {
             $page = $this->prevPeople[$title->getText()];
         } else {
             $page = Family::loadFamilyMember($title->getText());
         }
         $attrs = self::$PERSON_ATTRS;
     } else {
         // NS_FAMILY
         if (isset($this->prevFamilies[$title->getText()])) {
             $page = $this->prevFamilies[$title->getText()];
         } else {
             $page = array();
         }
         $attrs = self::$FAMILY_ATTRS;
     }
     $result = "<{$tag} title=\"" . StructuredData::escapeXml($title->getText()) . '"';
     foreach ($attrs as $attr) {
         if (isset($page[$attr])) {
             $attrValue = trim($page[$attr]);
             if (strlen($attrValue) > 0) {
                 $result .= " {$attr}=\"" . StructuredData::escapeXml($attrValue) . '"';
             }
         }
     }
     $result .= "/>\n";
     return $result;
 }
示例#11
0
文件: Hooks.php 项目: k-hasan-19/wiki
function wrArticleSave(&$article, &$user, $text)
{
    $newTitle = Title::newFromRedirect($text);
    // can't use $article->content or SD:getRedirectToTitle because they return the wrong results
    if ($newTitle != null) {
        // if this article is a redirect
        $newTitle = StructuredData::getRedirectToTitle($newTitle, true);
        // get final redirect; unreliable on the article title for some reason
        $newRevision = StructuredData::getRevision($newTitle, false, true);
        $newText = $newRevision ? $newRevision->getText() : '';
        $summary = StructuredData::getWatchlistSummary($newTitle, $newText);
        WatchedItem::duplicateEntries($article->getTitle(), $newTitle, $summary);
        StructuredData::purgeTitle($newTitle, +1);
        StructuredData::requestIndex($newTitle);
        // remove watchers from redirected titles
        StructuredData::removeAllWatchers($article->getTitle());
    }
    return true;
}
示例#12
0
/**
 * Return whether the specified page titles have been redirected
 *
 * @param unknown_type $args title|title|title,... (up to IAF_MAX_COUNT_CONTENTS)
 * @return IAF_SUCCESS, IAF_INVALID_ARG
 */
function wfGetPageRedirects($args)
{
    global $wgAjaxCachePolicy;
    // set cache policy
    $wgAjaxCachePolicy->setPolicy(0);
    // validate input arguments
    $status = IAF_SUCCESS;
    $result = array();
    $pageTitles = explode('|', $args);
    if (!$args || count($pageTitles) > IAF_MAX_COUNT_CONTENTS) {
        $status = IAF_INVALID_ARG;
    } else {
        $db =& wfGetDB(DB_SLAVE);
        $db->ignoreErrors(true);
        $result = array();
        foreach ($pageTitles as $pageTitle) {
            $ot = Title::newFromText($pageTitle);
            if ($ot) {
                $nt = StructuredData::getRedirectToTitle($ot, false, $db);
                $errno = $db->lastErrno();
                if ($errno != 0) {
                    $status = IAF_DB_ERROR;
                    break;
                }
                if ($nt && $ot->getPrefixedDBkey() != $nt->getPrefixedDBkey()) {
                    $result[] = '<page source="' . StructuredData::escapeXml($ot->getPrefixedText()) . '" target="' . StructuredData::escapeXml($nt->getPrefixedText()) . '"/>';
                }
            }
        }
    }
    // return status
    return "<result status=\"{$status}\">" . join("\n", $result) . '</result>';
}
示例#13
0
 protected function formatResearchLinks($value, $dummy)
 {
     $surname = StructuredData::standardizeNameCase((string) $value['surname'], false);
     $fields = explode('|', (string) $value['place']);
     $titleText = trim($fields[0]);
     $t = Title::newFromText($titleText, NS_PLACE);
     if ($t) {
         $t = StructuredData::getRedirectToTitle($t);
         $titleText = $t->getText();
     }
     $place = $titleText;
     $surnames = array();
     $places = array();
     if ($surname) {
         $surnames[] = $surname;
     }
     if ($place) {
         $places[] = $place;
     }
     $categories = StructuredData::addCategories($surnames, $places, true, '', NS_MAIN, true);
     $ret = '';
     if ($surname && $place) {
         $ret .= "<dl><dt>[[{$surname} in {$place}]]<dd><small>Categories: {$categories}</small></dl>";
     } else {
         if ($surname) {
             $ret .= "<dl><dt>[[Surname:{$surname}]]<dd><small>Category: {$categories}</small></dl>";
         } else {
             if ($place) {
                 //			if ($surname) {
                 //				$ret .= "\n|- style=\"border-top-style:hidden\"\n|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
                 //			}
                 $ret .= "<dl><dt>[[Place:{$place}]]<dd><small>Category: {$categories}</small></dl>";
             }
         }
     }
     return $ret;
 }