' . htmlspecialchars($value) . ''; $js='jQuery("#' . $name . '").editable("' . WT_SERVER_NAME . WT_SCRIPT_PATH . 'save.php", {submit:"  ' . /* I18N: button label */ WT_I18N::translate('save') . '  ", style:"inherit", placeholder: "'.WT_I18N::translate('click to edit').'"});'; if ($controller) { $controller->addInlineJavascript($js); return $html; } else { // For AJAX callbacks return $html . ''; } } // Create a text area for inline editing using jeditable function edit_text_inline($name, $value, $controller=null) { $html='' . htmlspecialchars($value) . ''; $js='jQuery("#' . $name . '").editable("' . WT_SERVER_NAME . WT_SCRIPT_PATH . 'save.php", {submit:"  ' . WT_I18N::translate('save') . '  ", style:"inherit", placeholder: "'.WT_I18N::translate('click to edit').'", type: "textarea", rows:4, cols:60 });'; if ($controller) { $controller->addInlineJavascript($js); return $html; } else { // For AJAX callbacks return $html . ''; } } // Create a '.$html.''; } // An inline-editing version of select_edit_control() function select_edit_control_inline($name, $values, $empty, $selected, $controller=null) { if (!is_null($empty)) { // Push ''=>$empty onto the front of the array, maintaining keys $tmp=array(''=>htmlspecialchars($empty)); foreach ($values as $key=>$value) { $tmp[$key]=htmlspecialchars($value); } $values=$tmp; } $values['selected']=htmlspecialchars($selected); $html='' . (array_key_exists($selected, $values) ? $values[$selected] : '') . ''; $js='jQuery("#' . $name . '").editable("' . WT_SERVER_NAME . WT_SCRIPT_PATH . 'save.php", {type:"select", data:' . json_encode($values) . ', submit:"  ' . WT_I18N::translate('save') . '  ", style:"inherit", placeholder: "'.WT_I18N::translate('click to edit').'", callback:function(value, settings) {jQuery(this).html(settings.data[value]);} });'; if ($controller) { $controller->addInlineJavascript($js); return $html; } else { // For AJAX callbacks return $html . ''; } } // 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.(int)(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=>WT_I18N::translate('no'),true=>WT_I18N::translate('yes')), $selected, $extra ); } // An inline-editing version of edit_field_yes_no() function edit_field_yes_no_inline($name, $selected=false, $controller=null) { return select_edit_control_inline( $name, array(true=>WT_I18N::translate('yes'), false=>WT_I18N::translate('no')), null, (int)$selected, $controller ); } // 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 (WT_I18N::installed_languages() as $code=>$name) { $content = ' '.$name.''; // print in two columns switch ($i % 3) { case 0: echo ''; break; case 1: echo ''; break; case 2: echo ''; break; } $i++; } switch ($i % 3) { case 0: echo ''; break; case 1: echo ''; break; case 2: echo ''; break; } echo '
', $content, '', $content, '', $content, '
'; } // Print an edit control for access level function edit_field_access_level($name, $selected='', $extra='') { $ACCESS_LEVEL=array( WT_PRIV_PUBLIC=>WT_I18N::translate('Show to visitors'), WT_PRIV_USER =>WT_I18N::translate('Show to members'), WT_PRIV_NONE =>WT_I18N::translate('Show to managers'), WT_PRIV_HIDE =>WT_I18N::translate('Hide from everyone') ); return select_edit_control($name, $ACCESS_LEVEL, null, $selected, $extra); } // Print an edit control for a RESN field function edit_field_resn($name, $selected='', $extra='') { $RESN=array( '' =>'', 'none' =>WT_I18N::translate('Show to visitors'), // Not valid GEDCOM, but very useful 'privacy' =>WT_I18N::translate('Show to members'), 'confidential'=>WT_I18N::translate('Show to managers'), 'locked' =>WT_I18N::translate('Only managers can edit') ); return select_edit_control($name, $RESN, 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' =>WT_I18N::translate('webtrees internal messaging'), 'messaging2'=>WT_I18N::translate('Internal messaging with emails'), 'messaging3'=>WT_I18N::translate('webtrees sends emails with no storage'), 'mailto' =>WT_I18N::translate('Mailto link'), 'none' =>WT_I18N::translate('No contact'), ); return select_edit_control($name, $CONTACT_METHODS, null, $selected, $extra); } function edit_field_contact_inline($name, $selected='', $controller=null) { // Different ways to contact the users $CONTACT_METHODS=array( 'messaging' =>WT_I18N::translate('webtrees internal messaging'), 'messaging2'=>WT_I18N::translate('Internal messaging with emails'), 'messaging3'=>WT_I18N::translate('webtrees sends emails with no storage'), 'mailto' =>WT_I18N::translate('Mailto link'), 'none' =>WT_I18N::translate('No contact'), ); return select_edit_control_inline($name, $CONTACT_METHODS, null, $selected, $controller); } // Print an edit control for a language field function edit_field_language($name, $selected='', $extra='') { return select_edit_control($name, WT_I18N::installed_languages(), null, $selected, $extra); } // An inline-editing version of edit_field_language() function edit_field_language_inline($name, $selected=false, $controller=null) { return select_edit_control_inline( $name, WT_I18N::installed_languages(), null, $selected, $controller ); } // Print an edit control for a range of integers function edit_field_integers($name, $selected='', $min, $max, $extra='') { $array=array(); for ($i=$min; $i<=$max; ++$i) { $array[$i]=WT_I18N::number($i); } return select_edit_control($name, $array, 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($name, $selected='', $extra='', WT_Individual $individual=null) { return select_edit_control($name, WT_Gedcom_Code_Adop::getValues($individual), null, $selected, $extra); } // Print an edit control for a PEDI field function edit_field_pedi($name, $selected='', $extra='', WT_Individual $individual=null) { return select_edit_control($name, WT_Gedcom_Code_Pedi::getValues($individual), '', $selected, $extra); } // Print an edit control for a NAME TYPE field function edit_field_name_type($name, $selected='', $extra='', WT_Individual $individual=null) { return select_edit_control($name, WT_Gedcom_Code_Name::getValues($individual), '', $selected, $extra); } // Print an edit control for a RELA field function edit_field_rela($name, $selected='', $extra='') { $rela_codes=WT_Gedcom_Code_Rela::getValues(); // 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); } // Remove all links from $gedrec to $xref, and any sub-tags. function remove_links($gedrec, $xref) { $gedrec = preg_replace('/\n1 '.WT_REGEX_TAG.' @'.$xref.'@(\n[2-9].*)*/', '', $gedrec); $gedrec = preg_replace('/\n2 '.WT_REGEX_TAG.' @'.$xref.'@(\n[3-9].*)*/', '', $gedrec); $gedrec = preg_replace('/\n3 '.WT_REGEX_TAG.' @'.$xref.'@(\n[4-9].*)*/', '', $gedrec); $gedrec = preg_replace('/\n4 '.WT_REGEX_TAG.' @'.$xref.'@(\n[5-9].*)*/', '', $gedrec); $gedrec = preg_replace('/\n5 '.WT_REGEX_TAG.' @'.$xref.'@(\n[6-9].*)*/', '', $gedrec); return $gedrec; } // generates javascript code for calendar popup in user's language function print_calendar_popup($id) { return ' '. ''; } function print_addnewmedia_link($element_id) { return ''; } function print_addnewrepository_link($element_id) { return ''; } function print_addnewnote_link($element_id) { return ''; } /// Used in GEDFact CENS assistant function print_addnewnote_assisted_link($element_id, $xref) { return ''.WT_I18N::translate('Create a new Shared Note using Assistant').''; } function print_editnote_link($note_id) { return ''; } function print_addnewsource_link($element_id) { return ''; } /** * 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 $MEDIA_DIRECTORY, $tags, $emptyfacts, $main_fact, $TEXT_DIRECTION; global $NPFX_accept, $SPFX_accept, $NSFX_accept, $FILE_FORM_accept, $upload_count; global $xref, $linkToID, $bdm, $action, $event_add, $CensDate; global $QUICK_REQUIRED_FACTS, $QUICK_REQUIRED_FAMFACTS, $PREFER_LEVEL2_SOURCES; 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 ($label) { echo $label; } elseif ($upperlevel) { echo WT_Gedcom_Tag::getLabel($upperlevel.':'.$fact); } else { echo WT_Gedcom_Tag::getLabel($fact); } // help link // If using GEDFact-assistant window if ($action=="addnewnote_assisted") { // Do not print on GEDFact Assistant window } else { // Not all facts have help text. switch ($fact) { case 'FORM': if ($upperlevel!='OBJE') { echo help_link($fact); } break; case 'NOTE': if ($islink) { echo help_link('edit_add_SHARED_NOTE'); } else { echo help_link($fact); } break; case 'NAME': if ($upperlevel!='REPO') { echo help_link($fact); } break; case 'ASSO': case '_ASSO': // Some apps (including webtrees) use "2 _ASSO", since "2 ASSO" is not strictly valid GEDCOM if ($level==1) { echo help_link('ASSO_1'); } else { echo help_link('ASSO_2'); } break; case 'ADDR': case 'AGNC': case 'CAUS': case 'DATE': case 'EMAI': case 'EMAIL': case 'EMAL': case '_EMAIL': case 'FAX': case 'OBJE': case 'PAGE': case 'PEDI': case 'PHON': case 'PLAC': case 'RELA': case 'RESN': case 'ROMN': case 'SEX': case 'SOUR': case 'STAT': case 'SURN': case 'TEMP': case 'TEXT': case 'TIME': case 'URL': case '_HEB': case '_PRIM': echo help_link($fact); break; } } // 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 ""; } echo ""; // value echo ""; if (WT_DEBUG) { echo $tag, "
"; } // retrieve linked NOTE if ($fact=="NOTE" && $islink) { $note1=WT_Note::getInstance($value); if ($note1) { $noterec=$note1->getGedcom(); preg_match("/$value/i", $noterec, $notematch); $value=$notematch[0]; } } if (in_array($fact, $emptyfacts) && ($value=='' || $value=='Y' || $value=='y')) { echo ""; if ($level<=1) { echo '"; echo WT_I18N::translate('yes'); } } else if ($fact=="TEMP") { echo select_edit_control($element_name, WT_Gedcom_Code_Temp::templeNames(), WT_I18N::translate('No Temple - Living Ordinance'), $value); } else if ($fact=="ADOP") { echo edit_field_adop($element_name, $value, '', WT_Individual::getInstance($xref)); } else if ($fact=="PEDI") { echo edit_field_pedi($element_name, $value, '', WT_Individual::getInstance($xref)); } else if ($fact=='STAT') { echo select_edit_control($element_name, WT_Gedcom_Code_Stat::statusNames($upperlevel), '', $value); } else if ($fact=='RELA') { echo edit_field_rela($element_name, strtolower($value)); } else if ($fact=='QUAY') { echo select_edit_control($element_name, WT_Gedcom_Code_Quay::getValues(), '', $value); } else if ($fact=='_WT_USER') { echo edit_field_username($element_name, $value); } else if ($fact=='RESN') { echo edit_field_resn($element_name, $value); } else if ($fact=='_PRIM') { 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 '', htmlspecialchars($value), ''; echo ' '; } else { // textarea if ($fact=='TEXT' || $fact=='ADDR' || ($fact=='NOTE' && !$islink)) { echo "
"; } else { // text // If using GEDFact-assistant window if ($action=="addnewnote_assisted") { echo ""; } $tmp_array = array('TYPE','TIME','NOTE','SOUR','REPO','OBJE','ASSO','_ASSO','AGE'); // split PLAC if ($fact=="PLAC" && $readOnly=='') { echo "
"; echo print_specialchar_link($element_id), ' ', print_findplace_link($element_id); echo ''; echo '
'; if (array_key_exists('places_assistant', WT_Module::getActiveModules())) { places_assistant_WT_Module::setup_place_subfields($element_id); places_assistant_WT_Module::print_place_subfields($element_id); } } elseif (!in_array($fact, $tmp_array) && $readOnly=='') { echo print_specialchar_link($element_id); } } // MARRiage TYPE : hide text field and show a selection list if ($fact=='TYPE' && $level==2 && $tags[0]=='MARR') { echo ''; echo ""; } // NAME TYPE : hide text field and show a selection list else if ($fact=='TYPE' && $level==0) { $extra = 'onchange="document.getElementById(\''.$element_id.'\').value=this.value;"'; echo edit_field_name_type($element_name, $value, $extra, WT_Individual::getInstance($xref)); echo ''; } // popup links if (!$readOnly) { switch ($fact) { case 'DATE': echo print_calendar_popup($element_id); // If GEDFact_assistant/_CENS/ module is installed ------------------------------------------------- if ($action=='add' && array_key_exists('GEDFact_assistant', WT_Module::getActiveModules())) { if (isset($CensDate) && $CensDate=='yes') { require_once WT_ROOT.WT_MODULES_DIR . 'GEDFact_assistant/_CENS/census_asst_date.php'; } } // ------------------------------------------------------------------------------------------------- break; case 'FAMC': case 'FAMS': echo print_findfamily_link($element_id); break; case 'ASSO': case '_ASSO': echo print_findindi_link($element_id); break; case 'FILE': print_findmedia_link($element_id, "0file"); break; case 'SOUR': echo print_findsource_link($element_id), ' ', print_addnewsource_link($element_id); //-- 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 WT_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 WT_Gedcom_Tag::getLabel($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 WT_Gedcom_Tag::getLabel($match); } } } } if (strpos($bdm, 'M')!==false) { echo ' '; echo WT_I18N::translate('Family'); if (preg_match_all('/('.WT_REGEX_TAG.')/', $QUICK_REQUIRED_FAMFACTS, $matches)) { foreach ($matches[1] as $match) { echo ' '; echo WT_Gedcom_Tag::getLabel($match); } } } } break; case 'REPO': echo print_findrepository_link($element_id), ' ', print_addnewrepository_link($element_id); break; case 'NOTE': // Shared Notes Icons ======================================== if ($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 (($action=='add' || $action=='edit') && $xref && array_key_exists('GEDFact_assistant', WT_Module::getActiveModules())) { // Check if a CENS event --------------------------- if ($event_add=='census_add') { $type_pid=WT_GedcomRecord::getInstance($xref); if ($type_pid instanceof WT_Individual) { echo '
', print_addnewnote_assisted_link($element_id, $xref); } } } } break; case 'OBJE': echo print_findmedia_link($element_id, '1media'); if (!$value) { echo ' ', print_addnewmedia_link($element_id); $value = 'new'; } break; } echo '
'; } // current value if ($fact=='DATE') { $date=new WT_Date($value); echo $date->Display(false); } if ($value && $value!='new' && $islink) { switch ($fact) { case 'ASSO': case 'ASSO': $tmp = WT_Individual::getInstance($value); if ($tmp) { echo ' ', $tmp->getFullname(); } break; case 'SOUR': $tmp = WT_Source::getInstance($value); if ($tmp) { echo ' ', $tmp->getFullname(); } break; case 'NOTE': $tmp = WT_Note::getInstance($value); if ($tmp) { echo ' ', $tmp->getFullname(); } break; case 'OBJE': $tmp = WT_Media::getInstance($value); if ($tmp) { echo ' ', $tmp->getFullname(); } break; case 'REPO': $tmp = WT_Repository::getInstance($value); if ($tmp) { echo ' ', $tmp->getFullname(); } break; } } // pastable values if ($readOnly=='') { if ($fact=='FORM' && $upperlevel=='OBJE') print_autopaste_link($element_id, $FILE_FORM_accept); } if ($noClose != 'NOCLOSE') echo ''; return $element_id; } // prints collapsable fields to add ASSO/RELA, SOUR, OBJE ... function print_add_layer($tag, $level=2) { global $FULL_SOURCES; if ($tag=='OBJE' && get_gedcom_setting(WT_GED_ID, 'MEDIA_UPLOAD') < WT_USER_ACCESS_LEVEL) { return; } if ($tag=="SOUR") { //-- Add new source to fact echo " ", WT_I18N::translate('Add a new source citation'), ""; echo help_link('edit_add_SOUR'); echo "
"; 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", '', WT_Gedcom_Tag::getLabel('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 " ", WT_I18N::translate('Add a new associate'), ""; echo help_link('edit_add_ASSO'); echo "
"; echo "
"; } else { echo " ", WT_I18N::translate('Add a new associate'), ""; echo help_link('edit_add_ASSO'); echo "
"; 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 " ", WT_I18N::translate('Add a new note'), ""; echo help_link('edit_add_NOTE'); echo "
"; 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 " ", WT_I18N::translate('Add a new shared note'), ""; echo help_link('edit_add_SHARED_NOTE'); echo "
"; echo "
"; echo ""; // 2 SHARED NOTE add_simple_tag(($level)." SHARED_NOTE "); echo "
"; } if ($tag=="OBJE") { //-- Add new obje to fact echo " ", WT_I18N::translate('Add a new media object'), ""; echo help_link('OBJE'); echo "
"; echo "
"; echo ""; add_simple_tag($level." OBJE"); echo "
"; } if ($tag=="RESN") { //-- Retrieve existing resn or add new resn to fact $text = ''; echo " ", WT_I18N::translate('Add a new restriction'), ""; echo help_link('RESN'); echo "
"; 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; // For new individuals, these facts default to "Y" if ($fact=='MARR' /*|| $fact=='BIRT'*/) { add_simple_tag("0 {$fact} Y"); } else { add_simple_tag("0 {$fact}"); } add_simple_tag("0 DATE", $fact, WT_Gedcom_Tag::getLabel("{$fact}:DATE")); add_simple_tag("0 PLAC", $fact, WT_Gedcom_Tag::getLabel("{$fact}:PLAC")); if (preg_match_all('/('.WT_REGEX_TAG.')/', $ADVANCED_PLAC_FACTS, $match)) { foreach ($match[1] as $tag) { add_simple_tag("0 {$tag}", $fact, WT_Gedcom_Tag::getLabel("{$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="\n1 NAME ".safe_POST('NAME', WT_REGEX_UNSAFE, '//'); $tags=array('NPFX', 'GIVN', 'SPFX', 'SURN', 'NSFX'); if (preg_match_all('/('.WT_REGEX_TAG.')/', $ADVANCED_NAME_FACTS, $match)) { $tags=array_merge($tags, $match[1]); } // Paternal and Polish and Lithuanian surname traditions can also create a _MARNM $SURNAME_TRADITION=get_gedcom_setting(WT_GED_ID, 'SURNAME_TRADITION'); if ($SURNAME_TRADITION=='paternal' || $SURNAME_TRADITION=='polish' || $SURNAME_TRADITION=='lithuanian') { $tags[]='_MARNM'; } foreach (array_unique($tags) as $tag) { $TAG=safe_POST($tag, WT_REGEX_UNSAFE); if ($TAG) { $gedrec.="\n2 {$tag} {$TAG}"; } } return $gedrec; } function addNewSex() { switch (safe_POST('SEX', '[MF]', 'U')) { case 'M': return "\n1 SEX M"; case 'F': return "\n1 SEX F"; default: return "\n1 SEX U"; } } 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="\n1 {$fact} {$FACT}"; } else { $gedrec="\n1 {$fact}"; } if ($DATE) { $gedrec.="\n2 DATE {$DATE}"; } if ($PLAC) { $gedrec.="\n2 PLAC {$PLAC}"; 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.="\n3 {$tag} {$TAG}"; } } } $LATI=safe_POST("{$fact}_LATI", WT_REGEX_UNSAFE); $LONG=safe_POST("{$fact}_LONG", WT_REGEX_UNSAFE); if ($LATI || $LONG) { $gedrec.="\n3 MAP\n4 LATI {$LATI}\n4 LONG {$LONG}"; } } if (safe_POST_bool("SOUR_{$fact}")) { return updateSOUR($gedrec, 2); } else { return $gedrec; } } elseif ($FACT=='Y') { if (safe_POST_bool("SOUR_{$fact}")) { return updateSOUR("\n1 {$fact} Y", 2); } else { return "\n1 {$fact} Y"; } } 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 .= "\n".str_replace("\n", "\n" . (1 + substr($newline, 0, 1)) . ' CONT ', $newline); } } return $newged; } /** * 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, $emptyfacts; $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.=' @'; } if (in_array($fact, $emptyfacts)) { add_simple_tag('1 '.$fact.' Y'); } else { 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", '', WT_Gedcom_Tag::getLabel('DATA:DATE')); add_simple_tag("2 QUAY"); } } } } // Create a form to edit a WT_Fact object function create_edit_form(WT_GedcomRecord $record, WT_Fact $fact) { global $WORD_WRAPPED_NOTES, $ADVANCED_PLAC_FACTS, $date_and_time, $FULL_SOURCES; global $tags; $pid = $record->getXref(); $tags=array(); $gedlines = explode("\n", $fact->getGedcom()); $linenum = 0; $fields = explode(' ', $gedlines[$linenum]); $glevel = $fields[0]; $level = $glevel; $type = $fact->getTag(); $parent = $fact->getParent(); $level0type = $parent::RECORD_TYPE; $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 = WT_Individual::getInstance($pid); $subrecord = $level.' '.$type.' '.$text; if ($inSource && $type=="DATE") { add_simple_tag($subrecord, '', WT_Gedcom_Tag::getLabel($label, $person)); } elseif (!$inSource && $type=="DATE") { add_simple_tag($subrecord, $level1type, WT_Gedcom_Tag::getLabel($label, $person)); $add_date = false; } elseif ($type=='STAT') { add_simple_tag($subrecord, $level1type, WT_Gedcom_Tag::getLabel($label, $person)); } elseif ($level0type=='REPO') { $repo = WT_Repository::getInstance($pid); add_simple_tag($subrecord, $level0type, WT_Gedcom_Tag::getLabel($label, $repo)); } else { add_simple_tag($subrecord, $level0type, WT_Gedcom_Tag::getLabel($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, '', WT_Gedcom_Tag::getLabel("{$label}:{$subtag}")); } if (!empty($expected_subtags[$subtag])) { foreach ($expected_subtags[$subtag] as $subsubtag) { add_simple_tag(($level+2).' '.$subsubtag, '', WT_Gedcom_Tag::getLabel("{$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' && WT_Gedcom_Code_Temp::isTagLDS($level1type) && !in_array('DATE', $subtags)) { add_simple_tag("3 DATE", '', WT_Gedcom_Tag::getLabel('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; } if ($level1type!='_PRIM') { 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, $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)) { continue; } if (in_array($level1tag, $value) && !in_array($key, $tags)) { if ($key=='TYPE') { add_simple_tag('2 TYPE '.$type_val, $level1tag); } elseif ($level1tag=='_TODO' && $key=='DATE') { add_simple_tag('2 '.$key.' '.strtoupper(date('d M Y')), $level1tag); } elseif ($level1tag=='_TODO' && $key=='_WT_USER') { add_simple_tag('2 '.$key.' '.WT_USER_NAME, $level1tag); } else if ($level1tag=='TITL' && strstr($ADVANCED_NAME_FACTS, $key)!==false) { add_simple_tag('2 '.$key, $level1tag); } else if ($level1tag=='NAME' && strstr($ADVANCED_NAME_FACTS, $key)!==false) { add_simple_tag('2 '.$key, $level1tag); } else if ($level1tag!='TITL' && $level1tag!='NAME') { add_simple_tag('2 '.$key, $level1tag); } 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", '', WT_Gedcom_Tag::getLabel("{$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 (WT_Gedcom_Code_Temp::isTagLDS($level1tag)) { add_simple_tag('3 DATE', '', WT_Gedcom_Tag::getLabel('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, WT_Gedcom_Tag::getLabel("{$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", '', WT_Gedcom_Tag::getLabel("{$level1tag}:PLAC:{$tag}")); } } add_simple_tag('3 MAP'); add_simple_tag('4 LATI'); add_simple_tag('4 LONG'); } } }