/**
  * @param UniversalTimestamp $timestamp
  * @return null|\MongoDate
  */
 public function convertToDatabaseValue($timestamp)
 {
     if (extension_loaded('mongo')) {
         return null !== $timestamp ? $timestamp->asMongoDate() : null;
     } elseif (extension_loaded('mongodb')) {
         return null !== $timestamp ? $timestamp->asMongodbUTCDateTime() : null;
     } else {
         throw new \RuntimeException('Missing MongoDB extension');
     }
 }
 /**
  * Updates the given LexEntry in $projectId
  * @param string $projectId
  * @param array $params
  * @param string $userId
  * @param string $mergeQueuePath
  * @param string $pidFilePath
  * @param string $command
  * @return bool|array<encoded LexEntryModel> if the project is syncing (or on hold) return false (no save)FixSe
  */
 public static function updateEntry($projectId, $params, $userId, $mergeQueuePath = null, $pidFilePath = null, $command = null)
 {
     CodeGuard::checkTypeAndThrow($params, 'array');
     $project = new LexProjectModel($projectId);
     ProjectCommands::checkIfArchivedAndThrow($project);
     $now = UniversalTimestamp::now();
     if (array_key_exists('id', $params) && $params['id'] != '') {
         $entry = new LexEntryModel($project, $params['id']);
         $action = 'update';
     } else {
         $entry = new LexEntryModel($project);
         $entry->authorInfo->createdByUserRef->id = $userId;
         $entry->authorInfo->createdDate = $now;
         $entry->guid = Guid::create();
         $action = 'create';
         // TODO: Consider adding more specific activity entry: which fields were modified? 2014-09-03 RM
         // E.g., "User _____ updated entry _____ by adding a new sense with definition ______"
     }
     $entry->authorInfo->modifiedDate = $now;
     $entry->authorInfo->modifiedByUserRef->id = $userId;
     if ($project->hasSendReceive()) {
         //            $entry->dirtySR++;
         $entry->dirtySR = 0;
         $status = SendReceiveCommands::getProjectStatus($projectId);
         if ($status && $status['SRState'] != 'IDLE') {
             return false;
         }
     }
     LexEntryDecoder::decode($entry, $params);
     $entry->write();
     ActivityCommands::writeEntry($project, $userId, $entry, $action);
     //        SendReceiveCommands::queueProjectForUpdate($project, $mergeQueuePath);
     //        SendReceiveCommands::startLFMergeIfRequired($projectId, 'merge', $pidFilePath, $command);
     return JsonEncoder::encode($entry);
 }
 public static function updateReply($projectId, $userId, $website, $commentId, $params)
 {
     CodeGuard::checkTypeAndThrow($params, 'array');
     CodeGuard::checkEmptyAndThrow($commentId, 'commentId in updateReply()');
     $project = new LexProjectModel($projectId);
     ProjectCommands::checkIfArchivedAndThrow($project);
     $comment = new LexCommentModel($project, $commentId);
     $rightsHelper = new RightsHelper($userId, $project, $website);
     $replyId = $params['id'];
     if (array_key_exists('id', $params) && $replyId != '') {
         $reply = $comment->getReply($replyId);
         if ($reply->authorInfo->createdByUserRef->asString() != $userId && !$rightsHelper->userHasProjectRight(Domain::COMMENTS + Operation::EDIT)) {
             throw new \Exception("No permission to update other people's lex comment replies!");
         }
         if ($reply->content != $params['content']) {
             $reply->authorInfo->modifiedDate = UniversalTimestamp::now();
         }
         $reply->content = $params['content'];
         $comment->setReply($replyId, $reply);
     } else {
         $reply = new LexCommentReply();
         $reply->content = $params['content'];
         $reply->authorInfo->createdByUserRef->id = $userId;
         $reply->authorInfo->modifiedByUserRef->id = $userId;
         $now = UniversalTimestamp::now();
         $reply->authorInfo->createdDate = $now;
         $reply->authorInfo->modifiedDate = $now;
         $comment->replies->append($reply);
         $replyId = $reply->id;
     }
     $comment->write();
     return $replyId;
 }
 /**
  * Writes the model to the mongo collection
  * @return string The unique id of the object written
  * @see MongoMapper::write()
  */
 public function write()
 {
     CodeGuard::checkTypeAndThrow($this->id, 'Api\\Model\\Shared\\Mapper\\Id');
     $now = UniversalTimestamp::now();
     $this->dateModified = $now;
     if (Id::isEmpty($this->id)) {
         $this->dateCreated = $now;
     }
     $this->id->id = $this->_mapper->write($this, $this->id->id);
     return $this->id->id;
 }
 public function __construct()
 {
     $this->createdByUserRef = new IdReference();
     $this->modifiedByUserRef = new IdReference();
     $now = UniversalTimestamp::now();
     $this->createdDate = $now;
     $this->modifiedDate = $now;
     $this->setReadOnlyProp('createdByUserRef');
     $this->setReadOnlyProp('modifiedByUserRef');
     $this->setReadOnlyProp('createdDate');
     $this->setReadOnlyProp('modifiedDate');
 }
 public function testEncodeDecodeUniversalTimestamp_HistoricalDate_Same()
 {
     $model = new TestMongoDateModel();
     $model->universalTimestamp = UniversalTimestamp::fromStringTimestamp('2001-01-01 12:01:01.321');
     $encoded = MongoEncoder::encode($model);
     $this->assertInstanceOf(UTCDateTime::class, $encoded['universalTimestamp']);
     //        var_dump($encoded);
     $decodedModel = new TestMongoDateModel();
     MongoDecoder::decode($decodedModel, $encoded);
     $this->assertEquals($model->universalTimestamp, $decodedModel->universalTimestamp);
     //        $iso8601 = $decodedModel->universalTimestamp->asFormattedString(UniversalTimestamp::ISO8601_WITH_MILLISECONDS);
     //        var_dump($iso8601);
 }
 public function testEncodeDecodeUniversalTimestamp_HistoricalDate_Same()
 {
     $model = new TestJsonDateModel();
     $model->universalTimestamp = UniversalTimestamp::fromStringTimestamp(self::StringTimestampWithMilliseconds);
     $encoded = JsonEncoder::encode($model);
     $this->assertInternalType('string', $encoded['universalTimestamp']);
     //        var_dump($encoded);
     $decodedModel = new TestJsonDateModel();
     JsonDecoder::decode($decodedModel, $encoded);
     $iso8601 = $decodedModel->universalTimestamp->asFormattedString(UniversalTimestamp::ISO8601_WITH_MILLISECONDS);
     $this->assertEquals($encoded['universalTimestamp'], $iso8601);
     $this->assertEquals($model->universalTimestamp, $decodedModel->universalTimestamp);
     //        var_dump($iso8601);
 }
 /**
  * @param UniversalTimestamp $model
  * @param string $data
  */
 public function decodeUniversalTimestamp(&$model, $data)
 {
     if ($data !== null) {
         $model = UniversalTimestamp::fromWhatever($data);
     }
 }
 /**
  * @param UniversalTimestamp $model
  * @return string;
  */
 public function encodeUniversalTimestamp($model)
 {
     return $model->asFormattedString(UniversalTimestamp::ISO8601_WITH_MILLISECONDS);
 }
 /**
  * @param string $importDateModified
  * @param UniversalTimestamp $entryDateModified
  * @return boolean
  */
 private static function differentModTime($importDateModified, $entryDateModified)
 {
     $dateModified = UniversalTimestamp::fromWhatever($importDateModified);
     return $dateModified->asMilliseconds() != $entryDateModified->asMilliseconds();
 }
 /**
  * @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]);
     }
 }
 /**
  * @param UniversalTimestamp $model
  * @return UTCDateTime;
  */
 public function encodeUniversalTimestamp($model)
 {
     return new UTCDateTime($model->asMilliseconds());
 }