Пример #1
0
 public function process($part)
 {
     // initialize parameters and paths / filename
     $params = JoaktreeHelper::getJTParams($this->procObject->id);
     $conversion_type = $params->get('unicode2utf');
     $path = JPATH_ROOT . DS . $params->get('gedcomfile_path');
     $filename = $path . DS . $params->get('gedcomfile_name');
     $patronymSetting = (int) $params->get('patronym');
     $truncate_rel_value = (int) $params->get('truncrelations');
     //		$procStep			= (int) $params->get('processStep', 1);
     $procStepSize = (int) $params->get('procStepSize', 50);
     $ret = true;
     //		$indAjax 			= ($procStep == 1);
     $indAjax = true;
     // check if gedcom file exists
     if (!JFile::exists($filename)) {
         $this->procObject->msg .= '<br />' . JText::sprintf('JTGEDCOM_MESSAGE_NOGEDCOM', $filename);
         $this->procObject->status = 'error';
         return $this->procObject;
     }
     // initialize array
     $objectLine = array();
     $this->objectLines = array();
     // What type of conversion
     if ($conversion_type == 0) {
         // no conversion
         $conversion = false;
     } else {
         if ($conversion_type == 1) {
             // conversion from ANSEL to UTF-8
             $conversion = true;
             $this->unicode2utf = true;
         } else {
             if ($conversion_type == 2) {
                 // conversion from ANSEL to Unicode
                 $conversion = true;
                 $this->unicode2utf = false;
             } else {
                 // parameter has unknown value: no conversion
                 $conversion = false;
             }
         }
     }
     // remove double and trailing characters, like comma's
     if ($params->get('removeChar')) {
         $removeChar = $params->get('removeChar');
     } else {
         $removeChar = false;
     }
     // initialize counters
     $teller0 = 0;
     // counter for gedcom objects
     $tellert = 0;
     // counter for total number of lines in file
     // Loop through the array looking for header info.
     $ansel = false;
     $char_done = false;
     $vers_done = false;
     // open file
     $handle = @fopen($filename, "r");
     if ($handle && $this->procObject->status == 'new') {
         // loop through the lines
         while (!feof($handle)) {
             $line = fgets($handle, 4096);
             $line = trim($line);
             // we are ready
             if ($char_done and $vers_done) {
                 break;
             }
             // remove end-of-line characters
             $line = rtrim($line, "\r\n");
             // split line into three parts with space as deviding character
             $elements = explode(" ", $line, 3);
             if (!isset($elements[0])) {
                 $elements[0] = null;
             } else {
                 $elements[0] = trim($elements[0]);
             }
             if (!isset($elements[1])) {
                 $elements[1] = null;
             } else {
                 $elements[1] = trim($elements[1]);
             }
             if (!isset($elements[2])) {
                 $elements[2] = null;
             } else {
                 $elements[2] = trim($elements[2]);
             }
             // first part of line is the level;
             $level = $elements[0];
             // process only the header: so is this the header
             if ($level == 0) {
                 if ($elements[1] == 'HEAD') {
                     $ind_header = true;
                 } else {
                     $ind_header = false;
                 }
             }
             // process only the header
             if ($ind_header == true) {
                 // see whether we have to transer ANSEL to UTF-8
                 // other character sets are left alone.
                 if ($elements[1] == 'CHAR') {
                     $char_done = true;
                     if ($elements[2] == 'ANSEL') {
                         $ansel = true;
                     }
                 }
                 // check the version of GEDCOM: is this the GEDCOM and not SOURCE?
                 if ($elements[1] == 'GEDC') {
                     $ind_get_vers = true;
                 } else {
                     $ind_get_vers = false;
                 }
                 // check version of GEDCOM
                 if ($elements[1] == 'VERS' and $ind_get_vers) {
                     $vers_done = true;
                     $version = substr($elements[2], 0, 3);
                     if ($version != '5.5' and $version != '5.5.1') {
                         $this->procObject->msg .= '<br />' . JText::_('JTGEDCOM_MESSAGE_NOV55');
                         $this->procObject->status = 'error';
                         return $this->procObject;
                     }
                 }
             }
             // end of if ind_header == true
         }
         // end of loop
     }
     // if charcter set is ANSEL
     if ($conversion == true and $ansel == true) {
         $result = $this->prepareANSEL();
         if ($result) {
             $this->procObject->msg .= $result;
         }
     }
     $this->objectType = 'START';
     switch ($part) {
         case "person":
             $filterTag = 'INDI';
             break;
         case "family":
             $filterTag = 'FAM';
             // remove relations
             if ($truncate_rel_value == 1 && $this->procObject->status == 'new') {
                 $relation_notes =& JMFPKTable::getInstance('joaktree_relation_notes', 'Table');
                 $retdelete = $relation_notes->truncateApp($this->procObject->id);
                 $relation_events =& JMFPKTable::getInstance('joaktree_relation_events', 'Table');
                 $retdelete = $relation_events->truncateApp($this->procObject->id);
                 $relations =& JMFPKTable::getInstance('joaktree_relations', 'Table');
                 $retdelete = $relations->truncateApp($this->procObject->id);
                 $relation_citations =& JMFPKTable::getInstance('joaktree_citations', 'Table');
                 $retdelete = $relation_citations->truncateRelationCitations($this->procObject->id);
             }
             break;
         case "source":
             $filterTag = 'SOUR';
             break;
         case "repository":
             $filterTag = 'REPO';
             break;
         case "note":
             $filterTag = 'NOTE';
             break;
         case "document":
             $filterTag = 'OBJE';
             break;
         case "all":
             // same as default
         // same as default
         default:
             $filterTag = null;
             // remove relations
             if ($truncate_rel_value == 1 && $this->procObject->status == 'new') {
                 $relation_notes =& JMFPKTable::getInstance('joaktree_relation_notes', 'Table');
                 $retdelete = $relation_notes->truncateApp($this->procObject->id);
                 $relation_events =& JMFPKTable::getInstance('joaktree_relation_events', 'Table');
                 $retdelete = $relation_events->truncateApp($this->procObject->id);
                 $relations =& JMFPKTable::getInstance('joaktree_relations', 'Table');
                 $retdelete = $relations->truncateApp($this->procObject->id);
                 $relation_citations =& JMFPKTable::getInstance('joaktree_citations', 'Table');
                 $retdelete = $relation_citations->truncateRelationCitations($this->procObject->id);
             }
             break;
     }
     $indProcess = false;
     if (!$indAjax) {
         // we will not be looping back to the caller
         // instead we will go one time through the whole GedCom file
         // so status is set now to 'progress'
         $this->procObject->status = 'progress';
     }
     // Loop through the array.
     if ($handle && ($this->procObject->status == 'progress' || $this->procObject->status == 'new')) {
         // move to the beginning
         fseek($handle, $this->procObject->cursor);
         // loop through the lines
         while (!feof($handle)) {
             $line = fgets($handle);
             $line = trim($line);
             $tellert++;
             // remove end-of-line characters
             $line = rtrim($line, "\r\n");
             // if ANSEL convert the line
             if ($conversion == true and $ansel == true) {
                 $line = $this->convertANSEL($line);
             }
             // remove double or trailing characters
             if ($removeChar) {
                 $remove = true;
                 while ($remove) {
                     $line = str_replace($removeChar . $removeChar, $removeChar, $line, $countReplace);
                     if ($countReplace == 0) {
                         $remove = false;
                     }
                 }
                 $line = trim($line, $removeChar);
             }
             // split line into three parts with space as deviding character
             $elements = explode(" ", $line, 3);
             if (!isset($elements[0])) {
                 $elements[0] = null;
             } else {
                 $elements[0] = trim($elements[0]);
             }
             if (!isset($elements[1])) {
                 $elements[1] = null;
             } else {
                 $elements[1] = trim($elements[1]);
             }
             if (!isset($elements[2])) {
                 $elements[2] = null;
             } else {
                 $elements[2] = trim($elements[2]);
             }
             // first part of line is the level;
             $level = $elements[0];
             // the level 0 lines are the main lines (=gedcom objects)
             // these lines are stored in object table
             // when level is greater than 0, it is a depending line and
             // stored in object-line table
             if ($level == 0) {
                 // level = 0: we dealing with the object
                 // first process the previous object (if existing)
                 if ($indProcess) {
                     $this->process_object();
                     if ($indAjax && $teller0 == $procStepSize) {
                         $this->procObject->cursor = $fileCursor;
                         $this->procObject->status = 'progress';
                         fclose($handle);
                         return $this->procObject;
                     }
                 }
                 // set boolean to check the first objectline
                 $indFirstLine = true;
                 if ($elements[2] == null) {
                     // third element is empty for level 0 line
                     // tag is in the second element
                     // there is no value. this will be filled with value from counter object_value_id
                     $this->objectType = $elements[1];
                     $this->objectKey = null;
                 } else {
                     // third element is not empty. this countains the tag
                     // second element contains the value
                     // value has to be stripped from @ characters
                     // However third element may also contain a value ... it is weird but true
                     $subelems = explode(" ", $elements[2], 2);
                     if (!isset($subelems[0])) {
                         $subelems[0] = null;
                     } else {
                         $subelems[0] = trim($subelems[0]);
                     }
                     if (!isset($subelems[1])) {
                         $subelems[1] = null;
                     } else {
                         $subelems[1] = trim($subelems[1]);
                     }
                     if ($subelems[1] == null) {
                         // everything is ok and normal
                         $this->objectType = $elements[2];
                         $this->objectKey = ltrim(rtrim($elements[1], '@'), '@');
                     } else {
                         // extra value found in the line!!
                         $this->objectType = $subelems[0];
                         $this->objectKey = ltrim(rtrim($elements[1], '@'), '@');
                         // this is really a new tag.
                         $objectLine['object_id'] = $this->objectKey;
                         $objectLine['level'] = 1;
                         $objectLine['tag'] = "TEXT";
                         $objectLine['value'] = $subelems[1];
                         // keep the object line
                         $this->objectLines[] = $objectLine;
                         $indFirstLine = false;
                     }
                 }
                 $teller0++;
                 if ($filterTag) {
                     if ($filterTag == $this->objectType) {
                         $indProcess = true;
                     } else {
                         $indProcess = false;
                     }
                 } else {
                     $indProcess = true;
                 }
             } else {
                 if ($indProcess) {
                     // level <> 0: we dealing with object lines
                     // element 2 contains the tag; element 3 contains the value
                     $tag = $elements[1];
                     $value = $elements[2];
                     // replace special characters in value
                     // & (= ampersand)
                     $value = str_replace("&", "&#38;", $value);
                     // < (= less than sign)
                     $value = str_replace("<", "&#60;", $value);
                     // > (= greater than sign)
                     $value = str_replace(">", "&#62;", $value);
                     // ' (= single quote)
                     //$value = str_replace("'", "&#39;", $value);
                     //$value = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
                     // Deal with the first line if it is not a real tag
                     if ($indFirstLine) {
                         // Aldfaer uses for notes as first line CONC.
                         // This should be text, and here we fix it.
                         if ($tag == 'CONC' or $tag == 'CONT') {
                             $tag = 'TEXT';
                         }
                         $indFirstLine = false;
                     }
                     if ($tag == 'CONC' or $tag == 'CONT') {
                         // this line is a continutation of the previouse line
                         $objectLine = array_pop($this->objectLines);
                         if ($tag == 'CONC') {
                             $objectLine['value'] = $objectLine['value'] . $value;
                         } else {
                             if ($tag == 'CONT') {
                                 $objectLine['value'] = $objectLine['value'] . '&#10;&#13;' . $value;
                             }
                         }
                         // keep the object line
                         $this->objectLines[] = $objectLine;
                     } else {
                         // this is really a new tag.
                         $objectLine['object_id'] = $this->objectKey;
                         $objectLine['level'] = $level;
                         $objectLine['tag'] = $tag;
                         $objectLine['value'] = $value;
                         // keep the object line
                         $this->objectLines[] = $objectLine;
                     }
                 }
             }
             // end of check on level = 0
             $fileCursor = ftell($handle);
         }
         // end of loop through array
     }
     if ($handle) {
         fclose($handle);
     }
     // if the number of objects is smaller than the step size
     // status never reached 'progress'. It is still 'new'.
     if ($indAjax && $this->procObject->status == 'new' && $teller0 < $procStepSize) {
         $this->procObject->cursor = $fileCursor;
         $this->procObject->status = 'progress';
         return $this->procObject;
     }
     $this->procObject->cursor = isset($fileCursor) ? $fileCursor : 0;
     if ($this->procObject->status == 'progress') {
         // status is progress: this means our last action was reading the file
         // we are done with that for now - time for a new status
         $this->procObject->status = 'endload';
         if ($indAjax) {
             // we are looping back to the caller
             return $this->procObject;
         }
     }
     if ($patronymSetting != 0 && $patronymSetting != 1 && $this->procObject->status == 'endload') {
         // we are not setting the patronyms - just update the status to the next
         $this->procObject->status = 'endpat';
         if ($indAjax) {
             // we are looping back to the caller
             return $this->procObject;
         }
     }
     // if setting is NOT to retrieve patronyms from name string, patronyms have to determined now
     if (($patronymSetting == 0 || $patronymSetting == 1) && $this->procObject->status == 'endload') {
         $ret = jt_names::setPatronyms($this->procObject->id);
         if (!$ret) {
             // if no result - an error occured and we stop
             $this->procObject->status = 'error';
             $this->procObject->msg .= JText::_('JTGEDCOM_MESSAGE_NOSUCPATRONYMS');
             return $this->procObject;
         } else {
             // we are done - so change the status
             $this->procObject->status = 'endpat';
             if ($indAjax) {
                 // we are looping back to the caller
                 $this->procObject->msg .= JText::_('JTGEDCOM_MESSAGE_SUCPATRONYMS');
                 return $this->procObject;
             }
         }
     }
     // Set the indicators for different types of relationships after processing all persons
     if ($this->procObject->status == 'endpat') {
         $ret = jt_relations::setRelationIndicators($this->procObject->id);
         // if no result - an error occured and we stop
         if (!$ret) {
             $this->procObject->status = 'error';
             $this->procObject->msg .= JText::_('JTGEDCOM_MESSAGE_NOSUCRELINDICATORS');
             return $this->procObject;
         } else {
             $this->procObject->status = 'endrel';
             if ($indAjax) {
                 // we are looping back to the caller
                 $this->procObject->msg .= JText::_('JTGEDCOM_MESSAGE_SUCRELINDICATORS');
                 return $this->procObject;
             }
         }
     }
     return $this->procObject;
 }
Пример #2
0
 public function process(&$person_id, &$row_lines)
 {
     $ret = true;
     // every loop: update counter and start with empty record
     $this->persons->loadEmpty();
     $this->persons->set('app_id', $this->app_id);
     $this->persons->set('id', $person_id);
     $event1Type = 'none';
     $event2Type = 'none';
     $event3Type = 'none';
     $firstTimeNameTag = true;
     // admin settings
     $this->indLiving = true;
     unset($this->birthYear);
     unset($this->deathYear);
     // check whether a record exists with person id
     if ($this->persons->load()) {
         // record exists: existing record will be updated
         $ind_update = true;
     } else {
         // record does not exists: new record will be inserted
         $ind_update = false;
     }
     // spouses
     $spouseCounter = 0;
     // initialize names, events, notes, documents, citations, relations, spouses for this person
     // names
     $retdelete = $this->person_names->deleteNames($person_id);
     $this->person_names->loadEmpty();
     $this->person_names->set('app_id', $this->app_id);
     $this->person_names->set('person_id', $person_id);
     $this->namePersonCounter = 0;
     $retdelete = $this->person_events->deleteEvents($person_id);
     $this->person_events->loadEmpty();
     $this->person_events->set('app_id', $this->app_id);
     $this->person_events->set('person_id', $person_id);
     $this->eventPersonCounter = 0;
     // notes
     $retdelete = $this->person_notes->deleteNotes($person_id);
     $this->person_notes->loadEmpty();
     $this->person_notes->set('app_id', $this->app_id);
     $this->person_notes->set('person_id', $person_id);
     $this->notePersonCounter = 0;
     // documents
     $retdelete = $this->person_docs_1->deleteDocuments($person_id);
     $this->documentPersonCounter = 0;
     // sources
     $retdelete = $this->person_citations->deletePersonCitations($person_id);
     $this->person_citations->loadEmpty();
     $this->person_citations->set('app_id', $this->app_id);
     $this->person_citations->set('person_id_1', $person_id);
     $this->person_citations->set('person_id_2', 'EMPTY');
     $this->citationPersonCounter = 0;
     // logs
     $this->logs->set('object_id', $person_id);
     // loop through lines related to the person
     foreach ($row_lines as $row_line_num => $row_line) {
         switch ($row_line['level']) {
             case "1":
                 // set $information to be used for level 2 info
                 $information = $row_line['tag'];
                 switch ($information) {
                     case "NAME":
                         $event1Type = 'personName';
                         // extract first name and family name
                         $names = explode("/", $row_line['value'], 3);
                         if (!isset($names[0])) {
                             $names[0] = null;
                         } else {
                             $names[0] = trim($names[0]);
                         }
                         if (!isset($names[1])) {
                             $names[1] = null;
                         } else {
                             $names[1] = trim($names[1]);
                         }
                         if ($firstTimeNameTag) {
                             // The first time the NAME tag is read -> this is the main name!
                             if ($this->patronymSetting == 9) {
                                 // extract patronym from name field using patronymString-separation
                                 $tmpName = explode($this->patronymString, $names[0], 3);
                                 if (!isset($tmpName[0])) {
                                     $tmpName[0] = null;
                                 } else {
                                     $tmpName[0] = trim($tmpName[0]);
                                 }
                                 if (!isset($tmpName[1])) {
                                     $tmpName[1] = null;
                                 } else {
                                     $tmpName[1] = trim($tmpName[1]);
                                 }
                                 $this->persons->set('firstName', $tmpName[0]);
                                 $this->persons->set('patronym', $tmpName[1]);
                             } else {
                                 $this->persons->set('firstName', $names[0]);
                             }
                             // set the familyName and namePreposition
                             jt_names::setFamilyName($names[1], $this->persons, $this->familynameSetting);
                             $firstTimeNameTag = false;
                         } else {
                             // concurrent NAME tags -> This are "also known as" names.
                             $information = 'AKA';
                             if ($ret) {
                                 $ret = $this->setPersonName($information, $names[0] . ' ' . $names[1]);
                             }
                         }
                         break;
                     case "SEX":
                         $event1Type = 'none';
                         $this->persons->set('sex', $row_line['value']);
                         break;
                     case "FAMS":
                         $event1Type = 'none';
                         // FAMS is the family this person is a spouse
                         // in this family a spouse can be found
                         $spouseCounter++;
                         if ($ret) {
                             $ret = $this->spouse($person_id, rtrim(ltrim($row_line['value'], '@'), '@'), $spouseCounter);
                         }
                         break;
                     case "FAMC":
                         $event1Type = 'familyChild';
                         $family_id = trim($row_line['value'], '@');
                         break;
                     case "BIRT":
                         // do nothing
                     // do nothing
                     case "CHR":
                         // do nothing
                     // do nothing
                     case "DEAT":
                         if ($information == 'DEAT') {
                             $this->indLiving = false;
                         }
                     case "BURI":
                         if ($information == 'BURI') {
                             $this->indLiving = false;
                         }
                     case "CREM":
                         if ($information == 'CREM') {
                             $this->indLiving = false;
                         }
                         //case "ADOP":	// do nothing
                     //case "ADOP":	// do nothing
                     case "BAPM":
                         // do nothing
                     // do nothing
                     case "BARM":
                         // do nothing
                     // do nothing
                     case "BASM":
                         // do nothing
                     // do nothing
                     case "BLES":
                         // do nothing
                     // do nothing
                     case "CHRA":
                         // do nothing
                     // do nothing
                     case "CONF":
                         // do nothing
                     // do nothing
                     case "FCOM":
                         // do nothing
                     // do nothing
                     case "NATU":
                         // do nothing
                     // do nothing
                     case "EMIG":
                         // do nothing
                     // do nothing
                     case "IMMI":
                         // do nothing
                     // do nothing
                     case "GRAD":
                         // do nothing
                     // do nothing
                     case "RETI":
                         // do nothing
                     // do nothing
                     case "EVEN":
                         // do nothing
                     // do nothing
                     case "CAST":
                         // do nothing
                     // do nothing
                     case "DSCR":
                         // do nothing
                     // do nothing
                     case "EDUC":
                         // do nothing
                     // do nothing
                     case "NATI":
                         // do nothing
                     // do nothing
                     case "OCCU":
                         // do nothing
                     // do nothing
                     case "RELI":
                         // do nothing
                     // do nothing
                     case "RESI":
                         // do nothing
                     // do nothing
                     case "_BRTM":
                         if ($information == '_BRTM') {
                             $information = 'BRTM';
                         }
                     case "CIRC":
                         if ($information == 'CIRC') {
                             $information = 'BRTM';
                         }
                     case "_YART":
                         if ($information == '_YART') {
                             $information = 'YART';
                             $this->indLiving = false;
                         }
                     case "TITL":
                         $event1Type = 'personEvent';
                         if ($ret) {
                             $ret = $this->setPersonEvent($information, $row_line['value']);
                         }
                         break;
                     case "SOUR":
                         // Source for person
                         $event1Type = 'personSource';
                         $sourceKey = $this->getSourceKey($row_line['value']);
                         if ($ret) {
                             $ret = $this->setPersonCitation('person', $sourceKey);
                         }
                         if ($ret) {
                             $this->persons->set('indCitation', true);
                         }
                         break;
                     case "NOTE":
                         // Note for person
                         $event1Type = 'personNote';
                         if ($ret) {
                             $ret = $this->setPersonNote('person', $row_line['value']);
                         }
                         if ($ret) {
                             $this->persons->set('indNote', true);
                         }
                         break;
                     case "OBJE":
                         // Document for person
                         $event1Type = 'personDocument';
                         if ($ret) {
                             $ret = $this->setDocument($person_id, null, $row_line['value']);
                         }
                         break;
                     case "CHAN":
                         // changeDateTime
                         $event1Type = 'changeDateTime';
                         break;
                     default:
                         $event1Type = 'none';
                         break;
                 }
                 break;
             case "2":
                 if ($information == 'NAME' || $information == 'AKA') {
                     // case "2": if ($information == 'NAME') {
                     $nameTag = $row_line['tag'];
                     switch ($nameTag) {
                         case "GIVN":
                             // do nothing
                         // do nothing
                         case "SURN":
                             // do nothing
                         // do nothing
                         case "NICK":
                             // do nothing
                         // do nothing
                         case "_ADPN":
                             if ($nameTag == '_ADPN') {
                                 $nameTag = 'ADPN';
                             }
                         case "_AKA":
                             if ($nameTag == '_AKA') {
                                 $nameTag = 'AKA';
                             }
                         case "_AKAN":
                             if ($nameTag == '_AKAN') {
                                 $nameTag = 'AKA';
                             }
                         case "_CALL":
                             if ($nameTag == '_CALL') {
                                 $nameTag = 'AKA';
                             }
                         case "AKA":
                             // do nothing
                         // do nothing
                         case "_BIRN":
                             if ($nameTag == '_BIRN') {
                                 $nameTag = 'BIRN';
                             }
                         case "_CENN":
                             if ($nameTag == '_CENN') {
                                 $nameTag = 'CENN';
                             }
                         case "_CURN":
                             if ($nameTag == '_CURN') {
                                 $nameTag = 'CURN';
                             }
                         case "_FKAN":
                             if ($nameTag == '_FKAN') {
                                 $nameTag = 'FRKA';
                             }
                         case "_FRKA":
                             if ($nameTag == '_FRKA') {
                                 $nameTag = 'FRKA';
                             }
                         case "_HEBN":
                             if ($nameTag == '_HEBN') {
                                 $nameTag = 'HEBN';
                             }
                         case "_INDN":
                             if ($nameTag == '_INDN') {
                                 $nameTag = 'INDG';
                             }
                         case "_INDG":
                             if ($nameTag == '_INDG') {
                                 $nameTag = 'INDG';
                             }
                         case "_MARN":
                             if ($nameTag == '_MARN') {
                                 $nameTag = 'MARN';
                             }
                         case "_MARNM":
                             if ($nameTag == '_MARNM') {
                                 $nameTag = 'MARN';
                             }
                         case "_OTHN":
                             if ($nameTag == '_OTHN') {
                                 $nameTag = 'OTHN';
                             }
                         case "_RELN":
                             if ($nameTag == '_RELN') {
                                 $nameTag = 'RELN';
                             }
                         case "NAMR":
                             if ($nameTag == 'NAMR') {
                                 $nameTag = 'RELN';
                             }
                             $event2Type = 'personName';
                             if ($ret) {
                                 $ret = $this->setPersonName($nameTag, $row_line['value']);
                             }
                             break;
                         case "_PATR":
                             if ($this->patronymSetting == 2) {
                                 $this->persons->set('patronym', $row_line['value']);
                             }
                             break;
                         case "NPFX":
                             $this->persons->set('prefix', $row_line['value']);
                             break;
                         case "NSFX":
                             $this->persons->set('suffix', $row_line['value']);
                             break;
                         default:
                             $event2Type = 'none';
                             break;
                     }
                 }
                 switch ($row_line['tag']) {
                     case "DATE":
                         // all events
                         $event2Type = 'none';
                         if ($event1Type == 'personEvent') {
                             $this->person_events->set('eventDate', $row_line['value']);
                             switch ($information) {
                                 case "BIRT":
                                     // do nothing
                                 // do nothing
                                 case "CHR":
                                     // do nothing
                                 // do nothing
                                 case "BRTM":
                                     // do nothing
                                 // do nothing
                                 case "BAPM":
                                     // do nothing
                                     if (!isset($this->birthYear)) {
                                         $this->birthYear = (int) substr(trim($row_line['value']), -4);
                                     }
                                 case "BARM":
                                     // do nothing
                                 // do nothing
                                 case "BASM":
                                     // do nothing
                                 // do nothing
                                 case "BLES":
                                     // do nothing
                                 // do nothing
                                 case "CHRA":
                                     // do nothing
                                     $eventYear = (int) substr(trim($row_line['value']), -4);
                                     if ($eventYear < $this->offsetYear) {
                                         $this->indLiving = false;
                                     }
                                     break;
                                 case "DEAT":
                                     // do nothing
                                 // do nothing
                                 case "BURI":
                                     // do nothing
                                 // do nothing
                                 case "CREM":
                                     // do nothing
                                     if (!isset($this->deathYear)) {
                                         $this->deathYear = (int) substr(trim($row_line['value']), -4);
                                     }
                                     break;
                                 default:
                                     break;
                             }
                         } else {
                             if ($event1Type == 'changeDateTime') {
                                 $this->logs->setChangeDateTime(trim($row_line['value']));
                             }
                         }
                         break;
                     case "PLAC":
                         $event2Type = 'none';
                         if ($event1Type == 'personEvent') {
                             $this->person_events->set('location', $row_line['value']);
                         }
                         break;
                     case "TYPE":
                         // all other events
                         $event2Type = 'none';
                         if ($event1Type == 'personEvent') {
                             $this->person_events->set('type', $row_line['value']);
                         }
                         break;
                     case "PAGE":
                         $event2Type = 'none';
                         if ($event1Type == 'personSource') {
                             $this->person_citations->set('page', $row_line['value']);
                         }
                         break;
                     case "QUAY":
                         $event2Type = 'none';
                         if ($event1Type == 'personSource') {
                             $this->person_citations->set('dataQuality', $row_line['value']);
                         }
                         break;
                     case "FORM":
                         $event2Type = 'none';
                         if ($event1Type == 'personDocument') {
                             $this->documents->set('fileformat', $row_line['value']);
                         }
                         break;
                     case "FILE":
                         $event2Type = 'none';
                         if ($event1Type == 'personDocument') {
                             $this->documents->set('file', $row_line['value']);
                         }
                         break;
                     case "TITL":
                         $event2Type = 'none';
                         if ($event1Type == 'personDocument') {
                             $this->documents->set('title', $row_line['value']);
                         }
                         break;
                     case "NOTE":
                         if ($event1Type == 'personSource') {
                             // do nothing for right now
                             $event2Type = 'none';
                             $this->person_citations->set('note', $row_line['value']);
                         } else {
                             if ($event1Type == 'personDocument') {
                                 $event2Type = 'none';
                                 // try to strip @ and save in local value
                                 $tmpValue = ltrim(rtrim($row_line['value'], '@'), '@');
                                 if ($row_line['value'] != $tmpValue) {
                                     // @ are stripped and local value is therefore different than value
                                     // this is an note_id
                                     $this->documents->set('note_id', $tmpValue);
                                 } else {
                                     // stripping had no effect. values are identical
                                     // this is a real note
                                     $this->documents->set('note', $row_line['value']);
                                 }
                             } else {
                                 // Note for event
                                 $event2Type = 'personNote';
                                 if ($ret) {
                                     $ret = $this->setPersonNote($event1Type, $row_line['value']);
                                 }
                                 if ($event1Type == 'personEvent') {
                                     if ($ret) {
                                         $this->person_events->set('indNote', true);
                                     }
                                 }
                             }
                         }
                         break;
                     case "SOUR":
                         // collect all sources for this person
                         $event2Type = 'personSource';
                         if ($ret and $event1Type != 'none') {
                             $sourceKey = $this->getSourceKey($row_line['value']);
                             $ret = $this->setPersonCitation($event1Type, $sourceKey);
                             if ($event1Type == 'personEvent') {
                                 if ($ret) {
                                     $this->person_events->set('indCitation', true);
                                 }
                                 if ($ret) {
                                     $this->persons->set('indCitation', true);
                                 }
                             } else {
                                 if ($event1Type == 'personNote') {
                                     if ($ret) {
                                         $this->person_notes->set('indCitation', true);
                                     }
                                     if ($ret) {
                                         $this->persons->set('indCitation', true);
                                     }
                                 } else {
                                     if ($event1Type == 'personDocument' and $this->docsFromGedcom) {
                                         if ($ret) {
                                             $this->documents->set('indCitation', true);
                                         }
                                         if ($ret) {
                                             $this->persons->set('indCitation', true);
                                         }
                                     }
                                 }
                             }
                         }
                         break;
                     case "ADOP":
                         // Adopted child - don't know how this tag is used
                     // Adopted child - don't know how this tag is used
                     case "FOST":
                         // Foster child - don't know how this tag is used
                         $row_line['value'] = $row_line['tag'] == 'ADOP' ? 'adopted' : 'foster';
                         // continue
                     // continue
                     case "PEDI":
                         if ($event1Type == 'familyChild') {
                             $this->keepChild($person_id, $family_id, $row_line['value']);
                             unset($family_id);
                         }
                         break;
                     case "CHAN":
                         // changeDateTime
                         $event2Type = 'changeDateTime';
                         break;
                     default:
                         break;
                 }
                 break;
             case "3":
                 switch ($row_line['tag']) {
                     case "DATE":
                         $event3Type = 'none';
                         if ($information == 'NAME' and $event2Type == 'personName') {
                             $this->person_names->set('eventDate', $row_line['value']);
                         } else {
                             if ($event2Type == 'changeDateTime') {
                                 $this->logs->setChangeDateTime(trim($row_line['value']));
                             }
                         }
                         break;
                     case "PAGE":
                         $event3Type = 'none';
                         if ($event2Type == 'personSource') {
                             $this->person_citations->set('page', $row_line['value']);
                         }
                         break;
                     case "QUAY":
                         $event3Type = 'none';
                         if ($event2Type == 'personSource') {
                             $this->person_citations->set('dataQuality', $row_line['value']);
                         }
                         break;
                     case "TEXT":
                         $event3Type = 'none';
                         if ($event1Type == 'personSource') {
                             $this->person_citations->set('quotation', $row_line['value']);
                         }
                         break;
                     case "NOTE":
                         if ($event2Type == 'personSource') {
                             $event3Type = 'none';
                             $this->person_citations->set('note', $row_line['value']);
                         } else {
                             $event3Type = 'personNote';
                             if ($ret) {
                                 $ret = $this->setPersonNote($event2Type, $row_line['value']);
                             }
                             if ($event2Type == 'personName') {
                                 if ($ret) {
                                     $this->person_names->set('indNote', true);
                                 }
                             }
                         }
                         break;
                         // new level for source
                     // new level for source
                     case "SOUR":
                         // collect all sources for this person
                         $event3Type = 'personSource';
                         if ($ret and $event2Type != 'none') {
                             $sourceKey = $this->getSourceKey($row_line['value']);
                             $ret = $this->setPersonCitation($event2Type, $sourceKey);
                             if ($event2Type == 'personName') {
                                 if ($ret) {
                                     $this->person_names->set('indCitation', true);
                                 }
                                 if ($ret) {
                                     $this->persons->set('indCitation', true);
                                 }
                             } else {
                                 if ($event2Type == 'personNote') {
                                     if ($ret) {
                                         $this->person_notes->set('indCitation', true);
                                     }
                                     if ($ret) {
                                         $this->persons->set('indCitation', true);
                                     }
                                 }
                             }
                         }
                         break;
                     case "CHAN":
                         // changeDateTime
                         $event3Type = 'changeDateTime';
                         break;
                     default:
                         break;
                 }
                 break;
             case "4":
                 switch ($row_line['tag']) {
                     case "DATE":
                         if ($event3Type == 'changeDateTime') {
                             $this->logs->setChangeDateTime(trim($row_line['value']));
                         }
                         break;
                     case "PAGE":
                         if ($event3Type == 'personSource') {
                             $this->person_citations->set('page', $row_line['value']);
                         }
                         break;
                     case "QUAY":
                         if ($event3Type == 'personSource') {
                             $this->person_citations->set('dataQuality', $row_line['value']);
                         }
                         break;
                     case "TEXT":
                         if ($event2Type == 'personSource') {
                             $this->person_citations->set('quotation', $row_line['value']);
                         }
                         break;
                     case "NOTE":
                         if ($event3Type == 'personSource') {
                             $this->person_citations->set('note', $row_line['value']);
                         }
                         break;
                     default:
                         break;
                 }
                 break;
             case "5":
                 switch ($row_line['tag']) {
                     case "TEXT":
                         if ($event3Type == 'personSource') {
                             $this->person_citations->set('quotation', $row_line['value']);
                         }
                         break;
                     default:
                         break;
                 }
                 break;
             default:
                 break;
         }
         // end of level switch
     }
     // end of loop throuth lines related to person
     if (!$ind_update) {
         // insert new record for admin table
         if ($ret) {
             $ret = $this->admin_person();
         }
     }
     // store record
     if ($ret) {
         $ret = $this->persons->store();
     }
     // update last person name
     if ($ret) {
         $ret = $this->setPersonName(null, null);
     }
     // update last person event
     if ($ret) {
         $ret = $this->setPersonEvent(null, null);
     }
     // update last person note
     if ($ret) {
         $ret = $this->setPersonNote(null, null);
     }
     // update last person citation
     if ($ret) {
         $ret = $this->setPersonCitation('none', null);
     }
     // update last person document
     if ($ret) {
         $ret = $this->setDocument(null, null, null);
     }
     // log update
     if ($ret) {
         $ret = $this->logs->logChangeDateTime();
     }
     // if insert or update went ok, continue with next source; else stop
     if (!$ret) {
         $this->application->enqueueMessage(JText::sprintf('JTGEDCOM_MESSAGE_NOSUCPERSON', $person_id), 'notice');
     }
     return $ret;
 }