* @git Joomla Component Builder * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace VDM\Joomla\Abstraction; use VDM\Joomla\Interfaces\Tableinterface; /** * Base Table * * @since 3.2.0 */ abstract class BaseTable implements Tableinterface { /** * All areas/views/tables with their field details * * @var array * @since 3.2.0 **/ protected array $tables; /** * All default fields * * @var array * @since 3.2.1 **/ protected array $defaults = [ 'id' => [ 'order' => -1, 'name' => 'id', 'label' => 'ID', 'type' => 'text', 'title' => false, 'list' => NULL, 'store' => NULL, 'tab_name' => NULL, 'db' => [ 'type' => 'INT(11)', 'default' => 'EMPTY', 'auto_increment' => true, 'primary_key' => true, 'null_switch' => 'NOT NULL' ] ], 'asset_id' => [ 'name' => 'asset_id', 'label' => NULL, 'type' => NULL, 'title' => false, 'list' => NULL, 'store' => NULL, 'tab_name' => NULL, 'db' => [ 'type' => 'INT(10) unsigned', 'default' => '0', 'null_switch' => 'NOT NULL', 'comment' => 'FK to the #__assets table.' ] ], 'ordering' => [ 'name' => 'ordering', 'label' => 'Ordering', 'type' => 'number', 'title' => false, 'list' => NULL, 'store' => NULL, 'tab_name' => NULL, 'db' => [ 'type' => 'INT(11)', 'default' => '0', 'null_switch' => 'NOT NULL' ] ], 'published' => [ 'name' => 'published', 'label' => 'Status', 'type' => 'list', 'title' => false, 'list' => NULL, 'store' => NULL, 'tab_name' => NULL, 'db' => [ 'type' => 'TINYINT(3)', 'default' => '1', 'null_switch' => 'NOT NULL', 'key' => true, 'key_name' => 'state' ] ], 'modified_by' => [ 'name' => 'modified_by', 'label' => 'Modified by', 'type' => 'user', 'title' => false, 'list' => NULL, 'store' => NULL, 'tab_name' => NULL, 'db' => [ 'type' => 'INT(10) unsigned', 'default' => '0', 'null_switch' => 'NOT NULL', 'key' => true, 'key_name' => 'modifiedby' ] ], 'modified' => [ 'name' => 'modified', 'label' => 'Modified', 'type' => 'calendar', 'title' => false, 'list' => NULL, 'store' => NULL, 'tab_name' => NULL, 'db' => [ 'type' => 'DATETIME', 'default' => '0000-00-00 00:00:00', 'null_switch' => 'NOT NULL' ] ], 'created_by' => [ 'name' => 'created_by', 'label' => 'Created by', 'type' => 'user', 'title' => false, 'list' => NULL, 'store' => NULL, 'tab_name' => NULL, 'db' => [ 'type' => 'INT(10) unsigned', 'default' => '0', 'null_switch' => 'NOT NULL', 'key' => true, 'key_name' => 'createdby' ] ], 'created' => [ 'name' => 'created', 'label' => 'Created', 'type' => 'calendar', 'title' => false, 'list' => NULL, 'store' => NULL, 'tab_name' => NULL, 'db' => [ 'type' => 'DATETIME', 'default' => '0000-00-00 00:00:00', 'null_switch' => 'NOT NULL' ] ], 'checked_out' => [ 'name' => 'checked_out', 'label' => NULL, 'type' => NULL, 'title' => false, 'list' => NULL, 'store' => NULL, 'tab_name' => NULL, 'db' => [ 'type' => 'INT(10) unsigned', 'default' => '0', 'null_switch' => 'NOT NULL', 'key' => true, 'key_name' => 'checkout' ] ], 'checked_out_time' => [ 'name' => 'checked_out_time', 'label' => NULL, 'type' => NULL, 'title' => false, 'list' => NULL, 'store' => NULL, 'tab_name' => NULL, 'db' => [ 'type' => 'DATETIME', 'default' => '0000-00-00 00:00:00', 'null_switch' => 'NOT NULL' ] ], 'hits' => [ 'name' => 'hits', 'label' => 'Hits', 'type' => 'number', 'title' => false, 'list' => NULL, 'store' => NULL, 'tab_name' => NULL, 'db' => [ 'type' => 'INT(10) unsigned', 'default' => '0', 'null_switch' => 'NOT NULL' ] ], 'version' => [ 'name' => 'version', 'label' => 'Version', 'type' => 'text', 'title' => false, 'list' => NULL, 'store' => NULL, 'tab_name' => NULL, 'db' => [ 'type' => 'INT(10) unsigned', 'default' => '1', 'null_switch' => 'NOT NULL' ] ], 'params' => [ 'name' => 'params', 'label' => NULL, 'type' => NULL, 'title' => false, 'list' => NULL, 'store' => 'json', 'tab_name' => NULL, 'db' => [ 'type' => 'TEXT', 'default' => 'EMPTY', 'null_switch' => 'NULL' ] ] ]; /** * Get any value from a item/field/column of an area/view/table * Example: $this->get('table_name', 'field_name', 'value_key'); * Get an item/field/column of an area/view/table * Example: $this->get('table_name', 'field_name'); * Get all items/fields/columns of an area/view/table * Example: $this->get('table_name'); * Get all areas/views/tables with all their item/field/column details * Example: $this->get('All'); * Example: $this->get(); * * @param string|null $table The table * @param string|null $field The field * @param string|null $key The value key * * @return mixed * @since 3.2.1 */ public function get(?string $table = null, ?string $field = null, ?string $key = null) { // Return specific value if ($table && $field && $key) { return $this->tables[$table][$field][$key] ?? $this->getDefaultKey($field, $key); } // Return field within table if ($table && $field) { return $this->tables[$table][$field] ?? $this->getDefault($field); } // Return all fields in a table or all tables if 'All' is passed if ($table) { if (strtoupper($table) === 'ALL') { return $this->tables; } return $this->tables[$table] ?? null; } // Return all tables return $this->tables; } /** * Get title field from an area/view/table * * @param string $table The area * * @return ?array * @since 3.2.0 */ public function title(string $table): ?array { // return the title item/field/column of an area/view/table if (($table = $this->get($table)) !== null) { foreach ($table as $item) { if ($item['title']) { return $item; } } } // none found return null; } /** * Get title field name * * @param string $table The area * * @return string * @since 3.2.0 */ public function titleName(string $table): string { // return the title name of an area/view/table if (($field = $this->title($table)) !== null) { return $field['name']; } // none found default to ID return 'id'; } /** * Get all tables * * @return array * @since 3.2.0 */ public function tables(): array { // return all areas/views/tables return array_keys($this->tables); } /** * Check if a table (and field) exist * * @param string $table The area * @param string|null $field The area * * @return bool * @since 3.2.0 */ public function exist(string $table, ?string $field = null): bool { if (isset($this->tables[$table])) { // if we have a field if (is_string($field)) { if (isset($this->tables[$table][$field])) { return true; } } else { return true; } } return $this->isDefault($field); } /** * Get all fields of an area/view/table * * @param string $table The area * @param bool $default Add the default fields * @param bool $details Add/Leave fields the details * * @return array|null On success an array of fields * @since 3.2.0 */ public function fields(string $table, bool $default = false, bool $details = false): ?array { // Retrieve fields from the specified table $fields = $this->get($table); if ($fields === null) { return null; } // Determine the fields output based on the $default and $details flags if ($details) { return $default ? $this->addDefaultDetails($fields) : $fields; } $fieldKeys = array_keys($fields); return $default ? $this->addDefault($fieldKeys) : $fieldKeys; } /** * Add the default fields * * @param array $fields The table dynamic fields * * @return array Fields (with defaults added) * @since 3.2.0 */ protected function addDefault(array $fields): array { // add default fields foreach ($this->defaults as $default) { if (in_array($default['name'], $fields)) { continue; } // used just for loading the fields $order = $default['order'] ?? 1; unset($default['order']); if ($order < 0) { array_unshift($fields, $default['name']); } else { $fields[] = $default['name']; } } return $fields; } /** * Add the default fields * * @param array $fields The table dynamic fields * * @return array Fields (with defaults details added) * @since 3.2.0 */ protected function addDefaultDetails(array $fields): array { // add default fields foreach ($this->defaults as $default) { // remove ordering for now unset($default['order']); if (!isset($fields[$default['name']])) { $fields[$default['name']] = $default; } } return $fields; } /** * Check if the field is a default field * * @param string $field The field to check * * @return bool True if a default field * @since 3.2.0 */ protected function isDefault(string $field): bool { return isset($this->defaults[$field]); } /** * Get a default field * * @param string $field The field to check * * @return array|null True if a default field * @since 3.2.0 */ protected function getDefault(string $field): ?array { return $this->defaults[$field] ?? null; } /** * Get a default field property * * @param string $field The field to check * @param string $key The field key/property to check * * @return mixed String value if a default field property exist * @since 3.2.0 */ protected function getDefaultKey(string $field, string $key) { return $this->defaults[$field][$key] ?? null; } }