/**
  * Fetch related, foreign rows for a whole rowset's ManyToOne relationships.
  * (Given a table's schema and rows, iterate and replace all of its foreign
  * keys with the contents of these foreign rows.)
  * @param  array $schema  Table schema array
  * @param  array $entries Table rows
  * @return array          Revised table rows, now including foreign rows
  */
 public function loadManyToOneRelationships($schemaArray, $table_entries)
 {
     // Identify the ManyToOne columns
     foreach ($schemaArray as $col) {
         $isManyToOneColumn = array_key_exists('relationship', $col) && $col['relationship']['type'] == 'MANYTOONE';
         if ($isManyToOneColumn) {
             $foreign_id_column = $col['id'];
             if (array_key_exists('relationship', $col)) {
                 $foreign_table_name = $col['relationship']['table_related'];
             } else {
                 $message = 'Non single_file Many-to-One relationship lacks `table_related` value.';
                 if (array_key_exists('column_name', $col)) {
                     $message .= " Column: " . $col['column_name'];
                 }
                 if (array_key_exists('table_name', $col)) {
                     $message .= " Table: " . $col['table_name'];
                 }
                 throw new Exception\RelationshipMetadataException($message);
             }
             // Aggregate all foreign keys for this relationship (for each row, yield the specified foreign id)
             $yield = function ($row) use($foreign_id_column, $table_entries) {
                 if (array_key_exists($foreign_id_column, $row)) {
                     return $row[$foreign_id_column];
                 }
             };
             $ids = array_map($yield, $table_entries);
             if (empty($ids)) {
                 continue;
             }
             if (!TableSchema::canGroupViewTable($foreign_table_name)) {
                 continue;
             }
             // Fetch the foreign data
             $select = new Select($foreign_table_name);
             $select->where->in('id', $ids);
             $columnNames = TableSchema::getAllNonAliasTableColumnNames($foreign_table_name);
             $select->columns($columnNames);
             $TableGateway = new RelationalTableGateway($this->acl, $foreign_table_name, $this->adapter);
             $rowset = $TableGateway->selectWith($select);
             $results = $rowset->toArray();
             $foreign_table = array();
             $columns = TableSchema::getAllNonAliasTableColumns($foreign_table_name);
             foreach ($results as $row) {
                 $row = $this->parseRecordValuesByMysqlType($row, $columns);
                 $foreign_table[$row['id']] = $row;
             }
             // Replace foreign keys with foreign rows
             foreach ($table_entries as &$parentRow) {
                 if (array_key_exists($foreign_id_column, $parentRow)) {
                     $foreign_id = (int) $parentRow[$foreign_id_column];
                     $parentRow[$foreign_id_column] = null;
                     // "Did we retrieve the foreign row with this foreign ID in our recent query of the foreign table"?
                     if (array_key_exists($foreign_id, $foreign_table)) {
                         $parentRow[$foreign_id_column] = $foreign_table[$foreign_id];
                     }
                 }
             }
         }
     }
     return $table_entries;
 }
 public function fetchAllByUser($user_id, $assoc = false)
 {
     $select = new Select($this->table);
     $select->columns(array('id', 'user', 'table_name', 'columns_visible', 'sort', 'sort_order', STATUS_COLUMN_NAME, 'title', 'search_string'));
     $select->where->equalTo('user', $user_id)->isNull('title');
     $select->where('table_name NOT IN(
                 "directus_columns",
                 "directus_ip_whitelist",
                 "directus_preferences",
                 "directus_privileges",
                 "directus_settings",
                 "directus_storage_adapters",
                 "directus_tables",
                 "directus_tab_privileges",
                 "directus_ui"
             )');
     $metadata = new \Zend\Db\Metadata\Metadata($this->getAdapter());
     $tables = $metadata->getTableNames(DB_NAME);
     $tables = array_diff($tables, array("directus_columns", "directus_ip_whitelist", "directus_preferences", "directus_privileges", "directus_settings", "directus_storage_adapters", "directus_tables", "directus_tab_privileges", "directus_ui"));
     $rows = $this->selectWith($select)->toArray();
     $preferences = array();
     $tablePrefs = array();
     foreach ($rows as $row) {
         $tablePrefs[$row['table_name']] = $row;
     }
     //Get Default Preferences
     foreach ($tables as $key => $table) {
         // Honor ACL. Skip the tables that the user doesn't have access too
         if (!TableSchema::canGroupViewTable($table)) {
             continue;
         }
         $tableName = $table;
         if (!isset($tablePrefs[$table])) {
             $table = null;
         } else {
             $table = $tablePrefs[$table];
         }
         if (!isset($table['user'])) {
             $table = null;
         }
         $table = $this->constructPreferences($user_id, $tableName, $table);
         $preferences[$tableName] = $table;
     }
     return $preferences;
 }
 /**
  * Fetch related, foreign rows for a whole rowset's ManyToOne relationships.
  * (Given a table's schema and rows, iterate and replace all of its foreign
  * keys with the contents of these foreign rows.)
  *
  * @param array $schemaArray Table schema array
  * @param array $table_entries Table rows
  * @param string|null $parentField
  * @param int $level
  *
  * @return array Revised table rows, now including foreign rows
  *
  * @throws Exception\RelationshipMetadataException
  */
 public function loadManyToOneRelationships($schemaArray, $table_entries, $parentField = null, $level = 0)
 {
     // Identify the ManyToOne columns
     foreach ($schemaArray as $col) {
         $isManyToOneColumn = array_key_exists('relationship', $col) && $col['relationship']['type'] == 'MANYTOONE';
         if ($isManyToOneColumn) {
             $foreign_id_column = $col['id'];
             if (array_key_exists('relationship', $col)) {
                 $foreign_table_name = $col['relationship']['related_table'];
             } else {
                 $message = 'Non single_file Many-to-One relationship lacks `related_table` value.';
                 if (array_key_exists('column_name', $col)) {
                     $message .= ' Column: ' . $col['column_name'];
                 }
                 if (array_key_exists('table_name', $col)) {
                     $message .= ' Table: ' . $col['table_name'];
                 }
                 throw new Exception\RelationshipMetadataException($message);
             }
             // =============================================================================
             // HOTFIX: prevent infinite circle loop
             // =============================================================================
             if ($parentField && $this->hasToManyCallStack($parentField, $foreign_table_name)) {
                 return $table_entries;
             }
             $this->addToManyCallStack($level, is_null($parentField) ? $foreign_id_column : $parentField, $foreign_table_name);
             // Aggregate all foreign keys for this relationship (for each row, yield the specified foreign id)
             $yield = function ($row) use($foreign_id_column, $table_entries) {
                 if (array_key_exists($foreign_id_column, $row)) {
                     return $row[$foreign_id_column];
                 }
             };
             $ids = array_map($yield, $table_entries);
             if (empty($ids)) {
                 continue;
             }
             if (!TableSchema::canGroupViewTable($foreign_table_name)) {
                 continue;
             }
             // Fetch the foreign data
             $select = new Select($foreign_table_name);
             $select->where->in('id', $ids);
             $columnNames = TableSchema::getAllNonAliasTableColumnNames($foreign_table_name);
             $select->columns($columnNames);
             $TableGateway = new RelationalTableGateway($this->acl, $foreign_table_name, $this->adapter);
             $rowset = $TableGateway->selectWith($select);
             $results = $rowset->toArray();
             $foreign_table = [];
             foreach ($results as $row) {
                 $row = $this->parseRecord($row, $foreign_table_name);
                 $foreign_table[$row['id']] = $row;
             }
             // Get table column schema
             $schemaArray = TableSchema::getSchemaArray($foreign_table_name);
             // Eager-load related ManyToOne records
             $foreign_table = $this->loadManyToOneRelationships($schemaArray, $foreign_table, $parentField, $level + 1);
             // Convert dates into ISO 8601 Format
             $foreign_table = $this->convertDates($foreign_table, $schemaArray);
             // Replace foreign keys with foreign rows
             foreach ($table_entries as &$parentRow) {
                 if (array_key_exists($foreign_id_column, $parentRow)) {
                     $foreign_id = (int) $parentRow[$foreign_id_column];
                     $parentRow[$foreign_id_column] = null;
                     // "Did we retrieve the foreign row with this foreign ID in our recent query of the foreign table"?
                     if (array_key_exists($foreign_id, $foreign_table)) {
                         $parentRow[$foreign_id_column] = $foreign_table[$foreign_id];
                     }
                 }
             }
         }
     }
     return $table_entries;
 }
 public function fetchAllByUser($user_id, $assoc = false)
 {
     $select = new Select($this->table);
     $select->columns(['id', 'user', 'table_name', 'columns_visible', 'sort', 'sort_order', 'status', 'title', 'search_string']);
     $select->where->equalTo('user', $user_id)->isNull('title');
     $coreTables = SchemaManager::getDirectusTables(static::$IGNORED_TABLES);
     $select->where->addPredicate(new NotIn('table_name', $coreTables));
     $metadata = new \Zend\Db\Metadata\Metadata($this->getAdapter());
     $tables = $metadata->getTableNames();
     $tables = array_diff($tables, $coreTables);
     $rows = $this->selectWith($select)->toArray();
     $preferences = [];
     $tablePrefs = [];
     foreach ($rows as $row) {
         $tablePrefs[$row['table_name']] = $row;
     }
     //Get Default Preferences
     foreach ($tables as $key => $table) {
         // Honor ACL. Skip the tables that the user doesn't have access too
         if (!TableSchema::canGroupViewTable($table)) {
             continue;
         }
         $tableName = $table;
         if (!isset($tablePrefs[$table])) {
             $table = null;
         } else {
             $table = $tablePrefs[$table];
         }
         if (!isset($table['user'])) {
             $table = null;
         }
         $table = $this->constructPreferences($user_id, $tableName, $table);
         $preferences[$tableName] = $table;
     }
     return $preferences;
 }