Beispiel #1
0
 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;
     }
 }
Beispiel #2
0
 /**
  * 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)
 {
     global $wrIsGedcomUpload, $wgESINHandler;
     $result = true;
     // cache new xml - it's used right away to generate family badges on the related person pages,
     // if you don't cache it, the badges pick up the old html
     $this->cachePageXml();
     // update people that link to this family, because the family-badge contents could have changed
     // TODO this could be made more efficient by only invalidating if names, birthdates, or deathdates have changed
     $u = new HTMLCacheUpdate($this->title, 'pagelinks');
     $u->doUpdate();
     // get current info
     $propagatedData = Family::getPropagatedData($this->xml);
     $redirTitle = Title::newFromRedirect($text);
     // get original info
     $origPropagatedData = Family::getPropagatedData(null);
     // don't bother construction page text from WLH in a gedcom upload because nothing will link to this new page
     if (!@$wrIsGedcomUpload && (!$oldText || mb_strpos($oldText, '<family>') === false)) {
         // oldText contains MediaWiki:noarticletext if the article is being created
         // construct <family> text from What Links Here
         $oldText = $this->getPageTextFromWLH(false);
     }
     $origXml = null;
     if ($oldText) {
         $origXml = StructuredData::getXml('family', $oldText);
         if (isset($origXml)) {
             $origPropagatedData = Family::getPropagatedData($origXml);
         }
     }
     // TODO!!!
     // Revert, Unmerge, and eventually Undo should be getting the current attrs for existing people from origPropagatedData
     // and getting the current attrs and redirect-titles for newly-added people from the Person pages when adding the family title to them
     // then unmerge wouldn't need to get them in unmerge, and revert wouldn't be broken, and undo won't break things.
     // This duplicates the functionality found in fromEditFields, but it allows us to update the pages without going through fromEditFields
     // and it doesn't require reading any pages that we weren't reading already.
     // Also, instead of isMerging, if this Family page is on the propagation manager blacklist, then you can't trust the prior version
     // and we should get the person attrs from the Person pages for _all_ family members.
     // Finally, make sure that after redirects we don't have 2 links to the same Person (and also two links to the same Family on Person pages).
     // ignore changes of the husband <-> wife role for the same person
     $temp = array_diff($propagatedData['husbands'], $origPropagatedData['wives']);
     $origPropagatedData['wives'] = array_diff($origPropagatedData['wives'], $propagatedData['husbands']);
     $propagatedData['husbands'] = $temp;
     $temp = array_diff($propagatedData['wives'], $origPropagatedData['husbands']);
     $origPropagatedData['husbands'] = array_diff($origPropagatedData['husbands'], $propagatedData['wives']);
     $propagatedData['wives'] = $temp;
     $result = $result && $this->propagateFamilyMemberEditData($propagatedData['husbands'], $origPropagatedData['husbands'], 'husband', 'spouse_of_family', $text, $textChanged);
     $result = $result && $this->propagateFamilyMemberEditData($propagatedData['wives'], $origPropagatedData['wives'], 'wife', 'spouse_of_family', $text, $textChanged);
     $result = $result && $this->propagateFamilyMemberEditData($propagatedData['children'], $origPropagatedData['children'], 'child', 'child_of_family', $text, $textChanged);
     if (StructuredData::removeDuplicateLinks('husband|wife|child', $text)) {
         $textChanged = true;
     }
     $result = $result && $wgESINHandler->propagateSINEdit($this->title, 'family', $this->titleString, $propagatedData, $origPropagatedData, $text, $textChanged);
     // ensure footer tag is still there (might have been removed by editing the last section)
     if ($redirTitle == null && strpos($text, ESINHandler::ESIN_FOOTER_TAG) === false) {
         if (strlen($text) > 0 && substr($text, strlen($text) - 1) != "\n") {
             $text .= "\n";
         }
         $text .= ESINHandler::ESIN_FOOTER_TAG;
         $textChanged = true;
     }
     // update watchlist summary if changed
     $summary = Family::getSummary($this->xml, $this->title);
     $origSummary = Family::getSummary($origXml, $this->title);
     if ($summary != $origSummary) {
         StructuredData::updateWatchlistSummary($this->title, $summary);
     }
     // if it's a redirect, add the people, families, and images that were on this page to the redirect target
     // but don't bother updating the redir target during a merge
     if ($redirTitle != null && PropagationManager::isPropagatablePage($redirTitle)) {
         // get the text of the redir page
         $article = StructuredData::getArticle($redirTitle, true);
         if ($article) {
             $content =& $article->fetchContent();
             $updated = false;
             // add husbands from this page to the redir page
             foreach ($origPropagatedData['husbands'] as $p) {
                 // get propagated data for p
                 $pd = Person::getPropagatedData(StructuredData::getXmlForTitle('person', Title::newFromText($p, NS_PERSON)));
                 Family::updatePersonLink('husband', $p, $p, $pd, 'spouse_of_family', $content, $updated);
             }
             // add wives from this page to the redir page
             foreach ($origPropagatedData['wives'] as $p) {
                 $pd = Person::getPropagatedData(StructuredData::getXmlForTitle('person', Title::newFromText($p, NS_PERSON)));
                 Family::updatePersonLink('wife', $p, $p, $pd, 'spouse_of_family', $content, $updated);
             }
             // add children from this page to the redir page
             foreach ($origPropagatedData['children'] as $p) {
                 $pd = Person::getPropagatedData(StructuredData::getXmlForTitle('person', Title::newFromText($p, NS_PERSON)));
                 Family::updatePersonLink('child', $p, $p, $pd, 'child_of_family', $content, $updated);
             }
             // add images from this page to the redir page
             foreach ($origPropagatedData['images'] as $i) {
                 ESINHandler::updateImageLink('family', $i['filename'], $i['filename'], $i['caption'], $content, $updated);
             }
             // update the redir page if necessary
             if ($updated) {
                 $result = $result && $article->doEdit($content, 'Copy data from [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS);
             }
         }
     }
     if (!$result) {
         error_log("ERROR! Family edit/rollback not propagated: {$this->titleString}\n");
     }
     return $result;
 }
Beispiel #3
0
 private function addNamesToRequestData(&$requestData, &$keepKeys, &$count, &$primaryNameFound, &$notesMap, &$sourcesMap, $elements, &$noteAdoptions, &$sourceAdoptions)
 {
     if (is_array($elements)) {
         foreach ($elements as $element) {
             if (@$keepKeys[$element['key']]) {
                 if ($count == 0) {
                     $count = 1;
                 }
                 if ($element['type'] == self::$PRIMARY_NAME) {
                     if (!$primaryNameFound) {
                         $i = 0;
                         $type = '';
                         $primaryNameFound = true;
                     } else {
                         $type = Person::$ALT_NAME_TAG;
                         $i = $count;
                         $count++;
                     }
                 } else {
                     $type = $element['type'];
                     $i = $count;
                     $count++;
                 }
                 $notes = $this->addAdoptions($element['key'], ESINHandler::mapSourcesImagesNotes($notesMap, $element['notes']), $noteAdoptions);
                 $sources = $this->addAdoptions($element['key'], ESINHandler::mapSourcesImagesNotes($sourcesMap, $element['sources']), $sourceAdoptions);
                 Person::addNameToRequestData($requestData, $i, $type, $element['given'], $element['surname'], $element['title_prefix'], $element['title_suffix'], $sources, $notes);
             }
         }
     }
 }
Beispiel #4
0
 /**
  * Propagate data in xml property to other articles if necessary
  * @param string $oldText contains text being replaced
  * @param String $text new text
  * @param bool $textChanged which we never touch when propagating places
  * @return bool true if propagation was successful
  */
 protected function propagateEditData($oldText, &$text, &$textChanged)
 {
     global $wrIsGedcomUpload, $wgESINHandler;
     $result = true;
     // clear xml cache
     $this->clearPageXmlCache();
     // get current info
     $propagatedData = Person::getPropagatedData($this->xml);
     $redirTitle = Title::newFromRedirect($text);
     // get original info
     $origPropagatedData = Person::getPropagatedData(null);
     // don't bother construction page text from WLH in a gedcom upload because nothing will link to this new page
     if (!@$wrIsGedcomUpload && (!$oldText || mb_strpos($oldText, '<person>') === false)) {
         // oldText contains MediaWiki:noarticletext if the article is being created
         // construct <person> text from What Links Here
         $oldText = $this->getPageTextFromWLH(false);
     }
     $origXml = null;
     if ($oldText) {
         $origXml = StructuredData::getXml('person', $oldText);
         if (isset($origXml)) {
             $origPropagatedData = Person::getPropagatedData($origXml);
         }
     }
     $result = $result && $this->propagateFamilyEditData($propagatedData['parentFamilies'], $origPropagatedData['parentFamilies'], 'child_of_family', 'child', 'child', $propagatedData, $origPropagatedData, $text, $textChanged);
     $oldTag = Person::getSpouseTagFromGender($origPropagatedData['gender']);
     $newTag = Person::getSpouseTagFromGender($propagatedData['gender']);
     $result = $result && $this->propagateFamilyEditData($propagatedData['spouseFamilies'], $origPropagatedData['spouseFamilies'], 'spouse_of_family', $oldTag, $newTag, $propagatedData, $origPropagatedData, $text, $textChanged);
     if (StructuredData::removeDuplicateLinks('child_of_family|spouse_of_family', $text)) {
         $textChanged = true;
     }
     $result = $result && $wgESINHandler->propagateSINEdit($this->title, 'person', $this->titleString, $propagatedData, $origPropagatedData, $text, $textChanged);
     // ensure footer tag is still there (might have been removed by editing the last section)
     if ($redirTitle == null && strpos($text, ESINHandler::ESIN_FOOTER_TAG) === false) {
         if (strlen($text) > 0 && substr($text, strlen($text) - 1) != "\n") {
             $text .= "\n";
         }
         $text .= ESINHandler::ESIN_FOOTER_TAG;
         $textChanged = true;
     }
     // update watchlist summary if changed
     $summary = Person::getSummary($this->xml, $this->title);
     $origSummary = Person::getSummary($origXml, $this->title);
     if ($summary != $origSummary) {
         StructuredData::updateWatchlistSummary($this->title, $summary);
     }
     // if it's a redirect, add the people, families, and images that were on this page to the redirect target
     // but don't bother updating the redir target during a merge
     if ($redirTitle != null && PropagationManager::isPropagatablePage($redirTitle)) {
         // get the text of the redir page
         $article = StructuredData::getArticle($redirTitle, true);
         if ($article) {
             $content =& $article->fetchContent();
             $updated = false;
             // add parent families from this page to the redir page
             foreach ($origPropagatedData['parentFamilies'] as $f) {
                 Person::updateFamilyLink('child_of_family', $f, $f, $content, $updated);
             }
             // add spouse families from this page to the redir page
             foreach ($origPropagatedData['spouseFamilies'] as $f) {
                 Person::updateFamilyLink('spouse_of_family', $f, $f, $content, $updated);
             }
             // add images from this page to the redir page
             foreach ($origPropagatedData['images'] as $i) {
                 ESINHandler::updateImageLink('person', $i['filename'], $i['filename'], $i['caption'], $content, $updated);
             }
             // update the redir page if necessary
             if ($updated) {
                 $result = $result && $article->doEdit($content, 'Copy data from [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS);
             }
         }
     }
     if (!$result) {
         error_log("ERROR! Person edit/rollback not propagated: {$this->titleString}\n");
     }
     return $result;
 }
/**
 * Create family tree page
 *
 * This is also called by search.js
 *
 * @param unknown_type $args
 * @return GE_SUCCESS, GE_INVALID_ARG, GE_NOT_LOGGED_IN, GE_NOT_AUTHORIZED, GE_NOT_FOUND, GE_DUP_KEY, GE_DB_ERROR
 */
function wfAddPage($args)
{
    global $wgUser, $wgAjaxCachePolicy, $wgArticle, $wgTitle, $wgLang;
    // set cache policy
    $wgAjaxCachePolicy->setPolicy(0);
    $status = GE_SUCCESS;
    $title = null;
    $titleString = null;
    $error = '';
    $args = AjaxUtil::getArgs($args);
    $ns = $wgLang->getNsIndex($args['ns']);
    $titleString = @$args['title'];
    $update = $args['update'] == 'true';
    if (!$wgUser->isLoggedIn()) {
        $status = GE_NOT_LOGGED_IN;
    } else {
        if ($wgUser->isBlocked() || wfReadOnly()) {
            $status = GE_NOT_AUTHORIZED;
        }
    }
    if ($status == GE_SUCCESS) {
        $dbw =& wfGetDB(DB_MASTER);
        $dbw->ignoreErrors(true);
        $dbw->begin();
        $text = '';
        if ($titleString) {
            // user passed in existing title; just add to watchlist and trees
            $title = Title::newFromText($titleString, $ns);
        } else {
            if ($ns == NS_PERSON) {
                if (ESINHandler::isLivingDates($args['bd'], null, $args['dd'], $args['dp'])) {
                    $error = 'Living people cannot be added to WeRelate. People born in the last 110 years must have a death date';
                } else {
                    if (ESINHandler::isAmbiguousDate($args['bd']) || ESINHandler::isAmbiguousDate($args['dd'])) {
                        $error = "Please write dates in D MMM YYYY format so they are unambiguous (ie 5 Jan 1900)";
                    } else {
                        if (!$title) {
                            $title = StructuredData::constructPersonTitle($args['g'], $args['s']);
                        }
                        if ($title) {
                            if ($args['bt'] == 'chr') {
                                $bird = '';
                                $birp = '';
                                $chrd = $args['bd'];
                                $chrp = $args['bp'];
                            } else {
                                $bird = $args['bd'];
                                $birp = $args['bp'];
                                $chrd = '';
                                $chrp = '';
                            }
                            if ($args['dt'] == 'bur') {
                                $dead = '';
                                $deap = '';
                                $burd = $args['dd'];
                                $burp = $args['dp'];
                            } else {
                                $dead = $args['dd'];
                                $deap = $args['dp'];
                                $burd = '';
                                $burp = '';
                            }
                            $text = Person::getPageText($args['g'], $args['s'], $args['gnd'], $bird, $birp, $dead, $deap, $title->getText(), null, @$args['pf'], @$args['sf'], $chrd, $chrp, $burd, $burp);
                        }
                    }
                }
            } else {
                if ($ns == NS_FAMILY) {
                    if (ESINHandler::isAmbiguousDate($args['md'])) {
                        $error = "Please write dates in D MMM YYYY format so they are unambiguous (ie 5 Jan 1900)";
                    } else {
                        $title = StructuredData::constructFamilyTitle($args['hg'], $args['hs'], $args['wg'], $args['ws']);
                        if ($title) {
                            $text = Family::getPageText($args['md'], $args['mp'], $title->getText(), null, @$args['ht'], @$args['wt'], @$args['ct']);
                        }
                    }
                } else {
                    if ($ns == NS_SOURCE) {
                        $title = StructuredData::constructSourceTitle($args['sty'], $args['st'], $args['a'], $args['p'], $args['pi'], $args['pu']);
                        if ($title) {
                            $text = Source::getPageText($args['sty'], $args['st'], $args['a'], $args['p'], $args['pi'], $args['pu']);
                        } else {
                            $error = 'Required source fields are missing; please press the Back button on your browser to enter the required fields.';
                        }
                    } else {
                        if ($ns == NS_MYSOURCE) {
                            $t = $args['t'];
                            if (mb_strpos($t, $wgUser->getName() . '/') != 0) {
                                $t = $wgUser->getName() . '/' . $t;
                            }
                            $title = Title::newFromText($t, NS_MYSOURCE);
                            if ($title) {
                                $text = MySource::getPageText($args['a'], $args['p'], $args['s']);
                            }
                        } else {
                            if ($ns == NS_PLACE) {
                                $title = StructuredData::constructPlaceTitle($args['pn'], $args['li']);
                                $text = Place::getPageText();
                                // check existing located-in, not root
                                $titleText = $title->getFullText();
                                $pos = mb_strpos($titleText, ',');
                                if ($pos === false) {
                                    $title = null;
                                    $error = 'You need to fill in the country';
                                } else {
                                    $locatedIn = Title::newFromText(trim(mb_substr($titleText, $pos + 1)), NS_PLACE);
                                    if (!$locatedIn->exists()) {
                                        $title = null;
                                        $error = 'Before you can add this place, you must first add ' . $locatedIn->getFullText();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        if ($status == GE_SUCCESS && $title == null) {
            $status = GE_INVALID_ARG;
            if (!$error) {
                $error = 'Invalid page title; unable to create page';
            }
        }
        // don't update in the case of the user passing in a non-existing titleString
        if ($update && !($titleString && !$title->exists())) {
            if ($status == GE_SUCCESS) {
                $article = new Article($title, 0);
                // don't set the global article and title to this; we don't need to propagate -- but we do for  places
                // NOTE: This doesn't execute the code in FamilyTreePropagator to update familytree_page and add page to tree, but we don't want that to be called
                // because we add the page to the tree below
                if ($title->exists()) {
                    // don't update the page if it already exists, except to add a spouse-family
                    if ($ns == NS_PERSON && @$args['sf']) {
                        $content =& $article->fetchContent();
                        $updated = false;
                        Person::updateFamilyLink('spouse_of_family', '', $args['sf'], $content, $updated);
                        if ($updated) {
                            $article->doEdit($content, 'Add spouse family: [[Family:' . $args['sf'] . ']]', EDIT_UPDATE);
                            StructuredData::purgeTitle($title, +1);
                            // purge person with a fudge factor so family link will be blue
                        }
                    }
                    $revid = 0;
                    // ok for revid to be 0 if page exists because we no longer use revid
                } else {
                    if (!$article->doEdit($text, '')) {
                        $status = GE_WIKI_ERROR;
                    } else {
                        $revid = $article->mRevIdEdited;
                    }
                }
            }
            if ($status == GE_SUCCESS) {
                // add the page to the trees (or to no trees)
                $allTrees = FamilyTreeUtil::getFamilyTrees($wgUser->getName());
                $trees = explode('|', @$args['tree']);
                $checkedTreeIds = array();
                foreach ($allTrees as $tree) {
                    if (in_array(FamilyTreeUtil::toInputName($tree['name']), $trees)) {
                        $checkedTreeIds[] = $tree['id'];
                        //                  if (!FamilyTreeUtil::addPage($dbw, $wgUser, $tree['id'], $title, $revid, 0)) {
                        //                     $status = GE_DB_ERROR;
                        //                  }
                    }
                }
                // update which trees are checked
                FamilyTreeUtil::updateTrees($dbw, $title, $revid, $allTrees, array(), $checkedTreeIds);
            }
            // watch the page
            if ($status == GE_SUCCESS) {
                StructuredData::addWatch($wgUser, $article, true);
            }
        }
        if ($status == GE_SUCCESS) {
            $dbw->commit();
        } else {
            $dbw->rollback();
            if (!$error) {
                $error = 'Unable to create page';
            }
        }
    }
    // return status
    $titleString = '';
    if ($title) {
        $titleString = StructuredData::escapeXml($title->getText());
    }
    return "<addpage status=\"{$status}\" title=\"{$titleString}\" error=\"{$error}\"></addpage>";
}
Beispiel #6
0
 private function updatePage($linkTitle, $tag, $newTitle, &$text, &$textChanged)
 {
     if (!PropagationManager::isPropagatablePage($linkTitle)) {
         return true;
     }
     $result = true;
     $article = StructuredData::getArticle($linkTitle, true);
     if ($article) {
         $content =& $article->fetchContent();
         $updated = false;
         ESINHandler::updateImageLink($tag, $this->titleString, $newTitle, '', $content, $updated);
         if ($updated) {
             $result = $article->doEdit($content, self::PROPAGATE_MESSAGE . ' [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS);
         } else {
             error_log("propagating image " . $this->titleString . " nothing changed in " . $linkTitle->getPrefixedText());
         }
         // if we're not deleting this entry (newTitle is not empty), and the page to update is a redirect (article title != linkTitle),
         // we need to update the page title in the image page text
         if ($newTitle && $linkTitle->getText() != $article->getTitle()->getText()) {
             $old = 'title="' . StructuredData::escapeXml($linkTitle->getText()) . '"';
             $new = 'title="' . StructuredData::escapeXml($article->getTitle()->getText()) . '"';
             $text = str_replace($old, $new, $text);
             $textChanged = true;
         }
     }
     return $result;
 }