function LastChangeTimestamp($add_url) { global $DATE_FORMAT, $TIME_FORMAT; $chan = $this->getChangeEvent(); if (is_null($chan)) { return ' '; } $d = $chan->getDate(); if (preg_match('/^(\\d\\d):(\\d\\d):(\\d\\d)/', get_gedcom_value('DATE:TIME', 2, $chan->getGedcomRecord(), '', false) . ':00', $match)) { $t = mktime($match[1], $match[2], $match[3]); $sort = $d->MinJD() . $match[1] . $match[2] . $match[3]; $text = strip_tags($d->Display(false, "{$DATE_FORMAT} -", array()) . date(" {$TIME_FORMAT}", $t)); } else { $sort = $d->MinJD() . '000000'; $text = strip_tags($d->Display(false, "{$DATE_FORMAT}", array())); } if ($add_url) { $text = '<a name="' . $sort . '" href="' . encode_url($this->getLinkUrl()) . '">' . $text . '</a>'; } return $text; }
function print_todo($block = true, $config = '', $side, $index) { global $pgv_lang, $factarray, $ctype, $PGV_IMAGE_DIR, $PGV_IMAGES, $PGV_BLOCKS; $block = true; // Always restrict this block's height if (empty($config)) { $config = $PGV_BLOCKS['print_todo']['config']; } $id = 'todo'; $title = print_help_link('todo_help', 'qm', '', false, true); if ($PGV_BLOCKS['print_todo']['canconfig']) { if ($ctype == 'gedcom' && PGV_USER_GEDCOM_ADMIN || $ctype == 'user' && PGV_USER_ID) { if ($ctype == 'gedcom') { $name = PGV_GEDCOM; } else { $name = PGV_USER_NAME; } $title .= "<a href=\"javascript: configure block\" onclick=\"window.open('" . encode_url("index_edit.php?name={$name}&ctype={$ctype}&action=configure&side={$side}&index={$index}") . "', '_blank', 'top=50,left=50,width=600,height=350,scrollbars=1,resizable=1'); return false;\">"; $title .= "<img class=\"adminicon\" src=\"{$PGV_IMAGE_DIR}/{$PGV_IMAGES['admin']['small']}\" width=\"15\" height=\"15\" border=\"0\" alt=\"{$pgv_lang['config_block']}\" /></a>"; } } $title .= $pgv_lang['todo_block']; $content = ""; require_once PGV_ROOT . 'js/sorttable.js.htm'; require_once PGV_ROOT . 'includes/classes/class_gedcomrecord.php'; $table_id = 'ID' . floor(microtime() * 1000000); // sorttable requires a unique ID $content .= '<table id="' . $table_id . '" class="sortable list_table center">'; $content .= '<tr>'; $content .= '<th class="list_label">' . $factarray['DATE'] . '</th>'; $content .= '<th class="list_label">' . $pgv_lang['record'] . '</th>'; if ($config['show_unassigned'] == 'yes' || $config['show_other'] == 'yes') { $content .= '<th class="list_label">' . $pgv_lang['username'] . '</th>'; } $content .= '<th class="list_label">' . $factarray['TEXT'] . '</th>'; $content .= '</tr>'; $found = false; $end_jd = $config['show_future'] == 'yes' ? 99999999 : client_jd(); foreach (get_calendar_events(0, $end_jd, '_TODO', PGV_GED_ID) as $todo) { $record = GedcomRecord::getInstance($todo['id']); if ($record && $record->canDisplayDetails()) { $pgvu = get_gedcom_value('_PGVU', 2, $todo['factrec']); if ($pgvu == PGV_USER_NAME || !$pgvu && $config['show_unassigned'] == 'yes' || $pgvu && $config['show_other'] == 'yes') { $content .= '<tr valign="top">'; $content .= '<td class="list_value_wrap">' . str_replace('<a', '<a name="' . $todo['date']->MinJD() . '"', $todo['date']->Display(false)) . '</td>'; $name = $record->getListName(); $content .= '<td class="list_value_wrap" align="' . get_align(PGV_GEDCOM) . '"><a href="' . encode_url($record->getLinkUrl()) . '">' . PrintReady($name) . '</a></td>'; if ($config['show_unassigned'] == 'yes' || $config['show_other'] == 'yes') { $content .= '<td class="list_value_wrap">' . $pgvu . '</td>'; } $text = get_gedcom_value('_TODO', 1, $todo['factrec']); $content .= '<td class="list_value_wrap" align="' . get_align($text) . '">' . PrintReady($text) . '</td>'; $content .= '</tr>'; $found = true; } } } $content .= '</table>'; if (!$found) { $content .= '<p>' . $pgv_lang['todo_nothing'] . '</p>'; } global $THEME_DIR; if ($block) { require $THEME_DIR . 'templates/block_small_temp.php'; } else { require $THEME_DIR . 'templates/block_main_temp.php'; } }
/** * print parents informations * @param Family family * @param Array people * @param String family type * @return html table rows */ function printParentsRows(&$family, &$people, $type) { global $personcount, $pgv_changes, $pgv_lang, $factarray; global $PGV_IMAGE_DIR, $PGV_IMAGES; global $lang_short_cut, $LANGUAGE; $elderdate = ""; //-- new father/husband $styleadd = ""; if (isset($people["newhusb"])) { $styleadd = "red"; ?> <tr> <td class="facts_labelblue"><?php print $people["newhusb"]->getLabel(); ?> </td> <td class="<?php print $this->getPersonStyle($people["newhusb"]); ?> "> <?php print_pedigree_person($people["newhusb"]->getXref(), 2, !$this->isPrintPreview(), 0, $personcount++); ?> </td> </tr> <?php $elderdate = $people["newhusb"]->getBirthDate(); } //-- father/husband if (isset($people["husb"])) { ?> <tr> <td class="facts_label<?php print $styleadd; ?> "><?php print $people["husb"]->getLabel(); ?> </td> <td class="<?php print $this->getPersonStyle($people["husb"]); ?> "> <?php print_pedigree_person($people["husb"]->getXref(), 2, !$this->isPrintPreview(), 0, $personcount++); ?> </td> </tr> <?php $elderdate = $people["husb"]->getBirthDate(); } //-- missing father if ($type == "parents" && !isset($people["husb"]) && !isset($people["newhusb"])) { if (!$this->isPrintPreview() && PGV_USER_CAN_EDIT && $this->indi->canDisplayDetails()) { ?> <tr> <td class="facts_label"><?php print $pgv_lang["add_father"]; ?> </td> <td class="facts_value"><?php print_help_link("edit_add_parent_help", "qm"); ?> <a href="javascript <?php print $pgv_lang["add_father"]; ?> " onclick="return addnewparentfamily('<?php print $this->pid; ?> ', 'HUSB', '<?php print $family->getXref(); ?> ');"><?php print $pgv_lang["add_father"]; ?> </a></td> </tr> <?php } } //-- missing husband if ($type == "spouse" && $this->indi->equals($people["wife"]) && !isset($people["husb"]) && !isset($people["newhusb"])) { if (!$this->isPrintPreview() && PGV_USER_CAN_EDIT && $this->indi->canDisplayDetails()) { ?> <tr> <td class="facts_label"><?php print $pgv_lang["add_husb"]; ?> </td> <td class="facts_value"><a href="javascript:;" onclick="return addnewspouse('<?php print $family->getXref(); ?> ', 'HUSB');"><?php print $pgv_lang["add_husb_to_family"]; ?> </a></td> </tr> <?php } } //-- new mother/wife $styleadd = ""; if (isset($people["newwife"])) { $styleadd = "red"; ?> <tr> <td class="facts_labelblue"><?php print $people["newwife"]->getLabel($elderdate); ?> </td> <td class="<?php print $this->getPersonStyle($people["newwife"]); ?> "> <?php print_pedigree_person($people["newwife"]->getXref(), 2, !$this->isPrintPreview(), 0, $personcount++); ?> </td> </tr> <?php } //-- mother/wife if (isset($people["wife"])) { ?> <tr> <td class="facts_label<?php print $styleadd; ?> "><?php print $people["wife"]->getLabel($elderdate); ?> </td> <td class="<?php print $this->getPersonStyle($people["wife"]); ?> "> <?php print_pedigree_person($people["wife"]->getXref(), 2, !$this->isPrintPreview(), 0, $personcount++); ?> </td> </tr> <?php } //-- missing mother if ($type == "parents" && !isset($people["wife"]) && !isset($people["newwife"])) { if (!$this->isPrintPreview() && PGV_USER_CAN_EDIT && $this->indi->canDisplayDetails()) { ?> <tr> <td class="facts_label"><?php print $pgv_lang["add_mother"]; ?> </td> <td class="facts_value"><?php print_help_link("edit_add_parent_help", "qm"); ?> <a href="javascript:;" onclick="return addnewparentfamily('<?php print $this->pid; ?> ', 'WIFE', '<?php print $family->getXref(); ?> ');"><?php print $pgv_lang["add_mother"]; ?> </a></td> </tr> <?php } } //-- missing wife if ($type == "spouse" && $this->indi->equals($people["husb"]) && !isset($people["wife"]) && !isset($people["newwife"])) { if (!$this->isPrintPreview() && PGV_USER_CAN_EDIT && $this->indi->canDisplayDetails()) { ?> <tr> <td class="facts_label"><?php print $pgv_lang["add_wife"]; ?> </td> <td class="facts_value"><a href="javascript:;" onclick="return addnewspouse('<?php print $family->getXref(); ?> ', 'WIFE');"><?php print $pgv_lang["add_wife_to_family"]; ?> </a></td> </tr> <?php } } //-- marriage row if ($family->getMarriageRecord() != "" || PGV_USER_CAN_EDIT) { $styleadd = ""; $date = $family->getMarriageDate(); $place = $family->getMarriagePlace(); $famid = $family->getXref(); if (!$date && $this->show_changes && isset($pgv_changes[$famid . "_" . $GEDCOM])) { $famrec = find_updated_record($famid); $marrrec = get_sub_record(1, "1 MARR", $famrec); if ($marrrec != $family->getMarriageRecord()) { $date = new GedcomDate(get_gedcom_value("MARR:DATE", 1, $marrrec, '', false)); $place = get_gedcom_value("MARR:PLAC", 1, $marrrec, '', false); $styleadd = "blue"; } } ?> <tr> <td class="facts_label"><br /> </td> <td class="facts_value<?php print $styleadd; ?> "> <?php //echo "<span class=\"details_label\">".$factarray["NCHI"].": </span>".$family->getNumberOfChildren()."<br />"; ?> <?php if ($date && $date->isOK() || $place) { $marr_type = "MARR_" . strtoupper($family->getMarriageType()); if (isset($factarray[$marr_type])) { echo "<span class=\"details_label\">" . $factarray[$marr_type] . ": </span>"; } else { echo "<span class=\"details_label\">" . $factarray["MARR"] . ": </span>" . $family->getMarriageType(); } if ($date) { echo $date->Display(false); if (!empty($place)) { echo ' -- '; } } if (!empty($place)) { echo $place; } } else { if (get_sub_record(1, "1 _NMR", find_family_record($famid))) { // Allow special processing for different languages $func = "fact_NMR_localisation_{$lang_short_cut[$LANGUAGE]}"; if (function_exists($func)) { // Localise the _NMR facts $func("_NMR", $famid); } echo $factarray["_NMR"]; } else { if (get_sub_record(1, "1 _NMAR", find_family_record($famid))) { // Allow special processing for different languages $func = "fact_NMR_localisation_{$lang_short_cut[$LANGUAGE]}"; if (function_exists($func)) { // Localise the _NMR facts $func("_NMAR", $famid); } echo $factarray["_NMAR"]; } else { if ($family->getMarriageRecord() == "" && PGV_USER_CAN_EDIT) { print "<a href=\"#\" onclick=\"return add_new_record('" . $famid . "', 'MARR');\">" . $pgv_lang['add_marriage'] . "</a>"; } else { $factdetail = explode(' ', trim($family->getMarriageRecord())); if ($family->getMarriageType()) { $marr_type = "MARR_" . strtoupper($family->getMarriageType()); } else { $marr_type = "MARR"; } if (isset($factarray[$marr_type])) { if (isset($factdetail)) { if (count($factdetail) == 3) { if (strtoupper($factdetail[2]) == "Y") { echo "<span class=\"details_label\">" . $factarray[$marr_type] . ": </span>" . $pgv_lang["yes"]; } else { if (strtoupper($factdetail[2]) == "N") { echo "<span class=\"details_label\">" . $factarray[$marr_type] . ": </span>" . $pgv_lang["no"]; } } } } } else { echo "<span class=\"details_label\">" . $factarray["MARR"] . ": </span>" . $family->getMarriageType(); } } } } } ?> </td> </tr> <?php } }
/** * print a media row in a table * @param string $rtype whether this is a 'new', 'old', or 'normal' media row... this is used to determine if the rows should be printed with an outline color * @param array $rowm An array with the details about this media item * @param string $pid The record id this media item was attached to */ function media_reorder_row($rtype, $rowm, $pid) { global $PGV_IMAGE_DIR, $PGV_IMAGES, $view, $MEDIA_DIRECTORY, $TEXT_DIRECTION; global $SHOW_ID_NUMBERS, $GEDCOM, $factarray, $pgv_lang, $THUMBNAIL_WIDTH, $USE_MEDIA_VIEWER; global $SEARCH_SPIDER; global $t, $n, $item, $items, $p, $edit, $SERVER_URL, $reorder, $LB_AL_THUMB_LINKS, $note, $rowm; global $LB_URL_WIDTH, $LB_URL_HEIGHT, $order1, $mediaType; if (!isset($rowm)) { $rowm = $row; } print "<li class=\"facts_value\" style=\"list-style:none;cursor:move;margin-bottom:2px;\" id=\"li_" . $rowm['m_media'] . "\" >"; //print $rtype." ".$rowm["m_media"]." ".$pid; if (!displayDetailsById($rowm['m_media'], 'OBJE') || FactViewRestricted($rowm['m_media'], $rowm['m_gedrec'])) { //print $rowm['m_media']." no privacy "; return false; } $styleadd = ""; if ($rtype == 'new') { $styleadd = "change_new"; } if ($rtype == 'old') { $styleadd = "change_old"; } // NOTE Start printing the media details $thumbnail = thumbnail_file($rowm["m_file"], true, false, $pid); // $isExternal = stristr($thumbnail,"://"); $isExternal = isFileExternal($thumbnail); $linenum = 0; // NOTE Get the title of the media if (showFactDetails("OBJE", $pid)) { $mediaTitle = $rowm["m_titl"]; $subtitle = get_gedcom_value("TITL", 2, $rowm["mm_gedrec"]); if (!empty($subtitle)) { $mediaTitle = $subtitle; } $mainMedia = check_media_depth($rowm["m_file"], "NOTRUNC"); if ($mediaTitle == "") { $mediaTitle = basename($rowm["m_file"]); } print "\n" . "<table class=\"pic\"><tr>" . "\n"; print "<td width=\"80\" valign=\"top\" align=\"center\" >" . "\n"; // Get info on how to handle this media file $mediaInfo = mediaFileInfo($mainMedia, $thumbnail, $rowm["m_media"], $mediaTitle, ''); //-- Thumbnail field print "<img src=\"" . $mediaInfo['thumb'] . "\" height=\"38\" border=\"0\" "; if (eregi("1 SOUR", $rowm['m_gedrec'])) { print " alt=\"" . PrintReady($mediaTitle) . "\" title=\"" . PrintReady($mediaTitle) . "\nSource info available\" />"; } else { print " alt=\"" . PrintReady($mediaTitle) . "\" title=\"" . PrintReady($mediaTitle) . "\" />"; } //print media info $ttype2 = preg_match("/\\d TYPE (.*)/", $rowm["m_gedrec"], $match); if ($ttype2 > 0) { $mediaType = trim($match[1]); $varName = "TYPE__" . strtolower($mediaType); if (isset($pgv_lang[$varName])) { $mediaType = $pgv_lang[$varName]; } // print "\n\t\t\t<br /><span class=\"label\">".$pgv_lang["type"].": </span> <span class=\"field\">$mediaType</span>"; } print "\n" . "</td><td> </td>" . "\n"; print "<td valign=\"top\" align=\"left\">"; //print "<font color=\"blue\">"; print $rowm['m_media']; //print "</font>"; print "<b>"; print " " . $mediaType; print "</b>"; print "<br>" . "\n"; print $mediaTitle . "\n"; print "</td>" . "\n"; print "</tr>"; print "</table>" . "\n"; } if (!isset($j)) { $j = 0; } else { $j = $j; } $media_data = $rowm['m_media']; print "<input type=\"hidden\" name=\"order1[{$media_data}]\" value=\"{$j}\" />"; print "</li>"; print "\n\n"; return true; }
/** * XML <List> start element handler * * @see ListEHandler() * * @param array $attrs an array of key value pairs for the attributes */ function ListSHandler($attrs) { global $gedrec, $repeats, $repeatBytes, $list, $repeatsStack, $processRepeats, $parser, $vars, $sortby; global $GEDCOM; $processRepeats++; if ($processRepeats > 1) { return; } $match = array(); if (isset($attrs['sortby'])) { $sortby = $attrs['sortby']; if (preg_match("/\\\$(\\w+)/", $sortby, $match)) { $sortby = $vars[$match[1]]['id']; $sortby = trim($sortby); } } else { $sortby = "NAME"; } if (isset($attrs['list'])) { $listname = $attrs['list']; } else { $listname = "individual"; } // Some filters/sorts can be applied using SQL, while others require PHP switch ($listname) { case "pending": $rows = WT_DB::prepare("SELECT xref, gedcom_id, CASE new_gedcom WHEN '' THEN old_gedcom ELSE new_gedcom END AS gedcom" . " FROM `##change`" . " WHERE (xref, change_id) IN (" . " SELECT xref, MAX(change_id)" . " FROM `##change`" . " WHERE status='pending' AND gedcom_id=?" . " GROUP BY xref" . " )")->execute(array(WT_GED_ID))->fetchAll(); $list = array(); foreach ($rows as $row) { $list[] = WT_GedcomRecord::getInstance($row->xref, $row->gedcom_id, $row->gedcom); } break; case "individual": case "family": $sql_col_prefix = substr($listname, 0, 1) . "_"; // i_ for individual, f_ for family, etc. $sql_join = array(); $sql_where = array($sql_col_prefix . "file=" . WT_GED_ID); $sql_order_by = array(); foreach ($attrs as $attr => $value) { if (strpos($attr, "filter") === 0 && $value) { // Substitute global vars $value = preg_replace_callback('/\\$(\\w+)/', function ($matches) use($vars) { return $vars[$matches[1]]['id']; }, $value); // Convert the various filters into SQL if (preg_match('/^(\\w+):DATE (LTE|GTE) (.+)$/', $value, $match)) { $sql_join[] = "JOIN `##dates` AS {$attr} ON ({$attr}.d_file={$sql_col_prefix}file AND {$attr}.d_gid={$sql_col_prefix}id)"; $sql_where[] = "{$attr}.d_fact='{$match[1]}'"; $date = new WT_Date($match[3]); if ($match[2] == "LTE") { $sql_where[] = "{$attr}.d_julianday2<=" . $date->minJD(); } else { $sql_where[] = "{$attr}.d_julianday1>=" . $date->minJD(); } if ($sortby == $match[1]) { $sortby = ""; $sql_order_by[] = "{$attr}.d_julianday1"; } unset($attrs[$attr]); // This filter has been fully processed } elseif ($listname == "individual" && preg_match('/^NAME CONTAINS (.*)$/', $value, $match)) { // Do nothing, unless you have to if ($match[1] != "" or $sortby == "NAME") { $sql_join[] = "JOIN `##name` AS {$attr} ON (n_file={$sql_col_prefix}file AND n_id={$sql_col_prefix}id)"; // Search the DB only if there is any name supplied if ($match[1] != "") { $names = explode(" ", $match[1]); foreach ($names as $name) { $sql_where[] = "{$attr}.n_full LIKE " . WT_DB::quote("%{$name}%"); } } // Let the DB do the name sorting even when no name was entered if ($sortby == "NAME") { $sortby = ""; $sql_order_by[] = "{$attr}.n_sort"; } } unset($attrs[$attr]); // This filter has been fully processed } elseif ($listname == "individual" && preg_match('/^REGEXP \\/(.+)\\//', $value, $match)) { $sql_where[] = "i_gedcom REGEXP '" . $match[1] . "'"; unset($attrs[$attr]); // This filter has been fully processed } elseif ($listname == "family" && preg_match('/^REGEXP \\/(.+)\\//', $value, $match)) { $sql_where[] = "f_gedcom REGEXP '" . $match[1] . "'"; unset($attrs[$attr]); // This filter has been fully processed } elseif ($listname == "family" && preg_match('/^NAME CONTAINS (.+)$/', $value, $match)) { // Eventually, family "names" will be stored in wt_name. Until then, an extra is needed.... $sql_join[] = "JOIN `##link` AS {$attr}a ON ({$attr}a.l_file={$sql_col_prefix}file AND {$attr}a.l_from={$sql_col_prefix}id)"; $sql_join[] = "JOIN `##name` AS {$attr}b ON ({$attr}b.n_file={$sql_col_prefix}file AND n_id={$sql_col_prefix}id)"; $sql_where[] = "{$attr}a.l_type=IN ('HUSB, 'WIFE')"; $sql_where[] = "{$attr}.n_full LIKE " . WT_DB::quote("%{$match[1]}%"); if ($sortby == "NAME") { $sortby = ""; $sql_order_by[] = "{$attr}.n_sort"; } unset($attrs[$attr]); // This filter has been fully processed } elseif (preg_match('/^(?:\\w+):PLAC CONTAINS (.+)$/', $value, $match)) { $sql_join[] = "JOIN `##places` AS {$attr}a ON ({$attr}a.p_file={$sql_col_prefix}file)"; $sql_join[] = "JOIN `##placelinks` AS {$attr}b ON ({$attr}a.p_file={$attr}b.pl_file AND {$attr}b.pl_p_id={$attr}a.p_id AND {$attr}b.pl_gid={$sql_col_prefix}id)"; $sql_where[] = "{$attr}a.p_place LIKE " . WT_DB::quote("%{$match[1]}%"); // Don't unset this filter. This is just the first primary PLAC filter to reduce the returned list from the DB } elseif ($listname == "individual" && preg_match('/^(\\w*):*(\\w*) CONTAINS (.+)$/', $value, $match)) { $query = ""; // Level 1 tag if ($match[1] != "") { $query .= "%1 {$match[1]}%"; } // Level 2 tag if ($match[2] != "") { $query .= "%2 {$match[2]}%"; } // Contains what? if ($match[3] != "") { $query .= "%{$match[3]}%"; } $sql_where[] = "i_gedcom LIKE " . WT_DB::quote($query); } elseif ($listname == "family" && preg_match('/^(\\w*):*(\\w*) CONTAINS (.+)$/', $value, $match)) { $query = ""; // Level 1 tag if ($match[1] != "") { $query .= "%1 {$match[1]}%"; } // Level 2 tag if ($match[2] != "") { $query .= "%2 {$match[2]}%"; } // Contains what? if ($match[3] != "") { $query .= "%{$match[3]}%"; } $sql_where[] = "f_gedcom LIKE " . WT_DB::quote($query); } else { // TODO: what other filters can we apply in SQL? } } } if ($listname == "family") { $list = search_fams_custom($sql_join, $sql_where, $sql_order_by); } else { $list = search_indis_custom($sql_join, $sql_where, $sql_order_by); } // Clean up the SQL queries - they will not be used again unset($sql_join, $sql_where, $sql_order_by); break; default: die("Invalid list name: {$listname}"); } $filters = array(); $filters2 = array(); if (isset($attrs['filter1']) and count($list) > 0) { foreach ($attrs as $key => $value) { if (preg_match("/filter(\\d)/", $key)) { $condition = $value; if (preg_match("/@(\\w+)/", $condition, $match)) { $id = $match[1]; $value = "''"; if ($id == "ID") { if (preg_match("/0 @(.+)@/", $gedrec, $match)) { $value = "'" . $match[1] . "'"; } } elseif ($id == "fact") { $value = "'{$fact}'"; } elseif ($id == "desc") { $value = "'{$desc}'"; } else { if (preg_match("/\\d {$id} (.+)/", $gedrec, $match)) { $value = "'" . str_replace("@", "", trim($match[1])) . "'"; } } $condition = preg_replace("/@{$id}/", $value, $condition); } //-- handle regular expressions if (preg_match("/([A-Z:]+)\\s*([^\\s]+)\\s*(.+)/", $condition, $match)) { $tag = trim($match[1]); $expr = trim($match[2]); $val = trim($match[3]); if (preg_match("/\\\$(\\w+)/", $val, $match)) { $val = $vars[$match[1]]['id']; $val = trim($val); } if ($val) { $searchstr = ""; $tags = explode(":", $tag); //-- only limit to a level number if we are specifically looking at a level if (count($tags) > 1) { $level = 1; foreach ($tags as $t) { if (!empty($searchstr)) { $searchstr .= "[^\n]*(\n[2-9][^\n]*)*\n"; } //-- search for both EMAIL and _EMAIL... silly double gedcom standard if ($t == "EMAIL" || $t == "_EMAIL") { $t = "_?EMAIL"; } $searchstr .= $level . " " . $t; $level++; } } else { if ($tag == "EMAIL" || $tag == "_EMAIL") { $tag = "_?EMAIL"; } $t = $tag; $searchstr = "1 " . $tag; } switch ($expr) { case "CONTAINS": if ($t == "PLAC") { $searchstr .= "[^\n]*[, ]*" . $val; } else { $searchstr .= "[^\n]*" . $val; } $filters[] = $searchstr; break; default: $filters2[] = array("tag" => $tag, "expr" => $expr, "val" => $val); break; } } } } } } //-- apply other filters to the list that could not be added to the search string if ($filters) { foreach ($list as $key => $record) { foreach ($filters as $filter) { if (!preg_match("/" . $filter . "/i", $record->privatizeGedcom(WT_USER_ACCESS_LEVEL))) { unset($list[$key]); break; } } } } if ($filters2) { $mylist = array(); foreach ($list as $indi) { $key = $indi->getXref(); $grec = $indi->privatizeGedcom(WT_USER_ACCESS_LEVEL); $keep = true; foreach ($filters2 as $filter) { if ($keep) { $tag = $filter['tag']; $expr = $filter['expr']; $val = $filter['val']; if ($val == "''") { $val = ""; } $tags = explode(":", $tag); $t = end($tags); $v = get_gedcom_value($tag, 1, $grec); //-- check for EMAIL and _EMAIL (silly double gedcom standard :P) if ($t == "EMAIL" && empty($v)) { $tag = str_replace("EMAIL", "_EMAIL", $tag); $tags = explode(":", $tag); $t = end($tags); $v = get_sub_record(1, $tag, $grec); } $level = count($tags); switch ($expr) { case "GTE": if ($t == "DATE") { $date1 = new WT_Date($v); $date2 = new WT_Date($val); $keep = WT_Date::Compare($date1, $date2) >= 0; } elseif ($val >= $v) { $keep = true; } break; case "LTE": if ($t == "DATE") { $date1 = new WT_Date($v); $date2 = new WT_Date($val); $keep = WT_Date::Compare($date1, $date2) <= 0; } elseif ($val >= $v) { $keep = true; } break; default: if ($v == $val) { $keep = true; } else { $keep = false; } break; } } } if ($keep) { $mylist[$key] = $indi; } } $list = $mylist; } switch ($sortby) { case "NAME": uasort($list, array("WT_GedcomRecord", "compare")); break; case "CHAN": uasort($list, function (WT_GedcomRecord $x, WT_GedcomRecord $y) { $f1 = $x->getFirstFact('CHAN'); $f2 = $y->getFirstFact('CHAN'); if ($f1 && $f2) { $d1 = $f1->getDate(); $d2 = $f2->getDate(); $cmp = WT_Date::compare($d1, $d2); if ($cmp) { return $cmp; } else { // Same date. Compare times preg_match('/\\n3 TIME (.+)/', $f1->getGedcom(), $m1); preg_match('/\\n3 TIME (.+)/', $f2->getGedcom(), $m2); return strcmp($m1[1], $m2[1]); } } else { return 0; } }); break; case "BIRT:DATE": uasort($list, array("WT_Individual", "CompareBirtDate")); break; case "DEAT:DATE": uasort($list, array("WT_Individual", "CompareDeatDate")); break; case "MARR:DATE": uasort($list, array("WT_Family", "compareMarrDate")); break; default: // unsorted or already sorted by SQL break; } array_push($repeatsStack, array($repeats, $repeatBytes)); $repeatBytes = xml_get_current_line_number($parser) + 1; }
/** * prints a form to add an individual or edit an individual's name * * @param string $nextaction the next action the edit_interface.php file should take after the form is submitted * @param string $famid the family that the new person should be added to * @param string $namerec the name subrecord when editing a name * @param string $famtag how the new person is added to the family */ function print_indi_form($nextaction, $famid, $linenum = "", $namerec = "", $famtag = "CHIL", $sextag = "") { global $pgv_lang, $factarray, $pid, $PGV_IMAGE_DIR, $PGV_IMAGES, $WORD_WRAPPED_NOTES; global $NPFX_accept, $SPFX_accept, $NSFX_accept, $FILE_FORM_accept, $GEDCOM, $NAME_REVERSE; global $bdm, $TEXT_DIRECTION, $STANDARD_NAME_FACTS, $REVERSED_NAME_FACTS, $ADVANCED_NAME_FACTS, $ADVANCED_PLAC_FACTS, $SURNAME_TRADITION; global $QUICK_REQUIRED_FACTS, $QUICK_REQUIRED_FAMFACTS; $bdm = ""; // used to copy '1 SOUR' to '2 SOUR' for BIRT DEAT MARR init_calendar_popup(); echo "<form method=\"post\" name=\"addchildform\" onsubmit=\"return checkform();\">\n"; echo "<input type=\"hidden\" name=\"action\" value=\"{$nextaction}\" />\n"; echo "<input type=\"hidden\" name=\"linenum\" value=\"{$linenum}\" />\n"; echo "<input type=\"hidden\" name=\"famid\" value=\"{$famid}\" />\n"; echo "<input type=\"hidden\" name=\"pid\" value=\"{$pid}\" />\n"; echo "<input type=\"hidden\" name=\"famtag\" value=\"{$famtag}\" />\n"; echo "<input type=\"submit\" value=\"" . $pgv_lang["save"] . "\" />\n"; echo "<input type=\"hidden\" name=\"goto\" value=\"\" />\n"; if (preg_match('/^add(child|spouse|newparent|newrepository)/', $nextaction)) { echo "<input type=\"submit\" value=\"{$pgv_lang['saveandgo']}\" onclick=\"document.addchildform.goto.value='new';\"/>\n"; } echo "<table class=\"facts_table\">"; // When adding a new child, specify the pedigree if ($nextaction == 'addchildaction') { add_simple_tag("0 PEDI"); } // Populate the standard NAME field and subfields $name_fields = array(); if (!$NAME_REVERSE) { foreach ($STANDARD_NAME_FACTS as $tag) { $name_fields[$tag] = get_gedcom_value($tag, 0, $namerec); } } else { foreach ($REVERSED_NAME_FACTS as $tag) { $name_fields[$tag] = get_gedcom_value($tag, 0, $namerec); } } $new_marnm = ''; // Inherit surname from parents, spouse or child if (empty($namerec)) { // We'll need the parent's name to set the child's surname if (isset($pgv_changes[$famid . "_" . $GEDCOM])) { $famrec = find_updated_record($famid); } else { $famrec = find_family_record($famid); } $parents = find_parents_in_record($famrec); $father_name = get_gedcom_value('NAME', 0, find_person_record($parents['HUSB'])); $mother_name = get_gedcom_value('NAME', 0, find_person_record($parents['WIFE'])); // We'll need the spouse/child's name to set the spouse/parent's surname if (isset($pgv_changes[$pid . "_" . $GEDCOM])) { $prec = find_updated_record($pid); } else { $prec = find_person_record($pid); } $indi_name = get_gedcom_value('NAME', 0, $prec); // Different cultures do surnames differently switch ($SURNAME_TRADITION) { case 'spanish': //Mother: Maria /AAAA BBBB/ //Father: Jose /CCCC DDDD/ //Child: Pablo /CCCC AAAA/ switch ($nextaction) { case 'addchildaction': if (preg_match('/\\/(\\S+)\\s+\\S+\\//', $mother_name, $matchm) && preg_match('/\\/(\\S+)\\s+\\S+\\//', $father_name, $matchf)) { $name_fields['SURN'] = $matchf[1] . ' ' . $matchm[1]; $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/'; } break; case 'addnewparentaction': if ($famtag == 'HUSB' && preg_match('/\\/(\\S+)\\s+\\S+\\//', $indi_name, $match)) { $name_fields['SURN'] = $match[1] . ' '; $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/'; } if ($famtag == 'WIFE' && preg_match('/\\/\\S+\\s+(\\S+)\\//', $indi_name, $match)) { $name_fields['SURN'] = $match[1] . ' '; $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/'; } break; } break; case 'portuguese': //Mother: Maria /AAAA BBBB/ //Father: Jose /CCCC DDDD/ //Child: Pablo /BBBB DDDD/ switch ($nextaction) { case 'addchildaction': if (preg_match('/\\/\\S+\\s+(\\S+)\\//', $mother_name, $matchm) && preg_match('/\\/\\S+\\s+(\\S+)\\//', $father_name, $matchf)) { $name_fields['SURN'] = $matchf[1] . ' ' . $matchm[1]; $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/'; } break; case 'addnewparentaction': if ($famtag == 'HUSB' && preg_match('/\\/\\S+\\s+(\\S+)\\//', $indi_name, $match)) { $name_fields['SURN'] = ' ' . $match[1]; $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/'; } if ($famtag == 'WIFE' && preg_match('/\\/(\\S+)\\s+\\S+\\//', $indi_name, $match)) { $name_fields['SURN'] = ' ' . $match[1]; $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/'; } break; } break; case 'icelandic': // Sons get their father's given name plus "sson" // Daughters get their father's given name plus "sdottir" switch ($nextaction) { case 'addchildaction': if ($sextag == 'M' && preg_match('/(\\S+)\\s+\\/.*\\//', $father_name, $match)) { $name_fields['SURN'] = preg_replace('/s$/', '', $match[1]) . 'sson'; $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/'; } if ($sextag == 'F' && preg_match('/(\\S+)\\s+\\/.*\\//', $father_name, $match)) { $name_fields['SURN'] = preg_replace('/s$/', '', $match[1]) . 'sdottir'; $name_fields['NAME'] = '/' . $name_fields['SURN'] . '/'; } break; case 'addnewparentaction': if ($famtag == 'HUSB' && preg_match('/(\\S+)sson\\s+\\/.*\\//i', $indi_name, $match)) { $name_fields['GIVN'] = $match[1]; $name_fields['NAME'] = $name_fields['GIVN'] . ' //'; } if ($famtag == 'WIFE' && preg_match('/(\\S+)sdottir\\s+\\/.*\\//i', $indi_name, $match)) { $name_fields['GIVN'] = $match[1]; $name_fields['NAME'] = $name_fields['GIVN'] . ' //'; } break; } break; case 'paternal': case 'polish': // Father gives his surname to his wife and children switch ($nextaction) { case 'addspouseaction': if ($famtag == 'WIFE' && preg_match('/\\/(.*)\\//', $indi_name, $match)) { if ($SURNAME_TRADITION == 'polish') { $match[1] = preg_replace(array('/ski$/', '/cki$/', '/dzki$/'), array('ska', 'cka', 'dzka'), $match[1]); } $new_marnm = $match[1]; } break; case 'addchildaction': if (preg_match('/\\/((?:[a-z]{2,3}\\s+)*)(.*)\\//i', $father_name, $match)) { if ($SURNAME_TRADITION == 'polish' && $sextag == 'F') { $match[2] = preg_replace(array('/ski$/', '/cki$/', '/dzki$/'), array('ska', 'cka', 'dzka'), $match[2]); } $name_fields['SPFX'] = trim($match[1]); $name_fields['SURN'] = $match[2]; $name_fields['NAME'] = "/{$match[1]}{$match[2]}/"; } break; case 'addnewparentaction': if ($famtag == 'HUSB' && preg_match('/\\/((?:[a-z]{2,3}\\s+)*)(.*)\\//i', $indi_name, $match)) { if ($SURNAME_TRADITION == 'polish' && $sextag == 'M') { $match[2] = preg_replace(array('/ska$/', '/cka$/', '/dzka$/'), array('ski', 'cki', 'dzki'), $match[2]); } $name_fields['SPFX'] = trim($match[1]); $name_fields['SURN'] = $match[2]; $name_fields['NAME'] = "/{$match[1]}{$match[2]}/"; } break; } break; } } // Make sure there are two slashes in the name if (!preg_match('/\\//', $name_fields['NAME'])) { $name_fields['NAME'] .= ' /'; } if (!preg_match('/\\/.*\\//', $name_fields['NAME'])) { $name_fields['NAME'] .= '/'; } // Populate any missing 2 XXXX fields from the 1 NAME field $npfx_accept = implode('|', $NPFX_accept); if (preg_match("/((({$npfx_accept})\\.? +)*)([^\n\\/\"]*)(\"(.*)\")? *\\/(([a-z]{2,3} +)*)(.*)\\/ *(.*)/i", $name_fields['NAME'], $name_bits)) { if (empty($name_fields['NPFX'])) { $name_fields['NPFX'] = $name_bits[1]; } if (!$NAME_REVERSE && empty($name_fields['GIVN'])) { $name_fields['GIVN'] = $name_bits[4]; } if (empty($name_fields['SPFX']) && empty($name_fields['SURN'])) { $name_fields['SPFX'] = trim($name_bits[7]); $name_fields['SURN'] = $name_bits[9]; } if (empty($name_fields['NSFX'])) { $name_fields['NSFX'] = $name_bits[10]; } if ($NAME_REVERSE && empty($name_fields['GIVN'])) { $name_fields['GIVN'] = $name_bits[4]; } // Don't automatically create an empty NICK - it is an "advanced" field. if (empty($name_fields['NICK']) && !empty($name_bits[6]) && !preg_match('/^2 NICK/m', $namerec)) { $name_fields['NICK'] = $name_bits[6]; } } // Edit the standard name fields foreach ($name_fields as $tag => $value) { add_simple_tag("0 {$tag} {$value}"); } // Get the advanced name fields $adv_name_fields = array(); if (preg_match_all('/(' . PGV_REGEX_TAG . ')/', $ADVANCED_NAME_FACTS, $match)) { foreach ($match[1] as $tag) { $adv_name_fields[$tag] = ''; } } // This is a custom tag, but PGV uses it extensively. if ($SURNAME_TRADITION == 'paternal' || $SURNAME_TRADITION == 'polish' || preg_match('/2 _MARNM/', $namerec)) { $adv_name_fields['_MARNM'] = ''; } foreach ($adv_name_fields as $tag => $dummy) { // Edit existing tags if (preg_match_all("/2 {$tag} (.+)/", $namerec, $match)) { foreach ($match[1] as $value) { if ($tag == '_MARNM') { $mnsct = preg_match('/\\/(.+)\\//', $value, $match2); $marnm_surn = ""; if ($mnsct > 0) { $marnm_surn = $match2[1]; } add_simple_tag("2 _MARNM " . $value); add_simple_tag("2 _MARNM_SURN " . $marnm_surn); } else { add_simple_tag("2 {$tag} {$value}", "", fact_label("NAME:{$tag}")); } } } // Allow a new row to be entered if there was no row provided if (count($match[1]) == 0 && empty($name_fields[$tag]) || $tag != '_HEB' && $tag != 'NICK') { if ($tag == '_MARNM') { add_simple_tag("0 _MARNM"); add_simple_tag("0 _MARNM_SURN {$new_marnm}"); } else { add_simple_tag("0 {$tag}", "", fact_label("NAME:{$tag}")); } } } // Handle any other NAME subfields that aren't included above (SOUR, NOTE, _CUSTOM, etc) if ($namerec != "" && $namerec != "NEW") { $gedlines = split("\n", $namerec); // -- find the number of lines in the record $fields = explode(' ', $gedlines[0]); $glevel = $fields[0]; $level = $glevel; $type = trim($fields[1]); $level1type = $type; $tags = array(); $i = 0; do { if (!isset($name_fields[$type]) && !isset($adv_name_fields[$type])) { $text = ""; for ($j = 2; $j < count($fields); $j++) { if ($j > 2) { $text .= " "; } $text .= $fields[$j]; } $iscont = false; while ($i + 1 < count($gedlines) && preg_match("/" . ($level + 1) . " (CON[CT])\\s?(.*)/", $gedlines[$i + 1], $cmatch) > 0) { $iscont = true; if ($cmatch[1] == "CONT") { $text .= "\n"; } if ($WORD_WRAPPED_NOTES) { $text .= " "; } $text .= $cmatch[2]; $i++; } add_simple_tag($level . " " . $type . " " . $text); } $tags[] = $type; $i++; if (isset($gedlines[$i])) { $fields = explode(' ', $gedlines[$i]); $level = $fields[0]; if (isset($fields[1])) { $type = $fields[1]; } } } while ($level > $glevel && $i < count($gedlines)); } // If we are adding a new individual, add the basic details if ($nextaction != 'update') { echo '</table><br/><table class="facts_table">'; // 1 SEX if ($famtag == "HUSB" || $sextag == "M") { add_simple_tag("0 SEX M"); } elseif ($famtag == "WIFE" || $sextag == "F") { add_simple_tag("0 SEX F"); } else { add_simple_tag("0 SEX"); } $bdm = "BD"; if (preg_match_all('/(' . PGV_REGEX_TAG . ')/', $QUICK_REQUIRED_FACTS, $matches)) { foreach ($matches[1] as $match) { if (!in_array($match, explode('|', PGV_EVENTS_DEAT))) { addSimpleTags($match); } } } //-- if adding a spouse add the option to add a marriage fact to the new family if ($nextaction == 'addspouseaction' || $nextaction == 'addnewparentaction' && $famid != 'new') { $bdm .= "M"; if (preg_match_all('/(' . PGV_REGEX_TAG . ')/', $QUICK_REQUIRED_FAMFACTS, $matches)) { foreach ($matches[1] as $match) { addSimpleTags($match); } } } if (preg_match_all('/(' . PGV_REGEX_TAG . ')/', $QUICK_REQUIRED_FACTS, $matches)) { foreach ($matches[1] as $match) { if (in_array($match, explode('|', PGV_EVENTS_DEAT))) { addSimpleTags($match); } } } } if (PGV_USER_IS_ADMIN) { echo "<tr><td class=\"descriptionbox " . $TEXT_DIRECTION . " wrap width25\">"; print_help_link("no_update_CHAN_help", "qm"); echo $pgv_lang["admin_override"] . "</td><td class=\"optionbox wrap\">\n"; echo "<input type=\"checkbox\" name=\"preserve_last_changed\" />\n"; echo $pgv_lang["no_update_CHAN"] . "<br />\n"; if (isset($famrec)) { $event = new Event(get_sub_record(1, "1 CHAN", $famrec)); echo format_fact_date($event, false, true); } echo "</td></tr>\n"; } echo "</table>\n"; if ($nextaction == 'update') { // GEDCOM 5.5.1 spec says NAME doesn't get a OBJE print_add_layer('SOUR'); print_add_layer('NOTE'); print_add_layer('SHARED_NOTE'); } else { print_add_layer('SOUR', 1); print_add_layer('NOTE', 1); print_add_layer('SHARED_NOTE', 1); print_add_layer('OBJE', 1); } echo "<input type=\"submit\" value=\"" . $pgv_lang["save"] . "\" />\n"; if (preg_match('/^add(child|spouse|newparent|source)/', $nextaction)) { echo "<input type=\"submit\" value=\"{$pgv_lang['saveandgo']}\" onclick=\"document.addchildform.goto.value='new';\"/>\n"; } echo "</form>\n"; ?> <script type="text/javascript"> <!-- function trim(str) { // Commas are used in the GIVN and SURN field to separate lists of surnames. // For example, to differentiate the two Spanish surnames from an English // double-barred name. // Commas *may* be used in the NAME field, and will form part of the displayed // name. This is not encouraged, as it may confuse some logic that assumes // "list" format names are always "surn, givn". str=str.replace(/,/g," "); str=str.replace(/\s\s+/g," "); return str.replace(/(^\s+)|(\s+$)/g,''); } function lang_class(str) { if (str.match(/[\u0370-\u03FF]/)) return "greek"; if (str.match(/[\u0400-\u04FF]/)) return "cyrillic"; if (str.match(/[\u0590-\u05FF]/)) return "hebrew"; if (str.match(/[\u0600-\u06FF]/)) return "arabic"; return "latin"; // No matched text implies latin :-) } // Generate a full name from the name components function generate_name() { var frm =document.forms[0]; var npfx=frm.NPFX.value; var givn=frm.GIVN.value; var spfx=frm.SPFX.value; var surn=frm.SURN.value; var nsfx=frm.NSFX.value; return trim(npfx+" "+givn+" /"+trim(spfx+" "+surn.replace(/ *, */, " "))+"/ "+nsfx); } // Update the NAME and _MARNM fields from the name components // and also display the value in read-only "gedcom" format. function updatewholename() { // don't update the name if the user manually changed it if (manualChange) return; // Update NAME field from components and display it var frm =document.forms[0]; var npfx=frm.NPFX.value; var givn=frm.GIVN.value; var spfx=frm.SPFX.value; var surn=frm.SURN.value; var nsfx=frm.NSFX.value; document.getElementById('NAME').value=generate_name(); document.getElementById('NAME_display').innerHTML=frm.NAME.value; // Married names inherit some NSFX values, but not these nsfx=nsfx.replace(/^(I|II|III|IV|V|VI|Junior|Jr\.?|Senior|Sr\.?)$/i, ''); // Update _MARNM field from _MARNM_SURN field and display it // Be careful of mixing latin/hebrew/etc. character sets. var ip=document.getElementsByTagName('input'); var marnm_id=''; var romn=''; var heb=''; for (var i=0; i<ip.length; i++) { var val=ip[i].value; if (ip[i].id.indexOf("_HEB")==0) heb=val; if (ip[i].id.indexOf("ROMN")==0) romn=val; if (ip[i].id.indexOf("_MARNM")==0) { if (ip[i].id.indexOf("_MARNM_SURN")==0) { var msurn=''; if (val!='') { var lc=lang_class(document.getElementById(ip[i].id).value); if (lang_class(frm.NAME.value)==lc) msurn=trim(npfx+" "+givn+" /"+val+"/ "+nsfx); else if (lc=="hebrew") msurn=heb.replace(/\/.*\//, '/'+val+'/'); else if (lang_class(romn)==lc) msurn=romn.replace(/\/.*\//, '/'+val+'/'); } document.getElementById(marnm_id).value=msurn; document.getElementById(marnm_id+"_display").innerHTML=msurn; } else { marnm_id=ip[i].id; } } } } /** * convert a hidden field to a text box */ var oldName = ""; var manualChange = false; function convertHidden(eid) { var element = document.getElementById(eid); if (element) { if (element.type=="hidden") { // IE doesn't allow changing the "type" of an input field so we'll cludge it ( silly :P) if (IE) { var newInput = document.createElement('input'); newInput.setAttribute("type", "text"); newInput.setAttribute("name", element.Name); newInput.setAttribute("id", element.id); newInput.setAttribute("value", element.value); newInput.setAttribute("onchange", element.onchange); var parent = element.parentNode; parent.replaceChild(newInput, element); element = newInput; } else { element.type="text"; } element.size="40"; oldName = element.value; manualChange = true; var delement = document.getElementById(eid+"_display"); if (delement) { delement.style.display='none'; // force FF ui to update the display if (delement.innerHTML != oldName) { oldName = delement.innerHTML; element.value = oldName; } } } else { manualChange = false; // IE doesn't allow changing the "type" of an input field so we'll cludge it ( silly :P) if (IE) { var newInput = document.createElement('input'); newInput.setAttribute("type", "hidden"); newInput.setAttribute("name", element.Name); newInput.setAttribute("id", element.id); newInput.setAttribute("value", element.value); newInput.setAttribute("onchange", element.onchange); var parent = element.parentNode; parent.replaceChild(newInput, element); element = newInput; } else { element.type="hidden"; } var delement = document.getElementById(eid+"_display"); if (delement) { delement.style.display='inline'; } } } } /** * if the user manually changed the NAME field, then update the textual * HTML representation of it * If the value changed set manualChange to true so that changing * the other fields doesn't change the NAME line */ function updateTextName(eid) { var element = document.getElementById(eid); if (element) { if (element.value!=oldName) manualChange = true; var delement = document.getElementById(eid+"_display"); if (delement) { delement.innerHTML = element.value; } } } function checkform() { var ip=document.getElementsByTagName('input'); for (var i=0; i<ip.length; i++) { // ADD slashes to _HEB and _AKA names if (ip[i].id.indexOf('_AKA')==0 || ip[i].id.indexOf('_HEB')==0 || ip[i].id.indexOf('ROMN')==0) if (ip[i].value.indexOf('/')<0 && ip[i].value!='') ip[i].value=ip[i].value.replace(/([^\s]+)\s*$/, "/$1/"); // Blank out temporary _MARNM_SURN and empty name fields if (ip[i].id.indexOf("_MARNM_SURN")==0 || ip[i].value=='//') ip[i].value=''; // Convert "xxx yyy" and "xxx y yyy" surnames to "xxx,yyy" if ('<?php echo $SURNAME_TRADITION; ?> '=='spanish' || '<?php echo $SURNAME_TRADITION; ?> '=='portuguese') if (ip[i].id.indexOf("SURN")==0) ip[i].value=document.forms[0].SURN.value.replace(/^\s*([^\s,]{2,})\s+([iIyY] +)?([^\s,]{2,})\s*$/, "$1,$3");; } return true; } // If the name isn't initially formed from the components in a standard way, // then don't automatically update it. if (document.getElementById("NAME").value!=generate_name() && document.getElementById("NAME").value!="//") convertHidden("NAME"); //--> </script> <?php }
/** * Accpet changed gedcom record into database * * This function gets an updated record from the gedcom file and replaces it in the database * @author John Finlay * @param string $cid The change id of the record to accept */ function accept_changes($cid) { global $pgv_changes, $GEDCOM, $TBLPREFIX, $FILE, $GEDCOMS; global $INDEX_DIRECTORY, $SYNC_GEDCOM_FILE, $fcontents, $manual_save; if (isset($pgv_changes[$cid])) { $changes = $pgv_changes[$cid]; $change = $changes[count($changes) - 1]; if ($GEDCOM != $change["gedcom"]) { $GEDCOM = $change["gedcom"]; } $FILE = $GEDCOM; $gid = $change["gid"]; $gedrec = $change["undo"]; if (empty($gedrec)) { $gedrec = find_gedcom_record($gid); } update_record($gedrec, $change["type"] == "delete"); //-- write the changes back to the gedcom file if ($SYNC_GEDCOM_FILE) { // TODO: We merge CONC lines on import, so need to add them back on export if (!isset($manual_save) || $manual_save == false) { //-- only allow one thread to accept changes at a time // $mutex = new Mutex("accept_changes"); // $mutex->Wait(); } if (empty($fcontents)) { read_gedcom_file(); } if ($change["type"] == "delete") { $pos1 = find_newline_string($fcontents, "0 @{$gid}@"); if ($pos1 !== false) { $pos2 = find_newline_string($fcontents, "0", $pos1 + 5); if ($pos2 === false) { $fcontents = substr($fcontents, 0, $pos1) . '0 TRLR' . PGV_EOL; AddToLog("Corruption found in GEDCOM {$GEDCOM} Attempted to correct"); } else { $fcontents = substr($fcontents, 0, $pos1) . substr($fcontents, $pos2); } } else { AddToLog("Corruption found in GEDCOM {$GEDCOM} Attempted to correct. Deleted gedcom record {$gid} was not found in the gedcom file."); } } elseif ($change["type"] == "append") { $pos1 = find_newline_string($fcontents, "0 TRLR"); $fcontents = substr($fcontents, 0, $pos1) . reformat_record_export($gedrec) . '0 TRLR' . PGV_EOL; } elseif ($change["type"] == "replace") { $pos1 = find_newline_string($fcontents, "0 @{$gid}@"); if ($pos1 !== false) { $pos2 = find_newline_string($fcontents, "0", $pos1 + 5); if ($pos2 === false) { $fcontents = substr($fcontents, 0, $pos1) . '0 TRLR' . PGV_EOL; AddToLog("Corruption found in GEDCOM {$GEDCOM} Attempted to correct"); } else { $fcontents = substr($fcontents, 0, $pos1) . reformat_record_export($gedrec) . substr($fcontents, $pos2); } } else { //-- attempted to replace a record that doesn't exist AddToLog("Corruption found in GEDCOM {$GEDCOM} Attempted to correct. Replaced gedcom record {$gid} was not found in the gedcom file."); $pos1 = find_newline_string($fcontents, "0 TRLR"); $fcontents = substr($fcontents, 0, $pos1) . reformat_record_export($gedrec) . '0 TRLR' . PGV_EOL; AddToLog("Gedcom record {$gid} was appended back to the GEDCOM file."); } } if (!isset($manual_save) || $manual_save == false) { write_file(); // $mutex->Release(); } } if ($change["type"] != "delete") { //-- synchronize the gedcom record with any user account $username = get_user_from_gedcom_xref($GEDCOM, $gid); if ($username && get_user_setting($username, 'sync_gedcom') == 'Y') { $firstname = get_gedcom_value("GIVN", 2, $gedrec); $lastname = get_gedcom_value("SURN", 2, $gedrec); if (empty($lastname)) { $fullname = get_gedcom_value("NAME", 1, $gedrec, "", false); $ct = preg_match("~(.*)/(.*)/~", $fullname, $match); if ($ct > 0) { $firstname = $match[1]; $lastname = $match[2]; } else { $firstname = $fullname; } } //-- SEE [ 1753047 ] Email/sync with account $email = get_gedcom_value("EMAIL", 1, $gedrec); if (empty($email)) { $email = get_gedcom_value("_EMAIL", 1, $gedrec); } if (!empty($email)) { set_user_setting($username, 'email', $email); } set_user_setting($username, 'firstname', $firstname); set_user_setting($username, 'lastname', $lastname); } } unset($pgv_changes[$cid]); if (!isset($manual_save) || $manual_save == false) { write_changes(); } $logline = AddToLog("Accepted change {$cid} " . $change["type"] . " into database"); check_in($logline, $GEDCOM, dirname($GEDCOMS[$GEDCOM]['path'])); if (isset($change["linkpid"])) { accept_changes($change["linkpid"] . "_" . $GEDCOM); } return true; } return false; }
/** * get the number of children in this family * @return int the number of children */ function getNumberOfChildren() { if ($this->numChildren !== false) { return $this->numChildren; } $this->numChildren = get_gedcom_value("NCHI", 1, $this->gedrec); if ($this->numChildren != "") { return $this->numChildren . "."; } $this->numChildren = preg_match_all("/1\\s*CHIL\\s*@(.*)@/", $this->gedrec, $smatch); return $this->numChildren; }
/** * get a list of remote servers */ function get_server_list() { global $GEDCOM, $GEDCOMS, $TBLPREFIX, $sitelist, $gBitDb; $sitelist = array(); if (isset($GEDCOMS[$GEDCOM]) && check_for_import($GEDCOM)) { $rows = $gBitDb->getAll("SELECT s_id, s_name, s_gedcom, s_file FROM {$TBLPREFIX}sources WHERE s_file=? AND s_dbid=? ORDER BY s_name", array(PGV_GED_ID, 'Y')); foreach ($rows as $row) { $source = array(); $source["name"] = $row['s_name']; $source["gedcom"] = $row['s_gedcom']; $source["gedfile"] = $row['s_file']; $source["url"] = get_gedcom_value("URL", 1, $row['s_gedcom']); $sitelist[$row['s_id']] = $source; } } return $sitelist; }
/** * returns FAM:SOUR:PAGE matching filter * @return Array of string */ function autocomplete_FAM_SOUR_PAGE($FILTER, $OPTION) { global $TBLPREFIX, $gBitDb; $sql = "SELECT 'FAM' AS type, f_id AS xref, f_file AS ged_id, f_gedcom AS gedrec, f_husb, f_wife, f_chil, f_numchil FROM {$TBLPREFIX}families WHERE f_gedcom LIKE ? AND f_file=?"; $rows = $gBitDb->query($sql, array("% SOUR @{$OPTION}@% PAGE %{$FILTER}%", PGV_GED_ID), PGV_AUTOCOMPLETE_LIMIT); $data = array(); while ($row = $rows->fetchRows()) { $family = Family::getInstance($row); if ($family->canDisplayDetails()) { // a single FAM may have multiple level 1 and level 2 sources for ($level = 1; $level <= 2; $level++) { $i = 1; do { $srec = get_sub_record("SOUR @{$OPTION}@", $level, $family->gedrec, $i++); $page = get_gedcom_value("PAGE", $level + 1, $srec); if (stripos($page, $FILTER) !== false || empty($FILTER)) { $data[] = $page; } } while ($srec); } } } return $data; }
splitSOUR(); // separate SOUR record from the rest if (isset($_REQUEST['spid'])) { $spid = $_REQUEST['spid']; } if (!empty($spid)) { if (isset($pgv_changes[$spid . '_' . PGV_GEDCOM])) { $gedrec = find_updated_record($spid, PGV_GED_ID); } else { $gedrec = find_person_record($spid, PGV_GED_ID); } $gedrec = trim($gedrec); if (!empty($gedrec)) { if ($famid == "new") { $famrec = "0 @new@ FAM\n"; $SEX = get_gedcom_value("SEX", 1, $gedrec, '', false); if ($SEX == "M") { $famtag = "HUSB"; } if ($SEX == "F") { $famtag = "WIFE"; } if ($famtag == "HUSB") { $famrec .= "1 HUSB @{$spid}@\n"; $famrec .= "1 WIFE @{$pid}@\n"; } else { $famrec .= "1 WIFE @{$spid}@\n"; $famrec .= "1 HUSB @{$pid}@\n"; } $famrec .= addNewFact('MARR'); if (safe_POST_bool('SOUR_FAM') || count($tagSOUR) > 0) {
/** * @todo add info * @see PGVRListEHandler() * @param array $attrs an array of key value pairs for the attributes */ function PGVRListSHandler($attrs) { global $pgvreport, $gedrec, $repeats, $repeatBytes, $list, $repeatsStack, $processRepeats, $parser, $vars, $sortby; global $pgv_changes, $GEDCOM, $TBLPREFIX; $processRepeats++; if ($processRepeats > 1) { return; } if (isset($attrs["sortby"])) { $sortby = $attrs["sortby"]; $vmatch = array(); if (preg_match("/\\\$(\\w+)/", $sortby, $vmatch) > 0) { $sortby = $vars[$vmatch[1]]["id"]; $sortby = trim($sortby); } } else { $sortby = "NAME"; } if (isset($attrs["list"])) { $listname = $attrs["list"]; } else { $listname = "individual"; } // Some filters/sorts can be applied using SQL, while others require PHP switch ($listname) { case 'pending': $list = array(); foreach ($pgv_changes as $changes) { $change = end($changes); if ($change['gedcom'] == $GEDCOM) { $list[] = new GedcomRecord($change['undo']); } } break; case 'individual': case 'family': $sql_col_prefix = substr($listname, 0, 1) . '_'; // i_ for individual, f_ for family, etc. $sql_join = array(); $sql_where = array($sql_col_prefix . "file=" . PGV_GED_ID); $sql_order_by = array(); foreach ($attrs as $attr => $value) { if (strpos($attr, 'filter') === 0 && $value) { // Substitute global vars $value = preg_replace('/\\$(\\w+)/e', '$vars["\\1"]["id"]', $value); // Convert the various filters into SQL $match = array(); if (preg_match('/^(\\w+):DATE (LTE|GTE) (.+)$/', $value, $match)) { $sql_join[] = "JOIN {$TBLPREFIX}dates AS {$attr} ON ({$attr}.d_file={$sql_col_prefix}file AND {$attr}.d_gid={$sql_col_prefix}id)"; $sql_where[] = "{$attr}.d_fact='{$match[1]}'"; $date = new GedcomDate($match[3]); if ($match[2] == 'LTE') { $sql_where[] = "{$attr}.d_julianday2<=" . $date->minJD(); } else { $sql_where[] = "{$attr}.d_julianday1>=" . $date->minJD(); } if ($sortby == $match[1]) { $sortby = ''; $sql_order_by[] = "{$attr}.d_julianday1"; } unset($attrs[$attr]); // This filter has been fully processed } elseif ($listname == 'individual' && preg_match('/^NAME CONTAINS (.+)$/', $value, $match)) { $sql_join[] = "JOIN {$TBLPREFIX}name AS {$attr} ON (n_file={$sql_col_prefix}file AND n_id={$sql_col_prefix}id)"; $sql_where[] = "{$attr}.n_sort LIKE '" . UTF8_strtoupper($match[1]) . "%'"; if ($sortby == 'NAME') { $sortby = ''; $sql_order_by[] = "{$attr}.n_sort"; } unset($attrs[$attr]); // This filter has been fully processed } elseif ($listname == 'family' && preg_match('/^NAME CONTAINS (.+)$/', $value, $match)) { // Eventually, family "names" will be stored in pgv_name. Until then, an extra is needed.... $sql_join[] = "JOIN {$TBLPREFIX}link AS {$attr}a ON ({$attr}a.l_file={$sql_col_prefix}file AND {$attr}a.l_from={$sql_col_prefix}id)"; $sql_join[] = "JOIN {$TBLPREFIX}name AS {$attr}b ON ({$attr}b.n_file={$sql_col_prefix}file AND n_id={$sql_col_prefix}id)"; $sql_where[] = "{$attr}a.l_type=IN ('HUSB, 'WIFE')"; $sql_where[] = "{$attr}.n_sort LIKE '" . UTF8_strtoupper($match[1]) . "%'"; if ($sortby == 'NAME') { $sortby = ''; $sql_order_by[] = "{$attr}.n_sort"; } unset($attrs[$attr]); // This filter has been fully processed //returns all the record with the filter place - does not verify that we speak of a BIRT record for the birth report value=BIRT:PLAC etc. /* } elseif (preg_match('/^(?:\w+):PLAC CONTAINS (.+)$/', $value, $match)) { $sql_join[]="JOIN {$TBLPREFIX}places AS {$attr}a ON ({$attr}a.p_file={$sql_col_prefix}file)"; $sql_join[]="JOIN {$TBLPREFIX}placelinks AS {$attr}b ON ({$attr}a.p_file={$attr}b.pl_file AND {$attr}b.pl_p_id={$attr}a.p_id AND {$attr}b.pl_gid={$sql_col_prefix}id)"; $sql_where[]="{$attr}a.p_place LIKE '".UTF8_strtoupper($match[1])."%'"; unset($attrs[$attr]); // This filter has been fully processed */ } else { // TODO: what other filters can we apply in SQL? //var_dump($value); } } } if ($listname == 'family') { $list = search_fams_custom($sql_join, $sql_where, $sql_order_by); } else { $list = search_indis_custom($sql_join, $sql_where, $sql_order_by); } break; default: die("Invalid list name: {$listname}"); } $filters = array(); $filters2 = array(); if (isset($attrs["filter1"])) { $j = 0; foreach ($attrs as $key => $value) { $ct = preg_match("/filter(\\d)/", $key, $match); if ($ct > 0) { $condition = $value; $ct = preg_match("/@(\\w+)/", $condition, $match); if ($ct > 0) { $id = $match[1]; $value = "''"; if ($id == "ID") { $ct = preg_match("/0 @(.+)@/", $gedrec, $match); if ($ct > 0) { $value = "'" . $match[1] . "'"; } } else { if ($id == "fact") { $value = "'{$fact}'"; } else { if ($id == "desc") { $value = "'{$desc}'"; } else { $ct = preg_match("/\\d {$id} (.+)/", $gedrec, $match); if ($ct > 0) { $value = "'" . preg_replace("/@/", "", trim($match[1])) . "'"; } } } } $condition = preg_replace("/@{$id}/", $value, $condition); } //-- handle regular expressions $ct = preg_match("/([A-Z:]+)\\s*([^\\s]+)\\s*(.+)/", $condition, $match); if ($ct > 0) { $tag = trim($match[1]); $expr = trim($match[2]); $val = trim($match[3]); if (preg_match("/\\\$(\\w+)/", $val, $vmatch) > 0) { $val = $vars[$vmatch[1]]["id"]; $val = trim($val); } $searchstr = ""; $tags = explode(':', $tag); //-- only limit to a level number if we are specifically looking at a level if (count($tags) > 1) { $level = 1; foreach ($tags as $t) { if (!empty($searchstr)) { $searchstr .= "[^\n]*(\n[2-9][^\n]*)*\n"; } //-- search for both EMAIL and _EMAIL... silly double gedcom standard if ($t == "EMAIL" || $t == "_EMAIL") { $t = "_?EMAIL"; } $searchstr .= $level . " " . $t; $level++; } } else { if ($tag == "EMAIL" || $tag == "_EMAIL") { $tag = "_?EMAIL"; } $t = $tag; $searchstr = "1 " . $tag; } switch ($expr) { case "CONTAINS": if ($t == "PLAC") { $searchstr .= "[^\n]*[, ]" . $val; } else { $searchstr .= "[^\n]*" . $val; } $filters[] = $searchstr; break; default: if (!empty($val)) { $filters2[] = array("tag" => $tag, "expr" => $expr, "val" => $val); } break; } } } $j++; } } //-- apply other filters to the list that could not be added to the search string if ($filters) { foreach ($list as $key => $record) { foreach ($filters as $filter) { if (!preg_match('/' . $filter . '/i', $record->getGedcomRecord())) { unset($list[$key]); break; } } } } if ($filters2) { $mylist = array(); foreach ($list as $indi) { $key = $indi->getXref(); $value = $indi->getGedcomRecord(); $keep = true; foreach ($filters2 as $filter) { if ($keep) { $tag = $filter["tag"]; $expr = $filter["expr"]; $val = $filter["val"]; if ($val == "''") { $val = ""; } $tags = explode(':', $tag); $t = end($tags); $v = get_gedcom_value($tag, 1, $value["gedcom"], '', false); //-- check for EMAIL and _EMAIL (silly double gedcom standard :P) if ($t == "EMAIL" && empty($v)) { $tag = preg_replace("/EMAIL/", "_EMAIL", $tag); $tags = explode(':', $tag); $t = end($tags); $v = get_sub_record(1, $tag, $value["gedcom"]); } $level = count($tags); switch ($expr) { case "GTE": if ($t == "DATE") { $date1 = new GedcomDate($v); $date2 = new GedcomDate($val); $keep = GedcomDate::Compare($date1, $date2) >= 0; } else { if ($val >= $v) { $keep = true; } } break; case "LTE": if ($t == "DATE") { $date1 = new GedcomDate($v); $date2 = new GedcomDate($val); $keep = GedcomDate::Compare($date1, $date2) <= 0; } else { if ($val >= $v) { $keep = true; } } break; case "SUBCONTAINS": $v = get_sub_record($level, $level . " " . $tag, $value["gedcom"]); if (empty($v) && $tag == "ADDR") { $v = get_sub_record($level + 1, $level + 1 . " " . $tag, $value["gedcom"]); } $ct = preg_match("/{$val}\\b/i", $v); if ($ct > 0) { $keep = true; } else { $keep = false; } break; default: if ($v == $val) { $keep = true; } else { $keep = false; } break; } } } if ($keep) { $mylist[$key] = $indi; } } $list = $mylist; } switch ($sortby) { case 'NAME': uasort($list, array('GedcomRecord', 'Compare')); break; case 'ID': uasort($list, array('GedcomRecord', 'CompareId')); break; case 'CHAN': uasort($list, array('GedcomRecord', 'CompareChanDate')); break; case 'BIRT:DATE': uasort($list, array('Person', 'CompareBirtDate')); break; case 'DEAT:DATE': uasort($list, array('Person', 'CompareDeatDate')); break; case 'MARR:DATE': uasort($list, array('Family', 'CompareMarrDate')); break; default: // unsorted or already sorted by SQL break; } array_push($repeatsStack, array($repeats, $repeatBytes)); $repeatBytes = xml_get_current_line_number($parser) + 1; }
/** * get the author of this source record * @return string */ function getAuth() { return get_gedcom_value('AUTH', 1, $this->gedrec, '', false); }
/** * Creates the SourceRef element and appends it to the Parent Element. If the actual Source has not * been previously created, this will retrieve the record for that, and create that also. * * @param DOMElement $eParent - the parent DOMElement to which the created Note Element is appended * @param string $sourcerefRec - the record containing the reference to a Source * @param int $level - The GEDCOM line level where the SOUR tag may be found */ function create_sourceref($eParent, $sourcerefRec, $level) { if (($sourceID = get_gedcom_value("SOUR", $level, $sourcerefRec)) != null) { if (id_in_cart($sourceID)) { $eSourceRef = $this->dom->createElement("sourceref"); $eSourceRef = $eParent->appendChild($eSourceRef); if (($sourceHlink = $this->query_dom("./sources/source[@id = \"{$sourceID}\"]/@handle")) == null) { $this->create_source($sourceID, find_source_record($sourceID)); } $eSourceRef->setAttribute("hlink", $this->query_dom("./sources/source[@id = \"{$sourceID}\"]/@handle")); if (($page = get_gedcom_value("SOUR:PAGE", $level, $sourcerefRec)) != null) { $eSPage = $this->dom->createElement("spage"); $etSPage = $this->dom->createTextNode($page); $etSPage = $eSPage->appendChild($etSPage); $eSPage = $eSourceRef->appendChild($eSPage); } if (($comments = get_gedcom_value("SOUR:NOTE", $level, $sourcerefRec)) != null) { $eSComments = $this->dom->createElement("scomments"); $etSComments = $this->dom->createTextNode($comments); $etSComments = $eSComments->appendChild($etSComments); $eSComments = $eSourceRef->appendChild($eSComments); } if (($text = get_gedcom_value("SOUR:TEXT", $level, $sourcerefRec)) != null) { $num = 1; while (($cont = get_gedcom_value("SOUR:TEXT:CONT", $level, $sourcerefRec, $num)) != null) { $text .= $cont; $num++; } $eSText = $this->dom->createElement("stext"); $etSText = $this->dom->createTextNode($text); $etSText = $eSText->appendChild($etSText); $eSText = $eSourceRef->appendChild($eSText); } if (($dateRec = get_sub_record(1, $level + 1 . " DATE", $sourcerefRec)) != null) { $this->create_date($eSourceRef, $dateRec, $level + 1); } } } }
/** * Creates the lds_ord element and appends the correct information depending * on the type of lds_ord (Endowment, Sealing, Baptism). If there is a sealing, * the function will search if the family is in the clippings cart and if the * family is created or not. If the family is not created yet, it will be created * and added to the DOMDocument * * @param $indirec - The full INDI GEDCOM record of the person the lds_ord is being created * @param $eventName - the name of the LDS event (Baptism, Sealing, Endowment, etc...) * @param $eventABV - the event abbreviation in the GEDCOM (ie. SLGC, BAPL, ENDL) * @param $eParent - The parent element the lds event is attached to */ function create_lds_event($indirec, $eventName, $eventABV, $eParent) { global $ePerson, $TEMPLE_CODES, $clipping; if (($hasldsevent = get_sub_record(1, "1 " . $eventABV, $indirec)) != null) { // Create <lds_ord> and attaches the type attribute $eLdsEvent = $this->dom->createElement("lds_ord"); $eLdsEvent->setAttribute("type", $eventName); if (($dateRec = get_sub_record(1, "2 DATE", $hasldsevent)) != null) { $this->create_date($eLdsEvent, $dateRec, 2); } // Create <temple>, this element is common with all lds ords if (($temple = get_gedcom_value($eventABV . ":TEMP", 1, $indirec)) != null) { $eTemple = $this->dom->createElement("temple"); $eTemple->setAttribute("val", $temple); $eTemple = $eLdsEvent->appendChild($eTemple); } if (($place = get_gedcom_value($eventABV . ":PLAC", 1, $indirec)) != null) { $hlink = $this->query_dom("./places/placeobj[@title=\"{$place}\"]/@handle"); if ($hlink == null) { $hlink = $this->generateHandle(); $this->create_placeobj($place, $hlink); $this->create_place($eLdsEvent, $hlink); } else { $this->create_place($eLdsEvent, $hlink); } } // Check to see if the STAT of the ordinance is set and add it to the // <lds_ord> element if (($stat = get_gedcom_value($eventABV . ":STAT", 1, $indirec)) != null) { $eStatus = $this->dom->createElement("status"); $stat = get_gedcom_value($eventABV . ":STAT", 1, $indirec); $eStatus->setAttribute("val", isset($stat)); $eStatus = $eLdsEvent->appendChild($eStatus); } // If the event is a sealing if ($eventABV == "SLGC") { // Create an instance of person and look for their family record $person = Person::getInstance($clipping["id"]); $famId = $person->getChildFamilyIds(); $famrec = find_family_record($famId[0]); $fid = $famId[0]; $handle = $this->query_dom("./families/family[@id=\"{$fid}\"]/@handle"); if ($handle == null) { /* * If the family does not exist and their ID is in the clippings cart, * you must create the family before you can query them in the dom to get * their hlink. The hlink is generated when the person element is created. * This causes overhead creating objects that are never added to the XML file * perhaps there is some other way this can be done reducing the overhead? * */ $this->create_family($famrec, $famId[0]); $handle = $this->query_dom("./families/family[@id=\"{$fid}\"]/@handle"); $eFam = $this->dom->createElement("sealed_to"); $eFam->setAttribute("hlink", $handle); $eFam = $eLdsEvent->appendChild($eFam); $person = null; } else { if ($handle != null) { $eFam = $this->dom->createElement("sealed_to"); $eFam->setAttribute("hlink", $handle); $eFam = $eLdsEvent->appendChild($eFam); $person = null; } } } if (($note = get_sub_record(1, "2 NOTE", $hasldsevent)) != null) { $this->create_note($eLdsEvent, $note, 2); } $num = 1; while (($sourcerefRec = get_sub_record(2, "2 SOUR", $hasldsevent, $num)) != null) { $this->create_sourceref($eLdsEvent, $sourcerefRec, 2); $num++; } $eLdsEvent = $eParent->appendChild($eLdsEvent); } }
/** * Creates the Source and appends it to the Sources Element * * @param string $sourceID - the ID of the source to be created * @param string $sourceRec - the entire GEDCOM record containing the Source * @param int $level - the level the source is on in the GEDCOM record * @param int $done - whether the method is called from the GrampsExport($done=1) or a sub-class */ function create_source($sourceID, $sourceRec, $level = 1, $done = 1) { $eSource = $this->dom->createElement("source"); $eSource->setAttribute("id", $sourceID); $eSource->setAttribute("handle", $this->generateHandle()); $eSource->setAttribute("change", time()); if (($title = get_gedcom_value("TITL", $level, $sourceRec)) != null) { $eSTitle = $this->dom->createElement("stitle"); $etSTitle = $this->dom->createTextNode($title); $etSTitle = $eSTitle->appendChild($etSTitle); $eSTitle = $eSource->appendChild($eSTitle); } if (($author = get_gedcom_value("AUTH", $level, $sourceRec)) != null) { $eSAuthor = $this->dom->createElement("sauthor"); $etSAuthor = $this->dom->createTextNode($author); $etSAuthor = $eSAuthor->appendChild($etSAuthor); $eSAuthor = $eSource->appendChild($eSAuthor); } if (($pubInfo = get_gedcom_value("PUBL", $level, $sourceRec)) != null) { $eSPubInfo = $this->dom->createElement("spubinfo"); $etSPubInfo = $this->dom->createTextNode($pubInfo); $etSPubInfo = $eSPubInfo->appendChild($etSPubInfo); $eSPubInfo = $eSource->appendChild($eSPubInfo); } if (($abbrev = get_gedcom_value("ABBR", $level, $sourceRec)) != null) { $eSAbbrev = $this->dom->createElement("sabbrev"); $etSAbbrev = $this->dom->createTextNode($abbrev); $etSAbbrev = $eSAbbrev->appendChild($etSAbbrev); $eSAbbrev = $eSource->appendChild($eSAbbrev); } if (($note = get_sub_record($level, $level . " NOTE", $sourceRec)) != null) { $this->create_note($eSource, $note, $level); } $num = 1; while (($nameSource = get_sub_record(1, "1 OBJE", $sourceRec, $num)) != null) { $this->create_mediaref($this->eSources, $nameSource, 1, $done); $num++; } $eSource = $this->eSources->appendChild($eSource); }
function create_sourceref($eParent, $sourcerefRec, $level, $done = 1) { if (($sourceID = get_gedcom_value("SOUR", $level, $sourcerefRec)) != null) { $eSourceRef = $this->dom->createElement("sourceref"); $eSourceRef = $eParent->appendChild($eSourceRef); $eSourceRef->setAttribute("hlink", $sourceID); } }
if (!empty($CITY)) { $ADDR .= $cityspace . $CITY; } else { $ADDR .= $cityspace; } $STAE = get_gedcom_value("STAE", 2, $subrec); if (!empty($STAE)) { $ADDR .= ", " . $STAE; } if ($POSTAL_CODE) { $POST = get_gedcom_value("POST", 2, $subrec); if (!empty($POST)) { $ADDR .= " " . $POST; } } $CTRY = get_gedcom_value("CTRY", 2, $subrec); if (!empty($CTRY)) { $ADDR .= "\n" . $CTRY; } } /** * @todo add support for ADDR subtags ADR1, CITY, STAE etc */ } $PHON = ""; $subrec = get_sub_record(1, "1 PHON", $gedrec); if (!empty($subrec)) { $ct = preg_match("/1 PHON (.*)/", $subrec, $match); if ($ct > 0) { $PHON = trim($match[1]); }
/** * get a singleton instance of this client * @return ServiceClient */ static function &getInstance($id) { global $PGV_SERVERS, $SERVER_URL, $GEDCOM; if (isset($PGV_SERVERS[$id])) { return $PGV_SERVERS[$id]; } $gedrec = find_gedcom_record($id); if (empty($gedrec)) { $gedrec = find_updated_record($id); } if (!empty($gedrec)) { $url = get_gedcom_value("URL", 1, $gedrec); $gedfile = get_gedcom_value("_DBID", 1, $gedrec); if (empty($url) && empty($gedfile)) { return null; } if (!empty($url) && strtolower($url) != strtolower($SERVER_URL)) { $server = new ServiceClient($gedrec); } else { include_once 'includes/classes/class_localclient.php'; $server = new LocalClient($gedrec); } $PGV_SERVERS[$id] = $server; return $server; } return null; }
/** * find the highlighted media object for a gedcom entity * * Rules for finding the highlighted media object: * 1. The first _PRIM Y object will be used regardless of level in gedcom record * 2. The first level 1 object will be used if there if it doesn't have _PRIM N (level 1 objects appear on the media tab on the individual page) * * @param string $pid the individual, source, or family id * @param string $indirec the gedcom record to look in * @return array an object array with indexes "thumb" and "file" for thumbnail and filename */ function find_highlighted_object($pid, $indirec) { global $MEDIA_DIRECTORY, $MEDIA_DIRECTORY_LEVELS, $PGV_IMAGE_DIR, $PGV_IMAGES, $MEDIA_EXTERNAL; global $GEDCOMS, $GEDCOM, $TBLPREFIX, $gBitDb; if (!showFactDetails("OBJE", $pid)) { return false; } $object = array(); $media = array(); //-- handle finding the media of remote objects $ct = preg_match("/(.*):(.*)/", $pid, $match); if ($ct > 0) { require_once '../classes/class_serviceclient.php'; $client = ServiceClient::getInstance($match[1]); if (!is_null($client)) { $mt = preg_match_all('/\\n\\d OBJE @(' . PGV_REGEX_XREF . ')@/', $indirec, $matches, PREG_SET_ORDER); for ($i = 0; $i < $mt; $i++) { $mediaObj = Media::getInstance($matches[$i][1]); $mrec = $mediaObj->getGedcomRecord(); if (!empty($mrec)) { $file = get_gedcom_value("FILE", 1, $mrec); $row = array($matches[$i][1], $file, $mrec, $matches[$i][0]); $media[] = $row; } } } } //-- find all of the media items for a person $media = $gBitDb->query("SELECT m_media, m_file, m_gedrec, mm_gedrec FROM {$TBLPREFIX}media, {$TBLPREFIX}media_mapping WHERE m_media=mm_media AND m_gedfile=mm_gedfile AND m_gedfile=? AND mm_gid=? ORDER BY mm_order", array($GEDCOMS[$GEDCOM]["id"], $pid)); while ($row = $media->fetchRow()) { if (displayDetailsById($row['m_media'], 'OBJE') && !FactViewRestricted($row['m_media'], $row['m_gedrec'])) { $level = 0; $ct = preg_match("/(\\d+) OBJE/", $row['mm_gedrec'], $match); if ($ct > 0) { $level = $match[1]; } if (strstr($row['mm_gedrec'], "_PRIM ")) { $thum = get_gedcom_value('_THUM', $level + 1, $row['mm_gedrec']); $prim = get_gedcom_value('_PRIM', $level + 1, $row['mm_gedrec']); } else { $thum = get_gedcom_value('_THUM', 1, $row['m_gedrec']); $prim = get_gedcom_value('_PRIM', 1, $row['m_gedrec']); } if ($prim == 'N') { continue; } // Skip _PRIM N objects if ($prim == 'Y') { // Take the first _PRIM Y object $object["file"] = check_media_depth($row['m_file']); $object["thumb"] = thumbnail_file($row['m_file'], true, false, $pid); // $object["_PRIM"] = $prim; // Not sure whether this is needed. $object["_THUM"] = $thum; // This overrides GEDCOM's "Use main image as thumbnail" option $object["level"] = $level; $object["mid"] = $row['m_media']; break; // Stop looking: we found a suitable image } if ($level == 1 && empty($object)) { // Take the first level 1 object, but keep looking for an overriding _PRIM Y $object["file"] = check_media_depth($row['m_file']); $object["thumb"] = thumbnail_file($row['m_file'], true, false, $pid); // $object["_PRIM"] = $prim; // Not sure whether this is needed. $object["_THUM"] = $thum; // This overrides GEDCOM's "Use main image as thumbnail" option $object["level"] = $level; $object["mid"] = $row['m_media']; } } } return $object; }
/** * returns FAM:SOUR:PAGE matching filter * @return Array of string */ function autocomplete_FAM_SOUR_PAGE($FILTER, $OPTION) { $rows = get_autocomplete_FAM_SOUR_PAGE($FILTER, $OPTION); $data = array(); foreach ($rows as $row) { $family = Family::getInstance($row); if ($family->canDisplayDetails()) { // a single FAM may have multiple level 1 and level 2 sources for ($level = 1; $level <= 2; $level++) { $i = 1; do { $srec = get_sub_record("SOUR @{$OPTION}@", $level, $family->gedrec, $i++); $page = get_gedcom_value("PAGE", $level + 1, $srec); if (stripos($page, $FILTER) !== false || empty($FILTER)) { $data[] = $page; } } while ($srec); } } } return $data; }
/** * get the media type * @return string */ function getMediatype() { $mediaType = strtolower(get_gedcom_value("FORM:TYPE", 2, $this->gedrec)); return $mediaType; }
function addLink() { global $pgv_lang, $GEDCOM; switch ($this->form_location) { case 'remote': $serverID = $this->addRemoteServer($this->form_txtTitle, $this->form_txtURL, $this->form_txtGID, $this->form_txtUsername, $this->form_txtPassword); break; case 'local': $serverID = $this->addLocalServer($this->form_txtCB_Title, $this->form_txtCB_GID); break; case 'existing': $serverID = $this->form_cbExistingServers; break; case "FamilySearch": //TODO: Make sure that it is merging correctly $serverID = $this->addFamilySearchServer($this->form_txtFS_URL, $this->form_txtFS_URL, $this->form_txtFS_GID, $this->form_txtFS_Username, $this->form_txtFS_Password); break; } $link_pid = $this->form_txtPID; $relation_type = $this->form_cbRelationship; if ($serverID && $link_pid) { if (isset($pgv_changes[$this->pid . "_" . $GEDCOM])) { $indirec = find_updated_record($this->pid); } else { $indirec = find_person_record($this->pid); } switch ($relation_type) { case "father": $indistub = "0 @new@ INDI\n1 SOUR @{$serverID}@\n2 PAGE {$link_pid}\n1 RFN {$serverID}:{$link_pid}"; $stub_id = append_gedrec($indistub, false); $indistub = find_updated_record($stub_id); $gedcom_fam = "0 @new@ FAM\n1 HUSB @{$stub_id}@\n1 CHIL @{$this->pid}@"; $fam_id = append_gedrec($gedcom_fam); $indirec .= "\n1 FAMC @{$fam_id}@"; replace_gedrec($this->pid, $indirec); $serviceClient = ServiceClient::getInstance($serverID); $indistub = $serviceClient->mergeGedcomRecord($link_pid, $indistub, true, true); $indistub .= "\n1 FAMS @{$fam_id}@"; replace_gedrec($stub_id, $indistub, false); break; case "mother": $indistub = "0 @new@ INDI\n1 SOUR @{$serverID}@\n2 PAGE {$link_pid}\n1 RFN {$serverID}:{$link_pid}"; $stub_id = append_gedrec($indistub, false); $indistub = find_updated_record($stub_id); $gedcom_fam = "0 @new@ FAM\n1 WIFE @{$stub_id}@\n1 CHIL @{$this->pid}@"; $fam_id = append_gedrec($gedcom_fam); $indirec .= "\n1 FAMC @{$fam_id}@"; replace_gedrec($this->pid, $indirec); $serviceClient = ServiceClient::getInstance($serverID); $indistub = $serviceClient->mergeGedcomRecord($link_pid, $indistub, true, true); $indistub .= "\n1 FAMS @" . $fam_id . "@"; replace_gedrec($stub_id, $indistub, false); break; case "husband": $indistub = "0 @new@ INDI\n1 SOUR @{$serverID}@\n2 PAGE {$link_pid}\n1 RFN {$serverID}:{$link_pid}"; $stub_id = append_gedrec($indistub, false); $indistub = find_updated_record($stub_id); $gedcom_fam = "0 @new@ FAM\n1 MARR Y\n1 WIFE @{$this->pid}@\n1 HUSB @{$stub_id}@\n"; $fam_id = append_gedrec($gedcom_fam); $indirec .= "\n1 FAMS @{$fam_id}@"; replace_gedrec($this->pid, $indirec); $serviceClient = ServiceClient::getInstance($serverID); $indistub = $serviceClient->mergeGedcomRecord($link_pid, $indistub, true, true); $indistub .= "\n1 FAMS @{$fam_id}@"; replace_gedrec($stub_id, $indistub, false); break; case "wife": $indistub = "0 @new@ INDI\n1 SOUR @{$serverID}@\n2 PAGE {$link_pid}\n1 RFN {$serverID}:{$link_pid}"; $stub_id = append_gedrec($indistub, false); $indistub = find_updated_record($stub_id); $gedcom_fam = "0 @new@ FAM\n1 MARR Y\n1 WIFE @{$stub_id}@\n1 HUSB @{$this->pid}@"; $fam_id = append_gedrec($gedcom_fam); $indirec .= "\n1 FAMS @{$fam_id}@"; replace_gedrec($this->pid, $indirec); $serviceClient = ServiceClient::getInstance($serverID); $indistub = $serviceClient->mergeGedcomRecord($link_pid, $indistub, true, true); $indistub .= "\n1 FAMS @{$fam_id}@\n"; replace_gedrec($stub_id, $indistub, false); break; case "son": case "daughter": $indistub = "0 @new@ INDI\n1 SOUR @{$serverID}@\n2 PAGE {$link_pid}\n1 RFN {$serverID}:{$link_pid}"; $stub_id = append_gedrec($indistub, false); $indistub = find_updated_record($stub_id); if (get_gedcom_value('SEX', 1, $indirec, '', false) == 'F') { $gedcom_fam = "0 @new@ FAM\n1 WIFE @{$this->pid}@\n1 CHIL @{$stub_id}@"; } else { $gedcom_fam = "0 @new@ FAM\n1 HUSB @{$this->pid}@\n1 CHIL @{$stub_id}@"; } $fam_id = append_gedrec($gedcom_fam); $indirec .= "\n1 FAMS @{$fam_id}@"; replace_gedrec($this->pid, $indirec); $serviceClient = ServiceClient::getInstance($serverID); $indistub = $serviceClient->mergeGedcomRecord($link_pid, $indistub, true, true); $indistub .= "\n1 FAMC @" . $fam_id . "@"; replace_gedrec($stub_id, $indistub, false); break; case 'current_person': $indirec .= "\n1 RFN {$serverID}:{$link_pid}\n1 SOUR @{$serverID}@\n2 PAGE {$link_pid}"; $serviceClient = ServiceClient::getInstance($serverID); if (!is_null($serviceClient)) { //-- get rid of change date $pos1 = strpos($indirec, "\n1 CHAN"); if ($pos1 !== false) { $pos2 = strpos($indirec, "\n1", $pos1 + 5); $indirec = substr($indirec, 0, $pos1) . substr($indirec, $pos2); } $indirec = $serviceClient->mergeGedcomRecord($link_pid, $indirec, true, true); } else { echo 'Unable to find server'; } break; } echo '<b>', $pgv_lang['link_success'], '</b>'; return true; } return false; }
$xrefs = preg_split("/[;, ]/", $xref, 0, PREG_SPLIT_NO_EMPTY); $gedrecords = ""; foreach ($xrefs as $xref1) { if (!empty($xref1)) { $gedrec = find_updated_record($xref1); if (!$gedrec) { $gedrec = find_gedcom_record($xref1); if ($gedrec) { preg_match("/0 @(.*)@ (.*)/", $gedrec, $match); $type = trim($match[2]); if (!displayDetailsById($xref1, $type)) { //-- do not have full access to this record, so privatize it $gedrec = privatize_gedcom($gedrec); } else { if ($view == 'version' || $view == 'change') { $chan = get_gedcom_value('CHAN', 1, $gedrec); if (empty($chan)) { $head = find_gedcom_record("HEAD"); $head_date = get_sub_record(1, "1 DATE", $head); $lines = explode("\n", $head_date); $head_date = ""; foreach ($lines as $line) { $num = $line[0]; $head_date .= $num + 1 . substr($line, 1) . "\n"; } $chan = "1 CHAN\n" . $head_date; } $gedrec = '0 @' . $xref1 . '@ ' . $type . "\n" . $chan; } } if (!empty($gedrec)) {
/** * get a singleton instance of the results * returned by the soapClient search method * * @param string $query - the query to search on * @param integer $start - the start index of the results to return * @param integer $max - the maximum number of results to return */ function &search($query, $start = 0, $max = 100) { //$this->authenticate(); //$result = $this->soapClient->search($this->SID, $query, $start, $max); $search_results = search_indis(array($query), array($this->gedfile), 'AND', true); // loop thru the returned result of the method call foreach ($search_results as $gid => $indi) { // privatize the gedcoms returned $gedrec = privatize_gedcom($indi["gedcom"]); //AddToLog(substr($gedrec,0,50)); // set the fields that exist and return all the results that are not private if (preg_match("~" . $query . "~i", $gedrec) > 0) { $person = new SOAP_Value('person', 'person', ""); $person->PID = $gid; $person->gedcomName = get_gedcom_value("NAME", 1, $gedrec, '', false); $person->birthDate = get_gedcom_value("BIRT:DATE", 1, $gedrec, '', false); $person->birthPlace = get_gedcom_value("BIRT:PLAC", 1, $gedrec, '', false); $person->deathDate = get_gedcom_value("DEAT:DATE", 1, $gedrec, '', false); $person->deathPlace = get_gedcom_value("DEAT:PLAC", 1, $gedrec, '', false); $person->gender = get_gedcom_value("SEX", 1, $gedrec, '', false); //$search_result_element['gedcom'] = $gedrec; $results_array[] = $person; } } // AddToLog('Found '.count($results_array).' after privatizing'); // set the number of possible results //$results[0]['totalResults'] = count($results_array); $results_array = array_slice($results_array, $start, $max); //$results[0]['persons'] = $results_array; $return = new SOAP_Value('searchResult', 'searchResult', ""); $return->totalResults = count($results_array); $return->persons = $results_array; return $return; }
/** * print fact DATE TIME * * @param string $factrec gedcom fact record * @param boolean $anchor option to print a link to calendar * @param boolean $time option to print TIME value * @param string $fact optional fact name (to print age) * @param string $pid optional person ID (to print age) * @param string $indirec optional individual record (to print age) */ function print_fact_date($factrec, $anchor = false, $time = false, $fact = false, $pid = false, $indirec = false) { global $factarray, $pgv_lang, $SEARCH_SPIDER; $ct = preg_match("/2 DATE (.+)/", $factrec, $match); if ($ct > 0) { print " "; // link to calendar if ($anchor && empty($SEARCH_SPIDER)) { print get_date_url($match[1]); } else { print get_changed_date(trim($match[1])); } // time if ($time) { $timerec = get_sub_record(2, "2 TIME", $factrec); if (empty($timerec)) { $timerec = get_sub_record(2, "2 DATE", $factrec); } $tt = preg_match("/[2-3] TIME (.*)/", $timerec, $tmatch); if ($tt > 0) { print " - <span class=\"date\">" . $tmatch[1] . "</span>"; } } if ($fact and $pid) { // age of parents at child birth if ($fact == "BIRT") { print_parents_age($pid, $match[1]); } else { if ($fact != "CHAN") { if (!$indirec) { $indirec = find_person_record($pid); } // do not print age after death $deatrec = get_sub_record(1, "1 DEAT", $indirec); if (empty($deatrec) || compare_facts($factrec, $deatrec) != 1 || strstr($factrec, "1 DEAT")) { print get_age($indirec, $match[1]); } } } } print " "; } else { // 1 DEAT Y with no DATE => print YES // 1 DEAT N is not allowed // It is not proper GEDCOM form to use a N(o) value with an event tag to infer that it did not happen. $factrec = str_replace("\r\nPGV_OLD\r\n", "", $factrec); $factrec = str_replace("\r\nPGV_NEW\r\n", "", $factrec); $factdetail = preg_split("/ /", trim($factrec)); if (isset($factdetail)) { if (count($factdetail) == 3) { if (strtoupper($factdetail[2]) == "Y") { print $pgv_lang["yes"]; } } } } // gedcom indi age $ages = array(); $agerec = get_gedcom_value("AGE", 2, $factrec); $daterec = get_sub_record(2, "2 DATE", $factrec); if (empty($agerec)) { $agerec = get_gedcom_value("AGE", 3, $daterec); } $ages[0] = $agerec; // gedcom husband age $husbrec = get_sub_record(2, "2 HUSB", $factrec); if (!empty($husbrec)) { $agerec = get_gedcom_value("AGE", 3, $husbrec); } else { $agerec = ""; } $ages[1] = $agerec; // gedcom wife age $wiferec = get_sub_record(2, "2 WIFE", $factrec); if (!empty($wiferec)) { $agerec = get_gedcom_value("AGE", 3, $wiferec); } else { $agerec = ""; } $ages[2] = $agerec; // print gedcom ages foreach ($ages as $indexval => $agerec) { if (!empty($agerec)) { print "<span class=\"label\">"; if ($indexval == 1) { print $pgv_lang["husband"]; } else { if ($indexval == 2) { print $pgv_lang["wife"]; } else { print $factarray["AGE"]; } } print "</span>: "; $age = get_age_at_event($agerec); print PrintReady($age); print " "; } } }
/** * add historical events to individual facts array * * @return records added to indifacts array * * Historical facts are imported from optional language file : histo.xx.php * where xx is language code * This file should contain records similar to : * * $histo[]="1 EVEN\n2 TYPE History\n2 DATE 11 NOV 1918\n2 NOTE WW1 Armistice"; * $histo[]="1 EVEN\n2 TYPE History\n2 DATE 8 MAY 1945\n2 NOTE WW2 Armistice"; * etc... * */ function add_historical_facts() { global $LANGUAGE, $lang_short_cut; global $SHOW_RELATIVES_EVENTS; if (!$SHOW_RELATIVES_EVENTS) { return; } // Only include events between birth and death $bDate = $this->getEstimatedBirthDate(); $dDate = $this->getEstimatedDeathDate(); if (!$bDate->isOK()) { return; } if ($SHOW_RELATIVES_EVENTS && file_exists('languages/histo.' . $lang_short_cut[$LANGUAGE] . '.php')) { include 'languages/histo.' . $lang_short_cut[$LANGUAGE] . '.php'; foreach ($histo as $indexval => $hrec) { $sdate = new GedcomDate(get_gedcom_value('DATE', 2, $hrec, '', false)); if ($sdate->isOK() && GedcomDate::Compare($this->getEstimatedBirthDate(), $sdate) <= 0 && GedcomDate::Compare($sdate, $this->getEstimatedDeathDate()) <= 0) { $event = new Event($hrec); $event->setParentObject($this); $this->indifacts[] = $event; } } } }