' . htmlspecialchars($value) . '' . WT_JS_START . 'jQuery("#' . $name . '").editable("' . WT_SERVER_NAME . WT_SCRIPT_PATH . 'save.php", {submit:"' . i18n::translate('OK') . '", style:"inherit"})' . WT_JS_END; } // Create a '.$html.''; } // An inline-editing version of select_edit_control() function select_edit_control_inline($name, $values, $empty, $selected, $extra='') { if (!is_null($empty)) { // Push ''=>$empty onto the front of the array, maintaining keys $tmp=array(''=>$empty); foreach ($values as $key=>$value) { $tmp[$key]=$value; } $values=$tmp; } $values['selected']=$selected; return '' . (array_key_exists($selected, $values) ? htmlspecialchars($values[$selected]) : ''). '' . WT_JS_START . 'jQuery("#' . $name . '").editable("' . WT_SERVER_NAME . WT_SCRIPT_PATH . 'save.php", {type:"select", data:' . json_encode($values) . ', submit:"' . i18n::translate('OK') . '", style:"inherit", callback:function(value, settings) {jQuery(this).html(settings.data[value]);} })' . WT_JS_END; } // Create a set of radio buttons for a form // $name - the ID for the form element // $values - array of value=>display items // $selected - the currently selected item (if any) // $extra - extra markup for field (e.g. tab key sequence) function radio_buttons($name, $values, $selected, $extra='') { $html=''; foreach ($values as $key=>$value) { $uniqueID = $name.floor(microtime() * 1000000); $html.=''.htmlspecialchars($value).''; } return $html; } // Print an edit control for a Yes/No field function edit_field_yes_no($name, $selected=false, $extra='') { return radio_buttons( $name, array(false=>i18n::translate('no'),true=>i18n::translate('yes')), $selected, $extra ); //return select_edit_control( //$name, array(true=>i18n::translate('yes'), false=>i18n::translate('no')), null, $selected, $extra //); } // An inline-editing version of edit_field_yes_no() function edit_field_yes_no_inline($name, $selected=false, $extra='') { return select_edit_control_inline( $name, array(true=>i18n::translate('yes'), false=>i18n::translate('no')), null, $selected, $extra ); } // Print an edit control for a checkbox function checkbox($name, $is_checked=false, $extra='') { return ''; } // Print an edit control for a checkbox, with a hidden field to store one of the two states. // By default, a checkbox is either set, or not sent. // This function gives us a three options, set, unset or not sent. // Useful for dynamically generated forms where we don't know what elements are present. function two_state_checkbox($name, $is_checked=0, $extra='') { return ''. ''; } // Print a set of edit controls to select languages function edit_language_checkboxes($field_prefix, $languages) { echo ''; $i=0; foreach (i18n::installed_languages() as $code=>$name) { $content = ' '.$name.''; // print in two columns if (($i % 2)==0) { echo ''; } else { echo ''; } $i++; } if (($i % 2)!=0) echo ''; echo '
', $content, '', $content, '
'; } // Print an edit control for access level function edit_field_access_level($name, $selected='', $extra='') { $ACCESS_LEVEL=array( WT_PRIV_PUBLIC=>i18n::translate('Show to visitors'), WT_PRIV_USER =>i18n::translate('Show to members'), WT_PRIV_NONE =>i18n::translate('Show to managers'), WT_PRIV_HIDE =>i18n::translate('Hide from everyone') ); return select_edit_control($name, $ACCESS_LEVEL, null, $selected, $extra); } // Print an edit control for a contact method field function edit_field_contact($name, $selected='', $extra='') { // Different ways to contact the users $CONTACT_METHODS=array( 'messaging' =>i18n::translate('webtrees internal messaging'), 'messaging2'=>i18n::translate('Internal messaging with emails'), 'messaging3'=>i18n::translate('webtrees sends emails with no storage'), 'mailto' =>i18n::translate('Mailto link'), 'none' =>i18n::translate('No contact'), ); if (!get_site_setting('STORE_MESSAGES')) { unset($CONTACT_METHODS['messaging'], $CONTACT_METHODS['messaging2']); } return select_edit_control($name, $CONTACT_METHODS, null, $selected, $extra); } // Print an edit control for a language field function edit_field_language($name, $selected='', $extra='') { return select_edit_control($name, i18n::installed_languages(), null, $selected, $extra); } // An inline-editing version of edit_field_language() function edit_field_language_inline($name, $selected=false, $extra='') { return select_edit_control_inline( $name, i18n::installed_languages(), null, $selected, $extra ); } // Print an edit control for a username function edit_field_username($name, $selected='', $extra='') { $all_users=WT_DB::prepare( "SELECT user_name, CONCAT_WS(' ', real_name, '-', user_name) FROM `##user` ORDER BY real_name" )->fetchAssoc(); // The currently selected user may not exist if ($selected && !array_key_exists($selected, $all_users)) { $all_users[$selected]=$selected; } return select_edit_control($name, $all_users, '-', $selected, $extra); } // Print an edit control for a ADOP field function edit_field_adop_u($name, $selected='', $extra='') { global $ADOP_CODES; return select_edit_control($name, $ADOP_CODES, null, $selected, $extra); } // Print an edit control for a ADOP female field function edit_field_adop_f($name, $selected='', $extra='') { global $ADOP_CODES_F; return select_edit_control($name, $ADOP_CODES_F, null, $selected, $extra); } // Print an edit control for a ADOP male field function edit_field_adop_m($name, $selected='', $extra='') { global $ADOP_CODES_M; return select_edit_control($name, $ADOP_CODES_M, null, $selected, $extra); } // Print an edit control for a PEDI field function edit_field_pedi_u($name, $selected='', $extra='') { global $PEDI_CODES; return select_edit_control($name, $PEDI_CODES, '', $selected, $extra); } // Print an edit control for a PEDI female field function edit_field_pedi_f($name, $selected='', $extra='') { global $PEDI_CODES_F; return select_edit_control($name, $PEDI_CODES_F, '', $selected, $extra); } // Print an edit control for a PEDI male field function edit_field_pedi_m($name, $selected='', $extra='') { global $PEDI_CODES_M; return select_edit_control($name, $PEDI_CODES_M, '', $selected, $extra); } // Print an edit control for a RELA field function edit_field_rela($name, $selected='', $extra='') { global $RELA_CODES; uasort($RELA_CODES, 'strcasecmp'); // The user is allowed to specify values that aren't in the list. if (!array_key_exists($selected, $RELA_CODES)) { $RELA_CODES[$selected]=$selected; } return select_edit_control($name, $RELA_CODES, '', $selected, $extra); } // Print an edit control for a default tab field function edit_field_default_tab($name, $selected='', $extra='') { $tabs=array(); foreach (WT_Module::getActiveTabs() as $module) { $tabs[$module->getName()]=$module->getTitle(); } return select_edit_control($name, $tabs, null, $selected, $extra); } //-- this function creates a new unique connection //-- and adds it to the connections file //-- it returns the connection identifier function newConnection() { return WT_SESSION_NAME."\t".Zend_Session::getId()."\n"; } /** * Check if the given gedcom record has changed since the last session access * This is used to check if the gedcom record changed between the time the user * loaded the individual page and the time they clicked on a link to edit * the data. * * @param string $pid The gedcom id of the record to check */ function checkChangeTime($pid, $gedrec, $last_time) { $change=WT_DB::prepare( "SELECT UNIX_TIMESTAMP(change_time) AS change_time, user_name". " FROM `##change`". " JOIN `##user` USING (user_id)". " WHERE status<>'rejected' AND gedcom_id=? AND xref=? AND change_time>?". " ORDER BY change_id DESC". " LIMIT 1" )->execute(array(WT_GED_ID, $pid, $last_time))->fetchOneRow(); if ($change) { $changeTime=$change->change_time; $changeUser=$change->user_name; } else { $changeTime = 0; $changeUser = ''; } if (isset($_REQUEST['linenum']) && $changeTime!=0 && $last_time && $changeTime > $last_time) { echo "", i18n::translate('The record with id %s was changed by another user since you last accessed it.', $pid), "

"; if (!empty($changeUser)) echo i18n::translate('This record was last changed by %s at %s', $changeUser, date("d M Y H:i:s", $changeTime)), "

"; echo i18n::translate('Please reload the previous page to make sure you are working with the most recent record.'), "
"; print_simple_footer(); exit; } } /** * This function will replace a gedcom record with * the id $gid with the $gedrec * @param string $gid The XREF id of the record to replace * @param string $gedrec The new gedcom record to replace with * @param boolean $chan Whether or not to update/add the CHAN record */ function replace_gedrec($gid, $ged_id, $gedrec, $chan=true) { global $pgv_private_records; //-- restore any data that was hidden during privatizing if (isset($pgv_private_records[$gid])) { $privatedata = trim(get_last_private_data($gid)); $subs = get_all_subrecords("\n".$privatedata, '', false, false); foreach ($subs as $s=>$sub) { if (strstr($gedrec, $sub)===false) $gedrec = trim($gedrec)."\n".$sub; } unset($pgv_private_records[$gid]); } if (($gedrec = check_gedcom($gedrec, $chan))!==false) { //-- the following block of code checks if the XREF was changed in this record. //-- if it was changed we add a warning to the change log $ct = preg_match("/0 @(.*)@/", $gedrec, $match); if ($ct>0) { $oldgid = $gid; $gid = trim($match[1]); if ($oldgid!=$gid) { if ($gid=="REF" || $gid=="new" || $gid=="NEW") { $gedrec = preg_replace("/0 @(.*)@/", "0 @".$oldgid."@", $gedrec); $gid = $oldgid; } else { AddToLog("Warning: $oldgid was changed to $gid", 'edit'); } } } $old_gedrec=find_gedcom_record($gid, $ged_id, true); if ($old_gedrec!=$gedrec) { WT_DB::prepare( "INSERT INTO `##change` (gedcom_id, xref, old_gedcom, new_gedcom, user_id) VALUES (?, ?, ?, ?, ?)" )->execute(array( $ged_id, $gid, $old_gedrec, $gedrec, WT_USER_ID )); } if (WT_USER_AUTO_ACCEPT) { accept_all_changes($gid, WT_GED_ID); } return true; } return false; } //-- this function will append a new gedcom record at //-- the end of the gedcom file. function append_gedrec($gedrec, $ged_id) { if (($gedrec = check_gedcom($gedrec, true))!==false && preg_match("/0 @(".WT_REGEX_XREF.")@ (".WT_REGEX_TAG.")/", $gedrec, $match)) { $gid = $match[1]; $type = $match[2]; if (preg_match("/\d/", $gid)==0) { $xref = get_new_xref($type); } else { $xref = $gid; } $gedrec=preg_replace("/^0 @(.*)@/", "0 @$xref@", $gedrec); WT_DB::prepare( "INSERT INTO `##change` (gedcom_id, xref, old_gedcom, new_gedcom, user_id) VALUES (?, ?, ?, ?, ?)" )->execute(array( $ged_id, $xref, '', $gedrec, WT_USER_ID )); AddToLog("Appending new $type record $xref", 'edit'); if (WT_USER_AUTO_ACCEPT) { accept_all_changes($xref, WT_GED_ID); } return $xref; } return false; } //-- this function will delete the gedcom record with //-- the given $xref function delete_gedrec($xref, $ged_id) { WT_DB::prepare( "INSERT INTO `##change` (gedcom_id, xref, old_gedcom, new_gedcom, user_id) VALUES (?, ?, ?, ?, ?)" )->execute(array( $ged_id, $xref, find_gedcom_record($xref, $ged_id, true), '', WT_USER_ID )); AddToLog("Deleting gedcom record $xref", 'edit'); if (WT_USER_AUTO_ACCEPT) { accept_all_changes($xref, WT_GED_ID); } } //-- this function will check a GEDCOM record for valid gedcom format function check_gedcom($gedrec, $chan=true) { $gedrec = trim(stripLRMRLM($gedrec)); $ct = preg_match("/0 @(.*)@ (.*)/", $gedrec, $match); if ($ct==0) { echo "ERROR 20: Invalid GEDCOM format"; AddToLog("ERROR 20: Invalid GEDCOM format:\n".$gedrec, 'edit'); if (WT_DEBUG) { echo "
$gedrec
"; echo debug_print_backtrace(); } return false; } $gedrec = trim($gedrec); if ($chan) { $pos1 = strpos($gedrec, "1 CHAN"); if ($pos1!==false) { $pos2 = strpos($gedrec, "\n1", $pos1+4); if ($pos2===false) $pos2 = strlen($gedrec); $newgedrec = substr($gedrec, 0, $pos1); $newgedrec .= "1 CHAN\n2 DATE ".strtoupper(date("d M Y"))."\n"; $newgedrec .= "3 TIME ".date("H:i:s")."\n"; $newgedrec .= "2 _WT_USER ".WT_USER_NAME."\n"; $newgedrec .= substr($gedrec, $pos2); $gedrec = $newgedrec; } else { $newgedrec = "\n1 CHAN\n2 DATE ".strtoupper(date("d M Y"))."\n"; $newgedrec .= "3 TIME ".date("H:i:s")."\n"; $newgedrec .= "2 _WT_USER ".WT_USER_NAME; $gedrec .= $newgedrec; } } $gedrec = preg_replace('/\\\+/', "\\", $gedrec); //-- remove any empty lines $lines = explode("\n", $gedrec); $newrec = ''; foreach ($lines as $ind=>$line) { //-- remove any whitespace $line = trim($line); if (!empty($line)) $newrec .= $line."\n"; } $newrec = html_entity_decode($newrec, ENT_COMPAT, 'UTF-8'); return $newrec; } /** * remove a subrecord from a parent record by gedcom tag * * @param string $oldrecord the parent record to remove the subrecord from * @param string $tag the GEDCOM subtag to start deleting at * @param string $gid [optional] gid can be used to limit to @gid@ * @param int $num [optional] num specifies which multiple of the tag to remove, set to -1 to remove all * @return string returns the oldrecord minus the subrecord(s) */ function remove_subrecord($oldrecord, $tag, $gid='', $num=0) { $newrec = ''; $gedlines = explode("\n", $oldrecord); $n = 0; $matchstr = $tag; if (!empty($gid)) $matchstr .= " @".$gid."@"; for ($i=0; $i0) { if ($num==-1 || $n==$num) { $glevel = $gedlines[$i]{0}; $i++; while ((isset($gedlines[$i]))&&(strlen($gedlines[$i])<4 || $gedlines[$i]{0}>$glevel)) $i++; $i--; } else $n++; } else $newrec .= $gedlines[$i]."\n"; } return trim($newrec); } /** * delete a subrecord from a parent record using the linenumber * * @param string $oldrecord parent record to delete from * @param int $linenum linenumber where the subrecord to delete starts * @return string the new record */ function remove_subline($oldrecord, $linenum) { $newrec = ''; $gedlines = explode("\n", $oldrecord); for ($i=0; $i<$linenum; $i++) { if (trim($gedlines[$i])!='') $newrec .= $gedlines[$i]."\n"; } if (isset($gedlines[$linenum])) { $fields = explode(' ', $gedlines[$linenum]); $glevel = $fields[0]; $i++; if ($i$glevel)) $i++; while ($i"; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; if (preg_match('/^add(child|spouse|newparent|newrepository)/', $nextaction)) { echo ""; } echo ""; // 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(); foreach ($STANDARD_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 $famrec=find_gedcom_record($famid, WT_GED_ID, true); $parents=find_parents_in_record($famrec); $father_name=get_gedcom_value('NAME', 0, find_person_record($parents['HUSB'], WT_GED_ID)); $mother_name=get_gedcom_value('NAME', 0, find_person_record($parents['WIFE'], WT_GED_ID)); // We'll need the spouse/child's name to set the spouse/parent's surname $prec=find_gedcom_record($pid, WT_GED_ID, true); $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 (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['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('/('.WT_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' || (strpos($namerec, '2 _MARNM')!==false)) $adv_name_fields['_MARNM']=''; $person = Person::getInstance($pid); 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", '', translate_fact("NAME:{$tag}", $person)); } } // 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", '', translate_fact("NAME:{$tag}", $person)); } } // Handle any other NAME subfields that aren't included above (SOUR, NOTE, _CUSTOM, etc) if ($namerec!='' && $namerec!="NEW") { $gedlines = explode("\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; $j2) $text .= ' '; $text .= $fields[$j]; } $iscont = false; while (($i+10)) { $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
'; // 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('/('.WT_REGEX_TAG.')/', $QUICK_REQUIRED_FACTS, $matches)) { foreach ($matches[1] as $match) { if (!in_array($match, explode('|', WT_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('/('.WT_REGEX_TAG.')/', $QUICK_REQUIRED_FAMFACTS, $matches)) { foreach ($matches[1] as $match) { addSimpleTags($match); } } } if (preg_match_all('/('.WT_REGEX_TAG.')/', $QUICK_REQUIRED_FACTS, $matches)) { foreach ($matches[1] as $match) { if (in_array($match, explode('|', WT_EVENTS_DEAT))) { addSimpleTags($match); } } } } if (WT_USER_IS_ADMIN) { echo ""; } echo "
"; echo i18n::translate('Admin Option'), help_link('no_update_CHAN'), ""; if ($NO_UPDATE_CHAN) { echo ""; } else { echo ""; } echo i18n::translate('Do not update the CHAN (Last Change) record'), "
"; if (isset($famrec)) { $event = new Event(get_sub_record(1, "1 CHAN", $famrec)); echo format_fact_date($event, false, true); } echo "
"; 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 ""; if (preg_match('/^add(child|spouse|newparent|source)/', $nextaction)) { echo ""; } echo ""; ?> "; else $Link = $text; $out = ' '; $out .= ""; $out .= $Link; $out .= ""; $out .= ""; if ($asString) return $out; else echo $out; } /** * @todo add comments */ function print_addnewmedia_link($element_id) { global $WT_IMAGES, $pid; $text = i18n::translate('Add a new media item'); if (isset($WT_IMAGES["button_addmedia"])) $Link = "\"".$text."\""; else $Link = $text; echo '   '; echo $Link; echo ""; } /** * @todo add comments */ function print_addnewrepository_link($element_id) { global $WT_IMAGES; $text = i18n::translate('Create Repository'); if (isset($WT_IMAGES["button_addrepository"])) $Link = "\"".$text."\""; else $Link = $text; echo "   "; echo $Link; echo ""; } /** * @todo add comments */ function print_addnewnote_link($element_id) { global $WT_IMAGES, $pid; $text = i18n::translate('Create a new Shared Note'); if (isset($WT_IMAGES["button_addnote"])) $Link = "\"".$text."\""; else $Link = $text; echo "   "; echo $Link; echo ""; } /** * // Used in GEDFact CENS assistant ===================== */ function print_addnewnote_assisted_link($element_id) { global $WT_IMAGES, $pid; $text = i18n::translate('Create a new Shared Note using Assistant'); if (isset($WT_IMAGES["button_addnote"])) $Link = "\"".$text."\""; else $Link = $text; echo "   "; echo $Link; echo ""; } /** * @todo add comments */ function print_editnote_link($note_id) { global $WT_IMAGES; $text = i18n::translate('Edit Shared Note'); if (isset($WT_IMAGES["button_note"])) $Link = "\"".$text."\""; else $Link = $text; echo ""; echo $Link; echo ""; } /** * @todo add comments */ function print_addnewsource_link($element_id) { global $WT_IMAGES; $text = i18n::translate('Create a new source'); if (isset($WT_IMAGES["button_addsource"])) $Link = "\"".$text."\""; else $Link = $text; echo "   "; echo $Link; echo ""; } /** * add a new tag input field * * called for each fact to be edited on a form. * Fact level=0 means a new empty form : data are POSTed by name * else data are POSTed using arrays : * glevels[] : tag level * islink[] : tag is a link * tag[] : tag name * text[] : tag value * * @param string $tag fact record to edit (eg 2 DATE xxxxx) * @param string $upperlevel optional upper level tag (eg BIRT) * @param string $label An optional label to echo instead of the default * @param string $readOnly optional, when "READONLY", fact data can't be changed * @param string $noClose optional, when "NOCLOSE", final "" won't be printed * (so that additional text can be printed in the box) * @param boolean $rowDisplay True to have the row displayed by default, false to hide it by default */ function add_simple_tag($tag, $upperlevel='', $label='', $readOnly='', $noClose='', $rowDisplay=true) { global $WT_IMAGES, $MEDIA_DIRECTORY, $TEMPLE_CODES; global $tags, $emptyfacts, $main_fact, $TEXT_DIRECTION; global $NPFX_accept, $SPFX_accept, $NSFX_accept, $FILE_FORM_accept, $upload_count; global $STATUS_CODES, $SPLIT_PLACES, $pid, $gender, $linkToID; global $bdm, $RESN_CODES; global $QUICK_REQUIRED_FACTS, $QUICK_REQUIRED_FAMFACTS, $PREFER_LEVEL2_SOURCES; global $action, $event_add; global $CensDate, $MEDIA_TYPES; if (substr($tag, 0, strpos($tag, "CENS"))) { $event_add="census_add"; } if (substr($tag, 0, strpos($tag, "PLAC"))) { ?> "; if (in_array($fact, $subnamefacts) || $fact=="LATI" || $fact=="LONG") { echo ""; } else { echo ""; } if (WT_DEBUG) { echo $element_name, "
"; } // tag name if (!empty($label)) { if ($label=="Note" && $islink) { echo i18n::translate('Shared note'); } else { echo $label; } } else { if ($fact=="NOTE" && $islink) { echo translate_fact('SHARED_NOTE'); /* if (file_exists(WT_ROOT.'modules/GEDFact_assistant/_CENS/census_1_ctrl.php') && $pid && $label=="GEDFact Assistant") { // use $label (GEDFact Assistant); } else { echo i18n::translate('Shared note'); } */ } else { echo translate_fact($fact); } } // help link // If using GEDFact-assistant window if ($action=="addnewnote_assisted") { // Do not print on GEDFact Assistant window } else { if (!in_array($fact, $emptyfacts)) { if ($fact=="DATE") { echo help_link('def_gedcom_date'); } elseif ($fact=="FORM" && $upperlevel!='OBJE') { echo help_link('FORM'); } elseif ($fact=="NOTE" && $islink) { if (file_exists(WT_ROOT.'modules/GEDFact_assistant/_CENS/census_1_ctrl.php') && $pid && $label=="GEDFact Assistant") { echo help_link('edit_add_GEDFact_ASSISTED'); } else { echo help_link('edit_add_SHARED_NOTE'); } } else { echo help_link($fact); } } } // tag level if ($level>0) { if ($fact=="TEXT" and $level>1) { echo ""; echo ""; echo ""; //-- leave data text[] value empty because the following TEXT line will //--- cause the DATA to be added echo ""; } echo ""; echo ""; echo ""; // Shared Notes Debug ------------------------------------------------ // Please leave until GEDFact assistant/_CENS is released - B.Holland // echo "
Label = ".$label; // echo "
Level = ".$level; // echo "
Link = ".$islink; // echo "
Fact = ".$fact; // echo "
Value = ".$value; // End Debug --------------------------------------------------------- } echo ""; // value echo ""; if (WT_DEBUG) { echo $tag, "
"; } // retrieve linked NOTE if ($fact=="NOTE" && $islink) { $note1=Note::getInstance($value); if ($note1) { $noterec=$note1->getGedcomRecord(); preg_match("/$value/i", $noterec, $notematch); $value=$notematch[0]; } } if (in_array($fact, $emptyfacts)&& (empty($value) || $value=="y" || $value=="Y")) { $value = strtoupper($value); //-- don't default anything to Y when adding events through people //-- default to Y when specifically adding one of these events if ($level==1) $value="Y"; // default YES echo ""; if ($level<=1) { echo ""; echo i18n::translate('Yes'); } /* // If GEDFAct_assistant/_CENS/ module exists && we are on the INDI page && action is ADD a new CENS event // Then show the add Shared note input field and the GEDFact assisted icon. // If GEDFAct_assistant/_CENS/ module not installed ... do not show if (file_exists(WT_ROOT.'modules/GEDFact_assistant/_CENS/census_1_ctrl.php') && $pid && $fact=="CENS") { $type_pid=GedcomRecord::getInstance($pid); if ($type_pid->getType()=="INDI" && $action=="add" ) { add_simple_tag("2 SHARED_NOTE", "", "GEDFact Assistant"); } } // ----------------------------------------------------------------------------------------------------- */ } else if ($fact=="TEMP") { echo select_edit_control($element_name, $TEMPLE_CODES, i18n::translate('No Temple - Living Ordinance'), $value); } else if ($fact=="ADOP") { switch ($gender) { case 'M': echo edit_field_adop_m($element_name, $value); break; case 'F': echo edit_field_adop_f($element_name, $value); break; default: echo edit_field_adop_u($element_name, $value); break; } } else if ($fact=="PEDI") { switch ($gender) { case 'M': echo edit_field_pedi_m($element_name, $value); break; case 'F': echo edit_field_pedi_f($element_name, $value); break; default: echo edit_field_pedi_u($element_name, $value); break; } } else if ($fact=="STAT") { echo select_edit_control($element_name, $STATUS_CODES, '', $value); } else if ($fact=="RELA") { echo edit_field_rela($element_name, strtolower($value)); } else if ($fact=="_WT_USER") { echo edit_field_username($element_name, $value); } else if ($fact=="RESN") { ?> "; echo ""; foreach ($RESN_CODES as $resn_val => $text) { if ($resn_val=="none") $resnv=""; else $resnv=$resn_val; echo ""; } echo "
", $text, ""; echo "
 \"",
"; } else if ($fact=="_PRIM" or $fact=="_THUM") { echo ""; } else if ($fact=="SEX") { echo ""; } else if ($fact == "TYPE" && $level == '3') { //-- Build the selector for the Media "TYPE" Fact echo ""; } else if (($fact=="NAME" && $upperlevel!='REPO') || $fact=="_MARNM") { // Populated in javascript from sub-tags echo ""; echo "", PrintReady(htmlspecialchars($value)), ""; echo " "; if (isset($WT_IMAGES["edit_indi"])) echo "\"","; else echo "[", i18n::translate('Edit name'), "]"; echo ""; } else { // textarea if ($rows>1) echo "
"; else { // text // If using GEDFact-assistant window if ($action=="addnewnote_assisted") { echo ""; } // split PLAC if ($fact=="PLAC" && $readOnly=='') { echo "
"; print_specialchar_link($element_id, false); print_findplace_link($element_id); echo "
"; echo "\"","; if ($SPLIT_PLACES) { if (!function_exists("print_place_subfields")) { require WT_ROOT.'includes/functions/functions_places.php'; } setup_place_subfields($element_id); print_place_subfields($element_id); } } else if (($cols>20 || $fact=="NPFX") && $readOnly=='') print_specialchar_link($element_id, false); } // MARRiage TYPE : hide text field and show a selection list if ($fact=="TYPE" and $tags[0]=="MARR") { echo ""; echo ""; } // popup links if ($readOnly=='') { if ($fact=="DATE") { print_calendar_popup($element_id); // If GEDFact_assistant/_CENS/ module is installed ------------------------------------------------- if ($action=="add" && file_exists(WT_ROOT.'modules/GEDFact_assistant/_CENS/census_1_ctrl.php') ) { if (isset($CensDate) && $CensDate=="yes") { require_once WT_ROOT.'modules/GEDFact_assistant/_CENS/census_asst_date.php'; } } // ------------------------------------------------------------------------------------------------- } if ($fact=="FAMC") print_findfamily_link($element_id, ''); if ($fact=="FAMS") print_findfamily_link($element_id, ''); if ($fact=="ASSO") print_findindi_link($element_id, ''); if ($fact=="FILE") print_findmedia_link($element_id, "0file"); if ($fact=="SOUR") { print_findsource_link($element_id); print_addnewsource_link($element_id); //print_autopaste_link($element_id, array("S1", "S2"), false, false, true); //-- checkboxes to apply '1 SOUR' to BIRT/MARR/DEAT as '2 SOUR' if ($level==1) { echo '
'; if ($PREFER_LEVEL2_SOURCES==='0') { $level1_checked=''; $level2_checked=''; } else if ($PREFER_LEVEL2_SOURCES==='1' || $PREFER_LEVEL2_SOURCES===true) { $level1_checked=''; $level2_checked=' checked="checked"'; } else { $level1_checked=' checked="checked"'; $level2_checked=''; } if (strpos($bdm, 'B')!==false) { echo ' '; echo i18n::translate('Individual'); if (preg_match_all('/('.WT_REGEX_TAG.')/', $QUICK_REQUIRED_FACTS, $matches)) { foreach ($matches[1] as $match) { if (!in_array($match, explode('|', WT_EVENTS_DEAT))) { echo ' '; echo i18n::translate($match); } } } } if (strpos($bdm, 'D')!==false) { if (preg_match_all('/('.WT_REGEX_TAG.')/', $QUICK_REQUIRED_FACTS, $matches)) { foreach ($matches[1] as $match) { if (in_array($match, explode('|', WT_EVENTS_DEAT))) { echo ' '; echo i18n::translate($match); } } } } if (strpos($bdm, 'M')!==false) { echo ' '; echo i18n::translate('Family'); if (preg_match_all('/('.WT_REGEX_TAG.')/', $QUICK_REQUIRED_FAMFACTS, $matches)) { foreach ($matches[1] as $match) { echo ' '; echo i18n::translate($match); } } } } } if ($fact=="REPO") { print_findrepository_link($element_id); print_addnewrepository_link($element_id); } // Shared Notes Icons ======================================== if ($fact=="NOTE" && $islink) { // Print regular Shared Note icons --------------------------- echo "  "; print_findnote_link($element_id); print_addnewnote_link($element_id); if ($value!="") { echo "   "; print_editnote_link($value); } // If GEDFact_assistant/_CENS/ module exists && we are on the INDI page and the action is a GEDFact CENS assistant addition. // Then show the add Shared note assisted icon, if not ... show regular Shared note icons. if (file_exists(WT_ROOT.'modules/GEDFact_assistant/_CENS/census_1_ctrl.php') && ($action=="add" || $action=="edit" ) && $pid) { // Check if a CENS event --------------------------- if ($event_add=="census_add") { $type_pid=GedcomRecord::getInstance($pid); if ($type_pid->getType()=="INDI" ) { echo "     "; echo "     "; echo ""; echo i18n::translate('Shared Note using Assistant'); echo ""; print_addnewnote_assisted_link($element_id); } } } } if ($fact=="OBJE") { print_findmedia_link($element_id, "1media"); } if ($fact=="OBJE" && !$value) { print_addnewmedia_link($element_id); $value = "new"; } echo "
"; } // current value if ($TEXT_DIRECTION=="ltr") { if ($fact=="DATE") { $date=new GedcomDate($value); echo $date->Display(false); } if (($fact=="ASSO" || $fact=="SOUR" || $fact=="OBJE" || ($fact=="NOTE" && $islink)) && $value) { $record=GedcomRecord::getInstance($value); if ($record) { echo ' ', PrintReady($record->getFullName()), ' (', $value, ')'; } else if ($value!="new") { echo ' ', $value; } } } else { if ($fact=="DATE") { $date=new GedcomDate($value); echo getRLM(), $date->Display(false), getRLM(); } if (($fact=="ASSO" || $fact=="SOUR" || $fact=="OBJE" || ($fact=="NOTE" && $islink)) && $value) { $record=GedcomRecord::getInstance($value); if ($record) { echo getRLM(), PrintReady($record->getFullName()), ' ', getLRM(), '(', $value, ') ', getLRM(), getRLM(); } else if ($value!="new") { echo getRLM(), $value, ' ', getRLM(); } } } // pastable values if ($readOnly=='') { if ($fact=="SPFX") print_autopaste_link($element_id, $SPFX_accept); if ($fact=="NSFX") print_autopaste_link($element_id, $NSFX_accept); if ($fact=="FORM" && $upperlevel=='OBJE') print_autopaste_link($element_id, $FILE_FORM_accept, false, false); } if ($noClose != "NOCLOSE") echo ""; return $element_id; } /** * prints collapsable fields to add ASSO/RELA, SOUR, OBJE ... * * @param string $tag Gedcom tag name */ function print_add_layer($tag, $level=2, $printSaveButton=true) { global $WT_IMAGES, $MEDIA_DIRECTORY, $TEXT_DIRECTION, $gedrec, $FULL_SOURCES, $islink; if ($tag=="SOUR") { //-- Add new source to fact echo "\"\" ", i18n::translate('Add a new source citation'), ""; echo help_link('edit_add_SOUR'); echo "
"; echo "
"; if ($printSaveButton) echo ""; echo ""; // 2 SOUR $source = "SOUR @"; add_simple_tag("$level $source"); // 3 PAGE $page = "PAGE"; add_simple_tag(($level+1)." $page"); // 3 DATA // 4 TEXT $text = "TEXT"; add_simple_tag(($level+2)." $text"); if ($FULL_SOURCES) { // 4 DATE add_simple_tag(($level+2)." DATE", '', translate_fact('DATA:DATE')); // 3 QUAY add_simple_tag(($level+1)." QUAY"); } // 3 OBJE add_simple_tag(($level+1)." OBJE"); // 3 SHARED_NOTE add_simple_tag(($level+1)." SHARED_NOTE"); echo "
"; } if ($tag=="ASSO" || $tag=="ASSO2") { //-- Add a new ASSOciate if ($tag=="ASSO") { echo "\"\" ", i18n::translate('Add a new associate'), ""; echo help_link('edit_add_ASSO'); echo "
"; echo "
"; } else { echo "\"\" ", i18n::translate('Add a new associate'), ""; echo help_link('edit_add_ASSO'); echo "
"; echo "
"; } if ($printSaveButton) echo ""; echo ""; // 2 ASSO add_simple_tag(($level)." ASSO @"); // 3 RELA add_simple_tag(($level+1)." RELA"); // 3 NOTE add_simple_tag(($level+1)." NOTE"); // 3 SHARED_NOTE add_simple_tag(($level+1)." SHARED_NOTE"); echo "
"; } if ($tag=="NOTE") { //-- Retrieve existing note or add new note to fact $text = ''; echo "\"\" ", i18n::translate('Add a new note'), ""; echo help_link('edit_add_NOTE'); echo "
"; echo "
"; if ($printSaveButton) echo ""; echo ""; // 2 NOTE add_simple_tag(($level)." NOTE ".$text); echo "
"; } if ($tag=="SHARED_NOTE") { //-- Retrieve existing shared note or add new shared note to fact $text = ''; echo "\"\" ", i18n::translate('Add a new shared note'), ""; echo help_link('edit_add_SHARED_NOTE'); echo "
"; echo "
"; if ($printSaveButton) echo ""; echo ""; // 2 SHARED NOTE add_simple_tag(($level)." SHARED_NOTE "); echo "
"; } if ($tag=="OBJE") { //-- Add new obje to fact echo "\"\" ", i18n::translate('Add a new Multimedia object'), ""; echo help_link('add_media'); echo "
"; echo "
"; if ($printSaveButton) echo ""; echo ""; add_simple_tag($level." OBJE"); echo "
"; } if ($tag=="RESN") { //-- Retrieve existing resn or add new resn to fact $text = ''; echo "\"\" ", translate_fact('RESN'), ""; echo help_link('RESN'); echo "
"; echo "
"; if ($printSaveButton) echo ""; echo ""; // 2 RESN add_simple_tag(($level)." RESN ".$text); echo "
"; } } // Add some empty tags to create a new fact function addSimpleTags($fact) { global $ADVANCED_PLAC_FACTS; add_simple_tag("0 {$fact}"); add_simple_tag("0 DATE", $fact, translate_fact("{$fact}:DATE")); add_simple_tag("0 PLAC", $fact, translate_fact("{$fact}:PLAC")); if (preg_match_all('/('.WT_REGEX_TAG.')/', $ADVANCED_PLAC_FACTS, $match)) { foreach ($match[1] as $tag) { add_simple_tag("0 {$tag}", $fact, translate_fact("{$fact}:PLAC:{$tag}")); } } add_simple_tag("0 MAP", $fact); add_simple_tag("0 LATI", $fact); add_simple_tag("0 LONG", $fact); } // Assemble the pieces of a newly created record into gedcom function addNewName() { global $ADVANCED_NAME_FACTS; $gedrec='1 NAME '.safe_POST('NAME', WT_REGEX_UNSAFE, '//')."\n"; $tags=array('TYPE', 'NPFX', 'GIVN', 'SPFX', 'SURN', 'NSFX', '_MARNM'); if (preg_match_all('/('.WT_REGEX_TAG.')/', $ADVANCED_NAME_FACTS, $match)) { $tags=array_merge($tags, $match[1]); } foreach ($tags as $tag) { $TAG=safe_POST($tag, WT_REGEX_UNSAFE); if ($TAG) { $gedrec.="2 {$tag} {$TAG}\n"; } } return $gedrec; } function addNewSex() { switch (safe_POST('SEX', '[MF]', 'U')) { case 'M': return "1 SEX M\n"; case 'F': return "1 SEX F\n"; default: return "1 SEX U\n"; } } function addNewFact($fact) { global $tagSOUR, $ADVANCED_PLAC_FACTS; $FACT=safe_POST($fact, WT_REGEX_UNSAFE); $DATE=safe_POST("{$fact}_DATE", WT_REGEX_UNSAFE); $PLAC=safe_POST("{$fact}_PLAC", WT_REGEX_UNSAFE); if ($DATE || $PLAC || $FACT && $FACT!='Y') { if ($FACT && $FACT!='Y') { $gedrec="1 {$fact} {$FACT}\n"; } else { $gedrec="1 {$fact}\n"; } if ($DATE) { $gedrec.="2 DATE {$DATE}\n"; } if ($PLAC) { $gedrec.="2 PLAC {$PLAC}\n"; if (preg_match_all('/('.WT_REGEX_TAG.')/', $ADVANCED_PLAC_FACTS, $match)) { foreach ($match[1] as $tag) { $TAG=safe_POST("{$fact}_{$tag}", WT_REGEX_UNSAFE); if ($TAG) { $gedrec.="3 {$tag} {$TAG}\n"; } } } $LATI=safe_POST("{$fact}_LATI", WT_REGEX_UNSAFE); $LONG=safe_POST("{$fact}_LONG", WT_REGEX_UNSAFE); if ($LATI || $LONG) { $gedrec.="3 MAP\n4 LATI {$LATI}\n4 LONG {$LONG}\n"; } } if (safe_POST_bool("SOUR_{$fact}")) { return updateSOUR($gedrec, 2); } else { return $gedrec; } } elseif ($FACT=='Y') { if (safe_POST_bool("SOUR_{$fact}")) { return updateSOUR("1 {$fact} Y\n", 2); } else { return "1 {$fact} Y\n"; } } else { return ''; } } /** * This function splits the $glevels, $tag, $islink, and $text arrays so that the * entries associated with a SOUR record are separate from everything else. * * Input arrays: * - $glevels[] - an array of the gedcom level for each line that was edited * - $tag[] - an array of the tags for each gedcom line that was edited * - $islink[] - an array of 1 or 0 values to indicate when the text is a link element * - $text[] - an array of the text data for each line * * Output arrays: * ** For the SOUR record: * - $glevelsSOUR[] - an array of the gedcom level for each line that was edited * - $tagSOUR[] - an array of the tags for each gedcom line that was edited * - $islinkSOUR[] - an array of 1 or 0 values to indicate when the text is a link element * - $textSOUR[] - an array of the text data for each line * ** For the remaining records: * - $glevelsRest[] - an array of the gedcom level for each line that was edited * - $tagRest[] - an array of the tags for each gedcom line that was edited * - $islinkRest[] - an array of 1 or 0 values to indicate when the text is a link element * - $textRest[] - an array of the text data for each line * */ function splitSOUR() { global $glevels, $tag, $islink, $text; global $glevelsSOUR, $tagSOUR, $islinkSOUR, $textSOUR; global $glevelsRest, $tagRest, $islinkRest, $textRest; $glevelsSOUR = array(); $tagSOUR = array(); $islinkSOUR = array(); $textSOUR = array(); $glevelsRest = array(); $tagRest = array(); $islinkRest = array(); $textRest = array(); $inSOUR = false; for ($i=0; $i$glevel[0].' '.$tag[0].' '.$text[0] * There will be an index in each of these arrays for each line of the gedcom * fact that is being edited. * If the $text[] array is empty for the given line, then it means that the * user removed that line during editing or that the line is supposed to be * empty (1 DEAT, 1 BIRT) for example. To know if the line should be removed * there is a section of code that looks ahead to the next lines to see if there * are sub lines. For example we don't want to remove the 1 DEAT line if it has * a 2 PLAC or 2 DATE line following it. If there are no sub lines, then the line * can be safely removed. * @param string $newged the new gedcom record to add the lines to * @param int $levelOverride Override GEDCOM level specified in $glevels[0] * @return string The updated gedcom record */ function handle_updates($newged, $levelOverride="no") { global $glevels, $islink, $tag, $uploaded_files, $text, $NOTE, $WORD_WRAPPED_NOTES; if ($levelOverride=="no" || count($glevels)==0) $levelAdjust = 0; else $levelAdjust = $levelOverride - $glevels[0]; for ($j=0; $j$glevels[$j])) { $text[$k] = ''; $k++; } } if (trim($text[$j])!='') { $pass = true; } else { //-- for facts with empty values they must have sub records //-- this section checks if they have subrecords $k=$j+1; $pass=false; while (($k$glevels[$j])) { if ($text[$k]!='') { if (($tag[$j]!="OBJE")||($tag[$k]=="FILE")) { $pass=true; break; } } if (($tag[$k]=="FILE")&&(count($uploaded_files)>0)) { $filename = array_shift($uploaded_files); if (!empty($filename)) { $text[$k] = $filename; $pass=true; break; } } $k++; } } //-- if the value is not empty or it has sub lines //--- then write the line to the gedcom record //if ((($text[trim($j)]!='')||($pass==true)) && (strlen($text[$j]) > 0)) { //-- we have to let some emtpy text lines pass through... (DEAT, BIRT, etc) if ($pass==true) { $newline = $glevels[$j]+$levelAdjust.' '.$tag[$j]; //-- check and translate the incoming dates if ($tag[$j]=="DATE" && $text[$j]!='') { } // echo $newline; if ($text[$j]!='') { if ($islink[$j]) $newline .= " @".$text[$j]."@"; else $newline .= ' '.$text[$j]; } $newged .= breakConts($newline); } } return $newged; } /** * Link Media ID to Indi, Family, or Source ID * * Code was removed from inverselink.php to become a callable function * * @param string $mediaid Media ID to be linked * @param string $linktoid Indi, Family, or Source ID that the Media ID should link to * @param int $level Level where the Media Object reference should be created * @param boolean $chan Whether or not to update/add the CHAN record * @return bool success or failure */ function linkMedia($mediaid, $linktoid, $level=1, $chan=true) { if (empty($level)) $level = 1; if ($level!=1) return false; // Level 2 items get linked elsewhere // find Indi, Family, or Source record to link to $gedrec = find_gedcom_record($linktoid, WT_GED_ID, true); //-- check if we are re-editing an unaccepted link that is not already in the DB if (strpos($gedrec, "1 OBJE @$mediaid@")!==false) return false; if ($gedrec) { $newrec = $gedrec."\n1 OBJE @".$mediaid."@"; replace_gedrec($linktoid, WT_GED_ID, $newrec, $chan); return true; } else { echo "
", i18n::translate('No such ID exists in this GEDCOM file.'), "
"; return false; } } /** * unLink Media ID to Indi, Family, or Source ID * * @param string $mediaid Media ID to be unlinked. * @param string $linktoid Indi, Family, or Source ID that the Media ID should be unlinked from. * @param $linenum should be ALWAYS set to 'OBJE'. * @param int $level Level where the Media Object reference should be removed from (not used) * @param boolean $chan Whether or not to update/add the CHAN record * * @return bool success or failure */ function unlinkMedia($linktoid, $linenum, $mediaid, $level=1, $chan=true) { if (empty($level)) $level = 1; if ($level!=1) return false; // Level 2 items get unlinked elsewhere (maybe ??) // find Indi, Family, or Source record to unlink from $gedrec = find_gedcom_record($linktoid, WT_GED_ID, true); //-- when deleting/unlinking a media link //-- $linenum comes as an OBJE and the $mediaid to delete should be set if (!is_numeric($linenum)) { $newged = remove_subrecord($gedrec, $linenum, $mediaid); } else { $newged = remove_subline($gedrec, $linenum); } replace_gedrec($linktoid, WT_GED_ID, $newged, $chan); } /** * builds the form for adding new facts * @param string $fact the new fact we are adding */ function create_add_form($fact) { global $tags, $FULL_SOURCES; $tags = array(); // GEDFact_assistant ================================================ if ($fact=="CENS") { global $TEXT_DIRECTION, $CensDate; $CensDate="yes"; } // ================================================================== // handle MARRiage TYPE if (substr($fact, 0, 5)=="MARR_") { $tags[0] = "MARR"; add_simple_tag("1 MARR"); insert_missing_subtags($fact); } else { $tags[0] = $fact; if ($fact=='_UID') { $fact.=' '.uuid(); } // These new level 1 tags need to be turned into links if (in_array($fact, array('ASSO'))) { $fact.=' @'; } add_simple_tag("1 ".$fact); insert_missing_subtags($tags[0]); //-- handle the special SOURce case for level 1 sources [ 1759246 ] if ($fact=="SOUR") { add_simple_tag("2 PAGE"); add_simple_tag("3 TEXT"); if ($FULL_SOURCES) { add_simple_tag("3 DATE", '', translate_fact('DATA:DATE')); add_simple_tag("2 QUAY"); } } } } /** * creates the form for editing the fact within the given gedcom record at the * given line number * @param string $gedrec the level 0 gedcom record * @param int $linenum the line number of the fact to edit within $gedrec * @param string $level0type the type of the level 0 gedcom record */ function create_edit_form($gedrec, $linenum, $level0type) { global $WORD_WRAPPED_NOTES; global $pid, $tags, $ADVANCED_PLAC_FACTS, $date_and_time, $templefacts; global $FULL_SOURCES, $TEXT_DIRECTION; $tags=array(); $gedlines = explode("\n", $gedrec); // -- find the number of lines in the record if (!isset($gedlines[$linenum])) { echo "", i18n::translate('An error occurred while creating the Edit form. Another user may have changed this record since you previously viewed it.'), "

"; echo i18n::translate('Please reload the previous page to make sure you are working with the most recent record.'), "
"; return; } $fields = explode(' ', $gedlines[$linenum]); $glevel = $fields[0]; $level = $glevel; if ($level!=1 && preg_match("~/@.*/@~i", trim($fields[1]))) { echo "", i18n::translate('An error occurred while creating the Edit form. Another user may have changed this record since you previously viewed it.'), "

"; echo i18n::translate('Please reload the previous page to make sure you are working with the most recent record.'), "
"; return; } $type = trim($fields[1]); $level1type = $type; // GEDFact_assistant ================================================ if ($type=="CENS") { global $TEXT_DIRECTION, $CensDate; $CensDate="yes"; } // ================================================================== if (count($fields)>2) { $ct = preg_match("/@.*@/", $fields[2]); $levellink = $ct > 0; } else { $levellink = false; } $i = $linenum; $inSource = false; $levelSource = 0; $add_date = true; // List of tags we would expect at the next level // NB add_missing_subtags() already takes care of the simple cases // where a level 1 tag is missing a level 2 tag. Here we only need to // handle the more complicated cases. $expected_subtags=array( 'SOUR'=>array('PAGE', 'DATA'), 'DATA'=>array('TEXT'), 'PLAC'=>array('MAP'), 'MAP' =>array('LATI', 'LONG') ); if ($FULL_SOURCES) { $expected_subtags['SOUR'][]='QUAY'; $expected_subtags['DATA'][]='DATE'; } if (preg_match_all('/('.WT_REGEX_TAG.')/', $ADVANCED_PLAC_FACTS, $match)) { $expected_subtags['PLAC']=array_merge($match[1], $expected_subtags['PLAC']); } $stack=array(0=>$level0type); // Loop on existing tags : while (true) { // Keep track of our hierarchy, e.g. 1=>BIRT, 2=>PLAC, 3=>FONE $stack[(int)$level]=$type; // Merge them together, e.g. BIRT:PLAC:FONE $label=implode(':', array_slice($stack, 1, $level)); $text = ''; for ($j=2; $j2) $text .= ' '; $text .= $fields[$j]; } $text = rtrim($text); while (($i+10)) { $text.="\n".$cmatch[1]; $i++; } if ($type=="SOUR") { $inSource = true; $levelSource = $level; } elseif ($levelSource>=$level) { $inSource = false; } if ($type!="DATA" && $type!="CONT") { $tags[]=$type; $person = Person::getInstance($pid); $subrecord = $level.' '.$type.' '.$text; if ($inSource && $type=="DATE") { add_simple_tag($subrecord, '', translate_fact($label, $person)); } elseif (!$inSource && $type=="DATE") { add_simple_tag($subrecord, $level1type, translate_fact($label, $person)); $add_date = false; } else { add_simple_tag($subrecord, $level0type, translate_fact($label, $person)); } } // Get a list of tags present at the next level $subtags=array(); for ($ii=$i+1; isset($gedlines[$ii]) && preg_match('/^\s*(\d+)\s+(\S+)/', $gedlines[$ii], $mm) && $mm[1]>$level; ++$ii) if ($mm[1]==$level+1) $subtags[]=$mm[2]; // Insert missing tags if (!empty($expected_subtags[$type])) { foreach ($expected_subtags[$type] as $subtag) { if (!in_array($subtag, $subtags)) { if (!$inSource || $subtag!="DATA") { add_simple_tag(($level+1).' '.$subtag, '', translate_fact("{$label}:{$subtag}")); } if (!empty($expected_subtags[$subtag])) { foreach ($expected_subtags[$subtag] as $subsubtag) { add_simple_tag(($level+2).' '.$subsubtag, '', translate_fact("{$label}:{$subtag}:{$subsubtag}")); } } } } } // Awkward special cases if ($level==2 && $type=='DATE' && in_array($level1type, $date_and_time) && !in_array('TIME', $subtags)) { add_simple_tag("3 TIME"); // TIME is NOT a valid 5.5.1 tag } if ($level==2 && $type=='STAT' && in_array($level1type, $templefacts) && !in_array('DATE', $subtags)) { add_simple_tag("3 DATE", '', translate_fact('STAT:DATE')); } $i++; if (isset($gedlines[$i])) { $fields = explode(' ', $gedlines[$i]); $level = $fields[0]; if (isset($fields[1])) { $type = trim($fields[1]); } else { $level = 0; } } else { $level = 0; } if ($level<=$glevel) break; } insert_missing_subtags($level1type, $add_date); return $level1type; } /** * Populates the global $tags array with any missing sub-tags. * @param string $level1tag the type of the level 1 gedcom record */ function insert_missing_subtags($level1tag, $add_date=false) { global $tags, $date_and_time, $templefacts, $level2_tags, $ADVANCED_PLAC_FACTS, $ADVANCED_NAME_FACTS; global $nondatefacts, $nonplacfacts; // handle MARRiage TYPE $type_val = ''; if (substr($level1tag, 0, 5)=="MARR_") { $type_val = substr($level1tag, 5); $level1tag = "MARR"; } foreach ($level2_tags as $key=>$value) { if ($key=='DATE' && in_array($level1tag, $nondatefacts) || $key=='PLAC' && in_array($level1tag, $nonplacfacts)) { break; } if (in_array($level1tag, $value) && !in_array($key, $tags)) { if ($key=="TYPE") { add_simple_tag("2 TYPE ".$type_val); } elseif ($level1tag=='_TODO' && $key=='DATE') { add_simple_tag("2 ".$key.' '.strtoupper(date('d M Y'))); } elseif ($level1tag=='_TODO' && $key=='_WT_USER') { add_simple_tag("2 ".$key.' '.WT_USER_NAME); } else if ($level1tag=='TITL' && strstr($ADVANCED_NAME_FACTS, $key)!==false) { add_simple_tag("2 ".$key); } else if ($level1tag!='TITL') { add_simple_tag("2 ".$key); } switch ($key) { // Add level 3/4 tags as appropriate case "PLAC": if (preg_match_all('/('.WT_REGEX_TAG.')/', $ADVANCED_PLAC_FACTS, $match)) { foreach ($match[1] as $tag) { add_simple_tag("3 $tag", '', translate_fact("{$level1tag}:PLAC:{$tag}")); } } add_simple_tag("3 MAP"); add_simple_tag("4 LATI"); add_simple_tag("4 LONG"); break; case "FILE": add_simple_tag("3 FORM"); break; case "EVEN": add_simple_tag("3 DATE"); add_simple_tag("3 PLAC"); break; case "STAT": if (in_array($level1tag, $templefacts)) add_simple_tag("3 DATE", '', translate_fact('STAT:DATE')); break; case "DATE": if (in_array($level1tag, $date_and_time)) add_simple_tag("3 TIME"); // TIME is NOT a valid 5.5.1 tag break; case "HUSB": case "WIFE": add_simple_tag("3 AGE"); break; case "FAMC": if ($level1tag=='ADOP') add_simple_tag("3 ADOP BOTH"); break; } } elseif ($key=="DATE" && $add_date) { add_simple_tag("2 DATE", $level1tag, translate_fact("{$level1tag}:DATE")); } } // Do something (anything!) with unrecognised custom tags if (substr($level1tag, 0, 1)=='_' && $level1tag!='_UID' && $level1tag!='_TODO') foreach (array('DATE', 'PLAC', 'ADDR', 'AGNC', 'TYPE', 'AGE') as $tag) if (!in_array($tag, $tags)) { add_simple_tag("2 {$tag}"); if ($tag=='PLAC') { if (preg_match_all('/('.WT_REGEX_TAG.')/', $ADVANCED_PLAC_FACTS, $match)) { foreach ($match[1] as $tag) { add_simple_tag("3 $tag", '', translate_fact("{$level1tag}:PLAC:{$tag}")); } } add_simple_tag("3 MAP"); add_simple_tag("4 LATI"); add_simple_tag("4 LONG"); } } } /** * Delete a person and update all records that link to that person * @param string $pid the id of the person to delete * @param string $gedrec the gedcom record of the person to delete * @return boolean true or false based on the successful completion of the deletion */ function delete_person($pid, $gedrec='') { if (WT_DEBUG) { phpinfo(INFO_VARIABLES); echo "
$gedrec
"; } if (empty($gedrec)) $gedrec = find_person_record($pid, WT_GED_ID); if (!empty($gedrec)) { $success = true; $ct = preg_match_all("/1 FAM. @(.*)@/", $gedrec, $match, PREG_SET_ORDER); for ($i=0; $i<$ct; $i++) { $famid = $match[$i][1]; $famrec = find_gedcom_record($famid, WT_GED_ID, true); if (!empty($famrec)) { $lines = explode("\n", $famrec); $newfamrec = ''; $lastlevel = -1; foreach ($lines as $indexval => $line) { $ct = preg_match("/^(\d+)/", $line, $levelmatch); if ($ct>0) $level = $levelmatch[1]; else $level = 1; //-- make sure we don't add any sublevel records if ($level<=$lastlevel) $lastlevel = -1; if ((strpos($line, "@$pid@")===false) && ($lastlevel==-1)) $newfamrec .= $line."\n"; else { $lastlevel=$level; } } //-- if there is not at least two people in a family then the family is deleted $pt = preg_match_all("/1 (?:HUSB|WIFE|CHIL) @(.*)@/", $newfamrec, $pmatch, PREG_SET_ORDER); if ($pt<2) { for ($j=0; $j<$pt; $j++) { $xref = $pmatch[$j][1]; if ($xref!=$pid) { $indirec = find_gedcom_record($xref, WT_GED_ID, true); $indirec = preg_replace("/1.*@$famid@.*/", '', $indirec); if (WT_DEBUG) { echo "
$indirec
"; } replace_gedrec($xref, WT_GED_ID, $indirec); } } delete_gedrec($famid, WT_GED_ID); } else replace_gedrec($famid, WT_GED_ID, $newfamrec); } } delete_gedrec($pid, WT_GED_ID); return true; } return false; } /** * Delete a person and update all records that link to that person * @param string $pid the id of the person to delete * @param string $gedrec the gedcom record of the person to delete * @return boolean true or false based on the successful completion of the deletion */ function delete_family($pid, $gedrec='') { if (empty($gedrec)) $gedrec = find_family_record($pid, WT_GED_ID); if (!empty($gedrec)) { $success = true; $ct = preg_match_all("/1 (\w+) @(.*)@/", $gedrec, $match, PREG_SET_ORDER); for ($i=0; $i<$ct; $i++) { $type = $match[$i][1]; $id = $match[$i][2]; if (WT_DEBUG) { echo $type, ' ', $id, ' '; } $indirec = find_gedcom_record($id, WT_GED_ID, true); if (!empty($indirec)) { $lines = explode("\n", $indirec); $newindirec = ''; $lastlevel = -1; foreach ($lines as $indexval => $line) { $lct = preg_match("/^(\d+)/", $line, $levelmatch); if ($lct>0) $level = $levelmatch[1]; else $level = 1; //-- make sure we don't add any sublevel records if ($level<=$lastlevel) $lastlevel = -1; if ((strpos($line, "@$pid@")===false) && ($lastlevel==-1)) $newindirec .= $line."\n"; else { $lastlevel=$level; } } replace_gedrec($id, WT_GED_ID, $newindirec); } } if ($success) { delete_gedrec($pid, WT_GED_ID); } return true; } return false; }