/**
  * @param string $projectId
  * @param string $userId
  * @return array - the DTO array
  */
 public static function encode($projectId, $userId)
 {
     $data = array();
     $user = new UserProfileModel($userId);
     $project = new LexProjectModel($projectId);
     $config = JsonEncoder::encode($project->config);
     $config['inputSystems'] = JsonEncoder::encode($project->inputSystems);
     $data['config'] = $config;
     // comment out at the moment until a refactor can be done that is more efficient (language data in the database?)
     /*
     $interfaceLanguageCode = $project->interfaceLanguageCode;
     if ($user->interfaceLanguageCode) {
         $interfaceLanguageCode = $user->interfaceLanguageCode;
     }
     $options = self::getInterfaceLanguages(APPPATH . 'angular-app/languageforge/lexicon/lang');
     asort($options);    // sort by language name
     $selectInterfaceLanguages = array(
         'optionsOrder' => array_keys($options),
         'options' => $options
     );
     $data['interfaceConfig'] = array('userLanguageCode' => $interfaceLanguageCode);
     $data['interfaceConfig']['selectLanguages'] = $selectInterfaceLanguages;
     */
     // a stand in for the code above
     $data['interfaceConfig'] = array('userLanguageCode' => 'en', 'selectLanguages' => array('options' => array('en' => 'English'), 'optionsOrder' => array('en')));
     $optionlistListModel = new LexOptionListListModel($project);
     $optionlistListModel->read();
     $data['optionlists'] = $optionlistListModel->entries;
     if ($project->hasSendReceive()) {
         $data['sendReceive'] = array();
         $data['sendReceive']['status'] = SendReceiveCommands::getProjectStatus($projectId);
     }
     return $data;
 }
 public function testCreateProject_NewSRProject_SRProjectWithLinks()
 {
     self::$environ = new LexiconMongoTestEnvironment();
     self::$environ->clean();
     $user1Id = self::$environ->createUser("user1name", "User1 Name", "*****@*****.**");
     $user1 = new UserModel($user1Id);
     $srProject = array('identifier' => 'srIdentifier', 'name' => 'srName', 'repository' => 'http://public.languagedepot.org', 'role' => 'manager');
     $projectId = ProjectCommands::createProject(SF_TESTPROJECT, SF_TESTPROJECTCODE, LexProjectModel::LEXICON_APP, $user1->id->asString(), self::$environ->website, $srProject);
     $project = new LexProjectModel($projectId);
     $assetImagePath = $project->getImageFolderPath();
     $assetAudioPath = $project->getAudioFolderPath();
     $this->assertTrue($project->hasSendReceive());
     $this->assertTrue(is_link($assetImagePath));
     $this->assertTrue(is_link($assetAudioPath));
     $projectWorkPath = $project->getSendReceiveWorkFolder();
     FileUtilities::removeFolderAndAllContents($project->getAssetsFolderPath());
     FileUtilities::removeFolderAndAllContents($projectWorkPath);
 }
 /**
  * @param string $projectId
  * @param string $userId
  * @param null $lastFetchTime
  * @param int $offset
  * @throws \Exception
  * @return array
  */
 public static function encode($projectId, $userId, $lastFetchTime = null, $offset = 0)
 {
     $data = array();
     $project = new LexProjectModel($projectId);
     if ($lastFetchTime) {
         $entriesModel = new LexEntryListModel($project, $lastFetchTime);
         $entriesModel->readAsModels();
         $commentsModel = new LexCommentListModel($project, $lastFetchTime);
         $commentsModel->readAsModels();
     } else {
         $entriesModel = new LexEntryListModel($project, null, self::MAX_ENTRIES_PER_REQUEST, $offset);
         $entriesModel->readAsModels();
         $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 = LexDbeDtoEntriesEncoder::encode($entriesModel);
     $entries = $entries['entries'];
     $encodedComments = LexDbeDtoCommentsEncoder::encode($commentsModel);
     $data['comments'] = $encodedComments['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[LexConfig::LEXEME]->inputSystems;
     usort($entries, function ($a, $b) use($lexemeInputSystems) {
         $lexeme1Value = '';
         if (array_key_exists(LexConfig::LEXEME, $a)) {
             $lexeme1 = $a[LexConfig::LEXEME];
             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;
                 }
             }
         }
         $lexeme2Value = '';
         if (array_key_exists(LexConfig::LEXEME, $b)) {
             $lexeme2 = $b[LexConfig::LEXEME];
             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
     if ($project->hasSendReceive()) {
         $data['sendReceive'] = array();
         $data['sendReceive']['status'] = SendReceiveCommands::getProjectStatus($projectId);
     }
     return $data;
 }
 /**
  * @param string $projectCode
  * @param string $statePath
  * @param string $sendQueuePath
  * @param string $pidFilePath
  * @param string $command
  * @return bool true if notification file is created (or already exists) and LFMerge started, false otherwise
  * @throws \Exception
  */
 public static function notificationSendRequest($projectCode, $statePath = null, $sendQueuePath = null, $pidFilePath = null, $command = null)
 {
     $project = new LexProjectModel();
     if (!$project->readByProperty('projectCode', $projectCode)) {
         return false;
     }
     if (!$project->hasSendReceive()) {
         return false;
     }
     $status = self::getProjectStatus($project->id->asString(), $statePath);
     if (!$status || !array_key_exists('uncommittedEditCount', $status)) {
         return false;
     }
     if ($status['uncommittedEditCount'] <= 0) {
         return false;
     }
     if (is_null($sendQueuePath)) {
         $sendQueuePath = self::getLFMergePaths()->sendQueuePath;
     }
     $notificationFilePath = $sendQueuePath . '/' . $project->projectCode . '.notification';
     if (!file_exists($notificationFilePath) || !is_file($notificationFilePath)) {
         FileUtilities::createAllFolders($sendQueuePath);
         if (file_put_contents($notificationFilePath, '') === false) {
             throw new \Exception('Cannot write to Send/Receive Send Queue. Contact the website administrator.');
         }
     }
     return self::startLFMergeIfRequired($project->id->asString(), $pidFilePath, $command);
 }