getTable(); } /** * Get a fresh timestamp for the model. * * @return \Illuminate\Support\Carbon */ public function now() { return $this->freshTimestamp(); } /** * Get model class name * * @param string $modelName model name * @param string|object $moduleName module name or instance * @return string */ public function modelClass(string $modelName, $moduleName): string { return bff::model($moduleName, $modelName, true); } /** * Create a new Eloquent query builder for the model. * > Use extended EloquentBuilder * * @param \Illuminate\Database\Query\Builder|QueryBuilder $query * @return \Illuminate\Database\Eloquent\Builder|EloquentBuilder */ public function newEloquentBuilder($query) { return new EloquentBuilder($query); } /** * Get a new query builder instance for the connection. * > Use extended QueryBuilder * * @return \Illuminate\Database\Query\Builder|QueryBuilder */ protected function newBaseQueryBuilder() { return $this->getConnection()->query(); } /** * Does model use any langs trait * * @return bool */ public function usesLangs() { return method_exists($this, 'isLangColumn'); } /** * Does model use Langs table * * @return bool */ public function usesLangsTable() { return method_exists($this, 'langLoad'); } /** * Does model use Langs columns * * @return bool */ public function usesLangsColumns() { return method_exists($this, 'langDataTransform'); } /** * Does model use LangsColumnsJson trait * @return bool */ public function usesLangsColumnsJson() { return method_exists($this, 'langColumnsJson'); } /** * Merge relations * * @param QueryBuilder $query * @param string|array $relations * @param string|array $columns * @param string $joinType * @return QueryBuilder */ public function scopeMerge($query, $relations, $columns = null, $joinType = 'left') { $columns = ($columns ? $columns : ['*']); if (is_string($relations)) { $relations = [$relations => $columns]; } $tableMain = $this->getTable(); foreach ((array) $relations as $key => $cols) { $rel = (!is_numeric($key) ? $key : $cols); if (stripos($rel, ' as ') !== false) { $segments = preg_split('/\s+as\s+/i', $rel); $rel = $segments[0]; $relAlias = $segments[1]; } if (strpos($rel, '.') === false && method_exists($this, $rel)) { $cols = (is_numeric($key) ? $columns : $cols); $relation = $this->$rel(); $model = $relation->getRelated(); $tableJoinAlias = (!empty($relAlias) ? $relAlias : $rel); if (! $query->hasColumns()) { $query->addSelect($tableMain . '.*'); } $query->join( $model->getTable() . ' as ' . $tableJoinAlias, $tableJoinAlias . '.' . $relation->getForeignKeyName(), '=', $relation->getQualifiedParentKeyName(), $joinType ); if ($model->usesLangsTable()) { $model->joinLangs($query, ['*'], $tableJoinAlias); } if (is_string($cols)) { $cols = explode(',', $cols); } foreach ($cols as $column) { $query->addSelect($model->prefixColumn(trim($column), $tableJoinAlias)); } } } return $query; } /** * Enabled scope * * @param QueryBuilder $query * @param int $value * @return QueryBuilder */ public function scopeEnabled($query, $value = 1) { return $query->where($this->getTable() . '.enabled', '=', $value); } /** * Toggle column value * * @param string $column column name to invert value * @param array $extra columns to update * @return bool */ public function toggle(string $column, array $extra = []): bool { if (! empty($column)) { return $this->update(array_merge([$column => ($this->{$column} ? 0 : 1)], $extra)); } return false; } /** * Load model data to edit in admin panel * * @param int|mixed $id record id * @param array $with relations * @param bool $asArray convert to array * @param array $opts * @return static|array data */ public function editAdmin($id, array $with = [], bool $asArray = false, array $opts = []) { return $this->one($id, ($asArray ? [] : ['*']), $with, true, $opts); } /** * Forms: load event * @param mixed $id record id * @param array $opts * @return static|array */ public function onAdminFormLoad($id, array $opts = []) { return $this->editAdmin($id, $opts['with'] ?? [], true, $opts); } /** * Add table prefix to column name * * @param string|array $column * @param string|null $table table to prefix with or null (model table) * @return string prefixed column name */ public function prefixColumn($column, ?string $table = null) { if ($column instanceof Expression) { return $column; } if (is_array($column)) { foreach ($column as $k => $col) { $column[$k] = $this->prefixColumn($col, $table); } return $column; } return (mb_strpos($column, '.') === false ? ($table ? $table : $this->getTable()) . '.' . $column : $column); } /** * Prefix columns to avoid "column 'key' in where clause is ambiguous" error * * @param \Illuminate\Database\Query\Builder|QueryBuilder $query * @return void */ public function prefixWhereColumns($query) { foreach ($query->wheres as &$where) { if (isset($where['column']) && strpos($where['column'], '.') === false) { $where['column'] = $this->prefixColumn($where['column']); } elseif ($where['type'] === 'Nested' && isset($where['query'])) { $this->prefixWhereColumns($where['query']); } } } /** * Rotate table drag&drop wrapper * * @param string $column * @param array $opts * @return bool */ public function rotateTableDnd(string $column, array $opts = []): bool { $opts = array_merge([ 'additionalQuery' => '', 'tree' => false, 'pid' => 'pid', 'prefix' => 'dnd-', 'idField' => $this->getKeyName(), ], $opts); return bff::database()->rotateTablednd( $this->getTable(), $opts['additionalQuery'], $opts['idField'], $column, $opts['tree'], $opts['pid'], $opts['prefix'] ); } /** * Rotate Up, Down * @param integer $id * @param string $direction * @param array $opts * @return bool */ public function rotateUpDown(int $id, string $direction, array $opts = []): bool { $opts['fields']['id'] = $this->getKeyName(); return bff::database()->rotateUpDown($this->getTable(), $id, $direction, $opts); } /** * Encode the given value as JSON. * @param mixed $value * @return string */ protected function asJson($value) { return json_encode($value, JSON_UNESCAPED_UNICODE); } }