/**
  * Analyze a lexicon project and migrate the semantic domain keys in the senses
  * @param ProjectModelForUseWithSemanticDomainMigration $project
  * @param string $projectId
  * @param string $testMode
  * @param string $message
  */
 private function analyzeProject($project, $projectId, $testMode, &$message)
 {
     $entryModifiedCount = 0;
     $entryList = LexEntryCommands::listEntries($projectId);
     foreach ($entryList->entries as $entryListItem) {
         $entry = new LexEntryModel($project, $entryListItem['id']);
         $entryModified = false;
         if ($entry->hasSenses()) {
             /** @var LexSense $sense */
             foreach ($entry->senses as $sense) {
                 $this->migrateSemDomKey($sense, $project->projectName, $message, $entryModified);
             }
         }
         if ($entryModified) {
             $entryModifiedCount++;
             if (!$testMode) {
                 $entry->write();
             }
         }
     }
     if (!$testMode) {
         $project->hasMigratedSemanticDomainKeys = true;
         $project->write();
     }
     if ($entryModifiedCount > 0) {
         print "{$entryModifiedCount} entries with semantic domains were migrated\n";
     }
 }
 /**
  * Analyze a lexicon project and create Sense, Example and Picture guids. Remove id from Sense and Example
  * @param LexProjectModelForUseWithSenseGuidMigration $project
  * @param string $projectId
  * @param string $testMode
  */
 private static function analyzeProject($project, $projectId, $testMode)
 {
     $entryModifiedCount = 0;
     $exampleModifiedCount = 0;
     $pictureModifiedCount = 0;
     $entryList = LexEntryCommands::listEntries($projectId);
     foreach ($entryList->entries as $entryListItem) {
         $entry = new LexEntryModel($project, $entryListItem['id']);
         $entryModified = false;
         if ($entry->hasSenses()) {
             /** @var LexSense $sense */
             foreach ($entry->senses as $sense) {
                 self::createSenseGuids($sense, $entryModified, $exampleModifiedCount, $pictureModifiedCount);
             }
             if ($entryModified) {
                 $entryModifiedCount++;
             }
             if (!$testMode) {
                 $entry->write();
             }
         }
     }
     if (!$testMode) {
         $project->hasHadSenseGuidsMigrated = true;
         $project->write();
     }
     print "{$exampleModifiedCount} example and {$pictureModifiedCount} picture guids created.\n";
     print "{$entryModifiedCount} of {$entryList->count} entries had sense guids created.\n";
 }
 /**
  * Analyze a lexicon project and create Entry guids.
  * @param LexProjectModelForEntryGuidMigration $project
  * @param string $testMode
  * @internal param string $projectId
  */
 private static function analyzeProject($project, $testMode)
 {
     $entryModifiedCount = 0;
     $entryList = new LexAllEntryListModel($project);
     $entryList->read();
     foreach ($entryList->entries as $entryListItem) {
         $entry = new LexEntryModel($project, $entryListItem['id']);
         if (!isset($entry->guid) || !$entry->guid || !Guid::isValid($entry->guid)) {
             $entry->guid = Guid::create();
             $entryModifiedCount++;
             if (!$testMode) {
                 $entry->write();
             }
         }
     }
     if (!$testMode) {
         $project->hasHadEntryGuidMigrated = true;
         $project->write();
     }
     print "{$entryModifiedCount} of {$entryList->count} entries had guids created.\n";
 }
 /**
  * Upload an audio file
  *
  * @param string $projectId
  * @param string $mediaType
  * @param string $tmpFilePath
  * @throws \Exception
  * @return \Api\Model\Shared\Command\UploadResponse
  */
 public static function uploadAudioFile($projectId, $mediaType, $tmpFilePath)
 {
     if ($mediaType != 'entry-audio') {
         throw new \Exception("Unsupported upload type.");
     }
     if (!$tmpFilePath) {
         throw new \Exception("Upload controller did not move the uploaded file.");
     }
     $entryId = $_POST['entryId'];
     $file = $_FILES['file'];
     $fileName = $file['name'];
     $finfo = finfo_open(FILEINFO_MIME_TYPE);
     $fileType = finfo_file($finfo, $tmpFilePath);
     finfo_close($finfo);
     $fileName = FileUtilities::replaceSpecialCharacters($fileName);
     $fileExt = false === ($pos = strrpos($fileName, '.')) ? '' : substr($fileName, $pos);
     $allowedTypes = array("audio/mpeg", "audio/mp3");
     $allowedExtensions = array(".mp3");
     $response = new UploadResponse();
     if (in_array(strtolower($fileType), $allowedTypes) && in_array(strtolower($fileExt), $allowedExtensions)) {
         // make the folders if they don't exist
         $project = new LfProjectModel($projectId);
         $folderPath = $project->getAssetsFolderPath() . '/audio';
         FileUtilities::createAllFolders($folderPath);
         // cleanup previous files of any allowed extension
         self::cleanupFiles($folderPath, $entryId, $allowedExtensions);
         // move uploaded file from tmp location to assets
         $filePath = self::mediaFilePath($folderPath, $entryId, $fileName);
         $moveOk = copy($tmpFilePath, $filePath);
         @unlink($tmpFilePath);
         // update database with file location
         $entry = new LexEntryModel($project, $entryId);
         $entry->audioFileName = '';
         if ($moveOk) {
             $entry->audioFileName = $fileName;
         }
         $entry->write();
         // construct server response
         if ($moveOk && $tmpFilePath) {
             $data = new MediaResult();
             $data->path = $project->getAssetsRelativePath();
             $data->fileName = $fileName;
             $response->result = true;
         } else {
             $data = new ErrorResult();
             $data->errorType = 'UserMessage';
             $data->errorMessage = "{$fileName} could not be saved to the right location. Contact your Site Administrator.";
             $response->result = false;
         }
     } else {
         $allowedExtensionsStr = implode(", ", $allowedExtensions);
         $data = new ErrorResult();
         $data->errorType = 'UserMessage';
         if (count($allowedExtensions) < 1) {
             $data->errorMessage = "{$fileName} is not an allowed audio file. No audio file formats are currently enabled, contact your Site Administrator.";
         } elseif (count($allowedExtensions) == 1) {
             $data->errorMessage = "{$fileName} is not an allowed audio file. Ensure the file is a {$allowedExtensionsStr}.";
         } else {
             $data->errorMessage = "{$fileName} is not an allowed audio file. Ensure the file is one of the following types: {$allowedExtensionsStr}.";
         }
         $response->result = false;
     }
     $response->data = $data;
     return $response;
 }
 public static function removeEntry($projectId, $entryId, $userId)
 {
     $project = new ProjectModel($projectId);
     $entry = new LexEntryModel($project, $entryId);
     $entry->isDeleted = true;
     $entry->write();
     ActivityCommands::deleteEntry($project, $userId, $entryId);
     return true;
 }
 public function testListEntries_someEntriesWithNoDefinition_Ok()
 {
     $e = new LexiconMongoTestEnvironment();
     $e->clean();
     $project = $e->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $projectId = $project->id->asString();
     for ($i = 0; $i < 10; $i++) {
         $entry = new LexEntryModel($project);
         $entry->lexeme->form('th', 'Apfel' . $i);
         if ($i % 2 == 0) {
             $sense = new Sense();
             $entry->senses[] = $sense;
         }
         if ($i % 3 == 0) {
             $sense = new Sense();
             $sense->definition->form('en', 'apple');
             $sense->partOfSpeech->value = 'noun';
             $entry->senses[] = $sense;
         }
         $entry->write();
     }
     $result = LexEntryCommands::listEntries($projectId);
     $this->assertEqual($result->entries[0]['lexeme']['th']['value'], 'Apfel0');
     $this->assertTrue(!array_key_exists('definition', $result->entries[0]['senses'][0]));
     $this->assertEqual($result->entries[3]['senses'][0]['definition']['en']['value'], 'apple');
 }
 function testReadEntry_NoComments_ReadBackOk()
 {
     $e = new LexiconMongoTestEnvironment();
     $e->clean();
     $project = $e->createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE);
     $projectId = $project->id->asString();
     $entry = new LexEntryModel($project);
     $entry->lexeme->form('th', 'apple');
     $sense = new Sense();
     $sense->definition->form('en', 'red fruit');
     $sense->partOfSpeech = new LexiconField('noun');
     $example = new Example();
     $example->sentence->form('th', 'example1');
     $example->translation->form('en', 'trans1');
     $sense->examples[] = $example;
     $entry->senses[] = $sense;
     $entryId = $entry->write();
     $newEntry = LexEntryCommands::readEntry($projectId, $entryId);
     $this->assertEqual($newEntry['lexeme']['th']['value'], 'apple');
     $this->assertEqual($newEntry['senses'][0]['definition']['en']['value'], 'red fruit');
     $this->assertEqual($newEntry['senses'][0]['partOfSpeech']['value'], 'noun');
     $this->assertEqual($newEntry['senses'][0]['examples'][0]['sentence']['th']['value'], 'example1');
     $this->assertEqual($newEntry['senses'][0]['examples'][0]['translation']['en']['value'], 'trans1');
 }