Feature/v2 refactor and renamer#20
Conversation
Replace legacy .gitignore patterns with generated-artifact entries. Remove blanket-silenced PHPCS rules in favour of targeted inline ignores. Add composer.json with PSR-4 autoloading, dev dependencies (PHPUnit 11, WPCS 3), scripts (lint, test, package, make-pot), and lock file pinning saltus/framework plus PHPUnit and PHPCS packages. Add phpunit.xml.dist and bin/package.php CLI for distributable ZIPs. Remove obsolete package-lock.json as Node/Grunt is no longer used.
Move plugin header constants to defined() guards for safety. Add PHP version check and Composer dependency check with admin notices. Replace deprecated Loader stub with direct framework registration. Convert Core properties from public to private typed fields with getters. Add return type declarations to all methods across core classes. Remove unused property storage after construction.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request modernizes the Saltus Framework Demo plugin by upgrading the PHP requirement to 8.3, replacing Grunt build tasks with Composer scripts, and introducing a new plugin generator UI to download renamed copies of the plugin as a ZIP file. Feedback on these changes highlights a regex bug in the package name generator that mangles uppercase author names, a risk of corrupting third-party assets by globally replacing the version string '2.0.0', an unused $framework parameter in the Core constructor, and the necessity of clearing active output buffers before streaming the ZIP file to prevent archive corruption.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
The Core class no longer needs the Saltus Framework reference. The framework is still instantiated and registered at the plugin level, but is no longer passed into Core. The unused unset() call in the constructor is removed.
Clear all output buffers before sending ZIP headers to prevent "headers already sent" errors.
The regex now allows uppercase letters to pass through before strtolower() runs. Previously, uppercase letters in author names were replaced with dashes, producing incorrect package name segments.
Verify that the renamer correctly replaces the PLUGIN_VERSION value in the main plugin file when a custom version is provided.
Verify the renamer correctly rewrites the composer.json package name from saltus/framework-demo to the target author/slug combination. The test uses a mixed-case author name (Acme Inc) to verify the updated regex preserves uppercase letters before strtolower conversion.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request modernizes the Saltus Framework Demo plugin by upgrading the PHP requirement to 8.3, replacing the Grunt build system with Composer scripts, and introducing a new admin UI to generate and download renamed copies of the plugin as a ZIP file. It also updates array syntax to match WordPress standards and adds PHPUnit tests. The review feedback highlights three key improvement opportunities: correcting the return value check for wp_tempnam() and ensuring temporary files are cleaned up via a shutdown function, removing a redundant submenu page registration, and simplifying the unslashing of $_POST data using wp_unslash() directly.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request modernizes the WordPress demo plugin by upgrading the PHP requirement to 8.3, replacing Grunt with Composer scripts, and refactoring the codebase to adhere to WordPress coding standards. It also introduces a new plugin renamer feature that allows users to generate and download a renamed copy of the plugin as a ZIP file, complete with PHPUnit tests. The review feedback highlights several critical improvements for the renamer feature: validating URLs before they are sanitized by esc_url_raw() to prevent validation bypasses, making validation error messages translatable, checking the return values of ZipArchive operations to handle failures gracefully, and ensuring the error query parameter is a string before sanitizing it to avoid PHP warnings.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Check that $_GET['framework_demo_error'] is a string before passing it to sanitize_text_field(), which expects a string. A malicious array parameter would otherwise trigger PHP warnings.
Run validation before esc_url_raw() to catch invalid URLs before they are silently converted to empty strings. Wrap validation error messages in __() for i18n support.
ZipArchive::close() and addFromString() return false on failure without throwing exceptions. Check their return values and throw RuntimeException on failure to prevent silently generating incomplete or corrupted ZIP files.
Restore WordPress function stubs removed in prior cleanup. Make esc_url_raw return empty string for invalid URLs to match real WordPress behavior.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request modernizes the WordPress plugin by upgrading the minimum PHP requirement to 8.3, replacing Grunt with Composer scripts, and introducing a new "Rename Plugin" feature that generates customized, renamed ZIP packages of the plugin. It also adds PHPUnit tests, updates coding standards, and refactors core classes to use typed properties and return types. The review feedback suggests improving security and usability on the renamer admin page by storing redirect error messages in WordPress Transients instead of passing them as raw URL query parameters.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Fix the spelling 'permanetly' -> 'permanently' in the bulk delete message for the book post type.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request modernizes the Saltus Framework Demo plugin by upgrading the minimum PHP requirement to 8.3, replacing the Grunt build system with Composer scripts, and refactoring the core codebase to use strict typing and modern PHP features. It also introduces a new admin generator UI to let users download a renamed copy of the demo plugin as a ZIP file, backed by PHPUnit tests. The review feedback identifies two critical issues: a text domain mismatch bug in the renamer utility that breaks translations when the custom text domain differs from the plugin slug, and an invalid absolute path passed to load_plugin_textdomain which prevents local translation files from loading.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
plugin_basename() returns a relative path from WP_PLUGIN_DIR, preventing the invalid concatenation that occurs when passing an absolute path to load_plugin_textdomain.
Remove the standalone text_domain field from the generator UI. The text domain is now always derived from the plugin_slug per WordPress convention.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request modernizes the Saltus Framework Demo plugin by upgrading the PHP requirement to 8.3, replacing Grunt with Composer-based tooling, adding PHPCS and PHPUnit configurations, and introducing a new admin UI and utility to generate renamed copies of the plugin as ZIP files. Feedback on these changes suggests performing the PHP version check before loading any class files to prevent fatal parse errors on older PHP versions, using ZipArchive::addFile for binary files in the renamer utility to improve memory efficiency, and refining the version replacement logic to avoid accidental global replacements of unrelated version numbers.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Move the vendor/autoload.php and src/Core.php require statements below the PHP version compatibility check so that dependencies are only loaded when the runtime meets the minimum PHP requirement. Previously the autoload and Core bootstrap ran unconditionally before the version guard, which could produce fatal errors on unsupported PHP versions.
Convert Yoda conditions ('' === ) to standard comparisons ( === '')
for consistency and readability.
In PluginIdentity:
- Add /* translators: */ comments for i18n context
- Annotate ValidationException throws with phpcs:ignore
In PluginRenamer:
- Split add_files() to handle text vs binary files separately,
avoiding unnecessary file_get_contents on binary files
- Scope version string replacement to 'Version: N.N.N' header format
instead of broad 'N.N.N' replacement
- Annotate RuntimeExceptions with phpcs:ignore
In post-type-all:
- Fix whitespace alignment in labels array
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request modernizes the Saltus Framework Demo plugin by replacing the legacy Grunt-based build system with a modern Composer-based workflow, updating the minimum PHP requirement to 8.3, and refactoring the codebase to use strict typing and return types. It also introduces a new generator UI that allows users to download a renamed copy of the demo plugin as a ZIP file. Feedback on the new renamer feature highlights a path-trimming bug on Windows systems that causes truncated filenames in the generated ZIP, as well as a security vulnerability where unvalidated inputs could allow PHP code injection through comment breakout.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
- Strip both forward and backward slashes from source directory path - Validate version against strict semver format - Strip PHP comment closers from plugin name, description, and author
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request modernizes the Saltus Framework Demo plugin by upgrading the minimum PHP requirement to 8.3, replacing Grunt-based build tasks with Composer scripts, and introducing a new plugin renamer feature that allows users to generate and download a renamed copy of the plugin as a ZIP file. The review feedback suggests a valuable improvement to make the plugin renamer more robust and maintainable by passing the source version dynamically through the constructor of the PluginRenamer class rather than relying on a hardcoded version constant, which also requires updating the corresponding instantiations in the admin page and unit tests.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| ) | ||
| ); | ||
|
|
||
| $renamer = new PluginRenamer( $source ); |
Add brianhenryie/strauss for prefixing production Composer dependencies into vendor-prefixed/ during release builds. Replace inline ZIP loop with staging pipeline: copy files, composer install, prefix-namespaces, remove vendor, then zip. Output filename now includes the plugin version. Enable Strauss plugin in composer.json allow-plugins.
Remove the ORIGINAL_NAME ORIGINAL_DESCRIPTION ORIGINAL_AUTHOR ORIGINAL_AUTHOR_URI ORIGINAL_PLUGIN_URI constants. Replace string-by-string header edits with a preg_replace-based docblock swap targeting the @Wordpress-Plugin annotation. Add dedicated add_main_file method that reads the main plugin file rewrites the full header docblock then adds it to the ZIP separately from the file iterator. Add rewrite_composer_autoloader_classes to recompute ComposerAutoloaderInit and ComposerStaticInit hashes from a deterministic value derived from the new plugin identity. Update default author URI and plugin URI to saltus.dev.
Add copy-activate delivery path to generate_plugin that builds the renamed plugin into a ZIP extracts it to WP_PLUGIN_DIR activates the new plugin then deactivates the source demo. Show activation notice on plugin activation with a link to the rebrand tool. Add a plugin row quick-action link for one-click access to the rebrand page. Restore submitted form values on validation errors via transient. Show success messages from transient. Add sidebar guide explaining the rebrand workflow steps. Refactor redirect_with_error to accept form data for value persistence. Add notice dismiss action.
Add grid layout for the renamer page with two-column form-plus-guide arrangement on wide screens collapsing to single column on narrow. Style the form and guide panels with white background and border.
Sync the POT file after renaming "Rename Plugin" to "Rebrand This Demo" and adding the new UI strings for copy-activate delivery activation notice and guide sidebar.
Add assertions for plugin URI Author URI and Text Domain fields in the generated ZIP main file. Verify the source header docblock is fully replaced not just overlaid. Add assertions for vendor-prefixed autoload.php and composer autoload_real.php: verify ComposerAutoloaderInit and ComposerStaticInit hashes are rewritten and the original hashes are absent. Verify PluginFrameworkDemo namespace is absent from prefixed files. Include vendor-prefixed fixture files (autoload.php autoload_real.php autoload_static.php) in the test fixture.
Replace the "Rename UI" section with "Rebrand This Demo" covering the new copy-activate delivery mode and the two install paths. Present field descriptions as a bullet list for clarity.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request modernizes the WordPress plugin demo by migrating from Grunt to a Composer-based build system, requiring PHP 8.3, and introducing a new 'Rebrand This Demo' feature that allows users to generate a customized copy of the plugin. It also adds PHPUnit tests, updates coding standards, and adds return types and typed properties across the codebase. A critical security vulnerability was identified in the plugin renamer where the author_uri and plugin_uri fields are not sanitized against comment breakout sequences (*/), potentially leading to Remote Code Execution (RCE) in the generated plugin.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
…kout The author_uri and plugin_uri fields were sanitized with esc_url_raw() and validated with FILTER_VALIDATE_URL, but neither check strips the multi-line comment closing sequence */. Since these fields are written directly into the generated plugin's /** */ header block, an attacker could inject a URL like https://example.com?a=1*/system(current());/* to close the comment early and execute arbitrary PHP code. Add author_uri and plugin_uri to the existing str_replace('*/', '', ...) loop that already covers plugin_name, description, and author.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request modernizes the Saltus Framework Demo plugin by upgrading the minimum PHP requirement to 8.3, replacing Grunt with Composer-based scripts, and introducing a new rebranding tool. The rebranding tool allows users to generate customized copies of the plugin directly from the WordPress admin panel. Feedback on these changes suggests renaming the Composer-generated composerRequire helper function to prevent fatal redeclaration errors when multiple rebranded plugins are active, and checking if the WordPress plugin directory is writable before initiating the ZIP generation process to ensure early failure with a clear error message.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Composer generates a composerRequire[hash] global helper function in autoload_real.php. Without renaming, activating multiple rebranded plugins causes a fatal "Cannot redeclare composerRequire[hash]()" error. Adds the pattern to the existing set of renamed Composer autoloader identifiers (ComposerAutoloaderInit, ComposerStaticInit) and extends the test fixture and assertions to cover it.
Fails early with a clear error message when the plugin directory is not writable, rather than throwing a generic error during ZipArchive::extractTo.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request modernizes the WordPress plugin demo by upgrading the minimum PHP requirement to 8.3, replacing Grunt with Composer-based scripts (including Strauss for namespace prefixing, PHPCS, and PHPUnit), and introducing a new "Rebrand This Demo" admin tool to generate customized copies of the plugin. Feedback on the rebranding tool highlights a potential PHP code injection vulnerability in PluginIdentity.php due to incomplete sanitization of PHP tags, untranslatable field labels in validation errors, the omission of .js files from text file renaming, a duplicate submenu registration conflict in RenamerPage.php, and unused dead code (redirect_with_success()). Additionally, the translation template (.pot) needs to be regenerated to match the updated user-facing strings.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| private static function label( string $field ): string { | ||
| return ucwords( str_replace( '_', ' ', $field ) ); | ||
| } |
There was a problem hiding this comment.
The label() method generates English labels dynamically (e.g., 'Plugin Name'). Since these generated strings are not passed through translation functions, the field names in validation error messages (e.g., sprintf( __( '%s is required.', 'framework-demo' ), self::label( $field ) )) will always be displayed in English, regardless of the site's locale. Please map these fields to their translated labels to ensure full internationalization support.
private static function label( string $field ): string {
$labels = array(
'plugin_name' => __( 'Plugin Name', 'framework-demo' ),
'plugin_slug' => __( 'Plugin Slug', 'framework-demo' ),
'main_file' => __( 'Main Plugin File', 'framework-demo' ),
'namespace_segment' => __( 'Namespace Segment', 'framework-demo' ),
'description' => __( 'Description', 'framework-demo' ),
'author' => __( 'Author', 'framework-demo' ),
'author_uri' => __( 'Author URI', 'framework-demo' ),
'plugin_uri' => __( 'Plugin URI', 'framework-demo' ),
'version' => __( 'Version', 'framework-demo' ),
'prefix' => __( 'Code Prefix', 'framework-demo' ),
);
return $labels[ $field ] ?? ucwords( str_replace( '_', ' ', $field ) );
}| private function is_text_file( string $relative_path ): bool { | ||
| return (bool) preg_match( '/\.(php|json|md|txt|xml|css|pot)$/', $relative_path ); | ||
| } |
There was a problem hiding this comment.
The is_text_file() method does not include .js files. If a developer extends this demo plugin and adds custom JavaScript files (e.g., for block editor blocks or admin features), any hardcoded namespaces, slugs, or prefixes in those JS files will not be renamed during rebranding. Adding js to the regex ensures JavaScript files are correctly processed.
private function is_text_file( string $relative_path ): bool {
return (bool) preg_match( '/\\.(php|json|md|txt|xml|css|js|pot)$/', $relative_path );
}| public function add_page(): void { | ||
| add_submenu_page( | ||
| 'framework-demo-settings', | ||
| __( 'Rebrand This Demo', 'framework-demo' ), | ||
| __( 'Rebrand This Demo', 'framework-demo' ), | ||
| 'manage_options', | ||
| self::PAGE_SLUG, | ||
| array( $this, 'render' ) | ||
| ); | ||
|
|
||
| add_management_page( | ||
| __( 'Rebrand This Demo', 'framework-demo' ), | ||
| __( 'Rebrand This Demo', 'framework-demo' ), | ||
| 'manage_options', | ||
| self::PAGE_SLUG, | ||
| array( $this, 'render' ) | ||
| ); | ||
| } |
There was a problem hiding this comment.
Registering the exact same submenu page slug (self::PAGE_SLUG) under two different parent menus (framework-demo-settings and tools.php) can cause conflicts in WordPress. WordPress uses the page slug as a unique identifier for registered pages, and duplicate registrations can overwrite global page hooks, screen options, or cause scripts/styles to not load correctly on one of the pages. It is recommended to register the rebranding tool under a single logical location (e.g., Tools) or use unique slugs if both are required.
public function add_page(): void {
add_management_page(
__( 'Rebrand This Demo', 'framework-demo' ),
__( 'Rebrand This Demo', 'framework-demo' ),
'manage_options',
self::PAGE_SLUG,
array( $this, 'render' )
);
}| private function redirect_with_success( string $message ): void { | ||
| $token = wp_generate_uuid4(); | ||
| set_transient( 'framework_demo_success_' . $token, $message, 30 ); | ||
|
|
||
| wp_safe_redirect( | ||
| add_query_arg( | ||
| array( 'framework_demo_success' => $token ), | ||
| $this->tool_url() | ||
| ) | ||
| ); | ||
| exit; | ||
| } |
| #: src/Plugin/Admin/RenamerPage.php:153 | ||
| msgid "Make it yours. Generate a customized copy of this demo plugin as a ZIP file. The installed demo plugin is not changed." | ||
| msgstr "" |
There was a problem hiding this comment.
There is a mismatch between the user-facing strings in src/Plugin/Admin/RenamerPage.php and the generated languages/framework-demo.pot file. For example, the string on line 153 of RenamerPage.php is "Make it yours. Generate a customized copy of this demo plugin as a ZIP file, or copy and activate it directly.", but the POT file contains the old version "Make it yours. Generate a customized copy of this demo plugin as a ZIP file. The installed demo plugin is not changed.". Please regenerate the POT file using composer make-pot to ensure all strings are correctly translatable.
No description provided.