diff --git a/.gitattributes b/.gitattributes index 1cbf2b7..83d27c6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,12 +1,11 @@ /.github export-ignore -/.yarn export-ignore /docs export-ignore -/tests export-ignore /.codeclimate.yml export-ignore /.editorconfig export-ignore /.gitattributes export-ignore /.gitignore export-ignore /CODE_OF_CONDUCT.md export-ignore +/composer.lock export-ignore /CONTRIBUTING.md export-ignore /LICENSE export-ignore /README.md export-ignore diff --git a/.gitignore b/.gitignore index ff89e47..155f521 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,2 @@ -node_modules +languages/*.php vendor -test.php -php_errors.log - -.yarn/* -.yarn/cache -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/sdks -!.yarn/versions diff --git a/composer.lock b/composer.lock index 23c89dc..89e26e4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a762970ddcb11ee1a26bab32fbc7f6bc", + "content-hash": "7d2bb0da0dd22ced214347a658af3460", "packages": [ { "name": "automattic/jetpack-constants", @@ -761,16 +761,16 @@ }, { "name": "oblak/wordpress-coding-standard", - "version": "v1.0.1", + "version": "v1.1.1", "source": { "type": "git", "url": "https://github.com/oblakstudio/wordpress-coding-standards.git", - "reference": "1200c99b65b7ea0698bce345bbe10e3b635fab58" + "reference": "b1f62524c09c639a9fdf4272ad3fd113259a8952" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/oblakstudio/wordpress-coding-standards/zipball/1200c99b65b7ea0698bce345bbe10e3b635fab58", - "reference": "1200c99b65b7ea0698bce345bbe10e3b635fab58", + "url": "https://api.github.com/repos/oblakstudio/wordpress-coding-standards/zipball/b1f62524c09c639a9fdf4272ad3fd113259a8952", + "reference": "b1f62524c09c639a9fdf4272ad3fd113259a8952", "shasum": "" }, "require": { @@ -780,7 +780,8 @@ "phpcompatibility/phpcompatibility-wp": "2.1.4", "phpcsstandards/phpcsextra": "1.1.0", "phpcsstandards/phpcsutils": "1.0.8", - "squizlabs/php_codesniffer": "3.7.2", + "slevomat/coding-standard": "^8.14", + "squizlabs/php_codesniffer": "3.8.1", "wp-coding-standards/wpcs": "^3" }, "require-dev": { @@ -808,9 +809,9 @@ ], "support": { "issues": "https://github.com/oblakstudio/wordpress-coding-standards/issues", - "source": "https://github.com/oblakstudio/wordpress-coding-standards/tree/v1.0.1" + "source": "https://github.com/oblakstudio/wordpress-coding-standards/tree/v1.1.1" }, - "time": "2023-12-09T17:30:35+00:00" + "time": "2024-01-24T23:43:48+00:00" }, { "name": "phpcompatibility/php-compatibility", @@ -1122,18 +1123,130 @@ }, "time": "2023-07-16T21:39:41+00:00" }, + { + "name": "phpstan/phpdoc-parser", + "version": "1.25.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "bd84b629c8de41aa2ae82c067c955e06f1b00240" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/bd84b629c8de41aa2ae82c067c955e06f1b00240", + "reference": "bd84b629c8de41aa2ae82c067c955e06f1b00240", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^4.15", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.25.0" + }, + "time": "2024-01-04T17:06:16+00:00" + }, + { + "name": "slevomat/coding-standard", + "version": "8.14.1", + "source": { + "type": "git", + "url": "https://github.com/slevomat/coding-standard.git", + "reference": "fea1fd6f137cc84f9cba0ae30d549615dbc6a926" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/fea1fd6f137cc84f9cba0ae30d549615dbc6a926", + "reference": "fea1fd6f137cc84f9cba0ae30d549615dbc6a926", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", + "php": "^7.2 || ^8.0", + "phpstan/phpdoc-parser": "^1.23.1", + "squizlabs/php_codesniffer": "^3.7.1" + }, + "require-dev": { + "phing/phing": "2.17.4", + "php-parallel-lint/php-parallel-lint": "1.3.2", + "phpstan/phpstan": "1.10.37", + "phpstan/phpstan-deprecation-rules": "1.1.4", + "phpstan/phpstan-phpunit": "1.3.14", + "phpstan/phpstan-strict-rules": "1.5.1", + "phpunit/phpunit": "8.5.21|9.6.8|10.3.5" + }, + "type": "phpcodesniffer-standard", + "extra": { + "branch-alias": { + "dev-master": "8.x-dev" + } + }, + "autoload": { + "psr-4": { + "SlevomatCodingStandard\\": "SlevomatCodingStandard/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", + "keywords": [ + "dev", + "phpcs" + ], + "support": { + "issues": "https://github.com/slevomat/coding-standard/issues", + "source": "https://github.com/slevomat/coding-standard/tree/8.14.1" + }, + "funding": [ + { + "url": "https://github.com/kukulich", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", + "type": "tidelift" + } + ], + "time": "2023-10-08T07:28:08+00:00" + }, { "name": "squizlabs/php_codesniffer", - "version": "3.7.2", + "version": "3.8.1", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" + "reference": "14f5fff1e64118595db5408e946f3a22c75807f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", - "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/14f5fff1e64118595db5408e946f3a22c75807f7", + "reference": "14f5fff1e64118595db5408e946f3a22c75807f7", "shasum": "" }, "require": { @@ -1143,11 +1256,11 @@ "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" }, "bin": [ - "bin/phpcs", - "bin/phpcbf" + "bin/phpcbf", + "bin/phpcs" ], "type": "library", "extra": { @@ -1162,20 +1275,29 @@ "authors": [ { "name": "Greg Sherwood", - "role": "lead" + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", "keywords": [ "phpcs", "standards", "static analysis" ], "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" }, "funding": [ { @@ -1191,7 +1313,7 @@ "type": "open_collective" } ], - "time": "2023-02-22T23:07:41+00:00" + "time": "2024-01-11T20:47:48+00:00" }, { "name": "wp-coding-standards/wpcs", diff --git a/languages/oblak-plugin-installer-sr_RS.mo.php b/languages/oblak-plugin-installer-sr_RS.mo.php deleted file mode 100644 index 903f5a5..0000000 --- a/languages/oblak-plugin-installer-sr_RS.mo.php +++ /dev/null @@ -1,2 +0,0 @@ -'','report-msgid-bugs-to'=>'','po-revision-date'=>'2022-10-25 13:08+0200','last-translator'=>'','language-team'=>'','language'=>'sr_RS','mime-version'=>'1.0','content-type'=>'text/plain; charset=UTF-8','content-transfer-encoding'=>'8bit','plural-forms'=>'nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);','x-generator'=>'Poedit 3.2','x-domain'=>'oblak-plugin-installer','messages'=>['%1$d update functions completed. Database version is %2$s'=>'%1$d ажурирања је извршено. Везрија базе података је %2$s','All database tables are up to date.'=>'Све табеле базе података су ажурне.','Creating missing tables...'=>'Креирам недостајуће табеле...','Found %1$d updates (%2$s)'=>'Нађено %1$d ажурирања (%2$s)','Missing'=>'Недостаје','No updates required. Database version is %s'=>'Ажурирање није потребно. Верзија базе података је %s','Plugin schema version not set'=>'Верзија шеме базе података додатка није подешена','Plugin slug not set'=>'Подложак додатка није подешен','Plugin version not set'=>'Верзија додатка није подешена','Run the command again with --create to create the missing tables.'=>'Покрените команду поново са --create параметром како бисте креирали недостајуће табеле.','Table %1$s: %2$s'=>'Табела %1$s: %2$s','The following database tables are out of sync with the schema:'=>'Следеће табеле нису синхронизоване са шемом:','The following tables are missing: '=>'Следеће табеле недостају: ','There was an error creating the missing tables.'=>'Дошло је до грешке приликом креирања табела.','Updating database'=>'Ажурирам базу података']]; diff --git a/src/Base_Plugin_Installer.php b/src/Base_Plugin_Installer.php index d68a70d..9bd3cd1 100644 --- a/src/Base_Plugin_Installer.php +++ b/src/Base_Plugin_Installer.php @@ -10,8 +10,6 @@ use Automattic\Jetpack\Constants; use Oblak\WP\Admin_Notice_Manager; - -use Exception; use WP_CLI; use function WP_CLI\Utils\make_progress_bar; @@ -69,7 +67,7 @@ protected function __construct() { $this->set_defaults(); $this->verify_defaults(); - $this->db_version = $this->db_version ?? $this->version; + $this->db_version ??= $this->version; } /** @@ -88,9 +86,9 @@ final public static function instance() { * @return string */ private static function class_basename( $classname ) { - $classname = is_object( $classname ) ? get_class( $classname ) : $classname; + $classname = \is_object( $classname ) ? $classname::class : $classname; - return str_replace( '\\', '/', $classname ); + return \str_replace( '\\', '/', $classname ); } /** @@ -103,48 +101,53 @@ abstract protected function set_defaults(); /** * Verifies the class defaults. * - * @throws Exception If the plugin slug is not set, or if the plugin version is not set. + * @throws \Exception If the plugin slug is not set, or if the plugin version is not set. */ - final protected function verify_defaults() { + protected function verify_defaults() { if ( '' === $this->version ) { - throw new Exception( esc_html__( 'Plugin version not set', 'oblak-plugin-installer' ) ); + throw new \Exception( \esc_html__( 'Plugin version not set', 'oblak-plugin-installer' ) ); } if ( '' === $this->slug ) { - throw new Exception( esc_html__( 'Plugin slug not set', 'oblak-plugin-installer' ) ); + throw new \Exception( \esc_html__( 'Plugin slug not set', 'oblak-plugin-installer' ) ); } - if ( '' === $this->db_version && ! empty( $this->get_schema() ) ) { - throw new Exception( esc_html__( 'Plugin schema version not set', 'oblak-plugin-installer' ) ); + if ( '' === $this->db_version && '' !== $this->get_schema() ) { + throw new \Exception( \esc_html__( 'Plugin schema version not set', 'oblak-plugin-installer' ) ); } } /** * Initialize and hook me baby one more time */ - final public function init() { - add_action( 'init', array( $this, 'load_textdomain' ) ); - add_action( 'init', array( $this, 'check_version' ) ); - add_action( 'admin_init', array( $this, 'install_actions' ) ); - add_action( 'cli_init', array( $this, 'register_commands' ) ); - add_filter( 'woocommerce_debug_tools', array( $this, 'add_debug_tools' ), ( 99 + count( static::$instances ) ), 1 ); + public function init() { + \add_action( 'init', array( $this, 'load_textdomain' ) ); + \add_action( 'init', array( $this, 'check_version' ) ); + \add_action( 'admin_init', array( $this, 'install_actions' ) ); + \add_action( 'cli_init', array( $this, 'register_commands' ) ); + \add_filter( + 'woocommerce_debug_tools', + array( $this, 'add_debug_tools' ), + 99 + \count( static::$instances ), + 1, + ); - add_action( "{$this->slug}_run_update_callback", array( $this, 'run_update_callback' ), 10, 2 ); + \add_action( "{$this->slug}_run_update_callback", array( $this, 'run_update_callback' ), 10, 2 ); } /** * Loads our textdomain file for translations */ - final public function load_textdomain() { - $locale = get_locale(); + public function load_textdomain() { + $locale = \get_locale(); - $mofile_path = dirname( __DIR__ ) . "/languages/oblak-plugin-installer-{$locale}.mo"; + $mofile_path = \dirname( __DIR__ ) . "/languages/oblak-plugin-installer-{$locale}.mo"; - if ( ! file_exists( $mofile_path ) ) { + if ( ! \file_exists( $mofile_path ) ) { return; } - load_textdomain( 'oblak-plugin-installer', $mofile_path ); + \load_textdomain( 'oblak-plugin-installer', $mofile_path ); } /** @@ -153,38 +156,40 @@ final public function load_textdomain() { * @return bool */ public function is_new_install() { - return is_null( get_option( "{$this->slug}_version", null ) ); + return \is_null( \get_option( "{$this->slug}_version", null ) ); } /** * Checks the plugin version and runs the updater if required */ - final public function check_version() { - $plugin_version = get_option( "{$this->slug}_version" ); + public function check_version() { + $plugin_version = \get_option( "{$this->slug}_version" ); $code_version = $this->version; - $needs_update = version_compare( $plugin_version, $code_version, '<' ); + $needs_update = \version_compare( $plugin_version, $code_version, '<' ); - if ( ! Constants::is_defined( 'IFRAME_REQUEST' ) && $needs_update ) { - $this->install(); - /** - * Action fired after plugin is updated - * - * @since 5.4.0 - */ - do_action( "{$this->slug}_updated" ); + if ( Constants::is_defined( 'IFRAME_REQUEST' ) || ! $needs_update ) { + return; } + + $this->install(); + /** + * Action fired after plugin is updated + * + * @since 5.4.0 + */ + \do_action( "{$this->slug}_updated" ); } /** * Runs the plugin installation */ - final public function install() { - if ( ! is_blog_installed() || get_transient( "{$this->slug}_installing" ) === 'yes' ) { + public function install() { + if ( ! \is_blog_installed() || 'yes' === \get_transient( "{$this->slug}_installing" ) ) { return; } - set_transient( "{$this->slug}_installing", 'yes', MINUTE_IN_SECONDS * 5 ); - Constants::set_constant( str_replace( '-', '_', strtoupper( $this->slug ) . '_INSTALLING' ), true ); + \set_transient( "{$this->slug}_installing", 'yes', MINUTE_IN_SECONDS * 5 ); + Constants::set_constant( \str_replace( '-', '_', \strtoupper( $this->slug ) . '_INSTALLING' ), true ); if ( $this->get_schema() ) { $this->create_tables(); @@ -204,10 +209,10 @@ final public function install() { * * @since 1.0.0 */ - do_action( "{$this->slug}_install" ); + \do_action( "{$this->slug}_install" ); } - delete_transient( "{$this->slug}_installing" ); + \delete_transient( "{$this->slug}_installing" ); } /** @@ -218,14 +223,14 @@ final public function install() { * * @since 2.0.0 */ - final public function create_tables() { + public function create_tables() { global $wpdb; $wpdb->hide_errors(); require_once ABSPATH . 'wp-admin/includes/upgrade.php'; - dbDelta( $this->get_schema() ); + \dbDelta( $this->get_schema() ); } /** @@ -237,6 +242,57 @@ protected function get_schema(): ?string { return null; } + /** + * Get the database table names which are not in sync + * + * @return array + */ + protected function get_unsynced_tables(): array { + global $wpdb; + + $queries = \dbDelta( $this->get_schema(), false ); + $tables = array(); + + foreach ( $queries as $table_name => $result ) { + if ( \is_numeric( $table_name ) || ! \str_contains( $table_name, $wpdb->prefix ) ) { + continue; + } + + $tables[] = \strtok( $table_name, '.' ); + } + + return $tables; + } + + /** + * Display a notice if the database tables are missing or out of sync + * + * @param bool $modify_notice Can we modify the notice. + * @param array $missing_tables List of missing tables. + */ + protected function display_missing_tables_notice( bool $modify_notice, array $missing_tables = array() ) { + if ( ! $modify_notice || ! $this->show_admin_notices ) { + return; + } + + Admin_Notice_Manager::get_instance()->add_notice( + "{$this->slug}_missing_tables", + array( + 'caps' => 'manage_woocommerce', + 'dismissible' => false, + 'message' => \sprintf( + '

%s - %s: %s

', + \esc_html( $this->slug ), + \esc_html__( 'The following tables are missing: ', 'oblak-plugin-installer' ), + \implode( ', ', $missing_tables ), + ), + 'persistent' => true, + 'type' => 'error', + ), + true, + ); + } + /** * Verifies if the database tables have been created. * @@ -244,50 +300,21 @@ protected function get_schema(): ?string { * @param bool $execute Are we executing table creation. * @return string[] List of missing tables. */ - final public function verify_base_tables( $modify_notice = true, $execute = false ) { + public function verify_base_tables( $modify_notice = true, $execute = false ) { require_once ABSPATH . 'wp-admin/includes/upgrade.php'; - global $wpdb; - if ( $execute ) { $this->create_tables(); } - $queries = dbDelta( $this->get_schema(), false ); - $missing_tables = array(); + $missing_tables = $this->get_unsynced_tables(); - foreach ( $queries as $table_name => $result ) { - if ( is_numeric( $table_name ) || ! str_contains( $table_name, $wpdb->prefix ) ) { - continue; - } - - $missing_tables[] = strtok( $table_name, '.' ); - } - - if ( 0 < count( $missing_tables ) ) { - if ( $modify_notice && $this->show_admin_notices ) { - Admin_Notice_Manager::get_instance()->add_notice( - "{$this->slug}_missing_tables", - array( - 'type' => 'error', - 'caps' => 'manage_woocommerce', - 'message' => sprintf( - '

%s - %s: %s

', - esc_html( $this->slug ), - esc_html__( 'The following tables are missing: ', 'oblak-plugin-installer' ), - implode( ', ', $missing_tables ), - ), - 'dismissible' => false, - 'persistent' => true, - ), - true - ); - } - } else { - if ( $modify_notice && $this->show_admin_notices ) { + if ( 0 < \count( $missing_tables ) ) { + $this->display_missing_tables_notice( $modify_notice ); + } elseif ( $modify_notice && $this->show_admin_notices ) { Admin_Notice_Manager::get_instance()->remove_notice( "{$this->slug}_missing_tables", true ); - } - update_option( "{$this->slug}_schema_version", $this->db_version ); + } else { + \update_option( "{$this->slug}_schema_version", $this->db_version ); } return $missing_tables; @@ -297,12 +324,14 @@ final public function verify_base_tables( $modify_notice = true, $execute = fals * Creates the default plugin options, if needed */ public function create_options() { + // Does nothing. } /** * Creates the default roles for the plugin. */ public function create_roles() { + // Does nothing. } /** @@ -311,47 +340,32 @@ public function create_roles() { * CPT registration, taxonomies, etc. */ public function setup_environment() { + // Does nothing. } /** * Creates terms for the plugin. */ public function create_terms() { + // Does nothing. } /** - * Adds the admin update notice. + * Get the admin update notice args. * - * @return void + * Enables users to change the plugin name, slug, update URL, etc... + * + * @param string $file_name Template name to get the args for. + * @return array{cli_update_faq: string, how_to_update: string, plugin_name: string, plugin_slug: string, scheduler_url: string, update_url: string} */ - protected function add_admin_update_notice() { - if ( ! $this->show_admin_notices ) { - return; - } - - $file_name = ''; - if ( $this->get_update_handler()?->needs_update() ) { - $next_scheduled_date = as_next_scheduled_action( "{$this->slug}_run_update_callback", null, "{$this->slug}-db-updates" ); - - //phpcs:ignore WordPress.Security.NonceVerification.Recommended - if ( $next_scheduled_date || ! empty( $_GET[ "do-update_{$this->slug}" ] ) ) { - $file_name = 'update-in-progress'; - } else { - $file_name = 'update-needed'; - } - } else { - $file_name = 'update-complete'; - } - - $file = $this->get_template_file( $file_name ); - + protected function get_notice_args( string $file_name ): array { $file_args = array( + 'cli_update_faq' => '#', + 'how_to_update' => '#', 'plugin_name' => $this->name, 'plugin_slug' => $this->slug, 'scheduler_url' => "tools.php?page=action-scheduler&s={$this->slug}_run_update&status=pending", 'update_url' => '', - 'how_to_update' => '#', - 'cli_update_faq' => '#', ); /** @@ -363,19 +377,56 @@ protected function add_admin_update_notice() { * * @since 1.0.0 */ - $file_args = apply_filters( "{$this->slug}_update_notice_args", $file_args, $file_name ); + return \apply_filters( "{$this->slug}_update_notice_args", $file_args, $file_name ); + } + + /** + * Get the admin update notice template. + * + * @return string + */ + protected function get_update_notice_template(): string { + if ( $this->get_update_handler()?->needs_update() ) { + $next_scheduled_date = \as_next_scheduled_action( + "{$this->slug}_run_update_callback", + null, + "{$this->slug}-db-updates", + ); + + //phpcs:ignore WordPress.Security.NonceVerification.Recommended + $doing_updates = \sanitize_text_field( \wp_unslash( $_GET[ "do-update_{$this->slug}" ] ?? '' ) ); + + return $next_scheduled_date || '' !== $doing_updates ? 'update-in-progress' : 'update-needed'; + } + + return 'update-complete'; + } + + /** + * Adds the admin update notice. + * + * @return void + */ + protected function add_admin_update_notice() { + if ( ! $this->show_admin_notices ) { + return; + } + + $name = $this->get_update_notice_template(); + $file = $this->get_template_file( $name ); + $args = $this->get_notice_args( $name ); Admin_Notice_Manager::get_instance()->add_notice( "{$this->slug}_update_notice", array( - 'type' => 'info', 'caps' => 'manage_options', + 'dismissible' => 'update-complete' === $file, + 'file_args' => $args, 'message' => $file, - 'file_args' => $file_args, - 'dismissible' => 'update-complete' === $file ? true : false, 'persistent' => false, + 'type' => 'info', ), - true + true, ); } @@ -385,8 +436,8 @@ protected function add_admin_update_notice() { * @param string $template_name Template name. * @return string Template file path. */ - final protected function get_template_file( $template_name ) { - $default_path = dirname( __DIR__ ) . "/templates/notice-{$template_name}.php"; + protected function get_template_file( $template_name ) { + $default_path = \dirname( __DIR__ ) . "/templates/notice-{$template_name}.php"; /** * Filters the template path for the plugin. @@ -397,13 +448,13 @@ final protected function get_template_file( $template_name ) { * * @since 1.0.0 */ - return apply_filters( "{$this->slug}_get_update_notice_template_file", $default_path, $template_name ); + return \apply_filters( "{$this->slug}_get_update_notice_template_file", $default_path, $template_name ); } /** * See if we need to show or run database updates during install. */ - final protected function maybe_update_db_version() { + protected function maybe_update_db_version() { if ( $this->get_update_handler()?->needs_update() ) { //phpcs:ignore if ( apply_filters( "{$this->slug}_enable_auto_update_db", !$this->show_admin_notices ) ) { @@ -419,12 +470,14 @@ final protected function maybe_update_db_version() { /** * Push all needed updates to the queue for processing. */ - final public function update() { - $current_version = get_option( "{$this->slug}_db_version", null ); + public function update() { + $current_version = \get_option( "{$this->slug}_db_version", null ); - if ( $current_version ) { - $this->get_update_handler()?->update( $current_version ); + if ( ! $current_version ) { + return; } + + $this->get_update_handler()?->update( $current_version ); } /** @@ -441,7 +494,7 @@ protected function get_update_handler(): ?Update_Callback_Handler { * * @param string $update_callback Callback name. */ - final public function run_update_callback( $update_callback ) { + public function run_update_callback( $update_callback ) { $this->get_update_handler()->run_update_callback( $update_callback ); } @@ -450,19 +503,21 @@ final public function run_update_callback( $update_callback ) { * * This function is hooked into admin_init to affect admin only. */ - final public function install_actions() { - if ( ! empty( $_GET[ "do_update_{$this->slug}" ] ) ) { // WPCS: input var ok. - check_admin_referer( "{$this->slug}_db_update", "{$this->slug}_db_update_nonce" ); - $this->update(); - $this->add_admin_update_notice(); + public function install_actions() { + if ( '' === \sanitize_text_field( \wp_unslash( $_GET[ "do_update_{$this->slug}" ] ?? '' ) ) ) { + return; } + + \check_admin_referer( "{$this->slug}_db_update", "{$this->slug}_db_update_nonce" ); + $this->update(); + $this->add_admin_update_notice(); } /** * Update plugin version to current. */ - final public function update_plugin_version() { - update_option( "{$this->slug}_version", $this->version ); + public function update_plugin_version() { + \update_option( "{$this->slug}_version", $this->version ); } /** @@ -470,11 +525,13 @@ final public function update_plugin_version() { * * @param string|null $version New plugin DB version or null. */ - final public function update_db_version( $version = null ) { - $version = $version ?? $this->db_version; - if ( '0.0.0' !== $version ) { - update_option( "{$this->slug}_db_version", is_null( $version ) ? $this->version : $version ); + public function update_db_version( $version = null ) { + $version ??= $this->db_version; + if ( '0.0.0' === $version ) { + return; } + + \update_option( "{$this->slug}_db_version", \is_null( $version ) ? $this->version : $version ); } /** @@ -483,9 +540,11 @@ final public function update_db_version( $version = null ) { public function register_commands() { WP_CLI::add_command( "{$this->slug} update", array( $this, 'cli_update' ) ); - if ( $this->get_schema() ) { - WP_CLI::add_command( "{$this->slug} verify_tables", array( $this, 'cli_verify_tables' ) ); + if ( ! $this->get_schema() ) { + return; } + + WP_CLI::add_command( "{$this->slug} verify_tables", array( $this, 'cli_verify_tables' ) ); } // phpcs:disable Squiz.Commenting.FunctionComment.MissingParamTag @@ -502,13 +561,14 @@ public function register_commands() { * [--force] * : Force the update even if the database is already up to date. */ - final public function cli_update( $args = array(), $assoc_args = array() ) { - $assoc_args = wp_parse_args( + public function cli_update( $args = array(), $assoc_args = array() ) { + //phpcs:ignore SlevomatCodingStandard.Functions.RequireSingleLineCall.RequiredSingleLineCall + $assoc_args = \wp_parse_args( $assoc_args, array( 'force' => false, - 'from' => null, - ) + 'from' => null, + ), ); global $wpdb; @@ -518,30 +578,57 @@ final public function cli_update( $args = array(), $assoc_args = array() ) { $handler = $this->get_update_handler(); $current_db_version = $assoc_args['from'] ?? - ( $assoc_args['force'] ? '0.0.0' : get_option( "{$this->slug}_db_version", '0.0.1' ) ); + ( $assoc_args['force'] ? '0.0.0' : \get_option( "{$this->slug}_db_version", '0.0.1' ) ); $update_count = 0; - $callbacks_to_run = $handler?->get_needed_update_callbacks( $current_db_version, $assoc_args['force'] ) ?? array(); + $callbacks_to_run = $handler?->get_needed_update_callbacks( + $current_db_version, + $assoc_args['force'], + ) ?? array(); - if ( empty( $callbacks_to_run ) ) { + if ( 0 === \count( $callbacks_to_run ) ) { // Ensure DB version is set to the current plugin version to match WP-Admin update routine. $this->update_db_version(); - /* translators: %s Database version number */ - WP_CLI::success( sprintf( __( 'No updates required. Database version is %s', 'oblak-plugin-installer' ), $current_db_version ) ); + WP_CLI::success( + \sprintf( + // translators: %s Database version number. + \__( 'No updates required. Database version is %s', 'oblak-plugin-installer' ), + $current_db_version, + ), + ); return; } - /* translators: 1: Number of database updates 2: List of update callbacks */ - WP_CLI::log( sprintf( __( 'Found %1$d updates (%2$s)', 'oblak-plugin-installer' ), count( $callbacks_to_run ), implode( ', ', wp_list_pluck( $callbacks_to_run, 'details' ) ) ) ); + WP_CLI::log( + \sprintf( + // Translators: 1: Number of database updates 2: List of update callbacks. + \__( 'Found %1$d updates (%2$s)', 'oblak-plugin-installer' ), + \count( $callbacks_to_run ), + \implode( ', ', \wp_list_pluck( $callbacks_to_run, 'details' ) ), + ), + ); - $progress = make_progress_bar( __( 'Updating database', 'oblak-plugin-installer' ), count( $callbacks_to_run ) ); + $progress = make_progress_bar( + \__( 'Updating database', 'oblak-plugin-installer' ), + \count( $callbacks_to_run ), + ); foreach ( $callbacks_to_run as $index => $callback_data ) { - // Translators: 1: update callback details, 2: update callback version, 3: update callback index, 4: total number of update callbacks. - $progress->tick( 0, sprintf( esc_html__( 'Updating to %2$s: %1$s (%3$d/%4$d)', 'oblak-plugin-installer' ), $callback_data['details'], WP_CLi::colorize( "%C{$callback_data['version']}%n" ), $index + 1, count( $callbacks_to_run ) ) ); + + $progress->tick( + 0, + \sprintf( + // Translators: 1: update callback details, 2: update callback version, 3: update callback index, 4: total number of update callbacks. + \esc_html__( 'Updating to %2$s: %1$s (%3$d/%4$d)', 'oblak-plugin-installer' ), + $callback_data['details'], + WP_CLi::colorize( "%C{$callback_data['version']}%n" ), + $index + 1, + \count( $callbacks_to_run ), + ), + ); $status = $handler->run_update_callback( $callback_data['method'] ); - sleep( 3 ); + \sleep( 3 ); $progress->tick( 1 ); @@ -553,12 +640,12 @@ final public function cli_update( $args = array(), $assoc_args = array() ) { Admin_Notice_Manager::get_instance()->remove_notice( "{$this->slug}_update_notice", true ); WP_CLI::success( - sprintf( + \sprintf( /* translators: 1: Number of database updates performed 2: Database version number */ - __( '%1$d update functions completed. Database version is %2$s', 'oblak-plugin-installer' ), - absint( $update_count ), - get_option( "{$this->slug}_db_version" ) - ) + \__( '%1$d update functions completed. Database version is %2$s', 'oblak-plugin-installer' ), + \absint( $update_count ), + \get_option( "{$this->slug}_db_version" ), + ), ); } @@ -570,43 +657,52 @@ final public function cli_update( $args = array(), $assoc_args = array() ) { * [--create] * : Create the missing tables. */ - final public function cli_verify_tables( $args = array(), $assoc_args = array() ) { + public function cli_verify_tables( $args = array(), $assoc_args = array() ) { $results = $this->verify_base_tables(); - $assoc_args = wp_parse_args( - $assoc_args, - array( - 'create' => false, - ) - ); + $assoc_args = \wp_parse_args( $assoc_args, array( 'create' => false ) ); - if ( empty( $results ) ) { - WP_CLI::success( __( 'All database tables are up to date.', 'oblak-plugin-installer' ) ); + if ( 0 === \count( $results ) ) { + WP_CLI::success( \__( 'All database tables are up to date.', 'oblak-plugin-installer' ) ); return; } - WP_CLI::warning( __( 'The following database tables are out of sync with the schema:', 'oblak-plugin-installer' ) ); + WP_CLI::warning( + \__( 'The following database tables are out of sync with the schema:', 'oblak-plugin-installer' ), + ); foreach ( $results as $table ) { - /* Translators: 1: table name, 2: result */ - WP_CLI::log( sprintf( __( 'Table %1$s: %2$s', 'oblak-plugin-installer' ), $table, __( 'Missing', 'oblak-plugin-installer' ) ) ); + + WP_CLI::log( + \sprintf( + // Translators: 1: table name, 2: result. + \__( 'Table %1$s: %2$s', 'oblak-plugin-installer' ), + $table, + \__( 'Missing', 'oblak-plugin-installer' ), + ), + ); } if ( ! $assoc_args['create'] ) { - WP_CLI::line( __( 'Run the command again with --create to create the missing tables.', 'oblak-plugin-installer' ) ); + WP_CLI::line( + \__( + 'Run the command again with --create to create the missing tables.', + 'oblak-plugin-installer', + ), + ); return; } - WP_CLI::line( __( 'Creating missing tables...', 'oblak-plugin-installer' ) ); + WP_CLI::line( \__( 'Creating missing tables...', 'oblak-plugin-installer' ) ); $this->verify_base_tables( false, true ); $results = $this->verify_base_tables(); - if ( empty( $results ) ) { - WP_CLI::success( __( 'All database tables are up to date.', 'oblak-plugin-installer' ) ); + if ( 0 === \count( $results ) ) { + WP_CLI::success( \__( 'All database tables are up to date.', 'oblak-plugin-installer' ) ); return; } - WP_CLI::error( __( 'There was an error creating the missing tables.', 'oblak-plugin-installer' ) ); + WP_CLI::error( \__( 'There was an error creating the missing tables.', 'oblak-plugin-installer' ) ); } /** @@ -615,22 +711,26 @@ final public function cli_verify_tables( $args = array(), $assoc_args = array() * @param array $tools Debug tools. * @return array */ - final public function add_debug_tools( array $tools ): array { + public function add_debug_tools( array $tools ): array { if ( ! $this->get_schema() ) { return $tools; } - return array_merge( + return \array_merge( $tools, array( "{$this->slug}_verify_db_tables" => array( - 'name' => sprintf( '%s: %s', $this->name, __( 'Verify base database tables', 'woocommerce' ) ), - 'desc' => __( 'Verify if all base database tables are present.', 'woocommerce' ), - 'button' => __( 'Verify database', 'woocommerce' ), - 'callback' => array( $this, 'debug_verify_db_tables' ), + 'button' => \__( 'Verify database', 'woocommerce' ), + 'callback' => array( $this, 'debug_verify_db_tables' ), + 'desc' => \__( 'Verify if all base database tables are present.', 'woocommerce' ), + 'name' => \sprintf( + '%s: %s', + $this->name, + \__( 'Verify base database tables', 'woocommerce' ), + ), ), - ) + ), ); } @@ -639,13 +739,16 @@ final public function add_debug_tools( array $tools ): array { * * @return string */ - final public function debug_verify_db_tables() { + public function debug_verify_db_tables() { Admin_Notice_Manager::get_instance()->remove_notice( "{$this->slug}_missing_tables", true ); $missing_tables = $this->verify_base_tables( false, true ); - return 0 === count( $missing_tables ) - ? __( 'Database verified successfully.', 'woocommerce' ) - : __( 'Verifying database... One or more tables are still missing: ', 'woocommerce' ) . implode( ', ', $missing_tables ); + return 0 === \count( $missing_tables ) + ? \__( 'Database verified successfully.', 'woocommerce' ) + : \__( 'Verifying database... One or more tables are still missing: ', 'woocommerce' ) . \implode( + ', ', + $missing_tables, + ); } }