Version Description
- Fix: There was a issue with the .htaccess rewriting (Class Meow_Admin not found).
- Update: Core was totally re-organized and cleaned. Ready for nice updates.
- Update: LazyLoading from version 2.0 to 3.0.
- Info: There will be an important warning showing up during this update. It is an important annoucement.
Download this release
Release Info
Developer | TigrouMeow |
Plugin | WP Retina 2x |
Version | 5.0.2 |
Comparing to | |
See all releases |
Code changes from version 4.8.0 to 5.0.2
- ajax.php +666 -0
- api.php +22 -0
- common/{meow-admin.css → admin.css} +0 -0
- common/{meow_admin.php → admin.php} +98 -161
- core.php +1225 -0
- dashboard.php +313 -0
- img/burn.png +0 -0
- img/clock.png +0 -0
- img/cross-small.png +0 -0
- img/exclamation.png +0 -0
- img/photo-album--plus.png +0 -0
- img/prohibition-small.png +0 -0
- img/refresh.png +0 -0
- img/replace.png +0 -0
- img/tick-circle.png +0 -0
- img/wpengine.png +0 -0
- inc/Mobile_Detect.php +0 -1231
- js/lazysizes.min.js +2 -2
- img/loading.gif → loading.gif +0 -0
- media-library.php +58 -0
- readme.txt +9 -2
- screenshot-1.png +0 -0
- screenshot-2.png +0 -0
- screenshot-3.png +0 -0
- screenshot.png +0 -0
- wp-retina-2x.php +12 -1132
- wr2x_admin.php +36 -65
- wr2x_ajax.php +0 -664
- wr2x_media-library.php +0 -54
- wr2x_responsive.php +0 -45
- wr2x_retina-dashboard.php +0 -315
- wr2x_retina_uploader.php +0 -104
- wr2x_vt_resize.php +0 -52
ajax.php
ADDED
@@ -0,0 +1,666 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Meow_WR2X_Ajax {
|
4 |
+
|
5 |
+
public $core = null;
|
6 |
+
|
7 |
+
public function __construct( $core) {
|
8 |
+
$this->core = $core;
|
9 |
+
add_action( 'wp_ajax_wr2x_generate', array( $this, 'wp_ajax_wr2x_generate' ) );
|
10 |
+
add_action( 'wp_ajax_wr2x_delete', array( $this, 'wp_ajax_wr2x_delete' ) );
|
11 |
+
add_action( 'wp_ajax_wr2x_delete_full', array( $this, 'wp_ajax_wr2x_delete_full' ) );
|
12 |
+
add_action( 'wp_ajax_wr2x_list_all', array( $this, 'wp_ajax_wr2x_list_all' ) );
|
13 |
+
add_action( 'wp_ajax_wr2x_replace', array( $this, 'wp_ajax_wr2x_replace' ) );
|
14 |
+
add_action( 'wp_ajax_wr2x_upload', array( $this, 'wp_ajax_wr2x_upload' ) );
|
15 |
+
add_action( 'wp_ajax_wr2x_retina_details', array( $this, 'wp_ajax_wr2x_retina_details' ) );
|
16 |
+
add_action( 'admin_head', array( $this, 'admin_head' ) );
|
17 |
+
}
|
18 |
+
|
19 |
+
function admin_head() {
|
20 |
+
?>
|
21 |
+
<script type="text/javascript" >
|
22 |
+
|
23 |
+
/* GENERATE RETINA IMAGES ACTION */
|
24 |
+
|
25 |
+
var current;
|
26 |
+
var maxPhpSize = <?php echo $this->core->get_max_filesize(); ?>;
|
27 |
+
var ids = [];
|
28 |
+
var errors = 0;
|
29 |
+
var ajax_action = "generate"; // generate | delete
|
30 |
+
|
31 |
+
function wr2x_display_please_refresh() {
|
32 |
+
wr2x_refresh_progress_status();
|
33 |
+
jQuery('#wr2x_progression').html(jQuery('#wr2x_progression').html() + " - <?php echo _e( "<a href='?page=wp-retina-2x&view=issues&refresh=true'>Refresh</a> this page.", 'wp-retina-2x' ); ?>");
|
34 |
+
}
|
35 |
+
|
36 |
+
function wr2x_refresh_progress_status() {
|
37 |
+
var errortext = "";
|
38 |
+
if ( errors > 0 ) {
|
39 |
+
errortext = ' - ' + errors + ' error(s)';
|
40 |
+
}
|
41 |
+
jQuery('#wr2x_progression').text(current + "/" + ids.length +
|
42 |
+
" (" + Math.round(current / ids.length * 100) + "%)" + errortext);
|
43 |
+
}
|
44 |
+
|
45 |
+
function wr2x_do_next () {
|
46 |
+
var data = { action: 'wr2x_' + ajax_action, attachmentId: ids[current - 1] };
|
47 |
+
wr2x_refresh_progress_status();
|
48 |
+
jQuery.post(ajaxurl, data, function (response) {
|
49 |
+
try {
|
50 |
+
reply = jQuery.parseJSON(response);
|
51 |
+
}
|
52 |
+
catch (e) {
|
53 |
+
reply = null;
|
54 |
+
}
|
55 |
+
if ( !reply || !reply.success )
|
56 |
+
errors++;
|
57 |
+
else {
|
58 |
+
wr2x_refresh_media_sizes(reply.results);
|
59 |
+
if (reply.results_full)
|
60 |
+
wr2x_refresh_full(reply.results_full);
|
61 |
+
}
|
62 |
+
if (++current <= ids.length)
|
63 |
+
wr2x_do_next();
|
64 |
+
else {
|
65 |
+
current--;
|
66 |
+
wr2x_display_please_refresh();
|
67 |
+
}
|
68 |
+
}).fail(function () {
|
69 |
+
errors++;
|
70 |
+
if (++current <= ids.length)
|
71 |
+
wr2x_do_next();
|
72 |
+
else {
|
73 |
+
current--;
|
74 |
+
wr2x_display_please_refresh();
|
75 |
+
}
|
76 |
+
});
|
77 |
+
}
|
78 |
+
|
79 |
+
function wr2x_do_all () {
|
80 |
+
current = 1;
|
81 |
+
ids = [];
|
82 |
+
errors = 0;
|
83 |
+
var data = { action: 'wr2x_list_all', issuesOnly: 0 };
|
84 |
+
jQuery('#wr2x_progression').text("<?php _e( "Wait...", 'wp-retina-2x' ); ?>");
|
85 |
+
jQuery.post(ajaxurl, data, function (response) {
|
86 |
+
reply = jQuery.parseJSON(response);
|
87 |
+
if (reply.success = false) {
|
88 |
+
alert('Error: ' + reply.message);
|
89 |
+
return;
|
90 |
+
}
|
91 |
+
if (reply.total == 0) {
|
92 |
+
jQuery('#wr2x_progression').html("<?php _e( "Nothing to do ;)", 'wp-retina-2x' ); ?>");
|
93 |
+
return;
|
94 |
+
}
|
95 |
+
ids = reply.ids;
|
96 |
+
jQuery('#wr2x_progression').text(current + "/" + ids.length + " (" + Math.round(current / ids.length * 100) + "%)");
|
97 |
+
wr2x_do_next();
|
98 |
+
});
|
99 |
+
}
|
100 |
+
|
101 |
+
function wr2x_delete_all () {
|
102 |
+
ajax_action = 'delete';
|
103 |
+
wr2x_do_all();
|
104 |
+
}
|
105 |
+
|
106 |
+
function wr2x_generate_all () {
|
107 |
+
ajax_action = 'generate';
|
108 |
+
wr2x_do_all();
|
109 |
+
}
|
110 |
+
|
111 |
+
// Refresh the dashboard retina full with the results from the Ajax operation (Upload)
|
112 |
+
function wr2x_refresh_full (results) {
|
113 |
+
jQuery.each(results, function (id, html) {
|
114 |
+
jQuery('#wr2x-info-full-' + id).html(html);
|
115 |
+
jQuery('#wr2x-info-full-' + id + ' img').attr('src', jQuery('#wr2x-info-full-' + id + ' img').attr('src')+'?'+ Math.random());
|
116 |
+
jQuery('#wr2x-info-full-' + id + ' img').on('click', function (evt) {
|
117 |
+
wr2x_delete_full( jQuery(evt.target).parents('.wr2x-file-row').attr('postid') );
|
118 |
+
});
|
119 |
+
});
|
120 |
+
}
|
121 |
+
|
122 |
+
// Refresh the dashboard media sizes with the results from the Ajax operation (Replace or Generate)
|
123 |
+
function wr2x_refresh_media_sizes (results) {
|
124 |
+
jQuery.each(results, function (id, html) {
|
125 |
+
jQuery('#wr2x-info-' + id).html(html);
|
126 |
+
});
|
127 |
+
}
|
128 |
+
|
129 |
+
function wr2x_generate (attachmentId, retinaDashboard) {
|
130 |
+
var data = { action: 'wr2x_generate', attachmentId: attachmentId };
|
131 |
+
jQuery('#wr2x_generate_button_' + attachmentId).text("<?php echo __( "Wait...", 'wp-retina-2x' ); ?>");
|
132 |
+
jQuery.post(ajaxurl, data, function (response) {
|
133 |
+
var reply = jQuery.parseJSON(response);
|
134 |
+
if (!reply.success) {
|
135 |
+
alert(reply.message);
|
136 |
+
return;
|
137 |
+
}
|
138 |
+
jQuery('#wr2x_generate_button_' + attachmentId).html("<?php echo __( "GENERATE", 'wp-retina-2x' ); ?>");
|
139 |
+
wr2x_refresh_media_sizes(reply.results);
|
140 |
+
});
|
141 |
+
}
|
142 |
+
|
143 |
+
/* REPLACE FUNCTION */
|
144 |
+
|
145 |
+
function wr2x_stop_propagation(evt) {
|
146 |
+
evt.stopPropagation();
|
147 |
+
evt.preventDefault();
|
148 |
+
}
|
149 |
+
|
150 |
+
function wr2x_delete_full(attachmentId) {
|
151 |
+
var data = {
|
152 |
+
action: 'wr2x_delete_full',
|
153 |
+
isAjax: true,
|
154 |
+
attachmentId: attachmentId
|
155 |
+
};
|
156 |
+
|
157 |
+
jQuery.post(ajaxurl, data, function (response) {
|
158 |
+
var data = jQuery.parseJSON(response);
|
159 |
+
if (data.success === false) {
|
160 |
+
alert(data.message);
|
161 |
+
}
|
162 |
+
else {
|
163 |
+
wr2x_refresh_full(data.results);
|
164 |
+
wr2x_display_please_refresh();
|
165 |
+
}
|
166 |
+
});
|
167 |
+
}
|
168 |
+
|
169 |
+
function wr2x_load_details(attachmentId) {
|
170 |
+
var data = {
|
171 |
+
action: 'wr2x_retina_details',
|
172 |
+
isAjax: true,
|
173 |
+
attachmentId: attachmentId
|
174 |
+
};
|
175 |
+
|
176 |
+
jQuery.post(ajaxurl, data, function (response) {
|
177 |
+
var data = jQuery.parseJSON(response);
|
178 |
+
if (data.success === false) {
|
179 |
+
alert(data.message);
|
180 |
+
}
|
181 |
+
else {
|
182 |
+
jQuery('#meow-modal-info .loading').css('display', 'none');
|
183 |
+
jQuery('#meow-modal-info .content').html(data.result);
|
184 |
+
}
|
185 |
+
});
|
186 |
+
}
|
187 |
+
|
188 |
+
function wr2x_filedropped (evt) {
|
189 |
+
wr2x_stop_propagation(evt);
|
190 |
+
var files = evt.dataTransfer.files;
|
191 |
+
var count = files.length;
|
192 |
+
if (count < 0) {
|
193 |
+
return;
|
194 |
+
}
|
195 |
+
|
196 |
+
var wr2x_replace = jQuery(evt.target).parent().hasClass('wr2x-fullsize-replace');
|
197 |
+
var wr2x_upload = jQuery(evt.target).parent().hasClass('wr2x-fullsize-retina-upload');
|
198 |
+
|
199 |
+
function wr2x_handleprogress(prg) {
|
200 |
+
console.debug("Upload of " + prg.srcElement.filename + ": " + prg.loaded / prg.total * 100 + "%");
|
201 |
+
}
|
202 |
+
|
203 |
+
function wr2x_uploadFile(file, attachmentId, filename) {
|
204 |
+
var action = "";
|
205 |
+
if (wr2x_replace) {
|
206 |
+
action = 'wr2x_replace';
|
207 |
+
}
|
208 |
+
else if (wr2x_upload) {
|
209 |
+
action = 'wr2x_upload';
|
210 |
+
}
|
211 |
+
else {
|
212 |
+
alert("Unknown command. Contact the developer.");
|
213 |
+
}
|
214 |
+
var data = new FormData();
|
215 |
+
data.append('file', file);
|
216 |
+
data.append('action', action);
|
217 |
+
data.append('attachmentId', attachmentId);
|
218 |
+
data.append('isAjax', true);
|
219 |
+
data.append('filename', filename);
|
220 |
+
// var data = {
|
221 |
+
// action: action,
|
222 |
+
// isAjax: true,
|
223 |
+
// filename: evt.target.filename,
|
224 |
+
// data: form_data,
|
225 |
+
// attachmentId: attachmentId
|
226 |
+
// };
|
227 |
+
|
228 |
+
jQuery.ajax({
|
229 |
+
type: 'POST',
|
230 |
+
url: ajaxurl,
|
231 |
+
contentType: false,
|
232 |
+
processData: false,
|
233 |
+
data: data,
|
234 |
+
success: function (response) {
|
235 |
+
jQuery('[postid=' + attachmentId + '] td').removeClass('wr2x-loading-file');
|
236 |
+
jQuery('[postid=' + attachmentId + '] .wr2x-dragdrop').removeClass('wr2x-hover-drop');
|
237 |
+
try {
|
238 |
+
var data = jQuery.parseJSON(response);
|
239 |
+
}
|
240 |
+
catch (e) {
|
241 |
+
alert("The server-side returned an abnormal response. Check your PHP error logs and also your browser console (WP Retina 2x will try to display it there).");
|
242 |
+
console.debug(response);
|
243 |
+
return;
|
244 |
+
}
|
245 |
+
if (wr2x_replace) {
|
246 |
+
var imgSelector = '[postid=' + attachmentId + '] .wr2x-info-thumbnail img';
|
247 |
+
jQuery(imgSelector).attr('src', jQuery(imgSelector).attr('src')+'?'+ Math.random());
|
248 |
+
}
|
249 |
+
if (wr2x_upload) {
|
250 |
+
var imgSelector = '[postid=' + attachmentId + '] .wr2x-info-full img';
|
251 |
+
jQuery(imgSelector).attr('src', jQuery(imgSelector).attr('src')+'?'+ Math.random());
|
252 |
+
}
|
253 |
+
if (data.success === false) {
|
254 |
+
alert(data.message);
|
255 |
+
}
|
256 |
+
else {
|
257 |
+
if ( wr2x_replace ) {
|
258 |
+
wr2x_refresh_media_sizes(data.results);
|
259 |
+
}
|
260 |
+
else if ( wr2x_upload ) {
|
261 |
+
wr2x_refresh_full(data.results);
|
262 |
+
}
|
263 |
+
}
|
264 |
+
},
|
265 |
+
error: function(XMLHttpRequest, textStatus, errorThrown) {
|
266 |
+
jQuery('[postid=' + attachmentId + '] td').removeClass('wr2x-loading-file');
|
267 |
+
jQuery('[postid=' + attachmentId + '] .wr2x-dragdrop').removeClass('wr2x-hover-drop');
|
268 |
+
alert("An error occurred on the server-side. Please check your PHP error logs.");
|
269 |
+
}
|
270 |
+
});
|
271 |
+
}
|
272 |
+
var file = files[0];
|
273 |
+
if (file.size > maxPhpSize) {
|
274 |
+
jQuery(this).removeClass('wr2x-hover-drop');
|
275 |
+
alert( "Your PHP configuration only allows file upload of a maximum of " + (maxPhpSize / 1000000) + "MB." );
|
276 |
+
return;
|
277 |
+
}
|
278 |
+
var postId = jQuery(evt.target).parents('.wr2x-file-row').attr('postid');
|
279 |
+
jQuery(evt.target).parents('td').addClass('wr2x-loading-file');
|
280 |
+
wr2x_uploadFile(file, postId, file.name);
|
281 |
+
}
|
282 |
+
|
283 |
+
jQuery(document).ready(function () {
|
284 |
+
jQuery('.wr2x-dragdrop').on('dragenter', function (evt) {
|
285 |
+
wr2x_stop_propagation(evt);
|
286 |
+
jQuery(this).addClass('wr2x-hover-drop');
|
287 |
+
});
|
288 |
+
|
289 |
+
jQuery('.wr2x-dragdrop').on('dragover', function (evt) {
|
290 |
+
wr2x_stop_propagation(evt);
|
291 |
+
jQuery(this).addClass('wr2x-hover-drop');
|
292 |
+
});
|
293 |
+
|
294 |
+
jQuery('.wr2x-dragdrop').on('dragleave', function (evt) {
|
295 |
+
wr2x_stop_propagation(evt);
|
296 |
+
jQuery(this).removeClass('wr2x-hover-drop');
|
297 |
+
});
|
298 |
+
|
299 |
+
jQuery('.wr2x-dragdrop').on('dragexit', wr2x_stop_propagation);
|
300 |
+
|
301 |
+
jQuery('.wr2x-dragdrop').each(function (index, elem) {
|
302 |
+
this.addEventListener('drop', wr2x_filedropped);
|
303 |
+
});
|
304 |
+
|
305 |
+
jQuery('.wr2x-info, .wr2x-button-view').on('click', function (evt) {
|
306 |
+
jQuery('#meow-modal-info-backdrop').css('display', 'block');
|
307 |
+
jQuery('#meow-modal-info .content').html("");
|
308 |
+
jQuery('#meow-modal-info .loading').css('display', 'block');
|
309 |
+
jQuery('#meow-modal-info').css('display', 'block');
|
310 |
+
jQuery('#meow-modal-info').focus();
|
311 |
+
var postid = jQuery(evt.target).parents('.wr2x-info').attr('postid');
|
312 |
+
if (!postid)
|
313 |
+
postid = jQuery(evt.target).parents('.wr2x-file-row').attr('postid');
|
314 |
+
wr2x_load_details(postid);
|
315 |
+
});
|
316 |
+
|
317 |
+
jQuery('#meow-modal-info .close, #meow-modal-info-backdrop').on('click', function (evt) {
|
318 |
+
jQuery('#meow-modal-info').css('display', 'none');
|
319 |
+
jQuery('#meow-modal-info-backdrop').css('display', 'none');
|
320 |
+
});
|
321 |
+
|
322 |
+
jQuery('.wr2x-info-full img').on('click', function (evt) {
|
323 |
+
wr2x_delete_full( jQuery(evt.target).parents('.wr2x-file-row').attr('postid') );
|
324 |
+
});
|
325 |
+
|
326 |
+
jQuery('#meow-modal-info').bind('keydown', function (evt) {
|
327 |
+
if (evt.keyCode === 27) {
|
328 |
+
jQuery('#meow-modal-info').css('display', 'none');
|
329 |
+
jQuery('#meow-modal-info-backdrop').css('display', 'none');
|
330 |
+
}
|
331 |
+
});
|
332 |
+
});
|
333 |
+
|
334 |
+
</script>
|
335 |
+
<?php
|
336 |
+
}
|
337 |
+
|
338 |
+
/**
|
339 |
+
*
|
340 |
+
* AJAX SERVER-SIDE
|
341 |
+
*
|
342 |
+
*/
|
343 |
+
|
344 |
+
// Using issuesOnly, only the IDs with a PENDING status will be processed
|
345 |
+
function wp_ajax_wr2x_list_all( $issuesOnly ) {
|
346 |
+
$issuesOnly = intval( $_POST['issuesOnly'] );
|
347 |
+
if ( $issuesOnly == 1 ) {
|
348 |
+
$ids = $this->core->get_issues();
|
349 |
+
echo json_encode(
|
350 |
+
array(
|
351 |
+
'success' => true,
|
352 |
+
'message' => "List of issues only.",
|
353 |
+
'ids' => $ids,
|
354 |
+
'total' => count( $ids )
|
355 |
+
) );
|
356 |
+
die;
|
357 |
+
}
|
358 |
+
$reply = array();
|
359 |
+
try {
|
360 |
+
$ids = array();
|
361 |
+
$total = 0;
|
362 |
+
global $wpdb;
|
363 |
+
$postids = $wpdb->get_col( "
|
364 |
+
SELECT p.ID
|
365 |
+
FROM $wpdb->posts p
|
366 |
+
WHERE post_status = 'inherit'
|
367 |
+
AND post_type = 'attachment'
|
368 |
+
AND ( post_mime_type = 'image/jpeg' OR
|
369 |
+
post_mime_type = 'image/png' OR
|
370 |
+
post_mime_type = 'image/gif' )
|
371 |
+
" );
|
372 |
+
foreach ($postids as $id) {
|
373 |
+
if ( $this->core->is_ignore( $id ) )
|
374 |
+
continue;
|
375 |
+
array_push( $ids, $id );
|
376 |
+
$total++;
|
377 |
+
}
|
378 |
+
echo json_encode(
|
379 |
+
array(
|
380 |
+
'success' => true,
|
381 |
+
'message' => "List of everything.",
|
382 |
+
'ids' => $ids,
|
383 |
+
'total' => $total
|
384 |
+
) );
|
385 |
+
die;
|
386 |
+
}
|
387 |
+
catch (Exception $e) {
|
388 |
+
echo json_encode(
|
389 |
+
array(
|
390 |
+
'success' => false,
|
391 |
+
'message' => $e->getMessage()
|
392 |
+
) );
|
393 |
+
die;
|
394 |
+
}
|
395 |
+
}
|
396 |
+
|
397 |
+
function wp_ajax_wr2x_delete_full( $pleaseReturn = false ) {
|
398 |
+
|
399 |
+
if ( !isset( $_POST['attachmentId'] ) ) {
|
400 |
+
echo json_encode(
|
401 |
+
array(
|
402 |
+
'success' => false,
|
403 |
+
'message' => __( "The attachment ID is missing.", 'wp-retina-2x' )
|
404 |
+
)
|
405 |
+
);
|
406 |
+
die();
|
407 |
+
}
|
408 |
+
$attachmentId = intval( $_POST['attachmentId'] );
|
409 |
+
$originalfile = get_attached_file( $attachmentId );
|
410 |
+
$pathinfo = pathinfo( $originalfile );
|
411 |
+
$retina_file = trailingslashit( $pathinfo['dirname'] ) . $pathinfo['filename'] . $this->core->retina_extension() . $pathinfo['extension'];
|
412 |
+
if ( $retina_file && file_exists( $retina_file ) )
|
413 |
+
unlink( $retina_file );
|
414 |
+
|
415 |
+
// RESULTS FOR RETINA DASHBOARD
|
416 |
+
$info = $this->core->html_get_basic_retina_info_full( $attachmentId, $this->core->retina_info( $attachmentId ) );
|
417 |
+
$results[$attachmentId] = $info;
|
418 |
+
|
419 |
+
// Return if that's not the final step.
|
420 |
+
if ( $pleaseReturn )
|
421 |
+
return $info;
|
422 |
+
|
423 |
+
echo json_encode(
|
424 |
+
array(
|
425 |
+
'results' => $results,
|
426 |
+
'success' => true,
|
427 |
+
'message' => __( "Full retina file deleted.", 'wp-retina-2x' )
|
428 |
+
)
|
429 |
+
);
|
430 |
+
die();
|
431 |
+
}
|
432 |
+
|
433 |
+
function wp_ajax_wr2x_delete() {
|
434 |
+
|
435 |
+
if ( !isset( $_POST['attachmentId'] ) ) {
|
436 |
+
echo json_encode(
|
437 |
+
array(
|
438 |
+
'success' => false,
|
439 |
+
'message' => __( "The attachment ID is missing.", 'wp-retina-2x' )
|
440 |
+
)
|
441 |
+
);
|
442 |
+
die();
|
443 |
+
}
|
444 |
+
|
445 |
+
// Information for the retina version of the full-size
|
446 |
+
$attachmentId = intval( $_POST['attachmentId'] );
|
447 |
+
$results_full[$attachmentId] = $this->wp_ajax_wr2x_delete_full( true );
|
448 |
+
|
449 |
+
$this->core->delete_attachment( $attachmentId, true );
|
450 |
+
$meta = wp_get_attachment_metadata( $attachmentId );
|
451 |
+
|
452 |
+
// RESULTS FOR RETINA DASHBOARD
|
453 |
+
$this->core->update_issue_status( $attachmentId );
|
454 |
+
$info = $this->core->html_get_basic_retina_info( $attachmentId, $this->core->retina_info( $attachmentId ) );
|
455 |
+
$results[$attachmentId] = $info;
|
456 |
+
echo json_encode(
|
457 |
+
array(
|
458 |
+
'results' => $results,
|
459 |
+
'results_full' => $results_full,
|
460 |
+
'success' => true,
|
461 |
+
'message' => __( "Retina files deleted.", 'wp-retina-2x' )
|
462 |
+
)
|
463 |
+
);
|
464 |
+
die();
|
465 |
+
}
|
466 |
+
|
467 |
+
function wp_ajax_wr2x_retina_details() {
|
468 |
+
if ( !isset( $_POST['attachmentId'] ) ) {
|
469 |
+
echo json_encode(
|
470 |
+
array(
|
471 |
+
'success' => false,
|
472 |
+
'message' => __( "The attachment ID is missing.", 'wp-retina-2x' )
|
473 |
+
)
|
474 |
+
);
|
475 |
+
die();
|
476 |
+
}
|
477 |
+
|
478 |
+
$attachmentId = intval( $_POST['attachmentId'] );
|
479 |
+
$info = $this->core->html_get_details_retina_info( $attachmentId, $this->core->retina_info( $attachmentId ) );
|
480 |
+
echo json_encode(
|
481 |
+
array(
|
482 |
+
'result' => $info,
|
483 |
+
'success' => true,
|
484 |
+
'message' => __( "Details retrieved.", 'wp-retina-2x' )
|
485 |
+
)
|
486 |
+
);
|
487 |
+
die();
|
488 |
+
}
|
489 |
+
|
490 |
+
function wp_ajax_wr2x_generate() {
|
491 |
+
if ( !isset( $_POST['attachmentId'] ) ) {
|
492 |
+
echo json_encode(
|
493 |
+
array(
|
494 |
+
'success' => false,
|
495 |
+
'message' => __( "The attachment ID is missing.", 'wp-retina-2x' )
|
496 |
+
)
|
497 |
+
);
|
498 |
+
die();
|
499 |
+
}
|
500 |
+
|
501 |
+
$attachmentId = intval( $_POST['attachmentId'] );
|
502 |
+
$this->core->delete_attachment( $attachmentId, false );
|
503 |
+
|
504 |
+
// Regenerate the Thumbnails
|
505 |
+
$file = get_attached_file( $attachmentId );
|
506 |
+
$meta = wp_generate_attachment_metadata( $attachmentId, $file );
|
507 |
+
wp_update_attachment_metadata( $attachmentId, $meta );
|
508 |
+
|
509 |
+
// Regenerate Retina
|
510 |
+
//$meta = wp_get_attachment_metadata( $attachmentId );
|
511 |
+
$this->core->generate_images( $meta );
|
512 |
+
|
513 |
+
// RESULTS FOR RETINA DASHBOARD
|
514 |
+
$info = $this->core->html_get_basic_retina_info( $attachmentId, $this->core->retina_info( $attachmentId ) );
|
515 |
+
$results[$attachmentId] = $info;
|
516 |
+
echo json_encode(
|
517 |
+
array(
|
518 |
+
'results' => $results,
|
519 |
+
'success' => true,
|
520 |
+
'message' => __( "Retina files generated.", 'wp-retina-2x' )
|
521 |
+
)
|
522 |
+
);
|
523 |
+
die();
|
524 |
+
}
|
525 |
+
|
526 |
+
function check_get_ajax_uploaded_file() {
|
527 |
+
if ( !current_user_can('upload_files') ) {
|
528 |
+
echo json_encode( array(
|
529 |
+
'success' => false,
|
530 |
+
'message' => __( "You do not have permission to upload files.", 'wp-retina-2x' )
|
531 |
+
));
|
532 |
+
die();
|
533 |
+
}
|
534 |
+
|
535 |
+
$tmpfname = $_FILES['file']['tmp_name'];
|
536 |
+
|
537 |
+
// Check if it is an image
|
538 |
+
$file_info = getimagesize( $tmpfname );
|
539 |
+
if ( empty( $file_info ) ) {
|
540 |
+
$this->core->log( "The file is not an image or the upload went wrong." );
|
541 |
+
unlink( $tmpfname );
|
542 |
+
echo json_encode( array(
|
543 |
+
'success' => false,
|
544 |
+
'message' => __( "The file is not an image or the upload went wrong.", 'wp-retina-2x' )
|
545 |
+
));
|
546 |
+
die();
|
547 |
+
}
|
548 |
+
|
549 |
+
$filedata = wp_check_filetype_and_ext( $tmpfname, $_POST['filename'] );
|
550 |
+
if ( $filedata["ext"] == "" ) {
|
551 |
+
$this->core->log( "You cannot use this file (wrong extension? wrong type?)." );
|
552 |
+
unlink( $current_file );
|
553 |
+
echo json_encode( array(
|
554 |
+
'success' => false,
|
555 |
+
'message' => __( "You cannot use this file (wrong extension? wrong type?).", 'wp-retina-2x' )
|
556 |
+
));
|
557 |
+
die();
|
558 |
+
}
|
559 |
+
|
560 |
+
$this->core->log( "The temporary file was written successfully." );
|
561 |
+
return $tmpfname;
|
562 |
+
}
|
563 |
+
|
564 |
+
function wp_ajax_wr2x_upload() {
|
565 |
+
try {
|
566 |
+
$tmpfname = $this->check_get_ajax_uploaded_file();
|
567 |
+
$attachmentId = (int) $_POST['attachmentId'];
|
568 |
+
$meta = wp_get_attachment_metadata( $attachmentId );
|
569 |
+
$current_file = get_attached_file( $attachmentId );
|
570 |
+
$pathinfo = pathinfo( $current_file );
|
571 |
+
$basepath = $pathinfo['dirname'];
|
572 |
+
$retinafile = trailingslashit( $pathinfo['dirname'] ) . $pathinfo['filename'] . $this->core->retina_extension() . $pathinfo['extension'];
|
573 |
+
|
574 |
+
if ( file_exists( $retinafile ) )
|
575 |
+
unlink( $retinafile );
|
576 |
+
|
577 |
+
// Insert the new file and delete the temporary one
|
578 |
+
list( $width, $height ) = getimagesize( $tmpfname );
|
579 |
+
|
580 |
+
if ( !$this->core->are_dimensions_ok( $width, $height, $meta['width'] * 2, $meta['height'] * 2 ) ) {
|
581 |
+
echo json_encode( array(
|
582 |
+
'success' => false,
|
583 |
+
'message' => "This image has a resolution of ${width}×${height} but your Full Size image requires a retina image of at least " . ( $meta['width'] * 2 ) . "x" . ( $meta['height'] * 2 ) . "."
|
584 |
+
));
|
585 |
+
die();
|
586 |
+
}
|
587 |
+
require('wr2x_vt_resize.php');
|
588 |
+
wr2x_vt_resize( $tmpfname, $meta['width'] * 2, $meta['height'] * 2, null, $retinafile );
|
589 |
+
chmod( $retinafile, 0644 );
|
590 |
+
unlink( $tmpfname );
|
591 |
+
|
592 |
+
// Get the results
|
593 |
+
$info = $this->core->retina_info( $attachmentId );
|
594 |
+
$this->core->update_issue_status( $attachmentId );
|
595 |
+
$results[$attachmentId] = $this->core->html_get_basic_retina_info_full( $attachmentId, $info );
|
596 |
+
}
|
597 |
+
catch (Exception $e) {
|
598 |
+
echo json_encode( array(
|
599 |
+
'success' => false,
|
600 |
+
'results' => null,
|
601 |
+
'message' => __( "Error: " . $e->getMessage(), 'wp-retina-2x' )
|
602 |
+
));
|
603 |
+
die();
|
604 |
+
}
|
605 |
+
echo json_encode( array(
|
606 |
+
'success' => true,
|
607 |
+
'results' => $results,
|
608 |
+
'message' => __( "Uploaded successfully.", 'wp-retina-2x' )
|
609 |
+
));
|
610 |
+
die();
|
611 |
+
}
|
612 |
+
|
613 |
+
function wp_ajax_wr2x_replace() {
|
614 |
+
$tmpfname = $this->check_get_ajax_uploaded_file();
|
615 |
+
$attachmentId = (int) $_POST['attachmentId'];
|
616 |
+
$meta = wp_get_attachment_metadata( $attachmentId );
|
617 |
+
$current_file = get_attached_file( $attachmentId );
|
618 |
+
$this->core->delete_attachment( $attachmentId, false );
|
619 |
+
$pathinfo = pathinfo( $current_file );
|
620 |
+
$basepath = $pathinfo['dirname'];
|
621 |
+
|
622 |
+
// Let's clean everything first
|
623 |
+
if ( wp_attachment_is_image( $attachmentId ) ) {
|
624 |
+
$sizes = $this->core->get_image_sizes();
|
625 |
+
foreach ($sizes as $name => $attr) {
|
626 |
+
if ( isset( $meta['sizes'][$name] ) && isset( $meta['sizes'][$name]['file'] ) && file_exists( trailingslashit( $basepath ) . $meta['sizes'][$name]['file'] ) ) {
|
627 |
+
$normal_file = trailingslashit( $basepath ) . $meta['sizes'][$name]['file'];
|
628 |
+
$pathinfo = pathinfo( $normal_file );
|
629 |
+
$retina_file = trailingslashit( $pathinfo['dirname'] ) . $pathinfo['filename'] . $this->core->retina_extension() . $pathinfo['extension'];
|
630 |
+
|
631 |
+
// Test if the file exists and if it is actually a file (and not a dir)
|
632 |
+
// Some old WordPress Media Library are sometimes broken and link to directories
|
633 |
+
if ( file_exists( $normal_file ) && is_file( $normal_file ) )
|
634 |
+
unlink( $normal_file );
|
635 |
+
if ( file_exists( $retina_file ) && is_file( $retina_file ) )
|
636 |
+
unlink( $retina_file );
|
637 |
+
}
|
638 |
+
}
|
639 |
+
}
|
640 |
+
if ( file_exists( $current_file ) )
|
641 |
+
unlink( $current_file );
|
642 |
+
|
643 |
+
// Insert the new file and delete the temporary one
|
644 |
+
rename( $tmpfname, $current_file );
|
645 |
+
chmod( $current_file, 0644 );
|
646 |
+
|
647 |
+
// Generate the images
|
648 |
+
wp_update_attachment_metadata( $attachmentId, wp_generate_attachment_metadata( $attachmentId, $current_file ) );
|
649 |
+
$meta = wp_get_attachment_metadata( $attachmentId );
|
650 |
+
$this->core->generate_images( $meta );
|
651 |
+
|
652 |
+
// Get the results
|
653 |
+
$info = $this->core->retina_info( $attachmentId );
|
654 |
+
$results[$attachmentId] = $this->core->html_get_basic_retina_info( $attachmentId, $info );
|
655 |
+
|
656 |
+
echo json_encode( array(
|
657 |
+
'success' => true,
|
658 |
+
'results' => $results,
|
659 |
+
'message' => __( "Replaced successfully.", 'wp-retina-2x' )
|
660 |
+
));
|
661 |
+
die();
|
662 |
+
}
|
663 |
+
|
664 |
+
}
|
665 |
+
|
666 |
+
?>
|
api.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
*
|
5 |
+
* FUNCTIONS THAT CAN BE USED BY THEMES/PLUGINS DEVELOPERS
|
6 |
+
* FOR ADDITIONAL RETINA SUPPORT
|
7 |
+
*
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Return Retina URL from the Image URL
|
11 |
+
function wr2x_get_retina_from_url( $url ) {
|
12 |
+
global $wr2x_core;
|
13 |
+
return $wr2x_core->get_retina_from_url( $url );
|
14 |
+
}
|
15 |
+
|
16 |
+
// Return the retina file if my found for this normal file
|
17 |
+
function wr2x_get_retina( $file ) {
|
18 |
+
global $wr2x_core;
|
19 |
+
return $wr2x_core->get_retina( $file );
|
20 |
+
}
|
21 |
+
|
22 |
+
?>
|
common/{meow-admin.css → admin.css}
RENAMED
File without changes
|
common/{meow_admin.php → admin.php}
RENAMED
@@ -1,32 +1,59 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
if ( !class_exists( '
|
4 |
|
5 |
-
class
|
6 |
|
7 |
public static $loaded = false;
|
8 |
-
public static $
|
9 |
-
public $prefix = null;
|
10 |
-
public $item = null;
|
11 |
|
12 |
-
public
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
15 |
if ( is_admin() ) {
|
16 |
add_action( 'admin_menu', array( $this, 'admin_menu_start' ) );
|
17 |
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
18 |
add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
|
19 |
}
|
|
|
20 |
}
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
}
|
28 |
}
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
}
|
31 |
|
32 |
function display_ads() {
|
@@ -35,6 +62,8 @@ if ( !class_exists( 'Meow_Admin' ) ) {
|
|
35 |
|
36 |
function display_title( $title = "Meow Apps",
|
37 |
$author = "By <a style='text-decoration: none;' href='http://meowapps.com' target='_blank'>Jordy Meow</a>" ) {
|
|
|
|
|
38 |
if ( $this->display_ads() ) {
|
39 |
echo '<a class="meow-header-ad" target="_blank" href="http://www.shareasale.com/r.cfm?b=906810&u=767054&m=41388&urllink=&afftrack="">
|
40 |
<img src="' . $this->common_url( 'img/wpengine.png' ) . '" height="60" border="0" /></a>';
|
@@ -50,8 +79,8 @@ if ( !class_exists( 'Meow_Admin' ) ) {
|
|
50 |
}
|
51 |
|
52 |
function admin_enqueue_scripts() {
|
53 |
-
wp_register_style( 'meowapps-
|
54 |
-
wp_enqueue_style( 'meowapps-
|
55 |
}
|
56 |
|
57 |
function admin_menu_start() {
|
@@ -66,8 +95,8 @@ if ( !class_exists( 'Meow_Admin' ) ) {
|
|
66 |
if ( !isset( $submenu[ 'meowapps-main-menu' ] ) ) {
|
67 |
add_menu_page( 'Meow Apps', 'Meow Apps', 'manage_options', 'meowapps-main-menu',
|
68 |
array( $this, 'admin_meow_apps' ), 'dashicons-camera', 82 );
|
69 |
-
add_submenu_page( 'meowapps-main-menu', __( 'Dashboard',
|
70 |
-
__( 'Dashboard',
|
71 |
'meowapps-main-menu', array( $this, 'admin_meow_apps' ) );
|
72 |
}
|
73 |
|
@@ -86,7 +115,7 @@ if ( !class_exists( 'Meow_Admin' ) ) {
|
|
86 |
$value = get_option( 'meowapps_hide_ads', null );
|
87 |
$html = '<input type="checkbox" id="meowapps_hide_ads" name="meowapps_hide_ads" value="1" ' .
|
88 |
checked( 1, get_option( 'meowapps_hide_ads' ), false ) . '/>';
|
89 |
-
$html .= '<label>Hide</label><br /><small>
|
90 |
echo $html;
|
91 |
}
|
92 |
|
@@ -94,138 +123,54 @@ if ( !class_exists( 'Meow_Admin' ) ) {
|
|
94 |
$value = get_option( 'meowapps_hide_meowapps', null );
|
95 |
$html = '<input type="checkbox" id="meowapps_hide_meowapps" name="meowapps_hide_meowapps" value="1" ' .
|
96 |
checked( 1, get_option( 'meowapps_hide_meowapps' ), false ) . '/>';
|
97 |
-
$html .= __( '<label>Hide <b>Meow Apps</b> Menu</label><br /><small>Hide Meow Apps menu and all its components, for a nicer an faster WordPress admin UI. An option will be added in Settings > General to display it again.</small>',
|
98 |
echo $html;
|
99 |
}
|
100 |
|
101 |
-
function admin_menu_for_serialkey() {
|
102 |
-
// SUBMENU > Settings > Pro Serial
|
103 |
-
add_settings_section( $this->prefix . '_settings_serialkey', null, null, $this->prefix . '_settings_serialkey-menu' );
|
104 |
-
add_settings_field( $this->prefix . '_pro_serial', __( "Serial Key", $this->domain ),
|
105 |
-
array( $this, 'admin_serialkey_callback' ),
|
106 |
-
$this->prefix . '_settings_serialkey-menu', $this->prefix . '_settings_serialkey' );
|
107 |
-
register_setting( $this->prefix . '_settings_serialkey', $this->prefix . '_pro_serial' );
|
108 |
-
}
|
109 |
-
|
110 |
-
function admin_serialkey_callback( $args ) {
|
111 |
-
$value = get_option( $this->prefix . '_pro_serial', null );
|
112 |
-
$html = '<input type="text" id="' . $this->prefix . '_pro_serial" name="' . $this->prefix . '_pro_serial" value="' . $value . '" />';
|
113 |
-
echo $html;
|
114 |
-
}
|
115 |
-
|
116 |
function display_serialkey_box( $url = "https://meowapps.com/" ) {
|
117 |
-
$
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
<?php endif; ?>
|
128 |
-
<?php settings_fields( $this->prefix . '_settings_serialkey' ); ?>
|
129 |
-
<?php do_settings_sections( $this->prefix . '_settings_serialkey-menu' ); ?>
|
130 |
-
<?php if ( !$this->is_pro() ): ?>
|
131 |
-
<small class="description">
|
132 |
-
<?php echo sprintf(
|
133 |
-
__( 'Insert your serial key above. If you don\'t have one yet, you can get one <a target="_blank" href="%s">here.</a>',
|
134 |
-
$this->domain ),
|
135 |
-
$url );
|
136 |
-
?>
|
137 |
-
</small>
|
138 |
-
<?php endif; ?>
|
139 |
-
<?php submit_button(); ?>
|
140 |
-
</form>
|
141 |
-
</div>
|
142 |
-
</div>
|
143 |
-
<?php
|
144 |
}
|
145 |
|
146 |
-
function
|
147 |
-
|
148 |
-
$this->validate_pro( $new_value );
|
149 |
-
}
|
150 |
-
}
|
151 |
-
|
152 |
-
function is_pro() {
|
153 |
-
$prefix = $this->prefix;
|
154 |
-
$validated = get_transient( $prefix . '_validated' );
|
155 |
-
$subscr_id = get_option( $prefix . '_pro_serial', "" );
|
156 |
-
if ( $validated )
|
157 |
-
return !empty( $subscr_id );
|
158 |
-
if ( !empty( $subscr_id ) )
|
159 |
-
return $this->validate_pro( $subscr_id );
|
160 |
-
return false;
|
161 |
-
}
|
162 |
-
|
163 |
-
function validate_pro( $subscr_id ) {
|
164 |
-
$prefix = $this->prefix;
|
165 |
-
$item = $this->item;
|
166 |
-
delete_option( $prefix . '_pro_serial', "" );
|
167 |
-
update_option( $prefix . '_pro_status', "" );
|
168 |
-
set_transient( $prefix . '_validated', false, 0 );
|
169 |
-
if ( empty( $subscr_id ) )
|
170 |
-
return false;
|
171 |
-
$bodyreq = array( 'subscr_id' => $subscr_id, 'item' => $item, 'url' => get_site_url() );
|
172 |
-
$response = wp_remote_post( 'https://meowapps.com/wp-json/meow/v1/auth', array(
|
173 |
-
'body' => $bodyreq,
|
174 |
-
'user-agent' => "MeowApps",
|
175 |
-
'sslverify' => false,
|
176 |
-
'timeout' => 45,
|
177 |
-
'method' => 'POST'
|
178 |
-
));
|
179 |
-
$body = is_array( $response ) ? $response['body'] : null;
|
180 |
-
$post = @json_decode( $body );
|
181 |
-
if ( !$post || ( property_exists( $post, 'code' ) ) ) {
|
182 |
-
$status = __( "There was an error while validating the serial.<br />Please contact <a target='_blank' href='https://meowapps.com/contact/'>Meow Apps</a> and mention the following log: <br /><ul>", $this->domain );
|
183 |
-
$status .= "<li>Server IP: <b>" . gethostbyname( $_SERVER['SERVER_NAME'] ) . "</b></li>";
|
184 |
-
$status .= "<li>Google GET: ";
|
185 |
-
$r = wp_remote_get( 'http://google.com' );
|
186 |
-
$status .= is_wp_error( $r ) ? print_r( $r, true ) : 'OK';
|
187 |
-
$status .= "</li><li>MeowApps GET: ";
|
188 |
-
$r = wp_remote_get( 'http://google.com' );
|
189 |
-
$status .= is_wp_error( $r ) ? print_r( $r, true ) : 'OK';
|
190 |
-
$status .= "</li><li>MeowApps POST: ";
|
191 |
-
$status .= print_r( $response, true );
|
192 |
-
$status .= "</li></ul>";
|
193 |
-
error_log( print_r( $response, true ) );
|
194 |
-
update_option( $prefix . '_pro_status', $status );
|
195 |
-
return false;
|
196 |
-
}
|
197 |
-
if ( !$post->success ) {
|
198 |
-
if ( $post->message_code == "NO_SUBSCRIPTION" )
|
199 |
-
$status = __( "Your serial ('$subscr_id') does not seem right." );
|
200 |
-
else if ( $post->message_code == "NOT_ACTIVE" )
|
201 |
-
$status = __( "Your subscription is not active." );
|
202 |
-
else if ( $post->message_code == "TOO_MANY_URLS" )
|
203 |
-
$status = __( "Too many URLs are linked to your subscription." );
|
204 |
-
else
|
205 |
-
$status = "There is a problem with your subscription.";
|
206 |
-
update_option( $prefix . '_pro_status', $status );
|
207 |
-
return false;
|
208 |
-
}
|
209 |
-
set_transient( $prefix . '_validated', $subscr_id, 3600 * 24 * 100 );
|
210 |
-
update_option( $prefix . '_pro_serial', $subscr_id );
|
211 |
-
update_option( $prefix . '_pro_status', '' );
|
212 |
-
return true;
|
213 |
}
|
214 |
|
215 |
function check_install( $plugin ) {
|
216 |
-
$
|
|
|
217 |
if ( !file_exists( $pluginpath ) ) {
|
218 |
-
$
|
219 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
220 |
}
|
|
|
221 |
$plugin_file = $plugin . '/' . $plugin . '.php';
|
222 |
-
if ( is_plugin_active( $plugin_file ) )
|
223 |
-
|
|
|
|
|
|
|
|
|
224 |
else {
|
225 |
$url = wp_nonce_url( self_admin_url( 'plugins.php?action=activate&plugin=' . $plugin_file ),
|
226 |
'activate-plugin_' . $plugin_file );
|
227 |
-
return '<small><span style="color:
|
228 |
-
(<a style="color: rgba(30,140,190
|
229 |
$url . '">enable</a>)</span></small>';
|
230 |
}
|
231 |
}
|
@@ -284,7 +229,7 @@ if ( !class_exists( 'Meow_Admin' ) ) {
|
|
284 |
?>
|
285 |
<?php $this->display_title(); ?>
|
286 |
<p>
|
287 |
-
<?php _e( 'Meow Apps is run by
|
288 |
?>
|
289 |
</p>
|
290 |
<div class="meow-row">
|
@@ -292,34 +237,26 @@ if ( !class_exists( 'Meow_Admin' ) ) {
|
|
292 |
<h3 class=""><span class="dashicons dashicons-camera"></span> UI Plugins </h3>
|
293 |
<ul class="">
|
294 |
<li><b>WP/LR Sync</b> <?php echo $this->check_install( 'wplr-sync' ) ?><br />
|
295 |
-
|
296 |
-
</li>
|
297 |
<li><b>Meow Lightbox</b> <?php echo $this->check_install( 'meow-lightbox' ) ?><br />
|
298 |
-
|
299 |
-
</li>
|
300 |
<li><b>Meow Gallery</b> <?php echo $this->check_install( 'meow-gallery' ) ?><br />
|
301 |
-
|
302 |
-
</li>
|
303 |
<li><b>Audio Story for Images</b> <?php echo $this->check_install( 'audio-story-images' ) ?><br />
|
304 |
-
|
305 |
-
</li>
|
306 |
</ul>
|
307 |
</div>
|
308 |
<div class="meow-box meow-col meow-span_1_of_2">
|
309 |
<h3 class=""><span class="dashicons dashicons-admin-tools"></span> System Plugins</h3>
|
310 |
<ul class="">
|
311 |
<li><b>Media File Renamer</b> <?php echo $this->check_install( 'media-file-renamer' ) ?><br />
|
312 |
-
|
313 |
-
</li>
|
314 |
<li><b>Media Cleaner</b> <?php echo $this->check_install( 'media-cleaner' ) ?><br />
|
315 |
-
|
316 |
-
</li>
|
317 |
<li><b>WP Retina 2x</b> <?php echo $this->check_install( 'wp-retina-2x' ) ?><br />
|
318 |
-
|
319 |
-
</li>
|
320 |
<li><b>WP Category Permalink</b> <?php echo $this->check_install( 'wp-category-permalink' ) ?><br />
|
321 |
-
|
322 |
-
</li>
|
323 |
</ul>
|
324 |
</div>
|
325 |
</div>
|
@@ -340,12 +277,8 @@ if ( !class_exists( 'Meow_Admin' ) ) {
|
|
340 |
<h3><span class="dashicons dashicons-admin-tools"></span> Debug</h3>
|
341 |
<div class="inside">
|
342 |
<ul>
|
343 |
-
<li><a href="?page=meowapps-main-menu&tool=error_log">
|
344 |
-
|
345 |
-
</a></li>
|
346 |
-
<li><a href="?page=meowapps-main-menu&tool=phpinfo">
|
347 |
-
<?php _e( 'Display PHP Info', $this->domain ); ?>
|
348 |
-
</a></li>
|
349 |
</ul>
|
350 |
</div>
|
351 |
</div>
|
@@ -355,7 +288,7 @@ if ( !class_exists( 'Meow_Admin' ) ) {
|
|
355 |
|
356 |
}
|
357 |
|
358 |
-
echo "<br /><small style='color: lightgray;'>Meow Admin " .
|
359 |
}
|
360 |
|
361 |
// HELPERS
|
@@ -372,4 +305,8 @@ if ( !class_exists( 'Meow_Admin' ) ) {
|
|
372 |
|
373 |
}
|
374 |
|
|
|
|
|
|
|
|
|
375 |
?>
|
1 |
<?php
|
2 |
|
3 |
+
if ( !class_exists( 'MeowApps_Admin' ) ) {
|
4 |
|
5 |
+
class MeowApps_Admin {
|
6 |
|
7 |
public static $loaded = false;
|
8 |
+
public static $admin_version = "1.2";
|
|
|
|
|
9 |
|
10 |
+
public $prefix; // prefix used for actions, filters (mfrh)
|
11 |
+
public $mainfile; // plugin main file (media-file-renamer.php)
|
12 |
+
public $domain; // domain used for translation (media-file-renamer)
|
13 |
+
|
14 |
+
public function __construct( $prefix, $mainfile, $domain ) {
|
15 |
+
|
16 |
+
// Core Admin (used by all Meow Apps plugins)
|
17 |
+
if ( !MeowApps_Admin::$loaded ) {
|
18 |
if ( is_admin() ) {
|
19 |
add_action( 'admin_menu', array( $this, 'admin_menu_start' ) );
|
20 |
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
21 |
add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
|
22 |
}
|
23 |
+
MeowApps_Admin::$loaded = true;
|
24 |
}
|
25 |
+
|
26 |
+
// Variables for this plugin
|
27 |
+
$this->prefix = $prefix;
|
28 |
+
$this->mainfile = $mainfile;
|
29 |
+
$this->domain = $domain;
|
30 |
+
|
31 |
+
// Check if the free version is installed but there is license
|
32 |
+
// TODO: In the future, this should be removed ideally
|
33 |
+
if ( is_admin() ) {
|
34 |
+
$license = get_option( $this->prefix . '_license', "" );
|
35 |
+
if ( ( !empty( $license ) ) && !file_exists( plugin_dir_path( __FILE__ ) . '/meowapps/admin.php' ) ) {
|
36 |
+
add_action( 'admin_notices', array( $this, 'admin_notices_licensed_free' ) );
|
37 |
}
|
38 |
}
|
39 |
+
}
|
40 |
+
|
41 |
+
function admin_notices_licensed_free() {
|
42 |
+
if ( isset( $_POST[$this->prefix . '_reset_sub'] ) ) {
|
43 |
+
delete_option( $this->prefix . '_pro_serial' );
|
44 |
+
delete_option( $this->prefix . '_license' );
|
45 |
+
return;
|
46 |
+
}
|
47 |
+
echo '<div class="error">';
|
48 |
+
echo '<p>It looks like you are using the free version of the plugin (<b>' . $this->mainfile . '</b>) but a license for the Pro version was also found. The Pro version might have been replaced by the Free version during an update (might be caused by a temporarily issue). If it is the case, <b>please download it again</b> from the <a target="_blank" href="https://store.meowapps.com">Meow Store</a>. If you wish to continue using the free version and clear this message, click on this button.';
|
49 |
+
echo '<p>
|
50 |
+
<form method="post" action="">
|
51 |
+
<input type="hidden" name="' . $this->prefix . '_reset_sub" value="true">
|
52 |
+
<input type="submit" name="submit" id="submit" class="button" value="Remove the license">
|
53 |
+
</form>
|
54 |
+
</p>
|
55 |
+
';
|
56 |
+
echo '</div>';
|
57 |
}
|
58 |
|
59 |
function display_ads() {
|
62 |
|
63 |
function display_title( $title = "Meow Apps",
|
64 |
$author = "By <a style='text-decoration: none;' href='http://meowapps.com' target='_blank'>Jordy Meow</a>" ) {
|
65 |
+
if ( !empty( $this->prefix ) )
|
66 |
+
$title = apply_filters( $this->prefix . '_plugin_title', $title );
|
67 |
if ( $this->display_ads() ) {
|
68 |
echo '<a class="meow-header-ad" target="_blank" href="http://www.shareasale.com/r.cfm?b=906810&u=767054&m=41388&urllink=&afftrack="">
|
69 |
<img src="' . $this->common_url( 'img/wpengine.png' ) . '" height="60" border="0" /></a>';
|
79 |
}
|
80 |
|
81 |
function admin_enqueue_scripts() {
|
82 |
+
wp_register_style( 'meowapps-core-css', $this->common_url( 'admin.css' ) );
|
83 |
+
wp_enqueue_style( 'meowapps-core-css' );
|
84 |
}
|
85 |
|
86 |
function admin_menu_start() {
|
95 |
if ( !isset( $submenu[ 'meowapps-main-menu' ] ) ) {
|
96 |
add_menu_page( 'Meow Apps', 'Meow Apps', 'manage_options', 'meowapps-main-menu',
|
97 |
array( $this, 'admin_meow_apps' ), 'dashicons-camera', 82 );
|
98 |
+
add_submenu_page( 'meowapps-main-menu', __( 'Dashboard', 'meowapps' ),
|
99 |
+
__( 'Dashboard', 'meowapps' ), 'manage_options',
|
100 |
'meowapps-main-menu', array( $this, 'admin_meow_apps' ) );
|
101 |
}
|
102 |
|
115 |
$value = get_option( 'meowapps_hide_ads', null );
|
116 |
$html = '<input type="checkbox" id="meowapps_hide_ads" name="meowapps_hide_ads" value="1" ' .
|
117 |
checked( 1, get_option( 'meowapps_hide_ads' ), false ) . '/>';
|
118 |
+
$html .= __( '<label>Hide</label><br /><small>Doesn\'t display the ads.</small>', 'wp-retina-2x' );
|
119 |
echo $html;
|
120 |
}
|
121 |
|
123 |
$value = get_option( 'meowapps_hide_meowapps', null );
|
124 |
$html = '<input type="checkbox" id="meowapps_hide_meowapps" name="meowapps_hide_meowapps" value="1" ' .
|
125 |
checked( 1, get_option( 'meowapps_hide_meowapps' ), false ) . '/>';
|
126 |
+
$html .= __( '<label>Hide <b>Meow Apps</b> Menu</label><br /><small>Hide Meow Apps menu and all its components, for a nicer an faster WordPress admin UI. An option will be added in Settings > General to display it again.</small>', 'wp-retina-2x' );
|
127 |
echo $html;
|
128 |
}
|
129 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
function display_serialkey_box( $url = "https://meowapps.com/" ) {
|
131 |
+
$html = '<div class="meow-box">';
|
132 |
+
$html .= '<h3 class="' . ( $this->is_registered( $this->prefix ) ? 'meow-bk-blue' : 'meow-bk-red' ) . '">Pro Version ' .
|
133 |
+
( $this->is_registered( $this->prefix ) ? '(enabled)' : '(disabled)' ) . '</h3>';
|
134 |
+
$html .= '<div class="inside">';
|
135 |
+
echo $html;
|
136 |
+
$html = apply_filters( $this->prefix . '_meowapps_license_input', ( 'More information about the Pro version here:
|
137 |
+
<a target="_blank" href="' . $url . '">' . $url . '</a>.' ), $url );
|
138 |
+
$html .= '</div>';
|
139 |
+
$html .= '</div>';
|
140 |
+
echo $html;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
141 |
}
|
142 |
|
143 |
+
function is_registered() {
|
144 |
+
return apply_filters( $this->prefix . '_meowapps_is_registered', false, $this->prefix );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
}
|
146 |
|
147 |
function check_install( $plugin ) {
|
148 |
+
$pro = false;
|
149 |
+
$pluginpath = get_home_path() . 'wp-content/plugins/' . $plugin . '-pro';
|
150 |
if ( !file_exists( $pluginpath ) ) {
|
151 |
+
$pluginpath = get_home_path() . 'wp-content/plugins/' . $plugin;
|
152 |
+
if ( !file_exists( $pluginpath ) ) {
|
153 |
+
$url = wp_nonce_url( "update.php?action=install-plugin&plugin=$plugin", "install-plugin_$plugin" );
|
154 |
+
return "<a href='$url'><small><span class='' style='float: right;'>install</span></small></a>";
|
155 |
+
}
|
156 |
+
}
|
157 |
+
else {
|
158 |
+
$pro = true;
|
159 |
+
$plugin = $plugin . "-pro";
|
160 |
}
|
161 |
+
|
162 |
$plugin_file = $plugin . '/' . $plugin . '.php';
|
163 |
+
if ( is_plugin_active( $plugin_file ) ) {
|
164 |
+
if ( $pro )
|
165 |
+
return "<small><span style='float: right;'><span class='dashicons dashicons-heart' style='color: rgba(255, 63, 0, 1); font-size: 30px !important; margin-right: 10px;'></span></span></small>";
|
166 |
+
else
|
167 |
+
return "<small><span style='float: right;'><span class='dashicons dashicons-yes' style='color: #00b4ff; font-size: 30px !important; margin-right: 10px;'></span></span></small>";
|
168 |
+
}
|
169 |
else {
|
170 |
$url = wp_nonce_url( self_admin_url( 'plugins.php?action=activate&plugin=' . $plugin_file ),
|
171 |
'activate-plugin_' . $plugin_file );
|
172 |
+
return '<small><span style="color: black; float: right;">off
|
173 |
+
(<a style="color: rgba(30,140,190,1); text-decoration: none;" href="' .
|
174 |
$url . '">enable</a>)</span></small>';
|
175 |
}
|
176 |
}
|
229 |
?>
|
230 |
<?php $this->display_title(); ?>
|
231 |
<p>
|
232 |
+
<?php _e( 'Meow Apps is run by Jordy Meow, a photographer and software developer living in Japan (and taking <a target="_blank" href="http://offbeatjapan.org">a lot of photos</a>). Meow Apps is a suite of plugins focusing on photography, imaging, optimization and it teams up with the best players in the community (other themes and plugins developers). For more information, please check <a href="http://meowapps.com" target="_blank">Meow Apps</a>.', 'meowapps' )
|
233 |
?>
|
234 |
</p>
|
235 |
<div class="meow-row">
|
237 |
<h3 class=""><span class="dashicons dashicons-camera"></span> UI Plugins </h3>
|
238 |
<ul class="">
|
239 |
<li><b>WP/LR Sync</b> <?php echo $this->check_install( 'wplr-sync' ) ?><br />
|
240 |
+
Bring synchronization from Lightroom to WordPress.</li>
|
|
|
241 |
<li><b>Meow Lightbox</b> <?php echo $this->check_install( 'meow-lightbox' ) ?><br />
|
242 |
+
Lightbox with EXIF information nicely displayed.</li>
|
|
|
243 |
<li><b>Meow Gallery</b> <?php echo $this->check_install( 'meow-gallery' ) ?><br />
|
244 |
+
Simple gallery to make your photos look better (Masonry and others).</li>
|
|
|
245 |
<li><b>Audio Story for Images</b> <?php echo $this->check_install( 'audio-story-images' ) ?><br />
|
246 |
+
Add audio to your images.</li>
|
|
|
247 |
</ul>
|
248 |
</div>
|
249 |
<div class="meow-box meow-col meow-span_1_of_2">
|
250 |
<h3 class=""><span class="dashicons dashicons-admin-tools"></span> System Plugins</h3>
|
251 |
<ul class="">
|
252 |
<li><b>Media File Renamer</b> <?php echo $this->check_install( 'media-file-renamer' ) ?><br />
|
253 |
+
Nicer filenames and better SEO, automatically.</li>
|
|
|
254 |
<li><b>Media Cleaner</b> <?php echo $this->check_install( 'media-cleaner' ) ?><br />
|
255 |
+
Detect the files which are not in use.</li>
|
|
|
256 |
<li><b>WP Retina 2x</b> <?php echo $this->check_install( 'wp-retina-2x' ) ?><br />
|
257 |
+
The famous plugin that adds Retina support.</li>
|
|
|
258 |
<li><b>WP Category Permalink</b> <?php echo $this->check_install( 'wp-category-permalink' ) ?><br />
|
259 |
+
Allows you to select a main category (or taxonomy) for nicer permalinks.</li>
|
|
|
260 |
</ul>
|
261 |
</div>
|
262 |
</div>
|
277 |
<h3><span class="dashicons dashicons-admin-tools"></span> Debug</h3>
|
278 |
<div class="inside">
|
279 |
<ul>
|
280 |
+
<li><a href="?page=meowapps-main-menu&tool=error_log">Display Error Log</a></li>
|
281 |
+
<li><a href="?page=meowapps-main-menu&tool=phpinfo">Display PHP Info</a></li>
|
|
|
|
|
|
|
|
|
282 |
</ul>
|
283 |
</div>
|
284 |
</div>
|
288 |
|
289 |
}
|
290 |
|
291 |
+
echo "<br /><small style='color: lightgray;'>Meow Admin " . MeowApps_Admin::$admin_version . "</small></div>";
|
292 |
}
|
293 |
|
294 |
// HELPERS
|
305 |
|
306 |
}
|
307 |
|
308 |
+
if ( file_exists( plugin_dir_path( __FILE__ ) . '/meowapps/admin.php' ) ) {
|
309 |
+
require( 'meowapps/admin.php' );
|
310 |
+
}
|
311 |
+
|
312 |
?>
|
core.php
ADDED
@@ -0,0 +1,1225 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Meow_WR2X_Core {
|
4 |
+
|
5 |
+
public $admin = null;
|
6 |
+
|
7 |
+
public function __construct( $admin ) {
|
8 |
+
$this->admin = $admin;
|
9 |
+
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
10 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ) );
|
11 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ) );
|
12 |
+
add_filter( 'wp_generate_attachment_metadata', array( $this, 'wp_generate_attachment_metadata' ) );
|
13 |
+
add_action( 'delete_attachment', array( $this, 'delete_attachment' ) );
|
14 |
+
add_filter( 'generate_rewrite_rules', array( 'Meow_WR2X_Admin', 'generate_rewrite_rules' ) );
|
15 |
+
add_filter( 'retina_validate_src', array( $this, 'validate_src' ) );
|
16 |
+
add_filter( 'wp_calculate_image_srcset', array( $this, 'calculate_image_srcset' ), 1000, 3 );
|
17 |
+
add_action( 'init', array( $this, 'init' ) );
|
18 |
+
require( 'api.php' );
|
19 |
+
|
20 |
+
if ( is_admin() ) {
|
21 |
+
require( 'ajax.php' );
|
22 |
+
new Meow_WR2X_Ajax( $this );
|
23 |
+
if ( !get_option( "wr2x_hide_retina_dashboard" ) ) {
|
24 |
+
require( 'dashboard.php' );
|
25 |
+
new Meow_WR2X_Dashboard( $this );
|
26 |
+
}
|
27 |
+
if ( !get_option( "wr2x_hide_retina_column" ) )
|
28 |
+
require( 'media-library.php' );
|
29 |
+
new Meow_WR2X_MediaLibrary( $this );
|
30 |
+
//if ( !get_option( "wr2x_hide_retina_column" ) )
|
31 |
+
//require( 'wr2x_retina_uploader.php' );
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
function init() {
|
36 |
+
//load_plugin_textdomain( 'wp-retina-2x', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
|
37 |
+
|
38 |
+
if ( get_option( 'wr2x_disable_medium_large' ) ) {
|
39 |
+
remove_image_size( 'medium_large' );
|
40 |
+
add_filter( 'image_size_names_choose', array( $this, 'unset_medium_large' ) );
|
41 |
+
add_filter( 'intermediate_image_sizes_advanced', array( $this, 'unset_medium_large' ) );
|
42 |
+
}
|
43 |
+
|
44 |
+
if ( is_admin() ) {
|
45 |
+
wp_register_style( 'wr2x-admin-css', plugins_url( '/wr2x_admin.css', __FILE__ ) );
|
46 |
+
wp_enqueue_style( 'wr2x-admin-css' );
|
47 |
+
if ( !get_option( "wr2x_retina_admin" ) )
|
48 |
+
return;
|
49 |
+
}
|
50 |
+
|
51 |
+
$method = get_option( "wr2x_method" );
|
52 |
+
if ( $method == "Picturefill" ) {
|
53 |
+
add_action( 'wp_head', array( $this, 'picture_buffer_start' ) );
|
54 |
+
add_action( 'wp_footer', array( $this, 'picture_buffer_end' ) );
|
55 |
+
}
|
56 |
+
else if ( $method == 'HTML Rewrite' ) {
|
57 |
+
$is_retina = false;
|
58 |
+
if ( isset( $_COOKIE['devicePixelRatio'] ) ) {
|
59 |
+
$is_retina = ceil( floatval( $_COOKIE['devicePixelRatio'] ) ) > 1;
|
60 |
+
}
|
61 |
+
if ( $is_retina || $this->is_debug() ) {
|
62 |
+
add_action( 'wp_head', array( $this, 'buffer_start' ) );
|
63 |
+
add_action( 'wp_footer', array( $this, 'buffer_end' ) );
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
}
|
68 |
+
|
69 |
+
function unset_medium_large( $sizes ) {
|
70 |
+
unset( $sizes['medium_large'] );
|
71 |
+
return $sizes;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
*
|
76 |
+
* PICTURE METHOD
|
77 |
+
*
|
78 |
+
*/
|
79 |
+
|
80 |
+
function is_supported_image( $url ) {
|
81 |
+
$wr2x_supported_image = array( 'jpg', 'jpeg', 'png', 'gif' );
|
82 |
+
$ext = strtolower( pathinfo( $url, PATHINFO_EXTENSION ) );
|
83 |
+
if ( !in_array( $ext, $wr2x_supported_image ) ) {
|
84 |
+
$this->log( "Extension (" . $ext . ") is not " . implode( ', ', $wr2x_supported_image ) . "." );
|
85 |
+
return false;
|
86 |
+
}
|
87 |
+
return true;
|
88 |
+
}
|
89 |
+
|
90 |
+
function picture_buffer_start () {
|
91 |
+
ob_start( array( $this, "picture_rewrite" ) );
|
92 |
+
$this->log( "* HTML REWRITE FOR PICTUREFILL" );
|
93 |
+
}
|
94 |
+
|
95 |
+
function picture_buffer_end () {
|
96 |
+
ob_end_flush();
|
97 |
+
}
|
98 |
+
|
99 |
+
// Replace the IMG tags by PICTURE tags with SRCSET
|
100 |
+
function picture_rewrite( $buffer ) {
|
101 |
+
if ( !isset( $buffer ) || trim( $buffer ) === '' )
|
102 |
+
return $buffer;
|
103 |
+
if ( !function_exists( "str_get_html" ) )
|
104 |
+
require( 'inc/simple_html_dom.php' );
|
105 |
+
|
106 |
+
$lazysize = get_option( "wr2x_picturefill_lazysizes" ) && $this->admin->is_registered();
|
107 |
+
$killsrc = !get_option( "wr2x_picturefill_keep_src" );
|
108 |
+
$nodes_count = 0;
|
109 |
+
$nodes_replaced = 0;
|
110 |
+
$html = str_get_html( $buffer );
|
111 |
+
if ( !$html ) {
|
112 |
+
$this->log( "The HTML buffer is null, another plugin might block the process." );
|
113 |
+
return $buffer;
|
114 |
+
}
|
115 |
+
|
116 |
+
// IMG TAGS
|
117 |
+
foreach( $html->find( 'img' ) as $element ) {
|
118 |
+
$nodes_count++;
|
119 |
+
$parent = $element->parent();
|
120 |
+
if ( $parent->tag == "picture" ) {
|
121 |
+
$this->log("The img tag is inside a picture tag. Tag ignored.");
|
122 |
+
continue;
|
123 |
+
}
|
124 |
+
else {
|
125 |
+
$valid = apply_filters( "wr2x_validate_src", $element->src );
|
126 |
+
if ( empty( $valid ) ) {
|
127 |
+
$nodes_count--;
|
128 |
+
continue;
|
129 |
+
}
|
130 |
+
|
131 |
+
// Original HTML
|
132 |
+
$from = substr( $element, 0 );
|
133 |
+
|
134 |
+
// SRC-SET already exists, let's check if LazySize is used
|
135 |
+
if ( !empty( $element->srcset ) ) {
|
136 |
+
if ( $lazysize ) {
|
137 |
+
$this->log( "The src-set has already been created but it will be modifid to data-srcset for lazyload." );
|
138 |
+
$element->class = $element->class . ' lazyload';
|
139 |
+
$element->{'data-srcset'} = $element->srcset;
|
140 |
+
$element->srcset = null;
|
141 |
+
if ( $killsrc )
|
142 |
+
$element->src = null;
|
143 |
+
$to = $element;
|
144 |
+
$buffer = str_replace( trim( $from, "</> "), trim( $to, "</> " ), $buffer );
|
145 |
+
$this->log( "The img tag '$from' was rewritten to '$to'" );
|
146 |
+
$nodes_replaced++;
|
147 |
+
}
|
148 |
+
else {
|
149 |
+
$this->log( "The src-set has already been created. Tag ignored." );
|
150 |
+
}
|
151 |
+
continue;
|
152 |
+
}
|
153 |
+
|
154 |
+
// Process of SRC-SET creation
|
155 |
+
if ( !$this->is_supported_image( $element->src ) ) {
|
156 |
+
$nodes_count--;
|
157 |
+
continue;
|
158 |
+
}
|
159 |
+
$retina_url = $this->get_retina_from_url( $element->src );
|
160 |
+
$retina_url = apply_filters( 'wr2x_img_retina_url', $retina_url );
|
161 |
+
if ( $retina_url != null ) {
|
162 |
+
$retina_url = $this->cdn_this( $retina_url );
|
163 |
+
$img_url = $this->cdn_this( $element->src );
|
164 |
+
$img_url = apply_filters( 'wr2x_img_url', $img_url );
|
165 |
+
if ( $lazysize ) {
|
166 |
+
$element->class = $element->class . ' lazyload';
|
167 |
+
$element->{'data-srcset'} = "$img_url, $retina_url 2x";
|
168 |
+
}
|
169 |
+
else
|
170 |
+
$element->srcset = "$img_url, $retina_url 2x";
|
171 |
+
if ( $killsrc )
|
172 |
+
$element->src = null;
|
173 |
+
else {
|
174 |
+
$img_src = apply_filters( 'wr2x_img_src', $element->src );
|
175 |
+
$element->src = $this->cdn_this( $img_src );
|
176 |
+
}
|
177 |
+
$to = $element;
|
178 |
+
$buffer = str_replace( trim( $from, "</> "), trim( $to, "</> " ), $buffer );
|
179 |
+
$this->log( "The img tag '$from' was rewritten to '$to'" );
|
180 |
+
$nodes_replaced++;
|
181 |
+
}
|
182 |
+
else {
|
183 |
+
$this->log( "The img tag was not rewritten. No retina for '" . $element->src . "'." );
|
184 |
+
}
|
185 |
+
}
|
186 |
+
}
|
187 |
+
$this->log( "$nodes_replaced/$nodes_count img tags were replaced." );
|
188 |
+
|
189 |
+
// INLINE CSS BACKGROUND
|
190 |
+
if ( get_option( 'wr2x_picturefill_css_background', false ) && $this->admin->is_registered() ) {
|
191 |
+
preg_match_all( "/url(?:\(['\"]?)(.*?)(?:['\"]?\))/", $buffer, $matches );
|
192 |
+
$match_css = $matches[0];
|
193 |
+
$match_url = $matches[1];
|
194 |
+
if ( count( $matches ) != 2 )
|
195 |
+
return $buffer;
|
196 |
+
$nodes_count = 0;
|
197 |
+
$nodes_replaced = 0;
|
198 |
+
for ( $c = 0; $c < count( $matches[0] ); $c++ ) {
|
199 |
+
$css = $match_css[$c];
|
200 |
+
$url = $match_url[$c];
|
201 |
+
if ( !$this->is_supported_image( $url ) )
|
202 |
+
continue;
|
203 |
+
$nodes_count++;
|
204 |
+
$retina_url = $this->get_retina_from_url( $url );
|
205 |
+
$retina_url = apply_filters( 'wr2x_img_retina_url', $retina_url );
|
206 |
+
if ( $retina_url != null ) {
|
207 |
+
$retina_url = $this->cdn_this( $retina_url );
|
208 |
+
$minibuffer = str_replace( $url, $retina_url, $css );
|
209 |
+
$buffer = str_replace( $css, $minibuffer, $buffer );
|
210 |
+
$this->log( "The background src '$css' was rewritten to '$minibuffer'" );
|
211 |
+
$nodes_replaced++;
|
212 |
+
}
|
213 |
+
else {
|
214 |
+
$this->log( "The background src was not rewritten. No retina for '" . $url . "'." );
|
215 |
+
}
|
216 |
+
}
|
217 |
+
$this->log( "$nodes_replaced/$nodes_count background src were replaced." );
|
218 |
+
}
|
219 |
+
|
220 |
+
return $buffer;
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
*
|
225 |
+
* HTML REWRITE METHOD
|
226 |
+
*
|
227 |
+
*/
|
228 |
+
|
229 |
+
function buffer_start () {
|
230 |
+
ob_start( array( $this, "html_rewrite" ) );
|
231 |
+
$this->log( "* HTML REWRITE" );
|
232 |
+
}
|
233 |
+
|
234 |
+
function buffer_end () {
|
235 |
+
ob_end_flush();
|
236 |
+
}
|
237 |
+
|
238 |
+
// Replace the images by retina images (if available)
|
239 |
+
function html_rewrite( $buffer ) {
|
240 |
+
if ( !isset( $buffer ) || trim( $buffer ) === '' )
|
241 |
+
return $buffer;
|
242 |
+
$nodes_count = 0;
|
243 |
+
$nodes_replaced = 0;
|
244 |
+
$doc = new DOMDocument();
|
245 |
+
@$doc->loadHTML( $buffer ); // = ($doc->strictErrorChecking = false;)
|
246 |
+
$imageTags = $doc->getElementsByTagName('img');
|
247 |
+
foreach ( $imageTags as $tag ) {
|
248 |
+
$nodes_count++;
|
249 |
+
$img_pathinfo = $this->get_pathinfo_from_image_src( $tag->getAttribute('src') );
|
250 |
+
$filepath = trailingslashit( $this->get_upload_root() ) . $img_pathinfo;
|
251 |
+
$system_retina = $this->get_retina( $filepath );
|
252 |
+
if ( $system_retina != null ) {
|
253 |
+
$retina_pathinfo = $this->cdn_this( ltrim( str_replace( $this->get_upload_root(), "", $system_retina ), '/' ) );
|
254 |
+
$buffer = str_replace( $img_pathinfo, $retina_pathinfo, $buffer );
|
255 |
+
$this->log( "The img src '$img_pathinfo' was replaced by '$retina_pathinfo'" );
|
256 |
+
$nodes_replaced++;
|
257 |
+
}
|
258 |
+
else {
|
259 |
+
$this->log( "The file '$system_retina' was not found. Tag not modified." );
|
260 |
+
}
|
261 |
+
}
|
262 |
+
$this->log( "$nodes_replaced/$nodes_count were replaced." );
|
263 |
+
return $buffer;
|
264 |
+
}
|
265 |
+
|
266 |
+
|
267 |
+
// Converts PHP INI size type (e.g. 24M) to int
|
268 |
+
function parse_ini_size( $size ) {
|
269 |
+
$unit = preg_replace('/[^bkmgtpezy]/i', '', $size);
|
270 |
+
$size = preg_replace('/[^0-9\.]/', '', $size);
|
271 |
+
if ( $unit )
|
272 |
+
return round( $size * pow( 1024, stripos( 'bkmgtpezy', $unit[0] ) ) );
|
273 |
+
else
|
274 |
+
round( $size );
|
275 |
+
}
|
276 |
+
|
277 |
+
function get_max_filesize() {
|
278 |
+
if ( defined ('HHVM_VERSION' ) ) {
|
279 |
+
return ini_get( 'upload_max_filesize' ) ? (int)$this->parse_ini_size( ini_get( 'upload_max_filesize' ) ) :
|
280 |
+
(int)ini_get( 'hhvm.server.upload.upload_max_file_size' );
|
281 |
+
}
|
282 |
+
else {
|
283 |
+
return (int)$this->parse_ini_size( ini_get( 'upload_max_filesize' ) );
|
284 |
+
}
|
285 |
+
}
|
286 |
+
|
287 |
+
/**
|
288 |
+
*
|
289 |
+
* RESPONSIVE IMAGES METHOD
|
290 |
+
*
|
291 |
+
*/
|
292 |
+
|
293 |
+
function calculate_image_srcset( $srcset, $size ) {
|
294 |
+
if ( get_option( "wr2x_disable_responsive" ) )
|
295 |
+
return null;
|
296 |
+
$method = get_option( "wr2x_method" );
|
297 |
+
if ( $method == "none" )
|
298 |
+
return $srcset;
|
299 |
+
$count = 0;
|
300 |
+
$total = 0;
|
301 |
+
$retinized_srcset = $srcset;
|
302 |
+
if ( empty( $srcset ) )
|
303 |
+
return $srcset;
|
304 |
+
foreach ( $srcset as $s => $cfg ) {
|
305 |
+
$total++;
|
306 |
+
$retina = $this->cdn_this( $this->get_retina_from_url( $cfg['url'] ) );
|
307 |
+
if ( !empty( $retina ) ) {
|
308 |
+
$count++;
|
309 |
+
$retinized_srcset[(int)$s * 2] = array(
|
310 |
+
'url' => $retina,
|
311 |
+
'descriptor' => 'w',
|
312 |
+
'value' => (int)$s * 2 );
|
313 |
+
}
|
314 |
+
}
|
315 |
+
$this->log( "WP's srcset: " . $count . " retina files added out of " . $total . " image sizes" );
|
316 |
+
return $retinized_srcset;
|
317 |
+
}
|
318 |
+
|
319 |
+
/**
|
320 |
+
*
|
321 |
+
* ISSUES CALCULATION AND FUNCTIONS
|
322 |
+
*
|
323 |
+
*/
|
324 |
+
|
325 |
+
// Compares two images dimensions (resolutions) against each while accepting an margin error
|
326 |
+
function are_dimensions_ok( $width, $height, $retina_width, $retina_height ) {
|
327 |
+
$w_margin = $width - $retina_width;
|
328 |
+
$h_margin = $height - $retina_height;
|
329 |
+
return ( $w_margin >= -2 && $h_margin >= -2 );
|
330 |
+
}
|
331 |
+
|
332 |
+
// UPDATE THE ISSUE STATUS OF THIS ATTACHMENT
|
333 |
+
function update_issue_status( $attachmentId, $issues = null, $info = null ) {
|
334 |
+
if ( $this->is_ignore( $attachmentId ) )
|
335 |
+
return;
|
336 |
+
if ( $issues == null )
|
337 |
+
$issues = $this->get_issues();
|
338 |
+
if ( $info == null )
|
339 |
+
$info = $this->retina_info( $attachmentId );
|
340 |
+
$consideredIssue = in_array( $attachmentId, $issues );
|
341 |
+
$realIssue = $this->info_has_issues( $info );
|
342 |
+
if ( $consideredIssue && !$realIssue )
|
343 |
+
$this->remove_issue( $attachmentId );
|
344 |
+
else if ( !$consideredIssue && $realIssue )
|
345 |
+
$this->add_issue( $attachmentId );
|
346 |
+
return $realIssue;
|
347 |
+
}
|
348 |
+
|
349 |
+
function get_issues() {
|
350 |
+
$issues = get_transient( 'wr2x_issues' );
|
351 |
+
if ( !$issues || !is_array( $issues ) ) {
|
352 |
+
$issues = array();
|
353 |
+
set_transient( 'wr2x_issues', $issues );
|
354 |
+
}
|
355 |
+
return $issues;
|
356 |
+
}
|
357 |
+
|
358 |
+
// CHECK IF THE 'INFO' OBJECT CONTAINS ISSUE (RETURN TRUE OR FALSE)
|
359 |
+
function info_has_issues( $info ) {
|
360 |
+
foreach ( $info as $aindex => $aval ) {
|
361 |
+
if ( is_array( $aval ) || $aval == 'PENDING' )
|
362 |
+
return true;
|
363 |
+
}
|
364 |
+
return false;
|
365 |
+
}
|
366 |
+
|
367 |
+
function calculate_issues() {
|
368 |
+
global $wpdb;
|
369 |
+
$postids = $wpdb->get_col( "
|
370 |
+
SELECT p.ID FROM $wpdb->posts p
|
371 |
+
WHERE post_status = 'inherit'
|
372 |
+
AND post_type = 'attachment'" . $this->create_sql_if_wpml_original() . "
|
373 |
+
AND ( post_mime_type = 'image/jpeg' OR
|
374 |
+
post_mime_type = 'image/jpg' OR
|
375 |
+
post_mime_type = 'image/png' OR
|
376 |
+
post_mime_type = 'image/gif' )
|
377 |
+
" );
|
378 |
+
$issues = array();
|
379 |
+
foreach ( $postids as $id ) {
|
380 |
+
$info = $this->retina_info( $id );
|
381 |
+
if ( $this->info_has_issues( $info ) )
|
382 |
+
array_push( $issues, $id );
|
383 |
+
|
384 |
+
}
|
385 |
+
set_transient( 'wr2x_ignores', array() );
|
386 |
+
set_transient( 'wr2x_issues', $issues );
|
387 |
+
}
|
388 |
+
|
389 |
+
function add_issue( $attachmentId ) {
|
390 |
+
if ( $this->is_ignore( $attachmentId ) )
|
391 |
+
return;
|
392 |
+
$issues = $this->get_issues();
|
393 |
+
if ( !in_array( $attachmentId, $issues ) ) {
|
394 |
+
array_push( $issues, $attachmentId );
|
395 |
+
set_transient( 'wr2x_issues', $issues );
|
396 |
+
}
|
397 |
+
return $issues;
|
398 |
+
}
|
399 |
+
|
400 |
+
function remove_issue( $attachmentId, $onlyIgnore = false ) {
|
401 |
+
$issues = array_diff( $this->get_issues(), array( $attachmentId ) );
|
402 |
+
set_transient( 'wr2x_issues', $issues );
|
403 |
+
if ( !$onlyIgnore )
|
404 |
+
$this->remove_ignore( $attachmentId );
|
405 |
+
return $issues;
|
406 |
+
}
|
407 |
+
|
408 |
+
// IGNORE
|
409 |
+
|
410 |
+
function get_ignores( $force = false ) {
|
411 |
+
$ignores = get_transient( 'wr2x_ignores' );
|
412 |
+
if ( !$ignores || !is_array( $ignores ) ) {
|
413 |
+
$ignores = array();
|
414 |
+
set_transient( 'wr2x_ignores', $ignores );
|
415 |
+
}
|
416 |
+
return $ignores;
|
417 |
+
}
|
418 |
+
|
419 |
+
function is_ignore( $attachmentId ) {
|
420 |
+
$ignores = $this->get_ignores();
|
421 |
+
return in_array( $attachmentId, $this->get_ignores() );
|
422 |
+
}
|
423 |
+
|
424 |
+
function remove_ignore( $attachmentId ) {
|
425 |
+
$ignores = $this->get_ignores();
|
426 |
+
$ignores = array_diff( $ignores, array( $attachmentId ) );
|
427 |
+
set_transient( 'wr2x_ignores', $ignores );
|
428 |
+
return $ignores;
|
429 |
+
}
|
430 |
+
|
431 |
+
function add_ignore( $attachmentId ) {
|
432 |
+
$ignores = $this->get_ignores();
|
433 |
+
if ( !in_array( $attachmentId, $ignores ) ) {
|
434 |
+
array_push( $ignores, $attachmentId );
|
435 |
+
set_transient( 'wr2x_ignores', $ignores );
|
436 |
+
}
|
437 |
+
$this->remove_issue( $attachmentId, true );
|
438 |
+
return $ignores;
|
439 |
+
}
|
440 |
+
|
441 |
+
/**
|
442 |
+
*
|
443 |
+
* INFORMATION ABOUT THE RETINA IMAGE IN HTML
|
444 |
+
*
|
445 |
+
*/
|
446 |
+
|
447 |
+
function html_get_basic_retina_info_full( $attachmentId, $retina_info ) {
|
448 |
+
$status = ( isset( $retina_info ) && isset( $retina_info['full-size'] ) ) ? $retina_info['full-size'] : 'IGNORED';
|
449 |
+
if ( $status == 'EXISTS' ) {
|
450 |
+
return '<ul class="meow-sized-images"><li class="meow-bk-blue" title="full-size"></li></ul>';
|
451 |
+
}
|
452 |
+
else if ( is_array( $status ) ) {
|
453 |
+
return '<ul class="meow-sized-images"><li class="meow-bk-orange" title="full-size"></li></ul>';
|
454 |
+
}
|
455 |
+
else if ( $status == 'IGNORED' ) {
|
456 |
+
return __( "N/A", "wp-retina-2x" );
|
457 |
+
}
|
458 |
+
return $status;
|
459 |
+
}
|
460 |
+
|
461 |
+
function format_title( $i, $size ) {
|
462 |
+
return $i . ' (' . ( $size['width'] * 2 ) . 'x' . ( $size['height'] * 2 ) . ')';
|
463 |
+
}
|
464 |
+
|
465 |
+
// Information for the 'Media Sizes Retina-ized' Column in the Retina Dashboard
|
466 |
+
function html_get_basic_retina_info( $attachmentId, $retina_info ) {
|
467 |
+
$sizes = $this->get_active_image_sizes();
|
468 |
+
$result = '<ul class="meow-sized-images" postid="' . ( is_integer( $attachmentId ) ? $attachmentId : $attachmentId->ID ) . '">';
|
469 |
+
foreach ( $sizes as $i => $size ) {
|
470 |
+
$status = ( isset( $retina_info ) && isset( $retina_info[$i] ) ) ? $retina_info[$i] : null;
|
471 |
+
if ( is_array( $status ) )
|
472 |
+
$result .= '<li class="meow-bk-red" title="' . $this->format_title( $i, $size ) . '">'
|
473 |
+
. Meow_Admin::size_shortname( $i ) . '</li>';
|
474 |
+
else if ( $status == 'EXISTS' )
|
475 |
+
$result .= '<li class="meow-bk-blue" title="' . $this->format_title( $i, $size ) . '">'
|
476 |
+
. Meow_Admin::size_shortname( $i ) . '</li>';
|
477 |
+
else if ( $status == 'PENDING' )
|
478 |
+
$result .= '<li class="meow-bk-orange" title="' . $this->format_title( $i, $size ) . '">'
|
479 |
+
. Meow_Admin::size_shortname( $i ) . '</li>';
|
480 |
+
else if ( $status == 'MISSING' )
|
481 |
+
$result .= '<li class="meow-bk-red" title="' . $this->format_title( $i, $size ) . '">'
|
482 |
+
. Meow_Admin::size_shortname( $i ) . '</li>';
|
483 |
+
else if ( $status == 'IGNORED' )
|
484 |
+
$result .= '<li class="meow-bk-gray" title="' . $this->format_title( $i, $size ) . '">'
|
485 |
+
. Meow_Admin::size_shortname( $i ) . '</li>';
|
486 |
+
else {
|
487 |
+
error_log( "Retina: This status is not recognized: " . $status );
|
488 |
+
}
|
489 |
+
}
|
490 |
+
$result .= '</ul>';
|
491 |
+
return $result;
|
492 |
+
}
|
493 |
+
|
494 |
+
// Information for Details in the Retina Dashboard
|
495 |
+
function html_get_details_retina_info( $post, $retina_info ) {
|
496 |
+
if ( !$this->admin->is_registered() ) {
|
497 |
+
return __( "PRO VERSION ONLY", 'wp-retina-2x' );
|
498 |
+
}
|
499 |
+
|
500 |
+
$sizes = $this->get_image_sizes();
|
501 |
+
$total = 0; $possible = 0; $issue = 0; $ignored = 0; $retina = 0;
|
502 |
+
|
503 |
+
$postinfo = get_post( $post, OBJECT );
|
504 |
+
$meta = wp_get_attachment_metadata( $post );
|
505 |
+
$fullsize_file = get_attached_file( $post );
|
506 |
+
$pathinfo_system = pathinfo( $fullsize_file );
|
507 |
+
$pathinfo = pathinfo( $meta['file'] );
|
508 |
+
$uploads = wp_upload_dir();
|
509 |
+
$basepath_url = trailingslashit( $uploads['baseurl'] ) . $pathinfo['dirname'];
|
510 |
+
if ( get_option( "wr2x_full_size" ) ) {
|
511 |
+
$sizes['full-size']['file'] = $pathinfo['basename'];
|
512 |
+
$sizes['full-size']['width'] = $meta['width'];
|
513 |
+
$sizes['full-size']['height'] = $meta['height'];
|
514 |
+
$meta['sizes']['full-size']['file'] = $pathinfo['basename'];
|
515 |
+
$meta['sizes']['full-size']['width'] = $meta['width'];
|
516 |
+
$meta['sizes']['full-size']['height'] = $meta['height'];
|
517 |
+
}
|
518 |
+
$result = "<p>This screen displays all the image sizes set-up by your WordPress configuration with the Retina details.</p>";
|
519 |
+
$result .= "<br /><a target='_blank' href='" . trailingslashit( $uploads['baseurl'] ) . $meta['file'] . "'><img src='" . trailingslashit( $uploads['baseurl'] ) . $meta['file'] . "' height='100px' style='float: left; margin-right: 10px;' /></a><div class='base-info'>";
|
520 |
+
$result .= "Title: <b>" . ( $postinfo->post_title ? $postinfo->post_title : '<i>Untitled</i>' ) . "</b><br />";
|
521 |
+
$result .= "Full-size: <b>" . $meta['width'] . "×" . $meta['height'] . "</b><br />";
|
522 |
+
$result .= "Image URL: <a target='_blank' href='" . trailingslashit( $uploads['baseurl'] ) . $meta['file'] . "'>" . trailingslashit( $uploads['baseurl'] ) . $meta['file'] . "</a><br />";
|
523 |
+
$result .= "Image Path: " . $fullsize_file . "<br />";
|
524 |
+
$result .= "</div><div style='clear: both;'></div><br />";
|
525 |
+
$result .= "<div class='scrollable-info'>";
|
526 |
+
|
527 |
+
foreach ( $sizes as $i => $sizemeta ) {
|
528 |
+
$total++;
|
529 |
+
$normal_file_system = ""; $retina_file_system = "";
|
530 |
+
$normal_file = ""; $retina_file = ""; $width = ""; $height = "";
|
531 |
+
|
532 |
+
if ( isset( $retina_info[$i] ) && $retina_info[$i] == 'IGNORED' ) {
|
533 |
+
$status = "IGNORED";
|
534 |
+
}
|
535 |
+
else if ( !isset( $meta['sizes'] ) ) {
|
536 |
+
$statusText = __( "The metadata is broken! This is not related to the retina plugin. You should probably use a plugin to re-generate the missing metadata and images.", 'wp-retina-2x' );
|
537 |
+
$status = "MISSING";
|
538 |
+
}
|
539 |
+
else if ( !isset( $meta['sizes'][$i] ) ) {
|
540 |
+
$statusText = sprintf( __( "The image size '%s' could not be found. You probably changed your image sizes but this specific image was not re-build. This is not related to the retina plugin. You should probably use a plugin to re-generate the missing metadata and images.", 'wp-retina-2x' ), $i );
|
541 |
+
$status = "MISSING";
|
542 |
+
}
|
543 |
+
else {
|
544 |
+
$normal_file_system = trailingslashit( $pathinfo_system['dirname'] ) . $meta['sizes'][$i]['file'];
|
545 |
+
$retina_file_system = $this->get_retina( $normal_file_system );
|
546 |
+
$normal_file = trailingslashit( $basepath_url ) . $meta['sizes'][$i]['file'];
|
547 |
+
$retina_file = $this->get_retina_from_url( $normal_file );
|
548 |
+
$status = ( isset( $retina_info ) && isset( $retina_info[$i] ) ) ? $retina_info[$i] : null;
|
549 |
+
$width = $meta['sizes'][$i]['width'];
|
550 |
+
$height = $meta['sizes'][$i]['height'];
|
551 |
+
}
|
552 |
+
|
553 |
+
$result .= "<h3>";
|
554 |
+
|
555 |
+
// Status Icon
|
556 |
+
if ( is_array( $status ) && $i == 'full-size' ) {
|
557 |
+
$result .= '<div class="meow-sized-image meow-bk-red"></div>';
|
558 |
+
$statusText = sprintf( __( "The retina version of the Full-Size image is missing.<br />Full Size Retina has been checked in the Settings and this image is therefore required.<br />Please drag & drop an image of at least <b>%dx%d</b> in the <b>Full-Size Retina Upload</b> column.", 'wp-retina-2x' ), $status['width'], $status['height'] );
|
559 |
+
}
|
560 |
+
else if ( is_array( $status ) ) {
|
561 |
+
$result .= '<div class="meow-sized-image meow-bk-red"></div>';
|
562 |
+
$statusText = sprintf( __( "The Full-Size image is too small (<b>%dx%d</b>) and this size cannot be generated.<br />Please upload an image of at least <b>%dx%d</b>.", 'wp-retina-2x' ), $meta['width'], $meta['height'], $status['width'], $status['height'] );
|
563 |
+
$issue++;
|
564 |
+
}
|
565 |
+
else if ( $status == 'EXISTS' ) {
|
566 |
+
$result .= '<div class="meow-sized-image meow-bk-blue"></div>';
|
567 |
+
$statusText = "";
|
568 |
+
$retina++;
|
569 |
+
}
|
570 |
+
else if ( $status == 'PENDING' ) {
|
571 |
+
$result .= '<div class="meow-sized-image meow-bk-orange"></div>';
|
572 |
+
$statusText = __( "The retina image can be created. Please use the 'GENERATE' button.", 'wp-retina-2x' );
|
573 |
+
$possible++;
|
574 |
+
}
|
575 |
+
else if ( $status == 'MISSING' ) {
|
576 |
+
$result .= '<div class="meow-sized-image meow-bk-gray"></div>';
|
577 |
+
$statusText = __( "The standard image normally created by WordPress is missing.", 'wp-retina-2x' );
|
578 |
+
$total--;
|
579 |
+
}
|
580 |
+
else if ( $status == 'IGNORED' ) {
|
581 |
+
$result .= '<div class="meow-sized-image meow-bk-gray"></div>';
|
582 |
+
$statusText = __( "This size is ignored by your retina settings.", 'wp-retina-2x' );
|
583 |
+
$ignored++;
|
584 |
+
$total--;
|
585 |
+
}
|
586 |
+
|
587 |
+
$result .= " Size: $i</h3><p>$statusText</p>";
|
588 |
+
|
589 |
+
if ( !is_array( $status ) && $status !== 'IGNORED' && $status !== 'MISSING' ) {
|
590 |
+
$result .= "<table><tr><th>Normal (" . $width . "×" . $height. ")</th><th>Retina 2x (" . $width * 2 . "×" . $height * 2 . ")</th></tr><tr><td><a target='_blank' href='$normal_file'><img src='$normal_file' width='100'></a></td><td><a target='_blank' href='$retina_file'><img src='$retina_file' width='100'></a></td></tr></table>";
|
591 |
+
$result .= "<p><small>";
|
592 |
+
$result .= "Image URL: <a target='_blank' href='$normal_file'>$normal_file</a><br />";
|
593 |
+
$result .= "Retina URL: <a target='_blank' href='$retina_file'>$retina_file</a><br />";
|
594 |
+
$result .= "Image Path: $normal_file_system<br />";
|
595 |
+
$result .= "Retina Path: $retina_file_system<br />";
|
596 |
+
$result .= "</small></p>";
|
597 |
+
}
|
598 |
+
}
|
599 |
+
$result .= "</table>";
|
600 |
+
$result .= "</div>";
|
601 |
+
return $result;
|
602 |
+
}
|
603 |
+
|
604 |
+
/**
|
605 |
+
*
|
606 |
+
* WP RETINA 2X CORE
|
607 |
+
*
|
608 |
+
*/
|
609 |
+
|
610 |
+
// Get WordPress upload directory
|
611 |
+
function get_upload_root() {
|
612 |
+
$uploads = wp_upload_dir();
|
613 |
+
return $uploads['basedir'];
|
614 |
+
}
|
615 |
+
|
616 |
+
function get_upload_root_url() {
|
617 |
+
$uploads = wp_upload_dir();
|
618 |
+
return $uploads['baseurl'];
|
619 |
+
}
|
620 |
+
|
621 |
+
// Get WordPress directory
|
622 |
+
function get_wordpress_root() {
|
623 |
+
return ABSPATH;
|
624 |
+
}
|
625 |
+
|
626 |
+
// Resize the image
|
627 |
+
function resize( $file_path, $width, $height, $crop, $newfile, $customCrop = false ) {
|
628 |
+
$crop_params = $crop == '1' ? true : $crop;
|
629 |
+
$orig_size = getimagesize( $file_path );
|
630 |
+
$image_src[0] = $file_path;
|
631 |
+
$image_src[1] = $orig_size[0];
|
632 |
+
$image_src[2] = $orig_size[1];
|
633 |
+
$file_info = pathinfo( $file_path );
|
634 |
+
$newfile_info = pathinfo( $newfile );
|
635 |
+
$extension = '.' . $newfile_info['extension'];
|
636 |
+
$no_ext_path = $file_info['dirname'] . '/' . $file_info['filename'];
|
637 |
+
$cropped_img_path = $no_ext_path . '-' . $width . 'x' . $height . "-tmp" . $extension;
|
638 |
+
$image = wp_get_image_editor( $file_path );
|
639 |
+
|
640 |
+
if ( is_wp_error( $image ) ) {
|
641 |
+
$this->log( "Resize failure: " . $image->get_error_message() );
|
642 |
+
error_log( "Resize failure: " . $image->get_error_message() );
|
643 |
+
return null;
|
644 |
+
}
|
645 |
+
|
646 |
+
// Resize or use Custom Crop
|
647 |
+
if ( !$customCrop )
|
648 |
+
$image->resize( $width, $height, $crop_params );
|
649 |
+
else
|
650 |
+
$image->crop( $customCrop['x'] * $customCrop['scale'], $customCrop['y'] * $customCrop['scale'], $customCrop['w'] * $customCrop['scale'], $customCrop['h'] * $customCrop['scale'], $width, $height, false );
|
651 |
+
|
652 |
+
// Quality
|
653 |
+
$quality = get_option( 'wr2x_quality', 90 );
|
654 |
+
$image->set_quality( $quality );
|
655 |
+
|
656 |
+
$saved = $image->save( $cropped_img_path );
|
657 |
+
if ( is_wp_error( $saved ) ) {
|
658 |
+
$error = $saved->get_error_message();
|
659 |
+
trigger_error( "Retina: Could not create/resize image " . $file_path . " to " . $newfile . ": " . $error , E_WARNING );
|
660 |
+
error_log( "Retina: Could not create/resize image " . $file_path . " to " . $newfile . ":" . $error );
|
661 |
+
return null;
|
662 |
+
}
|
663 |
+
if ( rename( $saved['path'], $newfile ) )
|
664 |
+
$cropped_img_path = $newfile;
|
665 |
+
else {
|
666 |
+
trigger_error( "Retina: Could not move " . $saved['path'] . " to " . $newfile . "." , E_WARNING );
|
667 |
+
error_log( "Retina: Could not move " . $saved['path'] . " to " . $newfile . "." );
|
668 |
+
return null;
|
669 |
+
}
|
670 |
+
$new_img_size = getimagesize( $cropped_img_path );
|
671 |
+
$new_img = str_replace( basename( $image_src[0] ), basename( $cropped_img_path ), $image_src[0] );
|
672 |
+
$vt_image = array ( 'url' => $new_img, 'width' => $new_img_size[0], 'height' => $new_img_size[1] );
|
673 |
+
return $vt_image;
|
674 |
+
}
|
675 |
+
|
676 |
+
// Return the retina file if there is any (system path)
|
677 |
+
function get_retina( $file ) {
|
678 |
+
$pathinfo = pathinfo( $file ) ;
|
679 |
+
if ( empty( $pathinfo ) || !isset( $pathinfo['dirname'] ) ) {
|
680 |
+
if ( empty( $file ) ) {
|
681 |
+
$this->log( "An empty filename was given to $this->get_retina()." );
|
682 |
+
error_log( "An empty filename was given to $this->get_retina()." );
|
683 |
+
}
|
684 |
+
else {
|
685 |
+
$this->log( "Pathinfo is null for " . $file . "." );
|
686 |
+
error_log( "Pathinfo is null for " . $file . "." );
|
687 |
+
}
|
688 |
+
return null;
|
689 |
+
}
|
690 |
+
$retina_file = trailingslashit( $pathinfo['dirname'] ) . $pathinfo['filename'] .
|
691 |
+
$this->retina_extension() . ( isset( $pathinfo['extension'] ) ? $pathinfo['extension'] : "" );
|
692 |
+
if ( file_exists( $retina_file ) )
|
693 |
+
return $retina_file;
|
694 |
+
$this->log( "Retina file at '{$retina_file}' does not exist." );
|
695 |
+
return null;
|
696 |
+
}
|
697 |
+
|
698 |
+
function get_retina_from_remote_url( $url ) {
|
699 |
+
$over_http = get_option( 'wr2x_over_http_check', false ) && $this->admin->is_registered();
|
700 |
+
if ( !$over_http )
|
701 |
+
return null;
|
702 |
+
$potential_retina_url = $this->rewrite_url_to_retina( $url );
|
703 |
+
$response = wp_remote_head( $potential_retina_url, array(
|
704 |
+
'user-agent' => "MeowApps-Retina",
|
705 |
+
'sslverify' => false,
|
706 |
+
'timeout' => 10
|
707 |
+
));
|
708 |
+
if ( is_array( $response ) && is_array( $response['response'] ) && isset( $response['response']['code'] ) ) {
|
709 |
+
if ( $response['response']['code'] == 200 ) {
|
710 |
+
$this->log( "Retina URL: " . $potential_retina_url, true);
|
711 |
+
return $potential_retina_url;
|
712 |
+
}
|
713 |
+
else
|
714 |
+
$this->log( "Remote head failed with code " . $response['response']['code'] . "." );
|
715 |
+
}
|
716 |
+
$this->log( "Retina URL couldn't be found (URL -> Retina URL).", true);
|
717 |
+
}
|
718 |
+
|
719 |
+
// Return retina URL from the image URL
|
720 |
+
function get_retina_from_url( $url ) {
|
721 |
+
$this->log( "Standard URL: " . $url, true);
|
722 |
+
$over_http = get_option( 'wr2x_over_http_check', false ) && $this->admin->is_registered();
|
723 |
+
$filepath = $this->from_url_to_system( $url );
|
724 |
+
if ( empty ( $filepath ) )
|
725 |
+
return $this->get_retina_from_remote_url( $url );
|
726 |
+
$this->log( "Standard PATH: " . $filepath, true);
|
727 |
+
$system_retina = $this->get_retina( $filepath );
|
728 |
+
if ( empty ( $system_retina ) )
|
729 |
+
return $this->get_retina_from_remote_url( $url );
|
730 |
+
$this->log( "Retina PATH: " . $system_retina, true);
|
731 |
+
$retina_url = $this->rewrite_url_to_retina( $url );
|
732 |
+
$this->log( "Retina URL: " . $retina_url, true);
|
733 |
+
return $retina_url;
|
734 |
+
}
|
735 |
+
|
736 |
+
// Get the filepath from the URL
|
737 |
+
function from_url_to_system( $url ) {
|
738 |
+
$img_pathinfo = $this->get_pathinfo_from_image_src( $url );
|
739 |
+
$filepath = trailingslashit( $this->get_wordpress_root() ) . $img_pathinfo;
|
740 |
+
if ( file_exists( $filepath ) )
|
741 |
+
return $filepath;
|
742 |
+
$filepath = trailingslashit( $this->get_upload_root() ) . $img_pathinfo;
|
743 |
+
if ( file_exists( $filepath ) )
|
744 |
+
return $filepath;
|
745 |
+
$this->log( "Standard PATH couldn't be found (URL -> System).", true);
|
746 |
+
return null;
|
747 |
+
}
|
748 |
+
|
749 |
+
function rewrite_url_to_retina( $url ) {
|
750 |
+
$whereisdot = strrpos( $url, '.' );
|
751 |
+
$url = substr( $url, 0, $whereisdot ) . $this->retina_extension() . substr( $url, $whereisdot + 1 );
|
752 |
+
return $url;
|
753 |
+
}
|
754 |
+
|
755 |
+
// Clean the PathInfo of the IMG SRC.
|
756 |
+
// IMPORTANT: This function STRIPS THE UPLOAD FOLDER if it's found
|
757 |
+
// REASON: The reason is that on some installs the uploads folder is linked to a different "unlogical" physical folder
|
758 |
+
// http://wordpress.org/support/topic/cant-find-retina-file-with-custom-uploads-constant?replies=3#post-5078892
|
759 |
+
function get_pathinfo_from_image_src( $image_src ) {
|
760 |
+
$uploads_url = trailingslashit( $this->get_upload_root_url() );
|
761 |
+
if ( strpos( $image_src, $uploads_url ) === 0 )
|
762 |
+
return ltrim( substr( $image_src, strlen( $uploads_url ) ), '/');
|
763 |
+
else if ( strpos( $image_src, wp_make_link_relative( $uploads_url ) ) === 0 )
|
764 |
+
return ltrim( substr( $image_src, strlen( wp_make_link_relative( $uploads_url ) ) ), '/');
|
765 |
+
$img_info = parse_url( $image_src );
|
766 |
+
return ltrim( $img_info['path'], '/' );
|
767 |
+
}
|
768 |
+
|
769 |
+
// Rename this filename with CDN
|
770 |
+
function cdn_this( $url ) {
|
771 |
+
$cdn_domain = "";
|
772 |
+
if ( $this->admin->is_registered() )
|
773 |
+
$cdn_domain = get_option( "wr2x_cdn_domain" );
|
774 |
+
if ( empty( $cdn_domain ) )
|
775 |
+
return $url;
|
776 |
+
|
777 |
+
$home_url = parse_url( home_url() );
|
778 |
+
$uploads_url = trailingslashit( $this->get_upload_root_url() );
|
779 |
+
$uploads_url_cdn = str_replace( $home_url['host'], $cdn_domain, $uploads_url );
|
780 |
+
// Perform additional CDN check (Issue #1631 by Martin)
|
781 |
+
if ( strpos( $url, $uploads_url_cdn ) === 0 ) {
|
782 |
+
$this->log( "URL already has CDN: $url" );
|
783 |
+
return $url;
|
784 |
+
}
|
785 |
+
$this->log( "URL before CDN: $url" );
|
786 |
+
$site_url = preg_replace( '#^https?://#', '', rtrim( get_site_url(), '/' ) );
|
787 |
+
$new_url = str_replace( $site_url, $cdn_domain, $url );
|
788 |
+
$this->log( "URL with CDN: $new_url" );
|
789 |
+
return $new_url;
|
790 |
+
}
|
791 |
+
|
792 |
+
// function admin_menu() {
|
793 |
+
// add_options_page( 'Retina', 'Retina', 'manage_options', 'wr2x_settings', 'wr2x_settings_page' );
|
794 |
+
// }
|
795 |
+
|
796 |
+
function get_image_sizes() {
|
797 |
+
$sizes = array();
|
798 |
+
global $_wp_additional_image_sizes;
|
799 |
+
foreach ( get_intermediate_image_sizes() as $s ) {
|
800 |
+
$crop = false;
|
801 |
+
if ( isset( $_wp_additional_image_sizes[$s] ) ) {
|
802 |
+
$width = intval($_wp_additional_image_sizes[$s]['width']);
|
803 |
+
$height = intval($_wp_additional_image_sizes[$s]['height']);
|
804 |
+
$crop = $_wp_additional_image_sizes[$s]['crop'];
|
805 |
+
} else {
|
806 |
+
$width = get_option( $s . '_size_w' );
|
807 |
+
$height = get_option( $s . '_size_h' );
|
808 |
+
$crop = get_option( $s . '_crop' );
|
809 |
+
}
|
810 |
+
$sizes[$s] = array( 'width' => $width, 'height' => $height, 'crop' => $crop );
|
811 |
+
}
|
812 |
+
if ( get_option( 'wr2x_disable_medium_large' ) )
|
813 |
+
unset( $sizes['medium_large'] );
|
814 |
+
return $sizes;
|
815 |
+
}
|
816 |
+
|
817 |
+
function get_active_image_sizes() {
|
818 |
+
$sizes = $this->get_image_sizes();
|
819 |
+
$active_sizes = array();
|
820 |
+
$ignore = get_option( "wr2x_ignore_sizes", array() );
|
821 |
+
if ( empty( $ignore ) )
|
822 |
+
$ignore = array();
|
823 |
+
$ignore = array_keys( $ignore );
|
824 |
+
foreach ( $sizes as $name => $attr ) {
|
825 |
+
$validSize = !empty( $attr['width'] ) || !empty( $attr['height'] );
|
826 |
+
if ( $validSize && !in_array( $name, $ignore ) ) {
|
827 |
+
$active_sizes[$name] = $attr;
|
828 |
+
}
|
829 |
+
}
|
830 |
+
return $active_sizes;
|
831 |
+
}
|
832 |
+
|
833 |
+
function is_wpml_installed() {
|
834 |
+
return function_exists( 'icl_object_id' ) && !class_exists( 'Polylang' );
|
835 |
+
}
|
836 |
+
|
837 |
+
// SQL Query if WPML with an AND to check if the p.ID (p is attachment) is indeed an original
|
838 |
+
// That is to limit the SQL that queries all the attachments
|
839 |
+
function create_sql_if_wpml_original() {
|
840 |
+
$whereIsOriginal = "";
|
841 |
+
if ( $this->is_wpml_installed() ) {
|
842 |
+
global $wpdb;
|
843 |
+
global $sitepress;
|
844 |
+
$tbl_wpml = $wpdb->prefix . "icl_translations";
|
845 |
+
$language = $sitepress->get_default_language();
|
846 |
+
$whereIsOriginal = " AND p.ID IN (SELECT element_id FROM $tbl_wpml WHERE element_type = 'post_attachment' AND language_code = '$language') ";
|
847 |
+
}
|
848 |
+
return $whereIsOriginal;
|
849 |
+
}
|
850 |
+
|
851 |
+
function is_debug() {
|
852 |
+
static $debug = -1;
|
853 |
+
if ( $debug == -1 ) {
|
854 |
+
$debug = get_option( "wr2x_debug" );
|
855 |
+
}
|
856 |
+
return !!$debug;
|
857 |
+
}
|
858 |
+
|
859 |
+
function log( $data, $isExtra = false ) {
|
860 |
+
if ( !$this->is_debug() )
|
861 |
+
return;
|
862 |
+
$fh = fopen( trailingslashit( WP_PLUGIN_DIR ) . 'wp-retina-2x/wp-retina-2x.log', 'a' );
|
863 |
+
$date = date( "Y-m-d H:i:s" );
|
864 |
+
fwrite( $fh, "$date: {$data}\n" );
|
865 |
+
fclose( $fh );
|
866 |
+
}
|
867 |
+
|
868 |
+
// Based on http://wordpress.stackexchange.com/questions/6645/turn-a-url-into-an-attachment-post-id
|
869 |
+
function get_attachment_id( $file ) {
|
870 |
+
$query = array(
|
871 |
+
'post_type' => 'attachment',
|
872 |
+
'meta_query' => array(
|
873 |
+
array(
|
874 |
+
'key' => '_wp_attached_file',
|
875 |
+
'value' => ltrim( $file, '/' )
|
876 |
+
)
|
877 |
+
)
|
878 |
+
);
|
879 |
+
$posts = get_posts( $query );
|
880 |
+
foreach( $posts as $post )
|
881 |
+
return $post->ID;
|
882 |
+
return false;
|
883 |
+
}
|
884 |
+
|
885 |
+
// Return the retina extension followed by a dot
|
886 |
+
function retina_extension() {
|
887 |
+
return '@2x.';
|
888 |
+
}
|
889 |
+
|
890 |
+
function is_image_meta( $meta ) {
|
891 |
+
if ( !isset( $meta ) )
|
892 |
+
return false;
|
893 |
+
if ( !isset( $meta['sizes'] ) )
|
894 |
+
return false;
|
895 |
+
if ( !isset( $meta['width'], $meta['height'] ) )
|
896 |
+
return false;
|
897 |
+
return true;
|
898 |
+
}
|
899 |
+
|
900 |
+
function retina_info( $id ) {
|
901 |
+
$result = array();
|
902 |
+
$meta = wp_get_attachment_metadata( $id );
|
903 |
+
if ( !$this->is_image_meta( $meta ) )
|
904 |
+
return $result;
|
905 |
+
$original_width = $meta['width'];
|
906 |
+
$original_height = $meta['height'];
|
907 |
+
$sizes = $this->get_image_sizes();
|
908 |
+
$required_files = true;
|
909 |
+
$originalfile = get_attached_file( $id );
|
910 |
+
$pathinfo = pathinfo( $originalfile );
|
911 |
+
$basepath = $pathinfo['dirname'];
|
912 |
+
$ignore = get_option( "wr2x_ignore_sizes", array() );
|
913 |
+
if ( empty( $ignore ) )
|
914 |
+
$ignore = array();
|
915 |
+
$ignore = array_keys( $ignore );
|
916 |
+
|
917 |
+
// Full-Size (if required in the settings)
|
918 |
+
$fullsize_required = get_option( "wr2x_full_size" ) && $this->admin->is_registered();
|
919 |
+
$retina_file = trailingslashit( $pathinfo['dirname'] ) . $pathinfo['filename'] . $this->retina_extension() . $pathinfo['extension'];
|
920 |
+
if ( $retina_file && file_exists( $retina_file ) )
|
921 |
+
$result['full-size'] = 'EXISTS';
|
922 |
+
else if ( $fullsize_required && $retina_file )
|
923 |
+
$result['full-size'] = array( 'width' => $original_width * 2, 'height' => $original_height * 2 );
|
924 |
+
//}
|
925 |
+
|
926 |
+
if ( $sizes ) {
|
927 |
+
foreach ( $sizes as $name => $attr ) {
|
928 |
+
$validSize = !empty( $attr['width'] ) || !empty( $attr['height'] );
|
929 |
+
if ( !$validSize || in_array( $name, $ignore ) ) {
|
930 |
+
$result[$name] = 'IGNORED';
|
931 |
+
continue;
|
932 |
+
}
|
933 |
+
// Check if the file related to this size is present
|
934 |
+
$pathinfo = null;
|
935 |
+
$retina_file = null;
|
936 |
+
|
937 |
+
if ( isset( $meta['sizes'][$name]['width'] ) && isset( $meta['sizes'][$name]['height']) && isset($meta['sizes'][$name]) && isset($meta['sizes'][$name]['file']) && file_exists( trailingslashit( $basepath ) . $meta['sizes'][$name]['file'] ) ) {
|
938 |
+
$normal_file = trailingslashit( $basepath ) . $meta['sizes'][$name]['file'];
|
939 |
+
$pathinfo = pathinfo( $normal_file ) ;
|
940 |
+
$retina_file = trailingslashit( $pathinfo['dirname'] ) . $pathinfo['filename'] . $this->retina_extension() . $pathinfo['extension'];
|
941 |
+
}
|
942 |
+
// None of the file exist
|
943 |
+
else {
|
944 |
+
$result[$name] = 'MISSING';
|
945 |
+
$required_files = false;
|
946 |
+
continue;
|
947 |
+
}
|
948 |
+
|
949 |
+
// The retina file exists
|
950 |
+
if ( $retina_file && file_exists( $retina_file ) ) {
|
951 |
+
$result[$name] = 'EXISTS';
|
952 |
+
continue;
|
953 |
+
}
|
954 |
+
// The size file exists
|
955 |
+
else if ( $retina_file )
|
956 |
+
$result[$name] = 'PENDING';
|
957 |
+
|
958 |
+
// The retina file exists
|
959 |
+
$required_width = $meta['sizes'][$name]['width'] * 2;
|
960 |
+
$required_height = $meta['sizes'][$name]['height'] * 2;
|
961 |
+
if ( !$this->are_dimensions_ok( $original_width, $original_height, $required_width, $required_height ) ) {
|
962 |
+
$result[$name] = array( 'width' => $required_width, 'height' => $required_height );
|
963 |
+
}
|
964 |
+
}
|
965 |
+
}
|
966 |
+
return $result;
|
967 |
+
}
|
968 |
+
|
969 |
+
function delete_attachment( $attach_id, $deleteFullSize = true ) {
|
970 |
+
$meta = wp_get_attachment_metadata( $attach_id );
|
971 |
+
$this->delete_images( $meta, $deleteFullSize );
|
972 |
+
$this->remove_issue( $attach_id );
|
973 |
+
}
|
974 |
+
|
975 |
+
function wp_generate_attachment_metadata( $meta ) {
|
976 |
+
if ( get_option( "wr2x_auto_generate" ) == true )
|
977 |
+
if ( $this->is_image_meta( $meta ) )
|
978 |
+
$this->generate_images( $meta );
|
979 |
+
return $meta;
|
980 |
+
}
|
981 |
+
|
982 |
+
function generate_images( $meta ) {
|
983 |
+
global $_wp_additional_image_sizes;
|
984 |
+
$sizes = $this->get_image_sizes();
|
985 |
+
if ( !isset( $meta['file'] ) )
|
986 |
+
return;
|
987 |
+
$originalfile = $meta['file'];
|
988 |
+
$uploads = wp_upload_dir();
|
989 |
+
$pathinfo = pathinfo( $originalfile );
|
990 |
+
$original_basename = $pathinfo['basename'];
|
991 |
+
$basepath = trailingslashit( $uploads['basedir'] ) . $pathinfo['dirname'];
|
992 |
+
$ignore = get_option( "wr2x_ignore_sizes" );
|
993 |
+
if ( empty( $ignore ) )
|
994 |
+
$ignore = array();
|
995 |
+
$ignore = array_keys( $ignore );
|
996 |
+
$issue = false;
|
997 |
+
$id = $this->get_attachment_id( $meta['file'] );
|
998 |
+
|
999 |
+
$this->log("* GENERATE RETINA FOR ATTACHMENT '{$meta['file']}'");
|
1000 |
+
$this->log( "Full-Size is {$original_basename}." );
|
1001 |
+
|
1002 |
+
foreach ( $sizes as $name => $attr ) {
|
1003 |
+
$normal_file = "";
|
1004 |
+
if ( in_array( $name, $ignore ) ) {
|
1005 |
+
$this->log( "Retina for {$name} ignored (settings)." );
|
1006 |
+
continue;
|
1007 |
+
}
|
1008 |
+
// Is the file related to this size there?
|
1009 |
+
$pathinfo = null;
|
1010 |
+
$retina_file = null;
|
1011 |
+
|
1012 |
+
if ( isset( $meta['sizes'][$name] ) && isset( $meta['sizes'][$name]['file'] ) ) {
|
1013 |
+
$normal_file = trailingslashit( $basepath ) . $meta['sizes'][$name]['file'];
|
1014 |
+
$pathinfo = pathinfo( $normal_file ) ;
|
1015 |
+
$retina_file = trailingslashit( $pathinfo['dirname'] ) . $pathinfo['filename'] . $this->retina_extension() . $pathinfo['extension'];
|
1016 |
+
}
|
1017 |
+
|
1018 |
+
if ( $retina_file && file_exists( $retina_file ) ) {
|
1019 |
+
$this->log( "Base for {$name} is '{$normal_file }'." );
|
1020 |
+
$this->log( "Retina for {$name} already exists: '$retina_file'." );
|
1021 |
+
continue;
|
1022 |
+
}
|
1023 |
+
if ( $retina_file ) {
|
1024 |
+
$originalfile = trailingslashit( $pathinfo['dirname'] ) . $original_basename;
|
1025 |
+
|
1026 |
+
if ( !file_exists( $originalfile ) ) {
|
1027 |
+
$this->log( "[ERROR] Original file '{$originalfile}' cannot be found." );
|
1028 |
+
return $meta;
|
1029 |
+
}
|
1030 |
+
|
1031 |
+
// Maybe that new image is exactly the size of the original image.
|
1032 |
+
// In that case, let's make a copy of it.
|
1033 |
+
if ( $meta['sizes'][$name]['width'] * 2 == $meta['width'] && $meta['sizes'][$name]['height'] * 2 == $meta['height'] ) {
|
1034 |
+
copy ( $originalfile, $retina_file );
|
1035 |
+
$this->log( "Retina for {$name} created: '{$retina_file}' (as a copy of the full-size)." );
|
1036 |
+
}
|
1037 |
+
// Otherwise let's resize (if the original size is big enough).
|
1038 |
+
else if ( $this->are_dimensions_ok( $meta['width'], $meta['height'], $meta['sizes'][$name]['width'] * 2, $meta['sizes'][$name]['height'] * 2 ) ) {
|
1039 |
+
// Change proposed by Nicscott01, slighlty modified by Jordy (+isset)
|
1040 |
+
// (https://wordpress.org/support/topic/issue-with-crop-position?replies=4#post-6200271)
|
1041 |
+
$crop = isset( $_wp_additional_image_sizes[$name] ) ? $_wp_additional_image_sizes[$name]['crop'] : true;
|
1042 |
+
$customCrop = null;
|
1043 |
+
|
1044 |
+
// Support for Manual Image Crop
|
1045 |
+
// If the size of the image was manually cropped, let's keep it.
|
1046 |
+
if ( class_exists( 'ManualImageCrop' ) && isset( $meta['micSelectedArea'] ) && isset( $meta['micSelectedArea'][$name] ) && isset( $meta['micSelectedArea'][$name]['scale'] ) ) {
|
1047 |
+
$customCrop = $meta['micSelectedArea'][$name];
|
1048 |
+
}
|
1049 |
+
$image = $this->resize( $originalfile, $meta['sizes'][$name]['width'] * 2,
|
1050 |
+
$meta['sizes'][$name]['height'] * 2, $crop, $retina_file, $customCrop );
|
1051 |
+
}
|
1052 |
+
if ( !file_exists( $retina_file ) ) {
|
1053 |
+
$this->log( "[ERROR] Retina for {$name} could not be created. Full-Size is " . $meta['width'] . "x" . $meta['height'] . " but Retina requires a file of at least " . $meta['sizes'][$name]['width'] * 2 . "x" . $meta['sizes'][$name]['height'] * 2 . "." );
|
1054 |
+
$issue = true;
|
1055 |
+
}
|
1056 |
+
else {
|
1057 |
+
do_action( 'wr2x_retina_file_added', $id, $retina_file, $name );
|
1058 |
+
$this->log( "Retina for {$name} created: '{$retina_file}'." );
|
1059 |
+
}
|
1060 |
+
} else {
|
1061 |
+
if ( empty( $normal_file ) )
|
1062 |
+
$this->log( "[ERROR] Base file for '{$name}' does not exist." );
|
1063 |
+
else
|
1064 |
+
$this->log( "[ERROR] Base file for '{$name}' cannot be found here: '{$normal_file}'." );
|
1065 |
+
}
|
1066 |
+
}
|
1067 |
+
|
1068 |
+
// Checks attachment ID + issues
|
1069 |
+
if ( !$id )
|
1070 |
+
return $meta;
|
1071 |
+
if ( $issue )
|
1072 |
+
$this->add_issue( $id );
|
1073 |
+
else
|
1074 |
+
$this->remove_issue( $id );
|
1075 |
+
return $meta;
|
1076 |
+
}
|
1077 |
+
|
1078 |
+
function delete_images( $meta, $deleteFullSize = false ) {
|
1079 |
+
if ( !$this->is_image_meta( $meta ) )
|
1080 |
+
return $meta;
|
1081 |
+
$sizes = $meta['sizes'];
|
1082 |
+
if ( !$sizes || !is_array( $sizes ) )
|
1083 |
+
return $meta;
|
1084 |
+
$this->log("* DELETE RETINA FOR ATTACHMENT '{$meta['file']}'");
|
1085 |
+
$originalfile = $meta['file'];
|
1086 |
+
$id = $this->get_attachment_id( $originalfile );
|
1087 |
+
$pathinfo = pathinfo( $originalfile );
|
1088 |
+
$uploads = wp_upload_dir();
|
1089 |
+
$basepath = trailingslashit( $uploads['basedir'] ) . $pathinfo['dirname'];
|
1090 |
+
foreach ( $sizes as $name => $attr ) {
|
1091 |
+
$pathinfo = pathinfo( $attr['file'] );
|
1092 |
+
$retina_file = $pathinfo['filename'] . $this->retina_extension() . $pathinfo['extension'];
|
1093 |
+
if ( file_exists( trailingslashit( $basepath ) . $retina_file ) ) {
|
1094 |
+
$fullpath = trailingslashit( $basepath ) . $retina_file;
|
1095 |
+
unlink( $fullpath );
|
1096 |
+
do_action( 'wr2x_retina_file_removed', $id, $retina_file );
|
1097 |
+
$this->log("Deleted '$fullpath'.");
|
1098 |
+
}
|
1099 |
+
}
|
1100 |
+
// Remove full-size if there is any
|
1101 |
+
if ( $deleteFullSize ) {
|
1102 |
+
$pathinfo = pathinfo( $originalfile );
|
1103 |
+
$retina_file = $pathinfo[ 'filename' ] . $this->retina_extension() . $pathinfo[ 'extension' ];
|
1104 |
+
if ( file_exists( trailingslashit( $basepath ) . $retina_file ) ) {
|
1105 |
+
$fullpath = trailingslashit( $basepath ) . $retina_file;
|
1106 |
+
unlink( $fullpath );
|
1107 |
+
do_action( 'wr2x_retina_file_removed', $id, $retina_file );
|
1108 |
+
$this->log( "Deleted '$fullpath'." );
|
1109 |
+
}
|
1110 |
+
}
|
1111 |
+
return $meta;
|
1112 |
+
}
|
1113 |
+
|
1114 |
+
/**
|
1115 |
+
*
|
1116 |
+
* FILTERS
|
1117 |
+
*
|
1118 |
+
*/
|
1119 |
+
|
1120 |
+
function validate_src( $src ) {
|
1121 |
+
if ( preg_match( "/^data:/i", $src ) )
|
1122 |
+
return null;
|
1123 |
+
return $src;
|
1124 |
+
}
|
1125 |
+
|
1126 |
+
/**
|
1127 |
+
*
|
1128 |
+
* LOAD SCRIPTS IF REQUIRED
|
1129 |
+
*
|
1130 |
+
*/
|
1131 |
+
|
1132 |
+
function wp_enqueue_scripts () {
|
1133 |
+
global $wr2x_version, $wr2x_retinajs, $wr2x_retina_image, $wr2x_picturefill, $wr2x_lazysizes;
|
1134 |
+
$method = get_option( "wr2x_method" );
|
1135 |
+
|
1136 |
+
if ( is_admin() && !get_option( "wr2x_retina_admin" ) )
|
1137 |
+
return;
|
1138 |
+
|
1139 |
+
// Picturefill
|
1140 |
+
if ( $method == "Picturefill" ) {
|
1141 |
+
if ( $this->is_debug() )
|
1142 |
+
wp_enqueue_script( 'wr2x-debug', plugins_url( '/js/debug.js', __FILE__ ), array(), $wr2x_version, false );
|
1143 |
+
// Picturefill
|
1144 |
+
if ( !get_option( "wr2x_picturefill_noscript" ) )
|
1145 |
+
wp_enqueue_script( 'picturefill', plugins_url( '/js/picturefill.min.js', __FILE__ ), array(), $wr2x_picturefill, false );
|
1146 |
+
// Lazysizes
|
1147 |
+
if ( get_option( "wr2x_picturefill_lazysizes" ) && $this->admin->is_registered() )
|
1148 |
+
wp_enqueue_script( 'lazysizes', plugins_url( '/js/lazysizes.min.js', __FILE__ ), array(), $wr2x_lazysizes, false );
|
1149 |
+
return;
|
1150 |
+
}
|
1151 |
+
|
1152 |
+
// Debug + HTML Rewrite = No JS!
|
1153 |
+
if ( $this->is_debug() && $method == "HTML Rewrite" ) {
|
1154 |
+
return;
|
1155 |
+
}
|
1156 |
+
|
1157 |
+
// Debug mode, we force the devicePixelRatio to be Retina
|
1158 |
+
if ( $this->is_debug() )
|
1159 |
+
wp_enqueue_script( 'wr2x-debug', plugins_url( '/js/debug.js', __FILE__ ), array(), $wr2x_version, false );
|
1160 |
+
|
1161 |
+
// Retina-Images and HTML Rewrite both need the devicePixelRatio cookie on the server-side
|
1162 |
+
if ( $method == "Retina-Images" || $method == "HTML Rewrite" )
|
1163 |
+
wp_enqueue_script( 'retina-images', plugins_url( '/js/retina-cookie.js', __FILE__ ), array(), $wr2x_retina_image, false );
|
1164 |
+
|
1165 |
+
// Retina.js only needs itself
|
1166 |
+
if ($method == "retina.js")
|
1167 |
+
wp_enqueue_script( 'retinajs', plugins_url( '/js/retina.min.js', __FILE__ ), array(), $wr2x_retinajs, true );
|
1168 |
+
}
|
1169 |
+
|
1170 |
+
/*******************************************************************************
|
1171 |
+
* OLD PRO / TODO: THIS FUNCTION SHOULD BE REMOVED IN THE FUTURE
|
1172 |
+
******************************************************************************/
|
1173 |
+
|
1174 |
+
function admin_notices() {
|
1175 |
+
if ( isset( $_POST['wr2x_reset_sub'] ) ) {
|
1176 |
+
delete_transient( 'wr2x_validated' );
|
1177 |
+
delete_option( 'wr2x_pro_serial' );
|
1178 |
+
delete_option( 'wr2x_pro_status' );
|
1179 |
+
}
|
1180 |
+
$validated = get_transient( 'wr2x_validated' );
|
1181 |
+
$subscr_id = get_option( 'wr2x_pro_serial', "" );
|
1182 |
+
if ( empty( $subscr_id ) || empty( $validated ) )
|
1183 |
+
return;
|
1184 |
+
$forever = strpos( $subscr_id, 'F-' ) !== false;
|
1185 |
+
$yearly = strpos( $subscr_id, 'I-' ) !== false;
|
1186 |
+
?>
|
1187 |
+
<div class="error">
|
1188 |
+
<p>
|
1189 |
+
<b>IMPORTANT MESSAGE ABOUT WP RETINA 2X.</b>
|
1190 |
+
In order to comply with WordPress.org rules, big changes in the code and how the plugin was sold had to be made. The plugin now requires to be bought through <a target='_blank' href="https://store.meowapps.com">https://store.meowapps.com</a>. You will be able to download the Pro version there, manage your keys and websites. It is a much more robust system. Since only the free version can be hosted by WordPress.org, this is the one which is active now. I am trying to ease this upgrade, depending on your current license.<br /><br />
|
1191 |
+
Your license is <b><?php echo $subscr_id ?></b>.
|
1192 |
+
<?php
|
1193 |
+
if ( $forever ) {
|
1194 |
+
echo "You have a Forever license. If you got this license less than 160 days ago, reply to the welcome e-mail (after buying a new license) with your previous license key ($subscr_id) and the e-mail you are using in Paypal. I will refund the previous payment. If it is more than 160 days, we are out of luck. So here is a discount of <b>90% off</b>, for any license you like: <b>UPGRADE90WPRETINA</b>. If you use the discount, the refund will be of course not possible.";
|
1195 |
+
}
|
1196 |
+
else if ( $yearly ) {
|
1197 |
+
echo "You have a Yearly license. If you got this license less than 160 days ago, reply to the welcome e-mail (after buying a new license) with your previous license key ($subscr_id) and the e-mail you are using in Paypal. I will refund the previous payment. If it is more than 160 days ago, we are out of luck. So here is a discount of <b>50% off</b>, for any license you like: <b>UPGRADEWPRETINA50</b>. Also, don't forget to cancel your current subscription in Paypal (<a target='_blank' href='https://www.paypal.com/us/selfhelp/article/How-do-I-cancel-an-automatic-payment-I-have-with-a-merchant-FAQ2058'>click here</a> if you don't know how to do this).";
|
1198 |
+
}
|
1199 |
+
else {
|
1200 |
+
echo "Your license is special, so please contact me.";
|
1201 |
+
}
|
1202 |
+
?>
|
1203 |
+
If you absolutely need to use the plugin as it was before, with your current license key, please download it again here: <a target='_blank' href="https://meowapps.com/previous-versions/">Previous Versions</a>. I will keep the old system up for a while, but no updates will be possible.
|
1204 |
+
<br /><br />Also note that I also have now an <a target='_blank' href='https://store.meowapps.com/affiliate-area/'>Affiliate Program</a> in that store, don't hesitate to register for it. Thanks a lot for your comprehension and sorry for the troubles. Not easy for anyone but it had to be done and I think you will really enjoy the new store more than the previous clunky system. I wrote a little post about this change here, so don't hesitate to add a comment if you have a question: <a href="https://meowapps.com/migration-store/">Migration to the Meow Apps Store</a>.
|
1205 |
+
</p>
|
1206 |
+
<p>
|
1207 |
+
<form method="post" action="">
|
1208 |
+
<input type="hidden" name="wr2x_reset_sub" value="true">
|
1209 |
+
<input type="submit" name="submit" id="submit" class="button" value="Got it. Understood!">
|
1210 |
+
<br /><small>Make sure you got a new license and all before clicking this button. It will also clean your install from the old key data.</small>
|
1211 |
+
</form>
|
1212 |
+
</p>
|
1213 |
+
</div>
|
1214 |
+
<?php
|
1215 |
+
}
|
1216 |
+
|
1217 |
+
}
|
1218 |
+
|
1219 |
+
// Used by WP Rocket (and maybe by other plugins)
|
1220 |
+
function wr2x_is_registered() {
|
1221 |
+
global $wr2x_core;
|
1222 |
+
return $wr2x_core->admin->is_registered();
|
1223 |
+
}
|
1224 |
+
|
1225 |
+
?>
|
dashboard.php
ADDED
@@ -0,0 +1,313 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Meow_WR2X_Dashboard {
|
4 |
+
|
5 |
+
public $core = null;
|
6 |
+
|
7 |
+
public function __construct( $core ) {
|
8 |
+
$this->core = $core;
|
9 |
+
add_action( 'admin_menu', array( $this, 'admin_menu_dashboard' ) );
|
10 |
+
}
|
11 |
+
|
12 |
+
function admin_menu_dashboard () {
|
13 |
+
$flagged = count( $this->core->get_issues() );
|
14 |
+
$warning_title = __( "Retina images", 'wp-retina-2x' );
|
15 |
+
$menu_label = sprintf( __( 'Retina %s' ), "<span class='update-plugins count-$flagged' title='$warning_title'><span class='update-count'>" . number_format_i18n( $flagged ) . "</span></span>" );
|
16 |
+
add_media_page( 'Retina', $menu_label, 'manage_options', 'wp-retina-2x', array( $this, 'dashboard' ) );
|
17 |
+
}
|
18 |
+
|
19 |
+
function dashboard() {
|
20 |
+
$refresh = isset ( $_GET[ 'refresh' ] ) ? $_GET[ 'refresh' ] : 0;
|
21 |
+
$clearlogs = isset ( $_GET[ 'clearlogs' ] ) ? $_GET[ 'clearlogs' ] : 0;
|
22 |
+
$ignore = isset ( $_GET[ 'ignore' ] ) ? $_GET[ 'ignore' ] : false;
|
23 |
+
if ( $ignore ) {
|
24 |
+
if ( !$this->core->admin->is_registered() ) {
|
25 |
+
echo "<div class='error' style='margin-top: 20px;'><p>";
|
26 |
+
_e( "Ignore is a Pro feature.", 'wp-retina-2x' );
|
27 |
+
echo "</p></div>";
|
28 |
+
}
|
29 |
+
else
|
30 |
+
$this->core->add_ignore( $ignore );
|
31 |
+
}
|
32 |
+
if ( $refresh ) {
|
33 |
+
$this->core->calculate_issues();
|
34 |
+
}
|
35 |
+
if ( $clearlogs ) {
|
36 |
+
if ( file_exists( plugin_dir_path( __FILE__ ) . '/wp-retina-2x.log' ) ) {
|
37 |
+
unlink( plugin_dir_path( __FILE__ ) . '/wp-retina-2x.log' );
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
$hide_ads = get_option( 'meowapps_hide_ads', false );
|
42 |
+
$view = isset ( $_GET[ 'view' ] ) ? $_GET[ 'view' ] : 'issues';
|
43 |
+
$paged = isset ( $_GET[ 'paged' ] ) ? $_GET[ 'paged' ] : 1;
|
44 |
+
$s = isset( $_GET[ 's' ] ) && !empty( $_GET[ 's' ] ) ? sanitize_text_field( $_GET[ 's' ] ) : null;
|
45 |
+
$issues = $count = 0;
|
46 |
+
$posts_per_page = 15; // TODO: HOW TO GET THE NUMBER OF MEDIA PER PAGES? IT IS NOT get_option('posts_per_page');
|
47 |
+
$issues = $this->core->get_issues();
|
48 |
+
$ignored = $this->core->get_ignores();
|
49 |
+
|
50 |
+
echo '<div class="wrap">';
|
51 |
+
echo $this->core->admin->display_title( "WP Retina 2x" );
|
52 |
+
echo '<p></p>';
|
53 |
+
|
54 |
+
if ( $this->core->admin->is_registered() && $view == 'issues' ) {
|
55 |
+
global $wpdb;
|
56 |
+
$totalcount = $wpdb->get_var( $wpdb->prepare( "
|
57 |
+
SELECT COUNT(*)
|
58 |
+
FROM $wpdb->posts p
|
59 |
+
WHERE post_status = 'inherit'
|
60 |
+
AND post_type = 'attachment'" . $this->core->create_sql_if_wpml_original() . "
|
61 |
+
AND post_title LIKE %s
|
62 |
+
AND ( post_mime_type = 'image/jpeg' OR
|
63 |
+
post_mime_type = 'image/png' OR
|
64 |
+
post_mime_type = 'image/gif' )
|
65 |
+
", '%' . $s . '%' ) );
|
66 |
+
$postin = count( $issues ) < 1 ? array( -1 ) : $issues;
|
67 |
+
$query = new WP_Query(
|
68 |
+
array(
|
69 |
+
'post_status' => 'inherit',
|
70 |
+
'post_type' => 'attachment',
|
71 |
+
'post__in' => $postin,
|
72 |
+
'paged' => $paged,
|
73 |
+
'posts_per_page' => $posts_per_page,
|
74 |
+
's' => $s
|
75 |
+
)
|
76 |
+
);
|
77 |
+
}
|
78 |
+
else if ( $this->core->admin->is_registered() && $view == 'ignored' ) {
|
79 |
+
global $wpdb;
|
80 |
+
$totalcount = $wpdb->get_var( $wpdb->prepare( "
|
81 |
+
SELECT COUNT(*)
|
82 |
+
FROM $wpdb->posts p
|
83 |
+
WHERE post_status = 'inherit'
|
84 |
+
AND post_type = 'attachment'" . $this->core->create_sql_if_wpml_original() . "
|
85 |
+
AND post_title LIKE %s
|
86 |
+
AND ( post_mime_type = 'image/jpeg' OR
|
87 |
+
post_mime_type = 'image/jpg' OR
|
88 |
+
post_mime_type = 'image/png' OR
|
89 |
+
post_mime_type = 'image/gif' )
|
90 |
+
", '%' . $s . '%' ) );
|
91 |
+
$postin = count( $ignored ) < 1 ? array( -1 ) : $ignored;
|
92 |
+
$query = new WP_Query(
|
93 |
+
array(
|
94 |
+
'post_status' => 'inherit',
|
95 |
+
'post_type' => 'attachment',
|
96 |
+
'post__in' => $postin,
|
97 |
+
'paged' => $paged,
|
98 |
+
'posts_per_page' => $posts_per_page,
|
99 |
+
's' => $s
|
100 |
+
)
|
101 |
+
);
|
102 |
+
}
|
103 |
+
else {
|
104 |
+
$query = new WP_Query(
|
105 |
+
array(
|
106 |
+
'post_status' => 'inherit',
|
107 |
+
'post_type' => 'attachment',
|
108 |
+
'post_mime_type' => 'image/jpeg,image/gif,image/jpg,image/png',
|
109 |
+
'paged' => $paged,
|
110 |
+
'posts_per_page' => $posts_per_page,
|
111 |
+
's' => $s
|
112 |
+
)
|
113 |
+
);
|
114 |
+
|
115 |
+
//$s
|
116 |
+
$totalcount = $query->found_posts;
|
117 |
+
}
|
118 |
+
|
119 |
+
$issues_count = count( $issues );
|
120 |
+
|
121 |
+
// If 'search', then we need to clean-up the issues count
|
122 |
+
if ( $s && $issues_count > 0 ) {
|
123 |
+
global $wpdb;
|
124 |
+
$issues_count = $wpdb->get_var( $wpdb->prepare( "
|
125 |
+
SELECT COUNT(*)
|
126 |
+
FROM $wpdb->posts p
|
127 |
+
WHERE id IN ( " . implode( ',', $issues ) . " )" . $this->core->create_sql_if_wpml_original() . "
|
128 |
+
AND post_title LIKE %s
|
129 |
+
", '%' . $s . '%' ) );
|
130 |
+
}
|
131 |
+
|
132 |
+
$results = array();
|
133 |
+
$count = $query->found_posts;
|
134 |
+
$pagescount = $query->max_num_pages;
|
135 |
+
foreach ( $query->posts as $post ) {
|
136 |
+
$info = $this->core->retina_info( $post->ID );
|
137 |
+
array_push( $results, array( 'post' => $post, 'info' => $info ) );
|
138 |
+
}
|
139 |
+
?>
|
140 |
+
|
141 |
+
<div style='background: #FFF; padding: 5px; border-radius: 4px; height: 28px; box-shadow: 0px 0px 6px #C2C2C2;'>
|
142 |
+
|
143 |
+
<!-- REFRESH -->
|
144 |
+
<a id='wr2x_refresh' href='?page=wp-retina-2x&view=issues&refresh=true' class='button' style='float: left;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-controls-repeat"></span><?php _e("Refresh", 'wp-retina-2x'); ?></a>
|
145 |
+
|
146 |
+
<!-- SEARCH -->
|
147 |
+
<form id="posts-filter" action="upload.php" method="get">
|
148 |
+
<p class="search-box" style='margin-left: 5px; float: left;'>
|
149 |
+
<input type="search" name="s" value="<?php echo $s ? $s : ""; ?>">
|
150 |
+
<input type="hidden" name="page" value="wp-retina-2x">
|
151 |
+
<input type="hidden" name="view" value="<?php echo $view; ?>">
|
152 |
+
<input type="hidden" name="paged" value="<?php echo $paged; ?>">
|
153 |
+
<input type="submit" class="button" value="Search">
|
154 |
+
</p>
|
155 |
+
</form>
|
156 |
+
|
157 |
+
<!-- REMOVE BUTTON ALL -->
|
158 |
+
<a id='wr2x_remove_button_all' onclick='wr2x_delete_all()' class='button button-red' style='float: right;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-trash"></span><?php _e("Bulk Delete (Retina Only)", 'wp-retina-2x'); ?></a>
|
159 |
+
|
160 |
+
<!-- GENERATE ALL -->
|
161 |
+
<a id='wr2x_generate_button_all' onclick='wr2x_generate_all()' class='button-primary' style='float: right; margin-right: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-controls-play"></span><?php _e("Bulk Generate (Thumbnails & Retina)", 'wp-retina-2x'); ?></a>
|
162 |
+
|
163 |
+
|
164 |
+
<!-- PROGRESS -->
|
165 |
+
<span style='margin-left: 12px; font-size: 13px; top: 5px; position: relative; color: #24547C; font-weight: bold;' id='wr2x_progression'></span>
|
166 |
+
|
167 |
+
</div>
|
168 |
+
|
169 |
+
<?php
|
170 |
+
if (isset ( $_GET[ 'clearlogs' ] ) ? $_GET[ 'clearlogs' ] : 0) {
|
171 |
+
echo "<div class='updated' style='margin-top: 20px;'><p>";
|
172 |
+
_e( "The logs have been cleared.", 'wp-retina-2x' );
|
173 |
+
echo "</p></div>";
|
174 |
+
}
|
175 |
+
|
176 |
+
$active_sizes = $this->core->get_active_image_sizes();
|
177 |
+
$full_size_needed = get_option( "wr2x_full_size" );
|
178 |
+
|
179 |
+
$max_width = 0;
|
180 |
+
$max_height = 0;
|
181 |
+
foreach ( $active_sizes as $name => $active_size ) {
|
182 |
+
if ( $active_size['height'] != 9999 && $active_size['height'] > $max_height ) {
|
183 |
+
$max_height = $active_size['height'];
|
184 |
+
}
|
185 |
+
if ( $active_size['width'] != 9999 && $active_size['width'] > $max_width ) {
|
186 |
+
$max_width = $active_size['width'];
|
187 |
+
}
|
188 |
+
}
|
189 |
+
$max_width = $max_width * 2;
|
190 |
+
$max_height = $max_height * 2;
|
191 |
+
|
192 |
+
$upload_max_size = $this->core->get_max_filesize();
|
193 |
+
?>
|
194 |
+
|
195 |
+
<p>
|
196 |
+
<?php printf( __( 'The full-size images should have a resolution of <b>%d×%d</b> at least for the plugin to be able generate the <b>%d retina images</b> required by your website.', 'wp-retina-2x' ), $max_width, $max_height, count( $active_sizes ) ); ?>
|
197 |
+
<?php if ( $full_size_needed ) printf( __( "You <b>also need</b> to upload a retina image for the Full-Size image (might be <b>%d×%d</b>).", 'wp-retina-2x' ), $max_width * 2, $max_height * 2 ); ?>
|
198 |
+
<?php _e("You can upload or replace the images by drag & drop.", 'wp-retina-2x' ); ?>
|
199 |
+
<?php printf( __( "Your PHP configuration allows uploads of <b>%dMB</b> maximum.", 'wp-retina-2x'), $upload_max_size / 1000000 ); ?>
|
200 |
+
|
201 |
+
<?php
|
202 |
+
if ( file_exists( plugin_dir_path( __FILE__ ) . '/wp-retina-2x.log' ) ) {
|
203 |
+
printf( __( 'The <a target="_blank" href="%s/wp-retina-2x.log">log file</a> is available. You can also <a href="?page=wp-retina-2x&view=issues&clearlogs=true">clear</a> it.', 'wp-retina-2x' ), plugin_dir_url( __FILE__ ) );
|
204 |
+
}
|
205 |
+
?>
|
206 |
+
</p>
|
207 |
+
|
208 |
+
<?php
|
209 |
+
if ( !$this->core->admin->is_registered() && !get_option( "wr2x_hide_pro", false ) ) {
|
210 |
+
echo '<div class="updated"><p>';
|
211 |
+
echo __( '<b>Only Pro users have access to the features of this dashboard.</b> As a standard user, the dashboard allow you to Bulk Generate, Bulk Delete and access the Retina Logs. If you wish to stay a standard user and never see this dashboard aver again, you can hide it in the settings.<br /><br />The Pro version of the plugin allows you to <b>replace directly an image already uploaded in the Media Library</b> by a simple drag & drop, upload a <b>retina image for a full-size image</b>, use <b>lazy-loading</b> to load your images (for better performance) and, more importantly, <b>supports the developer</b> :)<br /><br /><a class="button-primary" href="https://store.meowapps.com/wp-retina-2x/" target="_blank">Get WP Retina 2x Pro</a>', 'wp-retina-2x' );
|
212 |
+
echo '</p></div>';
|
213 |
+
}
|
214 |
+
?>
|
215 |
+
|
216 |
+
<div id='wr2x-pages'>
|
217 |
+
<?php
|
218 |
+
echo paginate_links(array(
|
219 |
+
'base' => '?page=wp-retina-2x&s=' . urlencode($s) . '&view=' . $view . '%_%',
|
220 |
+
'current' => $paged,
|
221 |
+
'format' => '&paged=%#%',
|
222 |
+
'total' => $pagescount,
|
223 |
+
'prev_next' => false
|
224 |
+
));
|
225 |
+
?>
|
226 |
+
</div>
|
227 |
+
|
228 |
+
<ul class="subsubsub">
|
229 |
+
<li class="all"><a <?php if ( $view == 'all' ) echo "class='current'"; ?> href='?page=wp-retina-2x&s=<?php echo $s; ?>&view=all'><?php _e( "All", 'wp-retina-2x' ); ?></a><span class="count">(<?php echo $totalcount; ?>)</span></li> |
|
230 |
+
|
231 |
+
<?php if ( $this->core->admin->is_registered() ): ?>
|
232 |
+
|
233 |
+
<li class="all"><a <?php if ( $view == 'issues' ) echo "class='current'"; ?> href='?page=wp-retina-2x&s=<?php echo $s; ?>&view=issues'><?php _e( "Issues", 'wp-retina-2x' ); ?></a><span class="count">(<?php echo $issues_count; ?>)</span></li> |
|
234 |
+
<li class="all"><a <?php if ( $view == 'ignored' ) echo "class='current'"; ?> href='?page=wp-retina-2x&s=<?php echo $s; ?>&view=ignored'><?php _e( "Ignored", 'wp-retina-2x' ); ?></a><span class="count">(<?php echo count( $ignored ); ?>)</span></li>
|
235 |
+
|
236 |
+
<?php else: ?>
|
237 |
+
|
238 |
+
<li class="all"><span><?php _e( "Issues", 'wp-retina-2x' ); ?></span> <span class="count">(<?php echo $issues_count; ?>)</span></li> |
|
239 |
+
<li class="all"><span><?php _e( "Ignored", 'wp-retina-2x' ); ?></span> <span class="count">(<?php echo count( $ignored ); ?>)</span></li>
|
240 |
+
|
241 |
+
<?php endif; ?>
|
242 |
+
|
243 |
+
|
244 |
+
</ul>
|
245 |
+
<table class='wp-list-table widefat fixed media wr2x-table'>
|
246 |
+
<thead><tr>
|
247 |
+
<?php
|
248 |
+
echo "<th style='width: 56px;'>Thumbnail</th>";
|
249 |
+
echo "<th style=' width: 360px;'>" . __( "Base image", 'wp-retina-2x' ) . "</th>";
|
250 |
+
echo "<th style=''>" . __( "Media Sizes<br />Retina-ized", 'wp-retina-2x' ) . "</th>";
|
251 |
+
echo "<th style=''>" . __( "Full-Size<br/><b>Replace</b>", 'wp-retina-2x' ) . "</th>";
|
252 |
+
echo "<th style=''>" . __( "Full-Size Retina", 'wp-retina-2x' ) . "</th>";
|
253 |
+
echo "<th style=''>" . __( "Full-Size Retina<br/><b>Upload</b>", 'wp-retina-2x' ) . "</th>";
|
254 |
+
?>
|
255 |
+
</tr></thead>
|
256 |
+
<tbody>
|
257 |
+
<?php
|
258 |
+
foreach ($results as $index => $attr) {
|
259 |
+
$post = $attr['post'];
|
260 |
+
$info = $attr['info'];
|
261 |
+
$meta = wp_get_attachment_metadata( $post->ID );
|
262 |
+
// Let's clean the issues status
|
263 |
+
if ( $view != 'issues' ) {
|
264 |
+
$this->core->update_issue_status( $post->ID, $issues, $info );
|
265 |
+
}
|
266 |
+
if ( isset( $meta ) && isset( $meta['width'] ) ) {
|
267 |
+
$original_width = $meta['width'];
|
268 |
+
$original_height = $meta['height'];
|
269 |
+
}
|
270 |
+
|
271 |
+
$attachmentsrc = wp_get_attachment_image_src( $post->ID, 'thumbnail' );
|
272 |
+
echo "<tr class='wr2x-file-row' postId='" . $post->ID . "'>";
|
273 |
+
echo "<td class='wr2x-image wr2x-info-thumbnail'><img src='" . $attachmentsrc[0] . "' /></td>";
|
274 |
+
echo "<td class='wr2x-title'><a href='media.php?attachment_id=" . $post->ID . "&action=edit'>" . ( $post->post_title ? $post->post_title : '<i>Untitled</i>' ) . '</a><br />' .
|
275 |
+
"<span class='resolution'>Full-Size: <span class='" . ( $original_width < $max_width ? "red" : "" ) . "'>" . $original_width . "</span>×<span class='" . ( $original_height < $max_height ? "red" : "" ) . "'>" . $original_height . "</span></span>";
|
276 |
+
echo "<div class='actions'>";
|
277 |
+
echo "<a style='position: relative;' onclick='wr2x_generate(" . $post->ID . ", true)' id='wr2x_generate_button_" . $post->ID . "' class='wr2x-button'>" . __( "GENERATE", 'wp-retina-2x' ) . "</a>";
|
278 |
+
if ( !$this->core->is_ignore( $post->ID ) )
|
279 |
+
echo " <a href='?page=wp-retina-2x&view=" . $view . "&paged=" . $paged . "&ignore=" . $post->ID . "' id='wr2x_generate_button_" . $post->ID . "' class='wr2x-button wr2x-button-ignore'>" . __( "IGNORE", 'wp-retina-2x' ) . "</a>";
|
280 |
+
echo " <a style='position: relative;' class='wr2x-button wr2x-button-view'>" . __( "DETAILS", 'wp-retina-2x' ) . "</a>";
|
281 |
+
echo "</div></td>";
|
282 |
+
|
283 |
+
// Media Sizes Retina-ized
|
284 |
+
echo '<td id="wr2x-info-' . $post->ID . '" style="padding-top: 10px;" class="wr2x-info">';
|
285 |
+
echo $this->core->html_get_basic_retina_info( $post, $info );
|
286 |
+
echo "</td>";
|
287 |
+
|
288 |
+
if ( $this->core->admin->is_registered() ) {
|
289 |
+
// Full-Size Replace
|
290 |
+
echo "<td class='wr2x-fullsize-replace'><div class='wr2x-dragdrop'></div>";
|
291 |
+
echo "</td>";
|
292 |
+
// Full-Size Retina
|
293 |
+
echo '<td id="wr2x-info-full-' . $post->ID . '" class="wr2x-image wr2x-info-full">';
|
294 |
+
echo $this->core->html_get_basic_retina_info_full( $post->ID, $info );
|
295 |
+
echo "</td>";
|
296 |
+
// Full-Size Retina Upload
|
297 |
+
echo "<td class='wr2x-fullsize-retina-upload'>";
|
298 |
+
echo "<div class='wr2x-dragdrop'></div>";
|
299 |
+
echo "</td>";
|
300 |
+
}
|
301 |
+
else
|
302 |
+
echo "<td colspan='3' style='text-align: center; background: #F9F9F9;'><small><br />PRO VERSION ONLY</small></td>";
|
303 |
+
echo "</tr>";
|
304 |
+
}
|
305 |
+
?>
|
306 |
+
</tbody>
|
307 |
+
</table>
|
308 |
+
</div>
|
309 |
+
|
310 |
+
<?php
|
311 |
+
}
|
312 |
+
}
|
313 |
+
?>
|
img/burn.png
DELETED
Binary file
|
img/clock.png
DELETED
Binary file
|
img/cross-small.png
DELETED
Binary file
|
img/exclamation.png
DELETED
Binary file
|
img/photo-album--plus.png
DELETED
Binary file
|
img/prohibition-small.png
DELETED
Binary file
|
img/refresh.png
DELETED
Binary file
|
img/replace.png
DELETED
Binary file
|
img/tick-circle.png
DELETED
Binary file
|
img/wpengine.png
DELETED
Binary file
|
inc/Mobile_Detect.php
DELETED
@@ -1,1231 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Mobile Detect Library
|
4 |
-
* =====================
|
5 |
-
*
|
6 |
-
* Motto: "Every business should have a mobile detection script to detect mobile readers"
|
7 |
-
*
|
8 |
-
* Mobile_Detect is a lightweight PHP class for detecting mobile devices (including tablets).
|
9 |
-
* It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.
|
10 |
-
*
|
11 |
-
* @author Current authors: Serban Ghita <serbanghita@gmail.com>, Nick Ilyin <nick.ilyin@gmail.com>
|
12 |
-
* Original author: Victor Stanciu <vic.stanciu@gmail.com>
|
13 |
-
*
|
14 |
-
* @license Code and contributions have 'MIT License'
|
15 |
-
* More details: https://github.com/serbanghita/Mobile-Detect/blob/master/LICENSE.txt
|
16 |
-
*
|
17 |
-
* @link Homepage: http://mobiledetect.net
|
18 |
-
* GitHub Repo: https://github.com/serbanghita/Mobile-Detect
|
19 |
-
* Google Code: http://code.google.com/p/php-mobile-detect/
|
20 |
-
* README: https://github.com/serbanghita/Mobile-Detect/blob/master/README.md
|
21 |
-
* HOWTO: https://github.com/serbanghita/Mobile-Detect/wiki/Code-examples
|
22 |
-
*
|
23 |
-
* @version 2.8.0
|
24 |
-
*/
|
25 |
-
|
26 |
-
class Mobile_Detect
|
27 |
-
{
|
28 |
-
/**
|
29 |
-
* Mobile detection type.
|
30 |
-
*
|
31 |
-
* @deprecated since version 2.6.9
|
32 |
-
*/
|
33 |
-
const DETECTION_TYPE_MOBILE = 'mobile';
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Extended detection type.
|
37 |
-
*
|
38 |
-
* @deprecated since version 2.6.9
|
39 |
-
*/
|
40 |
-
const DETECTION_TYPE_EXTENDED = 'extended';
|
41 |
-
|
42 |
-
/**
|
43 |
-
* A frequently used regular expression to extract version #s.
|
44 |
-
*
|
45 |
-
* @deprecated since version 2.6.9
|
46 |
-
*/
|
47 |
-
const VER = '([\w._\+]+)';
|
48 |
-
|
49 |
-
/**
|
50 |
-
* Top-level device.
|
51 |
-
*/
|
52 |
-
const MOBILE_GRADE_A = 'A';
|
53 |
-
|
54 |
-
/**
|
55 |
-
* Mid-level device.
|
56 |
-
*/
|
57 |
-
const MOBILE_GRADE_B = 'B';
|
58 |
-
|
59 |
-
/**
|
60 |
-
* Low-level device.
|
61 |
-
*/
|
62 |
-
const MOBILE_GRADE_C = 'C';
|
63 |
-
|
64 |
-
/**
|
65 |
-
* Stores the version number of the current release.
|
66 |
-
*/
|
67 |
-
const VERSION = '2.8.0';
|
68 |
-
|
69 |
-
/**
|
70 |
-
* A type for the version() method indicating a string return value.
|
71 |
-
*/
|
72 |
-
const VERSION_TYPE_STRING = 'text';
|
73 |
-
|
74 |
-
/**
|
75 |
-
* A type for the version() method indicating a float return value.
|
76 |
-
*/
|
77 |
-
const VERSION_TYPE_FLOAT = 'float';
|
78 |
-
|
79 |
-
/**
|
80 |
-
* The User-Agent HTTP header is stored in here.
|
81 |
-
* @var string
|
82 |
-
*/
|
83 |
-
protected $userAgent = null;
|
84 |
-
|
85 |
-
/**
|
86 |
-
* HTTP headers in the PHP-flavor. So HTTP_USER_AGENT and SERVER_SOFTWARE.
|
87 |
-
* @var array
|
88 |
-
*/
|
89 |
-
protected $httpHeaders = array();
|
90 |
-
|
91 |
-
/**
|
92 |
-
* The detection type, using self::DETECTION_TYPE_MOBILE or self::DETECTION_TYPE_EXTENDED.
|
93 |
-
*
|
94 |
-
* @deprecated since version 2.6.9
|
95 |
-
*
|
96 |
-
* @var string
|
97 |
-
*/
|
98 |
-
protected $detectionType = self::DETECTION_TYPE_MOBILE;
|
99 |
-
|
100 |
-
/**
|
101 |
-
* HTTP headers that trigger the 'isMobile' detection
|
102 |
-
* to be true.
|
103 |
-
*
|
104 |
-
* @var array
|
105 |
-
*/
|
106 |
-
protected static $mobileHeaders = array(
|
107 |
-
|
108 |
-
'HTTP_ACCEPT' => array('matches' => array(
|
109 |
-
// Opera Mini; @reference: http://dev.opera.com/articles/view/opera-binary-markup-language/
|
110 |
-
'application/x-obml2d',
|
111 |
-
// BlackBerry devices.
|
112 |
-
'application/vnd.rim.html',
|
113 |
-
'text/vnd.wap.wml',
|
114 |
-
'application/vnd.wap.xhtml+xml'
|
115 |
-
)),
|
116 |
-
'HTTP_X_WAP_PROFILE' => null,
|
117 |
-
'HTTP_X_WAP_CLIENTID' => null,
|
118 |
-
'HTTP_WAP_CONNECTION' => null,
|
119 |
-
'HTTP_PROFILE' => null,
|
120 |
-
// Reported by Opera on Nokia devices (eg. C3).
|
121 |
-
'HTTP_X_OPERAMINI_PHONE_UA' => null,
|
122 |
-
'HTTP_X_NOKIA_IPADDRESS' => null,
|
123 |
-
'HTTP_X_NOKIA_GATEWAY_ID' => null,
|
124 |
-
'HTTP_X_ORANGE_ID' => null,
|
125 |
-
'HTTP_X_VODAFONE_3GPDPCONTEXT' => null,
|
126 |
-
'HTTP_X_HUAWEI_USERID' => null,
|
127 |
-
// Reported by Windows Smartphones.
|
128 |
-
'HTTP_UA_OS' => null,
|
129 |
-
// Reported by Verizon, Vodafone proxy system.
|
130 |
-
'HTTP_X_MOBILE_GATEWAY' => null,
|
131 |
-
// Seend this on HTC Sensation. @ref: SensationXE_Beats_Z715e.
|
132 |
-
'HTTP_X_ATT_DEVICEID' => null,
|
133 |
-
// Seen this on a HTC.
|
134 |
-
'HTTP_UA_CPU' => array('matches' => array('ARM')),
|
135 |
-
);
|
136 |
-
|
137 |
-
/**
|
138 |
-
* List of mobile devices (phones).
|
139 |
-
*
|
140 |
-
* @var array
|
141 |
-
*/
|
142 |
-
protected static $phoneDevices = array(
|
143 |
-
'iPhone' => '\biPhone.*Mobile|\biPod', // |\biTunes
|
144 |
-
'BlackBerry' => 'BlackBerry|\bBB10\b|rim[0-9]+',
|
145 |
-
'HTC' => 'HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\bEVO\b|T-Mobile G1|Z520m',
|
146 |
-
'Nexus' => 'Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile',
|
147 |
-
// @todo: Is 'Dell Streak' a tablet or a phone? ;)
|
148 |
-
'Dell' => 'Dell.*Streak|Dell.*Aero|Dell.*Venue|DELL.*Venue Pro|Dell Flash|Dell Smoke|Dell Mini 3iX|XCD28|XCD35|\b001DL\b|\b101DL\b|\bGS01\b',
|
149 |
-
'Motorola' => 'Motorola|DROIDX|DROID BIONIC|\bDroid\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925',
|
150 |
-
'Samsung' => 'Samsung|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E',
|
151 |
-
'LG' => '\bLG\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802)',
|
152 |
-
'Sony' => 'SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i',
|
153 |
-
'Asus' => 'Asus.*Galaxy|PadFone.*Mobile',
|
154 |
-
// @ref: http://www.micromaxinfo.com/mobiles/smartphones
|
155 |
-
// Added because the codes might conflict with Acer Tablets.
|
156 |
-
'Micromax' => 'Micromax.*\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\b',
|
157 |
-
'Palm' => 'PalmSource|Palm', // avantgo|blazer|elaine|hiptop|plucker|xiino ; @todo - complete the regex.
|
158 |
-
'Vertu' => 'Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature', // Just for fun ;)
|
159 |
-
// @ref: http://www.pantech.co.kr/en/prod/prodList.do?gbrand=VEGA (PANTECH)
|
160 |
-
// Most of the VEGA devices are legacy. PANTECH seem to be newer devices based on Android.
|
161 |
-
'Pantech' => 'PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790',
|
162 |
-
// @ref: http://www.fly-phone.com/devices/smartphones/ ; Included only smartphones.
|
163 |
-
'Fly' => 'IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250',
|
164 |
-
'iMobile' => 'i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)',
|
165 |
-
// Added simvalley mobile just for fun. They have some interesting devices.
|
166 |
-
// @ref: http://www.simvalley.fr/telephonie---gps-_22_telephonie-mobile_telephones_.html
|
167 |
-
'SimValley' => '\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\b',
|
168 |
-
// @Tapatalk is a mobile app; @ref: http://support.tapatalk.com/threads/smf-2-0-2-os-and-browser-detection-plugin-and-tapatalk.15565/#post-79039
|
169 |
-
'GenericPhone' => 'Tapatalk|PDA;|SAGEM|\bmmp\b|pocket|\bpsp\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\bwap\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser'
|
170 |
-
);
|
171 |
-
|
172 |
-
/**
|
173 |
-
* List of tablet devices.
|
174 |
-
*
|
175 |
-
* @var array
|
176 |
-
*/
|
177 |
-
protected static $tabletDevices = array(
|
178 |
-
'iPad' => 'iPad|iPad.*Mobile', // @todo: check for mobile friendly emails topic.
|
179 |
-
'NexusTablet' => '^.*Android.*Nexus(((?:(?!Mobile))|(?:(\s(7|10).+))).)*$',
|
180 |
-
'SamsungTablet' => 'SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-I9205|GT-P5200|GT-P5210|SM-T311|SM-T310|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T520|SM-T525',
|
181 |
-
// @reference: http://www.labnol.org/software/kindle-user-agent-string/20378/
|
182 |
-
'Kindle' => 'Kindle|Silk.*Accelerated|Android.*\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE)\b',
|
183 |
-
// Only the Surface tablets with Windows RT are considered mobile.
|
184 |
-
// @ref: http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx
|
185 |
-
'SurfaceTablet' => 'Windows NT [0-9.]+; ARM;',
|
186 |
-
// @ref: http://shopping1.hp.com/is-bin/INTERSHOP.enfinity/WFS/WW-USSMBPublicStore-Site/en_US/-/USD/ViewStandardCatalog-Browse?CatalogCategoryID=JfIQ7EN5lqMAAAEyDcJUDwMT
|
187 |
-
'HPTablet' => 'HP Slate 7|HP ElitePad 900|hp-tablet|EliteBook.*Touch',
|
188 |
-
// @note: watch out for PadFone, see #132
|
189 |
-
'AsusTablet' => '^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\bK00F\b|TX201LA',
|
190 |
-
'BlackBerryTablet' => 'PlayBook|RIM Tablet',
|
191 |
-
'HTCtablet' => 'HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200',
|
192 |
-
'MotorolaTablet' => 'xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617',
|
193 |
-
'NookTablet' => 'Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2',
|
194 |
-
// @ref: http://www.acer.ro/ac/ro/RO/content/drivers
|
195 |
-
// @ref: http://www.packardbell.co.uk/pb/en/GB/content/download (Packard Bell is part of Acer)
|
196 |
-
// @ref: http://us.acer.com/ac/en/US/content/group/tablets
|
197 |
-
// @note: Can conflict with Micromax and Motorola phones codes.
|
198 |
-
'AcerTablet' => 'Android.*; \b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810)\b|W3-810|\bA3-A10\b',
|
199 |
-
// @ref: http://eu.computers.toshiba-europe.com/innovation/family/Tablets/1098744/banner_id/tablet_footerlink/
|
200 |
-
// @ref: http://us.toshiba.com/tablets/tablet-finder
|
201 |
-
// @ref: http://www.toshiba.co.jp/regza/tablet/
|
202 |
-
'ToshibaTablet' => 'Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO',
|
203 |
-
// @ref: http://www.nttdocomo.co.jp/english/service/developer/smart_phone/technical_info/spec/index.html
|
204 |
-
'LGTablet' => '\bL-06C|LG-V900|LG-V500|LG-V909\b',
|
205 |
-
'FujitsuTablet' => 'Android.*\b(F-01D|F-05E|F-10D|M532|Q572)\b',
|
206 |
-
// Prestigio Tablets http://www.prestigio.com/support
|
207 |
-
'PrestigioTablet' => 'PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD',
|
208 |
-
// @ref: http://support.lenovo.com/en_GB/downloads/default.page?#
|
209 |
-
'LenovoTablet' => 'IdeaTab|S2110|S6000|K3011|A3000|A1000|A2107|A2109|A1107|ThinkPad([ ]+)?Tablet',
|
210 |
-
// @ref: http://www.yarvik.com/en/matrix/tablets/
|
211 |
-
'YarvikTablet' => 'Android.*\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\b',
|
212 |
-
'MedionTablet' => 'Android.*\bOYO\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB',
|
213 |
-
'ArnovaTablet' => 'AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT',
|
214 |
-
// http://www.intenso.de/kategorie_en.php?kategorie=33
|
215 |
-
// @todo: http://www.nbhkdz.com/read/b8e64202f92a2df129126bff.html - investigate
|
216 |
-
'IntensoTablet' => 'INM8002KP|INM1010FP|INM805ND|Intenso Tab',
|
217 |
-
// IRU.ru Tablets http://www.iru.ru/catalog/soho/planetable/
|
218 |
-
'IRUTablet' => 'M702pro',
|
219 |
-
'MegafonTablet' => 'MegaFon V9|\bZTE V9\b|Android.*\bMT7A\b',
|
220 |
-
// @ref: http://www.e-boda.ro/tablete-pc.html
|
221 |
-
'EbodaTablet' => 'E-Boda (Supreme|Impresspeed|Izzycomm|Essential)',
|
222 |
-
// @ref: http://www.allview.ro/produse/droseries/lista-tablete-pc/
|
223 |
-
'AllViewTablet' => 'Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)',
|
224 |
-
// @reference: http://wiki.archosfans.com/index.php?title=Main_Page
|
225 |
-
'ArchosTablet' => '\b(101G9|80G9|A101IT)\b|Qilive 97R|ARCHOS 101G10',
|
226 |
-
// @ref: http://www.ainol.com/plugin.php?identifier=ainol&module=product
|
227 |
-
'AinolTablet' => 'NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark',
|
228 |
-
// @todo: inspect http://esupport.sony.com/US/p/select-system.pl?DIRECTOR=DRIVER
|
229 |
-
// @ref: Readers http://www.atsuhiro-me.net/ebook/sony-reader/sony-reader-web-browser
|
230 |
-
// @ref: http://www.sony.jp/support/tablet/
|
231 |
-
'SonyTablet' => 'Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201',
|
232 |
-
// @ref: db + http://www.cube-tablet.com/buy-products.html
|
233 |
-
'CubeTablet' => 'Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT',
|
234 |
-
// @ref: http://www.cobyusa.com/?p=pcat&pcat_id=3001
|
235 |
-
'CobyTablet' => 'MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010',
|
236 |
-
// @ref: http://www.match.net.cn/products.asp
|
237 |
-
'MIDTablet' => 'M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733',
|
238 |
-
// @ref: http://pdadb.net/index.php?m=pdalist&list=SMiT (NoName Chinese Tablets)
|
239 |
-
// @ref: http://www.imp3.net/14/show.php?itemid=20454
|
240 |
-
'SMiTTablet' => 'Android.*(\bMID\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)',
|
241 |
-
// @ref: http://www.rock-chips.com/index.php?do=prod&pid=2
|
242 |
-
'RockChipTablet' => 'Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A',
|
243 |
-
// @ref: http://www.fly-phone.com/devices/tablets/ ; http://www.fly-phone.com/service/
|
244 |
-
'FlyTablet' => 'IQ310|Fly Vision',
|
245 |
-
// @ref: http://www.bqreaders.com/gb/tablets-prices-sale.html
|
246 |
-
'bqTablet' => 'bq.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant)|Maxwell.*Lite|Maxwell.*Plus',
|
247 |
-
// @ref: http://www.huaweidevice.com/worldwide/productFamily.do?method=index&directoryId=5011&treeId=3290
|
248 |
-
// @ref: http://www.huaweidevice.com/worldwide/downloadCenter.do?method=index&directoryId=3372&treeId=0&tb=1&type=software (including legacy tablets)
|
249 |
-
'HuaweiTablet' => 'MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim',
|
250 |
-
// Nec or Medias Tab
|
251 |
-
'NecTablet' => '\bN-06D|\bN-08D',
|
252 |
-
// Pantech Tablets: http://www.pantechusa.com/phones/
|
253 |
-
'PantechTablet' => 'Pantech.*P4100',
|
254 |
-
// Broncho Tablets: http://www.broncho.cn/ (hard to find)
|
255 |
-
'BronchoTablet' => 'Broncho.*(N701|N708|N802|a710)',
|
256 |
-
// @ref: http://versusuk.com/support.html
|
257 |
-
'VersusTablet' => 'TOUCHPAD.*[78910]|\bTOUCHTAB\b',
|
258 |
-
// @ref: http://www.zync.in/index.php/our-products/tablet-phablets
|
259 |
-
'ZyncTablet' => 'z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900',
|
260 |
-
// @ref: http://www.positivoinformatica.com.br/www/pessoal/tablet-ypy/
|
261 |
-
'PositivoTablet' => 'TB07STA|TB10STA|TB07FTA|TB10FTA',
|
262 |
-
// @ref: https://www.nabitablet.com/
|
263 |
-
'NabiTablet' => 'Android.*\bNabi',
|
264 |
-
'KoboTablet' => 'Kobo Touch|\bK080\b|\bVox\b Build|\bArc\b Build',
|
265 |
-
// French Danew Tablets http://www.danew.com/produits-tablette.php
|
266 |
-
'DanewTablet' => 'DSlide.*\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\b',
|
267 |
-
// Texet Tablets and Readers http://www.texet.ru/tablet/
|
268 |
-
'TexetTablet' => 'NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE',
|
269 |
-
// @note: Avoid detecting 'PLAYSTATION 3' as mobile.
|
270 |
-
'PlaystationTablet' => 'Playstation.*(Portable|Vita)',
|
271 |
-
// @ref: http://www.trekstor.de/surftabs.html
|
272 |
-
'TrekstorTablet' => 'ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2',
|
273 |
-
// @ref: http://www.pyleaudio.com/Products.aspx?%2fproducts%2fPersonal-Electronics%2fTablets
|
274 |
-
'PyleAudioTablet' => '\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\b',
|
275 |
-
// @ref: http://www.advandigital.com/index.php?link=content-product&jns=JP001
|
276 |
-
// @Note: because of the short codenames we have to include whitespaces to reduce the possible conflicts.
|
277 |
-
'AdvanTablet' => 'Android.* \b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\b ',
|
278 |
-
// @ref: http://www.danytech.com/category/tablet-pc
|
279 |
-
'DanyTechTablet' => 'Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1',
|
280 |
-
// @ref: http://www.galapad.net/product.html
|
281 |
-
'GalapadTablet' => 'Android.*\bG1\b',
|
282 |
-
// @ref: http://www.micromaxinfo.com/tablet/funbook
|
283 |
-
'MicromaxTablet' => 'Funbook|Micromax.*\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\b',
|
284 |
-
// http://www.karbonnmobiles.com/products_tablet.php
|
285 |
-
'KarbonnTablet' => 'Android.*\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\b',
|
286 |
-
// @ref: http://www.myallfine.com/Products.asp
|
287 |
-
'AllFineTablet' => 'Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide',
|
288 |
-
// @ref: http://www.proscanvideo.com/products-search.asp?itemClass=TABLET&itemnmbr=
|
289 |
-
'PROSCANTablet' => '\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\b',
|
290 |
-
// @ref: http://www.yonesnav.com/products/products.php
|
291 |
-
'YONESTablet' => 'BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026',
|
292 |
-
// @ref: http://www.cjshowroom.com/eproducts.aspx?classcode=004001001
|
293 |
-
// China manufacturer makes tablets for different small brands (eg. http://www.zeepad.net/index.html)
|
294 |
-
'ChangJiaTablet' => 'TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503',
|
295 |
-
// @ref: http://www.gloryunion.cn/products.asp
|
296 |
-
// @ref: http://www.allwinnertech.com/en/apply/mobile.html
|
297 |
-
// @ref: http://www.ptcl.com.pk/pd_content.php?pd_id=284 (EVOTAB)
|
298 |
-
// @todo: Softwiner tablets?
|
299 |
-
// aka. Cute or Cool tablets. Not sure yet, must research to avoid collisions.
|
300 |
-
'GUTablet' => 'TX-A1301|TX-M9002|Q702|kf026', // A12R|D75A|D77|D79|R83|A95|A106C|R15|A75|A76|D71|D72|R71|R73|R77|D82|R85|D92|A97|D92|R91|A10F|A77F|W71F|A78F|W78F|W81F|A97F|W91F|W97F|R16G|C72|C73E|K72|K73|R96G
|
301 |
-
// @ref: http://www.pointofview-online.com/showroom.php?shop_mode=product_listing&category_id=118
|
302 |
-
'PointOfViewTablet' => 'TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10',
|
303 |
-
// @ref: http://www.overmax.pl/pl/katalog-produktow,p8/tablety,c14/
|
304 |
-
// @todo: add more tests.
|
305 |
-
'OvermaxTablet' => 'OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)',
|
306 |
-
// @ref: http://hclmetablet.com/India/index.php
|
307 |
-
'HCLTablet' => 'HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync',
|
308 |
-
// @ref: http://www.edigital.hu/Tablet_es_e-book_olvaso/Tablet-c18385.html
|
309 |
-
'DPSTablet' => 'DPS Dream 9|DPS Dual 7',
|
310 |
-
// @ref: http://www.visture.com/index.asp
|
311 |
-
'VistureTablet' => 'V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10',
|
312 |
-
// @ref: http://www.mijncresta.nl/tablet
|
313 |
-
'CrestaTablet' => 'CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989',
|
314 |
-
// MediaTek - http://www.mediatek.com/_en/01_products/02_proSys.php?cata_sn=1&cata1_sn=1&cata2_sn=309
|
315 |
-
'MediatekTablet' => '\bMT8125|MT8389|MT8135|MT8377\b',
|
316 |
-
// Concorde tab
|
317 |
-
'ConcordeTablet' => 'Concorde([ ]+)?Tab|ConCorde ReadMan',
|
318 |
-
// GoClever Tablets - http://www.goclever.com/uk/products,c1/tablet,c5/
|
319 |
-
'GoCleverTablet' => 'GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042',
|
320 |
-
// Modecom Tablets - http://www.modecom.eu/tablets/portal/
|
321 |
-
'ModecomTablet' => 'FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003',
|
322 |
-
// Vonino Tablets - http://www.vonino.eu/tablets
|
323 |
-
'VoninoTablet' => '\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\bQ8\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\b',
|
324 |
-
// ECS Tablets - http://www.ecs.com.tw/ECSWebSite/Product/Product_Tablet_List.aspx?CategoryID=14&MenuID=107&childid=M_107&LanID=0
|
325 |
-
'ECSTablet' => 'V07OT2|TM105A|S10OT1|TR10CS1',
|
326 |
-
// Storex Tablets - http://storex.fr/espace_client/support.html
|
327 |
-
// @note: no need to add all the tablet codes since they are guided by the first regex.
|
328 |
-
'StorexTablet' => 'eZee[_\']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab',
|
329 |
-
// Generic Vodafone tablets.
|
330 |
-
'VodafoneTablet' => 'SmartTab([ ]+)?[0-9]+|SmartTabII10',
|
331 |
-
// French tablets - Essentiel B http://www.boulanger.fr/tablette_tactile_e-book/tablette_tactile_essentiel_b/cl_68908.htm?multiChoiceToDelete=brand&mc_brand=essentielb
|
332 |
-
// Aka: http://www.essentielb.fr/
|
333 |
-
'EssentielBTablet' => 'Smart[ \']?TAB[ ]+?[0-9]+|Family[ \']?TAB2',
|
334 |
-
// Ross & Moor - http://ross-moor.ru/
|
335 |
-
'RossMoorTablet' => 'RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711',
|
336 |
-
// i-mobile http://product.i-mobilephone.com/Mobile_Device
|
337 |
-
'iMobileTablet' => 'i-mobile i-note',
|
338 |
-
// @ref: http://www.tolino.de/de/vergleichen/
|
339 |
-
'TolinoTablet' => 'tolino tab [0-9.]+|tolino shine',
|
340 |
-
// AudioSonic - a Kmart brand
|
341 |
-
// http://www.kmart.com.au/webapp/wcs/stores/servlet/Search?langId=-1&storeId=10701&catalogId=10001&categoryId=193001&pageSize=72¤tPage=1&searchCategory=193001%2b4294965664&sortBy=p_MaxPrice%7c1
|
342 |
-
'AudioSonicTablet' => '\bC-22Q|T7-QC|T-17B|T-17P\b',
|
343 |
-
// AMPE Tablets - http://www.ampe.com.my/product-category/tablets/
|
344 |
-
// @todo: add them gradually to avoid conflicts.
|
345 |
-
'AMPETablet' => 'Android.* A78 ',
|
346 |
-
// Skk Mobile - http://skkmobile.com.ph/product_tablets.php
|
347 |
-
'SkkTablet' => 'Android.* (SKYPAD|PHOENIX|CYCLOPS)',
|
348 |
-
// Tecno Mobile (only tablet) - http://www.tecno-mobile.com/index.php/product?filterby=smart&list_order=all&page=1
|
349 |
-
'TecnoTablet' => 'TECNO P9',
|
350 |
-
// JXD (consoles & tablets) - http://jxd.hk/products.asp?selectclassid=009008&clsid=3
|
351 |
-
'JXDTablet' => 'Android.*\b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\b',
|
352 |
-
// i-Joy tablets - http://www.i-joy.es/en/cat/products/tablets/
|
353 |
-
'iJoyTablet' => 'Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)',
|
354 |
-
// @ref: http://www.tesco.com/direct/hudl/
|
355 |
-
'Hudl' => 'Hudl HT7S3',
|
356 |
-
// @ref: http://www.telstra.com.au/home-phone/thub-2/
|
357 |
-
'TelstraTablet' => 'T-Hub2',
|
358 |
-
'GenericTablet' => 'Android.*\b97D\b|Tablet(?!.*PC)|ViewPad7|BNTV250A|MID-WCDMA|LogicPD Zoom2|\bA7EB\b|CatNova8|A1_07|CT704|CT1002|\bM721\b|rk30sdk|\bEVOTAB\b|M758A|ET904|ALUMIUM10|Smartfren Tab',
|
359 |
-
);
|
360 |
-
|
361 |
-
/**
|
362 |
-
* List of mobile Operating Systems.
|
363 |
-
*
|
364 |
-
* @var array
|
365 |
-
*/
|
366 |
-
protected static $operatingSystems = array(
|
367 |
-
'AndroidOS' => 'Android',
|
368 |
-
'BlackBerryOS' => 'blackberry|\bBB10\b|rim tablet os',
|
369 |
-
'PalmOS' => 'PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino',
|
370 |
-
'SymbianOS' => 'Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\bS60\b',
|
371 |
-
// @reference: http://en.wikipedia.org/wiki/Windows_Mobile
|
372 |
-
'WindowsMobileOS' => 'Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;',
|
373 |
-
// @reference: http://en.wikipedia.org/wiki/Windows_Phone
|
374 |
-
// http://wifeng.cn/?r=blog&a=view&id=106
|
375 |
-
// http://nicksnettravels.builttoroam.com/post/2011/01/10/Bogus-Windows-Phone-7-User-Agent-String.aspx
|
376 |
-
'WindowsPhoneOS' => 'Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7',
|
377 |
-
'iOS' => '\biPhone.*Mobile|\biPod|\biPad',
|
378 |
-
// http://en.wikipedia.org/wiki/MeeGo
|
379 |
-
// @todo: research MeeGo in UAs
|
380 |
-
'MeeGoOS' => 'MeeGo',
|
381 |
-
// http://en.wikipedia.org/wiki/Maemo
|
382 |
-
// @todo: research Maemo in UAs
|
383 |
-
'MaemoOS' => 'Maemo',
|
384 |
-
'JavaOS' => 'J2ME/|\bMIDP\b|\bCLDC\b', // '|Java/' produces bug #135
|
385 |
-
'webOS' => 'webOS|hpwOS',
|
386 |
-
'badaOS' => '\bBada\b',
|
387 |
-
'BREWOS' => 'BREW',
|
388 |
-
);
|
389 |
-
|
390 |
-
/**
|
391 |
-
* List of mobile User Agents.
|
392 |
-
*
|
393 |
-
* @var array
|
394 |
-
*/
|
395 |
-
protected static $browsers = array(
|
396 |
-
// @reference: https://developers.google.com/chrome/mobile/docs/user-agent
|
397 |
-
'Chrome' => '\bCrMo\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?',
|
398 |
-
'Dolfin' => '\bDolfin\b',
|
399 |
-
'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+|Coast/[0-9.]+',
|
400 |
-
'Skyfire' => 'Skyfire',
|
401 |
-
'IE' => 'IEMobile|MSIEMobile', // |Trident/[.0-9]+
|
402 |
-
'Firefox' => 'fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile',
|
403 |
-
'Bolt' => 'bolt',
|
404 |
-
'TeaShark' => 'teashark',
|
405 |
-
'Blazer' => 'Blazer',
|
406 |
-
// @reference: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/OptimizingforSafarioniPhone/OptimizingforSafarioniPhone.html#//apple_ref/doc/uid/TP40006517-SW3
|
407 |
-
'Safari' => 'Version.*Mobile.*Safari|Safari.*Mobile',
|
408 |
-
// @ref: http://en.wikipedia.org/wiki/Midori_(web_browser)
|
409 |
-
//'Midori' => 'midori',
|
410 |
-
'Tizen' => 'Tizen',
|
411 |
-
'UCBrowser' => 'UC.*Browser|UCWEB',
|
412 |
-
// @ref: https://github.com/serbanghita/Mobile-Detect/issues/7
|
413 |
-
'DiigoBrowser' => 'DiigoBrowser',
|
414 |
-
// http://www.puffinbrowser.com/index.php
|
415 |
-
'Puffin' => 'Puffin',
|
416 |
-
// @ref: http://mercury-browser.com/index.html
|
417 |
-
'Mercury' => '\bMercury\b',
|
418 |
-
// @reference: http://en.wikipedia.org/wiki/Minimo
|
419 |
-
// http://en.wikipedia.org/wiki/Vision_Mobile_Browser
|
420 |
-
'GenericBrowser' => 'NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger'
|
421 |
-
);
|
422 |
-
|
423 |
-
/**
|
424 |
-
* Utilities.
|
425 |
-
*
|
426 |
-
* @var array
|
427 |
-
*/
|
428 |
-
protected static $utilities = array(
|
429 |
-
// Experimental. When a mobile device wants to switch to 'Desktop Mode'.
|
430 |
-
// @ref: http://scottcate.com/technology/windows-phone-8-ie10-desktop-or-mobile/
|
431 |
-
// @ref: https://github.com/serbanghita/Mobile-Detect/issues/57#issuecomment-15024011
|
432 |
-
'DesktopMode' => 'WPDesktop',
|
433 |
-
'TV' => 'SonyDTV|HbbTV', // experimental
|
434 |
-
'WebKit' => '(webkit)[ /]([\w.]+)',
|
435 |
-
'Bot' => 'Googlebot|DoCoMo|YandexBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|facebookexternalhit',
|
436 |
-
'MobileBot' => 'Googlebot-Mobile|DoCoMo|YahooSeeker/M1A1-R2D2',
|
437 |
-
// @todo: Include JXD consoles.
|
438 |
-
'Console' => '\b(Nintendo|Nintendo WiiU|PLAYSTATION|Xbox)\b',
|
439 |
-
'Watch' => 'SM-V700',
|
440 |
-
);
|
441 |
-
|
442 |
-
/**
|
443 |
-
* All possible HTTP headers that represent the
|
444 |
-
* User-Agent string.
|
445 |
-
*
|
446 |
-
* @var array
|
447 |
-
*/
|
448 |
-
protected static $uaHttpHeaders = array(
|
449 |
-
// The default User-Agent string.
|
450 |
-
'HTTP_USER_AGENT',
|
451 |
-
// Header can occur on devices using Opera Mini.
|
452 |
-
'HTTP_X_OPERAMINI_PHONE_UA',
|
453 |
-
// Vodafone specific header: http://www.seoprinciple.com/mobile-web-community-still-angry-at-vodafone/24/
|
454 |
-
'HTTP_X_DEVICE_USER_AGENT',
|
455 |
-
'HTTP_X_ORIGINAL_USER_AGENT',
|
456 |
-
'HTTP_X_SKYFIRE_PHONE',
|
457 |
-
'HTTP_X_BOLT_PHONE_UA',
|
458 |
-
'HTTP_DEVICE_STOCK_UA',
|
459 |
-
'HTTP_X_UCBROWSER_DEVICE_UA'
|
460 |
-
);
|
461 |
-
|
462 |
-
/**
|
463 |
-
* The individual segments that could exist in a User-Agent string. VER refers to the regular
|
464 |
-
* expression defined in the constant self::VER.
|
465 |
-
*
|
466 |
-
* @var array
|
467 |
-
*/
|
468 |
-
protected static $properties = array(
|
469 |
-
|
470 |
-
// Build
|
471 |
-
'Mobile' => 'Mobile/[VER]',
|
472 |
-
'Build' => 'Build/[VER]',
|
473 |
-
'Version' => 'Version/[VER]',
|
474 |
-
'VendorID' => 'VendorID/[VER]',
|
475 |
-
|
476 |
-
// Devices
|
477 |
-
'iPad' => 'iPad.*CPU[a-z ]+[VER]',
|
478 |
-
'iPhone' => 'iPhone.*CPU[a-z ]+[VER]',
|
479 |
-
'iPod' => 'iPod.*CPU[a-z ]+[VER]',
|
480 |
-
//'BlackBerry' => array('BlackBerry[VER]', 'BlackBerry [VER];'),
|
481 |
-
'Kindle' => 'Kindle/[VER]',
|
482 |
-
|
483 |
-
// Browser
|
484 |
-
'Chrome' => array('Chrome/[VER]', 'CriOS/[VER]', 'CrMo/[VER]'),
|
485 |
-
'Coast' => array('Coast/[VER]'),
|
486 |
-
'Dolfin' => 'Dolfin/[VER]',
|
487 |
-
// @reference: https://developer.mozilla.org/en-US/docs/User_Agent_Strings_Reference
|
488 |
-
'Firefox' => 'Firefox/[VER]',
|
489 |
-
'Fennec' => 'Fennec/[VER]',
|
490 |
-
// @reference: http://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx
|
491 |
-
'IE' => array('IEMobile/[VER];', 'IEMobile [VER]', 'MSIE [VER];'),
|
492 |
-
// http://en.wikipedia.org/wiki/NetFront
|
493 |
-
'NetFront' => 'NetFront/[VER]',
|
494 |
-
'NokiaBrowser' => 'NokiaBrowser/[VER]',
|
495 |
-
'Opera' => array( ' OPR/[VER]', 'Opera Mini/[VER]', 'Version/[VER]' ),
|
496 |
-
'Opera Mini' => 'Opera Mini/[VER]',
|
497 |
-
'Opera Mobi' => 'Version/[VER]',
|
498 |
-
'UC Browser' => 'UC Browser[VER]',
|
499 |
-
'MQQBrowser' => 'MQQBrowser/[VER]',
|
500 |
-
'MicroMessenger' => 'MicroMessenger/[VER]',
|
501 |
-
// @note: Safari 7534.48.3 is actually Version 5.1.
|
502 |
-
// @note: On BlackBerry the Version is overwriten by the OS.
|
503 |
-
'Safari' => array( 'Version/[VER]', 'Safari/[VER]' ),
|
504 |
-
'Skyfire' => 'Skyfire/[VER]',
|
505 |
-
'Tizen' => 'Tizen/[VER]',
|
506 |
-
'Webkit' => 'webkit[ /][VER]',
|
507 |
-
|
508 |
-
// Engine
|
509 |
-
'Gecko' => 'Gecko/[VER]',
|
510 |
-
'Trident' => 'Trident/[VER]',
|
511 |
-
'Presto' => 'Presto/[VER]',
|
512 |
-
|
513 |
-
// OS
|
514 |
-
'iOS' => ' \bOS\b [VER] ',
|
515 |
-
'Android' => 'Android [VER]',
|
516 |
-
'BlackBerry' => array('BlackBerry[\w]+/[VER]', 'BlackBerry.*Version/[VER]', 'Version/[VER]'),
|
517 |
-
'BREW' => 'BREW [VER]',
|
518 |
-
'Java' => 'Java/[VER]',
|
519 |
-
// @reference: http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/08/29/introducing-the-ie9-on-windows-phone-mango-user-agent-string.aspx
|
520 |
-
// @reference: http://en.wikipedia.org/wiki/Windows_NT#Releases
|
521 |
-
'Windows Phone OS' => array( 'Windows Phone OS [VER]', 'Windows Phone [VER]'),
|
522 |
-
'Windows Phone' => 'Windows Phone [VER]',
|
523 |
-
'Windows CE' => 'Windows CE/[VER]',
|
524 |
-
// http://social.msdn.microsoft.com/Forums/en-US/windowsdeveloperpreviewgeneral/thread/6be392da-4d2f-41b4-8354-8dcee20c85cd
|
525 |
-
'Windows NT' => 'Windows NT [VER]',
|
526 |
-
'Symbian' => array('SymbianOS/[VER]', 'Symbian/[VER]'),
|
527 |
-
'webOS' => array('webOS/[VER]', 'hpwOS/[VER];'),
|
528 |
-
);
|
529 |
-
|
530 |
-
/**
|
531 |
-
* Construct an instance of this class.
|
532 |
-
*
|
533 |
-
* @param array $headers Specify the headers as injection. Should be PHP _SERVER flavored.
|
534 |
-
* If left empty, will use the global _SERVER['HTTP_*'] vars instead.
|
535 |
-
* @param string $userAgent Inject the User-Agent header. If null, will use HTTP_USER_AGENT
|
536 |
-
* from the $headers array instead.
|
537 |
-
*/
|
538 |
-
public function __construct(
|
539 |
-
array $headers = null,
|
540 |
-
$userAgent = null
|
541 |
-
){
|
542 |
-
$this->setHttpHeaders($headers);
|
543 |
-
$this->setUserAgent($userAgent);
|
544 |
-
}
|
545 |
-
|
546 |
-
/**
|
547 |
-
* Get the current script version.
|
548 |
-
* This is useful for the demo.php file,
|
549 |
-
* so people can check on what version they are testing
|
550 |
-
* for mobile devices.
|
551 |
-
*
|
552 |
-
* @return string The version number in semantic version format.
|
553 |
-
*/
|
554 |
-
public static function getScriptVersion()
|
555 |
-
{
|
556 |
-
return self::VERSION;
|
557 |
-
}
|
558 |
-
|
559 |
-
/**
|
560 |
-
* Set the HTTP Headers. Must be PHP-flavored. This method will reset existing headers.
|
561 |
-
*
|
562 |
-
* @param array $httpHeaders The headers to set. If null, then using PHP's _SERVER to extract
|
563 |
-
* the headers. The default null is left for backwards compatibilty.
|
564 |
-
*/
|
565 |
-
public function setHttpHeaders($httpHeaders = null)
|
566 |
-
{
|
567 |
-
//use global _SERVER if $httpHeaders aren't defined
|
568 |
-
if (!is_array($httpHeaders) || !count($httpHeaders)) {
|
569 |
-
$httpHeaders = $_SERVER;
|
570 |
-
}
|
571 |
-
|
572 |
-
//clear existing headers
|
573 |
-
$this->httpHeaders = array();
|
574 |
-
|
575 |
-
//Only save HTTP headers. In PHP land, that means only _SERVER vars that
|
576 |
-
//start with HTTP_.
|
577 |
-
foreach ($httpHeaders as $key => $value) {
|
578 |
-
if (substr($key,0,5) == 'HTTP_') {
|
579 |
-
$this->httpHeaders[$key] = $value;
|
580 |
-
}
|
581 |
-
}
|
582 |
-
}
|
583 |
-
|
584 |
-
/**
|
585 |
-
* Retrieves the HTTP headers.
|
586 |
-
*
|
587 |
-
* @return array
|
588 |
-
*/
|
589 |
-
public function getHttpHeaders()
|
590 |
-
{
|
591 |
-
return $this->httpHeaders;
|
592 |
-
}
|
593 |
-
|
594 |
-
/**
|
595 |
-
* Retrieves a particular header. If it doesn't exist, no exception/error is caused.
|
596 |
-
* Simply null is returned.
|
597 |
-
*
|
598 |
-
* @param string $header The name of the header to retrieve. Can be HTTP compliant such as
|
599 |
-
* "User-Agent" or "X-Device-User-Agent" or can be php-esque with the
|
600 |
-
* all-caps, HTTP_ prefixed, underscore seperated awesomeness.
|
601 |
-
*
|
602 |
-
* @return string|null The value of the header.
|
603 |
-
*/
|
604 |
-
public function getHttpHeader($header)
|
605 |
-
{
|
606 |
-
//are we using PHP-flavored headers?
|
607 |
-
if (strpos($header, '_') === false) {
|
608 |
-
$header = str_replace('-', '_', $header);
|
609 |
-
$header = strtoupper($header);
|
610 |
-
}
|
611 |
-
|
612 |
-
//test the alternate, too
|
613 |
-
$altHeader = 'HTTP_' . $header;
|
614 |
-
|
615 |
-
//Test both the regular and the HTTP_ prefix
|
616 |
-
if (isset($this->httpHeaders[$header])) {
|
617 |
-
return $this->httpHeaders[$header];
|
618 |
-
} elseif (isset($this->httpHeaders[$altHeader])) {
|
619 |
-
return $this->httpHeaders[$altHeader];
|
620 |
-
}
|
621 |
-
}
|
622 |
-
|
623 |
-
public function getMobileHeaders()
|
624 |
-
{
|
625 |
-
return self::$mobileHeaders;
|
626 |
-
}
|
627 |
-
|
628 |
-
/**
|
629 |
-
* Get all possible HTTP headers that
|
630 |
-
* can contain the User-Agent string.
|
631 |
-
*
|
632 |
-
* @return array List of HTTP headers.
|
633 |
-
*/
|
634 |
-
public function getUaHttpHeaders()
|
635 |
-
{
|
636 |
-
return self::$uaHttpHeaders;
|
637 |
-
}
|
638 |
-
|
639 |
-
/**
|
640 |
-
* Set the User-Agent to be used.
|
641 |
-
*
|
642 |
-
* @param string $userAgent The user agent string to set.
|
643 |
-
*/
|
644 |
-
public function setUserAgent($userAgent = null)
|
645 |
-
{
|
646 |
-
if (!empty($userAgent)) {
|
647 |
-
return $this->userAgent = $userAgent;
|
648 |
-
} else {
|
649 |
-
|
650 |
-
$this->userAgent = null;
|
651 |
-
|
652 |
-
foreach($this->getUaHttpHeaders() as $altHeader){
|
653 |
-
if(!empty($this->httpHeaders[$altHeader])){ // @todo: should use getHttpHeader(), but it would be slow. (Serban)
|
654 |
-
$this->userAgent .= $this->httpHeaders[$altHeader] . " ";
|
655 |
-
}
|
656 |
-
}
|
657 |
-
|
658 |
-
return $this->userAgent = (!empty($this->userAgent) ? trim($this->userAgent) : null);
|
659 |
-
|
660 |
-
}
|
661 |
-
}
|
662 |
-
|
663 |
-
/**
|
664 |
-
* Retrieve the User-Agent.
|
665 |
-
*
|
666 |
-
* @return string|null The user agent if it's set.
|
667 |
-
*/
|
668 |
-
public function getUserAgent()
|
669 |
-
{
|
670 |
-
return $this->userAgent;
|
671 |
-
}
|
672 |
-
|
673 |
-
/**
|
674 |
-
* Set the detection type. Must be one of self::DETECTION_TYPE_MOBILE or
|
675 |
-
* self::DETECTION_TYPE_EXTENDED. Otherwise, nothing is set.
|
676 |
-
*
|
677 |
-
* @deprecated since version 2.6.9
|
678 |
-
*
|
679 |
-
* @param string $type The type. Must be a self::DETECTION_TYPE_* constant. The default
|
680 |
-
* parameter is null which will default to self::DETECTION_TYPE_MOBILE.
|
681 |
-
*/
|
682 |
-
public function setDetectionType($type = null)
|
683 |
-
{
|
684 |
-
if ($type === null) {
|
685 |
-
$type = self::DETECTION_TYPE_MOBILE;
|
686 |
-
}
|
687 |
-
|
688 |
-
if ($type != self::DETECTION_TYPE_MOBILE && $type != self::DETECTION_TYPE_EXTENDED) {
|
689 |
-
return;
|
690 |
-
}
|
691 |
-
|
692 |
-
$this->detectionType = $type;
|
693 |
-
}
|
694 |
-
|
695 |
-
/**
|
696 |
-
* Retrieve the list of known phone devices.
|
697 |
-
*
|
698 |
-
* @return array List of phone devices.
|
699 |
-
*/
|
700 |
-
public static function getPhoneDevices()
|
701 |
-
{
|
702 |
-
return self::$phoneDevices;
|
703 |
-
}
|
704 |
-
|
705 |
-
/**
|
706 |
-
* Retrieve the list of known tablet devices.
|
707 |
-
*
|
708 |
-
* @return array List of tablet devices.
|
709 |
-
*/
|
710 |
-
public static function getTabletDevices()
|
711 |
-
{
|
712 |
-
return self::$tabletDevices;
|
713 |
-
}
|
714 |
-
|
715 |
-
/**
|
716 |
-
* Alias for getBrowsers() method.
|
717 |
-
*
|
718 |
-
* @return array List of user agents.
|
719 |
-
*/
|
720 |
-
public static function getUserAgents()
|
721 |
-
{
|
722 |
-
return self::getBrowsers();
|
723 |
-
}
|
724 |
-
|
725 |
-
/**
|
726 |
-
* Retrieve the list of known browsers. Specifically, the user agents.
|
727 |
-
*
|
728 |
-
* @return array List of browsers / user agents.
|
729 |
-
*/
|
730 |
-
public static function getBrowsers()
|
731 |
-
{
|
732 |
-
return self::$browsers;
|
733 |
-
}
|
734 |
-
|
735 |
-
/**
|
736 |
-
* Retrieve the list of known utilities.
|
737 |
-
*
|
738 |
-
* @return array List of utilities.
|
739 |
-
*/
|
740 |
-
public static function getUtilities()
|
741 |
-
{
|
742 |
-
return self::$utilities;
|
743 |
-
}
|
744 |
-
|
745 |
-
/**
|
746 |
-
* Method gets the mobile detection rules. This method is used for the magic methods $detect->is*().
|
747 |
-
*
|
748 |
-
* @deprecated since version 2.6.9
|
749 |
-
*
|
750 |
-
* @return array All the rules (but not extended).
|
751 |
-
*/
|
752 |
-
public static function getMobileDetectionRules()
|
753 |
-
{
|
754 |
-
static $rules;
|
755 |
-
|
756 |
-
if (!$rules) {
|
757 |
-
$rules = array_merge(
|
758 |
-
self::$phoneDevices,
|
759 |
-
self::$tabletDevices,
|
760 |
-
self::$operatingSystems,
|
761 |
-
self::$browsers
|
762 |
-
);
|
763 |
-
}
|
764 |
-
|
765 |
-
return $rules;
|
766 |
-
|
767 |
-
}
|
768 |
-
|
769 |
-
/**
|
770 |
-
* Method gets the mobile detection rules + utilities.
|
771 |
-
* The reason this is separate is because utilities rules
|
772 |
-
* don't necessary imply mobile. This method is used inside
|
773 |
-
* the new $detect->is('stuff') method.
|
774 |
-
*
|
775 |
-
* @deprecated since version 2.6.9
|
776 |
-
*
|
777 |
-
* @return array All the rules + extended.
|
778 |
-
*/
|
779 |
-
public function getMobileDetectionRulesExtended()
|
780 |
-
{
|
781 |
-
static $rules;
|
782 |
-
|
783 |
-
if (!$rules) {
|
784 |
-
// Merge all rules together.
|
785 |
-
$rules = array_merge(
|
786 |
-
self::$phoneDevices,
|
787 |
-
self::$tabletDevices,
|
788 |
-
self::$operatingSystems,
|
789 |
-
self::$browsers,
|
790 |
-
self::$utilities
|
791 |
-
);
|
792 |
-
}
|
793 |
-
|
794 |
-
return $rules;
|
795 |
-
}
|
796 |
-
|
797 |
-
/**
|
798 |
-
* Retrieve the current set of rules.
|
799 |
-
*
|
800 |
-
* @deprecated since version 2.6.9
|
801 |
-
*
|
802 |
-
* @return array
|
803 |
-
*/
|
804 |
-
public function getRules()
|
805 |
-
{
|
806 |
-
if ($this->detectionType == self::DETECTION_TYPE_EXTENDED) {
|
807 |
-
return self::getMobileDetectionRulesExtended();
|
808 |
-
} else {
|
809 |
-
return self::getMobileDetectionRules();
|
810 |
-
}
|
811 |
-
}
|
812 |
-
|
813 |
-
/**
|
814 |
-
* Retrieve the list of mobile operating systems.
|
815 |
-
*
|
816 |
-
* @return array The list of mobile operating systems.
|
817 |
-
*/
|
818 |
-
public static function getOperatingSystems()
|
819 |
-
{
|
820 |
-
return self::$operatingSystems;
|
821 |
-
}
|
822 |
-
|
823 |
-
/**
|
824 |
-
* Check the HTTP headers for signs of mobile.
|
825 |
-
* This is the fastest mobile check possible; it's used
|
826 |
-
* inside isMobile() method.
|
827 |
-
*
|
828 |
-
* @return bool
|
829 |
-
*/
|
830 |
-
public function checkHttpHeadersForMobile()
|
831 |
-
{
|
832 |
-
|
833 |
-
foreach($this->getMobileHeaders() as $mobileHeader => $matchType){
|
834 |
-
if( isset($this->httpHeaders[$mobileHeader]) ){
|
835 |
-
if( is_array($matchType['matches']) ){
|
836 |
-
foreach($matchType['matches'] as $_match){
|
837 |
-
if( strpos($this->httpHeaders[$mobileHeader], $_match) !== false ){
|
838 |
-
return true;
|
839 |
-
}
|
840 |
-
}
|
841 |
-
return false;
|
842 |
-
} else {
|
843 |
-
return true;
|
844 |
-
}
|
845 |
-
}
|
846 |
-
}
|
847 |
-
|
848 |
-
return false;
|
849 |
-
|
850 |
-
}
|
851 |
-
|
852 |
-
/**
|
853 |
-
* Magic overloading method.
|
854 |
-
*
|
855 |
-
* @method boolean is[...]()
|
856 |
-
* @param string $name
|
857 |
-
* @param array $arguments
|
858 |
-
* @return mixed
|
859 |
-
* @throws BadMethodCallException when the method doesn't exist and doesn't start with 'is'
|
860 |
-
*/
|
861 |
-
public function __call($name, $arguments)
|
862 |
-
{
|
863 |
-
//make sure the name starts with 'is', otherwise
|
864 |
-
if (substr($name, 0, 2) != 'is') {
|
865 |
-
throw new BadMethodCallException("No such method exists: $name");
|
866 |
-
}
|
867 |
-
|
868 |
-
$this->setDetectionType(self::DETECTION_TYPE_MOBILE);
|
869 |
-
|
870 |
-
$key = substr($name, 2);
|
871 |
-
|
872 |
-
return $this->matchUAAgainstKey($key);
|
873 |
-
}
|
874 |
-
|
875 |
-
/**
|
876 |
-
* Find a detection rule that matches the current User-agent.
|
877 |
-
*
|
878 |
-
* @param null $userAgent deprecated
|
879 |
-
* @return boolean
|
880 |
-
*/
|
881 |
-
protected function matchDetectionRulesAgainstUA($userAgent = null)
|
882 |
-
{
|
883 |
-
// Begin general search.
|
884 |
-
foreach ($this->getRules() as $_regex) {
|
885 |
-
if (empty($_regex)) {
|
886 |
-
continue;
|
887 |
-
}
|
888 |
-
if ($this->match($_regex, $userAgent)) {
|
889 |
-
return true;
|
890 |
-
}
|
891 |
-
}
|
892 |
-
|
893 |
-
return false;
|
894 |
-
}
|
895 |
-
|
896 |
-
/**
|
897 |
-
* Search for a certain key in the rules array.
|
898 |
-
* If the key is found the try to match the corresponding
|
899 |
-
* regex agains the User-Agent.
|
900 |
-
*
|
901 |
-
* @param string $key
|
902 |
-
* @param null $userAgent deprecated
|
903 |
-
* @return mixed
|
904 |
-
*/
|
905 |
-
protected function matchUAAgainstKey($key, $userAgent = null)
|
906 |
-
{
|
907 |
-
// Make the keys lowercase so we can match: isIphone(), isiPhone(), isiphone(), etc.
|
908 |
-
$key = strtolower($key);
|
909 |
-
|
910 |
-
//change the keys to lower case
|
911 |
-
$_rules = array_change_key_case($this->getRules());
|
912 |
-
|
913 |
-
if (array_key_exists($key, $_rules)) {
|
914 |
-
if (empty($_rules[$key])) {
|
915 |
-
return null;
|
916 |
-
}
|
917 |
-
|
918 |
-
return $this->match($_rules[$key], $userAgent);
|
919 |
-
}
|
920 |
-
|
921 |
-
return false;
|
922 |
-
}
|
923 |
-
|
924 |
-
/**
|
925 |
-
* Check if the device is mobile.
|
926 |
-
* Returns true if any type of mobile device detected, including special ones
|
927 |
-
* @param null $userAgent deprecated
|
928 |
-
* @param null $httpHeaders deprecated
|
929 |
-
* @return bool
|
930 |
-
*/
|
931 |
-
public function isMobile($userAgent = null, $httpHeaders = null)
|
932 |
-
{
|
933 |
-
|
934 |
-
if ($httpHeaders) {
|
935 |
-
$this->setHttpHeaders($httpHeaders);
|
936 |
-
}
|
937 |
-
|
938 |
-
if ($userAgent) {
|
939 |
-
$this->setUserAgent($userAgent);
|
940 |
-
}
|
941 |
-
|
942 |
-
$this->setDetectionType(self::DETECTION_TYPE_MOBILE);
|
943 |
-
|
944 |
-
if ($this->checkHttpHeadersForMobile()) {
|
945 |
-
return true;
|
946 |
-
} else {
|
947 |
-
return $this->matchDetectionRulesAgainstUA();
|
948 |
-
}
|
949 |
-
|
950 |
-
}
|
951 |
-
|
952 |
-
/**
|
953 |
-
* Check if the device is a tablet.
|
954 |
-
* Return true if any type of tablet device is detected.
|
955 |
-
*
|
956 |
-
* @param string $userAgent deprecated
|
957 |
-
* @param array $httpHeaders deprecated
|
958 |
-
* @return bool
|
959 |
-
*/
|
960 |
-
public function isTablet($userAgent = null, $httpHeaders = null)
|
961 |
-
{
|
962 |
-
$this->setDetectionType(self::DETECTION_TYPE_MOBILE);
|
963 |
-
|
964 |
-
foreach (self::$tabletDevices as $_regex) {
|
965 |
-
if ($this->match($_regex, $userAgent)) {
|
966 |
-
return true;
|
967 |
-
}
|
968 |
-
}
|
969 |
-
|
970 |
-
return false;
|
971 |
-
}
|
972 |
-
|
973 |
-
/**
|
974 |
-
* This method checks for a certain property in the
|
975 |
-
* userAgent.
|
976 |
-
* @todo: The httpHeaders part is not yet used.
|
977 |
-
*
|
978 |
-
* @param $key
|
979 |
-
* @param string $userAgent deprecated
|
980 |
-
* @param string $httpHeaders deprecated
|
981 |
-
* @return bool|int|null
|
982 |
-
*/
|
983 |
-
public function is($key, $userAgent = null, $httpHeaders = null)
|
984 |
-
{
|
985 |
-
// Set the UA and HTTP headers only if needed (eg. batch mode).
|
986 |
-
if ($httpHeaders) {
|
987 |
-
$this->setHttpHeaders($httpHeaders);
|
988 |
-
}
|
989 |
-
|
990 |
-
if ($userAgent) {
|
991 |
-
$this->setUserAgent($userAgent);
|
992 |
-
}
|
993 |
-
|
994 |
-
$this->setDetectionType(self::DETECTION_TYPE_EXTENDED);
|
995 |
-
|
996 |
-
return $this->matchUAAgainstKey($key);
|
997 |
-
}
|
998 |
-
|
999 |
-
/**
|
1000 |
-
* Some detection rules are relative (not standard),
|
1001 |
-
* because of the diversity of devices, vendors and
|
1002 |
-
* their conventions in representing the User-Agent or
|
1003 |
-
* the HTTP headers.
|
1004 |
-
*
|
1005 |
-
* This method will be used to check custom regexes against
|
1006 |
-
* the User-Agent string.
|
1007 |
-
*
|
1008 |
-
* @param $regex
|
1009 |
-
* @param string $userAgent
|
1010 |
-
* @return bool
|
1011 |
-
*
|
1012 |
-
* @todo: search in the HTTP headers too.
|
1013 |
-
*/
|
1014 |
-
public function match($regex, $userAgent = null)
|
1015 |
-
{
|
1016 |
-
// Escape the special character which is the delimiter.
|
1017 |
-
$regex = str_replace('/', '\/', $regex);
|
1018 |
-
|
1019 |
-
return (bool) preg_match('/'.$regex.'/is', (!empty($userAgent) ? $userAgent : $this->userAgent));
|
1020 |
-
}
|
1021 |
-
|
1022 |
-
/**
|
1023 |
-
* Get the properties array.
|
1024 |
-
*
|
1025 |
-
* @return array
|
1026 |
-
*/
|
1027 |
-
public static function getProperties()
|
1028 |
-
{
|
1029 |
-
return self::$properties;
|
1030 |
-
}
|
1031 |
-
|
1032 |
-
/**
|
1033 |
-
* Prepare the version number.
|
1034 |
-
*
|
1035 |
-
* @todo Remove the error supression from str_replace() call.
|
1036 |
-
*
|
1037 |
-
* @param string $ver The string version, like "2.6.21.2152";
|
1038 |
-
*
|
1039 |
-
* @return float
|
1040 |
-
*/
|
1041 |
-
public function prepareVersionNo($ver)
|
1042 |
-
{
|
1043 |
-
$ver = str_replace(array('_', ' ', '/'), '.', $ver);
|
1044 |
-
$arrVer = explode('.', $ver, 2);
|
1045 |
-
|
1046 |
-
if (isset($arrVer[1])) {
|
1047 |
-
$arrVer[1] = @str_replace('.', '', $arrVer[1]); // @todo: treat strings versions.
|
1048 |
-
}
|
1049 |
-
|
1050 |
-
return (float) implode('.', $arrVer);
|
1051 |
-
}
|
1052 |
-
|
1053 |
-
/**
|
1054 |
-
* Check the version of the given property in the User-Agent.
|
1055 |
-
* Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31)
|
1056 |
-
*
|
1057 |
-
* @param string $propertyName The name of the property. See self::getProperties() array
|
1058 |
-
* keys for all possible properties.
|
1059 |
-
* @param string $type Either self::VERSION_TYPE_STRING to get a string value or
|
1060 |
-
* self::VERSION_TYPE_FLOAT indicating a float value. This parameter
|
1061 |
-
* is optional and defaults to self::VERSION_TYPE_STRING. Passing an
|
1062 |
-
* invalid parameter will default to the this type as well.
|
1063 |
-
*
|
1064 |
-
* @return string|float The version of the property we are trying to extract.
|
1065 |
-
*/
|
1066 |
-
public function version($propertyName, $type = self::VERSION_TYPE_STRING)
|
1067 |
-
{
|
1068 |
-
if (empty($propertyName)) {
|
1069 |
-
return false;
|
1070 |
-
}
|
1071 |
-
|
1072 |
-
//set the $type to the default if we don't recognize the type
|
1073 |
-
if ($type != self::VERSION_TYPE_STRING && $type != self::VERSION_TYPE_FLOAT) {
|
1074 |
-
$type = self::VERSION_TYPE_STRING;
|
1075 |
-
}
|
1076 |
-
|
1077 |
-
$properties = self::getProperties();
|
1078 |
-
|
1079 |
-
// Check if the property exists in the properties array.
|
1080 |
-
if (array_key_exists($propertyName, $properties)) {
|
1081 |
-
|
1082 |
-
// Prepare the pattern to be matched.
|
1083 |
-
// Make sure we always deal with an array (string is converted).
|
1084 |
-
$properties[$propertyName] = (array) $properties[$propertyName];
|
1085 |
-
|
1086 |
-
foreach ($properties[$propertyName] as $propertyMatchString) {
|
1087 |
-
|
1088 |
-
$propertyPattern = str_replace('[VER]', self::VER, $propertyMatchString);
|
1089 |
-
|
1090 |
-
// Escape the special character which is the delimiter.
|
1091 |
-
$propertyPattern = str_replace('/', '\/', $propertyPattern);
|
1092 |
-
|
1093 |
-
// Identify and extract the version.
|
1094 |
-
preg_match('/'.$propertyPattern.'/is', $this->userAgent, $match);
|
1095 |
-
|
1096 |
-
if (!empty($match[1])) {
|
1097 |
-
$version = ( $type == self::VERSION_TYPE_FLOAT ? $this->prepareVersionNo($match[1]) : $match[1] );
|
1098 |
-
|
1099 |
-
return $version;
|
1100 |
-
}
|
1101 |
-
|
1102 |
-
}
|
1103 |
-
|
1104 |
-
}
|
1105 |
-
|
1106 |
-
return false;
|
1107 |
-
}
|
1108 |
-
|
1109 |
-
/**
|
1110 |
-
* Retrieve the mobile grading, using self::MOBILE_GRADE_* constants.
|
1111 |
-
*
|
1112 |
-
* @return string One of the self::MOBILE_GRADE_* constants.
|
1113 |
-
*/
|
1114 |
-
public function mobileGrade()
|
1115 |
-
{
|
1116 |
-
$isMobile = $this->isMobile();
|
1117 |
-
|
1118 |
-
if (
|
1119 |
-
// Apple iOS 3.2-5.1 - Tested on the original iPad (4.3 / 5.0), iPad 2 (4.3), iPad 3 (5.1), original iPhone (3.1), iPhone 3 (3.2), 3GS (4.3), 4 (4.3 / 5.0), and 4S (5.1)
|
1120 |
-
$this->version('iPad', self::VERSION_TYPE_FLOAT)>=4.3 ||
|
1121 |
-
$this->version('iPhone', self::VERSION_TYPE_FLOAT)>=3.1 ||
|
1122 |
-
$this->version('iPod', self::VERSION_TYPE_FLOAT)>=3.1 ||
|
1123 |
-
|
1124 |
-
// Android 2.1-2.3 - Tested on the HTC Incredible (2.2), original Droid (2.2), HTC Aria (2.1), Google Nexus S (2.3). Functional on 1.5 & 1.6 but performance may be sluggish, tested on Google G1 (1.5)
|
1125 |
-
// Android 3.1 (Honeycomb) - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM
|
1126 |
-
// Android 4.0 (ICS) - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices
|
1127 |
-
// Android 4.1 (Jelly Bean) - Tested on a Galaxy Nexus and Galaxy 7
|
1128 |
-
( $this->version('Android', self::VERSION_TYPE_FLOAT)>2.1 && $this->is('Webkit') ) ||
|
1129 |
-
|
1130 |
-
// Windows Phone 7-7.5 - Tested on the HTC Surround (7.0) HTC Trophy (7.5), LG-E900 (7.5), Nokia Lumia 800
|
1131 |
-
$this->version('Windows Phone OS', self::VERSION_TYPE_FLOAT)>=7.0 ||
|
1132 |
-
|
1133 |
-
// Blackberry 7 - Tested on BlackBerry® Torch 9810
|
1134 |
-
// Blackberry 6.0 - Tested on the Torch 9800 and Style 9670
|
1135 |
-
$this->is('BlackBerry') && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)>=6.0 ||
|
1136 |
-
// Blackberry Playbook (1.0-2.0) - Tested on PlayBook
|
1137 |
-
$this->match('Playbook.*Tablet') ||
|
1138 |
-
|
1139 |
-
// Palm WebOS (1.4-2.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0)
|
1140 |
-
( $this->version('webOS', self::VERSION_TYPE_FLOAT)>=1.4 && $this->match('Palm|Pre|Pixi') ) ||
|
1141 |
-
// Palm WebOS 3.0 - Tested on HP TouchPad
|
1142 |
-
$this->match('hp.*TouchPad') ||
|
1143 |
-
|
1144 |
-
// Firefox Mobile (12 Beta) - Tested on Android 2.3 device
|
1145 |
-
( $this->is('Firefox') && $this->version('Firefox', self::VERSION_TYPE_FLOAT)>=12 ) ||
|
1146 |
-
|
1147 |
-
// Chrome for Android - Tested on Android 4.0, 4.1 device
|
1148 |
-
( $this->is('Chrome') && $this->is('AndroidOS') && $this->version('Android', self::VERSION_TYPE_FLOAT)>=4.0 ) ||
|
1149 |
-
|
1150 |
-
// Skyfire 4.1 - Tested on Android 2.3 device
|
1151 |
-
( $this->is('Skyfire') && $this->version('Skyfire', self::VERSION_TYPE_FLOAT)>=4.1 && $this->is('AndroidOS') && $this->version('Android', self::VERSION_TYPE_FLOAT)>=2.3 ) ||
|
1152 |
-
|
1153 |
-
// Opera Mobile 11.5-12: Tested on Android 2.3
|
1154 |
-
( $this->is('Opera') && $this->version('Opera Mobi', self::VERSION_TYPE_FLOAT)>11 && $this->is('AndroidOS') ) ||
|
1155 |
-
|
1156 |
-
// Meego 1.2 - Tested on Nokia 950 and N9
|
1157 |
-
$this->is('MeeGoOS') ||
|
1158 |
-
|
1159 |
-
// Tizen (pre-release) - Tested on early hardware
|
1160 |
-
$this->is('Tizen') ||
|
1161 |
-
|
1162 |
-
// Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser
|
1163 |
-
// @todo: more tests here!
|
1164 |
-
$this->is('Dolfin') && $this->version('Bada', self::VERSION_TYPE_FLOAT)>=2.0 ||
|
1165 |
-
|
1166 |
-
// UC Browser - Tested on Android 2.3 device
|
1167 |
-
( ($this->is('UC Browser') || $this->is('Dolfin')) && $this->version('Android', self::VERSION_TYPE_FLOAT)>=2.3 ) ||
|
1168 |
-
|
1169 |
-
// Kindle 3 and Fire - Tested on the built-in WebKit browser for each
|
1170 |
-
( $this->match('Kindle Fire') ||
|
1171 |
-
$this->is('Kindle') && $this->version('Kindle', self::VERSION_TYPE_FLOAT)>=3.0 ) ||
|
1172 |
-
|
1173 |
-
// Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet
|
1174 |
-
$this->is('AndroidOS') && $this->is('NookTablet') ||
|
1175 |
-
|
1176 |
-
// Chrome Desktop 11-21 - Tested on OS X 10.7 and Windows 7
|
1177 |
-
$this->version('Chrome', self::VERSION_TYPE_FLOAT)>=11 && !$isMobile ||
|
1178 |
-
|
1179 |
-
// Safari Desktop 4-5 - Tested on OS X 10.7 and Windows 7
|
1180 |
-
$this->version('Safari', self::VERSION_TYPE_FLOAT)>=5.0 && !$isMobile ||
|
1181 |
-
|
1182 |
-
// Firefox Desktop 4-13 - Tested on OS X 10.7 and Windows 7
|
1183 |
-
$this->version('Firefox', self::VERSION_TYPE_FLOAT)>=4.0 && !$isMobile ||
|
1184 |
-
|
1185 |
-
// Internet Explorer 7-9 - Tested on Windows XP, Vista and 7
|
1186 |
-
$this->version('MSIE', self::VERSION_TYPE_FLOAT)>=7.0 && !$isMobile ||
|
1187 |
-
|
1188 |
-
// Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7
|
1189 |
-
// @reference: http://my.opera.com/community/openweb/idopera/
|
1190 |
-
$this->version('Opera', self::VERSION_TYPE_FLOAT)>=10 && !$isMobile
|
1191 |
-
|
1192 |
-
){
|
1193 |
-
return self::MOBILE_GRADE_A;
|
1194 |
-
}
|
1195 |
-
|
1196 |
-
if (
|
1197 |
-
$this->version('iPad', self::VERSION_TYPE_FLOAT)<4.3 ||
|
1198 |
-
$this->version('iPhone', self::VERSION_TYPE_FLOAT)<3.1 ||
|
1199 |
-
$this->version('iPod', self::VERSION_TYPE_FLOAT)<3.1 ||
|
1200 |
-
|
1201 |
-
// Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770
|
1202 |
-
$this->is('Blackberry') && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)>=5 && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)<6 ||
|
1203 |
-
|
1204 |
-
//Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3
|
1205 |
-
( $this->version('Opera Mini', self::VERSION_TYPE_FLOAT)>=5.0 && $this->version('Opera Mini', self::VERSION_TYPE_FLOAT)<=6.5 &&
|
1206 |
-
($this->version('Android', self::VERSION_TYPE_FLOAT)>=2.3 || $this->is('iOS')) ) ||
|
1207 |
-
|
1208 |
-
// Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1)
|
1209 |
-
$this->match('NokiaN8|NokiaC7|N97.*Series60|Symbian/3') ||
|
1210 |
-
|
1211 |
-
// @todo: report this (tested on Nokia N71)
|
1212 |
-
$this->version('Opera Mobi', self::VERSION_TYPE_FLOAT)>=11 && $this->is('SymbianOS')
|
1213 |
-
){
|
1214 |
-
return self::MOBILE_GRADE_B;
|
1215 |
-
}
|
1216 |
-
|
1217 |
-
if (
|
1218 |
-
// Blackberry 4.x - Tested on the Curve 8330
|
1219 |
-
$this->version('BlackBerry', self::VERSION_TYPE_FLOAT)<5.0 ||
|
1220 |
-
// Windows Mobile - Tested on the HTC Leo (WinMo 5.2)
|
1221 |
-
$this->match('MSIEMobile|Windows CE.*Mobile') || $this->version('Windows Mobile', self::VERSION_TYPE_FLOAT)<=5.2
|
1222 |
-
|
1223 |
-
){
|
1224 |
-
return self::MOBILE_GRADE_C;
|
1225 |
-
}
|
1226 |
-
|
1227 |
-
//All older smartphone platforms and featurephones - Any device that doesn't support media queries
|
1228 |
-
//will receive the basic, C grade experience.
|
1229 |
-
return self::MOBILE_GRADE_C;
|
1230 |
-
}
|
1231 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
js/lazysizes.min.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
-
/*! lazysizes -
|
2 |
-
!function(a,b){var c=b(a,a.document);a.lazySizes=c,"object"==typeof module&&module.exports&&(module.exports=c)}(window,function(a,b){"use strict";if(b.getElementsByClassName){var c,d=b.documentElement,e=a.Date,f=a.HTMLPictureElement,g="addEventListener",h="getAttribute",i=a[g],j=a.setTimeout,k=a.requestAnimationFrame||j,l=a.requestIdleCallback,m=/^picture$/i,n=["load","error","lazyincluded","_lazyloaded"],o={},p=Array.prototype.forEach,q=function(a,b){return o[b]||(o[b]=new RegExp("(\\s|^)"+b+"(\\s|$)")),o[b].test(a[h]("class")||"")&&o[b]},r=function(a,b){q(a,b)||a.setAttribute("class",(a[h]("class")||"").trim()+" "+b)},s=function(a,b){var c;(c=q(a,b))&&a.setAttribute("class",(a[h]("class")||"").replace(c," "))},t=function(a,b,c){var d=c?g:"removeEventListener";c&&t(a,b),n.forEach(function(c){a[d](c,b)})},u=function(a,c,d,e,f){var g=b.createEvent("CustomEvent");return g.initCustomEvent(c,!e,!f,d||{}),a.dispatchEvent(g),g},v=function(b,d){var e;!f&&(e=a.picturefill||c.pf)?e({reevaluate:!0,elements:[b]}):d&&d.src&&(b.src=d.src)},w=function(a,b){return(getComputedStyle(a,null)||{})[b]},x=function(a,b,d){for(d=d||a.offsetWidth;d<c.minSize&&b&&!a._lazysizesWidth;)d=b.offsetWidth,b=b.parentNode;return d},y=function(){var a,c,d=[],e=function(){var b;for(a=!0,c=!1;
|
1 |
+
/*! lazysizes - v3.0.0 */
|
2 |
+
!function(a,b){var c=b(a,a.document);a.lazySizes=c,"object"==typeof module&&module.exports&&(module.exports=c)}(window,function(a,b){"use strict";if(b.getElementsByClassName){var c,d=b.documentElement,e=a.Date,f=a.HTMLPictureElement,g="addEventListener",h="getAttribute",i=a[g],j=a.setTimeout,k=a.requestAnimationFrame||j,l=a.requestIdleCallback,m=/^picture$/i,n=["load","error","lazyincluded","_lazyloaded"],o={},p=Array.prototype.forEach,q=function(a,b){return o[b]||(o[b]=new RegExp("(\\s|^)"+b+"(\\s|$)")),o[b].test(a[h]("class")||"")&&o[b]},r=function(a,b){q(a,b)||a.setAttribute("class",(a[h]("class")||"").trim()+" "+b)},s=function(a,b){var c;(c=q(a,b))&&a.setAttribute("class",(a[h]("class")||"").replace(c," "))},t=function(a,b,c){var d=c?g:"removeEventListener";c&&t(a,b),n.forEach(function(c){a[d](c,b)})},u=function(a,c,d,e,f){var g=b.createEvent("CustomEvent");return g.initCustomEvent(c,!e,!f,d||{}),a.dispatchEvent(g),g},v=function(b,d){var e;!f&&(e=a.picturefill||c.pf)?e({reevaluate:!0,elements:[b]}):d&&d.src&&(b.src=d.src)},w=function(a,b){return(getComputedStyle(a,null)||{})[b]},x=function(a,b,d){for(d=d||a.offsetWidth;d<c.minSize&&b&&!a._lazysizesWidth;)d=b.offsetWidth,b=b.parentNode;return d},y=function(){var a,c,d=[],e=[],f=d,g=function(){var b=f;for(f=d.length?e:d,a=!0,c=!1;b.length;)b.shift()();a=!1},h=function(d,e){a&&!e?d.apply(this,arguments):(f.push(d),c||(c=!0,(b.hidden?j:k)(g)))};return h._lsFlush=g,h}(),z=function(a,b){return b?function(){y(a)}:function(){var b=this,c=arguments;y(function(){a.apply(b,c)})}},A=function(a){var b,c=0,d=125,f=666,g=f,h=function(){b=!1,c=e.now(),a()},i=l?function(){l(h,{timeout:g}),g!==f&&(g=f)}:z(function(){j(h)},!0);return function(a){var f;(a=a===!0)&&(g=44),b||(b=!0,f=d-(e.now()-c),0>f&&(f=0),a||9>f&&l?i():j(i,f))}},B=function(a){var b,c,d=99,f=function(){b=null,a()},g=function(){var a=e.now()-c;d>a?j(g,d-a):(l||f)(f)};return function(){c=e.now(),b||(b=j(g,d))}},C=function(){var f,k,l,n,o,x,C,E,F,G,H,I,J,K,L,M=/^img$/i,N=/^iframe$/i,O="onscroll"in a&&!/glebot/.test(navigator.userAgent),P=0,Q=0,R=0,S=-1,T=function(a){R--,a&&a.target&&t(a.target,T),(!a||0>R||!a.target)&&(R=0)},U=function(a,c){var e,f=a,g="hidden"==w(b.body,"visibility")||"hidden"!=w(a,"visibility");for(F-=c,I+=c,G-=c,H+=c;g&&(f=f.offsetParent)&&f!=b.body&&f!=d;)g=(w(f,"opacity")||1)>0,g&&"visible"!=w(f,"overflow")&&(e=f.getBoundingClientRect(),g=H>e.left&&G<e.right&&I>e.top-1&&F<e.bottom+1);return g},V=function(){var a,e,g,i,j,m,n,p,q;if((o=c.loadMode)&&8>R&&(a=f.length)){e=0,S++,null==K&&("expand"in c||(c.expand=d.clientHeight>500&&d.clientWidth>500?500:370),J=c.expand,K=J*c.expFactor),K>Q&&1>R&&S>2&&o>2&&!b.hidden?(Q=K,S=0):Q=o>1&&S>1&&6>R?J:P;for(;a>e;e++)if(f[e]&&!f[e]._lazyRace)if(O)if((p=f[e][h]("data-expand"))&&(m=1*p)||(m=Q),q!==m&&(C=innerWidth+m*L,E=innerHeight+m,n=-1*m,q=m),g=f[e].getBoundingClientRect(),(I=g.bottom)>=n&&(F=g.top)<=E&&(H=g.right)>=n*L&&(G=g.left)<=C&&(I||H||G||F)&&(l&&3>R&&!p&&(3>o||4>S)||U(f[e],m))){if(ba(f[e]),j=!0,R>9)break}else!j&&l&&!i&&4>R&&4>S&&o>2&&(k[0]||c.preloadAfterLoad)&&(k[0]||!p&&(I||H||G||F||"auto"!=f[e][h](c.sizesAttr)))&&(i=k[0]||f[e]);else ba(f[e]);i&&!j&&ba(i)}},W=A(V),X=function(a){r(a.target,c.loadedClass),s(a.target,c.loadingClass),t(a.target,Z)},Y=z(X),Z=function(a){Y({target:a.target})},$=function(a,b){try{a.contentWindow.location.replace(b)}catch(c){a.src=b}},_=function(a){var b,d,e=a[h](c.srcsetAttr);(b=c.customMedia[a[h]("data-media")||a[h]("media")])&&a.setAttribute("media",b),e&&a.setAttribute("srcset",e),b&&(d=a.parentNode,d.insertBefore(a.cloneNode(),a),d.removeChild(a))},aa=z(function(a,b,d,e,f){var g,i,k,l,o,q;(o=u(a,"lazybeforeunveil",b)).defaultPrevented||(e&&(d?r(a,c.autosizesClass):a.setAttribute("sizes",e)),i=a[h](c.srcsetAttr),g=a[h](c.srcAttr),f&&(k=a.parentNode,l=k&&m.test(k.nodeName||"")),q=b.firesLoad||"src"in a&&(i||g||l),o={target:a},q&&(t(a,T,!0),clearTimeout(n),n=j(T,2500),r(a,c.loadingClass),t(a,Z,!0)),l&&p.call(k.getElementsByTagName("source"),_),i?a.setAttribute("srcset",i):g&&!l&&(N.test(a.nodeName)?$(a,g):a.src=g),(i||l)&&v(a,{src:g})),a._lazyRace&&delete a._lazyRace,s(a,c.lazyClass),y(function(){(!q||a.complete&&a.naturalWidth>1)&&(q?T(o):R--,X(o))},!0)}),ba=function(a){var b,d=M.test(a.nodeName),e=d&&(a[h](c.sizesAttr)||a[h]("sizes")),f="auto"==e;(!f&&l||!d||!a.src&&!a.srcset||a.complete||q(a,c.errorClass))&&(b=u(a,"lazyunveilread").detail,f&&D.updateElem(a,!0,a.offsetWidth),a._lazyRace=!0,R++,aa(a,b,f,e,d))},ca=function(){if(!l){if(e.now()-x<999)return void j(ca,999);var a=B(function(){c.loadMode=3,W()});l=!0,c.loadMode=3,W(),i("scroll",function(){3==c.loadMode&&(c.loadMode=2),a()},!0)}};return{_:function(){x=e.now(),f=b.getElementsByClassName(c.lazyClass),k=b.getElementsByClassName(c.lazyClass+" "+c.preloadClass),L=c.hFac,i("scroll",W,!0),i("resize",W,!0),a.MutationObserver?new MutationObserver(W).observe(d,{childList:!0,subtree:!0,attributes:!0}):(d[g]("DOMNodeInserted",W,!0),d[g]("DOMAttrModified",W,!0),setInterval(W,999)),i("hashchange",W,!0),["focus","mouseover","click","load","transitionend","animationend","webkitAnimationEnd"].forEach(function(a){b[g](a,W,!0)}),/d$|^c/.test(b.readyState)?ca():(i("load",ca),b[g]("DOMContentLoaded",W),j(ca,2e4)),f.length?(V(),y._lsFlush()):W()},checkElems:W,unveil:ba}}(),D=function(){var a,d=z(function(a,b,c,d){var e,f,g;if(a._lazysizesWidth=d,d+="px",a.setAttribute("sizes",d),m.test(b.nodeName||""))for(e=b.getElementsByTagName("source"),f=0,g=e.length;g>f;f++)e[f].setAttribute("sizes",d);c.detail.dataAttr||v(a,c.detail)}),e=function(a,b,c){var e,f=a.parentNode;f&&(c=x(a,f,c),e=u(a,"lazybeforesizes",{width:c,dataAttr:!!b}),e.defaultPrevented||(c=e.detail.width,c&&c!==a._lazysizesWidth&&d(a,f,e,c)))},f=function(){var b,c=a.length;if(c)for(b=0;c>b;b++)e(a[b])},g=B(f);return{_:function(){a=b.getElementsByClassName(c.autosizesClass),i("resize",g)},checkElems:g,updateElem:e}}(),E=function(){E.i||(E.i=!0,D._(),C._())};return function(){var b,d={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",autosizesClass:"lazyautosizes",srcAttr:"data-src",srcsetAttr:"data-srcset",sizesAttr:"data-sizes",minSize:40,customMedia:{},init:!0,expFactor:1.5,hFac:.8,loadMode:2};c=a.lazySizesConfig||a.lazysizesConfig||{};for(b in d)b in c||(c[b]=d[b]);a.lazySizesConfig=c,j(function(){c.init&&E()})}(),{cfg:c,autoSizer:D,loader:C,init:E,uP:v,aC:r,rC:s,hC:q,fire:u,gW:x,rAF:y}}});
|
img/loading.gif → loading.gif
RENAMED
File without changes
|
media-library.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Meow_WR2X_MediaLibrary {
|
4 |
+
|
5 |
+
public $core = null;
|
6 |
+
|
7 |
+
public function __construct( $core ) {
|
8 |
+
$this->core = $core;
|
9 |
+
add_filter( 'manage_media_columns', array( $this, 'manage_media_columns' ) );
|
10 |
+
add_action( 'manage_media_custom_column', array( $this, 'manage_media_custom_column' ), 10, 2 );
|
11 |
+
add_action( 'admin_footer', array( $this, 'admin_footer_library' ) );
|
12 |
+
}
|
13 |
+
|
14 |
+
function manage_media_columns( $cols ) {
|
15 |
+
$cols["Retina"] = "Retina";
|
16 |
+
return $cols;
|
17 |
+
}
|
18 |
+
|
19 |
+
function manage_media_custom_column( $column_name, $id ) {
|
20 |
+
if ( $column_name == 'Retina' ) {
|
21 |
+
$info = $this->core->retina_info( $id );
|
22 |
+
if ( empty( $info ) )
|
23 |
+
return;
|
24 |
+
$info = $this->core->html_get_basic_retina_info( $id, $info );
|
25 |
+
echo "<a style='' onclick='wr2x_generate(" . $id . ", true)' id='wr2x_generate_button_" .
|
26 |
+
$id . "' class='wr2x-button'>" . __( "GENERATE", 'wp-retina-2x' ) . "</a><br />";
|
27 |
+
echo '<div class="wr2x-info" postid="' . $id . '" id="wr2x-info-' . $id . '">';
|
28 |
+
echo $info;
|
29 |
+
echo '</div>';
|
30 |
+
}
|
31 |
+
else if ( $column_name == 'Retina-Actions' ) {
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
function admin_footer_library() {
|
36 |
+
$screen = get_current_screen();
|
37 |
+
if ( $screen->base != 'upload' && $screen->base != 'media_page_wp-retina-2x' )
|
38 |
+
return;
|
39 |
+
?>
|
40 |
+
<div id="meow-modal-info-backdrop" style="display: none;">
|
41 |
+
</div>
|
42 |
+
|
43 |
+
<div id="meow-modal-info" style="display: none;" tabindex="1">
|
44 |
+
<div class="close">X</div>
|
45 |
+
<h2 style="margin-top: 0px;">Retina Details</h2>
|
46 |
+
<div class="loading">
|
47 |
+
<img src="<?php echo plugin_dir_url( __FILE__ ); ?>loading.gif" />
|
48 |
+
</div>
|
49 |
+
<div class="content">
|
50 |
+
</div>
|
51 |
+
</div>
|
52 |
+
<?php
|
53 |
+
}
|
54 |
+
|
55 |
+
}
|
56 |
+
|
57 |
+
|
58 |
+
?>
|
readme.txt
CHANGED
@@ -2,8 +2,8 @@
|
|
2 |
Contributors: TigrouMeow
|
3 |
Tags: retina, images, image, responsive, lazysizes, lazy, attachment, media, files, iphone, ipad, high-dpi
|
4 |
Requires at least: 3.5
|
5 |
-
Tested up to: 4.7
|
6 |
-
Stable tag:
|
7 |
|
8 |
Make your website look beautiful and crisp on modern displays by creating and displaying retina images. WP 4.4+ is also supported and enhanced.
|
9 |
|
@@ -33,9 +33,16 @@ More information and tutorial available one http://meowapps.com/wp-retina-2x/.
|
|
33 |
|
34 |
== Changelog ==
|
35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
= 4.8.0 =
|
37 |
* Add: Retina Image Quality for JPG (between 0 and 100). I know this little setting was really wanted :)
|
38 |
* Fix: Disabled sizes weren't really disabled in the UI.
|
|
|
39 |
* Add: Handles incompatibility with JetPack's Photon.
|
40 |
* Info: If you are using Lightroom, please have a look at my plugin for synchronizing your Lightroom to WordPress: http://meowapps.com/wplr-sync/. And if youi love my Retina plugin, please write a little review here: https://wordpress.org/support/plugin/wp-retina-2x/reviews/?rate=5#new-post. Thank you :)
|
41 |
|
2 |
Contributors: TigrouMeow
|
3 |
Tags: retina, images, image, responsive, lazysizes, lazy, attachment, media, files, iphone, ipad, high-dpi
|
4 |
Requires at least: 3.5
|
5 |
+
Tested up to: 4.7
|
6 |
+
Stable tag: 5.0.2
|
7 |
|
8 |
Make your website look beautiful and crisp on modern displays by creating and displaying retina images. WP 4.4+ is also supported and enhanced.
|
9 |
|
33 |
|
34 |
== Changelog ==
|
35 |
|
36 |
+
= 5.0.2 =
|
37 |
+
* Fix: There was a issue with the .htaccess rewriting (Class ‘Meow_Admin’ not found).
|
38 |
+
* Update: Core was totally re-organized and cleaned. Ready for nice updates.
|
39 |
+
* Update: LazyLoading from version 2.0 to 3.0.
|
40 |
+
* Info: There will be an important warning showing up during this update. It is an important annoucement.
|
41 |
+
|
42 |
= 4.8.0 =
|
43 |
* Add: Retina Image Quality for JPG (between 0 and 100). I know this little setting was really wanted :)
|
44 |
* Fix: Disabled sizes weren't really disabled in the UI.
|
45 |
+
* Fix: Notices about Ignore appearing in other screens.
|
46 |
* Add: Handles incompatibility with JetPack's Photon.
|
47 |
* Info: If you are using Lightroom, please have a look at my plugin for synchronizing your Lightroom to WordPress: http://meowapps.com/wplr-sync/. And if youi love my Retina plugin, please write a little review here: https://wordpress.org/support/plugin/wp-retina-2x/reviews/?rate=5#new-post. Thank you :)
|
48 |
|
screenshot-1.png
DELETED
Binary file
|
screenshot-2.png
DELETED
Binary file
|
screenshot-3.png
DELETED
Binary file
|
screenshot.png
DELETED
Binary file
|
wp-retina-2x.php
CHANGED
@@ -2,8 +2,8 @@
|
|
2 |
/*
|
3 |
Plugin Name: WP Retina 2x
|
4 |
Plugin URI: http://meowapps.com
|
5 |
-
Description: Make your website look beautiful and crisp on modern displays by creating + displaying retina images.
|
6 |
-
Version:
|
7 |
Author: Jordy Meow
|
8 |
Author URI: http://meowapps.com
|
9 |
Text Domain: wp-retina-2x
|
@@ -18,1142 +18,22 @@ Originally developed for two of my websites:
|
|
18 |
- Haikyo (http://www.haikyo.org)
|
19 |
*/
|
20 |
|
21 |
-
|
22 |
-
|
23 |
-
* @author Jordy Meow <http://meowapps.com>
|
24 |
-
* @package Wordpress
|
25 |
-
* @subpackage Administration
|
26 |
-
*
|
27 |
-
*/
|
28 |
|
29 |
-
$wr2x_version = '
|
30 |
$wr2x_retinajs = '2.0.0';
|
31 |
$wr2x_picturefill = '3.0.2';
|
32 |
-
$wr2x_lazysizes = '
|
33 |
$wr2x_retina_image = '1.7.2';
|
34 |
-
$wr2x_extra_debug = false;
|
35 |
|
36 |
-
//
|
37 |
-
add_action( 'wp_enqueue_scripts', 'wr2x_wp_enqueue_scripts' );
|
38 |
-
add_action( 'admin_enqueue_scripts', 'wr2x_wp_enqueue_scripts' );
|
39 |
-
add_filter( 'wp_generate_attachment_metadata', 'wr2x_wp_generate_attachment_metadata' );
|
40 |
-
add_action( 'delete_attachment', 'wr2x_delete_attachment' );
|
41 |
-
add_filter( 'generate_rewrite_rules', array( 'WR2X_Admin', 'generate_rewrite_rules' ) );
|
42 |
-
add_filter( 'wr2x_validate_src', 'wr2x_validate_src' );
|
43 |
-
add_action( 'init', 'wr2x_init' );
|
44 |
-
|
45 |
-
register_deactivation_hook( __FILE__, 'wr2x_deactivate' );
|
46 |
-
register_activation_hook( __FILE__, 'wr2x_activate' );
|
47 |
-
|
48 |
-
global $wr2x_admin;
|
49 |
require( 'wr2x_admin.php');
|
50 |
-
$wr2x_admin = new
|
51 |
-
|
52 |
-
if ( is_admin() ) {
|
53 |
-
require( 'wr2x_ajax.php' );
|
54 |
-
if ( !get_option( "wr2x_hide_retina_dashboard" ) )
|
55 |
-
require( 'wr2x_retina-dashboard.php' );
|
56 |
-
if ( !get_option( "wr2x_hide_retina_column" ) )
|
57 |
-
require( 'wr2x_media-library.php' );
|
58 |
-
}
|
59 |
-
|
60 |
-
require( 'wr2x_responsive.php' );
|
61 |
-
|
62 |
-
// if ( get_option( "ignore_mobile" ) && !class_exists( 'Mobile_Detect' ) )
|
63 |
-
// require( 'inc/Mobile_Detect.php');
|
64 |
-
|
65 |
-
//if ( !get_option( "wr2x_hide_retina_column" ) )
|
66 |
-
//require( 'wr2x_retina_uploader.php' );
|
67 |
-
|
68 |
-
function wr2x_init() {
|
69 |
-
load_plugin_textdomain( 'wp-retina-2x', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
|
70 |
-
|
71 |
-
if ( get_option( 'wr2x_disable_medium_large' ) ) {
|
72 |
-
remove_image_size( 'medium_large' );
|
73 |
-
add_filter( 'image_size_names_choose', 'wr2x_unset_medium_large' );
|
74 |
-
add_filter( 'intermediate_image_sizes_advanced', 'wr2x_unset_medium_large' );
|
75 |
-
}
|
76 |
-
|
77 |
-
if ( is_admin() ) {
|
78 |
-
wp_register_style( 'wr2x-admin-css', plugins_url( '/wr2x_admin.css', __FILE__ ) );
|
79 |
-
wp_enqueue_style( 'wr2x-admin-css' );
|
80 |
-
if ( !get_option( "wr2x_retina_admin" ) )
|
81 |
-
return;
|
82 |
-
}
|
83 |
-
|
84 |
-
$method = get_option( "wr2x_method" );
|
85 |
-
if ( $method == "Picturefill" ) {
|
86 |
-
add_action( 'wp_head', 'wr2x_picture_buffer_start' );
|
87 |
-
add_action( 'wp_footer', 'wr2x_picture_buffer_end' );
|
88 |
-
}
|
89 |
-
else if ( $method == 'HTML Rewrite' ) {
|
90 |
-
$is_retina = false;
|
91 |
-
if ( isset( $_COOKIE['devicePixelRatio'] ) ) {
|
92 |
-
$is_retina = ceil( floatval( $_COOKIE['devicePixelRatio'] ) ) > 1;
|
93 |
-
// if ( get_option( "wr2x_ignore_mobile" ) ) {
|
94 |
-
// $mobileDetect = new Mobile_Detect();
|
95 |
-
// $is_retina = !$mobileDetect->isMobile();
|
96 |
-
// }
|
97 |
-
}
|
98 |
-
if ( $is_retina || wr2x_is_debug() ) {
|
99 |
-
add_action( 'wp_head', 'wr2x_buffer_start' );
|
100 |
-
add_action( 'wp_footer', 'wr2x_buffer_end' );
|
101 |
-
}
|
102 |
-
}
|
103 |
-
|
104 |
-
}
|
105 |
-
|
106 |
-
function wr2x_unset_medium_large( $sizes ) {
|
107 |
-
unset( $sizes['medium_large'] );
|
108 |
-
return $sizes;
|
109 |
-
}
|
110 |
-
|
111 |
-
/**
|
112 |
-
*
|
113 |
-
* PICTURE METHOD
|
114 |
-
*
|
115 |
-
*/
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
function wr2x_is_supported_image( $url ) {
|
120 |
-
$wr2x_supported_image = array( 'jpg', 'jpeg', 'png', 'gif' );
|
121 |
-
$ext = strtolower( pathinfo( $url, PATHINFO_EXTENSION ) );
|
122 |
-
if ( !in_array( $ext, $wr2x_supported_image ) ) {
|
123 |
-
wr2x_log( "Extension (" . $ext . ") is not " . implode( ', ', $wr2x_supported_image ) . "." );
|
124 |
-
return false;
|
125 |
-
}
|
126 |
-
return true;
|
127 |
-
}
|
128 |
-
|
129 |
-
function wr2x_picture_buffer_start () {
|
130 |
-
ob_start( "wr2x_picture_rewrite" );
|
131 |
-
wr2x_log( "* HTML REWRITE FOR PICTUREFILL" );
|
132 |
-
}
|
133 |
-
|
134 |
-
function wr2x_picture_buffer_end () {
|
135 |
-
ob_end_flush();
|
136 |
-
}
|
137 |
-
|
138 |
-
// Replace the IMG tags by PICTURE tags with SRCSET
|
139 |
-
function wr2x_picture_rewrite( $buffer ) {
|
140 |
-
global $wr2x_admin;
|
141 |
-
if ( !isset( $buffer ) || trim( $buffer ) === '' )
|
142 |
-
return $buffer;
|
143 |
-
if ( !function_exists( "str_get_html" ) )
|
144 |
-
require( 'inc/simple_html_dom.php' );
|
145 |
-
|
146 |
-
$lazysize = get_option( "wr2x_picturefill_lazysizes" ) && $wr2x_admin->is_pro();
|
147 |
-
$killsrc = !get_option( "wr2x_picturefill_keep_src" );
|
148 |
-
$nodes_count = 0;
|
149 |
-
$nodes_replaced = 0;
|
150 |
-
$html = str_get_html( $buffer );
|
151 |
-
if ( !$html ) {
|
152 |
-
wr2x_log( "The HTML buffer is null, another plugin might block the process." );
|
153 |
-
return $buffer;
|
154 |
-
}
|
155 |
-
|
156 |
-
// IMG TAGS
|
157 |
-
foreach( $html->find( 'img' ) as $element ) {
|
158 |
-
$nodes_count++;
|
159 |
-
$parent = $element->parent();
|
160 |
-
if ( $parent->tag == "picture" ) {
|
161 |
-
wr2x_log("The img tag is inside a picture tag. Tag ignored.");
|
162 |
-
continue;
|
163 |
-
}
|
164 |
-
else {
|
165 |
-
$valid = apply_filters( "wr2x_validate_src", $element->src );
|
166 |
-
if ( empty( $valid ) ) {
|
167 |
-
$nodes_count--;
|
168 |
-
continue;
|
169 |
-
}
|
170 |
-
|
171 |
-
// Original HTML
|
172 |
-
$from = substr( $element, 0 );
|
173 |
-
|
174 |
-
// SRC-SET already exists, let's check if LazySize is used
|
175 |
-
if ( !empty( $element->srcset ) ) {
|
176 |
-
if ( $lazysize ) {
|
177 |
-
wr2x_log( "The src-set has already been created but it will be modifid to data-srcset for lazyload." );
|
178 |
-
$element->class = $element->class . ' lazyload';
|
179 |
-
$element->{'data-srcset'} = $element->srcset;
|
180 |
-
$element->srcset = null;
|
181 |
-
if ( $killsrc )
|
182 |
-
$element->src = null;
|
183 |
-
$to = $element;
|
184 |
-
$buffer = str_replace( trim( $from, "</> "), trim( $to, "</> " ), $buffer );
|
185 |
-
wr2x_log( "The img tag '$from' was rewritten to '$to'" );
|
186 |
-
$nodes_replaced++;
|
187 |
-
}
|
188 |
-
else {
|
189 |
-
wr2x_log( "The src-set has already been created. Tag ignored." );
|
190 |
-
}
|
191 |
-
continue;
|
192 |
-
}
|
193 |
-
|
194 |
-
// Process of SRC-SET creation
|
195 |
-
if ( !wr2x_is_supported_image( $element->src ) ) {
|
196 |
-
$nodes_count--;
|
197 |
-
continue;
|
198 |
-
}
|
199 |
-
$retina_url = wr2x_get_retina_from_url( $element->src );
|
200 |
-
$retina_url = apply_filters( 'wr2x_img_retina_url', $retina_url );
|
201 |
-
if ( $retina_url != null ) {
|
202 |
-
$retina_url = wr2x_cdn_this( $retina_url );
|
203 |
-
$img_url = wr2x_cdn_this( $element->src );
|
204 |
-
$img_url = apply_filters( 'wr2x_img_url', $img_url );
|
205 |
-
if ( $lazysize ) {
|
206 |
-
$element->class = $element->class . ' lazyload';
|
207 |
-
$element->{'data-srcset'} = "$img_url, $retina_url 2x";
|
208 |
-
}
|
209 |
-
else
|
210 |
-
$element->srcset = "$img_url, $retina_url 2x";
|
211 |
-
if ( $killsrc )
|
212 |
-
$element->src = null;
|
213 |
-
else {
|
214 |
-
$img_src = apply_filters( 'wr2x_img_src', $element->src );
|
215 |
-
$element->src = wr2x_cdn_this( $img_src );
|
216 |
-
}
|
217 |
-
$to = $element;
|
218 |
-
$buffer = str_replace( trim( $from, "</> "), trim( $to, "</> " ), $buffer );
|
219 |
-
wr2x_log( "The img tag '$from' was rewritten to '$to'" );
|
220 |
-
$nodes_replaced++;
|
221 |
-
}
|
222 |
-
else {
|
223 |
-
wr2x_log( "The img tag was not rewritten. No retina for '" . $element->src . "'." );
|
224 |
-
}
|
225 |
-
}
|
226 |
-
}
|
227 |
-
wr2x_log( "$nodes_replaced/$nodes_count img tags were replaced." );
|
228 |
-
|
229 |
-
// INLINE CSS BACKGROUND
|
230 |
-
if ( get_option( 'wr2x_picturefill_css_background', false ) && $wr2x_admin->is_pro() ) {
|
231 |
-
preg_match_all( "/url(?:\(['\"]?)(.*?)(?:['\"]?\))/", $buffer, $matches );
|
232 |
-
$match_css = $matches[0];
|
233 |
-
$match_url = $matches[1];
|
234 |
-
if ( count( $matches ) != 2 )
|
235 |
-
return $buffer;
|
236 |
-
$nodes_count = 0;
|
237 |
-
$nodes_replaced = 0;
|
238 |
-
for ( $c = 0; $c < count( $matches[0] ); $c++ ) {
|
239 |
-
$css = $match_css[$c];
|
240 |
-
$url = $match_url[$c];
|
241 |
-
if ( !wr2x_is_supported_image( $url ) )
|
242 |
-
continue;
|
243 |
-
$nodes_count++;
|
244 |
-
$retina_url = wr2x_get_retina_from_url( $url );
|
245 |
-
$retina_url = apply_filters( 'wr2x_img_retina_url', $retina_url );
|
246 |
-
if ( $retina_url != null ) {
|
247 |
-
$retina_url = wr2x_cdn_this( $retina_url );
|
248 |
-
$minibuffer = str_replace( $url, $retina_url, $css );
|
249 |
-
$buffer = str_replace( $css, $minibuffer, $buffer );
|
250 |
-
wr2x_log( "The background src '$css' was rewritten to '$minibuffer'" );
|
251 |
-
$nodes_replaced++;
|
252 |
-
}
|
253 |
-
else {
|
254 |
-
wr2x_log( "The background src was not rewritten. No retina for '" . $url . "'." );
|
255 |
-
}
|
256 |
-
}
|
257 |
-
wr2x_log( "$nodes_replaced/$nodes_count background src were replaced." );
|
258 |
-
}
|
259 |
-
|
260 |
-
return $buffer;
|
261 |
-
}
|
262 |
-
|
263 |
-
/**
|
264 |
-
*
|
265 |
-
* HTML REWRITE METHOD
|
266 |
-
*
|
267 |
-
*/
|
268 |
-
|
269 |
-
function wr2x_buffer_start () {
|
270 |
-
ob_start( "wr2x_html_rewrite" );
|
271 |
-
wr2x_log( "* HTML REWRITE" );
|
272 |
-
}
|
273 |
-
|
274 |
-
function wr2x_buffer_end () {
|
275 |
-
ob_end_flush();
|
276 |
-
}
|
277 |
-
|
278 |
-
// Replace the images by retina images (if available)
|
279 |
-
function wr2x_html_rewrite( $buffer ) {
|
280 |
-
if ( !isset( $buffer ) || trim( $buffer ) === '' )
|
281 |
-
return $buffer;
|
282 |
-
$nodes_count = 0;
|
283 |
-
$nodes_replaced = 0;
|
284 |
-
$doc = new DOMDocument();
|
285 |
-
@$doc->loadHTML( $buffer ); // = ($doc->strictErrorChecking = false;)
|
286 |
-
$imageTags = $doc->getElementsByTagName('img');
|
287 |
-
foreach ( $imageTags as $tag ) {
|
288 |
-
$nodes_count++;
|
289 |
-
$img_pathinfo = wr2x_get_pathinfo_from_image_src( $tag->getAttribute('src') );
|
290 |
-
$filepath = trailingslashit( wr2x_get_upload_root() ) . $img_pathinfo;
|
291 |
-
$system_retina = wr2x_get_retina( $filepath );
|
292 |
-
if ( $system_retina != null ) {
|
293 |
-
$retina_pathinfo = wr2x_cdn_this( ltrim( str_replace( wr2x_get_upload_root(), "", $system_retina ), '/' ) );
|
294 |
-
$buffer = str_replace( $img_pathinfo, $retina_pathinfo, $buffer );
|
295 |
-
wr2x_log( "The img src '$img_pathinfo' was replaced by '$retina_pathinfo'" );
|
296 |
-
$nodes_replaced++;
|
297 |
-
}
|
298 |
-
else {
|
299 |
-
wr2x_log( "The file '$system_retina' was not found. Tag not modified." );
|
300 |
-
}
|
301 |
-
}
|
302 |
-
wr2x_log( "$nodes_replaced/$nodes_count were replaced." );
|
303 |
-
return $buffer;
|
304 |
-
}
|
305 |
-
|
306 |
-
|
307 |
-
// Converts PHP INI size type (e.g. 24M) to int
|
308 |
-
function wr2x_parse_ini_size( $size ) {
|
309 |
-
$unit = preg_replace('/[^bkmgtpezy]/i', '', $size);
|
310 |
-
$size = preg_replace('/[^0-9\.]/', '', $size);
|
311 |
-
if ( $unit )
|
312 |
-
return round( $size * pow( 1024, stripos( 'bkmgtpezy', $unit[0] ) ) );
|
313 |
-
else
|
314 |
-
round( $size );
|
315 |
-
}
|
316 |
-
|
317 |
-
function wr2x_get_max_filesize() {
|
318 |
-
if ( defined ('HHVM_VERSION' ) ) {
|
319 |
-
return ini_get( 'upload_max_filesize' ) ? (int)wr2x_parse_ini_size( ini_get( 'upload_max_filesize' ) ) :
|
320 |
-
(int)ini_get( 'hhvm.server.upload.upload_max_file_size' );
|
321 |
-
}
|
322 |
-
else {
|
323 |
-
return (int)wr2x_parse_ini_size( ini_get( 'upload_max_filesize' ) );
|
324 |
-
}
|
325 |
-
}
|
326 |
-
|
327 |
-
/**
|
328 |
-
*
|
329 |
-
* ISSUES CALCULATION AND FUNCTIONS
|
330 |
-
*
|
331 |
-
*/
|
332 |
-
|
333 |
-
// Compares two images dimensions (resolutions) against each while accepting an margin error
|
334 |
-
function wr2x_are_dimensions_ok( $width, $height, $retina_width, $retina_height ) {
|
335 |
-
$w_margin = $width - $retina_width;
|
336 |
-
$h_margin = $height - $retina_height;
|
337 |
-
return ( $w_margin >= -2 && $h_margin >= -2 );
|
338 |
-
}
|
339 |
-
|
340 |
-
// UPDATE THE ISSUE STATUS OF THIS ATTACHMENT
|
341 |
-
function wr2x_update_issue_status( $attachmentId, $issues = null, $info = null ) {
|
342 |
-
if ( wr2x_is_ignore( $attachmentId ) )
|
343 |
-
return;
|
344 |
-
if ( $issues == null )
|
345 |
-
$issues = wr2x_get_issues();
|
346 |
-
if ( $info == null )
|
347 |
-
$info = wr2x_retina_info( $attachmentId );
|
348 |
-
$consideredIssue = in_array( $attachmentId, $issues );
|
349 |
-
$realIssue = wr2x_info_has_issues( $info );
|
350 |
-
if ( $consideredIssue && !$realIssue )
|
351 |
-
wr2x_remove_issue( $attachmentId );
|
352 |
-
else if ( !$consideredIssue && $realIssue )
|
353 |
-
wr2x_add_issue( $attachmentId );
|
354 |
-
return $realIssue;
|
355 |
-
}
|
356 |
-
|
357 |
-
function wr2x_get_issues() {
|
358 |
-
$issues = get_transient( 'wr2x_issues' );
|
359 |
-
if ( !$issues || !is_array( $issues ) ) {
|
360 |
-
$issues = array();
|
361 |
-
set_transient( 'wr2x_issues', $issues );
|
362 |
-
}
|
363 |
-
return $issues;
|
364 |
-
}
|
365 |
-
|
366 |
-
// CHECK IF THE 'INFO' OBJECT CONTAINS ISSUE (RETURN TRUE OR FALSE)
|
367 |
-
function wr2x_info_has_issues( $info ) {
|
368 |
-
foreach ( $info as $aindex => $aval ) {
|
369 |
-
if ( is_array( $aval ) || $aval == 'PENDING' )
|
370 |
-
return true;
|
371 |
-
}
|
372 |
-
return false;
|
373 |
-
}
|
374 |
-
|
375 |
-
function wr2x_calculate_issues() {
|
376 |
-
global $wpdb;
|
377 |
-
$postids = $wpdb->get_col( "
|
378 |
-
SELECT p.ID FROM $wpdb->posts p
|
379 |
-
WHERE post_status = 'inherit'
|
380 |
-
AND post_type = 'attachment'" . wr2x_create_sql_if_wpml_original() . "
|
381 |
-
AND ( post_mime_type = 'image/jpeg' OR
|
382 |
-
post_mime_type = 'image/jpg' OR
|
383 |
-
post_mime_type = 'image/png' OR
|
384 |
-
post_mime_type = 'image/gif' )
|
385 |
-
" );
|
386 |
-
$issues = array();
|
387 |
-
foreach ( $postids as $id ) {
|
388 |
-
$info = wr2x_retina_info( $id );
|
389 |
-
if ( wr2x_info_has_issues( $info ) )
|
390 |
-
array_push( $issues, $id );
|
391 |
-
|
392 |
-
}
|
393 |
-
set_transient( 'wr2x_ignores', array() );
|
394 |
-
set_transient( 'wr2x_issues', $issues );
|
395 |
-
}
|
396 |
-
|
397 |
-
function wr2x_add_issue( $attachmentId ) {
|
398 |
-
if ( wr2x_is_ignore( $attachmentId ) )
|
399 |
-
return;
|
400 |
-
$issues = wr2x_get_issues();
|
401 |
-
if ( !in_array( $attachmentId, $issues ) ) {
|
402 |
-
array_push( $issues, $attachmentId );
|
403 |
-
set_transient( 'wr2x_issues', $issues );
|
404 |
-
}
|
405 |
-
return $issues;
|
406 |
-
}
|
407 |
-
|
408 |
-
function wr2x_remove_issue( $attachmentId, $onlyIgnore = false ) {
|
409 |
-
$issues = array_diff( wr2x_get_issues(), array( $attachmentId ) );
|
410 |
-
set_transient( 'wr2x_issues', $issues );
|
411 |
-
if ( !$onlyIgnore )
|
412 |
-
wr2x_remove_ignore( $attachmentId );
|
413 |
-
return $issues;
|
414 |
-
}
|
415 |
-
|
416 |
-
// IGNORE
|
417 |
-
|
418 |
-
function wr2x_get_ignores( $force = false ) {
|
419 |
-
$ignores = get_transient( 'wr2x_ignores' );
|
420 |
-
if ( !$ignores || !is_array( $ignores ) ) {
|
421 |
-
$ignores = array();
|
422 |
-
set_transient( 'wr2x_ignores', $ignores );
|
423 |
-
}
|
424 |
-
return $ignores;
|
425 |
-
}
|
426 |
-
|
427 |
-
function wr2x_is_ignore( $attachmentId ) {
|
428 |
-
$ignores = wr2x_get_ignores();
|
429 |
-
return in_array( $attachmentId, wr2x_get_ignores() );
|
430 |
-
}
|
431 |
-
|
432 |
-
function wr2x_remove_ignore( $attachmentId ) {
|
433 |
-
$ignores = wr2x_get_ignores();
|
434 |
-
$ignores = array_diff( $ignores, array( $attachmentId ) );
|
435 |
-
set_transient( 'wr2x_ignores', $ignores );
|
436 |
-
return $ignores;
|
437 |
-
}
|
438 |
-
|
439 |
-
function wr2x_add_ignore( $attachmentId ) {
|
440 |
-
$ignores = wr2x_get_ignores();
|
441 |
-
if ( !in_array( $attachmentId, $ignores ) ) {
|
442 |
-
array_push( $ignores, $attachmentId );
|
443 |
-
set_transient( 'wr2x_ignores', $ignores );
|
444 |
-
}
|
445 |
-
wr2x_remove_issue( $attachmentId, true );
|
446 |
-
return $ignores;
|
447 |
-
}
|
448 |
-
|
449 |
-
/**
|
450 |
-
*
|
451 |
-
* INFORMATION ABOUT THE RETINA IMAGE IN HTML
|
452 |
-
*
|
453 |
-
*/
|
454 |
-
|
455 |
-
function wpr2x_html_get_basic_retina_info_full( $attachmentId, $retina_info ) {
|
456 |
-
$status = ( isset( $retina_info ) && isset( $retina_info['full-size'] ) ) ? $retina_info['full-size'] : 'IGNORED';
|
457 |
-
if ( $status == 'EXISTS' ) {
|
458 |
-
return '<ul class="meow-sized-images"><li class="meow-bk-blue" title="full-size"></li></ul>';
|
459 |
-
}
|
460 |
-
else if ( is_array( $status ) ) {
|
461 |
-
return '<ul class="meow-sized-images"><li class="meow-bk-orange" title="full-size"></li></ul>';
|
462 |
-
}
|
463 |
-
else if ( $status == 'IGNORED' ) {
|
464 |
-
return __( "N/A", "wp-retina-2x" );
|
465 |
-
}
|
466 |
-
return $status;
|
467 |
-
}
|
468 |
-
|
469 |
-
function wr2x_format_title( $i, $size ) {
|
470 |
-
return $i . ' (' . ( $size['width'] * 2 ) . 'x' . ( $size['height'] * 2 ) . ')';
|
471 |
-
}
|
472 |
-
|
473 |
-
// Information for the 'Media Sizes Retina-ized' Column in the Retina Dashboard
|
474 |
-
function wpr2x_html_get_basic_retina_info( $attachmentId, $retina_info ) {
|
475 |
-
$sizes = wr2x_get_active_image_sizes();
|
476 |
-
$result = '<ul class="meow-sized-images" postid="' . ( is_integer( $attachmentId ) ? $attachmentId : $attachmentId->ID ) . '">';
|
477 |
-
foreach ( $sizes as $i => $size ) {
|
478 |
-
$status = ( isset( $retina_info ) && isset( $retina_info[$i] ) ) ? $retina_info[$i] : null;
|
479 |
-
if ( is_array( $status ) )
|
480 |
-
$result .= '<li class="meow-bk-red" title="' . wr2x_format_title( $i, $size ) . '">'
|
481 |
-
. Meow_Admin::size_shortname( $i ) . '</li>';
|
482 |
-
else if ( $status == 'EXISTS' )
|
483 |
-
$result .= '<li class="meow-bk-blue" title="' . wr2x_format_title( $i, $size ) . '">'
|
484 |
-
. Meow_Admin::size_shortname( $i ) . '</li>';
|
485 |
-
else if ( $status == 'PENDING' )
|
486 |
-
$result .= '<li class="meow-bk-orange" title="' . wr2x_format_title( $i, $size ) . '">'
|
487 |
-
. Meow_Admin::size_shortname( $i ) . '</li>';
|
488 |
-
else if ( $status == 'MISSING' )
|
489 |
-
$result .= '<li class="meow-bk-red" title="' . wr2x_format_title( $i, $size ) . '">'
|
490 |
-
. Meow_Admin::size_shortname( $i ) . '</li>';
|
491 |
-
else if ( $status == 'IGNORED' )
|
492 |
-
$result .= '<li class="meow-bk-gray" title="' . wr2x_format_title( $i, $size ) . '">'
|
493 |
-
. Meow_Admin::size_shortname( $i ) . '</li>';
|
494 |
-
else {
|
495 |
-
error_log( "Retina: This status is not recognized: " . $status );
|
496 |
-
}
|
497 |
-
}
|
498 |
-
$result .= '</ul>';
|
499 |
-
return $result;
|
500 |
-
}
|
501 |
-
|
502 |
-
// Information for Details in the Retina Dashboard
|
503 |
-
function wpr2x_html_get_details_retina_info( $post, $retina_info ) {
|
504 |
-
global $wr2x_admin;
|
505 |
-
if ( !$wr2x_admin->is_pro() ) {
|
506 |
-
return __( "PRO VERSION ONLY", 'wp-retina-2x' );
|
507 |
-
}
|
508 |
-
|
509 |
-
$sizes = wr2x_get_image_sizes();
|
510 |
-
$total = 0; $possible = 0; $issue = 0; $ignored = 0; $retina = 0;
|
511 |
-
|
512 |
-
$postinfo = get_post( $post, OBJECT );
|
513 |
-
$meta = wp_get_attachment_metadata( $post );
|
514 |
-
$fullsize_file = get_attached_file( $post );
|
515 |
-
$pathinfo_system = pathinfo( $fullsize_file );
|
516 |
-
$pathinfo = pathinfo( $meta['file'] );
|
517 |
-
$uploads = wp_upload_dir();
|
518 |
-
$basepath_url = trailingslashit( $uploads['baseurl'] ) . $pathinfo['dirname'];
|
519 |
-
if ( get_option( "wr2x_full_size" ) ) {
|
520 |
-
$sizes['full-size']['file'] = $pathinfo['basename'];
|
521 |
-
$sizes['full-size']['width'] = $meta['width'];
|
522 |
-
$sizes['full-size']['height'] = $meta['height'];
|
523 |
-
$meta['sizes']['full-size']['file'] = $pathinfo['basename'];
|
524 |
-
$meta['sizes']['full-size']['width'] = $meta['width'];
|
525 |
-
$meta['sizes']['full-size']['height'] = $meta['height'];
|
526 |
-
}
|
527 |
-
$result = "<p>This screen displays all the image sizes set-up by your WordPress configuration with the Retina details.</p>";
|
528 |
-
$result .= "<br /><a target='_blank' href='" . trailingslashit( $uploads['baseurl'] ) . $meta['file'] . "'><img src='" . trailingslashit( $uploads['baseurl'] ) . $meta['file'] . "' height='100px' style='float: left; margin-right: 10px;' /></a><div class='base-info'>";
|
529 |
-
$result .= "Title: <b>" . ( $postinfo->post_title ? $postinfo->post_title : '<i>Untitled</i>' ) . "</b><br />";
|
530 |
-
$result .= "Full-size: <b>" . $meta['width'] . "×" . $meta['height'] . "</b><br />";
|
531 |
-
$result .= "Image URL: <a target='_blank' href='" . trailingslashit( $uploads['baseurl'] ) . $meta['file'] . "'>" . trailingslashit( $uploads['baseurl'] ) . $meta['file'] . "</a><br />";
|
532 |
-
$result .= "Image Path: " . $fullsize_file . "<br />";
|
533 |
-
$result .= "</div><div style='clear: both;'></div><br />";
|
534 |
-
$result .= "<div class='scrollable-info'>";
|
535 |
-
|
536 |
-
foreach ( $sizes as $i => $sizemeta ) {
|
537 |
-
$total++;
|
538 |
-
$normal_file_system = ""; $retina_file_system = "";
|
539 |
-
$normal_file = ""; $retina_file = ""; $width = ""; $height = "";
|
540 |
-
|
541 |
-
if ( isset( $retina_info[$i] ) && $retina_info[$i] == 'IGNORED' ) {
|
542 |
-
$status = "IGNORED";
|
543 |
-
}
|
544 |
-
else if ( !isset( $meta['sizes'] ) ) {
|
545 |
-
$statusText = __( "The metadata is broken! This is not related to the retina plugin. You should probably use a plugin to re-generate the missing metadata and images.", 'wp-retina-2x' );
|
546 |
-
$status = "MISSING";
|
547 |
-
}
|
548 |
-
else if ( !isset( $meta['sizes'][$i] ) ) {
|
549 |
-
$statusText = sprintf( __( "The image size '%s' could not be found. You probably changed your image sizes but this specific image was not re-build. This is not related to the retina plugin. You should probably use a plugin to re-generate the missing metadata and images.", 'wp-retina-2x' ), $i );
|
550 |
-
$status = "MISSING";
|
551 |
-
}
|
552 |
-
else {
|
553 |
-
$normal_file_system = trailingslashit( $pathinfo_system['dirname'] ) . $meta['sizes'][$i]['file'];
|
554 |
-
$retina_file_system = wr2x_get_retina( $normal_file_system );
|
555 |
-
$normal_file = trailingslashit( $basepath_url ) . $meta['sizes'][$i]['file'];
|
556 |
-
$retina_file = wr2x_get_retina_from_url( $normal_file );
|
557 |
-
$status = ( isset( $retina_info ) && isset( $retina_info[$i] ) ) ? $retina_info[$i] : null;
|
558 |
-
$width = $meta['sizes'][$i]['width'];
|
559 |
-
$height = $meta['sizes'][$i]['height'];
|
560 |
-
}
|
561 |
-
|
562 |
-
$result .= "<h3>";
|
563 |
-
|
564 |
-
// Status Icon
|
565 |
-
if ( is_array( $status ) && $i == 'full-size' ) {
|
566 |
-
$result .= '<div class="meow-sized-image meow-bk-red"></div>';
|
567 |
-
$statusText = sprintf( __( "The retina version of the Full-Size image is missing.<br />Full Size Retina has been checked in the Settings and this image is therefore required.<br />Please drag & drop an image of at least <b>%dx%d</b> in the <b>Full-Size Retina Upload</b> column.", 'wp-retina-2x' ), $status['width'], $status['height'] );
|
568 |
-
}
|
569 |
-
else if ( is_array( $status ) ) {
|
570 |
-
$result .= '<div class="meow-sized-image meow-bk-red"></div>';
|
571 |
-
$statusText = sprintf( __( "The Full-Size image is too small (<b>%dx%d</b>) and this size cannot be generated.<br />Please upload an image of at least <b>%dx%d</b>.", 'wp-retina-2x' ), $meta['width'], $meta['height'], $status['width'], $status['height'] );
|
572 |
-
$issue++;
|
573 |
-
}
|
574 |
-
else if ( $status == 'EXISTS' ) {
|
575 |
-
$result .= '<div class="meow-sized-image meow-bk-blue"></div>';
|
576 |
-
$statusText = "";
|
577 |
-
$retina++;
|
578 |
-
}
|
579 |
-
else if ( $status == 'PENDING' ) {
|
580 |
-
$result .= '<div class="meow-sized-image meow-bk-orange"></div>';
|
581 |
-
$statusText = __( "The retina image can be created. Please use the 'GENERATE' button.", 'wp-retina-2x' );
|
582 |
-
$possible++;
|
583 |
-
}
|
584 |
-
else if ( $status == 'MISSING' ) {
|
585 |
-
$result .= '<div class="meow-sized-image meow-bk-gray"></div>';
|
586 |
-
$statusText = __( "The standard image normally created by WordPress is missing.", 'wp-retina-2x' );
|
587 |
-
$total--;
|
588 |
-
}
|
589 |
-
else if ( $status == 'IGNORED' ) {
|
590 |
-
$result .= '<div class="meow-sized-image meow-bk-gray"></div>';
|
591 |
-
$statusText = __( "This size is ignored by your retina settings.", 'wp-retina-2x' );
|
592 |
-
$ignored++;
|
593 |
-
$total--;
|
594 |
-
}
|
595 |
-
|
596 |
-
$result .= " Size: $i</h3><p>$statusText</p>";
|
597 |
-
|
598 |
-
if ( !is_array( $status ) && $status !== 'IGNORED' && $status !== 'MISSING' ) {
|
599 |
-
$result .= "<table><tr><th>Normal (" . $width . "×" . $height. ")</th><th>Retina 2x (" . $width * 2 . "×" . $height * 2 . ")</th></tr><tr><td><a target='_blank' href='$normal_file'><img src='$normal_file' width='100'></a></td><td><a target='_blank' href='$retina_file'><img src='$retina_file' width='100'></a></td></tr></table>";
|
600 |
-
$result .= "<p><small>";
|
601 |
-
$result .= "Image URL: <a target='_blank' href='$normal_file'>$normal_file</a><br />";
|
602 |
-
$result .= "Retina URL: <a target='_blank' href='$retina_file'>$retina_file</a><br />";
|
603 |
-
$result .= "Image Path: $normal_file_system<br />";
|
604 |
-
$result .= "Retina Path: $retina_file_system<br />";
|
605 |
-
$result .= "</small></p>";
|
606 |
-
}
|
607 |
-
}
|
608 |
-
$result .= "</table>";
|
609 |
-
$result .= "</div>";
|
610 |
-
return $result;
|
611 |
-
}
|
612 |
-
|
613 |
-
/**
|
614 |
-
*
|
615 |
-
* WP RETINA 2X CORE
|
616 |
-
*
|
617 |
-
*/
|
618 |
-
|
619 |
-
// Get WordPress upload directory
|
620 |
-
function wr2x_get_upload_root() {
|
621 |
-
$uploads = wp_upload_dir();
|
622 |
-
return $uploads['basedir'];
|
623 |
-
}
|
624 |
-
|
625 |
-
function wr2x_get_upload_root_url() {
|
626 |
-
$uploads = wp_upload_dir();
|
627 |
-
return $uploads['baseurl'];
|
628 |
-
}
|
629 |
-
|
630 |
-
// Get WordPress directory
|
631 |
-
function wr2x_get_wordpress_root() {
|
632 |
-
return ABSPATH;
|
633 |
-
}
|
634 |
-
|
635 |
-
// Return the retina file if there is any (system path)
|
636 |
-
function wr2x_get_retina( $file ) {
|
637 |
-
$pathinfo = pathinfo( $file ) ;
|
638 |
-
if ( empty( $pathinfo ) || !isset( $pathinfo['dirname'] ) ) {
|
639 |
-
if ( empty( $file ) ) {
|
640 |
-
wr2x_log( "An empty filename was given to wr2x_get_retina()." );
|
641 |
-
error_log( "An empty filename was given to wr2x_get_retina()." );
|
642 |
-
}
|
643 |
-
else {
|
644 |
-
wr2x_log( "Pathinfo is null for " . $file . "." );
|
645 |
-
error_log( "Pathinfo is null for " . $file . "." );
|
646 |
-
}
|
647 |
-
return null;
|
648 |
-
}
|
649 |
-
$retina_file = trailingslashit( $pathinfo['dirname'] ) . $pathinfo['filename'] .
|
650 |
-
wr2x_retina_extension() . ( isset( $pathinfo['extension'] ) ? $pathinfo['extension'] : "" );
|
651 |
-
if ( file_exists( $retina_file ) )
|
652 |
-
return $retina_file;
|
653 |
-
wr2x_log( "Retina file at '{$retina_file}' does not exist." );
|
654 |
-
return null;
|
655 |
-
}
|
656 |
-
|
657 |
-
function wr2x_get_retina_from_remote_url( $url ) {
|
658 |
-
global $wr2x_admin;
|
659 |
-
$over_http = get_option( 'wr2x_over_http_check', false ) && $wr2x_admin->is_pro();
|
660 |
-
if ( !$over_http )
|
661 |
-
return null;
|
662 |
-
$potential_retina_url = wr2x_rewrite_url_to_retina( $url );
|
663 |
-
$response = wp_remote_head( $potential_retina_url, array(
|
664 |
-
'user-agent' => "MeowApps-Retina",
|
665 |
-
'sslverify' => false,
|
666 |
-
'timeout' => 10
|
667 |
-
));
|
668 |
-
if ( is_array( $response ) && is_array( $response['response'] ) && isset( $response['response']['code'] ) ) {
|
669 |
-
if ( $response['response']['code'] == 200 ) {
|
670 |
-
wr2x_log( "Retina URL: " . $potential_retina_url, true);
|
671 |
-
return $potential_retina_url;
|
672 |
-
}
|
673 |
-
else
|
674 |
-
wr2x_log( "Remote head failed with code " . $response['response']['code'] . "." );
|
675 |
-
}
|
676 |
-
wr2x_log( "Retina URL couldn't be found (URL -> Retina URL).", true);
|
677 |
-
}
|
678 |
-
|
679 |
-
// Return retina URL from the image URL
|
680 |
-
function wr2x_get_retina_from_url( $url ) {
|
681 |
-
wr2x_log( "Standard URL: " . $url, true);
|
682 |
-
global $wr2x_admin;
|
683 |
-
$over_http = get_option( 'wr2x_over_http_check', false ) && $wr2x_admin->is_pro();
|
684 |
-
$filepath = wr2x_from_url_to_system( $url );
|
685 |
-
if ( empty ( $filepath ) )
|
686 |
-
return wr2x_get_retina_from_remote_url( $url );
|
687 |
-
wr2x_log( "Standard PATH: " . $filepath, true);
|
688 |
-
$system_retina = wr2x_get_retina( $filepath );
|
689 |
-
if ( empty ( $system_retina ) )
|
690 |
-
return wr2x_get_retina_from_remote_url( $url );
|
691 |
-
wr2x_log( "Retina PATH: " . $system_retina, true);
|
692 |
-
$retina_url = wr2x_rewrite_url_to_retina( $url );
|
693 |
-
wr2x_log( "Retina URL: " . $retina_url, true);
|
694 |
-
return $retina_url;
|
695 |
-
}
|
696 |
-
|
697 |
-
// Get the filepath from the URL
|
698 |
-
function wr2x_from_url_to_system( $url ) {
|
699 |
-
$img_pathinfo = wr2x_get_pathinfo_from_image_src( $url );
|
700 |
-
$filepath = trailingslashit( wr2x_get_wordpress_root() ) . $img_pathinfo;
|
701 |
-
if ( file_exists( $filepath ) )
|
702 |
-
return $filepath;
|
703 |
-
$filepath = trailingslashit( wr2x_get_upload_root() ) . $img_pathinfo;
|
704 |
-
if ( file_exists( $filepath ) )
|
705 |
-
return $filepath;
|
706 |
-
wr2x_log( "Standard PATH couldn't be found (URL -> System).", true);
|
707 |
-
return null;
|
708 |
-
}
|
709 |
-
|
710 |
-
function wr2x_rewrite_url_to_retina( $url ) {
|
711 |
-
$whereisdot = strrpos( $url, '.' );
|
712 |
-
$url = substr( $url, 0, $whereisdot ) . wr2x_retina_extension() . substr( $url, $whereisdot + 1 );
|
713 |
-
return $url;
|
714 |
-
}
|
715 |
-
|
716 |
-
// Clean the PathInfo of the IMG SRC.
|
717 |
-
// IMPORTANT: This function STRIPS THE UPLOAD FOLDER if it's found
|
718 |
-
// REASON: The reason is that on some installs the uploads folder is linked to a different "unlogical" physical folder
|
719 |
-
// http://wordpress.org/support/topic/cant-find-retina-file-with-custom-uploads-constant?replies=3#post-5078892
|
720 |
-
function wr2x_get_pathinfo_from_image_src( $image_src ) {
|
721 |
-
$uploads_url = trailingslashit( wr2x_get_upload_root_url() );
|
722 |
-
if ( strpos( $image_src, $uploads_url ) === 0 )
|
723 |
-
return ltrim( substr( $image_src, strlen( $uploads_url ) ), '/');
|
724 |
-
else if ( strpos( $image_src, wp_make_link_relative( $uploads_url ) ) === 0 )
|
725 |
-
return ltrim( substr( $image_src, strlen( wp_make_link_relative( $uploads_url ) ) ), '/');
|
726 |
-
$img_info = parse_url( $image_src );
|
727 |
-
return ltrim( $img_info['path'], '/' );
|
728 |
-
}
|
729 |
-
|
730 |
-
// Rename this filename with CDN
|
731 |
-
function wr2x_cdn_this( $url ) {
|
732 |
-
global $wr2x_admin;
|
733 |
-
$cdn_domain = "";
|
734 |
-
if ( $wr2x_admin->is_pro() )
|
735 |
-
$cdn_domain = get_option( "wr2x_cdn_domain" );
|
736 |
-
if ( empty( $cdn_domain ) )
|
737 |
-
return $url;
|
738 |
-
|
739 |
-
$home_url = parse_url( home_url() );
|
740 |
-
$uploads_url = trailingslashit( wr2x_get_upload_root_url() );
|
741 |
-
$uploads_url_cdn = str_replace( $home_url['host'], $cdn_domain, $uploads_url );
|
742 |
-
// Perform additional CDN check (Issue #1631 by Martin)
|
743 |
-
if ( strpos( $url, $uploads_url_cdn ) === 0 ) {
|
744 |
-
wr2x_log( "URL already has CDN: $url" );
|
745 |
-
return $url;
|
746 |
-
}
|
747 |
-
wr2x_log( "URL before CDN: $url" );
|
748 |
-
$site_url = preg_replace( '#^https?://#', '', rtrim( get_site_url(), '/' ) );
|
749 |
-
$new_url = str_replace( $site_url, $cdn_domain, $url );
|
750 |
-
wr2x_log( "URL with CDN: $new_url" );
|
751 |
-
return $new_url;
|
752 |
-
}
|
753 |
-
|
754 |
-
// function wr2x_admin_menu() {
|
755 |
-
// add_options_page( 'Retina', 'Retina', 'manage_options', 'wr2x_settings', 'wr2x_settings_page' );
|
756 |
-
// }
|
757 |
-
|
758 |
-
function wr2x_get_image_sizes() {
|
759 |
-
$sizes = array();
|
760 |
-
global $_wp_additional_image_sizes;
|
761 |
-
foreach ( get_intermediate_image_sizes() as $s ) {
|
762 |
-
$crop = false;
|
763 |
-
if ( isset( $_wp_additional_image_sizes[$s] ) ) {
|
764 |
-
$width = intval($_wp_additional_image_sizes[$s]['width']);
|
765 |
-
$height = intval($_wp_additional_image_sizes[$s]['height']);
|
766 |
-
$crop = $_wp_additional_image_sizes[$s]['crop'];
|
767 |
-
} else {
|
768 |
-
$width = get_option( $s . '_size_w' );
|
769 |
-
$height = get_option( $s . '_size_h' );
|
770 |
-
$crop = get_option( $s . '_crop' );
|
771 |
-
}
|
772 |
-
$sizes[$s] = array( 'width' => $width, 'height' => $height, 'crop' => $crop );
|
773 |
-
}
|
774 |
-
if ( get_option( 'wr2x_disable_medium_large' ) )
|
775 |
-
unset( $sizes['medium_large'] );
|
776 |
-
return $sizes;
|
777 |
-
}
|
778 |
-
|
779 |
-
function wr2x_get_active_image_sizes() {
|
780 |
-
$sizes = wr2x_get_image_sizes();
|
781 |
-
$active_sizes = array();
|
782 |
-
$ignore = get_option( "wr2x_ignore_sizes", array() );
|
783 |
-
if ( empty( $ignore ) )
|
784 |
-
$ignore = array();
|
785 |
-
$ignore = array_keys( $ignore );
|
786 |
-
foreach ( $sizes as $name => $attr ) {
|
787 |
-
$validSize = !empty( $attr['width'] ) || !empty( $attr['height'] );
|
788 |
-
if ( $validSize && !in_array( $name, $ignore ) ) {
|
789 |
-
$active_sizes[$name] = $attr;
|
790 |
-
}
|
791 |
-
}
|
792 |
-
return $active_sizes;
|
793 |
-
}
|
794 |
-
|
795 |
-
function wr2x_is_wpml_installed() {
|
796 |
-
return function_exists( 'icl_object_id' ) && !class_exists( 'Polylang' );
|
797 |
-
}
|
798 |
-
|
799 |
-
// SQL Query if WPML with an AND to check if the p.ID (p is attachment) is indeed an original
|
800 |
-
// That is to limit the SQL that queries all the attachments
|
801 |
-
function wr2x_create_sql_if_wpml_original() {
|
802 |
-
$whereIsOriginal = "";
|
803 |
-
if ( wr2x_is_wpml_installed() ) {
|
804 |
-
global $wpdb;
|
805 |
-
global $sitepress;
|
806 |
-
$tbl_wpml = $wpdb->prefix . "icl_translations";
|
807 |
-
$language = $sitepress->get_default_language();
|
808 |
-
$whereIsOriginal = " AND p.ID IN (SELECT element_id FROM $tbl_wpml WHERE element_type = 'post_attachment' AND language_code = '$language') ";
|
809 |
-
}
|
810 |
-
return $whereIsOriginal;
|
811 |
-
}
|
812 |
-
|
813 |
-
function wr2x_is_debug() {
|
814 |
-
static $debug = -1;
|
815 |
-
if ( $debug == -1 ) {
|
816 |
-
$debug = get_option( "wr2x_debug" );
|
817 |
-
}
|
818 |
-
return !!$debug;
|
819 |
-
}
|
820 |
-
|
821 |
-
function wr2x_log( $data, $isExtra = false ) {
|
822 |
-
global $wr2x_extra_debug;
|
823 |
-
if ( !wr2x_is_debug() )
|
824 |
-
return;
|
825 |
-
$fh = fopen( trailingslashit( WP_PLUGIN_DIR ) . 'wp-retina-2x/wp-retina-2x.log', 'a' );
|
826 |
-
$date = date( "Y-m-d H:i:s" );
|
827 |
-
fwrite( $fh, "$date: {$data}\n" );
|
828 |
-
fclose( $fh );
|
829 |
-
}
|
830 |
-
|
831 |
-
// Based on http://wordpress.stackexchange.com/questions/6645/turn-a-url-into-an-attachment-post-id
|
832 |
-
function wr2x_get_attachment_id( $file ) {
|
833 |
-
$query = array(
|
834 |
-
'post_type' => 'attachment',
|
835 |
-
'meta_query' => array(
|
836 |
-
array(
|
837 |
-
'key' => '_wp_attached_file',
|
838 |
-
'value' => ltrim( $file, '/' )
|
839 |
-
)
|
840 |
-
)
|
841 |
-
);
|
842 |
-
$posts = get_posts( $query );
|
843 |
-
foreach( $posts as $post )
|
844 |
-
return $post->ID;
|
845 |
-
return false;
|
846 |
-
}
|
847 |
-
|
848 |
-
// Return the retina extension followed by a dot
|
849 |
-
function wr2x_retina_extension() {
|
850 |
-
return '@2x.';
|
851 |
-
}
|
852 |
-
|
853 |
-
function wr2x_is_image_meta( $meta ) {
|
854 |
-
if ( !isset( $meta ) )
|
855 |
-
return false;
|
856 |
-
if ( !isset( $meta['sizes'] ) )
|
857 |
-
return false;
|
858 |
-
if ( !isset( $meta['width'], $meta['height'] ) )
|
859 |
-
return false;
|
860 |
-
return true;
|
861 |
-
}
|
862 |
-
|
863 |
-
function wr2x_retina_info( $id ) {
|
864 |
-
global $wr2x_admin;
|
865 |
-
$result = array();
|
866 |
-
$meta = wp_get_attachment_metadata( $id );
|
867 |
-
if ( !wr2x_is_image_meta( $meta ) )
|
868 |
-
return $result;
|
869 |
-
$original_width = $meta['width'];
|
870 |
-
$original_height = $meta['height'];
|
871 |
-
$sizes = wr2x_get_image_sizes();
|
872 |
-
$required_files = true;
|
873 |
-
$originalfile = get_attached_file( $id );
|
874 |
-
$pathinfo = pathinfo( $originalfile );
|
875 |
-
$basepath = $pathinfo['dirname'];
|
876 |
-
$ignore = get_option( "wr2x_ignore_sizes", array() );
|
877 |
-
if ( empty( $ignore ) )
|
878 |
-
$ignore = array();
|
879 |
-
$ignore = array_keys( $ignore );
|
880 |
-
|
881 |
-
// Full-Size (if required in the settings)
|
882 |
-
$fullsize_required = get_option( "wr2x_full_size" ) && $wr2x_admin->is_pro();
|
883 |
-
$retina_file = trailingslashit( $pathinfo['dirname'] ) . $pathinfo['filename'] . wr2x_retina_extension() . $pathinfo['extension'];
|
884 |
-
if ( $retina_file && file_exists( $retina_file ) )
|
885 |
-
$result['full-size'] = 'EXISTS';
|
886 |
-
else if ( $fullsize_required && $retina_file )
|
887 |
-
$result['full-size'] = array( 'width' => $original_width * 2, 'height' => $original_height * 2 );
|
888 |
-
//}
|
889 |
-
|
890 |
-
if ( $sizes ) {
|
891 |
-
foreach ( $sizes as $name => $attr ) {
|
892 |
-
$validSize = !empty( $attr['width'] ) || !empty( $attr['height'] );
|
893 |
-
if ( !$validSize || in_array( $name, $ignore ) ) {
|
894 |
-
$result[$name] = 'IGNORED';
|
895 |
-
continue;
|
896 |
-
}
|
897 |
-
// Check if the file related to this size is present
|
898 |
-
$pathinfo = null;
|
899 |
-
$retina_file = null;
|
900 |
-
|
901 |
-
if ( isset( $meta['sizes'][$name]['width'] ) && isset( $meta['sizes'][$name]['height']) && isset($meta['sizes'][$name]) && isset($meta['sizes'][$name]['file']) && file_exists( trailingslashit( $basepath ) . $meta['sizes'][$name]['file'] ) ) {
|
902 |
-
$normal_file = trailingslashit( $basepath ) . $meta['sizes'][$name]['file'];
|
903 |
-
$pathinfo = pathinfo( $normal_file ) ;
|
904 |
-
$retina_file = trailingslashit( $pathinfo['dirname'] ) . $pathinfo['filename'] . wr2x_retina_extension() . $pathinfo['extension'];
|
905 |
-
}
|
906 |
-
// None of the file exist
|
907 |
-
else {
|
908 |
-
$result[$name] = 'MISSING';
|
909 |
-
$required_files = false;
|
910 |
-
continue;
|
911 |
-
}
|
912 |
-
|
913 |
-
// The retina file exists
|
914 |
-
if ( $retina_file && file_exists( $retina_file ) ) {
|
915 |
-
$result[$name] = 'EXISTS';
|
916 |
-
continue;
|
917 |
-
}
|
918 |
-
// The size file exists
|
919 |
-
else if ( $retina_file )
|
920 |
-
$result[$name] = 'PENDING';
|
921 |
-
|
922 |
-
// The retina file exists
|
923 |
-
$required_width = $meta['sizes'][$name]['width'] * 2;
|
924 |
-
$required_height = $meta['sizes'][$name]['height'] * 2;
|
925 |
-
if ( !wr2x_are_dimensions_ok( $original_width, $original_height, $required_width, $required_height ) ) {
|
926 |
-
$result[$name] = array( 'width' => $required_width, 'height' => $required_height );
|
927 |
-
}
|
928 |
-
}
|
929 |
-
}
|
930 |
-
return $result;
|
931 |
-
}
|
932 |
-
|
933 |
-
function wr2x_delete_attachment( $attach_id, $deleteFullSize = true ) {
|
934 |
-
$meta = wp_get_attachment_metadata( $attach_id );
|
935 |
-
wr2x_delete_images( $meta, $deleteFullSize );
|
936 |
-
wr2x_remove_issue( $attach_id );
|
937 |
-
}
|
938 |
-
|
939 |
-
function wr2x_wp_generate_attachment_metadata( $meta ) {
|
940 |
-
if ( get_option( "wr2x_auto_generate" ) == true )
|
941 |
-
if ( wr2x_is_image_meta( $meta ) )
|
942 |
-
wr2x_generate_images( $meta );
|
943 |
-
return $meta;
|
944 |
-
}
|
945 |
-
|
946 |
-
function wr2x_generate_images( $meta ) {
|
947 |
-
require( 'wr2x_vt_resize.php' );
|
948 |
-
global $_wp_additional_image_sizes;
|
949 |
-
$sizes = wr2x_get_image_sizes();
|
950 |
-
if ( !isset( $meta['file'] ) )
|
951 |
-
return;
|
952 |
-
$originalfile = $meta['file'];
|
953 |
-
$uploads = wp_upload_dir();
|
954 |
-
$pathinfo = pathinfo( $originalfile );
|
955 |
-
$original_basename = $pathinfo['basename'];
|
956 |
-
$basepath = trailingslashit( $uploads['basedir'] ) . $pathinfo['dirname'];
|
957 |
-
$ignore = get_option( "wr2x_ignore_sizes" );
|
958 |
-
if ( empty( $ignore ) )
|
959 |
-
$ignore = array();
|
960 |
-
$ignore = array_keys( $ignore );
|
961 |
-
$issue = false;
|
962 |
-
$id = wr2x_get_attachment_id( $meta['file'] );
|
963 |
-
|
964 |
-
wr2x_log("* GENERATE RETINA FOR ATTACHMENT '{$meta['file']}'");
|
965 |
-
wr2x_log( "Full-Size is {$original_basename}." );
|
966 |
-
|
967 |
-
foreach ( $sizes as $name => $attr ) {
|
968 |
-
$normal_file = "";
|
969 |
-
if ( in_array( $name, $ignore ) ) {
|
970 |
-
wr2x_log( "Retina for {$name} ignored (settings)." );
|
971 |
-
continue;
|
972 |
-
}
|
973 |
-
// Is the file related to this size there?
|
974 |
-
$pathinfo = null;
|
975 |
-
$retina_file = null;
|
976 |
-
|
977 |
-
if ( isset( $meta['sizes'][$name] ) && isset( $meta['sizes'][$name]['file'] ) ) {
|
978 |
-
$normal_file = trailingslashit( $basepath ) . $meta['sizes'][$name]['file'];
|
979 |
-
$pathinfo = pathinfo( $normal_file ) ;
|
980 |
-
$retina_file = trailingslashit( $pathinfo['dirname'] ) . $pathinfo['filename'] . wr2x_retina_extension() . $pathinfo['extension'];
|
981 |
-
}
|
982 |
-
|
983 |
-
if ( $retina_file && file_exists( $retina_file ) ) {
|
984 |
-
wr2x_log( "Base for {$name} is '{$normal_file }'." );
|
985 |
-
wr2x_log( "Retina for {$name} already exists: '$retina_file'." );
|
986 |
-
continue;
|
987 |
-
}
|
988 |
-
if ( $retina_file ) {
|
989 |
-
$originalfile = trailingslashit( $pathinfo['dirname'] ) . $original_basename;
|
990 |
-
|
991 |
-
if ( !file_exists( $originalfile ) ) {
|
992 |
-
wr2x_log( "[ERROR] Original file '{$originalfile}' cannot be found." );
|
993 |
-
return $meta;
|
994 |
-
}
|
995 |
-
|
996 |
-
// Maybe that new image is exactly the size of the original image.
|
997 |
-
// In that case, let's make a copy of it.
|
998 |
-
if ( $meta['sizes'][$name]['width'] * 2 == $meta['width'] && $meta['sizes'][$name]['height'] * 2 == $meta['height'] ) {
|
999 |
-
copy ( $originalfile, $retina_file );
|
1000 |
-
wr2x_log( "Retina for {$name} created: '{$retina_file}' (as a copy of the full-size)." );
|
1001 |
-
}
|
1002 |
-
// Otherwise let's resize (if the original size is big enough).
|
1003 |
-
else if ( wr2x_are_dimensions_ok( $meta['width'], $meta['height'], $meta['sizes'][$name]['width'] * 2, $meta['sizes'][$name]['height'] * 2 ) ) {
|
1004 |
-
// Change proposed by Nicscott01, slighlty modified by Jordy (+isset)
|
1005 |
-
// (https://wordpress.org/support/topic/issue-with-crop-position?replies=4#post-6200271)
|
1006 |
-
$crop = isset( $_wp_additional_image_sizes[$name] ) ? $_wp_additional_image_sizes[$name]['crop'] : true;
|
1007 |
-
$customCrop = null;
|
1008 |
-
|
1009 |
-
// Support for Manual Image Crop
|
1010 |
-
// If the size of the image was manually cropped, let's keep it.
|
1011 |
-
if ( class_exists( 'ManualImageCrop' ) && isset( $meta['micSelectedArea'] ) && isset( $meta['micSelectedArea'][$name] ) && isset( $meta['micSelectedArea'][$name]['scale'] ) ) {
|
1012 |
-
$customCrop = $meta['micSelectedArea'][$name];
|
1013 |
-
}
|
1014 |
-
$image = wr2x_vt_resize( $originalfile, $meta['sizes'][$name]['width'] * 2,
|
1015 |
-
$meta['sizes'][$name]['height'] * 2, $crop, $retina_file, $customCrop );
|
1016 |
-
}
|
1017 |
-
if ( !file_exists( $retina_file ) ) {
|
1018 |
-
wr2x_log( "[ERROR] Retina for {$name} could not be created. Full-Size is " . $meta['width'] . "x" . $meta['height'] . " but Retina requires a file of at least " . $meta['sizes'][$name]['width'] * 2 . "x" . $meta['sizes'][$name]['height'] * 2 . "." );
|
1019 |
-
$issue = true;
|
1020 |
-
}
|
1021 |
-
else {
|
1022 |
-
do_action( 'wr2x_retina_file_added', $id, $retina_file, $name );
|
1023 |
-
wr2x_log( "Retina for {$name} created: '{$retina_file}'." );
|
1024 |
-
}
|
1025 |
-
} else {
|
1026 |
-
if ( empty( $normal_file ) )
|
1027 |
-
wr2x_log( "[ERROR] Base file for '{$name}' does not exist." );
|
1028 |
-
else
|
1029 |
-
wr2x_log( "[ERROR] Base file for '{$name}' cannot be found here: '{$normal_file}'." );
|
1030 |
-
}
|
1031 |
-
}
|
1032 |
-
|
1033 |
-
// Checks attachment ID + issues
|
1034 |
-
if ( !$id )
|
1035 |
-
return $meta;
|
1036 |
-
if ( $issue )
|
1037 |
-
wr2x_add_issue( $id );
|
1038 |
-
else
|
1039 |
-
wr2x_remove_issue( $id );
|
1040 |
-
return $meta;
|
1041 |
-
}
|
1042 |
-
|
1043 |
-
function wr2x_delete_images( $meta, $deleteFullSize = false ) {
|
1044 |
-
if ( !wr2x_is_image_meta( $meta ) )
|
1045 |
-
return $meta;
|
1046 |
-
$sizes = $meta['sizes'];
|
1047 |
-
if ( !$sizes || !is_array( $sizes ) )
|
1048 |
-
return $meta;
|
1049 |
-
wr2x_log("* DELETE RETINA FOR ATTACHMENT '{$meta['file']}'");
|
1050 |
-
$originalfile = $meta['file'];
|
1051 |
-
$id = wr2x_get_attachment_id( $originalfile );
|
1052 |
-
$pathinfo = pathinfo( $originalfile );
|
1053 |
-
$uploads = wp_upload_dir();
|
1054 |
-
$basepath = trailingslashit( $uploads['basedir'] ) . $pathinfo['dirname'];
|
1055 |
-
foreach ( $sizes as $name => $attr ) {
|
1056 |
-
$pathinfo = pathinfo( $attr['file'] );
|
1057 |
-
$retina_file = $pathinfo['filename'] . wr2x_retina_extension() . $pathinfo['extension'];
|
1058 |
-
if ( file_exists( trailingslashit( $basepath ) . $retina_file ) ) {
|
1059 |
-
$fullpath = trailingslashit( $basepath ) . $retina_file;
|
1060 |
-
unlink( $fullpath );
|
1061 |
-
do_action( 'wr2x_retina_file_removed', $id, $retina_file );
|
1062 |
-
wr2x_log("Deleted '$fullpath'.");
|
1063 |
-
}
|
1064 |
-
}
|
1065 |
-
// Remove full-size if there is any
|
1066 |
-
if ( $deleteFullSize ) {
|
1067 |
-
$pathinfo = pathinfo( $originalfile );
|
1068 |
-
$retina_file = $pathinfo[ 'filename' ] . wr2x_retina_extension() . $pathinfo[ 'extension' ];
|
1069 |
-
if ( file_exists( trailingslashit( $basepath ) . $retina_file ) ) {
|
1070 |
-
$fullpath = trailingslashit( $basepath ) . $retina_file;
|
1071 |
-
unlink( $fullpath );
|
1072 |
-
do_action( 'wr2x_retina_file_removed', $id, $retina_file );
|
1073 |
-
wr2x_log( "Deleted '$fullpath'." );
|
1074 |
-
}
|
1075 |
-
}
|
1076 |
-
return $meta;
|
1077 |
-
}
|
1078 |
-
|
1079 |
-
function wr2x_activate() {
|
1080 |
-
global $wp_rewrite;
|
1081 |
-
$wp_rewrite->flush_rules();
|
1082 |
-
}
|
1083 |
-
|
1084 |
-
function wr2x_deactivate() {
|
1085 |
-
remove_filter( 'generate_rewrite_rules', array( 'WR2X_Admin', 'generate_rewrite_rules' ) );
|
1086 |
-
global $wp_rewrite;
|
1087 |
-
$wp_rewrite->flush_rules();
|
1088 |
-
}
|
1089 |
-
|
1090 |
-
/**
|
1091 |
-
*
|
1092 |
-
* FILTERS
|
1093 |
-
*
|
1094 |
-
*/
|
1095 |
-
|
1096 |
-
function wr2x_validate_src( $src ) {
|
1097 |
-
if ( preg_match( "/^data:/i", $src ) )
|
1098 |
-
return null;
|
1099 |
-
return $src;
|
1100 |
-
}
|
1101 |
-
|
1102 |
-
/**
|
1103 |
-
*
|
1104 |
-
* LOAD SCRIPTS IF REQUIRED
|
1105 |
-
*
|
1106 |
-
*/
|
1107 |
-
|
1108 |
-
function wr2x_wp_enqueue_scripts () {
|
1109 |
-
global $wr2x_version, $wr2x_retinajs, $wr2x_retina_image, $wr2x_picturefill, $wr2x_lazysizes;
|
1110 |
-
global $wr2x_admin;
|
1111 |
-
$method = get_option( "wr2x_method" );
|
1112 |
-
|
1113 |
-
if ( is_admin() && !get_option( "wr2x_retina_admin" ) )
|
1114 |
-
return;
|
1115 |
-
|
1116 |
-
// Picturefill
|
1117 |
-
if ( $method == "Picturefill" ) {
|
1118 |
-
if ( wr2x_is_debug() )
|
1119 |
-
wp_enqueue_script( 'wr2x-debug', plugins_url( '/js/debug.js', __FILE__ ), array(), $wr2x_version, false );
|
1120 |
-
// Picturefill
|
1121 |
-
if ( !get_option( "wr2x_picturefill_noscript" ) )
|
1122 |
-
wp_enqueue_script( 'picturefill', plugins_url( '/js/picturefill.min.js', __FILE__ ), array(), $wr2x_picturefill, false );
|
1123 |
-
// Lazysizes
|
1124 |
-
if ( get_option( "wr2x_picturefill_lazysizes" ) && $wr2x_admin->is_pro() )
|
1125 |
-
wp_enqueue_script( 'lazysizes', plugins_url( '/js/lazysizes.min.js', __FILE__ ), array(), $wr2x_lazysizes, false );
|
1126 |
-
return;
|
1127 |
-
}
|
1128 |
-
|
1129 |
-
// Debug + HTML Rewrite = No JS!
|
1130 |
-
if ( wr2x_is_debug() && $method == "HTML Rewrite" ) {
|
1131 |
-
return;
|
1132 |
-
}
|
1133 |
-
|
1134 |
-
// Debug mode, we force the devicePixelRatio to be Retina
|
1135 |
-
if ( wr2x_is_debug() )
|
1136 |
-
wp_enqueue_script( 'wr2x-debug', plugins_url( '/js/debug.js', __FILE__ ), array(), $wr2x_version, false );
|
1137 |
-
// Not Debug Mode + Ignore Mobile
|
1138 |
-
// else if ( get_option( "wr2x_ignore_mobile" ) ) {
|
1139 |
-
// $mobileDetect = new Mobile_Detect();
|
1140 |
-
// if ( $mobileDetect->isMobile() )
|
1141 |
-
// return;
|
1142 |
-
// }
|
1143 |
-
|
1144 |
-
// Retina-Images and HTML Rewrite both need the devicePixelRatio cookie on the server-side
|
1145 |
-
if ( $method == "Retina-Images" || $method == "HTML Rewrite" )
|
1146 |
-
wp_enqueue_script( 'retina-images', plugins_url( '/js/retina-cookie.js', __FILE__ ), array(), $wr2x_retina_image, false );
|
1147 |
-
|
1148 |
-
// Retina.js only needs itself
|
1149 |
-
if ($method == "retina.js")
|
1150 |
-
wp_enqueue_script( 'retinajs', plugins_url( '/js/retina.min.js', __FILE__ ), array(), $wr2x_retinajs, true );
|
1151 |
-
}
|
1152 |
|
1153 |
-
//
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
}
|
1158 |
|
1159 |
?>
|
2 |
/*
|
3 |
Plugin Name: WP Retina 2x
|
4 |
Plugin URI: http://meowapps.com
|
5 |
+
Description: Make your website look beautiful and crisp on modern displays by creating + displaying retina images.
|
6 |
+
Version: 5.0.2
|
7 |
Author: Jordy Meow
|
8 |
Author URI: http://meowapps.com
|
9 |
Text Domain: wp-retina-2x
|
18 |
- Haikyo (http://www.haikyo.org)
|
19 |
*/
|
20 |
|
21 |
+
global $wr2x_picturefill, $wr2x_retinajs, $wr2x_lazysizes,
|
22 |
+
$wr2x_retina_image, $wr2x_core;
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
+
$wr2x_version = '5.0.2';
|
25 |
$wr2x_retinajs = '2.0.0';
|
26 |
$wr2x_picturefill = '3.0.2';
|
27 |
+
$wr2x_lazysizes = '3.0.0';
|
28 |
$wr2x_retina_image = '1.7.2';
|
|
|
29 |
|
30 |
+
// Admin
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
require( 'wr2x_admin.php');
|
32 |
+
$wr2x_admin = new Meow_WR2X_Admin( 'wr2x', __FILE__, 'wp-retina-2x' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
|
34 |
+
// Core
|
35 |
+
require( 'core.php' );
|
36 |
+
$wr2x_core = new Meow_WR2X_Core( $wr2x_admin );
|
37 |
+
$wr2x_admin->core = $wr2x_core;
|
|
|
38 |
|
39 |
?>
|
wr2x_admin.php
CHANGED
@@ -1,16 +1,16 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
|
|
4 |
|
5 |
-
|
6 |
|
7 |
-
|
8 |
-
parent::__construct( 'wr2x', 'retina' );
|
9 |
|
10 |
-
|
11 |
-
if ( $method == 666 )
|
12 |
-
$this->initial_setup();
|
13 |
|
|
|
|
|
14 |
if ( is_admin() ) {
|
15 |
add_action( 'admin_menu', array( $this, 'app_menu' ) );
|
16 |
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
@@ -20,7 +20,7 @@ class WR2X_Admin extends Meow_Admin {
|
|
20 |
function admin_notices() {
|
21 |
if ( delete_transient( 'wr2x_flush_rules' ) ) {
|
22 |
global $wp_rewrite;
|
23 |
-
|
24 |
}
|
25 |
if ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'photon' ) ) {
|
26 |
echo "<div class='error' style='margin-top: 20px;'><p>";
|
@@ -29,37 +29,16 @@ class WR2X_Admin extends Meow_Admin {
|
|
29 |
}
|
30 |
}
|
31 |
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
update_option( 'wr2x_disable_responsive', $disable_responsive, false );
|
43 |
-
$disable_medium_large = $this->old_getoption( 'disable_medium_large', 'wr2x_basics', true );
|
44 |
-
update_option( 'wr2x_disable_medium_large', $disable_medium_large, false );
|
45 |
-
$debug = $this->old_getoption( 'debug', 'wr2x_advanced', false );
|
46 |
-
update_option( 'wr2x_debug', $debug, false );
|
47 |
-
$cdn_domain = $this->old_getoption( 'cdn_domain', 'wr2x_advanced', '' );
|
48 |
-
update_option( 'wr2x_cdn_domain', $cdn_domain, false );
|
49 |
-
$picturefill_keep_src = $this->old_getoption( 'picturefill_keep_src', 'wr2x_advanced', false );
|
50 |
-
update_option( 'wr2x_picturefill_keep_src', $picturefill_keep_src, false );
|
51 |
-
$picturefill_lazysizes = $this->old_getoption( 'picturefill_lazysizes', 'wr2x_advanced', false );
|
52 |
-
update_option( 'wr2x_picturefill_lazysizes', $picturefill_lazysizes, false );
|
53 |
-
$picturefill_noscript = $this->old_getoption( 'picturefill_noscript', 'wr2x_advanced', false );
|
54 |
-
update_option( 'wr2x_picturefill_noscript', $picturefill_noscript, false );
|
55 |
-
$hide_retina_column = $this->old_getoption( 'hide_retina_column', 'wr2x_advanced', false );
|
56 |
-
update_option( 'wr2x_hide_retina_column', $hide_retina_column, false );
|
57 |
-
$hide_retina_dashboard = $this->old_getoption( 'hide_retina_dashboard', 'wr2x_advanced', false );
|
58 |
-
update_option( 'wr2x_hide_retina_dashboard', $hide_retina_dashboard, false );
|
59 |
-
delete_option( 'wr2x_basics' );
|
60 |
-
delete_option( 'wr2x_advanced' );
|
61 |
-
delete_option( 'wr2x_pro' );
|
62 |
-
}
|
63 |
|
64 |
static function generate_rewrite_rules( $wp_rewrite, $flush = false ) {
|
65 |
global $wp_rewrite;
|
@@ -171,9 +150,13 @@ class WR2X_Admin extends Meow_Admin {
|
|
171 |
add_settings_field( 'wr2x_hide_retina_dashboard', __( "Retina Dashboard", 'wp-retina-2x' ),
|
172 |
array( $this, 'admin_hide_retina_dashboard_callback' ),
|
173 |
'wr2x_ui_settings-menu', 'wr2x_ui_settings' );
|
|
|
|
|
|
|
174 |
|
175 |
register_setting( 'wr2x_ui_settings', 'wr2x_hide_retina_column' );
|
176 |
register_setting( 'wr2x_ui_settings', 'wr2x_hide_retina_dashboard' );
|
|
|
177 |
}
|
178 |
|
179 |
function admin_settings() {
|
@@ -301,7 +284,7 @@ class WR2X_Admin extends Meow_Admin {
|
|
301 |
$ignore_sizes = get_option( 'wr2x_ignore_sizes' );
|
302 |
if ( empty( $ignore_sizes ) )
|
303 |
$ignore_sizes = array();
|
304 |
-
$wpsizes =
|
305 |
$sizes = array();
|
306 |
$html = "";
|
307 |
foreach ( $wpsizes as $name => $attr ) {
|
@@ -352,7 +335,7 @@ class WR2X_Admin extends Meow_Admin {
|
|
352 |
|
353 |
function admin_full_size_callback( $args ) {
|
354 |
$value = get_option( 'wr2x_full_size', null );
|
355 |
-
$html = '<input ' . disabled( $this->
|
356 |
checked( 1, get_option( 'wr2x_full_size' ), false ) . '/>';
|
357 |
$html .= '<label>Enable</label><br /><small>Checks for retina for full-size will be enabled and upload features made available in the <i>Retina Dashboard</i>.</small>';
|
358 |
echo $html;
|
@@ -375,14 +358,14 @@ class WR2X_Admin extends Meow_Admin {
|
|
375 |
|
376 |
function admin_cdn_domain_callback( $args ) {
|
377 |
$value = get_option( 'wr2x_cdn_domain', null );
|
378 |
-
$html = '<input ' . disabled( $this->
|
379 |
$html .= __( '<br /><small>If not empty, your site domain will be replaced with this CDN domain (PictureFill and HTML Rewrite only).</small>', 'wp-retina-2x' );
|
380 |
echo $html;
|
381 |
}
|
382 |
|
383 |
function admin_over_http_check_callback( $args ) {
|
384 |
$value = get_option( 'wr2x_over_http_check', null );
|
385 |
-
$html = '<input type="checkbox" id="wr2x_over_http_check" name="wr2x_over_http_check" value="1" ' .
|
386 |
checked( 1, get_option( 'wr2x_over_http_check' ), false ) . '/>';
|
387 |
$html .= __( '<label>Enable</label><br /><small>Normally, the plugin checks if the Retina files exists through your filesystem. With this option, it will check using HTTP requests, that will enable Retina on exotic WordPress installs and also for images hosted on different servers.</small>', 'wp-retina-2x' );
|
388 |
echo $html;
|
@@ -398,7 +381,7 @@ class WR2X_Admin extends Meow_Admin {
|
|
398 |
|
399 |
function admin_picturefill_lazysizes_callback( $args ) {
|
400 |
$value = get_option( 'wr2x_picturefill_lazysizes', null );
|
401 |
-
$html = '<input ' . disabled( $this->
|
402 |
name="wr2x_picturefill_lazysizes" value="1" ' .
|
403 |
checked( 1, get_option( 'wr2x_picturefill_lazysizes' ), false ) . '/>';
|
404 |
$html .= __( '<label>Enabled</label><br /><small>Retina images will not be loaded until the visitor gets close to them. HTML will be rewritten and the lazysizes script will be also loaded. </small>', 'wp-retina-2x' );
|
@@ -407,7 +390,7 @@ class WR2X_Admin extends Meow_Admin {
|
|
407 |
|
408 |
function admin_picturefill_noscript_callback( $args ) {
|
409 |
$value = get_option( 'wr2x_picturefill_noscript', null );
|
410 |
-
$html = '<input
|
411 |
name="wr2x_picturefill_noscript" value="1" ' .
|
412 |
checked( 1, get_option( 'wr2x_picturefill_noscript' ), false ) . '/>';
|
413 |
$html .= __( '<label>Disable</label><br /><small>Only <a href="http://caniuse.com/#feat=srcset" target="_blank">the browsers with src-set support</a> will display Retina images. You can also choose this if you want to load the Picturefill Polyfill script manually or if it is already loaded by your theme.</small>', 'wp-retina-2x' );
|
@@ -416,7 +399,7 @@ class WR2X_Admin extends Meow_Admin {
|
|
416 |
|
417 |
function admin_picturefill_css_background_callback( $args ) {
|
418 |
$value = get_option( 'wr2x_picturefill_css_background', null );
|
419 |
-
$html = '<input type="checkbox" id="wr2x_picturefill_css_background" name="wr2x_picturefill_css_background" value="1" ' .
|
420 |
checked( 1, get_option( 'wr2x_picturefill_css_background' ), false ) . '/>';
|
421 |
$html .= __( '<label>Retina-ize</label><br /><small>In your HTML, inline CSS Background will be replaced by the Retina version of the image.</small>', 'wp-retina-2x' );
|
422 |
echo $html;
|
@@ -438,25 +421,13 @@ class WR2X_Admin extends Meow_Admin {
|
|
438 |
echo $html;
|
439 |
}
|
440 |
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
$options = get_option( $section );
|
449 |
-
if ( isset( $options[$option] ) ) {
|
450 |
-
if ( $options[$option] == "off" ) {
|
451 |
-
return false;
|
452 |
-
}
|
453 |
-
if ( $options[$option] == "on" ) {
|
454 |
-
return true;
|
455 |
-
}
|
456 |
-
return $options[$option];
|
457 |
-
}
|
458 |
-
return $default;
|
459 |
-
}
|
460 |
|
461 |
}
|
462 |
|
1 |
<?php
|
2 |
|
3 |
+
register_deactivation_hook( 'Meow_WR2X_Admin', 'wr2x_deactivate' );
|
4 |
+
register_activation_hook( 'Meow_WR2X_Admin', 'wr2x_activate' );
|
5 |
|
6 |
+
include "common/admin.php";
|
7 |
|
8 |
+
class Meow_WR2X_Admin extends MeowApps_Admin {
|
|
|
9 |
|
10 |
+
public $core = null;
|
|
|
|
|
11 |
|
12 |
+
public function __construct( $prefix, $mainfile, $domain ) {
|
13 |
+
parent::__construct( $prefix, $mainfile, $domain );
|
14 |
if ( is_admin() ) {
|
15 |
add_action( 'admin_menu', array( $this, 'app_menu' ) );
|
16 |
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
20 |
function admin_notices() {
|
21 |
if ( delete_transient( 'wr2x_flush_rules' ) ) {
|
22 |
global $wp_rewrite;
|
23 |
+
Meow_WR2X_Admin::generate_rewrite_rules( $wp_rewrite, true );
|
24 |
}
|
25 |
if ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'photon' ) ) {
|
26 |
echo "<div class='error' style='margin-top: 20px;'><p>";
|
29 |
}
|
30 |
}
|
31 |
|
32 |
+
static function activate() {
|
33 |
+
global $wp_rewrite;
|
34 |
+
$wp_rewrite->flush_rules();
|
35 |
+
}
|
36 |
+
|
37 |
+
static function deactivate() {
|
38 |
+
remove_filter( 'generate_rewrite_rules', array( 'Meow_WR2X_Admin', 'generate_rewrite_rules' ) );
|
39 |
+
global $wp_rewrite;
|
40 |
+
$wp_rewrite->flush_rules();
|
41 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
|
43 |
static function generate_rewrite_rules( $wp_rewrite, $flush = false ) {
|
44 |
global $wp_rewrite;
|
150 |
add_settings_field( 'wr2x_hide_retina_dashboard', __( "Retina Dashboard", 'wp-retina-2x' ),
|
151 |
array( $this, 'admin_hide_retina_dashboard_callback' ),
|
152 |
'wr2x_ui_settings-menu', 'wr2x_ui_settings' );
|
153 |
+
add_settings_field( 'wr2x_hide_pro', __( "Pro Information", 'wp-retina-2x' ),
|
154 |
+
array( $this, 'admin_hide_pro_callback' ),
|
155 |
+
'wr2x_ui_settings-menu', 'wr2x_ui_settings' );
|
156 |
|
157 |
register_setting( 'wr2x_ui_settings', 'wr2x_hide_retina_column' );
|
158 |
register_setting( 'wr2x_ui_settings', 'wr2x_hide_retina_dashboard' );
|
159 |
+
register_setting( 'wr2x_ui_settings', 'wr2x_hide_pro' );
|
160 |
}
|
161 |
|
162 |
function admin_settings() {
|
284 |
$ignore_sizes = get_option( 'wr2x_ignore_sizes' );
|
285 |
if ( empty( $ignore_sizes ) )
|
286 |
$ignore_sizes = array();
|
287 |
+
$wpsizes = $this->core->get_image_sizes();
|
288 |
$sizes = array();
|
289 |
$html = "";
|
290 |
foreach ( $wpsizes as $name => $attr ) {
|
335 |
|
336 |
function admin_full_size_callback( $args ) {
|
337 |
$value = get_option( 'wr2x_full_size', null );
|
338 |
+
$html = '<input ' . disabled( $this->is_registered(), false, false ) . ' type="checkbox" id="wr2x_full_size" name="wr2x_full_size" value="1" ' .
|
339 |
checked( 1, get_option( 'wr2x_full_size' ), false ) . '/>';
|
340 |
$html .= '<label>Enable</label><br /><small>Checks for retina for full-size will be enabled and upload features made available in the <i>Retina Dashboard</i>.</small>';
|
341 |
echo $html;
|
358 |
|
359 |
function admin_cdn_domain_callback( $args ) {
|
360 |
$value = get_option( 'wr2x_cdn_domain', null );
|
361 |
+
$html = '<input ' . disabled( $this->is_registered(), false, false ) . ' type="text" id="wr2x_cdn_domain" name="wr2x_cdn_domain" value="' . $value . '" />';
|
362 |
$html .= __( '<br /><small>If not empty, your site domain will be replaced with this CDN domain (PictureFill and HTML Rewrite only).</small>', 'wp-retina-2x' );
|
363 |
echo $html;
|
364 |
}
|
365 |
|
366 |
function admin_over_http_check_callback( $args ) {
|
367 |
$value = get_option( 'wr2x_over_http_check', null );
|
368 |
+
$html = '<input ' . disabled( $this->is_registered(), false, false ) . ' type="checkbox" id="wr2x_over_http_check" name="wr2x_over_http_check" value="1" ' .
|
369 |
checked( 1, get_option( 'wr2x_over_http_check' ), false ) . '/>';
|
370 |
$html .= __( '<label>Enable</label><br /><small>Normally, the plugin checks if the Retina files exists through your filesystem. With this option, it will check using HTTP requests, that will enable Retina on exotic WordPress installs and also for images hosted on different servers.</small>', 'wp-retina-2x' );
|
371 |
echo $html;
|
381 |
|
382 |
function admin_picturefill_lazysizes_callback( $args ) {
|
383 |
$value = get_option( 'wr2x_picturefill_lazysizes', null );
|
384 |
+
$html = '<input ' . disabled( $this->is_registered(), false, false ) . ' type="checkbox" id="wr2x_picturefill_lazysizes"
|
385 |
name="wr2x_picturefill_lazysizes" value="1" ' .
|
386 |
checked( 1, get_option( 'wr2x_picturefill_lazysizes' ), false ) . '/>';
|
387 |
$html .= __( '<label>Enabled</label><br /><small>Retina images will not be loaded until the visitor gets close to them. HTML will be rewritten and the lazysizes script will be also loaded. </small>', 'wp-retina-2x' );
|
390 |
|
391 |
function admin_picturefill_noscript_callback( $args ) {
|
392 |
$value = get_option( 'wr2x_picturefill_noscript', null );
|
393 |
+
$html = '<input type="checkbox" id="wr2x_picturefill_noscript"
|
394 |
name="wr2x_picturefill_noscript" value="1" ' .
|
395 |
checked( 1, get_option( 'wr2x_picturefill_noscript' ), false ) . '/>';
|
396 |
$html .= __( '<label>Disable</label><br /><small>Only <a href="http://caniuse.com/#feat=srcset" target="_blank">the browsers with src-set support</a> will display Retina images. You can also choose this if you want to load the Picturefill Polyfill script manually or if it is already loaded by your theme.</small>', 'wp-retina-2x' );
|
399 |
|
400 |
function admin_picturefill_css_background_callback( $args ) {
|
401 |
$value = get_option( 'wr2x_picturefill_css_background', null );
|
402 |
+
$html = '<input ' . disabled( $this->is_registered(), false, false ) . ' type="checkbox" id="wr2x_picturefill_css_background" name="wr2x_picturefill_css_background" value="1" ' .
|
403 |
checked( 1, get_option( 'wr2x_picturefill_css_background' ), false ) . '/>';
|
404 |
$html .= __( '<label>Retina-ize</label><br /><small>In your HTML, inline CSS Background will be replaced by the Retina version of the image.</small>', 'wp-retina-2x' );
|
405 |
echo $html;
|
421 |
echo $html;
|
422 |
}
|
423 |
|
424 |
+
function admin_hide_pro_callback( $args ) {
|
425 |
+
$value = get_option( 'wr2x_hide_pro', null );
|
426 |
+
$html = '<input type="checkbox" id="wr2x_hide_pro" name="wr2x_hide_pro" value="1" ' .
|
427 |
+
checked( 1, get_option( 'wr2x_hide_pro' ), false ) . '/>';
|
428 |
+
$html .= __( '<label>Hide</label><br /><small>Hide information about Pro version.</small>', 'wp-retina-2x' );
|
429 |
+
echo $html;
|
430 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
431 |
|
432 |
}
|
433 |
|
wr2x_ajax.php
DELETED
@@ -1,664 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
add_action( 'wp_ajax_wr2x_generate', 'wr2x_wp_ajax_wr2x_generate' );
|
4 |
-
add_action( 'wp_ajax_wr2x_delete', 'wr2x_wp_ajax_wr2x_delete' );
|
5 |
-
add_action( 'wp_ajax_wr2x_delete_full', 'wr2x_wp_ajax_wr2x_delete_full' );
|
6 |
-
add_action( 'wp_ajax_wr2x_list_all', 'wr2x_wp_ajax_wr2x_list_all' );
|
7 |
-
add_action( 'wp_ajax_wr2x_replace', 'wr2x_wp_ajax_wr2x_replace' );
|
8 |
-
add_action( 'wp_ajax_wr2x_upload', 'wr2x_wp_ajax_wr2x_upload' );
|
9 |
-
add_action( 'wp_ajax_wr2x_retina_details', 'wr2x_wp_ajax_wr2x_retina_details' );
|
10 |
-
add_action( 'admin_head', 'wr2x_admin_head' );
|
11 |
-
|
12 |
-
/**
|
13 |
-
*
|
14 |
-
* AJAX CLIENT-SIDE
|
15 |
-
*
|
16 |
-
*/
|
17 |
-
|
18 |
-
function wr2x_admin_head() {
|
19 |
-
?>
|
20 |
-
<script type="text/javascript" >
|
21 |
-
|
22 |
-
/* GENERATE RETINA IMAGES ACTION */
|
23 |
-
|
24 |
-
var current;
|
25 |
-
var maxPhpSize = <?php echo wr2x_get_max_filesize(); ?>;
|
26 |
-
var ids = [];
|
27 |
-
var errors = 0;
|
28 |
-
var ajax_action = "generate"; // generate | delete
|
29 |
-
|
30 |
-
function wr2x_display_please_refresh() {
|
31 |
-
wr2x_refresh_progress_status();
|
32 |
-
jQuery('#wr2x_progression').html(jQuery('#wr2x_progression').html() + " - <?php echo _e( "<a href='?page=wp-retina-2x&view=issues&refresh=true'>Refresh</a> this page.", 'wp-retina-2x' ); ?>");
|
33 |
-
}
|
34 |
-
|
35 |
-
function wr2x_refresh_progress_status() {
|
36 |
-
var errortext = "";
|
37 |
-
if ( errors > 0 ) {
|
38 |
-
errortext = ' - ' + errors + ' error(s)';
|
39 |
-
}
|
40 |
-
jQuery('#wr2x_progression').text(current + "/" + ids.length +
|
41 |
-
" (" + Math.round(current / ids.length * 100) + "%)" + errortext);
|
42 |
-
}
|
43 |
-
|
44 |
-
function wr2x_do_next () {
|
45 |
-
var data = { action: 'wr2x_' + ajax_action, attachmentId: ids[current - 1] };
|
46 |
-
wr2x_refresh_progress_status();
|
47 |
-
jQuery.post(ajaxurl, data, function (response) {
|
48 |
-
try {
|
49 |
-
reply = jQuery.parseJSON(response);
|
50 |
-
}
|
51 |
-
catch (e) {
|
52 |
-
reply = null;
|
53 |
-
}
|
54 |
-
if ( !reply || !reply.success )
|
55 |
-
errors++;
|
56 |
-
else {
|
57 |
-
wr2x_refresh_media_sizes(reply.results);
|
58 |
-
if (reply.results_full)
|
59 |
-
wr2x_refresh_full(reply.results_full);
|
60 |
-
}
|
61 |
-
if (++current <= ids.length)
|
62 |
-
wr2x_do_next();
|
63 |
-
else {
|
64 |
-
current--;
|
65 |
-
wr2x_display_please_refresh();
|
66 |
-
}
|
67 |
-
}).fail(function () {
|
68 |
-
errors++;
|
69 |
-
if (++current <= ids.length)
|
70 |
-
wr2x_do_next();
|
71 |
-
else {
|
72 |
-
current--;
|
73 |
-
wr2x_display_please_refresh();
|
74 |
-
}
|
75 |
-
});
|
76 |
-
}
|
77 |
-
|
78 |
-
function wr2x_do_all () {
|
79 |
-
current = 1;
|
80 |
-
ids = [];
|
81 |
-
errors = 0;
|
82 |
-
var data = { action: 'wr2x_list_all', issuesOnly: 0 };
|
83 |
-
jQuery('#wr2x_progression').text("<?php _e( "Wait...", 'wp-retina-2x' ); ?>");
|
84 |
-
jQuery.post(ajaxurl, data, function (response) {
|
85 |
-
reply = jQuery.parseJSON(response);
|
86 |
-
if (reply.success = false) {
|
87 |
-
alert('Error: ' + reply.message);
|
88 |
-
return;
|
89 |
-
}
|
90 |
-
if (reply.total == 0) {
|
91 |
-
jQuery('#wr2x_progression').html("<?php _e( "Nothing to do ;)", 'wp-retina-2x' ); ?>");
|
92 |
-
return;
|
93 |
-
}
|
94 |
-
ids = reply.ids;
|
95 |
-
jQuery('#wr2x_progression').text(current + "/" + ids.length + " (" + Math.round(current / ids.length * 100) + "%)");
|
96 |
-
wr2x_do_next();
|
97 |
-
});
|
98 |
-
}
|
99 |
-
|
100 |
-
function wr2x_delete_all () {
|
101 |
-
ajax_action = 'delete';
|
102 |
-
wr2x_do_all();
|
103 |
-
}
|
104 |
-
|
105 |
-
function wr2x_generate_all () {
|
106 |
-
ajax_action = 'generate';
|
107 |
-
wr2x_do_all();
|
108 |
-
}
|
109 |
-
|
110 |
-
// Refresh the dashboard retina full with the results from the Ajax operation (Upload)
|
111 |
-
function wr2x_refresh_full (results) {
|
112 |
-
jQuery.each(results, function (id, html) {
|
113 |
-
jQuery('#wr2x-info-full-' + id).html(html);
|
114 |
-
jQuery('#wr2x-info-full-' + id + ' img').attr('src', jQuery('#wr2x-info-full-' + id + ' img').attr('src')+'?'+ Math.random());
|
115 |
-
jQuery('#wr2x-info-full-' + id + ' img').on('click', function (evt) {
|
116 |
-
wr2x_delete_full( jQuery(evt.target).parents('.wr2x-file-row').attr('postid') );
|
117 |
-
});
|
118 |
-
});
|
119 |
-
}
|
120 |
-
|
121 |
-
// Refresh the dashboard media sizes with the results from the Ajax operation (Replace or Generate)
|
122 |
-
function wr2x_refresh_media_sizes (results) {
|
123 |
-
jQuery.each(results, function (id, html) {
|
124 |
-
jQuery('#wr2x-info-' + id).html(html);
|
125 |
-
});
|
126 |
-
}
|
127 |
-
|
128 |
-
function wr2x_generate (attachmentId, retinaDashboard) {
|
129 |
-
var data = { action: 'wr2x_generate', attachmentId: attachmentId };
|
130 |
-
jQuery('#wr2x_generate_button_' + attachmentId).text("<?php echo __( "Wait...", 'wp-retina-2x' ); ?>");
|
131 |
-
jQuery.post(ajaxurl, data, function (response) {
|
132 |
-
var reply = jQuery.parseJSON(response);
|
133 |
-
if (!reply.success) {
|
134 |
-
alert(reply.message);
|
135 |
-
return;
|
136 |
-
}
|
137 |
-
jQuery('#wr2x_generate_button_' + attachmentId).html("<?php echo __( "GENERATE", 'wp-retina-2x' ); ?>");
|
138 |
-
wr2x_refresh_media_sizes(reply.results);
|
139 |
-
});
|
140 |
-
}
|
141 |
-
|
142 |
-
/* REPLACE FUNCTION */
|
143 |
-
|
144 |
-
function wr2x_stop_propagation(evt) {
|
145 |
-
evt.stopPropagation();
|
146 |
-
evt.preventDefault();
|
147 |
-
}
|
148 |
-
|
149 |
-
function wr2x_delete_full(attachmentId) {
|
150 |
-
var data = {
|
151 |
-
action: 'wr2x_delete_full',
|
152 |
-
isAjax: true,
|
153 |
-
attachmentId: attachmentId
|
154 |
-
};
|
155 |
-
|
156 |
-
jQuery.post(ajaxurl, data, function (response) {
|
157 |
-
var data = jQuery.parseJSON(response);
|
158 |
-
if (data.success === false) {
|
159 |
-
alert(data.message);
|
160 |
-
}
|
161 |
-
else {
|
162 |
-
wr2x_refresh_full(data.results);
|
163 |
-
wr2x_display_please_refresh();
|
164 |
-
}
|
165 |
-
});
|
166 |
-
}
|
167 |
-
|
168 |
-
function wr2x_load_details(attachmentId) {
|
169 |
-
var data = {
|
170 |
-
action: 'wr2x_retina_details',
|
171 |
-
isAjax: true,
|
172 |
-
attachmentId: attachmentId
|
173 |
-
};
|
174 |
-
|
175 |
-
jQuery.post(ajaxurl, data, function (response) {
|
176 |
-
var data = jQuery.parseJSON(response);
|
177 |
-
if (data.success === false) {
|
178 |
-
alert(data.message);
|
179 |
-
}
|
180 |
-
else {
|
181 |
-
jQuery('#meow-modal-info .loading').css('display', 'none');
|
182 |
-
jQuery('#meow-modal-info .content').html(data.result);
|
183 |
-
}
|
184 |
-
});
|
185 |
-
}
|
186 |
-
|
187 |
-
function wr2x_filedropped (evt) {
|
188 |
-
wr2x_stop_propagation(evt);
|
189 |
-
var files = evt.dataTransfer.files;
|
190 |
-
var count = files.length;
|
191 |
-
if (count < 0) {
|
192 |
-
return;
|
193 |
-
}
|
194 |
-
|
195 |
-
var wr2x_replace = jQuery(evt.target).parent().hasClass('wr2x-fullsize-replace');
|
196 |
-
var wr2x_upload = jQuery(evt.target).parent().hasClass('wr2x-fullsize-retina-upload');
|
197 |
-
|
198 |
-
function wr2x_handleprogress(prg) {
|
199 |
-
console.debug("Upload of " + prg.srcElement.filename + ": " + prg.loaded / prg.total * 100 + "%");
|
200 |
-
}
|
201 |
-
|
202 |
-
function wr2x_uploadFile(file, attachmentId, filename) {
|
203 |
-
var action = "";
|
204 |
-
if (wr2x_replace) {
|
205 |
-
action = 'wr2x_replace';
|
206 |
-
}
|
207 |
-
else if (wr2x_upload) {
|
208 |
-
action = 'wr2x_upload';
|
209 |
-
}
|
210 |
-
else {
|
211 |
-
alert("Unknown command. Contact the developer.");
|
212 |
-
}
|
213 |
-
var data = new FormData();
|
214 |
-
data.append('file', file);
|
215 |
-
data.append('action', action);
|
216 |
-
data.append('attachmentId', attachmentId);
|
217 |
-
data.append('isAjax', true);
|
218 |
-
data.append('filename', filename);
|
219 |
-
// var data = {
|
220 |
-
// action: action,
|
221 |
-
// isAjax: true,
|
222 |
-
// filename: evt.target.filename,
|
223 |
-
// data: form_data,
|
224 |
-
// attachmentId: attachmentId
|
225 |
-
// };
|
226 |
-
|
227 |
-
jQuery.ajax({
|
228 |
-
type: 'POST',
|
229 |
-
url: ajaxurl,
|
230 |
-
contentType: false,
|
231 |
-
processData: false,
|
232 |
-
data: data,
|
233 |
-
success: function (response) {
|
234 |
-
jQuery('[postid=' + attachmentId + '] td').removeClass('wr2x-loading-file');
|
235 |
-
jQuery('[postid=' + attachmentId + '] .wr2x-dragdrop').removeClass('wr2x-hover-drop');
|
236 |
-
try {
|
237 |
-
var data = jQuery.parseJSON(response);
|
238 |
-
}
|
239 |
-
catch (e) {
|
240 |
-
alert("The server-side returned an abnormal response. Check your PHP error logs and also your browser console (WP Retina 2x will try to display it there).");
|
241 |
-
console.debug(response);
|
242 |
-
return;
|
243 |
-
}
|
244 |
-
if (wr2x_replace) {
|
245 |
-
var imgSelector = '[postid=' + attachmentId + '] .wr2x-info-thumbnail img';
|
246 |
-
jQuery(imgSelector).attr('src', jQuery(imgSelector).attr('src')+'?'+ Math.random());
|
247 |
-
}
|
248 |
-
if (wr2x_upload) {
|
249 |
-
var imgSelector = '[postid=' + attachmentId + '] .wr2x-info-full img';
|
250 |
-
jQuery(imgSelector).attr('src', jQuery(imgSelector).attr('src')+'?'+ Math.random());
|
251 |
-
}
|
252 |
-
if (data.success === false) {
|
253 |
-
alert(data.message);
|
254 |
-
}
|
255 |
-
else {
|
256 |
-
if ( wr2x_replace ) {
|
257 |
-
wr2x_refresh_media_sizes(data.results);
|
258 |
-
}
|
259 |
-
else if ( wr2x_upload ) {
|
260 |
-
wr2x_refresh_full(data.results);
|
261 |
-
}
|
262 |
-
}
|
263 |
-
},
|
264 |
-
error: function(XMLHttpRequest, textStatus, errorThrown) {
|
265 |
-
jQuery('[postid=' + attachmentId + '] td').removeClass('wr2x-loading-file');
|
266 |
-
jQuery('[postid=' + attachmentId + '] .wr2x-dragdrop').removeClass('wr2x-hover-drop');
|
267 |
-
alert("An error occurred on the server-side. Please check your PHP error logs.");
|
268 |
-
}
|
269 |
-
});
|
270 |
-
}
|
271 |
-
var file = files[0];
|
272 |
-
if (file.size > maxPhpSize) {
|
273 |
-
jQuery(this).removeClass('wr2x-hover-drop');
|
274 |
-
alert( "Your PHP configuration only allows file upload of a maximum of " + (maxPhpSize / 1000000) + "MB." );
|
275 |
-
return;
|
276 |
-
}
|
277 |
-
var postId = jQuery(evt.target).parents('.wr2x-file-row').attr('postid');
|
278 |
-
jQuery(evt.target).parents('td').addClass('wr2x-loading-file');
|
279 |
-
wr2x_uploadFile(file, postId, file.name);
|
280 |
-
}
|
281 |
-
|
282 |
-
jQuery(document).ready(function () {
|
283 |
-
jQuery('.wr2x-dragdrop').on('dragenter', function (evt) {
|
284 |
-
wr2x_stop_propagation(evt);
|
285 |
-
jQuery(this).addClass('wr2x-hover-drop');
|
286 |
-
});
|
287 |
-
|
288 |
-
jQuery('.wr2x-dragdrop').on('dragover', function (evt) {
|
289 |
-
wr2x_stop_propagation(evt);
|
290 |
-
jQuery(this).addClass('wr2x-hover-drop');
|
291 |
-
});
|
292 |
-
|
293 |
-
jQuery('.wr2x-dragdrop').on('dragleave', function (evt) {
|
294 |
-
wr2x_stop_propagation(evt);
|
295 |
-
jQuery(this).removeClass('wr2x-hover-drop');
|
296 |
-
});
|
297 |
-
|
298 |
-
jQuery('.wr2x-dragdrop').on('dragexit', wr2x_stop_propagation);
|
299 |
-
|
300 |
-
jQuery('.wr2x-dragdrop').each(function (index, elem) {
|
301 |
-
this.addEventListener('drop', wr2x_filedropped);
|
302 |
-
});
|
303 |
-
|
304 |
-
jQuery('.wr2x-info, .wr2x-button-view').on('click', function (evt) {
|
305 |
-
jQuery('#meow-modal-info-backdrop').css('display', 'block');
|
306 |
-
jQuery('#meow-modal-info .content').html("");
|
307 |
-
jQuery('#meow-modal-info .loading').css('display', 'block');
|
308 |
-
jQuery('#meow-modal-info').css('display', 'block');
|
309 |
-
jQuery('#meow-modal-info').focus();
|
310 |
-
var postid = jQuery(evt.target).parents('.wr2x-info').attr('postid');
|
311 |
-
if (!postid)
|
312 |
-
postid = jQuery(evt.target).parents('.wr2x-file-row').attr('postid');
|
313 |
-
wr2x_load_details(postid);
|
314 |
-
});
|
315 |
-
|
316 |
-
jQuery('#meow-modal-info .close, #meow-modal-info-backdrop').on('click', function (evt) {
|
317 |
-
jQuery('#meow-modal-info').css('display', 'none');
|
318 |
-
jQuery('#meow-modal-info-backdrop').css('display', 'none');
|
319 |
-
});
|
320 |
-
|
321 |
-
jQuery('.wr2x-info-full img').on('click', function (evt) {
|
322 |
-
wr2x_delete_full( jQuery(evt.target).parents('.wr2x-file-row').attr('postid') );
|
323 |
-
});
|
324 |
-
|
325 |
-
jQuery('#meow-modal-info').bind('keydown', function (evt) {
|
326 |
-
if (evt.keyCode === 27) {
|
327 |
-
jQuery('#meow-modal-info').css('display', 'none');
|
328 |
-
jQuery('#meow-modal-info-backdrop').css('display', 'none');
|
329 |
-
}
|
330 |
-
});
|
331 |
-
});
|
332 |
-
|
333 |
-
</script>
|
334 |
-
<?php
|
335 |
-
}
|
336 |
-
|
337 |
-
/**
|
338 |
-
*
|
339 |
-
* AJAX SERVER-SIDE
|
340 |
-
*
|
341 |
-
*/
|
342 |
-
|
343 |
-
// Using issuesOnly, only the IDs with a PENDING status will be processed
|
344 |
-
function wr2x_wp_ajax_wr2x_list_all( $issuesOnly ) {
|
345 |
-
$issuesOnly = intval( $_POST['issuesOnly'] );
|
346 |
-
if ( $issuesOnly == 1 ) {
|
347 |
-
$ids = wr2x_get_issues();
|
348 |
-
echo json_encode(
|
349 |
-
array(
|
350 |
-
'success' => true,
|
351 |
-
'message' => "List of issues only.",
|
352 |
-
'ids' => $ids,
|
353 |
-
'total' => count( $ids )
|
354 |
-
) );
|
355 |
-
die;
|
356 |
-
}
|
357 |
-
$reply = array();
|
358 |
-
try {
|
359 |
-
$ids = array();
|
360 |
-
$total = 0;
|
361 |
-
global $wpdb;
|
362 |
-
$postids = $wpdb->get_col( "
|
363 |
-
SELECT p.ID
|
364 |
-
FROM $wpdb->posts p
|
365 |
-
WHERE post_status = 'inherit'
|
366 |
-
AND post_type = 'attachment'
|
367 |
-
AND ( post_mime_type = 'image/jpeg' OR
|
368 |
-
post_mime_type = 'image/png' OR
|
369 |
-
post_mime_type = 'image/gif' )
|
370 |
-
" );
|
371 |
-
foreach ($postids as $id) {
|
372 |
-
if ( wr2x_is_ignore( $id ) )
|
373 |
-
continue;
|
374 |
-
array_push( $ids, $id );
|
375 |
-
$total++;
|
376 |
-
}
|
377 |
-
echo json_encode(
|
378 |
-
array(
|
379 |
-
'success' => true,
|
380 |
-
'message' => "List of everything.",
|
381 |
-
'ids' => $ids,
|
382 |
-
'total' => $total
|
383 |
-
) );
|
384 |
-
die;
|
385 |
-
}
|
386 |
-
catch (Exception $e) {
|
387 |
-
echo json_encode(
|
388 |
-
array(
|
389 |
-
'success' => false,
|
390 |
-
'message' => $e->getMessage()
|
391 |
-
) );
|
392 |
-
die;
|
393 |
-
}
|
394 |
-
}
|
395 |
-
|
396 |
-
function wr2x_wp_ajax_wr2x_delete_full( $pleaseReturn = false ) {
|
397 |
-
|
398 |
-
if ( !isset( $_POST['attachmentId'] ) ) {
|
399 |
-
echo json_encode(
|
400 |
-
array(
|
401 |
-
'success' => false,
|
402 |
-
'message' => __( "The attachment ID is missing.", 'wp-retina-2x' )
|
403 |
-
)
|
404 |
-
);
|
405 |
-
die();
|
406 |
-
}
|
407 |
-
$attachmentId = intval( $_POST['attachmentId'] );
|
408 |
-
$originalfile = get_attached_file( $attachmentId );
|
409 |
-
$pathinfo = pathinfo( $originalfile );
|
410 |
-
$retina_file = trailingslashit( $pathinfo['dirname'] ) . $pathinfo['filename'] . wr2x_retina_extension() . $pathinfo['extension'];
|
411 |
-
if ( $retina_file && file_exists( $retina_file ) )
|
412 |
-
unlink( $retina_file );
|
413 |
-
|
414 |
-
// RESULTS FOR RETINA DASHBOARD
|
415 |
-
$info = wpr2x_html_get_basic_retina_info_full( $attachmentId, wr2x_retina_info( $attachmentId ) );
|
416 |
-
$results[$attachmentId] = $info;
|
417 |
-
|
418 |
-
// Return if that's not the final step.
|
419 |
-
if ( $pleaseReturn )
|
420 |
-
return $info;
|
421 |
-
|
422 |
-
echo json_encode(
|
423 |
-
array(
|
424 |
-
'results' => $results,
|
425 |
-
'success' => true,
|
426 |
-
'message' => __( "Full retina file deleted.", 'wp-retina-2x' )
|
427 |
-
)
|
428 |
-
);
|
429 |
-
die();
|
430 |
-
}
|
431 |
-
|
432 |
-
function wr2x_wp_ajax_wr2x_delete() {
|
433 |
-
|
434 |
-
if ( !isset( $_POST['attachmentId'] ) ) {
|
435 |
-
echo json_encode(
|
436 |
-
array(
|
437 |
-
'success' => false,
|
438 |
-
'message' => __( "The attachment ID is missing.", 'wp-retina-2x' )
|
439 |
-
)
|
440 |
-
);
|
441 |
-
die();
|
442 |
-
}
|
443 |
-
|
444 |
-
// Information for the retina version of the full-size
|
445 |
-
$attachmentId = intval( $_POST['attachmentId'] );
|
446 |
-
$results_full[$attachmentId] = wr2x_wp_ajax_wr2x_delete_full( true );
|
447 |
-
|
448 |
-
wr2x_delete_attachment( $attachmentId, true );
|
449 |
-
$meta = wp_get_attachment_metadata( $attachmentId );
|
450 |
-
|
451 |
-
// RESULTS FOR RETINA DASHBOARD
|
452 |
-
wr2x_update_issue_status( $attachmentId );
|
453 |
-
$info = wpr2x_html_get_basic_retina_info( $attachmentId, wr2x_retina_info( $attachmentId ) );
|
454 |
-
$results[$attachmentId] = $info;
|
455 |
-
echo json_encode(
|
456 |
-
array(
|
457 |
-
'results' => $results,
|
458 |
-
'results_full' => $results_full,
|
459 |
-
'success' => true,
|
460 |
-
'message' => __( "Retina files deleted.", 'wp-retina-2x' )
|
461 |
-
)
|
462 |
-
);
|
463 |
-
die();
|
464 |
-
}
|
465 |
-
|
466 |
-
function wr2x_wp_ajax_wr2x_retina_details() {
|
467 |
-
if ( !isset( $_POST['attachmentId'] ) ) {
|
468 |
-
echo json_encode(
|
469 |
-
array(
|
470 |
-
'success' => false,
|
471 |
-
'message' => __( "The attachment ID is missing.", 'wp-retina-2x' )
|
472 |
-
)
|
473 |
-
);
|
474 |
-
die();
|
475 |
-
}
|
476 |
-
|
477 |
-
$attachmentId = intval( $_POST['attachmentId'] );
|
478 |
-
$info = wpr2x_html_get_details_retina_info( $attachmentId, wr2x_retina_info( $attachmentId ) );
|
479 |
-
echo json_encode(
|
480 |
-
array(
|
481 |
-
'result' => $info,
|
482 |
-
'success' => true,
|
483 |
-
'message' => __( "Details retrieved.", 'wp-retina-2x' )
|
484 |
-
)
|
485 |
-
);
|
486 |
-
die();
|
487 |
-
}
|
488 |
-
|
489 |
-
function wr2x_wp_ajax_wr2x_generate() {
|
490 |
-
if ( !isset( $_POST['attachmentId'] ) ) {
|
491 |
-
echo json_encode(
|
492 |
-
array(
|
493 |
-
'success' => false,
|
494 |
-
'message' => __( "The attachment ID is missing.", 'wp-retina-2x' )
|
495 |
-
)
|
496 |
-
);
|
497 |
-
die();
|
498 |
-
}
|
499 |
-
|
500 |
-
$attachmentId = intval( $_POST['attachmentId'] );
|
501 |
-
wr2x_delete_attachment( $attachmentId, false );
|
502 |
-
|
503 |
-
// Regenerate the Thumbnails
|
504 |
-
$file = get_attached_file( $attachmentId );
|
505 |
-
$meta = wp_generate_attachment_metadata( $attachmentId, $file );
|
506 |
-
wp_update_attachment_metadata( $attachmentId, $meta );
|
507 |
-
|
508 |
-
// Regenerate Retina
|
509 |
-
//$meta = wp_get_attachment_metadata( $attachmentId );
|
510 |
-
wr2x_generate_images( $meta );
|
511 |
-
|
512 |
-
// RESULTS FOR RETINA DASHBOARD
|
513 |
-
$info = wpr2x_html_get_basic_retina_info( $attachmentId, wr2x_retina_info( $attachmentId ) );
|
514 |
-
$results[$attachmentId] = $info;
|
515 |
-
echo json_encode(
|
516 |
-
array(
|
517 |
-
'results' => $results,
|
518 |
-
'success' => true,
|
519 |
-
'message' => __( "Retina files generated.", 'wp-retina-2x' )
|
520 |
-
)
|
521 |
-
);
|
522 |
-
die();
|
523 |
-
}
|
524 |
-
|
525 |
-
function wr2x_check_get_ajax_uploaded_file() {
|
526 |
-
|
527 |
-
if ( !current_user_can('upload_files') ) {
|
528 |
-
echo json_encode( array(
|
529 |
-
'success' => false,
|
530 |
-
'message' => __( "You do not have permission to upload files.", 'wp-retina-2x' )
|
531 |
-
));
|
532 |
-
die();
|
533 |
-
}
|
534 |
-
|
535 |
-
$tmpfname = $_FILES['file']['tmp_name'];
|
536 |
-
|
537 |
-
// Check if it is an image
|
538 |
-
$file_info = getimagesize( $tmpfname );
|
539 |
-
if ( empty( $file_info ) ) {
|
540 |
-
wr2x_log( "The file is not an image or the upload went wrong." );
|
541 |
-
unlink( $tmpfname );
|
542 |
-
echo json_encode( array(
|
543 |
-
'success' => false,
|
544 |
-
'message' => __( "The file is not an image or the upload went wrong.", 'wp-retina-2x' )
|
545 |
-
));
|
546 |
-
die();
|
547 |
-
}
|
548 |
-
|
549 |
-
$filedata = wp_check_filetype_and_ext( $tmpfname, $_POST['filename'] );
|
550 |
-
if ( $filedata["ext"] == "" ) {
|
551 |
-
wr2x_log( "You cannot use this file (wrong extension? wrong type?)." );
|
552 |
-
unlink( $current_file );
|
553 |
-
echo json_encode( array(
|
554 |
-
'success' => false,
|
555 |
-
'message' => __( "You cannot use this file (wrong extension? wrong type?).", 'wp-retina-2x' )
|
556 |
-
));
|
557 |
-
die();
|
558 |
-
}
|
559 |
-
|
560 |
-
wr2x_log( "The temporary file was written successfully." );
|
561 |
-
return $tmpfname;
|
562 |
-
}
|
563 |
-
|
564 |
-
function wr2x_wp_ajax_wr2x_upload() {
|
565 |
-
try {
|
566 |
-
$tmpfname = wr2x_check_get_ajax_uploaded_file();
|
567 |
-
$attachmentId = (int) $_POST['attachmentId'];
|
568 |
-
$meta = wp_get_attachment_metadata( $attachmentId );
|
569 |
-
$current_file = get_attached_file( $attachmentId );
|
570 |
-
$pathinfo = pathinfo( $current_file );
|
571 |
-
$basepath = $pathinfo['dirname'];
|
572 |
-
$retinafile = trailingslashit( $pathinfo['dirname'] ) . $pathinfo['filename'] . wr2x_retina_extension() . $pathinfo['extension'];
|
573 |
-
|
574 |
-
if ( file_exists( $retinafile ) )
|
575 |
-
unlink( $retinafile );
|
576 |
-
|
577 |
-
// Insert the new file and delete the temporary one
|
578 |
-
list( $width, $height ) = getimagesize( $tmpfname );
|
579 |
-
|
580 |
-
if ( !wr2x_are_dimensions_ok( $width, $height, $meta['width'] * 2, $meta['height'] * 2 ) ) {
|
581 |
-
echo json_encode( array(
|
582 |
-
'success' => false,
|
583 |
-
'message' => "This image has a resolution of ${width}×${height} but your Full Size image requires a retina image of at least " . ( $meta['width'] * 2 ) . "x" . ( $meta['height'] * 2 ) . "."
|
584 |
-
));
|
585 |
-
die();
|
586 |
-
}
|
587 |
-
require('wr2x_vt_resize.php');
|
588 |
-
wr2x_vt_resize( $tmpfname, $meta['width'] * 2, $meta['height'] * 2, null, $retinafile );
|
589 |
-
chmod( $retinafile, 0644 );
|
590 |
-
unlink( $tmpfname );
|
591 |
-
|
592 |
-
// Get the results
|
593 |
-
$info = wr2x_retina_info( $attachmentId );
|
594 |
-
wr2x_update_issue_status( $attachmentId );
|
595 |
-
$results[$attachmentId] = wpr2x_html_get_basic_retina_info_full( $attachmentId, $info );
|
596 |
-
}
|
597 |
-
catch (Exception $e) {
|
598 |
-
echo json_encode( array(
|
599 |
-
'success' => false,
|
600 |
-
'results' => null,
|
601 |
-
'message' => __( "Error: " . $e->getMessage(), 'wp-retina-2x' )
|
602 |
-
));
|
603 |
-
die();
|
604 |
-
}
|
605 |
-
echo json_encode( array(
|
606 |
-
'success' => true,
|
607 |
-
'results' => $results,
|
608 |
-
'message' => __( "Uploaded successfully.", 'wp-retina-2x' )
|
609 |
-
));
|
610 |
-
die();
|
611 |
-
}
|
612 |
-
|
613 |
-
function wr2x_wp_ajax_wr2x_replace() {
|
614 |
-
$tmpfname = wr2x_check_get_ajax_uploaded_file();
|
615 |
-
$attachmentId = (int) $_POST['attachmentId'];
|
616 |
-
$meta = wp_get_attachment_metadata( $attachmentId );
|
617 |
-
$current_file = get_attached_file( $attachmentId );
|
618 |
-
wr2x_delete_attachment( $attachmentId, false );
|
619 |
-
$pathinfo = pathinfo( $current_file );
|
620 |
-
$basepath = $pathinfo['dirname'];
|
621 |
-
|
622 |
-
// Let's clean everything first
|
623 |
-
if ( wp_attachment_is_image( $attachmentId ) ) {
|
624 |
-
$sizes = wr2x_get_image_sizes();
|
625 |
-
foreach ($sizes as $name => $attr) {
|
626 |
-
if ( isset( $meta['sizes'][$name] ) && isset( $meta['sizes'][$name]['file'] ) && file_exists( trailingslashit( $basepath ) . $meta['sizes'][$name]['file'] ) ) {
|
627 |
-
$normal_file = trailingslashit( $basepath ) . $meta['sizes'][$name]['file'];
|
628 |
-
$pathinfo = pathinfo( $normal_file );
|
629 |
-
$retina_file = trailingslashit( $pathinfo['dirname'] ) . $pathinfo['filename'] . wr2x_retina_extension() . $pathinfo['extension'];
|
630 |
-
|
631 |
-
// Test if the file exists and if it is actually a file (and not a dir)
|
632 |
-
// Some old WordPress Media Library are sometimes broken and link to directories
|
633 |
-
if ( file_exists( $normal_file ) && is_file( $normal_file ) )
|
634 |
-
unlink( $normal_file );
|
635 |
-
if ( file_exists( $retina_file ) && is_file( $retina_file ) )
|
636 |
-
unlink( $retina_file );
|
637 |
-
}
|
638 |
-
}
|
639 |
-
}
|
640 |
-
if ( file_exists( $current_file ) )
|
641 |
-
unlink( $current_file );
|
642 |
-
|
643 |
-
// Insert the new file and delete the temporary one
|
644 |
-
rename( $tmpfname, $current_file );
|
645 |
-
chmod( $current_file, 0644 );
|
646 |
-
|
647 |
-
// Generate the images
|
648 |
-
wp_update_attachment_metadata( $attachmentId, wp_generate_attachment_metadata( $attachmentId, $current_file ) );
|
649 |
-
$meta = wp_get_attachment_metadata( $attachmentId );
|
650 |
-
wr2x_generate_images( $meta );
|
651 |
-
|
652 |
-
// Get the results
|
653 |
-
$info = wr2x_retina_info( $attachmentId );
|
654 |
-
$results[$attachmentId] = wpr2x_html_get_basic_retina_info( $attachmentId, $info );
|
655 |
-
|
656 |
-
echo json_encode( array(
|
657 |
-
'success' => true,
|
658 |
-
'results' => $results,
|
659 |
-
'message' => __( "Replaced successfully.", 'wp-retina-2x' )
|
660 |
-
));
|
661 |
-
die();
|
662 |
-
}
|
663 |
-
|
664 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wr2x_media-library.php
DELETED
@@ -1,54 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
add_filter( 'manage_media_columns', 'wr2x_manage_media_columns' );
|
4 |
-
add_action( 'manage_media_custom_column', 'wr2x_manage_media_custom_column', 10, 2 );
|
5 |
-
add_action( 'admin_footer', 'wr2x_admin_footer_library' );
|
6 |
-
|
7 |
-
/**
|
8 |
-
*
|
9 |
-
* MEDIA LIBRARY
|
10 |
-
*
|
11 |
-
*/
|
12 |
-
|
13 |
-
function wr2x_manage_media_columns( $cols ) {
|
14 |
-
$cols["Retina"] = "Retina";
|
15 |
-
return $cols;
|
16 |
-
}
|
17 |
-
|
18 |
-
function wr2x_manage_media_custom_column( $column_name, $id ) {
|
19 |
-
if ( $column_name == 'Retina' ) {
|
20 |
-
$info = wr2x_retina_info( $id );
|
21 |
-
if ( empty( $info ) )
|
22 |
-
return;
|
23 |
-
$info = wpr2x_html_get_basic_retina_info( $id, $info );
|
24 |
-
echo "<a style='' onclick='wr2x_generate(" . $id . ", true)' id='wr2x_generate_button_" . $id . "' class='wr2x-button'>" . __( "GENERATE", 'wp-retina-2x' ) . "</a><br />";
|
25 |
-
echo '<div class="wr2x-info" postid="' . $id . '" id="wr2x-info-' . $id . '">';
|
26 |
-
echo $info;
|
27 |
-
echo '</div>';
|
28 |
-
}
|
29 |
-
else if ( $column_name == 'Retina-Actions' ) {
|
30 |
-
}
|
31 |
-
}
|
32 |
-
|
33 |
-
function wr2x_admin_footer_library() {
|
34 |
-
$screen = get_current_screen();
|
35 |
-
if ( $screen->base != 'upload' && $screen->base != 'media_page_wp-retina-2x' )
|
36 |
-
return;
|
37 |
-
?>
|
38 |
-
<div id="meow-modal-info-backdrop" style="display: none;">
|
39 |
-
</div>
|
40 |
-
|
41 |
-
<div id="meow-modal-info" style="display: none;" tabindex="1">
|
42 |
-
<div class="close">X</div>
|
43 |
-
<h2 style="margin-top: 0px;">Retina Details</h2>
|
44 |
-
<div class="loading">
|
45 |
-
<img src="<?php echo plugin_dir_url( __FILE__ ); ?>img/loading.gif" />
|
46 |
-
</div>
|
47 |
-
<div class="content">
|
48 |
-
</div>
|
49 |
-
</div>
|
50 |
-
<?php
|
51 |
-
}
|
52 |
-
|
53 |
-
|
54 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wr2x_responsive.php
DELETED
@@ -1,45 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
add_filter( 'wp_calculate_image_srcset', 'wr2x_wp_calculate_image_srcset', 1000, 2 );
|
4 |
-
//add_filter( 'wp_calculate_image_sizes', 'wr2x_wp_calculate_image_sizes', 1000, 2 );
|
5 |
-
//add_filter( 'wp_get_attachment_image_attributes', 'wr2x_wp_get_attachment_image_attributes', 1000, 2 );
|
6 |
-
|
7 |
-
/**
|
8 |
-
*
|
9 |
-
* SUPPORT FOR WP 4.4
|
10 |
-
*
|
11 |
-
*/
|
12 |
-
|
13 |
-
function wr2x_wp_calculate_image_srcset( $srcset, $size ) {
|
14 |
-
if ( get_option( "wr2x_disable_responsive" ) )
|
15 |
-
return null;
|
16 |
-
$method = get_option( "wr2x_method" );
|
17 |
-
if ( $method == "none" )
|
18 |
-
return $srcset;
|
19 |
-
$count = 0;
|
20 |
-
$total = 0;
|
21 |
-
$retinized_srcset = $srcset;
|
22 |
-
if ( empty( $srcset ) )
|
23 |
-
return $srcset;
|
24 |
-
foreach ( $srcset as $s => $cfg ) {
|
25 |
-
$total++;
|
26 |
-
$retina = wr2x_get_retina_from_url( $cfg['url'] );
|
27 |
-
if ( !empty( $retina ) ) {
|
28 |
-
$count++;
|
29 |
-
$retinized_srcset[(int)$s * 2] = array(
|
30 |
-
'url' => $retina,
|
31 |
-
'descriptor' => 'w',
|
32 |
-
'value' => (int)$s * 2 );
|
33 |
-
}
|
34 |
-
}
|
35 |
-
wr2x_log( "WP's srcset: " . $count . " retina files added out of " . $total . " image sizes" );
|
36 |
-
return $retinized_srcset;
|
37 |
-
}
|
38 |
-
|
39 |
-
function wr2x_wp_calculate_image_sizes( $srcset, $size ) {
|
40 |
-
}
|
41 |
-
|
42 |
-
function wr2x_wp_get_attachment_image_attributes( $srcset, $size ) {
|
43 |
-
}
|
44 |
-
|
45 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wr2x_retina-dashboard.php
DELETED
@@ -1,315 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
add_action( 'admin_menu', 'wr2x_admin_menu_dashboard' );
|
4 |
-
|
5 |
-
/**
|
6 |
-
*
|
7 |
-
* RETINA DASHBOARD
|
8 |
-
*
|
9 |
-
*/
|
10 |
-
|
11 |
-
function wr2x_admin_menu_dashboard () {
|
12 |
-
global $wr2x_admin;
|
13 |
-
$refresh = isset ( $_GET[ 'refresh' ] ) ? $_GET[ 'refresh' ] : 0;
|
14 |
-
$clearlogs = isset ( $_GET[ 'clearlogs' ] ) ? $_GET[ 'clearlogs' ] : 0;
|
15 |
-
$ignore = isset ( $_GET[ 'ignore' ] ) ? $_GET[ 'ignore' ] : false;
|
16 |
-
if ( $ignore ) {
|
17 |
-
if ( !$wr2x_admin->is_pro() ) {
|
18 |
-
echo "<div class='error' style='margin-top: 20px;'><p>";
|
19 |
-
_e( "Ignore is a Pro feature.", 'wp-retina-2x' );
|
20 |
-
echo "</p></div>";
|
21 |
-
}
|
22 |
-
else
|
23 |
-
wr2x_add_ignore( $ignore );
|
24 |
-
}
|
25 |
-
if ( $refresh ) {
|
26 |
-
wr2x_calculate_issues();
|
27 |
-
}
|
28 |
-
if ( $clearlogs ) {
|
29 |
-
if ( file_exists( plugin_dir_path( __FILE__ ) . '/wp-retina-2x.log' ) ) {
|
30 |
-
unlink( plugin_dir_path( __FILE__ ) . '/wp-retina-2x.log' );
|
31 |
-
}
|
32 |
-
}
|
33 |
-
$flagged = count( wr2x_get_issues() );
|
34 |
-
$warning_title = __( "Retina images", 'wp-retina-2x' );
|
35 |
-
$menu_label = sprintf( __( 'Retina %s' ), "<span class='update-plugins count-$flagged' title='$warning_title'><span class='update-count'>" . number_format_i18n( $flagged ) . "</span></span>" );
|
36 |
-
add_media_page( 'Retina', $menu_label, 'manage_options', 'wp-retina-2x', 'wpr2x_wp_retina_2x' );
|
37 |
-
}
|
38 |
-
|
39 |
-
function wpr2x_wp_retina_2x() {
|
40 |
-
global $wr2x_admin;
|
41 |
-
$hide_ads = get_option( 'meowapps_hide_ads', false );
|
42 |
-
$view = isset ( $_GET[ 'view' ] ) ? $_GET[ 'view' ] : 'issues';
|
43 |
-
$paged = isset ( $_GET[ 'paged' ] ) ? $_GET[ 'paged' ] : 1;
|
44 |
-
$s = isset( $_GET[ 's' ] ) && !empty( $_GET[ 's' ] ) ? sanitize_text_field( $_GET[ 's' ] ) : null;
|
45 |
-
$issues = $count = 0;
|
46 |
-
$posts_per_page = 15; // TODO: HOW TO GET THE NUMBER OF MEDIA PER PAGES? IT IS NOT get_option('posts_per_page');
|
47 |
-
$issues = wr2x_get_issues();
|
48 |
-
$ignored = wr2x_get_ignores();
|
49 |
-
|
50 |
-
echo '<div class="wrap">';
|
51 |
-
echo $wr2x_admin->display_title( "WP Retina 2x" );
|
52 |
-
echo '<p></p>';
|
53 |
-
|
54 |
-
if ( $wr2x_admin->is_pro() && $view == 'issues' ) {
|
55 |
-
global $wpdb;
|
56 |
-
$totalcount = $wpdb->get_var( $wpdb->prepare( "
|
57 |
-
SELECT COUNT(*)
|
58 |
-
FROM $wpdb->posts p
|
59 |
-
WHERE post_status = 'inherit'
|
60 |
-
AND post_type = 'attachment'" . wr2x_create_sql_if_wpml_original() . "
|
61 |
-
AND post_title LIKE %s
|
62 |
-
AND ( post_mime_type = 'image/jpeg' OR
|
63 |
-
post_mime_type = 'image/png' OR
|
64 |
-
post_mime_type = 'image/gif' )
|
65 |
-
", '%' . $s . '%' ) );
|
66 |
-
$postin = count( $issues ) < 1 ? array( -1 ) : $issues;
|
67 |
-
$query = new WP_Query(
|
68 |
-
array(
|
69 |
-
'post_status' => 'inherit',
|
70 |
-
'post_type' => 'attachment',
|
71 |
-
'post__in' => $postin,
|
72 |
-
'paged' => $paged,
|
73 |
-
'posts_per_page' => $posts_per_page,
|
74 |
-
's' => $s
|
75 |
-
)
|
76 |
-
);
|
77 |
-
}
|
78 |
-
else if ( $wr2x_admin->is_pro() && $view == 'ignored' ) {
|
79 |
-
global $wpdb;
|
80 |
-
$totalcount = $wpdb->get_var( $wpdb->prepare( "
|
81 |
-
SELECT COUNT(*)
|
82 |
-
FROM $wpdb->posts p
|
83 |
-
WHERE post_status = 'inherit'
|
84 |
-
AND post_type = 'attachment'" . wr2x_create_sql_if_wpml_original() . "
|
85 |
-
AND post_title LIKE %s
|
86 |
-
AND ( post_mime_type = 'image/jpeg' OR
|
87 |
-
post_mime_type = 'image/jpg' OR
|
88 |
-
post_mime_type = 'image/png' OR
|
89 |
-
post_mime_type = 'image/gif' )
|
90 |
-
", '%' . $s . '%' ) );
|
91 |
-
$postin = count( $ignored ) < 1 ? array( -1 ) : $ignored;
|
92 |
-
$query = new WP_Query(
|
93 |
-
array(
|
94 |
-
'post_status' => 'inherit',
|
95 |
-
'post_type' => 'attachment',
|
96 |
-
'post__in' => $postin,
|
97 |
-
'paged' => $paged,
|
98 |
-
'posts_per_page' => $posts_per_page,
|
99 |
-
's' => $s
|
100 |
-
)
|
101 |
-
);
|
102 |
-
}
|
103 |
-
else {
|
104 |
-
$query = new WP_Query(
|
105 |
-
array(
|
106 |
-
'post_status' => 'inherit',
|
107 |
-
'post_type' => 'attachment',
|
108 |
-
'post_mime_type' => 'image/jpeg,image/gif,image/jpg,image/png',
|
109 |
-
'paged' => $paged,
|
110 |
-
'posts_per_page' => $posts_per_page,
|
111 |
-
's' => $s
|
112 |
-
)
|
113 |
-
);
|
114 |
-
|
115 |
-
//$s
|
116 |
-
$totalcount = $query->found_posts;
|
117 |
-
}
|
118 |
-
|
119 |
-
$issues_count = count( $issues );
|
120 |
-
|
121 |
-
// If 'search', then we need to clean-up the issues count
|
122 |
-
if ( $s && $issues_count > 0 ) {
|
123 |
-
global $wpdb;
|
124 |
-
$issues_count = $wpdb->get_var( $wpdb->prepare( "
|
125 |
-
SELECT COUNT(*)
|
126 |
-
FROM $wpdb->posts p
|
127 |
-
WHERE id IN ( " . implode( ',', $issues ) . " )" . wr2x_create_sql_if_wpml_original() . "
|
128 |
-
AND post_title LIKE %s
|
129 |
-
", '%' . $s . '%' ) );
|
130 |
-
}
|
131 |
-
|
132 |
-
$results = array();
|
133 |
-
$count = $query->found_posts;
|
134 |
-
$pagescount = $query->max_num_pages;
|
135 |
-
foreach ( $query->posts as $post ) {
|
136 |
-
$info = wr2x_retina_info( $post->ID );
|
137 |
-
array_push( $results, array( 'post' => $post, 'info' => $info ) );
|
138 |
-
}
|
139 |
-
?>
|
140 |
-
|
141 |
-
<div style='background: #FFF; padding: 5px; border-radius: 4px; height: 28px; box-shadow: 0px 0px 6px #C2C2C2;'>
|
142 |
-
|
143 |
-
<!-- REFRESH -->
|
144 |
-
<a id='wr2x_refresh' href='?page=wp-retina-2x&view=issues&refresh=true' class='button' style='float: left;'><img style='position: relative; top: 3px; left: -2px; margin-right: 3px; width: 16px; height: 16px;' src='<?php echo plugin_dir_url( __FILE__ ); ?>img/refresh.png' /><?php _e("Refresh", 'wp-retina-2x'); ?></a>
|
145 |
-
|
146 |
-
<!-- SEARCH -->
|
147 |
-
<form id="posts-filter" action="upload.php" method="get">
|
148 |
-
<p class="search-box" style='margin-left: 5px; float: left;'>
|
149 |
-
<input type="search" name="s" value="<?php echo $s ? $s : ""; ?>">
|
150 |
-
<input type="hidden" name="page" value="wp-retina-2x">
|
151 |
-
<input type="hidden" name="view" value="<?php echo $view; ?>">
|
152 |
-
<input type="hidden" name="paged" value="<?php echo $paged; ?>">
|
153 |
-
<input type="submit" class="button" value="Search">
|
154 |
-
</p>
|
155 |
-
</form>
|
156 |
-
|
157 |
-
<!-- REMOVE BUTTON ALL -->
|
158 |
-
<a id='wr2x_remove_button_all' onclick='wr2x_delete_all()' class='button button-red' style='float: right;'><img style='position: relative; top: 3px; left: -2px; margin-right: 3px; width: 16px; height: 16px;' src='<?php echo plugin_dir_url( __FILE__ ); ?>img/burn.png' /><?php _e("Bulk Delete (Retina Only)", 'wp-retina-2x'); ?></a>
|
159 |
-
|
160 |
-
<!-- GENERATE ALL -->
|
161 |
-
<a id='wr2x_generate_button_all' onclick='wr2x_generate_all()' class='button-primary' style='float: right; margin-right: 5px;'><img style='position: relative; top: 3px; left: -2px; margin-right: 3px; width: 16px; height: 16px;' src='<?php echo plugin_dir_url( __FILE__ ); ?>img/photo-album--plus.png' /><?php _e("Bulk Generate (Thumbnails & Retina)", 'wp-retina-2x'); ?></a>
|
162 |
-
|
163 |
-
|
164 |
-
<!-- PROGRESS -->
|
165 |
-
<span style='margin-left: 12px; font-size: 13px; top: 5px; position: relative; color: #24547C; font-weight: bold;' id='wr2x_progression'></span>
|
166 |
-
|
167 |
-
</div>
|
168 |
-
|
169 |
-
<?php
|
170 |
-
if (isset ( $_GET[ 'clearlogs' ] ) ? $_GET[ 'clearlogs' ] : 0) {
|
171 |
-
echo "<div class='updated' style='margin-top: 20px;'><p>";
|
172 |
-
_e( "The logs have been cleared.", 'wp-retina-2x' );
|
173 |
-
echo "</p></div>";
|
174 |
-
}
|
175 |
-
|
176 |
-
$active_sizes = wr2x_get_active_image_sizes();
|
177 |
-
$full_size_needed = get_option( "wr2x_full_size" );
|
178 |
-
|
179 |
-
$max_width = 0;
|
180 |
-
$max_height = 0;
|
181 |
-
foreach ( $active_sizes as $name => $active_size ) {
|
182 |
-
if ( $active_size['height'] != 9999 && $active_size['height'] > $max_height ) {
|
183 |
-
$max_height = $active_size['height'];
|
184 |
-
}
|
185 |
-
if ( $active_size['width'] != 9999 && $active_size['width'] > $max_width ) {
|
186 |
-
$max_width = $active_size['width'];
|
187 |
-
}
|
188 |
-
}
|
189 |
-
$max_width = $max_width * 2;
|
190 |
-
$max_height = $max_height * 2;
|
191 |
-
|
192 |
-
$upload_max_size = wr2x_get_max_filesize();
|
193 |
-
?>
|
194 |
-
|
195 |
-
<p>
|
196 |
-
<?php printf( __( 'The full-size images should have a resolution of <b>%d×%d</b> at least for the plugin to be able generate the <b>%d retina images</b> required by your website.', 'wp-retina-2x' ), $max_width, $max_height, count( $active_sizes ) ); ?>
|
197 |
-
<?php if ( $full_size_needed ) printf( __( "You <b>also need</b> to upload a retina image for the Full-Size image (might be <b>%d×%d</b>).", 'wp-retina-2x' ), $max_width * 2, $max_height * 2 ); ?>
|
198 |
-
<?php _e("You can upload or replace the images by drag & drop.", 'wp-retina-2x' ); ?>
|
199 |
-
<?php printf( __( "Your PHP configuration allows uploads of <b>%dMB</b> maximum.", 'wp-retina-2x'), $upload_max_size / 1000000 ); ?>
|
200 |
-
|
201 |
-
<?php
|
202 |
-
if ( file_exists( plugin_dir_path( __FILE__ ) . '/wp-retina-2x.log' ) ) {
|
203 |
-
printf( __( 'The <a target="_blank" href="%s/wp-retina-2x.log">log file</a> is available. You can also <a href="?page=wp-retina-2x&view=issues&clearlogs=true">clear</a> it.', 'wp-retina-2x' ), plugin_dir_url( __FILE__ ) );
|
204 |
-
}
|
205 |
-
?>
|
206 |
-
</p>
|
207 |
-
|
208 |
-
<!--
|
209 |
-
It is activated through a serial key that you can buy here: <a href='http://apps.meow.fr/wp-retina-2x/'>Meow Apps</a>. -->
|
210 |
-
|
211 |
-
<?php
|
212 |
-
if ( !$wr2x_admin->is_pro() && !$hide_ads ) {
|
213 |
-
echo '<div class="updated"><p>';
|
214 |
-
echo __( '<b>Only Pro users have access to the features of this dashboard.</b> As a standard user, the dashboard allow you to Bulk Generate, Bulk Delete and access the Retina Logs. If you wish to stay a standard user and never see this dashboard aver again, you can hide it in the settings.<br /><br />The Pro version of the plugin allows you to <b>replace directly an image already uploaded in the Media Library</b> by a simple drag & drop, upload a <b>retina image for a full-size image</b>, use <b>lazy-loading</b> to load your images (for better performance) and, more importantly, <b>supports the developer</b> :) The serial key for the Pro has to be inserted in your Settings > Retina > Pro tab. Thank you :)<br /><br /><a class="button-primary" href="http://meowapps.com/wp-retina-2x/" target="_blank">Get the serial key for the Pro</a>', 'wp-retina-2x' );
|
215 |
-
echo '</p></div>';
|
216 |
-
}
|
217 |
-
?>
|
218 |
-
|
219 |
-
<div id='wr2x-pages'>
|
220 |
-
<?php
|
221 |
-
echo paginate_links(array(
|
222 |
-
'base' => '?page=wp-retina-2x&s=' . urlencode($s) . '&view=' . $view . '%_%',
|
223 |
-
'current' => $paged,
|
224 |
-
'format' => '&paged=%#%',
|
225 |
-
'total' => $pagescount,
|
226 |
-
'prev_next' => false
|
227 |
-
));
|
228 |
-
?>
|
229 |
-
</div>
|
230 |
-
|
231 |
-
<ul class="subsubsub">
|
232 |
-
<li class="all"><a <?php if ( $view == 'all' ) echo "class='current'"; ?> href='?page=wp-retina-2x&s=<?php echo $s; ?>&view=all'><?php _e( "All", 'wp-retina-2x' ); ?></a><span class="count">(<?php echo $totalcount; ?>)</span></li> |
|
233 |
-
|
234 |
-
<?php if ( $wr2x_admin->is_pro() ): ?>
|
235 |
-
|
236 |
-
<li class="all"><a <?php if ( $view == 'issues' ) echo "class='current'"; ?> href='?page=wp-retina-2x&s=<?php echo $s; ?>&view=issues'><?php _e( "Issues", 'wp-retina-2x' ); ?></a><span class="count">(<?php echo $issues_count; ?>)</span></li> |
|
237 |
-
<li class="all"><a <?php if ( $view == 'ignored' ) echo "class='current'"; ?> href='?page=wp-retina-2x&s=<?php echo $s; ?>&view=ignored'><?php _e( "Ignored", 'wp-retina-2x' ); ?></a><span class="count">(<?php echo count( $ignored ); ?>)</span></li>
|
238 |
-
|
239 |
-
<?php else: ?>
|
240 |
-
|
241 |
-
<li class="all"><span><?php _e( "Issues", 'wp-retina-2x' ); ?></span> <span class="count">(<?php echo $issues_count; ?>)</span></li> |
|
242 |
-
<li class="all"><span><?php _e( "Ignored", 'wp-retina-2x' ); ?></span> <span class="count">(<?php echo count( $ignored ); ?>)</span></li>
|
243 |
-
|
244 |
-
<?php endif; ?>
|
245 |
-
|
246 |
-
|
247 |
-
</ul>
|
248 |
-
<table class='wp-list-table widefat fixed media wr2x-table'>
|
249 |
-
<thead><tr>
|
250 |
-
<?php
|
251 |
-
echo "<th style='width: 56px;'>Thumbnail</th>";
|
252 |
-
echo "<th style=' width: 360px;'>" . __( "Base image", 'wp-retina-2x' ) . "</th>";
|
253 |
-
echo "<th style=''>" . __( "Media Sizes<br />Retina-ized", 'wp-retina-2x' ) . "</th>";
|
254 |
-
echo "<th style=''>" . __( "Full-Size<br/><b>Replace</b>", 'wp-retina-2x' ) . "</th>";
|
255 |
-
echo "<th style=''>" . __( "Full-Size Retina", 'wp-retina-2x' ) . "</th>";
|
256 |
-
echo "<th style=''>" . __( "Full-Size Retina<br/><b>Upload</b>", 'wp-retina-2x' ) . "</th>";
|
257 |
-
?>
|
258 |
-
</tr></thead>
|
259 |
-
<tbody>
|
260 |
-
<?php
|
261 |
-
foreach ($results as $index => $attr) {
|
262 |
-
$post = $attr['post'];
|
263 |
-
$info = $attr['info'];
|
264 |
-
$meta = wp_get_attachment_metadata( $post->ID );
|
265 |
-
// Let's clean the issues status
|
266 |
-
if ( $view != 'issues' ) {
|
267 |
-
wr2x_update_issue_status( $post->ID, $issues, $info );
|
268 |
-
}
|
269 |
-
if ( isset( $meta ) && isset( $meta['width'] ) ) {
|
270 |
-
$original_width = $meta['width'];
|
271 |
-
$original_height = $meta['height'];
|
272 |
-
}
|
273 |
-
|
274 |
-
$attachmentsrc = wp_get_attachment_image_src( $post->ID, 'thumbnail' );
|
275 |
-
echo "<tr class='wr2x-file-row' postId='" . $post->ID . "'>";
|
276 |
-
echo "<td class='wr2x-image wr2x-info-thumbnail'><img src='" . $attachmentsrc[0] . "' /></td>";
|
277 |
-
echo "<td class='wr2x-title'><a href='media.php?attachment_id=" . $post->ID . "&action=edit'>" . ( $post->post_title ? $post->post_title : '<i>Untitled</i>' ) . '</a><br />' .
|
278 |
-
"<span class='resolution'>Full-Size: <span class='" . ( $original_width < $max_width ? "red" : "" ) . "'>" . $original_width . "</span>×<span class='" . ( $original_height < $max_height ? "red" : "" ) . "'>" . $original_height . "</span></span>";
|
279 |
-
echo "<div class='actions'>";
|
280 |
-
echo "<a style='position: relative;' onclick='wr2x_generate(" . $post->ID . ", true)' id='wr2x_generate_button_" . $post->ID . "' class='wr2x-button'>" . __( "GENERATE", 'wp-retina-2x' ) . "</a>";
|
281 |
-
if ( !wr2x_is_ignore( $post->ID ) )
|
282 |
-
echo " <a href='?page=wp-retina-2x&view=" . $view . "&paged=" . $paged . "&ignore=" . $post->ID . "' id='wr2x_generate_button_" . $post->ID . "' class='wr2x-button wr2x-button-ignore'>" . __( "IGNORE", 'wp-retina-2x' ) . "</a>";
|
283 |
-
echo " <a style='position: relative;' class='wr2x-button wr2x-button-view'>" . __( "DETAILS", 'wp-retina-2x' ) . "</a>";
|
284 |
-
echo "</div></td>";
|
285 |
-
|
286 |
-
// Media Sizes Retina-ized
|
287 |
-
echo '<td id="wr2x-info-' . $post->ID . '" style="padding-top: 10px;" class="wr2x-info">';
|
288 |
-
echo wpr2x_html_get_basic_retina_info( $post, $info );
|
289 |
-
echo "</td>";
|
290 |
-
|
291 |
-
if ( $wr2x_admin->is_pro() ) {
|
292 |
-
// Full-Size Replace
|
293 |
-
echo "<td class='wr2x-fullsize-replace'><div class='wr2x-dragdrop'></div>";
|
294 |
-
echo "</td>";
|
295 |
-
// Full-Size Retina
|
296 |
-
echo '<td id="wr2x-info-full-' . $post->ID . '" class="wr2x-image wr2x-info-full">';
|
297 |
-
echo wpr2x_html_get_basic_retina_info_full( $post->ID, $info );
|
298 |
-
echo "</td>";
|
299 |
-
// Full-Size Retina Upload
|
300 |
-
echo "<td class='wr2x-fullsize-retina-upload'>";
|
301 |
-
echo "<div class='wr2x-dragdrop'></div>";
|
302 |
-
echo "</td>";
|
303 |
-
}
|
304 |
-
else
|
305 |
-
echo "<td colspan='3' style='text-align: center; background: #F9F9F9;'><small><br />PRO VERSION ONLY</small></td>";
|
306 |
-
echo "</tr>";
|
307 |
-
}
|
308 |
-
?>
|
309 |
-
</tbody>
|
310 |
-
</table>
|
311 |
-
</div>
|
312 |
-
|
313 |
-
<?php
|
314 |
-
}
|
315 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wr2x_retina_uploader.php
DELETED
@@ -1,104 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
// Based on code provided by gmazzap on
|
4 |
-
// http://wordpress.stackexchange.com/questions/126969/what-filter-should-i-use-to-insert-a-button-inside-on-mediaadd-new
|
5 |
-
|
6 |
-
class WR2x_Retina_Uploader {
|
7 |
-
|
8 |
-
static function getLabel() {
|
9 |
-
// change here the label of your custom upload button
|
10 |
-
return 'Add Full Retina';
|
11 |
-
}
|
12 |
-
|
13 |
-
static function getUrl() {
|
14 |
-
// change here the url of your custom upload button
|
15 |
-
return add_query_arg( array( 'page' => 'my-custom-upload' ), admin_url( 'upload.php' ) );
|
16 |
-
}
|
17 |
-
|
18 |
-
function render() {
|
19 |
-
// this is the function that render your custom upload system
|
20 |
-
if ( !current_user_can( 'upload_files' ) ) {
|
21 |
-
echo '<h2>Sorry, you are not allowed to upload files.</h2>';
|
22 |
-
return;
|
23 |
-
}
|
24 |
-
?>
|
25 |
-
<div class="wrap">
|
26 |
-
<h2>Upload New Media as a Retina for Full Size</h2>
|
27 |
-
<p>The image you are uploading here will be used as a Retina for Full Size. It means that whatever its size is, the normal size will be created depending on it (width and height divided by two)</p>
|
28 |
-
<div id="plupload-upload-ui" class="hide-if-no-js drag-drop">
|
29 |
-
<div id="drag-drop-area" style="position: relative;">
|
30 |
-
<div class="drag-drop-inside">
|
31 |
-
<p class="drag-drop-info">Drop files here</p>
|
32 |
-
<p>or</p>
|
33 |
-
<p class="drag-drop-buttons"><input id="plupload-browse-button" type="button" value="Select Files" class="button" style="position: relative; z-index: 1;"></p>
|
34 |
-
</div>
|
35 |
-
</div>
|
36 |
-
|
37 |
-
|
38 |
-
</div>
|
39 |
-
<?php
|
40 |
-
}
|
41 |
-
|
42 |
-
function __construct() {
|
43 |
-
add_action( 'load-upload.php', array( $this, 'indexButton' ) );
|
44 |
-
add_action( 'admin_menu', array( $this, 'submenu') );
|
45 |
-
add_action( 'wp_before_admin_bar_render', array( $this, "adminBar" ) );
|
46 |
-
add_action( 'post-plupload-upload-ui', array( $this, 'mediaButton' ) );
|
47 |
-
}
|
48 |
-
|
49 |
-
function submenu() {
|
50 |
-
add_media_page( self::getLabel(), self::getLabel(), 'upload_files', 'my-custom-upload', array( $this, 'render') );
|
51 |
-
}
|
52 |
-
|
53 |
-
function adminBar() {
|
54 |
-
if ( !current_user_can( 'upload_files' ) || !is_admin_bar_showing() ) return;
|
55 |
-
global $wp_admin_bar;
|
56 |
-
$wp_admin_bar->add_node( array(
|
57 |
-
'parent' => 'new-content',
|
58 |
-
'id' => 'custom-upload-link',
|
59 |
-
'title' => self::getLabel(),
|
60 |
-
'href' => self::getUrl()
|
61 |
-
) );
|
62 |
-
}
|
63 |
-
|
64 |
-
|
65 |
-
function mediaButton() {
|
66 |
-
if ( current_user_can( 'upload_files' ) ) {
|
67 |
-
echo '<div><p align="center">';
|
68 |
-
echo '<input id="custom-browse-button" type="button" value="' . self::getLabel() . '" class="button" />';
|
69 |
-
echo '</p></div>';
|
70 |
-
$this->mediaButtonScript();
|
71 |
-
}
|
72 |
-
}
|
73 |
-
|
74 |
-
function mediaButtonScript() {
|
75 |
-
if ( !current_user_can( 'upload_files' ) ) return;
|
76 |
-
?>
|
77 |
-
<script>
|
78 |
-
jQuery(document).on('click', '#custom-browse-button', function(e) {
|
79 |
-
e.preventDefault();
|
80 |
-
window.location = '<?php echo self::getUrl(); ?>';
|
81 |
-
});
|
82 |
-
</script>
|
83 |
-
<?php
|
84 |
-
}
|
85 |
-
|
86 |
-
function indexButton() {
|
87 |
-
if ( !current_user_can( 'upload_files' ) ) return;
|
88 |
-
add_filter( 'esc_html', array(__CLASS__, 'h2Button'), 999, 2 );
|
89 |
-
}
|
90 |
-
|
91 |
-
static function h2Button( $safe_text, $text ) {
|
92 |
-
if ( !current_user_can( 'upload_files' ) ) return $safe_text;
|
93 |
-
if ( $text === __('Media Library') && did_action( 'all_admin_notices' ) ) {
|
94 |
-
remove_filter( 'esc_html', array(__CLASS__, 'h2Button'), 999, 2 );
|
95 |
-
$format = ' <a href="%s" class="add-new-h2">%s</a>';
|
96 |
-
$mybutton = sprintf($format, esc_url(self::getUrl()), esc_html(self::getLabel()) );
|
97 |
-
$safe_text .= $mybutton;
|
98 |
-
}
|
99 |
-
return $safe_text;
|
100 |
-
}
|
101 |
-
|
102 |
-
}
|
103 |
-
|
104 |
-
$ui = new WR2x_Retina_Uploader;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wr2x_vt_resize.php
DELETED
@@ -1,52 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !function_exists( 'wr2x_vt_resize' ) ) {
|
4 |
-
function wr2x_vt_resize( $file_path, $width, $height, $crop, $newfile, $customCrop = false ) {
|
5 |
-
$crop_params = $crop == '1' ? true : $crop;
|
6 |
-
$orig_size = getimagesize( $file_path );
|
7 |
-
$image_src[0] = $file_path;
|
8 |
-
$image_src[1] = $orig_size[0];
|
9 |
-
$image_src[2] = $orig_size[1];
|
10 |
-
$file_info = pathinfo( $file_path );
|
11 |
-
$newfile_info = pathinfo( $newfile );
|
12 |
-
$extension = '.' . $newfile_info['extension'];
|
13 |
-
$no_ext_path = $file_info['dirname'] . '/' . $file_info['filename'];
|
14 |
-
$cropped_img_path = $no_ext_path . '-' . $width . 'x' . $height . "-tmp" . $extension;
|
15 |
-
$image = wp_get_image_editor( $file_path );
|
16 |
-
|
17 |
-
if ( is_wp_error( $image ) ) {
|
18 |
-
wr2x_log( "Resize failure: " . $image->get_error_message() );
|
19 |
-
error_log( "Resize failure: " . $image->get_error_message() );
|
20 |
-
return null;
|
21 |
-
}
|
22 |
-
|
23 |
-
// Resize or use Custom Crop
|
24 |
-
if ( !$customCrop )
|
25 |
-
$image->resize( $width, $height, $crop_params );
|
26 |
-
else
|
27 |
-
$image->crop( $customCrop['x'] * $customCrop['scale'], $customCrop['y'] * $customCrop['scale'], $customCrop['w'] * $customCrop['scale'], $customCrop['h'] * $customCrop['scale'], $width, $height, false );
|
28 |
-
|
29 |
-
// Quality
|
30 |
-
$quality = get_option( 'wr2x_quality', 90 );
|
31 |
-
$image->set_quality( $quality );
|
32 |
-
|
33 |
-
$saved = $image->save( $cropped_img_path );
|
34 |
-
if ( is_wp_error( $saved ) ) {
|
35 |
-
$error = $saved->get_error_message();
|
36 |
-
trigger_error( "Retina: Could not create/resize image " . $file_path . " to " . $newfile . ": " . $error , E_WARNING );
|
37 |
-
error_log( "Retina: Could not create/resize image " . $file_path . " to " . $newfile . ":" . $error );
|
38 |
-
return null;
|
39 |
-
}
|
40 |
-
if ( rename( $saved['path'], $newfile ) )
|
41 |
-
$cropped_img_path = $newfile;
|
42 |
-
else {
|
43 |
-
trigger_error( "Retina: Could not move " . $saved['path'] . " to " . $newfile . "." , E_WARNING );
|
44 |
-
error_log( "Retina: Could not move " . $saved['path'] . " to " . $newfile . "." );
|
45 |
-
return null;
|
46 |
-
}
|
47 |
-
$new_img_size = getimagesize( $cropped_img_path );
|
48 |
-
$new_img = str_replace( basename( $image_src[0] ), basename( $cropped_img_path ), $image_src[0] );
|
49 |
-
$vt_image = array ( 'url' => $new_img, 'width' => $new_img_size[0], 'height' => $new_img_size[1] );
|
50 |
-
return $vt_image;
|
51 |
-
}
|
52 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|