예제 #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;
 }