Ejemplo n.º 1
0
 /**
  * @param string $liftFilePath
  * @param LexiconProjectModel $projectModel
  * @param LiftMergeRule $mergeRule
  * @param boolean $skipSameModTime
  * @param boolean $deleteMatchingEntry
  * @return \Api\Model\Languageforge\Lexicon\LiftImport
  */
 public function merge($liftFilePath, $projectModel, $mergeRule = LiftMergeRule::CREATE_DUPLICATES, $skipSameModTime = true, $deleteMatchingEntry = false)
 {
     ini_set('max_execution_time', 180);
     // Sufficient time to import webster.  TODO Make this async CP 2014-10
     $entryList = new LexEntryListModel($projectModel);
     $entryList->read();
     $hasExistingData = $entryList->count != 0;
     if (!$hasExistingData) {
         $projectModel->config->clearAllInputSystems();
         // save and clear input systems
         $savedInputSystems = $projectModel->inputSystems->getArrayCopy();
         $projectModel->inputSystems->exchangeArray(array());
     }
     $reader = new \XMLReader();
     $reader->open($liftFilePath);
     $this->liftDecoder = new LiftDecoder($projectModel);
     $this->stats = new LiftImportStats($entryList->count);
     $this->report = new ImportErrorReport();
     $this->liftImportNodeError = new LiftImportNodeError(LiftImportNodeError::FILE, basename($liftFilePath));
     $liftRangeDecoder = new LiftRangeDecoder($projectModel);
     $liftRangeFiles = array();
     // Keys: filenames. Values: parsed files.
     $liftRanges = array();
     // Keys: @id attributes of <range> elements. Values: parsed <range> elements.
     $liftFolderPath = dirname($liftFilePath);
     while ($reader->read()) {
         // Read LIFT ranges in the header of the LIFT file
         if ($reader->nodeType == \XMLReader::ELEMENT && $reader->localName == 'range') {
             $node = $reader->expand();
             $rangeId = $node->attributes->getNamedItem('id')->textContent;
             $rangeHref = $node->attributes->getNamedItem('href')->textContent;
             $hrefPath = parse_url($rangeHref, PHP_URL_PATH);
             $rangeFilename = basename($hrefPath);
             $rangeImportNodeError = new LiftRangeImportNodeError(LiftRangeImportNodeError::FILE, $rangeFilename);
             if (!array_key_exists($rangeFilename, $liftRangeFiles)) {
                 // Haven't parsed the .lift-ranges file yet. We'll assume it is alongside the .lift file.
                 $rangeFilePath = $liftFolderPath . "/" . $rangeFilename;
                 if (file_exists($rangeFilePath)) {
                     $sxeNode = simplexml_load_file($rangeFilePath);
                     $parsedRanges = $liftRangeDecoder->decode($sxeNode);
                     $liftRanges = array_merge($liftRanges, $parsedRanges);
                     $liftRangeFiles[] = $rangeFilename;
                 } else {
                     // Range file was NOT found in alongside the .lift file
                     $rangeImportNodeError->addRangeFileNotFound(basename($liftFilePath));
                 }
             }
             // pull out the referenced range
             if (isset($liftRanges[$rangeId])) {
                 $range = $liftRanges[$rangeId];
             } else {
                 $range = null;
                 if (file_exists($rangeFilePath)) {
                     // Range was NOT found in referenced .lift-ranges file after parsing it
                     $rangeImportNodeError->addRangeNotFound($rangeId);
                 }
             }
             // Range elements defined in LIFT file override any values defined in .lift-ranges file.
             if ($node->hasChildNodes()) {
                 $rangeNode = self::domNode_to_sxeNode($node);
                 $range = $liftRangeDecoder->readRange($rangeNode, $range);
                 $liftRanges[$rangeId] = $range;
             }
             if ($rangeImportNodeError->hasErrors()) {
                 $this->liftImportNodeError->addSubnodeError($rangeImportNodeError);
             }
         }
         // Read the custom 'fields' spec in the header of the LIFT file
         if ($reader->nodeType == \XMLReader::ELEMENT && $reader->localName == 'fields') {
             $isInFieldsSectionOfLift = true;
             $this->liftDecoder->liftFields = array();
             while ($isInFieldsSectionOfLift && $reader->read()) {
                 if ($reader->nodeType == \XMLReader::ELEMENT && $reader->localName == 'field') {
                     $node = $reader->expand();
                     $sxeNode = self::domNode_to_sxeNode($node);
                     $LiftFieldTag = (string) $sxeNode['tag'];
                     $liftField = array();
                     foreach ($sxeNode as $element) {
                         if ($element->getName() === 'form') {
                             $inputSystemTag = (string) $element['lang'];
                             $liftField[$inputSystemTag] = (string) $element->text;
                         }
                     }
                     $this->liftDecoder->liftFields[$LiftFieldTag] = $liftField;
                 } elseif ($reader->nodeType == \XMLReader::END_ELEMENT && $reader->localName == 'fields') {
                     $isInFieldsSectionOfLift = false;
                 }
             }
         }
         // Read an entry node
         if ($reader->nodeType == \XMLReader::ELEMENT && $reader->localName == 'entry') {
             $this->stats->importEntries++;
             $node = $reader->expand();
             $sxeNode = self::domNode_to_sxeNode($node);
             $guid = $reader->getAttribute('guid');
             $existingEntry = $entryList->searchEntriesFor('guid', $guid);
             if ($existingEntry) {
                 $entry = new LexEntryModel($projectModel, $existingEntry['id']);
                 $dateModified = $reader->getAttribute('dateModified');
                 if (self::differentModTime($dateModified, $entry->authorInfo->modifiedDate) || !$skipSameModTime) {
                     if ($mergeRule == LiftMergeRule::CREATE_DUPLICATES) {
                         $entry = new LexEntryModel($projectModel);
                         $this->readEntryWithErrorReport($sxeNode, $entry, $mergeRule);
                         $entry->guid = '';
                         $entry->write();
                         $this->stats->entriesDuplicated++;
                     } else {
                         if (isset($sxeNode->{'lexical-unit'})) {
                             $this->readEntryWithErrorReport($sxeNode, $entry, $mergeRule);
                             $entry->write();
                             $this->stats->entriesMerged++;
                         } elseif (isset($sxeNode->attributes()->dateDeleted) && $deleteMatchingEntry) {
                             LexEntryModel::remove($projectModel, $existingEntry['id']);
                             $this->stats->entriesDeleted++;
                         }
                     }
                 } else {
                     // skip because same mod time and skip enabled
                     if (!isset($sxeNode->{'lexical-unit'}) && isset($sxeNode->attributes()->dateDeleted) && $deleteMatchingEntry) {
                         LexEntryModel::remove($projectModel, $existingEntry['id']);
                         $this->stats->entriesDeleted++;
                     }
                 }
             } else {
                 if (isset($sxeNode->{'lexical-unit'})) {
                     $entry = new LexEntryModel($projectModel);
                     $this->readEntryWithErrorReport($sxeNode, $entry, $mergeRule);
                     $entry->write();
                     $this->stats->newEntries++;
                 }
             }
         }
     }
     $reader->close();
     // put back saved input systems if none found in the imported data
     if (!$hasExistingData && $projectModel->inputSystems->count() <= 0) {
         $projectModel->inputSystems->exchangeArray($savedInputSystems);
     }
     // add lift ranges
     if ($mergeRule != LiftMergeRule::IMPORT_LOSES) {
         foreach ($liftRanges as $liftRangeCode => $liftRange) {
             // add everything except semantic domains
             if (strpos($liftRangeCode, 'semantic-domain') === false) {
                 self::rangeToOptionList($projectModel, $liftRangeCode, LexiconConfigObj::flexOptionlistName($liftRangeCode), $liftRange);
             }
         }
     }
     $this->report->nodeErrors[] = $this->liftImportNodeError;
     if ($this->report->hasError()) {
         error_log($this->report->toString());
     }
     return $this;
 }
 /**
  * @param string $projectId
  * @param string $missingInfo - if empty, returns all entries.
  *          if matches one of LexConfig constants (e.g. POS, DEFINITION, etc), then return a subset of entries that have one or more senses missing the specified field
  * @return LexEntryListModel
  */
 public static function listEntries($projectId, $missingInfo = '')
 {
     $project = new LexProjectModel($projectId);
     $lexEntries = new LexEntryListModel($project);
     $lexEntries->readForDto($missingInfo);
     return $lexEntries;
 }
 public function testLiftImportMerge_ZipFileWithDir_CorrectValues()
 {
     $zipFilePath = self::$environ->copyTestUploadFile(TestPhpPath . 'common/TestLexProjectWithDir.zip');
     $project = self::$environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $importer = LiftImport::get()->importZip($zipFilePath, $project);
     $entryList = new LexEntryListModel($project);
     $entryList->read();
     $entries = $entryList->entries;
     $this->assertEquals(2, $entryList->count);
     $entriesByGuid = self::$environ->indexItemsBy($entries, 'guid');
     $entry0 = $entriesByGuid['dd15cbc4-9085-4d66-af3d-8428f078a7da'];
     $entry1 = $entriesByGuid['05473cb0-4165-4923-8d81-02f8b8ed3f26'];
     $this->assertEquals('dd15cbc4-9085-4d66-af3d-8428f078a7da', $entry0['guid']);
     $this->assertEquals('chùuchìi mǔu krɔ̂ɔp', $entry0['lexeme']['th-fonipa']['value']);
     $this->assertEquals('ฉู่ฉี่หมูกรอบ', $entry0['lexeme']['th']['value']);
     $this->assertCount(1, $entry0['senses']);
     $this->assertEquals('incorrect definition', $entry0['senses'][0]['definition']['en']['value']);
     $this->assertEquals('incorrect gloss', $entry0['senses'][0]['gloss']['en']['value']);
     $this->assertEquals('th incorrect gloss', $entry0['senses'][0]['gloss']['th']['value']);
     $this->assertEquals('Adjective', $entry0['senses'][0]['partOfSpeech']['value']);
     $this->assertEquals('5.2', $entry0['senses'][0]['semanticDomain']['values'][0]);
     $this->assertEquals('1', $entry0['senses'][0]['semanticDomain']['values'][1]);
     $this->assertEquals('sentence 1', $entry0['senses'][0]['examples'][0]['sentence']['th-fonipa']['value']);
     $this->assertEquals('translation 1', $entry0['senses'][0]['examples'][0]['translation']['en']['value']);
     $this->assertEquals('sentence 2', $entry0['senses'][0]['examples'][1]['sentence']['th-fonipa']['value']);
     $this->assertEquals('translation 2', $entry0['senses'][0]['examples'][1]['translation']['en']['value']);
     $this->assertEquals('05473cb0-4165-4923-8d81-02f8b8ed3f26', $entry1['guid']);
     $this->assertEquals('khâaw kài thɔ̀ɔt', $entry1['lexeme']['th-fonipa']['value']);
     $this->assertEquals('ข้าวไก่ทอด', $entry1['lexeme']['th']['value']);
     $this->assertEquals(false, $importer->getReport()->hasError());
 }
 public function testLiftImportMerge_MultiPara_ParagraphMarkerFound()
 {
     $liftFilePath = self::$environ->createTestLiftFile(self::liftOneEntryMultiParaV0_13, 'LiftOneEntryMultiParaV0_13.lift');
     $project = self::$environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $mergeRule = LiftMergeRule::IMPORT_WINS;
     $skipSameModTime = false;
     LiftImport::get()->merge($liftFilePath, $project, $mergeRule, $skipSameModTime);
     $entryList = new LexEntryListModel($project);
     $entryList->read();
     $entry0 = $entryList->entries[0];
     $this->assertEquals(1, $entryList->count);
     $this->assertArrayHasKey('customField_entry_Cust_MultiPara', $entry0['customFields'], 'custom field MultiPara exists');
     $this->assertEquals('First paragraph with <span lang="th">ไทย</span>', $entry0['customFields']['customField_entry_Cust_MultiPara']['paragraphs'][0]['content'], 'custom field MultiPara has paragraphs separated into paragraph 1 and native language spans removed');
     $this->assertEquals('Second Paragraph', $entry0['customFields']['customField_entry_Cust_MultiPara']['paragraphs'][1]['content'], 'custom field MultiPara has paragraphs separated into paragraph 2 and native language spans removed');
 }
 public function testLiftImportMerge_FlexAllFields_HasAllFields()
 {
     $liftFilePath = self::$environ->createTestLiftFile(self::liftAllFlexFields, 'LiftAllFlexFields.lift');
     $project = self::$environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $mergeRule = LiftMergeRule::IMPORT_WINS;
     $skipSameModTime = false;
     LiftImport::get()->merge($liftFilePath, $project, $mergeRule, $skipSameModTime);
     $entryList = new LexEntryListModel($project);
     $entryList->read();
     $entries = $entryList->entries;
     $this->assertEquals(2, $entryList->count);
     $entriesByGuid = self::$environ->indexItemsBy($entries, 'guid');
     $entry0 = new LexEntryModel($project, $entriesByGuid['0a18bb95-0eb2-422e-bf7e-c1fd90274670']['id']);
     new LexEntryModel($project, $entriesByGuid['dc4106ac-13fd-4ae0-a32b-b737f413d515']['id']);
     $this->assertEquals('0a18bb95-0eb2-422e-bf7e-c1fd90274670', $entry0->guid);
     $this->assertEquals('คาม', $entry0->lexeme['th']);
     $this->assertEquals('คาม', $entry0->citationForm['th']);
     $this->assertEquals('คาม', $entry0->etymology['th']);
     $this->assertEquals('A Etymology', $entry0->etymology['en']);
     $this->assertEquals('A Etymology Gloss', $entry0->etymologyGloss['en']);
     $this->assertEquals('A Etymology Comment', $entry0->etymologyComment['en']);
     $this->assertEquals('คาม', $entry0->pronunciation['th']);
     $this->assertEquals('stem', $entry0->morphologyType);
     $this->assertEquals('A Literal Meaning', $entry0->literalMeaning['en']);
     /* @var $sense00 LexSense */
     $sense00 = $entry0->senses[0];
     $this->assertEquals('Noun', $sense00->partOfSpeech->value);
     $this->assertEquals('A Word', $sense00->gloss['en']->value);
     $this->assertEquals('A Word Defn', $sense00->definition['en']->value);
     $this->assertEquals(LexMultiValue::createFromArray(['9.1.3.1']), $sense00->semanticDomain);
     $this->assertEquals(LexMultiValue::createFromArray(['901']), $sense00->anthropologyCategories);
     $this->assertEquals(LexMultiValue::createFromArray(['applied linguistics']), $sense00->academicDomains);
     $this->assertEquals(new LexValue('primary'), $sense00->senseType);
     $this->assertEquals(LexMultiValue::createFromArray(['Tentative']), $sense00->status);
     $this->assertEquals(LexMultiValue::createFromArray(['colloquial']), $sense00->usages);
     $expected = new LexPicture('Desert.jpg', $sense00->pictures[0]->guid);
     $expected->caption['th'] = 'รูป';
     $expected->caption['en'] = 'image';
     $expected->caption['fr'] = 'photo';
     $this->assertEquals($expected, $sense00->pictures[0]);
     /* @var $example000 LexExample */
     $example000 = $sense00->examples[0];
     $this->assertEquals('ใหท่ มี', $example000->sentence['th']);
     $this->assertEquals('A Translation', $example000->translation['en']->value);
 }
 public function testImportProjectZip_7zFile_StatsOkAndCustomFieldsImported()
 {
     $project = $this->environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $projectId = $project->id->asString();
     $fileName = 'TestLangProj.7z';
     // Ken Zook's test data
     $tmpFilePath = $this->environ->uploadFile(TestPath . "common/{$fileName}", $fileName);
     $userId = $this->environ->createUser('bob', 'bob', '*****@*****.**');
     $project->addUser($userId, LexiconRoles::OBSERVER);
     $project->config->userViews[$userId] = clone $project->config->roleViews[LexiconRoles::OBSERVER];
     $project->write();
     $this->assertFalse($project->config->entry->fieldOrder->array_search('customField_entry_Cust_Single_Line_All'), "custom field entry config doesn't yet exist");
     $this->assertFalse(array_key_exists('customField_entry_Cust_Single_Line_All', $project->config->entry->fields), "custom field entry config doesn't yet exist");
     $this->assertFalse(array_key_exists('customField_entry_Cust_Single_Line_All', $project->config->roleViews[LexiconRoles::OBSERVER]->fields), "custom field roleView config doesn't yet exist");
     $this->assertFalse(array_key_exists('customField_entry_Cust_Single_Line_All', $project->config->roleViews[LexiconRoles::MANAGER]->fields), "custom field roleView config doesn't yet exist");
     $this->assertFalse(array_key_exists('customField_entry_Cust_Single_Line_All', $project->config->userViews[$userId]->fields), "custom field userView config doesn't yet exist");
     $response = LexUploadCommands::importProjectZip($projectId, 'import-zip', $tmpFilePath);
     $project->read($project->id->asString());
     $filePath = $project->getAssetsFolderPath() . '/' . $response->data->fileName;
     $projectSlug = $project->databaseName();
     $entryList = new LexEntryListModel($project);
     $entryList->read();
     $entries = $entryList->entries;
     $entriesByGuid = $this->environ->indexItemsBy($entries, 'guid');
     $entryA = $entriesByGuid['05c54cf0-4e5a-4bf2-99f8-ec787e4113ac'];
     $entryB = $entriesByGuid['1a705846-a814-4289-8594-4b874faca6cc'];
     $entryBSensesByLiftId = $this->environ->indexItemsBy($entryB['senses'], 'liftId');
     $entryBSenseA = $entryBSensesByLiftId['eea9c29f-244f-4891-81db-c8274cd61f0c'];
     $optionListList = new LexOptionListListModel($project);
     $optionListList->read();
     $optionListByCodes = $this->environ->indexItemsBy($optionListList->entries, 'code');
     // stats OK?
     $this->assertTrue($response->result, 'Import should succeed');
     $this->assertPattern("/lexicon\\/{$projectSlug}/", $response->data->path, 'Uploaded zip file path should be in the right location');
     $this->assertEqual($fileName, $response->data->fileName, 'Uploaded zip fileName should have the original fileName');
     $this->assertTrue(file_exists($filePath), 'Uploaded zip file should exist');
     $this->assertEqual($response->data->stats->existingEntries, 0);
     $this->assertEqual($response->data->stats->importEntries, 64);
     $this->assertEqual($response->data->stats->newEntries, 64);
     $this->assertEqual($response->data->stats->entriesMerged, 0);
     $this->assertEqual($response->data->stats->entriesDuplicated, 0);
     $this->assertEqual($response->data->stats->entriesDeleted, 0);
     // custom fields imported?
     $this->assertEqual($entryList->count, 64);
     $this->assertEqual($optionListList->count, 24);
     $this->assertTrue(array_key_exists('grammatical-info', $optionListByCodes));
     $this->assertFalse(array_key_exists('semantic-domain-ddp4', $optionListByCodes));
     $this->assertEqual($entryA['lexeme']['qaa-fonipa-x-kal']['value'], '-kes');
     $this->assertEqual($entryA['customFields']['customField_entry_Cust_Single_Line_All']['en']['value'], '635459584141806142kes.wav');
     $this->assertTrue($project->config->entry->fieldOrder->array_search('customField_entry_Cust_Single_Line_All'), "custom field entry config exists");
     $this->assertTrue(array_key_exists('customField_entry_Cust_Single_Line_All', $project->config->entry->fields), "custom field entry config exists");
     $this->assertEqual($project->config->entry->fields['customField_entry_Cust_Single_Line_All']->label, 'Cust Single Line All');
     $this->assertEqual($project->config->entry->fields['customField_entry_Cust_Single_Line_All']->type, 'multitext');
     $this->assertTrue($project->config->entry->fields['customField_entry_Cust_Single_Line_All']->inputSystems->array_search('en'));
     $this->assertTrue(array_key_exists('customField_entry_Cust_Single_Line_All', $project->config->roleViews[LexiconRoles::OBSERVER]->fields), "custom field roleView config exists");
     $this->assertTrue(array_key_exists('customField_entry_Cust_Single_Line_All', $project->config->roleViews[LexiconRoles::MANAGER]->fields), "custom field roleView config exists");
     $this->assertTrue($project->config->roleViews[LexiconRoles::OBSERVER]->fields['customField_entry_Cust_Single_Line_All']->show);
     $this->assertTrue($project->config->roleViews[LexiconRoles::MANAGER]->fields['customField_entry_Cust_Single_Line_All']->show);
     $this->assertTrue(array_key_exists('customField_entry_Cust_Single_Line_All', $project->config->userViews[$userId]->fields), "custom field userView config doesn't yet exist");
     $this->assertTrue($project->config->userViews[$userId]->fields['customField_entry_Cust_Single_Line_All']->show);
     $this->assertEqual($entryB['lexeme']['qaa-fonipa-x-kal']['value'], 'zitʰɛstmen');
     $this->assertEqual($entryB['customFields']['customField_entry_Cust_Single_ListRef']['value'], 'comparative linguistics');
     $this->assertEqual(count($entryBSenseA['customFields']['customField_senses_Cust_Multi_ListRef']['values']), 2);
     $this->assertEqual($entryBSenseA['customFields']['customField_senses_Cust_Multi_ListRef']['values'][0], 'First Custom Item');
     $this->assertEqual($entryBSenseA['customFields']['customField_senses_Cust_Multi_ListRef']['values'][1], 'Second Custom Item');
     $this->assertEqual($entryBSenseA['examples'][0]['customFields']['customField_examples_Cust_Example']['qaa-x-kal']['value'], 'Custom example');
     /*
     echo '<pre style="height:500px; overflow:auto">';
     echo $response->data->importErrors;
     echo '</pre>';
     */
 }
Ejemplo n.º 7
0
 public static function encode($projectId, $userId, $lastFetchTime = null, $offset = 0)
 {
     $data = array();
     $project = new LexiconProjectModel($projectId);
     if ($lastFetchTime) {
         $entriesModel = new LexEntryListModel($project, $lastFetchTime);
         $entriesModel->readForDto();
         $commentsModel = new LexCommentListModel($project, $lastFetchTime);
         $commentsModel->readAsModels();
     } else {
         $entriesModel = new LexEntryListModel($project, null, self::MAX_ENTRIES_PER_REQUEST, $offset);
         $entriesModel->readForDto();
         $commentsModel = new LexCommentListModel($project, null, self::MAX_ENTRIES_PER_REQUEST, $offset);
         $commentsModel->readAsModels();
         $data['itemTotalCount'] = $entriesModel->totalCount > $commentsModel->totalCount ? $entriesModel->totalCount : $commentsModel->totalCount;
         $data['itemCount'] = $entriesModel->count > $commentsModel->count ? $entriesModel->count : $commentsModel->count;
         $data['offset'] = $offset;
     }
     $entries = $entriesModel->entries;
     $encodedComments = LexDbeDtoCommentsEncoder::encode($commentsModel);
     $data['comments'] = $encodedComments['entries'];
     /*
     $commentsModel->read();
     $data['comments'] = $commentsModel->entries;
     */
     $votes = new UserGenericVoteModel($userId, $projectId, 'lexCommentPlusOne');
     $votesDto = array();
     foreach ($votes->votes as $vote) {
         $votesDto[$vote->ref->id] = true;
     }
     $data['commentsUserPlusOne'] = $votesDto;
     if (!is_null($lastFetchTime)) {
         $deletedEntriesModel = new LexDeletedEntryListModel($project, $lastFetchTime);
         $deletedEntriesModel->read();
         $data['deletedEntryIds'] = array_map(function ($e) {
             return $e['id'];
         }, $deletedEntriesModel->entries);
         $deletedCommentsModel = new LexDeletedCommentListModel($project, $lastFetchTime);
         $deletedCommentsModel->read();
         $data['deletedCommentIds'] = array_map(function ($c) {
             return $c['id'];
         }, $deletedCommentsModel->entries);
     }
     $lexemeInputSystems = $project->config->entry->fields[LexiconConfigObj::LEXEME]->inputSystems;
     usort($entries, function ($a, $b) use($lexemeInputSystems) {
         $lexeme1 = $a[LexiconConfigObj::LEXEME];
         $lexeme1Value = '';
         foreach ($lexemeInputSystems as $ws) {
             if (array_key_exists($ws, $lexeme1) && $lexeme1[$ws]['value'] != '') {
                 $lexeme1Value = $lexeme1[$ws]['value'];
                 // '\P{xx} matches all characters without the Unicode property XX. L is the Unicode property "letter".
                 $lexeme1Value = preg_replace('/^\\P{L}+/', '', $lexeme1Value);
                 // Strip non-letter characters from front of word for sorting
                 break;
             }
         }
         $lexeme2 = $b[LexiconConfigObj::LEXEME];
         $lexeme2Value = '';
         foreach ($lexemeInputSystems as $ws) {
             if (array_key_exists($ws, $lexeme2) && $lexeme2[$ws]['value'] != '') {
                 $lexeme2Value = $lexeme2[$ws]['value'];
                 $lexeme2Value = preg_replace('/^\\P{L}+/', '', $lexeme2Value);
                 // Strip non-letter characters from front of word for sorting
                 break;
             }
         }
         return strtolower($lexeme1Value) > strtolower($lexeme2Value) ? 1 : -1;
     });
     $data['entries'] = $entries;
     $data['timeOnServer'] = time();
     // for offline syncing
     return $data;
 }
 public function testLiftImportMerge_ZipFileWithDir_CorrectValues()
 {
     $zipFilePath = $this->environ->copyTestUploadFile(TestPath . 'common/TestLexProjectWithDir.zip');
     $project = $this->environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $importer = LiftImport::get()->importZip($zipFilePath, $project);
     $entryList = new LexEntryListModel($project);
     $entryList->read();
     $entries = $entryList->entries;
     $this->assertEqual($entryList->count, 2);
     $entriesByGuid = $this->environ->indexItemsBy($entries, 'guid');
     $entry0 = $entriesByGuid['dd15cbc4-9085-4d66-af3d-8428f078a7da'];
     $entry1 = $entriesByGuid['05473cb0-4165-4923-8d81-02f8b8ed3f26'];
     $this->assertEqual($entry0['guid'], "dd15cbc4-9085-4d66-af3d-8428f078a7da");
     $this->assertEqual($entry0['lexeme']['th-fonipa']['value'], "chùuchìi mǔu krɔ̂ɔp");
     $this->assertEqual($entry0['lexeme']['th']['value'], "ฉู่ฉี่หมูกรอบ");
     $this->assertEqual(count($entry0['senses']), 1);
     $this->assertEqual($entry0['senses'][0]['definition']['en']['value'], "incorrect definition");
     $this->assertEqual($entry0['senses'][0]['gloss']['en']['value'], "incorrect gloss");
     $this->assertEqual($entry0['senses'][0]['gloss']['th']['value'], "th incorrect gloss");
     $this->assertEqual($entry0['senses'][0]['partOfSpeech']['value'], "Adjective");
     $this->assertEqual($entry0['senses'][0]['semanticDomain']['values'][0], "5.2 Food");
     $this->assertEqual($entry0['senses'][0]['semanticDomain']['values'][1], "1 Universe, creation");
     $this->assertEqual($entry0['senses'][0]['examples'][0]['sentence']['th-fonipa']['value'], "sentence 1");
     $this->assertEqual($entry0['senses'][0]['examples'][0]['translation']['en']['value'], "translation 1");
     $this->assertEqual($entry0['senses'][0]['examples'][1]['sentence']['th-fonipa']['value'], "sentence 2");
     $this->assertEqual($entry0['senses'][0]['examples'][1]['translation']['en']['value'], "translation 2");
     $this->assertEqual($entry1['guid'], "05473cb0-4165-4923-8d81-02f8b8ed3f26");
     $this->assertEqual($entry1['lexeme']['th-fonipa']['value'], "khâaw kài thɔ̀ɔt");
     $this->assertEqual($entry1['lexeme']['th']['value'], "ข้าวไก่ทอด");
     $this->assertFalse($importer->getReport()->hasError());
 }
Ejemplo n.º 9
0
 public function testLiftImportMerge_MultiPara_ParagraphMarkerFound()
 {
     $liftFilePath = $this->environ->createTestLiftFile(self::liftOneEntryMultiParaV0_13, 'LiftOneEntryMultiParaV0_13.lift');
     $project = $this->environ->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $mergeRule = LiftMergeRule::IMPORT_WINS;
     $skipSameModTime = false;
     $importer = LiftImport::get()->merge($liftFilePath, $project, $mergeRule, $skipSameModTime);
     $entryList = new LexEntryListModel($project);
     $entryList->read();
     $entry0 = $entryList->entries[0];
     $this->assertEqual($entryList->count, 1);
     $this->assertTrue(array_key_exists('customField_entry_Cust_MultiPara', $entry0['customFields']), 'custom field MultiPara exists');
     $this->assertEqual($entry0['customFields']['customField_entry_Cust_MultiPara']['en']['value'], '<p>First paragraph with <span lang="th">ไทย</span></p><p>Second Paragraph</p>', 'custom field MultiPara has paragraph separator character U+2029 replaced by paragraph markup and native language spans removed');
 }