Version Description
- New: You can now view plugin changelogs within the rollback screen. #7
- New: Added support for WordPress Multisite rollbacks for themes and plugins. #22
- New: Rollback button is fixed to the bottom of the page now to prevent long scrolls for rollbacks with many versions. #23
- New: Updated the WP.org plugin header graphic. #37
Download this release
Release Info
Developer | webdevmattcrom |
Plugin | WP Rollback |
Version | 1.5 |
Comparing to | |
See all releases |
Code changes from version 1.4 to 1.5
- assets/css/wp-rollback.css +65 -18
- assets/js/themes-wp-rollback.js +164 -169
- assets/js/wp-rollback.js +118 -26
- includes/class-rollback-plugin-upgrader.php +17 -6
- includes/class-rollback-theme-upgrader.php +18 -10
- includes/rollback-action.php +5 -5
- includes/rollback-menu.php +15 -17
- languages/wp-rollback.pot +37 -24
- license.txt +0 -281
- readme.txt +21 -15
- wp-rollback.php +203 -85
assets/css/wp-rollback.css
CHANGED
@@ -28,29 +28,23 @@
|
|
28 |
font-weight: 600;
|
29 |
}
|
30 |
|
31 |
-
.rollback-form {
|
32 |
-
|
33 |
-
}
|
34 |
-
|
35 |
.wpr-versions-wrap {
|
36 |
padding-left: 20px;
|
|
|
37 |
}
|
38 |
|
39 |
-
.rollback-form label {
|
40 |
-
display: block;
|
41 |
-
padding: 8px 0;
|
42 |
-
font-size: 16px;
|
43 |
-
}
|
44 |
-
|
45 |
-
.rollback-form label input {
|
46 |
-
margin-right: 5px;
|
47 |
-
}
|
48 |
|
49 |
.wpr-submit-wrap {
|
50 |
-
margin: 25px 0 0;
|
51 |
border-top: 1px solid #DADADA;
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
}
|
55 |
|
56 |
.rollback-form .current-version {
|
@@ -74,12 +68,24 @@
|
|
74 |
margin-right: 5px !important;
|
75 |
}
|
76 |
|
77 |
-
/*
|
78 |
|
79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
|
|
|
|
|
81 |
}
|
82 |
|
|
|
|
|
83 |
#wpr-modal-confirm .button-primary {
|
84 |
margin-right: 5px;
|
85 |
}
|
@@ -101,4 +107,45 @@
|
|
101 |
.wpr-rollback-intro {
|
102 |
font-size: 18px;
|
103 |
margin-top: 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
}
|
28 |
font-weight: 600;
|
29 |
}
|
30 |
|
|
|
|
|
|
|
|
|
31 |
.wpr-versions-wrap {
|
32 |
padding-left: 20px;
|
33 |
+
margin-bottom:30px;
|
34 |
}
|
35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
|
37 |
.wpr-submit-wrap {
|
|
|
38 |
border-top: 1px solid #DADADA;
|
39 |
+
position: fixed;
|
40 |
+
width: 100%;
|
41 |
+
display: block;
|
42 |
+
bottom: 0;
|
43 |
+
background: #FFF;
|
44 |
+
margin: 0 0 0 -22px;
|
45 |
+
padding: 20px 0 20px 20px;
|
46 |
+
z-index: 9999;
|
47 |
+
|
48 |
}
|
49 |
|
50 |
.rollback-form .current-version {
|
68 |
margin-right: 5px !important;
|
69 |
}
|
70 |
|
71 |
+
/* List */
|
72 |
|
73 |
+
.wpr-version-li {
|
74 |
+
clear: left;
|
75 |
+
padding: 8px 0;
|
76 |
+
overflow: hidden;
|
77 |
+
}
|
78 |
+
.wpr-version-li label {
|
79 |
+
float:left;
|
80 |
+
font-size: 16px;
|
81 |
+
}
|
82 |
|
83 |
+
.wpr-version-li label input {
|
84 |
+
margin-right: 5px;
|
85 |
}
|
86 |
|
87 |
+
|
88 |
+
/* Modal */
|
89 |
#wpr-modal-confirm .button-primary {
|
90 |
margin-right: 5px;
|
91 |
}
|
107 |
.wpr-rollback-intro {
|
108 |
font-size: 18px;
|
109 |
margin-top: 0;
|
110 |
+
}
|
111 |
+
|
112 |
+
|
113 |
+
/* Changelog link */
|
114 |
+
.wpr-changelog-link {
|
115 |
+
float: left;
|
116 |
+
margin: 4px 0 0 12px;
|
117 |
+
font-size: 11px;
|
118 |
+
font-style: italic;
|
119 |
+
opacity: 0;
|
120 |
+
line-height: 1;
|
121 |
+
transition: .15s ease-in-out;
|
122 |
+
-moz-transition: .15s ease-in-out;
|
123 |
+
-webkit-transition: .15s ease-in-out;
|
124 |
+
display: inline-block;
|
125 |
+
outline:none;
|
126 |
+
box-shadow:none !important;
|
127 |
+
text-decoration: none;
|
128 |
+
}
|
129 |
+
.wpr-changelog-link:hover {
|
130 |
+
text-decoration: underline;
|
131 |
+
}
|
132 |
+
.wpr-version-li:hover .wpr-changelog-link {
|
133 |
+
opacity: 0.75;
|
134 |
+
}
|
135 |
+
/* Hide full changelog */
|
136 |
+
.wpr-changelog, .wpr-hidden-changelog {
|
137 |
+
display: none;
|
138 |
+
}
|
139 |
+
|
140 |
+
/* The changelog that appears when loading via AJAX */
|
141 |
+
.wpr-changelog-entry {
|
142 |
+
padding: 6px 25px 18px;
|
143 |
+
background: #FFF;
|
144 |
+
margin: 20px 0;
|
145 |
+
max-height: 350px;
|
146 |
+
overflow-y: auto;
|
147 |
+
}
|
148 |
+
|
149 |
+
.wpr-no-changelog-message {
|
150 |
+
margin-bottom:0;
|
151 |
}
|
assets/js/themes-wp-rollback.js
CHANGED
@@ -7,172 +7,167 @@
|
|
7 |
var wpr_vars;
|
8 |
jQuery.noConflict();
|
9 |
|
10 |
-
(function
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
});
|
176 |
-
|
177 |
-
|
178 |
-
})(jQuery);
|
7 |
var wpr_vars;
|
8 |
jQuery.noConflict();
|
9 |
|
10 |
+
(function( $ ) {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Content Change DOM Event Listenter
|
14 |
+
*
|
15 |
+
* @see: http://stackoverflow.com/questions/3233991/jquery-watch-div/3234646#3234646
|
16 |
+
* @param callback
|
17 |
+
* @returns {*}
|
18 |
+
*/
|
19 |
+
jQuery.fn.contentChange = function( callback ) {
|
20 |
+
var elms = jQuery( this );
|
21 |
+
elms.each(
|
22 |
+
function( i ) {
|
23 |
+
var elm = jQuery( this );
|
24 |
+
elm.data( 'lastContents', elm.html() );
|
25 |
+
window.watchContentChange = window.watchContentChange ? window.watchContentChange : [];
|
26 |
+
window.watchContentChange.push( { 'element': elm, 'callback': callback } );
|
27 |
+
}
|
28 |
+
);
|
29 |
+
return elms;
|
30 |
+
};
|
31 |
+
setInterval( function() {
|
32 |
+
if ( window.watchContentChange ) {
|
33 |
+
for ( i in window.watchContentChange ) {
|
34 |
+
if ( window.watchContentChange[ i ].element.data( 'lastContents' ) != window.watchContentChange[ i ].element.html() ) {
|
35 |
+
window.watchContentChange[ i ].callback.apply( window.watchContentChange[ i ].element );
|
36 |
+
window.watchContentChange[ i ].element.data( 'lastContents', window.watchContentChange[ i ].element.html() );
|
37 |
+
}
|
38 |
+
|
39 |
+
}
|
40 |
+
}
|
41 |
+
}, 150 );
|
42 |
+
|
43 |
+
// On DOM Ready
|
44 |
+
$( function() {
|
45 |
+
var themes;
|
46 |
+
|
47 |
+
themes = wp.themes = wp.themes || {};
|
48 |
+
themes.data = typeof _wpThemeSettings !== 'undefined' ? _wpThemeSettings : '';
|
49 |
+
|
50 |
+
// On clicking a theme template
|
51 |
+
$( '.theme-overlay' ).contentChange( function( e ) {
|
52 |
+
|
53 |
+
// get theme name that was clicked
|
54 |
+
var clicked_theme = wpr_get_parameter_by_name( 'theme' );
|
55 |
+
|
56 |
+
// check that rollback button hasn't been placed
|
57 |
+
if ( is_rollback_btn_there() ) {
|
58 |
+
// button is there, bail
|
59 |
+
return false;
|
60 |
+
}
|
61 |
+
|
62 |
+
// pass off to rollback function
|
63 |
+
wpr_theme_rollback( clicked_theme );
|
64 |
+
|
65 |
+
} );
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Check to see if Rollback button is in place
|
69 |
+
*
|
70 |
+
* @returns {boolean}
|
71 |
+
*/
|
72 |
+
function is_rollback_btn_there() {
|
73 |
+
|
74 |
+
if ( $( '.wpr-theme-rollback' ).length > 0 ) {
|
75 |
+
return true;
|
76 |
+
}
|
77 |
+
return false;
|
78 |
+
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Is Theme WordPress.org?
|
83 |
+
*
|
84 |
+
* @description Rollback only supports WordPress.org themes
|
85 |
+
*/
|
86 |
+
function wpr_theme_rollback( theme ) {
|
87 |
+
|
88 |
+
var theme_data = wpr_get_theme_data( theme );
|
89 |
+
|
90 |
+
// ensure this theme can be rolled back (not premium, etc)
|
91 |
+
if ( theme_data !== null && typeof theme_data.hasRollback !== 'undefined' && theme_data.hasRollback !== false ) {
|
92 |
+
|
93 |
+
var active_theme = $( '.theme-overlay' ).hasClass( 'active' );
|
94 |
+
|
95 |
+
var rollback_btn_html = '<a href="' + encodeURI( 'index.php?page=wp-rollback&type=theme&theme_file=' + theme + '¤t_version=' + theme_data.version + '&rollback_name=' + theme_data.name + '&_wpnonce=' + wpr_vars.nonce ) + '" style="position:absolute;right: ' + (active_theme === true ? '5px' : '80px') + '; bottom: 5px;" class="button wpr-theme-rollback">' + wpr_vars.text_rollback_label + '</a>';
|
96 |
+
|
97 |
+
$( '.theme-wrap' ).find( '.theme-actions' ).append( rollback_btn_html );
|
98 |
+
|
99 |
+
} else {
|
100 |
+
// Can't roll back this theme, display the notice.
|
101 |
+
$( '.theme-wrap' ).find( '.theme-actions' ).append( '<span class="no-rollback" style="position: absolute;left: 23px;bottom: 16px;font-size: 12px;font-style: italic;color: rgb(181, 181, 181);">' + wpr_vars.text_not_rollbackable + '</span>' );
|
102 |
+
}
|
103 |
+
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Get Theme Data
|
108 |
+
*
|
109 |
+
* @description Loops through the wp.themes.data.themes object, finds a match, and returns the data
|
110 |
+
* @param theme
|
111 |
+
* @returns {*}
|
112 |
+
*/
|
113 |
+
function wpr_get_theme_data( theme ) {
|
114 |
+
|
115 |
+
var theme_data = wp.themes.data.themes;
|
116 |
+
|
117 |
+
// Loop through complete theme data to find this current theme's data
|
118 |
+
for ( var i = 0, len = theme_data.length; i < len; i ++ ) {
|
119 |
+
if ( theme_data[ i ].id === theme ) {
|
120 |
+
return theme_data[ i ]; // Return as soon as the object is found
|
121 |
+
}
|
122 |
+
}
|
123 |
+
return null; // The object was not found
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* JS Ready Query String (Helper)
|
128 |
+
*
|
129 |
+
* Kinda dirty but whatever...
|
130 |
+
*
|
131 |
+
* @see: http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript
|
132 |
+
* @param name
|
133 |
+
* @returns {string}
|
134 |
+
*/
|
135 |
+
function wpr_get_parameter_by_name( name ) {
|
136 |
+
name = name.replace( /[\[]/, '\\[' ).replace( /[\]]/, '\\]' );
|
137 |
+
var regex = new RegExp( '[\\?&]' + name + '=([^&#]*)' ),
|
138 |
+
results = regex.exec( location.search );
|
139 |
+
return results === null ? '' : decodeURIComponent( results[ 1 ].replace( /\+/g, ' ' ) );
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Get Parameter from Focused Theme
|
144 |
+
*
|
145 |
+
* @returns {*}
|
146 |
+
*/
|
147 |
+
function wpr_get_parameter_from_focused_theme() {
|
148 |
+
var focused_theme = wp.themes.focusedTheme;
|
149 |
+
var name = $( focused_theme ).find( '.theme-name' ).attr( 'id' );
|
150 |
+
|
151 |
+
if ( typeof name !== 'undefined' ) {
|
152 |
+
name = name.replace( '-name', '' );
|
153 |
+
} else {
|
154 |
+
return false;
|
155 |
+
}
|
156 |
+
|
157 |
+
return name;
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Theme Rollback Button Clicked
|
162 |
+
*
|
163 |
+
* Send them over to rollback.
|
164 |
+
*/
|
165 |
+
$( 'body' ).on( 'click', '.wpr-theme-rollback', function( e ) {
|
166 |
+
|
167 |
+
window.location = $( this ).attr( 'href' );
|
168 |
+
|
169 |
+
} );
|
170 |
+
|
171 |
+
} );
|
172 |
+
|
173 |
+
})( jQuery );
|
|
|
|
|
|
|
|
|
|
assets/js/wp-rollback.js
CHANGED
@@ -8,58 +8,152 @@
|
|
8 |
var wpr_vars;
|
9 |
|
10 |
jQuery.noConflict();
|
11 |
-
(function
|
12 |
|
13 |
-
//On DOM Ready
|
14 |
-
$( function
|
15 |
|
16 |
var form = $( '.rollback-form' );
|
17 |
var form_labels = $( 'label', form.get( 0 ) );
|
18 |
var form_submit_btn = $( '.magnific-popup' );
|
19 |
|
20 |
-
|
21 |
-
|
|
|
|
|
22 |
|
23 |
-
//add a selected class
|
24 |
form_labels.removeClass( 'wpr-selected' );
|
25 |
form_submit_btn.removeClass( 'wpr-rollback-disabled' );
|
26 |
$( this ).addClass( 'wpr-selected' );
|
27 |
|
28 |
-
//ensure the radio button always gets clicked
|
29 |
$( this ).find( 'input' ).prop( 'checked', true );
|
30 |
|
31 |
} );
|
32 |
|
33 |
-
|
34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
|
36 |
var rollback_form_vals = form.serializeArray();
|
37 |
|
38 |
var rollback_version = form.find( 'input[name="plugin_version"]:checked' ).val();
|
39 |
-
if ( !rollback_version ) {
|
40 |
rollback_version = form.find( 'input[name="theme_version"]:checked' ).val();
|
41 |
}
|
42 |
var installed_version = form.find( 'input[name="installed_version"]' ).val();
|
43 |
var new_version = form.find( 'input[name="new_version"]' ).val();
|
44 |
var rollback_name = form.find( 'input[name="rollback_name"]' ).val();
|
45 |
|
46 |
-
//Ensure a version is selected
|
47 |
-
if ( !rollback_version ) {
|
48 |
|
49 |
alert( wpr_vars.version_missing );
|
50 |
-
$.magnificPopup.close(); //just for good measure
|
51 |
|
52 |
} else {
|
53 |
|
54 |
-
//Passed
|
55 |
$.magnificPopup.open( {
|
56 |
-
items
|
57 |
-
src
|
58 |
type: 'inline'
|
59 |
},
|
60 |
closeBtnInside: false,
|
61 |
-
callbacks
|
62 |
-
open: function
|
63 |
|
64 |
$( 'span.wpr-plugin-name' ).text( rollback_name );
|
65 |
$( 'span.wpr-installed-version' ).text( installed_version );
|
@@ -69,23 +163,21 @@ jQuery.noConflict();
|
|
69 |
}
|
70 |
} );
|
71 |
|
72 |
-
|
73 |
}
|
74 |
|
75 |
} );
|
76 |
|
77 |
-
//Modal Close
|
78 |
-
$( '.wpr-close' ).on( 'click', function
|
79 |
e.preventDefault();
|
80 |
$.magnificPopup.close();
|
81 |
} );
|
82 |
-
//Modal Confirm (GO! GO! GO!)
|
83 |
-
$( '.wpr-go' ).on( 'click', function
|
84 |
-
//submit form
|
85 |
form.submit();
|
86 |
} );
|
87 |
|
88 |
} );
|
89 |
|
90 |
-
|
91 |
-
})( jQuery );
|
8 |
var wpr_vars;
|
9 |
|
10 |
jQuery.noConflict();
|
11 |
+
(function( $ ) {
|
12 |
|
13 |
+
// On DOM Ready
|
14 |
+
$( function() {
|
15 |
|
16 |
var form = $( '.rollback-form' );
|
17 |
var form_labels = $( 'label', form.get( 0 ) );
|
18 |
var form_submit_btn = $( '.magnific-popup' );
|
19 |
|
20 |
+
/**
|
21 |
+
* On version click
|
22 |
+
*/
|
23 |
+
form_labels.on( 'click', function() {
|
24 |
|
25 |
+
// add a selected class
|
26 |
form_labels.removeClass( 'wpr-selected' );
|
27 |
form_submit_btn.removeClass( 'wpr-rollback-disabled' );
|
28 |
$( this ).addClass( 'wpr-selected' );
|
29 |
|
30 |
+
// ensure the radio button always gets clicked
|
31 |
$( this ).find( 'input' ).prop( 'checked', true );
|
32 |
|
33 |
} );
|
34 |
|
35 |
+
/**
|
36 |
+
* On view changelog clicked.
|
37 |
+
*/
|
38 |
+
$( '.wpr-changelog-link' ).on( 'click', function( e ) {
|
39 |
+
|
40 |
+
e.preventDefault();
|
41 |
+
|
42 |
+
var changelog_container = $( '.wpr-changelog' );
|
43 |
+
var changelog_placement = $( this ).parent( 'li' );
|
44 |
+
var version = $( this ).data( 'version' );
|
45 |
+
|
46 |
+
// Ensure all change log links are visible.
|
47 |
+
$('.wpr-changelog-link').removeClass('wpr-hidden-changelog')
|
48 |
+
|
49 |
+
// If changelog was already fetched, use that data.
|
50 |
+
if ( changelog_container.html().length ) {
|
51 |
+
wpr_append_changelog_entry( changelog_placement, version );
|
52 |
+
return false;
|
53 |
+
}
|
54 |
+
|
55 |
+
// Get changelog via AJAX.
|
56 |
+
$.post( ajaxurl, {
|
57 |
+
'action': 'wpr_check_changelog',
|
58 |
+
'slug': $( 'input[name="plugin_slug"]' ).val()
|
59 |
+
}, function( response ) {
|
60 |
+
// Add changelog to DOM.
|
61 |
+
$( changelog_container ).append( $.parseHTML( response ) );
|
62 |
+
|
63 |
+
// Show changelog entry.
|
64 |
+
wpr_append_changelog_entry( changelog_placement, version );
|
65 |
+
|
66 |
+
}
|
67 |
+
);
|
68 |
+
|
69 |
+
} );
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Show changelog entry.
|
73 |
+
*
|
74 |
+
* @param placement
|
75 |
+
* @param version
|
76 |
+
*/
|
77 |
+
function wpr_append_changelog_entry( placement, version ) {
|
78 |
+
|
79 |
+
var changelog = $( '.wpr-changelog' );
|
80 |
+
var changelog_headings = $( changelog ).find( 'h4' );
|
81 |
+
|
82 |
+
// Remove old entry.
|
83 |
+
$( '.wpr-changelog-entry' ).remove();
|
84 |
+
|
85 |
+
// Hide this change log link.
|
86 |
+
$(placement).find('.wpr-changelog-link').addClass('wpr-hidden-changelog');
|
87 |
+
|
88 |
+
// Append a new one.
|
89 |
+
$( placement ).after( '<div class="wpr-changelog-entry"></div>' );
|
90 |
+
|
91 |
+
// Loop through changelog headings to get changelog entry.
|
92 |
+
$( changelog_headings ).each( function( index, value ) {
|
93 |
+
|
94 |
+
var raw_val = $( value ).text();
|
95 |
+
|
96 |
+
// Match the changelog version heading using regex from: https://github.com/sindresorhus/semver-regex/blob/master/index.js
|
97 |
+
// var regex_symver = /\bv?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[\da-z\-]+(?:\.[\da-z\-]+)*)?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?\b/;
|
98 |
+
|
99 |
+
// from: https://stackoverflow.com/a/27540795/684352
|
100 |
+
var regex_symver = /(?:(\d+)\.)?(?:(\d+)\.)?(?:(\d+)\.\d+)?(?:(\d+)\.\d+)/;
|
101 |
+
var found_version_num = raw_val.match( regex_symver );
|
102 |
+
var found_version_num = $( found_version_num ).get( 0 );
|
103 |
+
|
104 |
+
// Match version number.
|
105 |
+
if ( found_version_num == version ) {
|
106 |
+
|
107 |
+
// Assemble entry.
|
108 |
+
var changelog_heading = $( value ).clone();
|
109 |
+
var changelog_entry = $( value ).nextUntil( 'h4' ).clone();
|
110 |
+
|
111 |
+
// Append changelog entry.
|
112 |
+
$( '.wpr-changelog-entry' ).append( changelog_heading ).append( changelog_entry );
|
113 |
+
|
114 |
+
}
|
115 |
+
|
116 |
+
} );
|
117 |
+
|
118 |
+
// If no changelog found, show message.
|
119 |
+
if ( ! $( '.wpr-changelog-entry' ).html().length ) {
|
120 |
+
$( '.wpr-changelog-entry' ).append( '<p class="wpr-no-changelog-message">' + wpr_vars.text_no_changelog_found + '</p>' );
|
121 |
+
}
|
122 |
+
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Modal rollback.
|
127 |
+
*/
|
128 |
+
form_submit_btn.on( 'click', function() {
|
129 |
|
130 |
var rollback_form_vals = form.serializeArray();
|
131 |
|
132 |
var rollback_version = form.find( 'input[name="plugin_version"]:checked' ).val();
|
133 |
+
if ( ! rollback_version ) {
|
134 |
rollback_version = form.find( 'input[name="theme_version"]:checked' ).val();
|
135 |
}
|
136 |
var installed_version = form.find( 'input[name="installed_version"]' ).val();
|
137 |
var new_version = form.find( 'input[name="new_version"]' ).val();
|
138 |
var rollback_name = form.find( 'input[name="rollback_name"]' ).val();
|
139 |
|
140 |
+
// Ensure a version is selected
|
141 |
+
if ( ! rollback_version ) {
|
142 |
|
143 |
alert( wpr_vars.version_missing );
|
144 |
+
$.magnificPopup.close(); // just for good measure
|
145 |
|
146 |
} else {
|
147 |
|
148 |
+
// Passed
|
149 |
$.magnificPopup.open( {
|
150 |
+
items: {
|
151 |
+
src: $( '#wpr-modal-confirm' ), // can be a HTML string, jQuery object, or CSS selector
|
152 |
type: 'inline'
|
153 |
},
|
154 |
closeBtnInside: false,
|
155 |
+
callbacks: {
|
156 |
+
open: function() {
|
157 |
|
158 |
$( 'span.wpr-plugin-name' ).text( rollback_name );
|
159 |
$( 'span.wpr-installed-version' ).text( installed_version );
|
163 |
}
|
164 |
} );
|
165 |
|
|
|
166 |
}
|
167 |
|
168 |
} );
|
169 |
|
170 |
+
// Modal Close
|
171 |
+
$( '.wpr-close' ).on( 'click', function( e ) {
|
172 |
e.preventDefault();
|
173 |
$.magnificPopup.close();
|
174 |
} );
|
175 |
+
// Modal Confirm (GO! GO! GO!)
|
176 |
+
$( '.wpr-go' ).on( 'click', function( e ) {
|
177 |
+
// submit form
|
178 |
form.submit();
|
179 |
} );
|
180 |
|
181 |
} );
|
182 |
|
183 |
+
})( jQuery );
|
|
includes/class-rollback-plugin-upgrader.php
CHANGED
@@ -1,20 +1,31 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
|
|
|
|
4 |
*
|
5 |
-
* @description: Class that extends the WP Core Plugin_Upgrader found in core to do rollbacks
|
6 |
* @copyright : http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
7 |
* @since : 1.0.0
|
8 |
*/
|
9 |
|
10 |
-
// Exit if accessed directly
|
11 |
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
exit;
|
13 |
}
|
14 |
|
15 |
-
|
|
|
|
|
16 |
class WP_Rollback_Plugin_Upgrader extends Plugin_Upgrader {
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
public function rollback( $plugin, $args = array() ) {
|
19 |
|
20 |
$defaults = array(
|
@@ -66,10 +77,10 @@ class WP_Rollback_Plugin_Upgrader extends Plugin_Upgrader {
|
|
66 |
return $this->result;
|
67 |
}
|
68 |
|
69 |
-
// Force refresh of plugin update information
|
70 |
wp_clean_plugins_cache( $parsed_args['clear_update_cache'] );
|
71 |
|
72 |
return true;
|
73 |
}
|
74 |
|
75 |
-
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* WP Rollback Plugin Upgrader
|
4 |
+
*
|
5 |
+
* Class that extends the WP Core Plugin_Upgrader found in core to do rollbacks.
|
6 |
*
|
|
|
7 |
* @copyright : http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
8 |
* @since : 1.0.0
|
9 |
*/
|
10 |
|
11 |
+
// Exit if accessed directly.
|
12 |
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
exit;
|
14 |
}
|
15 |
|
16 |
+
/**
|
17 |
+
* Class WP_Rollback_Plugin_Upgrader
|
18 |
+
*/
|
19 |
class WP_Rollback_Plugin_Upgrader extends Plugin_Upgrader {
|
20 |
|
21 |
+
/**
|
22 |
+
* Plugin rollback.
|
23 |
+
*
|
24 |
+
* @param $plugin
|
25 |
+
* @param array $args
|
26 |
+
*
|
27 |
+
* @return array|bool|\WP_Error
|
28 |
+
*/
|
29 |
public function rollback( $plugin, $args = array() ) {
|
30 |
|
31 |
$defaults = array(
|
77 |
return $this->result;
|
78 |
}
|
79 |
|
80 |
+
// Force refresh of plugin update information.
|
81 |
wp_clean_plugins_cache( $parsed_args['clear_update_cache'] );
|
82 |
|
83 |
return true;
|
84 |
}
|
85 |
|
86 |
+
}
|
includes/class-rollback-theme-upgrader.php
CHANGED
@@ -1,20 +1,31 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
|
|
|
|
4 |
*
|
5 |
-
* @description: Class that extends the WP Core Theme_Upgrader found in core to do rollbacks
|
6 |
* @copyright : http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
7 |
* @since : 1.0.0
|
8 |
*/
|
9 |
|
10 |
-
// Exit if accessed directly
|
11 |
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
exit;
|
13 |
}
|
14 |
|
15 |
-
|
|
|
|
|
16 |
class WP_Rollback_Theme_Upgrader extends Theme_Upgrader {
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
public function rollback( $theme, $args = array() ) {
|
19 |
|
20 |
$defaults = array(
|
@@ -42,13 +53,11 @@ class WP_Rollback_Theme_Upgrader extends Theme_Upgrader {
|
|
42 |
|
43 |
$url = $download_endpoint . $theme_slug . '.' . $theme_version . '.zip';
|
44 |
|
45 |
-
|
46 |
add_filter( 'upgrader_pre_install', array( $this, 'current_before' ), 10, 2 );
|
47 |
add_filter( 'upgrader_post_install', array( $this, 'current_after' ), 10, 2 );
|
48 |
add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ), 10, 4 );
|
49 |
|
50 |
-
//'source_selection' => array($this, 'source_selection'), //there's a trac ticket to move up the directory for zip's which are made a bit differently, useful for non-.org plugins.
|
51 |
-
|
52 |
$this->run( array(
|
53 |
'package' => $url,
|
54 |
'destination' => get_theme_root(),
|
@@ -61,7 +70,6 @@ class WP_Rollback_Theme_Upgrader extends Theme_Upgrader {
|
|
61 |
),
|
62 |
) );
|
63 |
|
64 |
-
|
65 |
remove_filter( 'upgrader_pre_install', array( $this, 'current_before' ) );
|
66 |
remove_filter( 'upgrader_post_install', array( $this, 'current_after' ) );
|
67 |
remove_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ) );
|
@@ -70,11 +78,11 @@ class WP_Rollback_Theme_Upgrader extends Theme_Upgrader {
|
|
70 |
return $this->result;
|
71 |
}
|
72 |
|
73 |
-
// Force refresh of theme update information
|
74 |
wp_clean_themes_cache( $parsed_args['clear_update_cache'] );
|
75 |
|
76 |
return true;
|
77 |
|
78 |
}
|
79 |
|
80 |
-
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* WP Rollback Theme Upgrader
|
4 |
+
*
|
5 |
+
* Class that extends the WP Core Theme_Upgrader found in core to do rollbacks.
|
6 |
*
|
|
|
7 |
* @copyright : http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
8 |
* @since : 1.0.0
|
9 |
*/
|
10 |
|
11 |
+
// Exit if accessed directly.
|
12 |
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
exit;
|
14 |
}
|
15 |
|
16 |
+
/**
|
17 |
+
* Class WP_Rollback_Theme_Upgrader
|
18 |
+
*/
|
19 |
class WP_Rollback_Theme_Upgrader extends Theme_Upgrader {
|
20 |
|
21 |
+
/**
|
22 |
+
* Theme rollback.
|
23 |
+
*
|
24 |
+
* @param $theme
|
25 |
+
* @param array $args
|
26 |
+
*
|
27 |
+
* @return array|bool|\WP_Error
|
28 |
+
*/
|
29 |
public function rollback( $theme, $args = array() ) {
|
30 |
|
31 |
$defaults = array(
|
53 |
|
54 |
$url = $download_endpoint . $theme_slug . '.' . $theme_version . '.zip';
|
55 |
|
|
|
56 |
add_filter( 'upgrader_pre_install', array( $this, 'current_before' ), 10, 2 );
|
57 |
add_filter( 'upgrader_post_install', array( $this, 'current_after' ), 10, 2 );
|
58 |
add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ), 10, 4 );
|
59 |
|
60 |
+
// 'source_selection' => array($this, 'source_selection'), //there's a trac ticket to move up the directory for zip's which are made a bit differently, useful for non-.org plugins.
|
|
|
61 |
$this->run( array(
|
62 |
'package' => $url,
|
63 |
'destination' => get_theme_root(),
|
70 |
),
|
71 |
) );
|
72 |
|
|
|
73 |
remove_filter( 'upgrader_pre_install', array( $this, 'current_before' ) );
|
74 |
remove_filter( 'upgrader_post_install', array( $this, 'current_after' ) );
|
75 |
remove_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ) );
|
78 |
return $this->result;
|
79 |
}
|
80 |
|
81 |
+
// Force refresh of theme update information.
|
82 |
wp_clean_themes_cache( $parsed_args['clear_update_cache'] );
|
83 |
|
84 |
return true;
|
85 |
|
86 |
}
|
87 |
|
88 |
+
}
|
includes/rollback-action.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Rollback Action.
|
4 |
*/
|
5 |
|
6 |
-
// Exit if accessed directly
|
7 |
if ( ! defined( 'ABSPATH' ) ) {
|
8 |
exit;
|
9 |
}
|
@@ -13,10 +13,10 @@ $url = 'index.php?page=wp-rollback&plugin_file=' . esc_url( $args['plugin_fi
|
|
13 |
$plugin = $this->plugin_slug;
|
14 |
$version = $args['plugin_version'];
|
15 |
|
16 |
-
//Theme rollback
|
17 |
if ( ! empty( $_GET['theme_file'] ) && file_exists( WP_CONTENT_DIR . '/themes/' . $_GET['theme_file'] ) ) {
|
18 |
|
19 |
-
//
|
20 |
$nonce = 'upgrade-theme_' . $_GET['theme_file'];
|
21 |
$url = 'index.php?page=wp-rollback&theme_file=' . $args['theme_file'] . 'action=upgrade-theme';
|
22 |
$version = $_GET['theme_version'];
|
@@ -27,11 +27,11 @@ if ( ! empty( $_GET['theme_file'] ) && file_exists( WP_CONTENT_DIR . '/themes/'
|
|
27 |
$upgrader->rollback( $_GET['theme_file'] );
|
28 |
|
29 |
} elseif ( ! empty( $_GET['plugin_file'] ) && file_exists( WP_PLUGIN_DIR . '/' . $_GET['plugin_file'] ) ) {
|
30 |
-
//This is a plugin rollback
|
31 |
$upgrader = new WP_Rollback_Plugin_Upgrader( new Plugin_Upgrader_Skin( compact( 'title', 'nonce', 'url', 'plugin', 'version' ) ) );
|
32 |
|
33 |
$upgrader->rollback( $this->plugin_file );
|
34 |
} else {
|
35 |
-
_e( 'This rollback request is a
|
36 |
}
|
37 |
|
3 |
* Rollback Action.
|
4 |
*/
|
5 |
|
6 |
+
// Exit if accessed directly.
|
7 |
if ( ! defined( 'ABSPATH' ) ) {
|
8 |
exit;
|
9 |
}
|
13 |
$plugin = $this->plugin_slug;
|
14 |
$version = $args['plugin_version'];
|
15 |
|
16 |
+
// Theme rollback.
|
17 |
if ( ! empty( $_GET['theme_file'] ) && file_exists( WP_CONTENT_DIR . '/themes/' . $_GET['theme_file'] ) ) {
|
18 |
|
19 |
+
// Theme specific vars.
|
20 |
$nonce = 'upgrade-theme_' . $_GET['theme_file'];
|
21 |
$url = 'index.php?page=wp-rollback&theme_file=' . $args['theme_file'] . 'action=upgrade-theme';
|
22 |
$version = $_GET['theme_version'];
|
27 |
$upgrader->rollback( $_GET['theme_file'] );
|
28 |
|
29 |
} elseif ( ! empty( $_GET['plugin_file'] ) && file_exists( WP_PLUGIN_DIR . '/' . $_GET['plugin_file'] ) ) {
|
30 |
+
// This is a plugin rollback.
|
31 |
$upgrader = new WP_Rollback_Plugin_Upgrader( new Plugin_Upgrader_Skin( compact( 'title', 'nonce', 'url', 'plugin', 'version' ) ) );
|
32 |
|
33 |
$upgrader->rollback( $this->plugin_file );
|
34 |
} else {
|
35 |
+
_e( 'This rollback request is missing a proper query string. Please contact support.', 'wp-rollback' );
|
36 |
}
|
37 |
|
includes/rollback-menu.php
CHANGED
@@ -2,12 +2,10 @@
|
|
2 |
/**
|
3 |
* Rollback Menu
|
4 |
*
|
5 |
-
*
|
6 |
-
*
|
7 |
*/
|
8 |
|
9 |
-
|
10 |
-
//Ensure we have our necessary query strings
|
11 |
if ( ( ! isset( $_GET['type'] ) && ! isset( $_GET['theme'] ) ) || ( ! isset( $_GET['type'] ) && ! isset( $_GET['plugin_file'] ) ) ) {
|
12 |
wp_die( __( 'WP Rollback is missing necessary parameters to continue. Please contact support.', 'wp-rollback' ) );
|
13 |
}
|
@@ -21,31 +19,32 @@ $plugins = get_plugins();
|
|
21 |
<div class="wpr-content-wrap">
|
22 |
|
23 |
<h1>
|
24 |
-
<img src="<?php echo WP_ROLLBACK_PLUGIN_URL; ?>/assets/images/wprb-icon-final.svg"
|
|
|
25 |
</h1>
|
26 |
|
27 |
<p><?php echo apply_filters( 'wpr_rollback_description', sprintf( __( 'Please select which %1$s version you would like to rollback to from the releases listed below. You currently have version %2$s installed of %3$s.', 'wp-rollback' ), '<span class="type">' . ( $theme_rollback == true ? __( 'theme', 'wp-rollback' ) : __( 'plugin', 'wp-rollback' ) ) . '</span>', '<span class="current-version">' . esc_html( $args['current_version'] ) . '</span>', '<span class="rollback-name">' . esc_html( $args['rollback_name'] ) . '</span>' ) ); ?></p>
|
28 |
|
|
|
29 |
</div>
|
30 |
|
31 |
<?php if ( isset( $args['plugin_file'] ) && in_array( $args['plugin_file'], array_keys( $plugins ) ) ) {
|
32 |
$versions = WP_Rollback()->versions_select( 'plugin' );
|
33 |
} elseif ( $theme_rollback == true && isset( $_GET['theme_file'] ) ) {
|
34 |
-
//
|
35 |
$svn_tags = WP_Rollback()->get_svn_tags( 'theme', $_GET['theme_file'] );
|
36 |
-
|
37 |
$this->current_version = $_GET['current_version'];
|
38 |
$versions = WP_Rollback()->versions_select( 'theme' );
|
39 |
|
40 |
} else {
|
41 |
-
//Fallback check
|
42 |
-
wp_die( 'Oh no! We\'re missing required rollback query strings. Please contact support so we can check this bug out and squash it!', 'wp-rollback' );
|
43 |
-
}
|
44 |
-
?>
|
45 |
|
46 |
<form name="check_for_rollbacks" class="rollback-form" action="<?php echo admin_url( '/index.php' ); ?>">
|
47 |
<?php
|
48 |
-
//Output Versions
|
49 |
if ( ! empty( $versions ) ) { ?>
|
50 |
|
51 |
<div class="wpr-versions-wrap">
|
@@ -68,9 +67,10 @@ $plugins = get_plugins();
|
|
68 |
<?php do_action( 'wpr_hidden_fields' ); ?>
|
69 |
<input type="hidden" name="page" value="wp-rollback">
|
70 |
<?php
|
71 |
-
//Important: We need the appropriate file to perform a rollback
|
72 |
if ( $plugin_rollback == true ) { ?>
|
73 |
<input type="hidden" name="plugin_file" value="<?php echo esc_attr( $args['plugin_file'] ); ?>">
|
|
|
74 |
<?php } else { ?>
|
75 |
<input type="hidden" name="theme_file" value="<?php echo esc_attr( $_GET['theme_file'] ); ?>">
|
76 |
<?php } ?>
|
@@ -80,9 +80,7 @@ $plugins = get_plugins();
|
|
80 |
|
81 |
<div id="wpr-modal-confirm" class="white-popup mfp-hide">
|
82 |
<div class="wpr-modal-inner">
|
83 |
-
<p class="wpr-rollback-intro"><?php
|
84 |
-
_e( 'Are you sure you want to perform the following rollback?', 'wp-rollback' );
|
85 |
-
?></p>
|
86 |
|
87 |
<div class="rollback-details">
|
88 |
<table class="widefat">
|
@@ -128,4 +126,4 @@ $plugins = get_plugins();
|
|
128 |
|
129 |
</form>
|
130 |
|
131 |
-
</div>
|
2 |
/**
|
3 |
* Rollback Menu
|
4 |
*
|
5 |
+
* Provides the rollback screen view with releases.
|
|
|
6 |
*/
|
7 |
|
8 |
+
// Ensure we have our necessary query strings
|
|
|
9 |
if ( ( ! isset( $_GET['type'] ) && ! isset( $_GET['theme'] ) ) || ( ! isset( $_GET['type'] ) && ! isset( $_GET['plugin_file'] ) ) ) {
|
10 |
wp_die( __( 'WP Rollback is missing necessary parameters to continue. Please contact support.', 'wp-rollback' ) );
|
11 |
}
|
19 |
<div class="wpr-content-wrap">
|
20 |
|
21 |
<h1>
|
22 |
+
<img src="<?php echo WP_ROLLBACK_PLUGIN_URL; ?>/assets/images/wprb-icon-final.svg"
|
23 |
+
onerror="this.onerror=null; this.src='<?php echo WP_ROLLBACK_PLUGIN_URL; ?>/assets/images/wprb-logo.png';"><?php _e( 'WP Rollback', 'wp-rollback' ); ?>
|
24 |
</h1>
|
25 |
|
26 |
<p><?php echo apply_filters( 'wpr_rollback_description', sprintf( __( 'Please select which %1$s version you would like to rollback to from the releases listed below. You currently have version %2$s installed of %3$s.', 'wp-rollback' ), '<span class="type">' . ( $theme_rollback == true ? __( 'theme', 'wp-rollback' ) : __( 'plugin', 'wp-rollback' ) ) . '</span>', '<span class="current-version">' . esc_html( $args['current_version'] ) . '</span>', '<span class="rollback-name">' . esc_html( $args['rollback_name'] ) . '</span>' ) ); ?></p>
|
27 |
|
28 |
+
<div class="wpr-changelog"></div>
|
29 |
</div>
|
30 |
|
31 |
<?php if ( isset( $args['plugin_file'] ) && in_array( $args['plugin_file'], array_keys( $plugins ) ) ) {
|
32 |
$versions = WP_Rollback()->versions_select( 'plugin' );
|
33 |
} elseif ( $theme_rollback == true && isset( $_GET['theme_file'] ) ) {
|
34 |
+
// Theme rollback: set up our theme vars
|
35 |
$svn_tags = WP_Rollback()->get_svn_tags( 'theme', $_GET['theme_file'] );
|
36 |
+
WP_Rollback()->set_svn_versions_data( $svn_tags );
|
37 |
$this->current_version = $_GET['current_version'];
|
38 |
$versions = WP_Rollback()->versions_select( 'theme' );
|
39 |
|
40 |
} else {
|
41 |
+
// Fallback check
|
42 |
+
wp_die( __( 'Oh no! We\'re missing required rollback query strings. Please contact support so we can check this bug out and squash it!', 'wp-rollback' ) );
|
43 |
+
} ?>
|
|
|
44 |
|
45 |
<form name="check_for_rollbacks" class="rollback-form" action="<?php echo admin_url( '/index.php' ); ?>">
|
46 |
<?php
|
47 |
+
// Output Versions
|
48 |
if ( ! empty( $versions ) ) { ?>
|
49 |
|
50 |
<div class="wpr-versions-wrap">
|
67 |
<?php do_action( 'wpr_hidden_fields' ); ?>
|
68 |
<input type="hidden" name="page" value="wp-rollback">
|
69 |
<?php
|
70 |
+
// Important: We need the appropriate file to perform a rollback
|
71 |
if ( $plugin_rollback == true ) { ?>
|
72 |
<input type="hidden" name="plugin_file" value="<?php echo esc_attr( $args['plugin_file'] ); ?>">
|
73 |
+
<input type="hidden" name="plugin_slug" value="<?php echo esc_attr( $args['plugin_slug'] ); ?>">
|
74 |
<?php } else { ?>
|
75 |
<input type="hidden" name="theme_file" value="<?php echo esc_attr( $_GET['theme_file'] ); ?>">
|
76 |
<?php } ?>
|
80 |
|
81 |
<div id="wpr-modal-confirm" class="white-popup mfp-hide">
|
82 |
<div class="wpr-modal-inner">
|
83 |
+
<p class="wpr-rollback-intro"><?php _e( 'Are you sure you want to perform the following rollback?', 'wp-rollback' ); ?></p>
|
|
|
|
|
84 |
|
85 |
<div class="rollback-details">
|
86 |
<table class="widefat">
|
126 |
|
127 |
</form>
|
128 |
|
129 |
+
</div>
|
languages/wp-rollback.pot
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
# Copyright (C)
|
2 |
# This file is distributed under the same license as the WP Rollback package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
@@ -7,7 +7,7 @@ msgstr ""
|
|
7 |
"MIME-Version: 1.0\n"
|
8 |
"Content-Type: text/plain; charset=UTF-8\n"
|
9 |
"Content-Transfer-Encoding: 8bit\n"
|
10 |
-
"PO-Revision-Date:
|
11 |
"Language-Team: WordImpress <info@wordimpress.com>\n"
|
12 |
"X-Poedit-Basepath: ..\n"
|
13 |
"X-Poedit-SourceCharset: UTF-8\n"
|
@@ -15,90 +15,103 @@ msgstr ""
|
|
15 |
"X-Poedit-SearchPath-0: .\n"
|
16 |
"X-Poedit-SearchPathExcluded-0: *.js\n"
|
17 |
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
|
18 |
#: includes/rollback-action.php:35
|
19 |
-
msgid "This rollback request is a
|
20 |
msgstr ""
|
21 |
|
22 |
-
#: includes/rollback-menu.php:
|
23 |
msgid "WP Rollback is missing necessary parameters to continue. Please contact support."
|
24 |
msgstr ""
|
25 |
|
26 |
-
#: includes/rollback-menu.php:
|
27 |
msgid "WP Rollback"
|
28 |
msgstr ""
|
29 |
|
30 |
-
#: includes/rollback-menu.php:
|
31 |
msgid "Please select which %1$s version you would like to rollback to from the releases listed below. You currently have version %2$s installed of %3$s."
|
32 |
msgstr ""
|
33 |
|
34 |
-
#: includes/rollback-menu.php:
|
35 |
msgid "theme"
|
36 |
msgstr ""
|
37 |
|
38 |
-
#: includes/rollback-menu.php:
|
39 |
msgid "plugin"
|
40 |
msgstr ""
|
41 |
|
42 |
-
#: includes/rollback-menu.php:
|
|
|
|
|
|
|
|
|
43 |
msgid "Rollback"
|
44 |
msgstr ""
|
45 |
|
46 |
-
#: includes/rollback-menu.php:
|
47 |
msgid "Cancel"
|
48 |
msgstr ""
|
49 |
|
50 |
-
#: includes/rollback-menu.php:
|
51 |
msgid "Are you sure you want to perform the following rollback?"
|
52 |
msgstr ""
|
53 |
|
54 |
-
#: includes/rollback-menu.php:
|
55 |
msgid "Plugin Name:"
|
56 |
msgstr ""
|
57 |
|
58 |
-
#: includes/rollback-menu.php:
|
59 |
msgid "Theme Name:"
|
60 |
msgstr ""
|
61 |
|
62 |
-
#: includes/rollback-menu.php:
|
63 |
msgid "Installed Version:"
|
64 |
msgstr ""
|
65 |
|
66 |
-
#: includes/rollback-menu.php:
|
67 |
msgid "New Version:"
|
68 |
msgstr ""
|
69 |
|
70 |
-
#: includes/rollback-menu.php:
|
71 |
msgid "<strong>Notice:</strong> We strongly recommend you perform a test rollback on a staging site and create a complete backup of your WordPress files and database prior to performing a rollback. We are not responsible for any misuse, deletions, white screens, fatal errors, or any other issue arising from using this plugin."
|
72 |
msgstr ""
|
73 |
|
74 |
-
#: wp-rollback.php:
|
75 |
msgid "Cheatin’ huh?"
|
76 |
msgstr ""
|
77 |
|
78 |
-
#: wp-rollback.php:
|
79 |
msgid "No Rollback Available: This is a non-WordPress.org theme."
|
80 |
msgstr ""
|
81 |
|
82 |
-
#: wp-rollback.php:
|
83 |
msgid "Loading..."
|
84 |
msgstr ""
|
85 |
|
86 |
-
#: wp-rollback.php:
|
|
|
|
|
|
|
|
|
87 |
msgid "Please select a version number to perform a rollback."
|
88 |
msgstr ""
|
89 |
|
90 |
-
#: wp-rollback.php:
|
91 |
msgid "You do not have sufficient permissions to perform rollbacks for this site."
|
92 |
msgstr ""
|
93 |
|
94 |
-
#: wp-rollback.php:
|
95 |
msgid "Installed Version"
|
96 |
msgstr ""
|
97 |
|
98 |
-
#: wp-rollback.php:
|
|
|
|
|
|
|
|
|
99 |
msgid "An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href=\"https://wordpress.org/support/\">support forums</a>."
|
100 |
msgstr ""
|
101 |
|
102 |
-
#: wp-rollback.php:
|
103 |
msgid "(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)"
|
104 |
msgstr ""
|
1 |
+
# Copyright (C) 2017 WP Rollback
|
2 |
# This file is distributed under the same license as the WP Rollback package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
7 |
"MIME-Version: 1.0\n"
|
8 |
"Content-Type: text/plain; charset=UTF-8\n"
|
9 |
"Content-Transfer-Encoding: 8bit\n"
|
10 |
+
"PO-Revision-Date: 2017-MO-DA HO:MI+ZONE\n"
|
11 |
"Language-Team: WordImpress <info@wordimpress.com>\n"
|
12 |
"X-Poedit-Basepath: ..\n"
|
13 |
"X-Poedit-SourceCharset: UTF-8\n"
|
15 |
"X-Poedit-SearchPath-0: .\n"
|
16 |
"X-Poedit-SearchPathExcluded-0: *.js\n"
|
17 |
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
18 |
+
|
19 |
#: includes/rollback-action.php:35
|
20 |
+
msgid "This rollback request is missing a proper query string. Please contact support."
|
21 |
msgstr ""
|
22 |
|
23 |
+
#: includes/rollback-menu.php:10
|
24 |
msgid "WP Rollback is missing necessary parameters to continue. Please contact support."
|
25 |
msgstr ""
|
26 |
|
27 |
+
#: includes/rollback-menu.php:23
|
28 |
msgid "WP Rollback"
|
29 |
msgstr ""
|
30 |
|
31 |
+
#: includes/rollback-menu.php:26
|
32 |
msgid "Please select which %1$s version you would like to rollback to from the releases listed below. You currently have version %2$s installed of %3$s."
|
33 |
msgstr ""
|
34 |
|
35 |
+
#: includes/rollback-menu.php:26
|
36 |
msgid "theme"
|
37 |
msgstr ""
|
38 |
|
39 |
+
#: includes/rollback-menu.php:26
|
40 |
msgid "plugin"
|
41 |
msgstr ""
|
42 |
|
43 |
+
#: includes/rollback-menu.php:42
|
44 |
+
msgid "Oh no! We're missing required rollback query strings. Please contact support so we can check this bug out and squash it!"
|
45 |
+
msgstr ""
|
46 |
+
|
47 |
+
#: includes/rollback-menu.php:64, includes/rollback-menu.php:121, wp-rollback.php:263, wp-rollback.php:567, wp-rollback.php:567, wp-rollback.php:637, wp-rollback.php:688
|
48 |
msgid "Rollback"
|
49 |
msgstr ""
|
50 |
|
51 |
+
#: includes/rollback-menu.php:65, includes/rollback-menu.php:122
|
52 |
msgid "Cancel"
|
53 |
msgstr ""
|
54 |
|
55 |
+
#: includes/rollback-menu.php:83
|
56 |
msgid "Are you sure you want to perform the following rollback?"
|
57 |
msgstr ""
|
58 |
|
59 |
+
#: includes/rollback-menu.php:92
|
60 |
msgid "Plugin Name:"
|
61 |
msgstr ""
|
62 |
|
63 |
+
#: includes/rollback-menu.php:94
|
64 |
msgid "Theme Name:"
|
65 |
msgstr ""
|
66 |
|
67 |
+
#: includes/rollback-menu.php:101
|
68 |
msgid "Installed Version:"
|
69 |
msgstr ""
|
70 |
|
71 |
+
#: includes/rollback-menu.php:107
|
72 |
msgid "New Version:"
|
73 |
msgstr ""
|
74 |
|
75 |
+
#: includes/rollback-menu.php:117
|
76 |
msgid "<strong>Notice:</strong> We strongly recommend you perform a test rollback on a staging site and create a complete backup of your WordPress files and database prior to performing a rollback. We are not responsible for any misuse, deletions, white screens, fatal errors, or any other issue arising from using this plugin."
|
77 |
msgstr ""
|
78 |
|
79 |
+
#: wp-rollback.php:148, wp-rollback.php:160
|
80 |
msgid "Cheatin’ huh?"
|
81 |
msgstr ""
|
82 |
|
83 |
+
#: wp-rollback.php:264
|
84 |
msgid "No Rollback Available: This is a non-WordPress.org theme."
|
85 |
msgstr ""
|
86 |
|
87 |
+
#: wp-rollback.php:265
|
88 |
msgid "Loading..."
|
89 |
msgstr ""
|
90 |
|
91 |
+
#: wp-rollback.php:294
|
92 |
+
msgid "Sorry, we couldn't find a changelog entry found for this version. Try checking the <a href=\"%s\" target=\"_blank\">developer log</a> on WP.org."
|
93 |
+
msgstr ""
|
94 |
+
|
95 |
+
#: wp-rollback.php:295
|
96 |
msgid "Please select a version number to perform a rollback."
|
97 |
msgstr ""
|
98 |
|
99 |
+
#: wp-rollback.php:340
|
100 |
msgid "You do not have sufficient permissions to perform rollbacks for this site."
|
101 |
msgstr ""
|
102 |
|
103 |
+
#: wp-rollback.php:503
|
104 |
msgid "Installed Version"
|
105 |
msgstr ""
|
106 |
|
107 |
+
#: wp-rollback.php:510
|
108 |
+
msgid "View Changelog"
|
109 |
+
msgstr ""
|
110 |
+
|
111 |
+
#: wp-rollback.php:804
|
112 |
msgid "An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href=\"https://wordpress.org/support/\">support forums</a>."
|
113 |
msgstr ""
|
114 |
|
115 |
+
#: wp-rollback.php:804
|
116 |
msgid "(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)"
|
117 |
msgstr ""
|
license.txt
DELETED
@@ -1,281 +0,0 @@
|
|
1 |
-
GNU GENERAL PUBLIC LICENSE
|
2 |
-
Version 2, June 1991
|
3 |
-
|
4 |
-
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
5 |
-
51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
6 |
-
|
7 |
-
Everyone is permitted to copy and distribute verbatim copies
|
8 |
-
of this license document, but changing it is not allowed.
|
9 |
-
|
10 |
-
Preamble
|
11 |
-
|
12 |
-
The licenses for most software are designed to take away your
|
13 |
-
freedom to share and change it. By contrast, the GNU General Public
|
14 |
-
License is intended to guarantee your freedom to share and change free
|
15 |
-
software--to make sure the software is free for all its users. This
|
16 |
-
General Public License applies to most of the Free Software
|
17 |
-
Foundation's software and to any other program whose authors commit to
|
18 |
-
using it. (Some other Free Software Foundation software is covered by
|
19 |
-
the GNU Library General Public License instead.) You can apply it to
|
20 |
-
your programs, too.
|
21 |
-
|
22 |
-
When we speak of free software, we are referring to freedom, not
|
23 |
-
price. Our General Public Licenses are designed to make sure that you
|
24 |
-
have the freedom to distribute copies of free software (and charge for
|
25 |
-
this service if you wish), that you receive source code or can get it
|
26 |
-
if you want it, that you can change the software or use pieces of it
|
27 |
-
in new free programs; and that you know you can do these things.
|
28 |
-
|
29 |
-
To protect your rights, we need to make restrictions that forbid
|
30 |
-
anyone to deny you these rights or to ask you to surrender the rights.
|
31 |
-
These restrictions translate to certain responsibilities for you if you
|
32 |
-
distribute copies of the software, or if you modify it.
|
33 |
-
|
34 |
-
For example, if you distribute copies of such a program, whether
|
35 |
-
gratis or for a fee, you must give the recipients all the rights that
|
36 |
-
you have. You must make sure that they, too, receive or can get the
|
37 |
-
source code. And you must show them these terms so they know their
|
38 |
-
rights.
|
39 |
-
|
40 |
-
We protect your rights with two steps: (1) copyright the software, and
|
41 |
-
(2) offer you this license which gives you legal permission to copy,
|
42 |
-
distribute and/or modify the software.
|
43 |
-
|
44 |
-
Also, for each author's protection and ours, we want to make certain
|
45 |
-
that everyone understands that there is no warranty for this free
|
46 |
-
software. If the software is modified by someone else and passed on, we
|
47 |
-
want its recipients to know that what they have is not the original, so
|
48 |
-
that any problems introduced by others will not reflect on the original
|
49 |
-
authors' reputations.
|
50 |
-
|
51 |
-
Finally, any free program is threatened constantly by software
|
52 |
-
patents. We wish to avoid the danger that redistributors of a free
|
53 |
-
program will individually obtain patent licenses, in effect making the
|
54 |
-
program proprietary. To prevent this, we have made it clear that any
|
55 |
-
patent must be licensed for everyone's free use or not licensed at all.
|
56 |
-
|
57 |
-
The precise terms and conditions for copying, distribution and
|
58 |
-
modification follow.
|
59 |
-
|
60 |
-
GNU GENERAL PUBLIC LICENSE
|
61 |
-
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
62 |
-
|
63 |
-
0. This License applies to any program or other work which contains
|
64 |
-
a notice placed by the copyright holder saying it may be distributed
|
65 |
-
under the terms of this General Public License. The "Program", below,
|
66 |
-
refers to any such program or work, and a "work based on the Program"
|
67 |
-
means either the Program or any derivative work under copyright law:
|
68 |
-
that is to say, a work containing the Program or a portion of it,
|
69 |
-
either verbatim or with modifications and/or translated into another
|
70 |
-
language. (Hereinafter, translation is included without limitation in
|
71 |
-
the term "modification".) Each licensee is addressed as "you".
|
72 |
-
|
73 |
-
Activities other than copying, distribution and modification are not
|
74 |
-
covered by this License; they are outside its scope. The act of
|
75 |
-
running the Program is not restricted, and the output from the Program
|
76 |
-
is covered only if its contents constitute a work based on the
|
77 |
-
Program (independent of having been made by running the Program).
|
78 |
-
Whether that is true depends on what the Program does.
|
79 |
-
|
80 |
-
1. You may copy and distribute verbatim copies of the Program's
|
81 |
-
source code as you receive it, in any medium, provided that you
|
82 |
-
conspicuously and appropriately publish on each copy an appropriate
|
83 |
-
copyright notice and disclaimer of warranty; keep intact all the
|
84 |
-
notices that refer to this License and to the absence of any warranty;
|
85 |
-
and give any other recipients of the Program a copy of this License
|
86 |
-
along with the Program.
|
87 |
-
|
88 |
-
You may charge a fee for the physical act of transferring a copy, and
|
89 |
-
you may at your option offer warranty protection in exchange for a fee.
|
90 |
-
|
91 |
-
2. You may modify your copy or copies of the Program or any portion
|
92 |
-
of it, thus forming a work based on the Program, and copy and
|
93 |
-
distribute such modifications or work under the terms of Section 1
|
94 |
-
above, provided that you also meet all of these conditions:
|
95 |
-
|
96 |
-
a) You must cause the modified files to carry prominent notices
|
97 |
-
stating that you changed the files and the date of any change.
|
98 |
-
|
99 |
-
b) You must cause any work that you distribute or publish, that in
|
100 |
-
whole or in part contains or is derived from the Program or any
|
101 |
-
part thereof, to be licensed as a whole at no charge to all third
|
102 |
-
parties under the terms of this License.
|
103 |
-
|
104 |
-
c) If the modified program normally reads commands interactively
|
105 |
-
when run, you must cause it, when started running for such
|
106 |
-
interactive use in the most ordinary way, to print or display an
|
107 |
-
announcement including an appropriate copyright notice and a
|
108 |
-
notice that there is no warranty (or else, saying that you provide
|
109 |
-
a warranty) and that users may redistribute the program under
|
110 |
-
these conditions, and telling the user how to view a copy of this
|
111 |
-
License. (Exception: if the Program itself is interactive but
|
112 |
-
does not normally print such an announcement, your work based on
|
113 |
-
the Program is not required to print an announcement.)
|
114 |
-
|
115 |
-
These requirements apply to the modified work as a whole. If
|
116 |
-
identifiable sections of that work are not derived from the Program,
|
117 |
-
and can be reasonably considered independent and separate works in
|
118 |
-
themselves, then this License, and its terms, do not apply to those
|
119 |
-
sections when you distribute them as separate works. But when you
|
120 |
-
distribute the same sections as part of a whole which is a work based
|
121 |
-
on the Program, the distribution of the whole must be on the terms of
|
122 |
-
this License, whose permissions for other licensees extend to the
|
123 |
-
entire whole, and thus to each and every part regardless of who wrote it.
|
124 |
-
Thus, it is not the intent of this section to claim rights or contest
|
125 |
-
your rights to work written entirely by you; rather, the intent is to
|
126 |
-
exercise the right to control the distribution of derivative or
|
127 |
-
collective works based on the Program.
|
128 |
-
|
129 |
-
In addition, mere aggregation of another work not based on the Program
|
130 |
-
with the Program (or with a work based on the Program) on a volume of
|
131 |
-
a storage or distribution medium does not bring the other work under
|
132 |
-
the scope of this License.
|
133 |
-
|
134 |
-
3. You may copy and distribute the Program (or a work based on it,
|
135 |
-
under Section 2) in object code or executable form under the terms of
|
136 |
-
Sections 1 and 2 above provided that you also do one of the following:
|
137 |
-
|
138 |
-
a) Accompany it with the complete corresponding machine-readable
|
139 |
-
source code, which must be distributed under the terms of Sections
|
140 |
-
1 and 2 above on a medium customarily used for software interchange; or,
|
141 |
-
|
142 |
-
b) Accompany it with a written offer, valid for at least three
|
143 |
-
years, to give any third party, for a charge no more than your
|
144 |
-
cost of physically performing source distribution, a complete
|
145 |
-
machine-readable copy of the corresponding source code, to be
|
146 |
-
distributed under the terms of Sections 1 and 2 above on a medium
|
147 |
-
customarily used for software interchange; or,
|
148 |
-
|
149 |
-
c) Accompany it with the information you received as to the offer
|
150 |
-
to distribute corresponding source code. (This alternative is
|
151 |
-
allowed only for noncommercial distribution and only if you
|
152 |
-
received the program in object code or executable form with such
|
153 |
-
an offer, in accord with Subsection b above.)
|
154 |
-
|
155 |
-
The source code for a work means the preferred form of the work for
|
156 |
-
making modifications to it. For an executable work, complete source
|
157 |
-
code means all the source code for all modules it contains, plus any
|
158 |
-
associated interface definition files, plus the scripts used to
|
159 |
-
control compilation and installation of the executable. However, as a
|
160 |
-
special exception, the source code distributed need not include
|
161 |
-
anything that is normally distributed (in either source or binary
|
162 |
-
form) with the major components (compiler, kernel, and so on) of the
|
163 |
-
operating system on which the executable runs, unless that component
|
164 |
-
itself accompanies the executable.
|
165 |
-
|
166 |
-
If distribution of executable or object code is made by offering
|
167 |
-
access to copy from a designated place, then offering equivalent
|
168 |
-
access to copy the source code from the same place counts as
|
169 |
-
distribution of the source code, even though third parties are not
|
170 |
-
compelled to copy the source along with the object code.
|
171 |
-
|
172 |
-
4. You may not copy, modify, sublicense, or distribute the Program
|
173 |
-
except as expressly provided under this License. Any attempt
|
174 |
-
otherwise to copy, modify, sublicense or distribute the Program is
|
175 |
-
void, and will automatically terminate your rights under this License.
|
176 |
-
However, parties who have received copies, or rights, from you under
|
177 |
-
this License will not have their licenses terminated so long as such
|
178 |
-
parties remain in full compliance.
|
179 |
-
|
180 |
-
5. You are not required to accept this License, since you have not
|
181 |
-
signed it. However, nothing else grants you permission to modify or
|
182 |
-
distribute the Program or its derivative works. These actions are
|
183 |
-
prohibited by law if you do not accept this License. Therefore, by
|
184 |
-
modifying or distributing the Program (or any work based on the
|
185 |
-
Program), you indicate your acceptance of this License to do so, and
|
186 |
-
all its terms and conditions for copying, distributing or modifying
|
187 |
-
the Program or works based on it.
|
188 |
-
|
189 |
-
6. Each time you redistribute the Program (or any work based on the
|
190 |
-
Program), the recipient automatically receives a license from the
|
191 |
-
original licensor to copy, distribute or modify the Program subject to
|
192 |
-
these terms and conditions. You may not impose any further
|
193 |
-
restrictions on the recipients' exercise of the rights granted herein.
|
194 |
-
You are not responsible for enforcing compliance by third parties to
|
195 |
-
this License.
|
196 |
-
|
197 |
-
7. If, as a consequence of a court judgment or allegation of patent
|
198 |
-
infringement or for any other reason (not limited to patent issues),
|
199 |
-
conditions are imposed on you (whether by court order, agreement or
|
200 |
-
otherwise) that contradict the conditions of this License, they do not
|
201 |
-
excuse you from the conditions of this License. If you cannot
|
202 |
-
distribute so as to satisfy simultaneously your obligations under this
|
203 |
-
License and any other pertinent obligations, then as a consequence you
|
204 |
-
may not distribute the Program at all. For example, if a patent
|
205 |
-
license would not permit royalty-free redistribution of the Program by
|
206 |
-
all those who receive copies directly or indirectly through you, then
|
207 |
-
the only way you could satisfy both it and this License would be to
|
208 |
-
refrain entirely from distribution of the Program.
|
209 |
-
|
210 |
-
If any portion of this section is held invalid or unenforceable under
|
211 |
-
any particular circumstance, the balance of the section is intended to
|
212 |
-
apply and the section as a whole is intended to apply in other
|
213 |
-
circumstances.
|
214 |
-
|
215 |
-
It is not the purpose of this section to induce you to infringe any
|
216 |
-
patents or other property right claims or to contest validity of any
|
217 |
-
such claims; this section has the sole purpose of protecting the
|
218 |
-
integrity of the free software distribution system, which is
|
219 |
-
implemented by public license practices. Many people have made
|
220 |
-
generous contributions to the wide range of software distributed
|
221 |
-
through that system in reliance on consistent application of that
|
222 |
-
system; it is up to the author/donor to decide if he or she is willing
|
223 |
-
to distribute software through any other system and a licensee cannot
|
224 |
-
impose that choice.
|
225 |
-
|
226 |
-
This section is intended to make thoroughly clear what is believed to
|
227 |
-
be a consequence of the rest of this License.
|
228 |
-
|
229 |
-
8. If the distribution and/or use of the Program is restricted in
|
230 |
-
certain countries either by patents or by copyrighted interfaces, the
|
231 |
-
original copyright holder who places the Program under this License
|
232 |
-
may add an explicit geographical distribution limitation excluding
|
233 |
-
those countries, so that distribution is permitted only in or among
|
234 |
-
countries not thus excluded. In such case, this License incorporates
|
235 |
-
the limitation as if written in the body of this License.
|
236 |
-
|
237 |
-
9. The Free Software Foundation may publish revised and/or new versions
|
238 |
-
of the General Public License from time to time. Such new versions will
|
239 |
-
be similar in spirit to the present version, but may differ in detail to
|
240 |
-
address new problems or concerns.
|
241 |
-
|
242 |
-
Each version is given a distinguishing version number. If the Program
|
243 |
-
specifies a version number of this License which applies to it and "any
|
244 |
-
later version", you have the option of following the terms and conditions
|
245 |
-
either of that version or of any later version published by the Free
|
246 |
-
Software Foundation. If the Program does not specify a version number of
|
247 |
-
this License, you may choose any version ever published by the Free Software
|
248 |
-
Foundation.
|
249 |
-
|
250 |
-
10. If you wish to incorporate parts of the Program into other free
|
251 |
-
programs whose distribution conditions are different, write to the author
|
252 |
-
to ask for permission. For software which is copyrighted by the Free
|
253 |
-
Software Foundation, write to the Free Software Foundation; we sometimes
|
254 |
-
make exceptions for this. Our decision will be guided by the two goals
|
255 |
-
of preserving the free status of all derivatives of our free software and
|
256 |
-
of promoting the sharing and reuse of software generally.
|
257 |
-
|
258 |
-
NO WARRANTY
|
259 |
-
|
260 |
-
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
261 |
-
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
262 |
-
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
263 |
-
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
264 |
-
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
265 |
-
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
266 |
-
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
267 |
-
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
268 |
-
REPAIR OR CORRECTION.
|
269 |
-
|
270 |
-
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
271 |
-
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
272 |
-
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
273 |
-
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
274 |
-
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
275 |
-
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
276 |
-
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
277 |
-
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
278 |
-
POSSIBILITY OF SUCH DAMAGES.
|
279 |
-
|
280 |
-
END OF TERMS AND CONDITIONS
|
281 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: wordimpress, dlocc, drrobotnik, webdevmattcrom
|
|
3 |
Tags: rollback, revert, downgrade, version, plugins, themes, version, versions, backup, backups, revision, revisions
|
4 |
Requires at least: 4.0
|
5 |
Donate Link: https://wordimpress.com
|
6 |
-
Tested up to: 4.
|
7 |
-
Stable tag: 1.
|
8 |
License: GPLv3
|
9 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
10 |
|
@@ -85,7 +85,7 @@ The documentation for this plugin is located on our [Github Wiki](https://github
|
|
85 |
|
86 |
Yes! All strings are internationalized and ready to be translated. Simply use the languages/wp-rollback.pot file and your favorite translation tool. Once finished, please reach out to us on the WordPress.org forums or better yet, submit a pull request on the [Github Repo](https://github.com/WordImpress/WP-Rollback/).
|
87 |
|
88 |
-
= Did this plugin
|
89 |
|
90 |
Heck yes it did! The WordImpress team took home the gold.
|
91 |
|
@@ -111,19 +111,25 @@ This is the first version of this plugin. It is a tool for your convenience. Rol
|
|
111 |
|
112 |
== Changelog ==
|
113 |
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
= 1.4 =
|
115 |
-
* New: Updated plugin's text domain to the plugin's slug of 'wp-rollback' to support WordPress' GlotPress translations
|
116 |
-
* New: Gulp automated POT file generation and text domain checker
|
117 |
-
* 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
|
118 |
|
119 |
= 1.3 =
|
120 |
* Tested compatibility with WordPress 4.4 and verified as working; bumped up compatibility
|
121 |
-
* Fix: Trying to get property of non-object warning
|
122 |
-
* Improvement: Better version sorting now using usort & version_compare
|
123 |
|
124 |
= 1.2.4 =
|
125 |
-
* New: Portuguese translations added
|
126 |
-
* Fix: Limit HTTP requests to Plugin page only
|
127 |
|
128 |
= 1.2.3 =
|
129 |
* Fixed: XSS hardening. Thanks @secupress
|
@@ -132,17 +138,17 @@ This is the first version of this plugin. It is a tool for your convenience. Rol
|
|
132 |
|
133 |
= 1.2.2 =
|
134 |
* New: Russian translations from @Flector - thanks!
|
135 |
-
* Fix: Replaced use of wp_json_encode to support older WordPress versions
|
136 |
|
137 |
= 1.2.1 =
|
138 |
-
* Fix: Rollback link appears on non wp.org plugins https://github.com/WordImpress/WP-Rollback/issues/14
|
139 |
-
* Removed unnecessary WP_ROLLBACK_VERSION constant
|
140 |
|
141 |
= 1.2 =
|
142 |
-
* New: Swedish translation files - Thanks @WPDailyThemes
|
143 |
|
144 |
= 1.1 =
|
145 |
-
* Fixed "Cancel" button which was falsely submitting the form
|
146 |
|
147 |
= 1.0 =
|
148 |
|
3 |
Tags: rollback, revert, downgrade, version, plugins, themes, version, versions, backup, backups, revision, revisions
|
4 |
Requires at least: 4.0
|
5 |
Donate Link: https://wordimpress.com
|
6 |
+
Tested up to: 4.8
|
7 |
+
Stable tag: 1.5
|
8 |
License: GPLv3
|
9 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
10 |
|
85 |
|
86 |
Yes! All strings are internationalized and ready to be translated. Simply use the languages/wp-rollback.pot file and your favorite translation tool. Once finished, please reach out to us on the WordPress.org forums or better yet, submit a pull request on the [Github Repo](https://github.com/WordImpress/WP-Rollback/).
|
87 |
|
88 |
+
= Did this plugin win WordCamp Orange County's Plugin-Palooza? =
|
89 |
|
90 |
Heck yes it did! The WordImpress team took home the gold.
|
91 |
|
111 |
|
112 |
== Changelog ==
|
113 |
|
114 |
+
= 1.5 =
|
115 |
+
* New: You can now view plugin changelogs within the rollback screen. [#7](https://github.com/WordImpress/WP-Rollback/issues/7)
|
116 |
+
* New: Added support for WordPress Multisite rollbacks for themes and plugins. [#22](https://github.com/WordImpress/WP-Rollback/issues/22)
|
117 |
+
* 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/WordImpress/WP-Rollback/issues/23)
|
118 |
+
* New: Updated the WP.org plugin header graphic. [#37](https://github.com/WordImpress/WP-Rollback/issues/37)
|
119 |
+
|
120 |
= 1.4 =
|
121 |
+
* New: Updated plugin's text domain to the plugin's slug of 'wp-rollback' to support WordPress' GlotPress translations. [#28](https://github.com/WordImpress/WP-Rollback/issues/28)
|
122 |
+
* New: Gulp automated POT file generation and text domain checker. [#28](https://github.com/WordImpress/WP-Rollback/issues/28)
|
123 |
+
* 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/WordImpress/WP-Rollback/issues/27)
|
124 |
|
125 |
= 1.3 =
|
126 |
* Tested compatibility with WordPress 4.4 and verified as working; bumped up compatibility
|
127 |
+
* Fix: Trying to get property of non-object warning. [#20](https://github.com/WordImpress/WP-Rollback/issues/20)
|
128 |
+
* Improvement: Better version sorting now using usort & version_compare. [#16](https://github.com/WordImpress/WP-Rollback/issues/16)
|
129 |
|
130 |
= 1.2.4 =
|
131 |
+
* New: Portuguese translations added.
|
132 |
+
* 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)
|
133 |
|
134 |
= 1.2.3 =
|
135 |
* Fixed: XSS hardening. Thanks @secupress
|
138 |
|
139 |
= 1.2.2 =
|
140 |
* New: Russian translations from @Flector - thanks!
|
141 |
+
* 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)
|
142 |
|
143 |
= 1.2.1 =
|
144 |
+
* Fix: Rollback link appears on non wp.org plugins - thanks @scottopolis. [#14](https://github.com/WordImpress/WP-Rollback/issues/14)
|
145 |
+
* Removed unnecessary WP_ROLLBACK_VERSION constant.
|
146 |
|
147 |
= 1.2 =
|
148 |
+
* New: Swedish translation files - Thanks @WPDailyThemes.
|
149 |
|
150 |
= 1.1 =
|
151 |
+
* Fixed "Cancel" button which was falsely submitting the form.
|
152 |
|
153 |
= 1.0 =
|
154 |
|
wp-rollback.php
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
* Plugin Name: WP Rollback
|
4 |
-
* Plugin URI: https://wordimpress.com
|
5 |
* Description: Rollback (or forward) any WordPress.org plugin or theme like a boss.
|
6 |
* Author: WordImpress
|
7 |
-
* Author URI: https://wordimpress.com
|
8 |
-
* Version: 1.
|
9 |
* Text Domain: wp-rollback
|
10 |
* Domain Path: /languages
|
11 |
*
|
@@ -35,13 +35,15 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
35 |
* @since 1.0
|
36 |
*/
|
37 |
if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
|
38 |
/**
|
39 |
* Class WP_Rollback
|
40 |
*/
|
41 |
final class WP_Rollback {
|
42 |
-
/** Singleton *************************************************************/
|
43 |
|
44 |
/**
|
|
|
|
|
45 |
* @var WP_Rollback The one and only
|
46 |
* @since 1.0
|
47 |
*/
|
@@ -64,6 +66,7 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
64 |
|
65 |
/**
|
66 |
* Themes repo url.
|
|
|
67 |
* @var string
|
68 |
*/
|
69 |
public $themes_repo = 'http://themes.svn.wordpress.org';
|
@@ -117,26 +120,12 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
117 |
self::$instance = new WP_Rollback;
|
118 |
self::$instance->setup_constants();
|
119 |
|
120 |
-
//Only setup plugin rollback on specific page
|
121 |
if ( isset( $_GET['plugin_file'] ) && $_GET['page'] == 'wp-rollback' ) {
|
122 |
self::$instance->setup_plugin_vars();
|
123 |
}
|
124 |
|
125 |
-
|
126 |
-
add_action( 'plugins_loaded', array( self::$instance, 'load_textdomain' ) );
|
127 |
-
//Admin
|
128 |
-
add_action( 'admin_enqueue_scripts', array( self::$instance, 'scripts' ) );
|
129 |
-
add_action( 'admin_menu', array( self::$instance, 'admin_menu' ), 20 );
|
130 |
-
add_action( 'pre_current_active_plugins', array(
|
131 |
-
self::$instance,
|
132 |
-
'pre_current_active_plugins'
|
133 |
-
), 20, 1 );
|
134 |
-
add_action( 'wp_ajax_is_wordpress_theme', array( self::$instance, 'is_wordpress_theme' ) );
|
135 |
-
add_action( 'set_site_transient_update_themes', array( self::$instance, 'wpr_theme_updates_list' ) );
|
136 |
-
|
137 |
-
add_filter( 'wp_prepare_themes_for_js', array( self::$instance, 'wpr_prepare_themes_js' ) );
|
138 |
-
add_filter( 'plugin_action_links', array( self::$instance, 'plugin_action_links' ), 20, 4 );
|
139 |
-
|
140 |
self::$instance->includes();
|
141 |
|
142 |
}
|
@@ -210,6 +199,37 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
210 |
$this->set_svn_versions_data( $svn_tags );
|
211 |
}
|
212 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
/**
|
214 |
* Include required files
|
215 |
*
|
@@ -230,13 +250,12 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
230 |
* @param $hook
|
231 |
*
|
232 |
* @return void
|
233 |
-
*
|
234 |
*/
|
235 |
public function scripts( $hook ) {
|
236 |
|
237 |
-
if (
|
238 |
wp_enqueue_script( 'wp_rollback_themes_script', plugin_dir_url( __FILE__ ) . 'assets/js/themes-wp-rollback.js', array( 'jquery' ), false, true );
|
239 |
-
//Localize for i18n
|
240 |
wp_localize_script( 'wp_rollback_themes_script', 'wpr_vars', array(
|
241 |
'ajaxurl' => admin_url(),
|
242 |
'ajax_loader' => admin_url( 'images/spinner.gif' ),
|
@@ -247,20 +266,20 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
247 |
) );
|
248 |
}
|
249 |
|
250 |
-
if ( $hook
|
251 |
return;
|
252 |
}
|
253 |
|
254 |
$suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
|
255 |
|
256 |
-
//CSS
|
257 |
wp_register_style( 'wp_rollback_css', plugin_dir_url( __FILE__ ) . 'assets/css/wp-rollback.css' );
|
258 |
wp_enqueue_style( 'wp_rollback_css' );
|
259 |
|
260 |
wp_register_style( 'wp_rollback_modal_css', plugin_dir_url( __FILE__ ) . 'assets/css/magnific-popup.css' );
|
261 |
wp_enqueue_style( 'wp_rollback_modal_css' );
|
262 |
|
263 |
-
//JS
|
264 |
wp_register_script( 'wp_rollback_modal', plugin_dir_url( __FILE__ ) . 'assets/js/jquery.magnific-popup' . $suffix . '.js', array( 'jquery' ) );
|
265 |
wp_enqueue_script( 'wp_rollback_modal' );
|
266 |
|
@@ -269,13 +288,13 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
269 |
|
270 |
wp_enqueue_script( 'updates' );
|
271 |
|
272 |
-
//Localize for i18n.
|
273 |
wp_localize_script( 'wp_rollback_script', 'wpr_vars', array(
|
274 |
-
'ajaxurl'
|
275 |
-
'
|
|
|
276 |
) );
|
277 |
|
278 |
-
|
279 |
}
|
280 |
|
281 |
/**
|
@@ -316,12 +335,12 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
316 |
*/
|
317 |
public function html() {
|
318 |
|
319 |
-
//Permissions check
|
320 |
if ( ! current_user_can( 'update_plugins' ) ) {
|
321 |
wp_die( __( 'You do not have sufficient permissions to perform rollbacks for this site.', 'wp-rollback' ) );
|
322 |
}
|
323 |
|
324 |
-
//Get the necessary class
|
325 |
include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
|
326 |
|
327 |
$defaults = apply_filters( 'wpr_rollback_html_args', array(
|
@@ -329,24 +348,23 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
329 |
'plugin_file' => '',
|
330 |
'action' => '',
|
331 |
'plugin_version' => '',
|
332 |
-
'plugin' => ''
|
333 |
) );
|
334 |
|
335 |
-
|
336 |
$args = wp_parse_args( $_GET, $defaults );
|
337 |
|
338 |
if ( ! empty( $args['plugin_version'] ) ) {
|
339 |
-
//Plugin: rolling back.
|
340 |
check_admin_referer( 'wpr_rollback_nonce' );
|
341 |
include WP_ROLLBACK_PLUGIN_DIR . '/includes/class-rollback-plugin-upgrader.php';
|
342 |
include WP_ROLLBACK_PLUGIN_DIR . '/includes/rollback-action.php';
|
343 |
} elseif ( ! empty( $args['theme_version'] ) ) {
|
344 |
-
//Theme: rolling back.
|
345 |
check_admin_referer( 'wpr_rollback_nonce' );
|
346 |
include WP_ROLLBACK_PLUGIN_DIR . '/includes/class-rollback-theme-upgrader.php';
|
347 |
include WP_ROLLBACK_PLUGIN_DIR . '/includes/rollback-action.php';
|
348 |
} else {
|
349 |
-
//This is the menu.
|
350 |
check_admin_referer( 'wpr_rollback_nonce' );
|
351 |
include WP_ROLLBACK_PLUGIN_DIR . '/includes/rollback-menu.php';
|
352 |
|
@@ -355,33 +373,66 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
355 |
}
|
356 |
|
357 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
358 |
/**
|
359 |
* Get Subversion Tags
|
360 |
*
|
361 |
-
*
|
362 |
*
|
363 |
* @param $type
|
364 |
* @param $slug
|
365 |
*
|
366 |
* @return null|string
|
367 |
*/
|
368 |
-
|
369 |
|
370 |
$url = $this->plugins_repo . '/' . $this->plugin_slug . '/tags/';
|
371 |
|
372 |
-
//is this a theme svn request?
|
373 |
-
if (
|
374 |
$url = $this->themes_repo . '/' . $slug;
|
375 |
}
|
376 |
|
377 |
$response = wp_remote_get( $url );
|
378 |
|
379 |
-
//Do we have an error?
|
380 |
if ( wp_remote_retrieve_response_code( $response ) !== 200 ) {
|
381 |
return null;
|
382 |
}
|
383 |
|
384 |
-
//Nope: Return that bad boy
|
385 |
return wp_remote_retrieve_body( $response );
|
386 |
|
387 |
}
|
@@ -389,13 +440,11 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
389 |
/**
|
390 |
* Set SVN Version Data
|
391 |
*
|
392 |
-
* @description FILL ME IN
|
393 |
-
*
|
394 |
* @param $html
|
395 |
*
|
396 |
* @return array|bool
|
397 |
*/
|
398 |
-
|
399 |
|
400 |
if ( ! $html ) {
|
401 |
return false;
|
@@ -409,9 +458,9 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
409 |
$items = $DOM->getElementsByTagName( 'a' );
|
410 |
|
411 |
foreach ( $items as $item ) {
|
412 |
-
$href = str_replace( '/', '', $item->getAttribute( 'href' ) ); //Remove trailing slash
|
413 |
|
414 |
-
if ( strpos( $href, 'http' ) === false &&
|
415 |
$versions[] = $href;
|
416 |
}
|
417 |
}
|
@@ -436,34 +485,44 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
436 |
return false;
|
437 |
}
|
438 |
|
439 |
-
$versions_html = '';
|
440 |
|
441 |
usort( $this->versions, 'version_compare' );
|
442 |
|
443 |
$this->versions = array_reverse( $this->versions );
|
444 |
|
445 |
-
|
|
|
446 |
foreach ( $this->versions as $version ) {
|
447 |
|
|
|
448 |
$versions_html .= '<label><input type="radio" value="' . esc_attr( $version ) . '" name="' . $type . '_version">' . $version;
|
449 |
|
450 |
-
//Is this the current version?
|
451 |
if ( $version === $this->current_version ) {
|
452 |
$versions_html .= '<span class="current-version">' . __( 'Installed Version', 'wp-rollback' ) . '</span>';
|
453 |
}
|
454 |
|
455 |
$versions_html .= '</label>';
|
456 |
|
|
|
|
|
|
|
|
|
|
|
|
|
457 |
|
458 |
}
|
459 |
|
460 |
-
|
|
|
|
|
461 |
}
|
462 |
|
463 |
/**
|
464 |
* Set Plugin Slug
|
465 |
*
|
466 |
-
* @return bool
|
467 |
*/
|
468 |
private function set_plugin_slug() {
|
469 |
|
@@ -484,9 +543,7 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
484 |
wp_die( 'Plugin you\'re referencing does not exist.' );
|
485 |
}
|
486 |
|
487 |
-
|
488 |
-
|
489 |
-
//the plugin slug is the base directory name without the path to the main file
|
490 |
$plugin_slug = explode( '/', plugin_basename( $plugin_file ) );
|
491 |
|
492 |
$this->plugin_file = apply_filters( 'wpr_plugin_file', $plugin_file );
|
@@ -503,13 +560,13 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
503 |
*/
|
504 |
public function admin_menu() {
|
505 |
|
506 |
-
//Only show menu item when necessary (user is interacting with plugin, ie rolling back something)
|
507 |
if ( isset( $_GET['page'] ) && $_GET['page'] == 'wp-rollback' ) {
|
508 |
|
509 |
-
//Add it in a native WP way, like WP updates do... (a dashboard page)
|
510 |
add_dashboard_page( __( 'Rollback', 'wp-rollback' ), __( 'Rollback', 'wp-rollback' ), 'update_plugins', 'wp-rollback', array(
|
511 |
self::$instance,
|
512 |
-
'html'
|
513 |
) );
|
514 |
|
515 |
}
|
@@ -548,27 +605,35 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
548 |
*/
|
549 |
public function plugin_action_links( $actions, $plugin_file, $plugin_data, $context ) {
|
550 |
|
551 |
-
//
|
552 |
-
$rollback_url = 'index.php?page=wp-rollback&type=plugin&plugin_file=' . $plugin_file;
|
553 |
-
|
554 |
-
//Filter for other devs
|
555 |
$plugin_data = apply_filters( 'wpr_plugin_data', $plugin_data );
|
556 |
|
557 |
-
//If plugin is missing package data do not output Rollback option
|
558 |
if ( ! isset( $plugin_data['package'] ) || strpos( $plugin_data['package'], 'https://downloads.wordpress.org' ) === false ) {
|
559 |
return $actions;
|
560 |
}
|
561 |
|
562 |
-
//
|
563 |
-
if (
|
564 |
-
$
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
|
|
569 |
}
|
570 |
|
571 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
572 |
$actions['rollback'] = apply_filters( 'wpr_plugin_markup', '<a href="' . esc_url( $rollback_url ) . '">' . __( 'Rollback', 'wp-rollback' ) . '</a>' );
|
573 |
|
574 |
return apply_filters( 'wpr_plugin_action_links', $actions );
|
@@ -576,16 +641,70 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
576 |
}
|
577 |
|
578 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
579 |
/**
|
580 |
* Is WordPress Theme?
|
581 |
*
|
582 |
* Queries the WordPress.org API via theme's slug to see if this theme is on WordPress.
|
583 |
*
|
584 |
* @return bool
|
585 |
-
* @TODO Set transient here to speed up future checks?
|
586 |
*/
|
587 |
public function is_wordpress_theme() {
|
588 |
|
|
|
|
|
|
|
|
|
|
|
589 |
$url = add_query_arg( 'request[slug]', $_POST['theme'], 'https://api.wordpress.org/themes/info/1.1/?action=theme_information' );
|
590 |
$wp_api = wp_remote_get( $url );
|
591 |
|
@@ -602,8 +721,6 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
602 |
// Die is required to terminate immediately and return a proper response.
|
603 |
wp_die();
|
604 |
|
605 |
-
return true;
|
606 |
-
|
607 |
}
|
608 |
|
609 |
|
@@ -631,7 +748,7 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
631 |
|
632 |
include( ABSPATH . WPINC . '/version.php' ); // include an unmodified $wp_version
|
633 |
|
634 |
-
//Bounce out if improperly called.
|
635 |
if ( defined( 'WP_INSTALLING' ) || ! is_admin() ) {
|
636 |
return false;
|
637 |
}
|
@@ -667,12 +784,14 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
667 |
|
668 |
$timeout = 3 + (int) ( count( $themes ) / 10 );
|
669 |
|
|
|
|
|
670 |
$options = array(
|
671 |
'timeout' => $timeout,
|
672 |
'body' => array(
|
673 |
'themes' => json_encode( $request ),
|
674 |
),
|
675 |
-
'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )
|
676 |
);
|
677 |
|
678 |
$url = $http_url = 'http://api.wordpress.org/themes/update-check/1.1/';
|
@@ -698,7 +817,7 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
698 |
|
699 |
$response = json_decode( wp_remote_retrieve_body( $raw_response ), true );
|
700 |
|
701 |
-
if ( is_array( $response ) && isset($response['themes'])) {
|
702 |
$new_update->response = $response['themes'];
|
703 |
}
|
704 |
|
@@ -721,18 +840,18 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
721 |
$rollbacks = array();
|
722 |
$wp_themes = get_site_transient( 'rollback_themes' );
|
723 |
|
724 |
-
//Double check our transient is present.
|
725 |
-
if(empty($wp_themes) || !is_object($wp_themes)) {
|
726 |
$this->wpr_theme_updates_list();
|
727 |
$wp_themes = get_site_transient( 'rollback_themes' );
|
728 |
}
|
729 |
|
730 |
-
//Set $rollback response variable for loop ahead.
|
731 |
if ( is_object( $wp_themes ) ) {
|
732 |
$rollbacks = $wp_themes->response;
|
733 |
}
|
734 |
|
735 |
-
//Loop through themes and provide a 'hasRollback' boolean key for JS.
|
736 |
foreach ( $prepared_themes as $key => $value ) {
|
737 |
$themes[ $key ] = $prepared_themes[ $key ];
|
738 |
$themes[ $key ]['hasRollback'] = isset( $rollbacks[ $key ] );
|
@@ -741,7 +860,6 @@ if ( ! class_exists( 'WP Rollback' ) ) : {
|
|
741 |
return $themes;
|
742 |
}
|
743 |
|
744 |
-
|
745 |
}
|
746 |
}
|
747 |
|
@@ -758,11 +876,11 @@ endif; // End if class_exists check
|
|
758 |
* Example: <?php $wp_rollback = WP_Rollback(); ?>
|
759 |
*
|
760 |
* @since 1.0
|
761 |
-
* @return object
|
762 |
*/
|
763 |
function WP_Rollback() {
|
764 |
return WP_Rollback::instance();
|
765 |
}
|
766 |
|
767 |
// Get WP Rollback Running
|
768 |
-
WP_Rollback();
|
1 |
<?php
|
2 |
/**
|
3 |
* Plugin Name: WP Rollback
|
4 |
+
* Plugin URI: https://wordimpress.com/
|
5 |
* Description: Rollback (or forward) any WordPress.org plugin or theme like a boss.
|
6 |
* Author: WordImpress
|
7 |
+
* Author URI: https://wordimpress.com/
|
8 |
+
* Version: 1.5
|
9 |
* Text Domain: wp-rollback
|
10 |
* Domain Path: /languages
|
11 |
*
|
35 |
* @since 1.0
|
36 |
*/
|
37 |
if ( ! class_exists( 'WP Rollback' ) ) : {
|
38 |
+
|
39 |
/**
|
40 |
* Class WP_Rollback
|
41 |
*/
|
42 |
final class WP_Rollback {
|
|
|
43 |
|
44 |
/**
|
45 |
+
* WP_Rollback instance
|
46 |
+
*
|
47 |
* @var WP_Rollback The one and only
|
48 |
* @since 1.0
|
49 |
*/
|
66 |
|
67 |
/**
|
68 |
* Themes repo url.
|
69 |
+
*
|
70 |
* @var string
|
71 |
*/
|
72 |
public $themes_repo = 'http://themes.svn.wordpress.org';
|
120 |
self::$instance = new WP_Rollback;
|
121 |
self::$instance->setup_constants();
|
122 |
|
123 |
+
// Only setup plugin rollback on specific page
|
124 |
if ( isset( $_GET['plugin_file'] ) && $_GET['page'] == 'wp-rollback' ) {
|
125 |
self::$instance->setup_plugin_vars();
|
126 |
}
|
127 |
|
128 |
+
self::$instance->hooks();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
129 |
self::$instance->includes();
|
130 |
|
131 |
}
|
199 |
$this->set_svn_versions_data( $svn_tags );
|
200 |
}
|
201 |
|
202 |
+
/**
|
203 |
+
* Plugin hooks.
|
204 |
+
*
|
205 |
+
* @access private
|
206 |
+
* @since 1.5
|
207 |
+
* @return void
|
208 |
+
*/
|
209 |
+
private function hooks() {
|
210 |
+
// i18n
|
211 |
+
add_action( 'plugins_loaded', array( self::$instance, 'load_textdomain' ) );
|
212 |
+
// Admin
|
213 |
+
add_action( 'admin_enqueue_scripts', array( self::$instance, 'scripts' ) );
|
214 |
+
add_action( 'admin_menu', array( self::$instance, 'admin_menu' ), 20 );
|
215 |
+
add_action( 'pre_current_active_plugins', array(
|
216 |
+
self::$instance,
|
217 |
+
'pre_current_active_plugins',
|
218 |
+
), 20, 1 );
|
219 |
+
add_action( 'wp_ajax_is_wordpress_theme', array( self::$instance, 'is_wordpress_theme' ) );
|
220 |
+
add_action( 'set_site_transient_update_themes', array( self::$instance, 'wpr_theme_updates_list' ) );
|
221 |
+
|
222 |
+
add_filter( 'wp_prepare_themes_for_js', array( self::$instance, 'wpr_prepare_themes_js' ) );
|
223 |
+
add_filter( 'plugin_action_links', array( self::$instance, 'plugin_action_links' ), 20, 4 );
|
224 |
+
|
225 |
+
add_action( 'network_admin_menu', array( self::$instance, 'admin_menu' ), 20 );
|
226 |
+
add_filter( 'network_admin_plugin_action_links', array( self::$instance, 'plugin_action_links' ), 20, 4 );
|
227 |
+
|
228 |
+
add_filter( 'theme_action_links', array( self::$instance, 'theme_action_links' ), 20, 4 );
|
229 |
+
add_filter( 'wp_ajax_wpr_check_changelog', array( self::$instance, 'get_plugin_changelog' ) );
|
230 |
+
|
231 |
+
}
|
232 |
+
|
233 |
/**
|
234 |
* Include required files
|
235 |
*
|
250 |
* @param $hook
|
251 |
*
|
252 |
* @return void
|
|
|
253 |
*/
|
254 |
public function scripts( $hook ) {
|
255 |
|
256 |
+
if ( 'themes.php' === $hook ) {
|
257 |
wp_enqueue_script( 'wp_rollback_themes_script', plugin_dir_url( __FILE__ ) . 'assets/js/themes-wp-rollback.js', array( 'jquery' ), false, true );
|
258 |
+
// Localize for i18n
|
259 |
wp_localize_script( 'wp_rollback_themes_script', 'wpr_vars', array(
|
260 |
'ajaxurl' => admin_url(),
|
261 |
'ajax_loader' => admin_url( 'images/spinner.gif' ),
|
266 |
) );
|
267 |
}
|
268 |
|
269 |
+
if ( ! in_array( $hook, array( 'index_page_wp-rollback', 'dashboard_page_wp-rollback' ) ) ) {
|
270 |
return;
|
271 |
}
|
272 |
|
273 |
$suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
|
274 |
|
275 |
+
// CSS
|
276 |
wp_register_style( 'wp_rollback_css', plugin_dir_url( __FILE__ ) . 'assets/css/wp-rollback.css' );
|
277 |
wp_enqueue_style( 'wp_rollback_css' );
|
278 |
|
279 |
wp_register_style( 'wp_rollback_modal_css', plugin_dir_url( __FILE__ ) . 'assets/css/magnific-popup.css' );
|
280 |
wp_enqueue_style( 'wp_rollback_modal_css' );
|
281 |
|
282 |
+
// JS
|
283 |
wp_register_script( 'wp_rollback_modal', plugin_dir_url( __FILE__ ) . 'assets/js/jquery.magnific-popup' . $suffix . '.js', array( 'jquery' ) );
|
284 |
wp_enqueue_script( 'wp_rollback_modal' );
|
285 |
|
288 |
|
289 |
wp_enqueue_script( 'updates' );
|
290 |
|
291 |
+
// Localize for i18n.
|
292 |
wp_localize_script( 'wp_rollback_script', 'wpr_vars', array(
|
293 |
+
'ajaxurl' => admin_url(),
|
294 |
+
'text_no_changelog_found' => sprintf( __( 'Sorry, we couldn\'t find a changelog entry found for this version. Try checking the <a href="%s" target="_blank">developer log</a> on WP.org.', 'wp-rollback' ), 'https://wordpress.org/plugins/' . $_GET['plugin_slug'] . '/#developers' ),
|
295 |
+
'version_missing' => __( 'Please select a version number to perform a rollback.', 'wp-rollback' ),
|
296 |
) );
|
297 |
|
|
|
298 |
}
|
299 |
|
300 |
/**
|
335 |
*/
|
336 |
public function html() {
|
337 |
|
338 |
+
// Permissions check
|
339 |
if ( ! current_user_can( 'update_plugins' ) ) {
|
340 |
wp_die( __( 'You do not have sufficient permissions to perform rollbacks for this site.', 'wp-rollback' ) );
|
341 |
}
|
342 |
|
343 |
+
// Get the necessary class
|
344 |
include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
|
345 |
|
346 |
$defaults = apply_filters( 'wpr_rollback_html_args', array(
|
348 |
'plugin_file' => '',
|
349 |
'action' => '',
|
350 |
'plugin_version' => '',
|
351 |
+
'plugin' => '',
|
352 |
) );
|
353 |
|
|
|
354 |
$args = wp_parse_args( $_GET, $defaults );
|
355 |
|
356 |
if ( ! empty( $args['plugin_version'] ) ) {
|
357 |
+
// Plugin: rolling back.
|
358 |
check_admin_referer( 'wpr_rollback_nonce' );
|
359 |
include WP_ROLLBACK_PLUGIN_DIR . '/includes/class-rollback-plugin-upgrader.php';
|
360 |
include WP_ROLLBACK_PLUGIN_DIR . '/includes/rollback-action.php';
|
361 |
} elseif ( ! empty( $args['theme_version'] ) ) {
|
362 |
+
// Theme: rolling back.
|
363 |
check_admin_referer( 'wpr_rollback_nonce' );
|
364 |
include WP_ROLLBACK_PLUGIN_DIR . '/includes/class-rollback-theme-upgrader.php';
|
365 |
include WP_ROLLBACK_PLUGIN_DIR . '/includes/rollback-action.php';
|
366 |
} else {
|
367 |
+
// This is the menu.
|
368 |
check_admin_referer( 'wpr_rollback_nonce' );
|
369 |
include WP_ROLLBACK_PLUGIN_DIR . '/includes/rollback-menu.php';
|
370 |
|
373 |
}
|
374 |
|
375 |
|
376 |
+
/**
|
377 |
+
* Get Plugin Changelog
|
378 |
+
*
|
379 |
+
* Uses WP.org API to get a plugin's
|
380 |
+
*
|
381 |
+
* @return null|string
|
382 |
+
*/
|
383 |
+
public function get_plugin_changelog() {
|
384 |
+
|
385 |
+
// Need slug to continue.
|
386 |
+
if ( ! isset( $_POST['slug'] ) || empty( $_POST['slug'] ) ) {
|
387 |
+
return false;
|
388 |
+
}
|
389 |
+
|
390 |
+
$url = 'https://api.wordpress.org/plugins/info/1.0/' . $_POST['slug'];
|
391 |
+
|
392 |
+
$response = wp_remote_get( $url );
|
393 |
+
|
394 |
+
// Do we have an error?
|
395 |
+
if ( wp_remote_retrieve_response_code( $response ) !== 200 ) {
|
396 |
+
return null;
|
397 |
+
}
|
398 |
+
|
399 |
+
$response = maybe_unserialize( wp_remote_retrieve_body( $response ) );
|
400 |
+
|
401 |
+
// Nope: Return that bad boy
|
402 |
+
echo $response->sections['changelog'];
|
403 |
+
|
404 |
+
wp_die();
|
405 |
+
|
406 |
+
}
|
407 |
+
|
408 |
+
|
409 |
/**
|
410 |
* Get Subversion Tags
|
411 |
*
|
412 |
+
* cURLs wp.org repo to get the proper tags
|
413 |
*
|
414 |
* @param $type
|
415 |
* @param $slug
|
416 |
*
|
417 |
* @return null|string
|
418 |
*/
|
419 |
+
public function get_svn_tags( $type, $slug ) {
|
420 |
|
421 |
$url = $this->plugins_repo . '/' . $this->plugin_slug . '/tags/';
|
422 |
|
423 |
+
// is this a theme svn request?
|
424 |
+
if ( 'theme' === $type ) {
|
425 |
$url = $this->themes_repo . '/' . $slug;
|
426 |
}
|
427 |
|
428 |
$response = wp_remote_get( $url );
|
429 |
|
430 |
+
// Do we have an error?
|
431 |
if ( wp_remote_retrieve_response_code( $response ) !== 200 ) {
|
432 |
return null;
|
433 |
}
|
434 |
|
435 |
+
// Nope: Return that bad boy
|
436 |
return wp_remote_retrieve_body( $response );
|
437 |
|
438 |
}
|
440 |
/**
|
441 |
* Set SVN Version Data
|
442 |
*
|
|
|
|
|
443 |
* @param $html
|
444 |
*
|
445 |
* @return array|bool
|
446 |
*/
|
447 |
+
public function set_svn_versions_data( $html ) {
|
448 |
|
449 |
if ( ! $html ) {
|
450 |
return false;
|
458 |
$items = $DOM->getElementsByTagName( 'a' );
|
459 |
|
460 |
foreach ( $items as $item ) {
|
461 |
+
$href = str_replace( '/', '', $item->getAttribute( 'href' ) ); // Remove trailing slash
|
462 |
|
463 |
+
if ( strpos( $href, 'http' ) === false && '..' !== $href ) {
|
464 |
$versions[] = $href;
|
465 |
}
|
466 |
}
|
485 |
return false;
|
486 |
}
|
487 |
|
488 |
+
$versions_html = '<ul class="wpr-version-list">';
|
489 |
|
490 |
usort( $this->versions, 'version_compare' );
|
491 |
|
492 |
$this->versions = array_reverse( $this->versions );
|
493 |
|
494 |
+
|
495 |
+
// Loop through versions and output in a radio list.
|
496 |
foreach ( $this->versions as $version ) {
|
497 |
|
498 |
+
$versions_html .= '<li class="wpr-version-li">';
|
499 |
$versions_html .= '<label><input type="radio" value="' . esc_attr( $version ) . '" name="' . $type . '_version">' . $version;
|
500 |
|
501 |
+
// Is this the current version?
|
502 |
if ( $version === $this->current_version ) {
|
503 |
$versions_html .= '<span class="current-version">' . __( 'Installed Version', 'wp-rollback' ) . '</span>';
|
504 |
}
|
505 |
|
506 |
$versions_html .= '</label>';
|
507 |
|
508 |
+
// View changelog link.
|
509 |
+
if ( 'plugin' === $type ) {
|
510 |
+
$versions_html .= ' <a href="#" class="wpr-changelog-link" data-version="' . $version . '">' . __( 'View Changelog', 'wp-rollback' ) . '</a>';
|
511 |
+
}
|
512 |
+
|
513 |
+
$versions_html .= '</li>';
|
514 |
|
515 |
}
|
516 |
|
517 |
+
$versions_html .= '</ul>';
|
518 |
+
|
519 |
+
return apply_filters( 'versions_select_html', $versions_html );
|
520 |
}
|
521 |
|
522 |
/**
|
523 |
* Set Plugin Slug
|
524 |
*
|
525 |
+
* @return array|bool
|
526 |
*/
|
527 |
private function set_plugin_slug() {
|
528 |
|
543 |
wp_die( 'Plugin you\'re referencing does not exist.' );
|
544 |
}
|
545 |
|
546 |
+
// the plugin slug is the base directory name without the path to the main file
|
|
|
|
|
547 |
$plugin_slug = explode( '/', plugin_basename( $plugin_file ) );
|
548 |
|
549 |
$this->plugin_file = apply_filters( 'wpr_plugin_file', $plugin_file );
|
560 |
*/
|
561 |
public function admin_menu() {
|
562 |
|
563 |
+
// Only show menu item when necessary (user is interacting with plugin, ie rolling back something)
|
564 |
if ( isset( $_GET['page'] ) && $_GET['page'] == 'wp-rollback' ) {
|
565 |
|
566 |
+
// Add it in a native WP way, like WP updates do... (a dashboard page)
|
567 |
add_dashboard_page( __( 'Rollback', 'wp-rollback' ), __( 'Rollback', 'wp-rollback' ), 'update_plugins', 'wp-rollback', array(
|
568 |
self::$instance,
|
569 |
+
'html',
|
570 |
) );
|
571 |
|
572 |
}
|
605 |
*/
|
606 |
public function plugin_action_links( $actions, $plugin_file, $plugin_data, $context ) {
|
607 |
|
608 |
+
// Filter for other devs.
|
|
|
|
|
|
|
609 |
$plugin_data = apply_filters( 'wpr_plugin_data', $plugin_data );
|
610 |
|
611 |
+
// If plugin is missing package data do not output Rollback option.
|
612 |
if ( ! isset( $plugin_data['package'] ) || strpos( $plugin_data['package'], 'https://downloads.wordpress.org' ) === false ) {
|
613 |
return $actions;
|
614 |
}
|
615 |
|
616 |
+
// Multisite check.
|
617 |
+
if ( is_multisite() && ( ! is_network_admin() && ! is_main_site() ) ) {
|
618 |
+
return $actions;
|
619 |
+
}
|
620 |
+
|
621 |
+
// Must have version.
|
622 |
+
if ( ! isset( $plugin_data['Version'] ) ) {
|
623 |
+
return $actions;
|
624 |
}
|
625 |
|
626 |
+
// Base rollback URL
|
627 |
+
$rollback_url = 'index.php?page=wp-rollback&type=plugin&plugin_file=' . $plugin_file;
|
628 |
+
|
629 |
+
$rollback_url = add_query_arg( apply_filters( 'wpr_plugin_query_args', array(
|
630 |
+
'current_version' => urlencode( $plugin_data['Version'] ),
|
631 |
+
'rollback_name' => urlencode( $plugin_data['Name'] ),
|
632 |
+
'plugin_slug' => urlencode( $plugin_data['slug'] ),
|
633 |
+
'_wpnonce' => wp_create_nonce( 'wpr_rollback_nonce' ),
|
634 |
+
) ), $rollback_url );
|
635 |
+
|
636 |
+
// Final Output
|
637 |
$actions['rollback'] = apply_filters( 'wpr_plugin_markup', '<a href="' . esc_url( $rollback_url ) . '">' . __( 'Rollback', 'wp-rollback' ) . '</a>' );
|
638 |
|
639 |
return apply_filters( 'wpr_plugin_action_links', $actions );
|
641 |
}
|
642 |
|
643 |
|
644 |
+
/**
|
645 |
+
* Theme Action Links
|
646 |
+
*
|
647 |
+
* Adds a "rollback" link into the plugins listing page w/ appropriate query strings
|
648 |
+
*
|
649 |
+
* @param $actions
|
650 |
+
* @param $theme WP_Theme
|
651 |
+
* @param $context
|
652 |
+
*
|
653 |
+
* @return array $actions
|
654 |
+
*/
|
655 |
+
public function theme_action_links( $actions, $theme, $context ) {
|
656 |
+
|
657 |
+
$rollback_themes = get_site_transient( 'rollback_themes' );
|
658 |
+
if ( ! is_object( $rollback_themes ) ) {
|
659 |
+
$this->wpr_theme_updates_list();
|
660 |
+
$rollback_themes = get_site_transient( 'rollback_themes' );
|
661 |
+
}
|
662 |
+
|
663 |
+
$theme_slug = isset( $theme->template ) ? $theme->template : '';
|
664 |
+
|
665 |
+
// Only WP.org themes.
|
666 |
+
if ( empty( $theme_slug ) || ! array_key_exists( $theme_slug, $rollback_themes->response ) ) {
|
667 |
+
return $actions;
|
668 |
+
}
|
669 |
+
|
670 |
+
$theme_file = isset( $rollback_themes->response[ $theme_slug ]['package'] ) ? $rollback_themes->response[ $theme_slug ]['package'] : '';
|
671 |
+
|
672 |
+
// Base rollback URL.
|
673 |
+
$rollback_url = 'index.php?page=wp-rollback&type=theme&theme_file=' . $theme_file;
|
674 |
+
|
675 |
+
// Add in the current version for later reference.
|
676 |
+
if ( ! $theme->get( 'Version' ) ) {
|
677 |
+
return $actions;
|
678 |
+
}
|
679 |
+
|
680 |
+
$rollback_url = add_query_arg( apply_filters( 'wpr_theme_query_args', array(
|
681 |
+
'theme_file' => urlencode( $theme_slug ),
|
682 |
+
'current_version' => urlencode( $theme->get( 'Version' ) ),
|
683 |
+
'rollback_name' => urlencode( $theme->get( 'Name' ) ),
|
684 |
+
'_wpnonce' => wp_create_nonce( 'wpr_rollback_nonce' ),
|
685 |
+
) ), $rollback_url );
|
686 |
+
|
687 |
+
// Final Output
|
688 |
+
$actions['rollback'] = apply_filters( 'wpr_theme_markup', '<a href="' . esc_url( $rollback_url ) . '">' . __( 'Rollback', 'wp-rollback' ) . '</a>' );
|
689 |
+
|
690 |
+
return apply_filters( 'wpr_theme_action_links', $actions );
|
691 |
+
|
692 |
+
}
|
693 |
+
|
694 |
/**
|
695 |
* Is WordPress Theme?
|
696 |
*
|
697 |
* Queries the WordPress.org API via theme's slug to see if this theme is on WordPress.
|
698 |
*
|
699 |
* @return bool
|
|
|
700 |
*/
|
701 |
public function is_wordpress_theme() {
|
702 |
|
703 |
+
// Multisite check.
|
704 |
+
if ( is_multisite() && ( ! is_network_admin() && ! is_main_site() ) ) {
|
705 |
+
return false;
|
706 |
+
}
|
707 |
+
|
708 |
$url = add_query_arg( 'request[slug]', $_POST['theme'], 'https://api.wordpress.org/themes/info/1.1/?action=theme_information' );
|
709 |
$wp_api = wp_remote_get( $url );
|
710 |
|
721 |
// Die is required to terminate immediately and return a proper response.
|
722 |
wp_die();
|
723 |
|
|
|
|
|
724 |
}
|
725 |
|
726 |
|
748 |
|
749 |
include( ABSPATH . WPINC . '/version.php' ); // include an unmodified $wp_version
|
750 |
|
751 |
+
// Bounce out if improperly called.
|
752 |
if ( defined( 'WP_INSTALLING' ) || ! is_admin() ) {
|
753 |
return false;
|
754 |
}
|
784 |
|
785 |
$timeout = 3 + (int) ( count( $themes ) / 10 );
|
786 |
|
787 |
+
global $wp_version;
|
788 |
+
|
789 |
$options = array(
|
790 |
'timeout' => $timeout,
|
791 |
'body' => array(
|
792 |
'themes' => json_encode( $request ),
|
793 |
),
|
794 |
+
'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ),
|
795 |
);
|
796 |
|
797 |
$url = $http_url = 'http://api.wordpress.org/themes/update-check/1.1/';
|
817 |
|
818 |
$response = json_decode( wp_remote_retrieve_body( $raw_response ), true );
|
819 |
|
820 |
+
if ( is_array( $response ) && isset( $response['themes'] ) ) {
|
821 |
$new_update->response = $response['themes'];
|
822 |
}
|
823 |
|
840 |
$rollbacks = array();
|
841 |
$wp_themes = get_site_transient( 'rollback_themes' );
|
842 |
|
843 |
+
// Double check our transient is present.
|
844 |
+
if ( empty( $wp_themes ) || ! is_object( $wp_themes ) ) {
|
845 |
$this->wpr_theme_updates_list();
|
846 |
$wp_themes = get_site_transient( 'rollback_themes' );
|
847 |
}
|
848 |
|
849 |
+
// Set $rollback response variable for loop ahead.
|
850 |
if ( is_object( $wp_themes ) ) {
|
851 |
$rollbacks = $wp_themes->response;
|
852 |
}
|
853 |
|
854 |
+
// Loop through themes and provide a 'hasRollback' boolean key for JS.
|
855 |
foreach ( $prepared_themes as $key => $value ) {
|
856 |
$themes[ $key ] = $prepared_themes[ $key ];
|
857 |
$themes[ $key ]['hasRollback'] = isset( $rollbacks[ $key ] );
|
860 |
return $themes;
|
861 |
}
|
862 |
|
|
|
863 |
}
|
864 |
}
|
865 |
|
876 |
* Example: <?php $wp_rollback = WP_Rollback(); ?>
|
877 |
*
|
878 |
* @since 1.0
|
879 |
+
* @return WP_Rollback object The one true WP Rollback Instance
|
880 |
*/
|
881 |
function WP_Rollback() {
|
882 |
return WP_Rollback::instance();
|
883 |
}
|
884 |
|
885 |
// Get WP Rollback Running
|
886 |
+
WP_Rollback();
|