/**
  * @param LexSense $sense
  * @param bool $entryModified
  * @param int $exampleModifiedCount
  * @param int $pictureModifiedCount
  */
 private static function createSenseGuids($sense, &$entryModified, &$exampleModifiedCount = 0, &$pictureModifiedCount = 0)
 {
     $senseModified = false;
     unset($sense->id);
     if (!$sense->guid || !Guid::isValid($sense->guid)) {
         $liftGuid = Guid::extract($sense->liftId);
         if (Guid::isValid($liftGuid)) {
             $sense->guid = $liftGuid;
         } else {
             $sense->guid = Guid::create();
         }
         $senseModified = true;
     }
     if (isset($sense->examples)) {
         /** @var LexExample $example */
         foreach ($sense->examples as $example) {
             unset($example->id);
             if (!$example->guid || !Guid::isValid($example->guid)) {
                 $liftGuid = Guid::extract($example->liftId);
                 if (Guid::isValid($liftGuid)) {
                     $example->guid = $liftGuid;
                 } else {
                     $example->guid = Guid::create();
                 }
                 $exampleModifiedCount++;
                 $senseModified = true;
             }
         }
     }
     if (isset($sense->pictures)) {
         /** @var LexPicture $picture */
         foreach ($sense->pictures as $picture) {
             if (!$picture->guid || !Guid::isValid($picture->guid)) {
                 $picture->guid = Guid::create();
                 $pictureModifiedCount++;
                 $senseModified = true;
             }
         }
     }
     if ($senseModified) {
         $entryModified = true;
     }
 }
 public function testLiftDecoderGetGuid()
 {
     $guid = Guid::extract('');
     $this->assertEquals('', $guid);
     $guid = Guid::extract('does not contain guid');
     $this->assertEquals('', $guid);
     $liftGuid = Guid::create();
     $guid = Guid::extract('lexeme_' . $liftGuid);
     $this->assertEquals($liftGuid, $guid);
 }
 /**
  * @param \SimpleXMLElement $sxeNode
  * @param LexEntryModel $entry
  * @param string $mergeRule
  * @throws \Exception
  */
 public function readEntry($sxeNode, $entry, $mergeRule = LiftMergeRule::CREATE_DUPLICATES)
 {
     $this->nodeErrors = array();
     $this->nodeErrors[] = new LiftImportNodeError(LiftImportNodeError::ENTRY, (string) $sxeNode['guid']);
     /** @var \SimpleXMLElement $element */
     foreach ($sxeNode as $element) {
         switch ($element->getName()) {
             case 'lexical-unit':
                 if ($mergeRule != LiftMergeRule::IMPORT_LOSES || Id::isEmpty($entry->id)) {
                     $entry->guid = (string) $sxeNode['guid'];
                     $entry->authorInfo->createdDate = UniversalTimestamp::fromStringTimestamp((string) $sxeNode['dateCreated']);
                     $entry->authorInfo->modifiedDate = UniversalTimestamp::fromStringTimestamp((string) $sxeNode['dateModified']);
                     $entry->lexeme = $this->readMultiText($element, $this->project->config->entry->fields[LexConfig::LEXEME]->inputSystems);
                 }
                 break;
             case 'citation':
                 $entry->citationForm = $this->readMultiText($element, $this->project->config->entry->fields[LexConfig::CITATIONFORM]->inputSystems);
                 break;
             case 'note':
                 if ($element['type'] == '') {
                     $entry->note = $this->readMultiText($element, $this->project->config->entry->fields[LexConfig::NOTE]->inputSystems);
                 } else {
                     $this->addKnownUnhandledElement('Note: ' . $element['type']);
                 }
                 break;
             case 'etymology':
                 $entry->etymology = $this->readMultiText($element, $this->project->config->entry->fields[LexConfig::ETYMOLOGY]->inputSystems, true);
                 if ($element->{'gloss'}) {
                     $this->readMultiTextGloss($element->{'gloss'}[0], $entry->etymologyGloss, $this->project->config->entry->fields[LexConfig::ETYMOLOGYGLOSS]->inputSystems);
                 }
                 foreach ($element->{'field'} as $field) {
                     if ($field['type'] == 'comment') {
                         $entry->etymologyComment = $this->readMultiText($field, $this->project->config->entry->fields[LexConfig::ETYMOLOGYCOMMENT]->inputSystems);
                     } else {
                         $this->currentNodeError()->addUnhandledField('etymology: ' . $field['type']);
                     }
                 }
                 break;
             case 'pronunciation':
                 $entry->pronunciation = $this->readMultiText($element, $this->project->config->entry->fields[LexConfig::PRONUNCIATION]->inputSystems, true);
                 if ($element->{'media'}) {
                     $this->addKnownUnhandledElement('pronunciation: media');
                 }
                 break;
             case 'field':
                 switch ($element['type']) {
                     case 'literal-meaning':
                         $entry->literalMeaning = $this->readMultiText($element, $this->project->config->entry->fields[LexConfig::LITERALMEANING]->inputSystems);
                         break;
                     case 'summary-definition':
                         $entry->summaryDefinition = $this->readMultiText($element, $this->project->config->entry->fields[LexConfig::SUMMARYDEFINITION]->inputSystems);
                         break;
                     case 'import-residue':
                         // Currently ignored in LanguageForge
                         break;
                     default:
                         if ($this->isEntryCustomField($element['type'])) {
                             $this->addEntryCustomField($element, $element['type'], $entry);
                         } else {
                             $this->currentNodeError()->addUnhandledField($element['type']);
                         }
                 }
                 break;
             case 'trait':
                 switch ($element['name']) {
                     case 'morph-type':
                         $entry->morphologyType = (string) $element['value'];
                         break;
                     case 'do-not-publish-in':
                     case 'DoNotUseForParsing':
                         $this->addKnownUnhandledElement('trait: ' . $element['name']);
                         break;
                     default:
                         if ($this->isEntryCustomField($element['name'])) {
                             $this->addEntryCustomField($element, $element['name'], $entry);
                         } else {
                             $this->currentNodeError()->addUnhandledTrait($element['name']);
                         }
                 }
                 break;
             case 'sense':
                 $liftId = '';
                 if (isset($element['id'])) {
                     $liftId = (string) $element['id'];
                 }
                 $existingSenseIndex = $entry->searchSensesFor('liftId', $liftId);
                 if ($existingSenseIndex >= 0) {
                     switch ($mergeRule) {
                         case LiftMergeRule::CREATE_DUPLICATES:
                             $sense = new LexSense('');
                             $entry->senses[] = $this->readSense($element, $sense);
                             break;
                         case LiftMergeRule::IMPORT_WINS:
                             $sense = new LexSense($liftId, Guid::extract($liftId));
                             $entry->senses[$existingSenseIndex] = $this->readSense($element, $sense);
                             break;
                         case LiftMergeRule::IMPORT_LOSES:
                             break;
                         default:
                             throw new \Exception("unknown LiftMergeRule " . $mergeRule);
                     }
                 } else {
                     $sense = new LexSense($liftId, Guid::extract($liftId));
                     $entry->senses[] = $this->readSense($element, $sense);
                 }
                 break;
             case 'variant':
             case 'relation':
                 $this->addKnownUnhandledElement('Element: ' . $element->getName());
                 break;
             default:
                 $this->currentNodeError()->addUnhandledElement($element->getName());
         }
     }
     if (!$this->currentNodeError()->hasErrors()) {
         unset($this->nodeErrors[count($this->nodeErrors) - 1]);
     }
 }