예제 #1
0
/**
 * constructor
 */
function wfSpecialPlaceMap()
{
    global $wgOut, $wgRequest, $wgUser;
    $wgOut->setArticleRelated(false);
    $wgOut->setRobotpolicy('noindex,nofollow');
    $titleText = $wgRequest->getVal('pagetitle');
    $error = '';
    if ($titleText) {
        $title = Title::newFromText($titleText, NS_PLACE);
        if (is_null($title) || $title->getNamespace() != NS_PLACE || !$title->exists()) {
            $error = 'Please enter the title of a place page';
        } else {
            $revision = StructuredData::getRevision($title, true);
            if (!$revision) {
                $error = "Place map revision not found!\n";
            } else {
                $sk = $wgUser->getSkin();
                $text =& $revision->getText();
                $xml = StructuredData::getXml('place', $text);
                $wgOut->setPageTitle('Map of ' . $revision->getTitle()->getText());
                // place map
                $wgOut->addHTML('<H2>Map for ' . $sk->makeKnownLinkObj($revision->getTitle(), $revision->getTitle()->getText()) . '</H2>');
                $wgOut->addHTML('<div id="placemap" style="width: 760px; height: 520px"></div><br>');
                $mapData = SpecialPlaceMap::getContainedPlaceMapData($xml);
                if (!$mapData) {
                    $mapData = SpecialPlaceMap::getSelfMapData($revision->getTitle(), $xml);
                }
                $wgOut->addHTML(SpecialPlaceMap::getMapScripts(1, $mapData));
                $wgOut->addHTML('<div id="latlnginst" style="display: block">Click on the map to see the latitude and longitude at the cursor position.</div>');
                $wgOut->addHTML('<div id="latlngbox" style="display: none">Clicked on Latitude: <span id="latbox"></span> Longitude: <span id="lngbox"></span></div><br>');
                $unmappedPlaces = SpecialPlaceMap::getUnmappedPlaces($sk, $xml);
                if ($unmappedPlaces) {
                    $wgOut->addHTML("<h3>Places not on map</h3>" . $unmappedPlaces);
                }
                return;
            }
        }
    }
    $wgOut->setPageTitle('Place Map');
    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:PlaceMap" method="get">
<div id="searchFormDiv" style="{$queryBoxStyle}">
Place 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);
}
예제 #2
0
 private function loadPedigree()
 {
     // read the person
     if ($this->title->getNamespace() == NS_PERSON) {
         $revision = Revision::loadFromTitle($this->dbr, $this->title);
         // use load instead of new because I don't want ShowPedigree to ever access DB_MASTER
         if ($revision) {
             $xml = StructuredData::getXml('person', $revision->getText());
             if ($xml) {
                 foreach ($xml->spouse_of_family as $spouseFamily) {
                     $pos = ShowPedigree::SPOUSE_FAMILY_BASE + $this->numSpouseFamilies;
                     $this->loadFamily((string) $spouseFamily['title'], $pos, 0);
                     if (@$this->families[$pos]['exists']) {
                         $this->numSpouseFamilies += 1;
                     } else {
                         $this->families[$pos] = null;
                     }
                 }
                 $this->loadFamily((string) $xml->child_of_family['title'], 1, ShowPedigree::MAX_FAMILIES);
                 if ($this->numSpouseFamilies == 0) {
                     // no spouse families exist; get information on self from the person page (put into ['husband'] - it shouldn't matter)
                     $this->loadSelf($this->families[ShowPedigree::SPOUSE_FAMILY_BASE]['husband'], $xml);
                 }
             }
         }
         $selfTitle = @$this->families[ShowPedigree::SPOUSE_FAMILY_BASE]['husband']['title'];
         if ($selfTitle) {
             $this->selfTag = $selfTitle == $this->title->getText() ? 'husband' : 'wife';
             $this->spouseTag = $this->selfTag == 'husband' ? 'wife' : 'husband';
         }
     } else {
         $this->loadFamily($this->title->getText(), 1, ShowPedigree::MAX_FAMILIES);
         $this->selfTag = '';
         $this->spouseTag = '';
     }
 }
예제 #3
0
파일: Family.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 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;
 }
예제 #4
0
 /**
  * Create edit fields from xml property
  */
 protected function toEditFields(&$textbox1)
 {
     global $wgOut, $wgScriptPath, $wgRequest;
     $result = '';
     $target = $wgRequest->getVal('target');
     // add javascript functions
     $wgOut->addScript("<script type=\"text/javascript\" src=\"{$wgScriptPath}/autocomplete.10.js\"></script>");
     $invalidStyle = ' style="background-color:#fdd;"';
     //      $altNames = '';
     $surnames = '';
     $places = '';
     $fromYearStyle = '';
     $toYearStyle = '';
     $urlStyle = '';
     $fromYear = '';
     $toYear = '';
     $url = '';
     $abbrev = '';
     $author = '';
     $pubInfo = '';
     $callNumber = '';
     $type = '';
     $repoName = '';
     $repoAddr = '';
     $exists = isset($this->xml);
     if (!$exists) {
         global $wgRequest;
         // construct <source> text from request
         $text = MySource::getPageText($wgRequest->getVal('a'), $wgRequest->getVal('p'), $wgRequest->getVal('s'));
         $this->xml = StructuredData::getXml('mysource', $text);
     }
     if (isset($this->xml)) {
         $fromYear = htmlspecialchars((string) $this->xml->from_year);
         $toYear = htmlspecialchars((string) $this->xml->to_year);
         $url = htmlspecialchars((string) $this->xml->url);
         $abbrev = htmlspecialchars((string) $this->xml->abbrev);
         $author = htmlspecialchars((string) $this->xml->author);
         $pubInfo = htmlspecialchars((string) $this->xml->publication_info);
         $callNumber = htmlspecialchars((string) $this->xml->call_number);
         $type = htmlspecialchars((string) $this->xml->type);
         $repoName = htmlspecialchars((string) $this->xml->repository_name);
         $repoAddr = htmlspecialchars((string) $this->xml->repository_addr);
         //         foreach ($this->xml->alternate_name as $altName) {
         //            $altNames .= $altName . "\n";
         //         }
         foreach ($this->xml->surname as $surname) {
             $surnames .= htmlspecialchars($surname) . "\n";
         }
         foreach ($this->xml->place as $place) {
             $places .= htmlspecialchars($place) . "\n";
         }
     }
     if (!StructuredData::isValidYear($fromYear) || !StructuredData::isValidYear($toYear)) {
         if (!StructuredData::isValidYear($fromYear)) {
             $fromYearStyle = $invalidStyle;
         }
         if (!StructuredData::isValidYear($toYear)) {
             $toYearStyle = $invalidStyle;
         }
         $result .= "<p><font color=red>The year range is not valid</font></p>";
     }
     if (!StructuredData::isValidUrl($url)) {
         $urlStyle = $invalidStyle;
         $result .= "<p><font color=red>The URL is not valid</font></p>";
     }
     if ($this->isGedcomPage) {
         list($mysourcePrefix, $mysourceTitle, $mysourceSuffix) = MySource::splitGedcomMySourceTitle($this->titleString);
         $result .= '<br><label for="title">MySource title</label><input tabindex="1" size="80" name="mysource_title" value="' . htmlspecialchars($mysourceTitle) . '"/>';
     }
     $result .= "<br>";
     //      $result .= "<label for=\"altNames\">Alternate names (one per line):</label><br><textarea tabindex=\"1\" name=\"altNames\" rows=\"3\" cols=\"40\">".htmlspecialchars($altNames)."</textarea>";
     $result .= "<br><label for=\"surnames\">Surnames covered(one per line):</label><br><textarea tabindex=\"1\" name=\"surnames\" rows=\"3\" cols=\"60\">{$surnames}</textarea>" . "<br><label for=\"places\">Places covered (one per line):</label><br><textarea class=\"place_input\" tabindex=\"1\" name=\"places\" rows=\"3\" cols=\"60\">{$places}</textarea>" . "<table>" . "<tr><td align=right>Year range:</td><td align=left><input tabindex=\"1\" name=\"fromYear\" value=\"{$fromYear}\" size=\"5\"{$fromYearStyle}/>" . "&nbsp;&nbsp;-&nbsp;<input tabindex=\"1\" name=\"toYear\" value=\"{$toYear}\" size=\"5\"" . htmlspecialchars($toYearStyle) . "/></td></tr>";
     $result .= "<tr><td align=right>URL:</td><td align=left><input tabindex=\"1\" name=\"url\" value=\"{$url}\" size=\"60\"{$urlStyle}/></td></tr>" . "<tr><td align=right>Author:</td><td align=left><input tabindex=\"1\" name=\"author\" value=\"{$author}\" size=\"20\"/></td></tr>" . "<tr><td align=right>Publication info:</td><td align=left><input tabindex=\"1\" name=\"pubInfo\" value=\"{$pubInfo}\" size=\"60\"/></td></tr>" . "<tr><td align=right>Call number:</td><td align=left><input tabindex=\"1\" name=\"callNumber\" value=\"{$callNumber}\" size=\"20\"/></td></tr>" . "<tr><td align=right>Type:</td><td align=left><input tabindex=\"1\" name=\"type\" value=\"{$type}\" size=\"20\"/></td></tr>" . "<tr><td align=right>Repository name:</td><td align=left><input tabindex=\"1\" name=\"repoName\" value=\"{$repoName}\" size=\"60\"/></td></tr>" . "<tr><td align=right>Repository addr:</td><td align=left><input tabindex=\"1\" name=\"repoAddr\" value=\"{$repoAddr}\" size=\"60\"/></td></tr>" . "<tr><td align=right>Abbreviation:</td><td align=left><input tabindex=\"1\" name=\"abbrev\" value=\"{$abbrev}\" size=\"10\"/></td></tr>" . "</table>Text:<br>";
     return $result;
 }
예제 #5
0
 /**
  * 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;
 }
예제 #6
0
파일: Person.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 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;
 }
예제 #7
0
 private function loadPerson($titleText)
 {
     $xml = null;
     $title = Title::newFromText($titleText, NS_PERSON);
     $revision = Revision::loadFromTitle($this->dbr, $title);
     // use load instead of new because I don't want to ever access DB_MASTER
     if ($revision) {
         $xml = StructuredData::getXml('person', $revision->getText());
     }
     return $xml;
 }
예제 #8
0
/**
 * Generate family tree page
 *
 * @param unknown_type $args user, name, ns, title
 * @return GE_SUCCESS, GE_INVALID_ARG, GE_NOT_LOGGED_IN, GE_NOT_AUTHORIZED, GE_NOT_FOUND, GE_DUP_KEY, GE_DB_ERROR
 */
function wfGenerateFamilyTreePage($args)
{
    global $wgUser, $wgAjaxCachePolicy, $wrBotUserID, $wrIsGedcomUpload;
    // set cache policy
    $wgAjaxCachePolicy->setPolicy(0);
    $status = GE_SUCCESS;
    $ns = '';
    $text = '';
    $oldText = '';
    $titleString = '';
    $editFlags = 0;
    $wrIsGedcomUpload = true;
    if (!$wgUser->isLoggedIn()) {
        $status = GE_NOT_LOGGED_IN;
    } else {
        if (wfReadOnly() || $wgUser->getID() != $wrBotUserID) {
            $status = GE_NOT_AUTHORIZED;
        } else {
            $xml = simplexml_load_string($args);
            $ns = (int) $xml['namespace'];
            $titleString = (string) $xml['title'];
            PropagationManager::setWhitelist();
            // only pages to propagate to are on the whitelist
            $existingTitles = (string) $xml['existing_titles'];
            if ($existingTitles) {
                $existingTitles = explode('|', $existingTitles);
                foreach ($existingTitles as $existingTitle) {
                    PropagationManager::addWhitelistPage(Title::newFromText($existingTitle));
                }
            }
            $treeId = (int) $xml['tree_id'];
            $uid = (string) $xml['uid'];
            //   	wfDebug("wfGenerateFamilyTreePage ns=$ns title=$titleString treeId=$treeId\n");
            if (!$titleString || !$treeId) {
                //wfDebug("wfGenerate parmerr $treeId:$titleString\n");
                $status = GE_INVALID_ARG;
            }
        }
    }
    if ($status == GE_SUCCESS) {
        $dbr =& wfGetDB(DB_SLAVE);
        $dbr->ignoreErrors(true);
        $userName = $dbr->selectField('familytree', 'ft_user', array('ft_tree_id' => $treeId));
        $errno = $dbr->lastErrno();
        if ($errno > 0) {
            $status = GE_DB_ERROR;
        } else {
            if ($userName === false) {
                $status = GE_NOT_FOUND;
            } else {
                $wgUser = User::newFromName($userName, false);
                // switch the global user
                if (!$wgUser) {
                    $status = GE_NOT_FOUND;
                }
            }
        }
    }
    if ($status == GE_SUCCESS) {
        $title = Title::newFromText($titleString, $ns);
        $text = $xml->content;
        if ($title == null || !$treeId) {
            //wfDebug("wfGenerate error $treeId $ns $titleString\n");
            $status = GE_INVALID_ARG;
        } else {
            $article = new Article($title, 0);
            if (!$article->exists()) {
                $editFlags = EDIT_NEW;
            } else {
                $oldText = $article->getContent();
                $editFlags = EDIT_UPDATE;
            }
            //         else if ($ns == NS_MYSOURCE) {
            //            $existingMysource = true;
            //            $revid = $title->getLatestRevID(GAID_FOR_UPDATE);
            //         }
            //         // TODO during re-upload, we need to notify users of changes if others are watching; should we not suppress RC in this case?
            //         // also, decide whether FamilyTreePropagator should update ftp or not
            //         // (FamilyTreePropagator also processes the tree checkboxes, so we probably don't want it called)
            //         else {
            ////            $editFlags = EDIT_UPDATE;
            //            $status = GE_DUP_KEY;
            //         }
        }
    }
    if ($status == GE_SUCCESS && ($editFlags == EDIT_NEW || $text != $oldText)) {
        $isUpdatable = true;
        if ($editFlags == EDIT_UPDATE) {
            $revision = Revision::newFromId($article->getLatest());
            if ($revision && $revision->getComment() != 'gedcom upload') {
                $isUpdatable = false;
                error_log("Cannot update existing user-edited page: " . $article->getTitle()->getPrefixedText());
            }
        }
        if ($isUpdatable) {
            // NOTE: This doesn't execute the code in FamilyTreePropagator to update familytree_page, so if you edit a page, you'll have to update
            // the familytree_page.fp_latest yourself.  Also, FamilyTreePropagator adds the page to the tree (based upon request checkboxes), but we do this below
            if (!$article->doEdit($text, 'gedcom upload', $editFlags | EDIT_SUPPRESS_RC)) {
                $status = GE_WIKI_ERROR;
            }
            // TODO remove this
            if ($ns == NS_PERSON) {
                $xml = StructuredData::getXml('person', $text);
                $summaryFields = explode('|', Person::getSummary($xml, $title));
                $birthDate = $summaryFields[3];
                $deathDate = $summaryFields[5];
                $birthYear = '';
                $deathYear = '';
                if (preg_match('/\\d\\d\\d\\d/', $birthDate, $matches)) {
                    $birthYear = $matches[0];
                }
                if (preg_match('/\\d\\d\\d\\d/', $deathDate, $matches)) {
                    $deathYear = $matches[0];
                }
                if (($birthYear && $birthYear < 1750 || $deathYear && $deathYear < 1750) && !in_array($wgUser->getName(), explode('|', wfMsg('trustedgedcomuploaders')))) {
                    error_log($title->getPrefixedText() . "\n", 3, '/opt/wr/logs/earlypeople.txt');
                }
            }
        }
    }
    if ($status == GE_SUCCESS) {
        $dbw =& wfGetDB(DB_MASTER);
        $dbw->ignoreErrors(true);
        $dbw->begin();
        //      if ($status == GE_SUCCESS) {
        //         // save the data
        //         $data = $xml->data->asXML();
        //         if ($data) {
        //            $dataVersion = 1;
        //            $status == fgSaveData($dbw, $treeId, $title, $data, true);
        //         }
        //         else {
        //            $dataVersion = 0;
        //         }
        //      }
        // add the page to the tree
        if ($status == GE_SUCCESS) {
            if (!FamilyTreeUtil::addPage($dbw, $wgUser, $treeId, $title, 0, 0, 0, $uid, 0)) {
                $status = GE_DB_ERROR;
            }
        }
        // watch the page
        if ($status == GE_SUCCESS) {
            StructuredData::addWatch($wgUser, $article, true);
        }
        if ($status == GE_SUCCESS) {
            $dbw->commit();
        } else {
            $dbw->rollback();
        }
    }
    // return status
    $titleString = StructuredData::escapeXml($titleString);
    return "<generate status=\"{$status}\" ns=\"{$ns}\" title=\"{$titleString}\"></generate>";
}
예제 #9
0
    private function submitPage()
    {
        global $wgRequest, $wgOut;
        if (!$wgRequest->wasPosted() || !$wgRequest->getVal('wpEdittime')) {
            $this->showPage();
            return;
        }
        // from form
        $textbox1 = $wgRequest->getText('wpTextbox1');
        $ns = $wgRequest->getVal('gedcomns');
        $titleString = $wgRequest->getVal('gedcomtitle');
        $editPage = (object) array('textbox1' => $textbox1, 'section' => '');
        $obj = $this->getPageObj($ns, $titleString);
        $obj->importEditData($editPage, $wgRequest);
        if ($obj->getTitle()) {
            $titleString = $obj->getTitle()->getPrefixedText();
            // get updated title in case it was updated
        }
        $text = $editPage->textbox1;
        // grab xml and content from edited data
        $tagName = $obj->getTagName();
        $xml = StructuredData::getXml($tagName, $text);
        $content = trim(mb_substr($text, mb_strpos($text, '</' . $tagName . '>') + strlen("</{$tagName}>\n")));
        // add id's back and remove titles
        $saveTitles = array();
        foreach ($xml->child_of_family as $r) {
            $r['id'] = GedcomUtil::getKeyFromTitle((string) $r['title']);
            if ((string) $r['id']) {
                $saveTitles[(string) $r['id']] = (string) $r['title'];
                unset($r['title']);
            }
        }
        foreach ($xml->spouse_of_family as $r) {
            $r['id'] = GedcomUtil::getKeyFromTitle((string) $r['title']);
            if ((string) $r['id']) {
                $saveTitles[(string) $r['id']] = (string) $r['title'];
                unset($r['title']);
            }
        }
        foreach ($xml->husband as $r) {
            $r['id'] = GedcomUtil::getKeyFromTitle((string) $r['title']);
            if ((string) $r['id']) {
                $saveTitles[(string) $r['id']] = (string) $r['title'];
                unset($r['title']);
            }
        }
        foreach ($xml->wife as $r) {
            $r['id'] = GedcomUtil::getKeyFromTitle((string) $r['title']);
            if ((string) $r['id']) {
                $saveTitles[(string) $r['id']] = (string) $r['title'];
                unset($r['title']);
            }
        }
        foreach ($xml->child as $r) {
            $r['id'] = GedcomUtil::getKeyFromTitle((string) $r['title']);
            if ((string) $r['id']) {
                $saveTitles[(string) $r['id']] = (string) $r['title'];
                unset($r['title']);
            }
        }
        foreach ($xml->source_citation as $r) {
            $r['source_id'] = GedcomUtil::getKeyFromTitle((string) $r['title']);
            if ((string) $r['source_id']) {
                $saveTitles[(string) $r['source_id']] = (string) $r['title'];
                unset($r['title']);
            }
        }
        // save data to db
        $text = $xml->asXML();
        $text = substr($text, strpos($text, '<', 1)) . $content;
        // skip past the <?xml version="1.0"? > header and add content
        $dbw =& wfGetDB(DB_MASTER);
        $dbw->begin();
        $qtext = $dbw->addQuotes($text);
        $sql = 'INSERT INTO familytree_gedcom_data (fgd_gedcom_id, fgd_gedcom_key, fgd_text)' . ' VALUES(' . $dbw->addQuotes($this->gedcomid) . ',' . $dbw->addQuotes($this->gedcomkey) . ',' . $qtext . ')' . ' ON DUPLICATE KEY UPDATE fgd_text=' . $qtext;
        $dbw->query($sql);
        $dbw->commit();
        // convert to in-memory format and save to memory
        // add titles back
        foreach ($xml->child_of_family as $r) {
            if ((string) $r['id']) {
                $r['title'] = $saveTitles[(string) $r['id']];
            }
        }
        foreach ($xml->spouse_of_family as $r) {
            if ((string) $r['id']) {
                $r['title'] = $saveTitles[(string) $r['id']];
            }
        }
        foreach ($xml->husband as $r) {
            if ((string) $r['id']) {
                $r['title'] = $saveTitles[(string) $r['id']];
            }
        }
        foreach ($xml->wife as $r) {
            if ((string) $r['id']) {
                $r['title'] = $saveTitles[(string) $r['id']];
            }
        }
        foreach ($xml->child as $r) {
            if ((string) $r['id']) {
                $r['title'] = $saveTitles[(string) $r['id']];
            }
        }
        foreach ($xml->source_citation as $r) {
            if ((string) $r['source_id']) {
                $r['title'] = $saveTitles[(string) $r['source_id']];
            }
        }
        $xml->content = $content;
        $xml['id'] = $this->gedcomkey;
        $xml['ns'] = $ns;
        $xml['title'] = $titleString;
        $text = $xml->asXML();
        $text = substr($text, strpos($text, '<', 1));
        // skip past the <?xml version="1.0"? > header
        GedcomUtil::putGedcomDataString($text);
        // add script to notify swf of update
        $gedcomkey = htmlspecialchars($this->gedcomkey);
        $wgOut->addScript(<<<END
<script type="text/javascript">
//<![CDATA[
\$(document).ready(function(){
\ttry {
\t   if (parent && parent.review) {
\t      var swf=(navigator.appName.indexOf("Microsoft")!=-1) ? parent.review.window["gedcom"] : parent.review.document["gedcom"];
\t      if (swf && swf.pageUpdated) swf.pageUpdated("{$gedcomkey}");
\t   }
\t} catch (e) {}
});
//]]>
</script>
END
);
        // show page
        $this->showPage();
    }
예제 #10
0
파일: Place.php 프로젝트: k-hasan-19/wiki
 /**
  * Propagate data in xml property to other articles if necessary
  * @param string $oldText contains text being replaced
  * @param String $text which we never touch when propagating places
  * @param bool $textChanged which we never touch when propagating places
  * @return bool true if propagation was successful
  */
 protected function propagateEditData($oldText, &$text, &$textChanged)
 {
     $result = true;
     // determine current parents and type and lat and lng
     list($alsoLocatedIn, $type, $lat, $lng, $fromYear, $toYear) = Place::getPropagatedData($this->xml);
     // determine original parents by retrieving current version
     list($origAlsoLocatedIn, $origType, $origLat, $origLng, $origFromYear, $origToYear) = array(array(), null, null, null, null, null);
     if ($oldText) {
         $origXml = StructuredData::getXml('place', $oldText);
         if (isset($origXml)) {
             list($origAlsoLocatedIn, $origType, $origLat, $origLng, $origFromYear, $origToYear) = Place::getPropagatedData($origXml);
             // maintain place_abbrevs
             if (!isset($this->xml) || Place::placeAbbrevsChanged($origXml, $this->xml)) {
                 Place::placeAbbrevsDelete($this->titleString);
                 if (isset($this->xml)) {
                     Place::placeAbbrevsAdd($this->titleString, $this->xml);
                 }
             }
         } else {
             // new place comes here or below
             // add to place_abbrevs
             Place::placeAbbrevsDelete($this->titleString);
             Place::placeAbbrevsAdd($this->titleString, $this->xml);
         }
     } else {
         // add to place_abbrevs
         Place::placeAbbrevsDelete($this->titleString);
         Place::placeAbbrevsAdd($this->titleString, $this->xml);
     }
     //		$delAlsoLocatedIn = StructuredData::mapDiff($origAlsoLocatedIn, $alsoLocatedIn, 'place');
     // don't remove from X if this place is locatedIn X
     //		if ($this->locatedIn) {
     //		   $key = StructuredData::mapSearch($this->locatedIn, $delAlsoLocatedIn, 'place');
     //		   if ($key!==false) {
     //		      array_splice($delAlsoLocatedIn, $key, 1);
     //		   }
     //		}
     //      if ($type != $origType || $lat != $origLat || $lng != $origLng) {
     //         $updAlsoLocatedIn = $alsoLocatedIn;
     //      }
     //      else {
     //         $updAlsoLocatedIn = array_diff($alsoLocatedIn, $origAlsoLocatedIn);
     //      }
     // remove from original parent if necessary (don't remove from X if this place is now prevLocatedIn X)
     //		if ($origLocatedIn && $origLocatedIn != $locatedIn && array_search($origLocatedIn, $alsoLocatedIn)===false) {
     //            $parentArticle = StructuredData::getArticle(Title::newFromText((string)$origLocatedIn, NS_PLACE), true);
     //            if ($parentArticle) {
     //                $content =& $parentArticle->fetchContent();
     //                $updatedContent =& $this->updateContainedPlace(null, null, null, null, $content);
     //					if ($updatedContent) {
     //						$updateResult = $parentArticle->doEdit($updatedContent, self::PROPAGATE_MESSAGE, PROPAGATE_EDIT_FLAGS);
     //						$result = $result && $updateResult;
     //					}
     //            }
     //		}
     $isRedirect = StructuredData::isRedirect($text);
     if ($isRedirect) {
         // add alt name to redirect target
         list($prefName, $locatedIn) = Place::getPrefNameLocatedIn($this->titleString);
         $prefName = StructuredData::mb_str_replace($prefName, '_', ' ');
         // convert _'s back to spaces
         $newTitle = Title::newFromRedirect($text);
         $targetArticle = StructuredData::getArticle($newTitle, true);
         $targetContent =& $targetArticle->fetchContent();
         $targetXml = StructuredData::getXml('place', $targetContent);
         $found = false;
         foreach ($targetXml->alternate_name as $an) {
             $altName = (string) $an['name'];
             if ($altName == $prefName) {
                 $found = true;
                 break;
             }
         }
         if (!$found) {
             $altName = '<alternate_name name="' . StructuredData::escapeXml($prefName) . '" source="from redirect"/>';
             $targetContent = StructuredData::mb_str_replace($targetContent, "<place>", "<place>\n" . $altName);
             $targetArticle->doEdit($targetContent, 'Add alternate name from redirect', PROPAGATE_EDIT_FLAGS);
         }
         // edit wlh pages to point to the target title
         $job = new PlaceRedirectJob(array('old_title' => $this->titleString, 'new_title' => $newTitle->getText()));
         $job->insert();
     }
     // update type, lat, or lng if changed, or this place has been redirected or this place is new
     if ($this->locatedIn && ($isRedirect || !isset($origXml) || $type != $origType || $lat != $origLat || $lng != $origLng || $fromYear != $origFromYear || $toYear != $origToYear)) {
         $parentArticle = StructuredData::getArticle(Title::newFromText($this->locatedIn, NS_PLACE), true);
         if ($parentArticle) {
             $content =& $parentArticle->fetchContent();
             if ($isRedirect) {
                 // remove from parent
                 $updatedContent =& $this->updateContainedPlace(null, null, null, null, null, null, $content);
             } else {
                 $updatedContent =& $this->updateContainedPlace($this->titleString, $type, $lat, $lng, $fromYear, $toYear, $content);
             }
             if ($updatedContent) {
                 $updateResult = $parentArticle->doEdit($updatedContent, self::PROPAGATE_MESSAGE . ' [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS);
                 $result = $result && $updateResult;
             }
         }
     }
     // remove from deleted previous parents
     foreach ($origAlsoLocatedIn as $pli) {
         if ($this->locatedIn != (string) $pli['place'] && StructuredData::mapArraySearch((string) $pli['place'], $alsoLocatedIn, 'place') === false) {
             $parentArticle = StructuredData::getArticle(Title::newFromText((string) $pli['place'], NS_PLACE), true);
             if ($parentArticle) {
                 $content =& $parentArticle->fetchContent();
                 $updatedContent =& $this->updateContainedPlace(null, null, null, null, null, null, $content);
                 if ($updatedContent) {
                     $updateResult = $parentArticle->doEdit($updatedContent, self::PROPAGATE_MESSAGE . ' [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS);
                     $result = $result && $updateResult;
                 }
             }
         }
     }
     // add to new previous parents or update type, lat, lng on same previous-parents
     foreach ($alsoLocatedIn as $pli) {
         $origKey = StructuredData::mapArraySearch((string) $pli['place'], $origAlsoLocatedIn, 'place');
         if ($origKey !== false) {
             $origPli = $origAlsoLocatedIn[$origKey];
         }
         if ($this->locatedIn != (string) $pli['place'] && ($origKey === false || $type != $origType || $lat != $origLat || $lng != $origLng || (string) $pli['from_year'] != (string) $origPli['from_year'] || (string) $pli['to_year'] != (string) $origPli['to_year'])) {
             $parentArticle = StructuredData::getArticle(Title::newFromText((string) $pli['place'], NS_PLACE), true);
             if ($parentArticle) {
                 $content =& $parentArticle->fetchContent();
                 $updatedContent =& $this->updateContainedPlace($this->titleString, $type, $lat, $lng, (string) $pli['from_year'], (string) $pli['to_year'], $content);
                 if ($updatedContent) {
                     $updateResult = $parentArticle->doEdit($updatedContent, self::PROPAGATE_MESSAGE . ' [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS);
                     $result = $result && $updateResult;
                 }
             }
         }
     }
     if (!$result) {
         error_log("ERROR! Place edit/rollback not propagated: {$this->titleString}\n");
     }
     return $result;
 }
예제 #11
0
파일: SDImage.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 set to true if we change the text
  * @return bool true if success
  */
 protected function propagateMoveDeleteUndelete($newTitleString, $newNs, &$text, &$textChanged)
 {
     $result = true;
     $newTitle = $newTitleString ? Title::newFromText($newTitleString, NS_IMAGE) : null;
     // if we're undeleting, add additional people from WLH, getting updated person data
     if ($this->titleString == $newTitleString) {
         list($people, $families) = SDImage::getPropagatedData($this->xml);
         $this->addWhatLinksHere($people, $families);
         $pageText = $this->getPageElements($people, 'person', NS_PERSON) . $this->getPageElements($families, 'family', NS_FAMILY);
         // update text: replace old family information with new
         $text = preg_replace("\$<(person|family) [^>]*>\n\$", '', $text);
         $text = preg_replace('$</' . $this->tagName . '>$', StructuredData::protectRegexReplace($pageText . '</' . $this->tagName . '>'), $text, 1);
         $this->xml = StructuredData::getXml($this->tagName, $text);
         $textChanged = true;
     }
     // get data to propagate
     list($people, $families) = SDImage::getPropagatedData($this->xml);
     foreach ($people as $p) {
         $linkTitle = Title::newFromText((string) $p, NS_PERSON);
         PropagationManager::addPropagatedAction($this->title, 'dellink', $linkTitle);
         if ($newTitle) {
             PropagationManager::addPropagatedAction($newTitle, 'addlink', $linkTitle);
         }
         // don't need to check propagated action before calling updatePage, because propagateMoveDeleteUndelete is never part of a loop
         $result = $result && $this->updatePage($linkTitle, 'person', $newTitleString, $text, $textChanged);
     }
     foreach ($families as $p) {
         $linkTitle = Title::newFromText((string) $p, NS_FAMILY);
         PropagationManager::addPropagatedAction($this->title, 'dellink', $linkTitle);
         if ($newTitle) {
             PropagationManager::addPropagatedAction($newTitle, 'addlink', $linkTitle);
         }
         // don't need to check propagated action before calling updatePage, because propagateMoveDeleteUndelete is never part of a loop
         $result = $result && $this->updatePage($linkTitle, 'family', $newTitleString, $text, $textChanged);
     }
     if (!$result) {
         error_log("ERROR! Family move/delete/undelete not propagated: {$this->titleString} -> " . ($newTitleString ? $newTitleString : "[delete]") . "\n");
     }
     return $result;
 }
예제 #12
0
파일: Source.php 프로젝트: k-hasan-19/wiki
 /**
  * Create edit fields from xml property
  */
 protected function toEditFields(&$textbox1)
 {
     global $wgOut, $wgScriptPath, $wgRequest;
     $result = '';
     $target = $wgRequest->getVal('target');
     // add javascript functions
     $wgOut->addScript("<script type=\"text/javascript\" src=\"{$wgScriptPath}/autocomplete.10.js\"></script>");
     //      if ($target && $target != 'AddPage') {
     //         $result .= "<p><font color=red>Add any additional information you have about the source".
     //                     ($target == 'gedcom' ? ' and save the page' : ', save the page, then close this window').
     //                    ".</font></p>";
     //      }
     $wgOut->addScript("<script type=\"text/javascript\" src=\"{$wgScriptPath}/jquery.multiSelect.yui.1.js\"></script>");
     $wgOut->addScript("<script type=\"text/javascript\" src=\"{$wgScriptPath}/source.18.js\"></script>");
     $tm = new TipManager();
     $sourceType = '';
     $authors = '';
     $sourceTitle = '';
     $subtitle = '';
     $publisher = '';
     $dateIssued = '';
     $placeIssued = '';
     $seriesName = '';
     $pages = '';
     $references = '';
     $surnames = '';
     $places = '';
     $subjects = array();
     $ethnicity = '';
     $religion = '';
     $occupation = '';
     $fromYear = '';
     $toYear = '';
     $invalidStyle = ' style="background-color:#fdd;"';
     $fromYearStyle = '';
     $toYearStyle = '';
     $exists = isset($this->xml);
     if (!$exists) {
         // construct <source> text from request
         $text = Source::getPageText($wgRequest->getVal('sty'), $wgRequest->getVal('st'), $wgRequest->getVal('a'), $wgRequest->getVal('p'), $wgRequest->getVal('pi'), $wgRequest->getVal('pu'));
         $this->xml = StructuredData::getXml('source', $text);
     }
     if (isset($this->xml)) {
         $sourceType = htmlspecialchars((string) $this->xml->source_type);
         foreach ($this->xml->author as $author) {
             $authors .= htmlspecialchars((string) $author) . "\n";
         }
         $sourceTitle = htmlspecialchars((string) $this->xml->source_title);
         if (!$sourceTitle) {
             $sourceTitle = htmlspecialchars($this->titleString);
         }
         $subtitle = htmlspecialchars((string) $this->xml->subtitle);
         $publisher = htmlspecialchars((string) $this->xml->publisher);
         if (!$publisher) {
             $publisher = htmlspecialchars((string) $this->xml->publication_info);
         }
         $dateIssued = htmlspecialchars((string) $this->xml->date_issued);
         $placeIssued = htmlspecialchars((string) $this->xml->place_issued);
         $seriesName = htmlspecialchars((string) $this->xml->series_name);
         $volumes = htmlspecialchars((string) $this->xml->volumes);
         $pages = htmlspecialchars((string) $this->xml->pages);
         $references = htmlspecialchars((string) $this->xml->references);
         foreach ($this->xml->surname as $surname) {
             $surnames .= htmlspecialchars((string) $surname) . "\n";
         }
         foreach ($this->xml->place as $place) {
             $places .= htmlspecialchars((string) $place) . "\n";
         }
         foreach ($this->xml->subject as $subject) {
             $subjects[] = htmlspecialchars((string) $subject);
         }
         if (count($subjects) == 0 && (string) $this->xml->source_category) {
             $subjects[] = htmlspecialchars((string) $this->xml->source_category);
         }
         $ethnicity = htmlspecialchars((string) $this->xml->ethnicity);
         $religion = htmlspecialchars((string) $this->xml->religion);
         $occupation = htmlspecialchars((string) $this->xml->occupation);
         $fromYear = htmlspecialchars((string) $this->xml->from_year);
         $toYear = htmlspecialchars((string) $this->xml->to_year);
         $url = htmlspecialchars((string) $this->xml->url);
         // old
         $callNumber = htmlspecialchars((string) $this->xml->call_number);
         // old
         $repoName = htmlspecialchars((string) $this->xml->repository_name);
         // old
         $repoAddr = htmlspecialchars((string) $this->xml->repository_addr);
         // old
     }
     $missingAvailability = false;
     if (isset($this->xml)) {
         foreach ($this->xml->repository as $repository) {
             // the source_location condition is temporary
             if (!(string) $repository['availability'] && stripos((string) $repository['source_location'], 'www.familysearch.org/Eng/Library/fhlcatalog') === false) {
                 $missingAvailability = true;
             }
         }
         if ($url && stripos($url, 'www.familysearch.org/Eng/Library/fhlcatalog') === false) {
             $missingAvailability = true;
         }
     }
     if ($missingAvailability) {
         $result .= "<p><font color=red>Please select an Availability</font></p>";
     }
     if (!StructuredData::isValidYear($fromYear) || !StructuredData::isValidYear($toYear)) {
         if (!StructuredData::isValidYear($fromYear)) {
             $fromYearStyle = $invalidStyle;
         }
         if (!StructuredData::isValidYear($toYear)) {
             $toYearStyle = $invalidStyle;
         }
         $result .= "<p><font color=red>The year range is not valid</font></p>";
     }
     // display edit fields
     $result .= "<h2>Source information</h2><table>" . '<tr><td align=right>Type:</td><td align=left>' . StructuredData::addSelectToHtml(1, 'source_type', self::$SOURCE_TYPE_OPTIONS, $sourceType, 'onChange="showSourceFields()"') . $tm->addMsgTip('SourceType') . '</td></tr>' . '<tr id="authors_row"><td align=right>Authors:<br/><font size=\\"-1\\"><i>one per line<br/>surname, given</i></font></td>' . "<td align=left><textarea tabindex=\"1\" name=\"authors\" rows=\"3\" cols=\"60\">{$authors}</textarea></td></tr>" . "<tr id=\"source_title_row\"><td align=right>Title:</td><td align=left><input tabindex=\"1\" name=\"source_title\" value=\"{$sourceTitle}\" size=\"60\"/></td></tr>" . "<tr id=\"subtitle_row\"><td align=right>Subtitle:</td><td align=left><input tabindex=\"1\" name=\"subtitle\" value=\"{$subtitle}\" size=\"60\"/></td></tr>" . "<tr id=\"publisher_row\"><td align=right>Publisher:</td><td align=left><input tabindex=\"1\" name=\"publisher\" value=\"{$publisher}\" size=\"60\"/></td></tr>" . "<tr id=\"date_issued_row\"><td align=right>Date issued:</td><td align=left><input tabindex=\"1\" name=\"date_issued\" value=\"{$dateIssued}\" size=\"20\"/></td></tr>" . "<tr id=\"place_issued_row\"><td align=right>Place issued:</td><td align=left><input tabindex=\"1\" name=\"place_issued\" value=\"{$placeIssued}\" size=\"60\"/></td></tr>" . "<tr id=\"series_name_row\"><td align=right>Periodical/Series name:</td><td align=left><input tabindex=\"1\" class=\"source_input\" name=\"series_name\" value=\"{$seriesName}\" size=\"60\"/></td></tr>" . "<tr id=\"volumes_row\"><td align=right>Number of volumes:</td><td align=left><input tabindex=\"1\" name=\"volumes\" value=\"{$volumes}\" size=\"10\"/></td></tr>" . "<tr id=\"pages_row\"><td align=right>Volume/Film#/Pages:</td><td align=left><input tabindex=\"1\" name=\"pages\" value=\"{$pages}\" size=\"20\"/></td></tr>" . "<tr id=\"references_row\"><td align=right>References/Cites:</td><td align=left><input tabindex=\"1\" name=\"references\" value=\"{$references}\" size=\"60\"/></td></tr>" . "</table>";
     $result .= '<h2>Coverage</h2><table>' . "<tr><td align=right>Surnames covered:<br/><i>one per line</i></td><td align=left><textarea tabindex=\"1\" name=\"surnames\" rows=\"3\" cols=\"60\">{$surnames}</textarea></td></tr>" . "<tr><td align=right>Places covered:<br/><i>one per line</i></td><td align=left><textarea class=\"place_input\" tabindex=\"1\" name=\"places\" rows=\"3\" cols=\"60\">{$places}</textarea></td></tr>" . "<tr><td align=right>Year range:</td><td align=left><input tabindex=\"1\" name=\"fromYear\" value=\"{$fromYear}\" size=\"5\"{$fromYearStyle}/>" . "&nbsp;&nbsp;-&nbsp;<input tabindex=\"1\" name=\"toYear\" value=\"{$toYear}\" size=\"5\"{$toYearStyle}/></td></tr>" . "<tr><td align=right>Subject:</td><td align=left>" . StructuredData::addSelectToHtml(1, 'subject', self::$SOURCE_SUBJECT_OPTIONS, $subjects, 'multiple="multiple"') . "</td></tr>" . "<tr id=\"ethnicity_row\"><td align=right>Ethnicity/Culture:</td><td align=left>" . StructuredData::addSelectToHtml(1, 'ethnicity', self::$ETHNICITY_OPTIONS, $ethnicity) . "</td></tr>" . "<tr id=\"religion_row\"><td align=right>Religion:</td><td align=left>" . StructuredData::addSelectToHtml(1, 'religion', self::$RELIGION_OPTIONS, $religion) . "</td></tr>" . "<tr id=\"occupation_row\"><td align=right>Occupation:</td><td align=left>" . StructuredData::addSelectToHtml(1, 'occupation', self::$OCCUPATION_OPTIONS, $occupation) . "</td></tr>" . "</table>";
     $rows = '';
     $i = 0;
     if (isset($this->xml)) {
         foreach ($this->xml->repository as $repository) {
             $rows .= $this->addRepositoryInput($i, htmlspecialchars((string) $repository['title']), htmlspecialchars((string) $repository['source_location']), htmlspecialchars((string) $repository['availability']), (string) $repository['availability'] ? '' : $invalidStyle);
             $i++;
         }
         if ($url) {
             $rows .= $this->addRepositoryInput($i, '', $url, '', $invalidStyle);
             $i++;
         }
         if ($callNumber || $repoName) {
             $rows .= $this->addRepositoryInput($i, $repoName, $callNumber, '', $invalidStyle);
             $i++;
         }
     }
     if ($i == 0) {
         $rows .= $this->addRepositoryInput($i, '', '', '', '');
         $i++;
     }
     $result .= '<h2>Repositories</h2>';
     $result .= '<table id="repository_table" border="0" width="500px" style="display:block">';
     $result .= '<tr><th></th><th>Repository name</th><th>Location (call#, URL) of source within repository</th><th>Availability</th></tr>';
     $result .= "{$rows}</table><a href=\"javascript:void(0)\" onClick=\"addRepository('" . implode(',', self::$SOURCE_AVAILABILITY_OPTIONS) . "'); return preventDefaultAction(event);\">Add Repository</a>";
     $result .= $tm->getTipTexts();
     $result .= "<br><br>Text:<br>";
     return $result;
 }