/**
  * import record into database
  *
  * this function will parse the given gedcom record and add it to the database
  *
  * @param string $gedrec the raw gedcom record to parse
  * @param Tree   $tree   import the record into this tree
  * @param bool   $update whether or not this is an updated record that has been accepted
  */
 public static function importRecord($gedrec, Tree $tree, $update)
 {
     $tree_id = $tree->getTreeId();
     // Escaped @ signs (only if importing from file)
     if (!$update) {
         $gedrec = str_replace('@@', '@', $gedrec);
     }
     // Standardise gedcom format
     $gedrec = self::reformatRecord($gedrec, $tree);
     // import different types of records
     if (preg_match('/^0 @(' . WT_REGEX_XREF . ')@ (' . WT_REGEX_TAG . ')/', $gedrec, $match)) {
         list(, $xref, $type) = $match;
         // check for a _UID, if the record doesn't have one, add one
         if ($tree->getPreference('GENERATE_UIDS') && !strpos($gedrec, "\n1 _UID ")) {
             $gedrec .= "\n1 _UID " . GedcomTag::createUid();
         }
     } elseif (preg_match('/0 (HEAD|TRLR)/', $gedrec, $match)) {
         $type = $match[1];
         $xref = $type;
         // For HEAD/TRLR, use type as pseudo XREF.
     } else {
         echo I18N::translate('Invalid GEDCOM format'), '<br><pre>', $gedrec, '</pre>';
         return;
     }
     // If the user has downloaded their GEDCOM data (containing media objects) and edited it
     // using an application which does not support (and deletes) media objects, then add them
     // back in.
     if ($tree->getPreference('keep_media') && $xref) {
         $old_linked_media = Database::prepare("SELECT l_to FROM `##link` WHERE l_from=? AND l_file=? AND l_type='OBJE'")->execute(array($xref, $tree_id))->fetchOneColumn();
         foreach ($old_linked_media as $media_id) {
             $gedrec .= "\n1 OBJE @" . $media_id . "@";
         }
     }
     switch ($type) {
         case 'INDI':
             // Convert inline media into media objects
             $gedrec = self::convertInlineMedia($tree, $gedrec);
             $record = new Individual($xref, $gedrec, null, $tree);
             if (preg_match('/\\n1 RIN (.+)/', $gedrec, $match)) {
                 $rin = $match[1];
             } else {
                 $rin = $xref;
             }
             Database::prepare("INSERT INTO `##individuals` (i_id, i_file, i_rin, i_sex, i_gedcom) VALUES (?, ?, ?, ?, ?)")->execute(array($xref, $tree_id, $rin, $record->getSex(), $gedrec));
             // Update the cross-reference/index tables.
             self::updatePlaces($xref, $tree_id, $gedrec);
             self::updateDates($xref, $tree_id, $gedrec);
             self::updateLinks($xref, $tree_id, $gedrec);
             self::updateNames($xref, $tree_id, $record);
             break;
         case 'FAM':
             // Convert inline media into media objects
             $gedrec = self::convertInlineMedia($tree, $gedrec);
             if (preg_match('/\\n1 HUSB @(' . WT_REGEX_XREF . ')@/', $gedrec, $match)) {
                 $husb = $match[1];
             } else {
                 $husb = '';
             }
             if (preg_match('/\\n1 WIFE @(' . WT_REGEX_XREF . ')@/', $gedrec, $match)) {
                 $wife = $match[1];
             } else {
                 $wife = '';
             }
             $nchi = preg_match_all('/\\n1 CHIL @(' . WT_REGEX_XREF . ')@/', $gedrec, $match);
             if (preg_match('/\\n1 NCHI (\\d+)/', $gedrec, $match)) {
                 $nchi = max($nchi, $match[1]);
             }
             Database::prepare("INSERT INTO `##families` (f_id, f_file, f_husb, f_wife, f_gedcom, f_numchil) VALUES (?, ?, ?, ?, ?, ?)")->execute(array($xref, $tree_id, $husb, $wife, $gedrec, $nchi));
             // Update the cross-reference/index tables.
             self::updatePlaces($xref, $tree_id, $gedrec);
             self::updateDates($xref, $tree_id, $gedrec);
             self::updateLinks($xref, $tree_id, $gedrec);
             break;
         case 'SOUR':
             // Convert inline media into media objects
             $gedrec = self::convertInlineMedia($tree, $gedrec);
             $record = new Source($xref, $gedrec, null, $tree);
             if (preg_match('/\\n1 TITL (.+)/', $gedrec, $match)) {
                 $name = $match[1];
             } elseif (preg_match('/\\n1 ABBR (.+)/', $gedrec, $match)) {
                 $name = $match[1];
             } else {
                 $name = $xref;
             }
             Database::prepare("INSERT INTO `##sources` (s_id, s_file, s_name, s_gedcom) VALUES (?, ?, LEFT(?, 255), ?)")->execute(array($xref, $tree_id, $name, $gedrec));
             // Update the cross-reference/index tables.
             self::updateLinks($xref, $tree_id, $gedrec);
             self::updateNames($xref, $tree_id, $record);
             break;
         case 'REPO':
             // Convert inline media into media objects
             $gedrec = self::convertInlineMedia($tree, $gedrec);
             $record = new Repository($xref, $gedrec, null, $tree);
             Database::prepare("INSERT INTO `##other` (o_id, o_file, o_type, o_gedcom) VALUES (?, ?, 'REPO', ?)")->execute(array($xref, $tree_id, $gedrec));
             // Update the cross-reference/index tables.
             self::updateLinks($xref, $tree_id, $gedrec);
             self::updateNames($xref, $tree_id, $record);
             break;
         case 'NOTE':
             $record = new Note($xref, $gedrec, null, $tree);
             Database::prepare("INSERT INTO `##other` (o_id, o_file, o_type, o_gedcom) VALUES (?, ?, 'NOTE', ?)")->execute(array($xref, $tree_id, $gedrec));
             // Update the cross-reference/index tables.
             self::updateLinks($xref, $tree_id, $gedrec);
             self::updateNames($xref, $tree_id, $record);
             break;
         case 'OBJE':
             $record = new Media($xref, $gedrec, null, $tree);
             Database::prepare("INSERT INTO `##media` (m_id, m_ext, m_type, m_titl, m_filename, m_file, m_gedcom) VALUES (?, LEFT(?, 6), LEFT(?, 60), LEFT(?, 255), left(?, 512), ?, ?)")->execute(array($xref, $record->extension(), $record->getMediaType(), $record->getTitle(), $record->getFilename(), $tree_id, $gedrec));
             // Update the cross-reference/index tables.
             self::updateLinks($xref, $tree_id, $gedrec);
             self::updateNames($xref, $tree_id, $record);
             break;
         default:
             // HEAD, TRLR, SUBM, SUBN, and custom record types.
             // Force HEAD records to have a creation date.
             if ($type === 'HEAD' && strpos($gedrec, "\n1 DATE ") === false) {
                 $gedrec .= "\n1 DATE " . date('j M Y');
             }
             Database::prepare("INSERT INTO `##other` (o_id, o_file, o_type, o_gedcom) VALUES (?, ?, LEFT(?, 15), ?)")->execute(array($xref, $tree_id, $type, $gedrec));
             // Update the cross-reference/index tables.
             self::updateLinks($xref, $tree_id, $gedrec);
             break;
     }
 }
 /**
  * builds the form for adding new facts
  *
  * @param string $fact the new fact we are adding
  */
 public static function createAddForm($fact)
 {
     global $tags, $WT_TREE;
     $tags = array();
     // handle  MARRiage TYPE
     if (substr($fact, 0, 5) === 'MARR_') {
         $tags[0] = 'MARR';
         self::addSimpleTag('1 MARR');
         self::insertMissingSubtags($fact);
     } else {
         $tags[0] = $fact;
         if ($fact === '_UID') {
             $fact .= ' ' . GedcomTag::createUid();
         }
         // These new level 1 tags need to be turned into links
         if (in_array($fact, array('ALIA', 'ASSO'))) {
             $fact .= ' @';
         }
         if (in_array($fact, Config::emptyFacts())) {
             self::addSimpleTag('1 ' . $fact . ' Y');
         } else {
             self::addSimpleTag('1 ' . $fact);
         }
         self::insertMissingSubtags($tags[0]);
         //-- handle the special SOURce case for level 1 sources [ 1759246 ]
         if ($fact === 'SOUR') {
             self::addSimpleTag('2 PAGE');
             self::addSimpleTag('3 TEXT');
             if ($WT_TREE->getPreference('FULL_SOURCES')) {
                 self::addSimpleTag('3 DATE', '', GedcomTag::getLabel('DATA:DATE'));
                 self::addSimpleTag('2 QUAY');
             }
         }
     }
 }