Imagify Image Optimizer - Version 1.6.11

Version Description

  • Improvement: Imagify now works with the iOS app, and with XML-RPC in general.
  • Improvement: we harmonized and improved how user roles are handled.
  • Improvement: prevent optimized image to be cached by the browser in the comparison tool.
  • Fix: sometimes the comparison tool's button wouldn't show on the attachment edition page.
  • Fix: the bulk optimization button works again.
Download this release

Release Info

Developer wp_media
Plugin Icon 128x128 Imagify Image Optimizer
Version 1.6.11
Comparing to
See all releases

Code changes from version 1.6.10 to 1.6.11

Files changed (59) hide show
  1. assets/images/big-blue-check.png +0 -0
  2. assets/images/icon-arrow-choice.png +0 -0
  3. assets/images/icon-arrow-choice.svg +0 -0
  4. assets/images/icon-lock.png +0 -0
  5. assets/images/icon-lock.svg +0 -0
  6. assets/images/icon-pack.png +0 -0
  7. assets/images/icon-pack.svg +0 -0
  8. assets/images/pic-ericwaltr.jpg +0 -0
  9. assets/images/pic-srhdesign.jpg +0 -0
  10. assets/js/imagify-gulp.js +0 -0
  11. assets/js/imagify-gulp.min.js +0 -0
  12. assets/js/jquery.twentytwenty.js +41 -40
  13. assets/js/jquery.twentytwenty.min.js +1 -1
  14. imagify.php +7 -4
  15. inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf-attachment.php +0 -0
  16. inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf.php +4 -4
  17. inc/3rd-party/hosting/wpengine.php +0 -0
  18. inc/3rd-party/nextgen-gallery/inc/admin/ajax.php +60 -2
  19. inc/3rd-party/nextgen-gallery/inc/admin/bulk.php +0 -0
  20. inc/3rd-party/nextgen-gallery/inc/admin/db.php +0 -0
  21. inc/3rd-party/nextgen-gallery/inc/admin/enqueue.php +1 -1
  22. inc/3rd-party/nextgen-gallery/inc/admin/gallery.php +5 -1
  23. inc/3rd-party/nextgen-gallery/inc/admin/heartbeat.php +0 -0
  24. inc/3rd-party/nextgen-gallery/inc/admin/menu.php +2 -2
  25. inc/3rd-party/nextgen-gallery/inc/classes/class-imagify-ngg-attachment.php +14 -9
  26. inc/3rd-party/nextgen-gallery/inc/classes/class-imagify-ngg-db.php +0 -0
  27. inc/3rd-party/nextgen-gallery/inc/common/attachments.php +7 -8
  28. inc/3rd-party/nextgen-gallery/inc/functions/admin-stats.php +0 -0
  29. inc/3rd-party/nextgen-gallery/inc/functions/attachments.php +0 -0
  30. inc/3rd-party/nextgen-gallery/inc/functions/common.php +21 -0
  31. inc/3rd-party/nextgen-gallery/nextgen-gallery.php +1 -0
  32. inc/3rd-party/wp-rocket.php +0 -0
  33. inc/3rd-party/yoast-seo.php +1 -1
  34. inc/admin/ajax.php +0 -725
  35. inc/admin/media.php +9 -1
  36. inc/admin/menu.php +1 -1
  37. inc/admin/meta-boxes.php +1 -1
  38. inc/admin/options.php +11 -13
  39. inc/admin/ui/bulk.php +13 -11
  40. inc/admin/upload.php +11 -5
  41. inc/classes/abstracts/class-imagify-abstract-attachment.php +1 -1
  42. inc/classes/abstracts/class-imagify-abstract-db.php +0 -0
  43. inc/classes/class-imagify-admin-ajax-post.php +876 -0
  44. inc/classes/class-imagify-assets.php +38 -1
  45. inc/classes/class-imagify-attachment.php +0 -0
  46. inc/classes/class-imagify-notices.php +8 -17
  47. inc/classes/class-imagify.php +0 -0
  48. inc/common/admin-bar.php +1 -1
  49. inc/common/attachments.php +10 -4
  50. inc/functions/admin-ui.php +5 -1
  51. inc/functions/admin.php +11 -13
  52. inc/functions/api.php +1 -0
  53. inc/functions/common.php +106 -10
  54. inc/functions/compat.php +74 -22
  55. inc/functions/deprecated.php +256 -0
  56. inc/functions/i18n.php +15 -2
  57. inc/functions/process.php +31 -1
  58. readme.txt +8 -1
  59. uninstall.php +7 -5
assets/images/big-blue-check.png CHANGED
File without changes
assets/images/icon-arrow-choice.png CHANGED
File without changes
assets/images/icon-arrow-choice.svg CHANGED
File without changes
assets/images/icon-lock.png CHANGED
File without changes
assets/images/icon-lock.svg CHANGED
File without changes
assets/images/icon-pack.png CHANGED
File without changes
assets/images/icon-pack.svg CHANGED
File without changes
assets/images/pic-ericwaltr.jpg CHANGED
File without changes
assets/images/pic-srhdesign.jpg CHANGED
File without changes
assets/js/imagify-gulp.js CHANGED
File without changes
assets/js/imagify-gulp.min.js CHANGED
File without changes
assets/js/jquery.twentytwenty.js CHANGED
@@ -241,7 +241,7 @@
241
  // Load after img.
242
  $modal.find( '.imagify-img-after' ).on( 'load', function() {
243
  imgsLoaded++;
244
- } ).attr( 'src', settings.optimizedUrl );
245
 
246
  $tt = $modal.find( '.twentytwenty-container' );
247
  checkLoad = setInterval( function() {
@@ -262,7 +262,7 @@
262
 
263
  if ( ! $tt.closest( '.imagify-modal-content' ).hasClass( 'loaded' ) ) {
264
  $tt.closest( '.imagify-modal-content' ).removeClass( 'loading' ).addClass( 'loaded' );
265
- drawMeAChart( $modal.find( '.imagify-level-optimized' ).find( '.imagify-chart' ).find( 'canvas' ) );
266
  }
267
 
268
  // Check if image height is to big.
@@ -425,7 +425,7 @@
425
  // Fires on initialisation & each time the handle is moving.
426
  if ( ! $tt.closest( '.imagify-modal-content' ).hasClass( 'loaded' ) ) {
427
  $tt.closest( '.imagify-modal-content' ).removeClass( 'loading' ).addClass( 'loaded' );
428
- drawMeAChart( $( '.imagify-level-ultra' ).find( '.imagify-chart' ).find( 'canvas' ) );
429
  }
430
  } );
431
 
@@ -463,7 +463,7 @@
463
  $imgBefore.attr( 'style', '' );
464
  $imgBefore.removeClass( 'twentytwenty-before' );
465
  $container.find( '.img-' + image ).addClass( 'twentytwenty-before' ).css( 'clip', clipStyles );
466
- $( '.twentytwenty-before-label' ).find( '.twentytwenty-label-content' ).text( $container.data( image + '-label' ) );
467
  $( '.imagify-c-level.go-left' ).attr( 'aria-hidden', 'true' ).removeClass( 'go-left go-right' );
468
  $( '.imagify-level-' + image ).attr( 'aria-hidden', 'false' ).addClass( 'go-left' );
469
  }
@@ -472,44 +472,43 @@
472
  if ( 'right' === side ) {
473
  $imgAfter.removeClass( 'twentytwenty-after' );
474
  $container.find( '.img-' + image ).addClass( 'twentytwenty-after' );
475
- $( '.twentytwenty-after-label' ).find( '.twentytwenty-label-content' ).text( $container.data( image + '-label' ) );
476
  $( '.imagify-c-level.go-right' ).attr( 'aria-hidden', 'true' ).removeClass( 'go-left go-right' );
477
  $( '.imagify-level-' + image ).attr( 'aria-hidden', 'false' ).addClass( 'go-right' );
478
  }
479
 
480
- drawMeAChart( $( '.imagify-level-' + image ).find( '.imagify-chart' ).find( 'canvas' ) );
481
  } );
482
  } );
483
 
484
 
485
  /**
486
- * Imagify comparison inside Media post visualization.
487
  */
488
- if ( $( '.post-php' ).find( '.wp_attachment_image' ).find( '.thumbnail' ).length > 0 ) {
489
 
490
- var $oriParent = $( '.post-php' ).find( '.wp_attachment_image' ),
491
- $thumbnail = $oriParent.find( '.thumbnail' ),
492
- thumb = { src: $thumbnail.prop( 'src' ), width: $thumbnail.width(), height: $thumbnail.height() },
493
  oriSource = { src: $( '#imagify-full-original' ).val(), size: $( '#imagify-full-original-size' ).val() },
494
- $optimizeBtn = $( '#misc-publishing-actions' ).find( '.misc-pub-imagify' ).find( '.button-primary' ),
495
- widthLimit = 360,
496
  filesize, saving;
497
 
 
 
498
  // If shown image > 360, use twentytwenty.
499
- if ( thumb.width > widthLimit && $( '#imagify-full-original' ).length > 0 && $( '#imagify-full-original' ).val() !== '' ) {
500
 
501
- filesize = $( '.misc-pub-filesize' ).find( 'strong' ).text();
502
- saving = $( '.imagify-data-item' ).find( '.imagify-chart-value' ).text();
503
 
504
  // Create button to trigger.
505
  $( '[id^="imgedit-open-btn-"]' ).before( '<button type="button" class="imagify-button-primary button-primary imagify-modal-trigger" data-target="#imagify-visual-comparison" id="imagify-start-comparison">' + imagifyTTT.labels.compare + '</button>' );
506
 
507
  // Modal and trigger event creation.
508
  imagifyTwentyModal( {
509
- width: thumb.width,
510
- height: thumb.height,
511
  originalUrl: oriSource.src,
512
- optimizedUrl: thumb.src,
513
  originalSize: oriSource.size,
514
  optimizedSize: filesize,
515
  saving: saving,
@@ -519,20 +518,20 @@
519
  } );
520
  }
521
  // Else put images next to next.
522
- else if ( thumb.width < widthLimit && $( '#imagify-full-original' ).length > 0 && $( '#imagify-full-original' ).val() !== '' ) {
523
  // TODO
524
  }
525
  // If image has no backup.
526
- else if ( $( '#imagify-full-original' ).length > 0 && $( '#imagify-full-original' ).val() === '' ) {
527
  // do nothing ?
528
  }
529
  // In case image is not optimized.
530
  else {
531
  // If is not in optimizing process, propose the Optimize button trigger.
532
- if ( $( '#misc-publishing-actions' ).find( '.misc-pub-imagify' ).find( '.button-primary' ).length === 1 ) {
533
  $( '[id^="imgedit-open-btn-"]' ).before( '<span class="spinner imagify-hidden"></span><a class="imagify-button-primary button-primary imagify-optimize-trigger" id="imagify-optimize-trigger" href="' + $optimizeBtn.attr( 'href' ) + '">' + imagifyTTT.labels.optimize + '</a>' );
534
 
535
- $( '#imagify-optimize-trigger' ).on('click', function() {
536
  $( this ).prev( '.spinner' ).removeClass( 'imagify-hidden' ).addClass( 'is-active' );
537
  } );
538
  }
@@ -543,7 +542,7 @@
543
  /**
544
  * Images comparison in attachments list page (upload.php).
545
  */
546
- if ( $( '.upload-php' ).find( '.imagify-compare-images' ).length > 0 ) {
547
 
548
  $( '.imagify-compare-images' ).each( function() {
549
  var $this = $( this ),
@@ -552,12 +551,12 @@
552
 
553
  // Modal and trigger event creation.
554
  imagifyTwentyModal( {
555
- width: $this.data( 'full-width' ),
556
- height: $this.data( 'full-height' ),
557
  originalUrl: $this.data( 'backup-src' ),
558
  optimizedUrl: $this.data( 'full-src' ),
559
  originalSize: $datas.find( '.original' ).text(),
560
- optimizedSize: $datas.find( '.imagify-data-item' ).find( '.big' ).text(),
561
  saving: $datas.find( '.imagify-chart-value' ).text(),
562
  modalAppendTo: $this.closest( '.column-primary' ),
563
  trigger: $this,
@@ -569,7 +568,7 @@
569
  /**
570
  * Images Comparison in Grid View modal.
571
  */
572
- if ( $('.upload-php').length > 0 ) {
573
 
574
  var getVar = function ( param ) {
575
  var vars = {};
@@ -588,29 +587,31 @@
588
  },
589
  imagifyContentInModal = function() {
590
  var tempTimer = setInterval( function() {
591
- var $datas;
592
 
593
- if ( ! $( '.media-modal' ).find( '.imagify-datas-details' ).length ) {
594
  return;
595
  }
596
 
597
- if ( $( '#imagify-original-src' ).length > 0 && $( '#imagify-original-src' ) !== '' ) {
 
 
598
  // Trigger creation.
599
- $( '.media-frame-content' ).find( '.attachment-actions' ).prepend( '<button type="button" class="imagify-button-primary button-primary imagify-modal-trigger" data-target="#imagify-comparison-modal" id="imagify-media-frame-comparison-btn">' + imagifyTTT.labels.compare + '</button>' );
600
 
601
  // Get datas.
602
- $datas = $( '.media-frame-content' ).find( '.compat-field-imagify' );
603
 
604
  // Modal and trigger event creation.
605
  imagifyTwentyModal( {
606
- width: $( '#imagify-full-width' ).val(),
607
- height: $( '#imagify-full-height' ).val(),
608
- originalUrl: $( '#imagify-original-src' ).val(),
609
  optimizedUrl: $( '#imagify-full-src' ).val(),
610
  originalSize: $( '#imagify-original-size' ).val(),
611
- optimizedSize: $datas.find( '.imagify-data-item' ).find( '.big' ).text(),
612
  saving: $datas.find( '.imagify-chart-value' ).text(),
613
- modalAppendTo: $( '.media-frame-content' ).find( '.thumbnail-image' ),
614
  trigger: $( '#imagify-media-frame-comparison-btn' ),
615
  modalId: 'imagify-comparison-modal',
616
  openModal: true
@@ -622,12 +623,12 @@
622
  }, 20 );
623
  },
624
  waitContent = setInterval( function() {
625
- if ( ! $('.upload-php').find('.media-frame.mode-grid').find('.attachments').length ) {
626
  return;
627
  }
628
 
629
  // If attachment is clicked, build the modal inside the modal.
630
- $( '.upload-php' ).find( '.media-frame.mode-grid' ).on( 'click', '.attachment', function() {
631
  imagifyContentInModal();
632
  } );
633
 
241
  // Load after img.
242
  $modal.find( '.imagify-img-after' ).on( 'load', function() {
243
  imgsLoaded++;
244
+ } ).attr( 'src', settings.optimizedUrl + ( settings.optimizedUrl.indexOf( '?' ) > 0 ? '&' : '?' ) + 'v=' + Date.now() );
245
 
246
  $tt = $modal.find( '.twentytwenty-container' );
247
  checkLoad = setInterval( function() {
262
 
263
  if ( ! $tt.closest( '.imagify-modal-content' ).hasClass( 'loaded' ) ) {
264
  $tt.closest( '.imagify-modal-content' ).removeClass( 'loading' ).addClass( 'loaded' );
265
+ drawMeAChart( $modal.find( '.imagify-level-optimized .imagify-chart canvas' ) );
266
  }
267
 
268
  // Check if image height is to big.
425
  // Fires on initialisation & each time the handle is moving.
426
  if ( ! $tt.closest( '.imagify-modal-content' ).hasClass( 'loaded' ) ) {
427
  $tt.closest( '.imagify-modal-content' ).removeClass( 'loading' ).addClass( 'loaded' );
428
+ drawMeAChart( $( '.imagify-level-ultra .imagify-chart canvas' ) );
429
  }
430
  } );
431
 
463
  $imgBefore.attr( 'style', '' );
464
  $imgBefore.removeClass( 'twentytwenty-before' );
465
  $container.find( '.img-' + image ).addClass( 'twentytwenty-before' ).css( 'clip', clipStyles );
466
+ $( '.twentytwenty-before-label .twentytwenty-label-content' ).text( $container.data( image + '-label' ) );
467
  $( '.imagify-c-level.go-left' ).attr( 'aria-hidden', 'true' ).removeClass( 'go-left go-right' );
468
  $( '.imagify-level-' + image ).attr( 'aria-hidden', 'false' ).addClass( 'go-left' );
469
  }
472
  if ( 'right' === side ) {
473
  $imgAfter.removeClass( 'twentytwenty-after' );
474
  $container.find( '.img-' + image ).addClass( 'twentytwenty-after' );
475
+ $( '.twentytwenty-after-label .twentytwenty-label-content' ).text( $container.data( image + '-label' ) );
476
  $( '.imagify-c-level.go-right' ).attr( 'aria-hidden', 'true' ).removeClass( 'go-left go-right' );
477
  $( '.imagify-level-' + image ).attr( 'aria-hidden', 'false' ).addClass( 'go-right' );
478
  }
479
 
480
+ drawMeAChart( $( '.imagify-level-' + image + ' .imagify-chart canvas' ) );
481
  } );
482
  } );
483
 
484
 
485
  /**
486
+ * Imagify comparison inside Media post edition.
487
  */
488
+ if ( imagifyTTT.imageWidth && $( '.post-php .wp_attachment_image .thumbnail' ).length > 0 ) {
489
 
490
+ var $oriParent = $( '.post-php .wp_attachment_image' ),
 
 
491
  oriSource = { src: $( '#imagify-full-original' ).val(), size: $( '#imagify-full-original-size' ).val() },
492
+ $optimizeBtn = $( '#misc-publishing-actions' ).find( '.misc-pub-imagify .button-primary' ),
 
493
  filesize, saving;
494
 
495
+ imagifyTTT.widthLimit = parseInt( imagifyTTT.widthLimit, 10 );
496
+
497
  // If shown image > 360, use twentytwenty.
498
+ if ( imagifyTTT.imageWidth > imagifyTTT.widthLimit && oriSource.src ) {
499
 
500
+ filesize = $( '.misc-pub-filesize strong' ).text();
501
+ saving = $( '.imagify-data-item .imagify-chart-value' ).text();
502
 
503
  // Create button to trigger.
504
  $( '[id^="imgedit-open-btn-"]' ).before( '<button type="button" class="imagify-button-primary button-primary imagify-modal-trigger" data-target="#imagify-visual-comparison" id="imagify-start-comparison">' + imagifyTTT.labels.compare + '</button>' );
505
 
506
  // Modal and trigger event creation.
507
  imagifyTwentyModal( {
508
+ width: parseInt( imagifyTTT.imageWidth, 10 ),
509
+ height: parseInt( imagifyTTT.imageHeight, 10 ),
510
  originalUrl: oriSource.src,
511
+ optimizedUrl: imagifyTTT.imageSrc,
512
  originalSize: oriSource.size,
513
  optimizedSize: filesize,
514
  saving: saving,
518
  } );
519
  }
520
  // Else put images next to next.
521
+ else if ( imagifyTTT.imageWidth < imagifyTTT.widthLimit && oriSource.src ) {
522
  // TODO
523
  }
524
  // If image has no backup.
525
+ else if ( $( '#imagify-full-original' ).length > 0 && '' === oriSource.src ) {
526
  // do nothing ?
527
  }
528
  // In case image is not optimized.
529
  else {
530
  // If is not in optimizing process, propose the Optimize button trigger.
531
+ if ( $( '#misc-publishing-actions' ).find( '.misc-pub-imagify .button-primary' ).length === 1 ) {
532
  $( '[id^="imgedit-open-btn-"]' ).before( '<span class="spinner imagify-hidden"></span><a class="imagify-button-primary button-primary imagify-optimize-trigger" id="imagify-optimize-trigger" href="' + $optimizeBtn.attr( 'href' ) + '">' + imagifyTTT.labels.optimize + '</a>' );
533
 
534
+ $( '#imagify-optimize-trigger' ).on( 'click', function() {
535
  $( this ).prev( '.spinner' ).removeClass( 'imagify-hidden' ).addClass( 'is-active' );
536
  } );
537
  }
542
  /**
543
  * Images comparison in attachments list page (upload.php).
544
  */
545
+ if ( $( '.upload-php .imagify-compare-images' ).length > 0 ) {
546
 
547
  $( '.imagify-compare-images' ).each( function() {
548
  var $this = $( this ),
551
 
552
  // Modal and trigger event creation.
553
  imagifyTwentyModal( {
554
+ width: parseInt( $this.data( 'full-width' ), 10 ),
555
+ height: parseInt( $this.data( 'full-height' ), 10 ),
556
  originalUrl: $this.data( 'backup-src' ),
557
  optimizedUrl: $this.data( 'full-src' ),
558
  originalSize: $datas.find( '.original' ).text(),
559
+ optimizedSize: $datas.find( '.imagify-data-item .big' ).text(),
560
  saving: $datas.find( '.imagify-chart-value' ).text(),
561
  modalAppendTo: $this.closest( '.column-primary' ),
562
  trigger: $this,
568
  /**
569
  * Images Comparison in Grid View modal.
570
  */
571
+ if ( $( '.upload-php' ).length > 0 ) {
572
 
573
  var getVar = function ( param ) {
574
  var vars = {};
587
  },
588
  imagifyContentInModal = function() {
589
  var tempTimer = setInterval( function() {
590
+ var $datas, originalSrc;
591
 
592
+ if ( ! $( '.media-modal .imagify-datas-details' ).length ) {
593
  return;
594
  }
595
 
596
+ originalSrc = $( '#imagify-original-src' ).val();
597
+
598
+ if ( originalSrc ) {
599
  // Trigger creation.
600
+ $( '.media-frame-content .attachment-actions' ).prepend( '<button type="button" class="imagify-button-primary button-primary imagify-modal-trigger" data-target="#imagify-comparison-modal" id="imagify-media-frame-comparison-btn">' + imagifyTTT.labels.compare + '</button>' );
601
 
602
  // Get datas.
603
+ $datas = $( '.media-frame-content .compat-field-imagify' );
604
 
605
  // Modal and trigger event creation.
606
  imagifyTwentyModal( {
607
+ width: parseInt( $( '#imagify-full-width' ).val(), 10 ),
608
+ height: parseInt( $( '#imagify-full-height' ).val(), 10 ),
609
+ originalUrl: originalSrc,
610
  optimizedUrl: $( '#imagify-full-src' ).val(),
611
  originalSize: $( '#imagify-original-size' ).val(),
612
+ optimizedSize: $datas.find( '.imagify-data-item .big' ).text(),
613
  saving: $datas.find( '.imagify-chart-value' ).text(),
614
+ modalAppendTo: $( '.media-frame-content .thumbnail-image' ),
615
  trigger: $( '#imagify-media-frame-comparison-btn' ),
616
  modalId: 'imagify-comparison-modal',
617
  openModal: true
623
  }, 20 );
624
  },
625
  waitContent = setInterval( function() {
626
+ if ( ! $( '.upload-php .media-frame.mode-grid .attachments' ).length ) {
627
  return;
628
  }
629
 
630
  // If attachment is clicked, build the modal inside the modal.
631
+ $( '.upload-php .media-frame.mode-grid' ).on( 'click', '.attachment', function() {
632
  imagifyContentInModal();
633
  } );
634
 
assets/js/jquery.twentytwenty.min.js CHANGED
@@ -1 +1 @@
1
- !function(a,b,c,d){a.fn.twentytwenty=function(b,d){return b=a.extend({handlePosition:.5,orientation:"horizontal",labelBefore:"Before",labelAfter:"After"},b),this.each(function(){var e=b.handlePosition,f=a(this),g=b.orientation,h="vertical"===g?"down":"left",i="vertical"===g?"up":"right",j=f.find("img:first"),k=f.find("img:last");f.wrap('<div class="twentytwenty-wrapper twentytwenty-'+g+'"></div>'),f.append('<div class="twentytwenty-overlay"></div>'),f.append('<div class="twentytwenty-handle"></div>');var l=f.find(".twentytwenty-handle");l.append('<span class="twentytwenty-'+h+'-arrow"></span>'),l.append('<span class="twentytwenty-'+i+'-arrow"></span>'),f.addClass("twentytwenty-container"),j.addClass("twentytwenty-before"),k.addClass("twentytwenty-after");var m=f.find(".twentytwenty-overlay");m.append('<div class="twentytwenty-labels twentytwenty-before-label"><span class="twentytwenty-label-content">'+b.labelBefore+"</span></div>"),m.append('<div class="twentytwenty-labels twentytwenty-after-label"><span class="twentytwenty-label-content">'+b.labelAfter+"</span></div>");var n=function(a){var b=j.width(),c=j.height();return{w:b+"px",h:c+"px",cw:a*b+"px",ch:a*c+"px"}},o=function(a){var b=f.find(".twentytwenty-before");"vertical"===g?b.css("clip","rect(0,"+a.w+","+a.ch+",0)"):b.css("clip","rect(0,"+a.cw+","+a.h+",0)"),f.css("height",a.h),"function"==typeof d&&d()},p=function(a){var b=n(a);l.css("vertical"===g?"top":"left","vertical"===g?b.ch:b.cw),o(b)},q=0,r=0,s=0,t=0;a(c).on("resize.twentytwenty",function(){p(e)}),l.on("movestart",function(a){(a.distX>a.distY&&a.distX<-a.distY||a.distX<a.distY&&a.distX>-a.distY)&&"vertical"!==g?a.preventDefault():(a.distX<a.distY&&a.distX<-a.distY||a.distX>a.distY&&a.distX>-a.distY)&&"vertical"===g&&a.preventDefault(),f.addClass("active"),q=f.offset().left,r=f.offset().top,s=j.width(),t=j.height()}),l.on("moveend",function(){f.removeClass("active")}),l.on("move",function(a){f.hasClass("active")&&(e="vertical"===g?(a.pageY-r)/t:(a.pageX-q)/s,e<0&&(e=0),e>1&&(e=1),p(e))}),f.find("img").on("mousedown",function(a){a.preventDefault()}),a(c).trigger("resize.twentytwenty")})}}(jQuery,document,window),function(a,b,c,d){var e=function(b){b.each(function(){var b=a(this),c=parseInt(b.closest(".imagify-chart").next(".imagify-chart-value").text(),10),d=[{value:c,color:"#00B3D3"},{value:100-c,color:"#D8D8D8"}];new Chart(b[0].getContext("2d")).Doughnut(d,{segmentStrokeColor:"#2A2E3C",segmentStrokeWidth:1,animateRotate:!0,percentageInnerCutout:60,tooltipEvents:[]})})},f=function(b){var d,f={width:0,height:0,originalUrl:"",optimizedUrl:"",originalSize:0,optimizedSize:0,saving:0,modalAppendTo:a("body"),trigger:a('[data-target="imagify-visual-comparison"]'),modalId:"imagify-visual-comparison",openModal:!1},g=a.extend({},f,b);if(0===g.width||0===g.height||""===g.originalUrl||""===g.optimizedUrl||0===g.originalSize||0===g.optimizedSize||0===g.saving)return"error";d='<div id="'+g.modalId+'" class="imagify-modal imagify-visual-comparison" aria-hidden="true">',d+='<div class="imagify-modal-content loading">',d+='<div class="twentytwenty-container">',d+='<img class="imagify-img-before" alt="" width="'+g.width+'" height="'+g.height+'">',d+='<img class="imagify-img-after" alt="" width="'+g.width+'" height="'+g.height+'">',d+="</div>",d+='<div class="imagify-comparison-levels">',d+='<div class="imagify-c-level imagify-level-original go-left">',d+='<p class="imagify-c-level-row">',d+='<span class="label">'+imagifyTTT.labels.filesize+"</span>",d+='<span class="value level">'+g.originalSize+"</span>",d+="</p>",d+="</div>",d+='<div class="imagify-c-level imagify-level-optimized go-right">',d+='<p class="imagify-c-level-row">',d+='<span class="label">'+imagifyTTT.labels.filesize+"</span>",d+='<span class="value level">'+g.optimizedSize+"</span>",d+="</p>",d+='<p class="imagify-c-level-row">',d+='<span class="label">'+imagifyTTT.labels.saving+"</span>",d+='<span class="value"><span class="imagify-chart"><span class="imagify-chart-container"><canvas id="imagify-consumption-chart-normal" width="15" height="15"></canvas></span></span><span class="imagify-chart-value">'+g.saving+"</span>%</span>",d+="</p>",d+="</div>",d+="</div>",d+='<button class="close-btn absolute" type="button"><i aria-hidden="true" class="dashicons dashicons-no-alt"></i><span class="screen-reader-text">'+imagifyTTT.labels.close+"</span></button>",d+="</div>",d+="</div>",g.modalAppendTo.append(d),g.trigger.on("click.imagify",function(b){var d,f,h=a(a(this).data("target")),i=0;b.preventDefault(),g.openModal&&c.imagify.openModal(a(this)),h.find(".imagify-modal-content").css({width:.85*a(c).outerWidth()+"px","max-width":g.width}),h.find(".imagify-img-before").on("load",function(){i++}).attr("src",g.originalUrl),h.find(".imagify-img-after").on("load",function(){i++}).attr("src",g.optimizedUrl),d=h.find(".twentytwenty-container"),f=setInterval(function(){if(2===i)return d.twentytwenty({handlePosition:.3,orientation:"horizontal",labelBefore:imagifyTTT.labels.originalL,labelAfter:imagifyTTT.labels.optimizedL},function(){var b,f,g,i,j,k,l=a(c).height(),m=h.find(".twentytwenty-container").height(),n=h.find(".twentytwenty-wrapper").position().top;d.closest(".imagify-modal-content").hasClass("loaded")||(d.closest(".imagify-modal-content").removeClass("loading").addClass("loaded"),e(h.find(".imagify-level-optimized").find(".imagify-chart").find("canvas"))),l<m&&!h.hasClass("modal-is-too-high")&&(h.addClass("modal-is-too-high"),b=h.find(".twentytwenty-handle"),f=h.find(".twentytwenty-label-content"),g=h.find(".imagify-comparison-levels"),i=g.outerHeight(),j=(l-n-b.height())/2,k=l-3*n-i,b.css({top:j}),f.css({top:k,bottom:"auto"}),h.find(".twentytwenty-wrapper").css({paddingBottom:i}),h.find(".imagify-modal-content").on("scroll.imagify",function(){var c=a(this).scrollTop();b.css({top:j+c}),f.css({top:k+c}),g.css({bottom:-c})}))}),clearInterval(f),f=null,"done"},75)})};if(a(".imagify-visual-comparison-btn").on("click",function(){var b,d,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B;1!==a(".twentytwenty-wrapper").length&&(a(a(this).data("target")).find(".imagify-modal-content").css("width",.95*a(c).outerWidth()+"px"),a(".twentytwenty-container").length>0&&a(c).outerWidth()<=800||(b=a(".twentytwenty-container"),d=0,f=b.data("loader"),g=b.data("label-original"),h=b.data("label-normal"),i=b.data("label-aggressive"),j=b.data("label-ultra"),k=b.data("original-label").replace(/\*\*/,"<strong>").replace(/\*\*/,"</strong>"),l=b.data("original-alt"),m=b.data("original-img"),n=b.data("original-dim").split("x"),o=b.data("normal-alt"),p=b.data("normal-img"),q=b.data("normal-dim").split("x"),r=b.data("aggressive-alt"),s=b.data("aggressive-img"),t=b.data("aggressive-dim").split("x"),u=b.data("ultra-label").replace(/\*\*/,"<strong>").replace(/\*\*/,"</strong>"),v=b.data("ultra-alt"),w=b.data("ultra-img"),x=b.data("ultra-dim").split("x"),y='<span class="twentytwenty-duo-buttons twentytwenty-duo-left">',y+='<button type="button" class="imagify-comparison-original selected" data-img="original">'+g+"</button>",y+='<button type="button" class="imagify-comparison-normal" data-img="normal">'+h+"</button>",y+='<button type="button" class="imagify-comparison-aggressive" data-img="aggressive">'+i+"</button>",y+="</span>",z='<span class="twentytwenty-duo-buttons twentytwenty-duo-right">',z+='<button type="button" class="imagify-comparison-normal" data-img="normal">'+h+"</button>",z+='<button type="button" class="imagify-comparison-aggressive" data-img="aggressive">'+i+"</button>",z+='<button type="button" class="imagify-comparison-ultra selected" data-img="ultra">'+j+"</button>",z+="</span>",b.before('<img class="loader" src="'+f+'" alt="Loading…" width="64" height="64">'),a(".twentytwenty-left-buttons").append(y),a(".twentytwenty-right-buttons").append(z),A='<img class="img-original" alt="'+l+'" width="'+n[0]+'" height="'+n[1]+'">',A+='<img class="img-normal" alt="'+o+'" width="'+q[0]+'" height="'+q[1]+'">',A+='<img class="img-aggressive" alt="'+r+'" width="'+t[0]+'" height="'+t[1]+'">',A+='<img class="img-ultra" alt="'+v+'" width="'+x[0]+'" height="'+x[1]+'">',A+=a(".twentytwenty-left-buttons").lenght?y+z:"",b.closest(".imagify-modal-content").addClass("loading").find(".twentytwenty-container").append(A),a(".img-original").on("load",function(){d++}).attr("src",m),a(".img-normal").on("load",function(){d++}).attr("src",p),a(".img-aggressive").on("load",function(){d++}).attr("src",s),a(".img-ultra").on("load",function(){d++}).attr("src",w),B=setInterval(function(){4===d&&(b.twentytwenty({handlePosition:.6,orientation:"horizontal",labelBefore:k,labelAfter:u},function(){b.closest(".imagify-modal-content").hasClass("loaded")||(b.closest(".imagify-modal-content").removeClass("loading").addClass("loaded"),e(a(".imagify-level-ultra").find(".imagify-chart").find("canvas")))}),clearInterval(B),B=null)},75),a(".imagify-comparison-title").on("click",".twentytwenty-duo-buttons button:not(.selected)",function(b){var c,d=a(this),f=d.closest(".imagify-comparison-title").nextAll(".twentytwenty-wrapper").find(".twentytwenty-container"),g=d.closest(".twentytwenty-duo-buttons").hasClass("twentytwenty-duo-left")?"left":"right",h="left"===g?d.closest(".imagify-comparison-title").find(".twentytwenty-duo-right"):d.closest(".imagify-comparison-title").find(".twentytwenty-duo-left"),i=d.closest(".twentytwenty-duo-buttons").find("button"),j=f.find(".twentytwenty-before"),k=f.find(".twentytwenty-after"),l=d.data("img");b.stopPropagation(),b.preventDefault(),i.removeClass("selected"),d.addClass("selected"),h.find(".selected").data("img")===l&&h.find("button:not(.selected)").eq(0).trigger("click"),"left"===g&&(c=j.css("clip"),j.attr("style",""),j.removeClass("twentytwenty-before"),f.find(".img-"+l).addClass("twentytwenty-before").css("clip",c),a(".twentytwenty-before-label").find(".twentytwenty-label-content").text(f.data(l+"-label")),a(".imagify-c-level.go-left").attr("aria-hidden","true").removeClass("go-left go-right"),a(".imagify-level-"+l).attr("aria-hidden","false").addClass("go-left")),"right"===g&&(k.removeClass("twentytwenty-after"),f.find(".img-"+l).addClass("twentytwenty-after"),a(".twentytwenty-after-label").find(".twentytwenty-label-content").text(f.data(l+"-label")),a(".imagify-c-level.go-right").attr("aria-hidden","true").removeClass("go-left go-right"),a(".imagify-level-"+l).attr("aria-hidden","false").addClass("go-right")),e(a(".imagify-level-"+l).find(".imagify-chart").find("canvas"))})))}),a(".post-php").find(".wp_attachment_image").find(".thumbnail").length>0){var g,h,i=a(".post-php").find(".wp_attachment_image"),j=i.find(".thumbnail"),k={src:j.prop("src"),width:j.width(),height:j.height()},l={src:a("#imagify-full-original").val(),size:a("#imagify-full-original-size").val()},m=a("#misc-publishing-actions").find(".misc-pub-imagify").find(".button-primary");k.width>360&&a("#imagify-full-original").length>0&&""!==a("#imagify-full-original").val()?(g=a(".misc-pub-filesize").find("strong").text(),h=a(".imagify-data-item").find(".imagify-chart-value").text(),a('[id^="imgedit-open-btn-"]').before('<button type="button" class="imagify-button-primary button-primary imagify-modal-trigger" data-target="#imagify-visual-comparison" id="imagify-start-comparison">'+imagifyTTT.labels.compare+"</button>"),f({width:k.width,height:k.height,originalUrl:l.src,optimizedUrl:k.src,originalSize:l.size,optimizedSize:g,saving:h,modalAppendTo:i,trigger:a("#imagify-start-comparison"),modalId:"imagify-visual-comparison"})):k.width<360&&a("#imagify-full-original").length>0&&""!==a("#imagify-full-original").val()||a("#imagify-full-original").length>0&&""===a("#imagify-full-original").val()||1===a("#misc-publishing-actions").find(".misc-pub-imagify").find(".button-primary").length&&(a('[id^="imgedit-open-btn-"]').before('<span class="spinner imagify-hidden"></span><a class="imagify-button-primary button-primary imagify-optimize-trigger" id="imagify-optimize-trigger" href="'+m.attr("href")+'">'+imagifyTTT.labels.optimize+"</a>"),a("#imagify-optimize-trigger").on("click",function(){a(this).prev(".spinner").removeClass("imagify-hidden").addClass("is-active")}))}if(a(".upload-php").find(".imagify-compare-images").length>0&&a(".imagify-compare-images").each(function(){var b=a(this),c=b.data("id"),d=b.closest("#post-"+c).find(".column-imagify_optimized_file");f({width:b.data("full-width"),height:b.data("full-height"),originalUrl:b.data("backup-src"),optimizedUrl:b.data("full-src"),originalSize:d.find(".original").text(),optimizedSize:d.find(".imagify-data-item").find(".big").text(),saving:d.find(".imagify-chart-value").text(),modalAppendTo:b.closest(".column-primary"),trigger:b,modalId:"imagify-comparison-"+c})}),a(".upload-php").length>0)var n=function(a){var b={};return c.location.href.replace(/[?&]+([^=&]+)=?([^&]*)?/gi,function(a,c,d){b[c]=void 0!==d?d:""}),a?b[a]?b[a]:null:b},o=function(){var b=setInterval(function(){var c;a(".media-modal").find(".imagify-datas-details").length&&(a("#imagify-original-src").length>0&&""!==a("#imagify-original-src")&&(a(".media-frame-content").find(".attachment-actions").prepend('<button type="button" class="imagify-button-primary button-primary imagify-modal-trigger" data-target="#imagify-comparison-modal" id="imagify-media-frame-comparison-btn">'+imagifyTTT.labels.compare+"</button>"),c=a(".media-frame-content").find(".compat-field-imagify"),f({width:a("#imagify-full-width").val(),height:a("#imagify-full-height").val(),originalUrl:a("#imagify-original-src").val(),optimizedUrl:a("#imagify-full-src").val(),originalSize:a("#imagify-original-size").val(),optimizedSize:c.find(".imagify-data-item").find(".big").text(),saving:c.find(".imagify-chart-value").text(),modalAppendTo:a(".media-frame-content").find(".thumbnail-image"),trigger:a("#imagify-media-frame-comparison-btn"),modalId:"imagify-comparison-modal",openModal:!0})),clearInterval(b),b=null)},20)},p=setInterval(function(){a(".upload-php").find(".media-frame.mode-grid").find(".attachments").length&&(a(".upload-php").find(".media-frame.mode-grid").on("click",".attachment",function(){o()}),n("item")&&o(),clearInterval(p),p=null)},100)}(jQuery,document,window);
1
+ !function(a,b,c,d){a.fn.twentytwenty=function(b,d){return b=a.extend({handlePosition:.5,orientation:"horizontal",labelBefore:"Before",labelAfter:"After"},b),this.each(function(){var e=b.handlePosition,f=a(this),g=b.orientation,h="vertical"===g?"down":"left",i="vertical"===g?"up":"right",j=f.find("img:first"),k=f.find("img:last");f.wrap('<div class="twentytwenty-wrapper twentytwenty-'+g+'"></div>'),f.append('<div class="twentytwenty-overlay"></div>'),f.append('<div class="twentytwenty-handle"></div>');var l=f.find(".twentytwenty-handle");l.append('<span class="twentytwenty-'+h+'-arrow"></span>'),l.append('<span class="twentytwenty-'+i+'-arrow"></span>'),f.addClass("twentytwenty-container"),j.addClass("twentytwenty-before"),k.addClass("twentytwenty-after");var m=f.find(".twentytwenty-overlay");m.append('<div class="twentytwenty-labels twentytwenty-before-label"><span class="twentytwenty-label-content">'+b.labelBefore+"</span></div>"),m.append('<div class="twentytwenty-labels twentytwenty-after-label"><span class="twentytwenty-label-content">'+b.labelAfter+"</span></div>");var n=function(a){var b=j.width(),c=j.height();return{w:b+"px",h:c+"px",cw:a*b+"px",ch:a*c+"px"}},o=function(a){var b=f.find(".twentytwenty-before");"vertical"===g?b.css("clip","rect(0,"+a.w+","+a.ch+",0)"):b.css("clip","rect(0,"+a.cw+","+a.h+",0)"),f.css("height",a.h),"function"==typeof d&&d()},p=function(a){var b=n(a);l.css("vertical"===g?"top":"left","vertical"===g?b.ch:b.cw),o(b)},q=0,r=0,s=0,t=0;a(c).on("resize.twentytwenty",function(){p(e)}),l.on("movestart",function(a){(a.distX>a.distY&&a.distX<-a.distY||a.distX<a.distY&&a.distX>-a.distY)&&"vertical"!==g?a.preventDefault():(a.distX<a.distY&&a.distX<-a.distY||a.distX>a.distY&&a.distX>-a.distY)&&"vertical"===g&&a.preventDefault(),f.addClass("active"),q=f.offset().left,r=f.offset().top,s=j.width(),t=j.height()}),l.on("moveend",function(){f.removeClass("active")}),l.on("move",function(a){f.hasClass("active")&&(e="vertical"===g?(a.pageY-r)/t:(a.pageX-q)/s,e<0&&(e=0),e>1&&(e=1),p(e))}),f.find("img").on("mousedown",function(a){a.preventDefault()}),a(c).trigger("resize.twentytwenty")})}}(jQuery,document,window),function(a,b,c,d){var e=function(b){b.each(function(){var b=a(this),c=parseInt(b.closest(".imagify-chart").next(".imagify-chart-value").text(),10),d=[{value:c,color:"#00B3D3"},{value:100-c,color:"#D8D8D8"}];new Chart(b[0].getContext("2d")).Doughnut(d,{segmentStrokeColor:"#2A2E3C",segmentStrokeWidth:1,animateRotate:!0,percentageInnerCutout:60,tooltipEvents:[]})})},f=function(b){var d,f={width:0,height:0,originalUrl:"",optimizedUrl:"",originalSize:0,optimizedSize:0,saving:0,modalAppendTo:a("body"),trigger:a('[data-target="imagify-visual-comparison"]'),modalId:"imagify-visual-comparison",openModal:!1},g=a.extend({},f,b);if(0===g.width||0===g.height||""===g.originalUrl||""===g.optimizedUrl||0===g.originalSize||0===g.optimizedSize||0===g.saving)return"error";d='<div id="'+g.modalId+'" class="imagify-modal imagify-visual-comparison" aria-hidden="true">',d+='<div class="imagify-modal-content loading">',d+='<div class="twentytwenty-container">',d+='<img class="imagify-img-before" alt="" width="'+g.width+'" height="'+g.height+'">',d+='<img class="imagify-img-after" alt="" width="'+g.width+'" height="'+g.height+'">',d+="</div>",d+='<div class="imagify-comparison-levels">',d+='<div class="imagify-c-level imagify-level-original go-left">',d+='<p class="imagify-c-level-row">',d+='<span class="label">'+imagifyTTT.labels.filesize+"</span>",d+='<span class="value level">'+g.originalSize+"</span>",d+="</p>",d+="</div>",d+='<div class="imagify-c-level imagify-level-optimized go-right">',d+='<p class="imagify-c-level-row">',d+='<span class="label">'+imagifyTTT.labels.filesize+"</span>",d+='<span class="value level">'+g.optimizedSize+"</span>",d+="</p>",d+='<p class="imagify-c-level-row">',d+='<span class="label">'+imagifyTTT.labels.saving+"</span>",d+='<span class="value"><span class="imagify-chart"><span class="imagify-chart-container"><canvas id="imagify-consumption-chart-normal" width="15" height="15"></canvas></span></span><span class="imagify-chart-value">'+g.saving+"</span>%</span>",d+="</p>",d+="</div>",d+="</div>",d+='<button class="close-btn absolute" type="button"><i aria-hidden="true" class="dashicons dashicons-no-alt"></i><span class="screen-reader-text">'+imagifyTTT.labels.close+"</span></button>",d+="</div>",d+="</div>",g.modalAppendTo.append(d),g.trigger.on("click.imagify",function(b){var d,f,h=a(a(this).data("target")),i=0;b.preventDefault(),g.openModal&&c.imagify.openModal(a(this)),h.find(".imagify-modal-content").css({width:.85*a(c).outerWidth()+"px","max-width":g.width}),h.find(".imagify-img-before").on("load",function(){i++}).attr("src",g.originalUrl),h.find(".imagify-img-after").on("load",function(){i++}).attr("src",g.optimizedUrl+(g.optimizedUrl.indexOf("?")>0?"&":"?")+"v="+Date.now()),d=h.find(".twentytwenty-container"),f=setInterval(function(){if(2===i)return d.twentytwenty({handlePosition:.3,orientation:"horizontal",labelBefore:imagifyTTT.labels.originalL,labelAfter:imagifyTTT.labels.optimizedL},function(){var b,f,g,i,j,k,l=a(c).height(),m=h.find(".twentytwenty-container").height(),n=h.find(".twentytwenty-wrapper").position().top;d.closest(".imagify-modal-content").hasClass("loaded")||(d.closest(".imagify-modal-content").removeClass("loading").addClass("loaded"),e(h.find(".imagify-level-optimized .imagify-chart canvas"))),l<m&&!h.hasClass("modal-is-too-high")&&(h.addClass("modal-is-too-high"),b=h.find(".twentytwenty-handle"),f=h.find(".twentytwenty-label-content"),g=h.find(".imagify-comparison-levels"),i=g.outerHeight(),j=(l-n-b.height())/2,k=l-3*n-i,b.css({top:j}),f.css({top:k,bottom:"auto"}),h.find(".twentytwenty-wrapper").css({paddingBottom:i}),h.find(".imagify-modal-content").on("scroll.imagify",function(){var c=a(this).scrollTop();b.css({top:j+c}),f.css({top:k+c}),g.css({bottom:-c})}))}),clearInterval(f),f=null,"done"},75)})};if(a(".imagify-visual-comparison-btn").on("click",function(){var b,d,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B;1!==a(".twentytwenty-wrapper").length&&(a(a(this).data("target")).find(".imagify-modal-content").css("width",.95*a(c).outerWidth()+"px"),a(".twentytwenty-container").length>0&&a(c).outerWidth()<=800||(b=a(".twentytwenty-container"),d=0,f=b.data("loader"),g=b.data("label-original"),h=b.data("label-normal"),i=b.data("label-aggressive"),j=b.data("label-ultra"),k=b.data("original-label").replace(/\*\*/,"<strong>").replace(/\*\*/,"</strong>"),l=b.data("original-alt"),m=b.data("original-img"),n=b.data("original-dim").split("x"),o=b.data("normal-alt"),p=b.data("normal-img"),q=b.data("normal-dim").split("x"),r=b.data("aggressive-alt"),s=b.data("aggressive-img"),t=b.data("aggressive-dim").split("x"),u=b.data("ultra-label").replace(/\*\*/,"<strong>").replace(/\*\*/,"</strong>"),v=b.data("ultra-alt"),w=b.data("ultra-img"),x=b.data("ultra-dim").split("x"),y='<span class="twentytwenty-duo-buttons twentytwenty-duo-left">',y+='<button type="button" class="imagify-comparison-original selected" data-img="original">'+g+"</button>",y+='<button type="button" class="imagify-comparison-normal" data-img="normal">'+h+"</button>",y+='<button type="button" class="imagify-comparison-aggressive" data-img="aggressive">'+i+"</button>",y+="</span>",z='<span class="twentytwenty-duo-buttons twentytwenty-duo-right">',z+='<button type="button" class="imagify-comparison-normal" data-img="normal">'+h+"</button>",z+='<button type="button" class="imagify-comparison-aggressive" data-img="aggressive">'+i+"</button>",z+='<button type="button" class="imagify-comparison-ultra selected" data-img="ultra">'+j+"</button>",z+="</span>",b.before('<img class="loader" src="'+f+'" alt="Loading…" width="64" height="64">'),a(".twentytwenty-left-buttons").append(y),a(".twentytwenty-right-buttons").append(z),A='<img class="img-original" alt="'+l+'" width="'+n[0]+'" height="'+n[1]+'">',A+='<img class="img-normal" alt="'+o+'" width="'+q[0]+'" height="'+q[1]+'">',A+='<img class="img-aggressive" alt="'+r+'" width="'+t[0]+'" height="'+t[1]+'">',A+='<img class="img-ultra" alt="'+v+'" width="'+x[0]+'" height="'+x[1]+'">',A+=a(".twentytwenty-left-buttons").lenght?y+z:"",b.closest(".imagify-modal-content").addClass("loading").find(".twentytwenty-container").append(A),a(".img-original").on("load",function(){d++}).attr("src",m),a(".img-normal").on("load",function(){d++}).attr("src",p),a(".img-aggressive").on("load",function(){d++}).attr("src",s),a(".img-ultra").on("load",function(){d++}).attr("src",w),B=setInterval(function(){4===d&&(b.twentytwenty({handlePosition:.6,orientation:"horizontal",labelBefore:k,labelAfter:u},function(){b.closest(".imagify-modal-content").hasClass("loaded")||(b.closest(".imagify-modal-content").removeClass("loading").addClass("loaded"),e(a(".imagify-level-ultra .imagify-chart canvas")))}),clearInterval(B),B=null)},75),a(".imagify-comparison-title").on("click",".twentytwenty-duo-buttons button:not(.selected)",function(b){var c,d=a(this),f=d.closest(".imagify-comparison-title").nextAll(".twentytwenty-wrapper").find(".twentytwenty-container"),g=d.closest(".twentytwenty-duo-buttons").hasClass("twentytwenty-duo-left")?"left":"right",h="left"===g?d.closest(".imagify-comparison-title").find(".twentytwenty-duo-right"):d.closest(".imagify-comparison-title").find(".twentytwenty-duo-left"),i=d.closest(".twentytwenty-duo-buttons").find("button"),j=f.find(".twentytwenty-before"),k=f.find(".twentytwenty-after"),l=d.data("img");b.stopPropagation(),b.preventDefault(),i.removeClass("selected"),d.addClass("selected"),h.find(".selected").data("img")===l&&h.find("button:not(.selected)").eq(0).trigger("click"),"left"===g&&(c=j.css("clip"),j.attr("style",""),j.removeClass("twentytwenty-before"),f.find(".img-"+l).addClass("twentytwenty-before").css("clip",c),a(".twentytwenty-before-label .twentytwenty-label-content").text(f.data(l+"-label")),a(".imagify-c-level.go-left").attr("aria-hidden","true").removeClass("go-left go-right"),a(".imagify-level-"+l).attr("aria-hidden","false").addClass("go-left")),"right"===g&&(k.removeClass("twentytwenty-after"),f.find(".img-"+l).addClass("twentytwenty-after"),a(".twentytwenty-after-label .twentytwenty-label-content").text(f.data(l+"-label")),a(".imagify-c-level.go-right").attr("aria-hidden","true").removeClass("go-left go-right"),a(".imagify-level-"+l).attr("aria-hidden","false").addClass("go-right")),e(a(".imagify-level-"+l+" .imagify-chart canvas"))})))}),imagifyTTT.imageWidth&&a(".post-php .wp_attachment_image .thumbnail").length>0){var g,h,i=a(".post-php .wp_attachment_image"),j={src:a("#imagify-full-original").val(),size:a("#imagify-full-original-size").val()},k=a("#misc-publishing-actions").find(".misc-pub-imagify .button-primary");imagifyTTT.widthLimit=parseInt(imagifyTTT.widthLimit,10),imagifyTTT.imageWidth>imagifyTTT.widthLimit&&j.src?(g=a(".misc-pub-filesize strong").text(),h=a(".imagify-data-item .imagify-chart-value").text(),a('[id^="imgedit-open-btn-"]').before('<button type="button" class="imagify-button-primary button-primary imagify-modal-trigger" data-target="#imagify-visual-comparison" id="imagify-start-comparison">'+imagifyTTT.labels.compare+"</button>"),f({width:parseInt(imagifyTTT.imageWidth,10),height:parseInt(imagifyTTT.imageHeight,10),originalUrl:j.src,optimizedUrl:imagifyTTT.imageSrc,originalSize:j.size,optimizedSize:g,saving:h,modalAppendTo:i,trigger:a("#imagify-start-comparison"),modalId:"imagify-visual-comparison"})):imagifyTTT.imageWidth<imagifyTTT.widthLimit&&j.src||a("#imagify-full-original").length>0&&""===j.src||1===a("#misc-publishing-actions").find(".misc-pub-imagify .button-primary").length&&(a('[id^="imgedit-open-btn-"]').before('<span class="spinner imagify-hidden"></span><a class="imagify-button-primary button-primary imagify-optimize-trigger" id="imagify-optimize-trigger" href="'+k.attr("href")+'">'+imagifyTTT.labels.optimize+"</a>"),a("#imagify-optimize-trigger").on("click",function(){a(this).prev(".spinner").removeClass("imagify-hidden").addClass("is-active")}))}if(a(".upload-php .imagify-compare-images").length>0&&a(".imagify-compare-images").each(function(){var b=a(this),c=b.data("id"),d=b.closest("#post-"+c).find(".column-imagify_optimized_file");f({width:parseInt(b.data("full-width"),10),height:parseInt(b.data("full-height"),10),originalUrl:b.data("backup-src"),optimizedUrl:b.data("full-src"),originalSize:d.find(".original").text(),optimizedSize:d.find(".imagify-data-item .big").text(),saving:d.find(".imagify-chart-value").text(),modalAppendTo:b.closest(".column-primary"),trigger:b,modalId:"imagify-comparison-"+c})}),a(".upload-php").length>0)var l=function(a){var b={};return c.location.href.replace(/[?&]+([^=&]+)=?([^&]*)?/gi,function(a,c,d){b[c]=void 0!==d?d:""}),a?b[a]?b[a]:null:b},m=function(){var b=setInterval(function(){var c,d;a(".media-modal .imagify-datas-details").length&&(d=a("#imagify-original-src").val(),d&&(a(".media-frame-content .attachment-actions").prepend('<button type="button" class="imagify-button-primary button-primary imagify-modal-trigger" data-target="#imagify-comparison-modal" id="imagify-media-frame-comparison-btn">'+imagifyTTT.labels.compare+"</button>"),c=a(".media-frame-content .compat-field-imagify"),f({width:parseInt(a("#imagify-full-width").val(),10),height:parseInt(a("#imagify-full-height").val(),10),originalUrl:d,optimizedUrl:a("#imagify-full-src").val(),originalSize:a("#imagify-original-size").val(),optimizedSize:c.find(".imagify-data-item .big").text(),saving:c.find(".imagify-chart-value").text(),modalAppendTo:a(".media-frame-content .thumbnail-image"),trigger:a("#imagify-media-frame-comparison-btn"),modalId:"imagify-comparison-modal",openModal:!0})),clearInterval(b),b=null)},20)},n=setInterval(function(){a(".upload-php .media-frame.mode-grid .attachments").length&&(a(".upload-php .media-frame.mode-grid").on("click",".attachment",function(){m()}),l("item")&&m(),clearInterval(n),n=null)},100)}(jQuery,document,window);
imagify.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Imagify
4
  * Plugin URI: https://wordpress.org/plugins/imagify/
5
  * Description: Dramaticaly reduce image file sizes without losing quality, make your website load faster, boost your SEO and save money on your bandwidth using Imagify, the new most advanced image optimization tool.
6
- * Version: 1.6.10
7
  * Author: WP Media
8
  * Author URI: https://wp-media.me/
9
  * Licence: GPLv2
@@ -17,7 +17,7 @@
17
  defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
18
 
19
  // Imagify defines.
20
- define( 'IMAGIFY_VERSION' , '1.6.10' );
21
  define( 'IMAGIFY_SLUG' , 'imagify' );
22
  define( 'IMAGIFY_SETTINGS_SLUG' , IMAGIFY_SLUG . '_settings' );
23
  define( 'IMAGIFY_WEB_MAIN' , 'https://imagify.io' );
@@ -86,7 +86,6 @@ function _imagify_init() {
86
  if ( is_admin() ) {
87
  require( IMAGIFY_ADMIN_PATH . 'upgrader.php' );
88
  require( IMAGIFY_ADMIN_PATH . 'heartbeat.php' );
89
- require( IMAGIFY_ADMIN_PATH . 'ajax.php' );
90
  require( IMAGIFY_ADMIN_PATH . 'options.php' );
91
  require( IMAGIFY_ADMIN_PATH . 'menu.php' );
92
  require( IMAGIFY_ADMIN_PATH . 'plugins.php' );
@@ -95,11 +94,15 @@ function _imagify_init() {
95
  require( IMAGIFY_ADMIN_PATH . 'meta-boxes.php' );
96
  require( IMAGIFY_ADMIN_UI_PATH . 'options.php' );
97
  require( IMAGIFY_ADMIN_UI_PATH . 'bulk.php' );
 
98
 
99
  Imagify_Notices::get_instance()->init();
 
100
  }
101
 
102
- Imagify_Assets::get_instance()->init();
 
 
103
 
104
  /**
105
  * Fires when Imagify is correctly loaded.
3
  * Plugin Name: Imagify
4
  * Plugin URI: https://wordpress.org/plugins/imagify/
5
  * Description: Dramaticaly reduce image file sizes without losing quality, make your website load faster, boost your SEO and save money on your bandwidth using Imagify, the new most advanced image optimization tool.
6
+ * Version: 1.6.11
7
  * Author: WP Media
8
  * Author URI: https://wp-media.me/
9
  * Licence: GPLv2
17
  defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
18
 
19
  // Imagify defines.
20
+ define( 'IMAGIFY_VERSION' , '1.6.11' );
21
  define( 'IMAGIFY_SLUG' , 'imagify' );
22
  define( 'IMAGIFY_SETTINGS_SLUG' , IMAGIFY_SLUG . '_settings' );
23
  define( 'IMAGIFY_WEB_MAIN' , 'https://imagify.io' );
86
  if ( is_admin() ) {
87
  require( IMAGIFY_ADMIN_PATH . 'upgrader.php' );
88
  require( IMAGIFY_ADMIN_PATH . 'heartbeat.php' );
 
89
  require( IMAGIFY_ADMIN_PATH . 'options.php' );
90
  require( IMAGIFY_ADMIN_PATH . 'menu.php' );
91
  require( IMAGIFY_ADMIN_PATH . 'plugins.php' );
94
  require( IMAGIFY_ADMIN_PATH . 'meta-boxes.php' );
95
  require( IMAGIFY_ADMIN_UI_PATH . 'options.php' );
96
  require( IMAGIFY_ADMIN_UI_PATH . 'bulk.php' );
97
+ require( IMAGIFY_CLASSES_PATH . 'class-imagify-admin-ajax-post.php' );
98
 
99
  Imagify_Notices::get_instance()->init();
100
+ Imagify_Admin_Ajax_Post::get_instance()->init();
101
  }
102
 
103
+ if ( ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
104
+ Imagify_Assets::get_instance()->init();
105
+ }
106
 
107
  /**
108
  * Fires when Imagify is correctly loaded.
inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf-attachment.php CHANGED
File without changes
inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf.php CHANGED
@@ -103,9 +103,9 @@ class Imagify_AS3CF {
103
  */
104
  // Remove some of our hooks: let S3 work first in these cases.
105
  remove_filter( 'wp_generate_attachment_metadata', '_imagify_optimize_attachment', IMAGIFY_INT_MAX );
106
- remove_action( 'wp_ajax_imagify_async_optimize_as3cf', '_do_admin_post_async_optimize_upload_new_media' );
107
  remove_action( 'shutdown', '_imagify_optimize_save_image_editor_file' );
108
- remove_action( 'wp_ajax_imagify_async_optimize_save_image_editor_file', '_do_admin_post_async_optimize_save_image_editor_file' );
109
 
110
  // Store the IDs of the attachments being uploaded.
111
  add_filter( 'wp_generate_attachment_metadata', array( $this, 'store_upload_ids' ), 10, 2 );
@@ -335,7 +335,7 @@ class Imagify_AS3CF {
335
  }
336
 
337
  if ( ! isset( $auto_optimize ) ) {
338
- $auto_optimize = get_imagify_option( 'api_key' ) && get_imagify_option( 'auto_optimize' );
339
  }
340
 
341
  if ( $is_new_upload && ! $auto_optimize ) {
@@ -378,7 +378,7 @@ class Imagify_AS3CF {
378
 
379
  check_ajax_referer( 'imagify_async_optimize_as3cf' );
380
 
381
- if ( empty( $_POST['post_id'] ) || ! current_user_can( 'upload_files' ) ) {
382
  die();
383
  }
384
 
103
  */
104
  // Remove some of our hooks: let S3 work first in these cases.
105
  remove_filter( 'wp_generate_attachment_metadata', '_imagify_optimize_attachment', IMAGIFY_INT_MAX );
106
+ remove_action( 'wp_ajax_imagify_async_optimize_upload_new_media', array( Imagify_Admin_Ajax_Post::get_instance(), 'imagify_async_optimize_upload_new_media_callback' ) );
107
  remove_action( 'shutdown', '_imagify_optimize_save_image_editor_file' );
108
+ remove_action( 'wp_ajax_imagify_async_optimize_save_image_editor_file', array( Imagify_Admin_Ajax_Post::get_instance(), 'imagify_async_optimize_save_image_editor_file_callback' ) );
109
 
110
  // Store the IDs of the attachments being uploaded.
111
  add_filter( 'wp_generate_attachment_metadata', array( $this, 'store_upload_ids' ), 10, 2 );
335
  }
336
 
337
  if ( ! isset( $auto_optimize ) ) {
338
+ $auto_optimize = imagify_valid_key() && get_imagify_option( 'auto_optimize' );
339
  }
340
 
341
  if ( $is_new_upload && ! $auto_optimize ) {
378
 
379
  check_ajax_referer( 'imagify_async_optimize_as3cf' );
380
 
381
+ if ( empty( $_POST['post_id'] ) || ! imagify_current_user_can( 'auto-optimize' ) ) {
382
  die();
383
  }
384
 
inc/3rd-party/hosting/wpengine.php CHANGED
File without changes
inc/3rd-party/nextgen-gallery/inc/admin/ajax.php CHANGED
@@ -1,18 +1,76 @@
1
  <?php
2
  defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  add_action( 'wp_ajax_imagify_ngg_get_unoptimized_attachment_ids', '_do_wp_ajax_imagify_ngg_get_unoptimized_attachment_ids' );
5
  /**
6
  * Get all unoptimized attachment ids.
7
  *
8
- * @since 1.0
9
  * @author Jonathan Buttigieg
10
  */
11
  function _do_wp_ajax_imagify_ngg_get_unoptimized_attachment_ids() {
12
  global $wpdb;
13
 
14
  imagify_check_nonce( 'imagify-bulk-upload', 'imagifybulkuploadnonce' );
15
- imagify_check_user_capacity( 'upload_files' );
16
 
17
  $user = new Imagify_User();
18
 
1
  <?php
2
  defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
3
 
4
+ add_action( 'wp_ajax_imagify_manual_upload', '_do_admin_post_imagify_ngg_user_capacity', 5 );
5
+ add_action( 'admin_post_imagify_manual_upload', '_do_admin_post_imagify_ngg_user_capacity', 5 );
6
+ add_action( 'wp_ajax_imagify_manual_override_upload', '_do_admin_post_imagify_ngg_user_capacity', 5 );
7
+ add_action( 'admin_post_imagify_manual_override_upload', '_do_admin_post_imagify_ngg_user_capacity', 5 );
8
+ add_action( 'wp_ajax_imagify_restore_upload', '_do_admin_post_imagify_ngg_user_capacity', 5 );
9
+ add_action( 'admin_post_imagify_restore_upload', '_do_admin_post_imagify_ngg_user_capacity', 5 );
10
+ /**
11
+ * On manual optimization, manual re-optimization, and manual restoration, filter the user capacity to operate Imagify within NGG.
12
+ *
13
+ * @since 1.6.11
14
+ * @author Grégory Viguier
15
+ */
16
+ function _do_admin_post_imagify_ngg_user_capacity() {
17
+ if ( ! empty( $_GET['context'] ) && 'NGG' === $_GET['context'] ) { // WPCS: CSRF ok.
18
+ add_filter( 'imagify_capacity', 'imagify_get_ngg_capacity', 10, 2 );
19
+ }
20
+ }
21
+
22
+ add_filter( 'imagify_current_user_can', 'imagify_ngg_current_user_can', 10, 4 );
23
+ /**
24
+ * Filter the current user capability to operate Imagify.
25
+ *
26
+ * @since 1.6.11
27
+ * @author Grégory Viguier
28
+ *
29
+ * @param bool $user_can Tell if the current user has the required capacity to operate Imagify.
30
+ * @param string $capacity The user capacity.
31
+ * @param string $describer Capacity describer. Possible values are 'manage', 'bulk-optimize', 'manual-optimize', and 'auto-optimize'.
32
+ * @param int $post_id A post ID (a gallery ID for NGG).
33
+ * @return bool
34
+ */
35
+ function imagify_ngg_current_user_can( $user_can, $capacity, $describer, $post_id ) {
36
+ static $user_can_per_gallery = array();
37
+
38
+ if ( ! $user_can || ! $post_id || 'NextGEN Manage gallery' !== $capacity ) {
39
+ return $user_can;
40
+ }
41
+
42
+ $image = nggdb::find_image( $post_id );
43
+
44
+ if ( isset( $user_can_per_gallery[ $image->galleryid ] ) ) {
45
+ return $user_can_per_gallery[ $image->galleryid ];
46
+ }
47
+
48
+ $gallery_mapper = C_Gallery_Mapper::get_instance();
49
+ $gallery = $gallery_mapper->find( $image->galleryid, false );
50
+
51
+ if ( get_current_user_id() === $gallery->author || current_user_can( 'NextGEN Manage others gallery' ) ) {
52
+ // The user created this gallery or can edit others galleries.
53
+ $user_can_per_gallery[ $image->galleryid ] = true;
54
+ return $user_can_per_gallery[ $image->galleryid ];
55
+ }
56
+
57
+ // The user can't edit this gallery.
58
+ $user_can_per_gallery[ $image->galleryid ] = false;
59
+ return $user_can_per_gallery[ $image->galleryid ];
60
+ }
61
+
62
  add_action( 'wp_ajax_imagify_ngg_get_unoptimized_attachment_ids', '_do_wp_ajax_imagify_ngg_get_unoptimized_attachment_ids' );
63
  /**
64
  * Get all unoptimized attachment ids.
65
  *
66
+ * @since 1.0
67
  * @author Jonathan Buttigieg
68
  */
69
  function _do_wp_ajax_imagify_ngg_get_unoptimized_attachment_ids() {
70
  global $wpdb;
71
 
72
  imagify_check_nonce( 'imagify-bulk-upload', 'imagifybulkuploadnonce' );
73
+ imagify_check_user_capacity( 'bulk-optimize' );
74
 
75
  $user = new Imagify_User();
76
 
inc/3rd-party/nextgen-gallery/inc/admin/bulk.php CHANGED
File without changes
inc/3rd-party/nextgen-gallery/inc/admin/db.php CHANGED
File without changes
inc/3rd-party/nextgen-gallery/inc/admin/enqueue.php CHANGED
@@ -47,5 +47,5 @@ function _imagify_ngg_admin_print_styles() {
47
  $assets->enqueue_assets( array( 'pricing-modal', 'bulk' ) )->localize( 'imagifyBulk', $l10n );
48
 
49
  // Intercom.
50
- add_action( 'admin_footer-' . $bulk_screen_id, array( $assets, 'print_intercom' ) );
51
  }
47
  $assets->enqueue_assets( array( 'pricing-modal', 'bulk' ) )->localize( 'imagifyBulk', $l10n );
48
 
49
  // Intercom.
50
+ add_action( 'admin_footer-' . $bulk_screen_id, array( $assets, 'print_support_script' ) );
51
  }
inc/3rd-party/nextgen-gallery/inc/admin/gallery.php CHANGED
@@ -42,8 +42,12 @@ function _imagify_ngg_manage_media_columns() {
42
  * @return string
43
  */
44
  function _imagify_ngg_manage_media_custom_column( $output, $image ) {
 
45
  $attachment = new Imagify_NGG_Attachment( $image );
46
- return get_imagify_media_column_content( $attachment, 'NGG' );
 
 
 
47
  }
48
 
49
  add_filter( 'imagify_display_missing_thumbnails_link', '_imagify_ngg_hide_missing_thumbnails_link', 10, 3 );
42
  * @return string
43
  */
44
  function _imagify_ngg_manage_media_custom_column( $output, $image ) {
45
+ add_filter( 'imagify_capacity', 'imagify_get_ngg_capacity', 10, 2 );
46
  $attachment = new Imagify_NGG_Attachment( $image );
47
+ $output = get_imagify_media_column_content( $attachment, 'NGG' );
48
+ remove_filter( 'imagify_capacity', 'imagify_get_ngg_capacity' );
49
+
50
+ return $output;
51
  }
52
 
53
  add_filter( 'imagify_display_missing_thumbnails_link', '_imagify_ngg_hide_missing_thumbnails_link', 10, 3 );
inc/3rd-party/nextgen-gallery/inc/admin/heartbeat.php CHANGED
File without changes
inc/3rd-party/nextgen-gallery/inc/admin/menu.php CHANGED
@@ -5,7 +5,7 @@ add_action( 'admin_menu', '_imagify_ngg_bulk_optimization_menu' );
5
  /**
6
  * Add submenu in menu "Media"
7
  *
8
- * @since 1.5
9
  * @author Jonathan Buttigieg
10
  */
11
  function _imagify_ngg_bulk_optimization_menu() {
@@ -13,5 +13,5 @@ function _imagify_ngg_bulk_optimization_menu() {
13
  return;
14
  }
15
 
16
- add_submenu_page( NGGFOLDER, __( 'Bulk Optimization', 'imagify' ), __( 'Bulk Optimization', 'imagify' ), imagify_get_capacity( true ), IMAGIFY_SLUG . '-ngg-bulk-optimization', '_imagify_display_bulk_page' );
17
  }
5
  /**
6
  * Add submenu in menu "Media"
7
  *
8
+ * @since 1.5
9
  * @author Jonathan Buttigieg
10
  */
11
  function _imagify_ngg_bulk_optimization_menu() {
13
  return;
14
  }
15
 
16
+ add_submenu_page( NGGFOLDER, __( 'Bulk Optimization', 'imagify' ), __( 'Bulk Optimization', 'imagify' ), imagify_get_capacity( 'bulk-optimize' ), IMAGIFY_SLUG . '-ngg-bulk-optimization', '_imagify_display_bulk_page' );
17
  }
inc/3rd-party/nextgen-gallery/inc/classes/class-imagify-ngg-attachment.php CHANGED
@@ -123,30 +123,30 @@ class Imagify_NGG_Attachment extends Imagify_Attachment {
123
  }
124
 
125
  /**
126
- * Get the attachment optimization level.
127
  *
128
  * @since 1.5
129
  * @author Jonathan Buttigieg
130
  *
131
  * @access public
132
- * @return int|bool
133
  */
134
- public function get_optimization_level() {
135
- $row = $this->row ? $this->row : $this->get_row();
136
- return isset( $row['optimization_level'] ) ? (int) $row['optimization_level'] : false;
137
  }
138
 
139
  /**
140
- * Get the attachment SQL data row.
141
  *
142
  * @since 1.5
143
  * @author Jonathan Buttigieg
144
  *
145
  * @access public
146
- * @return array
147
  */
148
- public function get_row() {
149
- return imagify_ngg_db()->get( $this->id );
 
150
  }
151
 
152
  /**
@@ -285,6 +285,7 @@ class Imagify_NGG_Attachment extends Imagify_Attachment {
285
  'status' => $error_status,
286
  'data' => serialize( $data ),
287
  ) );
 
288
 
289
  return false;
290
  }
@@ -398,6 +399,7 @@ class Imagify_NGG_Attachment extends Imagify_Attachment {
398
  'pid' => $this->id,
399
  'optimization_level' => $optimization_level,
400
  ) );
 
401
 
402
  if ( ! $data ) {
403
  delete_transient( 'imagify-ngg-async-in-progress-' . $this->id );
@@ -418,6 +420,7 @@ class Imagify_NGG_Attachment extends Imagify_Attachment {
418
  'pid' => $this->id,
419
  'status' => 'success',
420
  ) );
 
421
 
422
  /**
423
  * Fires after optimizing an attachment.
@@ -538,6 +541,7 @@ class Imagify_NGG_Attachment extends Imagify_Attachment {
538
  'pid' => $this->id,
539
  'data' => serialize( $data ),
540
  ) );
 
541
  } // End if().
542
 
543
  /**
@@ -614,6 +618,7 @@ class Imagify_NGG_Attachment extends Imagify_Attachment {
614
  * Remove Imagify data.
615
  */
616
  imagify_ngg_db()->delete( $image->pid );
 
617
 
618
  /**
619
  * Fill in the NGG meta data.
123
  }
124
 
125
  /**
126
+ * Get the attachment SQL data row.
127
  *
128
  * @since 1.5
129
  * @author Jonathan Buttigieg
130
  *
131
  * @access public
132
+ * @return array
133
  */
134
+ public function get_row() {
135
+ return imagify_ngg_db()->get( $this->id );
 
136
  }
137
 
138
  /**
139
+ * Get the attachment optimization level.
140
  *
141
  * @since 1.5
142
  * @author Jonathan Buttigieg
143
  *
144
  * @access public
145
+ * @return int|bool
146
  */
147
+ public function get_optimization_level() {
148
+ $row = $this->row ? $this->row : $this->get_row();
149
+ return isset( $row['optimization_level'] ) ? (int) $row['optimization_level'] : false;
150
  }
151
 
152
  /**
285
  'status' => $error_status,
286
  'data' => serialize( $data ),
287
  ) );
288
+ $this->row = null;
289
 
290
  return false;
291
  }
399
  'pid' => $this->id,
400
  'optimization_level' => $optimization_level,
401
  ) );
402
+ $this->row = null;
403
 
404
  if ( ! $data ) {
405
  delete_transient( 'imagify-ngg-async-in-progress-' . $this->id );
420
  'pid' => $this->id,
421
  'status' => 'success',
422
  ) );
423
+ $this->row = null;
424
 
425
  /**
426
  * Fires after optimizing an attachment.
541
  'pid' => $this->id,
542
  'data' => serialize( $data ),
543
  ) );
544
+ $this->row = null;
545
  } // End if().
546
 
547
  /**
618
  * Remove Imagify data.
619
  */
620
  imagify_ngg_db()->delete( $image->pid );
621
+ $this->row = null;
622
 
623
  /**
624
  * Fill in the NGG meta data.
inc/3rd-party/nextgen-gallery/inc/classes/class-imagify-ngg-db.php CHANGED
File without changes
inc/3rd-party/nextgen-gallery/inc/common/attachments.php CHANGED
@@ -19,14 +19,13 @@ function _imagify_ngg_optimize_attachment( $gallery_id, $image_ids ) {
19
  }
20
 
21
  foreach ( $image_ids as $id ) {
22
- $body = array();
23
- $body['metadata'] = 1;
24
- $body['context'] = 'NGG';
25
- $body['attachment_id'] = $id;
26
- $body['action'] = 'imagify_async_optimize_upload_new_media';
27
- $body['_ajax_nonce'] = wp_create_nonce( 'new_media-' . $id );
28
-
29
- imagify_do_async_job( $body );
30
  }
31
  }
32
 
19
  }
20
 
21
  foreach ( $image_ids as $id ) {
22
+ imagify_do_async_job( array(
23
+ 'action' => 'imagify_async_optimize_upload_new_media',
24
+ '_ajax_nonce' => wp_create_nonce( 'new_media-' . $id ),
25
+ 'metadata' => 1,
26
+ 'context' => 'NGG',
27
+ 'attachment_id' => $id,
28
+ ) );
 
29
  }
30
  }
31
 
inc/3rd-party/nextgen-gallery/inc/functions/admin-stats.php CHANGED
File without changes
inc/3rd-party/nextgen-gallery/inc/functions/attachments.php CHANGED
File without changes
inc/3rd-party/nextgen-gallery/inc/functions/common.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
3
+
4
+ /**
5
+ * Get user capacity to operate Imagify within NGG galleries.
6
+ * It is meant to be used to filter 'imagify_capacity'.
7
+ *
8
+ * @since 1.6.11
9
+ * @author Grégory Viguier
10
+ *
11
+ * @param string $capacity The user capacity.
12
+ * @param string $describer Capacity describer. Possible values are 'manage', 'bulk-optimize', 'manual-optimize', and 'auto-optimize'.
13
+ * @return string
14
+ */
15
+ function imagify_get_ngg_capacity( $capacity = 'edit_post', $describer = 'manual-optimize' ) {
16
+ if ( 'manual-optimize' === $describer ) {
17
+ return 'NextGEN Manage gallery';
18
+ }
19
+
20
+ return $capacity;
21
+ }
inc/3rd-party/nextgen-gallery/nextgen-gallery.php CHANGED
@@ -18,6 +18,7 @@ require( IMAGIFY_NGG_CLASSES_PATH . 'class-imagify-ngg-db.php' );
18
  require( IMAGIFY_NGG_CLASSES_PATH . 'class-imagify-ngg-attachment.php' );
19
  require( IMAGIFY_NGG_FUNCTIONS_PATH . 'admin-stats.php' );
20
  require( IMAGIFY_NGG_FUNCTIONS_PATH . 'attachments.php' );
 
21
  require( IMAGIFY_NGG_COMMON_PATH . 'attachments.php' );
22
 
23
  imagify_ngg()->init();
18
  require( IMAGIFY_NGG_CLASSES_PATH . 'class-imagify-ngg-attachment.php' );
19
  require( IMAGIFY_NGG_FUNCTIONS_PATH . 'admin-stats.php' );
20
  require( IMAGIFY_NGG_FUNCTIONS_PATH . 'attachments.php' );
21
+ require( IMAGIFY_NGG_FUNCTIONS_PATH . 'common.php' );
22
  require( IMAGIFY_NGG_COMMON_PATH . 'attachments.php' );
23
 
24
  imagify_ngg()->init();
inc/3rd-party/wp-rocket.php CHANGED
File without changes
inc/3rd-party/yoast-seo.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
  defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
3
 
4
- if ( defined( 'WPSEO_VERSION' ) && is_admin() && ! defined( 'DOING_AJAX' ) ) :
5
 
6
  add_action( 'wp_print_scripts', '_imagify_dequeue_yoastseo_script' );
7
  /**
1
  <?php
2
  defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
3
 
4
+ if ( defined( 'WPSEO_VERSION' ) && is_admin() && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) :
5
 
6
  add_action( 'wp_print_scripts', '_imagify_dequeue_yoastseo_script' );
7
  /**
inc/admin/ajax.php DELETED
@@ -1,725 +0,0 @@
1
- <?php
2
- defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
3
-
4
- /** --------------------------------------------------------------------------------------------- */
5
- /** MANUAL OPTIMIZATION ========================================================================= */
6
- /** --------------------------------------------------------------------------------------------- */
7
-
8
- add_action( 'wp_ajax_imagify_manual_upload', '_do_admin_post_imagify_manual_upload' );
9
- add_action( 'admin_post_imagify_manual_upload', '_do_admin_post_imagify_manual_upload' );
10
- /**
11
- * Process all thumbnails of a specific image with Imagify with the manual method.
12
- *
13
- * @since 1.0
14
- * @author Jonathan Buttigieg
15
- */
16
- function _do_admin_post_imagify_manual_upload() {
17
- imagify_check_nonce( 'imagify-manual-upload' );
18
- imagify_check_user_capacity( 'upload_files' );
19
-
20
- if ( empty( $_GET['attachment_id'] ) || empty( $_GET['context'] ) ) {
21
- imagify_die( __( 'Invalid request', 'imagify' ) );
22
- }
23
-
24
- $context = esc_html( $_GET['context'] );
25
- $attachment_id = absint( $_GET['attachment_id'] );
26
- $class_name = get_imagify_attachment_class_name( $context, $attachment_id, 'imagify_manual_upload' );
27
- $attachment = new $class_name( $attachment_id );
28
-
29
- // Optimize it!!!!!
30
- $attachment->optimize();
31
-
32
- imagify_maybe_redirect();
33
-
34
- // Return the optimization statistics.
35
- $output = get_imagify_attachment_optimization_text( $attachment, $context );
36
- wp_send_json_success( $output );
37
- }
38
-
39
- add_action( 'wp_ajax_imagify_manual_override_upload', '_do_admin_post_imagify_manual_override_upload' );
40
- add_action( 'admin_post_imagify_manual_override_upload', '_do_admin_post_imagify_manual_override_upload' );
41
- /**
42
- * Process all thumbnails of a specific image with Imagify with a different optimization level.
43
- *
44
- * @since 1.0
45
- * @author Jonathan Buttigieg
46
- */
47
- function _do_admin_post_imagify_manual_override_upload() {
48
- imagify_check_nonce( 'imagify-manual-override-upload' );
49
- imagify_check_user_capacity( 'upload_files' );
50
-
51
- if ( empty( $_GET['attachment_id'] ) || empty( $_GET['context'] ) ) {
52
- imagify_die( __( 'Invalid request', 'imagify' ) );
53
- }
54
-
55
- $context = esc_html( $_GET['context'] );
56
- $attachment_id = absint( $_GET['attachment_id'] );
57
- $class_name = get_imagify_attachment_class_name( $context, $attachment_id, 'imagify_manual_override_upload' );
58
- $attachment = new $class_name( $attachment_id );
59
-
60
- // Restore the backup file.
61
- $attachment->restore();
62
-
63
- // Optimize it!!!!!
64
- $attachment->optimize( (int) $_GET['optimization_level'] );
65
-
66
- imagify_maybe_redirect();
67
-
68
- // Return the optimization statistics.
69
- $output = get_imagify_attachment_optimization_text( $attachment, $context );
70
- wp_send_json_success( $output );
71
- }
72
-
73
- add_action( 'wp_ajax_imagify_optimize_missing_sizes', '_do_admin_post_imagify_optimize_missing_sizes' );
74
- add_action( 'admin_post_imagify_optimize_missing_sizes', '_do_admin_post_imagify_optimize_missing_sizes' );
75
- /**
76
- * Process one or some thumbnails that are not optimized yet.
77
- *
78
- * @since 1.6.10
79
- * @author Grégory Viguier
80
- */
81
- function _do_admin_post_imagify_optimize_missing_sizes() {
82
- imagify_check_nonce( 'imagify-optimize-missing-sizes' );
83
- imagify_check_user_capacity( 'upload_files' );
84
-
85
- if ( empty( $_GET['attachment_id'] ) || empty( $_GET['context'] ) ) {
86
- imagify_die( __( 'Invalid request', 'imagify' ) );
87
- }
88
-
89
- $context = esc_html( $_GET['context'] );
90
- $attachment_id = absint( $_GET['attachment_id'] );
91
- $class_name = get_imagify_attachment_class_name( $context, $attachment_id, 'imagify_optimize_missing_sizes' );
92
- $attachment = new $class_name( $attachment_id );
93
-
94
- // Optimize the missing thumbnails.
95
- $attachment->optimize_missing_thumbnails();
96
-
97
- imagify_maybe_redirect();
98
-
99
- // Return the optimization statistics.
100
- $output = get_imagify_attachment_optimization_text( $attachment, $context );
101
- wp_send_json_success( $output );
102
- }
103
-
104
- add_action( 'wp_ajax_imagify_restore_upload', '_do_admin_post_imagify_restore_upload' );
105
- add_action( 'admin_post_imagify_restore_upload', '_do_admin_post_imagify_restore_upload' );
106
- /**
107
- * Process a restoration to the original attachment.
108
- *
109
- * @since 1.0
110
- * @author Jonathan Buttigieg
111
- */
112
- function _do_admin_post_imagify_restore_upload() {
113
- imagify_check_nonce( 'imagify-restore-upload' );
114
- imagify_check_user_capacity( 'upload_files' );
115
-
116
- if ( empty( $_GET['attachment_id'] ) || empty( $_GET['context'] ) ) {
117
- imagify_die( __( 'Invalid request', 'imagify' ) );
118
- }
119
-
120
- $context = esc_html( $_GET['context'] );
121
- $attachment_id = absint( $_GET['attachment_id'] );
122
- $class_name = get_imagify_attachment_class_name( $context, $attachment_id, 'imagify_restore_upload' );
123
- $attachment = new $class_name( $attachment_id );
124
-
125
- // Restore the backup file.
126
- $attachment->restore();
127
-
128
- imagify_maybe_redirect();
129
-
130
- // Return the optimization button.
131
- $output = get_imagify_admin_url( 'manual-upload', array( 'attachment_id' => $attachment->id, 'context' => $context ) );
132
- $output = '<a id="imagify-upload-' . $attachment->id . '" href="' . esc_url( $output ) . '" class="button-primary button-imagify-manual-upload" data-waiting-label="' . esc_attr__( 'Optimizing...', 'imagify' ) . '">' . __( 'Optimize', 'imagify' ) . '</a>';
133
- wp_send_json_success( $output );
134
- }
135
-
136
- add_action( 'wp_ajax_imagify_bulk_upload', '_do_wp_ajax_imagify_bulk_upload' );
137
- /**
138
- * Process all thumbnails of a specific image with Imagify with the bulk method.
139
- *
140
- * @since 1.0
141
- * @author Jonathan Buttigieg
142
- */
143
- function _do_wp_ajax_imagify_bulk_upload() {
144
- imagify_check_nonce( 'imagify-bulk-upload', 'imagifybulkuploadnonce' );
145
- imagify_check_user_capacity( 'upload_files' );
146
-
147
- if ( empty( $_POST['image'] ) || empty( $_POST['context'] ) ) {
148
- imagify_die( __( 'Invalid request', 'imagify' ) );
149
- }
150
-
151
- $context = esc_html( $_POST['context'] );
152
- $attachment_id = absint( $_POST['image'] );
153
- $class_name = get_imagify_attachment_class_name( $context, $attachment_id, 'imagify_bulk_upload' );
154
- $attachment = new $class_name( $attachment_id );
155
- $optimization_level = get_transient( 'imagify_bulk_optimization_level' );
156
-
157
- // Restore it if the optimization level is updated.
158
- if ( $optimization_level !== $attachment->get_optimization_level() ) {
159
- $attachment->restore();
160
- }
161
-
162
- // Optimize it!!!!!
163
- $attachment->optimize( $optimization_level );
164
-
165
- // Return the optimization statistics.
166
- $fullsize_data = $attachment->get_size_data();
167
- $stats_data = $attachment->get_stats_data();
168
- $user = new Imagify_User();
169
- $data = array();
170
-
171
- if ( ! $attachment->is_optimized() ) {
172
- $data['success'] = false;
173
- $data['error'] = $fullsize_data['error'];
174
-
175
- imagify_die( $data );
176
- }
177
-
178
- $data['success'] = true;
179
- $data['original_size'] = $fullsize_data['original_size'];
180
- $data['new_size'] = $fullsize_data['optimized_size'];
181
- $data['percent'] = $fullsize_data['percent'];
182
- $data['overall_saving'] = $stats_data['original_size'] - $stats_data['optimized_size'];
183
- $data['original_overall_size'] = $stats_data['original_size'];
184
- $data['new_overall_size'] = $stats_data['optimized_size'];
185
- $data['thumbnails'] = $attachment->get_optimized_sizes_count();
186
-
187
- wp_send_json_success( $data );
188
- }
189
-
190
- /** --------------------------------------------------------------------------------------------- */
191
- /** AUTOMATIC OPTIMIZATION ====================================================================== */
192
- /** --------------------------------------------------------------------------------------------- */
193
-
194
- add_action( 'wp_ajax_imagify_async_optimize_upload_new_media', '_do_admin_post_async_optimize_upload_new_media' );
195
- /**
196
- * Optimize image on picture uploading with async request.
197
- *
198
- * @since 1.5
199
- * @author Julio Potier
200
- * @see _imagify_optimize_attachment()
201
- */
202
- function _do_admin_post_async_optimize_upload_new_media() {
203
- if ( empty( $_POST['_ajax_nonce'] ) || empty( $_POST['attachment_id'] ) || empty( $_POST['metadata'] ) || empty( $_POST['context'] ) ) { // WPCS: CSRF ok.
204
- return;
205
- }
206
-
207
- imagify_check_nonce( 'new_media-' . $_POST['attachment_id'] );
208
- imagify_check_user_capacity( 'upload_files' );
209
-
210
- $context = esc_html( $_POST['context'] );
211
- $attachment_id = absint( $_POST['attachment_id'] );
212
- $class_name = get_imagify_attachment_class_name( $context, $attachment_id, 'imagify_async_optimize_upload_new_media' );
213
- $attachment = new $class_name( $attachment_id );
214
-
215
- // Optimize it!!!!!
216
- $attachment->optimize( null, $_POST['metadata'] );
217
- die( 1 );
218
- }
219
-
220
- add_action( 'wp_ajax_imagify_async_optimize_save_image_editor_file', '_do_admin_post_async_optimize_save_image_editor_file' );
221
- /**
222
- * Optimize image on picture editing (resize, crop...) with async request.
223
- *
224
- * @since 1.4
225
- * @author Julio Potier
226
- */
227
- function _do_admin_post_async_optimize_save_image_editor_file() {
228
- $attachment_id = ! empty( $_POST['postid'] ) ? (int) $_POST['postid'] : 0; // WPCS: CSRF ok.
229
-
230
- if ( ! $attachment_id || empty( $_POST['do'] ) ) { // WPCS: CSRF ok.
231
- return;
232
- }
233
-
234
- imagify_check_nonce( 'image_editor-' . $attachment_id );
235
- imagify_check_user_capacity( 'edit_post', $attachment_id );
236
-
237
- if ( ! get_post_meta( $attachment_id, '_imagify_data', true ) ) {
238
- return;
239
- }
240
-
241
- $optimization_level = (int) get_post_meta( $attachment_id, '_imagify_optimization_level', true );
242
- $class_name = get_imagify_attachment_class_name( 'wp', $attachment_id, 'wp_ajax_imagify_async_optimize_save_image_editor_file' );
243
- $attachment = new $class_name( $attachment_id );
244
- $metadata = wp_get_attachment_metadata( $attachment_id );
245
-
246
- // Remove old optimization data.
247
- $attachment->delete_imagify_data();
248
-
249
- if ( 'restore' === $_POST['do'] ) {
250
- // Restore the backup file.
251
- $attachment->restore();
252
-
253
- // Get old metadata to regenerate all thumbnails.
254
- $metadata = array( 'sizes' => array() );
255
- $backup_sizes = (array) get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true );
256
-
257
- foreach ( $backup_sizes as $size_key => $size_data ) {
258
- $size_key = str_replace( '-origin', '' , $size_key );
259
- $metadata['sizes'][ $size_key ] = $size_data;
260
- }
261
- }
262
-
263
- // Optimize it!!!!!
264
- $attachment->optimize( $optimization_level, $metadata );
265
- die( 1 );
266
- }
267
-
268
- /** --------------------------------------------------------------------------------------------- */
269
- /** VARIOUS FOR OPTIMIZATION ==================================================================== */
270
- /** --------------------------------------------------------------------------------------------- */
271
-
272
- add_action( 'wp_ajax_imagify_get_unoptimized_attachment_ids', '_do_wp_ajax_imagify_get_unoptimized_attachment_ids' );
273
- /**
274
- * Get all unoptimized attachment ids.
275
- *
276
- * @since 1.0
277
- * @author Jonathan Buttigieg
278
- */
279
- function _do_wp_ajax_imagify_get_unoptimized_attachment_ids() {
280
- global $wpdb;
281
-
282
- imagify_check_nonce( 'imagify-bulk-upload', 'imagifybulkuploadnonce' );
283
- imagify_check_user_capacity( imagify_get_capacity( true ) );
284
-
285
- if ( ! imagify_valid_key() ) {
286
- wp_send_json_error( array( 'message' => 'invalid-api-key' ) );
287
- }
288
-
289
- $user = new Imagify_User();
290
-
291
- if ( $user->is_over_quota() ) {
292
- wp_send_json_error( array( 'message' => 'over-quota' ) );
293
- }
294
-
295
- @set_time_limit( 0 );
296
-
297
- // Get (ordered) IDs.
298
- $optimization_level = (int) $_GET['optimization_level'];
299
- $optimization_level = ( -1 !== $optimization_level ) ? $optimization_level : (int) get_imagify_option( 'optimization_level', 1 );
300
-
301
- /**
302
- * Filter the unoptimized attachments limit query.
303
- *
304
- * @since 1.4.4
305
- *
306
- * @param int The limit (-1 for unlimited).
307
- */
308
- $unoptimized_attachment_limit = (int) apply_filters( 'imagify_unoptimized_attachment_limit', 10000 );
309
- $unoptimized_attachment_limit = -1 === $unoptimized_attachment_limit ? PHP_INT_MAX : $unoptimized_attachment_limit;
310
-
311
- $mime_types = get_imagify_mime_type();
312
- $mime_types = esc_sql( $mime_types );
313
- $mime_types = "'" . implode( "','", $mime_types ) . "'";
314
-
315
- $ids = $wpdb->get_col( $wpdb->prepare( // WPCS: unprepared SQL ok.
316
- "SELECT $wpdb->posts.ID
317
- FROM $wpdb->posts
318
- LEFT JOIN $wpdb->postmeta
319
- ON ( $wpdb->posts.ID = $wpdb->postmeta.post_id AND $wpdb->postmeta.meta_key = '_imagify_optimization_level' )
320
- LEFT JOIN $wpdb->postmeta AS mt1
321
- ON ( $wpdb->posts.ID = mt1.post_id AND mt1.meta_key = '_imagify_status' )
322
- WHERE
323
- $wpdb->posts.post_mime_type IN ( $mime_types )
324
- AND (
325
- $wpdb->postmeta.meta_value != '%d'
326
- OR
327
- $wpdb->postmeta.post_id IS NULL
328
- OR
329
- mt1.meta_value = 'error'
330
- )
331
- AND $wpdb->posts.post_type = 'attachment'
332
- AND $wpdb->posts.post_status <> 'trash'
333
- AND $wpdb->posts.post_status <> 'auto-draft'
334
- GROUP BY $wpdb->posts.ID
335
- ORDER BY
336
- CASE mt1.meta_value
337
- WHEN 'already_optimized' THEN 2
338
- ELSE 1
339
- END ASC,
340
- $wpdb->posts.ID DESC
341
- LIMIT 0, %d",
342
- $optimization_level,
343
- $unoptimized_attachment_limit
344
- ) );
345
-
346
- $wpdb->flush();
347
- unset( $unoptimized_attachment_limit, $mime_types );
348
- $ids = array_filter( array_map( 'absint', $ids ) );
349
-
350
- if ( ! $ids ) {
351
- wp_send_json_error( array( 'message' => 'no-images' ) );
352
- }
353
-
354
- $results = imagify_get_wpdb_metas( array(
355
- // Get attachments filename.
356
- 'filenames' => '_wp_attached_file',
357
- // Get attachments data.
358
- 'data' => '_imagify_data',
359
- // Get attachments optimization level.
360
- 'optimization_levels' => '_imagify_optimization_level',
361
- // Get attachments status.
362
- 'statuses' => '_imagify_status',
363
- ), $ids );
364
-
365
- // Save the optimization level in a transient to retrieve it later during the process.
366
- set_transient( 'imagify_bulk_optimization_level', $optimization_level );
367
-
368
- // First run.
369
- foreach ( $ids as $i => $id ) {
370
- $attachment_status = isset( $results['statuses'][ $id ] ) ? $results['statuses'][ $id ] : false;
371
- $attachment_optimization_level = isset( $results['optimization_levels'][ $id ] ) ? $results['optimization_levels'][ $id ] : false;
372
- $attachment_error = '';
373
-
374
- if ( isset( $results['data'][ $id ]['sizes']['full']['error'] ) ) {
375
- $attachment_error = $results['data'][ $id ]['sizes']['full']['error'];
376
- }
377
-
378
- // Don't try to re-optimize if the optimization level is still the same.
379
- if ( $optimization_level === $attachment_optimization_level && is_string( $attachment_error ) ) {
380
- unset( $ids[ $i ] );
381
- continue;
382
- }
383
-
384
- // Don't try to re-optimize images already compressed.
385
- if ( 'already_optimized' === $attachment_status && $attachment_optimization_level >= $optimization_level ) {
386
- unset( $ids[ $i ] );
387
- continue;
388
- }
389
-
390
- $attachment_error = trim( $attachment_error );
391
-
392
- // Don't try to re-optimize images with an empty error message.
393
- if ( 'error' === $attachment_status && empty( $attachment_error ) ) {
394
- unset( $ids[ $i ] );
395
- }
396
- }
397
-
398
- if ( ! $ids ) {
399
- wp_send_json_error( array( 'message' => 'no-images' ) );
400
- }
401
-
402
- $ids = array_values( $ids );
403
-
404
- /**
405
- * Triggered before testing for file existence.
406
- *
407
- * @since 1.6.7
408
- * @author Grégory Viguier
409
- *
410
- * @param array $ids An array of attachment IDs.
411
- * @param array $results An array of the data fetched from the database.
412
- * @param int $optimization_level The optimization level that will be used for the optimization.
413
- */
414
- do_action( 'imagify_bulk_optimize_before_file_existence_tests', $ids, $results, $optimization_level );
415
-
416
- $data = array();
417
-
418
- foreach ( $ids as $i => $id ) {
419
- $file_path = get_imagify_attached_file( $results['filenames'][ $id ] );
420
-
421
- /** This filter is documented in inc/functions/process.php. */
422
- $file_path = apply_filters( 'imagify_file_path', $file_path );
423
-
424
- if ( ! $file_path || ! file_exists( $file_path ) ) {
425
- continue;
426
- }
427
-
428
- $attachment_backup_path = get_imagify_attachment_backup_path( $file_path );
429
- $attachment_status = isset( $results['statuses'][ $id ] ) ? $results['statuses'][ $id ] : false;
430
- $attachment_optimization_level = isset( $results['optimization_levels'][ $id ] ) ? $results['optimization_levels'][ $id ] : false;
431
-
432
- // Don't try to re-optimize if there is no backup file.
433
- if ( 'success' === $attachment_status && $optimization_level !== $attachment_optimization_level && ! file_exists( $attachment_backup_path ) ) {
434
- continue;
435
- }
436
-
437
- $data[ '_' . $id ] = get_imagify_attachment_url( $results['filenames'][ $id ] );
438
- } // End foreach().
439
-
440
- if ( ! $data ) {
441
- wp_send_json_error( array( 'message' => 'no-images' ) );
442
- }
443
-
444
- wp_send_json_success( $data );
445
- }
446
-
447
- add_action( 'wp_ajax_imagify_check_backup_dir_is_writable', '_do_wp_ajax_imagify_check_backup_dir_is_writable' );
448
- /**
449
- * Check if the backup directory is writable.
450
- * This is used to display an error message in the plugin's settings page.
451
- *
452
- * @since 1.6.8
453
- * @author Grégory Viguier
454
- */
455
- function _do_wp_ajax_imagify_check_backup_dir_is_writable() {
456
- imagify_check_nonce( 'imagify_check_backup_dir_is_writable' );
457
- imagify_check_user_capacity();
458
-
459
- wp_send_json_success( array(
460
- 'is_writable' => (int) imagify_backup_dir_is_writable(),
461
- ) );
462
- }
463
-
464
- /** --------------------------------------------------------------------------------------------- */
465
- /** IMAGIFY ACCOUNT ============================================================================= */
466
- /** --------------------------------------------------------------------------------------------- */
467
-
468
- add_action( 'wp_ajax_imagify_signup', '_do_wp_ajax_imagify_signup' );
469
- /**
470
- * Create a new Imagify account.
471
- *
472
- * @since 1.0
473
- * @author Jonathan Buttigieg
474
- */
475
- function _do_wp_ajax_imagify_signup() {
476
- imagify_check_nonce( 'imagify-signup', 'imagifysignupnonce' );
477
- imagify_check_user_capacity();
478
-
479
- if ( empty( $_GET['email'] ) ) {
480
- imagify_die( __( 'Empty email address.', 'imagify' ) );
481
- }
482
-
483
- if ( ! is_email( $_GET['email'] ) ) {
484
- imagify_die( __( 'Not a valid email address.', 'imagify' ) );
485
- }
486
-
487
- $data = array(
488
- 'email' => $_GET['email'],
489
- 'password' => wp_generate_password( 12, false ),
490
- 'lang' => get_locale(),
491
- );
492
-
493
- $response = add_imagify_user( $data );
494
-
495
- if ( is_wp_error( $response ) ) {
496
- imagify_die( $response );
497
- }
498
-
499
- wp_send_json_success();
500
- }
501
-
502
- add_action( 'wp_ajax_imagify_check_api_key_validity', '_do_wp_ajax_imagify_check_api_key_validity' );
503
- /**
504
- * Process an API key check validity.
505
- *
506
- * @since 1.0
507
- * @author Jonathan Buttigieg
508
- */
509
- function _do_wp_ajax_imagify_check_api_key_validity() {
510
- imagify_check_nonce( 'imagify-check-api-key', 'imagifycheckapikeynonce' );
511
- imagify_check_user_capacity();
512
-
513
- if ( empty( $_GET['api_key'] ) ) {
514
- imagify_die( __( 'Empty API key.', 'imagify' ) );
515
- }
516
-
517
- $response = get_imagify_status( $_GET['api_key'] );
518
-
519
- if ( is_wp_error( $response ) ) {
520
- imagify_die( $response );
521
- }
522
-
523
- $options = get_site_option( IMAGIFY_SETTINGS_SLUG );
524
- $options['api_key'] = sanitize_key( $_GET['api_key'] );
525
-
526
- update_site_option( IMAGIFY_SETTINGS_SLUG, $options );
527
-
528
- wp_send_json_success();
529
- }
530
-
531
- add_action( 'wp_ajax_imagify_get_admin_bar_profile', '_do_wp_ajax_imagify_get_admin_bar_profile' );
532
- /**
533
- * Get admin bar profile output
534
- *
535
- * @since 1.2.3
536
- * @author Jonathan Buttigieg
537
- */
538
- function _do_wp_ajax_imagify_get_admin_bar_profile() {
539
- imagify_check_nonce( 'imagify-get-admin-bar-profile', 'imagifygetadminbarprofilenonce' );
540
- imagify_check_user_capacity();
541
-
542
- $user = new Imagify_User();
543
- $unconsumed_quota = $user->get_percent_unconsumed_quota();
544
- $meteo_icon = '<img src="' . IMAGIFY_ASSETS_IMG_URL . 'sun.svg" width="37" height="38" alt="" />';
545
- $bar_class = 'positive';
546
- $message = '';
547
-
548
- if ( $unconsumed_quota >= 21 && $unconsumed_quota <= 50 ) {
549
- $bar_class = 'neutral';
550
- $meteo_icon = '<img src="' . IMAGIFY_ASSETS_IMG_URL . 'cloudy-sun.svg" width="37" height="38" alt="" />';
551
- }
552
- elseif ( $unconsumed_quota <= 20 ) {
553
- $bar_class = 'negative';
554
- $meteo_icon = '<img src="' . IMAGIFY_ASSETS_IMG_URL . 'stormy.svg" width="38" height="36" alt="" />';
555
- }
556
-
557
- if ( $unconsumed_quota <= 20 && $unconsumed_quota > 0 ) {
558
- $message = '<div class="imagify-error">';
559
- $message .= '<p><i class="dashicons dashicons-warning" aria-hidden="true"></i><strong>' . __( 'Oops, It\'s almost over!', 'imagify' ) . '</strong></p>';
560
- /* translators: %s is a line break. */
561
- $message .= '<p>' . sprintf( __( 'You have almost used all your credit.%sDon\'t forget to upgrade your subscription to continue optimizing your images.', 'imagify' ), '<br/><br/>' ) . '</p>';
562
- $message .= '<p class="center txt-center text-center"><a class="btn imagify-btn-ghost" href="' . IMAGIFY_APP_MAIN . '/#/subscription" target="_blank">' . __( 'View My Subscription', 'imagify' ) . '</a></p>';
563
- $message .= '</div>';
564
- }
565
-
566
- if ( 0 === $unconsumed_quota ) {
567
- $message = '<div class="imagify-error">';
568
- $message .= '<p><i class="dashicons dashicons-warning" aria-hidden="true"></i><strong>' . __( 'Oops, It\'s Over!', 'imagify' ) . '</strong></p>';
569
- $message .= '<p>' . sprintf(
570
- /* translators: 1 is a data quota, 2 is a date. */
571
- __( 'You have consumed all your credit for this month. You will have <strong>%1$s back on %2$s</strong>.', 'imagify' ),
572
- size_format( $user->quota * 1048576 ),
573
- date_i18n( get_option( 'date_format' ), strtotime( $user->next_date_update ) )
574
- ) . '</p>';
575
- $message .= '<p class="center txt-center text-center"><a class="btn imagify-btn-ghost" href="' . IMAGIFY_APP_MAIN . '/#/subscription" target="_blank">' . __( 'Upgrade My Subscription', 'imagify' ) . '</a></p>';
576
- $message .= '</div>';
577
- }
578
-
579
- // Custom HTML.
580
- $quota_section = '<div class="imagify-admin-bar-quota">';
581
- $quota_section .= '<div class="imagify-abq-row">';
582
-
583
- if ( 1 === $user->plan_id ) {
584
- $quota_section .= '<div class="imagify-meteo-icon">' . $meteo_icon . '</div>';
585
- }
586
-
587
- $quota_section .= '<div class="imagify-account">';
588
- $quota_section .= '<p class="imagify-meteo-title">' . __( 'Account status', 'imagify' ) . '</p>';
589
- $quota_section .= '<p class="imagify-meteo-subs">' . __( 'Your subscription:', 'imagify' ) . '&nbsp;<strong class="imagify-user-plan">' . $user->plan_label . '</strong></p>';
590
- $quota_section .= '</div>'; // .imagify-account
591
- $quota_section .= '</div>'; // .imagify-abq-row
592
-
593
- if ( 1 === $user->plan_id ) {
594
- $quota_section .= '<div class="imagify-abq-row">';
595
- $quota_section .= '<div class="imagify-space-left">';
596
- /* translators: %s is a data quota. */
597
- $quota_section .= '<p>' . sprintf( __( 'You have %s space credit left', 'imagify' ), '<span class="imagify-unconsumed-percent">' . $unconsumed_quota . '%</span>' ) . '</p>';
598
- $quota_section .= '<div class="imagify-bar-' . $bar_class . '">';
599
- $quota_section .= '<div style="width: ' . $unconsumed_quota . '%;" class="imagify-unconsumed-bar imagify-progress"></div>';
600
- $quota_section .= '</div>'; // .imagify-bar-{$bar_class}
601
- $quota_section .= '</div>'; // .imagify-space-left
602
- $quota_section .= '</div>'; // .imagify-abq-row
603
- }
604
-
605
- $quota_section .= '<p class="imagify-abq-row">';
606
- $quota_section .= '<a class="imagify-account-link" href="' . IMAGIFY_APP_MAIN . '/#/subscription" target="_blank">';
607
- $quota_section .= '<span class="dashicons dashicons-admin-users"></span>';
608
- $quota_section .= '<span class="button-text">' . __( 'View my subscription', 'imagify' ) . '</span>';
609
- $quota_section .= '</a>'; // .imagify-account-link
610
- $quota_section .= '</p>'; // .imagify-abq-row
611
- $quota_section .= '</div>'; // .imagify-admin-bar-quota
612
- $quota_section .= $message;
613
-
614
- wp_send_json_success( $quota_section );
615
- }
616
-
617
- add_action( 'wp_ajax_imagify_get_prices', '_imagify_get_prices_from_api' );
618
- /**
619
- * Get pricings from API for Onetime and Plans at the same time.
620
- *
621
- * @since 1.6
622
- * @author Geoffrey Crofte
623
- */
624
- function _imagify_get_prices_from_api() {
625
- imagify_check_nonce( 'imagify_get_pricing_' . get_current_user_id(), 'imagifynonce' );
626
- imagify_check_user_capacity();
627
-
628
- $prices_all = get_imagify_all_prices();
629
-
630
- if ( is_wp_error( $prices_all ) ) {
631
- imagify_die( $prices_all );
632
- }
633
-
634
- if ( ! is_object( $prices_all ) ) {
635
- imagify_die( __( 'Wrongly formatted response from our server.', 'imagify' ) );
636
- }
637
-
638
- wp_send_json_success( array(
639
- 'onetimes' => $prices_all->Packs,
640
- 'monthlies' => $prices_all->Plans,
641
- ) );
642
- }
643
-
644
- add_action( 'wp_ajax_imagify_check_coupon', '_imagify_check_coupon_code' );
645
- /**
646
- * Check Coupon code on modal popin.
647
- *
648
- * @since 1.6
649
- * @author Geoffrey Crofte
650
- */
651
- function _imagify_check_coupon_code() {
652
- imagify_check_nonce( 'imagify_get_pricing_' . get_current_user_id(), 'imagifynonce' );
653
- imagify_check_user_capacity();
654
-
655
- if ( empty( $_POST['coupon'] ) ) {
656
- wp_send_json_success( array(
657
- 'success' => false,
658
- 'detail' => __( 'Coupon is empty.', 'imagify' ),
659
- ) );
660
- }
661
-
662
- $coupon = check_imagify_coupon_code( $_POST['coupon'] );
663
-
664
- if ( is_wp_error( $coupon ) ) {
665
- imagify_die( $coupon );
666
- }
667
-
668
- wp_send_json_success( imagify_translate_api_message( $coupon ) );
669
- }
670
-
671
- add_action( 'wp_ajax_imagify_get_discount', '_imagify_get_discount' );
672
- /**
673
- * Get current discount promotion to display information on payment modal.
674
- *
675
- * @since 1.6.3
676
- * @author Geoffrey Crofte
677
- */
678
- function _imagify_get_discount() {
679
- imagify_check_nonce( 'imagify_get_pricing_' . get_current_user_id(), 'imagifynonce' );
680
- imagify_check_user_capacity();
681
-
682
- wp_send_json_success( imagify_translate_api_message( check_imagify_discount() ) );
683
- }
684
-
685
- add_action( 'wp_ajax_imagify_get_images_counts', '_imagify_get_estimated_sizes' );
686
- /**
687
- * Get estimated sizes from the WordPress library.
688
- *
689
- * @since 1.6
690
- * @author Geoffrey Crofte
691
- */
692
- function _imagify_get_estimated_sizes() {
693
- imagify_check_nonce( 'imagify_get_pricing_' . get_current_user_id(), 'imagifynonce' );
694
- imagify_check_user_capacity();
695
-
696
- $raw_total_size_in_library = imagify_calculate_total_size_images_library();
697
- $raw_average_per_month = imagify_calculate_average_size_images_per_month();
698
- update_imagify_option( 'total_size_images_library', array( 'raw' => $raw_total_size_in_library, 'human' => size_format( $raw_total_size_in_library ) ) );
699
- update_imagify_option( 'average_size_images_per_month', array( 'raw' => $raw_average_per_month, 'human' => size_format( $raw_average_per_month ) ) );
700
-
701
- wp_send_json_success( array(
702
- 'total_library_size' => get_imagify_option( 'total_size_images_library', null ),
703
- 'average_month_size' => get_imagify_option( 'average_size_images_per_month', null ),
704
- ) );
705
- }
706
-
707
- add_action( 'wp_ajax_imagify_update_estimate_sizes', '_imagify_update_estimate_sizes' );
708
- /**
709
- * Estimate sizes and update the options values for them.
710
- *
711
- * @since 1.6
712
- * @author Remy Perona
713
- */
714
- function _imagify_update_estimate_sizes() {
715
- imagify_check_nonce( 'update_estimate_sizes' );
716
- imagify_check_user_capacity();
717
-
718
- $raw_total_size_in_library = imagify_calculate_total_size_images_library();
719
- $raw_average_per_month = imagify_calculate_average_size_images_per_month();
720
-
721
- update_imagify_option( 'total_size_images_library', array( 'raw' => $raw_total_size_in_library, 'human' => size_format( $raw_total_size_in_library ) ) );
722
- update_imagify_option( 'average_size_images_per_month', array( 'raw' => $raw_average_per_month, 'human' => size_format( $raw_average_per_month ) ) );
723
-
724
- die( 1 );
725
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin/media.php CHANGED
@@ -19,6 +19,10 @@ function _imagify_attachment_fields_to_edit( $form_fields, $post ) {
19
  return $form_fields;
20
  }
21
 
 
 
 
 
22
  $class_name = get_imagify_attachment_class_name( 'wp', $post->ID, 'attachment_fields_to_edit' );
23
  $attachment = new $class_name( $post->ID );
24
 
@@ -45,6 +49,10 @@ add_filter( 'media_row_actions', '_imagify_add_actions_to_media_list_row', IMAGI
45
  * @return array
46
  */
47
  function _imagify_add_actions_to_media_list_row( $actions, $post ) {
 
 
 
 
48
  // If this attachment is not an image, do nothing.
49
  if ( ! imagify_is_attachment_mime_type_supported( $post->ID ) ) {
50
  return $actions;
@@ -65,7 +73,7 @@ function _imagify_add_actions_to_media_list_row( $actions, $post ) {
65
 
66
  $image = wp_get_attachment_image_src( $post->ID, 'full' );
67
 
68
- // If full image is too small.
69
  if ( ! $image || (int) $image[1] < 360 ) {
70
  return $actions;
71
  }
19
  return $form_fields;
20
  }
21
 
22
+ if ( ! imagify_current_user_can( 'manual-optimize', $post->ID ) ) {
23
+ return $form_fields;
24
+ }
25
+
26
  $class_name = get_imagify_attachment_class_name( 'wp', $post->ID, 'attachment_fields_to_edit' );
27
  $attachment = new $class_name( $post->ID );
28
 
49
  * @return array
50
  */
51
  function _imagify_add_actions_to_media_list_row( $actions, $post ) {
52
+ if ( ! imagify_current_user_can( 'manual-optimize', $post->ID ) ) {
53
+ return $actions;
54
+ }
55
+
56
  // If this attachment is not an image, do nothing.
57
  if ( ! imagify_is_attachment_mime_type_supported( $post->ID ) ) {
58
  return $actions;
73
 
74
  $image = wp_get_attachment_image_src( $post->ID, 'full' );
75
 
76
+ // If full image is too small. See get_imagify_localize_script_translations().
77
  if ( ! $image || (int) $image[1] < 360 ) {
78
  return $actions;
79
  }
inc/admin/menu.php CHANGED
@@ -20,5 +20,5 @@ add_action( 'admin_menu', '_imagify_bulk_optimization_menu' );
20
  * @since 1.0
21
  */
22
  function _imagify_bulk_optimization_menu() {
23
- add_media_page( __( 'Bulk Optimization', 'imagify' ), __( 'Bulk Optimization', 'imagify' ), imagify_get_capacity( true ), IMAGIFY_SLUG . '-bulk-optimization', '_imagify_display_bulk_page' );
24
  }
20
  * @since 1.0
21
  */
22
  function _imagify_bulk_optimization_menu() {
23
+ add_media_page( __( 'Bulk Optimization', 'imagify' ), __( 'Bulk Optimization', 'imagify' ), imagify_get_capacity( 'bulk-optimize' ), IMAGIFY_SLUG . '-bulk-optimization', '_imagify_display_bulk_page' );
24
  }
inc/admin/meta-boxes.php CHANGED
@@ -10,7 +10,7 @@ add_action( 'attachment_submitbox_misc_actions', '_imagify_attachment_submitbox_
10
  function _imagify_attachment_submitbox_misc_actions() {
11
  global $post;
12
 
13
- if ( ! current_user_can( imagify_get_capacity( true ) ) ) {
14
  return;
15
  }
16
 
10
  function _imagify_attachment_submitbox_misc_actions() {
11
  global $post;
12
 
13
+ if ( ! imagify_current_user_can( 'manual-optimize', $post->ID ) ) {
14
  return;
15
  }
16
 
inc/admin/options.php CHANGED
@@ -1,12 +1,12 @@
1
  <?php
2
  defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
3
 
4
- add_filter( 'option_page_capability_imagify', '_imagify_correct_capability_for_options_page' );
5
  /**
6
  * Fix the capability for our capacity filter hook
7
  *
8
- * @author Jonathan
9
- * @since 1.0
10
  */
11
  function _imagify_correct_capability_for_options_page() {
12
  return imagify_get_capacity();
@@ -16,19 +16,19 @@ add_action( 'admin_init', '_imagify_register_setting' );
16
  /**
17
  * Tell to WordPress to be confident with our setting, we are clean!
18
  *
 
19
  * @author Jonathan
20
- * @since 1.0
21
  */
22
  function _imagify_register_setting() {
23
- register_setting( 'imagify', 'imagify_settings' );
24
  }
25
 
26
  add_filter( 'pre_update_option_' . IMAGIFY_SETTINGS_SLUG, '_imagify_pre_update_option', 10, 2 );
27
  /**
28
  * Filter specific options before its value is (maybe) serialized and updated.
29
  *
 
30
  * @author Jonathan
31
- * @since 1.0
32
  *
33
  * @param mixed $value The new option value.
34
  * @param mixed $old_value The old option value.
@@ -111,8 +111,8 @@ if ( imagify_is_active_for_network() ) {
111
  /**
112
  * Used to launch some actions after saving the network options.
113
  *
 
114
  * @author Grégory Viguier
115
- * @since 1.6.5
116
  *
117
  * @param string $option Name of the network option.
118
  * @param mixed $value Current value of the network option.
@@ -128,10 +128,10 @@ if ( ! imagify_is_active_for_network() ) {
128
  /**
129
  * Used to launch some actions after saving the options.
130
  *
131
- * @author Jonathan
132
  * @since 1.0
133
  * @since 1.5 Used to redirect user to Bulk Optimizer (if requested).
134
  * @since 1.6.8 Not used to redirect user to Bulk Optimizer anymore: see _imagify_maybe_set_redirection_before_save_options().
 
135
  *
136
  * @param mixed $old_value The old option value.
137
  * @param mixed $value The new option value.
@@ -168,10 +168,10 @@ if ( imagify_is_active_for_network() ) :
168
  $capability = apply_filters( "option_page_capability_{$option_group}", 'manage_network_options' );
169
 
170
  if ( ! current_user_can( $capability ) ) {
171
- wp_die( __( 'Cheatin&#8217; uh?' ), 403 );
172
  }
173
 
174
- check_admin_referer( $option_group . '-options' );
175
 
176
  $whitelist_options = apply_filters( 'whitelist_options', array() );
177
 
@@ -201,9 +201,7 @@ if ( imagify_is_active_for_network() ) :
201
  /**
202
  * Redirect back to the settings page that was submitted.
203
  */
204
- $goback = add_query_arg( 'settings-updated', 'true', wp_get_referer() );
205
- wp_safe_redirect( $goback );
206
- exit;
207
  }
208
 
209
  endif;
1
  <?php
2
  defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
3
 
4
+ add_filter( 'option_page_capability_' . IMAGIFY_SLUG, '_imagify_correct_capability_for_options_page' );
5
  /**
6
  * Fix the capability for our capacity filter hook
7
  *
8
+ * @since 1.0
9
+ * @author Jonathan
10
  */
11
  function _imagify_correct_capability_for_options_page() {
12
  return imagify_get_capacity();
16
  /**
17
  * Tell to WordPress to be confident with our setting, we are clean!
18
  *
19
+ * @since 1.0
20
  * @author Jonathan
 
21
  */
22
  function _imagify_register_setting() {
23
+ register_setting( IMAGIFY_SLUG, IMAGIFY_SETTINGS_SLUG );
24
  }
25
 
26
  add_filter( 'pre_update_option_' . IMAGIFY_SETTINGS_SLUG, '_imagify_pre_update_option', 10, 2 );
27
  /**
28
  * Filter specific options before its value is (maybe) serialized and updated.
29
  *
30
+ * @since 1.0
31
  * @author Jonathan
 
32
  *
33
  * @param mixed $value The new option value.
34
  * @param mixed $old_value The old option value.
111
  /**
112
  * Used to launch some actions after saving the network options.
113
  *
114
+ * @since 1.6.5
115
  * @author Grégory Viguier
 
116
  *
117
  * @param string $option Name of the network option.
118
  * @param mixed $value Current value of the network option.
128
  /**
129
  * Used to launch some actions after saving the options.
130
  *
 
131
  * @since 1.0
132
  * @since 1.5 Used to redirect user to Bulk Optimizer (if requested).
133
  * @since 1.6.8 Not used to redirect user to Bulk Optimizer anymore: see _imagify_maybe_set_redirection_before_save_options().
134
+ * @author Jonathan
135
  *
136
  * @param mixed $old_value The old option value.
137
  * @param mixed $value The new option value.
168
  $capability = apply_filters( "option_page_capability_{$option_group}", 'manage_network_options' );
169
 
170
  if ( ! current_user_can( $capability ) ) {
171
+ imagify_die();
172
  }
173
 
174
+ imagify_check_nonce( $option_group . '-options' );
175
 
176
  $whitelist_options = apply_filters( 'whitelist_options', array() );
177
 
201
  /**
202
  * Redirect back to the settings page that was submitted.
203
  */
204
+ imagify_maybe_redirect( false, array( 'settings-updated' => 'true' ) );
 
 
205
  }
206
 
207
  endif;
inc/admin/ui/bulk.php CHANGED
@@ -272,17 +272,19 @@ function _imagify_display_bulk_page() {
272
  </button>
273
  </p>
274
  </div>
275
- <div class="imagify-cell imagify-pl0">
276
- <p class="imagify-info-block">
277
- <?php
278
- printf(
279
- /* translators: %s is a file size. */
280
- __( 'All images greater than %s will be optimized when using a paid plan.', 'imagify' ),
281
- size_format( get_imagify_max_image_size() )
282
- );
283
- ?>
284
- </p>
285
- </div>
 
 
286
  </div>
287
  </div>
288
  </div><!-- .imagify-bulk-submit -->
272
  </button>
273
  </p>
274
  </div>
275
+ <?php if ( ! is_wp_error( get_imagify_max_image_size() ) ) { ?>
276
+ <div class="imagify-cell imagify-pl0">
277
+ <p class="imagify-info-block">
278
+ <?php
279
+ printf(
280
+ /* translators: %s is a file size. */
281
+ __( 'All images greater than %s will be optimized when using a paid plan.', 'imagify' ),
282
+ size_format( get_imagify_max_image_size() )
283
+ );
284
+ ?>
285
+ </p>
286
+ </div>
287
+ <?php } ?>
288
  </div>
289
  </div>
290
  </div><!-- .imagify-bulk-submit -->
inc/admin/upload.php CHANGED
@@ -5,14 +5,17 @@ add_filter( 'manage_media_columns', '_imagify_manage_media_columns' );
5
  /**
6
  * Add "Imagify" column in upload.php.
7
  *
8
- * @since 1.0
9
  * @author Jonathan Buttigieg
10
  *
11
  * @param array $columns An array of columns displayed in the Media list table.
12
  * @return array
13
  */
14
  function _imagify_manage_media_columns( $columns ) {
15
- $columns['imagify_optimized_file'] = __( 'Imagify', 'imagify' );
 
 
 
16
  return $columns;
17
  }
18
 
@@ -20,7 +23,7 @@ add_action( 'manage_media_custom_column', '_imagify_manage_media_custom_column',
20
  /**
21
  * Add content to the "Imagify" columns in upload.php.
22
  *
23
- * @since 1.0
24
  * @author Jonathan Buttigieg
25
  *
26
  * @param string $column_name Name of the custom column.
@@ -41,7 +44,7 @@ add_action( 'restrict_manage_posts', '_imagify_attachments_filter_dropdown' );
41
  /**
42
  * Adds a dropdown that allows filtering on the attachments Imagify status.
43
  *
44
- * @since 1.0
45
  * @author Jonathan Buttigieg
46
  */
47
  function _imagify_attachments_filter_dropdown() {
@@ -73,7 +76,7 @@ add_filter( 'request', '_imagify_sort_attachments_by_status' );
73
  /**
74
  * Modify the query based on the imagify-status variable in $_GET.
75
  *
76
- * @since 1.0
77
  * @author Jonathan Buttigieg
78
  *
79
  * @param array $vars The array of requested query variables.
@@ -104,6 +107,9 @@ function _imagify_sort_attachments_by_status( $vars ) {
104
  break;
105
  case 'errors':
106
  $status = 'error';
 
 
 
107
  }
108
 
109
  $vars = array_merge( $vars, array(
5
  /**
6
  * Add "Imagify" column in upload.php.
7
  *
8
+ * @since 1.0
9
  * @author Jonathan Buttigieg
10
  *
11
  * @param array $columns An array of columns displayed in the Media list table.
12
  * @return array
13
  */
14
  function _imagify_manage_media_columns( $columns ) {
15
+ if ( imagify_current_user_can( 'optimize' ) ) {
16
+ $columns['imagify_optimized_file'] = __( 'Imagify', 'imagify' );
17
+ }
18
+
19
  return $columns;
20
  }
21
 
23
  /**
24
  * Add content to the "Imagify" columns in upload.php.
25
  *
26
+ * @since 1.0
27
  * @author Jonathan Buttigieg
28
  *
29
  * @param string $column_name Name of the custom column.
44
  /**
45
  * Adds a dropdown that allows filtering on the attachments Imagify status.
46
  *
47
+ * @since 1.0
48
  * @author Jonathan Buttigieg
49
  */
50
  function _imagify_attachments_filter_dropdown() {
76
  /**
77
  * Modify the query based on the imagify-status variable in $_GET.
78
  *
79
+ * @since 1.0
80
  * @author Jonathan Buttigieg
81
  *
82
  * @param array $vars The array of requested query variables.
107
  break;
108
  case 'errors':
109
  $status = 'error';
110
+ break;
111
+ default:
112
+ return $vars;
113
  }
114
 
115
  $vars = array_merge( $vars, array(
inc/classes/abstracts/class-imagify-abstract-attachment.php CHANGED
@@ -436,7 +436,7 @@ class Imagify_Abstract_Attachment {
436
  return array();
437
  }
438
 
439
- $registered_sizes = static::get_registered_sizes();
440
  $attachment_sizes = $this->get_data();
441
  $attachment_sizes = ! empty( $attachment_sizes['sizes'] ) ? $attachment_sizes['sizes'] : array();
442
  $missing_sizes = array_diff_key( $registered_sizes, $attachment_sizes );
436
  return array();
437
  }
438
 
439
+ $registered_sizes = self::get_registered_sizes();
440
  $attachment_sizes = $this->get_data();
441
  $attachment_sizes = ! empty( $attachment_sizes['sizes'] ) ? $attachment_sizes['sizes'] : array();
442
  $missing_sizes = array_diff_key( $registered_sizes, $attachment_sizes );
inc/classes/abstracts/class-imagify-abstract-db.php CHANGED
File without changes
inc/classes/class-imagify-admin-ajax-post.php ADDED
@@ -0,0 +1,876 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
3
+
4
+ /**
5
+ * Class that handles admin ajax/post callbacks.
6
+ *
7
+ * @since 1.6.11
8
+ * @author Grégory Viguier
9
+ */
10
+ class Imagify_Admin_Ajax_Post {
11
+
12
+ /**
13
+ * Class version.
14
+ *
15
+ * @var string
16
+ */
17
+ const VERSION = '1.0';
18
+
19
+ /**
20
+ * Actions to be triggered on admin ajax and admin post.
21
+ *
22
+ * @var array
23
+ */
24
+ protected $ajax_post_actions = array(
25
+ 'imagify_manual_upload',
26
+ 'imagify_manual_override_upload',
27
+ 'imagify_optimize_missing_sizes',
28
+ 'imagify_restore_upload',
29
+ );
30
+
31
+ /**
32
+ * Actions to be triggered only on admin ajax.
33
+ *
34
+ * @var array
35
+ */
36
+ protected $ajax_only_actions = array(
37
+ 'imagify_bulk_upload',
38
+ 'imagify_async_optimize_upload_new_media',
39
+ 'imagify_async_optimize_save_image_editor_file',
40
+ 'imagify_get_unoptimized_attachment_ids',
41
+ 'imagify_check_backup_dir_is_writable',
42
+ 'nopriv_imagify_rpc',
43
+ 'imagify_signup',
44
+ 'imagify_check_api_key_validity',
45
+ 'imagify_get_admin_bar_profile',
46
+ 'imagify_get_prices',
47
+ 'imagify_check_coupon',
48
+ 'imagify_get_discount',
49
+ 'imagify_get_images_counts',
50
+ 'imagify_update_estimate_sizes',
51
+ );
52
+
53
+ /**
54
+ * Actions to be triggered only on admin post.
55
+ *
56
+ * @var array
57
+ */
58
+ protected $post_only_actions = array();
59
+
60
+ /**
61
+ * The single instance of the class.
62
+ *
63
+ * @var object
64
+ */
65
+ protected static $_instance;
66
+
67
+ /**
68
+ * The constructor.
69
+ *
70
+ * @return void
71
+ */
72
+ protected function __construct() {}
73
+
74
+
75
+ /** ----------------------------------------------------------------------------------------- */
76
+ /** PUBLIC METHODS ========================================================================== */
77
+ /** ----------------------------------------------------------------------------------------- */
78
+
79
+ /**
80
+ * Get the main Instance.
81
+ *
82
+ * @since 1.6.11
83
+ * @author Grégory Viguier
84
+ *
85
+ * @return object Main instance.
86
+ */
87
+ public static function get_instance() {
88
+ if ( ! isset( self::$_instance ) ) {
89
+ self::$_instance = new self();
90
+ }
91
+
92
+ return self::$_instance;
93
+ }
94
+
95
+ /**
96
+ * Launch the hooks.
97
+ *
98
+ * @since 1.6.11
99
+ * @author Grégory Viguier
100
+ */
101
+ public function init() {
102
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
103
+ // Actions triggered only on admin ajax.
104
+ $actions = array_merge( $this->ajax_post_actions, $this->ajax_only_actions );
105
+
106
+ foreach ( $actions as $action ) {
107
+ add_action( 'wp_ajax_' . $action, array( $this, $action . '_callback' ) );
108
+ }
109
+ }
110
+
111
+ // Actions triggered on both admin ajax and admin post.
112
+ $actions = array_merge( $this->ajax_post_actions, $this->post_only_actions );
113
+
114
+ foreach ( $actions as $action ) {
115
+ add_action( 'admin_post_' . $action, array( $this, $action . '_callback' ) );
116
+ }
117
+ }
118
+
119
+
120
+ /** ----------------------------------------------------------------------------------------- */
121
+ /** MANUAL OPTIMIZATION ===================================================================== */
122
+ /** ----------------------------------------------------------------------------------------- */
123
+
124
+ /**
125
+ * Optimize all thumbnails of a specific image with the manual method.
126
+ *
127
+ * @since 1.6.11
128
+ * @author Jonathan Buttigieg
129
+ */
130
+ public function imagify_manual_upload_callback() {
131
+ if ( empty( $_GET['attachment_id'] ) || empty( $_GET['context'] ) ) {
132
+ imagify_die( __( 'Invalid request', 'imagify' ) );
133
+ }
134
+
135
+ $context = imagify_sanitize_context( $_GET['context'] );
136
+ $attachment_id = absint( $_GET['attachment_id'] );
137
+
138
+ imagify_check_nonce( 'imagify-manual-upload-' . $attachment_id . '-' . $context );
139
+ imagify_check_user_capacity( 'manual-optimize', $attachment_id );
140
+
141
+ $class_name = get_imagify_attachment_class_name( $context, $attachment_id, 'imagify_manual_upload' );
142
+ $attachment = new $class_name( $attachment_id );
143
+
144
+ // Optimize it!!!!!
145
+ $attachment->optimize();
146
+
147
+ imagify_maybe_redirect();
148
+
149
+ // Return the optimization statistics.
150
+ $output = get_imagify_attachment_optimization_text( $attachment, $context );
151
+ wp_send_json_success( $output );
152
+ }
153
+
154
+ /**
155
+ * Optimize all thumbnails of a specific image with a different optimization level.
156
+ *
157
+ * @since 1.6.11
158
+ * @author Jonathan Buttigieg
159
+ */
160
+ public function imagify_manual_override_upload_callback() {
161
+ if ( empty( $_GET['attachment_id'] ) || empty( $_GET['context'] ) ) {
162
+ imagify_die( __( 'Invalid request', 'imagify' ) );
163
+ }
164
+
165
+ $context = imagify_sanitize_context( $_GET['context'] );
166
+ $attachment_id = absint( $_GET['attachment_id'] );
167
+
168
+ imagify_check_nonce( 'imagify-manual-override-upload-' . $attachment_id . '-' . $context );
169
+ imagify_check_user_capacity( 'manual-optimize', $attachment_id );
170
+
171
+ $class_name = get_imagify_attachment_class_name( $context, $attachment_id, 'imagify_manual_override_upload' );
172
+ $attachment = new $class_name( $attachment_id );
173
+
174
+ // Restore the backup file.
175
+ $attachment->restore();
176
+
177
+ // Optimize it!!!!!
178
+ $attachment->optimize( (int) $_GET['optimization_level'] );
179
+
180
+ imagify_maybe_redirect();
181
+
182
+ // Return the optimization statistics.
183
+ $output = get_imagify_attachment_optimization_text( $attachment, $context );
184
+ wp_send_json_success( $output );
185
+ }
186
+
187
+ /**
188
+ * Optimize one or some thumbnails that are not optimized yet.
189
+ *
190
+ * @since 1.6.11
191
+ * @author Grégory Viguier
192
+ */
193
+ public function imagify_optimize_missing_sizes_callback() {
194
+ if ( empty( $_GET['attachment_id'] ) || empty( $_GET['context'] ) ) {
195
+ imagify_die( __( 'Invalid request', 'imagify' ) );
196
+ }
197
+
198
+ $context = imagify_sanitize_context( $_GET['context'] );
199
+ $attachment_id = absint( $_GET['attachment_id'] );
200
+
201
+ imagify_check_nonce( 'imagify-optimize-missing-sizes-' . $attachment_id . '-' . $context );
202
+ imagify_check_user_capacity( 'manual-optimize', $attachment_id );
203
+
204
+ $class_name = get_imagify_attachment_class_name( $context, $attachment_id, 'imagify_optimize_missing_sizes' );
205
+ $attachment = new $class_name( $attachment_id );
206
+
207
+ // Optimize the missing thumbnails.
208
+ $attachment->optimize_missing_thumbnails();
209
+
210
+ imagify_maybe_redirect();
211
+
212
+ // Return the optimization statistics.
213
+ $output = get_imagify_attachment_optimization_text( $attachment, $context );
214
+ wp_send_json_success( $output );
215
+ }
216
+
217
+ /**
218
+ * Process a restoration to the original attachment.
219
+ *
220
+ * @since 1.6.11
221
+ * @author Jonathan Buttigieg
222
+ */
223
+ public function imagify_restore_upload_callback() {
224
+ if ( empty( $_GET['attachment_id'] ) || empty( $_GET['context'] ) ) {
225
+ imagify_die( __( 'Invalid request', 'imagify' ) );
226
+ }
227
+
228
+ $context = imagify_sanitize_context( $_GET['context'] );
229
+ $attachment_id = absint( $_GET['attachment_id'] );
230
+
231
+ imagify_check_nonce( 'imagify-restore-upload-' . $attachment_id . '-' . $context );
232
+ imagify_check_user_capacity( 'manual-optimize', $attachment_id );
233
+
234
+ $class_name = get_imagify_attachment_class_name( $context, $attachment_id, 'imagify_restore_upload' );
235
+ $attachment = new $class_name( $attachment_id );
236
+
237
+ // Restore the backup file.
238
+ $attachment->restore();
239
+
240
+ imagify_maybe_redirect();
241
+
242
+ // Return the optimization button.
243
+ $output = get_imagify_admin_url( 'manual-upload', array( 'attachment_id' => $attachment->id, 'context' => $context ) );
244
+ $output = '<a id="imagify-upload-' . $attachment->id . '" href="' . esc_url( $output ) . '" class="button-primary button-imagify-manual-upload" data-waiting-label="' . esc_attr__( 'Optimizing...', 'imagify' ) . '">' . __( 'Optimize', 'imagify' ) . '</a>';
245
+ wp_send_json_success( $output );
246
+ }
247
+
248
+ /**
249
+ * Optimize all thumbnails of a specific image with the bulk method.
250
+ *
251
+ * @since 1.6.11
252
+ * @author Jonathan Buttigieg
253
+ */
254
+ public function imagify_bulk_upload_callback() {
255
+ if ( empty( $_POST['image'] ) || empty( $_POST['context'] ) ) {
256
+ imagify_die( __( 'Invalid request', 'imagify' ) );
257
+ }
258
+
259
+ $context = imagify_sanitize_context( $_POST['context'] );
260
+ $attachment_id = absint( $_POST['image'] );
261
+
262
+ imagify_check_nonce( 'imagify-bulk-upload', 'imagifybulkuploadnonce' );
263
+ imagify_check_user_capacity( 'bulk-optimize', $attachment_id );
264
+
265
+ $class_name = get_imagify_attachment_class_name( $context, $attachment_id, 'imagify_bulk_upload' );
266
+ $attachment = new $class_name( $attachment_id );
267
+ $optimization_level = get_transient( 'imagify_bulk_optimization_level' );
268
+
269
+ // Restore it if the optimization level is updated.
270
+ if ( $optimization_level !== $attachment->get_optimization_level() ) {
271
+ $attachment->restore();
272
+ }
273
+
274
+ // Optimize it!!!!!
275
+ $attachment->optimize( $optimization_level );
276
+
277
+ // Return the optimization statistics.
278
+ $fullsize_data = $attachment->get_size_data();
279
+ $stats_data = $attachment->get_stats_data();
280
+ $user = new Imagify_User();
281
+ $data = array();
282
+
283
+ if ( ! $attachment->is_optimized() ) {
284
+ $data['success'] = false;
285
+ $data['error'] = $fullsize_data['error'];
286
+
287
+ imagify_die( $data );
288
+ }
289
+
290
+ $data['success'] = true;
291
+ $data['original_size'] = $fullsize_data['original_size'];
292
+ $data['new_size'] = $fullsize_data['optimized_size'];
293
+ $data['percent'] = $fullsize_data['percent'];
294
+ $data['overall_saving'] = $stats_data['original_size'] - $stats_data['optimized_size'];
295
+ $data['original_overall_size'] = $stats_data['original_size'];
296
+ $data['new_overall_size'] = $stats_data['optimized_size'];
297
+ $data['thumbnails'] = $attachment->get_optimized_sizes_count();
298
+
299
+ wp_send_json_success( $data );
300
+ }
301
+
302
+
303
+ /** ----------------------------------------------------------------------------------------- */
304
+ /** AUTOMATIC OPTIMIZATION ================================================================== */
305
+ /** ----------------------------------------------------------------------------------------- */
306
+
307
+ /**
308
+ * Optimize image on picture uploading with async request.
309
+ *
310
+ * @since 1.6.11
311
+ * @author Julio Potier
312
+ * @see _imagify_optimize_attachment()
313
+ */
314
+ public function imagify_async_optimize_upload_new_media_callback() {
315
+ if ( empty( $_POST['_ajax_nonce'] ) || empty( $_POST['attachment_id'] ) || empty( $_POST['metadata'] ) || empty( $_POST['context'] ) ) { // WPCS: CSRF ok.
316
+ return;
317
+ }
318
+
319
+ $context = imagify_sanitize_context( $_POST['context'] );
320
+ $attachment_id = absint( $_POST['attachment_id'] );
321
+
322
+ imagify_check_nonce( 'new_media-' . $attachment_id );
323
+ imagify_check_user_capacity( 'auto-optimize' );
324
+
325
+ $class_name = get_imagify_attachment_class_name( $context, $attachment_id, 'imagify_async_optimize_upload_new_media' );
326
+ $attachment = new $class_name( $attachment_id );
327
+
328
+ // Optimize it!!!!!
329
+ $attachment->optimize( null, $_POST['metadata'] );
330
+ die( 1 );
331
+ }
332
+
333
+ /**
334
+ * Optimize image on picture editing (resize, crop...) with async request.
335
+ *
336
+ * @since 1.6.11
337
+ * @author Julio Potier
338
+ */
339
+ public function imagify_async_optimize_save_image_editor_file_callback() {
340
+ $attachment_id = ! empty( $_POST['postid'] ) ? absint( $_POST['postid'] ) : 0;
341
+
342
+ if ( ! $attachment_id || empty( $_POST['do'] ) ) {
343
+ return;
344
+ }
345
+
346
+ imagify_check_nonce( 'image_editor-' . $attachment_id );
347
+ imagify_check_user_capacity( 'edit_post', $attachment_id );
348
+
349
+ if ( ! get_post_meta( $attachment_id, '_imagify_data', true ) ) {
350
+ return;
351
+ }
352
+
353
+ $optimization_level = (int) get_post_meta( $attachment_id, '_imagify_optimization_level', true );
354
+ $class_name = get_imagify_attachment_class_name( 'wp', $attachment_id, 'wp_ajax_imagify_async_optimize_save_image_editor_file' );
355
+ $attachment = new $class_name( $attachment_id );
356
+ $metadata = wp_get_attachment_metadata( $attachment_id );
357
+
358
+ // Remove old optimization data.
359
+ $attachment->delete_imagify_data();
360
+
361
+ if ( 'restore' === $_POST['do'] ) {
362
+ // Restore the backup file.
363
+ $attachment->restore();
364
+
365
+ // Get old metadata to regenerate all thumbnails.
366
+ $metadata = array( 'sizes' => array() );
367
+ $backup_sizes = (array) get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true );
368
+
369
+ foreach ( $backup_sizes as $size_key => $size_data ) {
370
+ $size_key = str_replace( '-origin', '' , $size_key );
371
+ $metadata['sizes'][ $size_key ] = $size_data;
372
+ }
373
+ }
374
+
375
+ // Optimize it!!!!!
376
+ $attachment->optimize( $optimization_level, $metadata );
377
+ die( 1 );
378
+ }
379
+
380
+
381
+ /** ----------------------------------------------------------------------------------------- */
382
+ /** VARIOUS FOR OPTIMIZATION ================================================================ */
383
+ /** ----------------------------------------------------------------------------------------- */
384
+
385
+ /**
386
+ * Get all unoptimized attachment ids.
387
+ *
388
+ * @since 1.6.11
389
+ * @author Jonathan Buttigieg
390
+ */
391
+ public function imagify_get_unoptimized_attachment_ids_callback() {
392
+ global $wpdb;
393
+
394
+ imagify_check_nonce( 'imagify-bulk-upload', 'imagifybulkuploadnonce' );
395
+ imagify_check_user_capacity( 'bulk-optimize' );
396
+
397
+ if ( ! imagify_valid_key() ) {
398
+ wp_send_json_error( array( 'message' => 'invalid-api-key' ) );
399
+ }
400
+
401
+ $user = new Imagify_User();
402
+
403
+ if ( $user->is_over_quota() ) {
404
+ wp_send_json_error( array( 'message' => 'over-quota' ) );
405
+ }
406
+
407
+ @set_time_limit( 0 );
408
+
409
+ // Get (ordered) IDs.
410
+ $optimization_level = (int) $_GET['optimization_level'];
411
+ $optimization_level = ( -1 !== $optimization_level ) ? $optimization_level : (int) get_imagify_option( 'optimization_level', 1 );
412
+
413
+ /**
414
+ * Filter the unoptimized attachments limit query.
415
+ *
416
+ * @since 1.4.4
417
+ *
418
+ * @param int The limit (-1 for unlimited).
419
+ */
420
+ $unoptimized_attachment_limit = (int) apply_filters( 'imagify_unoptimized_attachment_limit', 10000 );
421
+ $unoptimized_attachment_limit = -1 === $unoptimized_attachment_limit ? PHP_INT_MAX : $unoptimized_attachment_limit;
422
+
423
+ $mime_types = get_imagify_mime_type();
424
+ $mime_types = esc_sql( $mime_types );
425
+ $mime_types = "'" . implode( "','", $mime_types ) . "'";
426
+
427
+ $ids = $wpdb->get_col( $wpdb->prepare( // WPCS: unprepared SQL ok.
428
+ "SELECT $wpdb->posts.ID
429
+ FROM $wpdb->posts
430
+ LEFT JOIN $wpdb->postmeta
431
+ ON ( $wpdb->posts.ID = $wpdb->postmeta.post_id AND $wpdb->postmeta.meta_key = '_imagify_optimization_level' )
432
+ LEFT JOIN $wpdb->postmeta AS mt1
433
+ ON ( $wpdb->posts.ID = mt1.post_id AND mt1.meta_key = '_imagify_status' )
434
+ WHERE
435
+ $wpdb->posts.post_mime_type IN ( $mime_types )
436
+ AND (
437
+ $wpdb->postmeta.meta_value != '%d'
438
+ OR
439
+ $wpdb->postmeta.post_id IS NULL
440
+ OR
441
+ mt1.meta_value = 'error'
442
+ )
443
+ AND $wpdb->posts.post_type = 'attachment'
444
+ AND $wpdb->posts.post_status <> 'trash'
445
+ AND $wpdb->posts.post_status <> 'auto-draft'
446
+ GROUP BY $wpdb->posts.ID
447
+ ORDER BY
448
+ CASE mt1.meta_value
449
+ WHEN 'already_optimized' THEN 2
450
+ ELSE 1
451
+ END ASC,
452
+ $wpdb->posts.ID DESC
453
+ LIMIT 0, %d",
454
+ $optimization_level,
455
+ $unoptimized_attachment_limit
456
+ ) );
457
+
458
+ $wpdb->flush();
459
+ unset( $unoptimized_attachment_limit, $mime_types );
460
+ $ids = array_filter( array_map( 'absint', $ids ) );
461
+
462
+ if ( ! $ids ) {
463
+ wp_send_json_error( array( 'message' => 'no-images' ) );
464
+ }
465
+
466
+ $results = imagify_get_wpdb_metas( array(
467
+ // Get attachments filename.
468
+ 'filenames' => '_wp_attached_file',
469
+ // Get attachments data.
470
+ 'data' => '_imagify_data',
471
+ // Get attachments optimization level.
472
+ 'optimization_levels' => '_imagify_optimization_level',
473
+ // Get attachments status.
474
+ 'statuses' => '_imagify_status',
475
+ ), $ids );
476
+
477
+ // Save the optimization level in a transient to retrieve it later during the process.
478
+ set_transient( 'imagify_bulk_optimization_level', $optimization_level );
479
+
480
+ // First run.
481
+ foreach ( $ids as $i => $id ) {
482
+ $attachment_status = isset( $results['statuses'][ $id ] ) ? $results['statuses'][ $id ] : false;
483
+ $attachment_optimization_level = isset( $results['optimization_levels'][ $id ] ) ? $results['optimization_levels'][ $id ] : false;
484
+ $attachment_error = '';
485
+
486
+ if ( isset( $results['data'][ $id ]['sizes']['full']['error'] ) ) {
487
+ $attachment_error = $results['data'][ $id ]['sizes']['full']['error'];
488
+ }
489
+
490
+ // Don't try to re-optimize if the optimization level is still the same.
491
+ if ( $optimization_level === $attachment_optimization_level && is_string( $attachment_error ) ) {
492
+ unset( $ids[ $i ] );
493
+ continue;
494
+ }
495
+
496
+ // Don't try to re-optimize images already compressed.
497
+ if ( 'already_optimized' === $attachment_status && $attachment_optimization_level >= $optimization_level ) {
498
+ unset( $ids[ $i ] );
499
+ continue;
500
+ }
501
+
502
+ $attachment_error = trim( $attachment_error );
503
+
504
+ // Don't try to re-optimize images with an empty error message.
505
+ if ( 'error' === $attachment_status && empty( $attachment_error ) ) {
506
+ unset( $ids[ $i ] );
507
+ }
508
+ }
509
+
510
+ if ( ! $ids ) {
511
+ wp_send_json_error( array( 'message' => 'no-images' ) );
512
+ }
513
+
514
+ $ids = array_values( $ids );
515
+
516
+ /**
517
+ * Triggered before testing for file existence.
518
+ *
519
+ * @since 1.6.7
520
+ * @author Grégory Viguier
521
+ *
522
+ * @param array $ids An array of attachment IDs.
523
+ * @param array $results An array of the data fetched from the database.
524
+ * @param int $optimization_level The optimization level that will be used for the optimization.
525
+ */
526
+ do_action( 'imagify_bulk_optimize_before_file_existence_tests', $ids, $results, $optimization_level );
527
+
528
+ $data = array();
529
+
530
+ foreach ( $ids as $i => $id ) {
531
+ $file_path = get_imagify_attached_file( $results['filenames'][ $id ] );
532
+
533
+ /** This filter is documented in inc/functions/process.php. */
534
+ $file_path = apply_filters( 'imagify_file_path', $file_path );
535
+
536
+ if ( ! $file_path || ! file_exists( $file_path ) ) {
537
+ continue;
538
+ }
539
+
540
+ $attachment_backup_path = get_imagify_attachment_backup_path( $file_path );
541
+ $attachment_status = isset( $results['statuses'][ $id ] ) ? $results['statuses'][ $id ] : false;
542
+ $attachment_optimization_level = isset( $results['optimization_levels'][ $id ] ) ? $results['optimization_levels'][ $id ] : false;
543
+
544
+ // Don't try to re-optimize if there is no backup file.
545
+ if ( 'success' === $attachment_status && $optimization_level !== $attachment_optimization_level && ! file_exists( $attachment_backup_path ) ) {
546
+ continue;
547
+ }
548
+
549
+ $data[ '_' . $id ] = get_imagify_attachment_url( $results['filenames'][ $id ] );
550
+ } // End foreach().
551
+
552
+ if ( ! $data ) {
553
+ wp_send_json_error( array( 'message' => 'no-images' ) );
554
+ }
555
+
556
+ wp_send_json_success( $data );
557
+ }
558
+
559
+ /**
560
+ * Check if the backup directory is writable.
561
+ * This is used to display an error message in the plugin's settings page.
562
+ *
563
+ * @since 1.6.11
564
+ * @author Grégory Viguier
565
+ */
566
+ public function imagify_check_backup_dir_is_writable_callback() {
567
+ imagify_check_nonce( 'imagify_check_backup_dir_is_writable' );
568
+ imagify_check_user_capacity();
569
+
570
+ wp_send_json_success( array(
571
+ 'is_writable' => (int) imagify_backup_dir_is_writable(),
572
+ ) );
573
+ }
574
+
575
+ /**
576
+ * Bridge between XML-RPC and actions triggered by imagify_do_async_job().
577
+ * When XML-RPC is used, a current user is set, but no cookies are set, so they cannot be sent with the request. Instead we stored the user ID in a transient.
578
+ *
579
+ * @since 1.6.11
580
+ * @author Grégory Viguier
581
+ * @see imagify_do_async_job()
582
+ */
583
+ public function nopriv_imagify_rpc_callback() {
584
+ if ( empty( $_POST['imagify_rpc_action'] ) || empty( $_POST['imagify_rpc_id'] ) || 32 !== strlen( $_POST['imagify_rpc_id'] ) ) { // WPCS: CSRF ok.
585
+ imagify_die( __( 'Invalid request', 'imagify' ) );
586
+ }
587
+
588
+ // Not necessary but just in case, whitelist the original action.
589
+ $action = $_POST['imagify_rpc_action']; // WPCS: CSRF ok.
590
+ $actions = array_flip( $this->ajax_only_actions );
591
+ unset( $actions['nopriv_imagify_rpc'] );
592
+
593
+ if ( ! isset( $actions[ $action ] ) ) {
594
+ imagify_die( __( 'Invalid request', 'imagify' ) );
595
+ }
596
+
597
+ // Get the user ID.
598
+ $rpc_id = sanitize_key( $_POST['imagify_rpc_id'] );
599
+ $user_id = absint( get_transient( 'imagify_rpc_' . $rpc_id ) );
600
+ $user = $user_id ? get_userdata( $user_id ) : false;
601
+
602
+ delete_transient( 'imagify_rpc_' . $rpc_id );
603
+
604
+ if ( ! $user || ! $user->exists() ) {
605
+ imagify_die( __( 'Invalid request', 'imagify' ) );
606
+ }
607
+
608
+ // The current user must be set before verifying the nonce.
609
+ wp_set_current_user( $user_id );
610
+
611
+ imagify_check_nonce( 'imagify_rpc_' . $rpc_id, 'imagify_rpc_nonce' );
612
+
613
+ // Trigger the action we originally wanted.
614
+ $_POST['action'] = $action;
615
+ unset( $_POST['imagify_rpc_action'], $_POST['imagify_rpc_id'], $_POST['imagify_rpc_nonce'] );
616
+
617
+ /** This hook is documented in wp-admin/admin-ajax.php. */
618
+ do_action( 'wp_ajax_' . $_POST['action'] );
619
+ }
620
+
621
+
622
+ /** ----------------------------------------------------------------------------------------- */
623
+ /** IMAGIFY ACCOUNT ========================================================================= */
624
+ /** ----------------------------------------------------------------------------------------- */
625
+
626
+ /**
627
+ * Create a new Imagify account.
628
+ *
629
+ * @since 1.6.11
630
+ * @author Jonathan Buttigieg
631
+ */
632
+ public function imagify_signup_callback() {
633
+ imagify_check_nonce( 'imagify-signup', 'imagifysignupnonce' );
634
+ imagify_check_user_capacity();
635
+
636
+ if ( empty( $_GET['email'] ) ) {
637
+ imagify_die( __( 'Empty email address.', 'imagify' ) );
638
+ }
639
+
640
+ if ( ! is_email( $_GET['email'] ) ) {
641
+ imagify_die( __( 'Not a valid email address.', 'imagify' ) );
642
+ }
643
+
644
+ $data = array(
645
+ 'email' => $_GET['email'],
646
+ 'password' => wp_generate_password( 12, false ),
647
+ 'lang' => get_locale(),
648
+ );
649
+
650
+ $response = add_imagify_user( $data );
651
+
652
+ if ( is_wp_error( $response ) ) {
653
+ imagify_die( $response );
654
+ }
655
+
656
+ wp_send_json_success();
657
+ }
658
+
659
+ /**
660
+ * Check the API key validity.
661
+ *
662
+ * @since 1.6.11
663
+ * @author Jonathan Buttigieg
664
+ */
665
+ public function imagify_check_api_key_validity_callback() {
666
+ imagify_check_nonce( 'imagify-check-api-key', 'imagifycheckapikeynonce' );
667
+ imagify_check_user_capacity();
668
+
669
+ if ( empty( $_GET['api_key'] ) ) {
670
+ imagify_die( __( 'Empty API key.', 'imagify' ) );
671
+ }
672
+
673
+ $response = get_imagify_status( $_GET['api_key'] );
674
+
675
+ if ( is_wp_error( $response ) ) {
676
+ imagify_die( $response );
677
+ }
678
+
679
+ $options = get_site_option( IMAGIFY_SETTINGS_SLUG );
680
+ $options['api_key'] = sanitize_key( $_GET['api_key'] );
681
+
682
+ update_site_option( IMAGIFY_SETTINGS_SLUG, $options );
683
+
684
+ wp_send_json_success();
685
+ }
686
+
687
+ /**
688
+ * Get admin bar profile output.
689
+ *
690
+ * @since 1.6.11
691
+ * @author Jonathan Buttigieg
692
+ */
693
+ public function imagify_get_admin_bar_profile_callback() {
694
+ imagify_check_nonce( 'imagify-get-admin-bar-profile', 'imagifygetadminbarprofilenonce' );
695
+ imagify_check_user_capacity();
696
+
697
+ $user = new Imagify_User();
698
+ $unconsumed_quota = $user->get_percent_unconsumed_quota();
699
+ $meteo_icon = '<img src="' . IMAGIFY_ASSETS_IMG_URL . 'sun.svg" width="37" height="38" alt="" />';
700
+ $bar_class = 'positive';
701
+ $message = '';
702
+
703
+ if ( $unconsumed_quota >= 21 && $unconsumed_quota <= 50 ) {
704
+ $bar_class = 'neutral';
705
+ $meteo_icon = '<img src="' . IMAGIFY_ASSETS_IMG_URL . 'cloudy-sun.svg" width="37" height="38" alt="" />';
706
+ }
707
+ elseif ( $unconsumed_quota <= 20 ) {
708
+ $bar_class = 'negative';
709
+ $meteo_icon = '<img src="' . IMAGIFY_ASSETS_IMG_URL . 'stormy.svg" width="38" height="36" alt="" />';
710
+ }
711
+
712
+ if ( $unconsumed_quota <= 20 && $unconsumed_quota > 0 ) {
713
+ $message = '<div class="imagify-error">';
714
+ $message .= '<p><i class="dashicons dashicons-warning" aria-hidden="true"></i><strong>' . __( 'Oops, It\'s almost over!', 'imagify' ) . '</strong></p>';
715
+ /* translators: %s is a line break. */
716
+ $message .= '<p>' . sprintf( __( 'You have almost used all your credit.%sDon\'t forget to upgrade your subscription to continue optimizing your images.', 'imagify' ), '<br/><br/>' ) . '</p>';
717
+ $message .= '<p class="center txt-center text-center"><a class="btn imagify-btn-ghost" href="' . IMAGIFY_APP_MAIN . '/#/subscription" target="_blank">' . __( 'View My Subscription', 'imagify' ) . '</a></p>';
718
+ $message .= '</div>';
719
+ }
720
+
721
+ if ( 0 === $unconsumed_quota ) {
722
+ $message = '<div class="imagify-error">';
723
+ $message .= '<p><i class="dashicons dashicons-warning" aria-hidden="true"></i><strong>' . __( 'Oops, It\'s Over!', 'imagify' ) . '</strong></p>';
724
+ $message .= '<p>' . sprintf(
725
+ /* translators: 1 is a data quota, 2 is a date. */
726
+ __( 'You have consumed all your credit for this month. You will have <strong>%1$s back on %2$s</strong>.', 'imagify' ),
727
+ size_format( $user->quota * 1048576 ),
728
+ date_i18n( get_option( 'date_format' ), strtotime( $user->next_date_update ) )
729
+ ) . '</p>';
730
+ $message .= '<p class="center txt-center text-center"><a class="btn imagify-btn-ghost" href="' . IMAGIFY_APP_MAIN . '/#/subscription" target="_blank">' . __( 'Upgrade My Subscription', 'imagify' ) . '</a></p>';
731
+ $message .= '</div>';
732
+ }
733
+
734
+ // Custom HTML.
735
+ $quota_section = '<div class="imagify-admin-bar-quota">';
736
+ $quota_section .= '<div class="imagify-abq-row">';
737
+
738
+ if ( 1 === $user->plan_id ) {
739
+ $quota_section .= '<div class="imagify-meteo-icon">' . $meteo_icon . '</div>';
740
+ }
741
+
742
+ $quota_section .= '<div class="imagify-account">';
743
+ $quota_section .= '<p class="imagify-meteo-title">' . __( 'Account status', 'imagify' ) . '</p>';
744
+ $quota_section .= '<p class="imagify-meteo-subs">' . __( 'Your subscription:', 'imagify' ) . '&nbsp;<strong class="imagify-user-plan">' . $user->plan_label . '</strong></p>';
745
+ $quota_section .= '</div>'; // .imagify-account
746
+ $quota_section .= '</div>'; // .imagify-abq-row
747
+
748
+ if ( 1 === $user->plan_id ) {
749
+ $quota_section .= '<div class="imagify-abq-row">';
750
+ $quota_section .= '<div class="imagify-space-left">';
751
+ /* translators: %s is a data quota. */
752
+ $quota_section .= '<p>' . sprintf( __( 'You have %s space credit left', 'imagify' ), '<span class="imagify-unconsumed-percent">' . $unconsumed_quota . '%</span>' ) . '</p>';
753
+ $quota_section .= '<div class="imagify-bar-' . $bar_class . '">';
754
+ $quota_section .= '<div style="width: ' . $unconsumed_quota . '%;" class="imagify-unconsumed-bar imagify-progress"></div>';
755
+ $quota_section .= '</div>'; // .imagify-bar-{$bar_class}
756
+ $quota_section .= '</div>'; // .imagify-space-left
757
+ $quota_section .= '</div>'; // .imagify-abq-row
758
+ }
759
+
760
+ $quota_section .= '<p class="imagify-abq-row">';
761
+ $quota_section .= '<a class="imagify-account-link" href="' . IMAGIFY_APP_MAIN . '/#/subscription" target="_blank">';
762
+ $quota_section .= '<span class="dashicons dashicons-admin-users"></span>';
763
+ $quota_section .= '<span class="button-text">' . __( 'View my subscription', 'imagify' ) . '</span>';
764
+ $quota_section .= '</a>'; // .imagify-account-link
765
+ $quota_section .= '</p>'; // .imagify-abq-row
766
+ $quota_section .= '</div>'; // .imagify-admin-bar-quota
767
+ $quota_section .= $message;
768
+
769
+ wp_send_json_success( $quota_section );
770
+ }
771
+
772
+ /**
773
+ * Get pricings from API for Onetime and Plans at the same time.
774
+ *
775
+ * @since 1.6.11
776
+ * @author Geoffrey Crofte
777
+ */
778
+ public function imagify_get_prices_callback() {
779
+ imagify_check_nonce( 'imagify_get_pricing_' . get_current_user_id(), 'imagifynonce' );
780
+ imagify_check_user_capacity();
781
+
782
+ $prices_all = get_imagify_all_prices();
783
+
784
+ if ( is_wp_error( $prices_all ) ) {
785
+ imagify_die( $prices_all );
786
+ }
787
+
788
+ if ( ! is_object( $prices_all ) ) {
789
+ imagify_die( __( 'Wrongly formatted response from our server.', 'imagify' ) );
790
+ }
791
+
792
+ wp_send_json_success( array(
793
+ 'onetimes' => $prices_all->Packs,
794
+ 'monthlies' => $prices_all->Plans,
795
+ ) );
796
+ }
797
+
798
+ /**
799
+ * Check Coupon code on modal popin.
800
+ *
801
+ * @since 1.6.11
802
+ * @author Geoffrey Crofte
803
+ */
804
+ public function imagify_check_coupon_callback() {
805
+ imagify_check_nonce( 'imagify_get_pricing_' . get_current_user_id(), 'imagifynonce' );
806
+ imagify_check_user_capacity();
807
+
808
+ if ( empty( $_POST['coupon'] ) ) {
809
+ wp_send_json_success( array(
810
+ 'success' => false,
811
+ 'detail' => __( 'Coupon is empty.', 'imagify' ),
812
+ ) );
813
+ }
814
+
815
+ $coupon = check_imagify_coupon_code( $_POST['coupon'] );
816
+
817
+ if ( is_wp_error( $coupon ) ) {
818
+ imagify_die( $coupon );
819
+ }
820
+
821
+ wp_send_json_success( imagify_translate_api_message( $coupon ) );
822
+ }
823
+
824
+ /**
825
+ * Get current discount promotion to display information on payment modal.
826
+ *
827
+ * @since 1.6.11
828
+ * @author Geoffrey Crofte
829
+ */
830
+ public function imagify_get_discount_callback() {
831
+ imagify_check_nonce( 'imagify_get_pricing_' . get_current_user_id(), 'imagifynonce' );
832
+ imagify_check_user_capacity();
833
+
834
+ wp_send_json_success( imagify_translate_api_message( check_imagify_discount() ) );
835
+ }
836
+
837
+ /**
838
+ * Get estimated sizes from the WordPress library.
839
+ *
840
+ * @since 1.6.11
841
+ * @author Geoffrey Crofte
842
+ */
843
+ public function imagify_get_images_counts_callback() {
844
+ imagify_check_nonce( 'imagify_get_pricing_' . get_current_user_id(), 'imagifynonce' );
845
+ imagify_check_user_capacity();
846
+
847
+ $raw_total_size_in_library = imagify_calculate_total_size_images_library();
848
+ $raw_average_per_month = imagify_calculate_average_size_images_per_month();
849
+ update_imagify_option( 'total_size_images_library', array( 'raw' => $raw_total_size_in_library, 'human' => size_format( $raw_total_size_in_library ) ) );
850
+ update_imagify_option( 'average_size_images_per_month', array( 'raw' => $raw_average_per_month, 'human' => size_format( $raw_average_per_month ) ) );
851
+
852
+ wp_send_json_success( array(
853
+ 'total_library_size' => get_imagify_option( 'total_size_images_library', null ),
854
+ 'average_month_size' => get_imagify_option( 'average_size_images_per_month', null ),
855
+ ) );
856
+ }
857
+
858
+ /**
859
+ * Estimate sizes and update the options values for them.
860
+ *
861
+ * @since 1.6.11
862
+ * @author Remy Perona
863
+ */
864
+ public function imagify_update_estimate_sizes_callback() {
865
+ imagify_check_nonce( 'update_estimate_sizes' );
866
+ imagify_check_user_capacity();
867
+
868
+ $raw_total_size_in_library = imagify_calculate_total_size_images_library();
869
+ $raw_average_per_month = imagify_calculate_average_size_images_per_month();
870
+
871
+ update_imagify_option( 'total_size_images_library', array( 'raw' => $raw_total_size_in_library, 'human' => size_format( $raw_total_size_in_library ) ) );
872
+ update_imagify_option( 'average_size_images_per_month', array( 'raw' => $raw_average_per_month, 'human' => size_format( $raw_average_per_month ) ) );
873
+
874
+ die( 1 );
875
+ }
876
+ }
inc/classes/class-imagify-assets.php CHANGED
@@ -507,6 +507,8 @@ class Imagify_Assets {
507
  $this->current_handle = $handle;
508
  $this->current_handle_type = 'js';
509
 
 
 
510
  if ( ! empty( $this->scripts[ $handle ] ) ) {
511
  // If we registered it, it's one of our scripts.
512
  $handle = self::JS_PREFIX . $handle;
@@ -771,6 +773,41 @@ class Imagify_Assets {
771
  return $depts;
772
  }
773
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
774
  /**
775
  * Tell if debug is on.
776
  *
@@ -798,6 +835,6 @@ class Imagify_Assets {
798
 
799
  $has_api_key = ( defined( 'IMAGIFY_API_KEY' ) && IMAGIFY_API_KEY ) || get_imagify_option( 'api_key' );
800
 
801
- return $has_api_key && is_admin_bar_showing() && current_user_can( imagify_get_capacity() ) && get_imagify_option( 'admin_bar_menu' );
802
  }
803
  }
507
  $this->current_handle = $handle;
508
  $this->current_handle_type = 'js';
509
 
510
+ $this->maybe_register_heartbeat( $handle );
511
+
512
  if ( ! empty( $this->scripts[ $handle ] ) ) {
513
  // If we registered it, it's one of our scripts.
514
  $handle = self::JS_PREFIX . $handle;
773
  return $depts;
774
  }
775
 
776
+ /**
777
+ * Make sure Heartbeat is registered if the given script requires it.
778
+ * Lots of people love deregister Heartbeat.
779
+ *
780
+ * @since 1.6.11
781
+ * @author Grégory Viguier
782
+ *
783
+ * @param string $handle Name of the script. Should be unique.
784
+ */
785
+ protected function maybe_register_heartbeat( $handle ) {
786
+ if ( wp_script_is( 'heartbeat', 'registered' ) ) {
787
+ return;
788
+ }
789
+
790
+ if ( ! empty( $this->scripts[ $handle ] ) ) {
791
+ // If we registered it, it's one of our scripts.
792
+ $handle = self::JS_PREFIX . $handle;
793
+ }
794
+
795
+ $dependencies = wp_scripts()->query( $handle );
796
+
797
+ if ( ! $dependencies || ! $dependencies->deps ) {
798
+ return;
799
+ }
800
+
801
+ $dependencies = array_flip( $dependencies->deps );
802
+
803
+ if ( ! isset( $dependencies['heartbeat'] ) ) {
804
+ return;
805
+ }
806
+
807
+ $suffix = SCRIPT_DEBUG ? '' : '.min';
808
+ wp_register_script( 'heartbeat', "/wp-includes/js/heartbeat$suffix.js", array( 'jquery' ), false, true );
809
+ }
810
+
811
  /**
812
  * Tell if debug is on.
813
  *
835
 
836
  $has_api_key = ( defined( 'IMAGIFY_API_KEY' ) && IMAGIFY_API_KEY ) || get_imagify_option( 'api_key' );
837
 
838
+ return $has_api_key && is_admin_bar_showing() && imagify_current_user_can() && get_imagify_option( 'admin_bar_menu' );
839
  }
840
  }
inc/classes/class-imagify-attachment.php CHANGED
File without changes
inc/classes/class-imagify-notices.php CHANGED
@@ -74,15 +74,15 @@ class Imagify_Notices {
74
 
75
  /**
76
  * List of user capabilities to use for each notice.
77
- * Default value is not listed.
78
  *
79
  * @var array
80
  */
81
  protected static $capabilities = array(
82
- 'grid-view' => 'upload',
83
- 'backup-folder-not-writable' => 'admin',
84
- 'rating' => 'admin',
85
- 'wp-rocket' => 'admin',
86
  );
87
 
88
  /**
@@ -712,6 +712,7 @@ class Imagify_Notices {
712
 
713
  /**
714
  * Tell if the current user can see the notices.
 
715
  *
716
  * @since 1.6.10
717
  * @author Grégory Viguier
@@ -720,19 +721,9 @@ class Imagify_Notices {
720
  * @return bool
721
  */
722
  protected function user_can( $notice_id ) {
723
- static $user_can;
724
 
725
- if ( ! isset( $user_can ) ) {
726
- $user_can = array(
727
- 'network' => current_user_can( imagify_get_capacity() ),
728
- 'admin' => current_user_can( imagify_get_capacity( true ) ),
729
- 'upload' => current_user_can( 'upload_files' ),
730
- );
731
- }
732
-
733
- $capability = isset( self::$capabilities[ $notice_id ] ) ? self::$capabilities[ $notice_id ] : 'network';
734
-
735
- return isset( $user_can[ $capability ] ) ? $user_can[ $capability ] : $user_can['network'];
736
  }
737
 
738
  /**
74
 
75
  /**
76
  * List of user capabilities to use for each notice.
77
+ * Default value 'manage' is not listed.
78
  *
79
  * @var array
80
  */
81
  protected static $capabilities = array(
82
+ 'grid-view' => 'optimize',
83
+ 'backup-folder-not-writable' => 'bulk-optimize',
84
+ 'rating' => 'bulk-optimize',
85
+ 'wp-rocket' => 'bulk-optimize',
86
  );
87
 
88
  /**
712
 
713
  /**
714
  * Tell if the current user can see the notices.
715
+ * Notice IDs that are not listed in self::$capabilities are assumed as 'manage'.
716
  *
717
  * @since 1.6.10
718
  * @author Grégory Viguier
721
  * @return bool
722
  */
723
  protected function user_can( $notice_id ) {
724
+ $capability = isset( self::$capabilities[ $notice_id ] ) ? self::$capabilities[ $notice_id ] : 'manage';
725
 
726
+ return imagify_current_user_can( $capability );
 
 
 
 
 
 
 
 
 
 
727
  }
728
 
729
  /**
inc/classes/class-imagify.php CHANGED
File without changes
inc/common/admin-bar.php CHANGED
@@ -10,7 +10,7 @@ add_action( 'admin_bar_menu', '_imagify_admin_bar', IMAGIFY_INT_MAX );
10
  * @param object $wp_admin_bar WP_Admin_Bar instance, passed by reference.
11
  */
12
  function _imagify_admin_bar( $wp_admin_bar ) {
13
- if ( ! current_user_can( imagify_get_capacity() ) || ! get_imagify_option( 'admin_bar_menu' ) ) {
14
  return;
15
  }
16
 
10
  * @param object $wp_admin_bar WP_Admin_Bar instance, passed by reference.
11
  */
12
  function _imagify_admin_bar( $wp_admin_bar ) {
13
+ if ( ! imagify_current_user_can() || ! get_imagify_option( 'admin_bar_menu' ) ) {
14
  return;
15
  }
16
 
inc/common/attachments.php CHANGED
@@ -7,7 +7,7 @@ add_filter( 'wp_generate_attachment_metadata', '_imagify_optimize_attachment', I
7
  *
8
  * @since 1.0
9
  * @since 1.5 Async job.
10
- * @see _do_admin_post_async_optimize_upload_new_media()
11
  *
12
  * @param array $metadata An array of attachment meta data.
13
  * @param int $attachment_id Current attachment ID.
@@ -15,7 +15,7 @@ add_filter( 'wp_generate_attachment_metadata', '_imagify_optimize_attachment', I
15
  */
16
  function _imagify_optimize_attachment( $metadata, $attachment_id ) {
17
 
18
- if ( ! get_imagify_option( 'api_key' ) || ! get_imagify_option( 'auto_optimize' ) ) {
19
  return $metadata;
20
  }
21
 
@@ -54,9 +54,15 @@ function _imagify_optimize_save_image_editor_file() {
54
  return;
55
  }
56
 
57
- check_ajax_referer( 'image_editor-' . $_POST['postid'] );
58
 
59
- if ( ! get_post_meta( $_POST['postid'], '_imagify_data', true ) ) {
 
 
 
 
 
 
60
  return;
61
  }
62
 
7
  *
8
  * @since 1.0
9
  * @since 1.5 Async job.
10
+ * @see Imagify_Admin_Ajax_Post::imagify_async_optimize_upload_new_media_callback()
11
  *
12
  * @param array $metadata An array of attachment meta data.
13
  * @param int $attachment_id Current attachment ID.
15
  */
16
  function _imagify_optimize_attachment( $metadata, $attachment_id ) {
17
 
18
+ if ( ! imagify_valid_key() || ! get_imagify_option( 'auto_optimize' ) ) {
19
  return $metadata;
20
  }
21
 
54
  return;
55
  }
56
 
57
+ $attachment_id = absint( $_POST['postid'] );
58
 
59
+ if ( ! $attachment_id || ! imagify_valid_key() ) {
60
+ return;
61
+ }
62
+
63
+ check_ajax_referer( 'image_editor-' . $attachment_id );
64
+
65
+ if ( ! get_post_meta( $attachment_id, '_imagify_data', true ) ) {
66
  return;
67
  }
68
 
inc/functions/admin-ui.php CHANGED
@@ -285,6 +285,10 @@ function get_imagify_media_column_content( $attachment, $context = 'wp' ) {
285
  $attachment_id = $attachment->id;
286
  $attachment_ext = $attachment->get_extension();
287
 
 
 
 
 
288
  // Check if the attachment extension is allowed.
289
  if ( ! $attachment->is_mime_type_supported() ) {
290
  /* translators: %s is a file extension. */
@@ -335,7 +339,7 @@ function get_imagify_media_column_content( $attachment, $context = 'wp' ) {
335
  * @return string HTML.
336
  */
337
  function get_imagify_new_to_imagify() {
338
- if ( ! current_user_can( imagify_get_capacity() ) || ! imagify_valid_key() ) {
339
  return '';
340
  }
341
 
285
  $attachment_id = $attachment->id;
286
  $attachment_ext = $attachment->get_extension();
287
 
288
+ if ( ! imagify_current_user_can( 'manual-optimize', $attachment_id ) ) {
289
+ return __( 'You are not allowed to optimize this file.', 'imagify' );
290
+ }
291
+
292
  // Check if the attachment extension is allowed.
293
  if ( ! $attachment->is_mime_type_supported() ) {
294
  /* translators: %s is a file extension. */
339
  * @return string HTML.
340
  */
341
  function get_imagify_new_to_imagify() {
342
+ if ( ! imagify_current_user_can() || ! imagify_valid_key() ) {
343
  return '';
344
  }
345
 
inc/functions/admin.php CHANGED
@@ -109,16 +109,16 @@ function get_imagify_admin_url( $action = 'options-general', $arg = array() ) {
109
 
110
  switch ( $action ) {
111
  case 'manual-override-upload':
112
- return wp_nonce_url( admin_url( 'admin-post.php?action=imagify_manual_override_upload&attachment_id=' . $id . '&optimization_level=' . $level . '&context=' . $context ), 'imagify-manual-override-upload' );
113
 
114
  case 'optimize-missing-sizes':
115
- return wp_nonce_url( admin_url( 'admin-post.php?action=imagify_optimize_missing_sizes&attachment_id=' . $id . '&context=' . $context ), 'imagify-optimize-missing-sizes' );
116
 
117
  case 'manual-upload':
118
- return wp_nonce_url( admin_url( 'admin-post.php?action=imagify_manual_upload&attachment_id=' . $id . '&context=' . $context ), 'imagify-manual-upload' );
119
 
120
  case 'restore-upload':
121
- return wp_nonce_url( admin_url( 'admin-post.php?action=imagify_restore_upload&attachment_id=' . $id . '&context=' . $context ), 'imagify-restore-upload' );
122
 
123
  case 'dismiss-notice':
124
  return wp_nonce_url( admin_url( 'admin-post.php?action=imagify_dismiss_notice&notice=' . $arg ), Imagify_Notices::DISMISS_NONCE_ACTION );
@@ -354,17 +354,15 @@ function imagify_check_nonce( $action, $query_arg = false ) {
354
  * Check for user capacity.
355
  *
356
  * @since 1.6.10
 
357
  * @author Grégory Viguier
 
358
  *
359
- * @param string $capacity A user capacity.
360
- * @param int $post_id A post ID.
361
  */
362
- function imagify_check_user_capacity( $capacity = null, $post_id = null ) {
363
- if ( ! isset( $capacity ) ) {
364
- $capacity = imagify_get_capacity();
365
- }
366
-
367
- if ( ! current_user_can( $capacity, $post_id ) ) {
368
  imagify_die();
369
  }
370
  }
@@ -393,7 +391,7 @@ function imagify_die( $message = null ) {
393
  }
394
  }
395
 
396
- if ( defined( 'DOING_AJAX' ) ) {
397
  wp_send_json_error( $message );
398
  }
399
 
109
 
110
  switch ( $action ) {
111
  case 'manual-override-upload':
112
+ return wp_nonce_url( admin_url( 'admin-post.php?action=imagify_manual_override_upload&attachment_id=' . $id . '&optimization_level=' . $level . '&context=' . $context ), 'imagify-manual-override-upload-' . $id . '-' . $context );
113
 
114
  case 'optimize-missing-sizes':
115
+ return wp_nonce_url( admin_url( 'admin-post.php?action=imagify_optimize_missing_sizes&attachment_id=' . $id . '&context=' . $context ), 'imagify-optimize-missing-sizes-' . $id . '-' . $context );
116
 
117
  case 'manual-upload':
118
+ return wp_nonce_url( admin_url( 'admin-post.php?action=imagify_manual_upload&attachment_id=' . $id . '&context=' . $context ), 'imagify-manual-upload-' . $id . '-' . $context );
119
 
120
  case 'restore-upload':
121
+ return wp_nonce_url( admin_url( 'admin-post.php?action=imagify_restore_upload&attachment_id=' . $id . '&context=' . $context ), 'imagify-restore-upload-' . $id . '-' . $context );
122
 
123
  case 'dismiss-notice':
124
  return wp_nonce_url( admin_url( 'admin-post.php?action=imagify_dismiss_notice&notice=' . $arg ), Imagify_Notices::DISMISS_NONCE_ACTION );
354
  * Check for user capacity.
355
  *
356
  * @since 1.6.10
357
+ * @since 1.6.11 Uses a capacity describer instead of a capacity itself.
358
  * @author Grégory Viguier
359
+ * @see imagify_get_capacity()
360
  *
361
+ * @param string $describer Capacity describer. Possible values are 'manage', 'bulk-optimize', 'manual-optimize', and 'auto-optimize'. Can also be a "real" user capacity.
362
+ * @param int $post_id A post ID.
363
  */
364
+ function imagify_check_user_capacity( $describer = 'manage', $post_id = null ) {
365
+ if ( ! imagify_current_user_can( $describer, $post_id ) ) {
 
 
 
 
366
  imagify_die();
367
  }
368
  }
391
  }
392
  }
393
 
394
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
395
  wp_send_json_error( $message );
396
  }
397
 
inc/functions/api.php CHANGED
@@ -272,6 +272,7 @@ function imagify_translate_api_message( $message ) {
272
  'WELL DONE. This image is already compressed, no further compression required' => __( 'WELL DONE. This image is already optimized, no further optimization is required.', 'imagify' ),
273
  'You are not authorized to perform this action' => __( 'You are not authorized to perform this action.', 'imagify' ),
274
  'You\'ve consumed all your data. You have to upgrade your account to continue' => __( 'You have consumed all your data. You have to upgrade your account to continue.', 'imagify' ),
 
275
  );
276
 
277
  if ( isset( $messages[ $trim_message ] ) ) {
272
  'WELL DONE. This image is already compressed, no further compression required' => __( 'WELL DONE. This image is already optimized, no further optimization is required.', 'imagify' ),
273
  'You are not authorized to perform this action' => __( 'You are not authorized to perform this action.', 'imagify' ),
274
  'You\'ve consumed all your data. You have to upgrade your account to continue' => __( 'You have consumed all your data. You have to upgrade your account to continue.', 'imagify' ),
275
+ 'Invalid token' => __( 'Invalid API key', 'imagify' ),
276
  );
277
 
278
  if ( isset( $messages[ $trim_message ] ) ) {
inc/functions/common.php CHANGED
@@ -5,26 +5,122 @@ defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
5
  * Get user capacity to operate Imagify.
6
  *
7
  * @since 1.6.5
 
8
  * @author Grégory Viguier
9
  *
10
- * @param bool $force_mono Force capacity for mono-site.
11
  * @return string
12
  */
13
- function imagify_get_capacity( $force_mono = false ) {
14
- if ( $force_mono || ! is_multisite() ) {
15
- $capacity = 'manage_options';
16
- } else {
17
- $capacity = imagify_is_active_for_network() ? 'manage_network_options' : 'manage_options';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  }
19
 
20
  /**
21
  * Filter the user capacity used to operate Imagify.
22
  *
23
  * @since 1.0
24
- * @since 1.6.5 Added $force_mono parameter.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  *
26
- * @param string $capacity The user capacity.
27
- * @param bool $force_mono Force capacity for mono-site.
 
 
 
 
28
  */
29
- return apply_filters( 'imagify_capacity', $capacity, $force_mono );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  }
5
  * Get user capacity to operate Imagify.
6
  *
7
  * @since 1.6.5
8
+ * @since 1.6.11 Uses a string as describer for the first argument.
9
  * @author Grégory Viguier
10
  *
11
+ * @param string $describer Capacity describer. Possible values are 'manage', 'bulk-optimize', 'manual-optimize', and 'auto-optimize'.
12
  * @return string
13
  */
14
+ function imagify_get_capacity( $describer = 'manage' ) {
15
+ static $edit_attachment_cap;
16
+
17
+ // Back compat.
18
+ if ( ! is_string( $describer ) ) {
19
+ if ( $describer || ! is_multisite() ) {
20
+ $describer = 'bulk-optimize';
21
+ } else {
22
+ $describer = 'manage';
23
+ }
24
+ }
25
+
26
+ switch ( $describer ) {
27
+ case 'manage':
28
+ $capacity = imagify_is_active_for_network() ? 'manage_network_options' : 'manage_options';
29
+ break;
30
+ case 'bulk-optimize':
31
+ $capacity = 'manage_options';
32
+ break;
33
+ case 'optimize':
34
+ // This is a generic capacity: don't use it unless you have no other choices!
35
+ if ( ! isset( $edit_attachment_cap ) ) {
36
+ $edit_attachment_cap = get_post_type_object( 'attachment' );
37
+ $edit_attachment_cap = $edit_attachment_cap ? $edit_attachment_cap->cap->edit_posts : 'edit_posts';
38
+ }
39
+
40
+ $capacity = $edit_attachment_cap;
41
+ break;
42
+ case 'manual-optimize':
43
+ // Must be used with an Attachment ID.
44
+ $capacity = 'edit_post';
45
+ break;
46
+ case 'auto-optimize':
47
+ $capacity = 'upload_files';
48
+ break;
49
+ default:
50
+ $capacity = $describer;
51
  }
52
 
53
  /**
54
  * Filter the user capacity used to operate Imagify.
55
  *
56
  * @since 1.0
57
+ * @since 1.6.5 Added $force_mono parameter.
58
+ * @since 1.6.11 Replaced $force_mono by $describer.
59
+ *
60
+ * @param string $capacity The user capacity.
61
+ * @param string $describer Capacity describer. Possible values are 'manage', 'bulk-optimize', 'manual-optimize', and 'auto-optimize'.
62
+ */
63
+ return apply_filters( 'imagify_capacity', $capacity, $describer );
64
+ }
65
+
66
+ /**
67
+ * Tell if the current user has the required ability to operate Imagify.
68
+ *
69
+ * @since 1.6.11
70
+ * @author Grégory Viguier
71
+ *
72
+ * @param string $describer Capacity describer. Possible values are 'manage', 'bulk-optimize', 'manual-optimize', and 'auto-optimize'.
73
+ * @param int $post_id A post ID (a gallery ID for NGG).
74
+ * @return bool
75
+ */
76
+ function imagify_current_user_can( $describer = 'manage', $post_id = null ) {
77
+ static $can_upload;
78
+
79
+ $post_id = $post_id ? $post_id : null;
80
+ $capacity = imagify_get_capacity( $describer );
81
+ $user_can = false;
82
+
83
+ if ( 'manage' !== $describer && 'bulk-optimize' !== $describer ) {
84
+ // Describers that are not 'manage' and 'bulk-optimize' need an additional test for 'upload_files'.
85
+ if ( ! isset( $can_upload ) ) {
86
+ $can_upload = current_user_can( 'upload_files' );
87
+ }
88
+
89
+ if ( $can_upload ) {
90
+ if ( 'upload_files' === $capacity ) {
91
+ // We already know it's true.
92
+ $user_can = true;
93
+ } else {
94
+ $user_can = current_user_can( $capacity, $post_id );
95
+ }
96
+ }
97
+ } else {
98
+ $user_can = current_user_can( $capacity );
99
+ }
100
+
101
+ /**
102
+ * Filter the current user ability to operate Imagify.
103
  *
104
+ * @since 1.6.11
105
+ *
106
+ * @param bool $user_can Tell if the current user has the required ability to operate Imagify.
107
+ * @param string $capacity The user capacity.
108
+ * @param string $describer Capacity describer. Possible values are 'manage', 'bulk-optimize', 'manual-optimize', and 'auto-optimize'.
109
+ * @param int $post_id A post ID (a gallery ID for NGG).
110
  */
111
+ return apply_filters( 'imagify_current_user_can', $user_can, $capacity, $describer, $post_id );
112
+ }
113
+
114
+ /**
115
+ * Sanitize an optimization context.
116
+ *
117
+ * @since 1.6.11
118
+ * @author Grégory Viguier
119
+ *
120
+ * @param string $context The context.
121
+ * @return string
122
+ */
123
+ function imagify_sanitize_context( $context ) {
124
+ $context = preg_replace( '/[^a-zA-Z0-9_\-]/', '', $context );
125
+ return $context ? $context : 'wp';
126
  }
inc/functions/compat.php CHANGED
@@ -289,26 +289,6 @@ if ( ! function_exists( 'wp_normalize_path' ) ) :
289
  }
290
  endif;
291
 
292
- if ( ! function_exists( 'wp_get_additional_image_sizes' ) ) :
293
- /**
294
- * Retrieve additional image sizes.
295
- *
296
- * @since 1.6.10
297
- * @since WP 4.7.0
298
- *
299
- * @global array $_wp_additional_image_sizes
300
- *
301
- * @return array Additional images size data.
302
- */
303
- function wp_get_additional_image_sizes() {
304
- global $_wp_additional_image_sizes;
305
- if ( ! $_wp_additional_image_sizes ) {
306
- $_wp_additional_image_sizes = array(); // WPCS: override ok.
307
- }
308
- return $_wp_additional_image_sizes;
309
- }
310
- endif;
311
-
312
  if ( ! function_exists( 'wp_parse_url' ) ) :
313
  /**
314
  * A wrapper for PHP's parse_url() function that handles consistency in the return
@@ -371,7 +351,6 @@ if ( ! function_exists( 'wp_parse_url' ) ) :
371
  }
372
  endif;
373
 
374
-
375
  if ( ! function_exists( '_get_component_from_parsed_url_array' ) ) :
376
  /**
377
  * Retrieve a specific component from a parsed URL array.
@@ -405,7 +384,6 @@ if ( ! function_exists( '_get_component_from_parsed_url_array' ) ) :
405
  }
406
  endif;
407
 
408
-
409
  if ( ! function_exists( '_wp_translate_php_url_constant_to_key' ) ) :
410
  /**
411
  * Translate a PHP_URL_* constant to the named array keys PHP uses.
@@ -437,3 +415,77 @@ if ( ! function_exists( '_wp_translate_php_url_constant_to_key' ) ) :
437
  }
438
  }
439
  endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
  }
290
  endif;
291
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292
  if ( ! function_exists( 'wp_parse_url' ) ) :
293
  /**
294
  * A wrapper for PHP's parse_url() function that handles consistency in the return
351
  }
352
  endif;
353
 
 
354
  if ( ! function_exists( '_get_component_from_parsed_url_array' ) ) :
355
  /**
356
  * Retrieve a specific component from a parsed URL array.
384
  }
385
  endif;
386
 
 
387
  if ( ! function_exists( '_wp_translate_php_url_constant_to_key' ) ) :
388
  /**
389
  * Translate a PHP_URL_* constant to the named array keys PHP uses.
415
  }
416
  }
417
  endif;
418
+
419
+ if ( ! function_exists( 'wp_get_additional_image_sizes' ) ) :
420
+ /**
421
+ * Retrieve additional image sizes.
422
+ *
423
+ * @since 1.6.10
424
+ * @since WP 4.7.0
425
+ *
426
+ * @global array $_wp_additional_image_sizes
427
+ *
428
+ * @return array Additional images size data.
429
+ */
430
+ function wp_get_additional_image_sizes() {
431
+ global $_wp_additional_image_sizes;
432
+ if ( ! $_wp_additional_image_sizes ) {
433
+ $_wp_additional_image_sizes = array(); // WPCS: override ok.
434
+ }
435
+ return $_wp_additional_image_sizes;
436
+ }
437
+ endif;
438
+
439
+ if ( ! function_exists( 'doing_filter' ) ) :
440
+ /**
441
+ * Retrieve the name of a filter currently being processed.
442
+ *
443
+ * The function current_filter() only returns the most recent filter or action
444
+ * being executed. did_action() returns true once the action is initially
445
+ * processed.
446
+ *
447
+ * This function allows detection for any filter currently being
448
+ * executed (despite not being the most recent filter to fire, in the case of
449
+ * hooks called from hook callbacks) to be verified.
450
+ *
451
+ * @since 1.6.11
452
+ * @since WP 3.9.0
453
+ *
454
+ * @see current_filter()
455
+ * @see did_action()
456
+ * @global array $wp_current_filter Current filter.
457
+ *
458
+ * @param null|string $filter Optional. Filter to check. Defaults to null, which
459
+ * checks if any filter is currently being run.
460
+ * @return bool Whether the filter is currently in the stack.
461
+ */
462
+ function doing_filter( $filter = null ) {
463
+ global $wp_current_filter;
464
+
465
+ if ( null === $filter ) {
466
+ return ! empty( $wp_current_filter );
467
+ }
468
+
469
+ return in_array( $filter, $wp_current_filter, true );
470
+ }
471
+ endif;
472
+
473
+ if ( ! function_exists( 'wp_scripts' ) ) :
474
+ /**
475
+ * Initialize $wp_scripts if it has not been set.
476
+ *
477
+ * @global WP_Scripts $wp_scripts
478
+ *
479
+ * @since 1.6.11
480
+ * @since WP 4.2.0
481
+ *
482
+ * @return WP_Scripts WP_Scripts instance.
483
+ */
484
+ function wp_scripts() {
485
+ global $wp_scripts;
486
+ if ( ! ( $wp_scripts instanceof WP_Scripts ) ) {
487
+ $wp_scripts = new WP_Scripts(); // WPCS: override ok.
488
+ }
489
+ return $wp_scripts;
490
+ }
491
+ endif;
inc/functions/deprecated.php CHANGED
@@ -522,4 +522,260 @@ if ( is_admin() ) :
522
  return Imagify_Notices::notice_is_dismissed( $notice, $user_id );
523
  }
524
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
525
  endif;
522
  return Imagify_Notices::notice_is_dismissed( $notice, $user_id );
523
  }
524
 
525
+ /**
526
+ * Process all thumbnails of a specific image with Imagify with the manual method.
527
+ *
528
+ * @since 1.0
529
+ * @since 1.6.11 Deprecated.
530
+ * @author Jonathan Buttigieg
531
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_manual_upload_callback()
532
+ * @deprecated
533
+ */
534
+ function _do_admin_post_imagify_manual_upload() {
535
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_manual_upload_callback()' );
536
+
537
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_manual_upload_callback();
538
+ }
539
+
540
+ /**
541
+ * Process all thumbnails of a specific image with Imagify with a different optimization level.
542
+ *
543
+ * @since 1.0
544
+ * @since 1.6.11 Deprecated.
545
+ * @author Jonathan Buttigieg
546
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_manual_override_upload_callback()
547
+ * @deprecated
548
+ */
549
+ function _do_admin_post_imagify_manual_override_upload() {
550
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_manual_override_upload_callback()' );
551
+
552
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_manual_override_upload_callback();
553
+ }
554
+
555
+ /**
556
+ * Process one or some thumbnails that are not optimized yet.
557
+ *
558
+ * @since 1.6.10
559
+ * @since 1.6.11 Deprecated.
560
+ * @author Grégory Viguier
561
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_optimize_missing_sizes_callback()
562
+ * @deprecated
563
+ */
564
+ function _do_admin_post_imagify_optimize_missing_sizes() {
565
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_optimize_missing_sizes_callback()' );
566
+
567
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_optimize_missing_sizes_callback();
568
+ }
569
+
570
+ /**
571
+ * Process a restoration to the original attachment.
572
+ *
573
+ * @since 1.0
574
+ * @since 1.6.11 Deprecated.
575
+ * @author Jonathan Buttigieg
576
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_restore_upload_callback()
577
+ * @deprecated
578
+ */
579
+ function _do_admin_post_imagify_restore_upload() {
580
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_restore_upload_callback()' );
581
+
582
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_restore_upload_callback();
583
+ }
584
+
585
+ /**
586
+ * Process all thumbnails of a specific image with Imagify with the bulk method.
587
+ *
588
+ * @since 1.0
589
+ * @since 1.6.11 Deprecated.
590
+ * @author Jonathan Buttigieg
591
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_bulk_upload_callback()
592
+ * @deprecated
593
+ */
594
+ function _do_wp_ajax_imagify_bulk_upload() {
595
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_bulk_upload_callback()' );
596
+
597
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_bulk_upload_callback();
598
+ }
599
+
600
+ /**
601
+ * Optimize image on picture uploading with async request.
602
+ *
603
+ * @since 1.5
604
+ * @since 1.6.11 Deprecated.
605
+ * @author Julio Potier
606
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_async_optimize_upload_new_media_callback()
607
+ * @deprecated
608
+ */
609
+ function _do_admin_post_async_optimize_upload_new_media() {
610
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_async_optimize_upload_new_media_callback()' );
611
+
612
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_async_optimize_upload_new_media_callback();
613
+ }
614
+
615
+ /**
616
+ * Optimize image on picture editing (resize, crop...) with async request.
617
+ *
618
+ * @since 1.4
619
+ * @since 1.6.11 Deprecated.
620
+ * @author Julio Potier
621
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_async_optimize_save_image_editor_file_callback()
622
+ * @deprecated
623
+ */
624
+ function _do_admin_post_async_optimize_save_image_editor_file() {
625
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_async_optimize_save_image_editor_file_callback()' );
626
+
627
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_async_optimize_save_image_editor_file_callback();
628
+ }
629
+
630
+ /**
631
+ * Get all unoptimized attachment ids.
632
+ *
633
+ * @since 1.0
634
+ * @since 1.6.11 Deprecated.
635
+ * @author Jonathan Buttigieg
636
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_get_unoptimized_attachment_ids_callback()
637
+ * @deprecated
638
+ */
639
+ function _do_wp_ajax_imagify_get_unoptimized_attachment_ids() {
640
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_get_unoptimized_attachment_ids_callback()' );
641
+
642
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_get_unoptimized_attachment_ids_callback();
643
+ }
644
+
645
+ /**
646
+ * Check if the backup directory is writable.
647
+ * This is used to display an error message in the plugin's settings page.
648
+ *
649
+ * @since 1.6.8
650
+ * @since 1.6.11 Deprecated.
651
+ * @author Grégory Viguier
652
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_check_backup_dir_is_writable_callback()
653
+ * @deprecated
654
+ */
655
+ function _do_wp_ajax_imagify_check_backup_dir_is_writable() {
656
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_check_backup_dir_is_writable_callback()' );
657
+
658
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_check_backup_dir_is_writable_callback();
659
+ }
660
+
661
+ /**
662
+ * Create a new Imagify account.
663
+ *
664
+ * @since 1.0
665
+ * @since 1.6.11 Deprecated.
666
+ * @author Jonathan Buttigieg
667
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_signup_callback()
668
+ * @deprecated
669
+ */
670
+ function _do_wp_ajax_imagify_signup() {
671
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_signup_callback()' );
672
+
673
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_signup_callback();
674
+ }
675
+
676
+ /**
677
+ * Process an API key check validity.
678
+ *
679
+ * @since 1.0
680
+ * @since 1.6.11 Deprecated.
681
+ * @author Jonathan Buttigieg
682
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_check_api_key_validity_callback()
683
+ * @deprecated
684
+ */
685
+ function _do_wp_ajax_imagify_check_api_key_validity() {
686
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_check_api_key_validity_callback()' );
687
+
688
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_check_api_key_validity_callback();
689
+ }
690
+
691
+ /**
692
+ * Get admin bar profile output.
693
+ *
694
+ * @since 1.2.3
695
+ * @since 1.6.11 Deprecated.
696
+ * @author Jonathan Buttigieg
697
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_get_admin_bar_profile_callback()
698
+ * @deprecated
699
+ */
700
+ function _do_wp_ajax_imagify_get_admin_bar_profile() {
701
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_get_admin_bar_profile_callback()' );
702
+
703
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_get_admin_bar_profile_callback();
704
+ }
705
+
706
+ /**
707
+ * Get pricings from API for Onetime and Plans at the same time.
708
+ *
709
+ * @since 1.6
710
+ * @since 1.6.11 Deprecated.
711
+ * @author Geoffrey Crofte
712
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_get_prices_callback()
713
+ * @deprecated
714
+ */
715
+ function _imagify_get_prices_from_api() {
716
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_get_prices_callback()' );
717
+
718
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_get_prices_callback();
719
+ }
720
+
721
+ /**
722
+ * Check Coupon code on modal popin.
723
+ *
724
+ * @since 1.6
725
+ * @since 1.6.11 Deprecated.
726
+ * @author Geoffrey Crofte
727
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_check_coupon_callback()
728
+ * @deprecated
729
+ */
730
+ function _imagify_check_coupon_code() {
731
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_check_coupon_callback()' );
732
+
733
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_check_coupon_callback();
734
+ }
735
+
736
+ /**
737
+ * Get current discount promotion to display information on payment modal.
738
+ *
739
+ * @since 1.6.3
740
+ * @since 1.6.11 Deprecated.
741
+ * @author Geoffrey Crofte
742
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_get_discount_callback()
743
+ * @deprecated
744
+ */
745
+ function _imagify_get_discount() {
746
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_get_discount_callback()' );
747
+
748
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_get_discount_callback();
749
+ }
750
+
751
+ /**
752
+ * Get estimated sizes from the WordPress library.
753
+ *
754
+ * @since 1.6
755
+ * @since 1.6.11 Deprecated.
756
+ * @author Geoffrey Crofte
757
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_get_images_counts_callback()
758
+ * @deprecated
759
+ */
760
+ function _imagify_get_estimated_sizes() {
761
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_get_images_counts_callback()' );
762
+
763
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_get_images_counts_callback();
764
+ }
765
+
766
+ /**
767
+ * Estimate sizes and update the options values for them.
768
+ *
769
+ * @since 1.6
770
+ * @since 1.6.11 Deprecated.
771
+ * @author Remy Perona
772
+ * @see Imagify_Admin_Ajax_Post::get_instance()->imagify_update_estimate_sizes_callback()
773
+ * @deprecated
774
+ */
775
+ function _imagify_update_estimate_sizes() {
776
+ _deprecated_function( __FUNCTION__ . '()', '1.6.11', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_update_estimate_sizes_callback()' );
777
+
778
+ Imagify_Admin_Ajax_Post::get_instance()->imagify_update_estimate_sizes_callback();
779
+ }
780
+
781
  endif;
inc/functions/i18n.php CHANGED
@@ -4,13 +4,15 @@ defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
4
  /**
5
  * Get all translations we can use with wp_localize_script().
6
  *
7
- * @since 1.5
8
  * @author Jonathan Buttigieg
9
  *
10
  * @param string $context The translation context.
11
  * @return array $translations The translations.
12
  */
13
  function get_imagify_localize_script_translations( $context ) {
 
 
14
  switch ( $context ) {
15
  case 'admin-bar':
16
  if ( is_admin() ) {
@@ -72,8 +74,19 @@ function get_imagify_localize_script_translations( $context ) {
72
  );
73
 
74
  case 'twentytwenty':
 
 
 
 
 
 
 
75
  return array(
76
- 'labels' => array(
 
 
 
 
77
  'filesize' => __( 'File Size:', 'imagify' ),
78
  'saving' => __( 'Original Saving:', 'imagify' ),
79
  'close' => __( 'Close', 'imagify' ),
4
  /**
5
  * Get all translations we can use with wp_localize_script().
6
  *
7
+ * @since 1.5
8
  * @author Jonathan Buttigieg
9
  *
10
  * @param string $context The translation context.
11
  * @return array $translations The translations.
12
  */
13
  function get_imagify_localize_script_translations( $context ) {
14
+ global $post_id;
15
+
16
  switch ( $context ) {
17
  case 'admin-bar':
18
  if ( is_admin() ) {
74
  );
75
 
76
  case 'twentytwenty':
77
+ if ( imagify_is_screen( 'attachment' ) ) {
78
+ $image = wp_get_attachment_image_src( $post_id, 'full' );
79
+ $image = $image && is_array( $image ) ? $image : array( '', 0, 0 );
80
+ } else {
81
+ $image = array( '', 0, 0 );
82
+ }
83
+
84
  return array(
85
+ 'imageSrc' => $image[0],
86
+ 'imageWidth' => $image[1],
87
+ 'imageHeight' => $image[2],
88
+ 'widthLimit' => 360, // See _imagify_add_actions_to_media_list_row().
89
+ 'labels' => array(
90
  'filesize' => __( 'File Size:', 'imagify' ),
91
  'saving' => __( 'Original Saving:', 'imagify' ),
92
  'close' => __( 'Close', 'imagify' ),
inc/functions/process.php CHANGED
@@ -151,11 +151,19 @@ function do_imagify( $file_path, $args = array() ) {
151
  * @since 1.4
152
  */
153
  function imagify_do_async_job( $body ) {
 
 
 
 
 
 
 
 
154
  $args = array(
155
  'timeout' => 0.01,
156
  'blocking' => false,
157
  'body' => $body,
158
- 'cookies' => $_COOKIE,
159
  'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
160
  );
161
 
@@ -169,6 +177,28 @@ function imagify_do_async_job( $body ) {
169
  */
170
  $args = apply_filters( 'imagify_do_async_job_args', $args );
171
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  wp_remote_post( admin_url( 'admin-ajax.php' ), $args );
173
  }
174
 
151
  * @since 1.4
152
  */
153
  function imagify_do_async_job( $body ) {
154
+ // No need to send all the cookies.
155
+ $cookies = isset( $_COOKIE ) && is_array( $_COOKIE ) ? $_COOKIE : array();
156
+ $cookies = array_intersect_key( $_COOKIE, array(
157
+ SECURE_AUTH_COOKIE => '',
158
+ AUTH_COOKIE => '',
159
+ LOGGED_IN_COOKIE => '',
160
+ ) );
161
+
162
  $args = array(
163
  'timeout' => 0.01,
164
  'blocking' => false,
165
  'body' => $body,
166
+ 'cookies' => $cookies,
167
  'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
168
  );
169
 
177
  */
178
  $args = apply_filters( 'imagify_do_async_job_args', $args );
179
 
180
+ /**
181
+ * It can be a XML-RPC request. The problem is that XML-RPC doesn't use cookies.
182
+ */
183
+ if ( defined( 'XMLRPC_REQUEST' ) && get_current_user_id() ) {
184
+ /**
185
+ * In old WP versions, the field "option_name" in the wp_options table was limited to 64 characters.
186
+ * From 64, remove 19 characters for "_transient_timeout_" = 45.
187
+ * Then remove 12 characters for "imagify_rpc_" (transient name) = 33.
188
+ * Hopefully, a md5 is 32 characters long.
189
+ */
190
+ $rpc_id = md5( maybe_serialize( $body ) );
191
+
192
+ // Send the request to our RPC bridge instead.
193
+ $args['body']['imagify_rpc_action'] = $args['body']['action'];
194
+ $args['body']['action'] = 'imagify_rpc';
195
+ $args['body']['imagify_rpc_id'] = $rpc_id;
196
+ $args['body']['imagify_rpc_nonce'] = wp_create_nonce( 'imagify_rpc_' . $rpc_id );
197
+
198
+ // Since we can't send cookies to keep the user logged in, store the user ID in a transient.
199
+ set_transient( 'imagify_rpc_' . $rpc_id, get_current_user_id(), 30 );
200
+ }
201
+
202
  wp_remote_post( admin_url( 'admin-ajax.php' ), $args );
203
  }
204
 
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: wp_media, GregLone
3
  Tags: compress image, images, performance, optimization, photos, upload, resize, gif, png, jpg, reduce image size, retina
4
  Requires at least: 3.7.0
5
  Tested up to: 4.8.2
6
- Stable tag: 1.6.10
7
 
8
  Dramatically reduce image file sizes without losing quality, make your website load faster, boost your SEO and save money on your bandwidth.
9
 
@@ -136,6 +136,13 @@ When the plugin is disabled, your existing images remain optimized. Backups of t
136
  3. Media Page
137
 
138
  == Changelog ==
 
 
 
 
 
 
 
139
  = 1.6.10 =
140
  * New: if new thumbnail sizes appear after activating a new theme or plugin, you can now optimize only these missing sizes instead of restoring and re-optimizing all images.
141
  * Improvement: CSS and JS files have been split and are loaded only when needed.
3
  Tags: compress image, images, performance, optimization, photos, upload, resize, gif, png, jpg, reduce image size, retina
4
  Requires at least: 3.7.0
5
  Tested up to: 4.8.2
6
+ Stable tag: 1.6.11
7
 
8
  Dramatically reduce image file sizes without losing quality, make your website load faster, boost your SEO and save money on your bandwidth.
9
 
136
  3. Media Page
137
 
138
  == Changelog ==
139
+ = 1.6.11 =
140
+ * Improvement: Imagify now works with the iOS app, and with XML-RPC in general.
141
+ * Improvement: we harmonized and improved how user roles are handled.
142
+ * Improvement: prevent optimized image to be cached by the browser in the comparison tool.
143
+ * Fix: sometimes the comparison tool's button wouldn't show on the attachment edition page.
144
+ * Fix: the bulk optimization button works again.
145
+
146
  = 1.6.10 =
147
  * New: if new thumbnail sizes appear after activating a new theme or plugin, you can now optimize only these missing sizes instead of restoring and re-optimizing all images.
148
  * Improvement: CSS and JS files have been split and are loaded only when needed.
uninstall.php CHANGED
@@ -16,11 +16,13 @@ delete_site_transient( 'imagify_max_image_size' );
16
  wp_clear_scheduled_hook( 'imagify_rating_event' );
17
  wp_clear_scheduled_hook( 'imagify_update_library_size_calculations_event' );
18
 
19
- // WP transients.
20
- $wpdb->query( 'DELETE from ' . $wpdb->options . ' WHERE option_name LIKE "_transient_imagify-async-in-progress-%"' );
21
-
22
- // NextGen Gallery transients.
23
- $wpdb->query( 'DELETE from ' . $wpdb->options . ' WHERE option_name LIKE "_transient_imagify-ngg-async-in-progress-%"' );
 
 
24
 
25
  // Delete all user meta related to Imagify.
26
  delete_metadata( 'user', '', '_imagify_ignore_notices', '', true );
16
  wp_clear_scheduled_hook( 'imagify_rating_event' );
17
  wp_clear_scheduled_hook( 'imagify_update_library_size_calculations_event' );
18
 
19
+ // Delete transients.
20
+ $transients = implode( '" OR option_name LIKE "', array(
21
+ '_transient_%imagify-async-in-progress-%',
22
+ '_transient_%imagify-ngg-async-in-progress-%',
23
+ '_transient_%imagify_rpc_%',
24
+ ) );
25
+ $wpdb->query( 'DELETE from ' . $wpdb->options . ' WHERE option_name LIKE "' . $transients . '"' ); // WPCS: unprepared SQL ok.
26
 
27
  // Delete all user meta related to Imagify.
28
  delete_metadata( 'user', '', '_imagify_ignore_notices', '', true );