@since 1.0.0 * * @return string The properly namespaced schema version option key. */ public function get_schema_version_option(): string { return 'stellar_schema_version_' . static::get_schema_slug(); } /** * {@inheritdoc} */ public function get_sql() { return $this->get_definition(); } /** * Gets the previous schema version option value. * * @since 1.0.0 * * @return string|null The previous version stored in wp_options. */ public function get_stored_previous_version() { return get_option($this->get_schema_previous_version_option(), null); } /** * Gets the current schema version option value. * * @since 1.0.0 * * @return string|null The current version stored in wp_options. */ public function get_stored_version() { return get_option($this->get_schema_version_option(), null); } /** * Returns the table creation SQL in the format supported * by the `dbDelta` function. * * @since 3.0.0 * * @return string The table creation SQL, in the format supported * by the `dbDelta` function. */ public function get_definition(): string { global $wpdb; $table_name = static::table_name(true); $charset_collate = $wpdb->get_charset_collate(); $columns = static::get_columns(); $columns_definitions = []; $indexes_definitions = []; foreach ($columns as $column) { [$column_definition, $index_definition] = $column->get_definition(); $columns_definitions[] = $column_definition; $indexes_definitions[] = $index_definition; } $indexes_definitions = array_filter($indexes_definitions); $indexes_sql = !empty($indexes_definitions) ? implode(',' . PHP_EOL, $indexes_definitions) : ''; $columns_sql = implode(',' . PHP_EOL, $columns_definitions); $columns_sql = $indexes_sql ? $columns_sql . ',' . PHP_EOL : $columns_sql; return "\n\t\t\tCREATE TABLE `{$table_name}` (\n\t\t\t\t{$columns_sql}{$indexes_sql}\n\t\t\t) {$charset_collate};\n\t\t"; } /** * {@inheritdoc} */ public function get_version(): string { return static::SCHEMA_VERSION; } /** * {@inheritdoc} */ public static function group_name() { return static::$group; } /** * Checks if an index already exists on the table. * * @since 1.0.0 * * @param string $index The name of the index to check for. * @param string|null $table_name The table name to search the index for, or `null` * to use this table name. * * @throws \TEC\Common\StellarWP\DB\Database\Exceptions\DatabaseQueryException If the query fails. * * @return bool Whether the table already has an index or not. */ public function has_index($index, $table_name = null) { $table_name = $table_name ?: static::table_name(true); $index = $index ?: 'PRIMARY'; $count = $this->db::table($this->db::raw('information_schema.statistics'))->whereRaw('WHERE TABLE_SCHEMA = DATABASE()')->where('TABLE_NAME', $table_name)->where('INDEX_NAME', $index)->count(); return $count >= 1; } /** * {@inheritdoc} */ public function is_schema_current() { if (!static::SCHEMA_VERSION || !$this->get_schema_version_option()) { // @todo Error? } $version_applied = $this->get_stored_version() ?: ''; $current_version = $this->get_version(); return version_compare($version_applied, $current_version, '=='); } /** * Update our stored version with what we have defined. */ public function sync_stored_version() { $current_version = $this->get_version(); if (!add_option($this->get_schema_version_option(), $current_version)) { update_option($this->get_schema_version_option(), $current_version); } } /** * {@inheritdoc} */ public static function table_name($with_prefix = true) { $table_name = static::base_table_name(); if ($with_prefix) { global $wpdb; $table_name = $wpdb->prefix . $table_name; } return $table_name; } /** * {@inheritdoc} */ public static function uid_column(): string { $primary_columns = static::primary_columns(); return array_values($primary_columns)[0]; } /** * Gets the primary columns for the table. * * @since 3.0.0 * * @return array The primary columns for the table. */ public static function primary_columns(): array { return static::get_current_schema()->get_primary_key()->get_columns(); } /** * {@inheritdoc} */ public function update() { // @phpstan-ignore-next-line require_once ABSPATH . 'wp-admin/includes/upgrade.php'; $sql = $this->get_sql(); $results = []; try { /** * Hookable action before the table schema has updated. * * @since 3.0.0 * * @param string $table_name The prefix-less table name. * @param Table $table The table object. */ do_action('stellarwp_schema_table_before_update_' . static::get_schema_slug(), static::table_name(), $this); /** * Hookable action before the table schema has updated. * * @since 3.0.0 * * @param string $table_name The prefix-less table name. * @param Table $table The table object. */ do_action('stellarwp_schema_table_before_update', static::table_name(), $this); $results = (array) $this->db::delta($sql); $this->archive_previous_version(); $this->sync_stored_version(); $results = $this->after_update($results); /** * Hookable action after the table schema has updated. * * @since 3.0.0 * * @param string $table_name The prefix-less table name. * @param array $results The results of the table schema updates. * @param Table $table The table object. */ do_action('stellarwp_schema_table_after_update_' . static::get_schema_slug(), static::table_name(), $results, $this); /** * Hookable action after the table schema has updated. * * @since 3.0.0 * * @param string $table_name The prefix-less table name. * @param array $results The results of the table schema updates. * @param Table $table The table object. */ do_action('stellarwp_schema_table_after_update', static::table_name(), $results, $this); } catch (Exception $e) { if (!has_action('stellarwp_schema_table_update_error_' . static::get_schema_slug()) && !has_action('stellarwp_schema_table_update_error')) { throw $e; } /** * Hookable action after the table schema has failed to update. * * @since 3.0.0 * * @param Exception $e The exception. * @param Table $table The table object. */ do_action('stellarwp_schema_table_update_error_' . static::get_schema_slug(), $e, $this); /** * Hookable action after the table schema has failed to update. * * @since 3.0.0 * * @param Exception $e The exception. * @param Table $table The table object. */ do_action('stellarwp_schema_table_update_error', $e, $this); } return $results; } /** * Checks if a foreign key exists on a table. * * @since 1.1.3 * * @param string $foreign_key The foreign key to check for. * @param string $table_name The table name to check. Defaults to the current table. * * @return bool Whether the foreign key exists on the table. */ public function has_foreign_key(string $foreign_key, string $table_name = ''): bool { $table_name = $table_name ?: static::table_name(); $count = $this->db::table($this->db::raw('information_schema.statistics'))->whereRaw('WHERE TABLE_SCHEMA = DATABASE()')->where('TABLE_NAME', $table_name)->where('INDEX_NAME', $foreign_key)->count(); return $count >= 1; } /** * {@inheritdoc} */ public static function transform_from_array(array $result_array) { return $result_array; } }