47 | );
48 | };
49 |
50 | export default RollbackContent;
51 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 |
5 | ---
6 |
7 | # Bug Report
8 |
9 | ## User Story
10 |
11 | As a ________, I want ________ so that ________.
12 |
13 |
14 |
15 | ## Current Behavior
16 |
17 |
18 | ## Expected Behavior
19 |
20 |
21 | ## Bug Type
22 |
23 | - [ ] This bug describes functionality that once worked as expected in version X.X.X.
24 | - [ ] This bug describes functionality that never worked as expected.
25 | - [ ] I am not sure whether this functionality ever worked as expected.
26 |
27 | ## Steps to Reproduce
28 |
29 | 1.
30 | 2.
31 | 3.
32 |
33 | ## Visuals
34 |
35 |
36 | ## Possible Solution
37 |
38 |
39 | ## Related
40 |
41 |
42 | ## Acceptance Criteria
43 |
44 | - [ ] e.g. Something happens when an action is taken.
45 | - [ ] e.g. Something does not happen when an action is taken.
46 | - [ ] e.g. Fixing behavior in Component A does not affect existing behavior in Component B.
47 |
48 | ## Environment
49 |
50 |
51 | Operating System
52 |
53 |
Platform: Mac OS X | Microsoft Windows | Linux | Android | iOS
54 |
Version: X.X.X
55 |
56 |
57 |
58 |
59 | Browser
60 |
61 |
Name: Chrome | Firefox | Safari | IE | Edge
62 |
Version: X.X.X
63 |
64 |
65 |
66 |
67 | WordPress System Info
68 |
69 |
70 |
--------------------------------------------------------------------------------
/src/Rollbacks/PluginRollback.php:
--------------------------------------------------------------------------------
1 | plugin_info = new PluginInfo($pluginSlug);
28 | }
29 |
30 | /**
31 | * Initialize the rollback process
32 | *
33 | * @param string $version Version to rollback to
34 | * @return bool|\WP_Error True on success, WP_Error on failure
35 | */
36 | public function rollback(string $version) {
37 | if (!PluginUtility::currentUserCanRollback()) {
38 | return new \WP_Error(
39 | 'insufficient_permissions',
40 | __('You do not have permission to perform rollbacks.', 'wp-rollback')
41 | );
42 | }
43 |
44 | if (!PluginUtility::isValidVersion($version)) {
45 | return new \WP_Error(
46 | 'invalid_version',
47 | __('Invalid version number provided.', 'wp-rollback')
48 | );
49 | }
50 |
51 | $currentVersion = $this->plugin_info->getCurrentVersion();
52 | if ($currentVersion === $version) {
53 | return new \WP_Error(
54 | 'same_version',
55 | __('Cannot rollback to the same version.', 'wp-rollback')
56 | );
57 | }
58 |
59 | $availableVersions = $this->plugin_info->getAvailableVersions();
60 | if (!in_array($version, $availableVersions, true)) {
61 | return new \WP_Error(
62 | 'version_not_found',
63 | __('The requested version is not available.', 'wp-rollback')
64 | );
65 | }
66 |
67 | // Perform rollback logic here
68 | return true;
69 | }
70 | }
--------------------------------------------------------------------------------
/src/PluginSetup/PluginScripts.php:
--------------------------------------------------------------------------------
1 | make(AssetsManager::class);
44 |
45 | // Determine the correct admin URL based on context
46 | $adminUrl = is_network_admin()
47 | ? network_admin_url('settings.php?page=wp-rollback')
48 | : admin_url('tools.php?page=wp-rollback');
49 |
50 | $assetsManager->enqueueScript('tools', [
51 | 'rollback_nonce' => wp_create_nonce('wpr_rollback_nonce'),
52 | 'restApiNonce' => wp_create_nonce('wp_rest'),
53 | 'adminUrl' => $adminUrl,
54 | 'restUrl' => esc_url_raw(rest_url()),
55 | 'rollbackSteps' => $this->getRollbackSteps(),
56 | ]);
57 | }
58 |
59 | /**
60 | * Get rollback steps data for script localization.
61 | *
62 | * @since 3.0.0
63 | * @return array
64 | */
65 | protected function getRollbackSteps(): array
66 | {
67 | $stepRegisterer = SharedCore::container()->make(RollbackStepRegisterer::class);
68 | $steps = [];
69 |
70 | foreach ($stepRegisterer->getAllRollbackSteps() as $stepClass) {
71 | $steps[] = [
72 | 'id' => $stepClass::id(),
73 | 'rollbackProcessingMessage' => $stepClass::rollbackProcessingMessage()
74 | ];
75 | }
76 |
77 | return $steps;
78 | }
79 | }
--------------------------------------------------------------------------------
/src/PluginSetup/Language.php:
--------------------------------------------------------------------------------
1 | make(Constants::class);
32 | $pluginRelativePath = self::getRelativePath($constants);
33 |
34 | $locale = is_admin() && function_exists('get_user_locale') ? get_user_locale() : get_locale();
35 | // Traditional WordPress plugin locale filter.
36 | $locale = apply_filters('plugin_locale', $locale, $constants->getTextDomain());
37 |
38 | // Setup paths to current locale file.
39 | $moFile = sprintf('%1$s-%2$s.mo', $constants->getTextDomain(), $locale);
40 | $moFileLocal = trailingslashit(WP_PLUGIN_DIR) . $pluginRelativePath . $moFile;
41 | $moFileGlobal = trailingslashit(WP_LANG_DIR) . 'plugins/' . $moFile;
42 |
43 | unload_textdomain($constants->getTextDomain());
44 | if (file_exists($moFileGlobal)) {
45 | // Look in global /wp-content/languages/plugins folder.
46 | load_textdomain($constants->getTextDomain(), $moFileGlobal);
47 | } elseif (file_exists($moFileLocal)) {
48 | // Look in local /wp-content/plugins/wp-rollback/languages/ folder.
49 | load_textdomain($constants->getTextDomain(), $moFileLocal);
50 | } else {
51 | // Load the default language files.
52 | load_plugin_textdomain($constants->getTextDomain(), false, $pluginRelativePath);
53 | }
54 | }
55 |
56 | /**
57 | * Return the plugin language dir relative path, e.g. "wp-rollback/languages/"
58 | *
59 | * @since 3.0.0
60 | */
61 | public static function getRelativePath(Constants $constants): string
62 | {
63 | $pluginRelativePath = dirname(plugin_basename($constants->getPluginFile())) . '/languages/';
64 | $pluginRelativePath = ltrim(apply_filters('wprollback_languages_directory', $pluginRelativePath), '/\\');
65 |
66 | return trailingslashit($pluginRelativePath);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/Core/ServiceProvider.php:
--------------------------------------------------------------------------------
1 | singleton(BaseConstants::class, function () use ($constants) {
44 | return $constants;
45 | });
46 |
47 | SharedCore::container()->singleton(Constants::class, function () use ($constants) {
48 | return $constants;
49 | });
50 |
51 | // Register plugin-specific Request implementation
52 | SharedCore::container()->singleton(Request::class, function () use ($constants) {
53 | return new Request($constants);
54 | });
55 |
56 | // Register plugin-specific Cache implementation
57 | SharedCore::container()->singleton(Cache::class, function () use ($constants) {
58 | return new Cache($constants->getSlug());
59 | });
60 |
61 | // Register plugin-specific DebugMode if needed
62 | SharedCore::container()->singleton(DebugMode::class, function () {
63 | return DebugMode::makeWithWpDebugConstant();
64 | });
65 |
66 | // Register PluginScripts
67 | SharedCore::container()->singleton(PluginScripts::class);
68 | }
69 |
70 | /**
71 | * This function boots the service provider.
72 | *
73 | * @since 3.0.0
74 | */
75 | public function boot(): void
76 | {
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/PluginSetup/PluginMeta.php:
--------------------------------------------------------------------------------
1 | make(Constants::class);
30 |
31 | if ($constants->getBasename() !== $pluginFile) {
32 | return $pluginMeta;
33 | }
34 |
35 | $newMetaLinks = [
36 | sprintf(
37 | '%2$s',
38 | esc_url(
39 | add_query_arg(
40 | [
41 | 'utm_source' => 'free-plugin',
42 | 'utm_medium' => 'plugin-row',
43 | 'utm_campaign' => 'documentation',
44 | ],
45 | 'https://docs.wprollback.com/'
46 | )
47 | ),
48 | esc_html__('Documentation', 'wp-rollback')
49 | ),
50 | sprintf(
51 | '%2$s',
52 | esc_url(
53 | add_query_arg(
54 | [
55 | 'utm_source' => 'free-plugin',
56 | 'utm_medium' => 'plugin-row',
57 | 'utm_campaign' => 'support',
58 | ],
59 | 'https://wprollback.com/support/'
60 | )
61 | ),
62 | esc_html__('Support', 'wp-rollback')
63 | ),
64 | sprintf(
65 | '%2$s',
66 | esc_url(
67 | add_query_arg(
68 | [
69 | 'utm_source' => 'free-plugin',
70 | 'utm_medium' => 'plugin-row',
71 | 'utm_campaign' => 'go-pro',
72 | ],
73 | 'https://wprollback.com/pricing/'
74 | )
75 | ),
76 | esc_html__('Go Pro!', 'wp-rollback')
77 | ),
78 | ];
79 |
80 | return array_merge($pluginMeta, $newMetaLinks);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Deploy to WordPress.org
2 |
3 | on:
4 | release:
5 | types: [ released ]
6 |
7 | jobs:
8 | release:
9 | name: New release
10 | runs-on: ubuntu-20.04
11 | environment: live
12 | steps:
13 | - name: Checkout code
14 | uses: actions/checkout@v2
15 |
16 | - name: Setup PHP
17 | uses: shivammathur/setup-php@v2
18 | with:
19 | php-version: 7.4
20 | extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, mysql, mysqli, pdo_mysql, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo
21 | coverage: none
22 |
23 | # - name: Install composer dependencies
24 | # uses: php-actions/composer@v5
25 | # with:
26 | # php_version: 7.4
27 | # dev: no
28 |
29 | - uses: actions/setup-node@v2
30 | with:
31 | node-version: '12'
32 |
33 | - name: Install npm dependencies & build for translation
34 | run: |
35 | npm install -g npm@7
36 | npm ci
37 | npm run build
38 |
39 | # In order to run this WordPress also needs to be installed
40 | - name: Generate pot file
41 | run: |
42 | curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
43 | chmod +x wp-cli.phar
44 | mv wp-cli.phar /usr/local/bin/wp
45 | php -d xdebug.mode=off "$(which wp)" i18n make-pot ${{github.workspace}} ${{github.workspace}}/languages/wp-rollback.pot --exclude="$(cat .distignore | tr "\n" "," | sed 's/,$/ /' | tr " " "\n"),src/**/*.js,*.js.map"
46 |
47 | - name: Build assets for production
48 | run: npm run build
49 |
50 | - name: WordPress Plugin Deploy
51 | id: deploy
52 | uses: 10up/action-wordpress-plugin-deploy@stable
53 | with:
54 | generate-zip: true
55 | env:
56 | SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
57 | SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
58 | SLUG: wp-rollback
59 |
60 | - name: Upload release asset
61 | uses: actions/upload-release-asset@v1
62 | env:
63 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
64 | with:
65 | upload_url: ${{ github.event.release.upload_url }}
66 | asset_path: ${{github.workspace}}/wp-rollback.zip
67 | asset_name: wp-rollback.zip
68 | asset_content_type: application/zip
69 |
--------------------------------------------------------------------------------
/src/Rollbacks/RollbackSteps/UpsellValidatePackage.php:
--------------------------------------------------------------------------------
1 | getType();
47 | $assetSlug = $rollbackApiRequestDTO->getSlug();
48 |
49 | // Get the downloaded package from transient to verify it exists
50 | $package = get_transient("wpr_{$assetType}_{$assetSlug}_package");
51 |
52 | // Basic existence check (free version does minimal validation)
53 | if (empty($package) || !is_string($package) || !file_exists($package)) {
54 | return new RollbackStepResult(
55 | false,
56 | $rollbackApiRequestDTO,
57 | __('Package not found for rollback.', 'wp-rollback')
58 | );
59 | }
60 |
61 | // For the free version, we skip comprehensive validation and show success
62 | // with an upsell message about the pro version's enhanced security features
63 | $upsellMessage = __(
64 | 'Basic validation complete. 🔒 WP Rollback Pro includes advanced package integrity scanning. Upgrade at wprollback.com/pricing',
65 | 'wp-rollback'
66 | );
67 |
68 | return new RollbackStepResult(
69 | true,
70 | $rollbackApiRequestDTO,
71 | $upsellMessage,
72 | null,
73 | [
74 | 'validation_status' => 'basic',
75 | 'upsell_shown' => true,
76 | 'pro_features' => [
77 | 'advanced_security_scanning',
78 | 'malware_detection',
79 | 'comprehensive_integrity_checks',
80 | 'detailed_validation_reports'
81 | ]
82 | ]
83 | );
84 | }
85 |
86 | /**
87 | * @inheritdoc
88 | * @since 3.0.0
89 | */
90 | public static function rollbackProcessingMessage(): string
91 | {
92 | return esc_html__('Validating package integrity…', 'wp-rollback');
93 | }
94 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://wprollback.com)
2 |
3 | # WP Rollback
4 |
5 | Effortlessly rollback (or downgrade, as some may call it) any theme or plugin from WordPress.org to a previous version with WP Rollback. It's as simple as using the plugin updater, but instead, you downgrade to a specific version. Forget the hassle of manual downloads and FTP uploads; this plugin streamlines the process for you.
6 |
7 | ## Important: Usage Disclaimer
8 |
9 | Before performing a rollback, we highly recommend conducting a test on a staging site and creating a full backup of your
10 | WordPress files and database. **Please note: We are not liable for any issues such as data loss, white screens, fatal
11 | errors, or other problems that may arise from using this plugin**.
12 |
13 | ## Download
14 |
15 | For stable releases, visit the [WordPress Repository](https://wordpress.org/plugins/wp-rollback). You can also find them
16 | in your WordPress Dashboard under "Plugins > Add New." For development versions, see the contribution section below on
17 | how to clone this repo and start using the latest updates.
18 |
19 | ## Support
20 |
21 | Have questions or need assistance? Post all your support requests on
22 | the [WordPress Repository support page for WP Rollback](https://wordpress.org/support/plugin/wp-rollback). If you'd like
23 | to report bugs, request features, or contribute, we welcome your input!
24 |
25 | ## Documentation
26 |
27 | Designed for seamless integration with the WordPress interface, WP Rollback is straightforward and setting-free. We're
28 | confident that its functionality will be apparent and intuitive right after activation.
29 |
30 | [Read the WP Rollback Documentation](https://github.com/impress-org/wp-rollback/wiki)
31 |
32 | ## Contributing
33 |
34 | We appreciate contributions from the community! To contribute:
35 |
36 | 1. **Fork the Repository**: Click the 'Fork' button at the top right of this page to create your own copy of this
37 | repository.
38 |
39 | 2. **Clone Your Fork**: Clone your fork to your local machine. This can be done via the command line with
40 | `git clone https://github.com/DevinWalker/wp-rollback.git`. Make sure you clone it to the `wp-content/plugins`
41 | directory of your WordPress installation.
42 |
43 | 3. **Install Dependencies**: Run `bun install` to install all dependencies.
44 |
45 | 4. **Available Scripts**:
46 |
47 | - `bun run build` - Create a production build
48 | - `bun run dev-build` - Start development mode with file watching
49 | - `bun run generate:pot` - Generate translation files
50 | - `bun run plugin-zip` - Create a deployable plugin zip file
51 | - `bun run rm-modules` - Remove node_modules directory
52 |
53 | 5. **Create a New Branch**: Before making your changes, switch to a new branch with `git checkout -b your-branch-name`.
54 |
55 | 6. **Make Your Changes**: Implement your changes, enhancements, or bug fixes.
56 |
57 | 7. **Development**: Run `bun run dev-build` to start the development process. This will watch for changes to the JS and SCSS files and compile them automatically.
58 |
59 | 8. **Testing**: Before submitting, build the plugin with `bun run build` to ensure everything compiles correctly.
60 |
61 | 9. **Commit and Push**: Commit your changes with a clear commit message and push them to your fork with
62 | `git push origin your-branch-name`.
63 |
64 | 10. **Submit a Pull Request (PR)**: Go to the original WP Rollback repository and click 'New pull request'. Choose your
65 | fork and branch, then submit the pull request. Provide a decent PR description explaining the changes you made and
66 | we'll review your PR and merge it if it contributes positively to the project!
67 |
--------------------------------------------------------------------------------
/src/Rollbacks/resources/pages/Dashboard.jsx:
--------------------------------------------------------------------------------
1 | import { useNavigate } from 'react-router-dom';
2 | import { Card, CardBody, Button, Icon } from '@wordpress/components';
3 | import { __ } from '@wordpress/i18n';
4 | import { plugins, brush } from '@wordpress/icons';
5 | import Layout from '../layout/Layout';
6 |
7 | /**
8 | * Dashboard component that serves as the main landing page for WP Rollback.
9 | * Provides options to rollback plugins or themes.
10 | *
11 | * @return {JSX.Element} The rendered Dashboard component
12 | */
13 | export const Dashboard = () => {
14 | const navigate = useNavigate();
15 |
16 | return (
17 |
18 |
19 |
{ __( 'Rollback a Plugin or Theme', 'wp-rollback' ) }
20 |
21 | { __(
22 | 'With WP Rollback you can go back to a previous WordPress.org plugin or theme version with ease. Which action would you like to perform today?',
23 | 'wp-rollback'
24 | ) }
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
{ __( 'Plugin Version Rollback', 'wp-rollback' ) }
34 |
35 |
36 | { __(
37 | "Revert any WordPress.org plugin to a previous version with just a few clicks. Choose the plugin and version you'd like to restore.",
38 | 'wp-rollback'
39 | ) }
40 |
41 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
{ __( 'Theme Version Rollback', 'wp-rollback' ) }
57 |
58 |
59 | { __(
60 | "Revert any WordPress.org plugin to a previous version with just a few clicks. Choose the plugin and version you'd like to restore.",
61 | 'wp-rollback'
62 | ) }
63 |
64 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
{ __( 'The Safest Way to Rollback Premium Plugins & Themes', 'wp-rollback' ) }
80 |
81 | { __(
82 | 'Get complete control over every plugin on your site with automated backups, rollback notes for your team, and support for premium plugins from any marketplace.',
83 | 'wp-rollback'
84 | ) }
85 |
110 | { __( 'Take your rollback management to the next level with professional features designed for serious WordPress sites.', 'wp-rollback' ) }
111 |
153 | >
154 | );
155 | };
156 |
157 | export default FreeCompleteTemplate;
158 |
--------------------------------------------------------------------------------
/src/Rollbacks/resources/styles/_free-complete-template.scss:
--------------------------------------------------------------------------------
1 | // Free Complete Template Styles
2 | @use "@wp-rollback/shared-core/styles/variables" as *;
3 |
4 | // Success Notice Styling
5 | .wpr-success-notice {
6 | margin-bottom: 20px !important;
7 | border-left: 4px solid #15803d !important;
8 |
9 | .components-notice__content {
10 | margin: 0 !important;
11 | }
12 |
13 | &__content {
14 | display: flex;
15 | align-items: center;
16 | gap: 8px;
17 |
18 | .components-icon {
19 | color: #15803d;
20 | }
21 | }
22 | }
23 |
24 | // What's Next Section
25 | .wpr-next-steps {
26 | margin-bottom: 24px;
27 |
28 | &__heading {
29 | display: flex;
30 | align-items: center;
31 | gap: 8px;
32 | margin: 0 0 16px 0;
33 | font-size: 16px;
34 | font-weight: 600;
35 | color: #1d2327;
36 | border-bottom: 1px solid #e0e0e0;
37 | padding-bottom: 8px;
38 | }
39 |
40 | &__list {
41 | margin-bottom: 24px;
42 | line-height: 1.6;
43 |
44 | li {
45 | margin-bottom: 8px;
46 | color: #3c434a;
47 |
48 | &:last-child {
49 | margin-bottom: 0 !important;
50 | }
51 | }
52 | }
53 | }
54 |
55 | // Pro Upgrade Card - Modern Design
56 | .wpr-pro-upgrade-card {
57 | background: #fff;
58 | border: 1px solid #e5e7eb;
59 | border-left: 4px solid #8b5cf6;
60 | margin-bottom: 20px;
61 | border-radius: 0;
62 | transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
63 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
64 |
65 | &__body {
66 | padding: 24px;
67 | color: #1f2937;
68 | position: relative;
69 |
70 | // Subtle gradient overlay
71 | &::before {
72 | content: '';
73 | position: absolute;
74 | top: 0;
75 | right: 0;
76 | width: 100px;
77 | height: 100px;
78 | background: linear-gradient(135deg, rgba(139, 92, 246, 0.05) 0%, rgba(59, 130, 246, 0.05) 100%);
79 | border-radius: 50%;
80 | transform: translate(30px, -30px);
81 | pointer-events: none;
82 | }
83 | }
84 |
85 | &:hover {
86 | transform: translateY(-2px);
87 | box-shadow: 0 10px 25px rgba(139, 92, 246, 0.15), 0 4px 6px rgba(0, 0, 0, 0.05) !important;
88 | border-left-color: #7c3aed;
89 | }
90 |
91 | &__header {
92 | display: flex;
93 | align-items: center;
94 | gap: 12px;
95 | margin-bottom: 16px;
96 |
97 | h3 {
98 | margin: 0;
99 | font-size: 18px;
100 | line-height: 1.2;
101 | font-weight: 600;
102 | color: #1f2937;
103 | background: linear-gradient(135deg, #8b5cf6 0%, #3b82f6 100%);
104 | -webkit-background-clip: text;
105 | -webkit-text-fill-color: transparent;
106 | background-clip: text;
107 | }
108 | }
109 |
110 | &__description {
111 | margin: 0 0 20px 0;
112 | font-size: 14px;
113 | color: #6b7280;
114 | line-height: 1.5;
115 | }
116 |
117 | &__features {
118 | display: grid;
119 | gap: 16px;
120 | margin-bottom: 24px;
121 | }
122 |
123 | &__feature {
124 | display: flex;
125 | align-items: flex-start;
126 | gap: 12px;
127 | padding: 12px;
128 | background: linear-gradient(135deg, rgba(139, 92, 246, 0.03) 0%, rgba(59, 130, 246, 0.03) 100%);
129 | border-radius: 8px;
130 | border: 1px solid rgba(139, 92, 246, 0.1);
131 | transition: background-color 0.2s ease, border-color 0.2s ease;
132 |
133 | &:hover {
134 | background: linear-gradient(135deg, rgba(139, 92, 246, 0.05) 0%, rgba(59, 130, 246, 0.05) 100%);
135 | border-color: rgba(139, 92, 246, 0.2);
136 | }
137 |
138 | .components-icon {
139 | color: #8b5cf6;
140 | margin-top: 2px;
141 | flex-shrink: 0;
142 | animation: none;
143 | filter: drop-shadow(0 1px 2px rgba(139, 92, 246, 0.2));
144 | }
145 |
146 | &-content {
147 | h5 {
148 | margin: 0 0 4px 0;
149 | font-size: 14px;
150 | font-weight: 600;
151 | color: #1f2937;
152 | }
153 |
154 | p {
155 | margin: 0;
156 | font-size: 13px;
157 | color: #6b7280;
158 | line-height: 1.4;
159 | }
160 | }
161 | }
162 |
163 | &__actions {
164 | display: flex;
165 | gap: 12px;
166 | align-items: center;
167 |
168 | .components-button {
169 | background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%) !important;
170 | color: #fff !important;
171 | border: none !important;
172 | padding: 10px 20px;
173 | font-size: 14px;
174 | transition: all 0.2s ease;
175 | box-shadow: 0 2px 4px rgba(139, 92, 246, 0.2);
176 |
177 | &:hover {
178 | transform: translateY(-1px);
179 | box-shadow: 0 4px 12px rgba(139, 92, 246, 0.3);
180 | background: linear-gradient(135deg, #7c3aed 0%, #6d28d9 100%) !important;
181 | }
182 |
183 | &:active {
184 | transform: translateY(0);
185 | }
186 | }
187 |
188 | .components-external-link {
189 | color: #8b5cf6 !important;
190 | text-decoration: none;
191 | font-size: 14px;
192 | font-weight: 500;
193 | padding: 8px 12px;
194 | border-radius: 6px;
195 | transition: background-color 0.2s ease;
196 |
197 | &:hover {
198 | background: rgba(139, 92, 246, 0.1);
199 | text-decoration: underline;
200 | }
201 | }
202 | }
203 | }
204 |
205 | // Help Section
206 | .wpr-help-section {
207 | padding: 16px;
208 | background: #f8fafc;
209 | border-radius: 8px;
210 | text-align: center;
211 | margin-bottom: 20px;
212 | border: 1px solid #e2e8f0;
213 | transition: background-color 0.2s ease;
214 |
215 | &:hover {
216 | background: #f1f5f9 !important;
217 | }
218 |
219 | &__text {
220 | margin: 0 0 8px 0;
221 | font-size: 14px;
222 | color: #64748b;
223 | }
224 |
225 | .components-external-link {
226 | color: #3858e9 !important;
227 | text-decoration: none;
228 | font-size: 14px;
229 | font-weight: 500;
230 | }
231 | }
232 |
233 | // Modal content enhancements
234 | .wpr-modal {
235 | // Increase modal width for better layout
236 | max-width: 650px !important;
237 |
238 | .wpr-modal-content {
239 | // Add some breathing room
240 | padding: 0 4px;
241 | }
242 | }
243 |
244 | // Animations
245 | @keyframes pulse-star {
246 | 0% { transform: scale(1); }
247 | 50% { transform: scale(1.1); }
248 | 100% { transform: scale(1); }
249 | }
250 |
251 | // Responsive improvements
252 | @media (max-width: 600px) {
253 | .wpr-pro-upgrade-card {
254 | .components-card__body {
255 | padding: 16px !important;
256 | }
257 |
258 | &__header h3 {
259 | font-size: 16px !important;
260 | }
261 |
262 | &__features {
263 | grid-template-columns: 1fr !important;
264 | }
265 | }
266 |
267 | .wpr-next-steps {
268 | &__list {
269 | padding-left: 16px !important;
270 | }
271 | }
272 | }
--------------------------------------------------------------------------------
/src/Rollbacks/resources/components/LogoFree.jsx:
--------------------------------------------------------------------------------
1 | const LogoFree = ( { className, ...props } ) => {
2 | return (
3 |
163 | );
164 | };
165 |
166 | export default LogoFree;
167 |
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | === WP Rollback - Rollback Plugins and Themes ===
2 | Contributors: dlocc, drrobotnik, webdevmattcrom
3 | Tags: rollback, revert, downgrade, version, plugins
4 | Requires at least: 6.5
5 | Donate Link: https://wprollback.com/
6 | Tested up to: 6.9
7 | Requires PHP: 7.4
8 | Stable tag: 3.0.10
9 | License: GPLv3
10 | License URI: http://www.gnu.org/licenses/gpl-3.0.html
11 |
12 | Rollback (or forward) any WordPress.org plugin, theme, or block like a boss.
13 |
14 | == Description ==
15 |
16 | Quickly and easily rollback any theme or plugin from WordPress.org to any previous (or newer) version without any of the manual fuss. Works just like the plugin updater, except you're rolling back (or forward) to a specific version. No need for manually downloading and FTPing the files or learning Subversion. This plugin takes care of the trouble for you.
17 |
18 | = 🔙 Rollback WordPress.org Plugins and Themes =
19 |
20 | While it's considered best practice to always keep your WordPress plugins and themes updated, we understand there are times you may need to quickly revert to a previous version. This plugin makes that process as easy as a few mouse clicks. Simply select the version of the plugin or theme that you'd like to rollback to, confirm, and in a few moments you'll be using the version requested. No more fumbling to find the version, downloading, unzipping, FTPing, learning Subversion or hair pulling.
21 |
22 | For advanced features like premium plugin/theme support (Envato, Kadence Pro, Astra Pro, etc.), comprehensive activity logging, multisite network support, and priority support, consider upgrading to [WP Rollback Pro](https://wprollback.com/).
23 |
24 | = Muy Importante (Very Important): Always Test and Backup =
25 |
26 | **Important Disclaimer:** This plugin is not intended to be used without first taking the proper precautions to ensure zero data loss or site downtime. Always be sure you have first tested the rollback on a staging or development site prior to using WP Rollback on a live site.
27 |
28 | We provide no (zero) assurances, guarantees, or warranties that the plugin, theme, or WordPress version you are downgrading to will work as you expect. Use this plugin at your own risk.
29 |
30 | = Translation Ready =
31 |
32 | Do you speak another language? Want to contribute in a meaningful way to WP Rollback? There's no better way than to help us translate the plugin. This plugin is translation ready. Simply header over to the WP Rollback [translation project](https://translate.wordpress.org/projects/wp-plugins/wp-rollback/) that's powered by WordPress.org volunteer translators. There you can contribute to the translation of the plugin into your language.
33 |
34 | = Support and Documentation =
35 |
36 | We answer all free user support requests [on the WordPress.org support forum](https://wordpress.org/support/plugin/wp-rollback). For pro users, please submit your questions to [WP Rollback Pro support](https://wprollback.com/?utm_campaign=free-plugin&utm_medium=free-plugin&utm_source=readme).
37 |
38 | WP Rollback was created to be as intuitive to the natural WordPress experience as possible. We believe that once you activate WP Rollback, you'll quickly discover exactly how it works without question.
39 |
40 | **BUT!!**
41 |
42 | We do have documentation on our website. See [WP Rollback Documentation](https://docs.wprollback.com/?utm_source=free-plugin&utm_medium=readme&utm_campaign=documentation).
43 |
44 | == Installation ==
45 |
46 | = Minimum Requirements =
47 |
48 | * WordPress 6.5 or greater
49 | * PHP version 7.4 or greater
50 | * MySQL version 5.0 or greater
51 |
52 | = Automatic installation =
53 |
54 | Automatic installation is the easiest option as WordPress handles the file transfers itself and you don't need to leave your web browser. To do an automatic install of WP Rollback, log in to your WordPress dashboard, navigate to the Plugins menu and click Add New.
55 |
56 | In the search field type "WP Rollback" and click Search Plugins. Once you have found the plugin you can view details about it such as the point release, rating and description. Most importantly of course, you can install it by simply clicking "Install Now".
57 |
58 | = Manual installation =
59 |
60 | The manual installation method involves downloading our donation plugin and uploading it to your server via your favorite FTP application. The WordPress codex contains [instructions on how to do this here](http://codex.wordpress.org/Managing_Plugins#Manual_Plugin_Installation).
61 |
62 | = Updating =
63 |
64 | Automatic updates should work like a charm; as always though, ensure you backup your site just in case.
65 |
66 | == Frequently Asked Questions ==
67 |
68 | = Is this plugin safe to use? =
69 | Short answer = Yes. Longer answer = It depends on how you use it.
70 |
71 | WP Rollback is completely safe because all it does is take publicly available versions of the plugins you already have on your site and install the version that you designate. There is no other kinds of trickery or fancy offsite calls or anything. BUT!!!
72 |
73 | Safety largely depends on you. The WordPress website admin. We absolutely do NOT recommend rolling back any plugins or themes on a live site. Test the rollback locally first, have backups, use all the best practice tools available to you. This is intended to make rolling back easier, that's all.
74 |
75 | = Why isn't there a rollback button next to X plugin or theme? =
76 |
77 | WP Rollback only works with plugins or themes installed from the WordPress Repository. If you don't see the rollback link, then most likely that plugin or theme is not found on WordPress.org. This plugin does not support plugins from GitHub, ThemeForest, or other sources other than the WordPress.org Repo.
78 |
79 | = I rolled my [insert plugin name] back to version X.X and now my site is broken. This is your fault. =
80 |
81 | Nope. We warned you in **bold** print several times in many places. And our plugin delivered exactly what it said it would do. May the Gods of the internet pity your broken site's soul.
82 |
83 | = Where is the complete documentation located? =
84 |
85 | The documentation for this plugin is located on our the [WP Rollback site](https://docs.wprollback.com/?utm_source=free-plugin&utm_medium=readme&utm_campaign=documentation). This is where we make regular updates.
86 |
87 | = What's the difference between WP Rollback Free and Pro? =
88 |
89 | WP Rollback Free provides essential rollback functionality for WordPress.org plugins and themes. WP Rollback Pro adds powerful features including premium plugin/theme support (Gravity Forms, Elementor, Kadence Pro, Astra Pro, Divi, etc.), comprehensive activity logging, multisite network support, and priority support. [Learn more about Pro features](https://wprollback.com/).
90 |
91 | = Can this plugin be translated? =
92 |
93 | Yes! All strings are internationalized and ready to be translated. You can either use your favorite translation plugin, or [help translate the plugin on WordPress.org](https://translate.wordpress.org/projects/wp-plugins/wp-rollback/).
94 |
95 | == Screenshots ==
96 |
97 | 1. Click the Rollback link on the Plugins page to begin a plugin rollback.
98 |
99 | 2. Select the version you would like to switch to on the version selection page.
100 |
101 | 3. Confirm you would like to proceed with the rollback.
102 |
103 | 4. The plugin will update to the selected version.
104 |
105 | 5. Click the Rollback button on the Theme details screen to begin a theme rollback.
106 |
107 | 5. The theme Rollback version selection page works exactly like the plugins page.
108 |
109 | == Upgrade Notice ==
110 |
111 | This is the first version of this plugin. It is a tool for your convenience. Rollback at your own risk!
112 |
113 | == Changelog ==
114 |
115 | = 3.0.10 =
116 | * Fix: Resolved fatal error when Visual Composer page builder is active. The plugin now properly validates screen IDs to handle cases where page builders return non-standard screen ID values.
117 |
118 | = 3.0.9 =
119 | * New: Re-added "Trunk" as an available rollback version option for testing development versions.
120 | * New: Added support for pre-release versions including beta, alpha, and RC versions (e.g., 15.1-beta.2, 15.2-a.7, 2.5.0-RC1).
121 | * Enhancement: Improved version sorting algorithm to properly order pre-release versions alongside stable releases.
122 | * Tweak: Added smooth rotating animation to loading indicators for better visual feedback.
123 | * Tweak: Updated compatibility to WordPress 6.9.
124 |
125 | = 3.0.8 =
126 | * Fix: Changed the filesystem type in BackupService from WP_Filesystem_Direct to WP_Filesystem_Base to allow for broader compatibility with different filesystem implementations.
127 |
128 | = 3.0.7 =
129 | * Fix: Updated the WP_Filesystem call in BackupService to set $allow_relaxed_file_ownership to true, enabling support for Group/World writable files. This change aims to prevent potential issues with file permissions during backup operations. Thanks to @hanno from WP.org support forums.
130 |
131 | = 3.0.6 =
132 | * Enhancement: Premium plugin and theme archives are no longer recreated if an archive already exists for the current version. This improves performance during updates and rollbacks by skipping unnecessary backup operations.
133 | * Fix: Resolved critical issue where WooCommerce and other plugins with autoloaders would cause fatal errors during rollback. The plugin is now properly deactivated before deletion to prevent PHP errors when files are removed.
134 |
135 | = 3.0.5 =
136 | * Fix: Resolved conflict where maintenance mode was interfering with external monitoring tools like Nagios, WP-CLI, and automated WordPress update checks. The maintenance page is now only shown to regular site visitors, allowing monitoring tools and admin processes to function normally.
137 | * Fix: Maintenance mode now only activates when rolling back active plugins or themes. Inactive plugins and themes no longer trigger maintenance mode unnecessarily.
138 | * Fix: Corrected an issue where the maintenance mode step wasn't displaying in the Free version's rollback progress UI due to incorrect service provider load order.
139 | * Improvement: Refactored rollback step registration for better code maintainability across Free and Pro versions, ensuring consistent behavior.
140 |
141 | = 3.0.4 =
142 | * New: Added maintenance mode support during rollback operations to prevent site access while files are being replaced, following WordPress Core update patterns.
143 | * Improvement: Enhanced rollback safety with automatic maintenance mode cleanup that ensures your site never gets stuck in maintenance mode, even if a rollback fails.
144 | * Fix: Removed overly restrictive package validation that required plugin main files to match the plugin slug. This fix allows plugins like Visual Composer (with main file "plugin-wordpress.php") and other legitimate plugins with non-standard main file names to be rolled back successfully.
145 | * Fix: Resolved fatal error when using WP CLI bulk updates (`wp plugin update --all`) due to missing string type check. The backup service now properly handles cases where the package parameter is boolean instead of a string during bulk operations.
146 | * Fix: WordPress Multisite network admin pages now properly load rollback scripts and styles.
147 | * Fix: Resolved package validation errors on multisite installations where ZIP files were incorrectly flagged as invalid.
148 | * Fix: Fixed multisite upload size restrictions that prevented rollbacks due to the default 1MB limit.
149 |
150 | = 3.0.3 =
151 | * Fix: Resolved fatal error when attempting to rollback plugins that return boolean false for requires_php field instead of a string value. This fix ensures proper type validation for WordPress requirement fields.
152 | * Fix: Plugin and theme names containing HTML entities (like &, <, etc.) now display correctly in rollback modals instead of showing raw HTML characters.
153 |
154 | = 3.0.2 =
155 | * Improvement: Simplified theme rollback button display functionality - all themes now display rollback buttons without checking WordPress.org availability.
156 | * Improvement: Consolidated theme rollback JavaScript handlers between free and pro versions for better code maintainability.
157 | * Improvement: Removed visual distinction between WordPress.org and premium plugin rollback links for a more consistent UI.
158 | * Fix: Resolved fatal error on themes.php page caused by incorrect namespace references.
159 |
160 | = 3.0.1 =
161 | * Fix: Resolved an error with JetPack Sync and potentially other plugins that modify plugin data and return null.
162 |
163 | = 3.0.0 =
164 | * New: Added additional "WP Rollback" menu item under WP-Admin > Tools.
165 | * New: Added new "Plugin" and "Themes" list views to select a rollback more easily.
166 | * New: WP Rollback now stores premium assets locally on your server for easy future access.
167 | * New: Added upsells to the new [WP Rollback Pro](https://wprollback.com/).
168 | * New: Updated plugin to support PHP versions 7.4 - 8.4.
169 |
170 | = 2.0.7 =
171 | * Fix: Resolved a bug with plain permalink websites which caused a `rest_no_route` error when trying to rollback a plugin or theme. Thanks, @afizesan for helping pinpoint the issue.
172 | * Fix: Update the way the React app is loaded to suppress React 18+ warnings.
173 | * Tweak: Bumped the plugin's minimum required WordPress version to 6.0+ for best compatibility with new React components in UI.
174 |
175 | = 2.0.6 =
176 | Fix: The release corrects the paths used in plugin file includes and requires. The unnecessary forward slashes at the start of each file path have been removed. This change ensures proper file inclusion and requirement, avoiding potential issues with file not found errors.
177 |
178 | = 2.0.5 =
179 | * New: In this version we've brought back the "trunk" option to rollback to. This allows plugin or theme developers who use trunk for beta testing to rollback to the latest trunk version. Thanks, @megamenu for suggesting this be brought back.
180 | * Fix: Refactored how plugin avatar images are checked so that all available image types and sizes are checked. This resolves an issue where some plugins would not display an avatar image.
181 | * Fix: On the final rollback confirmation screen, the plugin name field was outputting raw HTML. This has been fixed to properly display the plugin name, even if it contains some html characters.
182 |
183 | = 2.0.4 =
184 | * Fix: Resolved issue REST route not including proper permission callback which created a PHP notice. Thanks, @rom1our for submitting the issue.
185 | * Fix: Resolve issue with REST API and multisite installs not being able to properly communicate with the endpoint.
186 |
187 | = 2.0.3 =
188 | * Fix: A few additional strings in JavaScript needed to be internationalized. Thanks, @pedro-mendonca for contributing the fix.
189 |
190 | = 2.0.2 =
191 | * Fix: Resolves an issue with WP Rollback not being able to communicate to its REST API on WordPress subdirectory installs. Thanks, @emaralive for reporting the issue.
192 |
193 | = 2.0.1 =
194 | * Fix: Resolved an issue with the POT file not properly being generated at release. This resolves the issue with the new UI not being able to be translated.
195 |
196 | = 2.0.0 =
197 | * New: Introducing version 2.0! In this new version the UI is now better looking and snappier than ever. The branding has also been updated to look and feel more modern.
198 |
199 | = 1.7.3 =
200 | * Fix: Resolved an issue with plugin rollbacks not correctly setting a filepath for the plugin being rolled back. Props to WP.org user @itmesteren for the fix.
201 |
202 | = 1.7.2 =
203 | * Fix: Ensure that the "Rollback" button displays properly when a WordPress site only has a single theme installed. Thanks [@eldertech](https://wordpress.org/support/users/eldertech/) for your help uncovering this bug.
204 | * Fix: Minor CSS fixes for the Rollback page.
205 | * Tweak: Update the WordPress.org readme.txt file to have better instructions for translating the plugin. We also fixed a few typos.
206 |
207 | = 1.7.1 =
208 | * Fix: Prevent PHP notice when rolling back a plugin or theme on PHP 7.4.
209 |
210 | = 1.7.0 =
211 | * Tweak: Removed the WP Time Capsule staging button and banner.
212 |
213 | = 1.6.0 =
214 | * New: You now have the ability to rollback to the trunk for plugins. This is useful for beta testing releases and more. Thanks to [karpstrucking](https://github.com/karpstrucking) for making this happen. [#45](https://github.com/impress-org/wp-rollback/issues/45)
215 | * New: Add actions "wpr_plugin_success", "wpr_plugin_failure", "wpr_theme_success", and "wpr_theme_failure" for developers.
216 | * New: If a plugin or theme does not have any tagged releases to select from then then an informative notice appears rather than empty space for a better user experience. [#42](https://github.com/impress-org/wp-rollback/issues/42)
217 | * Tweak: Use the WP.org API to retrieve plugin release version information for more reliable results. [#35](https://github.com/impress-org/wp-rollback/issues/35)
218 |
219 | = 1.5.1 =
220 | * Tweak: Added additional information about the importance of Staging and Backups and links to our preferred plugin.
221 |
222 | = 1.5 =
223 | * New: You can now view plugin changelogs within the rollback screen. [#7](https://github.com/impress-org/wp-rollback/issues/7)
224 | * New: Added support for WordPress Multisite rollbacks for themes and plugins. [#22](https://github.com/impress-org/wp-rollback/issues/22)
225 | * New: Rollback button is fixed to the bottom of the page now to prevent long scrolls for rollbacks with many versions. [#23](https://github.com/impress-org/wp-rollback/issues/23)
226 | * New: Updated the WP.org plugin header graphic. [#37](https://github.com/impress-org/wp-rollback/issues/37)
227 |
228 | = 1.4 =
229 | * New: Updated plugin's text domain to the plugin's slug of 'wp-rollback' to support WordPress' GlotPress translations. [#28](https://github.com/impress-org/wp-rollback/issues/28)
230 | * New: Gulp automated POT file generation and text domain checker. [#28](https://github.com/impress-org/wp-rollback/issues/28)
231 | * Fix: Check the WP install's themes transient is present, if not fetch it to see if a theme can be rolled back. Allows rollbacks for new WP installs or in a case where the transient is not set properly.[#27](https://github.com/impress-org/wp-rollback/issues/27)
232 |
233 | = 1.3 =
234 | * Tested compatibility with WordPress 4.4 and verified as working; bumped up compatibility
235 | * Fix: Trying to get property of non-object warning. [#20](https://github.com/impress-org/wp-rollback/issues/20)
236 | * Improvement: Better version sorting now using usort & version_compare. [#16](https://github.com/impress-org/wp-rollback/issues/16)
237 |
238 | = 1.2.4 =
239 | * New: Portuguese translations added.
240 | * Fix: Limit HTTP requests to Plugin page only. [Report 1](https://wordpress.org/support/topic/great-plugin-but-small-issue?replies=5) [Report 2](https://wordpress.org/support/topic/great-plugin-but-small-issue?replies=1#post-7234287)
241 |
242 | = 1.2.3 =
243 | * Fixed: XSS hardening. Thanks @secupress
244 | * Fixed: CSRF patch regarding missing nonces. Thanks @secupress
245 | * Improvement: escape all of the things.
246 |
247 | = 1.2.2 =
248 | * New: Russian translations from @Flector - thanks!
249 | * Fix: Replaced use of wp_json_encode to support older WordPress versions. [Report](https://wordpress.org/support/topic/wordpress-requirement-issue-with-wp_json_encode)
250 |
251 | = 1.2.1 =
252 | * Fix: Rollback link appears on non wp.org plugins - thanks @scottopolis. [#14](https://github.com/impress-org/wp-rollback/issues/14)
253 | * Removed unnecessary WP_ROLLBACK_VERSION constant.
254 |
255 | = 1.2 =
256 | * New: Swedish translation files - Thanks @WPDailyThemes.
257 |
258 | = 1.1 =
259 | * Fixed "Cancel" button which was falsely submitting the form.
260 |
261 | = 1.0 =
262 | * Initial plugin release. Yippee!
263 | * Adds "Rollback" link to all plugins from the WordPress repo on the plugin screen.
264 | * Adds "Rollback" link to all themes from the WordPress repo inside the modal details screen.
265 | * The "Rollback" page allows you to choose which version you want to rollback to.
266 |
--------------------------------------------------------------------------------