public function sendMessage($payload, $recipients, $from)
 {
     $defaultValues = ['response_to' => null];
     $payload = array_merge($defaultValues, $payload);
     $insert = new Insert($this->getTable());
     $insert->columns(['from', 'subject', 'message'])->values(['from' => $from, 'subject' => $payload['subject'], 'message' => $payload['message'], 'datetime' => DateUtils::now(), 'response_to' => $payload['response_to']]);
     $rows = $this->insertWith($insert);
     $messageId = $this->lastInsertValue;
     // Insert recipients
     $values = [];
     foreach ($recipients as $recipient) {
         $read = 0;
         if ((int) $recipient == (int) $from) {
             $read = 1;
         }
         $values[] = '(' . $messageId . ', ' . $recipient . ', ' . $read . ')';
     }
     $valuesString = implode(',', $values);
     //@todo sanitize and implement ACL
     $sql = 'INSERT INTO directus_messages_recipients (`message_id`, `recipient`, `read`) VALUES ' . $valuesString;
     $result = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
     return $messageId;
 }
 public function preSaveDataHook(array $rowData, $rowExistsInDatabase = false)
 {
     $log = Bootstrap::get('log');
     if (isset($rowData['id'])) {
         $logger = Bootstrap::get('log');
         $TableGateway = new AclAwareTableGateway($this->acl, $this->table, $this->sql->getAdapter());
         $dbRecord = $TableGateway->find($rowData['id']);
         if (false === $dbRecord) {
             // @todo is it better to throw an exception here?
             $rowExistsInDatabase = false;
         }
     }
     // User is updating themselves.
     // Corresponds to a ping indicating their last activity.
     // Updated their "last_access" value.
     if (AuthProvider::loggedIn()) {
         $currentUser = AuthProvider::getUserInfo();
         if (isset($rowData['id']) && $rowData['id'] == $currentUser['id']) {
             $rowData['last_access'] = DateUtils::now();
         }
     }
     return $rowData;
 }
 public function manageRecordUpdate($tableName, $recordData, $activityEntryMode = self::ACTIVITY_ENTRY_MODE_PARENT, &$childLogEntries = null, &$parentCollectionRelationshipsChanged = false, $parentData = [])
 {
     $TableGateway = $this;
     if ($tableName !== $this->table) {
         $TableGateway = new RelationalTableGateway($this->acl, $tableName, $this->adapter);
     }
     $recordIsNew = !array_key_exists($TableGateway->primaryKeyFieldName, $recordData);
     $schemaArray = TableSchema::getSchemaArray($tableName);
     $currentUser = AuthProvider::getUserRecord();
     // Upload file if necessary
     $TableGateway->copyFiles($tableName, $recordData);
     // Delete file if necessary
     $TableGateway->deleteFiles($tableName, $recordData);
     //Dont do for directus users since id is pk
     if ($recordIsNew && $tableName != 'directus_users') {
         $cmsOwnerColumnName = $this->acl->getCmsOwnerColumnByTable($tableName);
         if ($cmsOwnerColumnName) {
             $recordData[$cmsOwnerColumnName] = $currentUser['id'];
         }
     }
     //Dont let non-admins make admins
     if ($tableName == 'directus_users' && $currentUser['group'] != 1) {
         if (isset($recordData['group']) && $recordData['group']['id'] == 1) {
             unset($recordData['group']);
         }
     }
     $thisIsNested = $activityEntryMode == self::ACTIVITY_ENTRY_MODE_CHILD;
     // Recursive functions will change this value (by reference) as necessary
     // $nestedCollectionRelationshipsChanged = $thisIsNested ? $parentCollectionRelationshipsChanged : false;
     $nestedCollectionRelationshipsChanged = false;
     if ($thisIsNested) {
         $nestedCollectionRelationshipsChanged =& $parentCollectionRelationshipsChanged;
     }
     // Recursive functions will append to this array by reference
     // $nestedLogEntries = $thisIsNested ? $childLogEntries : [];
     $nestedLogEntries = [];
     if ($thisIsNested) {
         $nestedLogEntries =& $childLogEntries;
     }
     // Update and/or Add Many-to-One Associations
     $parentRecordWithForeignKeys = $TableGateway->addOrUpdateManyToOneRelationships($schemaArray, $recordData, $nestedLogEntries, $nestedCollectionRelationshipsChanged);
     // Merge the M21 foreign keys into the recordData array
     $recordData = array_merge($recordData, $parentRecordWithForeignKeys);
     // If more than the record ID is present.
     $newRecordObject = null;
     $parentRecordChanged = $this->recordDataContainsNonPrimaryKeyData($parentRecordWithForeignKeys);
     // || $recordIsNew;
     if ($parentRecordChanged) {
         // Update the parent row, w/ any new association fields replaced by their IDs
         $newRecordObject = $TableGateway->addOrUpdateRecordByArray($parentRecordWithForeignKeys);
         if (!$newRecordObject) {
             return [];
         }
         if ($newRecordObject) {
             $newRecordObject = $newRecordObject->toArray();
         }
     }
     // Do it this way, because & byref for outcome of ternary operator spells trouble
     $draftRecord =& $parentRecordWithForeignKeys;
     if ($recordIsNew) {
         $draftRecord =& $newRecordObject;
     }
     // Restore X2M relationship / alias fields to the record representation & process these relationships.
     $collectionColumns = TableSchema::getAllAliasTableColumns($tableName);
     foreach ($collectionColumns as $collectionColumn) {
         $colName = $collectionColumn['id'];
         if (isset($recordData[$colName])) {
             $draftRecord[$colName] = $recordData[$colName];
         }
     }
     // parent
     if ($activityEntryMode === self::ACTIVITY_ENTRY_MODE_PARENT) {
         $parentData = ['id' => array_key_exists($this->primaryKeyFieldName, $recordData) ? $recordData[$this->primaryKeyFieldName] : null, 'table_name' => $tableName];
     }
     $draftRecord = $TableGateway->addOrUpdateToManyRelationships($schemaArray, $draftRecord, $nestedLogEntries, $nestedCollectionRelationshipsChanged, $parentData);
     $rowId = $draftRecord[$this->primaryKeyFieldName];
     $columnNames = TableSchema::getAllNonAliasTableColumnNames($tableName);
     $TemporaryTableGateway = new TableGateway($tableName, $this->adapter);
     $fullRecordData = $TemporaryTableGateway->select(function ($select) use($rowId, $columnNames) {
         $select->where->equalTo($this->primaryKeyFieldName, $rowId);
         $select->limit(1)->columns($columnNames);
     })->current();
     if (!$fullRecordData) {
         $recordType = $recordIsNew ? 'new' : 'pre-existing';
         throw new \RuntimeException('Attempted to load ' . $recordType . ' record post-insert with empty result. Lookup via row id: ' . print_r($rowId, true));
     }
     $fullRecordData = (array) $fullRecordData;
     $deltaRecordData = $recordIsNew ? [] : array_intersect_key((array) $parentRecordWithForeignKeys, (array) $fullRecordData);
     switch ($activityEntryMode) {
         // Activity logging is enabled, and I am a nested action
         case self::ACTIVITY_ENTRY_MODE_CHILD:
             $logEntryAction = $recordIsNew ? DirectusActivityTableGateway::ACTION_ADD : DirectusActivityTableGateway::ACTION_UPDATE;
             $childLogEntries[] = ['type' => DirectusActivityTableGateway::makeLogTypeFromTableName($this->table), 'table_name' => $tableName, 'action' => $logEntryAction, 'user' => $currentUser['id'], 'datetime' => DateUtils::now(), 'parent_id' => isset($parentData['id']) ? $parentData['id'] : null, 'parent_table' => isset($parentData['table_name']) ? $parentData['table_name'] : null, 'data' => json_encode($fullRecordData), 'delta' => json_encode($deltaRecordData), 'parent_changed' => (int) $parentRecordChanged, 'row_id' => $rowId, 'identifier' => $this->findRecordIdentifier($schemaArray, $fullRecordData), 'logged_ip' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '', 'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''];
             if ($recordIsNew) {
                 /**
                  * This is a nested call, creating a new record w/in a foreign collection.
                  * Indicate by reference that the top-level record's relationships have changed.
                  */
                 $parentCollectionRelationshipsChanged = true;
             }
             break;
         case self::ACTIVITY_ENTRY_MODE_PARENT:
             // Does this act deserve a log?
             $parentRecordNeedsLog = $nestedCollectionRelationshipsChanged || $parentRecordChanged;
             /**
              * NESTED QUESTIONS!
              * @todo  what do we do if the foreign record OF a foreign record changes?
              * is that activity entry also directed towards this parent activity entry?
              * @todo  how should nested activity entries relate to the revision histories of foreign items?
              * @todo  one day: treat children as parents if this top-level record was not modified.
              */
             $recordIdentifier = $this->findRecordIdentifier($schemaArray, $fullRecordData);
             // Produce log if something changed.
             if ($parentRecordChanged || $nestedCollectionRelationshipsChanged) {
                 $logEntryAction = $recordIsNew ? DirectusActivityTableGateway::ACTION_ADD : DirectusActivityTableGateway::ACTION_UPDATE;
                 //If we are updating and active is being set to 0 then we are deleting
                 if (!$recordIsNew && array_key_exists(STATUS_COLUMN_NAME, $deltaRecordData)) {
                     if ($deltaRecordData[STATUS_COLUMN_NAME] == STATUS_DELETED_NUM) {
                         $logEntryAction = DirectusActivityTableGateway::ACTION_DELETE;
                     }
                 }
                 // Save parent log entry
                 $parentLogEntry = AclAwareRowGateway::makeRowGatewayFromTableName($this->acl, 'directus_activity', $this->adapter);
                 $logData = ['type' => DirectusActivityTableGateway::makeLogTypeFromTableName($this->table), 'table_name' => $tableName, 'action' => $logEntryAction, 'user' => $currentUser['id'], 'datetime' => DateUtils::now(), 'parent_id' => null, 'data' => json_encode($fullRecordData), 'delta' => json_encode($deltaRecordData), 'parent_changed' => (int) $parentRecordChanged, 'identifier' => $recordIdentifier, 'row_id' => $rowId, 'logged_ip' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '', 'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''];
                 $parentLogEntry->populate($logData, false);
                 $parentLogEntry->save();
                 // Update & insert nested activity entries
                 $ActivityGateway = new DirectusActivityTableGateway($this->acl, $this->adapter);
                 foreach ($nestedLogEntries as $entry) {
                     $entry['parent_id'] = $rowId;
                     // @todo ought to insert these in one batch
                     $ActivityGateway->insert($entry);
                 }
             }
             break;
     }
     // Yield record object
     $recordGateway = new AclAwareRowGateway($this->acl, $TableGateway->primaryKeyFieldName, $tableName, $this->adapter);
     $recordGateway->populate($fullRecordData, true);
     return $recordGateway;
 }
Example #4
0
 public static function getTable($tbl_name)
 {
     $acl = Bootstrap::get('acl');
     $zendDb = Bootstrap::get('ZendDb');
     // TODO: getTable should return an empty object
     // or and empty array instead of false
     // in any given situation that the table
     // can be find or used.
     if (!self::canGroupViewTable($tbl_name)) {
         return false;
     }
     $info = SchemaManager::getTable($tbl_name);
     if (!$info) {
         return false;
     }
     if ($info) {
         $info['count'] = (int) $info['count'];
         $info['date_created'] = DateUtils::convertToISOFormat($info['date_created'], 'UTC', get_user_timezone());
         $info['hidden'] = (bool) $info['hidden'];
         $info['single'] = (bool) $info['single'];
         $info['footer'] = (bool) $info['footer'];
     }
     $relationalTableGateway = new RelationalTableGateway($acl, $tbl_name, $zendDb);
     $info = array_merge($info, $relationalTableGateway->countActiveOld());
     $info['columns'] = self::getSchemaArray($tbl_name);
     $directusPreferencesTableGateway = new DirectusPreferencesTableGateway($acl, $zendDb);
     $currentUser = Auth::getUserInfo();
     $info['preferences'] = $directusPreferencesTableGateway->fetchByUserAndTable($currentUser['id'], $tbl_name);
     return $info;
 }
Example #5
0
            $i++;
        }
        foreach ($userRecipients as $recipient) {
            $usersTableGateway = new DirectusUsersTableGateway($acl, $ZendDb);
            $user = $usersTableGateway->findOneBy('id', $recipient);
            if (isset($user) && $user['email_messages'] == 1) {
                $data = ['message' => $requestPayload['message']];
                $view = 'mail/notification.twig.html';
                Mail::send($view, $data, function ($message) use($user, $requestPayload) {
                    $message->setSubject($requestPayload['subject']);
                    $message->setTo($user['email']);
                });
            }
        }
    }
    $requestPayload['datetime'] = DateUtils::now();
    $newRecord = $TableGateway->manageRecordUpdate('directus_messages', $requestPayload, TableGateway::ACTIVITY_ENTRY_MODE_DISABLED);
    $params['id'] = $newRecord['id'];
    // GET all table entries
    $entries = $TableGateway->getEntries($params);
    JsonView::render($entries);
});
/**
 * EXCEPTION LOG
 */
//$app->post("/$v/exception/?", function () use ($params, $requestPayload, $app, $acl, $ZendDb) {
//    print_r($requestPayload);die();
//    $data = array(
//        'server_addr'   =>$_SERVER['SERVER_ADDR'],
//        'server_port'   =>$_SERVER['SERVER_PORT'],
//        'user_agent'    =>$_SERVER['HTTP_USER_AGENT'],
Example #6
0
 /**
  * Creates a new file for Directus Media
  *
  * @param string $filePath
  * @param string $targetName
  *
  * @return Array file info
  */
 private function processUpload($filePath, $targetName)
 {
     // set true as $filePath it's outside adapter path
     // $filePath is on a temporary php directory
     $fileData = $this->getFileInfo($filePath, true);
     $mediaPath = $this->filesystem->getPath();
     $fileData['title'] = Formatting::fileNameToFileTitle($targetName);
     $targetName = $this->getFileName($targetName);
     $finalPath = rtrim($mediaPath, '/') . '/' . $targetName;
     $data = file_get_contents($filePath);
     $this->emitter->run('files.saving', ['name' => $targetName, 'size' => strlen($data)]);
     $this->filesystem->getAdapter()->write($targetName, $data);
     $this->emitter->run('files.saving:after', ['name' => $targetName, 'size' => strlen($data)]);
     $fileData['name'] = basename($finalPath);
     $fileData['date_uploaded'] = DateUtils::now();
     $fileData['storage_adapter'] = $this->config['adapter'];
     return $fileData;
 }
 public function recordMessage($data, $userId)
 {
     if (isset($data['response_to']) && $data['response_to'] > 0) {
         $action = 'REPLY';
     } else {
         $action = 'ADD';
     }
     $logData = ['type' => self::TYPE_MESSAGE, 'table_name' => 'directus_messages', 'action' => $action, 'user' => $userId, 'datetime' => DateUtils::now(), 'parent_id' => null, 'data' => json_encode($data), 'delta' => '[]', 'identifier' => $data['subject'], 'row_id' => $data['id'], 'logged_ip' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '', 'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''];
     $insert = new Insert($this->getTable());
     $insert->values($logData);
     $this->insertWith($insert);
 }
Example #8
0
 public function convertDates(array $records, array $schemaArray, $tableName = null)
 {
     $tableName = $tableName === null ? $this->table : $tableName;
     if (!SchemaManager::isDirectusTable($tableName)) {
         return $records;
     }
     // ==========================================================================
     // hotfix: records sometimes are no set as an array of rows.
     // NOTE: this code is duplicate @see: AbstractSchema::parseRecordValuesByType
     // ==========================================================================
     $singleRecord = false;
     if (!is_numeric_keys_array($records)) {
         $records = [$records];
         $singleRecord = true;
     }
     foreach ($records as $index => $row) {
         foreach ($schemaArray as $column) {
             if (in_array(strtolower($column['type']), ['timestamp', 'datetime'])) {
                 $columnName = $column['id'];
                 if (array_key_exists($columnName, $row)) {
                     $records[$index][$columnName] = DateUtils::convertToISOFormat($row[$columnName], 'UTC', get_user_timezone());
                 }
             }
         }
     }
     return $singleRecord ? reset($records) : $records;
 }
Example #9
0
 public function testPassed()
 {
     $datetime = new DateTime('now');
     $datetime->modify('-1 days');
     $this->assertTrue(DateUtils::hasPassed($datetime));
     $datetime->modify('2 days');
     $this->assertFalse(DateUtils::hasPassed($datetime));
     $datetime->modify('-3 days');
     $this->assertTrue(DateUtils::hasPassed($datetime->format('Y-m-d H:i:s')));
     $datetime->modify('4 days');
     $this->assertFalse(DateUtils::hasPassed($datetime->format('Y-m-d H:i:s')));
 }