public static function compareApiResponses($new, $old) { $id = time(); $old = self::format_json(json_encode($old)); $log = Bootstrap::get('app')->getLog(); $uri = $_SERVER['REQUEST_URI']; if (0 === strcmp($new, $old)) { return $log->info("The response comparison matched. [{$uri}]"); } $log->warn("The response comparison failed. [{$uri}]"); // Output path $fname_prefix = "cmp_{$id}"; $dir = APPLICATION_PATH . '/docs/api-responses'; if (!is_dir($dir)) { $log->fatal("Can't write API responses to output directory: {$dir}"); return; } // Write API responses to disk foreach (array('new', 'old') as $version) { $fname = "{$fname_prefix}_{$version}.json"; $fpath = "{$dir}/{$fname}"; $fp = fopen($fpath, 'w+'); fwrite($fp, ${$version}); fclose($fp); $log->info("Wrote {$version} API response version to {$fpath}"); } }
public static function compareApiResponses($new, $old) { $id = time(); $old = self::format_json(json_encode($old)); $log = Bootstrap::get('app')->getLog(); $uri = $_SERVER['REQUEST_URI']; if (0 === strcmp($new, $old)) { return $log->info('The response comparison matched. [' . $uri . ']'); } $log->warn('The response comparison failed. [' . $uri . ']'); // Output path $fname_prefix = 'cmp_' . $id; $dir = APPLICATION_PATH . '/docs/api-responses'; if (!is_dir($dir)) { $log->fatal('Can\'t write API responses to output directory: ' . $dir); return; } // Write API responses to disk foreach (['new', 'old'] as $version) { $fname = $fname_prefix . '_' . $version . '.json'; $fpath = $dir . '/' . $fname; $fp = fopen($fpath, 'w+'); fwrite($fp, ${$version}); fclose($fp); $log->info('Wrote $version API response version to ' . $fpath); } }
/** * Handle an uncaught exception * * @param \Throwable $e * @return void */ public function handleException($e) { $this->emitter->run('application.error', $e); $app = Bootstrap::get('app'); $exceptionView = new ExceptionView(); $exceptionView->exceptionHandler($app, $e); }
public static function send($viewPath, $data, $callback) { $config = Bootstrap::get('config'); $mailer = Bootstrap::get('mailer'); if (!$mailer) { throw new InvalidArgumentException(__t('mail_configuration_no_defined')); } $DirectusSettingsTableGateway = new \Zend\Db\TableGateway\TableGateway('directus_settings', Bootstrap::get('zendDb')); $rowSet = $DirectusSettingsTableGateway->select(); $settings = []; foreach ($rowSet as $setting) { $settings[$setting['collection']][$setting['name']] = $setting['value']; } $instance = new static($mailer, $settings); $message = Swift_Message::newInstance(); // default mail from address $mailConfig = $config['mail']; $message->setFrom($mailConfig['from']); call_user_func($callback, $message); if ($message->getBody() == null) { // Slim Extras View twig act weird on this version $viewContent = $instance->getViewContent($viewPath, $data); $message->setBody($viewContent, 'text/html'); } $instance->sendMessage($message); }
protected function cmdDiff($args, $extra) { // TODO: Accepts a language code to compare it with another. (Default: English) $languageManager = Bootstrap::get('languagesManager'); $languages = $languageManager->getLanguageList(); if (count($languages) <= 1) { return []; } $languagesPhrases = []; foreach ($languages as $code => $name) { $languagesPhrases[] = ['code' => $code, 'name' => $name, 'phrases_keys' => get_locale_keys($code), 'diff' => []]; } // ============================================================================= // A language to compare to the rest of languages keys // ============================================================================= $mainLanguage = $languagesPhrases[0]; unset($languagesPhrases[0]); foreach ($languagesPhrases as $language) { $diff = ArrayUtils::missing($mainLanguage['phrases_keys'], $language['phrases_keys']); echo "--------------------" . PHP_EOL; echo $language['name'] . " has " . count($diff) . " missing/removed keys compared against " . $mainLanguage['name'] . PHP_EOL; foreach ($diff as $key) { echo "\t - " . $key . PHP_EOL; } echo "--------------------" . PHP_EOL . PHP_EOL; } }
protected static function getHook($hookName) { $config = Bootstrap::get('config'); if (isset($config['dbHooks']) && isset($config['dbHooks'][$hookName])) { return $config['dbHooks'][$hookName]; } return false; }
public function __construct($base_path) { if ($base_path == null) { $base_path = BASE_PATH; } else { $this->directus_path = $base_path; } require_once $this->directus_path . '/api/config.php'; $this->db = Bootstrap::get('ZendDb'); $this->settingsTableGateway = new TableGateway('directus_settings', $this->db); }
public function __construct() { $acl = Bootstrap::get('acl'); $adapter = Bootstrap::get('ZendDb'); $this->filesystem = Bootstrap::get('filesystem'); $config = Bootstrap::get('config'); $this->config = $config['filesystem'] ?: []; // Fetch files settings $Settings = new DirectusSettingsTableGateway($acl, $adapter); $this->filesSettings = $Settings->fetchCollection('files', array('storage_adapter', 'storage_destination', 'thumbnail_storage_adapter', 'thumbnail_storage_destination', 'thumbnail_size', 'thumbnail_quality', 'thumbnail_crop_enabled')); }
public static function send($viewPath, $data, $callback) { $instance = new static(Bootstrap::get('mailer')); $message = Swift_Message::newInstance(); call_user_func($callback, $message); if ($message->getBody() == null) { // Slim Extras View twig act weird on this version $viewContent = $instance->getViewContent($viewPath, $data); $message->setBody($viewContent, 'text/html'); } $instance->sendMessage($message); }
protected static function prependSessionKey() { if (self::$prependedSessionKey) { return; } $config = Bootstrap::get('config'); if (!isset($config['session']) || !isset($config['session']['prefix']) || empty($config['session']['prefix'])) { throw new \RuntimeException("You must define session.prefix in api/configuration.php - see example configuration file."); } self::$SESSION_KEY = $config['session']['prefix'] . self::$SESSION_KEY; self::$prependedSessionKey = true; }
public function __construct() { parent::__construct(false); // @todo: global config object $DirectusSettingsTableGateway = new \Zend\Db\TableGateway\TableGateway('directus_settings', Bootstrap::get('zendDb')); $rowSet = $DirectusSettingsTableGateway->select(); foreach ($rowSet as $setting) { $this->settings[$setting['collection']][$setting['name']] = $setting['value']; } $this->setFrom('*****@*****.**', 'Directus'); $this->addReplyTo('*****@*****.**', 'No Reply'); $this->headers[] = 'X-Mailer: PHP/' . phpversion(); $this->headers[] = 'MIME-Version: 1.0'; $this->ContentType = 'text/html'; }
public function __construct() { $this->acl = Bootstrap::get('acl'); $this->adapter = Bootstrap::get('ZendDb'); // Fetch files settings $Settings = new DirectusSettingsTableGateway($this->acl, $this->adapter); $this->filesSettings = $Settings->fetchCollection('files', array('storage_adapter', 'storage_destination', 'thumbnail_storage_adapter', 'thumbnail_storage_destination', 'thumbnail_size', 'thumbnail_quality', 'thumbnail_crop_enabled')); // Initialize Storage Adapters $StorageAdapters = new DirectusStorageAdaptersTableGateway($this->acl, $this->adapter); $adapterRoles = array('DEFAULT', 'THUMBNAIL', 'TEMP'); $storage = $StorageAdapters->fetchByUniqueRoles($adapterRoles); if (count($storage) !== count($adapterRoles)) { throw new \RuntimeException(__CLASS__ . ' expects adapter settings for these default adapter roles: ' . implode(',', $adapterRoles)); } $this->FilesStorage = self::getStorage($storage['DEFAULT']); $this->ThumbnailStorage = self::getStorage($storage['THUMBNAIL']); $this->storageAdaptersByRole = $storage; }
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'] = new Expression("NOW()"); } } return $rowData; }
/** * Get all the columns information stored on Directus Columns table * * @param $tableName * @param $params * * @return array */ protected function getDirectusColumnsInfo($tableName, $params = null) { $acl = Bootstrap::get('acl'); $blacklist = $readFieldBlacklist = $acl->getTablePrivilegeList($tableName, $acl::FIELD_READ_BLACKLIST); $columnName = isset($params['column_name']) ? $params['column_name'] : -1; $select = new Select(); $select->columns(['id' => 'column_name', 'column_name', 'type' => new Expression('upper(data_type)'), 'char_length' => new Expression('NULL'), 'is_nullable' => new Expression('"NO"'), 'default_value' => new Expression('NULL'), 'comment', 'sort', 'column_type' => new Expression('NULL'), 'ui', 'hidden_list', 'hidden_input', 'relationship_type', 'related_table', 'junction_table', 'junction_key_left', 'junction_key_right', 'required' => new Expression('IFNULL(required, 0)')]); $select->from('directus_columns'); $where = new Where(); $where->equalTo('TABLE_NAME', $tableName)->addPredicate(new In('data_type', ['alias', 'MANYTOMANY', 'ONETOMANY'])); // ->nest() // ->addPredicate(new \Zend\Db\Sql\Predicate\Expression("'$columnName' = '-1'")) // ->OR // ->equalTo('column_name', $columnName) // ->unnest() // ->addPredicate(new IsNotNull('data_type')); if ($columnName != -1) { $where->equalTo('column_name', $columnName); } if (count($blacklist)) { $where->addPredicate(new NotIn('COLUMN_NAME', $blacklist)); } $select->where($where); $select->order('sort'); $sql = new Sql($this->adapter); $statement = $sql->prepareStatementForSqlObject($select); // $query = $sql->getSqlStringForSqlObject($select, $this->adapter->getPlatform()); // echo $query; $result = $statement->execute(); $columns = iterator_to_array($result); return $columns; }
$newNonces = $requestNonceProvider->getNewNoncesThisRequest(); $nonce_options = $requestNonceProvider->getOptions(); $response[$nonce_options['nonce_response_header']] = implode($newNonces, ","); } }); /** * Bootstrap Providers */ /** * @var \Zend\Db\Adapter */ $ZendDb = Bootstrap::get('ZendDb'); /** * @var \Directus\Acl */ $acl = Bootstrap::get('acl'); /** * Authentication */ $DirectusUsersTableGateway = new DirectusUsersTableGateway($acl, $ZendDb); Auth::setUserCacheRefreshProvider(function ($userId) use($DirectusUsersTableGateway) { $cacheFn = function () use($userId, $DirectusUsersTableGateway) { return $DirectusUsersTableGateway->find($userId); }; $cacheKey = MemcacheProvider::getKeyDirectusUserFind($userId); $user = $DirectusUsersTableGateway->memcache->getOrCache($cacheKey, $cacheFn, 10800); return $user; }); if (Auth::loggedIn()) { $user = Auth::getUserRecord(); $acl->setUserId($user['id']);
/** * Get Hook Emitter * * @return Emitter */ private static function hookEmitter() { $emitter = new Emitter(); $emitter->addAction('application.error', function ($e) { $log = Bootstrap::get('log'); $log->error($e); }); $emitter->addAction('table.insert.directus_groups', function ($data) { $acl = Bootstrap::get('acl'); $zendDb = Bootstrap::get('zendDb'); $privilegesTable = new DirectusPrivilegesTableGateway($acl, $zendDb); $privilegesTable->insertPrivilege(['group_id' => $data['id'], 'allow_view' => 1, 'allow_add' => 0, 'allow_edit' => 1, 'allow_delete' => 0, 'allow_alter' => 0, 'table_name' => 'directus_users', 'read_field_blacklist' => 'token', 'write_field_blacklist' => 'group,token']); }); return $emitter; }
/** * Add Directus default user * * @param array $data * @return array */ public static function addDefaultUser($data) { $db = Bootstrap::get('ZendDb'); $tableGateway = new TableGateway('directus_users', $db); $hash = password_hash($data['directus_password'], PASSWORD_DEFAULT, ['cost' => 12]); $data['user_salt'] = StringUtils::randomString(); $data['user_token'] = StringUtils::randomString(32); $data['avatar'] = get_gravatar($data['directus_email']); $tableGateway->insert(['active' => 1, 'first_name' => 'Admin', 'last_name' => 'User', 'email' => $data['directus_email'], 'password' => $hash, 'salt' => $data['user_salt'], 'avatar' => $data['avatar'], 'group' => 1, 'token' => $data['user_token'], 'language' => ArrayUtils::get($data, 'default_language', 'en')]); return $data; }
/** * Check if a user is logged in. * @return boolean */ public static function loggedIn() { if (self::$authenticated != null) { return self::$authenticated; } self::prependSessionKey(); if (php_sapi_name() != 'cli' && '' === session_id()) { session_start(); } self::$authenticated = $isLoggedIn = false; $ZendDb = Bootstrap::get('ZendDb'); $session = []; if (isset($_SESSION[self::$SESSION_KEY]) && !empty($_SESSION[self::$SESSION_KEY])) { $session = $_SESSION[self::$SESSION_KEY]; } if (is_array($session) && ArrayUtils::contains($session, ['id', 'access_token'])) { $DirectusUsersTableGateway = new \Zend\Db\TableGateway\TableGateway('directus_users', $ZendDb); $user = $DirectusUsersTableGateway->select(['id' => $session['id'], 'access_token' => $session['access_token']]); if ($user->count()) { self::$authenticated = $isLoggedIn = true; } } return $isLoggedIn; }
<?php use Directus\Bootstrap; use Directus\View\JsonView; // Slim App $app = Bootstrap::get('app'); // Simple GET endpoint example $app->get('/example', function () { return JsonView::render(['item 1', 'item 2']); });
public function logger() { return Bootstrap::get('app')->getLog(); }
/** * Get Hook Emitter * * @return Emitter */ private static function hookEmitter() { $emitter = new Emitter(); $emitter->addAction('application.error', function ($e) { $log = Bootstrap::get('log'); $log->error($e); }); $emitter->addAction('table.insert.directus_groups', function ($data) { $acl = Bootstrap::get('acl'); $zendDb = Bootstrap::get('zendDb'); $privilegesTable = new DirectusPrivilegesTableGateway($acl, $zendDb); $privilegesTable->insertPrivilege(['group_id' => $data['id'], 'allow_view' => 1, 'allow_add' => 0, 'allow_edit' => 1, 'allow_delete' => 0, 'allow_alter' => 0, 'table_name' => 'directus_users', 'read_field_blacklist' => 'token', 'write_field_blacklist' => 'group,token']); }); $emitter->addFilter('table.insert:before', function ($tableName, $data) { if ($tableName == 'directus_files') { unset($data['data']); $data['user'] = AuthProvider::getUserInfo('id'); } return $data; }); // Add file url and thumb url $emitter->addFilter('table.select', function ($result, $selectState) { if ($selectState['table'] == 'directus_files') { $fileRows = $result->toArray(); $files = new \Directus\Files\Files(); foreach ($fileRows as &$row) { $config = Bootstrap::get('config'); $fileURL = $config['filesystem']['root_url']; $thumbnailURL = $config['filesystem']['root_thumb_url']; $thumbnailFilenameParts = explode('.', $row['name']); $thumbnailExtension = array_pop($thumbnailFilenameParts); $row['url'] = $fileURL . '/' . $row['name']; if (in_array($thumbnailExtension, ['tif', 'tiff', 'psd', 'pdf'])) { $thumbnailExtension = 'jpg'; } $thumbnailFilename = $row['id'] . '.' . $thumbnailExtension; $row['thumbnail_url'] = $thumbnailURL . '/' . $thumbnailFilename; // filename-ext-100-100-true.jpg // @TODO: This should be another hook listener $row['thumbnail_url'] = null; $filename = implode('.', $thumbnailFilenameParts); if ($row['type'] == 'embed/vimeo') { $oldThumbnailFilename = $row['name'] . '-vimeo-220-124-true.jpg'; } else { $oldThumbnailFilename = $filename . '-' . $thumbnailExtension . '-160-160-true.jpg'; } // 314551321-vimeo-220-124-true.jpg // hotfix: there's not thumbnail for this file if ($files->exists('thumbs/' . $oldThumbnailFilename)) { $row['thumbnail_url'] = $thumbnailURL . '/' . $oldThumbnailFilename; } if ($files->exists('thumbs/' . $thumbnailFilename)) { $row['thumbnail_url'] = $thumbnailURL . '/' . $thumbnailFilename; } $embedManager = Bootstrap::get('embedManager'); $provider = $embedManager->getByType($row['type']); $row['html'] = null; if ($provider) { $row['html'] = $provider->getCode($row); } } $filesArrayObject = new \ArrayObject($fileRows); $result->initialize($filesArrayObject->getIterator()); } return $result; }); return $emitter; }
<?php // If config file doesnt exist, go to install file if (!file_exists('api/config.php') || filesize('api/config.php') == 0) { header('Location: installation/index.php'); exit; } // Composer Autoloader $loader = (require 'vendor/autoload.php'); define('BASE_PATH', dirname(__FILE__)); define('API_PATH', BASE_PATH . '/api'); use Directus\Bootstrap; require "api/config.php"; require "api/globals.php"; $emitter = Bootstrap::get('hookEmitter'); $emitter->run('directus.login.start'); // Temporary solution for disabling this page for logged in users. if (\Directus\Auth\Provider::loggedIn()) { header('Location: ' . DIRECTUS_PATH); exit; } // hotfix // see: https://github.com/directus/directus/issues/1268 $errorMessage = null; if (isset($_SESSION['error_message'])) { $errorMessage = $_SESSION['error_message']; unset($_SESSION['error_message']); } // Get current commit hash $git = __DIR__ . '/.git'; $cacheBuster = Directus\Util\Git::getCloneHash($git);
function getListViews() { return Bootstrap::get('listViews'); }
/** * Proxy method calls to the current database schema object * * @param $name * @param $arguments * @return mixed */ public static function __callStatic($name, $arguments) { $schema = Bootstrap::get('schema'); return call_user_func_array([$schema, $name], $arguments); }
/** * Get ui options * * @param $tbl_name * @param $col_name * @param $datatype_name */ public static function getUIOptions($tbl_name, $col_name, $datatype_name) { $result = []; $item = []; $zendDb = Bootstrap::get('zendDb'); $select = new Select(); $select->columns(['id' => 'ui_name', 'name', 'value']); $select->from('directus_ui'); $select->where([]); $select->where(['column_name' => $col_name, 'table_name' => $tbl_name, 'ui_name' => $datatype_name]); $select->order('ui_name'); $sql = new Sql($zendDb); $statement = $sql->prepareStatementForSqlObject($select); $rows = $statement->execute(); foreach ($rows as $row) { //first case if (!isset($ui)) { $item['id'] = $ui = $row['id']; } //new ui = new item if ($ui != $row['id']) { array_push($result, $item); $item = []; $item['id'] = $ui = $row['id']; } $item[$row['name']] = $row['value']; } if (count($item) > 0) { array_push($result, $item); } if (sizeof($result)) { return $result[0]; } return []; }
/** * Only run on tables which have an status column. * @return array */ public function countActive() { $select = new Select($this->table); $select->columns(array(STATUS_COLUMN_NAME, 'quantity' => new Expression('COUNT(*)')))->group(STATUS_COLUMN_NAME); $sql = new Sql($this->adapter, $this->table); $statement = $sql->prepareStatementForSqlObject($select); $results = $statement->execute(); $stats = array(); $statusMap = Bootstrap::get('status'); foreach ($results as $row) { if (isset($row[STATUS_COLUMN_NAME])) { $statSlug = $statusMap[$row[STATUS_COLUMN_NAME]]; $stats[$statSlug['name']] = (int) $row['quantity']; } } $vals = []; foreach ($statusMap as $value) { array_push($vals, $value['name']); } $possibleValues = array_values($vals); $makeMeZero = array_diff($possibleValues, array_keys($stats)); foreach ($makeMeZero as $unsetActiveColumn) { $stats[$unsetActiveColumn] = 0; } $stats['total'] = array_sum($stats); return $stats; }
/** * Get URL info * * @param string $url * * @return array */ public function getLink($url) { $info = []; // @TODO: use oEmbed // @TODO: better provider url validation // checking for 'youtube.com' for a valid youtube video is wrong // we can also be using youtube.com/img/a/youtube/image.jpg // which should fallback to ImageProvider // instead checking for a url with 'youtube.com/watch' with v param or youtu.be/ $embedManager = Bootstrap::get('embedManager'); try { $info = $embedManager->parse($url); } catch (\Exception $e) { $info = $this->getImageFromURL($url); } if ($info) { $info['date_uploaded'] = DateUtils::now(); $info['storage_adapter'] = $this->getConfig('adapter'); $info['charset'] = isset($info['charset']) ? $info['charset'] : ''; } return $info; }
/** * Get ui options * * @param $tbl_name * @param $col_name * @param $datatype_name */ public static function getUIOptions($tbl_name, $col_name, $datatype_name) { $ui; $result = array(); $item = array(); $zendDb = Bootstrap::get('zendDb'); $sth = $zendDb->query("SELECT ui_name as id, name, value FROM directus_ui WHERE column_name='{$col_name}' AND table_name='{$tbl_name}' AND ui_name='{$datatype_name}' ORDER BY ui_name"); $rows = $sth->execute(); foreach ($rows as $row) { //$sth->fetch(PDO::FETCH_ASSOC)) { //first case if (!isset($ui)) { $item['id'] = $ui = $row['id']; } //new ui = new item if ($ui != $row['id']) { array_push($result, $item); $item = array(); $item['id'] = $ui = $row['id']; } $item[$row['name']] = $row['value']; } if (count($item) > 0) { array_push($result, $item); } if (sizeof($result)) { return $result[0]; } return array(); }
protected function logger() { return Bootstrap::get('app')->getLog(); }
/** * @inheritDoc */ public function getColumns($tableName, $params = null) { $zendDb = Bootstrap::get('zendDb'); $acl = Bootstrap::get('acl'); $blacklist = $readFieldBlacklist = $acl->getTablePrivilegeList($tableName, $acl::FIELD_READ_BLACKLIST); $columnName = isset($params['column_name']) ? $params['column_name'] : -1; $selectOne = new Select(); $selectOne->quantifier($selectOne::QUANTIFIER_DISTINCT); $selectOne->columns(['id' => 'COLUMN_NAME', 'column_name' => 'COLUMN_NAME', 'type' => new Expression('UCASE(C.DATA_TYPE)'), 'char_length' => 'CHARACTER_MAXIMUM_LENGTH', 'is_nullable' => 'IS_NULLABLE', 'default_value' => 'COLUMN_DEFAULT', 'comment' => new Expression('IFNULL(comment, COLUMN_COMMENT)'), 'sort' => new Expression('IFNULL(sort, ORDINAL_POSITION)'), 'column_type' => 'COLUMN_TYPE']); $selectOne->from(['C' => new TableIdentifier('COLUMNS', 'INFORMATION_SCHEMA')]); $selectOne->join(['D' => 'directus_columns'], 'C.COLUMN_NAME = D.column_name AND C.TABLE_NAME = D.table_name', ['ui', 'hidden_list' => new Expression('IFNULL(hidden_list, 0)'), 'hidden_input' => new Expression('IFNULL(hidden_input, 0)'), 'relationship_type', 'related_table', 'junction_table', 'junction_key_left', 'junction_key_right', 'required' => new Expression('IFNULL(D.required, 0)')], $selectOne::JOIN_LEFT); $where = new Where(); $where->equalTo('C.TABLE_SCHEMA', $zendDb->getCurrentSchema())->equalTo('C.TABLE_NAME', $tableName)->nest()->addPredicate(new \Zend\Db\Sql\Predicate\Expression('"' . $columnName . '" = -1'))->OR->equalTo('C.column_name', $columnName)->unnest(); if (count($blacklist)) { $where->addPredicate(new NotIn('C.COLUMN_NAME', $blacklist)); } $selectOne->where($where); $selectTwo = new Select(); $selectTwo->columns(['id' => 'column_name', 'column_name', 'type' => new Expression('UCASE(data_type)'), 'char_length' => new Expression('NULL'), 'is_nullable' => new Expression('"NO"'), 'default_value' => new Expression('NULL'), 'comment', 'sort', 'column_type' => new Expression('NULL'), 'ui', 'hidden_list', 'hidden_input', 'relationship_type', 'related_table', 'junction_table', 'junction_key_left', 'junction_key_right', 'required' => new Expression('IFNULL(required, 0)')]); $selectTwo->from('directus_columns'); $where = new Where(); $where->equalTo('TABLE_NAME', $tableName)->addPredicate(new In('data_type', ['alias', 'MANYTOMANY', 'ONETOMANY']))->nest()->addPredicate(new \Zend\Db\Sql\Predicate\Expression('"' . $columnName . '" = -1'))->OR->equalTo('column_name', $columnName)->unnest()->addPredicate(new IsNotNull('relationship_type')); if (count($blacklist)) { $where->addPredicate(new NotIn('COLUMN_NAME', $blacklist)); } $selectTwo->where($where); $selectTwo->order('sort'); $selectOne->combine($selectTwo); $sql = new Sql($zendDb); $statement = $sql->prepareStatementForSqlObject($selectOne); $result = $statement->execute(); return iterator_to_array($result); }