Пример #1
0
/**
 * Print a form to add an individual or edit an individual’s name
 *
 * @param string     $nextaction
 * @param Individual $person
 * @param Family     $family
 * @param Fact       $name_fact
 * @param string     $famtag
 * @param string     $gender
 */
function print_indi_form($nextaction, Individual $person = null, Family $family = null, Fact $name_fact = null, $famtag = 'CHIL', $gender = 'U')
{
    global $WT_TREE, $bdm, $controller;
    if ($person) {
        $xref = $person->getXref();
    } elseif ($family) {
        $xref = $family->getXref();
    } else {
        $xref = 'new';
    }
    // Different cultures do surnames differently
    $surname_tradition = SurnameTradition::create($WT_TREE->getPreference('SURNAME_TRADITION'));
    $name_fields = array();
    if ($name_fact) {
        // Editing an existing name
        $name_fact_id = $name_fact->getFactId();
        $name_type = $name_fact->getAttribute('TYPE');
        $namerec = $name_fact->getGedcom();
        foreach (Config::standardNameFacts() as $tag) {
            if ($tag === 'NAME') {
                $name_fields[$tag] = $name_fact->getValue();
            } else {
                $name_fields[$tag] = $name_fact->getAttribute($tag);
            }
        }
        // Populate any missing 2 XXXX fields from the 1 NAME field
        $npfx_accept = implode('|', Config::namePrefixes());
        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]);
                // For names with two surnames, there will be four slashes.
                // Turn them into a list
                $name_fields['SURN'] = preg_replace('~/[^/]*/~', ',', $name_bits[9]);
            }
            if (empty($name_fields['GIVN'])) {
                $name_fields['GIVN'] = $name_bits[4];
            }
            if (empty($name_fields['NICK']) && !empty($name_bits[6]) && !preg_match('/^2 NICK/m', $namerec)) {
                $name_fields['NICK'] = $name_bits[6];
            }
        }
    } else {
        // Creating a new name
        $name_fact_id = null;
        $name_type = null;
        $namerec = null;
        // Populate the standard NAME field and subfields
        foreach (Config::standardNameFacts() as $tag) {
            $name_fields[$tag] = '';
        }
        // Inherit surname from parents, spouse or child
        if ($family) {
            $father = $family->getHusband();
            if ($father && $father->getFirstFact('NAME')) {
                $father_name = $father->getFirstFact('NAME')->getValue();
            } else {
                $father_name = '';
            }
            $mother = $family->getWife();
            if ($mother && $mother->getFirstFact('NAME')) {
                $mother_name = $mother->getFirstFact('NAME')->getValue();
            } else {
                $mother_name = '';
            }
        } else {
            $father = null;
            $mother = null;
            $father_name = '';
            $mother_name = '';
        }
        if ($person && $person->getFirstFact('NAME')) {
            $indi_name = $person->getFirstFact('NAME')->getValue();
        } else {
            $indi_name = '';
        }
        switch ($nextaction) {
            case 'add_child_to_family_action':
                $name_fields = $surname_tradition->newChildNames($father_name, $mother_name, $gender) + $name_fields;
                break;
            case 'add_child_to_individual_action':
                if ($person->getSex() === 'F') {
                    $name_fields = $surname_tradition->newChildNames('', $indi_name, $gender) + $name_fields;
                } else {
                    $name_fields = $surname_tradition->newChildNames($indi_name, '', $gender) + $name_fields;
                }
                break;
            case 'add_parent_to_individual_action':
                $name_fields = $surname_tradition->newParentNames($indi_name, $gender) + $name_fields;
                break;
            case 'add_spouse_to_family_action':
                if ($father) {
                    $name_fields = $surname_tradition->newSpouseNames($father_name, $gender) + $name_fields;
                } else {
                    $name_fields = $surname_tradition->newSpouseNames($mother_name, $gender) + $name_fields;
                }
                break;
            case 'add_spouse_to_individual_action':
                $name_fields = $surname_tradition->newSpouseNames($indi_name, $gender) + $name_fields;
                break;
            case 'add_unlinked_indi_action':
            case 'update':
                if ($surname_tradition->hasSurnames()) {
                    $name_fields['NAME'] = '//';
                }
                break;
        }
    }
    $bdm = '';
    // used to copy '1 SOUR' to '2 SOUR' for BIRT DEAT MARR
    echo '<div id="edit_interface-page">';
    echo '<h4>', $controller->getPageTitle(), '</h4>';
    FunctionsPrint::initializeCalendarPopup();
    echo '<form method="post" name="addchildform" onsubmit="return checkform();">';
    echo '<input type="hidden" name="ged" value="', $WT_TREE->getNameHtml(), '">';
    echo '<input type="hidden" name="action" value="', $nextaction, '">';
    echo '<input type="hidden" name="fact_id" value="', $name_fact_id, '">';
    echo '<input type="hidden" name="xref" value="', $xref, '">';
    echo '<input type="hidden" name="famtag" value="', $famtag, '">';
    echo '<input type="hidden" name="gender" value="', $gender, '">';
    echo '<input type="hidden" name="goto" value="">';
    // set by javascript
    echo Filter::getCsrf();
    echo '<table class="facts_table">';
    switch ($nextaction) {
        case 'add_child_to_family_action':
        case 'add_child_to_individual_action':
            // When adding a new child, specify the pedigree
            FunctionsEdit::addSimpleTag('0 PEDI');
            break;
        case 'update':
            // When adding/editing a name, specify the type
            FunctionsEdit::addSimpleTag('0 TYPE ' . $name_type, '', '', null, $person);
            break;
    }
    // First - new/existing standard name fields
    foreach ($name_fields as $tag => $value) {
        if (substr_compare($tag, '_', 0, 1) !== 0) {
            FunctionsEdit::addSimpleTag('0 ' . $tag . ' ' . $value);
        }
    }
    // Second - new/existing advanced name fields
    if ($surname_tradition->hasMarriedNames() || preg_match('/\\n2 _MARNM /', $namerec)) {
        $adv_name_fields = array('_MARNM' => '');
    } else {
        $adv_name_fields = array();
    }
    if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('ADVANCED_NAME_FACTS'), $match)) {
        foreach ($match[1] as $tag) {
            $adv_name_fields[$tag] = '';
        }
    }
    foreach (array_keys($adv_name_fields) as $tag) {
        // Edit existing tags, grouped together
        if (preg_match_all('/2 ' . $tag . ' (.+)/', $namerec, $match)) {
            foreach ($match[1] as $value) {
                FunctionsEdit::addSimpleTag('2 ' . $tag . ' ' . $value, '', GedcomTag::getLabel('NAME:' . $tag, $person));
                if ($tag === '_MARNM') {
                    preg_match_all('/\\/([^\\/]*)\\//', $value, $matches);
                    FunctionsEdit::addSimpleTag('2 _MARNM_SURN ' . implode(',', $matches[1]));
                }
            }
        }
        // Allow a new tag to be entered
        if (!array_key_exists($tag, $name_fields)) {
            FunctionsEdit::addSimpleTag('0 ' . $tag, '', GedcomTag::getLabel('NAME:' . $tag, $person));
            if ($tag === '_MARNM') {
                FunctionsEdit::addSimpleTag('0 _MARNM_SURN');
            }
        }
    }
    // Third - new/existing custom name fields
    foreach ($name_fields as $tag => $value) {
        if (substr_compare($tag, '_', 0, 1) === 0) {
            FunctionsEdit::addSimpleTag('0 ' . $tag . ' ' . $value);
            if ($tag === '_MARNM') {
                preg_match_all('/\\/([^\\/]*)\\//', $value, $matches);
                FunctionsEdit::addSimpleTag('2 _MARNM_SURN ' . implode(',', $matches[1]));
            }
        }
    }
    // Fourth - SOUR, NOTE, _CUSTOM, etc.
    if ($namerec) {
        $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]);
        $tags = array();
        $i = 0;
        do {
            if ($type !== 'TYPE' && !array_key_exists($type, $name_fields) && !array_key_exists($type, $adv_name_fields)) {
                $text = '';
                for ($j = 2; $j < count($fields); $j++) {
                    if ($j > 2) {
                        $text .= ' ';
                    }
                    $text .= $fields[$j];
                }
                while ($i + 1 < count($gedlines) && preg_match('/' . ($level + 1) . ' CONT ?(.*)/', $gedlines[$i + 1], $cmatch) > 0) {
                    $text .= "\n" . $cmatch[2];
                    $i++;
                }
                FunctionsEdit::addSimpleTag($level . ' ' . $type . ' ' . $text);
            }
            $tags[] = $type;
            $i++;
            if (isset($gedlines[$i])) {
                $fields = explode(' ', $gedlines[$i]);
                $level = $fields[0];
                if (isset($fields[1])) {
                    $type = $fields[1];
                }
            }
        } while ($level > $glevel && $i < count($gedlines));
    }
    // If we are adding a new individual, add the basic details
    if ($nextaction !== 'update') {
        echo '</table><br><table class="facts_table">';
        // 1 SEX
        if ($famtag === 'HUSB' || $gender === 'M') {
            FunctionsEdit::addSimpleTag("0 SEX M");
        } elseif ($famtag === 'WIFE' || $gender === 'F') {
            FunctionsEdit::addSimpleTag('0 SEX F');
        } else {
            FunctionsEdit::addSimpleTag('0 SEX');
        }
        $bdm = 'BD';
        if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
            foreach ($matches[1] as $match) {
                if (!in_array($match, explode('|', WT_EVENTS_DEAT))) {
                    FunctionsEdit::addSimpleTags($match);
                }
            }
        }
        //-- if adding a spouse add the option to add a marriage fact to the new family
        if ($nextaction === 'add_spouse_to_individual_action' || $nextaction === 'add_spouse_to_family_action') {
            $bdm .= 'M';
            if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('QUICK_REQUIRED_FAMFACTS'), $matches)) {
                foreach ($matches[1] as $match) {
                    FunctionsEdit::addSimpleTags($match);
                }
            }
        }
        if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
            foreach ($matches[1] as $match) {
                if (in_array($match, explode('|', WT_EVENTS_DEAT))) {
                    FunctionsEdit::addSimpleTags($match);
                }
            }
        }
    }
    echo keep_chan($person);
    echo '</table>';
    if ($nextaction === 'update') {
        // GEDCOM 5.5.1 spec says NAME doesn’t get a OBJE
        FunctionsEdit::printAddLayer('SOUR');
        FunctionsEdit::printAddLayer('NOTE');
        FunctionsEdit::printAddLayer('SHARED_NOTE');
        FunctionsEdit::printAddLayer('RESN');
    } else {
        FunctionsEdit::printAddLayer('SOUR', 1);
        FunctionsEdit::printAddLayer('NOTE', 1);
        FunctionsEdit::printAddLayer('SHARED_NOTE', 1);
        FunctionsEdit::printAddLayer('RESN', 1);
    }
    // If we are editing an existing name, allow raw GEDCOM editing
    if ($name_fact && (Auth::isAdmin() || $WT_TREE->getPreference('SHOW_GEDCOM_RECORD'))) {
        echo '<br><br><a href="edit_interface.php?action=editrawfact&amp;xref=', $xref, '&amp;fact_id=', $name_fact->getFactId(), '&amp;ged=', $WT_TREE->getNameUrl(), '">', I18N::translate('Edit raw GEDCOM'), '</a>';
    }
    echo '<p id="save-cancel">';
    echo '<input type="submit" class="save" value="', I18N::translate('save'), '">';
    if (preg_match('/^add_(child|spouse|parent|unlinked_indi)/', $nextaction)) {
        echo '<input type="submit" class="save" value="', I18N::translate('go to new individual'), '" onclick="document.addchildform.goto.value=\'new\';">';
    }
    echo '<input type="button" class="cancel" value="', I18N::translate('close'), '" onclick="window.close();">';
    echo '</p>';
    echo '</form>';
    $controller->addInlineJavascript('
	SURNAME_TRADITION="' . $WT_TREE->getPreference('SURNAME_TRADITION') . '";
	gender="' . $gender . '";
	famtag="' . $famtag . '";
	function trim(str) {
		str=str.replace(/\\s\\s+/g, " ");
		return str.replace(/(^\\s+)|(\\s+$)/g, "");
	}

	function lang_class(str) {
		if (str.match(/[\\u0370-\\u03FF]/)) return "greek";
		if (str.match(/[\\u0400-\\u04FF]/)) return "cyrillic";
		if (str.match(/[\\u0590-\\u05FF]/)) return "hebrew";
		if (str.match(/[\\u0600-\\u06FF]/)) return "arabic";
		return "latin"; // No matched text implies latin :-)
	}

	// Generate a full name from the name components
	function generate_name() {
		var npfx = jQuery("#NPFX").val();
		var givn = jQuery("#GIVN").val();
		var spfx = jQuery("#SPFX").val();
		var surn = jQuery("#SURN").val();
		var nsfx = jQuery("#NSFX").val();
		if (SURNAME_TRADITION === "polish" && (gender === "F" || famtag === "WIFE")) {
			surn = surn.replace(/ski$/, "ska");
			surn = surn.replace(/cki$/, "cka");
			surn = surn.replace(/dzki$/, "dzka");
			surn = surn.replace(/żki$/, "żka");
		}
		// Commas are used in the GIVN and SURN field to separate lists of surnames.
		// For example, to differentiate the two Spanish surnames from an English
		// double-barred name.
		// Commas *may* be used in other fields, and will form part of the NAME.
		if (WT_LOCALE=="vi" || WT_LOCALE=="hu") {
			// Default format: /SURN/ GIVN
			return trim(npfx+" /"+trim(spfx+" "+surn).replace(/ *, */g, " ")+"/ "+givn.replace(/ *, */g, " ")+" "+nsfx);
		} else if (WT_LOCALE=="zh") {
			// Default format: /SURN/GIVN
			return trim(npfx+" /"+trim(spfx+" "+surn).replace(/ *, */g, " ")+"/"+givn.replace(/ *, */g, " ")+" "+nsfx);
		} else {
			// Default format: GIVN /SURN/
			return trim(npfx+" "+givn.replace(/ *, */g, " ")+" /"+trim(spfx+" "+surn).replace(/ *, */g, " ")+"/ "+nsfx);
		}
	}

	// Update the NAME and _MARNM fields from the name components
	// and also display the value in read-only "gedcom" format.
	function updatewholename() {
		// Don’t update the name if the user manually changed it
		if (manualChange) {
			return;
		}
		var npfx = jQuery("#NPFX").val();
		var givn = jQuery("#GIVN").val();
		var spfx = jQuery("#SPFX").val();
		var surn = jQuery("#SURN").val();
		var nsfx = jQuery("#NSFX").val();
		var name = generate_name();
		jQuery("#NAME").val(name);
		jQuery("#NAME_display").text(name);
		// Married names inherit some NSFX values, but not these
		nsfx = nsfx.replace(/^(I|II|III|IV|V|VI|Junior|Jr\\.?|Senior|Sr\\.?)$/i, "");
		// Update _MARNM field from _MARNM_SURN field and display it
		// Be careful of mixing latin/hebrew/etc. character sets.
		var ip = document.getElementsByTagName("input");
		var marnm_id = "";
		var romn = "";
		var heb = "";
		for (var i = 0; i < ip.length; i++) {
			var val = trim(ip[i].value);
			if (ip[i].id.indexOf("_HEB") === 0)
				heb = val;
			if (ip[i].id.indexOf("ROMN") === 0)
				romn = val;
			if (ip[i].id.indexOf("_MARNM") === 0) {
				if (ip[i].id.indexOf("_MARNM_SURN") === 0) {
					var msurn = "";
					if (val !== "") {
						var lc = lang_class(document.getElementById(ip[i].id).value);
						if (lang_class(name) === lc)
							msurn = trim(npfx + " " + givn + " /" + val + "/ " + nsfx);
						else if (lc === "hebrew")
							msurn = heb.replace(/\\/.*\\//, "/" + val + "/");
						else if (lang_class(romn) === lc)
							msurn = romn.replace(/\\/.*\\//, "/" + val + "/");
					}
					document.getElementById(marnm_id).value = msurn;
					document.getElementById(marnm_id+"_display").innerHTML = msurn;
				} else {
					marnm_id = ip[i].id;
				}
			}
		}
	}

	// Toggle the name editor fields between
	// <input type="hidden"> <span style="display:inline">
	// <input type="text">   <span style="display:hidden">
	var oldName = "";

	// Calls to generate_name() trigger an update - hence need to
	// set the manual change to true first.  We are probably
	// listening to the wrong events on the input fields...
	var manualChange = true;
	manualChange = generate_name() !== jQuery("#NAME").val();

	function convertHidden(eid) {
		var input1 = jQuery("#" + eid);
		var input2 = jQuery("#" + eid + "_display");
		// Note that IE does not allow us to change the type of an input, so we must create a new one.
		if (input1.attr("type")=="hidden") {
			input1.replaceWith(input1.clone().attr("type", "text"));
			input2.hide();
		} else {
			input1.replaceWith(input1.clone().attr("type", "hidden"));
			input2.show();
		}
	}

	/**
	 * if the user manually changed the NAME field, then update the textual
	 * HTML representation of it
	 * If the value changed set manualChange to true so that changing
	 * the other fields doesn’t change the NAME line
	 */
	function updateTextName(eid) {
		var element = document.getElementById(eid);
		if (element) {
			if (element.value!=oldName) manualChange = true;
			var delement = document.getElementById(eid+"_display");
			if (delement) {
				delement.innerHTML = element.value;
			}
		}
	}

	function checkform() {
		var ip=document.getElementsByTagName("input");
		for (var i=0; i<ip.length; i++) {
			// ADD slashes to _HEB and _AKA names
			if (ip[i].id.indexOf("_AKA")==0 || ip[i].id.indexOf("_HEB")==0 || ip[i].id.indexOf("ROMN")==0)
				if (ip[i].value.indexOf("/")<0 && ip[i].value!="")
					ip[i].value=ip[i].value.replace(/([^\\s]+)\\s*$/, "/$1/");
			// Blank out temporary _MARNM_SURN
			if (ip[i].id.indexOf("_MARNM_SURN")==0)
					ip[i].value="";
			// Convert "xxx yyy" and "xxx y yyy" surnames to "xxx,yyy"
			if ((SURNAME_TRADITION=="spanish" || "SURNAME_TRADITION"=="portuguese") && ip[i].id.indexOf("SURN")==0) {
				ip[i].value=document.forms[0].SURN.value.replace(/^\\s*([^\\s,]{2,})\\s+([iIyY] +)?([^\\s,]{2,})\\s*$/, "$1,$3");
			}
		}
		return true;
	}

	// If the name isn’t initially formed from the components in a standard way,
	// then don’t automatically update it.
	if (document.getElementById("NAME").value!=generate_name() && document.getElementById("NAME").value!="//") {
		convertHidden("NAME");
	}
	');
    echo '</div>';
}
Пример #2
0
 /**
  * Generate the facts, for display in charts.
  *
  * @param Individual $individual
  *
  * @return string
  */
 protected function individualBoxFacts(Individual $individual)
 {
     $html = '';
     $opt_tags = preg_split('/\\W/', $individual->getTree()->getPreference('CHART_BOX_TAGS'), 0, PREG_SPLIT_NO_EMPTY);
     // Show BIRT or equivalent event
     foreach (explode('|', WT_EVENTS_BIRT) as $birttag) {
         if (!in_array($birttag, $opt_tags)) {
             $event = $individual->getFirstFact($birttag);
             if ($event) {
                 $html .= $event->summary();
                 break;
             }
         }
     }
     // Show optional events (before death)
     foreach ($opt_tags as $key => $tag) {
         if (!preg_match('/^(' . WT_EVENTS_DEAT . ')$/', $tag)) {
             $event = $individual->getFirstFact($tag);
             if (!is_null($event)) {
                 $html .= $event->summary();
                 unset($opt_tags[$key]);
             }
         }
     }
     // Show DEAT or equivalent event
     foreach (explode('|', WT_EVENTS_DEAT) as $deattag) {
         $event = $individual->getFirstFact($deattag);
         if ($event) {
             $html .= $event->summary();
             if (in_array($deattag, $opt_tags)) {
                 unset($opt_tags[array_search($deattag, $opt_tags)]);
             }
             break;
         }
     }
     // Show remaining optional events (after death)
     foreach ($opt_tags as $tag) {
         $event = $individual->getFirstFact($tag);
         if ($event) {
             $html .= $event->summary();
         }
     }
     return $html;
 }