File: /home/b/o/h/bohousj/www/wp-content/plugins/wp-fastest-cache-premium/pro/library/image.php
<?php
class WpFastestCacheImageOptimisation{
public $uploadDir;
private $id = false;
private $metadata = array();
private $name = "";
private $path = "";
private $url = "";
private $images = array();
private $images_clone = array();
private $location = "";
public function __construct(){
if(isset($_GET["id"]) && $_GET["id"]){
$this->id = intval($_GET["id"]);
}
$this->create_api_key();
$this->uploadDir = wp_upload_dir();
}
public function create_api_key(){
if(!get_option("WpFc_api_key")){
update_option("WpFc_api_key", md5(microtime(true)));
}
}
public function get_country_list(){
$countries = '{
"america" : "AI, AR, AW, BS, BB, BZ, BM, BO, BR, VG, CA, KY, CL, CO, CR, CU, CW, DM, DO, EC, SV, FK, GL, GP, GT, GY, HT, HN, JM, MX, MS, NI, PA, PY, PE, PR, BL, KN, LC, MF, PM, VC, SR, TT, US, UY, VE",
"oceania" : "AS, AU, CK, TL, FJ, PF, GU, KI, MH, FM, NR, NC, NZ, NU, NF, MP, PW, PG, PN, WS, SB, TK, TV, VU",
"asia" : "AF, AM, AZ, BH, BD, BT, BN, KH, CN, GE, HK, IN, ID, IR, IQ, JP, JO, KW, KG, LA, LB, MO, MY, MV, MN, MM, NP, KP, OM, PK, PH, QA, SA, SG, KR, LK, SY, TW, TJ, TH, TM, AE, UZ, VN, YE",
"w_europe" : "AD, AT, BE, DK, FO, FR, DE, GI, IS, IE, IM, IT, LI, LU, MT, MC, NL, PT, SM, ES, CH, GB, VA",
"e_europe" : "AL, BY, BA, BG, HR, CY, CZ, EE, FI, GR, HU, KZ, IL, XK, LV, LT, MK, MD, ME, NO, PL, RO, RU, RS, SK, SI, SE, TR, UA",
"africa" : "DZ, AO, BJ, BW, BF, BI, CM, CV, CF, KM, CD, DJ, EG, GQ, ER, ET, GA, GM, GH, GN, GW, CI, KE, LS, LR, LY, MG, MW, ML, MR, MU, MA, MZ, NA, NE, NG, CG, RE, RW, SH, ST, SN, SC, SL, SO, ZA, SS, SD, SZ, TZ, TG, TN, UG, EH, ZM, ZW"
}';
return $countries;
}
public function get_server_list(){
$servers = '{
"naw": [
{"key": "la", "time":0,"flag":"us","location":"Los Ang","color":"red", "url":"https://la.wpfastestcache.com"},
{"key": "dal", "time":0,"flag":"us","location":"Dallas","color":"red", "url":"https://dallas.wpfastestcache.com"},
{"key": "nev", "time":0,"flag":"us","location":"Nevada","color":"red", "url":"https://nevada.wpfastestcache.com"}
],
"nae": [
{"key": "dc", "time":0,"flag":"us","location":"New York","color":"red", "url":"https://dc.wpfastestcache.com"},
{"key": "stlo", "time":0,"flag":"us","location":"St. Louis","color":"red", "url":"https://stlouis.wpfastestcache.com"}
],
"euw": [
{"key": "fran", "time":0,"flag":"de","location":"Frankfurt","color":"red", "url":"https://frankfurt.wpfastestcache.com"},
{"key": "fr", "time":0,"flag":"de","location":"France","color":"red", "url":"https://fr.wpfastestcache.com"},
{"key": "it", "time":0,"flag":"it","location":"Italy","color":"red", "url":"https://it.wpfastestcache.com"},
{"key": "nl", "time":0,"flag":"nl","location":"Holland","color":"red", "url":"https://nl.wpfastestcache.com"},
{"key": "de", "time":0,"flag":"de","location":"Nuremberg","color":"red", "url":"https://nuremberg.wpfastestcache.com"},
{"key": "uk", "time":0,"flag":"gb","location":"UK","color":"red", "url":"https://uk.wpfastestcache.com"}
],
"eue": [
{"key": "bg", "time":0,"flag":"bg","location":"Bulgaria","color":"red", "url":"https://bulgaria.wpfastestcache.com"},
{"key": "pl", "time":0,"flag":"de","location":"Poland","color":"red", "url":"https://pl.wpfastestcache.com"},
{"key": "ru", "time":0,"flag":"de","location":"Russia","color":"red", "url":"https://russia.wpfastestcache.com"},
{"key": "se", "time":0,"flag":"de","location":"Sweden","color":"red", "url":"https://sweden.wpfastestcache.com"},
{"key": "tr", "time":0,"flag":"de","location":"Turkey","color":"red", "url":"https://tr.wpfastestcache.com"}
],
"as": [
{"key": "au", "time":0,"flag":"sg","location":"Australia","color":"red", "url":"https://au.wpfastestcache.com"},
{"key": "jp", "time":0,"flag":"jp","location":"Japan","color":"red", "url":"https://jp.wpfastestcache.com"}
]
}';
return $servers;
}
public function get_template_path($file_name){
return WPFC_WP_PLUGIN_DIR."/wp-fastest-cache-premium/pro/templates/".$file_name;
}
public function get_total_reduction_image_number(){
global $wpdb;
$query = "SELECT sum(`meta_value`) as total FROM `".$wpdb->prefix."postmeta` WHERE `meta_key`= 'wpfc_optimisation_reduction'";
$result = $wpdb->get_row( $query );
if($result->total){
return ($result->total && $result->total > 0) ? $result->total : 0;
}else{
return 0;
}
}
public function get_total_optimized_image_number(){
$query_images_args = array();
$query_images_args['post_type'] = 'attachment';
$query_images_args['post_mime_type'] = array('image/jpeg', 'image/png');
$query_images_args['post_status'] = 'inherit';
$query_images_args['posts_per_page'] = -1;
$query_images_args['meta_query'] = array(
array(
'key' => 'wpfc_optimisation',
'compare' => 'EXISTS'
),
array(
'key' => 'wpfc_optimisation',
'value' => base64_encode('"destination_path"'),
'compare' => 'LIKE'
)
);
return $this->get_count_only($query_images_args);
}
public function get_total_image_error_number(){
$query_images_args = array();
$query_images_args['post_type'] = 'attachment';
$query_images_args['post_mime_type'] = array('image/jpeg', 'image/png');
$query_images_args['post_status'] = 'inherit';
$query_images_args['posts_per_page'] = -1;
$query_images_args['meta_query'] = array(
array(
'key' => 'wpfc_optimisation',
'compare' => 'EXISTS'
),
array(
'key' => 'wpfc_optimisation',
'value' => base64_encode('"error_code"'),
'compare' => 'LIKE'
)
);
return $this->get_count_only($query_images_args);
}
public function null_posts_groupby(){
return "";
}
public function count_posts_fields(){
return "COUNT(*) as post_count_wpfc";
}
public function get_count_only($query_images_args){
add_filter( 'posts_fields', array($this,'count_posts_fields'));
add_filter( 'posts_groupby', array($this, 'null_posts_groupby'));
unset($query_images_args["offset"]);
unset($query_images_args["order"]);
unset($query_images_args["orderby"]);
$query_images_args['posts_per_page'] = -1;
$query_image = new WP_Query( $query_images_args );
return $query_image->posts[0]->post_count_wpfc;
}
public function get_total_image_number(){
$query_images_args = array();
$query_images_args['post_type'] = 'attachment';
$query_images_args['post_mime_type'] = array('image/jpeg', 'image/png');
$query_images_args['post_status'] = 'inherit';
$query_images_args['posts_per_page'] = -1;
$query_images_args['meta_query'] = array(
array(
'key' => '_wp_attachment_metadata',
'compare' => 'EXISTS'
)
);
return $this->get_count_only($query_images_args);
}
public function get_total_pending_image_number(){
$query_images_args = array();
$query_images_args['post_type'] = 'attachment';
$query_images_args['post_mime_type'] = array('image/jpeg', 'image/png');
$query_images_args['post_status'] = 'inherit';
$query_images_args['posts_per_page'] = -1;
$query_images_args['meta_query'] = array(
array(
'key' => '_wp_attachment_metadata',
'compare' => 'EXISTS'
),
array(
'key' => 'wpfc_optimisation',
'compare' => 'NOT EXISTS'
)
);
return $this->get_count_only($query_images_args);
}
public function hook(){
add_action('wp_ajax_wpfc_revert_image_ajax_request', array($this, "wpfc_revert_image_ajax_request"));
add_action('wp_ajax_wpfc_statics_ajax_request', array($this, "wpfc_statics_ajax_request"));
add_action('wp_ajax_wpfc_optimize_image_ajax_request', array($this, "wpfc_optimize_image_ajax_request"));
add_action('wp_ajax_wpfc_update_image_list_ajax_request', array($this, "wpfc_update_image_list_ajax_request"));
}
public function get_not_optimized_before(){
$tmp_image = array();
$valueJson = get_post_meta($this->id, 'wpfc_optimisation', true);
$tmpvalueJson = base64_decode($valueJson);
if($tmpvalueJson){
$std = json_decode($tmpvalueJson);
$metaOptimized = $this->object_to_array($std);
$percentage = count($metaOptimized)*100/count($this->images);
}else{
$percentage = 100/count($this->images);
return array("metaOptimized" => array(), "images" => array_slice($this->images, 0, 1), "total_reduction" => 0, "percentage" => $percentage);
}
foreach ($this->images as $key => $value) {
$exist = false;
foreach ($metaOptimized as $meta_key => $meta_value) {
if($value["file"] == $meta_value["file"]){
$exist = true;
//break;
}
}
if(!$exist){
array_push($tmp_image, $value);
}
}
//START: total reduction
$total_reduction = 0;
foreach ($metaOptimized as $m_key => $m_value) {
$m_value["reduction"] = isset($m_value["reduction"]) ? $m_value["reduction"] : 0;
$total_reduction += $m_value["reduction"];
}
//END: total reduction
if(count($tmp_image) > 0){
if(isset($_GET["last"])){
if(preg_match("/last-(\d+)/", $_GET["last"], $last_number)){
if(count($tmp_image) > 5){
$tmp_image = array_slice($tmp_image, $last_number[1]*-1, 1);
}
}
}
return array("metaOptimized" => $metaOptimized, "images" => array_slice($tmp_image, 0, 1), "total_reduction" => $total_reduction, "percentage" => $percentage);
}else{
return array("metaOptimized" => array(), "images" => array(), "total_reduction" => 0);
}
}
public function object_to_array($obj) {
if(is_object($obj)) $obj = (array) $obj;
if(is_array($obj)) {
$new = array();
foreach($obj as $key => $val) {
$new[$key] = $this->object_to_array($val);
}
}
else $new = $obj;
return $new;
}
public function re_order_by_dimensions(){
$tmp = $this->images;
foreach ($tmp as $key => $value) {
$width_list[$key] = $value['width'];
}
array_multisort($width_list, SORT_DESC, $tmp);
return $tmp;
}
public function optimizeFirstImage(){
$this->setId();
$this->setMetaData();
$this->set_server_location();
if(!$this->id){
return array("finish", "success");
}else if(!isset($this->metadata["file"]) && $this->id){
$metaOptimized = array();
$metaOptimized[0]["time"] = time();
$metaOptimized[0]["id"] = $this->id;
$metaOptimized[0]["error_code"] = 17;
update_post_meta($this->id, 'wpfc_optimisation_reduction', 0);
update_post_meta($this->id, 'wpfc_optimisation', base64_encode(json_encode($metaOptimized)));
delete_option("WpFcLastImageId");
return array("Image has been optimizedxx", "success", $this->id, 100);
}else{
$this->setName();
$this->setPath();
$this->setUrl();
$this->setImages();
}
if($this->id && count($this->images) == 0){
$metaOptimized = array();
$metaOptimized[0]["time"] = time();
$metaOptimized[0]["id"] = $this->id;
$metaOptimized[0]["error_code"] = 18;
update_post_meta($this->id, 'wpfc_optimisation_reduction', 0);
update_post_meta($this->id, 'wpfc_optimisation', base64_encode(json_encode($metaOptimized)));
delete_option("WpFcLastImageId");
return array("Image has been optimizedxx", "success", $this->id, 100);
}
if(!$this->backup_folder_exist()){
return array("Please Create folder ".$this->uploadDir["basedir"]."/wpfc-backup/", "error");
}else{
$error_exist = false;
$metaOptimized = array();
$total_reduction = 0;
$this->images = $this->image_arr_unique($this->images);
$this->images = $this->re_order_by_dimensions();
$this->images_clone = $this->images;
$optimized_before = $this->get_not_optimized_before();
$this->images = $optimized_before["images"];
$metaOptimized = $optimized_before["metaOptimized"];
$total_reduction = $optimized_before["total_reduction"];
$percentage = isset($optimized_before["percentage"]) && $optimized_before["percentage"] ? $optimized_before["percentage"] : 0;
if(count($this->images) == 0){
delete_option("WpFcLastImageId");
return array("Image has been optimizedxx", "success", "", 100);
}
foreach ($this->images as $key => $value) {
$res = $this->compress($value);
if($res["success"]){
$value["destination_path"] = $res["destination_path"];
$value["reduction"] = $res["reduction"];
$total_reduction += $value["reduction"];
$value["time"] = time();
$value["id"] = $this->id;
array_push($metaOptimized, $value);
}else{
if(!isset($res["error_code"]) && isset($res["error_message"])){
return array($res["error_message"], "error");
break;
}
if(in_array($res["error_code"] , array(2, 6, 7, 11, 19, 20))){
return array($res["error_message"], "error");
break;
}
$value["error_code"] = $res["error_code"];
$error_exist = true;
}
$value["time"] = time();
$value["id"] = $this->id;
if(isset($value["error_code"]) && $value["error_code"]){
if($value["error_code"] != 8 || ($value["error_code"] == 8 && $key === 0)){
array_push($metaOptimized, $value);
}
}
}
// if(!$error_exist){
// $this->clean_backups($metaOptimized);
// }
$percentage = $this->update_meta($total_reduction, $metaOptimized);
return array("Image has been optimizedxx", "success", $this->id, $percentage);
}
}
public function update_meta($total_reduction, $metaOptimized){
if(isset($metaOptimized[0]) && isset($metaOptimized[0]["error_code"]) && $metaOptimized[0]["error_code"]){
update_post_meta($this->id, 'wpfc_optimisation', base64_encode(json_encode($metaOptimized)));
update_post_meta($this->id, 'wpfc_optimisation_reduction', 0);
return 100;
}else{
$percentage = 0;
$meta_temp = array();
foreach ($this->images_clone as $key => $value){
$backup_file = str_replace($this->uploadDir["basedir"], $this->uploadDir["basedir"]."/wpfc-backup", $value["file"]);
if(file_exists($value["file"]) && file_exists($backup_file)){
$diff = filesize($backup_file) - filesize($value["file"]);
$diff = $diff > 0 ? $diff : 0;
$value["destination_path"] = $backup_file;
$value["reduction"] = $diff;
$value["time"] = time();
$value["id"] = $this->id;
array_push($meta_temp, $value);
}
}
foreach($metaOptimized as $m_key => $m_value){
if(isset($m_value["error_code"]) && $m_value["error_code"]){
$exist = false;
for($i=0; $i < count($meta_temp); $i++){
if(isset($m_value["file"]) && isset($meta_temp["file"])){
if($meta_temp["file"] == $m_value["file"]){
$exist = true;
}
}
}
if(!$exist){
$m_value["destination_path"] = "";
$m_value["reduction"] = 0;
$m_value["time"] = time();
$m_value["id"] = $this->id;
array_push($meta_temp, $m_value);
}
}
}
if(count($meta_temp) > 0){
$percentage = count($meta_temp)*100/count($this->images_clone);
}else{
$percentage = 0;
}
update_post_meta($this->id, 'wpfc_optimisation_reduction', $total_reduction);
update_post_meta($this->id, 'wpfc_optimisation', base64_encode(json_encode($meta_temp)));
return $percentage;
}
}
public function clean_backups($meta){
foreach ($meta as $key => $value) {
if(file_exists($value["destination_path"])){
unlink($value["destination_path"]);
}
}
}
public function compress($source_image){
/*
Error Codes
2 = in backup folder parent folder not writable
3 = no need to optimize
4 = source is not writable
5 = destination is not writable
6 = ImageMagick library is not avaliable
7 = Error via api
8 = Source file does not exist
9 = Image size exceed 5mb limit while processing
11 = Empty Name
12 = Forbidden
13 = CloudFlare to restrict access
14 = No Extension
15 = Image size is 0Kb
16 = Corrupted Image
17 = Empty Metadata
18 = No Image
19 = destination_move_source_path is not saved
20 = file size of destination_move_source_path is zero
21 = Unacceptable file type
*/
// if the url starts with /wp-content
if(preg_match("/^\/wp-content/i", $source_image["url"])){
$source_image["url"] = home_url().$source_image["url"];
}
$source_path = $source_image["file"];
$resBackup = array("success" => true, "error_message" => "");
$destination_path = str_replace($this->uploadDir['basedir'], $this->uploadDir['basedir']."/wpfc-backup", $source_path);
$destination_path = $destination_path."_tmp";
if($resBackup = $this->createBackupFolder($destination_path)){
if(strlen($this->name) === 0){
return array("success" => false, "error_code" => 11);
}
if(!file_exists($source_path)){
return array("success" => false, "error_code" => 8);
}
if(!pathinfo($source_image["url"], PATHINFO_EXTENSION)){
return array("success" => false, "error_code" => 14);
}
// if(@filesize($source_path) > 5000000){
// return array("success" => false, "error_code" => 9);
// }
if(!$this->acceptable_mime_type($source_path)){
return array("success" => false, "error_code" => 21);
}
// $image_exist = wp_remote_get($source_image["url"], array('timeout' => 5 ) );
// if (!$image_exist || is_wp_error($image_exist)){
// if($image_exist->get_error_message() == "Failure when receiving data from the peer"){
// //true for now
// }else{
// return array("success" => false, "error_message" => $image_exist->get_error_message());
// }
// }else{
// if(wp_remote_retrieve_response_code($image_exist) == 403){
// if(preg_match("/CloudFlare\s+to\s+restrict\s+access/", wp_remote_retrieve_body( $image_exist ))){
// return array("success" => false, "error_code" => 13);
// }else{
// return array("success" => false, "error_code" => 12);
// }
// }
// if(wp_remote_retrieve_response_code($image_exist) != 200){
// return array("success" => false, "error_code" => 8);
// }
// }
if(!$this->is_image($source_path)){
return array("success" => false, "error_code" => 16);
}
if(filesize($source_path) == 0){
return array("success" => false, "error_code" => 15);
}
if(@rename($source_path, $source_path."_writabletest")){
rename($source_path."_writabletest", $source_path);
}else{
return array("success" => false, "error_message" => $source_path." is not writable", "error_code" => 4);
}
if (@copy($source_path, $destination_path."_writabletest")) {
unlink($destination_path."_writabletest");
}else{
return array("success" => false, "error_message" => $destination_path." is not writable", "error_code" => 5);
}
if($resBackup["success"]){
$compressed_result = $this->compress_image_external($source_image["url"]);
if($compressed_result["success"]){
if($image_data = $compressed_result["url"]){
@file_put_contents($destination_path, $image_data);
}
}else{
if(preg_match("/Image\ssize\sexceed/i", $compressed_result["error_message"])){
return array("success" => false, "error_code" => 9);
}else{
return array("success" => false, "error_code" => 7, "error_message" => $compressed_result["error_message"]);
}
}
$source_move_backup_path = str_replace($this->uploadDir['basedir'], $this->uploadDir['basedir']."/wpfc-backup", $source_path);
$destination_move_source_path = str_replace("/wpfc-backup/", "/", $destination_path);
if (@copy($source_path, $source_move_backup_path)) {
if(@copy($destination_path, $destination_move_source_path)){
if(file_exists($destination_move_source_path)){
if(filesize($destination_move_source_path) > 50){
$diff = $this->compareSizes($source_path, $destination_path);
unlink($source_path);
unlink($destination_path);
rename($destination_move_source_path, preg_replace("/\_tmp$/", "", $destination_move_source_path));
$this->save_webp($source_image["url"], $destination_move_source_path);
return array("success" => true, "destination_path" => preg_replace("/\_tmp$/", "", $destination_path), "reduction" => $diff);
}else{
return array("success" => false, "error_code" => 20, "error_message" => $destination_path." file size of destination_move_source_path is zero");
}
}else{
return array("success" => false, "error_code" => 19, "error_message" => $destination_path." destination_move_source_path is not saved");
}
}else{
return array("success" => false, "error_code" => 5);
}
}else{
return array("success" => false, "error_code" => 4);
}
}else{
return $resBackup;
}
}
}
public function is_image($source_path){
$size = getimagesize($source_path);
if($size){
return true;
}
return false;
}
public function save_webp($url, $path){
$webp = true;
if($webp){
$path = preg_replace("/\_tmp$/", ".webp", $path);
$response = wp_remote_get($this->location."/image/webp/".$url,
array('user-agent' => $_SERVER["HTTP_HOST"],
'timeout' => 20,
'sslverify' => false,
'headers' => array(
// READ: cache-control causes an issue so removed => Notice: Array to string conversion in /wp-includes/class-http.php on line 1484
//"cache-control" => array("no-store, no-cache, must-revalidate", "post-check=0, pre-check=0")
)
)
);
if ( !$response || is_wp_error( $response ) ) {
//return array("success" => false, "error_message" => $response->get_error_message());
}else{
if(wp_remote_retrieve_response_code($response) == 200){
$server_output = wp_remote_retrieve_body($response);
if($server_output){
@file_put_contents($path, $server_output);
}
}
}
}
}
public function compress_image_external($url){
// WP Hide & Security Enhancer
global $wph;
if(isset($wph) && property_exists($wph, 'functions')){
$url = $wph->functions->content_urls_replacement($url, $wph->functions->get_replacement_list());
}
$response = wp_remote_get($this->location."/image/compress/".$url,
array('user-agent' => $_SERVER["HTTP_HOST"],
'sslverify' => false,
'timeout' => 20,
'headers' => array(
// READ: cache-control causes an issue so removed => Notice: Array to string conversion in /wp-includes/class-http.php on line 1484
//"cache-control" => array("no-store, no-cache, must-revalidate", "post-check=0, pre-check=0")
)
)
);
if ( !$response || is_wp_error( $response ) ) {
return array("success" => false, "error_message" => $response->get_error_message());
}else{
if(wp_remote_retrieve_response_code($response) == 200){
$server_output = wp_remote_retrieve_body( $response );
if($server_output && $server_output[0] != "{"){
return array("success" => true, "url" => $server_output);
}else{
if($server_output){
$res = json_decode($server_output);
return array("success" => false, "error_message" => $res->error_message);
}else{
return array("success" => false, "error_message" => "Error Code 103");
}
}
}else if(wp_remote_retrieve_response_code($response) == 500){
// sometimes 500 error returns for the sub images
if(preg_match("/\d+x\d+\./", $url)){
return array("success" => false, "error_message" => "500");
}else{
return array("success" => false, "error_message" => "Internal Server Error: ".$url);
}
}else{
return array("success" => false, "error_message" => "Could not connect server");
}
}
}
public function getQuality($img){
$d = $img->getImageGeometry();
if($d['width'] < 200 && $d['height'] < 200){
return 85;
}
return 90;
}
public function compareSizes($source_path, $destination_path){
$diff = filesize($source_path) - filesize($destination_path);
return ($diff > 0) ? $diff : 1;
}
public function createBackupFolder($destination_path){
$destination_path = str_replace($this->uploadDir['basedir'], "", $destination_path);
$pathArr = explode("/", $destination_path);
$path = $this->uploadDir['basedir'];
for ($i=1; $i < count($pathArr) - 1; $i++) {
$parentPath = $path;
$path = $path."/".$pathArr[$i];
if(!is_dir($path)){
if(@mkdir($path, 0755, true)){
}else{
//warning
if($pathArr[$i] == "wpfc-backup"){
//toDO: to stop cron job and warn the user
}
return array("success" => false, "error_message" => $parentPath." is not writable", "error_code" => 2);
}
}
}
return array("success" => true, "error_message" => "");
}
public function set_server_location(){
if(isset($_GET["server_url"]) && $_GET["server_url"]){
$this->location = $_GET["server_url"];
}else{
$this->location = "https://nuremberg.wpfastestcache.com";
}
}
public function setId(){
global $wpdb;
$last_id = $wpdb->get_var("SELECT `option_value` FROM `$wpdb->options` WHERE option_name = 'WpFcLastImageId';");
//$last_id = get_option("WpFcLastImageId")
if($last_id){
$this->id = $last_id;
}else if(isset($_GET["id"]) && $_GET["id"]){
$this->id = intval($_GET["id"]);
}else{
$this->id = $this->getFirstId();
if($this->id){
//add_option("WpFcLastImageId", $this->id, null, "yes");
$wpdb->insert($wpdb->options, array(
'option_name' => 'WpFcLastImageId',
'option_value' => $this->id,
'autoload' => 'yes'
));
}
}
}
public function setImages(){
if(isset($this->metadata["file"]) && $this->metadata["file"]){
$arr = array("file" => $this->uploadDir['basedir']."/".$this->metadata["file"],
"url" => $this->uploadDir['baseurl']."/".$this->metadata["file"],
"width" => $this->metadata["width"],
"height" => $this->metadata["height"],
"mime_type" => "");
array_push($this->images, $arr);
$i = 0;
$image_error = false;
if(is_array($this->metadata["sizes"])){
foreach((array)$this->metadata["sizes"] as $key => $value){
$value["url"] = $this->url.$value["file"];
$value["file"] = $this->path.$value["file"];
$value["mime_type"] = isset($value["mime-type"]) ? $value["mime-type"] : "";
unset($value["mime-type"]);
if($i == 0){
if($this->is_url_404($this->get_correct_url($this->uploadDir['baseurl']."/".$this->metadata["file"]))){
$image_error = true;
break;
}
}
if(!$this->is_url_404($this->get_correct_url($value["url"])) && $this->acceptable_mime_type($value["file"])){
array_push($this->images, $value);
}
$i++;
}
}
if(!$image_error){
$this->images_not_in_metadata();
}
//$this->images = array_slice($this->images, 0, 10);
}
}
public function get_correct_url($path){
if(preg_match("/^\/wp-content/i", $path)){
//content_url() must return HTTP but it return /wp-content so we need to check
if(content_url() == "/wp-content"){
if(home_url() == site_url()){
$path = home_url().$path;
}
}
}
return $path;
}
public function images_not_in_metadata(){
$paths = array();
foreach ($this->images as $key => $value) {
array_push($paths, $value["file"]);
}
$files = glob($this->path.$this->name."-"."*");
foreach ((array)$files as $dosya) {
if(@filesize($dosya) > 1000000){
continue;
}
if(!preg_match("/\.(jpg|jpeg|jpe|png)$/i", $dosya)){
continue;
}
$exp_dos = explode('/',$dosya);
$basename = end($exp_dos);
if(!in_array($dosya, $paths)){
if(preg_match("/".preg_quote($this->name, "/")."-(\d+)x(\d+)\..+/", $basename, $dimensions)){
$value = array();
$value["url"] = $this->url.$basename;
$value["file"] = $dosya;
$value["width"] = 0;
$value["height"] = 0;
$value["width"] = $dimensions[1];
$value["height"] = $dimensions[2];
if(!$this->is_url_404($value["url"])){
array_push($this->images, $value);
}
}
}
}
}
public function setPath(){
$this->path = $this->uploadDir['basedir']."/".preg_replace("/".preg_quote($this->name, "/")."\..+/", "", $this->metadata["file"]);
}
public function setUrl(){
$this->url = $this->uploadDir['baseurl']."/".preg_replace("/".preg_quote($this->name, "/")."\..+/", "", $this->metadata["file"]);
}
public function setName(){
if($this->metadata){
if(isset($this->metadata["sizes"]) && count($this->metadata["sizes"]) > 0){
$array_values = array_values($this->metadata["sizes"]);
$this->name = preg_replace("/-".$array_values[0]["width"]."x".$array_values[0]["height"].".+/", "", $array_values[0]["file"]);
if(!$this->name){
$this->name = substr($this->metadata["file"], strrpos($this->metadata["file"], "/") + 1);
}
}else{
$info = pathinfo($this->metadata["file"]);
$this->name = basename($this->metadata["file"],'.'.$info['extension']);
//$this->name = substr($this->metadata["file"], strrpos($this->metadata["file"], "/") + 1);
}
}
}
public function setMetaData(){
$this->metadata = wp_get_attachment_metadata($this->id);
}
//to get last image which is not optimized
public function getFirstId(){
// global $wpdb;
// $query = "SELECT SQL_CALC_FOUND_ROWS ".$wpdb->prefix."posts.ID FROM ".$wpdb->prefix."posts LEFT JOIN ".$wpdb->prefix."postmeta ON (".$wpdb->prefix."posts.ID = ".$wpdb->prefix."postmeta.post_id AND ".$wpdb->prefix."postmeta.meta_key = 'wpfc_optimisation' ) LEFT JOIN ".$wpdb->prefix."postmeta AS mt1 ON ( ".$wpdb->prefix."posts.ID = mt1.post_id ) WHERE 1=1 AND (".$wpdb->prefix."posts.post_mime_type = 'image/jpeg') AND ".$wpdb->prefix."posts.post_type = 'attachment' AND ((".$wpdb->prefix."posts.post_status = 'inherit')) AND (
// ".$wpdb->prefix."postmeta.post_id IS NULL
// AND
// mt1.meta_key = '_wp_attachment_metadata'
// ) GROUP BY ".$wpdb->prefix."posts.ID ORDER BY ".$wpdb->prefix."posts.ID DESC LIMIT 0, 1";
// $result = $wpdb->get_row( $query );
// if($result && $result->ID){
// return $result->ID;
// }else{
// // FOR PNG
// $query = "SELECT SQL_CALC_FOUND_ROWS ".$wpdb->prefix."posts.ID FROM ".$wpdb->prefix."posts LEFT JOIN ".$wpdb->prefix."postmeta ON (".$wpdb->prefix."posts.ID = ".$wpdb->prefix."postmeta.post_id AND ".$wpdb->prefix."postmeta.meta_key = 'wpfc_optimisation' ) LEFT JOIN ".$wpdb->prefix."postmeta AS mt1 ON ( ".$wpdb->prefix."posts.ID = mt1.post_id ) WHERE 1=1 AND (".$wpdb->prefix."posts.post_mime_type = 'image/png') AND ".$wpdb->prefix."posts.post_type = 'attachment' AND ((".$wpdb->prefix."posts.post_status = 'inherit')) AND (
// ".$wpdb->prefix."postmeta.post_id IS NULL
// AND
// mt1.meta_key = '_wp_attachment_metadata'
// ) GROUP BY ".$wpdb->prefix."posts.ID ORDER BY ".$wpdb->prefix."posts.ID DESC LIMIT 0, 1";
// $result = $wpdb->get_row( $query );
// if($result && $result->ID){
// return $result->ID;
// }else{
// return false;
// }
// }
$query_images_args = array(
'order' => 'DESC',
'orderby' => 'ID',
'post_type' => 'attachment',
'post_mime_type' =>'image/jpeg, image/png',
'post_status' => 'inherit',
'posts_per_page' => 1,
'meta_query' => array(
array(
'key' => 'wpfc_optimisation',
'compare' => 'NOT EXISTS'
),
array(
'key' => '_wp_attachment_metadata',
'compare' => 'EXISTS'
)
)
);
$query_image = new WP_Query( $query_images_args );
return count($query_image->posts) == 1 ? $query_image->posts[0]->ID : false;
}
public function wpfc_update_image_list_ajax_request(){
if(current_user_can('manage_options')){
$query_images_args = array();
$query_images_args["offset"] = $_GET["page"]*$_GET["per_page"];
$query_images_args['order'] = 'DESC';
$query_images_args['orderby'] = 'ID';
$query_images_args['post_type'] = 'attachment';
$query_images_args['post_mime_type'] = array('image/jpeg', 'image/png');
$query_images_args['post_status'] = 'inherit';
$query_images_args['posts_per_page'] = $_GET["per_page"];
$query_images_args['meta_query'] = array(
array(
'key' => 'wpfc_optimisation',
'compare' => 'EXISTS'
)
);
if(isset($_GET["search"]) && $_GET["search"]){
$query_images_args["s"] = isset($_GET["search"]) ? $_GET["search"] : "";
}
if(isset($_GET["filter"]) && $_GET["filter"]){
if($_GET["filter"] == "error_code"){
$filter = array(
'key' => 'wpfc_optimisation',
'value' => base64_encode('"error_code"'),
'compare' => 'LIKE'
);
$filter_second = array(
'key' => 'wpfc_optimisation',
'compare' => 'NOT LIKE'
);
array_push($query_images_args['meta_query'], $filter);
array_push($query_images_args['meta_query'], $filter_second);
}
}
$result = array("content" => $this->image_list_content($query_images_args),
"result_count" => $this->get_count_only($query_images_args)
);
echo json_encode($result);
exit;
}else{
wp_die("Must be admin");
}
}
public function get_credit(){
if($credit = get_transient("WpFc_credit")){
if(isset($_GET["credit"]) && $_GET["credit"] && $_GET["credit"] == "true"){
$credit = $credit - 1;
set_transient("WpFc_credit", $credit, 100);
return $credit;
}else{
return $credit;
}
}else{
$domain = preg_replace("/^www\d*\./", "", $_SERVER["HTTP_HOST"]);
$response = wp_remote_get("https://api.wpfastestcache.net/user/".$domain."/xcredit/".get_option("WpFc_api_key"),
array(
'timeout' => 5,
'sslverify' => false,
)
);
if ( !$response || is_wp_error( $response ) ) {
return $response->get_error_message();
}else{
if(wp_remote_retrieve_response_code($response) == 200){
$credit = wp_remote_retrieve_body( $response );
if (!is_numeric($credit)) {
return "Error Occured";
}
set_transient("WpFc_credit", $credit, 100);
return $credit;
}else{
if($credit = get_transient("WpFc_credit")){
return $credit;
}
return "Error Occured";
}
}
}
}
public function wpfc_statics_ajax_request(){
if(current_user_can('manage_options')){
$res = array(
"total_image_number" => $this->get_total_image_number(),
"error" => $this->get_total_image_error_number(),
"optimized" => 0,
//"optimized" => $this->get_total_optimized_image_number(),
"pending" => $this->get_total_pending_image_number(),
"reduction" => $this->get_total_reduction_image_number(),
"percent" => 0,
"credit" => $this->get_credit()
);
$res["optimized"] = $res["total_image_number"] - $res["pending"] - $res["error"];
if($res["total_image_number"] > 0){
$res["percent"] = ($res["total_image_number"] - $res["pending"] - $res["error"])*100/$res["total_image_number"];
}else{
$res["percent"] = 0;
}
$res["percent"] = number_format($res["percent"], 2);
$res["reduction"] = $res["reduction"]/1000;
die(json_encode($res));
}else{
wp_die("Must be admin");
}
}
public function wpfc_optimize_image_ajax_request(){
if(current_user_can('manage_options')){
$res = $this->optimizeFirstImage();
$res[1] = isset($res[1]) ? $res[1] : "";
$res[2] = isset($res[2]) ? $res[2] : "";
$res[3] = isset($res[3]) ? $res[3] : "";
// if(isset($res[1]) && $res[1] == "error"){
// if(isset($res[0]) && preg_match("/Buy\s+the\s+premium/", $res[0])){
// if(isset($GLOBALS['wp_fastest_cache']) && method_exists($GLOBALS['wp_fastest_cache'], 'rm_folder_recursively')){
// $GLOBALS["wp_fastest_cache"]->rm_folder_recursively(WPFC_WP_PLUGIN_DIR."/wp-fastest-cache-premium/pro/library");
// deactivate_plugins("wp-fastest-cache-premium/wpFastestCachePremium.php");
// }
// }
// }
die('{"message" : "'.$res[0].'", "success" : "'.$res[1].'", "id" : "'.$res[2].'", "percentage" : "'.$res[3].'"}');
}else{
wp_die("Must be admin");
}
}
public function wpfc_revert_image_ajax_request(){
if(current_user_can('manage_options')){
delete_option("WpFcLastImageId");
if($this->id){
$valueJson = get_post_meta($this->id, 'wpfc_optimisation', true);
$tmpvalueJson = base64_decode($valueJson);
$std = json_decode($tmpvalueJson);
if(count($std) == 1 && isset($std[0]) && $std[0]){
if(isset($std[0]->error_code) && $std[0]->error_code){
if($std[0]->error_code == 18 || $std[0]->error_code == 5){
delete_post_meta($this->id, "wpfc_optimisation");
delete_post_meta($this->id, "wpfc_optimisation_reduction");
die('{"success" : "true"}');
}
}
}
$result = false;
$std = array_reverse($std);
$error_numbers = 0;
foreach ($std as $key => $image) {
if(@rename($image->file, $image->file."_tmp")){
if(isset($image->destination_path) && file_exists($image->destination_path)){
if(@copy($image->destination_path, $image->file)){
unlink($image->destination_path);
unlink($image->file."_tmp");
if(file_exists($image->file.".webp")){
unlink($image->file.".webp");
}
delete_post_meta($this->id, "wpfc_optimisation");
delete_post_meta($this->id, "wpfc_optimisation_reduction");
$result = '{"success" : "true"}';
}else{
$result = '{"success" : "false"}';
//toDo not writeable folder
}
}else{
rename($image->file."_tmp", $image->file);
if(isset($image->error_code) && $image->error_code){
if(isset($this->metadata["file"]) && preg_match("/".preg_quote($this->metadata["file"], "/")."/", $image->url)){
delete_post_meta($this->id, "wpfc_optimisation");
delete_post_meta($this->id, "wpfc_optimisation_reduction");
$result = '{"success" : "true"}';
}else{
$error_numbers++;
if($error_numbers == count($std)){
delete_post_meta($this->id, "wpfc_optimisation");
delete_post_meta($this->id, "wpfc_optimisation_reduction");
$result = '{"success" : "true"}';
}
}
}else{
if(preg_match("/".preg_quote($this->metadata["file"], "/")."/", $image->url)){
delete_post_meta($this->id, "wpfc_optimisation");
delete_post_meta($this->id, "wpfc_optimisation_reduction");
$result = '{"success" : "true"}';
}
}
}
}else{
if(preg_match("/".preg_quote($this->metadata["file"], "/")."/", $image->url)){
if(file_exists($image->file)){
$result = '{"success" : "false", "message" : "'.$image->file.' is not writable"}';
break;
}
}
//toDo file is not writeable
}
}//end of loop
}else{
//toDO id not found
$result = '{"success" : "false"}';
}
die($result);
}else{
wp_die("Must be admin");
}
}
public function getErrorText($id){
/*
Error Codes
2 = in backup folder parent folder not writable
3 = no need to optimize
4 = source is not writable
5 = destination is not writable
6 = ImageMagick library is not avaliable
7 = Error via api
8 = Source file does not exist
*/
$errors = array(
2 => "In backup folder parent folder not writable",
3 => "No need to optimize",
4 => "Source is not writable",
5 => "Destination is not writable",
7 => "Error via api",
8 => "Source file does not exist",
9 => "Image size exceed 20mb limit while processing",
11 => "Empty Name",
12 => "Forbidden",
13 => "CloudFlare to restrict access",
14 => "No Extension",
15 => "Image size is 0Kb",
16 => "Corrupted Image",
17 => "Empty metadata",
18 => "No Image",
19 => "destination_move_source_path is not saved",
20 => "file size of destination_move_source_path is zero",
21 => "Unacceptable file type"
);
return isset($errors[$id]) ? $errors[$id] : "Unkown error code";
}
public function backup_folder_exist(){
$backup_folder_path = $this->uploadDir["basedir"]."/wpfc-backup";
if(is_dir($backup_folder_path)){
return true;
}else{
if(@mkdir($backup_folder_path, 0755, true)){
return true;
}
return false;
}
}
public function push_main_image($arr){
if(isset($arr[0]) && !isset($arr[0]->error_code)){
$main = clone $arr[0];
$total_reduction = 0;
foreach($arr as $stdKey => $stdValue){
if(!isset($stdValue->error_code)){
if(isset($stdValue->reduction) && $stdValue->reduction){
$total_reduction = $total_reduction + $stdValue->reduction;
}
}
}
$main->reduction = $total_reduction;
array_unshift($arr, $main);
}
return $arr;
}
public function image_list_content($query_images_args = array()){
$query_image = new WP_Query( $query_images_args );
$return_output = "";
if(count($query_image->posts) > 0){
foreach ($query_image->posts as $key => $post) {
$valueJson = get_post_meta( $post->ID, 'wpfc_optimisation', true);
$tmpvalueJson = base64_decode($valueJson);
$std = json_decode($tmpvalueJson);
$revert = true;
// $revert = false;
// foreach ($std as $keyTmp => $valueTmp) {
// if (array_key_exists("error_code", $valueTmp)){
// $revert = true;
// break;
// }
// }
$std = $this->push_main_image($std);
foreach ($std as $stdKey => $stdValue){
$template_name = $stdKey === 0 ? "image_line_first.html" : "image_line.html";
if($content = @file_get_contents($this->get_template_path($template_name))){
$stdValue->destination_path = isset($stdValue->destination_path) ? $stdValue->destination_path : "";
$stdValue->reduction = isset($stdValue->reduction) ? $stdValue->reduction : 0;
if($stdKey === 0 && $revert){
$revert_button = "";
}else{
$revert_button = "display:none;";
}
if(isset($stdValue->error_code) && $stdValue->error_code == 8){
$revert_button = "display:none;";
}
if(file_exists($stdValue->destination_path)){
$backup_url = str_replace($this->uploadDir['baseurl'], $this->uploadDir['baseurl']."/wpfc-backup",$stdValue->url)."?v=".time();
$backup_title = "Backup Image";
$backup_error_style = "";
}else{
if(isset($stdValue->error_code) && $stdValue->error_code){
$backup_url = get_edit_post_link($stdValue->id);
$backup_title = $this->getErrorText($stdValue->error_code);
$backup_error_style = "color: #FF0000;cursor:pointer;font-weight:bold;";
}else{
$backup_url = "#";
$backup_title = "";
$backup_error_style = "";
}
}
if(file_exists($stdValue->file)){
$stdValue->url = $stdValue->url."?v=".time();
}else{
$stdValue->url = plugins_url("wp-fastest-cache")."/images/no-image.gif";
}
$short_code = array("{{post_id}}",
"{{attachment}}",
"{{post_title}}",
"{{url}}",
"{{width}}",
"{{height}}",
"{{reduction}}",
"{{date}}",
"{{revert_button}}",
"{{backup_url}}",
"{{backup_title}}",
"{{backup_error_style}}"
);
$datas = array($stdValue->id,
$stdValue->url,
$post->post_title,
$stdValue->url,
$stdValue->width,
$stdValue->height,
$stdValue->reduction/1000,
date("d-m-Y <br> H:i:s", $stdValue->time),
$revert_button,
$backup_url,
$backup_title,
$backup_error_style
);
$return_output .= str_replace($short_code, $datas, $content);
}
}
}
}else{
$return_output = @file_get_contents($this->get_template_path("empty_image_line.html"));
}
return $return_output;
}
public function imageList(){ ?>
<div id="wpfc-image-list" style="display:none;">
<?php $this->paging(); ?>
<div style="float:left;">
<table class="wp-list-table widefat fixed media" style="width: 95%; margin-left: 20px;">
<thead>
<tr style="height: 35px;">
<th scope="col" id="icon" class="manage-column column-icon" style=""></th>
<th scope="col" id="title" class="manage-column column-title sortable desc" style="width: 323px;">
<span style="padding-left: 8px;">File Name</span>
</th>
<th scope="col" id="author" class="manage-column column-author sortable desc" style="width: 120px;text-align: center;">
<span>Reduction</span>
</th>
<th scope="col" id="date" class="manage-column column-date sortable asc" style="width: 91px;text-align: center;">
<span>Date</span>
</th>
<th scope="col" id="date" class="manage-column column-date sortable asc" style="width: 60px;text-align: center;">
<span>Revert</span>
</th>
</tr>
</thead>
<tbody id="the-list"></tbody>
</table>
</div>
</div>
<div id="revert-loader"></div>
<script type="text/javascript">
jQuery(document).ready(function() {
WpFcStatics.init("<?php echo admin_url(); ?>admin-ajax.php", "<?php echo plugins_url(); ?>", "<?php echo $this->get_country_code(); ?>", "<?php echo get_locale(); ?>");
WpFcStatics.set_click_event_revert_image();
jQuery("#wpfc-imageOptimisation").change(function(e){
WpFcStatics.update_statics();
WpFcStatics.wpfc_get_servers();
});
});
</script><?php
}
public function get_country_code($sslverify = false){
$country = get_transient("wpfc_country_code");
if($country){
return $country;
}else{
$response = wp_remote_get("https://detect-country.ehlibeyt.workers.dev/",
array(
'timeout' => 5,
'sslverify' => $sslverify,
'user-agent' => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:64.0) Gecko/20100101 Firefox/64.0"
)
);
if ( !$response || is_wp_error( $response ) ) {
if($sslverify){
return "";
}else{
return $this->get_country_code(true);
}
}else{
if(wp_remote_retrieve_response_code($response) == 200){
$country = trim(wp_remote_retrieve_body($response));
if(strlen($country) == 2){
set_transient("wpfc_country_code", $country, 60*60*24*3);
return $country;
}
}
}
return "";
}
}
public function paging(){
include_once($this->get_template_path("paging.html"));
}
public function statics(){
include_once($this->get_template_path("image-statics.php"));
}
public function acceptable_mime_type($filename){
$mimetype = false;
if(!file_exists($filename)){
return false;
}
if(function_exists('finfo_open')) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo, $filename);
finfo_close($finfo);
}else if(function_exists('getimagesize')) {
$img = getimagesize($filename);
$mimetype = $img["mime"];
}else{
echo "not found mime_content_type";
exit;
}
if(preg_match("/\.webp$/i", $filename)){
return false;
}
if(preg_match("/jpg|jpeg|jpe|png/i", $mimetype)){
return true;
}
return false;
}
public function is_url_404($url){
return false;
$res = wp_remote_head($url, array('timeout' => 3 ));
if(is_wp_error($res)){
$url_header = @get_headers($url);
if(preg_match("/200\s+OK/i", $url_header[0])){
return false;
}else{
return true;
}
}else{
if($res["response"]["code"] == 200){
return false;
}
}
return true;
}
public function image_arr_unique($images){
if(count($images) > 1){
$arr = array();
$images_tmp = array();
foreach ($images as $key => $value) {
if(!in_array($value["file"], $arr)){
array_push($arr, $value["file"]);
array_push($images_tmp, $value);
}
}
return $images_tmp;
}
return $images;
}
}
?>